Skip to content

Commit

Permalink
Rewrite wgetopt.rs to Rustier syntax and naming
Browse files Browse the repository at this point in the history
From #9515

Closes #9515
  • Loading branch information
vertesians authored and ridiculousfish committed Apr 17, 2024
1 parent 2e42d80 commit 13230cd
Show file tree
Hide file tree
Showing 49 changed files with 1,007 additions and 1,114 deletions.
54 changes: 25 additions & 29 deletions src/bin/fish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,44 +313,40 @@ fn run_command_list(parser: &Parser, cmds: &[OsString]) -> i32 {
}

fn fish_parse_opt(args: &mut [WString], opts: &mut FishCmdOpts) -> ControlFlow<i32, usize> {
use fish::wgetopt::{wgetopter_t, wopt, woption, woption_argument_t::*};
use fish::wgetopt::{wopt, ArgType::*, WGetopter, WOption};

const RUSAGE_ARG: char = 1 as char;
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 LONG_OPTS: &[woption<'static>] = &[
wopt(L!("command"), required_argument, 'c'),
wopt(L!("init-command"), required_argument, 'C'),
wopt(L!("features"), required_argument, 'f'),
wopt(L!("debug"), required_argument, 'd'),
wopt(L!("debug-output"), required_argument, 'o'),
wopt(L!("debug-stack-frames"), required_argument, 'D'),
wopt(L!("interactive"), no_argument, 'i'),
wopt(L!("login"), no_argument, 'l'),
wopt(L!("no-config"), no_argument, 'N'),
wopt(L!("no-execute"), no_argument, 'n'),
wopt(L!("print-rusage-self"), no_argument, RUSAGE_ARG),
const LONG_OPTS: &[WOption<'static>] = &[
wopt(L!("command"), RequiredArgument, 'c'),
wopt(L!("init-command"), RequiredArgument, 'C'),
wopt(L!("features"), RequiredArgument, 'f'),
wopt(L!("debug"), RequiredArgument, 'd'),
wopt(L!("debug-output"), RequiredArgument, 'o'),
wopt(L!("debug-stack-frames"), RequiredArgument, 'D'),
wopt(L!("interactive"), NoArgument, 'i'),
wopt(L!("login"), NoArgument, 'l'),
wopt(L!("no-config"), NoArgument, 'N'),
wopt(L!("no-execute"), NoArgument, 'n'),
wopt(L!("print-rusage-self"), NoArgument, RUSAGE_ARG),
wopt(
L!("print-debug-categories"),
no_argument,
NoArgument,
PRINT_DEBUG_CATEGORIES_ARG,
),
wopt(L!("profile"), required_argument, 'p'),
wopt(
L!("profile-startup"),
required_argument,
PROFILE_STARTUP_ARG,
),
wopt(L!("private"), no_argument, 'P'),
wopt(L!("help"), no_argument, 'h'),
wopt(L!("version"), no_argument, 'v'),
wopt(L!("profile"), RequiredArgument, 'p'),
wopt(L!("profile-startup"), RequiredArgument, PROFILE_STARTUP_ARG),
wopt(L!("private"), NoArgument, 'P'),
wopt(L!("help"), NoArgument, 'h'),
wopt(L!("version"), NoArgument, 'v'),
];

let mut shim_args: Vec<&wstr> = args.iter().map(|s| s.as_ref()).collect();
let mut w = wgetopter_t::new(SHORT_OPTS, LONG_OPTS, &mut shim_args);
while let Some(c) = w.wgetopt_long() {
let mut w = WGetopter::new(SHORT_OPTS, LONG_OPTS, &mut shim_args);
while let Some(c) = w.next_opt() {
match c {
'c' => opts
.batch_cmds
Expand Down Expand Up @@ -419,21 +415,21 @@ fn fish_parse_opt(args: &mut [WString], opts: &mut FishCmdOpts) -> ControlFlow<i
'?' => {
eprintln!(
"{}",
wgettext_fmt!(BUILTIN_ERR_UNKNOWN, "fish", args[w.woptind - 1])
wgettext_fmt!(BUILTIN_ERR_UNKNOWN, "fish", args[w.wopt_index - 1])
);
return ControlFlow::Break(1);
}
':' => {
eprintln!(
"{}",
wgettext_fmt!(BUILTIN_ERR_MISSING, "fish", args[w.woptind - 1])
wgettext_fmt!(BUILTIN_ERR_MISSING, "fish", args[w.wopt_index - 1])
);
return ControlFlow::Break(1);
}
_ => panic!("unexpected retval from wgetopter_t"),
_ => panic!("unexpected retval from WGetopter"),
}
}
let optind = w.woptind;
let optind = w.wopt_index;

// If our command name begins with a dash that implies we're a login shell.
opts.is_login |= args[0].char_at(0) == '-';
Expand Down
46 changes: 19 additions & 27 deletions src/bin/fish_indent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use fish::tokenizer::{TokenType, Tokenizer, TOK_SHOW_BLANK_LINES, TOK_SHOW_COMME
use fish::topic_monitor::topic_monitor_init;
use fish::wchar::prelude::*;
use fish::wcstringutil::count_preceding_backslashes;
use fish::wgetopt::{wgetopter_t, wopt, woption, woption_argument_t};
use fish::wgetopt::{wopt, ArgType, WGetopter, WOption};
use fish::wutil::perror;
use fish::wutil::{fish_iswalnum, write_to_fd};
use fish::{
Expand Down Expand Up @@ -779,38 +779,30 @@ fn throwing_main() -> i32 {
let mut debug_output = None;

let short_opts: &wstr = L!("+d:hvwicD:");
let long_opts: &[woption] = &[
wopt(L!("debug"), woption_argument_t::required_argument, 'd'),
wopt(
L!("debug-output"),
woption_argument_t::required_argument,
'o',
),
wopt(
L!("debug-stack-frames"),
woption_argument_t::required_argument,
'D',
),
wopt(L!("dump-parse-tree"), woption_argument_t::no_argument, 'P'),
wopt(L!("no-indent"), woption_argument_t::no_argument, 'i'),
wopt(L!("only-indent"), woption_argument_t::no_argument, '\x04'),
wopt(L!("only-unindent"), woption_argument_t::no_argument, '\x05'),
wopt(L!("help"), woption_argument_t::no_argument, 'h'),
wopt(L!("version"), woption_argument_t::no_argument, 'v'),
wopt(L!("write"), woption_argument_t::no_argument, 'w'),
wopt(L!("html"), woption_argument_t::no_argument, '\x01'),
wopt(L!("ansi"), woption_argument_t::no_argument, '\x02'),
wopt(L!("pygments"), woption_argument_t::no_argument, '\x03'),
wopt(L!("check"), woption_argument_t::no_argument, 'c'),
let long_opts: &[WOption] = &[
wopt(L!("debug"), ArgType::RequiredArgument, 'd'),
wopt(L!("debug-output"), ArgType::RequiredArgument, 'o'),
wopt(L!("debug-stack-frames"), ArgType::RequiredArgument, 'D'),
wopt(L!("dump-parse-tree"), ArgType::NoArgument, 'P'),
wopt(L!("no-indent"), ArgType::NoArgument, 'i'),
wopt(L!("only-indent"), ArgType::NoArgument, '\x04'),
wopt(L!("only-unindent"), ArgType::NoArgument, '\x05'),
wopt(L!("help"), ArgType::NoArgument, 'h'),
wopt(L!("version"), ArgType::NoArgument, 'v'),
wopt(L!("write"), ArgType::NoArgument, 'w'),
wopt(L!("html"), ArgType::NoArgument, '\x01'),
wopt(L!("ansi"), ArgType::NoArgument, '\x02'),
wopt(L!("pygments"), ArgType::NoArgument, '\x03'),
wopt(L!("check"), ArgType::NoArgument, 'c'),
];

let args: Vec<WString> = std::env::args_os()
.map(|osstr| str2wcstring(osstr.as_bytes()))
.collect();
let mut shim_args: Vec<&wstr> = args.iter().map(|s| s.as_ref()).collect();
let mut w = wgetopter_t::new(short_opts, long_opts, &mut shim_args);
let mut w = WGetopter::new(short_opts, long_opts, &mut shim_args);

while let Some(c) = w.wgetopt_long() {
while let Some(c) = w.next_opt() {
match c {
'P' => DUMP_PARSE_TREE.store(true),
'h' => {
Expand Down Expand Up @@ -855,7 +847,7 @@ fn throwing_main() -> i32 {
}
}

let args = &w.argv[w.woptind..];
let args = &w.argv[w.wopt_index..];

// Direct any debug output right away.
if let Some(debug_output) = debug_output {
Expand Down
20 changes: 10 additions & 10 deletions src/bin/fish_key_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use fish::{
threads,
topic_monitor::topic_monitor_init,
wchar::prelude::*,
wgetopt::{wgetopter_t, wopt, woption, woption_argument_t},
wgetopt::{wopt, ArgType, WGetopter, WOption},
};

/// Return true if the recent sequence of characters indicates the user wants to exit the program.
Expand Down Expand Up @@ -145,19 +145,19 @@ fn setup_and_process_keys(continuous_mode: bool) -> i32 {

fn parse_flags(continuous_mode: &mut bool) -> ControlFlow<i32> {
let short_opts: &wstr = L!("+chvV");
let long_opts: &[woption] = &[
wopt(L!("continuous"), woption_argument_t::no_argument, 'c'),
wopt(L!("help"), woption_argument_t::no_argument, 'h'),
wopt(L!("version"), woption_argument_t::no_argument, 'v'),
wopt(L!("verbose"), woption_argument_t::no_argument, 'V'), // Removed
let long_opts: &[WOption] = &[
wopt(L!("continuous"), ArgType::NoArgument, 'c'),
wopt(L!("help"), ArgType::NoArgument, 'h'),
wopt(L!("version"), ArgType::NoArgument, 'v'),
wopt(L!("verbose"), ArgType::NoArgument, 'V'), // Removed
];

let args: Vec<WString> = std::env::args_os()
.map(|osstr| str2wcstring(osstr.as_bytes()))
.collect();
let mut shim_args: Vec<&wstr> = args.iter().map(|s| s.as_ref()).collect();
let mut w = wgetopter_t::new(short_opts, long_opts, &mut shim_args);
while let Some(opt) = w.wgetopt_long() {
let mut w = WGetopter::new(short_opts, long_opts, &mut shim_args);
while let Some(opt) = w.next_opt() {
match opt {
'c' => {
*continuous_mode = true;
Expand All @@ -184,7 +184,7 @@ fn parse_flags(continuous_mode: &mut bool) -> ControlFlow<i32> {
wgettext_fmt!(
BUILTIN_ERR_UNKNOWN,
"fish_key_reader",
w.argv[w.woptind - 1]
w.argv[w.wopt_index - 1]
)
);
return ControlFlow::Break(1);
Expand All @@ -193,7 +193,7 @@ fn parse_flags(continuous_mode: &mut bool) -> ControlFlow<i32> {
}
}

let argc = args.len() - w.woptind;
let argc = args.len() - w.wopt_index;
if argc != 0 {
eprintf!("Expected no arguments, got %d\n", argc);
return ControlFlow::Break(1);
Expand Down
40 changes: 20 additions & 20 deletions src/builtins/abbr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,30 +435,30 @@ pub fn abbr(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Opt
// could be given literally, for example `abbr e emacs -nw`.
const short_options: &wstr = L!("-:af:r:seqgUh");

const longopts: &[woption] = &[
wopt(L!("add"), woption_argument_t::no_argument, 'a'),
wopt(L!("position"), woption_argument_t::required_argument, 'p'),
wopt(L!("regex"), woption_argument_t::required_argument, 'r'),
const longopts: &[WOption] = &[
wopt(L!("add"), ArgType::NoArgument, 'a'),
wopt(L!("position"), ArgType::RequiredArgument, 'p'),
wopt(L!("regex"), ArgType::RequiredArgument, 'r'),
wopt(
L!("set-cursor"),
woption_argument_t::optional_argument,
ArgType::OptionalArgument,
SET_CURSOR_SHORT,
),
wopt(L!("function"), woption_argument_t::required_argument, 'f'),
wopt(L!("rename"), woption_argument_t::no_argument, RENAME_SHORT),
wopt(L!("erase"), woption_argument_t::no_argument, 'e'),
wopt(L!("query"), woption_argument_t::no_argument, 'q'),
wopt(L!("show"), woption_argument_t::no_argument, 's'),
wopt(L!("list"), woption_argument_t::no_argument, 'l'),
wopt(L!("global"), woption_argument_t::no_argument, 'g'),
wopt(L!("universal"), woption_argument_t::no_argument, 'U'),
wopt(L!("help"), woption_argument_t::no_argument, 'h'),
wopt(L!("function"), ArgType::RequiredArgument, 'f'),
wopt(L!("rename"), ArgType::NoArgument, RENAME_SHORT),
wopt(L!("erase"), ArgType::NoArgument, 'e'),
wopt(L!("query"), ArgType::NoArgument, 'q'),
wopt(L!("show"), ArgType::NoArgument, 's'),
wopt(L!("list"), ArgType::NoArgument, 'l'),
wopt(L!("global"), ArgType::NoArgument, 'g'),
wopt(L!("universal"), ArgType::NoArgument, 'U'),
wopt(L!("help"), ArgType::NoArgument, 'h'),
];

let mut opts = Options::default();
let mut w = wgetopter_t::new(short_options, longopts, argv);
let mut w = WGetopter::new(short_options, longopts, argv);

while let Some(c) = w.wgetopt_long() {
while let Some(c) = w.next_opt() {
match c {
NON_OPTION_ARGUMENT => {
// If --add is specified (or implied by specifying no other commands), all
Expand Down Expand Up @@ -538,7 +538,7 @@ pub fn abbr(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Opt
streams.err.append(wgettext_fmt!(
"%ls: Warning: Option '%ls' was removed and is now ignored",
cmd,
argv_read[w.woptind - 1]
argv_read[w.wopt_index - 1]
));
builtin_print_error_trailer(parser, streams.err, cmd);
}
Expand All @@ -547,11 +547,11 @@ pub fn abbr(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Opt
return STATUS_CMD_OK;
}
':' => {
builtin_missing_argument(parser, streams, cmd, argv[w.woptind - 1], true);
builtin_missing_argument(parser, streams, cmd, argv[w.wopt_index - 1], true);
return STATUS_INVALID_ARGS;
}
'?' => {
builtin_unknown_option(parser, streams, cmd, argv[w.woptind - 1], false);
builtin_unknown_option(parser, streams, cmd, argv[w.wopt_index - 1], false);
return STATUS_INVALID_ARGS;
}
_ => {
Expand All @@ -560,7 +560,7 @@ pub fn abbr(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Opt
}
}

for arg in argv_read[w.woptind..].iter() {
for arg in argv_read[w.wopt_index..].iter() {
opts.args.push((*arg).into());
}

Expand Down
Loading

0 comments on commit 13230cd

Please sign in to comment.