input/vcd: unbreak the logic which skips a user specified period
Rephrase the default value for the 'skip' option and the detection of a user specified value. This is tricky because: Sample numbers are kept in 64bit values. Skip and downsample are fed to formulae so we want them both to be unsigned. Yet absence of a user spec as well as possible user values 0 and positive must be told apart. Use all-ones for the default of "-1" which translates to "first timestamp", users need not be able to specify that negative value. Make sure to only downsample 'skip' values when the user specified some. Which avoids the undesired insertion of huge idle gaps at the start of the capture. An earlier implementation had to check for -1, this recent version uses an unsigned number in combination with a boolean flag to achieve this. Reword some diagnostics messages, and print the samples count between timestamps while we are here. Add a check for successful text to number conversion of timestamp values. How to reproduce: $ pulseview -i file.vcd $ pulseview -i file.vcd -I vcd:downsample=5 $ pulseview -i file.vcd -I vcd:skip=111381600 Example file: $timescale 1 ns $end $scope module top $end $var wire 1 ! d1 $end $upscope $end $enddefinitions $end #111381815 0! #111381905 1! #111381990 0! #111382075
This commit is contained in:
parent
c03aaf342c
commit
dd8bec71c2
|
@ -1250,7 +1250,7 @@ static int parse_textline(const struct sr_input *in, char *lines)
|
|||
char *curr_word, *next_word, curr_first;
|
||||
gboolean is_timestamp, is_section, is_real, is_multibit, is_singlebit;
|
||||
uint64_t timestamp;
|
||||
char *identifier;
|
||||
char *identifier, *endptr;
|
||||
size_t count;
|
||||
|
||||
inc = in->priv;
|
||||
|
@ -1344,7 +1344,13 @@ static int parse_textline(const struct sr_input *in, char *lines)
|
|||
*/
|
||||
is_timestamp = curr_first == '#' && g_ascii_isdigit(curr_word[1]);
|
||||
if (is_timestamp) {
|
||||
timestamp = strtoull(&curr_word[1], NULL, 10);
|
||||
endptr = NULL;
|
||||
timestamp = strtoull(&curr_word[1], &endptr, 10);
|
||||
if (!endptr || *endptr) {
|
||||
sr_err("Invalid timestamp: %s.", curr_word);
|
||||
ret = SR_ERR_DATA;
|
||||
break;
|
||||
}
|
||||
sr_spew("Got timestamp: %" PRIu64, timestamp);
|
||||
if (inc->options.downsample > 1) {
|
||||
timestamp /= inc->options.downsample;
|
||||
|
@ -1357,11 +1363,13 @@ static int parse_textline(const struct sr_input *in, char *lines)
|
|||
* Skip > 0 => skip until timestamp >= skip.
|
||||
*/
|
||||
if (inc->options.skip_specified && !inc->use_skip) {
|
||||
sr_dbg("Seeding use of skip");
|
||||
sr_dbg("Seeding skip from user spec %" PRIu64,
|
||||
inc->options.skip_starttime);
|
||||
inc->prev_timestamp = inc->options.skip_starttime;
|
||||
inc->use_skip = TRUE;
|
||||
}
|
||||
if (!inc->use_skip) {
|
||||
sr_dbg("First timestamp, and no skip used");
|
||||
sr_dbg("Seeding skip from first timestamp");
|
||||
inc->options.skip_starttime = timestamp;
|
||||
inc->prev_timestamp = timestamp;
|
||||
inc->use_skip = TRUE;
|
||||
|
@ -1400,8 +1408,8 @@ static int parse_textline(const struct sr_input *in, char *lines)
|
|||
}
|
||||
|
||||
/* Generate samples from prev_timestamp up to timestamp - 1. */
|
||||
sr_spew("Got a new timestamp, feeding samples");
|
||||
count = timestamp - inc->prev_timestamp;
|
||||
sr_spew("Got a new timestamp, feeding %zu samples", count);
|
||||
add_samples(in, count, FALSE);
|
||||
inc->prev_timestamp = timestamp;
|
||||
inc->data_after_timestamp = FALSE;
|
||||
|
@ -1711,6 +1719,10 @@ static int init(struct sr_input *in, GHashTable *options)
|
|||
if (data) {
|
||||
inc->options.skip_specified = TRUE;
|
||||
inc->options.skip_starttime = g_variant_get_uint64(data);
|
||||
if (inc->options.skip_starttime == ~UINT64_C(0)) {
|
||||
inc->options.skip_specified = FALSE;
|
||||
inc->options.skip_starttime = 0;
|
||||
}
|
||||
inc->options.skip_starttime /= inc->options.downsample;
|
||||
}
|
||||
|
||||
|
@ -1865,7 +1877,7 @@ static const struct sr_option *get_options(void)
|
|||
if (!options[0].def) {
|
||||
options[OPT_NUM_CHANS].def = g_variant_ref_sink(g_variant_new_uint32(0));
|
||||
options[OPT_DOWN_SAMPLE].def = g_variant_ref_sink(g_variant_new_uint64(1));
|
||||
options[OPT_SKIP_COUNT].def = g_variant_ref_sink(g_variant_new_uint64(0));
|
||||
options[OPT_SKIP_COUNT].def = g_variant_ref_sink(g_variant_new_uint64(~UINT64_C(0)));
|
||||
options[OPT_COMPRESS].def = g_variant_ref_sink(g_variant_new_uint64(0));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue