]> sigrok.org Git - libsigrok.git/blame - src/input/vcd.c
input/vcd: do propagate parse error in file header
[libsigrok.git] / src / input / vcd.c
CommitLineData
99eaa206 1/*
50985c20 2 * This file is part of the libsigrok project.
99eaa206 3 *
0157808d 4 * Copyright (C) 2012 Petteri Aimonen <jpa@sr.mail.kapsi.fi>
7db06394 5 * Copyright (C) 2014 Bert Vermeulen <bert@biot.com>
0ab36d2f 6 * Copyright (C) 2017-2020 Gerhard Sittig <gerhard.sittig@gmx.net>
99eaa206
PA
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
0ab36d2f
GS
22/*
23 * The VCD input module has the following options. See the options[]
24 * declaration near the bottom of the input module's source file.
0157808d 25 *
0ab36d2f
GS
26 * numchannels: Maximum number of sigrok channels to create. VCD signals
27 * are detected in their order of declaration in the VCD file header,
28 * and mapped to sigrok channels.
0157808d 29 *
0ab36d2f
GS
30 * skip: Allows to skip data at the start of the input file. This can
31 * speed up operation on long captures.
32 * Value < 0: Skip until first timestamp that is listed in the file.
33 * (This is the default behaviour.)
34 * Value = 0: Do not skip, instead generate samples beginning from
35 * timestamp 0.
36 * Value > 0: Start at the given timestamp.
0157808d 37 *
0ab36d2f
GS
38 * downsample: Divide the samplerate by the given factor. This can
39 * speed up operation on long captures.
0157808d 40 *
0ab36d2f
GS
41 * compress: Trim idle periods which are longer than this value to span
42 * only this many timescale ticks. This can speed up operation on long
43 * captures (default 0, don't compress).
6b7ace48 44 *
0157808d
PA
45 * Based on Verilog standard IEEE Std 1364-2001 Version C
46 *
47 * Supported features:
48 * - $var with 'wire' and 'reg' types of scalar variables
49 * - $timescale definition for samplerate
50 * - multiple character variable identifiers
0ab36d2f
GS
51 * - same identifer used for multiple signals (identical values)
52 * - vector variables (bit vectors)
53 * - integer variables (analog signals with 0 digits, passed as single
54 * precision float number)
55 * - real variables (analog signals, passed on with single precision,
56 * arbitrary digits value, not user adjustable)
57 * - nested $scope, results in prefixed sigrok channel names
0157808d
PA
58 *
59 * Most important unsupported features:
0ab36d2f
GS
60 * - $dumpvars initial value declaration (is not an issue if generators
61 * provide sample data for the #0 timestamp, otherwise session data
62 * starts from zero values, and catches up when the signal changes its
63 * state to a supported value)
64 *
65 * Implementor's note: This input module specifically does _not_ use
66 * glib routines where they would hurt performance. Lots of memory
67 * allocations increase execution time not by percents but by huge
68 * factors. This motivated this module's custom code for splitting
69 * words on text lines, and pooling previously allocated buffers.
70 *
71 * TODO (in arbitrary order)
72 * - Map VCD scopes to sigrok channel groups?
73 * - Does libsigrok support nested channel groups? Or is this feature
74 * exclusive to Pulseview?
75 * - Check VCD input to VCD output behaviour. Verify that export and
76 * re-import results in identical data (well, VCD's constraints on
77 * timescale values is known to result in differences).
ec302917
GS
78 * - Check the minimum timestamp delta in the input data set, suggest
79 * the downsample=N option to users for reduced resource consumption.
80 * Popular VCD file creation utilities love to specify insanely tiny
81 * timescale values in the pico or even femto seconds range. Which
82 * results in huge sample counts after import, and potentially even
83 * terminates the application due to resource exhaustion. This issue
84 * only will vanish when common libsigrok infrastructure no longer
85 * depends on constant rate streams of samples at discrete points
86 * in time. The current input module implementation has code in place
87 * to gather timestamp statistics, but the most appropriate condition
88 * when to notify users is yet to be found.
0ab36d2f
GS
89 * - Cleanup the implementation.
90 * - Consistent use of the glib API (where appropriate).
91 * - More appropriate variable/function identifiers.
92 * - More robust handling of multi-word input phrases and chunked
93 * input buffers? This implementation assumes that e.g. b[01]+
94 * patterns are complete when they start, and the signal identifier
95 * is available as well. Which may be true assuming that input data
96 * comes in complete text lines.
97 * - See if other input modules have learned lessons that we could
98 * benefit from here as well? Pointless BOM (done), line oriented
99 * processing with EOL variants and with optional last EOL, module
100 * state reset and file re-read (stable channels list), buffered
101 * session feed, synchronized feed for mixed signal sources, digits
102 * or formats support for analog input, single vs double precision,
103 * etc.
104 * - Re-consider logging. Verbosity levels should be acceptable,
105 * but volume is an issue. Drop duplicates, and drop messages from
106 * known good code paths.
0157808d
PA
107 */
108
6ec6c43b 109#include <config.h>
0ab36d2f 110
99eaa206 111#include <glib.h>
c1aae900 112#include <libsigrok/libsigrok.h>
99eaa206 113#include "libsigrok-internal.h"
0ab36d2f
GS
114#include <stdio.h>
115#include <stdlib.h>
116#include <string.h>
99eaa206 117
3544f848 118#define LOG_PREFIX "input/vcd"
99eaa206 119
9a4fd01a 120#define CHUNK_SIZE (4 * 1024 * 1024)
0ab36d2f 121#define SCOPE_SEP '.'
e4c8a4d7
BV
122
123struct context {
0ab36d2f
GS
124 struct vcd_user_opt {
125 size_t maxchannels; /* sigrok channels (output) */
126 uint64_t downsample;
127 uint64_t compress;
128 uint64_t skip_starttime;
129 gboolean skip_specified;
130 } options;
131 gboolean use_skip;
c10ef17c 132 gboolean started;
7db06394 133 gboolean got_header;
f9bc17d4 134 uint64_t prev_timestamp;
e4c8a4d7 135 uint64_t samplerate;
0ab36d2f
GS
136 size_t vcdsignals; /* VCD signals (input) */
137 GSList *ignored_signals;
138 gboolean data_after_timestamp;
139 gboolean ignore_end_keyword;
7db06394 140 gboolean skip_until_end;
ba7dd8bb 141 GSList *channels;
0ab36d2f
GS
142 size_t unit_size;
143 size_t logic_count;
144 size_t analog_count;
145 uint8_t *current_logic;
146 float *current_floats;
147 struct {
148 size_t max_bits;
149 size_t unit_size;
150 uint8_t *value;
151 size_t sig_count;
152 } conv_bits;
153 GString *scope_prefix;
154 struct feed_queue_logic *feed_logic;
155 struct split_state {
156 size_t alloced;
157 char **words;
158 gboolean in_use;
159 } split;
ec302917
GS
160 struct ts_stats {
161 size_t total_ts_seen;
162 uint64_t last_ts_value;
163 uint64_t last_ts_delta;
164 size_t min_count;
165 struct {
166 uint64_t delta;
167 size_t count;
168 } min_items[2];
169 uint32_t early_check_shift;
170 size_t early_last_emitted;
171 } ts_stats;
0ab36d2f
GS
172 struct vcd_prev {
173 GSList *sr_channels;
174 GSList *sr_groups;
175 } prev;
e4c8a4d7
BV
176};
177
ba7dd8bb 178struct vcd_channel {
0ab36d2f
GS
179 char *name;
180 char *identifier;
181 size_t size;
182 enum sr_channeltype type;
183 size_t array_index;
184 size_t byte_idx;
185 uint8_t bit_mask;
186 char *base_name;
187 size_t range_lower, range_upper;
188 int submit_digits;
189 struct feed_queue_analog *feed_analog;
e4c8a4d7
BV
190};
191
0ab36d2f
GS
192static void free_channel(void *data)
193{
194 struct vcd_channel *vcd_ch;
195
196 vcd_ch = data;
197 if (!vcd_ch)
198 return;
199
200 g_free(vcd_ch->name);
201 g_free(vcd_ch->identifier);
202 g_free(vcd_ch->base_name);
203 feed_queue_analog_free(vcd_ch->feed_analog);
204
205 g_free(vcd_ch);
206}
207
ec302917
GS
208/*
209 * Another timestamp delta was observed, update statistics: Update the
210 * sorted list of minimum values, and increment the occurance counter.
211 * Returns the position of the item's statistics slot, or returns a huge
212 * invalid index when the current delta is larger than previously found
213 * values.
214 */
215static size_t ts_stats_update_min(struct ts_stats *stats, uint64_t delta)
216{
217 size_t idx, copy_idx;
218
219 /* Advance over previously recorded values which are smaller. */
220 idx = 0;
221 while (idx < stats->min_count && stats->min_items[idx].delta < delta)
222 idx++;
223 if (idx == ARRAY_SIZE(stats->min_items))
224 return idx;
225
226 /* Found the exact value that previously was registered? */
227 if (stats->min_items[idx].delta == delta) {
228 stats->min_items[idx].count++;
229 return idx;
230 }
231
232 /* Allocate another slot, bubble up larger values as needed. */
233 if (stats->min_count < ARRAY_SIZE(stats->min_items))
234 stats->min_count++;
235 for (copy_idx = stats->min_count - 1; copy_idx > idx; copy_idx--)
236 stats->min_items[copy_idx] = stats->min_items[copy_idx - 1];
237
238 /* Start tracking this value in the found or freed slot. */
239 memset(&stats->min_items[idx], 0, sizeof(stats->min_items[idx]));
240 stats->min_items[idx].delta = delta;
241 stats->min_items[idx].count++;
242
243 return idx;
244}
245
246/*
247 * Intermediate check for extreme oversampling in the input data. Rate
248 * limited emission of warnings to avoid noise, "late" emission of the
249 * first potential message to avoid false positives, yet need to emit
250 * the messages early (*way* before EOF) to raise awareness.
251 *
252 * TODO
253 * Tune the limits, improve perception and usefulness of these checks.
254 * Need to start emitting messages soon enough to be seen by users. Yet
255 * avoid unnecessary messages for valid input's idle/quiet phases. Slow
256 * input transitions are perfectly legal before bursty phases are seen
257 * in the input data. Needs the check become an option, on by default,
258 * but suppressable by users?
259 */
260static void ts_stats_check_early(struct ts_stats *stats)
261{
262 static const struct {
263 uint64_t delta;
264 size_t count;
265 } *cp, check_points[] = {
266 { 100, 1000000, }, /* Still x100 after 1mio transitions. */
267 { 1000, 100000, }, /* Still x1k after 100k transitions. */
268 { 10000, 10000, }, /* Still x10k after 10k transitions. */
269 { 1000000, 2500, }, /* Still x1m after 2.5k transitions. */
270 };
271
272 size_t cp_idx;
273 uint64_t seen_delta, check_delta;
274 size_t seen_count;
275
276 /* Get the current minimum's value and count. */
277 if (!stats->min_count)
278 return;
279 seen_delta = stats->min_items[0].delta;
280 seen_count = stats->min_items[0].count;
281
282 /* Emit at most one weak message per import. */
283 if (stats->early_last_emitted)
284 return;
285
286 /* Check arbitrary marks, emit rate limited warnings. */
287 (void)seen_count;
288 check_delta = seen_delta >> stats->early_check_shift;
289 for (cp_idx = 0; cp_idx < ARRAY_SIZE(check_points); cp_idx++) {
290 cp = &check_points[cp_idx];
291 /* No other match can happen below. Done iterating. */
292 if (stats->total_ts_seen > cp->count)
293 return;
294 /* Advance to the next checkpoint description. */
295 if (stats->total_ts_seen != cp->count)
296 continue;
297 /* First occurance of that timestamp count. Check the value. */
968b1a23 298 sr_dbg("TS early chk: total %zu, min delta %" PRIu64 " / %" PRIu64 ".",
ec302917
GS
299 cp->count, seen_delta, check_delta);
300 if (check_delta < cp->delta)
301 return;
302 sr_warn("Low change rate? (weak estimate, min TS delta %" PRIu64 " after %zu timestamps)",
303 seen_delta, stats->total_ts_seen);
304 sr_warn("Consider using the downsample=N option, or increasing its value.");
305 stats->early_last_emitted = stats->total_ts_seen;
306 return;
307 }
308}
309
310/* Reset the internal state of the timestamp tracker. */
311static int ts_stats_prep(struct context *inc)
312{
313 struct ts_stats *stats;
314 uint64_t down_sample_value;
315 uint32_t down_sample_shift;
316
317 stats = &inc->ts_stats;
318 memset(stats, 0, sizeof(*stats));
319
320 down_sample_value = inc->options.downsample;
321 down_sample_shift = 0;
322 while (down_sample_value >= 2) {
323 down_sample_shift++;
324 down_sample_value /= 2;
325 }
326 stats->early_check_shift = down_sample_shift;
327
328 return SR_OK;
329}
330
331/* Inspect another timestamp that was received. */
332static int ts_stats_check(struct ts_stats *stats, uint64_t curr_ts)
333{
334 uint64_t last_ts, delta;
335
336 last_ts = stats->last_ts_value;
337 stats->last_ts_value = curr_ts;
338 stats->total_ts_seen++;
339 if (stats->total_ts_seen < 2)
340 return SR_OK;
341
342 delta = curr_ts - last_ts;
343 stats->last_ts_delta = delta;
344 (void)ts_stats_update_min(stats, delta);
345
346 ts_stats_check_early(stats);
347
348 return SR_OK;
349}
350
351/* Postprocess internal timestamp tracker state. */
352static int ts_stats_post(struct context *inc, gboolean ignore_terminal)
353{
354 struct ts_stats *stats;
355 size_t min_idx;
356 uint64_t delta, over_sample, over_sample_scaled, suggest_factor;
357 enum sr_loglevel log_level;
358 gboolean is_suspicious, has_downsample;
359
360 stats = &inc->ts_stats;
361
362 /*
363 * Lookup the smallest timestamp delta which was found during
364 * data import. Ignore the last delta if its timestamp was never
365 * followed by data, and this was the only occurance. Absence of
366 * result data is non-fatal here -- this code exclusively serves
367 * to raise users' awareness of potential pitfalls, but does not
368 * change behaviour of data processing.
369 *
370 * TODO Also filter by occurance count? To not emit warnings when
371 * captured signals only change slowly by design. Only warn when
372 * the sample rate and samples count product exceeds a threshold?
373 * See below for the necessity (and potential) to adjust the log
374 * message's severity and content.
375 */
376 min_idx = 0;
377 if (ignore_terminal) do {
378 if (min_idx >= stats->min_count)
379 break;
380 delta = stats->last_ts_delta;
381 if (stats->min_items[min_idx].delta != delta)
382 break;
383 if (stats->min_items[min_idx].count != 1)
384 break;
385 min_idx++;
386 } while (0);
387 if (min_idx >= stats->min_count)
388 return SR_OK;
389
390 /*
391 * TODO Refine the condition whether to notify the user, and
392 * which severity to use after having inspected all input data.
393 * Any detail could get involved which previously was gathered
394 * during data processing: total sample count, channel count
395 * including their data type and bits width, the oversampling
396 * factor (minimum observed "change rate"), or any combination
397 * thereof. The current check is rather simple (unconditional
398 * warning for ratios starting at 100, regardless of sample or
399 * channel count).
400 */
401 over_sample = stats->min_items[min_idx].delta;
402 over_sample_scaled = over_sample / inc->options.downsample;
403 sr_dbg("TS post stats: oversample unscaled %" PRIu64 ", scaled %" PRIu64,
404 over_sample, over_sample_scaled);
405 if (over_sample_scaled < 10) {
406 sr_dbg("TS post stats: Low oversampling ratio, good.");
407 return SR_OK;
408 }
409
410 /*
411 * Avoid constructing the message from several tiny pieces by
412 * design, because this would be hard on translators. Stick with
413 * complete sentences instead, and accept the redundancy in the
414 * user's interest.
415 */
416 log_level = (over_sample_scaled > 20) ? SR_LOG_WARN : SR_LOG_INFO;
417 is_suspicious = over_sample_scaled > 20;
418 if (is_suspicious) {
419 sr_log(log_level, LOG_PREFIX ": "
420 "Suspiciously low overall change rate (total min TS delta %" PRIu64 ").",
421 over_sample_scaled);
422 } else {
423 sr_log(log_level, LOG_PREFIX ": "
424 "Low overall change rate (total min TS delta %" PRIu64 ").",
425 over_sample_scaled);
426 }
427 has_downsample = inc->options.downsample > 1;
428 suggest_factor = inc->options.downsample;
429 while (over_sample_scaled >= 10) {
430 suggest_factor *= 10;
431 over_sample_scaled /= 10;
432 }
433 if (has_downsample) {
434 sr_log(log_level, LOG_PREFIX ": "
435 "Suggest higher downsample value, like %" PRIu64 ".",
436 suggest_factor);
437 } else {
438 sr_log(log_level, LOG_PREFIX ": "
439 "Suggest to downsample, value like %" PRIu64 ".",
440 suggest_factor);
441 }
442
443 return SR_OK;
444}
445
0ab36d2f
GS
446static void check_remove_bom(GString *buf)
447{
448 static const char *bom_text = "\xef\xbb\xbf";
449
450 if (buf->len < strlen(bom_text))
451 return;
452 if (strncmp(buf->str, bom_text, strlen(bom_text)) != 0)
453 return;
454 g_string_erase(buf, 0, strlen(bom_text));
455}
456
e4c8a4d7 457/*
7db06394 458 * Reads a single VCD section from input file and parses it to name/contents.
d9251a2c 459 * e.g. $timescale 1ps $end => "timescale" "1ps"
99eaa206 460 */
0ab36d2f 461static gboolean parse_section(GString *buf, char **name, char **contents)
99eaa206 462{
0ab36d2f
GS
463 static const char *end_text = "$end";
464
99eaa206 465 gboolean status;
0ab36d2f
GS
466 size_t pos, len;
467 const char *grab_start, *grab_end;
468 GString *sname, *scontent;
7db06394 469
0ab36d2f 470 /* Preset falsy return values. Gets updated below. */
7db06394
BV
471 *name = *contents = NULL;
472 status = FALSE;
1f706c21 473
7db06394 474 /* Skip any initial white-space. */
0ab36d2f 475 pos = 0;
7db06394
BV
476 while (pos < buf->len && g_ascii_isspace(buf->str[pos]))
477 pos++;
cd1b0e8f 478
99eaa206 479 /* Section tag should start with $. */
7db06394 480 if (buf->str[pos++] != '$')
99eaa206 481 return FALSE;
cd1b0e8f 482
7db06394 483 /* Read the section tag. */
0ab36d2f 484 grab_start = &buf->str[pos];
7db06394 485 while (pos < buf->len && !g_ascii_isspace(buf->str[pos]))
0ab36d2f
GS
486 pos++;
487 grab_end = &buf->str[pos];
488 sname = g_string_new_len(grab_start, grab_end - grab_start);
7db06394
BV
489
490 /* Skip whitespace before content. */
491 while (pos < buf->len && g_ascii_isspace(buf->str[pos]))
492 pos++;
493
0ab36d2f
GS
494 /* Read the content up to the '$end' marker. */
495 scontent = g_string_sized_new(128);
496 grab_start = &buf->str[pos];
497 grab_end = g_strstr_len(grab_start, buf->len - pos, end_text);
498 if (grab_end) {
499 /* Advance 'pos' to after '$end' and more whitespace. */
500 pos = grab_end - buf->str;
501 pos += strlen(end_text);
7db06394
BV
502 while (pos < buf->len && g_ascii_isspace(buf->str[pos]))
503 pos++;
0ab36d2f
GS
504
505 /* Grab the (trimmed) content text. */
506 while (grab_end > grab_start && g_ascii_isspace(grab_end[-1]))
507 grab_end--;
508 len = grab_end - grab_start;
509 g_string_append_len(scontent, grab_start, len);
510 if (sname->len)
511 status = TRUE;
512
513 /* Consume the input text which just was taken. */
7db06394
BV
514 g_string_erase(buf, 0, pos);
515 }
99eaa206 516
0ab36d2f 517 /* Return section name and content if a section was seen. */
99eaa206 518 *name = g_string_free(sname, !status);
7db06394 519 *contents = g_string_free(scontent, !status);
7db06394 520
99eaa206
PA
521 return status;
522}
523
0ab36d2f
GS
524/*
525 * The glib routine which splits an input text into a list of words also
526 * "provides empty strings" which application code then needs to remove.
527 * And copies of the input text get allocated for all words.
528 *
529 * The repeated memory allocation is acceptable for small workloads like
530 * parsing the header sections. But the heavy lifting for sample data is
531 * done by DIY code to speedup execution. The use of glib routines would
532 * severely hurt throughput. Allocated memory gets re-used while a strict
533 * ping-pong pattern is assumed (each text line of input data enters and
534 * leaves in a strict symmetrical manner, due to the organization of the
535 * receive() routine and parse calls).
536 */
537
538/* Remove empty parts from an array returned by g_strsplit(). */
539static void remove_empty_parts(gchar **parts)
540{
541 gchar **src, **dest;
542
543 src = dest = parts;
544 while (*src) {
545 if (!**src) {
546 g_free(*src);
547 } else {
548 if (dest != src)
549 *dest = *src;
550 dest++;
551 }
552 src++;
553 }
554 *dest = NULL;
555}
556
557static char **split_text_line(struct context *inc, char *text, size_t *count)
558{
559 struct split_state *state;
560 size_t counted, alloced, wanted;
561 char **words, *p, **new_words;
562
563 state = &inc->split;
564
565 if (count)
566 *count = 0;
567
568 if (state->in_use) {
569 sr_dbg("coding error, split() called while \"in use\".");
570 return NULL;
571 }
572
573 /*
574 * Seed allocation when invoked for the first time. Assume
575 * simple logic data, start with a few words per line. Will
576 * automatically adjust with subsequent use.
577 */
578 if (!state->alloced) {
579 alloced = 20;
580 words = g_malloc(sizeof(words[0]) * alloced);
581 if (!words)
582 return NULL;
583 state->alloced = alloced;
584 state->words = words;
585 }
586
587 /* Start with most recently allocated word list space. */
588 alloced = state->alloced;
589 words = state->words;
590 counted = 0;
591
592 /* As long as more input text remains ... */
593 p = text;
594 while (*p) {
595 /* Resize word list if needed. Just double the size. */
596 if (counted + 1 >= alloced) {
597 wanted = 2 * alloced;
598 new_words = g_realloc(words, sizeof(words[0]) * wanted);
599 if (!new_words) {
600 return NULL;
601 }
602 words = new_words;
603 alloced = wanted;
604 state->words = words;
605 state->alloced = alloced;
606 }
607
608 /* Skip leading spaces. */
609 while (g_ascii_isspace(*p))
610 p++;
611 if (!*p)
612 break;
613
614 /* Add found word to word list. */
615 words[counted++] = p;
616
617 /* Find end of the word. Terminate loop upon EOS. */
618 while (*p && !g_ascii_isspace(*p))
619 p++;
620 if (!*p)
621 break;
622
623 /* More text follows. Terminate the word. */
624 *p++ = '\0';
625 }
626
627 /*
628 * NULL terminate the word list. Provide its length so that
629 * calling code need not re-iterate the list to get the count.
630 */
631 words[counted] = NULL;
632 if (count)
633 *count = counted;
634 state->in_use = TRUE;
635
636 return words;
637}
638
639static void free_text_split(struct context *inc, char **words)
640{
641 struct split_state *state;
642
643 state = &inc->split;
644
645 if (words && words != state->words) {
646 sr_dbg("coding error, free() arg differs from split() result.");
647 }
648
649 /* "Double free" finally releases the memory. */
650 if (!state->in_use) {
651 g_free(state->words);
652 state->words = NULL;
653 state->alloced = 0;
654 }
655
656 /* Mark as no longer in use. */
657 state->in_use = FALSE;
658}
659
660static gboolean have_header(GString *buf)
661{
662 static const char *enddef_txt = "$enddefinitions";
663 static const char *end_txt = "$end";
664
665 char *p, *p_stop;
666
667 /* Search for "end of definitions" section keyword. */
668 p = g_strstr_len(buf->str, buf->len, enddef_txt);
669 if (!p)
670 return FALSE;
671 p += strlen(enddef_txt);
672
673 /* Search for end of section (content expected to be empty). */
674 p_stop = &buf->str[buf->len];
675 p_stop -= strlen(end_txt);
676 while (p < p_stop && g_ascii_isspace(*p))
677 p++;
678 if (strncmp(p, end_txt, strlen(end_txt)) != 0)
679 return FALSE;
680 p += strlen(end_txt);
681
682 return TRUE;
683}
684
685static int parse_timescale(struct context *inc, char *contents)
db9679af 686{
0ab36d2f
GS
687 uint64_t p, q;
688
689 /*
690 * The standard allows for values 1, 10 or 100
691 * and units s, ms, us, ns, ps and fs.
692 */
693 if (sr_parse_period(contents, &p, &q) != SR_OK) {
694 sr_err("Parsing $timescale failed.");
695 return SR_ERR_DATA;
696 }
697
698 inc->samplerate = q / p;
699 sr_dbg("Samplerate: %" PRIu64, inc->samplerate);
700 if (q % p != 0) {
701 /* Does not happen unless time value is non-standard */
702 sr_warn("Inexact rounding of samplerate, %" PRIu64 " / %" PRIu64 " to %" PRIu64 " Hz.",
703 q, p, inc->samplerate);
704 }
705
706 return SR_OK;
707}
708
709/*
710 * Handle '$scope' and '$upscope' sections in the input file. Assume that
711 * input signals have a "base name", which may be ambiguous within the
712 * file. These names get declared within potentially nested scopes, which
713 * this implementation uses to create longer but hopefully unique and
714 * thus more usable sigrok channel names.
715 *
716 * Track the currently effective scopes in a string variable to simplify
717 * the channel name creation. Start from an empty string, then append the
718 * scope name and a separator when a new scope opens, and remove the last
719 * scope name when a scope closes. This allows to simply prefix basenames
720 * with the current scope to get a full name.
721 *
722 * It's an implementation detail to keep the trailing NUL here in the
723 * GString member, to simplify the g_strconcat() call in the channel name
724 * creation.
725 *
726 * TODO
727 * - Check whether scope types must get supported, this implementation
728 * does not distinguish between 'module' and 'begin' and what else
729 * may be seen. The first word simply gets ignored.
730 * - Check the allowed alphabet for scope names. This implementation
731 * assumes "programming language identifier" style (alphanumeric with
732 * underscores, plus brackets since we've seen them in example files).
733 */
734static int parse_scope(struct context *inc, char *contents, gboolean is_up)
735{
736 char *sep_pos, *name_pos;
737 char **parts;
738 size_t length;
739
740 /*
741 * The 'upscope' case, drop one scope level (if available). Accept
742 * excess 'upscope' calls, assume that a previous 'scope' section
743 * was ignored because it referenced our software package's name.
744 */
745 if (is_up) {
746 /*
747 * Check for a second right-most separator (and position
748 * right behind that, which is the start of the last
749 * scope component), or fallback to the start of string.
750 * g_string_erase() from that positon to the end to drop
751 * the last component.
752 */
753 name_pos = inc->scope_prefix->str;
754 do {
755 sep_pos = strrchr(name_pos, SCOPE_SEP);
756 if (!sep_pos)
757 break;
758 *sep_pos = '\0';
759 sep_pos = strrchr(name_pos, SCOPE_SEP);
760 if (!sep_pos)
761 break;
762 name_pos = ++sep_pos;
763 } while (0);
764 length = name_pos - inc->scope_prefix->str;
765 g_string_truncate(inc->scope_prefix, length);
766 g_string_append_c(inc->scope_prefix, '\0');
767 sr_dbg("$upscope, prefix now: \"%s\"", inc->scope_prefix->str);
768 return SR_OK;
769 }
770
771 /*
772 * The 'scope' case, add another scope level. But skip our own
773 * package name, assuming that this is an artificial node which
774 * was emitted by libsigrok's VCD output module.
775 */
776 sr_spew("$scope, got: \"%s\"", contents);
777 parts = g_strsplit_set(contents, " \r\n\t", 0);
778 remove_empty_parts(parts);
779 length = g_strv_length(parts);
780 if (length != 2) {
781 sr_err("Unsupported 'scope' syntax: %s", contents);
782 g_strfreev(parts);
783 return SR_ERR_DATA;
784 }
785 name_pos = parts[1];
786 if (strcmp(name_pos, PACKAGE_NAME) == 0) {
787 sr_info("Skipping scope with application's package name: %s",
788 name_pos);
789 *name_pos = '\0';
790 }
791 if (*name_pos) {
792 /* Drop NUL, append scope name and separator, and re-add NUL. */
793 g_string_truncate(inc->scope_prefix, inc->scope_prefix->len - 1);
794 g_string_append_printf(inc->scope_prefix,
795 "%s%c%c", name_pos, SCOPE_SEP, '\0');
796 }
797 g_strfreev(parts);
798 sr_dbg("$scope, prefix now: \"%s\"", inc->scope_prefix->str);
799
800 return SR_OK;
801}
802
803/**
804 * Parse a $var section which describes a VCD signal ("variable").
805 *
806 * @param[in] inc Input module context.
807 * @param[in] contents Input text, content of $var section.
808 */
809static int parse_header_var(struct context *inc, char *contents)
810{
811 char **parts;
812 size_t length;
813 char *type, *size_txt, *id, *ref, *idx;
814 gboolean is_reg, is_wire, is_real, is_int;
c1310f7d 815 gboolean is_str;
0ab36d2f
GS
816 enum sr_channeltype ch_type;
817 size_t size, next_size;
4237ab9e
GS
818 struct vcd_channel *vcd_ch;
819
0ab36d2f
GS
820 /*
821 * Format of $var or $reg header specs:
822 * $var type size identifier reference [opt-index] $end
823 */
824 parts = g_strsplit_set(contents, " \r\n\t", 0);
825 remove_empty_parts(parts);
826 length = g_strv_length(parts);
827 if (length != 4 && length != 5) {
828 sr_warn("$var section should have 4 or 5 items");
829 g_strfreev(parts);
830 return SR_ERR_DATA;
831 }
832
833 type = parts[0];
834 size_txt = parts[1];
835 id = parts[2];
836 ref = parts[3];
837 idx = parts[4];
838 if (idx && !*idx)
839 idx = NULL;
840 is_reg = g_strcmp0(type, "reg") == 0;
841 is_wire = g_strcmp0(type, "wire") == 0;
842 is_real = g_strcmp0(type, "real") == 0;
843 is_int = g_strcmp0(type, "integer") == 0;
c1310f7d 844 is_str = g_strcmp0(type, "string") == 0;
0ab36d2f
GS
845
846 if (is_reg || is_wire) {
847 ch_type = SR_CHANNEL_LOGIC;
848 } else if (is_real || is_int) {
849 ch_type = SR_CHANNEL_ANALOG;
c1310f7d
GS
850 } else if (is_str) {
851 sr_warn("Skipping id %s, name '%s%s', unsupported type '%s'.",
852 id, ref, idx ? idx : "", type);
853 inc->ignored_signals = g_slist_append(inc->ignored_signals,
854 g_strdup(id));
855 g_strfreev(parts);
856 return SR_OK;
0ab36d2f 857 } else {
1a35f711 858 sr_err("Unsupported signal type: '%s'", type);
0ab36d2f
GS
859 g_strfreev(parts);
860 return SR_ERR_DATA;
861 }
862
863 size = strtol(size_txt, NULL, 10);
864 if (ch_type == SR_CHANNEL_ANALOG) {
865 if (is_real && size != 32 && size != 64) {
866 /*
867 * The VCD input module does not depend on the
868 * specific width of the floating point value.
869 * This is just for information. Upon value
870 * changes, a mere string gets converted to
871 * float, so we may not care at all.
872 *
873 * Strictly speaking we might warn for 64bit
874 * (double precision) declarations, because
875 * sigrok internally uses single precision
876 * (32bit) only.
877 */
878 sr_info("Unexpected real width: '%s'", size_txt);
879 }
880 /* Simplify code paths below, by assuming size 1. */
881 size = 1;
882 }
883 if (!size) {
884 sr_warn("Unsupported signal size: '%s'", size_txt);
885 g_strfreev(parts);
886 return SR_ERR_DATA;
887 }
888 if (inc->conv_bits.max_bits < size)
889 inc->conv_bits.max_bits = size;
890 next_size = inc->logic_count + inc->analog_count + size;
891 if (inc->options.maxchannels && next_size > inc->options.maxchannels) {
892 sr_warn("Skipping '%s%s', exceeds requested channel count %zu.",
893 ref, idx ? idx : "", inc->options.maxchannels);
894 inc->ignored_signals = g_slist_append(inc->ignored_signals,
895 g_strdup(id));
896 g_strfreev(parts);
897 return SR_OK;
898 }
899
900 vcd_ch = g_malloc0(sizeof(*vcd_ch));
901 vcd_ch->identifier = g_strdup(id);
902 vcd_ch->name = g_strconcat(inc->scope_prefix->str, ref, idx, NULL);
903 vcd_ch->size = size;
904 vcd_ch->type = ch_type;
905 switch (ch_type) {
906 case SR_CHANNEL_LOGIC:
907 vcd_ch->array_index = inc->logic_count;
908 vcd_ch->byte_idx = vcd_ch->array_index / 8;
909 vcd_ch->bit_mask = 1 << (vcd_ch->array_index % 8);
910 inc->logic_count += size;
911 break;
912 case SR_CHANNEL_ANALOG:
913 vcd_ch->array_index = inc->analog_count++;
914 /* TODO: Use proper 'digits' value for this input module. */
915 vcd_ch->submit_digits = is_real ? 2 : 0;
916 break;
917 }
918 inc->vcdsignals++;
919 sr_spew("VCD signal %zu '%s' ID '%s' (size %zu), sr type %s, idx %zu.",
920 inc->vcdsignals, vcd_ch->name,
921 vcd_ch->identifier, vcd_ch->size,
922 vcd_ch->type == SR_CHANNEL_ANALOG ? "A" : "L",
923 vcd_ch->array_index);
924 inc->channels = g_slist_append(inc->channels, vcd_ch);
925 g_strfreev(parts);
926
927 return SR_OK;
db9679af
ML
928}
929
0ab36d2f
GS
930/**
931 * Construct the name of the nth sigrok channel for a VCD signal.
932 *
933 * Uses the VCD signal name for scalar types and single-bit signals.
934 * Uses "signal.idx" for multi-bit VCD signals without a range spec in
935 * their declaration. Uses "signal[idx]" when a range is known and was
936 * verified.
937 *
938 * @param[in] vcd_ch The VCD signal's description.
939 * @param[in] idx The sigrok channel's index within the VCD signal's group.
940 *
941 * @return An allocated text buffer which callers need to release, #NULL
942 * upon failure to create a sigrok channel name.
943 */
944static char *get_channel_name(struct vcd_channel *vcd_ch, size_t idx)
99eaa206 945{
0ab36d2f
GS
946 char *open_pos, *close_pos, *check_pos, *endptr;
947 gboolean has_brackets, has_range;
948 size_t upper, lower, tmp;
949 char *ch_name;
950
951 /* Handle simple scalar types, and single-bit logic first. */
952 if (vcd_ch->size <= 1)
953 return g_strdup(vcd_ch->name);
954
955 /*
956 * If not done before: Search for a matching pair of brackets in
957 * the right-most position at the very end of the string. Get the
958 * two colon separated numbers between the brackets, which are
959 * the range limits for array indices into the multi-bit signal.
960 * Grab the "base name" of the VCD signal.
961 *
962 * Notice that arrays can get nested. Earlier path components can
963 * be indexed as well, that's why we need the right-most range.
964 * This implementation does not handle bit vectors of size 1 here
965 * by explicit logic. The check for a [0:0] range would even fail.
966 * But the case of size 1 is handled above, and "happens to" give
967 * the expected result (just the VCD signal name).
968 *
969 * This implementation also deals with range limits in the reverse
970 * order, as well as ranges which are not 0-based (like "[4:7]").
971 */
972 if (!vcd_ch->base_name) {
973 has_range = TRUE;
974 open_pos = strrchr(vcd_ch->name, '[');
975 close_pos = strrchr(vcd_ch->name, ']');
976 if (close_pos && close_pos[1])
977 close_pos = NULL;
978 has_brackets = open_pos && close_pos && close_pos > open_pos;
979 if (!has_brackets)
980 has_range = FALSE;
981 if (has_range) {
982 check_pos = &open_pos[1];
983 endptr = NULL;
984 upper = strtoul(check_pos, &endptr, 10);
985 if (!endptr || *endptr != ':')
986 has_range = FALSE;
987 }
988 if (has_range) {
989 check_pos = &endptr[1];
990 endptr = NULL;
991 lower = strtoul(check_pos, &endptr, 10);
992 if (!endptr || endptr != close_pos)
993 has_range = FALSE;
994 }
995 if (has_range && lower > upper) {
996 tmp = lower;
997 lower = upper;
998 upper = tmp;
999 }
1000 if (has_range) {
1001 if (lower >= upper)
1002 has_range = FALSE;
1003 if (upper + 1 - lower != vcd_ch->size)
1004 has_range = FALSE;
1005 }
1006 if (has_range) {
1007 /* Temporarily patch the VCD channel's name. */
1008 *open_pos = '\0';
1009 vcd_ch->base_name = g_strdup(vcd_ch->name);
1010 *open_pos = '[';
1011 vcd_ch->range_lower = lower;
1012 vcd_ch->range_upper = upper;
1013 }
99eaa206 1014 }
0ab36d2f
GS
1015 has_range = vcd_ch->range_lower + vcd_ch->range_upper;
1016 if (has_range && idx >= vcd_ch->size)
1017 has_range = FALSE;
1018 if (!has_range)
1019 return g_strdup_printf("%s.%zu", vcd_ch->name, idx);
cd1b0e8f 1020
0ab36d2f
GS
1021 /*
1022 * Create a sigrok channel name with just the bit's index in
1023 * brackets. This avoids "name[7:0].3" results, instead results
1024 * in "name[3]".
1025 */
1026 ch_name = g_strdup_printf("%s[%zu]",
1027 vcd_ch->base_name, vcd_ch->range_lower + idx);
1028 return ch_name;
1029}
1030
1031/*
1032 * Create (analog or logic) sigrok channels for the VCD signals. Create
1033 * multiple sigrok channels for vector input since sigrok has no concept
1034 * of multi-bit signals. Create a channel group for the vector's bits
1035 * though to reflect that they form a unit. This is beneficial when UIs
1036 * support optional "collapsed" displays of channel groups (like
1037 * "parallel bus, hex output").
1038 *
1039 * Defer channel creation until after completion of parsing the input
1040 * file header. Make sure to create all logic channels first before the
1041 * analog channels get created. This avoids issues with the mapping of
1042 * channel indices to bitmap positions in the sample buffer.
1043 */
1044static void create_channels(const struct sr_input *in,
1045 struct sr_dev_inst *sdi, enum sr_channeltype ch_type)
1046{
1047 struct context *inc;
1048 size_t ch_idx;
1049 GSList *l;
1050 struct vcd_channel *vcd_ch;
1051 size_t size_idx;
1052 char *ch_name;
1053 struct sr_channel_group *cg;
1054 struct sr_channel *ch;
1055
1056 inc = in->priv;
1057
1058 ch_idx = 0;
1059 if (ch_type > SR_CHANNEL_LOGIC)
1060 ch_idx += inc->logic_count;
1061 if (ch_type > SR_CHANNEL_ANALOG)
1062 ch_idx += inc->analog_count;
1063 for (l = inc->channels; l; l = l->next) {
1064 vcd_ch = l->data;
1065 if (vcd_ch->type != ch_type)
1066 continue;
1067 cg = NULL;
d810901a
GS
1068 if (vcd_ch->size != 1)
1069 cg = sr_channel_group_new(sdi, vcd_ch->name, NULL);
0ab36d2f
GS
1070 for (size_idx = 0; size_idx < vcd_ch->size; size_idx++) {
1071 ch_name = get_channel_name(vcd_ch, size_idx);
1072 sr_dbg("sigrok channel idx %zu, name %s, type %s, en %d.",
1073 ch_idx, ch_name,
1074 ch_type == SR_CHANNEL_ANALOG ? "A" : "L", TRUE);
1075 ch = sr_channel_new(sdi, ch_idx, ch_type, TRUE, ch_name);
1076 g_free(ch_name);
1077 ch_idx++;
1078 if (cg)
1079 cg->channels = g_slist_append(cg->channels, ch);
1080 }
0ab36d2f
GS
1081 }
1082}
1083
1084static void create_feeds(const struct sr_input *in)
1085{
1086 struct context *inc;
1087 GSList *l;
1088 struct vcd_channel *vcd_ch;
1089 size_t ch_idx;
1090 struct sr_channel *ch;
1091
1092 inc = in->priv;
1093
1094 /* Create one feed for logic data. */
2cb4204c
GS
1095 if (inc->logic_count) {
1096 inc->unit_size = (inc->logic_count + 7) / 8;
1097 inc->feed_logic = feed_queue_logic_alloc(in->sdi,
1098 CHUNK_SIZE / inc->unit_size, inc->unit_size);
1099 }
0ab36d2f
GS
1100
1101 /* Create one feed per analog channel. */
1102 for (l = inc->channels; l; l = l->next) {
1103 vcd_ch = l->data;
1104 if (vcd_ch->type != SR_CHANNEL_ANALOG)
1105 continue;
1106 ch_idx = vcd_ch->array_index;
1107 ch_idx += inc->logic_count;
1108 ch = g_slist_nth_data(in->sdi->channels, ch_idx);
1109 vcd_ch->feed_analog = feed_queue_analog_alloc(in->sdi,
1110 CHUNK_SIZE / sizeof(float),
1111 vcd_ch->submit_digits, ch);
1112 }
99eaa206
PA
1113}
1114
08f8421a
GS
1115/*
1116 * Keep track of a previously created channel list, in preparation of
1117 * re-reading the input file. Gets called from reset()/cleanup() paths.
1118 */
1119static void keep_header_for_reread(const struct sr_input *in)
1120{
1121 struct context *inc;
1122
1123 inc = in->priv;
0ab36d2f 1124
d810901a 1125 g_slist_free_full(inc->prev.sr_groups, sr_channel_group_free_cb);
0ab36d2f
GS
1126 inc->prev.sr_groups = in->sdi->channel_groups;
1127 in->sdi->channel_groups = NULL;
1128
1129 g_slist_free_full(inc->prev.sr_channels, sr_channel_free_cb);
1130 inc->prev.sr_channels = in->sdi->channels;
08f8421a
GS
1131 in->sdi->channels = NULL;
1132}
1133
1134/*
1135 * Check whether the input file is being re-read, and refuse operation
1136 * when essential parameters of the acquisition have changed in ways
1137 * that are unexpected to calling applications. Gets called after the
1138 * file header got parsed (again).
1139 *
1140 * Changing the channel list across re-imports of the same file is not
1141 * supported, by design and for valid reasons, see bug #1215 for details.
1142 * Users are expected to start new sessions when they change these
1143 * essential parameters in the acquisition's setup. When we accept the
1144 * re-read file, then make sure to keep using the previous channel list,
1145 * applications may still reference them.
1146 */
0ab36d2f 1147static gboolean check_header_in_reread(const struct sr_input *in)
08f8421a
GS
1148{
1149 struct context *inc;
1150
1151 if (!in)
1152 return FALSE;
1153 inc = in->priv;
1154 if (!inc)
1155 return FALSE;
0ab36d2f 1156 if (!inc->prev.sr_channels)
08f8421a
GS
1157 return TRUE;
1158
0ab36d2f 1159 if (sr_channel_lists_differ(inc->prev.sr_channels, in->sdi->channels)) {
08f8421a
GS
1160 sr_err("Channel list change not supported for file re-read.");
1161 return FALSE;
1162 }
0ab36d2f 1163
d810901a 1164 g_slist_free_full(in->sdi->channel_groups, sr_channel_group_free_cb);
0ab36d2f
GS
1165 in->sdi->channel_groups = inc->prev.sr_groups;
1166 inc->prev.sr_groups = NULL;
1167
08f8421a 1168 g_slist_free_full(in->sdi->channels, sr_channel_free_cb);
0ab36d2f
GS
1169 in->sdi->channels = inc->prev.sr_channels;
1170 inc->prev.sr_channels = NULL;
08f8421a
GS
1171
1172 return TRUE;
1173}
1174
0ab36d2f
GS
1175/* Parse VCD file header sections (rate and variables declarations). */
1176static int parse_header(const struct sr_input *in, GString *buf)
99eaa206 1177{
7db06394 1178 struct context *inc;
93a28f0b 1179 gboolean enddef_seen, header_valid;
0ab36d2f
GS
1180 char *name, *contents;
1181 size_t size;
ec302917 1182 int ret;
99eaa206 1183
7db06394 1184 inc = in->priv;
0ab36d2f
GS
1185
1186 /* Parse sections until complete header was seen. */
93a28f0b
GS
1187 enddef_seen = FALSE;
1188 header_valid = TRUE;
0ab36d2f
GS
1189 name = contents = NULL;
1190 inc->conv_bits.max_bits = 1;
7db06394 1191 while (parse_section(buf, &name, &contents)) {
99eaa206 1192 sr_dbg("Section '%s', contents '%s'.", name, contents);
cd1b0e8f 1193
e4c8a4d7 1194 if (g_strcmp0(name, "enddefinitions") == 0) {
93a28f0b 1195 enddef_seen = TRUE;
0ab36d2f
GS
1196 goto done_section;
1197 }
1198 if (g_strcmp0(name, "timescale") == 0) {
1199 if (parse_timescale(inc, contents) != SR_OK)
93a28f0b 1200 header_valid = FALSE;
0ab36d2f
GS
1201 goto done_section;
1202 }
1203 if (g_strcmp0(name, "scope") == 0) {
1204 if (parse_scope(inc, contents, FALSE) != SR_OK)
93a28f0b 1205 header_valid = FALSE;
0ab36d2f
GS
1206 goto done_section;
1207 }
1208 if (g_strcmp0(name, "upscope") == 0) {
1209 if (parse_scope(inc, NULL, TRUE) != SR_OK)
93a28f0b 1210 header_valid = FALSE;
0ab36d2f
GS
1211 goto done_section;
1212 }
1213 if (g_strcmp0(name, "var") == 0) {
1214 if (parse_header_var(inc, contents) != SR_OK)
93a28f0b 1215 header_valid = FALSE;
0ab36d2f 1216 goto done_section;
99eaa206 1217 }
cd1b0e8f 1218
0ab36d2f 1219done_section:
db0e5c99
PA
1220 g_free(name);
1221 name = NULL;
1222 g_free(contents);
1223 contents = NULL;
0ab36d2f 1224
93a28f0b 1225 if (enddef_seen)
0ab36d2f 1226 break;
99eaa206 1227 }
99eaa206
PA
1228 g_free(name);
1229 g_free(contents);
cd1b0e8f 1230
93a28f0b
GS
1231 inc->got_header = enddef_seen && header_valid;
1232 if (!inc->got_header)
0ab36d2f 1233 return SR_ERR_DATA;
cd1b0e8f 1234
0ab36d2f
GS
1235 /* Create sigrok channels here, late, logic before analog. */
1236 create_channels(in, in->sdi, SR_CHANNEL_LOGIC);
1237 create_channels(in, in->sdi, SR_CHANNEL_ANALOG);
1238 if (!check_header_in_reread(in))
1239 return SR_ERR_DATA;
1240 create_feeds(in);
99eaa206 1241
e4c8a4d7 1242 /*
0ab36d2f
GS
1243 * Allocate space for text to number conversion, and buffers to
1244 * hold current sample values before submission to the session
1245 * feed. Allocate one buffer for all logic bits, and another for
1246 * all floating point values of all analog channels.
1247 *
1248 * The buffers get updated when the VCD input stream communicates
1249 * value changes. Upon reception of VCD timestamps, the buffer can
1250 * provide the previously received values, to "fill in the gaps"
1251 * in the generation of a continuous stream of samples for the
1252 * sigrok session.
99eaa206 1253 */
0ab36d2f
GS
1254 size = (inc->conv_bits.max_bits + 7) / 8;
1255 inc->conv_bits.unit_size = size;
1256 inc->conv_bits.value = g_malloc0(size);
1257 if (!inc->conv_bits.value)
1258 return SR_ERR_MALLOC;
1259
1260 size = (inc->logic_count + 7) / 8;
1261 inc->unit_size = size;
1262 inc->current_logic = g_malloc0(size);
1263 if (inc->unit_size && !inc->current_logic)
1264 return SR_ERR_MALLOC;
1265 size = sizeof(inc->current_floats[0]) * inc->analog_count;
1266 inc->current_floats = g_malloc0(size);
1267 if (size && !inc->current_floats)
1268 return SR_ERR_MALLOC;
1269 for (size = 0; size < inc->analog_count; size++)
1270 inc->current_floats[size] = 0.;
54ee427d 1271
ec302917
GS
1272 ret = ts_stats_prep(inc);
1273 if (ret != SR_OK)
1274 return ret;
1275
54ee427d 1276 return SR_OK;
99eaa206
PA
1277}
1278
0ab36d2f
GS
1279/*
1280 * Add N copies of previously received values to the session, before
1281 * subsequent value changes will update the data buffer. Locally buffer
1282 * sample data to minimize the number of send() calls.
1283 */
1284static void add_samples(const struct sr_input *in, size_t count, gboolean flush)
61a429c9 1285{
db0e5c99 1286 struct context *inc;
0ab36d2f
GS
1287 GSList *ch_list;
1288 struct vcd_channel *vcd_ch;
1289 struct feed_queue_analog *q;
1290 float value;
cd1b0e8f 1291
db0e5c99 1292 inc = in->priv;
61a429c9 1293
0ab36d2f
GS
1294 if (inc->logic_count) {
1295 feed_queue_logic_submit(inc->feed_logic,
1296 inc->current_logic, count);
1297 if (flush)
1298 feed_queue_logic_flush(inc->feed_logic);
1299 }
1300 for (ch_list = inc->channels; ch_list; ch_list = ch_list->next) {
1301 vcd_ch = ch_list->data;
1302 if (vcd_ch->type != SR_CHANNEL_ANALOG)
1303 continue;
1304 q = vcd_ch->feed_analog;
1305 if (!q)
1306 continue;
1307 value = inc->current_floats[vcd_ch->array_index];
1308 feed_queue_analog_submit(q, value, count);
1309 if (flush)
1310 feed_queue_analog_flush(q);
1311 }
1312}
cd1b0e8f 1313
0ab36d2f
GS
1314static gint vcd_compare_id(gconstpointer a, gconstpointer b)
1315{
1316 return strcmp((const char *)a, (const char *)b);
db0e5c99
PA
1317}
1318
0ab36d2f 1319static gboolean is_ignored(struct context *inc, const char *id)
db0e5c99 1320{
0ab36d2f 1321 GSList *ignored;
db0e5c99 1322
0ab36d2f
GS
1323 ignored = g_slist_find_custom(inc->ignored_signals, id, vcd_compare_id);
1324 return ignored != NULL;
1325}
cd1b0e8f 1326
0ab36d2f
GS
1327/*
1328 * Get an analog channel's value from a bit pattern (VCD 'integer' type).
1329 * The implementation assumes a maximum integer width (64bit), the API
1330 * doesn't (beyond the return data type). The use of SR_CHANNEL_ANALOG
1331 * channels may further constraint the number of significant digits
1332 * (current asumption: float -> 23bit).
1333 */
1334static float get_int_val(uint8_t *in_bits_data, size_t in_bits_count)
1335{
1336 uint64_t int_value;
1337 size_t byte_count, byte_idx;
1338 float flt_value; /* typeof(inc->current_floats[0]) */
1339
1340 /* Convert bit pattern to integer number (limited range). */
1341 int_value = 0;
1342 byte_count = (in_bits_count + 7) / 8;
1343 for (byte_idx = 0; byte_idx < byte_count; byte_idx++) {
1344 if (byte_idx >= sizeof(int_value))
1345 break;
1346 int_value |= *in_bits_data++ << (byte_idx * 8);
1347 }
1348 flt_value = int_value;
db0e5c99 1349
0ab36d2f
GS
1350 return flt_value;
1351}
cd1b0e8f 1352
0ab36d2f
GS
1353/*
1354 * Set a logic channel's level depending on the VCD signal's identifier
1355 * and parsed value. Multi-bit VCD values will affect several sigrok
1356 * channels. One VCD signal name can translate to several sigrok channels.
1357 */
1358static void process_bits(struct context *inc, char *identifier,
1359 uint8_t *in_bits_data, size_t in_bits_count)
1360{
1361 size_t size;
1362 gboolean have_int;
1363 GSList *l;
1364 struct vcd_channel *vcd_ch;
1365 float int_val;
1366 size_t bit_idx;
1367 uint8_t *in_bit_ptr, in_bit_mask;
1368 uint8_t *out_bit_ptr, out_bit_mask;
1369 uint8_t bit_val;
1370
1371 size = 0;
1372 have_int = FALSE;
1373 int_val = 0;
1374 for (l = inc->channels; l; l = l->next) {
1375 vcd_ch = l->data;
1376 if (g_strcmp0(identifier, vcd_ch->identifier) != 0)
1377 continue;
1378 if (vcd_ch->type == SR_CHANNEL_ANALOG) {
1379 /* Special case for 'integer' VCD signal types. */
1380 size = vcd_ch->size; /* Flag for "VCD signal found". */
1381 if (!have_int) {
1382 int_val = get_int_val(in_bits_data, in_bits_count);
1383 have_int = TRUE;
1384 }
1385 inc->current_floats[vcd_ch->array_index] = int_val;
1386 continue;
1387 }
1388 if (vcd_ch->type != SR_CHANNEL_LOGIC)
1389 continue;
1390 sr_spew("Processing %s data, id '%s', ch %zu sz %zu",
1391 (size == 1) ? "bit" : "vector",
1392 identifier, vcd_ch->array_index, vcd_ch->size);
1393
1394 /* Found our (logic) channel. Setup in/out bit positions. */
1395 size = vcd_ch->size;
1396 in_bit_ptr = in_bits_data;
1397 in_bit_mask = 1 << 0;
1398 out_bit_ptr = &inc->current_logic[vcd_ch->byte_idx];
1399 out_bit_mask = vcd_ch->bit_mask;
1400
1401 /*
1402 * Pass VCD input bit(s) to sigrok logic bits. Conversion
1403 * must be done repeatedly because one VCD signal name
1404 * can translate to several sigrok channels, and shifting
1405 * a previously computed bit field to another channel's
1406 * position in the buffer would be nearly as expensive,
1407 * and certain would increase complexity of the code.
1408 */
1409 for (bit_idx = 0; bit_idx < size; bit_idx++) {
1410 /* Get the bit value from input data. */
1411 bit_val = 0;
1412 if (bit_idx < in_bits_count) {
1413 bit_val = *in_bit_ptr & in_bit_mask;
1414 in_bit_mask <<= 1;
1415 if (!in_bit_mask) {
1416 in_bit_mask = 1 << 0;
1417 in_bit_ptr++;
1418 }
1419 }
1420 /* Manipulate the sample buffer data image. */
1421 if (bit_val)
1422 *out_bit_ptr |= out_bit_mask;
1423 else
1424 *out_bit_ptr &= ~out_bit_mask;
1425 /* Update output position after bitmap update. */
1426 out_bit_mask <<= 1;
1427 if (!out_bit_mask) {
1428 out_bit_mask = 1 << 0;
1429 out_bit_ptr++;
1430 }
db0e5c99 1431 }
61a429c9 1432 }
0ab36d2f
GS
1433 if (!size && !is_ignored(inc, identifier))
1434 sr_warn("VCD signal not found for ID '%s'.", identifier);
61a429c9
PA
1435}
1436
0ab36d2f
GS
1437/*
1438 * Set an analog channel's value from a floating point number. One
1439 * VCD signal name can translate to several sigrok channels.
1440 */
1441static void process_real(struct context *inc, char *identifier, float real_val)
36dacf17 1442{
0ab36d2f 1443 gboolean found;
36dacf17
WS
1444 GSList *l;
1445 struct vcd_channel *vcd_ch;
36dacf17 1446
0ab36d2f
GS
1447 found = FALSE;
1448 for (l = inc->channels; l; l = l->next) {
36dacf17 1449 vcd_ch = l->data;
0ab36d2f
GS
1450 if (vcd_ch->type != SR_CHANNEL_ANALOG)
1451 continue;
1452 if (g_strcmp0(identifier, vcd_ch->identifier) != 0)
1453 continue;
1454
1455 /* Found our (analog) channel. */
1456 found = TRUE;
1457 sr_spew("Processing real data, id '%s', ch %zu, val %.16g",
1458 identifier, vcd_ch->array_index, real_val);
1459 inc->current_floats[vcd_ch->array_index] = real_val;
36dacf17 1460 }
0ab36d2f
GS
1461 if (!found && !is_ignored(inc, identifier))
1462 sr_warn("VCD signal not found for ID '%s'.", identifier);
1463}
1464
1465/*
1466 * Converts a bit position's text character to a number value.
1467 *
1468 * TODO Check for complete coverage of Verilog's standard logic values
1469 * (IEEE-1364). The set is said to be “01XZHUWL-”, which only a part of
1470 * is handled here. What would be the complete mapping?
1471 * - 0/L -> bit value 0
1472 * - 1/H -> bit value 1
1473 * - X "don't care" -> TODO
1474 * - Z "high impedance" -> TODO
1475 * - W "weak(?)" -> TODO
1476 * - U "undefined" -> TODO
1477 * - '-' "TODO" -> TODO
1478 *
1479 * For simplicity, this input module implementation maps "known low"
1480 * values to 0, and "known high" values to 1. All other values will
1481 * end up assuming "low" (return number 0), while callers might warn.
1482 * It's up to users to provide compatible input data, or accept the
1483 * warnings. Silently accepting unknown input data is not desirable.
1484 */
1485static uint8_t vcd_char_to_value(char bit_char, int *warn)
1486{
1487
1488 bit_char = g_ascii_tolower(bit_char);
1489
1490 /* Convert the "undisputed" variants. */
1491 if (bit_char == '0' || bit_char == 'l')
1492 return 0;
1493 if (bit_char == '1' || bit_char == 'h')
1494 return 1;
1495
1496 /* Convert the "uncertain" variants. */
1497 if (warn)
1498 *warn = 1;
1499 if (bit_char == 'x' || bit_char == 'z')
1500 return 0;
1501 if (bit_char == 'u')
1502 return 0;
35810515
GS
1503 if (bit_char == '-')
1504 return 0;
0ab36d2f
GS
1505
1506 /* Unhandled input text. */
1507 return ~0;
36dacf17
WS
1508}
1509
c1310f7d
GS
1510/*
1511 * Check the validity of a VCD string value. It's essential to reliably
1512 * accept valid data which the community uses in the field, yet robustly
1513 * reject invalid data for users' awareness. Since IEEE 1800-2017 would
1514 * not discuss the representation of this data type, it's assumed to not
1515 * be an official feature of the VCD file format. This implementation is
1516 * an educated guess after inspection of other arbitrary implementations,
1517 * not backed by any specification or public documentation.
1518 *
1519 * A quick summary of the implemented assumptions: Must be a sequence of
1520 * ASCII printables. Must not contain whitespace. Might contain escape
1521 * sequences: A backslash followed by a single character, like '\n' or
1522 * '\\'. Or a backslash and the letter x followed by two hex digits,
1523 * like '\x20'. Or a backslash followed by three octal digits, like
1524 * '\007'. As an exception also accepts a single digit '\0' but only at
1525 * the text end. The string value may be empty, but must not be NULL.
1526 *
1527 * This implementation assumes an ASCII based platform for simplicity
1528 * and readability. Should be a given on sigrok supported platforms.
1529 */
1530static gboolean vcd_string_valid(const char *s)
1531{
1532 char c;
1533
1534 if (!s)
1535 return FALSE;
1536
1537 while (*s) {
1538 c = *s++;
1539 /* Reject non-printable ASCII chars including DEL. */
1540 if (c < ' ')
1541 return FALSE;
1542 if (c > '~')
1543 return FALSE;
1544 /* Deeper inspection of escape sequences. */
1545 if (c == '\\') {
1546 c = *s++;
1547 switch (c) {
1548 case 'a': /* BEL, bell aka "alarm" */
1549 case 'b': /* BS, back space */
1550 case 't': /* TAB, tabulator */
1551 case 'n': /* NL, newline */
1552 case 'v': /* VT, vertical tabulator */
1553 case 'f': /* FF, form feed */
1554 case 'r': /* CR, carriage return */
1555 case '"': /* double quotes */
1556 case '\'': /* tick, single quote */
1557 case '?': /* question mark */
1558 case '\\': /* backslash */
1559 continue;
1560 case 'x': /* \xNN two hex digits */
1561 c = *s++;
1562 if (!g_ascii_isxdigit(c))
1563 return FALSE;
1564 c = *s++;
1565 if (!g_ascii_isxdigit(c))
1566 return FALSE;
1567 continue;
1568 case '0': /* \NNN three octal digits */
1569 case '1':
1570 case '2':
1571 case '3':
1572 case '4':
1573 case '5':
1574 case '6':
1575 case '7':
1576 /* Special case '\0' at end of text. */
1577 if (c == '0' && !*s)
1578 return TRUE;
1579 /*
1580 * First digit was covered by the outer
1581 * switch(). Two more digits to check.
1582 */
1583 c = *s++;
1584 if (!g_ascii_isdigit(c) || c > '7')
1585 return FALSE;
1586 c = *s++;
1587 if (!g_ascii_isdigit(c) || c > '7')
1588 return FALSE;
1589 continue;
1590 default:
1591 return FALSE;
1592 }
1593 }
1594 }
1595
1596 return TRUE;
1597}
1598
0ab36d2f
GS
1599/* Parse one text line of the data section. */
1600static int parse_textline(const struct sr_input *in, char *lines)
61a429c9 1601{
7db06394 1602 struct context *inc;
0ab36d2f
GS
1603 int ret;
1604 char **words;
1605 size_t word_count, word_idx;
1606 char *curr_word, *next_word, curr_first;
c1310f7d
GS
1607 gboolean is_timestamp, is_section;
1608 gboolean is_real, is_multibit, is_singlebit, is_string;
f9bc17d4 1609 uint64_t timestamp;
dd8bec71 1610 char *identifier, *endptr;
0ab36d2f 1611 size_t count;
cd1b0e8f 1612
7db06394 1613 inc = in->priv;
cd1b0e8f 1614
0ab36d2f
GS
1615 /*
1616 * Split the caller's text lines into a list of space separated
1617 * words. Note that some of the branches consume the very next
1618 * words as well, and assume that both adjacent words will be
1619 * available when the first word is seen. This constraint applies
1620 * to bit vector data, multi-bit integers and real (float) data,
1621 * as well as single-bit data with whitespace before its
1622 * identifier (if that's valid in VCD, we'd accept it here).
1623 * The fact that callers always pass complete text lines should
1624 * make this assumption acceptable.
1625 */
1626 ret = SR_OK;
1627 words = split_text_line(inc, lines, &word_count);
1628 for (word_idx = 0; word_idx < word_count; word_idx++) {
1629 /*
1630 * Make the next two words available, to simpilify code
1631 * paths below. The second word is optional here.
1632 */
1633 curr_word = words[word_idx];
1634 if (!curr_word && !curr_word[0])
1635 continue;
1636 curr_first = g_ascii_tolower(curr_word[0]);
1637 next_word = words[word_idx + 1];
1638 if (next_word && !next_word[0])
1639 next_word = NULL;
1640
1641 /*
1642 * Optionally skip some sections that can be interleaved
1643 * with data (and may or may not be supported by this
1644 * input module). If the section is not skipped but the
1645 * $end keyword needs to get tracked, specifically handle
1646 * this case, for improved robustness (still reject files
1647 * which happen to use invalid syntax).
1648 */
7db06394 1649 if (inc->skip_until_end) {
0ab36d2f 1650 if (strcmp(curr_word, "$end") == 0) {
7db06394 1651 /* Done with unhandled/unknown section. */
0ab36d2f 1652 sr_dbg("done skipping until $end");
7db06394 1653 inc->skip_until_end = FALSE;
0ab36d2f
GS
1654 } else {
1655 sr_spew("skipping word: %s", curr_word);
1656 }
1657 continue;
1658 }
1659 if (inc->ignore_end_keyword) {
1660 if (strcmp(curr_word, "$end") == 0) {
1661 sr_dbg("done ignoring $end keyword");
1662 inc->ignore_end_keyword = FALSE;
1663 continue;
7db06394
BV
1664 }
1665 }
cd1b0e8f 1666
0ab36d2f
GS
1667 /*
1668 * There may be $keyword sections inside the data part of
1669 * the input file. Do inspect some of the sections' content
1670 * but ignore their surrounding keywords. Silently skip
1671 * unsupported section types (which transparently covers
1672 * $comment sections).
1673 */
1674 is_section = curr_first == '$' && curr_word[1];
1675 if (is_section) {
1676 gboolean inspect_data;
1677
1678 inspect_data = FALSE;
1679 inspect_data |= g_strcmp0(curr_word, "$dumpvars") == 0;
1680 inspect_data |= g_strcmp0(curr_word, "$dumpon") == 0;
1681 inspect_data |= g_strcmp0(curr_word, "$dumpoff") == 0;
1682 if (inspect_data) {
1683 /* Ignore keywords, yet parse contents. */
1684 sr_dbg("%s section, will parse content", curr_word);
1685 inc->ignore_end_keyword = TRUE;
1686 } else {
1687 /* Ignore section from here up to $end. */
1688 sr_dbg("%s section, will skip until $end", curr_word);
1689 inc->skip_until_end = TRUE;
1690 }
1691 continue;
1692 }
1693
1694 /*
1695 * Numbers prefixed by '#' are timestamps, which translate
1696 * to sigrok sample numbers. Apply optional downsampling,
1697 * and apply the 'skip' logic. Check the recent timestamp
1698 * for plausibility. Submit the corresponding number of
1699 * samples of previously accumulated data values to the
1700 * session feed.
1701 */
1702 is_timestamp = curr_first == '#' && g_ascii_isdigit(curr_word[1]);
1703 if (is_timestamp) {
dd8bec71
GS
1704 endptr = NULL;
1705 timestamp = strtoull(&curr_word[1], &endptr, 10);
1706 if (!endptr || *endptr) {
1707 sr_err("Invalid timestamp: %s.", curr_word);
1708 ret = SR_ERR_DATA;
1709 break;
1710 }
0ab36d2f 1711 sr_spew("Got timestamp: %" PRIu64, timestamp);
ec302917
GS
1712 ret = ts_stats_check(&inc->ts_stats, timestamp);
1713 if (ret != SR_OK)
1714 break;
0ab36d2f
GS
1715 if (inc->options.downsample > 1) {
1716 timestamp /= inc->options.downsample;
1717 sr_spew("Downsampled timestamp: %" PRIu64, timestamp);
1718 }
cd1b0e8f 1719
e4c8a4d7
BV
1720 /*
1721 * Skip < 0 => skip until first timestamp.
0157808d
PA
1722 * Skip = 0 => don't skip
1723 * Skip > 0 => skip until timestamp >= skip.
1724 */
0ab36d2f 1725 if (inc->options.skip_specified && !inc->use_skip) {
dd8bec71
GS
1726 sr_dbg("Seeding skip from user spec %" PRIu64,
1727 inc->options.skip_starttime);
1728 inc->prev_timestamp = inc->options.skip_starttime;
0ab36d2f
GS
1729 inc->use_skip = TRUE;
1730 }
1731 if (!inc->use_skip) {
dd8bec71 1732 sr_dbg("Seeding skip from first timestamp");
0ab36d2f 1733 inc->options.skip_starttime = timestamp;
f9bc17d4 1734 inc->prev_timestamp = timestamp;
0ab36d2f
GS
1735 inc->use_skip = TRUE;
1736 continue;
1737 }
1738 if (inc->options.skip_starttime && timestamp < inc->options.skip_starttime) {
1739 sr_spew("Timestamp skipped, before user spec");
1740 inc->prev_timestamp = inc->options.skip_starttime;
1741 continue;
1742 }
1743 if (timestamp == inc->prev_timestamp) {
1744 /*
1745 * Ignore repeated timestamps (e.g. sigrok
1746 * outputs these). Can also happen when
1747 * downsampling makes distinct input values
1748 * end up at the same scaled down value.
1749 * Also transparently covers the initial
1750 * timestamp.
1751 */
1752 sr_spew("Timestamp is identical to previous timestamp");
1753 continue;
1754 }
1755 if (timestamp < inc->prev_timestamp) {
1756 sr_err("Invalid timestamp: %" PRIu64 " (leap backwards).", timestamp);
1757 ret = SR_ERR_DATA;
ed367d68 1758 break;
0ab36d2f
GS
1759 }
1760 if (inc->options.compress) {
1761 /* Compress long idle periods */
1762 count = timestamp - inc->prev_timestamp;
1763 if (count > inc->options.compress) {
1764 sr_dbg("Long idle period, compressing");
1765 count = timestamp - inc->options.compress;
1766 inc->prev_timestamp = count;
6b7ace48 1767 }
61a429c9 1768 }
0ab36d2f
GS
1769
1770 /* Generate samples from prev_timestamp up to timestamp - 1. */
0ab36d2f 1771 count = timestamp - inc->prev_timestamp;
dd8bec71 1772 sr_spew("Got a new timestamp, feeding %zu samples", count);
0ab36d2f
GS
1773 add_samples(in, count, FALSE);
1774 inc->prev_timestamp = timestamp;
1775 inc->data_after_timestamp = FALSE;
1776 continue;
1777 }
1778 inc->data_after_timestamp = TRUE;
1779
1780 /*
1781 * Data values come in different formats, are associated
1782 * with channel identifiers, and correspond to the period
1783 * of time from the most recent timestamp to the next
1784 * timestamp.
1785 *
1786 * Supported input data formats are:
c1310f7d 1787 * - S<value> <sep> <id> (value not used, VCD type 'string').
0ab36d2f
GS
1788 * - R<value> <sep> <id> (analog channel, VCD type 'real').
1789 * - B<value> <sep> <id> (analog channel, VCD type 'integer').
1790 * - B<value> <sep> <id> (logic channels, VCD bit vectors).
1791 * - <value> <id> (logic channel, VCD single-bit values).
1792 *
1793 * Input values can be:
1794 * - Floating point numbers.
1795 * - Bit strings (which covers multi-bit aka integers
1796 * as well as vectors).
1797 * - Single bits.
1798 *
1799 * Things to note:
1800 * - Individual bits can be 0/1 which is supported by
1801 * libsigrok, or x or z which is treated like 0 here
1802 * (sigrok lacks support for ternary logic, neither is
1803 * there support for the full IEEE set of values).
1804 * - Single-bit values typically won't be separated from
1805 * the signal identifer, multi-bit values and floats
1806 * are separated (will reference the next word). This
1807 * implementation silently accepts separators for
1808 * single-bit values, too.
1809 */
1810 is_real = curr_first == 'r' && curr_word[1];
1811 is_multibit = curr_first == 'b' && curr_word[1];
1812 is_singlebit = curr_first == '0' || curr_first == '1';
35810515 1813 is_singlebit |= curr_first == 'l' || curr_first == 'h';
0ab36d2f 1814 is_singlebit |= curr_first == 'x' || curr_first == 'z';
35810515 1815 is_singlebit |= curr_first == 'u' || curr_first == '-';
c1310f7d 1816 is_string = curr_first == 's';
0ab36d2f
GS
1817 if (is_real) {
1818 char *real_text;
1819 float real_val;
1820
1821 real_text = &curr_word[1];
1822 identifier = next_word;
1823 word_idx++;
1824 if (!*real_text || !identifier || !*identifier) {
1825 sr_err("Unexpected real format.");
1826 ret = SR_ERR_DATA;
7db06394 1827 break;
8be87469 1828 }
0ab36d2f
GS
1829 sr_spew("Got real data %s for id '%s'.",
1830 real_text, identifier);
1831 if (sr_atof_ascii(real_text, &real_val) != SR_OK) {
1832 sr_err("Cannot convert value: %s.", real_text);
1833 ret = SR_ERR_DATA;
76bc28c3 1834 break;
0ab36d2f
GS
1835 }
1836 process_real(inc, identifier, real_val);
1837 continue;
1838 }
1839 if (is_multibit) {
1840 char *bits_text_start;
1841 size_t bit_count;
1842 char *bits_text, bit_char;
1843 uint8_t bit_value;
1844 uint8_t *value_ptr, value_mask;
1845 GString *bits_val_text;
1846
1847 /* TODO
1848 * Fold in single-bit code path here? To re-use
1849 * the X/Z support. Current redundancy is few so
1850 * there is little pressure to unify code paths.
1851 * Also multi-bit handling is often different
1852 * from single-bit handling, so the "unified"
1853 * path would often check for special cases. So
1854 * we may never unify code paths at all here.
34724ffa 1855 */
0ab36d2f
GS
1856 bits_text = &curr_word[1];
1857 identifier = next_word;
1858 word_idx++;
1859
1860 if (!*bits_text || !identifier || !*identifier) {
1861 sr_err("Unexpected integer/vector format.");
1862 ret = SR_ERR_DATA;
34724ffa
WS
1863 break;
1864 }
0ab36d2f
GS
1865 sr_spew("Got integer/vector data %s for id '%s'.",
1866 bits_text, identifier);
7db06394
BV
1867
1868 /*
0ab36d2f
GS
1869 * Accept a bit string of arbitrary length (sort
1870 * of, within the limits of the previously setup
1871 * conversion buffer). The input text omits the
1872 * leading zeroes, hence we convert from end to
1873 * the start, to get the significant bits. There
1874 * should only be errors for invalid input, or
1875 * for input that is rather strange (data holds
1876 * more bits than the signal's declaration in
1877 * the header suggested). Silently accept data
1878 * that fits in the conversion buffer, and has
1879 * more significant bits than the signal's type
1880 * (that'd be non-sence yet acceptable input).
7db06394 1881 */
0ab36d2f
GS
1882 bits_text_start = bits_text;
1883 bits_text += strlen(bits_text);
1884 bit_count = bits_text - bits_text_start;
1885 if (bit_count > inc->conv_bits.max_bits) {
1886 sr_err("Value exceeds conversion buffer: %s",
1887 bits_text_start);
1888 ret = SR_ERR_DATA;
1889 break;
1890 }
1891 memset(inc->conv_bits.value, 0, inc->conv_bits.unit_size);
1892 value_ptr = &inc->conv_bits.value[0];
1893 value_mask = 1 << 0;
1894 inc->conv_bits.sig_count = 0;
1895 while (bits_text > bits_text_start) {
1896 inc->conv_bits.sig_count++;
1897 bit_char = *(--bits_text);
1898 bit_value = vcd_char_to_value(bit_char, NULL);
1899 if (bit_value == 0) {
1900 /* EMPTY */
1901 } else if (bit_value == 1) {
1902 *value_ptr |= value_mask;
1903 } else {
1904 inc->conv_bits.sig_count = 0;
73f052d3
WS
1905 break;
1906 }
0ab36d2f
GS
1907 value_mask <<= 1;
1908 if (!value_mask) {
1909 value_ptr++;
1910 value_mask = 1 << 0;
1911 }
61a429c9 1912 }
0ab36d2f
GS
1913 if (!inc->conv_bits.sig_count) {
1914 sr_err("Unexpected vector format: %s",
1915 bits_text_start);
1916 ret = SR_ERR_DATA;
1917 break;
1918 }
1919 if (sr_log_loglevel_get() >= SR_LOG_SPEW) {
1920 bits_val_text = sr_hexdump_new(inc->conv_bits.value,
1921 value_ptr - inc->conv_bits.value + 1);
1922 sr_spew("Vector value: %s.", bits_val_text->str);
1923 sr_hexdump_free(bits_val_text);
1924 }
1925
1926 process_bits(inc, identifier,
1927 inc->conv_bits.value, inc->conv_bits.sig_count);
1928 continue;
8be87469 1929 }
0ab36d2f
GS
1930 if (is_singlebit) {
1931 char *bits_text, bit_char;
1932 uint8_t bit_value;
1933
1934 /* Get the value text, and signal identifier. */
1935 bits_text = &curr_word[0];
1936 bit_char = *bits_text;
1937 if (!bit_char) {
1938 sr_err("Bit value missing.");
1939 ret = SR_ERR_DATA;
1940 break;
1941 }
1942 identifier = ++bits_text;
1943 if (!*identifier) {
1944 identifier = next_word;
1945 word_idx++;
1946 }
1947 if (!identifier || !*identifier) {
1948 sr_err("Identifier missing.");
1949 ret = SR_ERR_DATA;
1950 break;
1951 }
1952
1953 /* Convert value text to single-bit number. */
1954 bit_value = vcd_char_to_value(bit_char, NULL);
1955 if (bit_value != 0 && bit_value != 1) {
1956 sr_err("Unsupported bit value '%c'.", bit_char);
1957 ret = SR_ERR_DATA;
1958 break;
1959 }
1960 inc->conv_bits.value[0] = bit_value;
1961 process_bits(inc, identifier, inc->conv_bits.value, 1);
1962 continue;
1963 }
c1310f7d
GS
1964 if (is_string) {
1965 const char *str_value;
1966
1967 str_value = &curr_word[1];
1968 identifier = next_word;
1969 word_idx++;
1970 if (!vcd_string_valid(str_value)) {
1971 sr_err("Invalid string data: %s", str_value);
1972 ret = SR_ERR_DATA;
1973 break;
1974 }
1975 if (!identifier || !*identifier) {
1976 sr_err("String value without identifier.");
1977 ret = SR_ERR_DATA;
1978 break;
1979 }
1980 sr_spew("Got string data, id '%s', value \"%s\".",
1981 identifier, str_value);
1982 if (!is_ignored(inc, identifier)) {
1983 sr_err("String value for identifier '%s'.",
1984 identifier);
1985 ret = SR_ERR_DATA;
1986 break;
1987 }
1988 continue;
1989 }
0ab36d2f
GS
1990
1991 /* Design choice: Consider unsupported input fatal. */
1992 sr_err("Unknown token '%s'.", curr_word);
1993 ret = SR_ERR_DATA;
1994 break;
7db06394 1995 }
0ab36d2f
GS
1996 free_text_split(inc, words);
1997
1998 return ret;
7db06394
BV
1999}
2000
0ab36d2f 2001static int process_buffer(struct sr_input *in, gboolean is_eof)
7db06394 2002{
7db06394 2003 struct context *inc;
0ab36d2f
GS
2004 uint64_t samplerate;
2005 GVariant *gvar;
2006 int ret;
2007 char *rdptr, *endptr, *trimptr;
2008 size_t rdlen;
7db06394 2009
0ab36d2f 2010 inc = in->priv;
cd1b0e8f 2011
93a28f0b
GS
2012 if (!inc->got_header)
2013 return SR_ERR_DATA;
2014
0ab36d2f
GS
2015 /* Send feed header and samplerate (once) before sample data. */
2016 if (!inc->started) {
2017 std_session_send_df_header(in->sdi);
7db06394 2018
0ab36d2f
GS
2019 samplerate = inc->samplerate / inc->options.downsample;
2020 if (samplerate) {
2021 gvar = g_variant_new_uint64(samplerate);
2022 sr_session_send_meta(in->sdi, SR_CONF_SAMPLERATE, gvar);
2023 }
7db06394 2024
0ab36d2f
GS
2025 inc->started = TRUE;
2026 }
7db06394 2027
0ab36d2f
GS
2028 /*
2029 * Workaround broken generators which output incomplete text
2030 * lines. Enforce the trailing line feed. Proper input is not
2031 * harmed by another empty line of input data.
2032 */
2033 if (is_eof)
2034 g_string_append_c(in->buf, '\n');
2035
2036 /* Find and process complete text lines in the input data. */
2037 ret = SR_OK;
2038 rdptr = in->buf->str;
2039 while (TRUE) {
2040 rdlen = &in->buf->str[in->buf->len] - rdptr;
2041 endptr = g_strstr_len(rdptr, rdlen, "\n");
2042 if (!endptr)
2043 break;
2044 trimptr = endptr;
2045 *endptr++ = '\0';
2046 while (g_ascii_isspace(*rdptr))
2047 rdptr++;
2048 while (trimptr > rdptr && g_ascii_isspace(trimptr[-1]))
2049 *(--trimptr) = '\0';
2050 if (!*rdptr) {
2051 rdptr = endptr;
2052 continue;
2053 }
2054 ret = parse_textline(in, rdptr);
2055 rdptr = endptr;
2056 if (ret != SR_OK)
2057 break;
2058 }
2059 rdlen = rdptr - in->buf->str;
2060 g_string_erase(in->buf, 0, rdlen);
db0e5c99 2061
0ab36d2f 2062 return ret;
61a429c9
PA
2063}
2064
0ab36d2f 2065static int format_match(GHashTable *metadata, unsigned int *confidence)
7db06394 2066{
0ab36d2f
GS
2067 GString *buf, *tmpbuf;
2068 gboolean status;
2069 char *name, *contents;
7db06394 2070
0ab36d2f
GS
2071 buf = g_hash_table_lookup(metadata,
2072 GINT_TO_POINTER(SR_INPUT_META_HEADER));
2073 tmpbuf = g_string_new_len(buf->str, buf->len);
2074
2075 /*
2076 * If we can parse the first section correctly, then it is
2077 * assumed that the input is in VCD format.
2078 */
2079 check_remove_bom(tmpbuf);
2080 status = parse_section(tmpbuf, &name, &contents);
2081 g_string_free(tmpbuf, TRUE);
2082 g_free(name);
2083 g_free(contents);
2084
2085 if (!status)
2086 return SR_ERR;
7db06394 2087
0ab36d2f
GS
2088 *confidence = 1;
2089 return SR_OK;
7db06394
BV
2090}
2091
0ab36d2f 2092static int init(struct sr_input *in, GHashTable *options)
99eaa206 2093{
7db06394 2094 struct context *inc;
0ab36d2f 2095 GVariant *data;
7db06394 2096
0ab36d2f 2097 inc = g_malloc0(sizeof(*inc));
99eaa206 2098
0ab36d2f
GS
2099 data = g_hash_table_lookup(options, "numchannels");
2100 inc->options.maxchannels = g_variant_get_uint32(data);
d0181813 2101
0ab36d2f
GS
2102 data = g_hash_table_lookup(options, "downsample");
2103 inc->options.downsample = g_variant_get_uint64(data);
2104 if (inc->options.downsample < 1)
2105 inc->options.downsample = 1;
99eaa206 2106
0ab36d2f
GS
2107 data = g_hash_table_lookup(options, "compress");
2108 inc->options.compress = g_variant_get_uint64(data);
2109 inc->options.compress /= inc->options.downsample;
2110
2111 data = g_hash_table_lookup(options, "skip");
2112 if (data) {
2113 inc->options.skip_specified = TRUE;
2114 inc->options.skip_starttime = g_variant_get_uint64(data);
dd8bec71
GS
2115 if (inc->options.skip_starttime == ~UINT64_C(0)) {
2116 inc->options.skip_specified = FALSE;
2117 inc->options.skip_starttime = 0;
2118 }
0ab36d2f 2119 inc->options.skip_starttime /= inc->options.downsample;
7db06394 2120 }
99eaa206 2121
0ab36d2f
GS
2122 in->sdi = g_malloc0(sizeof(*in->sdi));
2123 in->priv = inc;
2124
2125 inc->scope_prefix = g_string_new("\0");
2126
7db06394
BV
2127 return SR_OK;
2128}
cd1b0e8f 2129
7066fd46
BV
2130static int receive(struct sr_input *in, GString *buf)
2131{
2132 struct context *inc;
2133 int ret;
2134
0ab36d2f
GS
2135 inc = in->priv;
2136
2137 /* Collect all input chunks, potential deferred processing. */
7066fd46 2138 g_string_append_len(in->buf, buf->str, buf->len);
0ab36d2f
GS
2139 if (!inc->got_header && in->buf->len == buf->len)
2140 check_remove_bom(in->buf);
7066fd46 2141
0ab36d2f 2142 /* Must complete reception of the VCD header first. */
7066fd46
BV
2143 if (!inc->got_header) {
2144 if (!have_header(in->buf))
2145 return SR_OK;
0ab36d2f
GS
2146 ret = parse_header(in, in->buf);
2147 if (ret != SR_OK)
2148 return ret;
7066fd46 2149 /* sdi is ready, notify frontend. */
0ab36d2f 2150 in->sdi_ready = TRUE;
7066fd46
BV
2151 return SR_OK;
2152 }
2153
0ab36d2f
GS
2154 /* Process sample data. */
2155 ret = process_buffer(in, FALSE);
7066fd46
BV
2156
2157 return ret;
2158}
2159
2160static int end(struct sr_input *in)
7db06394
BV
2161{
2162 struct context *inc;
7066fd46 2163 int ret;
0ab36d2f 2164 size_t count;
7066fd46 2165
db0e5c99
PA
2166 inc = in->priv;
2167
0ab36d2f 2168 /* Must complete processing of previously received chunks. */
7066fd46 2169 if (in->sdi_ready)
0ab36d2f 2170 ret = process_buffer(in, TRUE);
7066fd46
BV
2171 else
2172 ret = SR_OK;
99eaa206 2173
0ab36d2f 2174 /* Flush most recently queued sample data when EOF is seen. */
93a28f0b
GS
2175 if (inc->got_header && ret == SR_OK) {
2176 count = inc->data_after_timestamp ? 1 : 0;
2177 add_samples(in, count, TRUE);
2178 }
db0e5c99 2179
ec302917 2180 /* Optionally suggest downsampling after all input data was seen. */
93a28f0b
GS
2181 if (inc->got_header)
2182 (void)ts_stats_post(inc, !inc->data_after_timestamp);
ec302917 2183
0ab36d2f 2184 /* Must send DF_END when DF_HEADER was sent before. */
3be42bc2 2185 if (inc->started)
bee2b016 2186 std_session_send_df_end(in->sdi);
c10ef17c 2187
7066fd46
BV
2188 return ret;
2189}
2190
d5cc282f 2191static void cleanup(struct sr_input *in)
7066fd46
BV
2192{
2193 struct context *inc;
2194
2195 inc = in->priv;
0ab36d2f 2196
08f8421a 2197 keep_header_for_reread(in);
0ab36d2f 2198
7db06394 2199 g_slist_free_full(inc->channels, free_channel);
4237ab9e 2200 inc->channels = NULL;
0ab36d2f
GS
2201 feed_queue_logic_free(inc->feed_logic);
2202 inc->feed_logic = NULL;
2203 g_free(inc->conv_bits.value);
2204 inc->conv_bits.value = NULL;
2205 g_free(inc->current_logic);
2206 inc->current_logic = NULL;
2207 g_free(inc->current_floats);
2208 inc->current_floats = NULL;
2209 g_string_free(inc->scope_prefix, TRUE);
2210 inc->scope_prefix = NULL;
2211 g_slist_free_full(inc->ignored_signals, g_free);
2212 inc->ignored_signals = NULL;
2213 free_text_split(inc, NULL);
99eaa206
PA
2214}
2215
f4b4725b
SA
2216static int reset(struct sr_input *in)
2217{
0ab36d2f
GS
2218 struct context *inc;
2219 struct vcd_user_opt save;
2220 struct vcd_prev prev;
2221
2222 inc = in->priv;
f4b4725b 2223
0ab36d2f 2224 /* Relase previously allocated resources. */
f4b4725b 2225 cleanup(in);
f4b4725b
SA
2226 g_string_truncate(in->buf, 0);
2227
0ab36d2f
GS
2228 /* Restore part of the context, init() won't run again. */
2229 save = inc->options;
2230 prev = inc->prev;
2231 memset(inc, 0, sizeof(*inc));
2232 inc->options = save;
2233 inc->prev = prev;
2234 inc->scope_prefix = g_string_new("\0");
4237ab9e 2235
f4b4725b
SA
2236 return SR_OK;
2237}
2238
0ab36d2f
GS
2239enum vcd_option_t {
2240 OPT_NUM_CHANS,
2241 OPT_DOWN_SAMPLE,
2242 OPT_SKIP_COUNT,
2243 OPT_COMPRESS,
2244 OPT_MAX,
2245};
2246
7db06394 2247static struct sr_option options[] = {
0ab36d2f
GS
2248 [OPT_NUM_CHANS] = {
2249 "numchannels", "Max number of sigrok channels",
2250 "The maximum number of sigrok channels to create for VCD input signals.",
2251 NULL, NULL,
2252 },
2253 [OPT_DOWN_SAMPLE] = {
2254 "downsample", "Downsampling factor",
2255 "Downsample the input file's samplerate, i.e. divide by the specified factor.",
2256 NULL, NULL,
2257 },
2258 [OPT_SKIP_COUNT] = {
2259 "skip", "Skip this many initial samples",
2260 "Skip samples until the specified timestamp. "
2261 "By default samples start at the first timestamp in the file. "
2262 "Value 0 creates samples starting at timestamp 0. "
2263 "Values above 0 only start processing at the given timestamp.",
2264 NULL, NULL,
2265 },
2266 [OPT_COMPRESS] = {
2267 "compress", "Compress idle periods",
2268 "Compress idle periods which are longer than the specified number of timescale ticks.",
2269 NULL, NULL,
2270 },
2271 [OPT_MAX] = ALL_ZERO,
7db06394
BV
2272};
2273
2c240774 2274static const struct sr_option *get_options(void)
7db06394
BV
2275{
2276 if (!options[0].def) {
0ab36d2f
GS
2277 options[OPT_NUM_CHANS].def = g_variant_ref_sink(g_variant_new_uint32(0));
2278 options[OPT_DOWN_SAMPLE].def = g_variant_ref_sink(g_variant_new_uint64(1));
dd8bec71 2279 options[OPT_SKIP_COUNT].def = g_variant_ref_sink(g_variant_new_uint64(~UINT64_C(0)));
0ab36d2f 2280 options[OPT_COMPRESS].def = g_variant_ref_sink(g_variant_new_uint64(0));
7db06394
BV
2281 }
2282
2283 return options;
2284}
2285
d4c93774 2286SR_PRIV struct sr_input_module input_vcd = {
99eaa206 2287 .id = "vcd",
7db06394 2288 .name = "VCD",
b20eb520 2289 .desc = "Value Change Dump data",
c7bc82ff 2290 .exts = (const char*[]){"vcd", NULL},
7db06394
BV
2291 .metadata = { SR_INPUT_META_HEADER | SR_INPUT_META_REQUIRED },
2292 .options = get_options,
99eaa206
PA
2293 .format_match = format_match,
2294 .init = init,
7db06394 2295 .receive = receive,
7066fd46 2296 .end = end,
7db06394 2297 .cleanup = cleanup,
f4b4725b 2298 .reset = reset,
99eaa206 2299};