Skip to content

Commit cd5e4c1

Browse files
committed
treewide: deduplicate token parameter parsing
1 parent a227459 commit cd5e4c1

File tree

6 files changed

+99
-67
lines changed

6 files changed

+99
-67
lines changed

acarsdec.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,3 +561,41 @@ int main(int argc, char **argv)
561561

562562
exit(res);
563563
}
564+
565+
/**
566+
* Parse a parameter string.
567+
* Parameter string formatted like "param1=foo,param2=blah,param3=42"
568+
* @paramsp pointer to params string input
569+
* @sp pointer to struct containing expected parameters, the #valp member will be updated for each match
570+
* @np array size of #sp
571+
* @return NULL if the input has been succesfully exhausted (or was NULL), pointer to first unmatched token otherwise
572+
* @note Behavior matching that of strsep(): *paramsp is updated to point to next token group or NULL if EOL
573+
* If an unidentified parameter is found in the string, it is returned by the function, with the '=' separator restored
574+
*/
575+
char * parse_params(char **paramsp, struct params_s *sp, const int np)
576+
{
577+
char *param, *sep;
578+
int i;
579+
580+
while ((param = strsep(paramsp, ","))) {
581+
sep = strchr(param, '=');
582+
if (!sep)
583+
continue;
584+
585+
*sep++ = '\0';
586+
587+
for (i = 0; i < np; i++) {
588+
if (!strcmp(sp[i].name, param)) {
589+
*sp[i].valp = sep;
590+
break;
591+
}
592+
}
593+
594+
if (np == i) { // unknown param
595+
*--sep = '='; // restore key-value separator for external processing
596+
return param;
597+
}
598+
}
599+
600+
return NULL;
601+
}

acarsdec.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,11 @@ typedef struct {
160160

161161
extern runtime_t R;
162162

163+
struct params_s {
164+
const char *const name;
165+
char **valp;
166+
};
167+
168+
char * parse_params(char **, struct params_s *, const int);
169+
163170
#endif /* acarsdec_h */

fileout.c

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -77,22 +77,18 @@ static FILE *open_outfile(fileout_t *fout)
7777
// optional "rotate=" parameter followed by "none" (default), "hourly", "daily"
7878
fileout_t *Fileoutinit(char *params)
7979
{
80-
char *param, *sep, *path = NULL, *rotate = NULL;
80+
char *path = NULL, *rotate = NULL;
81+
struct params_s filep[] = {
82+
{ .name = "path", .valp = &path, },
83+
{ .name = "rotate", .valp = &rotate, },
84+
};
85+
char *retp;
8186
fileout_t *fout;
8287

83-
while ((param = strsep(&params, ","))) {
84-
sep = strchr(param, '=');
85-
if (!sep)
86-
continue;
87-
*sep++ = '\0';
88-
if (!strcmp("path", param))
89-
path = sep;
90-
if (!strcmp("rotate", param))
91-
rotate = sep;
92-
else {
93-
fprintf(stderr, ERRPFX "unknown parameter '%s'\n", param);
94-
return NULL;
95-
}
88+
retp = parse_params(&params, filep, ARRAY_SIZE(filep));
89+
if (retp) {
90+
fprintf(stderr, ERRPFX "unknown parameter '%s'\n", retp);
91+
return NULL;
9692
}
9793

9894
fout = calloc(1, sizeof(*fout));

mqttout.c

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,34 +35,36 @@ mqttout_t *MQTTinit(char *params)
3535
mqttout_t *mqpriv;
3636
char *urls[15] = {};
3737
char **url, *topic = NULL, *user = NULL, *passwd = NULL, *msgtopic = NULL;
38-
char *param, *sep;
38+
struct params_s mqttp[] = {
39+
{ .name = "topic", .valp = &topic, },
40+
{ .name = "user", .valp = &user, },
41+
{ .name = "passwd", .valp = &passwd, },
42+
};
43+
char *retp, *sep;
3944
int rc;
4045
MQTTAsync_createOptions create_opts = MQTTAsync_createOptions_initializer;
4146
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
4247

4348
url = urls;
44-
while ((param = strsep(&params, ","))) {
45-
sep = strchr(param, '=');
46-
if (!sep)
47-
continue;
48-
*sep++ = '\0';
49-
if (!strcmp("topic", param))
50-
topic = sep;
51-
else if (!strcmp("user", param))
52-
user = sep;
53-
else if (!strcmp("passwd", param))
54-
passwd = sep;
55-
else if (!strcmp("uri", param)) {
56-
if (url > &urls[14])
57-
fprintf(stderr, WARNPFX "too many urls provided, ignoring '%s'\n", sep);
58-
else
59-
*url++ = sep;
60-
}
61-
else {
62-
fprintf(stderr, ERRPFX "unknown parameter '%s'\n", param);
63-
return NULL;
49+
50+
do {
51+
retp = parse_params(&params, mqttp, ARRAY_SIZE(mqttp));
52+
if (retp) {
53+
sep = strchr(retp, '='); // guaranteed to exist due to parse_params()
54+
*sep++ = '\0';
55+
if (!strcmp("uri", retp)) {
56+
if (url > &urls[14])
57+
fprintf(stderr, WARNPFX "too many urls provided, ignoring '%s'\n", sep);
58+
else
59+
*url++ = sep;
60+
}
61+
else {
62+
fprintf(stderr, ERRPFX "unknown parameter '%s'\n", retp);
63+
return NULL;
64+
65+
}
6466
}
65-
}
67+
} while (retp);
6668

6769
if (!urls[0]) {
6870
fprintf(stderr, ERRPFX "no URI provided\n");

netout.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,26 +38,21 @@
3838
// params is "host=xxx,port=yyy"
3939
netout_t *Netoutinit(char *params)
4040
{
41-
char *param, *sep;
4241
char *addr = NULL;
4342
char *port = NULL;
43+
struct params_s netp[] = {
44+
{ .name = "host", .valp = &addr, },
45+
{ .name = "port", .valp = &port, },
46+
};
47+
char *retp;
4448
struct addrinfo hints, *servinfo, *p;
4549
int sockfd, rv;
4650
netout_t *netpriv = NULL;
4751

48-
while ((param = strsep(&params, ","))) {
49-
sep = strchr(param, '=');
50-
if (!sep)
51-
continue;
52-
*sep++ = '\0';
53-
if (!strcmp("host", param))
54-
addr = sep;
55-
else if (!strcmp("port", param))
56-
port = sep;
57-
else {
58-
fprintf(stderr, ERRPFX "unknown parameter '%s'\n", param);
59-
return NULL;
60-
}
52+
retp = parse_params(&params, netp, ARRAY_SIZE(netp));
53+
if (retp) {
54+
fprintf(stderr, ERRPFX "unknown parameter '%s'\n", retp);
55+
return NULL;
6156
}
6257

6358
if (!addr) {

statsd.c

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,26 +49,20 @@ static struct {
4949
*/
5050
int statsd_init(char *params, const char *idstation)
5151
{
52-
const char *host = NULL, *port = NULL;
53-
char *param, *sep;
52+
char *host = NULL, *port = NULL, *retp;
53+
struct params_s statsdp[] = {
54+
{ .name = "host", .valp = &host, },
55+
{ .name = "port", .valp = &port, },
56+
};
5457
int sockfd;
5558
struct addrinfo hints;
5659
struct addrinfo *result, *rp;
5760
int ret;
5861

59-
while ((param = strsep(&params, ","))) {
60-
sep = strchr(param, '=');
61-
if (!sep)
62-
continue;
63-
*sep++ = '\0';
64-
if (!strcmp("host", param))
65-
host = sep;
66-
else if (!strcmp("port", param))
67-
port = sep;
68-
else {
69-
fprintf(stderr, ERRPFX "unknown parameter '%s'\n", param);
70-
return -1;
71-
}
62+
retp = parse_params(&params, statsdp, ARRAY_SIZE(statsdp));
63+
if (retp) {
64+
fprintf(stderr, ERRPFX "unknown parameter '%s'\n", retp);
65+
return -1;
7266
}
7367

7468
if (!host || !port) {
@@ -111,9 +105,9 @@ int statsd_init(char *params, const char *idstation)
111105
perror("statsd");
112106
goto cleanup;
113107
}
114-
sep = stpcpy(statsd_runtime.namespace, STATSD_NAMESPACE);
108+
retp = stpcpy(statsd_runtime.namespace, STATSD_NAMESPACE);
115109
if (idstation) {
116-
strcpy(sep, idstation);
110+
strcpy(retp, idstation);
117111
statsd_runtime.namespace[ret++] = '.';
118112
statsd_runtime.namespace[ret] = '\0';
119113
}

0 commit comments

Comments
 (0)