Some refactoring of argparse implicit ints

This commit is contained in:
ridiculousfish 2018-08-18 18:21:57 -07:00
parent d046452cdf
commit 4abdf8c301

View file

@ -458,29 +458,23 @@ static int validate_arg(const argparse_cmd_opts_t &opts, option_spec_t *opt_spec
return retval; return retval;
} }
// Check if it is an implicit integer option. Try to parse and validate it as a valid integer. The /// \return whether the option 'opt' is an implicit integer option.
// code that parses option specs has already ensured that implicit integers have either an explicit static bool is_implicit_int(const argparse_cmd_opts_t &opts, const wchar_t *val) {
// or implicit validation function.
static int check_for_implicit_int(const argparse_cmd_opts_t &opts, const wchar_t *val,
const wchar_t *cmd, const wchar_t *const *argv, wgetopter_t &w,
int opt, int long_idx, parser_t &parser, io_streams_t &streams) {
if (opts.implicit_int_flag == L'\0') { if (opts.implicit_int_flag == L'\0') {
// There is no implicit integer option so report an error. // There is no implicit integer option.
builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]); return false;
return STATUS_INVALID_ARGS;
} }
if (opt == '?') { // We succeed if this argument can be parsed as an integer.
// It's a flag that might be an implicit integer flag. Try to parse it as an integer to errno = 0;
// decide if it is in fact something like `-NNN` or an invalid flag.
(void)fish_wcstol(val); (void)fish_wcstol(val);
if (errno) { return errno == 0;
builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]);
return STATUS_INVALID_ARGS;
}
} }
// Okay, it looks like an integer. See if it passes the validation checks. // Store this value under the implicit int option.
static int validate_and_store_implicit_int(const argparse_cmd_opts_t &opts, const wchar_t *val,
wgetopter_t &w, int long_idx, io_streams_t &streams) {
// See if this option passes the validation checks.
auto found = opts.options.find(opts.implicit_int_flag); auto found = opts.options.find(opts.implicit_int_flag);
assert(found != opts.options.end()); assert(found != opts.options.end());
const auto &opt_spec = found->second; const auto &opt_spec = found->second;
@ -546,8 +540,14 @@ static int argparse_parse_flags(const argparse_cmd_opts_t &opts, const wchar_t *
if (opt == '?') { if (opt == '?') {
// It's not a recognized flag. See if it's an implicit int flag. // It's not a recognized flag. See if it's an implicit int flag.
int retval = check_for_implicit_int(opts, argv[w.woptind - 1] + 1, cmd, argv, w, opt, const wchar_t *arg_contents = argv[w.woptind - 1] + 1;
long_idx, parser, streams); int retval = STATUS_CMD_OK;
if (is_implicit_int(opts, arg_contents)) {
retval = validate_and_store_implicit_int(opts, arg_contents, w, long_idx, streams);
} else {
builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1]);
retval = STATUS_INVALID_ARGS;
}
if (retval != STATUS_CMD_OK) return retval; if (retval != STATUS_CMD_OK) return retval;
long_idx = -1; long_idx = -1;
continue; continue;