mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-25 09:39:52 +08:00
argparse: Jump to the next option after an unknown one
Previously, when we got an unknown option with --ignore-unknown, we would increment woptind but still try to read the same contents. This means in e.g. ``` argparse -i h -- -ooo -h ``` The `-h` would also be skipped as an option, because after the first `-o` getopt reads the other two `-o` and skips that many options. This could be handled more extensively in wgetopt, but the simpler fix is to just skip to the next argv entry once we have an unknown option - there's nothing more we can do with it anyway! Additionally, document this and clearly explain that we currently don't transform the option. Fixes #8637
This commit is contained in:
parent
8e60f1b4a3
commit
0781473564
|
@ -184,3 +184,18 @@ Some OPTION_SPEC examples:
|
||||||
After parsing the arguments the ``argv`` variable is set with local scope to any values not already consumed during flag processing. If there are no unbound values the variable is set but ``count $argv`` will be zero.
|
After parsing the arguments the ``argv`` variable is set with local scope to any values not already consumed during flag processing. If there are no unbound values the variable is set but ``count $argv`` will be zero.
|
||||||
|
|
||||||
If an error occurs during argparse processing it will exit with a non-zero status and print error messages to stderr.
|
If an error occurs during argparse processing it will exit with a non-zero status and print error messages to stderr.
|
||||||
|
|
||||||
|
Limitations
|
||||||
|
-----------
|
||||||
|
|
||||||
|
One limitation with **--ignore-unknown** is that, if an unknown option is given in a group with known options, the entire group will be kept in $argv. ``argparse`` will not do any permutations here.
|
||||||
|
|
||||||
|
For instance::
|
||||||
|
|
||||||
|
argparse --ignore-unknown h -- -ho
|
||||||
|
echo $_flag_h # is -h, because -h was given
|
||||||
|
echo $argv # is still -ho
|
||||||
|
|
||||||
|
This limitation may be lifted in future.
|
||||||
|
|
||||||
|
Additionally, it can only parse known options up to the first unknown option in the group - the unknown option could take options, so it isn't clear what any character after an unknown option means.
|
||||||
|
|
|
@ -596,6 +596,9 @@ static int argparse_parse_flags(parser_t &parser, argparse_cmd_opts_t &opts,
|
||||||
opts.argv.push_back(arg_contents - 1);
|
opts.argv.push_back(arg_contents - 1);
|
||||||
// Work around weirdness with wgetopt, which crashes if we `continue` here.
|
// Work around weirdness with wgetopt, which crashes if we `continue` here.
|
||||||
if (w.woptind == argc) break;
|
if (w.woptind == argc) break;
|
||||||
|
// Explain to wgetopt that we want to skip to the next arg,
|
||||||
|
// because we can't handle this opt group.
|
||||||
|
w.nextchar = nullptr;
|
||||||
}
|
}
|
||||||
if (retval != STATUS_CMD_OK) return retval;
|
if (retval != STATUS_CMD_OK) return retval;
|
||||||
long_idx = -1;
|
long_idx = -1;
|
||||||
|
|
|
@ -498,3 +498,14 @@ begin
|
||||||
#CHECKERR: ^
|
#CHECKERR: ^
|
||||||
#CHECKERR: (Type 'help argparse' for related documentation)
|
#CHECKERR: (Type 'help argparse' for related documentation)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
argparse --ignore-unknown h i -- -hoa -oia
|
||||||
|
echo -- $argv
|
||||||
|
#CHECK: -hoa -oia
|
||||||
|
echo $_flag_h
|
||||||
|
#CHECK: -h
|
||||||
|
set -q _flag_i
|
||||||
|
or echo No flag I
|
||||||
|
#CHECK: No flag I
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user