cli options parser

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <string.h>

struct cmdopt {
const char * name;
int argnums;
int (*handle)(const struct cmdopt *, const char **, void *);
};

int cmdarg_parse(int argc, const char **argv, const struct cmdopt *opts, int optnums, void *data)
{
int i;
int j;
int r;
const char *arg;

for (i = 0; i < argc; i++) {
arg = argv[i];
if (arg[0] != '-') {
break;
}
for (j = 0; j < optnums; j++) {
if (strcmp(&arg[1], opts[j].name) == 0) {
break;
}
}
if (j == optnums) {
break;
}
if ((argc - i - 1) < opts[j].argnums) {
break;
}
r = opts[j].handle(&opts[j], &argv[i + 1], data);
if (r == 0) {
break;
}
i += opts[j].argnums;
}
return i;
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
static int arg_handle(const struct cmdopt *opt, const char **argv, void *data);

const struct cmdopt options[] = {
{
"h",
1,
arg_handle
},
{
"p",
1,
arg_handle
}
};

static int arg_handle(const struct cmdopt *opt, const char **argv, void *data)
{
printf("%s %s %p\n", opt->name, argv[0], data);
return opt->argnums;
}

int main(int argc, const char **argv)
{
cmdarg_parse(argc - 1, &argv[1], options, 2, NULL);
return 0;
}