From 17f63de642c3cb613f91eabd2e19ebed6785f755 Mon Sep 17 00:00:00 2001 From: Bert Vermeulen Date: Sat, 27 Apr 2013 17:29:46 +0200 Subject: [PATCH] Fix output API receive() function This changes the new output API's recv() to receive(), and has it return an integer status code. The output of the function, if any, is stored in a new parameter as a pointer to a newly allocated GString. All output modules using this API have been adjusted. --- backend.c | 4 ++-- libsigrok.h | 34 +++++++++++++++++++++++++++++----- output/analog.c | 29 +++++++++++------------------ output/ols.c | 37 ++++++++++++++++++------------------- output/vcd.c | 25 ++++++++++++------------- 5 files changed, 72 insertions(+), 57 deletions(-) diff --git a/backend.c b/backend.c index c29968a4..ca1460f8 100644 --- a/backend.c +++ b/backend.c @@ -287,8 +287,8 @@ static int sanity_check_all_output_modules(void) } /* All modules must provide a data or recv API callback. */ - if (!outputs[i]->data && !outputs[i]->recv) { - sr_err("No data/recv in module %d ('%s').", i, d); + if (!outputs[i]->data && !outputs[i]->receive) { + sr_err("No data/receive in module %d ('%s').", i, d); errors++; } diff --git a/libsigrok.h b/libsigrok.h index 73af2d9d..6cda5543 100644 --- a/libsigrok.h +++ b/libsigrok.h @@ -454,7 +454,7 @@ struct sr_output_format { * data_out parameter, so the caller knows not to try * and g_free() it. * - * Note: This API call is obsolete, use recv() instead. + * Note: This API call is obsolete, use receive() instead. * * @param o Pointer to the respective 'struct sr_output'. * @param data_in Pointer to the input data buffer. @@ -486,7 +486,7 @@ struct sr_output_format { * it stored in the data_out and length_out * parameters, or NULL if no output was generated. * - * Note: This API call is obsolete, use recv() instead. + * Note: This API call is obsolete, use receive() instead. * * @param o Pointer to the respective 'struct sr_output'. * @param event_type Type of event that occured. @@ -496,11 +496,35 @@ struct sr_output_format { * @return SR_OK upon success, a negative error code otherwise. */ int (*event) (struct sr_output *o, int event_type, uint8_t **data_out, - uint64_t *length_out); + uint64_t *length_out); - GString *(*recv) (struct sr_output *o, const struct sr_dev_inst *sdi, - const struct sr_datafeed_packet *packet); + /** + * This function is passed a copy of every packed in the data feed. + * Any output generated by the output module in response to the + * packet should be returned in a newly allocated GString + * out, which will be freed by the caller. + * + * Packets not of interest to the output module can just be ignored, + * and the out parameter set to NULL. + * + * @param o Pointer to the respective 'struct sr_output'. + * @param sdi The device instance that generated the packet. + * @param packet The complete packet. + * @param out A pointer where a GString * should be stored if + * the module generates output, or NULL if not. + * + * @return SR_OK upon success, a negative error code otherwise. + */ + int (*receive) (struct sr_output *o, const struct sr_dev_inst *sdi, + const struct sr_datafeed_packet *packet, GString **out); + /** + * This function is called after the caller is finished using + * the output module, and can be used to free any internal + * resources the module may keep. + * + * @return SR_OK upon success, a negative error code otherwise. + */ int (*cleanup) (struct sr_output *o); }; diff --git a/output/analog.c b/output/analog.c index 68d1b623..e7e475fc 100644 --- a/output/analog.c +++ b/output/analog.c @@ -36,7 +36,6 @@ struct context { int num_enabled_probes; GPtrArray *probelist; - GString *out; }; static int init(struct sr_output *o) @@ -66,8 +65,6 @@ static int init(struct sr_output *o) ctx->num_enabled_probes++; } - ctx->out = g_string_sized_new(512); - return SR_OK; } @@ -188,10 +185,9 @@ static void fancyprint(int unit, int mqflags, float value, GString *out) g_string_append_c(out, '\n'); } -static GString *receive(struct sr_output *o, const struct sr_dev_inst *sdi, - const struct sr_datafeed_packet *packet) +static int receive(struct sr_output *o, const struct sr_dev_inst *sdi, + const struct sr_datafeed_packet *packet, GString **out) { - struct context *ctx; const struct sr_datafeed_analog *analog; struct sr_probe *probe; GSList *l; @@ -200,35 +196,33 @@ static GString *receive(struct sr_output *o, const struct sr_dev_inst *sdi, (void)sdi; + *out = NULL; if (!o || !o->sdi) - return NULL; - ctx = o->internal; + return SR_ERR_ARG; - g_string_set_size(ctx->out, 0); switch (packet->type) { - case SR_DF_HEADER: - break; case SR_DF_FRAME_BEGIN: - g_string_append_printf(ctx->out, "FRAME-BEGIN\n"); + *out = g_string_new("FRAME-BEGIN\n"); break; case SR_DF_FRAME_END: - g_string_append_printf(ctx->out, "FRAME-END\n"); + *out = g_string_new("FRAME-END\n"); break; case SR_DF_ANALOG: analog = packet->payload; fdata = (const float *)analog->data; + *out = g_string_sized_new(512); for (i = 0; i < analog->num_samples; i++) { for (l = analog->probes, p = 0; l; l = l->next, p++) { probe = l->data; - g_string_append_printf(ctx->out, "%s: ", probe->name); + g_string_append_printf(*out, "%s: ", probe->name); fancyprint(analog->unit, analog->mqflags, - fdata[i + p], ctx->out); + fdata[i + p], *out); } } break; } - return ctx->out; + return SR_OK; } static int cleanup(struct sr_output *o) @@ -240,7 +234,6 @@ static int cleanup(struct sr_output *o) ctx = o->internal; g_ptr_array_free(ctx->probelist, 1); - g_string_free(ctx->out, 1); g_free(ctx); o->internal = NULL; @@ -252,6 +245,6 @@ SR_PRIV struct sr_output_format output_analog = { .description = "Analog data", .df_type = SR_DF_ANALOG, .init = init, - .recv = receive, + .receive = receive, .cleanup = cleanup }; diff --git a/output/ols.c b/output/ols.c index a77dc627..09115f81 100644 --- a/output/ols.c +++ b/output/ols.c @@ -41,7 +41,7 @@ #define sr_err(s, args...) sr_err(DRIVER_LOG_DOMAIN s, ## args) struct context { - uint64_t samplerate; + uint64_t samplerate; uint64_t num_samples; }; @@ -55,7 +55,7 @@ static int init(struct sr_output *o) } o->internal = ctx; - ctx->samplerate = 0; + ctx->samplerate = 0; ctx->num_samples = 0; return SR_OK; @@ -69,7 +69,7 @@ static GString *gen_header(const struct sr_dev_inst *sdi, struct context *ctx) GVariant *gvar; int num_enabled_probes; - if (!ctx->samplerate && sr_config_get(sdi->driver, SR_CONF_SAMPLERATE, + if (!ctx->samplerate && sr_config_get(sdi->driver, SR_CONF_SAMPLERATE, &gvar, sdi) == SR_OK) { ctx->samplerate = g_variant_get_uint64(gvar); g_variant_unref(gvar); @@ -92,51 +92,50 @@ static GString *gen_header(const struct sr_dev_inst *sdi, struct context *ctx) return s; } -static GString *receive(struct sr_output *o, const struct sr_dev_inst *sdi, - const struct sr_datafeed_packet *packet) +static int receive(struct sr_output *o, const struct sr_dev_inst *sdi, + const struct sr_datafeed_packet *packet, GString **out) { struct context *ctx; const struct sr_datafeed_meta *meta; const struct sr_datafeed_logic *logic; const struct sr_config *src; GSList *l; - GString *out; unsigned int i, j; uint8_t c; + *out = NULL; if (!o || !o->sdi) - return NULL; + return SR_ERR_ARG; ctx = o->internal; - out = NULL; switch (packet->type) { - case SR_DF_META: + case SR_DF_META: meta = packet->payload; for (l = meta->config; l; l = l->next) { src = l->data; if (src->key == SR_CONF_SAMPLERATE) ctx->samplerate = g_variant_get_uint64(src->data); } - break; - case SR_DF_LOGIC: + break; + case SR_DF_LOGIC: logic = packet->payload; if (ctx->num_samples == 0) { /* First logic packet in the feed. */ - out = gen_header(sdi, ctx); + *out = gen_header(sdi, ctx); } else - out = g_string_sized_new(512); + *out = g_string_sized_new(512); for (i = 0; i <= logic->length - logic->unitsize; i += logic->unitsize) { for (j = 0; j < logic->unitsize; j++) { /* The OLS format wants the samples presented MSB first. */ c = *((uint8_t *)logic->data + i + logic->unitsize - 1 - j); - g_string_append_printf(out, "%02x", c); + g_string_append_printf(*out, "%02x", c); } - g_string_append_printf(out, "@%"PRIu64"\n", ctx->num_samples++); + g_string_append_printf(*out, "@%"PRIu64"\n", ctx->num_samples++); } break; } - return out; + return SR_OK; } static int cleanup(struct sr_output *o) @@ -147,8 +146,8 @@ static int cleanup(struct sr_output *o) return SR_ERR_ARG; ctx = o->internal; - g_free(ctx); - o->internal = NULL; + g_free(ctx); + o->internal = NULL; return SR_OK; } @@ -158,6 +157,6 @@ SR_PRIV struct sr_output_format output_ols = { .description = "OpenBench Logic Sniffer", .df_type = SR_DF_LOGIC, .init = init, - .recv = receive, + .receive = receive, .cleanup = cleanup }; diff --git a/output/vcd.c b/output/vcd.c index 90493f05..6e13d704 100644 --- a/output/vcd.c +++ b/output/vcd.c @@ -151,12 +151,11 @@ static int init(struct sr_output *o) return SR_OK; } -static GString *receive(struct sr_output *o, const struct sr_dev_inst *sdi, - const struct sr_datafeed_packet *packet) +static int receive(struct sr_output *o, const struct sr_dev_inst *sdi, + const struct sr_datafeed_packet *packet, GString **out) { const struct sr_datafeed_logic *logic; struct context *ctx; - GString *text; unsigned int i; int p, curbit, prevbit, index; uint8_t *sample; @@ -164,23 +163,23 @@ static GString *receive(struct sr_output *o, const struct sr_dev_inst *sdi, (void)sdi; + *out = NULL; if (!o || !o->internal) - return NULL; + return SR_ERR_ARG; ctx = o->internal; if (packet->type == SR_DF_END) { - text = g_string_sized_new(16); - g_string_printf(text, "$dumpoff\n$end\n"); - return text; + *out = g_string_new("$dumpoff\n$end\n"); + return SR_OK; } else if (packet->type != SR_DF_LOGIC) - return NULL; + return SR_OK; if (ctx->header) { /* The header is still here, this must be the first packet. */ - text = ctx->header; + *out = ctx->header; ctx->header = NULL; } else { - text = g_string_sized_new(512); + *out = g_string_sized_new(512); } logic = packet->payload; @@ -199,7 +198,7 @@ static GString *receive(struct sr_output *o, const struct sr_dev_inst *sdi, continue; /* Output which signal changed to which value. */ - g_string_append_printf(text, "#%" PRIu64 "\n%i%c\n", + g_string_append_printf(*out, "#%" PRIu64 "\n%i%c\n", (uint64_t)(((float)samplecount / ctx->samplerate) * ctx->period), curbit, (char)('!' + p)); } @@ -207,7 +206,7 @@ static GString *receive(struct sr_output *o, const struct sr_dev_inst *sdi, memcpy(ctx->prevsample, sample, ctx->unitsize); } - return text; + return SR_OK; } static int cleanup(struct sr_output *o) @@ -228,6 +227,6 @@ struct sr_output_format output_vcd = { .description = "Value Change Dump (VCD)", .df_type = SR_DF_LOGIC, .init = init, - .recv = receive, + .receive = receive, .cleanup = cleanup, };