X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Finput%2Fvcd.c;h=bf203193ef6ef06ea83ad1fe22083b83ba913b2a;hb=bbcffe51d29343f7648e1e2f3b925dd571984bd3;hp=66f126b422ed8c0f1521b14d0dcf324813b34459;hpb=3f48fc82b5bc13e749b30a47dd6ca06f8cd2b00e;p=libsigrok.git diff --git a/src/input/vcd.c b/src/input/vcd.c index 66f126b4..bf203193 100644 --- a/src/input/vcd.c +++ b/src/input/vcd.c @@ -26,7 +26,7 @@ * * skip: Allows skipping until given timestamp in the file. * This can speed up analyzing of long captures. - * + * * Value < 0: Skip until first timestamp listed in * the file. (default) * @@ -72,6 +72,7 @@ struct context { gboolean started; gboolean got_header; + uint64_t prev_timestamp; uint64_t samplerate; unsigned int maxchannels; unsigned int channelcount; @@ -93,7 +94,7 @@ struct vcd_channel { /* * Reads a single VCD section from input file and parses it to name/contents. - * e.g. $timescale 1ps $end => "timescale" "1ps" + * e.g. $timescale 1ps $end => "timescale" "1ps" */ static gboolean parse_section(GString *buf, gchar **name, gchar **contents) { @@ -105,6 +106,10 @@ static gboolean parse_section(GString *buf, gchar **name, gchar **contents) status = FALSE; pos = 0; + /* Skip UTF8 BOM */ + if (buf->len >= 3 && !strncmp(buf->str, "\xef\xbb\xbf", 3)) + pos = 3; + /* Skip any initial white-space. */ while (pos < buf->len && g_ascii_isspace(buf->str[pos])) pos++; @@ -363,12 +368,11 @@ static void process_bit(struct context *inc, char *identifier, unsigned int bit) static void parse_contents(const struct sr_input *in, char *data) { struct context *inc; - uint64_t timestamp, prev_timestamp; + uint64_t timestamp; unsigned int bit, i; char **tokens; inc = in->priv; - prev_timestamp = 0; /* Read one space-delimited token at a time. */ tokens = g_strsplit_set(data, " \t\r\n", 0); @@ -395,22 +399,22 @@ static void parse_contents(const struct sr_input *in, char *data) */ if (inc->skip < 0) { inc->skip = timestamp; - prev_timestamp = timestamp; + inc->prev_timestamp = timestamp; } else if (inc->skip > 0 && timestamp < (uint64_t)inc->skip) { - prev_timestamp = inc->skip; - } else if (timestamp == prev_timestamp) { + inc->prev_timestamp = inc->skip; + } else if (timestamp == inc->prev_timestamp) { /* Ignore repeated timestamps (e.g. sigrok outputs these) */ } else { - if (inc->compress != 0 && timestamp - prev_timestamp > inc->compress) { + if (inc->compress != 0 && timestamp - inc->prev_timestamp > inc->compress) { /* Compress long idle periods */ - prev_timestamp = timestamp - inc->compress; + inc->prev_timestamp = timestamp - inc->compress; } sr_dbg("New timestamp: %" PRIu64, timestamp); /* Generate samples from prev_timestamp up to timestamp - 1. */ - add_samples(in, timestamp - prev_timestamp); - prev_timestamp = timestamp; + add_samples(in, timestamp - inc->prev_timestamp); + inc->prev_timestamp = timestamp; } } else if (tokens[i][0] == '$' && tokens[i][1] != '\0') { /* @@ -526,7 +530,7 @@ static int process_buffer(struct sr_input *in) inc = in->priv; if (!inc->started) { - std_session_send_df_header(in->sdi, LOG_PREFIX); + std_session_send_df_header(in->sdi); packet.type = SR_DF_META; packet.payload = &meta; @@ -578,7 +582,6 @@ static int receive(struct sr_input *in, GString *buf) static int end(struct sr_input *in) { - struct sr_datafeed_packet packet; struct context *inc; int ret; @@ -592,10 +595,8 @@ static int end(struct sr_input *in) /* Send any samples that haven't been sent yet. */ send_buffer(in); - if (inc->started) { - packet.type = SR_DF_END; - sr_session_send(in->sdi, &packet); - } + if (inc->started) + std_session_send_df_end(in->sdi); return ret; } @@ -612,6 +613,17 @@ static void cleanup(struct sr_input *in) inc->current_levels = NULL; } +static int reset(struct sr_input *in) +{ + struct context *inc = in->priv; + + cleanup(in); + inc->started = FALSE; + g_string_truncate(in->buf, 0); + + return SR_OK; +} + static struct sr_option options[] = { { "numchannels", "Number of channels", "Number of channels", NULL, NULL }, { "skip", "Skip", "Skip until timestamp", NULL, NULL }, @@ -644,4 +656,5 @@ SR_PRIV struct sr_input_module input_vcd = { .receive = receive, .end = end, .cleanup = cleanup, + .reset = reset, };