Skip to content

Commit 54244d1

Browse files
committed
value: make optional value a usage flag, not a type
1 parent 98d01a0 commit 54244d1

File tree

5 files changed

+80
-70
lines changed

5 files changed

+80
-70
lines changed

adopt.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@
2929
#define spec_is_named_type(x) \
3030
((x)->type == ADOPT_TYPE_BOOL || \
3131
(x)->type == ADOPT_TYPE_SWITCH || \
32-
(x)->type == ADOPT_TYPE_VALUE || \
33-
(x)->type == ADOPT_TYPE_VALUE_OPTIONAL)
32+
(x)->type == ADOPT_TYPE_VALUE)
3433

3534
INLINE(const adopt_spec *) spec_byname(
3635
adopt_parser *parser, const char *name, size_t namelen)
@@ -140,7 +139,7 @@ static adopt_status_t parse_long(adopt_opt *opt, adopt_parser *parser)
140139
*((int *)spec->value) = spec->switch_value;
141140

142141
/* Parse values as "--foo=bar" or "--foo bar" */
143-
if (spec->type == ADOPT_TYPE_VALUE || spec->type == ADOPT_TYPE_VALUE_OPTIONAL) {
142+
if (spec->type == ADOPT_TYPE_VALUE) {
144143
if (eql && *(eql+1))
145144
opt->value = eql + 1;
146145
else if ((parser->idx + 1) <= parser->args_len)
@@ -151,7 +150,9 @@ static adopt_status_t parse_long(adopt_opt *opt, adopt_parser *parser)
151150
}
152151

153152
/* Required argument was not provided */
154-
if (spec->type == ADOPT_TYPE_VALUE && !opt->value)
153+
if (spec->type == ADOPT_TYPE_VALUE &&
154+
!opt->value &&
155+
!(spec->usage & ADOPT_USAGE_VALUE_OPTIONAL))
155156
opt->status = ADOPT_STATUS_MISSING_VALUE;
156157
else
157158
opt->status = ADOPT_STATUS_OK;
@@ -184,7 +185,7 @@ static adopt_status_t parse_short(adopt_opt *opt, adopt_parser *parser)
184185
*((int *)spec->value) = spec->switch_value;
185186

186187
/* Parse values as "-ifoo" or "-i foo" */
187-
if (spec->type == ADOPT_TYPE_VALUE || spec->type == ADOPT_TYPE_VALUE_OPTIONAL) {
188+
if (spec->type == ADOPT_TYPE_VALUE) {
188189
if (strlen(arg) > 2)
189190
opt->value = arg + 2;
190191
else if ((parser->idx + 1) <= parser->args_len)
@@ -490,14 +491,18 @@ int adopt_usage_fprint(
490491
if (error < 0)
491492
goto done;
492493

493-
if (spec->type == ADOPT_TYPE_VALUE && spec->alias && !(spec->usage & ADOPT_USAGE_SHOW_LONG))
494+
if (spec->type == ADOPT_TYPE_VALUE && spec->alias &&
495+
!(spec->usage & ADOPT_USAGE_VALUE_OPTIONAL) &&
496+
!(spec->usage & ADOPT_USAGE_SHOW_LONG))
494497
error = fprintf(file, "-%c <%s>", spec->alias, spec->value_name);
495-
else if (spec->type == ADOPT_TYPE_VALUE)
496-
error = fprintf(file, "--%s=<%s>", spec->name, spec->value_name);
497-
else if (spec->type == ADOPT_TYPE_VALUE_OPTIONAL && spec->alias)
498+
else if (spec->type == ADOPT_TYPE_VALUE && spec->alias &&
499+
!(spec->usage & ADOPT_USAGE_SHOW_LONG))
498500
error = fprintf(file, "-%c [<%s>]", spec->alias, spec->value_name);
499-
else if (spec->type == ADOPT_TYPE_VALUE_OPTIONAL)
501+
else if (spec->type == ADOPT_TYPE_VALUE &&
502+
!(spec->usage & ADOPT_USAGE_VALUE_OPTIONAL))
500503
error = fprintf(file, "--%s[=<%s>]", spec->name, spec->value_name);
504+
else if (spec->type == ADOPT_TYPE_VALUE)
505+
error = fprintf(file, "--%s=<%s>", spec->name, spec->value_name);
501506
else if (spec->type == ADOPT_TYPE_ARG)
502507
error = fprintf(file, "<%s>", spec->value_name);
503508
else if (spec->type == ADOPT_TYPE_ARGS)

adopt.h

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ typedef enum {
3434
/** An argument that has a value ("-nvalue" or "--name value") */
3535
ADOPT_TYPE_VALUE,
3636

37-
/** An argument that has an optional value ("-n" or "-n foo") */
38-
ADOPT_TYPE_VALUE_OPTIONAL,
39-
4037
/** The literal arguments follow specifier, bare "--" */
4138
ADOPT_TYPE_LITERAL,
4239

@@ -55,14 +52,22 @@ typedef enum {
5552
/** This argument is required. */
5653
ADOPT_USAGE_REQUIRED = (1u << 0),
5754

58-
/** This argument should not be displayed in usage. */
59-
ADOPT_USAGE_HIDDEN = (1u << 1),
55+
/**
56+
* This is a multiple choice argument, combined with the previous
57+
* argument. For example, when the previous argument is `-f` and
58+
* this optional is applied to an argument of type `-b` then one
59+
* of `-f` or `-b` may be specified.
60+
*/
61+
ADOPT_USAGE_CHOICE = (1u << 1),
6062

61-
/** This is a multiple choice argument, combined with the previous arg. */
62-
ADOPT_USAGE_CHOICE = (1u << 2),
63+
/** The argument's value is optional ("-n" or "-n foo") */
64+
ADOPT_USAGE_VALUE_OPTIONAL = (1u << 2),
65+
66+
/** This argument should not be displayed in usage. */
67+
ADOPT_USAGE_HIDDEN = (1u << 3),
6368

6469
/** In usage, show the long format instead of the abbreviated format. */
65-
ADOPT_USAGE_SHOW_LONG = (1u << 3),
70+
ADOPT_USAGE_SHOW_LONG = (1u << 4),
6671
} adopt_usage_t;
6772

6873
/** Specification for an available option. */
@@ -102,6 +107,12 @@ typedef struct adopt_spec {
102107
*/
103108
int switch_value;
104109

110+
/**
111+
* Optional usage flags that change parsing behavior and how
112+
* usage information is shown to the end-user.
113+
*/
114+
uint32_t usage;
115+
105116
/**
106117
* The name of the value, provided when creating usage information.
107118
* This is required only for the functions that display usage
@@ -110,12 +121,6 @@ typedef struct adopt_spec {
110121
*/
111122
const char *value_name;
112123

113-
/**
114-
* Optional usage flags that change parsing behavior and how
115-
* usage information is shown to the end-user.
116-
*/
117-
uint32_t usage;
118-
119124
/**
120125
* Optional short description of the option to display to the
121126
* end-user. This is only used when creating usage information.

examples/loop.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,20 @@ static char **other = NULL;
1919

2020
adopt_spec opt_specs[] = {
2121
{ ADOPT_TYPE_BOOL, "verbose", 'v', &verbose, 0,
22-
NULL, 0, "Turn on verbose information" },
22+
0, NULL, "Turn on verbose information" },
2323
{ ADOPT_TYPE_SWITCH, "quiet", 'q', &volume, 0,
24-
NULL, ADOPT_USAGE_REQUIRED, "Emit no output" },
24+
ADOPT_USAGE_REQUIRED, NULL, "Emit no output" },
2525
{ ADOPT_TYPE_SWITCH, "loud", 'l', &volume, 2,
26-
NULL, ADOPT_USAGE_CHOICE, "Emit louder than usual output" },
26+
ADOPT_USAGE_CHOICE, NULL, "Emit louder than usual output" },
2727
{ ADOPT_TYPE_VALUE, "channel", 'c', &channel, 0,
28-
"channel", 0, "Set the channel" },
28+
0, "channel", "Set the channel" },
2929
{ ADOPT_TYPE_LITERAL },
3030
{ ADOPT_TYPE_ARG, NULL, 0, &filename1, 0,
31-
"file1", ADOPT_USAGE_REQUIRED, "The first filename" },
31+
ADOPT_USAGE_REQUIRED, "file1", "The first filename" },
3232
{ ADOPT_TYPE_ARG, NULL, 0, &filename2, 0,
33-
"file2", 0, "The second (optional) filename" },
33+
0, "file2", "The second (optional) filename" },
3434
{ ADOPT_TYPE_ARGS, NULL, 0, &other, 0,
35-
"other", 0, "The other (optional) arguments" },
35+
0, "other", "The other (optional) arguments" },
3636
{ 0 }
3737
};
3838

examples/parse.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,20 @@ static char **other = NULL;
1919

2020
adopt_spec opt_specs[] = {
2121
{ ADOPT_TYPE_BOOL, "verbose", 'v', &verbose, 0,
22-
NULL, 0, "Turn on verbose information" },
22+
0, NULL, "Turn on verbose information" },
2323
{ ADOPT_TYPE_SWITCH, "quiet", 'q', &volume, 0,
24-
NULL, ADOPT_USAGE_REQUIRED, "Emit no output" },
24+
ADOPT_USAGE_REQUIRED, NULL, "Emit no output" },
2525
{ ADOPT_TYPE_SWITCH, "loud", 'l', &volume, 2,
26-
NULL, ADOPT_USAGE_CHOICE, "Emit louder than usual output" },
26+
ADOPT_USAGE_CHOICE, NULL, "Emit louder than usual output" },
2727
{ ADOPT_TYPE_VALUE, "channel", 'c', &channel, 0,
28-
"channel", 0, "Set the channel" },
28+
0, "channel", "Set the channel" },
2929
{ ADOPT_TYPE_LITERAL },
3030
{ ADOPT_TYPE_ARG, NULL, 0, &filename1, 0,
31-
"file1", ADOPT_USAGE_REQUIRED, "The first filename" },
31+
ADOPT_USAGE_REQUIRED, "file1", "The first filename" },
3232
{ ADOPT_TYPE_ARG, NULL, 0, &filename2, 0,
33-
"file2", 0, "The second (optional) filename" },
33+
0, "file2", "The second (optional) filename" },
3434
{ ADOPT_TYPE_ARGS, NULL, 0, &other, 0,
35-
"other", 0, "The other (optional) arguments" },
35+
0, "other", "The other (optional) arguments" },
3636
{ 0 }
3737
};
3838

tests/adopt.c

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,8 @@ void test_adopt__long_values1(void)
205205
char *foo = NULL, *bar = NULL;
206206

207207
adopt_spec specs[] = {
208-
{ ADOPT_TYPE_VALUE_OPTIONAL, "foo", 0, &foo, 0 },
209-
{ ADOPT_TYPE_VALUE_OPTIONAL, "bar", 0, &bar, 0 },
208+
{ ADOPT_TYPE_VALUE, "foo", 0, &foo, 0, ADOPT_USAGE_VALUE_OPTIONAL },
209+
{ ADOPT_TYPE_VALUE, "bar", 0, &bar, 0, ADOPT_USAGE_VALUE_OPTIONAL },
210210
{ 0 }
211211
};
212212

@@ -226,8 +226,8 @@ void test_adopt__long_values2(void)
226226
char *foo = NULL, *bar = NULL;
227227

228228
adopt_spec specs[] = {
229-
{ ADOPT_TYPE_VALUE_OPTIONAL, "foo", 0, &foo, 0 },
230-
{ ADOPT_TYPE_VALUE_OPTIONAL, "bar", 0, &bar, 0 },
229+
{ ADOPT_TYPE_VALUE, "foo", 0, &foo, 0, ADOPT_USAGE_VALUE_OPTIONAL },
230+
{ ADOPT_TYPE_VALUE, "bar", 0, &bar, 0, ADOPT_USAGE_VALUE_OPTIONAL },
231231
{ 0 }
232232
};
233233

@@ -247,8 +247,8 @@ void test_adopt__long_values3(void)
247247
char *foo = NULL, *bar = NULL;
248248

249249
adopt_spec specs[] = {
250-
{ ADOPT_TYPE_VALUE_OPTIONAL, "foo", 0, &foo, 0 },
251-
{ ADOPT_TYPE_VALUE_OPTIONAL, "bar", 0, &bar, 0 },
250+
{ ADOPT_TYPE_VALUE, "foo", 0, &foo, 0, ADOPT_USAGE_VALUE_OPTIONAL },
251+
{ ADOPT_TYPE_VALUE, "bar", 0, &bar, 0, ADOPT_USAGE_VALUE_OPTIONAL },
252252
{ 0 }
253253
};
254254

@@ -269,8 +269,8 @@ void test_adopt__long_values4(void)
269269
char *foo = NULL, *bar = NULL;
270270

271271
adopt_spec specs[] = {
272-
{ ADOPT_TYPE_VALUE_OPTIONAL, "foo", 0, &foo, 0 },
273-
{ ADOPT_TYPE_VALUE_OPTIONAL, "bar", 0, &bar, 0 },
272+
{ ADOPT_TYPE_VALUE, "foo", 0, &foo, 0, ADOPT_USAGE_VALUE_OPTIONAL },
273+
{ ADOPT_TYPE_VALUE, "bar", 0, &bar, 0, ADOPT_USAGE_VALUE_OPTIONAL },
274274
{ 0 }
275275
};
276276

@@ -290,8 +290,8 @@ void test_adopt__long_values5(void)
290290
char *foo = NULL, *bar = NULL;
291291

292292
adopt_spec specs[] = {
293-
{ ADOPT_TYPE_VALUE_OPTIONAL, "foo", 0, &foo, 0 },
294-
{ ADOPT_TYPE_VALUE_OPTIONAL, "bar", 0, &bar, 0 },
293+
{ ADOPT_TYPE_VALUE, "foo", 0, &foo, 0, ADOPT_USAGE_VALUE_OPTIONAL },
294+
{ ADOPT_TYPE_VALUE, "bar", 0, &bar, 0, ADOPT_USAGE_VALUE_OPTIONAL },
295295
{ 0 }
296296
};
297297

@@ -375,8 +375,8 @@ void test_adopt__short_values1(void)
375375
char *foo = NULL, *bar = NULL;
376376

377377
adopt_spec specs[] = {
378-
{ ADOPT_TYPE_VALUE_OPTIONAL, "foo", 'f', &foo, 0 },
379-
{ ADOPT_TYPE_VALUE_OPTIONAL, "bar", 'b', &bar, 0 },
378+
{ ADOPT_TYPE_VALUE, "foo", 'f', &foo, 0, ADOPT_USAGE_VALUE_OPTIONAL },
379+
{ ADOPT_TYPE_VALUE, "bar", 'b', &bar, 0, ADOPT_USAGE_VALUE_OPTIONAL },
380380
{ 0 }
381381
};
382382

@@ -396,8 +396,8 @@ void test_adopt__short_values2(void)
396396
char *foo = NULL, *bar = NULL;
397397

398398
adopt_spec specs[] = {
399-
{ ADOPT_TYPE_VALUE_OPTIONAL, "foo", 'f', &foo, 0 },
400-
{ ADOPT_TYPE_VALUE_OPTIONAL, "bar", 'b', &bar, 0 },
399+
{ ADOPT_TYPE_VALUE, "foo", 'f', &foo, 0, ADOPT_USAGE_VALUE_OPTIONAL },
400+
{ ADOPT_TYPE_VALUE, "bar", 'b', &bar, 0, ADOPT_USAGE_VALUE_OPTIONAL },
401401
{ 0 }
402402
};
403403

@@ -417,8 +417,8 @@ void test_adopt__short_values3(void)
417417
char *foo = NULL, *bar = NULL;
418418

419419
adopt_spec specs[] = {
420-
{ ADOPT_TYPE_VALUE_OPTIONAL, "foo", 'f', &foo, 0 },
421-
{ ADOPT_TYPE_VALUE_OPTIONAL, "bar", 'b', &bar, 0 },
420+
{ ADOPT_TYPE_VALUE, "foo", 'f', &foo, 0, ADOPT_USAGE_VALUE_OPTIONAL },
421+
{ ADOPT_TYPE_VALUE, "bar", 'b', &bar, 0, ADOPT_USAGE_VALUE_OPTIONAL },
422422
{ 0 }
423423
};
424424

@@ -439,8 +439,8 @@ void test_adopt__short_values4(void)
439439
char *foo = NULL, *bar = NULL;
440440

441441
adopt_spec specs[] = {
442-
{ ADOPT_TYPE_VALUE_OPTIONAL, "foo", 'f', &foo, 0 },
443-
{ ADOPT_TYPE_VALUE_OPTIONAL, "bar", 'b', &bar, 0 },
442+
{ ADOPT_TYPE_VALUE, "foo", 'f', &foo, 0, ADOPT_USAGE_VALUE_OPTIONAL },
443+
{ ADOPT_TYPE_VALUE, "bar", 'b', &bar, 0, ADOPT_USAGE_VALUE_OPTIONAL },
444444
{ 0 }
445445
};
446446

@@ -460,8 +460,8 @@ void test_adopt__short_values5(void)
460460
char *foo = NULL, *bar = NULL;
461461

462462
adopt_spec specs[] = {
463-
{ ADOPT_TYPE_VALUE_OPTIONAL, "foo", 'f', &foo, 0 },
464-
{ ADOPT_TYPE_VALUE_OPTIONAL, "bar", 'b', &bar, 0 },
463+
{ ADOPT_TYPE_VALUE, "foo", 'f', &foo, 0, ADOPT_USAGE_VALUE_OPTIONAL },
464+
{ ADOPT_TYPE_VALUE, "bar", 'b', &bar, 0, ADOPT_USAGE_VALUE_OPTIONAL },
465465
{ 0 }
466466
};
467467

@@ -782,9 +782,9 @@ void test_adopt__required_choice_missing(void)
782782
adopt_opt result;
783783

784784
adopt_spec specs[] = {
785-
{ ADOPT_TYPE_SWITCH, "foo", 'f', &foo, 'f', NULL, ADOPT_USAGE_REQUIRED },
786-
{ ADOPT_TYPE_VALUE, "bar", 0, &bar, 'b', NULL, ADOPT_USAGE_CHOICE },
787-
{ ADOPT_TYPE_ARGS, "argz", 0, &argz, 0, NULL, 0 },
785+
{ ADOPT_TYPE_SWITCH, "foo", 'f', &foo, 'f', ADOPT_USAGE_REQUIRED },
786+
{ ADOPT_TYPE_VALUE, "bar", 0, &bar, 'b', ADOPT_USAGE_CHOICE },
787+
{ ADOPT_TYPE_ARGS, "argz", 0, &argz, 0, 0 },
788788
{ 0 },
789789
};
790790

@@ -807,10 +807,10 @@ void test_adopt__required_choice_specified(void)
807807
adopt_opt result;
808808

809809
adopt_spec specs[] = {
810-
{ ADOPT_TYPE_SWITCH, "foo", 'f', &foo, 'f', NULL, ADOPT_USAGE_REQUIRED },
811-
{ ADOPT_TYPE_VALUE, "bar", 0, &bar, 'b', NULL, ADOPT_USAGE_CHOICE },
812-
{ ADOPT_TYPE_ARG, "baz", 0, &baz, 'z', NULL, ADOPT_USAGE_REQUIRED },
813-
{ ADOPT_TYPE_ARGS, "argz", 0, &argz, 0, NULL, 0 },
810+
{ ADOPT_TYPE_SWITCH, "foo", 'f', &foo, 'f', ADOPT_USAGE_REQUIRED },
811+
{ ADOPT_TYPE_VALUE, "bar", 0, &bar, 'b', ADOPT_USAGE_CHOICE },
812+
{ ADOPT_TYPE_ARG, "baz", 0, &baz, 'z', ADOPT_USAGE_REQUIRED },
813+
{ ADOPT_TYPE_ARGS, "argz", 0, &argz, 0, 0 },
814814
{ 0 },
815815
};
816816

@@ -833,11 +833,11 @@ void test_adopt__choice_switch_or_arg_advances_arg(void)
833833
adopt_opt result;
834834

835835
adopt_spec specs[] = {
836-
{ ADOPT_TYPE_SWITCH, "foo", 'f', &foo, 'f', NULL, 0 },
837-
{ ADOPT_TYPE_SWITCH, "fooz", 'z', &foo, 'z', NULL, ADOPT_USAGE_CHOICE },
838-
{ ADOPT_TYPE_VALUE, "bar", 0, &bar, 'b', NULL, ADOPT_USAGE_CHOICE },
839-
{ ADOPT_TYPE_ARG, "baz", 0, &baz, 0, NULL, ADOPT_USAGE_CHOICE },
840-
{ ADOPT_TYPE_ARG, "final", 0, &final, 0, NULL, 0 },
836+
{ ADOPT_TYPE_SWITCH, "foo", 'f', &foo, 'f', 0 },
837+
{ ADOPT_TYPE_SWITCH, "fooz", 'z', &foo, 'z', ADOPT_USAGE_CHOICE },
838+
{ ADOPT_TYPE_VALUE, "bar", 0, &bar, 'b', ADOPT_USAGE_CHOICE },
839+
{ ADOPT_TYPE_ARG, "baz", 0, &baz, 0, ADOPT_USAGE_CHOICE },
840+
{ ADOPT_TYPE_ARG, "final", 0, &final, 0, 0 },
841841
{ 0 },
842842
};
843843

0 commit comments

Comments
 (0)