From: Zbigniew Jędrzejewski-Szmek Date: Thu, 23 Apr 2026 08:10:31 +0000 (+0200) Subject: shared/options: add a 'data' parameter to options X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8cb4ff428e5f84551e578017bbb3a87893b1dd67;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/shared/options.h b/src/shared/options.h index cd9f64fd494..974c21d16a6 100644 --- a/src/shared/options.h +++ b/src/shared/options.h @@ -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) diff --git a/src/test/test-options.c b/src/test/test-options.c index 05fd4bcbe07..687bafd4a2b 100644 --- a/src/test/test-options.c +++ b/src/test/test-options.c @@ -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" },