X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Finput%2Fvcd.c;h=1064ad6a33ddc3e72599f2bc12826a73f840b32f;hb=7cfa93b013341e1980461c4a56c8d8c0bca800c8;hp=413712301318787f7201f9389de5748418dbfbeb;hpb=c1310f7deba7ac1f4ce75fbb5cc9b498ee66aa49;p=libsigrok.git diff --git a/src/input/vcd.c b/src/input/vcd.c index 41371230..1064ad6a 100644 --- a/src/input/vcd.c +++ b/src/input/vcd.c @@ -205,15 +205,6 @@ static void free_channel(void *data) g_free(vcd_ch); } -/* TODO Drop the local decl when this has become a common helper. */ -void sr_channel_group_free(struct sr_channel_group *cg); - -/* Wrapper for GDestroyNotify compatibility. */ -static void cg_free(void *p) -{ - sr_channel_group_free(p); -} - /* * Another timestamp delta was observed, update statistics: Update the * sorted list of minimum values, and increment the occurance counter. @@ -1074,10 +1065,8 @@ static void create_channels(const struct sr_input *in, if (vcd_ch->type != ch_type) continue; cg = NULL; - if (vcd_ch->size != 1) { - cg = g_malloc0(sizeof(*cg)); - cg->name = g_strdup(vcd_ch->name); - } + if (vcd_ch->size != 1) + cg = sr_channel_group_new(sdi, vcd_ch->name, NULL); for (size_idx = 0; size_idx < vcd_ch->size; size_idx++) { ch_name = get_channel_name(vcd_ch, size_idx); sr_dbg("sigrok channel idx %zu, name %s, type %s, en %d.", @@ -1089,8 +1078,6 @@ static void create_channels(const struct sr_input *in, if (cg) cg->channels = g_slist_append(cg->channels, ch); } - if (cg) - sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); } } @@ -1135,7 +1122,7 @@ static void keep_header_for_reread(const struct sr_input *in) inc = in->priv; - g_slist_free_full(inc->prev.sr_groups, cg_free); + g_slist_free_full(inc->prev.sr_groups, sr_channel_group_free_cb); inc->prev.sr_groups = in->sdi->channel_groups; in->sdi->channel_groups = NULL; @@ -1174,7 +1161,7 @@ static gboolean check_header_in_reread(const struct sr_input *in) return FALSE; } - g_slist_free_full(in->sdi->channel_groups, cg_free); + g_slist_free_full(in->sdi->channel_groups, sr_channel_group_free_cb); in->sdi->channel_groups = inc->prev.sr_groups; inc->prev.sr_groups = NULL; @@ -1189,7 +1176,7 @@ static gboolean check_header_in_reread(const struct sr_input *in) static int parse_header(const struct sr_input *in, GString *buf) { struct context *inc; - gboolean status; + gboolean enddef_seen, header_valid; char *name, *contents; size_t size; int ret; @@ -1197,34 +1184,35 @@ static int parse_header(const struct sr_input *in, GString *buf) inc = in->priv; /* Parse sections until complete header was seen. */ - status = FALSE; + enddef_seen = FALSE; + header_valid = TRUE; name = contents = NULL; inc->conv_bits.max_bits = 1; while (parse_section(buf, &name, &contents)) { sr_dbg("Section '%s', contents '%s'.", name, contents); if (g_strcmp0(name, "enddefinitions") == 0) { - status = TRUE; + enddef_seen = TRUE; goto done_section; } if (g_strcmp0(name, "timescale") == 0) { if (parse_timescale(inc, contents) != SR_OK) - status = FALSE; + header_valid = FALSE; goto done_section; } if (g_strcmp0(name, "scope") == 0) { if (parse_scope(inc, contents, FALSE) != SR_OK) - status = FALSE; + header_valid = FALSE; goto done_section; } if (g_strcmp0(name, "upscope") == 0) { if (parse_scope(inc, NULL, TRUE) != SR_OK) - status = FALSE; + header_valid = FALSE; goto done_section; } if (g_strcmp0(name, "var") == 0) { if (parse_header_var(inc, contents) != SR_OK) - status = FALSE; + header_valid = FALSE; goto done_section; } @@ -1234,14 +1222,14 @@ done_section: g_free(contents); contents = NULL; - if (status) + if (enddef_seen) break; } g_free(name); g_free(contents); - inc->got_header = status; - if (!status) + inc->got_header = enddef_seen && header_valid; + if (!inc->got_header) return SR_ERR_DATA; /* Create sigrok channels here, late, logic before analog. */ @@ -2021,6 +2009,9 @@ static int process_buffer(struct sr_input *in, gboolean is_eof) inc = in->priv; + if (!inc->got_header) + return SR_ERR_DATA; + /* Send feed header and samplerate (once) before sample data. */ if (!inc->started) { std_session_send_df_header(in->sdi); @@ -2181,11 +2172,14 @@ static int end(struct sr_input *in) ret = SR_OK; /* Flush most recently queued sample data when EOF is seen. */ - count = inc->data_after_timestamp ? 1 : 0; - add_samples(in, count, TRUE); + if (inc->got_header && ret == SR_OK) { + count = inc->data_after_timestamp ? 1 : 0; + add_samples(in, count, TRUE); + } /* Optionally suggest downsampling after all input data was seen. */ - (void)ts_stats_post(inc, !inc->data_after_timestamp); + if (inc->got_header) + (void)ts_stats_post(inc, !inc->data_after_timestamp); /* Must send DF_END when DF_HEADER was sent before. */ if (inc->started)