shared/options: add a 'data' parameter to options

This mirrors a similar field in Verb. In some cases it convenient
to pass a fixed value to the parser.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2026-04-23 11:13:07 +02:00
parent 9a3a861ff8
commit 8cb4ff428e
2 changed files with 20 additions and 3 deletions
+8 -3
View File
@@ -19,10 +19,11 @@ typedef struct Option {
char short_code;
const char *long_code;
const char *metavar;
uintptr_t data;
const char *help;
} Option;
#define _OPTION(counter, fl, sc, lc, mv, h) \
#define _OPTION(counter, fl, sc, lc, mv, d, h) \
_section_("SYSTEMD_OPTIONS") \
_alignptr_ \
_used_ \
@@ -35,6 +36,7 @@ typedef struct Option {
.short_code = sc, \
.long_code = lc, \
.metavar = mv, \
.data = d, \
.help = h, \
}; \
case (0x100 + counter)
@@ -43,14 +45,17 @@ typedef struct Option {
* The define is structured as 'case' so that it can be followed by ':' and indented appropriately.
*/
#define OPTION_GROUP(gr) \
_OPTION(__COUNTER__, OPTION_GROUP_MARKER, /* sc= */ 0, /* lc= */ gr, /* mv= */ NULL, /* h= */ NULL)
_OPTION(__COUNTER__, OPTION_GROUP_MARKER, /* sc= */ 0, /* lc= */ gr, /* mv= */ NULL, /* d= */ 0u, /* h= */ NULL)
#define OPTION_FULL(fl, sc, lc, mv, h) _OPTION(__COUNTER__, fl, sc, lc, mv, h)
#define OPTION_FULL_DATA(fl, sc, lc, mv, d, h) _OPTION(__COUNTER__, fl, sc, lc, mv, d, h)
#define OPTION_FULL(fl, sc, lc, mv, h) OPTION_FULL_DATA(fl, sc, lc, mv, /* d= */ 0u, h)
#define OPTION(sc, lc, mv, h) OPTION_FULL(/* fl= */ 0, sc, lc, mv, h)
#define OPTION_LONG(lc, mv, h) OPTION(/* sc= */ 0, lc, mv, h)
#define OPTION_LONG_FLAGS(fl, lc, mv, h) OPTION_FULL(fl, /* sc= */ 0, lc, mv, h)
#define OPTION_LONG_DATA(lc, mv, d, h) OPTION_FULL_DATA(/* fl= */ 0, /* sc= */ 0, lc, mv, d, h)
#define OPTION_SHORT(sc, mv, h) OPTION(sc, /* lc= */ NULL, mv, h)
#define OPTION_SHORT_FLAGS(fl, sc, mv, h) OPTION_FULL(fl, sc, /* lc= */ NULL, mv, h)
#define OPTION_SHORT_DATA(sc, mv, d, h) OPTION_FULL_DATA(/* fl= */ 0, sc, /* lc= */ NULL, mv, d, h)
#define OPTION_POSITIONAL OPTION_FULL(OPTION_POSITIONAL_ENTRY, /* sc= */ 0, "(positional)", /* mv= */ NULL, /* h= */ NULL)
#define OPTION_HELP_VERBATIM(lc, h) OPTION_FULL(OPTION_HELP_ENTRY_VERBATIM, /* sc= */ 0, lc, /* mv= */ NULL, h)
+12
View File
@@ -772,6 +772,12 @@ static void test_macros_parse_one(
if (entries[i].short_code != 0)
ASSERT_EQ(opt->short_code, entries[i].short_code);
ASSERT_TRUE(streq_ptr(arg, entries[i].argument));
if (streq_ptr(entries[i].long_code, "optional2"))
ASSERT_EQ(opt->data, 666u);
else
ASSERT_EQ(opt->data, 0u);
i++;
switch (c) {
@@ -796,6 +802,10 @@ static void test_macros_parse_one(
OPTION_FULL(OPTION_OPTIONAL_ARG, 'o', "optional", "ARG", "Optional arg option"):
break;
/* OPTION_FULL_DATA: optional arg */
OPTION_FULL_DATA(OPTION_OPTIONAL_ARG, 'O', "optional2", "ARG", 666, "Optional arg option"):
break;
/* OPTION_FULL: stops parsing */
OPTION_FULL(OPTION_STOPS_PARSING, 0, "exec", NULL, "Stop parsing after this"):
break;
@@ -1015,6 +1025,7 @@ TEST(option_macros) {
"-v",
"--required=rval",
"--optional=oval",
"--optional2=oval",
"--debug",
"pos2",
"-o",
@@ -1025,6 +1036,7 @@ TEST(option_macros) {
{ .short_code = 'v' },
{ "required", "rval" },
{ "optional", "oval" },
{ "optional2", "oval" },
{ "debug" },
{ "optional", NULL },
{ "help" },