/*
- * This file is part of the sigrok project.
+ * This file is part of the sigrok-cli project.
*
* Copyright (C) 2011 Bert Vermeulen <bert@biot.com>
*
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "sigrok-cli.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <glib.h>
-#include <sigrok.h>
-#include "sigrok-cli.h"
-char **parse_probestring(int max_probes, const char *probestring)
+struct sr_probe *find_probe(GSList *probelist, const char *probename)
{
- int tmp, b, e, i;
- char **tokens, **range, **probelist, *name, str[8];
- gboolean error;
+ struct sr_probe *probe;
+ GSList *l;
- error = FALSE;
- range = NULL;
- if (!(probelist = g_try_malloc0(max_probes * sizeof(char *)))) {
- /* TODO: Handle errors. */
+ probe = NULL;
+ for (l = probelist; l; l = l->next) {
+ probe = l->data;
+ if (!strcmp(probe->name, probename))
+ break;
}
- tokens = g_strsplit(probestring, ",", max_probes);
+ probe = l ? l->data : NULL;
+
+ return probe;
+}
+
+GSList *parse_probestring(struct sr_dev_inst *sdi, const char *probestring)
+{
+ struct sr_probe *probe;
+ GSList *probelist;
+ int ret, n, b, e, i;
+ char **tokens, **range, **names, *eptr, str[8];
+ if (!probestring || !probestring[0])
+ /* Use all probes by default. */
+ return g_slist_copy(sdi->probes);
+
+ ret = SR_OK;
+ range = NULL;
+ names = NULL;
+ probelist = NULL;
+ tokens = g_strsplit(probestring, ",", 0);
for (i = 0; tokens[i]; i++) {
+ if (tokens[i][0] == '\0') {
+ g_critical("Invalid empty probe.");
+ ret = SR_ERR;
+ break;
+ }
if (strchr(tokens[i], '-')) {
- /* A range of probes in the form 1-5. */
+ /* A range of probes in the form a-b. This will only work
+ * if the probes are named as numbers -- so every probe
+ * in the range must exist as a probe name string in the
+ * device. */
range = g_strsplit(tokens[i], "-", 2);
if (!range[0] || !range[1] || range[2]) {
/* Need exactly two arguments. */
- printf("Invalid probe syntax '%s'.\n",
- tokens[i]);
- error = TRUE;
- break;
+ g_critical("Invalid probe syntax '%s'.", tokens[i]);
+ ret = SR_ERR;
+ goto range_fail;
}
- b = strtol(range[0], NULL, 10);
+ b = strtol(range[0], &eptr, 10);
+ if (eptr == range[0] || *eptr != '\0') {
+ g_critical("Invalid probe '%s'.", range[0]);
+ ret = SR_ERR;
+ goto range_fail;
+ }
e = strtol(range[1], NULL, 10);
- if (b < 1 || e > max_probes || b >= e) {
- printf("Invalid probe range '%s'.\n",
- tokens[i]);
- error = TRUE;
- break;
+ if (eptr == range[1] || *eptr != '\0') {
+ g_critical("Invalid probe '%s'.", range[1]);
+ ret = SR_ERR;
+ goto range_fail;
+ }
+ if (b < 0 || b >= e) {
+ g_critical("Invalid probe range '%s'.", tokens[i]);
+ ret = SR_ERR;
+ goto range_fail;
}
while (b <= e) {
- snprintf(str, 7, "%d", b);
- probelist[b - 1] = g_strdup(str);
+ n = snprintf(str, 8, "%d", b);
+ if (n < 0 || n > 8) {
+ g_critical("Invalid probe '%d'.", b);
+ ret = SR_ERR;
+ break;
+ }
+ probe = find_probe(sdi->probes, str);
+ if (!probe) {
+ g_critical("unknown probe '%d'.", b);
+ ret = SR_ERR;
+ break;
+ }
+ probelist = g_slist_append(probelist, probe);
b++;
}
+range_fail:
+ if (range)
+ g_strfreev(range);
+
+ if (ret != SR_OK)
+ break;
} else {
- tmp = strtol(tokens[i], NULL, 10);
- if (tmp < 1 || tmp > max_probes) {
- printf("Invalid probe %d.\n", tmp);
- error = TRUE;
+ names = g_strsplit(tokens[i], "=", 2);
+ if (!names[0] || (names[1] && names[2])) {
+ /* Need one or two arguments. */
+ g_critical("Invalid probe '%s'.", tokens[i]);
+ g_strfreev(names);
+ ret = SR_ERR;
break;
}
- if ((name = strchr(tokens[i], '='))) {
- probelist[tmp - 1] = g_strdup(++name);
- if (strlen(probelist[tmp - 1]) > SR_MAX_PROBENAME_LEN)
- probelist[tmp - 1][SR_MAX_PROBENAME_LEN] = 0;
- } else {
- snprintf(str, 7, "%d", tmp);
- probelist[tmp - 1] = g_strdup(str);
+ probe = find_probe(sdi->probes, names[0]);
+ if (!probe) {
+ g_critical("unknown probe '%s'.", names[0]);
+ g_strfreev(names);
+ ret = SR_ERR;
+ break;
+ }
+ if (names[1]) {
+ /* Rename probe. */
+ g_free(probe->name);
+ probe->name = g_strdup(names[1]);
}
+ probelist = g_slist_append(probelist, probe);
+
+ g_strfreev(names);
}
}
- if (error) {
- for (i = 0; i < max_probes; i++)
- if (probelist[i])
- g_free(probelist[i]);
- g_free(probelist);
+ if (ret != SR_OK) {
+ g_slist_free(probelist);
probelist = NULL;
}
g_strfreev(tokens);
- if (range)
- g_strfreev(range);
return probelist;
}
-GHashTable *parse_generic_arg(const char *arg)
+GHashTable *parse_generic_arg(const char *arg, gboolean sep_first)
{
GHashTable *hash;
int i;
if (!arg || !arg[0])
return NULL;
- hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ i = 0;
+ hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, g_free);
elements = g_strsplit(arg, ":", 0);
- g_hash_table_insert(hash, g_strdup("sigrok_key"), g_strdup(elements[0]));
- for (i = 1; elements[i]; i++) {
+ if (sep_first)
+ g_hash_table_insert(hash, g_strdup("sigrok_key"),
+ g_strdup(elements[i++]));
+ for (; elements[i]; i++) {
e = strchr(elements[i], '=');
if (!e)
g_hash_table_insert(hash, g_strdup(elements[i]), NULL);
return hash;
}
-struct sr_dev *parse_devstring(const char *devstring)
+static char *strcanon(const char *str)
{
- struct sr_dev *dev, *d;
- struct sr_dev_driver **drivers;
- GSList *devs, *l;
- int i, num_devs, dev_num, dev_cnt;
- char *tmp;
+ int p0, p1;
+ char *s;
+
+ /* Returns newly allocated string. */
+ s = g_ascii_strdown(str, -1);
+ for (p0 = p1 = 0; str[p0]; p0++) {
+ if ((s[p0] >= 'a' && s[p0] <= 'z')
+ || (s[p0] >= '0' && s[p0] <= '9'))
+ s[p1++] = s[p0];
+ }
+ s[p1] = '\0';
- if (!devstring)
- return NULL;
+ return s;
+}
- dev = NULL;
- dev_num = strtol(devstring, &tmp, 10);
- if (tmp != devstring) {
- /* argument is numeric, meaning a device ID. Make all drivers
- * scan for devices.
- */
- num_devs = num_real_devs();
- if (dev_num < 0 || dev_num >= num_devs)
- return NULL;
-
- dev_cnt = 0;
- devs = sr_dev_list();
- for (l = devs; l; l = l->next) {
- d = l->data;
- if (sr_dev_has_hwcap(d, SR_HWCAP_DEMO_DEV))
- continue;
- if (dev_cnt == dev_num) {
- if (dev_num == dev_cnt) {
- dev = d;
- break;
- }
- }
- dev_cnt++;
- }
- } else {
- /* select device by driver -- only initialize that driver,
- * no need to let them all scan
- */
- dev = NULL;
- drivers = sr_hw_list();
- for (i = 0; drivers[i]; i++) {
- if (strcmp(drivers[i]->name, devstring))
- continue;
- num_devs = sr_hw_init(drivers[i]);
- if (num_devs == 1) {
- devs = sr_dev_list();
- dev = devs->data;
- } else if (num_devs > 1) {
- printf("driver '%s' found %d devices, select by ID instead.\n",
- devstring, num_devs);
- }
- /* fall through: selected driver found no devices */
- break;
- }
- }
+int canon_cmp(const char *str1, const char *str2)
+{
+ int ret;
+ char *s1, *s2;
+
+ s1 = strcanon(str1);
+ s2 = strcanon(str2);
+ ret = g_ascii_strcasecmp(s1, s2);
+ g_free(s2);
+ g_free(s1);
- return dev;
+ return ret;
}