/**
* Lookup a channel group from its name.
*
- * Uses the previously stored option value to lookup a channel group.
- * Returns a reference to the channel group when the lookup succeeded,
- * or #NULL after lookup failure, or #NULL for the global channel group
- * (the device's global parameters). Emits an error message when the
- * lookup failed while a channel group's name was specified.
+ * Uses the caller specified channel group name, or a previously stored
+ * option value as a fallback. Returns a reference to the channel group
+ * when the lookup succeeded, or #NULL after lookup failure, as well as
+ * #NULL for the global channel group (the device).
+ *
+ * Accepts either #NULL pointer, or an empty string, or the "global"
+ * literal to address the global channel group (the device). Emits an
+ * error message when the lookup failed while a name was specified.
*
* @param[in] sdi Device instance.
+ * @param[in] cg_name Caller provided channel group name.
*
* @returns The channel group, or #NULL for failed lookup.
*/
-struct sr_channel_group *lookup_channel_group(struct sr_dev_inst *sdi)
+struct sr_channel_group *lookup_channel_group(struct sr_dev_inst *sdi,
+ const char *cg_name)
{
struct sr_channel_group *cg;
GSList *l, *channel_groups;
- if (!opt_channel_group)
+ if (!cg_name)
+ cg_name = opt_channel_group;
+ if (cg_name && g_ascii_strcasecmp(cg_name, "global") == 0)
+ cg_name = NULL;
+ if (!cg_name || !*cg_name)
return NULL;
channel_groups = sr_dev_inst_channel_groups_get(sdi);
for (l = channel_groups; l; l = l->next) {
cg = l->data;
- if (g_ascii_strcasecmp(opt_channel_group, cg->name) != 0)
+ if (g_ascii_strcasecmp(cg_name, cg->name) != 0)
continue;
return cg;
}
- g_critical("Invalid channel group '%s'", opt_channel_group);
+ g_critical("Invalid channel group '%s'", cg_name);
return NULL;
}
const struct sr_key_info *ci;
GSList *devices;
GVariant *gvar;
- GHashTable *devargs;
int ret;
char *s;
struct sr_dev_driver *driver;
return;
}
- cg = lookup_channel_group(sdi);
+ cg = lookup_channel_group(sdi, NULL);
if (!(ci = sr_key_info_name_get(SR_KEY_CONFIG, opt_get)))
g_critical("Unknown option '%s'", opt_get);
- if ((devargs = parse_generic_arg(opt_config, FALSE, NULL)))
- set_dev_options(sdi, devargs);
- else
- devargs = NULL;
+ set_dev_options_array(sdi, opt_configs);
if ((ret = maybe_config_get(driver, sdi, cg, ci->key, &gvar)) != SR_OK)
g_critical("Failed to get '%s': %s", opt_get, sr_strerror(ret));
g_variant_unref(gvar);
sr_dev_close(sdi);
- if (devargs)
- g_hash_table_destroy(devargs);
}
static void set_options(void)
{
struct sr_dev_inst *sdi;
GSList *devices;
- GHashTable *devargs;
- if (!opt_config) {
+ if (!opt_configs) {
g_critical("No setting specified.");
return;
}
- if (!(devargs = parse_generic_arg(opt_config, FALSE, NULL)))
- return;
-
if (!(devices = device_scan())) {
g_critical("No devices found.");
return;
return;
}
- set_dev_options(sdi, devargs);
+ set_dev_options_array(sdi, opt_configs);
sr_dev_close(sdi);
- g_hash_table_destroy(devargs);
-
}
int main(int argc, char **argv)
gchar *opt_input_file = NULL;
gchar *opt_output_file = NULL;
gchar *opt_drv = NULL;
-gchar *opt_config = NULL;
+gchar **opt_configs = NULL;
gchar *opt_channels = NULL;
gchar *opt_channel_group = NULL;
gchar *opt_triggers = NULL;
}
CHECK_ONCE(opt_drv)
-CHECK_ONCE(opt_config)
CHECK_ONCE(opt_input_format)
CHECK_ONCE(opt_output_format)
CHECK_ONCE(opt_transform_module)
"Set loglevel (5 is most verbose)", NULL},
{"driver", 'd', 0, G_OPTION_ARG_CALLBACK, &check_opt_drv,
"The driver to use", NULL},
- {"config", 'c', 0, G_OPTION_ARG_CALLBACK, &check_opt_config,
+ {"config", 'c', 0, G_OPTION_ARG_STRING_ARRAY, &opt_configs,
"Specify device configuration options", NULL},
{"input-file", 'i', 0, G_OPTION_ARG_FILENAME_ARRAY, &input_file_array,
"Load input from file", NULL},
return ret;
}
+int set_dev_options_array(struct sr_dev_inst *sdi, char **opts)
+{
+ size_t opt_idx;
+ const char *opt_text;
+ GHashTable *args;
+ int ret;
+
+ for (opt_idx = 0; opts && opts[opt_idx]; opt_idx++) {
+ opt_text = opts[opt_idx];
+ args = parse_generic_arg(opt_text, FALSE, "channel_group");
+ if (!args)
+ continue;
+ ret = set_dev_options(sdi, args);
+ g_hash_table_destroy(args);
+ if (ret != SR_OK)
+ return ret;
+ }
+
+ return SR_OK;
+}
+
int set_dev_options(struct sr_dev_inst *sdi, GHashTable *args)
{
struct sr_config src;
+ const char *cg_name;
struct sr_channel_group *cg;
GHashTableIter iter;
gpointer key, value;
int ret;
+ /*
+ * Not finding the 'sigrok_key' key (optional user specified
+ * channel group name) in the current options group's hash table
+ * is perfectly fine. In that case the -g selection is used,
+ * which defaults to "the device" (global parameters).
+ */
+ cg_name = g_hash_table_lookup(args, "sigrok_key");
+ cg = lookup_channel_group(sdi, cg_name);
+
g_hash_table_iter_init(&iter, args);
while (g_hash_table_iter_next(&iter, &key, &value)) {
+ if (g_ascii_strcasecmp(key, "sigrok_key") == 0)
+ continue;
if ((ret = opt_to_gvar(key, value, &src)) != 0)
return ret;
- cg = lookup_channel_group(sdi);
if ((ret = maybe_config_set(sr_dev_inst_driver_get(sdi), sdi, cg,
src.key, src.data)) != SR_OK) {
g_critical("Failed to set device option '%s': %s.",
{
struct df_arg_desc df_arg;
GSList *devices, *real_devices, *sd;
- GHashTable *devargs;
GVariant *gvar;
struct sr_session *session;
struct sr_trigger *trigger;
return;
}
- if (opt_config) {
- if ((devargs = parse_generic_arg(opt_config, FALSE, NULL))) {
- if (set_dev_options(sdi, devargs) != SR_OK)
- return;
- g_hash_table_destroy(devargs);
- }
+ if (opt_configs) {
+ if (set_dev_options_array(sdi, opt_configs) != SR_OK)
+ return;
}
if (select_channels(sdi) != SR_OK) {
* returned, or which values for them.
*/
select_channels(sdi);
- channel_group = lookup_channel_group(sdi);
+ channel_group = lookup_channel_group(sdi, NULL);
if (!(opts = sr_dev_options(driver, sdi, channel_group)))
/* Driver supports no device instance options. */
/* device.c */
GSList *device_scan(void);
-struct sr_channel_group *lookup_channel_group(struct sr_dev_inst *sdi);
+struct sr_channel_group *lookup_channel_group(struct sr_dev_inst *sdi,
+ const char *cg_name);
/* session.c */
struct df_arg_desc {
void datafeed_in(const struct sr_dev_inst *sdi,
const struct sr_datafeed_packet *packet, void *cb_data);
int opt_to_gvar(char *key, char *value, struct sr_config *src);
+int set_dev_options_array(struct sr_dev_inst *sdi, char **opts);
int set_dev_options(struct sr_dev_inst *sdi, GHashTable *args);
void run_session(void);
extern gchar *opt_input_file;
extern gchar *opt_output_file;
extern gchar *opt_drv;
-extern gchar *opt_config;
+extern gchar **opt_configs;
extern gchar *opt_channels;
extern gchar *opt_channel_group;
extern gchar *opt_triggers;