From: Uwe Hermann Date: Tue, 25 Jul 2017 21:12:09 +0000 (+0200) Subject: drivers: Factor out std_*_idx*(). X-Git-Url: https://sigrok.org/gitweb/?p=libsigrok.git;a=commitdiff_plain;h=697fb6ddfc2522b2e6d35511c7837e2c61d8ae73 drivers: Factor out std_*_idx*(). --- diff --git a/src/hardware/agilent-dmm/api.c b/src/hardware/agilent-dmm/api.c index 2f99bb2f..293b5f84 100644 --- a/src/hardware/agilent-dmm/api.c +++ b/src/hardware/agilent-dmm/api.c @@ -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; } diff --git a/src/hardware/appa-55ii/api.c b/src/hardware/appa-55ii/api.c index c55a5fd0..ddf3fe4a 100644 --- a/src/hardware/appa-55ii/api.c +++ b/src/hardware/appa-55ii/api.c @@ -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; } diff --git a/src/hardware/atten-pps3xxx/api.c b/src/hardware/atten-pps3xxx/api.c index 6079f983..b87d230d 100644 --- a/src/hardware/atten-pps3xxx/api.c +++ b/src/hardware/atten-pps3xxx/api.c @@ -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; diff --git a/src/hardware/cem-dt-885x/api.c b/src/hardware/cem-dt-885x/api.c index a4d4c091..1976bd4f 100644 --- a/src/hardware/cem-dt-885x/api.c +++ b/src/hardware/cem-dt-885x/api.c @@ -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; diff --git a/src/hardware/demo/api.c b/src/hardware/demo/api.c index e3fa63b5..5c1543cb 100644 --- a/src/hardware/demo/api.c +++ b/src/hardware/demo/api.c @@ -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; diff --git a/src/hardware/dreamsourcelab-dslogic/api.c b/src/hardware/dreamsourcelab-dslogic/api.c index 04cc99b9..83090f2d 100644 --- a/src/hardware/dreamsourcelab-dslogic/api.c +++ b/src/hardware/dreamsourcelab-dslogic/api.c @@ -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; diff --git a/src/hardware/fx2lafw/api.c b/src/hardware/fx2lafw/api.c index 28b82de9..adcc246a 100644 --- a/src/hardware/fx2lafw/api.c +++ b/src/hardware/fx2lafw/api.c @@ -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); diff --git a/src/hardware/hameg-hmo/api.c b/src/hardware/hameg-hmo/api.c index 994c43e1..f7ec7149 100644 --- a/src/hardware/hameg-hmo/api.c +++ b/src/hardware/hameg-hmo/api.c @@ -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); diff --git a/src/hardware/hantek-6xxx/api.c b/src/hardware/hantek-6xxx/api.c index c5bb94eb..8d0d280d 100644 --- a/src/hardware/hantek-6xxx/api.c +++ b/src/hardware/hantek-6xxx/api.c @@ -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; diff --git a/src/hardware/hantek-dso/api.c b/src/hardware/hantek-dso/api.c index 22788e0e..cdc4360e 100644 --- a/src/hardware/hantek-dso/api.c +++ b/src/hardware/hantek-dso/api.c @@ -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; diff --git a/src/hardware/hung-chang-dso-2100/api.c b/src/hardware/hung-chang-dso-2100/api.c index 3a36aeab..4386053d 100644 --- a/src/hardware/hung-chang-dso-2100/api.c +++ b/src/hardware/hung-chang-dso-2100/api.c @@ -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: diff --git a/src/hardware/kecheng-kc-330b/api.c b/src/hardware/kecheng-kc-330b/api.c index d264b56a..15c84b65 100644 --- a/src/hardware/kecheng-kc-330b/api.c +++ b/src/hardware/kecheng-kc-330b/api.c @@ -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: diff --git a/src/hardware/lecroy-xstream/api.c b/src/hardware/lecroy-xstream/api.c index fb056931..dc6ee2bc 100644 --- a/src/hardware/lecroy-xstream/api.c +++ b/src/hardware/lecroy-xstream/api.c @@ -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)); diff --git a/src/hardware/motech-lps-30x/api.c b/src/hardware/motech-lps-30x/api.c index aa9187e8..76184fb2 100644 --- a/src/hardware/motech-lps-30x/api.c +++ b/src/hardware/motech-lps-30x/api.c @@ -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; diff --git a/src/hardware/pce-322a/api.c b/src/hardware/pce-322a/api.c index b9ff092f..ef6023da 100644 --- a/src/hardware/pce-322a/api.c +++ b/src/hardware/pce-322a/api.c @@ -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; diff --git a/src/hardware/rigol-ds/api.c b/src/hardware/rigol-ds/api.c index bdbdbc0e..367474d8 100644 --- a/src/hardware/rigol-ds/api.c +++ b/src/hardware/rigol-ds/api.c @@ -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; diff --git a/src/hardware/saleae-logic16/api.c b/src/hardware/saleae-logic16/api.c index 6ca0f594..e66d845b 100644 --- a/src/hardware/saleae-logic16/api.c +++ b/src/hardware/saleae-logic16/api.c @@ -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; diff --git a/src/hardware/sysclk-lwla/api.c b/src/hardware/sysclk-lwla/api.c index d0eb82ca..6055b83d 100644 --- a/src/hardware/sysclk-lwla/api.c +++ b/src/hardware/sysclk-lwla/api.c @@ -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; diff --git a/src/hardware/uni-t-ut32x/api.c b/src/hardware/uni-t-ut32x/api.c index d9eff157..8c114975 100644 --- a/src/hardware/uni-t-ut32x/api.c +++ b/src/hardware/uni-t-ut32x/api.c @@ -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; diff --git a/src/hardware/yokogawa-dlm/api.c b/src/hardware/yokogawa-dlm/api.c index b6c468e3..21b7e40a 100644 --- a/src/hardware/yokogawa-dlm/api.c +++ b/src/hardware/yokogawa-dlm/api.c @@ -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); diff --git a/src/libsigrok-internal.h b/src/libsigrok-internal.h index 65df3f26..94056317 100644 --- a/src/libsigrok-internal.h +++ b/src/libsigrok-internal.h @@ -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); diff --git a/src/std.c b/src/std.c index fbcad8a9..7add7dd9 100644 --- a/src/std.c +++ b/src/std.c @@ -26,6 +26,8 @@ */ #include +#include +#include #include #include #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; +}