mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-31 12:21:19 -03:00
Give a more helpful error when a boolean option has an argument.
This fixes an issue very similar to #6483, For example, fish --login=root used to print this: fish: --login=root: unknown option But `--login` is a valid option to fish. So the above now prints: fish: --login=root: option does not take an argument This is done by modifying WGetOpter so that it returns a ';' if it encountered an option with an argument, but the option was not declared as taking an option (this is only possible with the --long=value or legacy -long=value syntax). All uses of WGetOpter (except echo, fish_indent, and some tests) are modified to then print an appropriate error message when ';' is returned. echo doesn't have any long options, so it will panic if gets a ';'. fish_indent doesn't print any error messages for invalid options anyway, and I wasn't sure if this was intentional or not. Moreover, WGetOpter now always returns a ':' for options that are missing an argument. And you can no longer prefix a your option spec with a ':' to enable this (since every use of WGetOpter was doing this anyway, except wgetopt::test_exchange and tests::wgetopt::test_wgetopt).
This commit is contained in:
5
po/de.po
5
po/de.po
@@ -196,6 +196,11 @@ msgstr "%ls: %ls: ungültiger Unterbefehl\n"
|
||||
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
|
||||
msgstr ""
|
||||
|
||||
#
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option does not take an argument\n"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option requires an argument\n"
|
||||
msgstr ""
|
||||
|
||||
5
po/en.po
5
po/en.po
@@ -194,6 +194,11 @@ msgstr ""
|
||||
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
|
||||
msgstr ""
|
||||
|
||||
#
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option does not take an argument\n"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option requires an argument\n"
|
||||
msgstr ""
|
||||
|
||||
5
po/fr.po
5
po/fr.po
@@ -295,6 +295,11 @@ msgstr ""
|
||||
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
|
||||
msgstr ""
|
||||
|
||||
#
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option does not take an argument\n"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option requires an argument\n"
|
||||
msgstr ""
|
||||
|
||||
5
po/pl.po
5
po/pl.po
@@ -190,6 +190,11 @@ msgstr ""
|
||||
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
|
||||
msgstr ""
|
||||
|
||||
#
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option does not take an argument\n"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option requires an argument\n"
|
||||
msgstr ""
|
||||
|
||||
@@ -195,6 +195,11 @@ msgstr ""
|
||||
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
|
||||
msgstr ""
|
||||
|
||||
#
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option does not take an argument\n"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option requires an argument\n"
|
||||
msgstr ""
|
||||
|
||||
5
po/sv.po
5
po/sv.po
@@ -191,6 +191,11 @@ msgstr ""
|
||||
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
|
||||
msgstr ""
|
||||
|
||||
#
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option does not take an argument\n"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option requires an argument\n"
|
||||
msgstr ""
|
||||
|
||||
@@ -188,6 +188,11 @@ msgstr "%ls: %ls:无效的子命令\n"
|
||||
msgid "%ls: %ls: invalid variable name. See `help identifiers`\n"
|
||||
msgstr "%ls: %ls:无效的可变名称. 参见`help identifiers`\n"
|
||||
|
||||
#
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option does not take an argument\n"
|
||||
msgstr ""
|
||||
|
||||
#, c-format
|
||||
msgid "%ls: %ls: option requires an argument\n"
|
||||
msgstr "%ls:%ls: 选项需要参数\n"
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
builtins::{
|
||||
fish_indent, fish_key_reader,
|
||||
shared::{
|
||||
BUILTIN_ERR_MISSING, BUILTIN_ERR_UNKNOWN, STATUS_CMD_ERROR, STATUS_CMD_OK,
|
||||
STATUS_CMD_UNKNOWN,
|
||||
BUILTIN_ERR_MISSING, BUILTIN_ERR_UNEXP_ARG, BUILTIN_ERR_UNKNOWN, STATUS_CMD_ERROR,
|
||||
STATUS_CMD_OK, STATUS_CMD_UNKNOWN,
|
||||
},
|
||||
},
|
||||
common::{
|
||||
@@ -253,7 +253,7 @@ fn fish_parse_opt(args: &mut [WString], opts: &mut FishCmdOpts) -> ControlFlow<i
|
||||
const PRINT_DEBUG_CATEGORIES_ARG: char = 2 as char;
|
||||
const PROFILE_STARTUP_ARG: char = 3 as char;
|
||||
|
||||
const SHORT_OPTS: &wstr = L!("+:hPilNnvc:C:p:d:f:D:o:");
|
||||
const SHORT_OPTS: &wstr = L!("+hPilNnvc:C:p:d:f:D:o:");
|
||||
const LONG_OPTS: &[WOption<'static>] = &[
|
||||
wopt(L!("command"), RequiredArgument, 'c'),
|
||||
wopt(L!("init-command"), RequiredArgument, 'C'),
|
||||
@@ -359,6 +359,13 @@ fn fish_parse_opt(args: &mut [WString], opts: &mut FishCmdOpts) -> ControlFlow<i
|
||||
);
|
||||
return ControlFlow::Break(1);
|
||||
}
|
||||
';' => {
|
||||
eprintf!(
|
||||
"%ls\n",
|
||||
wgettext_fmt!(BUILTIN_ERR_UNEXP_ARG, "fish", args[w.wopt_index - 1])
|
||||
);
|
||||
return ControlFlow::Break(1);
|
||||
}
|
||||
_ => panic!("unexpected retval from WGetopter"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,7 +453,7 @@ pub fn abbr(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Bui
|
||||
// Note the leading '-' causes wgetopter to return arguments in order, instead of permuting
|
||||
// them. We need this behavior for compatibility with pre-builtin abbreviations where options
|
||||
// could be given literally, for example `abbr e emacs -nw`.
|
||||
const short_options: &wstr = L!("-:ac:f:r:seqgUh");
|
||||
const short_options: &wstr = L!("-ac:f:r:seqgUh");
|
||||
|
||||
const longopts: &[WOption] = &[
|
||||
wopt(L!("add"), ArgType::NoArgument, 'a'),
|
||||
@@ -572,6 +572,10 @@ pub fn abbr(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Bui
|
||||
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -83,7 +83,7 @@ fn new() -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
const SHORT_OPTIONS: &wstr = L!("+:hn:siux:N:X:");
|
||||
const SHORT_OPTIONS: &wstr = L!("+hn:siux:N:X:");
|
||||
const LONG_OPTIONS: &[WOption] = &[
|
||||
wopt(L!("stop-nonopt"), ArgType::NoArgument, 's'),
|
||||
wopt(L!("ignore-unknown"), ArgType::NoArgument, 'i'),
|
||||
@@ -574,6 +574,16 @@ fn parse_cmd_opts<'args>(
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
args[w.wopt_index - 1],
|
||||
/* print_hints */ false,
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
@@ -858,7 +868,7 @@ fn argparse_parse_flags<'args>(
|
||||
|
||||
// "+" means stop at nonopt, "-" means give nonoptions the option character code `1`, and don't
|
||||
// reorder.
|
||||
let mut short_options = WString::from(if opts.stop_nonopt { L!("+:") } else { L!("-:") });
|
||||
let mut short_options = WString::from(if opts.stop_nonopt { L!("+") } else { L!("-") });
|
||||
let mut long_options = vec![];
|
||||
populate_option_strings(opts, &mut short_options, &mut long_options);
|
||||
|
||||
@@ -876,6 +886,16 @@ fn argparse_parse_flags<'args>(
|
||||
);
|
||||
Err(STATUS_INVALID_ARGS)
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
&opts.name,
|
||||
args_read[w.wopt_index - 1],
|
||||
false,
|
||||
);
|
||||
Err(STATUS_INVALID_ARGS)
|
||||
}
|
||||
'?' => {
|
||||
// It's not a recognized flag. See if it's an implicit int flag.
|
||||
let arg_contents = &args_read[w.wopt_index - 1].slice_from(1);
|
||||
|
||||
@@ -407,7 +407,7 @@ fn parse_cmd_opts(
|
||||
streams: &mut IoStreams,
|
||||
) -> BuiltinResult {
|
||||
let cmd = argv[0];
|
||||
let short_options = L!(":aehkKfM:Lm:s");
|
||||
let short_options = L!("aehkKfM:Lm:s");
|
||||
const long_options: &[WOption] = &[
|
||||
wopt(L!("all"), NoArgument, 'a'),
|
||||
wopt(L!("erase"), NoArgument, 'e'),
|
||||
@@ -477,6 +477,10 @@ fn parse_cmd_opts(
|
||||
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -30,7 +30,7 @@ fn parse_options(
|
||||
) -> Result<(Options, usize), ErrorCode> {
|
||||
let cmd = args[0];
|
||||
|
||||
const SHORT_OPTS: &wstr = L!(":eghl");
|
||||
const SHORT_OPTS: &wstr = L!("eghl");
|
||||
const LONG_OPTS: &[WOption] = &[
|
||||
wopt(L!("erase"), ArgType::NoArgument, 'e'),
|
||||
wopt(L!("local"), ArgType::NoArgument, 'l'),
|
||||
@@ -59,6 +59,10 @@ fn parse_options(
|
||||
builtin_missing_argument(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -12,7 +12,7 @@ pub fn r#builtin(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -
|
||||
let print_hints = false;
|
||||
let mut opts: builtin_cmd_opts_t = Default::default();
|
||||
|
||||
const shortopts: &wstr = L!(":hnq");
|
||||
const shortopts: &wstr = L!("hnq");
|
||||
const longopts: &[WOption] = &[
|
||||
wopt(L!("help"), ArgType::NoArgument, 'h'),
|
||||
wopt(L!("names"), ArgType::NoArgument, 'n'),
|
||||
@@ -32,6 +32,16 @@ pub fn r#builtin(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -
|
||||
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
argv[w.wopt_index - 1],
|
||||
print_hints,
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -14,7 +14,7 @@ pub fn r#command(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -
|
||||
let print_hints = false;
|
||||
let mut opts: command_cmd_opts_t = Default::default();
|
||||
|
||||
const shortopts: &wstr = L!(":hasqv");
|
||||
const shortopts: &wstr = L!("hasqv");
|
||||
const longopts: &[WOption] = &[
|
||||
wopt(L!("help"), ArgType::NoArgument, 'h'),
|
||||
wopt(L!("all"), ArgType::NoArgument, 'a'),
|
||||
@@ -39,6 +39,16 @@ pub fn r#command(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -
|
||||
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
argv[w.wopt_index - 1],
|
||||
print_hints,
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -269,7 +269,7 @@ pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr])
|
||||
|
||||
let mut override_buffer = None;
|
||||
|
||||
const short_options: &wstr = L!(":abijpctfxorhI:CBELSsP");
|
||||
const short_options: &wstr = L!("abijpctfxorhI:CBELSsP");
|
||||
let long_options: &[WOption] = &[
|
||||
wopt(L!("append"), ArgType::NoArgument, 'a'),
|
||||
wopt(L!("insert"), ArgType::NoArgument, 'i'),
|
||||
@@ -355,6 +355,10 @@ pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr])
|
||||
builtin_missing_argument(parser, streams, cmd, w.argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, w.argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, w.argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -239,7 +239,7 @@ pub fn complete(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) ->
|
||||
let mut preserve_order = false;
|
||||
let mut unescape_output = true;
|
||||
|
||||
const short_options: &wstr = L!(":a:c:p:s:l:o:d:fFrxeuAn:C::w:hk");
|
||||
const short_options: &wstr = L!("a:c:p:s:l:o:d:fFrxeuAn:C::w:hk");
|
||||
const long_options: &[WOption] = &[
|
||||
wopt(L!("exclusive"), ArgType::NoArgument, 'x'),
|
||||
wopt(L!("no-files"), ArgType::NoArgument, 'f'),
|
||||
@@ -382,6 +382,10 @@ pub fn complete(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) ->
|
||||
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -14,7 +14,7 @@ fn parse_options(
|
||||
) -> Result<(Options, usize), ErrorCode> {
|
||||
let cmd = args[0];
|
||||
|
||||
const SHORT_OPTS: &wstr = L!("+:hi");
|
||||
const SHORT_OPTS: &wstr = L!("+hi");
|
||||
const LONG_OPTS: &[WOption] = &[
|
||||
wopt(L!("help"), ArgType::NoArgument, 'h'),
|
||||
wopt(L!("index"), ArgType::NoArgument, 'i'),
|
||||
@@ -31,6 +31,10 @@ fn parse_options(
|
||||
builtin_missing_argument(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -29,7 +29,7 @@ fn parse_options(
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
};
|
||||
|
||||
const SHORT_OPTS: &wstr = L!("+:Eens");
|
||||
const SHORT_OPTS: &wstr = L!("+Eens");
|
||||
const LONG_OPTS: &[WOption] = &[];
|
||||
|
||||
let mut opts = Options::default();
|
||||
@@ -48,6 +48,9 @@ fn parse_options(
|
||||
builtin_missing_argument(parser, streams, cmd, args[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
panic!("unexpected option arguments are only possible with long options")
|
||||
}
|
||||
'?' => {
|
||||
return Ok((oldopts, w.wopt_index - 1));
|
||||
}
|
||||
|
||||
@@ -212,6 +212,14 @@ fn parse_flags(
|
||||
'V' => {
|
||||
*verbose = true;
|
||||
}
|
||||
';' => {
|
||||
streams.err.append(wgettext_fmt!(
|
||||
BUILTIN_ERR_UNEXP_ARG,
|
||||
"fish_key_reader",
|
||||
w.argv[w.wopt_index - 1]
|
||||
));
|
||||
return ControlFlow::Break(Err(STATUS_CMD_ERROR));
|
||||
}
|
||||
'?' => {
|
||||
streams.err.append(wgettext_fmt!(
|
||||
BUILTIN_ERR_UNKNOWN,
|
||||
|
||||
@@ -40,7 +40,7 @@ fn default() -> Self {
|
||||
|
||||
// This command is atypical in using the "-" (RETURN_IN_ORDER) option for flag parsing.
|
||||
// This is needed due to the semantics of the -a/--argument-names flag.
|
||||
const SHORT_OPTIONS: &wstr = L!("-:a:d:e:hj:p:s:v:w:SV:");
|
||||
const SHORT_OPTIONS: &wstr = L!("-a:d:e:hj:p:s:v:w:SV:");
|
||||
#[rustfmt::skip]
|
||||
const LONG_OPTIONS: &[WOption] = &[
|
||||
wopt(L!("description"), ArgType::RequiredArgument, 'd'),
|
||||
@@ -219,6 +219,16 @@ fn parse_cmd_opts(
|
||||
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return STATUS_INVALID_ARGS;
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
argv[w.wopt_index - 1],
|
||||
print_hints,
|
||||
);
|
||||
return STATUS_INVALID_ARGS;
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return STATUS_INVALID_ARGS;
|
||||
|
||||
@@ -49,7 +49,7 @@ fn default() -> Self {
|
||||
|
||||
const NO_METADATA_SHORT: char = 2 as char;
|
||||
|
||||
const SHORT_OPTIONS: &wstr = L!(":Ht:Dacd:ehnqv");
|
||||
const SHORT_OPTIONS: &wstr = L!("Ht:Dacd:ehnqv");
|
||||
#[rustfmt::skip]
|
||||
const LONG_OPTIONS: &[WOption] = &[
|
||||
wopt(L!("erase"), ArgType::NoArgument, 'e'),
|
||||
@@ -101,6 +101,16 @@ fn parse_cmd_opts<'args>(
|
||||
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
argv[w.wopt_index - 1],
|
||||
print_hints,
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -66,7 +66,7 @@ struct HistoryCmdOpts {
|
||||
/// the non-flag subcommand form. While many of these flags are deprecated they must be
|
||||
/// supported at least until fish 3.0 and possibly longer to avoid breaking everyones
|
||||
/// config.fish and other scripts.
|
||||
const short_options: &wstr = L!(":CRcehmn:pt::z");
|
||||
const short_options: &wstr = L!("CRcehmn:pt::z");
|
||||
const longopts: &[WOption] = &[
|
||||
wopt(L!("prefix"), ArgType::NoArgument, 'p'),
|
||||
wopt(L!("contains"), ArgType::NoArgument, 'c'),
|
||||
@@ -211,6 +211,10 @@ fn parse_cmd_opts(
|
||||
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
// Try to parse it as a number; e.g., "-123".
|
||||
match fish_wcstol(&w.argv[w.wopt_index - 1][1..]) {
|
||||
|
||||
@@ -117,7 +117,7 @@ fn builtin_jobs_print(j: &Job, mode: JobsPrintMode, header: bool, streams: &mut
|
||||
};
|
||||
}
|
||||
|
||||
const SHORT_OPTIONS: &wstr = L!(":cghlpq");
|
||||
const SHORT_OPTIONS: &wstr = L!("cghlpq");
|
||||
const LONG_OPTIONS: &[WOption] = &[
|
||||
wopt(L!("command"), ArgType::NoArgument, 'c'),
|
||||
wopt(L!("group"), ArgType::NoArgument, 'g'),
|
||||
@@ -166,6 +166,10 @@ pub fn jobs(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Bui
|
||||
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -38,7 +38,7 @@ fn parse_cmd_opts(
|
||||
|
||||
// This command is atypical in using the "+" (REQUIRE_ORDER) option for flag parsing.
|
||||
// This is needed because of the minus, `-`, operator in math expressions.
|
||||
const SHORT_OPTS: &wstr = L!("+:hs:b:m:");
|
||||
const SHORT_OPTS: &wstr = L!("+hs:b:m:");
|
||||
const LONG_OPTS: &[WOption] = &[
|
||||
wopt(L!("scale"), ArgType::RequiredArgument, 's'),
|
||||
wopt(L!("base"), ArgType::RequiredArgument, 'b'),
|
||||
@@ -120,6 +120,16 @@ fn parse_cmd_opts(
|
||||
builtin_missing_argument(parser, streams, cmd, args[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
args[w.wopt_index - 1],
|
||||
print_hints,
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
// For most commands this is an error. We ignore it because a math expression
|
||||
// can begin with a minus sign.
|
||||
|
||||
@@ -178,7 +178,7 @@ fn path_out(streams: &mut IoStreams, opts: &Options<'_>, s: impl AsRef<wstr>) {
|
||||
|
||||
fn construct_short_opts(opts: &Options) -> WString {
|
||||
// All commands accept -z, -Z and -q
|
||||
let mut short_opts = WString::from(":zZq");
|
||||
let mut short_opts = WString::from("zZq");
|
||||
if opts.perms_valid {
|
||||
short_opts += L!("p:");
|
||||
short_opts += L!("rwx");
|
||||
@@ -247,6 +247,17 @@ fn parse_opts<'args>(
|
||||
builtin_missing_argument(parser, streams, cmd, args_read[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
streams.err.append(L!("path ")); // clone of string_error
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
args_read[w.wopt_index - 1],
|
||||
false,
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
path_unknown_option(parser, streams, cmd, args_read[w.wopt_index - 1]);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -25,6 +25,10 @@ pub fn pwd(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Buil
|
||||
builtin_print_help(parser, streams, cmd);
|
||||
return Ok(SUCCESS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, argv[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -14,7 +14,7 @@ pub fn random(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> B
|
||||
let argc = argv.len();
|
||||
let print_hints = false;
|
||||
|
||||
const shortopts: &wstr = L!("+:h");
|
||||
const shortopts: &wstr = L!("+h");
|
||||
const longopts: &[WOption] = &[wopt(L!("help"), ArgType::NoArgument, 'h')];
|
||||
|
||||
let mut w = WGetopter::new(shortopts, longopts, argv);
|
||||
@@ -29,6 +29,16 @@ pub fn random(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> B
|
||||
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
argv[w.wopt_index - 1],
|
||||
print_hints,
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -63,7 +63,7 @@ fn new() -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
const SHORT_OPTIONS: &wstr = L!(":ac:d:fghiLln:p:sStuxzP:UR:L");
|
||||
const SHORT_OPTIONS: &wstr = L!("ac:d:fghiLln:p:sStuxzP:UR:L");
|
||||
const LONG_OPTIONS: &[WOption] = &[
|
||||
wopt(L!("array"), ArgType::NoArgument, 'a'),
|
||||
wopt(L!("command"), ArgType::RequiredArgument, 'c'),
|
||||
@@ -185,6 +185,10 @@ fn parse_cmd_opts(
|
||||
builtin_missing_argument(parser, streams, cmd, args[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, args[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, args[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -15,7 +15,7 @@ struct Options {
|
||||
no_symlinks: bool,
|
||||
}
|
||||
|
||||
const short_options: &wstr = L!("+:hs");
|
||||
const short_options: &wstr = L!("+hs");
|
||||
const long_options: &[WOption] = &[
|
||||
wopt(L!("no-symlinks"), NoArgument, 's'),
|
||||
wopt(L!("help"), NoArgument, 'h'),
|
||||
@@ -40,6 +40,10 @@ fn parse_options(
|
||||
builtin_missing_argument(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -16,7 +16,7 @@ fn parse_options(
|
||||
) -> ControlFlow<ErrorCode, (Options, usize)> {
|
||||
let cmd = args[0];
|
||||
|
||||
const SHORT_OPTS: &wstr = L!(":h");
|
||||
const SHORT_OPTS: &wstr = L!("h");
|
||||
const LONG_OPTS: &[WOption] = &[wopt(L!("help"), ArgType::NoArgument, 'h')];
|
||||
|
||||
let mut opts = Options::default();
|
||||
@@ -30,6 +30,10 @@ fn parse_options(
|
||||
builtin_missing_argument(parser, streams, cmd, args[w.wopt_index - 1], true);
|
||||
return ControlFlow::Break(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, args[w.wopt_index - 1], true);
|
||||
return ControlFlow::Break(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
// We would normally invoke builtin_unknown_option() and return an error.
|
||||
// But for this command we want to let it try and parse the value as a negative
|
||||
|
||||
@@ -108,7 +108,7 @@ fn parse(
|
||||
// Variables used for parsing the argument list. This command is atypical in using the "+"
|
||||
// (REQUIRE_ORDER) option for flag parsing. This is not typical of most fish commands. It means
|
||||
// we stop scanning for flags when the first non-flag argument is seen.
|
||||
const SHORT_OPTS: &wstr = L!("+:LSUaefghlnpqux");
|
||||
const SHORT_OPTS: &wstr = L!("+LSUaefghlnpqux");
|
||||
const LONG_OPTS: &[WOption] = &[
|
||||
wopt(L!("export"), NoArgument, 'x'),
|
||||
wopt(L!("global"), NoArgument, 'g'),
|
||||
@@ -167,6 +167,16 @@ fn parse(
|
||||
builtin_missing_argument(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
args[w.wopt_index - 1],
|
||||
false,
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
// Specifically detect `set -o` because people might be bringing over bashisms.
|
||||
let optind = w.wopt_index;
|
||||
|
||||
@@ -86,6 +86,16 @@ pub fn set_color(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -
|
||||
// In future we change both to actually print an error.
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(UnexpectedOptArg(option_index)) => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
L!("set_color"),
|
||||
argv[option_index],
|
||||
true, /* print_hints */
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
Err(UnknownColor(arg)) => {
|
||||
streams
|
||||
.err
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
pub BUILTIN_ERR_MISSING
|
||||
"%ls: %ls: option requires an argument\n"
|
||||
|
||||
/// Error message on unexpected argument.
|
||||
pub BUILTIN_ERR_UNEXP_ARG
|
||||
"%ls: %ls: option does not take an argument\n"
|
||||
|
||||
/// Error message on missing man page.
|
||||
pub BUILTIN_ERR_MISSING_HELP
|
||||
"fish: %ls: missing man page\nDocumentation may not be installed.\n`help %ls` will show an online version\n"
|
||||
@@ -694,6 +698,22 @@ pub fn builtin_missing_argument(
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform error reporting for encounter with an extra argument.
|
||||
pub fn builtin_unexpected_argument(
|
||||
parser: &Parser,
|
||||
streams: &mut IoStreams,
|
||||
cmd: &wstr,
|
||||
opt: &wstr,
|
||||
print_hints: bool, /*=true*/
|
||||
) {
|
||||
streams
|
||||
.err
|
||||
.append(wgettext_fmt!(BUILTIN_ERR_UNEXP_ARG, cmd, opt));
|
||||
if print_hints {
|
||||
builtin_print_error_trailer(parser, streams.err, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/// Print the backtrace and call for help that we use at the end of error messages.
|
||||
pub fn builtin_print_error_trailer(parser: &Parser, b: &mut OutputStream, cmd: &wstr) {
|
||||
b.push('\n');
|
||||
@@ -736,7 +756,7 @@ pub fn parse(
|
||||
let cmd = args[0];
|
||||
let print_hints = true;
|
||||
|
||||
const shortopts: &wstr = L!("+:h");
|
||||
const shortopts: &wstr = L!("+h");
|
||||
const longopts: &[WOption] = &[wopt(L!("help"), ArgType::NoArgument, 'h')];
|
||||
|
||||
let mut print_help = false;
|
||||
@@ -756,6 +776,16 @@ pub fn parse(
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
args[w.wopt_index - 1],
|
||||
print_hints,
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(
|
||||
parser,
|
||||
|
||||
@@ -150,7 +150,7 @@ fn default() -> Self {
|
||||
const IS_NO_JOB_CTRL_SHORT: char = '\x04';
|
||||
const IS_INTERACTIVE_READ_SHORT: char = '\x05';
|
||||
|
||||
const SHORT_OPTIONS: &wstr = L!(":L:cbilfnhj:t");
|
||||
const SHORT_OPTIONS: &wstr = L!("L:cbilfnhj:t");
|
||||
const LONG_OPTIONS: &[WOption] = &[
|
||||
wopt(L!("help"), NoArgument, 'h'),
|
||||
wopt(L!("current-filename"), NoArgument, 'f'),
|
||||
@@ -304,6 +304,10 @@ fn parse_cmd_opts(
|
||||
builtin_missing_argument(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, args[w.wopt_index - 1], false);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -71,6 +71,17 @@ fn parse_opts(
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
streams.err.append(L!("string ")); // clone of string_error
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
args_read[w.wopt_index - 1],
|
||||
false,
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
string_unknown_option(parser, streams, cmd, args_read[w.wopt_index - 1]);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -11,7 +11,7 @@ impl StringSubCommand<'_> for Collect {
|
||||
wopt(L!("allow-empty"), NoArgument, 'a'),
|
||||
wopt(L!("no-trim-newlines"), NoArgument, 'N'),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":Na");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("Na");
|
||||
|
||||
fn parse_opt(&mut self, _n: &wstr, c: char, _arg: Option<&wstr>) -> Result<(), StringError> {
|
||||
match c {
|
||||
|
||||
@@ -12,7 +12,7 @@ impl StringSubCommand<'_> for Escape {
|
||||
wopt(L!("no-quoted"), NoArgument, 'n'),
|
||||
wopt(L!("style"), RequiredArgument, NON_OPTION_CHAR),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":n");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("n");
|
||||
|
||||
fn parse_opt(&mut self, name: &wstr, c: char, arg: Option<&wstr>) -> Result<(), StringError> {
|
||||
match c {
|
||||
|
||||
@@ -23,7 +23,7 @@ impl<'args> StringSubCommand<'args> for Join<'args> {
|
||||
wopt(L!("quiet"), NoArgument, 'q'),
|
||||
wopt(L!("no-empty"), NoArgument, 'n'),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":qn");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("qn");
|
||||
|
||||
fn parse_opt(&mut self, _n: &wstr, c: char, _arg: Option<&wstr>) -> Result<(), StringError> {
|
||||
match c {
|
||||
|
||||
@@ -11,7 +11,7 @@ impl StringSubCommand<'_> for Length {
|
||||
wopt(L!("quiet"), NoArgument, 'q'),
|
||||
wopt(L!("visible"), NoArgument, 'V'),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":qV");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("qV");
|
||||
|
||||
fn parse_opt(&mut self, _n: &wstr, c: char, _arg: Option<&wstr>) -> Result<(), StringError> {
|
||||
match c {
|
||||
|
||||
@@ -34,7 +34,7 @@ impl<'args> StringSubCommand<'args> for Match<'args> {
|
||||
wopt(L!("index"), NoArgument, 'n'),
|
||||
wopt(L!("max-matches"), RequiredArgument, 'm'),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":aegivqrnm:");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("aegivqrnm:");
|
||||
|
||||
fn parse_opt(&mut self, _n: &wstr, c: char, arg: Option<&wstr>) -> Result<(), StringError> {
|
||||
match c {
|
||||
|
||||
@@ -26,7 +26,7 @@ impl StringSubCommand<'_> for Pad {
|
||||
wopt(L!("right"), NoArgument, 'r'),
|
||||
wopt(L!("width"), RequiredArgument, 'w'),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":c:rw:");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("c:rw:");
|
||||
|
||||
fn parse_opt(&mut self, name: &wstr, c: char, arg: Option<&wstr>) -> Result<(), StringError> {
|
||||
match c {
|
||||
|
||||
@@ -15,7 +15,7 @@ impl StringSubCommand<'_> for Repeat {
|
||||
wopt(L!("quiet"), NoArgument, 'q'),
|
||||
wopt(L!("no-newline"), NoArgument, 'N'),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":n:m:qN");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("n:m:qN");
|
||||
|
||||
fn parse_opt(&mut self, name: &wstr, c: char, arg: Option<&wstr>) -> Result<(), StringError> {
|
||||
match c {
|
||||
|
||||
@@ -26,7 +26,7 @@ impl<'args> StringSubCommand<'args> for Replace<'args> {
|
||||
wopt(L!("regex"), NoArgument, 'r'),
|
||||
wopt(L!("max-matches"), RequiredArgument, 'm'),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":afiqrm:");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("afiqrm:");
|
||||
|
||||
fn parse_opt(&mut self, _n: &wstr, c: char, arg: Option<&wstr>) -> Result<(), StringError> {
|
||||
match c {
|
||||
|
||||
@@ -32,7 +32,7 @@ impl<'args> StringSubCommand<'args> for Shorten<'args> {
|
||||
wopt(L!("left"), NoArgument, 'l'),
|
||||
wopt(L!("quiet"), NoArgument, 'q'),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":c:m:Nlq");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("c:m:Nlq");
|
||||
|
||||
fn parse_opt(
|
||||
&mut self,
|
||||
|
||||
@@ -110,7 +110,7 @@ impl<'args> StringSubCommand<'args> for Split<'args> {
|
||||
wopt(L!("fields"), RequiredArgument, 'f'),
|
||||
wopt(L!("allow-empty"), NoArgument, 'a'),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":qrm:nf:a");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("qrm:nf:a");
|
||||
|
||||
fn parse_opt(&mut self, name: &wstr, c: char, arg: Option<&wstr>) -> Result<(), StringError> {
|
||||
match c {
|
||||
|
||||
@@ -17,7 +17,7 @@ impl StringSubCommand<'_> for Sub {
|
||||
wopt(L!("end"), RequiredArgument, 'e'),
|
||||
wopt(L!("quiet"), NoArgument, 'q'),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":l:qs:e:");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("l:qs:e:");
|
||||
|
||||
fn parse_opt(&mut self, name: &wstr, c: char, arg: Option<&wstr>) -> Result<(), StringError> {
|
||||
match c {
|
||||
|
||||
@@ -7,7 +7,7 @@ pub struct Transform {
|
||||
|
||||
impl StringSubCommand<'_> for Transform {
|
||||
const LONG_OPTIONS: &'static [WOption<'static>] = &[wopt(L!("quiet"), NoArgument, 'q')];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":q");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("q");
|
||||
fn parse_opt(&mut self, _n: &wstr, c: char, _arg: Option<&wstr>) -> Result<(), StringError> {
|
||||
match c {
|
||||
'q' => self.quiet = true,
|
||||
|
||||
@@ -26,7 +26,7 @@ impl<'args> StringSubCommand<'args> for Trim<'args> {
|
||||
wopt(L!("right"), NoArgument, 'r'),
|
||||
wopt(L!("quiet"), NoArgument, 'q'),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":c:lrq");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("c:lrq");
|
||||
|
||||
fn parse_opt(
|
||||
&mut self,
|
||||
|
||||
@@ -14,7 +14,7 @@ impl StringSubCommand<'_> for Unescape {
|
||||
wopt(L!("no-quoted"), NoArgument, 'n'),
|
||||
wopt(L!("style"), RequiredArgument, NON_OPTION_CHAR),
|
||||
];
|
||||
const SHORT_OPTIONS: &'static wstr = L!(":n");
|
||||
const SHORT_OPTIONS: &'static wstr = L!("n");
|
||||
|
||||
fn parse_opt(&mut self, name: &wstr, c: char, arg: Option<&wstr>) -> Result<(), StringError> {
|
||||
match c {
|
||||
|
||||
@@ -23,7 +23,7 @@ pub fn r#type(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> B
|
||||
let print_hints = false;
|
||||
let mut opts: type_cmd_opts_t = Default::default();
|
||||
|
||||
const shortopts: &wstr = L!(":hasftpPq");
|
||||
const shortopts: &wstr = L!("hasftpPq");
|
||||
const longopts: &[WOption] = &[
|
||||
wopt(L!("help"), ArgType::NoArgument, 'h'),
|
||||
wopt(L!("all"), ArgType::NoArgument, 'a'),
|
||||
@@ -54,6 +54,16 @@ pub fn r#type(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> B
|
||||
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
argv[w.wopt_index - 1],
|
||||
print_hints,
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -171,7 +171,7 @@ fn default() -> Self {
|
||||
pub fn ulimit(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> BuiltinResult {
|
||||
let cmd = args[0];
|
||||
|
||||
const SHORT_OPTS: &wstr = L!(":HSabcdefilmnqrstuvwyKPTh");
|
||||
const SHORT_OPTS: &wstr = L!("HSabcdefilmnqrstuvwyKPTh");
|
||||
|
||||
const LONG_OPTS: &[WOption] = &[
|
||||
wopt(L!("all"), ArgType::NoArgument, 'a'),
|
||||
@@ -237,6 +237,10 @@ pub fn ulimit(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> B
|
||||
builtin_missing_argument(parser, streams, cmd, w.argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(parser, streams, cmd, w.argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, w.argv[w.wopt_index - 1], true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -140,7 +140,7 @@ pub fn wait(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Bui
|
||||
let mut print_help = false;
|
||||
let print_hints = false;
|
||||
|
||||
const shortopts: &wstr = L!(":nh");
|
||||
const shortopts: &wstr = L!("nh");
|
||||
const longopts: &[WOption] = &[
|
||||
wopt(L!("any"), ArgType::NoArgument, 'n'),
|
||||
wopt(L!("help"), ArgType::NoArgument, 'h'),
|
||||
@@ -159,6 +159,16 @@ pub fn wait(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Bui
|
||||
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
';' => {
|
||||
builtin_unexpected_argument(
|
||||
parser,
|
||||
streams,
|
||||
cmd,
|
||||
argv[w.wopt_index - 1],
|
||||
print_hints,
|
||||
);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
}
|
||||
'?' => {
|
||||
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], print_hints);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
|
||||
@@ -170,6 +170,7 @@ pub(crate) enum ParsedArgs<'argarray, 'args> {
|
||||
|
||||
pub(crate) enum ParseError<'args> {
|
||||
MissingOptArg,
|
||||
UnexpectedOptArg(usize),
|
||||
UnknownColor(&'args wstr),
|
||||
UnknownUnderlineStyle(&'args wstr),
|
||||
UnknownOption(usize),
|
||||
@@ -180,7 +181,7 @@ pub(crate) fn parse_text_face_and_options<'argarray, 'args>(
|
||||
is_builtin: bool,
|
||||
) -> Result<ParsedArgs<'argarray, 'args>, ParseError<'args>> {
|
||||
let builtin_extra_args = if is_builtin { 0 } else { "hc".len() };
|
||||
let short_options = L!(":b:oidru::ch");
|
||||
let short_options = L!("b:oidru::ch");
|
||||
let short_options = &short_options[..short_options.len() - builtin_extra_args];
|
||||
let long_options: &[WOption] = &[
|
||||
wopt(L!("background"), ArgType::RequiredArgument, 'b'),
|
||||
@@ -262,6 +263,11 @@ pub(crate) fn parse_text_face_and_options<'argarray, 'args>(
|
||||
return Err(MissingOptArg);
|
||||
}
|
||||
}
|
||||
';' => {
|
||||
if is_builtin {
|
||||
return Err(UnexpectedOptArg(w.wopt_index - 1));
|
||||
}
|
||||
}
|
||||
'?' => {
|
||||
if is_builtin {
|
||||
return Err(UnknownOption(w.wopt_index - 1));
|
||||
|
||||
@@ -137,8 +137,6 @@ pub struct WGetopter<'opts, 'args, 'argarray> {
|
||||
/// Used when reordering elements. After scanning is finished, indicates the index
|
||||
/// after the final non-option skipped during parsing.
|
||||
pub last_nonopt: usize,
|
||||
/// Return `:` if an arg is missing.
|
||||
return_colon: bool,
|
||||
/// Prevents redundant initialization.
|
||||
initialized: bool,
|
||||
/// This will be populated with the elements of the original args that were interpreted
|
||||
@@ -163,13 +161,19 @@ pub fn new(
|
||||
ordering: Ordering::Permute,
|
||||
first_nonopt: 0,
|
||||
last_nonopt: 0,
|
||||
return_colon: false,
|
||||
initialized: false,
|
||||
argv_opts: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to get the next option.
|
||||
/// Try to get the next option, returning:
|
||||
/// * None if there are no more options
|
||||
/// * `Some(`[`NON_OPTION_CHAR`]`)` for a non-option when using [`Ordering::ReturnInOrder`]
|
||||
/// * `Some('?') for unrecognised options
|
||||
/// * `Some(':')` for options missing an argument,
|
||||
/// * `Some(';') for options with an unexpected argument (this is only possible when using the
|
||||
/// --long=value or -long=value syntax where long was declared as taking no arguments).
|
||||
/// * Otherwise, `Some(c)`, where `c` is the option's short character
|
||||
pub fn next_opt(&mut self) -> Option<char> {
|
||||
assert!(
|
||||
self.wopt_index <= self.argv.len(),
|
||||
@@ -233,11 +237,6 @@ fn initialize(&mut self) {
|
||||
self.ordering = Ordering::Permute;
|
||||
}
|
||||
|
||||
if optstring.char_at(0) == ':' {
|
||||
self.return_colon = true;
|
||||
optstring = &optstring[1..];
|
||||
}
|
||||
|
||||
self.shortopts = optstring;
|
||||
self.initialized = true;
|
||||
}
|
||||
@@ -371,7 +370,7 @@ fn handle_short_opt(&mut self) -> char {
|
||||
// no following element to consume, then the option
|
||||
// has no argument.
|
||||
self.unrecognized_opt = c;
|
||||
c = if self.return_colon { ':' } else { '?' };
|
||||
c = ':';
|
||||
} else {
|
||||
// Consume the next element.
|
||||
let val = self.argv[self.wopt_index];
|
||||
@@ -398,7 +397,7 @@ fn update_long_opt(
|
||||
if self.remaining_text.char_at(name_end) == '=' {
|
||||
if opt_found.arg_type == ArgType::NoArgument {
|
||||
self.remaining_text = empty_wstr();
|
||||
return '?';
|
||||
return ';';
|
||||
} else {
|
||||
self.woptarg = Some(self.remaining_text[(name_end + 1)..].into());
|
||||
}
|
||||
@@ -410,7 +409,7 @@ fn update_long_opt(
|
||||
self.wopt_index += 1;
|
||||
} else {
|
||||
self.remaining_text = empty_wstr();
|
||||
return if self.return_colon { ':' } else { '?' };
|
||||
return ':';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -639,5 +639,11 @@ begin
|
||||
# CHECK: argv_opts '-abv124' '-abv125' '-abv124' '-vd3'
|
||||
end
|
||||
|
||||
argparse a/alpha -- --banna=value
|
||||
# CHECKERR: argparse: --banna=value: unknown option
|
||||
# But this gives a better message
|
||||
argparse a/alpha -- --alpha=value --banna=value
|
||||
# CHECKERR: argparse: --alpha=value: option does not take an argument
|
||||
|
||||
# Check that the argparse's are properly wrapped in begin blocks
|
||||
set -l
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#RUN: %fish -Z
|
||||
# CHECKERR: {{.*fish}}: {{unrecognized option: Z|invalid option -- '?Z'?|unknown option -- Z|illegal option -- Z|-Z: unknown option}}
|
||||
#RUN: %fish --interactive=value
|
||||
# CHECKERR: {{.*fish}}: --interactive=value: option does not take an argument
|
||||
|
||||
@@ -229,3 +229,8 @@ functions --banana
|
||||
# CHECKERR: functions: --banana: unknown option
|
||||
echo $status
|
||||
# CHECK: 2
|
||||
|
||||
functions --all=arg
|
||||
# CHECKERR: functions: --all=arg: option does not take an argument
|
||||
echo $status
|
||||
# CHECK: 2
|
||||
|
||||
@@ -16,9 +16,12 @@ emit linenumber
|
||||
type --nonexistent-option-so-we-get-a-backtrace
|
||||
# CHECKERR: type: --nonexistent-option-so-we-get-a-backtrace: unknown option
|
||||
|
||||
type --short=cd
|
||||
# CHECKERR: type: --short=cd: option does not take an argument
|
||||
|
||||
function line-number
|
||||
status line-number
|
||||
end
|
||||
|
||||
line-number
|
||||
# CHECK: 20
|
||||
# CHECK: 23
|
||||
|
||||
@@ -13,6 +13,15 @@ string escape (set_color red reset yellow)
|
||||
string escape (set_color --background=reset)
|
||||
# CHECKERR: set_color: Unknown color 'reset'
|
||||
|
||||
string escape (set_color --bold=red)
|
||||
# CHECKERR: set_color: --bold=red: option does not take an argument
|
||||
#CHECKERR: {{.*}}checks/set_color.fish (line {{\d+}}):
|
||||
#CHECKERR: set_color --bold=red
|
||||
#CHECKERR: ^
|
||||
#CHECKERR: in command substitution
|
||||
#CHECKERR: called on line {{\d+}} of file {{.*}}checks/set_color.fish
|
||||
#CHECKERR: (Type 'help set_color' for related documentation)
|
||||
|
||||
string escape (set_color --bold red --background=normal)
|
||||
# CHECK: \e\[31m\e\[49m\e\[1m
|
||||
string escape (set_color --bold red --background=blue)
|
||||
|
||||
Reference in New Issue
Block a user