return state->argc - state->positional_offset;
}
-char* option_get_synopsis(const char *prefix, const Option *opt, const char *joiner, bool show_metavar) {
+char* option_get_synopsis(const Option *opt, const char *joiner, bool show_metavar) {
assert(opt);
assert(!FLAGS_SET(opt->flags, OPTION_GROUP_MARKER)); /* A group marker should not be displayed */
- if (!prefix)
- prefix = "";
-
if (opt->flags & (OPTION_HELP_ENTRY_VERBATIM | OPTION_POSITIONAL_ENTRY))
- return strjoin(prefix, ASSERT_PTR(opt->long_code));
+ return strdup(ASSERT_PTR(opt->long_code));
/* The option formatted appropriately for --help strings, error messages, and similar:
- * <prefix>-<short><joiner>--<long>=[<metavar>]
+ * -<short><joiner>--<long>=[<metavar>]
* "=" is shown only when a long form is defined: -l --long=ARG, --long=ARG, -s ARG.
* The joiner arg is used between the short and long forms.
* As a special case, if the option has no long form and show_metavar is true,
bool need_eq = option_takes_arg(opt) && opt->long_code;
if (!show_metavar)
- return strjoin(prefix,
- sc,
+ return strjoin(sc,
joiner,
opt->long_code ? "--" : "",
strempty(opt->long_code),
need_eq ? "=" : "");
bool need_quote = opt->metavar && strchr(opt->metavar, ' ');
- return strjoin(prefix,
- sc,
+ return strjoin(sc,
joiner,
opt->long_code ? "--" : "",
strempty(opt->long_code),
/* No help string — we do not show the option */
continue;
+ _cleanup_free_ char *s = option_get_synopsis(opt, " ", /* show_metavar= */ true);
+ if (!s)
+ return log_oom();
+
/* We indent the option string by two spaces. We could set the minimum cell width and
* right-align for a similar result, but that'd be more work. This is only used for
* display. */
- _cleanup_free_ char *s = option_get_synopsis(" ", opt, " ", /* show_metavar= */ true);
- if (!s)
+ const char *prefix = opt->short_code != 0 ? " " : " ";
+ _cleanup_free_ char *t = strjoin(prefix, s);
+ if (!t)
return log_oom();
- r = table_add_many(table, TABLE_STRING, s);
+ r = table_add_many(table, TABLE_STRING, t);
if (r < 0)
return table_log_add_error(r);
- _cleanup_strv_free_ char **t = strv_split(opt->help, /* separators= */ NULL);
- if (!t)
+ _cleanup_strv_free_ char **split = strv_split(opt->help, /* separators= */ NULL);
+ if (!split)
return log_oom();
- r = table_add_many(table, TABLE_STRV_WRAPPED, t);
+ r = table_add_many(table, TABLE_STRV_WRAPPED, split);
if (r < 0)
return table_log_add_error(r);
}
bool show_metavar,
const char *expected) {
log_debug("%s", expected);
- _cleanup_free_ char *s = option_get_synopsis(". ", opt, joiner, show_metavar);
+ _cleanup_free_ char *s = option_get_synopsis(opt, joiner, show_metavar);
ASSERT_STREQ(s, expected);
}
TEST(option_get_synopsis) {
- test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "X" }, "/", true, ". -x/--xxx=X");
- test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "X" }, NULL, true, ". -x --xxx=X");
- test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "X" }, "/", false, ". -x/--xxx=" );
- test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "X" }, " ", true, ". -x --xxx=X");
- test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "X" }, " ", false, ". -x --xxx=" );
- test_option_get_synopsis_one(&(const Option) { 0, 0, 0, "xxx", "X" }, "+", true, ". --xxx=X" );
- test_option_get_synopsis_one(&(const Option) { 0, 0, 0, "xxx", "X" }, "+", false, ". --xxx=" );
- test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', NULL, "X" }, " ", true, ". -x X" );
- test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', NULL, "X" }, "/", false, ". -x" );
-
- test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "A B" }, "/", true, ". -x/--xxx='A B'");
- test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "A B" }, " ", true, ". -x --xxx='A B'");
- test_option_get_synopsis_one(&(const Option) { 0, 0, 0, "xxx", "A B" }, "+", true, ". --xxx='A B'" );
- test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', NULL, "A B" }, " ", true, ". -x 'A B'" );
-
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "X" }, "/", true, ". -x/--xxx[=X]");
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "X" }, NULL, true, ". -x --xxx[=X]");
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "X" }, "/", true, "-x/--xxx=X");
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "X" }, NULL, true, "-x --xxx=X");
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "X" }, "/", false, "-x/--xxx=" );
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "X" }, " ", true, "-x --xxx=X");
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "X" }, " ", false, "-x --xxx=" );
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 0, "xxx", "X" }, "+", true, "--xxx=X" );
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 0, "xxx", "X" }, "+", false, "--xxx=" );
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', NULL, "X" }, " ", true, "-x X" );
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', NULL, "X" }, "/", false, "-x" );
+
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "A B" }, "/", true, "-x/--xxx='A B'");
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', "xxx", "A B" }, " ", true, "-x --xxx='A B'");
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 0, "xxx", "A B" }, "+", true, "--xxx='A B'" );
+ test_option_get_synopsis_one(&(const Option) { 0, 0, 'x', NULL, "A B" }, " ", true, "-x 'A B'" );
+
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "X" }, "/", true, "-x/--xxx[=X]");
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "X" }, NULL, true, "-x --xxx[=X]");
/* Note: --xxx[=] would be silly, so we show --xxx=. It's a corner case. Maybe this should change. */
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "X" }, "/", false, ". -x/--xxx=" );
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "X" }, " ", true, ". -x --xxx[=X]");
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "X" }, " ", false, ". -x --xxx=" );
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 0, "xxx", "X" }, "+", true, ". --xxx[=X]" );
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 0, "xxx", "X" }, "+", false, ". --xxx=" );
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', NULL, "X" }, " ", true, ". -x [X]" );
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', NULL, "X" }, "/", false, ". -x" );
-
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "A B" }, "/", true, ". -x/--xxx[='A B']");
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "A B" }, " ", true, ". -x --xxx[='A B']");
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 0, "xxx", "A B" }, "+", true, ". --xxx[='A B']" );
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', NULL, "A B" }, " ", true, ". -x ['A B']" );
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "X" }, "/", false, "-x/--xxx=" );
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "X" }, " ", true, "-x --xxx[=X]");
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "X" }, " ", false, "-x --xxx=" );
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 0, "xxx", "X" }, "+", true, "--xxx[=X]" );
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 0, "xxx", "X" }, "+", false, "--xxx=" );
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', NULL, "X" }, " ", true, "-x [X]" );
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', NULL, "X" }, "/", false, "-x" );
+
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "A B" }, "/", true, "-x/--xxx[='A B']");
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', "xxx", "A B" }, " ", true, "-x --xxx[='A B']");
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 0, "xxx", "A B" }, "+", true, "--xxx[='A B']" );
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG, 'x', NULL, "A B" }, " ", true, "-x ['A B']" );
test_option_get_synopsis_one(&(const Option) { 0, OPTION_OPTIONAL_ARG | OPTION_HELP_ENTRY | OPTION_STOPS_PARSING,
- 'x', "xxx", "A B" }, "/", true, ". -x/--xxx[='A B']");
+ 'x', "xxx", "A B" }, "/", true, "-x/--xxx[='A B']");
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_HELP_ENTRY_VERBATIM, 'u', "special special", "unused" }, "/", true, ". special special");
- test_option_get_synopsis_one(&(const Option) { 0, OPTION_POSITIONAL_ENTRY, 'u', "(fixed)", "unused" }, "/", true, ". (fixed)");
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_HELP_ENTRY_VERBATIM, 'u', "special special", "unused" }, "/", true, "special special");
+ test_option_get_synopsis_one(&(const Option) { 0, OPTION_POSITIONAL_ENTRY, 'u', "(fixed)", "unused" }, "/", true, "(fixed)");
}
DEFINE_TEST_MAIN(LOG_DEBUG);