+static GHashTable *parse_input_options(const struct sr_option **pd_opts,
+ GSList *user_specs)
+{
+ GHashTable *set_opts;
+ GVariant *pd_def, *gvar;
+ size_t idx;
+ GSList *l;
+ const char *pd_key;
+ const char *spec_text, *s;
+
+ set_opts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify)g_variant_unref);
+ for (idx = 0; pd_opts[idx]; idx++) {
+ pd_key = pd_opts[idx]->id;
+ /* Is the PD provided option in the set of input specs? */
+ s = NULL;
+ for (l = user_specs; l; l = l->next) {
+ spec_text = l->data;
+ if (strncmp(spec_text, pd_key, strlen(pd_key)) != 0)
+ continue;
+ spec_text += strlen(pd_key);
+ if (!*spec_text) {
+ /* Found 'key' up to end of text. */
+ s = spec_text;
+ break;
+ }
+ if (*spec_text == '=') {
+ /* Found 'key=...', position to RHS value. */
+ s = ++spec_text;
+ break;
+ }
+ }
+ if (!s)
+ continue;
+ /*
+ * Normalize the input text for the user specified value.
+ * A key without an explicit value is useful for booleans.
+ */
+ if (!*s)
+ s = "";
+ /*
+ * Convert the text to the PD default value's data type.
+ * Store the resulting variable in the hash which gets
+ * passed to the input module.
+ */
+ pd_def = pd_opts[idx]->def;
+ if (g_variant_is_of_type(pd_def, G_VARIANT_TYPE_UINT32)) {
+ gvar = g_variant_new_uint32(strtoul(s, NULL, 10));
+ g_hash_table_insert(set_opts, g_strdup(pd_key),
+ g_variant_ref_sink(gvar));
+ continue;
+ }
+ if (g_variant_is_of_type(pd_def, G_VARIANT_TYPE_INT32)) {
+ gvar = g_variant_new_int32(strtol(s, NULL, 10));
+ g_hash_table_insert(set_opts, g_strdup(pd_key),
+ g_variant_ref_sink(gvar));
+ continue;
+ }
+ if (g_variant_is_of_type(pd_def, G_VARIANT_TYPE_UINT64)) {
+ gvar = g_variant_new_uint64(strtoull(s, NULL, 10));
+ g_hash_table_insert(set_opts, g_strdup(pd_key),
+ g_variant_ref_sink(gvar));
+ continue;
+ }
+ if (g_variant_is_of_type(pd_def, G_VARIANT_TYPE_DOUBLE)) {
+ gvar = g_variant_new_double(strtod(s, NULL));
+ g_hash_table_insert(set_opts, g_strdup(pd_key),
+ g_variant_ref_sink(gvar));
+ continue;
+ }
+ if (g_variant_is_of_type(pd_def, G_VARIANT_TYPE_STRING)) {
+ gvar = g_variant_new_string(s);
+ g_hash_table_insert(set_opts, g_strdup(pd_key),
+ g_variant_ref_sink(gvar));
+ continue;
+ }
+ if (g_variant_is_of_type(pd_def, G_VARIANT_TYPE_BOOLEAN)) {
+ gboolean b;
+ if (strcmp(s, "false") == 0 || strcmp(s, "no") == 0) {
+ b = FALSE;
+ } else if (strcmp(s, "true") == 0 || strcmp(s, "yes") == 0) {
+ b = TRUE;
+ } else {
+ ERR("Cannot convert '%s' to boolean", s);
+ return NULL;
+ }
+ gvar = g_variant_new_boolean(b);
+ g_hash_table_insert(set_opts, g_strdup(pd_key),
+ g_variant_ref_sink(gvar));
+ continue;
+ }
+ ERR("Unsupported data type for option '%s'", pd_key);
+ return NULL;
+ }
+
+ return set_opts;
+}
+
+static int run_testcase(struct input *inp, GSList *pdlist, struct output *op)