shared/options: add new helper option_parser_get_arg
option_parser_next_arg() is renamed to option_parser_peek_next_arg() to match option_parser_consume_next_arg(). A new helper is added option_parser_get_arg(…, n). It is a common pattern to only need a single arg, and getting an array and extracting a single item from it is too verbose.
This commit is contained in:
@@ -31,7 +31,6 @@
|
||||
#include "process-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "tpm2-pcr.h"
|
||||
#include "tpm2-util.h"
|
||||
|
||||
@@ -579,14 +578,12 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
}
|
||||
|
||||
char **args = option_parser_get_args(&opts);
|
||||
if (option_parser_get_n_args(&opts) > 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Too many arguments, refusing.");
|
||||
|
||||
if (strv_length(args) > 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Too many arguments, refusing.");
|
||||
|
||||
if (args[0])
|
||||
r = parse_path_argument(args[0], false, &arg_node);
|
||||
const char *arg = option_parser_get_arg(&opts, 0);
|
||||
if (arg)
|
||||
r = parse_path_argument(arg, false, &arg_node);
|
||||
else if (!wipe_requested())
|
||||
r = determine_default_node();
|
||||
else
|
||||
|
||||
+1
-2
@@ -181,8 +181,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
"%s expects exactly one argument (the mount point).",
|
||||
program_invocation_short_name);
|
||||
|
||||
arg_target = option_parser_get_args(&opts)[0];
|
||||
|
||||
arg_target = option_parser_get_arg(&opts, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1420,7 +1420,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
* the old container user functionality. To maintain backwards compatibility
|
||||
* with the space-separated form (--user NAME), if the next opts.arg does not look
|
||||
* like an option, interpret it as a user name. */
|
||||
const char *t = option_parser_next_arg(&opts);
|
||||
const char *t = option_parser_peek_next_arg(&opts);
|
||||
if (t && t[0] != '-') {
|
||||
opts.arg = option_parser_consume_next_arg(&opts);
|
||||
log_warning("--user NAME is deprecated, use --uid=NAME instead.");
|
||||
|
||||
+10
-2
@@ -344,7 +344,7 @@ int option_parse(
|
||||
return r;
|
||||
}
|
||||
|
||||
char* option_parser_next_arg(const OptionParser *state) {
|
||||
char* option_parser_peek_next_arg(const OptionParser *state) {
|
||||
/* Peek at the next argument, whatever it is (option or position arg).
|
||||
* May return NULL. */
|
||||
|
||||
@@ -360,7 +360,7 @@ char* option_parser_consume_next_arg(OptionParser *state) {
|
||||
* so we won't try to interpret it as an option.
|
||||
* May return NULL. */
|
||||
|
||||
char *t = option_parser_next_arg(state);
|
||||
char *t = option_parser_peek_next_arg(state);
|
||||
if (t)
|
||||
shift_arg(state->argv, state->positional_offset++, state->optind++);
|
||||
return t;
|
||||
@@ -388,6 +388,14 @@ size_t option_parser_get_n_args(const OptionParser *state) {
|
||||
return state->argc - state->positional_offset;
|
||||
}
|
||||
|
||||
char* option_parser_get_arg(const OptionParser *state, size_t i) {
|
||||
assert(state->optind > 0);
|
||||
assert(state->state == OPTION_PARSER_DONE);
|
||||
assert(state->positional_offset <= state->argc);
|
||||
|
||||
return (size_t) (state->argc - state->positional_offset) > i ? state->argv[state->positional_offset + i] : NULL;
|
||||
}
|
||||
|
||||
char* option_get_synopsis(const Option *opt, const char *joiner, bool show_metavar) {
|
||||
assert(opt);
|
||||
assert(!(opt->flags & (OPTION_NAMESPACE_MARKER |
|
||||
|
||||
@@ -224,11 +224,17 @@ int option_parse(
|
||||
break; \
|
||||
} else
|
||||
|
||||
char* option_parser_next_arg(const OptionParser *state);
|
||||
/* Those helpers are used *during* option parsing and allow looking at or taking the next item in
|
||||
* the argv array, either an option or a positional parameter. */
|
||||
char* option_parser_peek_next_arg(const OptionParser *state);
|
||||
char* option_parser_consume_next_arg(OptionParser *state);
|
||||
|
||||
/* Those helpers are used *after* option parsing and return the positional arguments (and unparsed
|
||||
* options in case option parsing was stopped early, e.g. via "--"). */
|
||||
char** option_parser_get_args(const OptionParser *state);
|
||||
size_t option_parser_get_n_args(const OptionParser *state);
|
||||
char* option_parser_get_arg(const OptionParser *state, size_t i);
|
||||
|
||||
char* option_get_synopsis(const Option *opt, const char *joiner, bool show_metavar);
|
||||
|
||||
int _option_parser_get_help_table_full(
|
||||
|
||||
+12
-7
@@ -58,7 +58,12 @@ static void test_option_parse_one(
|
||||
ASSERT_TRUE(strv_equal(args, remaining));
|
||||
ASSERT_STREQ(argv[0], saved_argv0);
|
||||
|
||||
ASSERT_EQ(option_parser_get_n_args(&opts), strv_length(remaining));
|
||||
size_t l = strv_length(remaining);
|
||||
ASSERT_EQ(option_parser_get_n_args(&opts), l);
|
||||
ASSERT_STREQ(option_parser_get_arg(&opts, 0), l > 0 ? remaining[0] : NULL);
|
||||
ASSERT_STREQ(option_parser_get_arg(&opts, 1), l > 1 ? remaining[1] : NULL);
|
||||
ASSERT_STREQ(option_parser_get_arg(&opts, 2), l > 2 ? remaining[2] : NULL);
|
||||
ASSERT_STREQ(option_parser_get_arg(&opts, 3), l > 3 ? remaining[3] : NULL);
|
||||
}
|
||||
|
||||
static void test_option_invalid_one(
|
||||
@@ -1331,7 +1336,7 @@ TEST(option_optional_arg_consume) {
|
||||
|
||||
/* --user without arg: next arg is positional (doesn't start with -).
|
||||
* The option parser returns NULL for the arg. The caller would then
|
||||
* use option_parser_next_arg/consume_next_arg to grab it. */
|
||||
* use option_parser_peek_next_arg/consume_next_arg to grab it. */
|
||||
{
|
||||
char **argv = STRV_MAKE("arg0", "--user", "someuser", "pos1");
|
||||
int argc = strv_length(argv);
|
||||
@@ -1341,7 +1346,7 @@ TEST(option_optional_arg_consume) {
|
||||
ASSERT_OK_POSITIVE(option_parse(options, options + 3, &opts));
|
||||
ASSERT_STREQ(opts.opt->long_code, "user");
|
||||
ASSERT_NULL(opts.arg);
|
||||
ASSERT_STREQ(option_parser_next_arg(&opts), "someuser");
|
||||
ASSERT_STREQ(option_parser_peek_next_arg(&opts), "someuser");
|
||||
ASSERT_STREQ(option_parser_consume_next_arg(&opts), "someuser");
|
||||
|
||||
ASSERT_EQ(option_parse(options, options + 3, &opts), 0);
|
||||
@@ -1361,7 +1366,7 @@ TEST(option_optional_arg_consume) {
|
||||
ASSERT_OK_POSITIVE(option_parse(options, options + 3, &opts));
|
||||
ASSERT_STREQ(opts.opt->long_code, "user");
|
||||
ASSERT_NULL(opts.arg);
|
||||
ASSERT_NULL(option_parser_next_arg(&opts));
|
||||
ASSERT_NULL(option_parser_peek_next_arg(&opts));
|
||||
ASSERT_NULL(option_parser_consume_next_arg(&opts));
|
||||
|
||||
ASSERT_EQ(option_parse(options, options + 3, &opts), 0);
|
||||
@@ -1381,12 +1386,12 @@ TEST(option_optional_arg_consume) {
|
||||
ASSERT_OK_POSITIVE(option_parse(options, options + 3, &opts));
|
||||
ASSERT_STREQ(opts.opt->long_code, "user");
|
||||
ASSERT_NULL(opts.arg);
|
||||
ASSERT_STREQ(option_parser_next_arg(&opts), "-u");
|
||||
ASSERT_STREQ(option_parser_peek_next_arg(&opts), "-u");
|
||||
|
||||
ASSERT_OK_POSITIVE(option_parse(options, options + 3, &opts));
|
||||
ASSERT_STREQ(opts.opt->long_code, "uid");
|
||||
ASSERT_STREQ(opts.arg, "nobody");
|
||||
ASSERT_NULL(option_parser_next_arg(&opts));
|
||||
ASSERT_NULL(option_parser_peek_next_arg(&opts));
|
||||
ASSERT_NULL(option_parser_consume_next_arg(&opts));
|
||||
|
||||
ASSERT_EQ(option_parse(options, options + 3, &opts), 0);
|
||||
@@ -1413,7 +1418,7 @@ TEST(option_optional_arg_consume) {
|
||||
const char *arg = opts.arg;
|
||||
|
||||
if (!arg) {
|
||||
const char *t = option_parser_next_arg(&opts);
|
||||
const char *t = option_parser_peek_next_arg(&opts);
|
||||
if (t && t[0] != '-')
|
||||
arg = option_parser_consume_next_arg(&opts);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user