From ade65d8a69a5d64d015d020080f93b6bc52a61ab Mon Sep 17 00:00:00 2001 From: "Christian W. Zuckschwerdt" Date: Wed, 1 Sep 2021 12:34:44 +0200 Subject: [PATCH] minor: Add kwargs_match helper --- include/optparse.h | 14 ++++++++++++++ src/optparse.c | 35 +++++++++++++++++++++++++++++++++++ src/output_mqtt.c | 2 +- src/rtl_433.c | 41 +++++++++++++++++++++-------------------- src/sdr.c | 2 +- 5 files changed, 72 insertions(+), 22 deletions(-) diff --git a/include/optparse.h b/include/optparse.h index aab69f2f..7ad742b4 100644 --- a/include/optparse.h +++ b/include/optparse.h @@ -124,6 +124,20 @@ char *asepc(char **stringp, char delim); /// @return the original value of *stringp char *asepcb(char **stringp, char delim, char stop); +/// Match the first key in a comma-separated list of key/value pairs. +/// +/// @param s String of key=value pairs, separated by commas +/// @param key keyword argument to match with +/// @param[out] val value if found, NULL otherwise +/// @return 1 if the key matches exactly, 0 otherwise +int kwargs_match(char const *s, char const *key, char const **val); + +/// Skip the first key/value in a comma-separated list of key/value pairs. +/// +/// @param s String of key=value pairs, separated by commas +/// @return the next key in s, end of string or NULL otherwise +char const *kwargs_skip(char const *s); + /// Parse a comma-separated list of key/value pairs into kwargs. /// /// The input string will be modified and the pointer advanced. diff --git a/src/optparse.c b/src/optparse.c index 6f75d3a3..b9f89b4b 100644 --- a/src/optparse.c +++ b/src/optparse.c @@ -323,6 +323,41 @@ char *asepcb(char **stringp, char delim, char stop) return p; } +int kwargs_match(char const *s, char const *key, char const **val) +{ + size_t len = strlen(key); + // check prefix match + if (strncmp(s, key, len)) { + return 0; // no match + } + s += len; + // skip whitespace after match + while (*s == ' ' || *s == '\t') + ++s; + if (*s == '\0' || * s == ',') { + if (val) + *val = NULL; + return 1; // match with no arg + } + if (*s == '=') { + if (val) + *val = s + 1; + return 1; // match with arg + } + return 0; // no exact match +} + +char const *kwargs_skip(char const *s) +{ + // skip to the next comma if possible + while (s && *s && *s != ',') + ++s; + // skip comma and whitespace if possible + while (s && *s && (*s == ',' || *s == ' ' || *s == '\t')) + ++s; + return s; +} + char *getkwargs(char **s, char **key, char **val) { char *v = asepc(s, ','); diff --git a/src/output_mqtt.c b/src/output_mqtt.c index cfa0942a..f3043a93 100644 --- a/src/output_mqtt.c +++ b/src/output_mqtt.c @@ -506,7 +506,7 @@ struct data_output *data_output_mqtt_create(struct mg_mgr *mgr, char *param, cha if (strncmp(param, "mqtts", 5) == 0) { tls_opts.tls_ca_cert = "*"; // TLS is enabled but no cert verification is performed. } - param = arg_param(param); + param = arg_param(param); // strip scheme char *host = "localhost"; char *port = tls_opts.tls_ca_cert ? "8883" : "1883"; char *opts = hostport_param(param, &host, &port); diff --git a/src/rtl_433.c b/src/rtl_433.c index 2a386019..a3a463ce 100644 --- a/src/rtl_433.c +++ b/src/rtl_433.c @@ -1144,37 +1144,38 @@ static void parse_conf_option(r_cfg_t *cfg, int opt, char *arg) case 'Y': if (!arg) usage(1); - char *p = arg; + char const *p = arg; while (p && *p) { - if (!strncasecmp(p, "autolevel", 9)) - cfg->demod->auto_level = atoiv(arg_param(arg), 1); // arg_float_default(p + 9, "-Y autolevel: "); - else if (!strncasecmp(p, "squelch", 7)) - cfg->demod->squelch_offset = atoiv(arg_param(arg), 1); // arg_float_default(p + 7, "-Y squelch: "); - else if (!strncmp(p, "auto", 4)) + char const *val = NULL; + if (kwargs_match(p, "autolevel", &val)) + cfg->demod->auto_level = atoiv(val, 1); // arg_float_default(p + 9, "-Y autolevel: "); + else if (kwargs_match(p, "squelch", &val)) + cfg->demod->squelch_offset = atoiv(val, 1); // arg_float_default(p + 7, "-Y squelch: "); + else if (kwargs_match(p, "auto", &val)) cfg->fsk_pulse_detect_mode = FSK_PULSE_DETECT_AUTO; - else if (!strncmp(p, "classic", 7)) + else if (kwargs_match(p, "classic", &val)) cfg->fsk_pulse_detect_mode = FSK_PULSE_DETECT_OLD; - else if (!strncmp(p, "minmax", 6)) + else if (kwargs_match(p, "minmax", &val)) cfg->fsk_pulse_detect_mode = FSK_PULSE_DETECT_NEW; - else if (!strncmp(p, "ampest", 6)) + else if (kwargs_match(p, "ampest", &val)) cfg->demod->use_mag_est = 0; - else if (!strncmp(p, "verbose", 7)) + else if (kwargs_match(p, "verbose", &val)) cfg->demod->detect_verbosity++; - else if (!strncmp(p, "magest", 6)) + else if (kwargs_match(p, "magest", &val)) cfg->demod->use_mag_est = 1; - else if (!strncasecmp(p, "level", 5)) - cfg->demod->level_limit = arg_float(p + 5, "-Y level: "); - else if (!strncasecmp(p, "minlevel", 8)) - cfg->demod->min_level = arg_float(p + 8, "-Y minlevel: "); - else if (!strncasecmp(p, "minsnr", 6)) - cfg->demod->min_snr = arg_float(p + 6, "-Y minsnr: "); - else if (!strncasecmp(p, "filter", 6)) - cfg->demod->low_pass = arg_float(p + 6, "-Y filter: "); + else if (kwargs_match(p, "level", &val)) + cfg->demod->level_limit = arg_float(val, "-Y level: "); + else if (kwargs_match(p, "minlevel", &val)) + cfg->demod->min_level = arg_float(val, "-Y minlevel: "); + else if (kwargs_match(p, "minsnr", &val)) + cfg->demod->min_snr = arg_float(val, "-Y minsnr: "); + else if (kwargs_match(p, "filter", &val)) + cfg->demod->low_pass = arg_float(val, "-Y filter: "); else { fprintf(stderr, "Unknown pulse detector setting: %s\n", p); usage(1); } - p = arg_param(p); + p = kwargs_skip(p); } break; case 'E': diff --git a/src/sdr.c b/src/sdr.c index f2d4046f..31094b36 100644 --- a/src/sdr.c +++ b/src/sdr.c @@ -167,7 +167,7 @@ static int rtltcp_open(sdr_dev_t **out_dev, char const *dev_query, int verbose) char *port = "1234"; char hostport[280]; // 253 chars DNS name plus extra chars - char *param = arg_param(dev_query); + char *param = arg_param(dev_query); // strip scheme hostport[0] = '\0'; if (param) strncpy(hostport, param, sizeof(hostport) - 1);