uucore: Cache args_os(), util_name(), execution_phrase()

And remove args() because there's no valid use for it, invalid unicode
handling is specified in a different way.
This commit is contained in:
Jan Verbeek 2021-09-01 16:34:20 +02:00
parent d093c07887
commit 60df3c6b7c
8 changed files with 37 additions and 35 deletions

1
Cargo.lock generated
View file

@ -3276,6 +3276,7 @@ dependencies = [
"getopts", "getopts",
"lazy_static", "lazy_static",
"libc", "libc",
"once_cell",
"termion", "termion",
"thiserror", "thiserror",
"time", "time",

View file

@ -38,7 +38,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
let name = uucore::util_name(); let name = uucore::util_name();
let config_result: Result<base_common::Config, String> = let config_result: Result<base_common::Config, String> =
base_common::parse_base_cmd_args(args, &name, VERSION, ABOUT, &usage); base_common::parse_base_cmd_args(args, name, VERSION, ABOUT, &usage);
let config = config_result.unwrap_or_else(|s| crash!(BASE_CMD_PARSE_ERROR, "{}", s)); let config = config_result.unwrap_or_else(|s| crash!(BASE_CMD_PARSE_ERROR, "{}", s));
// Create a reference to stdin so we can return a locked stdin from // Create a reference to stdin so we can return a locked stdin from
@ -52,12 +52,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
config.wrap_cols, config.wrap_cols,
config.ignore_garbage, config.ignore_garbage,
config.decode, config.decode,
&name, name,
); );
0 0
} }
pub fn uu_app() -> App<'static, 'static> { pub fn uu_app() -> App<'static, 'static> {
base_common::base_app(&uucore::util_name(), VERSION, ABOUT) base_common::base_app(uucore::util_name(), VERSION, ABOUT)
} }

View file

@ -38,7 +38,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
let usage = usage(); let usage = usage();
let name = uucore::util_name(); let name = uucore::util_name();
let config_result: Result<base_common::Config, String> = let config_result: Result<base_common::Config, String> =
base_common::parse_base_cmd_args(args, &name, VERSION, ABOUT, &usage); base_common::parse_base_cmd_args(args, name, VERSION, ABOUT, &usage);
let config = config_result.unwrap_or_else(|s| crash!(BASE_CMD_PARSE_ERROR, "{}", s)); let config = config_result.unwrap_or_else(|s| crash!(BASE_CMD_PARSE_ERROR, "{}", s));
// Create a reference to stdin so we can return a locked stdin from // Create a reference to stdin so we can return a locked stdin from
@ -52,7 +52,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
config.wrap_cols, config.wrap_cols,
config.ignore_garbage, config.ignore_garbage,
config.decode, config.decode,
&name, name,
); );
0 0

View file

@ -47,7 +47,7 @@ fn usage() -> String {
} }
pub fn uu_app() -> App<'static, 'static> { pub fn uu_app() -> App<'static, 'static> {
let mut app = base_common::base_app(&uucore::util_name(), crate_version!(), ABOUT); let mut app = base_common::base_app(uucore::util_name(), crate_version!(), ABOUT);
for encoding in ENCODINGS { for encoding in ENCODINGS {
app = app.arg(Arg::with_name(encoding.0).long(encoding.0)); app = app.arg(Arg::with_name(encoding.0).long(encoding.0));
} }
@ -88,7 +88,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
config.wrap_cols, config.wrap_cols,
config.ignore_garbage, config.ignore_garbage,
config.decode, config.decode,
&name, name,
); );
0 0

View file

@ -466,7 +466,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let options = Options { let options = Options {
all: matches.is_present(options::ALL), all: matches.is_present(options::ALL),
util_name: uucore::util_name(), util_name: uucore::util_name().to_owned(),
max_depth, max_depth,
total: matches.is_present(options::TOTAL), total: matches.is_present(options::TOTAL),
separate_dirs: matches.is_present(options::SEPARATE_DIRS), separate_dirs: matches.is_present(options::SEPARATE_DIRS),

View file

@ -35,7 +35,7 @@ fn get_userlogin() -> Option<String> {
static SUMMARY: &str = "Print user's login name"; static SUMMARY: &str = "Print user's login name";
fn usage() -> String { fn usage() -> &'static str {
uucore::execution_phrase() uucore::execution_phrase()
} }
@ -44,8 +44,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.collect_str(InvalidEncodingHandling::Ignore) .collect_str(InvalidEncodingHandling::Ignore)
.accept_any(); .accept_any();
let usage = usage(); let _ = uu_app().usage(usage()).get_matches_from(args);
let _ = uu_app().usage(&usage[..]).get_matches_from(args);
match get_userlogin() { match get_userlogin() {
Some(userlogin) => println!("{}", userlogin), Some(userlogin) => println!("{}", userlogin),

View file

@ -30,6 +30,7 @@ data-encoding = { version="2.1", optional=true }
data-encoding-macro = { version="0.1.12", optional=true } data-encoding-macro = { version="0.1.12", optional=true }
z85 = { version="3.0.3", optional=true } z85 = { version="3.0.3", optional=true }
libc = { version="0.2.15", optional=true } libc = { version="0.2.15", optional=true }
once_cell = "1.8.0"
[dev-dependencies] [dev-dependencies]
clap = "2.33.3" clap = "2.33.3"

View file

@ -70,6 +70,8 @@ pub use crate::features::wide;
use std::ffi::OsString; use std::ffi::OsString;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use once_cell::sync::Lazy;
pub fn get_utility_is_second_arg() -> bool { pub fn get_utility_is_second_arg() -> bool {
crate::macros::UTILITY_IS_SECOND_ARG.load(Ordering::SeqCst) crate::macros::UTILITY_IS_SECOND_ARG.load(Ordering::SeqCst)
} }
@ -78,36 +80,40 @@ pub fn set_utility_is_second_arg() {
crate::macros::UTILITY_IS_SECOND_ARG.store(true, Ordering::SeqCst) crate::macros::UTILITY_IS_SECOND_ARG.store(true, Ordering::SeqCst)
} }
/// Get the executable path (as `OsString`). // args_os() can be expensive to call, it copies all of argv before iterating.
fn executable_os() -> OsString { // So if we want only the first arg or so it's overkill. We cache it.
args_os().next().unwrap() static ARGV: Lazy<Vec<OsString>> = Lazy::new(|| wild::args_os().collect());
}
/// Get the executable path (as `String`). static UTIL_NAME: Lazy<String> = Lazy::new(|| {
fn executable() -> String { if get_utility_is_second_arg() {
executable_os().to_string_lossy().into_owned() &ARGV[1]
} } else {
&ARGV[0]
}
.to_string_lossy()
.into_owned()
});
/// Derive the utility name. /// Derive the utility name.
pub fn util_name() -> String { pub fn util_name() -> &'static str {
if get_utility_is_second_arg() { &UTIL_NAME
args_os().nth(1).unwrap().to_string_lossy().into_owned()
} else {
executable()
}
} }
/// Derive the complete execution phrase for "usage". static EXECUTION_PHRASE: Lazy<String> = Lazy::new(|| {
pub fn execution_phrase() -> String {
if get_utility_is_second_arg() { if get_utility_is_second_arg() {
args_os() ARGV.iter()
.take(2) .take(2)
.map(|os_str| os_str.to_string_lossy().into_owned()) .map(|os_str| os_str.to_string_lossy().into_owned())
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(" ") .join(" ")
} else { } else {
executable() ARGV[0].to_string_lossy().into_owned()
} }
});
/// Derive the complete execution phrase for "usage".
pub fn execution_phrase() -> &'static str {
&EXECUTION_PHRASE
} }
pub enum InvalidEncodingHandling { pub enum InvalidEncodingHandling {
@ -204,13 +210,8 @@ pub trait Args: Iterator<Item = OsString> + Sized {
impl<T: Iterator<Item = OsString> + Sized> Args for T {} impl<T: Iterator<Item = OsString> + Sized> Args for T {}
// args() ...
pub fn args() -> impl Iterator<Item = String> {
wild::args()
}
pub fn args_os() -> impl Iterator<Item = OsString> { pub fn args_os() -> impl Iterator<Item = OsString> {
wild::args_os() ARGV.iter().cloned()
} }
#[cfg(test)] #[cfg(test)]