X-Git-Url: https://sigrok.org/gitweb/?p=libsigrok.git;a=blobdiff_plain;f=src%2Finput%2Fvcd.c;h=0ca7705a08bd6afb441c7f51848aee0968105972;hp=62b9a090086f55d4c8dbb6fda98878605ed27c2d;hb=c1aae90038456a61d0f9313d34e6107c3440d3e7;hpb=4f979115a4206bc1ff72c0319a340cbcad0f4b06 diff --git a/src/input/vcd.c b/src/input/vcd.c index 62b9a090..0ca7705a 100644 --- a/src/input/vcd.c +++ b/src/input/vcd.c @@ -61,7 +61,7 @@ #include #include #include -#include "libsigrok.h" +#include #include "libsigrok-internal.h" #define LOG_PREFIX "input/vcd" @@ -87,7 +87,6 @@ struct vcd_channel { gchar *identifier; }; - /* * Reads a single VCD section from input file and parses it to name/contents. * e.g. $timescale 1ps $end => "timescale" "1ps" @@ -404,13 +403,10 @@ static void parse_contents(const struct sr_input *in, char *data) static int init(struct sr_input *in, GHashTable *options) { - struct sr_channel *ch; int num_channels, i; char name[16]; struct context *inc; - inc = g_malloc0(sizeof(struct context)); - num_channels = g_variant_get_int32(g_hash_table_lookup(options, "numchannels")); if (num_channels < 1) { sr_err("Invalid value for numchannels: must be at least 1."); @@ -420,6 +416,7 @@ static int init(struct sr_input *in, GHashTable *options) sr_err("No more than 64 channels supported."); return SR_ERR_ARG; } + inc = in->priv = g_malloc0(sizeof(struct context)); inc->maxchannels = num_channels; inc->downsample = g_variant_get_int32(g_hash_table_lookup(options, "downsample")); @@ -430,13 +427,12 @@ static int init(struct sr_input *in, GHashTable *options) inc->skip = g_variant_get_int32(g_hash_table_lookup(options, "skip")); inc->skip /= inc->downsample; - in->sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, NULL, NULL, NULL); + in->sdi = g_malloc0(sizeof(struct sr_dev_inst)); in->priv = inc; for (i = 0; i < num_channels; i++) { snprintf(name, 16, "%d", i); - ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, name); - in->sdi->channels = g_slist_append(in->sdi->channels, ch); + sr_channel_new(in->sdi, i, SR_CHANNEL_LOGIC, TRUE, name); } return SR_OK; @@ -458,7 +454,7 @@ static gboolean have_header(GString *buf) return FALSE; } -static int receive(const struct sr_input *in, GString *buf) +static int process_buffer(struct sr_input *in) { struct sr_datafeed_packet packet; struct sr_datafeed_meta meta; @@ -467,18 +463,9 @@ static int receive(const struct sr_input *in, GString *buf) uint64_t samplerate; char *p; - g_string_append_len(in->buf, buf->str, buf->len); - inc = in->priv; - if (!inc->got_header) { - if (!have_header(in->buf)) - return SR_OK; - if (!parse_header(in, in->buf) != SR_OK) - /* There was a header in there, but it was malformed. */ - return SR_ERR; - + if (!inc->started) { std_session_send_df_header(in->sdi, LOG_PREFIX); - inc->started = TRUE; packet.type = SR_DF_META; packet.payload = &meta; @@ -487,6 +474,8 @@ static int receive(const struct sr_input *in, GString *buf) meta.config = g_slist_append(NULL, src); sr_session_send(in->sdi, &packet); sr_config_free(src); + + inc->started = TRUE; } while ((p = g_strrstr_len(in->buf->str, in->buf->len, "\n"))) { @@ -500,23 +489,57 @@ static int receive(const struct sr_input *in, GString *buf) return SR_OK; } -static int cleanup(struct sr_input *in) +static int receive(struct sr_input *in, GString *buf) +{ + struct context *inc; + int ret; + + g_string_append_len(in->buf, buf->str, buf->len); + + inc = in->priv; + if (!inc->got_header) { + if (!have_header(in->buf)) + return SR_OK; + if (!parse_header(in, in->buf)) + /* There was a header in there, but it was malformed. */ + return SR_ERR; + + in->sdi_ready = TRUE; + /* sdi is ready, notify frontend. */ + return SR_OK; + } + + ret = process_buffer(in); + + return ret; +} + +static int end(struct sr_input *in) { struct sr_datafeed_packet packet; struct context *inc; + int ret; + + if (in->sdi_ready) + ret = process_buffer(in); + else + ret = SR_OK; inc = in->priv; if (inc->started) { - /* End of stream. */ packet.type = SR_DF_END; sr_session_send(in->sdi, &packet); } - g_slist_free_full(inc->channels, free_channel); - g_free(inc); - in->priv = NULL; + return ret; +} - return SR_OK; +static void cleanup(struct sr_input *in) +{ + struct context *inc; + + inc = in->priv; + g_slist_free_full(inc->channels, free_channel); } static struct sr_option options[] = { @@ -543,10 +566,12 @@ SR_PRIV struct sr_input_module input_vcd = { .id = "vcd", .name = "VCD", .desc = "Value Change Dump", + .exts = (const char*[]){"vcd", NULL}, .metadata = { SR_INPUT_META_HEADER | SR_INPUT_META_REQUIRED }, .options = get_options, .format_match = format_match, .init = init, .receive = receive, + .end = end, .cleanup = cleanup, };