+ if (!found_id)
+ unknown = g_slist_append(unknown, g_strdup(used_id));
+ }
+
+ /* Return the list of unknown keywords, or NULL if empty. */
+ return unknown;
+}
+
+gboolean warn_unknown_keys(const struct sr_option **avail, GHashTable *used,
+ const char *caption)
+{
+ GSList *unknown, *l;
+ gboolean had_unknown;
+ const char *s;
+
+ if (!caption || !*caption)
+ caption = "Unknown keyword";
+
+ unknown = check_unknown_keys(avail, used);
+ had_unknown = unknown != NULL;
+ for (l = unknown; l; l = l->next) {
+ s = l->data;
+ g_warning("%s: %s.", caption, s);
+ }
+ g_slist_free_full(unknown, g_free);
+
+ return had_unknown;
+}
+
+GHashTable *generic_arg_to_opt(const struct sr_option **opts, GHashTable *genargs)
+{
+ GHashTable *hash;
+ GVariant *gvar;
+ int i;
+ char *s;
+ gboolean b;
+
+ hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify)g_variant_unref);
+ for (i = 0; opts[i]; i++) {
+ if (!(s = g_hash_table_lookup(genargs, opts[i]->id)))
+ continue;
+ if (g_variant_is_of_type(opts[i]->def, G_VARIANT_TYPE_UINT32)) {
+ gvar = g_variant_new_uint32(strtoul(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_INT32)) {
+ 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(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)) {
+ gvar = g_variant_new_double(strtod(s, NULL));
+ 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_STRING)) {
+ gvar = g_variant_new_string(s);
+ 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_BOOLEAN)) {
+ b = TRUE;
+ if (0 == strcmp(s, "false") || 0 == strcmp(s, "no")) {
+ b = FALSE;
+ } else if (!(0 == strcmp(s, "true") || 0 == strcmp(s, "yes"))) {
+ g_critical("Unable to convert '%s' to boolean!", s);