#include "process-util.h"
#include "string-table.h"
#include "string-util.h"
-#include "strv.h"
#include "tpm2-pcr.h"
#include "tpm2-util.h"
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
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. */
* 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;
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 |
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(
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(
/* --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);
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);
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);
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);
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);
}