From 09cd7c7ad9aebd27a32cd116ba5acaaee4fe2ec4 Mon Sep 17 00:00:00 2001 From: Fabian Boehm Date: Fri, 12 Jan 2024 19:10:56 +0100 Subject: [PATCH] Remove widestring-suffix uses This removes both the `#[widestrs]` annotation as well as all `"foo"L` suffixes, and does a `cargo fmt` run on the result --- src/ast.rs | 102 +++++++++++------------ src/autoload.rs | 67 ++++++++------- src/builtins/emit.rs | 3 +- src/builtins/math.rs | 33 ++++---- src/builtins/shared.rs | 139 +++++++++++++++---------------- src/builtins/tests/test_tests.rs | 7 +- src/builtins/wait.rs | 7 +- src/color.rs | 82 +++++++++--------- src/common.rs | 26 +++--- src/env/environment_impl.rs | 37 ++++---- src/env/var.rs | 31 ++++--- src/event.rs | 30 ++++--- src/exec.rs | 8 +- src/expand.rs | 12 ++- src/future_feature_flags.rs | 39 ++++----- src/history.rs | 4 +- src/parse_constants.rs | 128 ++++++++++++++-------------- src/parse_util.rs | 13 ++- src/parser.rs | 28 +++---- src/parser_keywords.rs | 56 ++++++++----- src/path.rs | 62 +++++++------- src/proc.rs | 16 ++-- src/signal.rs | 75 ++++++++--------- src/tests/env.rs | 8 +- src/tests/string_escape.rs | 54 ++++++------ src/tinyexpr.rs | 66 +++++++-------- src/tokenizer.rs | 3 +- src/topic_monitor.rs | 2 - src/wchar.rs | 12 --- src/wutil/mod.rs | 6 +- src/wutil/tests.rs | 25 +++--- 31 files changed, 567 insertions(+), 614 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index e9ba95d26..335896b39 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -2224,47 +2224,46 @@ impl BlockStatementHeaderVariant { } /// \return a string literal name for an ast type. -#[widestrs] pub fn ast_type_to_string(t: Type) -> &'static wstr { match t { - Type::token_base => "token_base"L, - Type::keyword_base => "keyword_base"L, - Type::redirection => "redirection"L, - Type::variable_assignment => "variable_assignment"L, - Type::variable_assignment_list => "variable_assignment_list"L, - Type::argument_or_redirection => "argument_or_redirection"L, - Type::argument_or_redirection_list => "argument_or_redirection_list"L, - Type::statement => "statement"L, - Type::job_pipeline => "job_pipeline"L, - Type::job_conjunction => "job_conjunction"L, - Type::for_header => "for_header"L, - Type::while_header => "while_header"L, - Type::function_header => "function_header"L, - Type::begin_header => "begin_header"L, - Type::block_statement => "block_statement"L, - Type::if_clause => "if_clause"L, - Type::elseif_clause => "elseif_clause"L, - Type::elseif_clause_list => "elseif_clause_list"L, - Type::else_clause => "else_clause"L, - Type::if_statement => "if_statement"L, - Type::case_item => "case_item"L, - Type::switch_statement => "switch_statement"L, - Type::decorated_statement => "decorated_statement"L, - Type::not_statement => "not_statement"L, - Type::job_continuation => "job_continuation"L, - Type::job_continuation_list => "job_continuation_list"L, - Type::job_conjunction_continuation => "job_conjunction_continuation"L, - Type::andor_job => "andor_job"L, - Type::andor_job_list => "andor_job_list"L, - Type::freestanding_argument_list => "freestanding_argument_list"L, - Type::token_conjunction => "token_conjunction"L, - Type::job_conjunction_continuation_list => "job_conjunction_continuation_list"L, - Type::maybe_newlines => "maybe_newlines"L, - Type::token_pipe => "token_pipe"L, - Type::case_item_list => "case_item_list"L, - Type::argument => "argument"L, - Type::argument_list => "argument_list"L, - Type::job_list => "job_list"L, + Type::token_base => L!("token_base"), + Type::keyword_base => L!("keyword_base"), + Type::redirection => L!("redirection"), + Type::variable_assignment => L!("variable_assignment"), + Type::variable_assignment_list => L!("variable_assignment_list"), + Type::argument_or_redirection => L!("argument_or_redirection"), + Type::argument_or_redirection_list => L!("argument_or_redirection_list"), + Type::statement => L!("statement"), + Type::job_pipeline => L!("job_pipeline"), + Type::job_conjunction => L!("job_conjunction"), + Type::for_header => L!("for_header"), + Type::while_header => L!("while_header"), + Type::function_header => L!("function_header"), + Type::begin_header => L!("begin_header"), + Type::block_statement => L!("block_statement"), + Type::if_clause => L!("if_clause"), + Type::elseif_clause => L!("elseif_clause"), + Type::elseif_clause_list => L!("elseif_clause_list"), + Type::else_clause => L!("else_clause"), + Type::if_statement => L!("if_statement"), + Type::case_item => L!("case_item"), + Type::switch_statement => L!("switch_statement"), + Type::decorated_statement => L!("decorated_statement"), + Type::not_statement => L!("not_statement"), + Type::job_continuation => L!("job_continuation"), + Type::job_continuation_list => L!("job_continuation_list"), + Type::job_conjunction_continuation => L!("job_conjunction_continuation"), + Type::andor_job => L!("andor_job"), + Type::andor_job_list => L!("andor_job_list"), + Type::freestanding_argument_list => L!("freestanding_argument_list"), + Type::token_conjunction => L!("token_conjunction"), + Type::job_conjunction_continuation_list => L!("job_conjunction_continuation_list"), + Type::maybe_newlines => L!("maybe_newlines"), + Type::token_pipe => L!("token_pipe"), + Type::case_item_list => L!("case_item_list"), + Type::argument => L!("argument"), + Type::argument_list => L!("argument_list"), + Type::job_list => L!("job_list"), } } @@ -2794,7 +2793,6 @@ impl<'s> NodeVisitorMut for Populator<'s> { self.depth += 1 } - #[widestrs] fn did_visit_fields_of<'a>(&'a mut self, node: &'a dyn NodeMut, flow: VisitResult) { self.depth -= 1; @@ -2817,27 +2815,27 @@ impl<'s> NodeVisitorMut for Populator<'s> { } Type::for_header => { let n = cursor.as_for_header().unwrap(); - break Some((n.kw_for.range.unwrap(), "for loop"L)); + break Some((n.kw_for.range.unwrap(), L!("for loop"))); } Type::while_header => { let n = cursor.as_while_header().unwrap(); - break Some((n.kw_while.range.unwrap(), "while loop"L)); + break Some((n.kw_while.range.unwrap(), L!("while loop"))); } Type::function_header => { let n = cursor.as_function_header().unwrap(); - break Some((n.kw_function.range.unwrap(), "function definition"L)); + break Some((n.kw_function.range.unwrap(), L!("function definition"))); } Type::begin_header => { let n = cursor.as_begin_header().unwrap(); - break Some((n.kw_begin.range.unwrap(), "begin"L)); + break Some((n.kw_begin.range.unwrap(), L!("begin"))); } Type::if_statement => { let n = cursor.as_if_statement().unwrap(); - break Some((n.if_clause.kw_if.range.unwrap(), "if statement"L)); + break Some((n.if_clause.kw_if.range.unwrap(), L!("if statement"))); } Type::switch_statement => { let n = cursor.as_switch_statement().unwrap(); - break Some((n.kw_switch.range.unwrap(), "switch statement"L)); + break Some((n.kw_switch.range.unwrap(), L!("switch statement"))); } _ => break None, } @@ -2919,31 +2917,29 @@ impl<'s> NodeVisitorMut for Populator<'s> { /// Helper to describe a list of keywords. /// TODO: these need to be localized properly. -#[widestrs] fn keywords_user_presentable_description(kws: &'static [ParseKeyword]) -> WString { assert!(!kws.is_empty(), "Should not be empty list"); if kws.len() == 1 { - return sprintf!("keyword '%ls'"L, kws[0]); + return sprintf!(L!("keyword '%ls'"), kws[0]); } - let mut res = "keywords "L.to_owned(); + let mut res = L!("keywords ").to_owned(); for (i, kw) in kws.iter().enumerate() { if i != 0 { - res += " or "L; + res += L!(" or "); } - res += &sprintf!("'%ls'"L, *kw)[..]; + res += &sprintf!(L!("'%ls'"), *kw)[..]; } res } /// Helper to describe a list of token types. /// TODO: these need to be localized properly. -#[widestrs] fn token_types_user_presentable_description(types: &'static [ParseTokenType]) -> WString { assert!(!types.is_empty(), "Should not be empty list"); let mut res = WString::new(); for typ in types { if !res.is_empty() { - res += " or "L; + res += L!(" or "); } res += &token_type_user_presentable_description(*typ, ParseKeyword::none)[..]; } diff --git a/src/autoload.rs b/src/autoload.rs index 84ded45ea..5f34b0729 100644 --- a/src/autoload.rs +++ b/src/autoload.rs @@ -318,7 +318,6 @@ impl AutoloadFileCache { } } -#[widestring_suffix::widestrs] #[test] #[serial] fn test_autoload() { @@ -349,47 +348,53 @@ fn test_autoload() { let p2 = charptr2wcstring(unsafe { libc::mkdtemp(t2.as_mut_ptr().cast()) }); let paths = &[p1.clone(), p2.clone()]; - let mut autoload = Autoload::new("test_var"L); - assert!(autoload.resolve_command_impl("file1"L, paths).is_none()); - assert!(autoload.resolve_command_impl("nothing"L, paths).is_none()); + let mut autoload = Autoload::new(L!("test_var")); + assert!(autoload.resolve_command_impl(L!("file1"), paths).is_none()); + assert!(autoload + .resolve_command_impl(L!("nothing"), paths) + .is_none()); assert!(autoload.get_autoloaded_commands().is_empty()); run!("touch %ls/file1.fish", p1); run!("touch %ls/file2.fish", p2); autoload.invalidate_cache(); - assert!(!autoload.autoload_in_progress("file1"L)); - assert!(autoload.resolve_command_impl("file1"L, paths).is_some()); - assert!(autoload.resolve_command_impl("file1"L, paths).is_none()); - assert!(autoload.autoload_in_progress("file1"L)); - assert!(autoload.get_autoloaded_commands() == vec!["file1"L]); - autoload.mark_autoload_finished("file1"L); - assert!(!autoload.autoload_in_progress("file1"L)); - assert!(autoload.get_autoloaded_commands() == vec!["file1"L]); + assert!(!autoload.autoload_in_progress(L!("file1"))); + assert!(autoload.resolve_command_impl(L!("file1"), paths).is_some()); + assert!(autoload.resolve_command_impl(L!("file1"), paths).is_none()); + assert!(autoload.autoload_in_progress(L!("file1"))); + assert!(autoload.get_autoloaded_commands() == vec![L!("file1")]); + autoload.mark_autoload_finished(L!("file1")); + assert!(!autoload.autoload_in_progress(L!("file1"))); + assert!(autoload.get_autoloaded_commands() == vec![L!("file1")]); - assert!(autoload.resolve_command_impl("file1"L, paths).is_none()); - assert!(autoload.resolve_command_impl("nothing"L, paths).is_none()); - assert!(autoload.resolve_command_impl("file2"L, paths).is_some()); - assert!(autoload.resolve_command_impl("file2"L, paths).is_none()); - autoload.mark_autoload_finished("file2"L); - assert!(autoload.resolve_command_impl("file2"L, paths).is_none()); - assert!((autoload.get_autoloaded_commands() == vec!["file1"L, "file2"L])); + assert!(autoload.resolve_command_impl(L!("file1"), paths).is_none()); + assert!(autoload + .resolve_command_impl(L!("nothing"), paths) + .is_none()); + assert!(autoload.resolve_command_impl(L!("file2"), paths).is_some()); + assert!(autoload.resolve_command_impl(L!("file2"), paths).is_none()); + autoload.mark_autoload_finished(L!("file2")); + assert!(autoload.resolve_command_impl(L!("file2"), paths).is_none()); + assert!((autoload.get_autoloaded_commands() == vec![L!("file1"), L!("file2")])); autoload.clear(); - assert!(autoload.resolve_command_impl("file1"L, paths).is_some()); - autoload.mark_autoload_finished("file1"L); - assert!(autoload.resolve_command_impl("file1"L, paths).is_none()); - assert!(autoload.resolve_command_impl("nothing"L, paths).is_none()); - assert!(autoload.resolve_command_impl("file2"L, paths).is_some()); - assert!(autoload.resolve_command_impl("file2"L, paths).is_none()); - autoload.mark_autoload_finished("file2"L); + assert!(autoload.resolve_command_impl(L!("file1"), paths).is_some()); + autoload.mark_autoload_finished(L!("file1")); + assert!(autoload.resolve_command_impl(L!("file1"), paths).is_none()); + assert!(autoload + .resolve_command_impl(L!("nothing"), paths) + .is_none()); + assert!(autoload.resolve_command_impl(L!("file2"), paths).is_some()); + assert!(autoload.resolve_command_impl(L!("file2"), paths).is_none()); + autoload.mark_autoload_finished(L!("file2")); - assert!(autoload.resolve_command_impl("file1"L, paths).is_none()); + assert!(autoload.resolve_command_impl(L!("file1"), paths).is_none()); touch_file(&sprintf!("%ls/file1.fish", p1)); autoload.invalidate_cache(); - assert!(autoload.resolve_command_impl("file1"L, paths).is_some()); - autoload.mark_autoload_finished("file1"L); + assert!(autoload.resolve_command_impl(L!("file1"), paths).is_some()); + autoload.mark_autoload_finished(L!("file1")); - run!("rm -Rf %ls"L, p1); - run!("rm -Rf %ls"L, p2); + run!(L!("rm -Rf %ls"), p1); + run!(L!("rm -Rf %ls"), p2); } diff --git a/src/builtins/emit.rs b/src/builtins/emit.rs index 6d1c25a2f..23ecbc2aa 100644 --- a/src/builtins/emit.rs +++ b/src/builtins/emit.rs @@ -1,7 +1,6 @@ use super::prelude::*; use crate::event; -#[widestrs] pub fn emit(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Option { let cmd = argv[0]; @@ -19,7 +18,7 @@ pub fn emit(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Opt let Some(event_name) = argv.get(opts.optind) else { streams .err - .append(sprintf!("%ls: expected event name\n"L, cmd)); + .append(sprintf!(L!("%ls: expected event name\n"), cmd)); return STATUS_INVALID_ARGS; }; diff --git a/src/builtins/math.rs b/src/builtins/math.rs index df556748e..368df6fee 100644 --- a/src/builtins/math.rs +++ b/src/builtins/math.rs @@ -14,22 +14,21 @@ struct Options { base: usize, } -#[widestrs] fn parse_cmd_opts( args: &mut [&wstr], parser: &Parser, streams: &mut IoStreams, ) -> Result<(Options, usize), Option> { - const cmd: &wstr = "math"L; + const cmd: &wstr = L!("math"); let print_hints = true; // 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 = "+:hs:b:"L; + const SHORT_OPTS: &wstr = L!("+:hs:b:"); const LONG_OPTS: &[woption] = &[ - wopt("scale"L, woption_argument_t::required_argument, 's'), - wopt("base"L, woption_argument_t::required_argument, 'b'), - wopt("help"L, woption_argument_t::no_argument, 'h'), + wopt(L!("scale"), woption_argument_t::required_argument, 's'), + wopt(L!("base"), woption_argument_t::required_argument, 'b'), + wopt(L!("help"), woption_argument_t::no_argument, 'h'), ]; let mut opts = Options { @@ -158,7 +157,6 @@ fn format_double(mut v: f64, opts: &Options) -> WString { ret } -#[widestrs] fn evaluate_expression( cmd: &wstr, streams: &mut IoStreams, @@ -174,11 +172,11 @@ fn evaluate_expression( // (e.g. infinite is the result of "x / 0"), // but that's much more work. let error_message = if n.is_infinite() { - "Result is infinite"L + L!("Result is infinite") } else if n.is_nan() { - "Result is not a number"L + L!("Result is not a number") } else if n.abs() >= MAX_CONTIGUOUS_INTEGER { - "Result magnitude is too large"L + L!("Result magnitude is too large") } else { let mut s = format_double(n, opts); s.push('\n'); @@ -189,24 +187,26 @@ fn evaluate_expression( streams .err - .append(sprintf!("%ls: Error: %ls\n"L, cmd, error_message)); - streams.err.append(sprintf!("'%ls'\n"L, expression)); + .append(sprintf!(L!("%ls: Error: %ls\n"), cmd, error_message)); + streams.err.append(sprintf!(L!("'%ls'\n"), expression)); STATUS_CMD_ERROR } Err(err) => { streams.err.append(sprintf!( - "%ls: Error: %ls\n"L, + L!("%ls: Error: %ls\n"), cmd, err.kind.describe_wstr() )); - streams.err.append(sprintf!("'%ls'\n"L, expression)); + streams.err.append(sprintf!(L!("'%ls'\n"), expression)); let padding = WString::from_chars(vec![' '; err.position + 1]); if err.len >= 2 { let tildes = WString::from_chars(vec!['~'; err.len - 2]); - streams.err.append(sprintf!("%ls^%ls^\n"L, padding, tildes)); + streams + .err + .append(sprintf!(L!("%ls^%ls^\n"), padding, tildes)); } else { - streams.err.append(sprintf!("%ls^\n"L, padding)); + streams.err.append(sprintf!(L!("%ls^\n"), padding)); } STATUS_CMD_ERROR @@ -218,7 +218,6 @@ fn evaluate_expression( const MATH_CHUNK_SIZE: usize = 1024; /// The math builtin evaluates math expressions. -#[widestrs] pub fn math(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Option { let cmd = argv[0]; diff --git a/src/builtins/shared.rs b/src/builtins/shared.rs index 6063f7dc6..7b9af81e6 100644 --- a/src/builtins/shared.rs +++ b/src/builtins/shared.rs @@ -17,7 +17,6 @@ use std::fs::File; use std::io::{BufRead, BufReader, Read}; use std::os::fd::FromRawFd; use std::sync::Arc; -use widestring_suffix::widestrs; pub type BuiltinCmd = fn(&Parser, &mut IoStreams, &mut [&wstr]) -> Option; @@ -115,250 +114,249 @@ struct BuiltinData { // Data about all the builtin commands in fish. // Functions that are bound to builtin_generic are handled directly by the parser. // NOTE: These must be kept in sorted order! -#[widestrs] const BUILTIN_DATAS: &[BuiltinData] = &[ BuiltinData { - name: "."L, + name: L!("."), func: source::source, }, BuiltinData { - name: ":"L, + name: L!(":"), func: builtin_true, }, BuiltinData { - name: "["L, // ] + name: L!("["), // ] func: test::test, }, BuiltinData { - name: "_"L, + name: L!("_"), func: builtin_gettext, }, BuiltinData { - name: "abbr"L, + name: L!("abbr"), func: abbr::abbr, }, BuiltinData { - name: "and"L, + name: L!("and"), func: builtin_generic, }, BuiltinData { - name: "argparse"L, + name: L!("argparse"), func: argparse::argparse, }, BuiltinData { - name: "begin"L, + name: L!("begin"), func: builtin_generic, }, BuiltinData { - name: "bg"L, + name: L!("bg"), func: bg::bg, }, BuiltinData { - name: "bind"L, + name: L!("bind"), func: bind::bind, }, BuiltinData { - name: "block"L, + name: L!("block"), func: block::block, }, BuiltinData { - name: "break"L, + name: L!("break"), func: builtin_break_continue, }, BuiltinData { - name: "breakpoint"L, + name: L!("breakpoint"), func: builtin_breakpoint, }, BuiltinData { - name: "builtin"L, + name: L!("builtin"), func: builtin::builtin, }, BuiltinData { - name: "case"L, + name: L!("case"), func: builtin_generic, }, BuiltinData { - name: "cd"L, + name: L!("cd"), func: cd::cd, }, BuiltinData { - name: "command"L, + name: L!("command"), func: command::command, }, BuiltinData { - name: "commandline"L, + name: L!("commandline"), func: commandline::commandline, }, BuiltinData { - name: "complete"L, + name: L!("complete"), func: complete::complete, }, BuiltinData { - name: "contains"L, + name: L!("contains"), func: contains::contains, }, BuiltinData { - name: "continue"L, + name: L!("continue"), func: builtin_break_continue, }, BuiltinData { - name: "count"L, + name: L!("count"), func: count::count, }, BuiltinData { - name: "disown"L, + name: L!("disown"), func: disown::disown, }, BuiltinData { - name: "echo"L, + name: L!("echo"), func: echo::echo, }, BuiltinData { - name: "else"L, + name: L!("else"), func: builtin_generic, }, BuiltinData { - name: "emit"L, + name: L!("emit"), func: emit::emit, }, BuiltinData { - name: "end"L, + name: L!("end"), func: builtin_generic, }, BuiltinData { - name: "eval"L, + name: L!("eval"), func: eval::eval, }, BuiltinData { - name: "exec"L, + name: L!("exec"), func: builtin_generic, }, BuiltinData { - name: "exit"L, + name: L!("exit"), func: exit::exit, }, BuiltinData { - name: "false"L, + name: L!("false"), func: builtin_false, }, BuiltinData { - name: "fg"L, + name: L!("fg"), func: fg::fg, }, BuiltinData { - name: "for"L, + name: L!("for"), func: builtin_generic, }, BuiltinData { - name: "function"L, + name: L!("function"), func: builtin_generic, }, BuiltinData { - name: "functions"L, + name: L!("functions"), func: functions::functions, }, BuiltinData { - name: "history"L, + name: L!("history"), func: history::history, }, BuiltinData { - name: "if"L, + name: L!("if"), func: builtin_generic, }, BuiltinData { - name: "jobs"L, + name: L!("jobs"), func: jobs::jobs, }, BuiltinData { - name: "math"L, + name: L!("math"), func: math::math, }, BuiltinData { - name: "not"L, + name: L!("not"), func: builtin_generic, }, BuiltinData { - name: "or"L, + name: L!("or"), func: builtin_generic, }, BuiltinData { - name: "path"L, + name: L!("path"), func: path::path, }, BuiltinData { - name: "printf"L, + name: L!("printf"), func: printf::printf, }, BuiltinData { - name: "pwd"L, + name: L!("pwd"), func: pwd::pwd, }, BuiltinData { - name: "random"L, + name: L!("random"), func: random::random, }, BuiltinData { - name: "read"L, + name: L!("read"), func: read::read, }, BuiltinData { - name: "realpath"L, + name: L!("realpath"), func: realpath::realpath, }, BuiltinData { - name: "return"L, + name: L!("return"), func: r#return::r#return, }, BuiltinData { - name: "set"L, + name: L!("set"), func: set::set, }, BuiltinData { - name: "set_color"L, + name: L!("set_color"), func: set_color::set_color, }, BuiltinData { - name: "source"L, + name: L!("source"), func: source::source, }, BuiltinData { - name: "status"L, + name: L!("status"), func: status::status, }, BuiltinData { - name: "string"L, + name: L!("string"), func: string::string, }, BuiltinData { - name: "switch"L, + name: L!("switch"), func: builtin_generic, }, BuiltinData { - name: "test"L, + name: L!("test"), func: test::test, }, BuiltinData { - name: "time"L, + name: L!("time"), func: builtin_generic, }, BuiltinData { - name: "true"L, + name: L!("true"), func: builtin_true, }, BuiltinData { - name: "type"L, + name: L!("type"), func: r#type::r#type, }, BuiltinData { - name: "ulimit"L, + name: L!("ulimit"), func: ulimit::ulimit, }, BuiltinData { - name: "wait"L, + name: L!("wait"), func: wait::wait, }, BuiltinData { - name: "while"L, + name: L!("while"), func: builtin_generic, }, ]; @@ -380,16 +378,15 @@ pub fn builtin_exists(name: &wstr) -> bool { } /// Is the command a keyword we need to special-case the handling of `-h` and `--help`. -#[widestrs] fn cmd_needs_help(cmd: &wstr) -> bool { [ - "for"L, - "while"L, - "function"L, - "if"L, - "end"L, - "switch"L, - "case"L, + L!("for"), + L!("while"), + L!("function"), + L!("if"), + L!("end"), + L!("switch"), + L!("case"), ] .contains(&cmd) } diff --git a/src/builtins/tests/test_tests.rs b/src/builtins/tests/test_tests.rs index 03e433360..572be26b6 100644 --- a/src/builtins/tests/test_tests.rs +++ b/src/builtins/tests/test_tests.rs @@ -47,7 +47,6 @@ fn run_test_test(expected: i32, lst: &[&str]) -> bool { nobracket } -#[widestrs] fn test_test_brackets() { // Ensure [ knows it needs a ]. let parser = Parser::principal_parser(); @@ -57,16 +56,16 @@ fn test_test_brackets() { let io_chain = IoChain::new(); let mut streams = IoStreams::new(&mut out, &mut err, &io_chain); - let args1 = &mut ["["L, "foo"L]; + let args1 = &mut [L!("["), L!("foo")]; assert_eq!( builtin_test(parser, &mut streams, args1), STATUS_INVALID_ARGS ); - let args2 = &mut ["["L, "foo"L, "]"L]; + let args2 = &mut [L!("["), L!("foo"), L!("]")]; assert_eq!(builtin_test(parser, &mut streams, args2), STATUS_CMD_OK); - let args3 = &mut ["["L, "foo"L, "]"L, "bar"L]; + let args3 = &mut [L!("["), L!("foo"), L!("]"), L!("bar")]; assert_eq!( builtin_test(parser, &mut streams, args3), STATUS_INVALID_ARGS diff --git a/src/builtins/wait.rs b/src/builtins/wait.rs index 690aaa58d..28316275b 100644 --- a/src/builtins/wait.rs +++ b/src/builtins/wait.rs @@ -127,7 +127,6 @@ fn wait_for_completion(parser: &Parser, whs: &[WaitHandleRef], any_flag: bool) - } } -#[widestrs] pub fn wait(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Option { let cmd = argv[0]; let argc = argv.len(); @@ -135,10 +134,10 @@ pub fn wait(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Opt let mut print_help = false; let print_hints = false; - const shortopts: &wstr = ":nh"L; + const shortopts: &wstr = L!(":nh"); const longopts: &[woption] = &[ - wopt("any"L, woption_argument_t::no_argument, 'n'), - wopt("help"L, woption_argument_t::no_argument, 'h'), + wopt(L!("any"), woption_argument_t::no_argument, 'n'), + wopt(L!("help"), woption_argument_t::no_argument, 'h'), ]; let mut w = wgetopter_t::new(shortopts, longopts, argv); diff --git a/src/color.rs b/src/color.rs index a4ff805b1..000b45d6c 100644 --- a/src/color.rs +++ b/src/color.rs @@ -231,13 +231,12 @@ impl RgbColor { } /// Try parsing a special color name like "normal". - #[widestrs] fn try_parse_special(special: &wstr) -> Option { // TODO: this is a very hot function, may need optimization by e.g. comparing length first, // depending on how well inlining of `simple_icase_compare` works - let typ = if simple_icase_compare(special, "normal"L) == Ordering::Equal { + let typ = if simple_icase_compare(special, L!("normal")) == Ordering::Equal { Type::Normal - } else if simple_icase_compare(special, "reset"L) == Ordering::Equal { + } else if simple_icase_compare(special, L!("reset")) == Ordering::Equal { Type::Reset } else { return None; @@ -320,32 +319,31 @@ struct NamedColor { hidden: bool, } -#[widestrs] #[rustfmt::skip] const NAMED_COLORS: &[NamedColor] = &[ // Keep this sorted alphabetically - NamedColor {name: "black"L, idx: 0, _rgb: [0x00, 0x00, 0x00], hidden: false}, - NamedColor {name: "blue"L, idx: 4, _rgb: [0x00, 0x00, 0x80], hidden: false}, - NamedColor {name: "brblack"L, idx: 8, _rgb: [0x80, 0x80, 0x80], hidden: false}, - NamedColor {name: "brblue"L, idx: 12, _rgb: [0x00, 0x00, 0xFF], hidden: false}, - NamedColor {name: "brbrown"L, idx: 11, _rgb: [0xFF, 0xFF, 0x00], hidden: true}, - NamedColor {name: "brcyan"L, idx: 14, _rgb: [0x00, 0xFF, 0xFF], hidden: false}, - NamedColor {name: "brgreen"L, idx: 10, _rgb: [0x00, 0xFF, 0x00], hidden: false}, - NamedColor {name: "brgrey"L, idx: 8, _rgb: [0x55, 0x55, 0x55], hidden: true}, - NamedColor {name: "brmagenta"L, idx: 13, _rgb: [0xFF, 0x00, 0xFF], hidden: false}, - NamedColor {name: "brown"L, idx: 3, _rgb: [0x72, 0x50, 0x00], hidden: true}, - NamedColor {name: "brpurple"L, idx: 13, _rgb: [0xFF, 0x00, 0xFF], hidden: true}, - NamedColor {name: "brred"L, idx: 9, _rgb: [0xFF, 0x00, 0x00], hidden: false}, - NamedColor {name: "brwhite"L, idx: 15, _rgb: [0xFF, 0xFF, 0xFF], hidden: false}, - NamedColor {name: "bryellow"L, idx: 11, _rgb: [0xFF, 0xFF, 0x00], hidden: false}, - NamedColor {name: "cyan"L, idx: 6, _rgb: [0x00, 0x80, 0x80], hidden: false}, - NamedColor {name: "green"L, idx: 2, _rgb: [0x00, 0x80, 0x00], hidden: false}, - NamedColor {name: "grey"L, idx: 7, _rgb: [0xE5, 0xE5, 0xE5], hidden: true}, - NamedColor {name: "magenta"L, idx: 5, _rgb: [0x80, 0x00, 0x80], hidden: false}, - NamedColor {name: "purple"L, idx: 5, _rgb: [0x80, 0x00, 0x80], hidden: true}, - NamedColor {name: "red"L, idx: 1, _rgb: [0x80, 0x00, 0x00], hidden: false}, - NamedColor {name: "white"L, idx: 7, _rgb: [0xC0, 0xC0, 0xC0], hidden: false}, - NamedColor {name: "yellow"L, idx: 3, _rgb: [0x80, 0x80, 0x00], hidden: false}, + NamedColor {name: L!("black"), idx: 0, _rgb: [0x00, 0x00, 0x00], hidden: false}, + NamedColor {name: L!("blue"), idx: 4, _rgb: [0x00, 0x00, 0x80], hidden: false}, + NamedColor {name: L!("brblack"), idx: 8, _rgb: [0x80, 0x80, 0x80], hidden: false}, + NamedColor {name: L!("brblue"), idx: 12, _rgb: [0x00, 0x00, 0xFF], hidden: false}, + NamedColor {name: L!("brbrown"), idx: 11, _rgb: [0xFF, 0xFF, 0x00], hidden: true}, + NamedColor {name: L!("brcyan"), idx: 14, _rgb: [0x00, 0xFF, 0xFF], hidden: false}, + NamedColor {name: L!("brgreen"), idx: 10, _rgb: [0x00, 0xFF, 0x00], hidden: false}, + NamedColor {name: L!("brgrey"), idx: 8, _rgb: [0x55, 0x55, 0x55], hidden: true}, + NamedColor {name: L!("brmagenta"), idx: 13, _rgb: [0xFF, 0x00, 0xFF], hidden: false}, + NamedColor {name: L!("brown"), idx: 3, _rgb: [0x72, 0x50, 0x00], hidden: true}, + NamedColor {name: L!("brpurple"), idx: 13, _rgb: [0xFF, 0x00, 0xFF], hidden: true}, + NamedColor {name: L!("brred"), idx: 9, _rgb: [0xFF, 0x00, 0x00], hidden: false}, + NamedColor {name: L!("brwhite"), idx: 15, _rgb: [0xFF, 0xFF, 0xFF], hidden: false}, + NamedColor {name: L!("bryellow"), idx: 11, _rgb: [0xFF, 0xFF, 0x00], hidden: false}, + NamedColor {name: L!("cyan"), idx: 6, _rgb: [0x00, 0x80, 0x80], hidden: false}, + NamedColor {name: L!("green"), idx: 2, _rgb: [0x00, 0x80, 0x00], hidden: false}, + NamedColor {name: L!("grey"), idx: 7, _rgb: [0xE5, 0xE5, 0xE5], hidden: true}, + NamedColor {name: L!("magenta"), idx: 5, _rgb: [0x80, 0x00, 0x80], hidden: false}, + NamedColor {name: L!("purple"), idx: 5, _rgb: [0x80, 0x00, 0x80], hidden: true}, + NamedColor {name: L!("red"), idx: 1, _rgb: [0x80, 0x00, 0x00], hidden: false}, + NamedColor {name: L!("white"), idx: 7, _rgb: [0xC0, 0xC0, 0xC0], hidden: false}, + NamedColor {name: L!("yellow"), idx: 3, _rgb: [0x80, 0x80, 0x00], hidden: false}, ]; assert_sorted_by_name!(NAMED_COLORS); @@ -434,28 +432,26 @@ mod tests { use crate::wchar::prelude::*; #[test] - #[widestrs] fn parse() { - assert!(RgbColor::from_wstr("#FF00A0"L).unwrap().is_rgb()); - assert!(RgbColor::from_wstr("FF00A0"L).unwrap().is_rgb()); - assert!(RgbColor::from_wstr("#F30"L).unwrap().is_rgb()); - assert!(RgbColor::from_wstr("F30"L).unwrap().is_rgb()); - assert!(RgbColor::from_wstr("f30"L).unwrap().is_rgb()); - assert!(RgbColor::from_wstr("#FF30a5"L).unwrap().is_rgb()); - assert!(RgbColor::from_wstr("3f30"L).is_none()); - assert!(RgbColor::from_wstr("##f30"L).is_none()); - assert!(RgbColor::from_wstr("magenta"L).unwrap().is_named()); - assert!(RgbColor::from_wstr("MaGeNTa"L).unwrap().is_named()); - assert!(RgbColor::from_wstr("mooganta"L).is_none()); + assert!(RgbColor::from_wstr(L!("#FF00A0")).unwrap().is_rgb()); + assert!(RgbColor::from_wstr(L!("FF00A0")).unwrap().is_rgb()); + assert!(RgbColor::from_wstr(L!("#F30")).unwrap().is_rgb()); + assert!(RgbColor::from_wstr(L!("F30")).unwrap().is_rgb()); + assert!(RgbColor::from_wstr(L!("f30")).unwrap().is_rgb()); + assert!(RgbColor::from_wstr(L!("#FF30a5")).unwrap().is_rgb()); + assert!(RgbColor::from_wstr(L!("3f30")).is_none()); + assert!(RgbColor::from_wstr(L!("##f30")).is_none()); + assert!(RgbColor::from_wstr(L!("magenta")).unwrap().is_named()); + assert!(RgbColor::from_wstr(L!("MaGeNTa")).unwrap().is_named()); + assert!(RgbColor::from_wstr(L!("mooganta")).is_none()); } #[test] - #[widestrs] fn parse_rgb() { - assert!(RgbColor::from_wstr("##FF00A0"L) == None); - assert!(RgbColor::from_wstr("#FF00A0"L) == Some(RgbColor::from_rgb(0xff, 0x00, 0xa0))); - assert!(RgbColor::from_wstr("FF00A0"L) == Some(RgbColor::from_rgb(0xff, 0x00, 0xa0))); - assert!(RgbColor::from_wstr("FAF"L) == Some(RgbColor::from_rgb(0xff, 0xaa, 0xff))); + assert!(RgbColor::from_wstr(L!("##FF00A0")) == None); + assert!(RgbColor::from_wstr(L!("#FF00A0")) == Some(RgbColor::from_rgb(0xff, 0x00, 0xa0))); + assert!(RgbColor::from_wstr(L!("FF00A0")) == Some(RgbColor::from_rgb(0xff, 0x00, 0xa0))); + assert!(RgbColor::from_wstr(L!("FAF")) == Some(RgbColor::from_rgb(0xff, 0xaa, 0xff))); } // Regression test for multiplicative overflow in convert_color. diff --git a/src/common.rs b/src/common.rs index 4ab76e691..2691ac550 100644 --- a/src/common.rs +++ b/src/common.rs @@ -180,7 +180,6 @@ pub fn escape_string(s: &wstr, style: EscapeStringStyle) -> WString { } /// Escape a string in a fashion suitable for using in fish script. -#[widestrs] fn escape_string_script(input: &wstr, flags: EscapeFlags) -> WString { let escape_printables = !flags.contains(EscapeFlags::NO_PRINTABLES); let no_quoted = flags.contains(EscapeFlags::NO_QUOTED); @@ -197,7 +196,7 @@ fn escape_string_script(input: &wstr, flags: EscapeFlags) -> WString { let mut need_complex_escape = false; if !no_quoted && input.is_empty() { - return "''"L.to_owned(); + return L!("''").to_owned(); } let mut out = WString::new(); @@ -220,7 +219,7 @@ fn escape_string_script(input: &wstr, flags: EscapeFlags) -> WString { if symbolic { out.push('␉'); } else { - out += "\\t"L; + out += L!("\\t"); } need_escape = true; need_complex_escape = true; @@ -229,7 +228,7 @@ fn escape_string_script(input: &wstr, flags: EscapeFlags) -> WString { if symbolic { out.push('␤'); } else { - out += "\\n"L; + out += L!("\\n"); } need_escape = true; need_complex_escape = true; @@ -238,7 +237,7 @@ fn escape_string_script(input: &wstr, flags: EscapeFlags) -> WString { if symbolic { out.push('␈'); } else { - out += "\\b"L; + out += L!("\\b"); } need_escape = true; need_complex_escape = true; @@ -247,7 +246,7 @@ fn escape_string_script(input: &wstr, flags: EscapeFlags) -> WString { if symbolic { out.push('␍'); } else { - out += "\\r"L; + out += L!("\\r"); } need_escape = true; need_complex_escape = true; @@ -256,7 +255,7 @@ fn escape_string_script(input: &wstr, flags: EscapeFlags) -> WString { if symbolic { out.push('␛'); } else { - out += "\\e"L; + out += L!("\\e"); } need_escape = true; need_complex_escape = true; @@ -265,7 +264,7 @@ fn escape_string_script(input: &wstr, flags: EscapeFlags) -> WString { if symbolic { out.push('␡'); } else { - out += "\\x7f"L; + out += L!("\\x7f"); } need_escape = true; need_complex_escape = true; @@ -286,7 +285,7 @@ fn escape_string_script(input: &wstr, flags: EscapeFlags) -> WString { out.push('*'); } ANY_STRING_RECURSIVE => { - out += "**"L; + out += L!("**"); } '&' | '$' | ' ' | '#' | '<' | '>' | '(' | ')' | '[' | ']' | '{' | '}' | '?' | '*' @@ -358,7 +357,6 @@ fn byte_to_hex(byte: u8) -> (char, char) { } /// Escape a string in a fashion suitable for using as a URL. Store the result in out_str. -#[widestrs] fn escape_string_url(input: &wstr) -> WString { let narrow = wcs2string(input); let mut out = WString::new(); @@ -1246,8 +1244,7 @@ fn count_ascii_prefix(inp: &[u8]) -> usize { } // Check if we are running in the test mode, where we should suppress error output -#[widestrs] -pub const TESTS_PROGRAM_NAME: &wstr = "(ignore)"L; +pub const TESTS_PROGRAM_NAME: &wstr = L!("(ignore)"); /// Hack to not print error messages in the tests. Do not call this from functions in this module /// like `debug()`. It is only intended to suppress diagnostic noise from testing things like the @@ -1533,7 +1530,6 @@ pub fn read_loop(fd: &Fd, buf: &mut [u8]) -> std::io::Result } /// Write the given paragraph of output, redoing linebreaks to fit \p termsize. -#[widestrs] pub fn reformat_for_screen(msg: &wstr, termsize: &Termsize) -> WString { let mut buff = WString::new(); @@ -1568,7 +1564,7 @@ pub fn reformat_for_screen(msg: &wstr, termsize: &Termsize) -> WString { if line_width != 0 { buff.push('\n'); } - buff += &sprintf!("%ls-\n"L, token)[..]; + buff += &sprintf!(L!("%ls-\n"), token)[..]; line_width = 0; } else { // Print the token. @@ -1579,7 +1575,7 @@ pub fn reformat_for_screen(msg: &wstr, termsize: &Termsize) -> WString { line_width = 0; } if line_width != 0 { - buff += " "L; + buff += L!(" "); } buff += token; line_width += line_width_unit + tok_width; diff --git a/src/env/environment_impl.rs b/src/env/environment_impl.rs index 60fae57d1..d9e625196 100644 --- a/src/env/environment_impl.rs +++ b/src/env/environment_impl.rs @@ -336,19 +336,18 @@ impl EnvScopedImpl { self.perproc_data.statuses = s; } - #[widestrs] fn try_get_computed(&self, key: &wstr) -> Option { let ev = ElectricVar::for_name(key); if ev.is_none() || !ev.unwrap().computed() { return None; } - if key == "PWD"L { + if key == L!("PWD") { Some(EnvVar::new( self.perproc_data.pwd.clone(), EnvVarFlags::EXPORT, )) - } else if key == "history"L { + } else if key == L!("history") { // Big hack. We only allow getting the history on the main thread. Note that history_t // may ask for an environment variable, so don't take the lock here (we don't need it). if (!is_main_thread()) { @@ -359,34 +358,40 @@ impl EnvScopedImpl { let session_id = history_session_id_from_var(fish_history_var); History::with_name(&session_id) }); - return Some(EnvVar::new_from_name_vec("history"L, history.get_history())); - } else if key == "fish_killring"L { - Some(EnvVar::new_from_name_vec("fish_killring"L, kill_entries())) - } else if key == "pipestatus"L { + return Some(EnvVar::new_from_name_vec( + L!("history"), + history.get_history(), + )); + } else if key == L!("fish_killring") { + Some(EnvVar::new_from_name_vec( + L!("fish_killring"), + kill_entries(), + )) + } else if key == L!("pipestatus") { let js = &self.perproc_data.statuses; let mut result = Vec::new(); result.reserve(js.pipestatus.len()); for i in &js.pipestatus { result.push(i.to_wstring()); } - Some(EnvVar::new_from_name_vec("pipestatus"L, result)) - } else if key == "status"L { + Some(EnvVar::new_from_name_vec(L!("pipestatus"), result)) + } else if key == L!("status") { let js = &self.perproc_data.statuses; - Some(EnvVar::new_from_name("status"L, js.status.to_wstring())) - } else if key == "status_generation"L { + Some(EnvVar::new_from_name(L!("status"), js.status.to_wstring())) + } else if key == L!("status_generation") { let status_generation = reader_status_count(); Some(EnvVar::new_from_name( - "status_generation"L, + L!("status_generation"), status_generation.to_wstring(), )) - } else if key == "fish_kill_signal"L { + } else if key == L!("fish_kill_signal") { let js = &self.perproc_data.statuses; let signal = js.kill_signal.map_or(0, |ks| ks.code()); Some(EnvVar::new_from_name( - "fish_kill_signal"L, + L!("fish_kill_signal"), signal.to_wstring(), )) - } else if key == "umask"L { + } else if key == L!("umask") { // note umask() is an absurd API: you call it to set the value and it returns the old // value. Thus we have to call it twice, to reset the value. The env_lock protects // against races. Guess what the umask is; if we guess right we don't need to reset it. @@ -396,7 +401,7 @@ impl EnvScopedImpl { if res != guess { unsafe { libc::umask(res) }; } - Some(EnvVar::new_from_name("umask"L, sprintf!("0%0.3o", res))) + Some(EnvVar::new_from_name(L!("umask"), sprintf!("0%0.3o", res))) } else { // We should never get here unless the electric var list is out of sync with the above code. panic!("Unrecognized computed var name {}", key); diff --git a/src/env/var.rs b/src/env/var.rs index a54a3a6c9..8069653e3 100644 --- a/src/env/var.rs +++ b/src/env/var.rs @@ -1,5 +1,5 @@ use crate::signal::Signal; -use crate::wchar::{widestrs, wstr, WString}; +use crate::wchar::{wstr, WString, L}; use crate::wcstringutil::join_strings; use bitflags::bitflags; use lazy_static::lazy_static; @@ -253,22 +253,21 @@ pub struct ElectricVar { // Keep sorted alphabetically #[rustfmt::skip] -#[widestrs] pub const ELECTRIC_VARIABLES: &[ElectricVar] = &[ - ElectricVar{name: "FISH_VERSION"L, flags: electric::READONLY}, - ElectricVar{name: "PWD"L, flags: electric::READONLY | electric::COMPUTED | electric::EXPORTS}, - ElectricVar{name: "SHLVL"L, flags: electric::READONLY | electric::EXPORTS}, - ElectricVar{name: "_"L, flags: electric::READONLY}, - ElectricVar{name: "fish_kill_signal"L, flags:electric::READONLY | electric::COMPUTED}, - ElectricVar{name: "fish_killring"L, flags:electric::READONLY | electric::COMPUTED}, - ElectricVar{name: "fish_pid"L, flags:electric::READONLY}, - ElectricVar{name: "history"L, flags:electric::READONLY | electric::COMPUTED}, - ElectricVar{name: "hostname"L, flags:electric::READONLY}, - ElectricVar{name: "pipestatus"L, flags:electric::READONLY | electric::COMPUTED}, - ElectricVar{name: "status"L, flags:electric::READONLY | electric::COMPUTED}, - ElectricVar{name: "status_generation"L, flags:electric::READONLY | electric::COMPUTED}, - ElectricVar{name: "umask"L, flags:electric::COMPUTED}, - ElectricVar{name: "version"L, flags:electric::READONLY}, + ElectricVar{name: L!("FISH_VERSION"), flags: electric::READONLY}, + ElectricVar{name: L!("PWD"), flags: electric::READONLY | electric::COMPUTED | electric::EXPORTS}, + ElectricVar{name: L!("SHLVL"), flags: electric::READONLY | electric::EXPORTS}, + ElectricVar{name: L!("_"), flags: electric::READONLY}, + ElectricVar{name: L!("fish_kill_signal"), flags:electric::READONLY | electric::COMPUTED}, + ElectricVar{name: L!("fish_killring"), flags:electric::READONLY | electric::COMPUTED}, + ElectricVar{name: L!("fish_pid"), flags:electric::READONLY}, + ElectricVar{name: L!("history"), flags:electric::READONLY | electric::COMPUTED}, + ElectricVar{name: L!("hostname"), flags:electric::READONLY}, + ElectricVar{name: L!("pipestatus"), flags:electric::READONLY | electric::COMPUTED}, + ElectricVar{name: L!("status"), flags:electric::READONLY | electric::COMPUTED}, + ElectricVar{name: L!("status_generation"), flags:electric::READONLY | electric::COMPUTED}, + ElectricVar{name: L!("umask"), flags:electric::COMPUTED}, + ElectricVar{name: L!("version"), flags:electric::READONLY}, ]; assert_sorted_by_name!(ELECTRIC_VARIABLES); diff --git a/src/event.rs b/src/event.rs index 86cfef95a..c1de62395 100644 --- a/src/event.rs +++ b/src/event.rs @@ -76,16 +76,15 @@ impl EventDescription { } } - #[widestrs] fn name(&self) -> &'static wstr { match self { - EventDescription::Any => "any"L, - EventDescription::Signal { .. } => "signal"L, - EventDescription::Variable { .. } => "variable"L, - EventDescription::ProcessExit { .. } => "process-exit"L, - EventDescription::JobExit { .. } => "job-exit"L, - EventDescription::CallerExit { .. } => "caller-exit"L, - EventDescription::Generic { .. } => "generic"L, + EventDescription::Any => L!("any"), + EventDescription::Signal { .. } => L!("signal"), + EventDescription::Variable { .. } => L!("variable"), + EventDescription::ProcessExit { .. } => L!("process-exit"), + EventDescription::JobExit { .. } => L!("job-exit"), + EventDescription::CallerExit { .. } => L!("caller-exit"), + EventDescription::Generic { .. } => L!("generic"), } } @@ -609,15 +608,14 @@ pub fn fire(parser: &Parser, event: Event) { } } -#[widestrs] pub const EVENT_FILTER_NAMES: [&wstr; 7] = [ - "signal"L, - "variable"L, - "exit"L, - "process-exit"L, - "job-exit"L, - "caller-exit"L, - "generic"L, + L!("signal"), + L!("variable"), + L!("exit"), + L!("process-exit"), + L!("job-exit"), + L!("caller-exit"), + L!("generic"), ]; /// Print all events. If type_filter is not empty, only output events with that type. diff --git a/src/exec.rs b/src/exec.rs index 0e36ca71d..53fff0850 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -59,7 +59,6 @@ use std::os::fd::{FromRawFd, RawFd}; use std::slice; use std::sync::atomic::Ordering; use std::sync::{atomic::AtomicUsize, Arc}; -use widestring_suffix::widestrs; /// Execute the processes specified by \p j in the parser \p. /// On a true return, the job was successfully launched and the parser will take responsibility for @@ -472,7 +471,6 @@ fn can_use_posix_spawn_for_job(job: &Job, dup2s: &Dup2List) -> bool { !wants_terminal } -#[widestrs] fn internal_exec(vars: &EnvStack, j: &Job, block_io: IoChain) { // Do a regular launch - but without forking first... let mut all_ios = block_io; @@ -499,8 +497,8 @@ fn internal_exec(vars: &EnvStack, j: &Job, block_io: IoChain) { { // Decrement SHLVL as we're removing ourselves from the shell "stack". if is_interactive_session() { - let shlvl_var = vars.getf("SHLVL"L, EnvMode::GLOBAL | EnvMode::EXPORT); - let mut shlvl_str = "0"L.to_owned(); + let shlvl_var = vars.getf(L!("SHLVL"), EnvMode::GLOBAL | EnvMode::EXPORT); + let mut shlvl_str = L!("0").to_owned(); if let Some(shlvl_var) = shlvl_var { if let Ok(shlvl) = fish_wcstol(&shlvl_var.as_string()) { if shlvl > 0 { @@ -508,7 +506,7 @@ fn internal_exec(vars: &EnvStack, j: &Job, block_io: IoChain) { } } } - vars.set_one("SHLVL"L, EnvMode::GLOBAL | EnvMode::EXPORT, shlvl_str); + vars.set_one(L!("SHLVL"), EnvMode::GLOBAL | EnvMode::EXPORT, shlvl_str); } // launch_process _never_ returns. diff --git a/src/expand.rs b/src/expand.rs index 83be59790..1ebc199c1 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -121,8 +121,7 @@ impl PartialEq for ExpandResult { } /// The string represented by PROCESS_EXPAND_SELF -#[widestrs] -pub const PROCESS_EXPAND_SELF_STR: &wstr = "%self"L; +pub const PROCESS_EXPAND_SELF_STR: &wstr = L!("%self"); /// Perform various forms of expansion on in, such as tilde expansion (\~USER becomes the users home /// directory), variable expansion (\$VAR_NAME becomes the value of the environment variable @@ -296,26 +295,25 @@ pub fn expand_tilde(input: &mut WString, vars: &dyn Environment) { } /// Perform the opposite of tilde expansion on the string, which is modified in place. -#[widestrs] pub fn replace_home_directory_with_tilde(s: &wstr, vars: &dyn Environment) -> WString { let mut result = s.to_owned(); // Only absolute paths get this treatment. - if result.starts_with("/"L) { - let mut home_directory = "~"L.to_owned(); + if result.starts_with(L!("/")) { + let mut home_directory = L!("~").to_owned(); expand_tilde(&mut home_directory, vars); // If we can't get a home directory, don't replace anything. // This is the case e.g. with --no-execute if home_directory.is_empty() { return result; } - if !home_directory.ends_with("/"L) { + if !home_directory.ends_with(L!("/")) { home_directory.push('/'); } // Now check if the home_directory prefixes the string. if result.starts_with(&home_directory) { // Success - result.replace_range(0..home_directory.len(), "~/"L); + result.replace_range(0..home_directory.len(), L!("~/")); } } result diff --git a/src/future_feature_flags.rs b/src/future_feature_flags.rs index b5454fa3d..b81376f9d 100644 --- a/src/future_feature_flags.rs +++ b/src/future_feature_flags.rs @@ -50,37 +50,36 @@ pub struct FeatureMetadata { } /// The metadata, indexed by flag. -#[widestrs] pub const METADATA: &[FeatureMetadata] = &[ FeatureMetadata { flag: FeatureFlag::stderr_nocaret, - name: "stderr-nocaret"L, - groups: "3.0"L, - description: "^ no longer redirects stderr (historical, can no longer be changed)"L, + name: L!("stderr-nocaret"), + groups: L!("3.0"), + description: L!("^ no longer redirects stderr (historical, can no longer be changed)"), default_value: true, read_only: true, }, FeatureMetadata { flag: FeatureFlag::qmark_noglob, - name: "qmark-noglob"L, - groups: "3.0"L, - description: "? no longer globs"L, + name: L!("qmark-noglob"), + groups: L!("3.0"), + description: L!("? no longer globs"), default_value: false, read_only: false, }, FeatureMetadata { flag: FeatureFlag::string_replace_backslash, - name: "regex-easyesc"L, - groups: "3.1"L, - description: "string replace -r needs fewer \\'s"L, + name: L!("regex-easyesc"), + groups: L!("3.1"), + description: L!("string replace -r needs fewer \\'s"), default_value: true, read_only: false, }, FeatureMetadata { flag: FeatureFlag::ampersand_nobg_in_token, - name: "ampersand-nobg-in-token"L, - groups: "3.4"L, - description: "& only backgrounds if followed by a separator"L, + name: L!("ampersand-nobg-in-token"), + groups: L!("3.4"), + description: L!("& only backgrounds if followed by a separator"), default_value: true, read_only: false, }, @@ -155,9 +154,8 @@ impl Features { self.values[flag as usize].store(value, Ordering::SeqCst) } - #[widestrs] fn set_from_string<'a>(&self, str: &wstr) { - let whitespace = "\t\n\0x0B\0x0C\r "L.as_char_slice(); + let whitespace = L!("\t\n\0x0B\0x0C\r ").as_char_slice(); for entry in str.as_char_slice().split(|c| *c == ',') { if entry.is_empty() { continue; @@ -169,7 +167,7 @@ impl Features { &entry[..entry.len() - entry.iter().take_while(|c| whitespace.contains(c)).count()]; // A "no-" prefix inverts the sense. - let (name, value) = match entry.strip_prefix("no-"L.as_char_slice()) { + let (name, value) = match entry.strip_prefix(L!("no-").as_char_slice()) { Some(suffix) => (suffix, false), None => (entry, true), }; @@ -186,7 +184,7 @@ impl Features { } } else { for md in METADATA { - if md.groups == name || name == "all"L { + if md.groups == name || name == L!("all") { if !md.read_only { self.set(md.flag, value); } @@ -216,12 +214,11 @@ pub fn scoped_test(flag: FeatureFlag, value: bool, test_fn: impl FnOnce()) { } #[test] -#[widestrs] fn test_feature_flags() { let f = Features::new(); - f.set_from_string("stderr-nocaret,nonsense"L); + f.set_from_string(L!("stderr-nocaret,nonsense")); assert!(f.test(FeatureFlag::stderr_nocaret)); - f.set_from_string("stderr-nocaret,no-stderr-nocaret,nonsense"L); + f.set_from_string(L!("stderr-nocaret,no-stderr-nocaret,nonsense")); assert!(f.test(FeatureFlag::stderr_nocaret)); // Ensure every metadata is represented once. @@ -235,7 +232,7 @@ fn test_feature_flags() { assert_eq!( METADATA[FeatureFlag::stderr_nocaret as usize].name, - "stderr-nocaret"L + L!("stderr-nocaret") ); } diff --git a/src/history.rs b/src/history.rs index 3d00abcc7..e93a5927e 100644 --- a/src/history.rs +++ b/src/history.rs @@ -37,7 +37,6 @@ use libc::{ }; use lru::LruCache; use rand::Rng; -use widestring_suffix::widestrs; use crate::{ ast::{Ast, Node}, @@ -204,7 +203,6 @@ impl LruCacheExt for LruCache { /// Returns the path for the history file for the given `session_id`, or `None` if it could not be /// loaded. If `suffix` is provided, append that suffix to the path; this is used for temporary files. -#[widestrs] fn history_filename(session_id: &wstr, suffix: &wstr) -> Option { if session_id.is_empty() { return None; @@ -216,7 +214,7 @@ fn history_filename(session_id: &wstr, suffix: &wstr) -> Option { result.push('/'); result.push_utfstr(session_id); - result.push_utfstr("_history"L); + result.push_utfstr(L!("_history")); result.push_utfstr(suffix); Some(result) } diff --git a/src/parse_constants.rs b/src/parse_constants.rs index b50395992..39787e074 100644 --- a/src/parse_constants.rs +++ b/src/parse_constants.rs @@ -184,21 +184,20 @@ impl Default for ParseTokenType { impl ParseTokenType { /// Return a string describing the token type. - #[widestrs] pub fn to_wstr(self) -> &'static wstr { match self { - ParseTokenType::comment => "ParseTokenType::comment"L, - ParseTokenType::error => "ParseTokenType::error"L, - ParseTokenType::tokenizer_error => "ParseTokenType::tokenizer_error"L, - ParseTokenType::background => "ParseTokenType::background"L, - ParseTokenType::end => "ParseTokenType::end"L, - ParseTokenType::pipe => "ParseTokenType::pipe"L, - ParseTokenType::redirection => "ParseTokenType::redirection"L, - ParseTokenType::string => "ParseTokenType::string"L, - ParseTokenType::andand => "ParseTokenType::andand"L, - ParseTokenType::oror => "ParseTokenType::oror"L, - ParseTokenType::terminate => "ParseTokenType::terminate"L, - ParseTokenType::invalid => "ParseTokenType::invalid"L, + ParseTokenType::comment => L!("ParseTokenType::comment"), + ParseTokenType::error => L!("ParseTokenType::error"), + ParseTokenType::tokenizer_error => L!("ParseTokenType::tokenizer_error"), + ParseTokenType::background => L!("ParseTokenType::background"), + ParseTokenType::end => L!("ParseTokenType::end"), + ParseTokenType::pipe => L!("ParseTokenType::pipe"), + ParseTokenType::redirection => L!("ParseTokenType::redirection"), + ParseTokenType::string => L!("ParseTokenType::string"), + ParseTokenType::andand => L!("ParseTokenType::andand"), + ParseTokenType::oror => L!("ParseTokenType::oror"), + ParseTokenType::terminate => L!("ParseTokenType::terminate"), + ParseTokenType::invalid => L!("ParseTokenType::invalid"), } } } @@ -211,28 +210,27 @@ impl Default for ParseKeyword { impl ParseKeyword { /// Return the keyword as a string. - #[widestrs] pub fn to_wstr(self) -> &'static wstr { match self { - ParseKeyword::kw_exclam => "!"L, - ParseKeyword::kw_and => "and"L, - ParseKeyword::kw_begin => "begin"L, - ParseKeyword::kw_builtin => "builtin"L, - ParseKeyword::kw_case => "case"L, - ParseKeyword::kw_command => "command"L, - ParseKeyword::kw_else => "else"L, - ParseKeyword::kw_end => "end"L, - ParseKeyword::kw_exec => "exec"L, - ParseKeyword::kw_for => "for"L, - ParseKeyword::kw_function => "function"L, - ParseKeyword::kw_if => "if"L, - ParseKeyword::kw_in => "in"L, - ParseKeyword::kw_not => "not"L, - ParseKeyword::kw_or => "or"L, - ParseKeyword::kw_switch => "switch"L, - ParseKeyword::kw_time => "time"L, - ParseKeyword::kw_while => "while"L, - _ => "unknown_keyword"L, + ParseKeyword::kw_exclam => L!("!"), + ParseKeyword::kw_and => L!("and"), + ParseKeyword::kw_begin => L!("begin"), + ParseKeyword::kw_builtin => L!("builtin"), + ParseKeyword::kw_case => L!("case"), + ParseKeyword::kw_command => L!("command"), + ParseKeyword::kw_else => L!("else"), + ParseKeyword::kw_end => L!("end"), + ParseKeyword::kw_exec => L!("exec"), + ParseKeyword::kw_for => L!("for"), + ParseKeyword::kw_function => L!("function"), + ParseKeyword::kw_if => L!("if"), + ParseKeyword::kw_in => L!("in"), + ParseKeyword::kw_not => L!("not"), + ParseKeyword::kw_or => L!("or"), + ParseKeyword::kw_switch => L!("switch"), + ParseKeyword::kw_time => L!("time"), + ParseKeyword::kw_while => L!("while"), + _ => L!("unknown_keyword"), } } } @@ -244,27 +242,26 @@ impl printf_compat::args::ToArg<'static> for ParseKeyword { } impl From<&wstr> for ParseKeyword { - #[widestrs] fn from(s: &wstr) -> Self { match s { - _ if s == "!"L => ParseKeyword::kw_exclam, - _ if s == "and"L => ParseKeyword::kw_and, - _ if s == "begin"L => ParseKeyword::kw_begin, - _ if s == "builtin"L => ParseKeyword::kw_builtin, - _ if s == "case"L => ParseKeyword::kw_case, - _ if s == "command"L => ParseKeyword::kw_command, - _ if s == "else"L => ParseKeyword::kw_else, - _ if s == "end"L => ParseKeyword::kw_end, - _ if s == "exec"L => ParseKeyword::kw_exec, - _ if s == "for"L => ParseKeyword::kw_for, - _ if s == "function"L => ParseKeyword::kw_function, - _ if s == "if"L => ParseKeyword::kw_if, - _ if s == "in"L => ParseKeyword::kw_in, - _ if s == "not"L => ParseKeyword::kw_not, - _ if s == "or"L => ParseKeyword::kw_or, - _ if s == "switch"L => ParseKeyword::kw_switch, - _ if s == "time"L => ParseKeyword::kw_time, - _ if s == "while"L => ParseKeyword::kw_while, + _ if s == L!("!") => ParseKeyword::kw_exclam, + _ if s == L!("and") => ParseKeyword::kw_and, + _ if s == L!("begin") => ParseKeyword::kw_begin, + _ if s == L!("builtin") => ParseKeyword::kw_builtin, + _ if s == L!("case") => ParseKeyword::kw_case, + _ if s == L!("command") => ParseKeyword::kw_command, + _ if s == L!("else") => ParseKeyword::kw_else, + _ if s == L!("end") => ParseKeyword::kw_end, + _ if s == L!("exec") => ParseKeyword::kw_exec, + _ if s == L!("for") => ParseKeyword::kw_for, + _ if s == L!("function") => ParseKeyword::kw_function, + _ if s == L!("if") => ParseKeyword::kw_if, + _ if s == L!("in") => ParseKeyword::kw_in, + _ if s == L!("not") => ParseKeyword::kw_not, + _ if s == L!("or") => ParseKeyword::kw_or, + _ if s == L!("switch") => ParseKeyword::kw_switch, + _ if s == L!("time") => ParseKeyword::kw_time, + _ if s == L!("while") => ParseKeyword::kw_while, _ => ParseKeyword::none, } } @@ -402,27 +399,26 @@ impl ParseError { } } -#[widestrs] pub fn token_type_user_presentable_description( type_: ParseTokenType, keyword: ParseKeyword, ) -> WString { if keyword != ParseKeyword::none { - return sprintf!("keyword: '%ls'"L, keyword.to_wstr()); + return sprintf!(L!("keyword: '%ls'"), keyword.to_wstr()); } match type_ { - ParseTokenType::string => "a string"L.to_owned(), - ParseTokenType::pipe => "a pipe"L.to_owned(), - ParseTokenType::redirection => "a redirection"L.to_owned(), - ParseTokenType::background => "a '&'"L.to_owned(), - ParseTokenType::andand => "'&&'"L.to_owned(), - ParseTokenType::oror => "'||'"L.to_owned(), - ParseTokenType::end => "end of the statement"L.to_owned(), - ParseTokenType::terminate => "end of the input"L.to_owned(), - ParseTokenType::error => "a parse error"L.to_owned(), - ParseTokenType::tokenizer_error => "an incomplete token"L.to_owned(), - ParseTokenType::comment => "a comment"L.to_owned(), - _ => sprintf!("a %ls"L, type_.to_wstr()), + ParseTokenType::string => L!("a string").to_owned(), + ParseTokenType::pipe => L!("a pipe").to_owned(), + ParseTokenType::redirection => L!("a redirection").to_owned(), + ParseTokenType::background => L!("a '&'").to_owned(), + ParseTokenType::andand => L!("'&&'").to_owned(), + ParseTokenType::oror => L!("'||'").to_owned(), + ParseTokenType::end => L!("end of the statement").to_owned(), + ParseTokenType::terminate => L!("end of the input").to_owned(), + ParseTokenType::error => L!("a parse error").to_owned(), + ParseTokenType::tokenizer_error => L!("an incomplete token").to_owned(), + ParseTokenType::comment => L!("a comment").to_owned(), + _ => sprintf!(L!("a %ls"), type_.to_wstr()), } } diff --git a/src/parse_util.rs b/src/parse_util.rs index 1aef2a4e6..52b3d6d06 100644 --- a/src/parse_util.rs +++ b/src/parse_util.rs @@ -626,15 +626,20 @@ pub fn parse_util_escape_wildcards(s: &wstr) -> WString { } /// Checks if the specified string is a help option. -#[widestrs] pub fn parse_util_argument_is_help(s: &wstr) -> bool { - ["-h"L, "--help"L].contains(&s) + [L!("-h"), L!("--help")].contains(&s) } /// Returns true if the specified command is a builtin that may not be used in a pipeline. -#[widestrs] fn parser_is_pipe_forbidden(word: &wstr) -> bool { - ["exec"L, "case"L, "break"L, "return"L, "continue"L].contains(&word) + [ + L!("exec"), + L!("case"), + L!("break"), + L!("return"), + L!("continue"), + ] + .contains(&word) } // \return a pointer to the first argument node of an argument_or_redirection_list_t, or nullptr if diff --git a/src/parser.rs b/src/parser.rs index f0512b32a..a6197e514 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -46,7 +46,6 @@ use std::sync::{ atomic::{AtomicIsize, AtomicU64, Ordering}, Arc, }; -use widestring_suffix::widestrs; /// block_t represents a block of commands. #[derive(Default)] @@ -97,22 +96,21 @@ impl Block { } /// Description of the block, for debugging. - #[widestrs] pub fn description(&self) -> WString { let mut result = match self.typ() { - BlockType::while_block => "while"L, - BlockType::for_block => "for"L, - BlockType::if_block => "if"L, - BlockType::function_call => "function_call"L, - BlockType::function_call_no_shadow => "function_call_no_shadow"L, - BlockType::switch_block => "switch"L, - BlockType::subst => "substitution"L, - BlockType::top => "top"L, - BlockType::begin => "begin"L, - BlockType::source => "source"L, - BlockType::event => "event"L, - BlockType::breakpoint => "breakpoint"L, - BlockType::variable_assignment => "variable_assignment"L, + BlockType::while_block => L!("while"), + BlockType::for_block => L!("for"), + BlockType::if_block => L!("if"), + BlockType::function_call => L!("function_call"), + BlockType::function_call_no_shadow => L!("function_call_no_shadow"), + BlockType::switch_block => L!("switch"), + BlockType::subst => L!("substitution"), + BlockType::top => L!("top"), + BlockType::begin => L!("begin"), + BlockType::source => L!("source"), + BlockType::event => L!("event"), + BlockType::breakpoint => L!("breakpoint"), + BlockType::variable_assignment => L!("variable_assignment"), } .to_owned(); diff --git a/src/parser_keywords.rs b/src/parser_keywords.rs index e65a684a4..287064eea 100644 --- a/src/parser_keywords.rs +++ b/src/parser_keywords.rs @@ -2,33 +2,45 @@ use crate::wchar::prelude::*; -#[widestrs] -const SKIP_KEYWORDS: &[&wstr] = &["else"L, "begin"L]; -#[widestrs] +const SKIP_KEYWORDS: &[&wstr] = &[L!("else"), L!("begin")]; const SUBCOMMAND_KEYWORDS: &[&wstr] = &[ - "command"L, "builtin"L, "while"L, "exec"L, "if"L, "and"L, "or"L, "not"L, "time"L, "begin"L, + L!("command"), + L!("builtin"), + L!("while"), + L!("exec"), + L!("if"), + L!("and"), + L!("or"), + L!("not"), + L!("time"), + L!("begin"), +]; +const BLOCK_KEYWORDS: &[&wstr] = &[ + L!("for"), + L!("while"), + L!("if"), + L!("function"), + L!("switch"), + L!("begin"), ]; -#[widestrs] -const BLOCK_KEYWORDS: &[&wstr] = &["for"L, "while"L, "if"L, "function"L, "switch"L, "begin"L]; // Don't forget to add any new reserved keywords to the documentation -#[widestrs] const RESERVED_KEYWORDS: &[&wstr] = &[ - "end"L, - "case"L, - "else"L, - "return"L, - "continue"L, - "break"L, - "argparse"L, - "read"L, - "string"L, - "set"L, - "status"L, - "test"L, - "["L, - "_"L, - "eval"L, + L!("end"), + L!("case"), + L!("else"), + L!("return"), + L!("continue"), + L!("break"), + L!("argparse"), + L!("read"), + L!("string"), + L!("set"), + L!("status"), + L!("test"), + L!("["), + L!("_"), + L!("eval"), ]; // The lists above are purposely implemented separately from the logic below, so that future diff --git a/src/path.rs b/src/path.rs index 85fe55c69..0c297648e 100644 --- a/src/path.rs +++ b/src/path.rs @@ -71,15 +71,14 @@ pub fn path_get_config_remoteness() -> DirRemoteness { /// Emit any errors if config directories are missing. /// Use the given environment stack to ensure this only occurs once. -#[widestrs] pub fn path_emit_config_directory_messages(vars: &EnvStack) { let data = get_data_directory(); if !data.success() { maybe_issue_path_warning( - "data"L, + L!("data"), &wgettext!("can not save history"), data.used_xdg, - "XDG_DATA_HOME"L, + L!("XDG_DATA_HOME"), &data.path, data.err, vars, @@ -92,10 +91,10 @@ pub fn path_emit_config_directory_messages(vars: &EnvStack) { let config = get_config_directory(); if !config.success() { maybe_issue_path_warning( - "config"L, + L!("config"), &wgettext!("can not save universal variables or functions"), config.used_xdg, - "XDG_CONFIG_HOME"L, + L!("XDG_CONFIG_HOME"), &config.path, config.err, vars, @@ -110,7 +109,6 @@ pub fn path_emit_config_directory_messages(vars: &EnvStack) { /// problem, and thus is not central to the behavior of that function. Second, we only want to issue /// the message once. If the current shell starts a new fish shell (e.g., by running `fish -c` from /// a function) we don't want that subshell to issue the same warnings. -#[widestrs] fn maybe_issue_path_warning( which_dir: &wstr, custom_error_msg: &wstr, @@ -120,7 +118,7 @@ fn maybe_issue_path_warning( saved_errno: libc::c_int, vars: &EnvStack, ) { - let warning_var_name = "_FISH_WARNED_"L.to_owned() + which_dir; + let warning_var_name = L!("_FISH_WARNED_").to_owned() + which_dir; if vars .getf(&warning_var_name, EnvMode::GLOBAL | EnvMode::EXPORT) .is_some() @@ -130,7 +128,7 @@ fn maybe_issue_path_warning( vars.set_one( &warning_var_name, EnvMode::GLOBAL | EnvMode::EXPORT, - "1"L.to_owned(), + L!("1").to_owned(), ); FLOG!(error, custom_error_msg); @@ -147,7 +145,7 @@ fn maybe_issue_path_warning( ) ); } else { - let env_var = if using_xdg { xdg_var } else { "HOME"L }; + let env_var = if using_xdg { xdg_var } else { L!("HOME") }; FLOG!( warning_path, wgettext_fmt!( @@ -184,13 +182,12 @@ pub fn path_get_path(cmd: &wstr, vars: &dyn Environment) -> Option { } // PREFIX is defined at build time. -#[widestrs] pub static DEFAULT_PATH: Lazy<[WString; 3]> = Lazy::new(|| { [ // TODO This should use env!. The fallback is only to appease "cargo test" for now. - WString::from_str(option_env!("PREFIX").unwrap_or("/usr/local")) + "/bin"L, - "/usr/bin"L.to_owned(), - "/bin"L.to_owned(), + WString::from_str(option_env!("PREFIX").unwrap_or("/usr/local")) + L!("/bin"), + L!("/usr/bin").to_owned(), + L!("/bin").to_owned(), ] }); @@ -357,23 +354,25 @@ pub fn path_get_cdpath(dir: &wstr, wd: &wstr, vars: &dyn Environment) -> Option< } /// Returns the given directory with all CDPATH components applied. -#[widestrs] pub fn path_apply_cdpath(dir: &wstr, wd: &wstr, env_vars: &dyn Environment) -> Vec { let mut paths = vec![]; if dir.chars().next() == Some('/') { // Absolute path. paths.push(dir.to_owned()); - } else if dir.starts_with("./"L) || dir.starts_with("../"L) || ["."L, ".."L].contains(&dir) { + } else if dir.starts_with(L!("./")) + || dir.starts_with(L!("../")) + || [L!("."), L!("..")].contains(&dir) + { // Path is relative to the working directory. paths.push(path_normalize_for_cd(wd, dir)); } else { // Respect CDPATH. let mut cdpathsv = vec![]; - if let Some(cdpaths) = env_vars.get("CDPATH"L) { + if let Some(cdpaths) = env_vars.get(L!("CDPATH")) { cdpathsv = cdpaths.as_list().to_vec(); } // Always append $PWD - cdpathsv.push("."L.to_owned()); + cdpathsv.push(L!(".").to_owned()); for path in cdpathsv { let mut abspath = WString::new(); // We want to return an absolute path (see issue 6220) @@ -399,15 +398,14 @@ pub fn path_apply_cdpath(dir: &wstr, wd: &wstr, env_vars: &dyn Environment) -> V /// Returns the path resolved as an implicit cd command, or none() if none. This requires it to /// start with one of the allowed prefixes (., .., ~) and resolve to a directory. -#[widestrs] pub fn path_as_implicit_cd(path: &wstr, wd: &wstr, vars: &dyn Environment) -> Option { let mut exp_path = path.to_owned(); expand_tilde(&mut exp_path, vars); - if exp_path.starts_with("/"L) - || exp_path.starts_with("./"L) - || exp_path.starts_with("../"L) - || exp_path.ends_with("/"L) - || exp_path == ".."L + if exp_path.starts_with(L!("/")) + || exp_path.starts_with(L!("./")) + || exp_path.starts_with(L!("../")) + || exp_path.ends_with(L!("/")) + || exp_path == L!("..") { // These paths can be implicit cd, so see if you cd to the path. Note that a single period // cannot (that's used for sourcing files anyways). @@ -495,15 +493,14 @@ pub fn paths_are_equivalent(p1: &wstr, p2: &wstr) -> bool { idx1 == len1 && idx2 == len2 } -#[widestrs] pub fn path_is_valid(path: &wstr, working_directory: &wstr) -> bool { // Some special paths are always valid. if path.is_empty() { false - } else if ["."L, "./"L].contains(&path) { + } else if [L!("."), L!("./")].contains(&path) { true - } else if [".."L, "../"L].contains(&path) { - !working_directory.is_empty() && working_directory != "/"L + } else if [L!(".."), L!("../")].contains(&path) { + !working_directory.is_empty() && working_directory != L!("/") } else if path.chars().next() != Some('/') { // Prepend the working directory. Note that we know path is not empty here. let mut tmp = working_directory.to_owned(); @@ -582,7 +579,6 @@ impl BaseDirectory { /// Attempt to get a base directory, creating it if necessary. If a variable named \p xdg_var is /// set, use that directory; otherwise use the path \p non_xdg_homepath rooted in $HOME. \return the /// result; see the base_directory_t fields. -#[widestrs] fn make_base_directory(xdg_var: &wstr, non_xdg_homepath: &wstr) -> BaseDirectory { // The vars we fetch must be exported. Allowing them to be universal doesn't make sense and // allowing that creates a lock inversion that deadlocks the shell since we're called before @@ -592,10 +588,10 @@ fn make_base_directory(xdg_var: &wstr, non_xdg_homepath: &wstr) -> BaseDirectory let mut path = WString::new(); let used_xdg; if let Some(xdg_dir) = vars.getf_unless_empty(xdg_var, EnvMode::GLOBAL | EnvMode::EXPORT) { - path = xdg_dir.as_string() + "/fish"L; + path = xdg_dir.as_string() + L!("/fish"); used_xdg = true; } else { - if let Some(home) = vars.getf_unless_empty("HOME"L, EnvMode::GLOBAL | EnvMode::EXPORT) { + if let Some(home) = vars.getf_unless_empty(L!("HOME"), EnvMode::GLOBAL | EnvMode::EXPORT) { path = home.as_string() + non_xdg_homepath; } used_xdg = false; @@ -706,17 +702,15 @@ fn path_remoteness(path: &wstr) -> DirRemoteness { } } -#[widestrs] fn get_data_directory() -> &'static BaseDirectory { static DIR: Lazy = - Lazy::new(|| make_base_directory("XDG_DATA_HOME"L, "/.local/share/fish"L)); + Lazy::new(|| make_base_directory(L!("XDG_DATA_HOME"), L!("/.local/share/fish"))); &*DIR } -#[widestrs] fn get_config_directory() -> &'static BaseDirectory { static DIR: Lazy = - Lazy::new(|| make_base_directory("XDG_CONFIG_HOME"L, "/.config/fish"L)); + Lazy::new(|| make_base_directory(L!("XDG_CONFIG_HOME"), L!("/.config/fish"))); &*DIR } diff --git a/src/proc.rs b/src/proc.rs index 892c921b5..08f7c2503 100644 --- a/src/proc.rs +++ b/src/proc.rs @@ -38,7 +38,6 @@ use std::os::fd::RawFd; use std::rc::Rc; use std::sync::atomic::{AtomicBool, AtomicI32, AtomicU64, AtomicU8, Ordering}; use std::sync::{Arc, Mutex}; -use widestring_suffix::widestrs; /// Types of processes. #[derive(Default, Eq, PartialEq)] @@ -844,15 +843,14 @@ impl Job { /// due to reuse of freed job ids. Prevents overloading the debug comments with the full, /// untruncated job string when we don't care what the job is, only which of the currently /// running jobs it is. - #[widestrs] pub fn preview(&self) -> WString { if self.processes().is_empty() { - return ""L.to_owned(); + return L!("").to_owned(); } // Note argv0 may be empty in e.g. a block process. let procs = self.processes(); - let result = procs.first().unwrap().argv0().unwrap_or("null"L); - result.to_owned() + "..."L + let result = procs.first().unwrap().argv0().unwrap_or(L!("null")); + result.to_owned() + L!("...") } /// \return our pgid, or none if we don't have one, or are internal to fish @@ -1185,7 +1183,6 @@ pub fn jobs_requiring_warning_on_exit(parser: &Parser) -> JobList { /// Print the exit warning for the given jobs, which should have been obtained via /// jobs_requiring_warning_on_exit(). -#[widestrs] pub fn print_exit_warning_for_jobs(jobs: &JobList) { printf!("%s", wgettext!("There are still jobs active:\n")); printf!("%s", wgettext!("\n PID Command\n")); @@ -1581,9 +1578,8 @@ fn call_job_summary(parser: &Parser, cmd: &wstr) { // \return a command which invokes fish_job_summary. // The process pointer may be null, in which case it represents the entire job. // Note this implements the arguments which fish_job_summary expects. -#[widestrs] fn summary_command(j: &Job, p: Option<&Process>) -> WString { - let mut buffer = "fish_job_summary"L.to_owned(); + let mut buffer = L!("fish_job_summary").to_owned(); // Job id. buffer += &sprintf!(" %s", j.job_id().to_wstring())[..]; @@ -1599,9 +1595,9 @@ fn summary_command(j: &Job, p: Option<&Process>) -> WString { None => { // No process, we are summarizing the whole job. buffer += if j.is_stopped() { - " STOPPED"L + L!(" STOPPED") } else { - " ENDED"L + L!(" ENDED") }; } Some(p) => { diff --git a/src/signal.rs b/src/signal.rs index 93bedb98d..b66a2b005 100644 --- a/src/signal.rs +++ b/src/signal.rs @@ -357,60 +357,59 @@ impl LookupEntry { // Lookup table used to convert between signal names and signal ids, etc. #[rustfmt::skip] -#[widestrs] const SIGNAL_TABLE : &[LookupEntry] = &[ - LookupEntry::new(libc::SIGHUP, "SIGHUP"L, "Terminal hung up"L), - LookupEntry::new(libc::SIGINT, "SIGINT"L, "Quit request from job control (^C)"L), - LookupEntry::new(libc::SIGQUIT, "SIGQUIT"L, "Quit request from job control with core dump (^\\)"L), - LookupEntry::new(libc::SIGILL, "SIGILL"L, "Illegal instruction"L), - LookupEntry::new(libc::SIGTRAP, "SIGTRAP"L, "Trace or breakpoint trap"L), - LookupEntry::new(libc::SIGABRT, "SIGABRT"L, "Abort"L), - LookupEntry::new(libc::SIGBUS, "SIGBUS"L, "Misaligned address error"L), - LookupEntry::new(libc::SIGFPE, "SIGFPE"L, "Floating point exception"L), - LookupEntry::new(libc::SIGKILL, "SIGKILL"L, "Forced quit"L), - LookupEntry::new(libc::SIGUSR1, "SIGUSR1"L, "User defined signal 1"L), - LookupEntry::new(libc::SIGUSR2, "SIGUSR2"L, "User defined signal 2"L), - LookupEntry::new(libc::SIGSEGV, "SIGSEGV"L, "Address boundary error"L), - LookupEntry::new(libc::SIGPIPE, "SIGPIPE"L, "Broken pipe"L), - LookupEntry::new(libc::SIGALRM, "SIGALRM"L, "Timer expired"L), - LookupEntry::new(libc::SIGTERM, "SIGTERM"L, "Polite quit request"L), - LookupEntry::new(libc::SIGCHLD, "SIGCHLD"L, "Child process status changed"L), - LookupEntry::new(libc::SIGCONT, "SIGCONT"L, "Continue previously stopped process"L), - LookupEntry::new(libc::SIGSTOP, "SIGSTOP"L, "Forced stop"L), - LookupEntry::new(libc::SIGTSTP, "SIGTSTP"L, "Stop request from job control (^Z)"L), - LookupEntry::new(libc::SIGTTIN, "SIGTTIN"L, "Stop from terminal input"L), - LookupEntry::new(libc::SIGTTOU, "SIGTTOU"L, "Stop from terminal output"L), - LookupEntry::new(libc::SIGURG, "SIGURG"L, "Urgent socket condition"L), - LookupEntry::new(libc::SIGXCPU, "SIGXCPU"L, "CPU time limit exceeded"L), - LookupEntry::new(libc::SIGXFSZ, "SIGXFSZ"L, "File size limit exceeded"L), - LookupEntry::new(libc::SIGVTALRM, "SIGVTALRM"L, "Virtual timefr expired"L), - LookupEntry::new(libc::SIGPROF, "SIGPROF"L, "Profiling timer expired"L), - LookupEntry::new(libc::SIGWINCH, "SIGWINCH"L, "Window size change"L), - LookupEntry::new(libc::SIGIO, "SIGIO"L, "I/O on asynchronous file descriptor is possible"L), - LookupEntry::new(libc::SIGSYS, "SIGSYS"L, "Bad system call"L), - LookupEntry::new(libc::SIGIOT, "SIGIOT"L, "Abort (Alias for SIGABRT)"L), + LookupEntry::new(libc::SIGHUP, L!("SIGHUP"), L!("Terminal hung up")), + LookupEntry::new(libc::SIGINT, L!("SIGINT"), L!("Quit request from job control (^C)")), + LookupEntry::new(libc::SIGQUIT, L!("SIGQUIT"), L!("Quit request from job control with core dump (^\\)")), + LookupEntry::new(libc::SIGILL, L!("SIGILL"), L!("Illegal instruction")), + LookupEntry::new(libc::SIGTRAP, L!("SIGTRAP"), L!("Trace or breakpoint trap")), + LookupEntry::new(libc::SIGABRT, L!("SIGABRT"), L!("Abort")), + LookupEntry::new(libc::SIGBUS, L!("SIGBUS"), L!("Misaligned address error")), + LookupEntry::new(libc::SIGFPE, L!("SIGFPE"), L!("Floating point exception")), + LookupEntry::new(libc::SIGKILL, L!("SIGKILL"), L!("Forced quit")), + LookupEntry::new(libc::SIGUSR1, L!("SIGUSR1"), L!("User defined signal 1")), + LookupEntry::new(libc::SIGUSR2, L!("SIGUSR2"), L!("User defined signal 2")), + LookupEntry::new(libc::SIGSEGV, L!("SIGSEGV"), L!("Address boundary error")), + LookupEntry::new(libc::SIGPIPE, L!("SIGPIPE"), L!("Broken pipe")), + LookupEntry::new(libc::SIGALRM, L!("SIGALRM"), L!("Timer expired")), + LookupEntry::new(libc::SIGTERM, L!("SIGTERM"), L!("Polite quit request")), + LookupEntry::new(libc::SIGCHLD, L!("SIGCHLD"), L!("Child process status changed")), + LookupEntry::new(libc::SIGCONT, L!("SIGCONT"), L!("Continue previously stopped process")), + LookupEntry::new(libc::SIGSTOP, L!("SIGSTOP"), L!("Forced stop")), + LookupEntry::new(libc::SIGTSTP, L!("SIGTSTP"), L!("Stop request from job control (^Z)")), + LookupEntry::new(libc::SIGTTIN, L!("SIGTTIN"), L!("Stop from terminal input")), + LookupEntry::new(libc::SIGTTOU, L!("SIGTTOU"), L!("Stop from terminal output")), + LookupEntry::new(libc::SIGURG, L!("SIGURG"), L!("Urgent socket condition")), + LookupEntry::new(libc::SIGXCPU, L!("SIGXCPU"), L!("CPU time limit exceeded")), + LookupEntry::new(libc::SIGXFSZ, L!("SIGXFSZ"), L!("File size limit exceeded")), + LookupEntry::new(libc::SIGVTALRM, L!("SIGVTALRM"), L!("Virtual timefr expired")), + LookupEntry::new(libc::SIGPROF, L!("SIGPROF"), L!("Profiling timer expired")), + LookupEntry::new(libc::SIGWINCH, L!("SIGWINCH"), L!("Window size change")), + LookupEntry::new(libc::SIGIO, L!("SIGIO"), L!("I/O on asynchronous file descriptor is possible")), + LookupEntry::new(libc::SIGSYS, L!("SIGSYS"), L!("Bad system call")), + LookupEntry::new(libc::SIGIOT, L!("SIGIOT"), L!("Abort (Alias for SIGABRT)")), #[cfg(any(feature = "bsd", target_os = "macos"))] - LookupEntry::new(libc::SIGEMT, "SIGEMT"L, "Unused signal"L), + LookupEntry::new(libc::SIGEMT, L!("SIGEMT"), L!("Unused signal")), #[cfg(any(feature = "bsd", target_os = "macos"))] - LookupEntry::new(libc::SIGINFO, "SIGINFO"L, "Information request"L), + LookupEntry::new(libc::SIGINFO, L!("SIGINFO"), L!("Information request")), #[cfg(target_os = "linux")] - LookupEntry::new(libc::SIGSTKFLT, "SISTKFLT"L, "Stack fault"L), + LookupEntry::new(libc::SIGSTKFLT, L!("SISTKFLT"), L!("Stack fault")), #[cfg(target_os = "linux")] - LookupEntry::new(libc::SIGIOT, "SIGIOT"L, "Abort (Alias for SIGABRT)"L), + LookupEntry::new(libc::SIGIOT, L!("SIGIOT"), L!("Abort (Alias for SIGABRT)")), #[cfg(target_os = "linux")] #[allow(deprecated)] - LookupEntry::new(libc::SIGUNUSED, "SIGUNUSED"L, "Unused signal"L), + LookupEntry::new(libc::SIGUNUSED, L!("SIGUNUSED"), L!("Unused signal")), #[cfg(target_os = "linux")] - LookupEntry::new(libc::SIGPWR, "SIGPWR"L, "Power failure"L), + LookupEntry::new(libc::SIGPWR, L!("SIGPWR"), L!("Power failure")), // TODO: determine whether SIGWIND is defined on any platform. - //LookupEntry::new(libc::SIGWIND, "SIGWIND"L, "Window size change"L), + //LookupEntry::new(libc::SIGWIND, L!("SIGWIND"), L!("Window size change")), ]; // Return true if two strings are equal, ignoring ASCII case. diff --git a/src/tests/env.rs b/src/tests/env.rs index 5b592bfd8..be41711c4 100644 --- a/src/tests/env.rs +++ b/src/tests/env.rs @@ -5,7 +5,6 @@ use crate::wchar::prelude::*; use crate::wutil::wgetcwd; use std::collections::HashMap; use std::time::{SystemTime, UNIX_EPOCH}; -use widestring_suffix::widestrs; /// An environment built around an std::map. #[derive(Clone, Default)] @@ -40,10 +39,9 @@ impl PwdEnvironment { Self::default() } } -#[widestrs] impl Environment for PwdEnvironment { fn getf(&self, name: &wstr, mode: EnvMode) -> Option { - if name == "PWD"L { + if name == L!("PWD") { return Some(EnvVar::new(wgetcwd(), EnvVarFlags::default())); } self.parent.getf(name, mode) @@ -51,8 +49,8 @@ impl Environment for PwdEnvironment { fn get_names(&self, flags: EnvMode) -> Vec { let mut res = self.parent.get_names(flags); - if !res.iter().any(|n| n == "PWD"L) { - res.push("PWD"L.to_owned()); + if !res.iter().any(|n| n == L!("PWD")) { + res.push(L!("PWD").to_owned()); } res } diff --git a/src/tests/string_escape.rs b/src/tests/string_escape.rs index 457de6c2c..4b59c1931 100644 --- a/src/tests/string_escape.rs +++ b/src/tests/string_escape.rs @@ -2,7 +2,7 @@ use crate::common::{ escape_string, str2wcstring, unescape_string, wcs2string, EscapeFlags, EscapeStringStyle, UnescapeStringStyle, ENCODE_DIRECT_BASE, ENCODE_DIRECT_END, }; -use crate::wchar::{widestrs, wstr, WString}; +use crate::wchar::{wstr, WString, L}; use crate::wutil::encoding::{wcrtomb, zero_mbstate, AT_LEAST_MB_LEN_MAX}; use rand::{Rng, RngCore}; use rand_pcg::Pcg64Mcg; @@ -31,41 +31,39 @@ fn setlocale() { panic!("No UTF-8 locale found"); } -#[widestrs] #[test] fn test_escape_string() { let regex = |input| escape_string(input, EscapeStringStyle::Regex); // plain text should not be needlessly escaped - assert_eq!(regex("hello world!"L), "hello world!"L); + assert_eq!(regex(L!("hello world!")), L!("hello world!")); // all the following are intended to be ultimately matched literally - even if they // don't look like that's the intent - so we escape them. - assert_eq!(regex(".ext"L), "\\.ext"L); - assert_eq!(regex("{word}"L), "\\{word\\}"L); - assert_eq!(regex("hola-mundo"L), "hola\\-mundo"L); + assert_eq!(regex(L!(".ext")), L!("\\.ext")); + assert_eq!(regex(L!("{word}")), L!("\\{word\\}")); + assert_eq!(regex(L!("hola-mundo")), L!("hola\\-mundo")); assert_eq!( - regex("$17.42 is your total?"L), - "\\$17\\.42 is your total\\?"L + regex(L!("$17.42 is your total?")), + L!("\\$17\\.42 is your total\\?") ); assert_eq!( - regex("not really escaped\\?"L), - "not really escaped\\\\\\?"L + regex(L!("not really escaped\\?")), + L!("not really escaped\\\\\\?") ); } -#[widestrs] #[test] pub fn test_unescape_sane() { const TEST_CASES: &[(&wstr, &wstr)] = &[ - ("abcd"L, "abcd"L), - ("'abcd'"L, "abcd"L), - ("'abcd\\n'"L, "abcd\\n"L), - ("\"abcd\\n\""L, "abcd\\n"L), - ("\"abcd\\n\""L, "abcd\\n"L), - ("\\143"L, "c"L), - ("'\\143'"L, "\\143"L), - ("\\n"L, "\n"L), // \n normally becomes newline + (L!("abcd"), L!("abcd")), + (L!("'abcd'"), L!("abcd")), + (L!("'abcd\\n'"), L!("abcd\\n")), + (L!("\"abcd\\n\""), L!("abcd\\n")), + (L!("\"abcd\\n\""), L!("abcd\\n")), + (L!("\\143"), L!("c")), + (L!("'\\143'"), L!("\\143")), + (L!("\\n"), L!("\n")), // \n normally becomes newline ]; for (input, expected) in TEST_CASES { @@ -80,17 +78,16 @@ pub fn test_unescape_sane() { } } -#[widestrs] #[test] fn test_escape_var() { const TEST_CASES: &[(&wstr, &wstr)] = &[ - (" a"L, "_20_a"L), - ("a B "L, "a_20_42_20_"L), - ("a b "L, "a_20_b_20_"L), - (" B"L, "_20_42_"L), - (" f"L, "_20_f"L), - (" 1"L, "_20_31_"L), - ("a\nghi_"L, "a_0A_ghi__"L), + (L!(" a"), L!("_20_a")), + (L!("a B "), L!("a_20_42_20_")), + (L!("a b "), L!("a_20_b_20_")), + (L!(" B"), L!("_20_42_")), + (L!(" f"), L!("_20_f")), + (L!(" 1"), L!("_20_31_")), + (L!("a\nghi_"), L!("a_0A_ghi__")), ]; for (input, expected) in TEST_CASES { @@ -142,11 +139,10 @@ fn test_escape_random_url() { escape_test(EscapeStringStyle::Url, UnescapeStringStyle::Url); } -#[widestrs] #[test] fn test_escape_no_printables() { // Verify that ESCAPE_NO_PRINTABLES also escapes backslashes so we don't regress on issue #3892. - let random_string = "line 1\\n\nline 2"L.to_owned(); + let random_string = L!("line 1\\n\nline 2").to_owned(); let escaped_string = escape_string( &random_string, EscapeStringStyle::Script(EscapeFlags::NO_PRINTABLES | EscapeFlags::NO_QUOTED), diff --git a/src/tinyexpr.rs b/src/tinyexpr.rs index e32426d1a..4742b7de1 100644 --- a/src/tinyexpr.rs +++ b/src/tinyexpr.rs @@ -95,7 +95,6 @@ pub enum ErrorKind { Unknown, } -#[widestrs] impl ErrorKind { pub fn describe_wstr(&self) -> &'static wstr { match self { @@ -273,50 +272,49 @@ fn npr(n: f64, r: f64) -> f64 { ncr(n, r) * fac(r) } -#[widestrs] const BUILTINS: &[(&wstr, Function)] = &[ // must be in alphabetical order - ("abs"L, Function::Fn1(f64::abs)), - ("acos"L, Function::Fn1(f64::acos)), - ("asin"L, Function::Fn1(f64::asin)), - ("atan"L, Function::Fn1(f64::atan)), - ("atan2"L, Function::Fn2(f64::atan2)), + (L!("abs"), Function::Fn1(f64::abs)), + (L!("acos"), Function::Fn1(f64::acos)), + (L!("asin"), Function::Fn1(f64::asin)), + (L!("atan"), Function::Fn1(f64::atan)), + (L!("atan2"), Function::Fn2(f64::atan2)), ( - "bitand"L, + L!("bitand"), Function::Fn2(|a, b| bitwise_op(a, b, BitAnd::bitand)), ), ( - "bitor"L, + L!("bitor"), Function::Fn2(|a, b| bitwise_op(a, b, BitOr::bitor)), ), ( - "bitxor"L, + L!("bitxor"), Function::Fn2(|a, b| bitwise_op(a, b, BitXor::bitxor)), ), - ("ceil"L, Function::Fn1(f64::ceil)), - ("cos"L, Function::Fn1(f64::cos)), - ("cosh"L, Function::Fn1(f64::cosh)), - ("e"L, Function::Constant(E)), - ("exp"L, Function::Fn1(f64::exp)), - ("fac"L, Function::Fn1(fac)), - ("floor"L, Function::Fn1(f64::floor)), - ("ln"L, Function::Fn1(f64::ln)), - ("log"L, Function::Fn1(f64::log10)), - ("log10"L, Function::Fn1(f64::log10)), - ("log2"L, Function::Fn1(f64::log2)), - ("max"L, Function::FnN(maximum)), - ("min"L, Function::FnN(minimum)), - ("ncr"L, Function::Fn2(ncr)), - ("npr"L, Function::Fn2(npr)), - ("pi"L, Function::Constant(PI)), - ("pow"L, Function::Fn2(f64::powf)), - ("round"L, Function::Fn1(f64::round)), - ("sin"L, Function::Fn1(f64::sin)), - ("sinh"L, Function::Fn1(f64::sinh)), - ("sqrt"L, Function::Fn1(f64::sqrt)), - ("tan"L, Function::Fn1(f64::tan)), - ("tanh"L, Function::Fn1(f64::tanh)), - ("tau"L, Function::Constant(TAU)), + (L!("ceil"), Function::Fn1(f64::ceil)), + (L!("cos"), Function::Fn1(f64::cos)), + (L!("cosh"), Function::Fn1(f64::cosh)), + (L!("e"), Function::Constant(E)), + (L!("exp"), Function::Fn1(f64::exp)), + (L!("fac"), Function::Fn1(fac)), + (L!("floor"), Function::Fn1(f64::floor)), + (L!("ln"), Function::Fn1(f64::ln)), + (L!("log"), Function::Fn1(f64::log10)), + (L!("log10"), Function::Fn1(f64::log10)), + (L!("log2"), Function::Fn1(f64::log2)), + (L!("max"), Function::FnN(maximum)), + (L!("min"), Function::FnN(minimum)), + (L!("ncr"), Function::Fn2(ncr)), + (L!("npr"), Function::Fn2(npr)), + (L!("pi"), Function::Constant(PI)), + (L!("pow"), Function::Fn2(f64::powf)), + (L!("round"), Function::Fn1(f64::round)), + (L!("sin"), Function::Fn1(f64::sin)), + (L!("sinh"), Function::Fn1(f64::sinh)), + (L!("sqrt"), Function::Fn1(f64::sqrt)), + (L!("tan"), Function::Fn1(f64::tan)), + (L!("tanh"), Function::Fn1(f64::tanh)), + (L!("tau"), Function::Constant(TAU)), ]; assert_sorted_by_name!(BUILTINS, 0); diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 76d82d719..f34892298 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -143,10 +143,9 @@ pub const TOK_SHOW_BLANK_LINES: TokFlags = TokFlags(4); pub const TOK_CONTINUE_AFTER_ERROR: TokFlags = TokFlags(8); impl From for &'static wstr { - #[widestrs] fn from(err: TokenizerError) -> Self { match err { - TokenizerError::none => ""L, + TokenizerError::none => L!(""), TokenizerError::unterminated_quote => { wgettext!("Unexpected end of string, quotes are not balanced") } diff --git a/src/topic_monitor.rs b/src/topic_monitor.rs index 4a0f2f034..b6dd85ece 100644 --- a/src/topic_monitor.rs +++ b/src/topic_monitor.rs @@ -32,7 +32,6 @@ use std::mem; use std::pin::Pin; use std::sync::atomic::{AtomicU8, Ordering}; use std::sync::{Condvar, Mutex, MutexGuard}; -use widestring_suffix::widestrs; /// The list of topics which may be observed. #[repr(u8)] @@ -73,7 +72,6 @@ pub fn all_topics() -> [topic_t; 3] { [topic_t::sighupint, topic_t::sigchld, topic_t::internal_exit] } -#[widestrs] impl GenerationsList { pub fn new() -> Self { Self::default() diff --git a/src/wchar.rs b/src/wchar.rs index 43174684c..c40bfe2de 100644 --- a/src/wchar.rs +++ b/src/wchar.rs @@ -16,7 +16,6 @@ pub mod prelude { wchar_ext::{ToWString, WExt}, wutil::{sprintf, wgettext, wgettext_fmt, wgettext_maybe_fmt, wgettext_str}, }; - pub use widestring_suffix::widestrs; } /// Creates a wstr string slice, like the "L" prefix of C++. @@ -30,17 +29,6 @@ macro_rules! L { } pub use L; -/// A proc-macro for creating wide string literals using an L *suffix*. -/// Example usage: -/// ```ignore -/// #[widestrs] -/// pub fn func() { -/// let s = "hello"L; // type &'static wstr -/// } -/// ``` -/// Note: the resulting string is NOT nul-terminated. -pub use widestring_suffix::widestrs; - /// Encode a literal byte in a UTF-32 character. This is required for e.g. the echo builtin, whose /// escape sequences can be used to construct raw byte sequences which are then interpreted as e.g. /// UTF-8 by the terminal. If we were to interpret each of those bytes as a codepoint and encode it diff --git a/src/wutil/mod.rs b/src/wutil/mod.rs index 8c34407b7..13bf9cb89 100644 --- a/src/wutil/mod.rs +++ b/src/wutil/mod.rs @@ -27,7 +27,6 @@ use std::io::{self, Write}; use std::os::unix::prelude::*; pub use wcstoi::*; -use widestring_suffix::widestrs; /// Wide character version of opendir(). Note that opendir() is guaranteed to set close-on-exec by /// POSIX (hooray). @@ -274,7 +273,6 @@ fn test_normalize_path() { /// appropriate for cd. That is, return effectively wd + path while resolving leading ../s from /// path. The intent here is to allow 'cd' out of a directory which may no longer exist, without /// allowing 'cd' into a directory that may not exist; see #5341. -#[widestrs] pub fn path_normalize_for_cd(wd: &wstr, path: &wstr) -> WString { // Fast paths. const sep: char = '/'; @@ -302,9 +300,9 @@ pub fn path_normalize_for_cd(wd: &wstr, path: &wstr) -> WString { let mut erase_count = 0; for comp in &path_comps { let mut erase_it = false; - if comp.is_empty() || comp == "."L { + if comp.is_empty() || comp == L!(".") { erase_it = true; - } else if comp == ".."L && !wd_comps.is_empty() { + } else if comp == L!("..") && !wd_comps.is_empty() { erase_it = true; wd_comps.pop(); } diff --git a/src/wutil/tests.rs b/src/wutil/tests.rs index 3caae3bda..223c6731f 100644 --- a/src/wutil/tests.rs +++ b/src/wutil/tests.rs @@ -8,23 +8,22 @@ use crate::fallback::fish_mkstemp_cloexec; use super::*; #[test] -#[widestrs] fn test_wdirname_wbasename() { // path, dir, base struct Test(&'static wstr, &'static wstr, &'static wstr); const testcases: &[Test] = &[ - Test(""L, "."L, "."L), - Test("foo//"L, "."L, "foo"L), - Test("foo//////"L, "."L, "foo"L), - Test("/////foo"L, "/"L, "foo"L), - Test("//foo/////bar"L, "//foo"L, "bar"L), - Test("foo/////bar"L, "foo"L, "bar"L), + Test(L!(""), L!("."), L!(".")), + Test(L!("foo//"), L!("."), L!("foo")), + Test(L!("foo//////"), L!("."), L!("foo")), + Test(L!("/////foo"), L!("/"), L!("foo")), + Test(L!("//foo/////bar"), L!("//foo"), L!("bar")), + Test(L!("foo/////bar"), L!("foo"), L!("bar")), // Examples given in XPG4.2. - Test("/usr/lib"L, "/usr"L, "lib"L), - Test("usr"L, "."L, "usr"L), - Test("/"L, "/"L, "/"L), - Test("."L, "."L, "."L), - Test(".."L, "."L, ".."L), + Test(L!("/usr/lib"), L!("/usr"), L!("lib")), + Test(L!("usr"), L!("."), L!("usr")), + Test(L!("/"), L!("/"), L!("/")), + Test(L!("."), L!("."), L!(".")), + Test(L!(".."), L!("."), L!("..")), ]; for tc in testcases { @@ -54,7 +53,7 @@ fn test_wdirname_wbasename() { let last_slash = longpath.chars().rposition(|c| c == '/').unwrap(); let longpath_dir = &longpath[..last_slash]; assert_eq!(wdirname(&longpath), longpath_dir); - assert_eq!(wbasename(&longpath), "overlong"L); + assert_eq!(wbasename(&longpath), L!("overlong")); } #[test]