diff --git a/doc/sigrok-cli.1 b/doc/sigrok-cli.1 index 3ec6768..efcb83b 100644 --- a/doc/sigrok-cli.1 +++ b/doc/sigrok-cli.1 @@ -181,13 +181,15 @@ The default is to use all the channels available on a device. You can name a channel like this: .BR "1=CLK" . A range of channels can also be given, in the form -.BR "1\-5" . +.BR "1\-5" +or (if they have a common prefix) +.BR "CH1\-5" . .sp Example: .sp .RB " $ " "sigrok\-cli \-\-driver fx2lafw \-\-samples 100" .br -.B " \-\-channels 1=CLK,2\-4,7" +.B " \-\-channels D1=CLK,D2\-4,D7" .br CLK:11111111 11111111 11111111 11111111 [...] 2:11111111 11111111 11111111 11111111 [...] diff --git a/parsers.c b/parsers.c index 317ead2..013e7bf 100644 --- a/parsers.c +++ b/parsers.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -45,8 +46,8 @@ GSList *parse_channelstring(struct sr_dev_inst *sdi, const char *channelstring) { struct sr_channel *ch; GSList *channellist, *channels; - int ret, n, b, e, i; - char **tokens, **range, **names, *eptr, str[8]; + int ret, n, b, e, i, plen; + char **tokens, **range, **names, *sptr, *eptr, str[8]; channels = sr_dev_inst_channels_get(sdi); @@ -89,9 +90,9 @@ GSList *parse_channelstring(struct sr_dev_inst *sdi, const char *channelstring) } else if (strchr(names[0], '-')) { /* * A range of channels in the form a-b. This will only work - * if the channels are named as numbers -- so every channel - * in the range must exist as a channel name string in the - * device. + * if the channels are named as numbers (with an optional prefix) + * -- so every channel in the range must exist as a channel name + * string in the device. */ if (names[1]) { /* Channel range syntax not allowed when renaming. */ @@ -108,15 +109,28 @@ GSList *parse_channelstring(struct sr_dev_inst *sdi, const char *channelstring) goto range_fail; } + /* Find start of numeric range (first digit) in range string. */ + for (sptr = names[0]; *sptr != '-' && !isdigit(*sptr); sptr++); + if (*sptr == '-') { /* no digit found before range separator. */ + g_critical("Channel range '%s' needs numbered channels.", names[0]); + ret = SR_ERR; + goto range_fail; + } + + /* Length of channel name prefix. */ + plen = sptr - names[0]; + + range = g_strsplit(sptr, "-", 2); + b = strtol(range[0], &eptr, 10); if (eptr == range[0] || *eptr != '\0') { - g_critical("Invalid channel '%s'.", range[0]); + g_critical("Invalid channel '%.*s%s'.", plen, names[0], range[0]); ret = SR_ERR; goto range_fail; } e = strtol(range[1], NULL, 10); if (eptr == range[1] || *eptr != '\0') { - g_critical("Invalid channel '%s'.", range[1]); + g_critical("Invalid channel '%.*s%s'.", plen, names[0], range[1]); ret = SR_ERR; goto range_fail; } @@ -127,15 +141,15 @@ GSList *parse_channelstring(struct sr_dev_inst *sdi, const char *channelstring) } while (b <= e) { - n = snprintf(str, 8, "%d", b); + n = snprintf(str, 8, "%.*s%d", plen, names[0], b); if (n < 0 || n > 8) { - g_critical("Invalid channel '%d'.", b); + g_critical("Invalid channel '%.*s%d'.", plen, names[0], b); ret = SR_ERR; break; } ch = find_channel(channels, str); if (!ch) { - g_critical("unknown channel '%d'.", b); + g_critical("unknown channel '%s'.", str); ret = SR_ERR; break; }