]> sigrok.org Git - libsigrok.git/commitdiff
drivers: Factor out std_*_idx*().
authorUwe Hermann <redacted>
Tue, 25 Jul 2017 21:12:09 +0000 (23:12 +0200)
committerUwe Hermann <redacted>
Mon, 31 Jul 2017 14:23:31 +0000 (16:23 +0200)
22 files changed:
src/hardware/agilent-dmm/api.c
src/hardware/appa-55ii/api.c
src/hardware/atten-pps3xxx/api.c
src/hardware/cem-dt-885x/api.c
src/hardware/demo/api.c
src/hardware/dreamsourcelab-dslogic/api.c
src/hardware/fx2lafw/api.c
src/hardware/hameg-hmo/api.c
src/hardware/hantek-6xxx/api.c
src/hardware/hantek-dso/api.c
src/hardware/hung-chang-dso-2100/api.c
src/hardware/kecheng-kc-330b/api.c
src/hardware/lecroy-xstream/api.c
src/hardware/motech-lps-30x/api.c
src/hardware/pce-322a/api.c
src/hardware/rigol-ds/api.c
src/hardware/saleae-logic16/api.c
src/hardware/sysclk-lwla/api.c
src/hardware/uni-t-ut32x/api.c
src/hardware/yokogawa-dlm/api.c
src/libsigrok-internal.h
src/std.c

index 2f99bb2ffd73ff976523562ec6997dcb0adaeeba..293b5f84c4336919916a113bdc08f05b737dfa42 100644 (file)
@@ -217,9 +217,7 @@ static int config_set(uint32_t key, GVariant *data,
 {
        struct dev_context *devc;
        uint64_t samplerate;
-       const char *tmp_str;
-       unsigned int i;
-       int ret;
+       int ret, idx;
 
        (void)cg;
 
@@ -238,17 +236,11 @@ static int config_set(uint32_t key, GVariant *data,
        case SR_CONF_LIMIT_MSEC:
                ret = sr_sw_limits_config_set(&devc->limits, key, data);
                break;
-       case SR_CONF_DATA_SOURCE: {
-               tmp_str = g_variant_get_string(data, NULL);
-               for (i = 0; i < ARRAY_SIZE(data_sources); i++)
-                       if (!strcmp(tmp_str, data_sources[i])) {
-                               devc->data_source = i;
-                               break;
-                       }
-               if (i == ARRAY_SIZE(data_sources))
-                       return SR_ERR;
+       case SR_CONF_DATA_SOURCE:
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(data_sources))) < 0)
+                       return SR_ERR_ARG;
+               devc->data_source = idx;
                break;
-       }
        default:
                ret = SR_ERR_NA;
        }
index c55a5fd0e87d0d940585ffe888c8935972ed8cc0..ddf3fe4a11885468a041838e1ab8d01a0300c2ea 100644 (file)
@@ -134,8 +134,7 @@ static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
        struct dev_context *devc;
-       const char *tmp_str;
-       unsigned int i;
+       int idx;
 
        (void)cg;
 
@@ -145,17 +144,11 @@ static int config_set(uint32_t key, GVariant *data,
        case SR_CONF_LIMIT_SAMPLES:
        case SR_CONF_LIMIT_MSEC:
                return sr_sw_limits_config_set(&devc->limits, key, data);
-       case SR_CONF_DATA_SOURCE: {
-               tmp_str = g_variant_get_string(data, NULL);
-               for (i = 0; i < ARRAY_SIZE(data_sources); i++)
-                       if (!strcmp(tmp_str, data_sources[i])) {
-                               devc->data_source = i;
-                               break;
-                       }
-               if (i == ARRAY_SIZE(data_sources))
-                       return SR_ERR;
+       case SR_CONF_DATA_SOURCE:
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(data_sources))) < 0)
+                       return SR_ERR_ARG;
+               devc->data_source = idx;
                break;
-       }
        default:
                return SR_ERR_NA;
        }
index 6079f9834f1c92d3b81b15d25b08829bc83e68dc..b87d230df0684cf690e6467aa0e0d026b090e50e 100644 (file)
@@ -234,21 +234,6 @@ static int config_get(uint32_t key, GVariant **data,
        return SR_OK;
 }
 
-static int find_str(const char *str, const char **strings, int array_size)
-{
-       int idx, i;
-
-       idx = -1;
-       for (i = 0; i < array_size; i++) {
-               if (!strcmp(str, strings[i])) {
-                       idx = i;
-                       break;
-               }
-       }
-
-       return idx;
-}
-
 static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
@@ -256,7 +241,6 @@ static int config_set(uint32_t key, GVariant *data,
        struct sr_channel *ch;
        gdouble dval;
        int channel, ret, ival;
-       const char *sval;
        gboolean bval;
 
        ret = SR_OK;
@@ -264,11 +248,8 @@ static int config_set(uint32_t key, GVariant *data,
        if (!cg) {
                switch (key) {
                case SR_CONF_CHANNEL_CONFIG:
-                       sval = g_variant_get_string(data, NULL);
-                       if ((ival = find_str(sval, ARRAY_AND_SIZE(channel_modes))) == -1) {
-                               ret = SR_ERR_ARG;
-                               break;
-                       }
+                       if ((ival = std_str_idx(data, ARRAY_AND_SIZE(channel_modes))) < 0)
+                               return SR_ERR_ARG;
                        if (devc->model->channel_modes && (1 << ival) == 0) {
                                /* Not supported on this model. */
                                ret = SR_ERR_ARG;
index a4d4c091e7bd7a7ddf13502d4b427aa2faebe735..1976bd4f1917efd582153395c31472404e9fe957 100644 (file)
@@ -197,10 +197,8 @@ static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
        struct dev_context *devc;
-       uint64_t tmp_u64, low, high;
-       unsigned int i;
-       int tmp, ret;
-       const char *tmp_str;
+       uint64_t tmp_u64;
+       int tmp, ret, idx;
 
        (void)cg;
 
@@ -217,27 +215,15 @@ static int config_set(uint32_t key, GVariant *data,
                ret = cem_dt_885x_recording_set(sdi, g_variant_get_boolean(data));
                break;
        case SR_CONF_SPL_WEIGHT_FREQ:
-               tmp_str = g_variant_get_string(data, NULL);
-               if (!strcmp(tmp_str, "A"))
-                       ret = cem_dt_885x_weight_freq_set(sdi,
-                                       SR_MQFLAG_SPL_FREQ_WEIGHT_A);
-               else if (!strcmp(tmp_str, "C"))
-                       ret = cem_dt_885x_weight_freq_set(sdi,
-                                       SR_MQFLAG_SPL_FREQ_WEIGHT_C);
-               else
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(weight_freq))) < 0)
                        return SR_ERR_ARG;
-               break;
+               return cem_dt_885x_weight_freq_set(sdi, (weight_freq[idx][0] == 'A') ?
+                       SR_MQFLAG_SPL_FREQ_WEIGHT_A : SR_MQFLAG_SPL_FREQ_WEIGHT_C);
        case SR_CONF_SPL_WEIGHT_TIME:
-               tmp_str = g_variant_get_string(data, NULL);
-               if (!strcmp(tmp_str, "F"))
-                       ret = cem_dt_885x_weight_time_set(sdi,
-                                       SR_MQFLAG_SPL_TIME_WEIGHT_F);
-               else if (!strcmp(tmp_str, "S"))
-                       ret = cem_dt_885x_weight_time_set(sdi,
-                                       SR_MQFLAG_SPL_TIME_WEIGHT_S);
-               else
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(weight_time))) < 0)
                        return SR_ERR_ARG;
-               break;
+               return cem_dt_885x_weight_time_set(sdi, (weight_time[idx][0] == 'F') ?
+                       SR_MQFLAG_SPL_TIME_WEIGHT_F : SR_MQFLAG_SPL_TIME_WEIGHT_S);
        case SR_CONF_HOLD_MAX:
                tmp = g_variant_get_boolean(data) ? SR_MQFLAG_MAX : 0;
                ret = cem_dt_885x_holdmode_set(sdi, tmp);
@@ -247,28 +233,18 @@ static int config_set(uint32_t key, GVariant *data,
                ret = cem_dt_885x_holdmode_set(sdi, tmp);
                break;
        case SR_CONF_SPL_MEASUREMENT_RANGE:
-               g_variant_get(data, "(tt)", &low, &high);
-               ret = SR_ERR_ARG;
-               for (i = 0; i < ARRAY_SIZE(meas_ranges); i++) {
-                       if (meas_ranges[i][0] == low && meas_ranges[i][1] == high) {
-                               ret = cem_dt_885x_meas_range_set(sdi, low, high);
-                               break;
-                       }
-               }
-               break;
+               if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(meas_ranges))) < 0)
+                       return SR_ERR_ARG;
+               return cem_dt_885x_meas_range_set(sdi, meas_ranges[idx][0], meas_ranges[idx][1]);
        case SR_CONF_POWER_OFF:
                if (g_variant_get_boolean(data))
                        ret = cem_dt_885x_power_off(sdi);
                break;
        case SR_CONF_DATA_SOURCE:
-               tmp_str = g_variant_get_string(data, NULL);
-               if (!strcmp(tmp_str, "Live"))
-                       devc->cur_data_source = DATA_SOURCE_LIVE;
-               else if (!strcmp(tmp_str, "Memory"))
-                       devc->cur_data_source = DATA_SOURCE_MEMORY;
-               else
-                       return SR_ERR;
-               devc->enable_data_source_memory = devc->cur_data_source == DATA_SOURCE_MEMORY;
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(data_sources))) < 0)
+                       return SR_ERR_ARG;
+               devc->cur_data_source = idx;
+               devc->enable_data_source_memory = (idx == DATA_SOURCE_MEMORY);
                break;
        default:
                ret = SR_ERR_NA;
index e3fa63b54a2f69042b72332daf1d5ce06b6b1356..5c1543cb1113229ff7849eaa8d4b1352ef9dff70 100644 (file)
@@ -265,8 +265,6 @@ static int config_set(uint32_t key, GVariant *data,
        struct sr_channel *ch;
        GSList *l;
        int logic_pattern, analog_pattern;
-       unsigned int i;
-       const char *stropt;
 
        devc = sdi->priv;
 
@@ -293,21 +291,9 @@ static int config_set(uint32_t key, GVariant *data,
        case SR_CONF_PATTERN_MODE:
                if (!cg)
                        return SR_ERR_CHANNEL_GROUP;
-               stropt = g_variant_get_string(data, NULL);
-               logic_pattern = analog_pattern = -1;
-               for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
-                       if (!strcmp(stropt, logic_pattern_str[i])) {
-                               logic_pattern = i;
-                               break;
-                       }
-               }
-               for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
-                       if (!strcmp(stropt, analog_pattern_str[i])) {
-                               analog_pattern = i;
-                               break;
-                       }
-               }
-               if (logic_pattern == -1 && analog_pattern == -1)
+               logic_pattern = std_str_idx(data, ARRAY_AND_SIZE(logic_pattern_str));
+               analog_pattern = std_str_idx(data, ARRAY_AND_SIZE(analog_pattern_str));
+               if (logic_pattern < 0 && analog_pattern < 0)
                        return SR_ERR_ARG;
                for (l = cg->channels; l; l = l->next) {
                        ch = l->data;
index 04cc99b9ea815a69125650ee98217d8b3741679c..83090f2d147a0823ac4520ad5d016a00a2fa66ca 100644 (file)
@@ -67,7 +67,7 @@ static const uint32_t devopts[] = {
        SR_CONF_CLOCK_EDGE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
 };
 
-static const char *const signal_edge_names[] = {
+static const char *signal_edge_names[] = {
        [DS_EDGE_RISING] = "rising",
        [DS_EDGE_FALLING] = "falling",
 };
@@ -380,7 +380,7 @@ static int config_get(uint32_t key, GVariant **data,
 {
        struct dev_context *devc;
        struct sr_usb_dev_inst *usb;
-       unsigned int i, voltage_range;
+       int idx;
 
        (void)cg;
 
@@ -402,15 +402,11 @@ static int config_get(uint32_t key, GVariant **data,
                break;
        case SR_CONF_VOLTAGE_THRESHOLD:
                if (!strcmp(devc->profile->model, "DSLogic")) {
-                       voltage_range = 0;
-
-                       for (i = 0; i < ARRAY_SIZE(voltage_thresholds); i++)
-                               if (voltage_thresholds[i][0] == devc->cur_threshold) {
-                                       voltage_range = i;
-                                       break;
-                               }
-                       *data = std_gvar_tuple_double(voltage_thresholds[voltage_range][0],
-                                       voltage_thresholds[voltage_range][1]);
+                       if ((idx = std_double_tuple_idx_d0(devc->cur_threshold,
+                                       ARRAY_AND_SIZE(voltage_thresholds))) < 0)
+                               return SR_ERR_BUG;
+                       *data = std_gvar_tuple_double(voltage_thresholds[idx][0],
+                                       voltage_thresholds[idx][1]);
                } else {
                        *data = std_gvar_tuple_double(devc->cur_threshold, devc->cur_threshold);
                }
@@ -431,8 +427,8 @@ static int config_get(uint32_t key, GVariant **data,
                *data = g_variant_new_boolean(devc->continuous_mode);
                break;
        case SR_CONF_CLOCK_EDGE:
-               i = devc->clock_edge;
-               if (i >= ARRAY_SIZE(signal_edge_names))
+               idx = devc->clock_edge;
+               if (idx >= (int)ARRAY_SIZE(signal_edge_names))
                        return SR_ERR_BUG;
                *data = g_variant_new_string(signal_edge_names[0]);
                break;
@@ -443,34 +439,11 @@ static int config_get(uint32_t key, GVariant **data,
        return SR_OK;
 }
 
-/*
- * Helper for mapping a string-typed configuration value to an index
- * within a table of possible values.
- */
-static int lookup_index(GVariant *value, const char *const *table, int len)
-{
-       const char *entry;
-       int i;
-
-       entry = g_variant_get_string(value, NULL);
-       if (!entry)
-               return -1;
-
-       /* Linear search is fine for very small tables. */
-       for (i = 0; i < len; i++) {
-               if (strcmp(entry, table[i]) == 0)
-                       return i;
-       }
-
-       return -1;
-}
-
 static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
        struct dev_context *devc;
-       uint64_t arg;
-       int i, ret;
+       int idx, ret;
        gdouble low, high;
 
        (void)cg;
@@ -484,15 +457,9 @@ static int config_set(uint32_t key, GVariant *data,
 
        switch (key) {
        case SR_CONF_SAMPLERATE:
-               arg = g_variant_get_uint64(data);
-               for (i = 0; i < devc->num_samplerates; i++) {
-                       if (devc->samplerates[i] == arg) {
-                               devc->cur_samplerate = arg;
-                               break;
-                       }
-               }
-               if (i == devc->num_samplerates)
-                       ret = SR_ERR_ARG;
+               if ((idx = std_u64_idx(data, devc->samplerates, devc->num_samplerates)) < 0)
+                       return SR_ERR_ARG;
+               devc->cur_samplerate = devc->samplerates[idx];
                break;
        case SR_CONF_LIMIT_SAMPLES:
                devc->limit_samples = g_variant_get_uint64(data);
@@ -502,18 +469,13 @@ static int config_set(uint32_t key, GVariant *data,
                ret = (devc->capture_ratio > 100) ? SR_ERR : SR_OK;
                break;
        case SR_CONF_VOLTAGE_THRESHOLD:
-               g_variant_get(data, "(dd)", &low, &high);
                if (!strcmp(devc->profile->model, "DSLogic")) {
-                       for (i = 0; (unsigned int)i < ARRAY_SIZE(voltage_thresholds); i++) {
-                               if (fabs(voltage_thresholds[i][0] - low) < 0.1 &&
-                                   fabs(voltage_thresholds[i][1] - high) < 0.1) {
-                                       devc->cur_threshold =
-                                               voltage_thresholds[i][0];
-                                       break;
-                               }
-                       }
+                       if ((idx = std_double_tuple_idx(data, ARRAY_AND_SIZE(voltage_thresholds))) < 0)
+                               return SR_ERR_ARG;
+                       devc->cur_threshold = voltage_thresholds[idx][0];
                        ret = dslogic_fpga_firmware_upload(sdi);
                } else {
+                       g_variant_get(data, "(dd)", &low, &high);
                        ret = dslogic_set_voltage_threshold(sdi, (low + high) / 2.0);
                }
                break;
@@ -524,10 +486,9 @@ static int config_set(uint32_t key, GVariant *data,
                devc->continuous_mode = g_variant_get_boolean(data);
                break;
        case SR_CONF_CLOCK_EDGE:
-               i = lookup_index(data, ARRAY_AND_SIZE(signal_edge_names));
-               if (i < 0)
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(signal_edge_names))) < 0)
                        return SR_ERR_ARG;
-               devc->clock_edge = i;
+               devc->clock_edge = idx;
                break;
        default:
                ret = SR_ERR_NA;
index 28b82de937a5cd966477c47dfd586416d08e269e..adcc246ac41ebe535c70c4c22a749635885975b5 100644 (file)
@@ -488,8 +488,7 @@ static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
        struct dev_context *devc;
-       uint64_t arg;
-       int i, ret;
+       int idx, ret;
 
        (void)cg;
 
@@ -502,15 +501,9 @@ static int config_set(uint32_t key, GVariant *data,
 
        switch (key) {
        case SR_CONF_SAMPLERATE:
-               arg = g_variant_get_uint64(data);
-               for (i = 0; i < devc->num_samplerates; i++) {
-                       if (devc->samplerates[i] == arg) {
-                               devc->cur_samplerate = arg;
-                               break;
-                       }
-               }
-               if (i == devc->num_samplerates)
-                       ret = SR_ERR_ARG;
+               if ((idx = std_u64_idx(data, devc->samplerates, devc->num_samplerates)) < 0)
+                       return SR_ERR_ARG;
+               devc->cur_samplerate = devc->samplerates[idx];
                break;
        case SR_CONF_LIMIT_SAMPLES:
                devc->limit_samples = g_variant_get_uint64(data);
index 994c43e1a0fc8c6e3be81dee19c01169884e1826..f7ec7149b93cc14cbadc2de303ad797bffe0195c 100644 (file)
@@ -47,17 +47,6 @@ enum {
        CG_DIGITAL,
 };
 
-static int check_manufacturer(const char *manufacturer)
-{
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(manufacturers); i++)
-               if (!strcmp(manufacturer, manufacturers[i]))
-                       return SR_OK;
-
-       return SR_ERR;
-}
-
 static struct sr_dev_inst *hmo_probe_serial_device(struct sr_scpi_dev_inst *scpi)
 {
        struct sr_dev_inst *sdi;
@@ -73,7 +62,7 @@ static struct sr_dev_inst *hmo_probe_serial_device(struct sr_scpi_dev_inst *scpi
                goto fail;
        }
 
-       if (check_manufacturer(hw_info->manufacturer) != SR_OK)
+       if (std_str_idx_s(hw_info->manufacturer, ARRAY_AND_SIZE(manufacturers)) < 0)
                goto fail;
 
        sdi = g_malloc0(sizeof(struct sr_dev_inst));
@@ -269,14 +258,13 @@ static int config_get(uint32_t key, GVariant **data,
 static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
-       int ret, cg_type;
+       int ret, cg_type, idx;
        unsigned int i, j;
        char command[MAX_COMMAND_SIZE], float_str[30];
        struct dev_context *devc;
        const struct scope_config *model;
        struct scope_state *state;
        const char *tmp;
-       uint64_t p, q;
        double tmp_d;
        gboolean update_sample_rate;
 
@@ -316,50 +304,35 @@ static int config_set(uint32_t key, GVariant *data,
        case SR_CONF_VDIV:
                if (cg_type == CG_NONE)
                        return SR_ERR_CHANNEL_GROUP;
-
-               g_variant_get(data, "(tt)", &p, &q);
-
-               for (i = 0; i < model->num_vdivs; i++) {
-                       if (p != (*model->vdivs)[i][0] ||
-                           q != (*model->vdivs)[i][1])
+               if ((idx = std_u64_tuple_idx(data, *model->vdivs, model->num_vdivs)) < 0)
+                       return SR_ERR_ARG;
+               for (j = 1; j <= model->analog_channels; j++) {
+                       if (cg != devc->analog_groups[j - 1])
                                continue;
-                       for (j = 1; j <= model->analog_channels; j++) {
-                               if (cg != devc->analog_groups[j - 1])
-                                       continue;
-                               state->analog_channels[j - 1].vdiv = i;
-                               g_ascii_formatd(float_str, sizeof(float_str), "%E", (float) p / q);
-                               g_snprintf(command, sizeof(command),
-                                          (*model->scpi_dialect)[SCPI_CMD_SET_VERTICAL_DIV],
-                                          j, float_str);
-
-                               if (sr_scpi_send(sdi->conn, command) != SR_OK ||
-                                   sr_scpi_get_opc(sdi->conn) != SR_OK)
-                                       return SR_ERR;
-
-                               break;
-                       }
-
-                       ret = SR_OK;
+                       state->analog_channels[j - 1].vdiv = idx;
+                       g_ascii_formatd(float_str, sizeof(float_str), "%E",
+                               (float) (*model->vdivs)[idx][0] / (*model->vdivs)[idx][1]);
+                       g_snprintf(command, sizeof(command),
+                                  (*model->scpi_dialect)[SCPI_CMD_SET_VERTICAL_DIV],
+                                  j, float_str);
+                       if (sr_scpi_send(sdi->conn, command) != SR_OK ||
+                           sr_scpi_get_opc(sdi->conn) != SR_OK)
+                               return SR_ERR;
                        break;
                }
+               ret = SR_OK;
                break;
        case SR_CONF_TIMEBASE:
-               g_variant_get(data, "(tt)", &p, &q);
-
-               for (i = 0; i < model->num_timebases; i++) {
-                       if (p != (*model->timebases)[i][0] ||
-                           q != (*model->timebases)[i][1])
-                               continue;
-                       state->timebase = i;
-                       g_ascii_formatd(float_str, sizeof(float_str), "%E", (float) p / q);
-                       g_snprintf(command, sizeof(command),
-                                  (*model->scpi_dialect)[SCPI_CMD_SET_TIMEBASE],
-                                  float_str);
-
-                       ret = sr_scpi_send(sdi->conn, command);
-                       update_sample_rate = TRUE;
-                       break;
-               }
+               if ((idx = std_u64_tuple_idx(data, *model->timebases, model->num_timebases)) < 0)
+                       return SR_ERR_ARG;
+               state->timebase = idx;
+               g_ascii_formatd(float_str, sizeof(float_str), "%E",
+                       (float) (*model->timebases)[idx][0] / (*model->timebases)[idx][1]);
+               g_snprintf(command, sizeof(command),
+                          (*model->scpi_dialect)[SCPI_CMD_SET_TIMEBASE],
+                          float_str);
+               ret = sr_scpi_send(sdi->conn, command);
+               update_sample_rate = TRUE;
                break;
        case SR_CONF_HORIZ_TRIGGERPOS:
                tmp_d = g_variant_get_double(data);
index c5bb94eb9958a9a278353f13be543164c8dd2cf0..8d0d280d6ab2434e0f9ec49deeecc900715aa450 100644 (file)
@@ -390,10 +390,7 @@ static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
        struct dev_context *devc;
-       uint64_t p, q;
-       int tmp_int, ch_idx;
-       unsigned int i;
-       const char *tmp_str;
+       int ch_idx, idx;
 
        devc = sdi->priv;
        if (!cg) {
@@ -420,30 +417,16 @@ static int config_set(uint32_t key, GVariant *data,
                        return SR_ERR_ARG;
                switch (key) {
                case SR_CONF_VDIV:
-                       g_variant_get(data, "(tt)", &p, &q);
-                       tmp_int = -1;
-                       for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
-                               if (vdivs[i][0] == p && vdivs[i][1] == q) {
-                                       tmp_int = i;
-                                       break;
-                               }
-                       }
-                       if (tmp_int >= 0) {
-                               devc->voltage[ch_idx] = tmp_int;
-                               hantek_6xxx_update_vdiv(sdi);
-                       } else
+                       if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(vdivs))) < 0)
                                return SR_ERR_ARG;
+                       devc->voltage[ch_idx] = idx;
+                       hantek_6xxx_update_vdiv(sdi);
                        break;
                case SR_CONF_COUPLING:
-                       tmp_str = g_variant_get_string(data, NULL);
-                       for (i = 0; i < devc->coupling_tab_size; i++) {
-                               if (!strcmp(tmp_str, devc->coupling_vals[i])) {
-                                       devc->coupling[ch_idx] = i;
-                                       break;
-                               }
-                       }
-                       if (i == devc->coupling_tab_size)
+                       if ((idx = std_str_idx(data, devc->coupling_vals,
+                                               devc->coupling_tab_size)) < 0)
                                return SR_ERR_ARG;
+                       devc->coupling[ch_idx] = idx;
                        break;
                default:
                        return SR_ERR_NA;
index 22788e0eb6f14a8722e44c1eeda95ca4ae14fc2e..cdc4360e9a40b440099ae86e7ada37b46b63edcf 100644 (file)
@@ -475,10 +475,7 @@ static int config_set(uint32_t key, GVariant *data,
 {
        struct dev_context *devc;
        double tmp_double;
-       uint64_t tmp_u64, p, q;
-       int tmp_int, ch_idx;
-       unsigned int i;
-       const char *tmp_str;
+       int ch_idx, idx;
 
        devc = sdi->priv;
        if (!cg) {
@@ -487,10 +484,9 @@ static int config_set(uint32_t key, GVariant *data,
                        devc->limit_frames = g_variant_get_uint64(data);
                        break;
                case SR_CONF_TRIGGER_SLOPE:
-                       tmp_str = g_variant_get_string(data, NULL);
-                       if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r'))
+                       if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_slopes))) < 0)
                                return SR_ERR_ARG;
-                       devc->triggerslope = (tmp_str[0] == 'r')
+                       devc->triggerslope = (trigger_slopes[idx][0] == 'r')
                                ? SLOPE_POSITIVE : SLOPE_NEGATIVE;
                        break;
                case SR_CONF_HORIZ_TRIGGERPOS:
@@ -502,40 +498,19 @@ static int config_set(uint32_t key, GVariant *data,
                                devc->triggerposition = tmp_double;
                        break;
                case SR_CONF_BUFFERSIZE:
-                       tmp_u64 = g_variant_get_uint64(data);
-                       for (i = 0; i < NUM_BUFFER_SIZES; i++) {
-                               if (devc->profile->buffersizes[i] == tmp_u64) {
-                                       devc->framesize = tmp_u64;
-                                       break;
-                               }
-                       }
-                       if (i == NUM_BUFFER_SIZES)
+                       if ((idx = std_u64_idx(data, devc->profile->buffersizes, NUM_BUFFER_SIZES)) < 0)
                                return SR_ERR_ARG;
+                       devc->framesize = devc->profile->buffersizes[idx];
                        break;
                case SR_CONF_TIMEBASE:
-                       g_variant_get(data, "(tt)", &p, &q);
-                       tmp_int = -1;
-                       for (i = 0; i < ARRAY_SIZE(timebases); i++) {
-                               if (timebases[i][0] == p && timebases[i][1] == q) {
-                                       tmp_int = i;
-                                       break;
-                               }
-                       }
-                       if (tmp_int >= 0)
-                               devc->timebase = tmp_int;
-                       else
+                       if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(timebases))) < 0)
                                return SR_ERR_ARG;
+                       devc->timebase = idx;
                        break;
                case SR_CONF_TRIGGER_SOURCE:
-                       tmp_str = g_variant_get_string(data, NULL);
-                       for (i = 0; trigger_sources[i]; i++) {
-                               if (!strcmp(tmp_str, trigger_sources[i])) {
-                                       devc->triggersource = g_strdup(tmp_str);
-                                       break;
-                               }
-                       }
-                       if (trigger_sources[i] == 0)
+                       if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_sources))) < 0)
                                return SR_ERR_ARG;
+                       devc->triggersource = g_strdup(trigger_sources[idx]);
                        break;
                default:
                        return SR_ERR_NA;
@@ -552,29 +527,14 @@ static int config_set(uint32_t key, GVariant *data,
                        devc->filter[ch_idx] = g_variant_get_boolean(data);
                        break;
                case SR_CONF_VDIV:
-                       g_variant_get(data, "(tt)", &p, &q);
-                       tmp_int = -1;
-                       for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
-                               if (vdivs[i][0] == p && vdivs[i][1] == q) {
-                                       tmp_int = i;
-                                       break;
-                               }
-                       }
-                       if (tmp_int >= 0) {
-                               devc->voltage[ch_idx] = tmp_int;
-                       } else
+                       if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(vdivs))) < 0)
                                return SR_ERR_ARG;
+                       devc->voltage[ch_idx] = idx;
                        break;
                case SR_CONF_COUPLING:
-                       tmp_str = g_variant_get_string(data, NULL);
-                       for (i = 0; coupling[i]; i++) {
-                               if (!strcmp(tmp_str, coupling[i])) {
-                                       devc->coupling[ch_idx] = i;
-                                       break;
-                               }
-                       }
-                       if (coupling[i] == 0)
+                       if ((idx = std_str_idx(data, ARRAY_AND_SIZE(coupling))) < 0)
                                return SR_ERR_ARG;
+                       devc->coupling[ch_idx] = idx;
                        break;
                default:
                        return SR_ERR_NA;
index 3a36aeabb677553bea11faf20984f95ee39e36a0..4386053d3d2f8a4639a6c6b52446a452d73945c2 100644 (file)
@@ -283,65 +283,12 @@ static int dev_close(struct sr_dev_inst *sdi)
        return SR_OK;
 }
 
-static int find_in_array(GVariant *data, const GVariantType *type,
-                        const void *arr, int n)
-{
-       const char * const *sarr;
-       const char *s;
-       const uint64_t *u64arr;
-       const uint8_t *u8arr;
-       uint64_t u64;
-       uint8_t u8;
-       int i;
-
-       if (!g_variant_is_of_type(data, type))
-               return -1;
-
-       switch (g_variant_classify(data)) {
-       case G_VARIANT_CLASS_STRING:
-               s = g_variant_get_string(data, NULL);
-               sarr = arr;
-
-               for (i = 0; i < n; i++)
-                       if (!strcmp(s, sarr[i]))
-                               return i;
-               break;
-       case G_VARIANT_CLASS_UINT64:
-               u64 = g_variant_get_uint64(data);
-               u64arr = arr;
-
-               for (i = 0; i < n; i++)
-                       if (u64 == u64arr[i])
-                               return i;
-               break;
-       case G_VARIANT_CLASS_BYTE:
-               u8 = g_variant_get_byte(data);
-               u8arr = arr;
-
-               for (i = 0; i < n; i++)
-                       if (u8 == u8arr[i])
-                               return i;
-       default:
-               break;
-       }
-
-       return -1;
-}
-
-static int reverse_map(uint8_t u, const uint8_t *arr, int n)
-{
-       GVariant *v = g_variant_new_byte(u);
-       int i = find_in_array(v, G_VARIANT_TYPE_BYTE, arr, n);
-       g_variant_unref(v);
-       return i;
-}
-
 static int config_get(uint32_t key, GVariant **data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
        struct dev_context *devc = sdi->priv;
        struct parport *port;
-       int i, ch = -1;
+       int idx, ch = -1;
 
        if (cg) /* sr_config_get will validate cg using config_list */
                ch = ((struct sr_channel *)cg->channels->data)->index;
@@ -358,11 +305,9 @@ static int config_get(uint32_t key, GVariant **data,
                *data = g_variant_new_uint64(samplerates[devc->rate]);
                break;
        case SR_CONF_TRIGGER_SOURCE:
-               i = reverse_map(devc->cctl[0] & 0xC0, ARRAY_AND_SIZE(trigger_sources_map));
-               if (i == -1)
-                       return SR_ERR;
-               else
-                       *data = g_variant_new_string(trigger_sources[i]);
+               if ((idx = std_u8_idx_s(devc->cctl[0] & 0xC0, ARRAY_AND_SIZE(trigger_sources_map))) < 0)
+                       return SR_ERR_BUG;
+               *data = g_variant_new_string(trigger_sources[idx]);
                break;
        case SR_CONF_TRIGGER_SLOPE:
                if (devc->edge >= ARRAY_SIZE(trigger_slopes))
@@ -377,23 +322,18 @@ static int config_get(uint32_t key, GVariant **data,
                if (ch == -1) {
                        return SR_ERR_CHANNEL_GROUP;
                } else {
-                       i = reverse_map(devc->cctl[ch] & 0x33, ARRAY_AND_SIZE(vdivs_map));
-                       if (i == -1)
-                               return SR_ERR;
-                       else
-                               *data = g_variant_new("(tt)", vdivs[i][0],
-                                                     vdivs[i][1]);
+                       if ((idx = std_u8_idx_s(devc->cctl[ch] & 0x33, ARRAY_AND_SIZE(vdivs_map))) < 0)
+                               return SR_ERR_BUG;
+                       *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
                }
                break;
        case SR_CONF_COUPLING:
                if (ch == -1) {
                        return SR_ERR_CHANNEL_GROUP;
                } else {
-                       i = reverse_map(devc->cctl[ch] & 0x0C, ARRAY_AND_SIZE(coupling_map));
-                       if (i == -1)
-                               return SR_ERR;
-                       else
-                               *data = g_variant_new_string(coupling[i]);
+                       if ((idx = std_u8_idx_s(devc->cctl[ch] & 0x0C, ARRAY_AND_SIZE(coupling_map))) < 0)
+                               return SR_ERR_BUG;
+                       *data = g_variant_new_string(coupling[idx]);
                }
                break;
        case SR_CONF_PROBE_FACTOR:
@@ -413,8 +353,8 @@ static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
        struct dev_context *devc = sdi->priv;
-       int i, ch = -1;
-       uint64_t u, v;
+       int idx, ch = -1;
+       uint64_t u;
 
        if (cg) /* sr_config_set will validate cg using config_list */
                ch = ((struct sr_channel *)cg->channels->data)->index;
@@ -424,37 +364,24 @@ static int config_set(uint32_t key, GVariant *data,
                devc->frame_limit = g_variant_get_uint64(data);
                break;
        case SR_CONF_SAMPLERATE:
-               i = find_in_array(data, G_VARIANT_TYPE_UINT64,
-                                 ARRAY_AND_SIZE(samplerates));
-               if (i == -1)
+               if ((idx = std_u64_idx(data, ARRAY_AND_SIZE(samplerates))) < 0)
                        return SR_ERR_ARG;
-               else
-                       devc->rate = i;
+               devc->rate = idx;
                break;
        case SR_CONF_TRIGGER_SOURCE:
-               i = find_in_array(data, G_VARIANT_TYPE_STRING,
-                                 ARRAY_AND_SIZE(trigger_sources));
-               if (i == -1)
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_sources))) < 0)
                        return SR_ERR_ARG;
-               else
-                       devc->cctl[0] = (devc->cctl[0] & 0x3F)
-                                     | trigger_sources_map[i];
+               devc->cctl[0] = (devc->cctl[0] & 0x3F) | trigger_sources_map[idx];
                break;
        case SR_CONF_TRIGGER_SLOPE:
-               i = find_in_array(data, G_VARIANT_TYPE_STRING,
-                                 ARRAY_AND_SIZE(trigger_slopes));
-               if (i == -1)
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_slopes))) < 0)
                        return SR_ERR_ARG;
-               else
-                       devc->edge = i;
+               devc->edge = idx;
                break;
        case SR_CONF_BUFFERSIZE:
-               i = find_in_array(data, G_VARIANT_TYPE_UINT64,
-                                 ARRAY_AND_SIZE(buffersizes));
-               if (i == -1)
+               if ((idx = std_u64_idx(data, ARRAY_AND_SIZE(buffersizes))) < 0)
                        return SR_ERR_ARG;
-               else
-                       devc->last_step = i;
+               devc->last_step = idx;
                break;
        case SR_CONF_VDIV:
                if (ch == -1) {
@@ -462,28 +389,18 @@ static int config_set(uint32_t key, GVariant *data,
                } else if (!g_variant_is_of_type(data, G_VARIANT_TYPE("(tt)"))) {
                        return SR_ERR_ARG;
                } else {
-                       g_variant_get(data, "(tt)", &u, &v);
-                       for (i = 0; i < (int)ARRAY_SIZE(vdivs); i++)
-                               if (vdivs[i][0] == u && vdivs[i][1] == v)
-                                       break;
-                       if (i == ARRAY_SIZE(vdivs))
+                       if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(vdivs))) < 0)
                                return SR_ERR_ARG;
-                       else
-                               devc->cctl[ch] = (devc->cctl[ch] & 0xCC)
-                                              | vdivs_map[i];
+                       devc->cctl[ch] = (devc->cctl[ch] & 0xCC) | vdivs_map[idx];
                }
                break;
        case SR_CONF_COUPLING:
                if (ch == -1) {
                        return SR_ERR_CHANNEL_GROUP;
                } else {
-                       i = find_in_array(data, G_VARIANT_TYPE_STRING,
-                                         ARRAY_AND_SIZE(coupling));
-                       if (i == -1)
+                       if ((idx = std_str_idx(data, ARRAY_AND_SIZE(coupling))) < 0)
                                return SR_ERR_ARG;
-                       else
-                               devc->cctl[ch] = (devc->cctl[ch] & 0xF3)
-                                              | coupling_map[i];
+                       devc->cctl[ch] = (devc->cctl[ch] & 0xF3) | coupling_map[idx];
                }
                break;
        case SR_CONF_PROBE_FACTOR:
index d264b56acf21462ec343715cb8778d52dacfd0a3..15c84b65209ef948cee34e2655f3945c37d68e9f 100644 (file)
@@ -247,10 +247,7 @@ static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
        struct dev_context *devc;
-       uint64_t p, q;
-       unsigned int i;
-       int tmp;
-       const char *tmp_str;
+       int idx;
 
        (void)cg;
 
@@ -262,49 +259,29 @@ static int config_set(uint32_t key, GVariant *data,
                       devc->limit_samples);
                break;
        case SR_CONF_SAMPLE_INTERVAL:
-               g_variant_get(data, "(tt)", &p, &q);
-               for (i = 0; i < ARRAY_SIZE(kecheng_kc_330b_sample_intervals); i++) {
-                       if (kecheng_kc_330b_sample_intervals[i][0] != p || kecheng_kc_330b_sample_intervals[i][1] != q)
-                               continue;
-                       devc->sample_interval = i;
-                       devc->config_dirty = TRUE;
-                       break;
-               }
-               if (i == ARRAY_SIZE(kecheng_kc_330b_sample_intervals))
+               if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(kecheng_kc_330b_sample_intervals))) < 0)
                        return SR_ERR_ARG;
+               devc->sample_interval = idx;
+               devc->config_dirty = TRUE;
                break;
        case SR_CONF_SPL_WEIGHT_FREQ:
-               tmp_str = g_variant_get_string(data, NULL);
-               if (!strcmp(tmp_str, "A"))
-                       tmp = SR_MQFLAG_SPL_FREQ_WEIGHT_A;
-               else if (!strcmp(tmp_str, "C"))
-                       tmp = SR_MQFLAG_SPL_FREQ_WEIGHT_C;
-               else
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(weight_freq))) < 0)
                        return SR_ERR_ARG;
                devc->mqflags &= ~(SR_MQFLAG_SPL_FREQ_WEIGHT_A | SR_MQFLAG_SPL_FREQ_WEIGHT_C);
-               devc->mqflags |= tmp;
+               devc->mqflags |= (weight_freq[idx][0] == 'A') ? SR_MQFLAG_SPL_FREQ_WEIGHT_A : SR_MQFLAG_SPL_FREQ_WEIGHT_C;
                devc->config_dirty = TRUE;
                break;
        case SR_CONF_SPL_WEIGHT_TIME:
-               tmp_str = g_variant_get_string(data, NULL);
-               if (!strcmp(tmp_str, "F"))
-                       tmp = SR_MQFLAG_SPL_TIME_WEIGHT_F;
-               else if (!strcmp(tmp_str, "S"))
-                       tmp = SR_MQFLAG_SPL_TIME_WEIGHT_S;
-               else
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(weight_time))) < 0)
                        return SR_ERR_ARG;
                devc->mqflags &= ~(SR_MQFLAG_SPL_TIME_WEIGHT_F | SR_MQFLAG_SPL_TIME_WEIGHT_S);
-               devc->mqflags |= tmp;
+               devc->mqflags |= (weight_time[idx][0] == 'F') ? SR_MQFLAG_SPL_TIME_WEIGHT_F : SR_MQFLAG_SPL_TIME_WEIGHT_S;
                devc->config_dirty = TRUE;
                break;
        case SR_CONF_DATA_SOURCE:
-               tmp_str = g_variant_get_string(data, NULL);
-               if (!strcmp(tmp_str, "Live"))
-                       devc->data_source = DATA_SOURCE_LIVE;
-               else if (!strcmp(tmp_str, "Memory"))
-                       devc->data_source = DATA_SOURCE_MEMORY;
-               else
-                       return SR_ERR;
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(data_sources))) < 0)
+                       return SR_ERR_ARG;
+               devc->data_source = idx;
                devc->config_dirty = TRUE;
                break;
        default:
index fb0569311a0024811e568b1a2e15dd30bf71507d..dc6ee2bcd795645bd9b3ec9740a97d506c04c4c2 100644 (file)
@@ -52,17 +52,6 @@ static const uint32_t devopts_cg_analog[] = {
        SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
 };
 
-static int check_manufacturer(const char *manufacturer)
-{
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(manufacturers); i++)
-               if (!strcmp(manufacturer, manufacturers[i]))
-                       return SR_OK;
-
-       return SR_ERR;
-}
-
 static struct sr_dev_inst *probe_serial_device(struct sr_scpi_dev_inst *scpi)
 {
        struct sr_dev_inst *sdi;
@@ -78,7 +67,7 @@ static struct sr_dev_inst *probe_serial_device(struct sr_scpi_dev_inst *scpi)
                goto fail;
        }
 
-       if (check_manufacturer(hw_info->manufacturer) != SR_OK)
+       if (std_str_idx_s(hw_info->manufacturer, ARRAY_AND_SIZE(manufacturers)) < 0)
                goto fail;
 
        sdi = g_malloc0(sizeof(struct sr_dev_inst));
index aa9187e87c5fb71399b5f06565b55b45fb6cdfb6..76184fb2815966ea32cb36517b57ae2b5635d68c 100644 (file)
@@ -548,10 +548,8 @@ static int config_set(uint32_t key, GVariant *data,
        struct sr_channel *ch;
        gdouble dval;
        int ch_idx;
-       const char *sval;
        gboolean bval;
        int idx;
-       gboolean found;
 
        devc = sdi->priv;
 
@@ -566,22 +564,15 @@ static int config_set(uint32_t key, GVariant *data,
                case SR_CONF_LIMIT_SAMPLES:
                        return sr_sw_limits_config_set(&devc->limits, key, data);
                case SR_CONF_CHANNEL_CONFIG:
-                       sval = g_variant_get_string(data, NULL);
-                       found = FALSE;
-                       for (idx = 0; idx < (int)ARRAY_SIZE(channel_modes); idx++) {
-                               if (!strcmp(sval, channel_modes[idx])) {
-                                       found = TRUE;
-                                       if (devc->tracking_mode == idx)
-                                               break;  /* Nothing to do! */
-                                       devc->tracking_mode = idx;
-                                       if (devc->model->modelid >= LPS_304) /* No use to set anything in the smaller models. */
-                                               return lps_cmd_ok(sdi->conn, "TRACK%1d", devc->tracking_mode);
-                               }
-                               if (devc->model->modelid <= LPS_303) /* Only first setting possible for smaller models. */
-                                       break;
-                       }
-                       if (!found)
+                       if ((idx = std_str_idx(data, ARRAY_AND_SIZE(channel_modes))) < 0)
                                return SR_ERR_ARG;
+                       if (devc->model->modelid <= LPS_303 && idx != 0)
+                               break; /* Only first setting possible for smaller models. */
+                       if (devc->tracking_mode == idx)
+                               break;  /* Nothing to do! */
+                       devc->tracking_mode = idx;
+                       if (devc->model->modelid >= LPS_304) /* No use to set anything in the smaller models. */
+                               return lps_cmd_ok(sdi->conn, "TRACK%1d", devc->tracking_mode);
                        break;
                default:
                        return SR_ERR_NA;
index b9ff092f34282978b94695cbc73571b9c41c398f..ef6023daa1243783b85365b4b8604e5be31921de 100644 (file)
@@ -161,10 +161,8 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd
        const struct sr_channel_group *cg)
 {
        struct dev_context *devc;
-       uint64_t tmp_u64, low, high;
-       unsigned int i;
-       int ret;
-       const char *tmp_str;
+       uint64_t tmp_u64;
+       int ret, idx;
 
        (void)cg;
 
@@ -178,49 +176,30 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd
                ret = SR_OK;
                break;
        case SR_CONF_SPL_WEIGHT_FREQ:
-               tmp_str = g_variant_get_string(data, NULL);
-               if (!strcmp(tmp_str, "A"))
-                       ret = pce_322a_weight_freq_set(sdi,
-                                       SR_MQFLAG_SPL_FREQ_WEIGHT_A);
-               else if (!strcmp(tmp_str, "C"))
-                       ret = pce_322a_weight_freq_set(sdi,
-                                       SR_MQFLAG_SPL_FREQ_WEIGHT_C);
-               else
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(weight_freq))) < 0)
                        return SR_ERR_ARG;
+               ret = pce_322a_weight_freq_set(sdi, (weight_freq[idx][0] == 'A') ?
+                       SR_MQFLAG_SPL_FREQ_WEIGHT_A : SR_MQFLAG_SPL_FREQ_WEIGHT_C);
                break;
        case SR_CONF_SPL_WEIGHT_TIME:
-               tmp_str = g_variant_get_string(data, NULL);
-               if (!strcmp(tmp_str, "F"))
-                       ret = pce_322a_weight_time_set(sdi,
-                                       SR_MQFLAG_SPL_TIME_WEIGHT_F);
-               else if (!strcmp(tmp_str, "S"))
-                       ret = pce_322a_weight_time_set(sdi,
-                                       SR_MQFLAG_SPL_TIME_WEIGHT_S);
-               else
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(weight_time))) < 0)
                        return SR_ERR_ARG;
+               ret = pce_322a_weight_time_set(sdi, (weight_time[idx][0] == 'F') ?
+                       SR_MQFLAG_SPL_TIME_WEIGHT_F : SR_MQFLAG_SPL_TIME_WEIGHT_S);
                break;
        case SR_CONF_SPL_MEASUREMENT_RANGE:
-               g_variant_get(data, "(tt)", &low, &high);
-               ret = SR_ERR_ARG;
-               for (i = 0; i < ARRAY_SIZE(meas_ranges); i++) {
-                       if (meas_ranges[i][0] == low && meas_ranges[i][1] == high) {
-                               ret = pce_322a_meas_range_set(sdi, low, high);
-                               break;
-                       }
-               }
+               if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(meas_ranges))) < 0)
+                       return SR_ERR_ARG;
+               ret = pce_322a_meas_range_set(sdi, meas_ranges[idx][0], meas_ranges[idx][1]);
                break;
        case SR_CONF_POWER_OFF:
                if (g_variant_get_boolean(data))
                        ret = pce_322a_power_off(sdi);
                break;
        case SR_CONF_DATA_SOURCE:
-               tmp_str = g_variant_get_string(data, NULL);
-               if (!strcmp(tmp_str, "Live"))
-                       devc->cur_data_source = DATA_SOURCE_LIVE;
-               else if (!strcmp(tmp_str, "Memory"))
-                       devc->cur_data_source = DATA_SOURCE_MEMORY;
-               else
-                       return SR_ERR;
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(data_sources))) < 0)
+                       return SR_ERR_ARG;
+               devc->cur_data_source = idx;
                break;
        default:
                ret = SR_ERR_NA;
index bdbdbc0e7e75e840a97e314ebbd7b438cf5433f9..367474d87915465208408e520974eb74ef862e5a 100644 (file)
@@ -617,10 +617,10 @@ static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
        struct dev_context *devc;
-       uint64_t p, q;
+       uint64_t p;
        double t_dbl;
-       unsigned int i, j;
-       int ret;
+       unsigned int i;
+       int ret, idx;
        const char *tmp_str;
        char buffer[16];
 
@@ -638,16 +638,10 @@ static int config_set(uint32_t key, GVariant *data,
                devc->limit_frames = g_variant_get_uint64(data);
                break;
        case SR_CONF_TRIGGER_SLOPE:
-               tmp_str = g_variant_get_string(data, NULL);
-
-               if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r')) {
-                       sr_err("Unknown trigger slope: '%s'.",
-                              (tmp_str) ? tmp_str : "NULL");
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_slopes))) < 0)
                        return SR_ERR_ARG;
-               }
-
                g_free(devc->trigger_slope);
-               devc->trigger_slope = g_strdup((tmp_str[0] == 'r') ? "POS" : "NEG");
+               devc->trigger_slope = g_strdup((trigger_slopes[idx][0] == 'r') ? "POS" : "NEG");
                ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
                break;
        case SR_CONF_HORIZ_TRIGGERPOS:
@@ -671,86 +665,60 @@ static int config_set(uint32_t key, GVariant *data,
                        devc->trigger_level = t_dbl;
                break;
        case SR_CONF_TIMEBASE:
-               g_variant_get(data, "(tt)", &p, &q);
-               for (i = 0; i < devc->num_timebases; i++) {
-                       if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
-                               devc->timebase = (float)p / q;
-                               g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
-                                               devc->timebase);
-                               ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
-                               break;
-                       }
-               }
-               if (i == devc->num_timebases) {
-                       sr_err("Invalid timebase index: %d.", i);
-                       ret = SR_ERR_ARG;
-               }
+               if ((idx = std_u64_tuple_idx(data, devc->timebases, devc->num_timebases)) < 0)
+                       return SR_ERR_ARG;
+               devc->timebase = (float)devc->timebases[idx][0] / devc->timebases[idx][1];
+               g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
+                               devc->timebase);
+               ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
                break;
        case SR_CONF_TRIGGER_SOURCE:
-               tmp_str = g_variant_get_string(data, NULL);
-               for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
-                       if (!strcmp(trigger_sources[i], tmp_str)) {
-                               g_free(devc->trigger_source);
-                               devc->trigger_source = g_strdup(trigger_sources[i]);
-                               if (!strcmp(devc->trigger_source, "AC Line"))
-                                       tmp_str = "ACL";
-                               else if (!strcmp(devc->trigger_source, "CH1"))
-                                       tmp_str = "CHAN1";
-                               else if (!strcmp(devc->trigger_source, "CH2"))
-                                       tmp_str = "CHAN2";
-                               else if (!strcmp(devc->trigger_source, "CH3"))
-                                       tmp_str = "CHAN3";
-                               else if (!strcmp(devc->trigger_source, "CH4"))
-                                       tmp_str = "CHAN4";
-                               else
-                                       tmp_str = (char *)devc->trigger_source;
-                               ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
-                               break;
-                       }
-               }
-               if (i == ARRAY_SIZE(trigger_sources)) {
-                       sr_err("Invalid trigger source index: %d.", i);
-                       ret = SR_ERR_ARG;
-               }
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_sources))) < 0)
+                       return SR_ERR_ARG;
+               g_free(devc->trigger_source);
+               devc->trigger_source = g_strdup(trigger_sources[idx]);
+               if (!strcmp(devc->trigger_source, "AC Line"))
+                       tmp_str = "ACL";
+               else if (!strcmp(devc->trigger_source, "CH1"))
+                       tmp_str = "CHAN1";
+               else if (!strcmp(devc->trigger_source, "CH2"))
+                       tmp_str = "CHAN2";
+               else if (!strcmp(devc->trigger_source, "CH3"))
+                       tmp_str = "CHAN3";
+               else if (!strcmp(devc->trigger_source, "CH4"))
+                       tmp_str = "CHAN4";
+               else
+                       tmp_str = (char *)devc->trigger_source;
+               ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
                break;
        case SR_CONF_VDIV:
                if (!cg)
                        return SR_ERR_CHANNEL_GROUP;
-               g_variant_get(data, "(tt)", &p, &q);
                for (i = 0; i < devc->model->analog_channels; i++) {
-                       if (cg == devc->analog_groups[i]) {
-                               for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
-                                       if (vdivs[j][0] != p || vdivs[j][1] != q)
-                                               continue;
-                                       devc->vdiv[i] = (float)p / q;
-                                       g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
-                                                       devc->vdiv[i]);
-                                       return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
-                                                       buffer);
-                               }
-                               sr_err("Invalid vdiv index: %d.", j);
+                       if (cg != devc->analog_groups[i])
+                               continue;
+                       if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(vdivs))) < 0)
                                return SR_ERR_ARG;
-                       }
+                       devc->vdiv[i] = (float)vdivs[idx][0] / vdivs[idx][1];
+                       g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
+                                       devc->vdiv[i]);
+                       return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
+                                       buffer);
                }
                sr_dbg("Didn't set vdiv, unknown channel(group).");
                return SR_ERR_NA;
        case SR_CONF_COUPLING:
                if (!cg)
                        return SR_ERR_CHANNEL_GROUP;
-               tmp_str = g_variant_get_string(data, NULL);
                for (i = 0; i < devc->model->analog_channels; i++) {
-                       if (cg == devc->analog_groups[i]) {
-                               for (j = 0; j < ARRAY_SIZE(coupling); j++) {
-                                       if (!strcmp(tmp_str, coupling[j])) {
-                                               g_free(devc->coupling[i]);
-                                               devc->coupling[i] = g_strdup(coupling[j]);
-                                               return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
-                                                               devc->coupling[i]);
-                                       }
-                               }
-                               sr_err("Invalid coupling index: %d.", j);
+                       if (cg != devc->analog_groups[i])
+                               continue;
+                       if ((idx = std_str_idx(data, ARRAY_AND_SIZE(coupling))) < 0)
                                return SR_ERR_ARG;
-                       }
+                       g_free(devc->coupling[i]);
+                       devc->coupling[i] = g_strdup(coupling[idx]);
+                       return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
+                                       devc->coupling[i]);
                }
                sr_dbg("Didn't set coupling, unknown channel(group).");
                return SR_ERR_NA;
@@ -759,20 +727,16 @@ static int config_set(uint32_t key, GVariant *data,
                        return SR_ERR_CHANNEL_GROUP;
                p = g_variant_get_uint64(data);
                for (i = 0; i < devc->model->analog_channels; i++) {
-                       if (cg == devc->analog_groups[i]) {
-                               for (j = 0; j < ARRAY_SIZE(probe_factor); j++) {
-                                       if (p == probe_factor[j]) {
-                                               devc->attenuation[i] = p;
-                                               ret = rigol_ds_config_set(sdi, ":CHAN%d:PROB %"PRIu64,
-                                                                         i + 1, p);
-                                               if (ret == SR_OK)
-                                                       rigol_ds_get_dev_cfg_vertical(sdi);
-                                               return ret;
-                                       }
-                               }
-                               sr_err("Invalid probe factor: %"PRIu64".", p);
+                       if (cg != devc->analog_groups[i])
+                               continue;
+                       if ((idx = std_u64_idx(data, ARRAY_AND_SIZE(probe_factor))) < 0)
                                return SR_ERR_ARG;
-                       }
+                       devc->attenuation[i] = probe_factor[idx];
+                       ret = rigol_ds_config_set(sdi, ":CHAN%d:PROB %"PRIu64,
+                                                 i + 1, p);
+                       if (ret == SR_OK)
+                               rigol_ds_get_dev_cfg_vertical(sdi);
+                       return ret;
                }
                sr_dbg("Didn't set probe factor, unknown channel(group).");
                return SR_ERR_NA;
index 6ca0f594bd9923bfb55f56d58ada1555bf7be6d8..e66d845b9f6d41189fa4dddbaed8bcd517cba7b9 100644 (file)
@@ -457,9 +457,7 @@ static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
        struct dev_context *devc;
-       gdouble low, high;
-       int ret;
-       unsigned int i;
+       int ret, idx;
 
        (void)cg;
 
@@ -478,17 +476,9 @@ static int config_set(uint32_t key, GVariant *data,
                ret = (devc->capture_ratio > 100) ? SR_ERR : SR_OK;
                break;
        case SR_CONF_VOLTAGE_THRESHOLD:
-               g_variant_get(data, "(dd)", &low, &high);
-               ret = SR_ERR_ARG;
-               for (i = 0; i < ARRAY_SIZE(volt_thresholds); i++) {
-                       if (fabs(volt_thresholds[i][0] - low) < 0.1 &&
-                           fabs(volt_thresholds[i][1] - high) < 0.1) {
-                               devc->selected_voltage_range =
-                                       volt_thresholds_ranges[i].range;
-                               ret = SR_OK;
-                               break;
-                       }
-               }
+               if ((idx = std_double_tuple_idx(data, ARRAY_AND_SIZE(volt_thresholds))) < 0)
+                       return SR_ERR_ARG;
+               devc->selected_voltage_range = volt_thresholds_ranges[idx].range;
                break;
        default:
                ret = SR_ERR_NA;
index d0eb82caec8babc61bf6fd4569370e9408153f16..6055b83d4da6b6a46a65218c82918e7e75c6df43 100644 (file)
@@ -41,12 +41,12 @@ static const int32_t trigger_matches[] = {
        SR_TRIGGER_FALLING,
 };
 
-static const char *const trigger_source_names[] = {
+static const char *trigger_source_names[] = {
        [TRIGGER_CHANNELS] = "CH",
        [TRIGGER_EXT_TRG] = "TRG",
 };
 
-static const char *const signal_edge_names[] = {
+static const char *signal_edge_names[] = {
        [EDGE_POSITIVE] = "r",
        [EDGE_NEGATIVE] = "f",
 };
@@ -382,27 +382,6 @@ static int config_get(uint32_t key, GVariant **data,
        return SR_OK;
 }
 
-/* Helper for mapping a string-typed configuration value to an index
- * within a table of possible values.
- */
-static int lookup_index(GVariant *value, const char *const *table, int len)
-{
-       const char *entry;
-       int i;
-
-       entry = g_variant_get_string(value, NULL);
-       if (!entry)
-               return -1;
-
-       /* Linear search is fine for very small tables. */
-       for (i = 0; i < len; i++) {
-               if (strcmp(entry, table[i]) == 0)
-                       return i;
-       }
-
-       return -1;
-}
-
 static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
@@ -448,20 +427,17 @@ static int config_set(uint32_t key, GVariant *data,
                        ? CLOCK_EXT_CLK : CLOCK_INTERNAL;
                break;
        case SR_CONF_CLOCK_EDGE:
-               idx = lookup_index(data, ARRAY_AND_SIZE(signal_edge_names));
-               if (idx < 0)
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(signal_edge_names))) < 0)
                        return SR_ERR_ARG;
                devc->cfg_clock_edge = idx;
                break;
        case SR_CONF_TRIGGER_SOURCE:
-               idx = lookup_index(data, ARRAY_AND_SIZE(trigger_source_names));
-               if (idx < 0)
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_source_names))) < 0)
                        return SR_ERR_ARG;
                devc->cfg_trigger_source = idx;
                break;
        case SR_CONF_TRIGGER_SLOPE:
-               idx = lookup_index(data, ARRAY_AND_SIZE(signal_edge_names));
-               if (idx < 0)
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(signal_edge_names))) < 0)
                        return SR_ERR_ARG;
                devc->cfg_trigger_slope = idx;
                break;
index d9eff157aa88c8c81f2f327ef3809ae28da54b74..8c11497582c480057600c16f48f741bdb95901d4 100644 (file)
@@ -178,7 +178,7 @@ static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
        struct dev_context *devc;
-       const char *tmp_str;
+       int idx;
 
        (void)cg;
 
@@ -189,13 +189,9 @@ static int config_set(uint32_t key, GVariant *data,
                devc->limit_samples = g_variant_get_uint64(data);
                break;
        case SR_CONF_DATA_SOURCE:
-               tmp_str = g_variant_get_string(data, NULL);
-               if (!strcmp(tmp_str, "Live"))
-                       devc->data_source = DATA_SOURCE_LIVE;
-               else if (!strcmp(tmp_str, "Memory"))
-                       devc->data_source = DATA_SOURCE_MEMORY;
-               else
-                       return SR_ERR;
+               if ((idx = std_str_idx(data, ARRAY_AND_SIZE(data_sources))) < 0)
+                       return SR_ERR_ARG;
+               devc->data_source = idx;
                break;
        default:
                return SR_ERR_NA;
index b6c468e3e32ae811463cb6cae1674c6fa9671a03..21b7e40a06f4bba765778f9028f3941706c15ee2 100644 (file)
@@ -282,14 +282,13 @@ static int config_get(uint32_t key, GVariant **data,
 static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
-       int ret, cg_type;
+       int ret, cg_type, idx;
        unsigned int i, j;
        char float_str[30];
        struct dev_context *devc;
        const struct scope_config *model;
        struct scope_state *state;
        const char *tmp;
-       uint64_t p, q;
        double tmp_d;
        gboolean update_sample_rate;
 
@@ -324,44 +323,29 @@ static int config_set(uint32_t key, GVariant *data,
        case SR_CONF_VDIV:
                if (cg_type == CG_NONE)
                        return SR_ERR_CHANNEL_GROUP;
-
-               g_variant_get(data, "(tt)", &p, &q);
-
-               for (i = 0; i < ARRAY_SIZE(dlm_vdivs); i++) {
-                       if (p != dlm_vdivs[i][0] ||
-                                       q != dlm_vdivs[i][1])
+               if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(dlm_vdivs))) < 0)
+                       return SR_ERR_ARG;
+               for (j = 1; j <= model->analog_channels; j++) {
+                       if (cg != devc->analog_groups[j - 1])
                                continue;
-                       for (j = 1; j <= model->analog_channels; j++) {
-                               if (cg != devc->analog_groups[j - 1])
-                                       continue;
-                               state->analog_states[j - 1].vdiv = i;
-                               g_ascii_formatd(float_str, sizeof(float_str),
-                                               "%E", (float) p / q);
-                               if (dlm_analog_chan_vdiv_set(sdi->conn, j, float_str) != SR_OK ||
-                                               sr_scpi_get_opc(sdi->conn) != SR_OK)
-                                       return SR_ERR;
-
-                               break;
-                       }
-
-                       ret = SR_OK;
+                       state->analog_states[j - 1].vdiv = idx;
+                       g_ascii_formatd(float_str, sizeof(float_str),
+                                       "%E", (float) dlm_vdivs[idx][0] / dlm_vdivs[idx][1]);
+                       if (dlm_analog_chan_vdiv_set(sdi->conn, j, float_str) != SR_OK ||
+                                       sr_scpi_get_opc(sdi->conn) != SR_OK)
+                               return SR_ERR;
                        break;
                }
+               ret = SR_OK;
                break;
        case SR_CONF_TIMEBASE:
-               g_variant_get(data, "(tt)", &p, &q);
-
-               for (i = 0; i < ARRAY_SIZE(dlm_timebases); i++) {
-                       if (p != dlm_timebases[i][0] ||
-                                       q != dlm_timebases[i][1])
-                               continue;
-                       state->timebase = i;
-                       g_ascii_formatd(float_str, sizeof(float_str),
-                                       "%E", (float) p / q);
-                       ret = dlm_timebase_set(sdi->conn, float_str);
-                       update_sample_rate = TRUE;
-                       break;
-               }
+               if ((idx = std_u64_tuple_idx(data, ARRAY_AND_SIZE(dlm_timebases))) < 0)
+                       return SR_ERR_ARG;
+               state->timebase = idx;
+               g_ascii_formatd(float_str, sizeof(float_str),
+                               "%E", (float) dlm_timebases[idx][0] / dlm_timebases[idx][1]);
+               ret = dlm_timebase_set(sdi->conn, float_str);
+               update_sample_rate = TRUE;
                break;
        case SR_CONF_HORIZ_TRIGGERPOS:
                tmp_d = g_variant_get_double(data);
index 65df3f261d378d6db8c62fad73aaac7fc1261316..94056317eb12a236a1b8efea7f547bdef7adb88b 100644 (file)
@@ -973,6 +973,17 @@ SR_PRIV GVariant *std_gvar_array_u64(const uint64_t *a, unsigned int n);
 
 SR_PRIV GVariant *std_gvar_thresholds(const double a[][2], unsigned int n);
 
+SR_PRIV int std_str_idx(GVariant *data, const char *a[], unsigned int n);
+SR_PRIV int std_u64_idx(GVariant *data, const uint64_t a[], unsigned int n);
+SR_PRIV int std_u8_idx(GVariant *data, const uint8_t a[], unsigned int n);
+
+SR_PRIV int std_str_idx_s(const char *s, const char *a[], unsigned int n);
+SR_PRIV int std_u8_idx_s(uint8_t b, const uint8_t a[], unsigned int n);
+
+SR_PRIV int std_u64_tuple_idx(GVariant *data, const uint64_t a[][2], unsigned int n);
+SR_PRIV int std_double_tuple_idx(GVariant *data, const double a[][2], unsigned int n);
+SR_PRIV int std_double_tuple_idx_d0(const double d, const double a[][2], unsigned int n);
+
 /*--- resource.c ------------------------------------------------------------*/
 
 SR_PRIV int64_t sr_file_get_size(FILE *file);
index fbcad8a9d65e74ec3318f8c2d7847e2b67bdc14e..7add7dd9c1ebdcebd6dfd9acea89f65f18430afa 100644 (file)
--- a/src/std.c
+++ b/src/std.c
@@ -26,6 +26,8 @@
  */
 
 #include <config.h>
+#include <string.h>
+#include <math.h>
 #include <glib.h>
 #include <libsigrok/libsigrok.h>
 #include "libsigrok-internal.h"
@@ -702,3 +704,127 @@ SR_PRIV GVariant *std_gvar_thresholds(const double a[][2], unsigned int n)
 
        return g_variant_builder_end(&gvb);
 }
+
+/* Return the index of 'data' in the array 'arr' (or -1). */
+static int find_in_array(GVariant *data, const GVariantType *type,
+                        const void *arr, unsigned int n)
+{
+       const char * const *sarr;
+       const char *s;
+       const uint64_t *u64arr;
+       const uint8_t *u8arr;
+       uint64_t u64;
+       uint8_t u8;
+       unsigned int i;
+
+       if (!g_variant_is_of_type(data, type))
+               return -1;
+
+       switch (g_variant_classify(data)) {
+       case G_VARIANT_CLASS_STRING:
+               s = g_variant_get_string(data, NULL);
+               sarr = arr;
+
+               for (i = 0; i < n; i++)
+                       if (!strcmp(s, sarr[i]))
+                               return i;
+               break;
+       case G_VARIANT_CLASS_UINT64:
+               u64 = g_variant_get_uint64(data);
+               u64arr = arr;
+
+               for (i = 0; i < n; i++)
+                       if (u64 == u64arr[i])
+                               return i;
+               break;
+       case G_VARIANT_CLASS_BYTE:
+               u8 = g_variant_get_byte(data);
+               u8arr = arr;
+
+               for (i = 0; i < n; i++)
+                       if (u8 == u8arr[i])
+                               return i;
+       default:
+               break;
+       }
+
+       return -1;
+}
+
+SR_PRIV int std_str_idx(GVariant *data, const char *a[], unsigned int n)
+{
+       return find_in_array(data, G_VARIANT_TYPE_STRING, a, n);
+}
+
+SR_PRIV int std_u64_idx(GVariant *data, const uint64_t a[], unsigned int n)
+{
+       return find_in_array(data, G_VARIANT_TYPE_UINT64, a, n);
+}
+
+SR_PRIV int std_u8_idx(GVariant *data, const uint8_t a[], unsigned int n)
+{
+       return find_in_array(data, G_VARIANT_TYPE_BYTE, a, n);
+}
+
+SR_PRIV int std_str_idx_s(const char *s, const char *a[], unsigned int n)
+{
+       int idx;
+       GVariant *data;
+
+       data = g_variant_new_string(s);
+       idx = find_in_array(data, G_VARIANT_TYPE_STRING, a, n);
+       g_variant_unref(data);
+
+       return idx;
+}
+
+SR_PRIV int std_u8_idx_s(uint8_t b, const uint8_t a[], unsigned int n)
+{
+       int idx;
+       GVariant *data;
+
+       data = g_variant_new_byte(b);
+       idx = find_in_array(data, G_VARIANT_TYPE_BYTE, a, n);
+       g_variant_unref(data);
+
+       return idx;
+}
+
+SR_PRIV int std_u64_tuple_idx(GVariant *data, const uint64_t a[][2], unsigned int n)
+{
+       unsigned int i;
+       uint64_t low, high;
+
+       g_variant_get(data, "(tt)", &low, &high);
+
+       for (i = 0; i < n; i++)
+               if (a[i][0] == low && a[i][1] == high)
+                       return i;
+
+       return -1;
+}
+
+SR_PRIV int std_double_tuple_idx(GVariant *data, const double a[][2], unsigned int n)
+{
+       unsigned int i;
+       double low, high;
+
+       g_variant_get(data, "(dd)", &low, &high);
+
+       for (i = 0; i < n; i++)
+               if ((fabs(a[i][0] - low) < 0.1) && ((fabs(a[i][1] - high) < 0.1)))
+                       return i;
+
+       return -1;
+}
+
+SR_PRIV int std_double_tuple_idx_d0(const double d, const double a[][2], unsigned int n)
+{
+       unsigned int i;
+
+       for (i = 0; i < n; i++)
+               if (d == a[i][0])
+                       return i;
+
+       return -1;
+}