diff --git a/Cargo.toml b/Cargo.toml index 2495437a9..c3697d6f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -214,7 +214,9 @@ feat_os_windows_legacy = [ [workspace] [dependencies] -uucore = "0.0.2" +lazy_static = { version="1.3" } +uucore = { version="0.0.2" } +# * uutils arch = { optional=true, path="src/uu/arch" } base32 = { optional=true, path="src/uu/base32" } base64 = { optional=true, path="src/uu/base64" } @@ -315,7 +317,6 @@ _backtrace = { version=">= 0.3.3, <= 0.3.30", package="backtrace" } [dev-dependencies] filetime = "0.2" -lazy_static = "1.3" libc = "0.2" rand = "0.6" regex = "1.0" diff --git a/src/bin/uutils.rs b/src/bin/uutils.rs index c90c73d02..f57155672 100644 --- a/src/bin/uutils.rs +++ b/src/bin/uutils.rs @@ -1,5 +1,3 @@ -#![crate_name = "uutils"] - /* * This file is part of the uutils coreutils package. * @@ -9,27 +7,37 @@ * file that was distributed with this source code. */ +// spell-checker:ignore (acronyms/names) Gehring +// spell-checker:ignore (rustlang) clippy concat rustlang +// spell-checker:ignore (uutils) coreutils uucore uumain uutils sigpipe +// spell-checker:ignore (shell) busybox + include!(concat!(env!("OUT_DIR"), "/uutils_crates.rs")); -use std::collections::hash_map::HashMap; -use std::io::Write; -use std::path::Path; - +extern crate lazy_static; extern crate uucore; -static NAME: &str = "uutils"; +use lazy_static::lazy_static; +use std::collections::hash_map::HashMap; +use std::io::Write; + static VERSION: &str = env!("CARGO_PKG_VERSION"); +lazy_static! { + static ref BINARY_PATH: std::path::PathBuf = std::env::current_exe().unwrap(); + static ref NAME: &'static str = &*BINARY_PATH.file_stem().unwrap().to_str().unwrap(); +} + include!(concat!(env!("OUT_DIR"), "/uutils_map.rs")); -fn usage(cmap: &UtilityMap) { - println!("{} {}", NAME, VERSION); +fn usage(utils: &UtilityMap) { + println!("{} {}", *NAME, VERSION); println!(); println!("Usage:"); - println!(" {} [util [arguments...]]\n", NAME); + println!(" {} [util [arguments...]]\n", *NAME); println!("Currently defined functions:"); #[allow(clippy::map_clone)] - let mut utils: Vec<&str> = cmap.keys().map(|&s| s).collect(); + let mut utils: Vec<&str> = utils.keys().map(|&s| s).collect(); utils.sort(); for util in utils { println!("\t{}", util); @@ -39,44 +47,36 @@ fn usage(cmap: &UtilityMap) { fn main() { uucore::panic::install_sigpipe_hook(); - let umap = util_map(); + let utils = util_map(); let mut args: Vec = uucore::args().collect(); - // try binary name as util name. - let args0 = args[0].clone(); - let binary = Path::new(&args0[..]); + let binary = &BINARY_PATH; let binary_as_util = binary.file_stem().unwrap().to_str().unwrap(); - if let Some(&uumain) = umap.get(binary_as_util) { + // binary name equals util name? + if let Some(&uumain) = utils.get(binary_as_util) { std::process::exit(uumain(args)); } - if binary_as_util.ends_with("uutils") - || binary_as_util.starts_with("uutils") - || binary_as_util.ends_with("busybox") - || binary_as_util.starts_with("busybox") - { - args.remove(0); + // binary name equals prefixed util name? + // * prefix/stem may be any string ending in a non-alphanumeric character + if let Some(util) = utils.keys().find(|util| { + binary_as_util.ends_with(*util) + && !(&binary_as_util[..binary_as_util.len() - (*util).len()]) + .ends_with(char::is_alphanumeric) + }) { + // prefixed util => replace 0th (aka, executable name) argument + args[0] = (*util).to_owned(); } else { - let mut found = false; - for util in umap.keys() { - if binary_as_util.ends_with(util) { - args[0] = (*util).to_owned(); - found = true; - break; - } - } - if !found { - println!("{}: applet not found", binary_as_util); - std::process::exit(1); - } + // unmatched binary name => regard as multi-binary container and advance argument list + args.remove(0); } - // try first arg as util name. + // 0th argument equals util name? if !args.is_empty() { let util = &args[0][..]; - match umap.get(util) { + match utils.get(util) { Some(&uumain) => { std::process::exit(uumain(args.clone())); } @@ -85,7 +85,7 @@ fn main() { // see if they want help on a specific util if args.len() >= 2 { let util = &args[1][..]; - match umap.get(util) { + match utils.get(util) { Some(&uumain) => { let code = uumain(vec![util.to_owned(), "--help".to_owned()]); std::io::stdout().flush().expect("could not flush stdout"); @@ -97,7 +97,7 @@ fn main() { } } } - usage(&umap); + usage(&utils); std::process::exit(0); } else { println!("{}: applet not found", util); @@ -107,7 +107,7 @@ fn main() { } } else { // no arguments provided - usage(&umap); + usage(&utils); std::process::exit(0); } }