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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
#include "../src/simple-opt.h"
int main(int argc, char **argv)
{
const char *set[] = { "str_a", "str_b", NULL };
/* array containing all options and their types / attributes */
struct simple_opt options[] = {
{ SIMPLE_OPT_FLAG, 'h', "help", false,
"print this help message and exit" },
{ SIMPLE_OPT_BOOL, 'b', "bool", false,
"(optionally) takes a boolean arg!" },
{ SIMPLE_OPT_INT, '\0', "int", true,
"requires an integer. has no short_name!" },
{ SIMPLE_OPT_UNSIGNED, 'u', "uns", true,
"this one has a custom_arg_string. normally it would say"
" \"UNSIGNED\" rather than \"NON-NEG-INT\"",
"NON-NEG-INT" },
{ SIMPLE_OPT_DOUBLE, 'd', "double", true,
"a floating point number" },
{ SIMPLE_OPT_STRING, 's', NULL, true,
"this one doesn't have a long_name version" },
{ SIMPLE_OPT_STRING_SET, '\0', "set-choice", true,
"a choice of one string from a NULL-terminated array",
"(str_a|str_b)", set },
{ SIMPLE_OPT_END },
};
/* contains an enum for identifying simple_opt_parse's return value, an
* array of the cli arguments which were not parsed as options, and
* information relevant for error handling */
struct simple_opt_result result;
int i;
result = simple_opt_parse(argc, argv, options);
/* handle errors */
switch (result.result_type) {
case SIMPLE_OPT_RESULT_UNRECOGNISED_OPTION:
fprintf(stderr, "err: unrecognised option `%s`\n",
result.option_string);
return 1;
case SIMPLE_OPT_RESULT_BAD_ARG:
fprintf(stderr, "err: bad argument `%s` passed to option `%s`\n",
result.argument_string, result.option_string);
return 1;
case SIMPLE_OPT_RESULT_MISSING_ARG:
fprintf(stderr, "err: argument expected for option `%s`\n",
result.option_string);
return 1;
case SIMPLE_OPT_RESULT_OPT_ARG_TOO_LONG:
fprintf(stderr, "internal err: argument passed to option `%s` is too long\n",
result.option_string);
return 1;
case SIMPLE_OPT_RESULT_TOO_MANY_ARGS:
fprintf(stderr, "internal err: too many cli arguments passed\n");
return 1;
case SIMPLE_OPT_RESULT_MALFORMED_OPTION_STRUCT:
fprintf(stderr, "internal err: malformed option struct\n");
return 1;
default:
break;
}
/* if the help flag was passed, print usage */
if (options[0].was_seen) {
simple_opt_print_usage(stdout, 80, argv[0],
"[OPTION]... [--] [NON-OPTION]...",
"This is where you would put an overview description of the "
"program and its general functionality.", options);
return 0;
}
/* print a summary of options passed */
for (i = 0; options[i].type != SIMPLE_OPT_END; i++) {
if (options[i].long_name != NULL)
printf("--%s, ", options[i].long_name);
else
printf("-%c, ", options[i].short_name);
printf("seen: %s", (options[i].was_seen ? "yes" : "no"));
if (options[i].arg_is_stored) {
switch (options[i].type) {
case SIMPLE_OPT_BOOL:
printf(", val: %s", options[i].val_bool ? "true" : "false");
break;
case SIMPLE_OPT_INT:
printf(", val: %ld", options[i].val_int);
break;
case SIMPLE_OPT_UNSIGNED:
printf(", val: %lu", options[i].val_unsigned);
break;
case SIMPLE_OPT_DOUBLE:
printf(", val: %lf", options[i].val_double);
break;
case SIMPLE_OPT_CHAR:
printf(", val: %c", options[i].val_char);
break;
case SIMPLE_OPT_STRING:
printf(", val: %s", options[i].val_string);
break;
case SIMPLE_OPT_STRING_SET:
printf(", val: %s",
options[i].string_set[options[i].val_string_set_idx]);
break;
default:
break;
}
}
puts("");
}
/* if any non-option arguments were passed, print them */
if (result.argc > 0) {
printf("\nnon-options:", result.argc);
for (i = 0; i < result.argc; i++)
printf(" %s", result.argv[i]);
puts("");
}
return 0;
}
|