X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=parsers.c;h=59a7a91830220f573d7dd9abb85789fc0b038884;hb=527dd7262e49dd051ff554401f9cb21c2c9006dd;hp=4f3b0c5203752a4bf404b260641fca8e6436a53e;hpb=cad0cba6bb76d7aab6304aef41a2dd304ddad974;p=sigrok-cli.git diff --git a/parsers.c b/parsers.c index 4f3b0c5..59a7a91 100644 --- a/parsers.c +++ b/parsers.c @@ -139,8 +139,7 @@ range_fail: } if (names[1]) { /* Rename channel. */ - g_free(ch->name); - ch->name = g_strdup(names[1]); + sr_dev_channel_name_set(ch, names[1]); } channellist = g_slist_append(channellist, ch); @@ -267,6 +266,43 @@ int parse_triggerstring(const struct sr_dev_inst *sdi, const char *s, return !error; } +/** + * Split an input text into a key and value respectively ('=' separator). + * + * @param[in] text Writeable copy of the input text, gets modified. + * @param[out] key Position of the keyword. + * @param[out] val Position of the value. + * + * TODO In theory the returned key/value locations could be const pointers. + * Which even would be preferrable. Unfortunately most call sites deal with + * glib hashes, and their insert API seriously lacks the const attribute. + * So we drop it here as well to avoid clutter at callers'. + */ +static void split_key_value(char *text, char **key, char **val) +{ + char *k, *v; + char *pos; + + if (key) + *key = NULL; + if (val) + *val = NULL; + if (!text || !*text) + return; + + k = text; + v = NULL; + pos = strchr(k, '='); + if (pos) { + *pos = '\0'; + v = ++pos; + } + if (key) + *key = k; + if (val) + *val = v; +} + /** * Create hash table from colon separated key-value pairs input text. * @@ -301,49 +337,39 @@ GHashTable *parse_generic_arg(const char *arg, gboolean sep_first, const char *key_first) { GHashTable *hash; + char **elements; int i; - char **elements, *e; - int l; - const char *s; + char *k, *v; if (!arg || !arg[0]) return NULL; + if (key_first && !key_first[0]) + key_first = NULL; - i = 0; - hash = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, g_free); + hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); elements = g_strsplit(arg, ":", 0); + i = 0; if (sep_first) { - /* - * Caller requested "[:=]*" case, Consume the - * first item, before processing more key-value pairs below. - */ - g_hash_table_insert(hash, g_strdup("sigrok_key"), - g_strdup(elements[i++])); - } else if (key_first && *key_first) { - /* - * Caller requested "[=][:=]*" case. - * Optional special handling of the first item, but only - * consume this first item here when its keyword matched - * the caller's specification. - */ - l = strlen(key_first); - s = elements[i]; - e = strchr(s, '='); - if (e && e - s == l && g_str_has_prefix(s, key_first)) { - g_hash_table_insert(hash, - g_strdup("sigrok_key"), g_strdup(++e)); - i++; + k = g_strdup("sigrok_key"); + v = g_strdup(elements[i++]); + g_hash_table_insert(hash, k, v); + } else if (key_first) { + split_key_value(elements[i], &k, &v); + if (g_ascii_strcasecmp(k, key_first) == 0) { + k = "sigrok_key"; } + k = g_strdup(k); + v = g_strdup(v); + g_hash_table_insert(hash, k, v); + i++; } for (; elements[i]; i++) { - e = strchr(elements[i], '='); - if (!e) - g_hash_table_insert(hash, g_strdup(elements[i]), NULL); - else { - *e++ = '\0'; - g_hash_table_insert(hash, g_strdup(elements[i]), g_strdup(e)); - } + if (!elements[i][0]) + continue; + split_key_value(elements[i], &k, &v); + k = g_strdup(k); + v = v ? g_strdup(v) : NULL; + g_hash_table_insert(hash, k, v); } g_strfreev(elements); @@ -419,11 +445,11 @@ GHashTable *generic_arg_to_opt(const struct sr_option **opts, GHashTable *genarg g_hash_table_insert(hash, g_strdup(opts[i]->id), g_variant_ref_sink(gvar)); } else if (g_variant_is_of_type(opts[i]->def, G_VARIANT_TYPE_INT32)) { - gvar = g_variant_new_int32(strtoul(s, NULL, 10)); + gvar = g_variant_new_int32(strtol(s, NULL, 10)); g_hash_table_insert(hash, g_strdup(opts[i]->id), g_variant_ref_sink(gvar)); } else if (g_variant_is_of_type(opts[i]->def, G_VARIANT_TYPE_UINT64)) { - gvar = g_variant_new_uint64(strtoul(s, NULL, 10)); + gvar = g_variant_new_uint64(strtoull(s, NULL, 10)); g_hash_table_insert(hash, g_strdup(opts[i]->id), g_variant_ref_sink(gvar)); } else if (g_variant_is_of_type(opts[i]->def, G_VARIANT_TYPE_DOUBLE)) {