1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 02:57:44 +00:00

Use an iterator over OsString for uumain()

Additionally, restructure `uname` so that we don't need to find the
iterator's length.
This commit is contained in:
Alex Lyon 2020-06-16 03:10:21 -05:00
parent 1309972149
commit 110d6844ad
No known key found for this signature in database
GPG key ID: 15B1C566BEF7A2D8
96 changed files with 330 additions and 178 deletions

View file

@ -43,10 +43,10 @@ pub fn main() {
let mut tf = File::create(Path::new(&out_dir).join("test_modules.rs")).unwrap();
mf.write_all(
"type UtilityMap = HashMap<&'static str, fn(Vec<String>) -> i32>;\n\
"type UtilityMap<T> = HashMap<&'static str, fn(T) -> i32>;\n\
\n\
fn util_map() -> UtilityMap {\n\
\tlet mut map: UtilityMap = HashMap::new();\n\
fn util_map<T: uucore::Args>() -> UtilityMap<T> {\n\
\tlet mut map = UtilityMap::new();\n\
"
.as_bytes(),
)

View file

@ -5,108 +5,112 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
extern crate lazy_static;
extern crate textwrap;
extern crate uucore;
use lazy_static::lazy_static;
use std::cmp;
use std::collections::hash_map::HashMap;
use std::io::Write;
use std::ffi::OsString;
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::process;
static VERSION: &str = env!("CARGO_PKG_VERSION");
lazy_static! {
static ref BINARY_PATH: std::path::PathBuf = {
// support symlinks by using args[0], when possible, with fallback to current_exe()
match std::env::args().next() {
Some(ref s) if !s.is_empty() => std::path::PathBuf::from(s),
_ => std::env::current_exe().unwrap(),
}
};
static ref NAME: &'static str = &*BINARY_PATH.file_stem().unwrap().to_str().unwrap();
}
const VERSION: &str = env!("CARGO_PKG_VERSION");
include!(concat!(env!("OUT_DIR"), "/uutils_map.rs"));
fn usage(utils: &UtilityMap) {
println!("{} {} (multi-call binary)\n", *NAME, VERSION);
println!("Usage: {} [function [arguments...]]\n", *NAME);
fn usage<T>(utils: &UtilityMap<T>, name: &str) {
println!("{} {} (multi-call binary)\n", name, VERSION);
println!("Usage: {} [function [arguments...]]\n", name);
println!("Currently defined functions/utilities:\n");
#[allow(clippy::map_clone)]
let mut utils: Vec<&str> = utils.keys().map(|&s| s).collect();
utils.sort();
let display_list = utils.join(", ");
let width = std::cmp::min(textwrap::termwidth(), 100) - 4 * 2; // (opinion/heuristic) max 100 chars wide with 4 character side indentions
let width = cmp::min(textwrap::termwidth(), 100) - 4 * 2; // (opinion/heuristic) max 100 chars wide with 4 character side indentions
println!(
"{}",
textwrap::indent(&textwrap::fill(&display_list, width), " ")
);
}
fn binary_path(args: &mut impl Iterator<Item = OsString>) -> PathBuf {
match args.next() {
Some(s) if !s.is_empty() => PathBuf::from(s),
_ => std::env::current_exe().unwrap(),
}
}
fn name(binary_path: &Path) -> &str {
binary_path.file_stem().unwrap().to_str().unwrap()
}
fn main() {
uucore::panic::mute_sigpipe_panic();
let utils = util_map();
let mut args: Vec<String> = uucore::args().collect();
let mut args = uucore::args_os();
let binary = &BINARY_PATH;
let binary_as_util = binary.file_stem().unwrap().to_str().unwrap();
let binary = binary_path(&mut args);
let binary_as_util = name(&binary);
// binary name equals util name?
if let Some(&uumain) = utils.get(binary_as_util) {
std::process::exit(uumain(args));
process::exit(uumain((vec![binary.into()].into_iter()).chain(args)));
}
// 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 {
// unmatched binary name => regard as multi-binary container and advance argument list
args.remove(0);
}
let utilname =
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
Some(OsString::from(*util))
} else {
// unmatched binary name => regard as multi-binary container and advance argument list
args.next()
};
// 0th argument equals util name?
if !args.is_empty() {
let util = &args[0][..];
if let Some(util_os) = utilname {
let util = util_os.as_os_str().to_string_lossy();
match utils.get(util) {
match utils.get(&util[..]) {
Some(&uumain) => {
std::process::exit(uumain(args.clone()));
process::exit(uumain((vec![util_os].into_iter()).chain(args)));
}
None => {
if &args[0][..] == "--help" || &args[0][..] == "-h" {
if util == "--help" || util == "-h" {
// see if they want help on a specific util
if args.len() >= 2 {
let util = &args[1][..];
match utils.get(util) {
if let Some(util_os) = args.next() {
let util = util_os.as_os_str().to_string_lossy();
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");
std::process::exit(code);
let code = uumain((vec![util_os, OsString::from("--help")].into_iter()).chain(args));
io::stdout().flush().expect("could not flush stdout");
process::exit(code);
}
None => {
println!("{}: function/utility not found", util);
std::process::exit(1);
process::exit(1);
}
}
}
usage(&utils);
std::process::exit(0);
usage(&utils, binary_as_util);
process::exit(0);
} else {
println!("{}: function/utility not found", util);
std::process::exit(1);
process::exit(1);
}
}
}
} else {
// no arguments provided
usage(&utils);
std::process::exit(0);
usage(&utils, binary_as_util);
process::exit(0);
}
}

View file

@ -16,8 +16,8 @@ static SYNTAX: &str = "Display machine architecture";
static SUMMARY: &str = "Determine architecture name for current machine.";
static LONG_HELP: &str = "";
pub fn uumain(args: Vec<String>) -> i32 {
app!(SYNTAX, SUMMARY, LONG_HELP).parse(args);
pub fn uumain(args: impl uucore::Args) -> i32 {
app!(SYNTAX, SUMMARY, LONG_HELP).parse(args.collect_str());
let uts = return_if_err!(1, PlatformInfo::new());
println!("{}", uts.machine().trim());
0

View file

@ -23,6 +23,6 @@ static LONG_HELP: &str = "
encoded stream.
";
pub fn uumain(args: Vec<String>) -> i32 {
base_common::execute(args, SYNTAX, SUMMARY, LONG_HELP, Format::Base32)
pub fn uumain(args: impl uucore::Args) -> i32 {
base_common::execute(args.collect_str(), SYNTAX, SUMMARY, LONG_HELP, Format::Base32)
}

View file

@ -24,6 +24,6 @@ static LONG_HELP: &str = "
encoded stream.
";
pub fn uumain(args: Vec<String>) -> i32 {
base_common::execute(args, SYNTAX, SUMMARY, LONG_HELP, Format::Base64)
pub fn uumain(args: impl uucore::Args) -> i32 {
base_common::execute(args.collect_str(), SYNTAX, SUMMARY, LONG_HELP, Format::Base64)
}

View file

@ -18,7 +18,9 @@ static SUMMARY: &str = "Print NAME with any leading directory components removed
If specified, also remove a trailing SUFFIX";
static LONG_HELP: &str = "";
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
//
// Argument parsing
//

View file

@ -124,7 +124,9 @@ enum InputType {
type CatResult<T> = Result<T, CatError>;
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("A", "show-all", "equivalent to -vET")
.optflag(

View file

@ -36,7 +36,9 @@ const FTS_COMFOLLOW: u8 = 1;
const FTS_PHYSICAL: u8 = 1 << 1;
const FTS_LOGICAL: u8 = 1 << 2;
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = app!(SYNTAX, SUMMARY, "");
opts.optflag("c",
"changes",

View file

@ -29,7 +29,9 @@ static LONG_HELP: &str = "
Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'.
";
pub fn uumain(mut args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let mut args = args.collect_str();
let syntax = format!(
"[OPTION]... MODE[,MODE]... FILE...
{0} [OPTION]... OCTAL-MODE FILE...

View file

@ -36,7 +36,9 @@ const FTS_COMFOLLOW: u8 = 1;
const FTS_PHYSICAL: u8 = 1 << 1;
const FTS_LOGICAL: u8 = 1 << 2;
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = app!(SYNTAX, SUMMARY, "");
opts.optflag("c",
"changes",

View file

@ -29,7 +29,9 @@ static LONG_HELP: &str = "
If $(SHELL) is not set, /bin/sh is used.
";
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
.optopt(
"u",

View file

@ -71,8 +71,8 @@ fn cksum(fname: &str) -> io::Result<(u32, usize)> {
//Ok((0 as u32,0 as usize))
}
pub fn uumain(args: Vec<String>) -> i32 {
let matches = app!(SYNTAX, SUMMARY, LONG_HELP).parse(args);
pub fn uumain(args: impl uucore::Args) -> i32 {
let matches = app!(SYNTAX, SUMMARY, LONG_HELP).parse(args.collect_str());
let files = matches.free;

View file

@ -121,7 +121,9 @@ fn open_file(name: &str) -> io::Result<LineReader> {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("1", "", "suppress column 1 (lines uniq to FILE1)")
.optflag("2", "", "suppress column 2 (lines uniq to FILE2)")

View file

@ -302,7 +302,7 @@ static DEFAULT_ATTRIBUTES: &[Attribute] = &[
Attribute::Timestamps,
];
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let usage = get_usage();
let matches = App::new(executable!())
.version(VERSION)
@ -465,7 +465,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
.arg(Arg::with_name(OPT_PATHS)
.multiple(true))
.get_matches_from(&args);
.get_matches_from(args);
if matches.is_present(OPT_VERSION) {
print_version();

View file

@ -423,7 +423,9 @@ fn cut_files(mut filenames: Vec<String>, mode: Mode) -> i32 {
exit_code
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
.optopt("b", "bytes", "filter byte columns from the input source", "sequence")
.optopt("c", "characters", "alias for character mode", "sequence")

View file

@ -129,7 +129,7 @@ impl<'a> From<&'a str> for Rfc3339Format {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let syntax = format!(
"{0} [OPTION]... [+FORMAT]...
{0} [OPTION]... [MMDDhhmm[[CC]YY][.ss]]",
@ -199,7 +199,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
.help("print or set Coordinated Universal Time (UTC)"),
)
.arg(Arg::with_name(OPT_FORMAT).multiple(true))
.get_matches_from(&args);
.get_matches_from(args);
let format = if let Some(form) = matches.value_of(OPT_FORMAT) {
let form = form[1..].into();

View file

@ -741,7 +741,7 @@ fn use_size(free_size: u64, total_size: u64) -> String {
);
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let usage = get_usage();
let matches = App::new(executable!())
.version(VERSION)
@ -862,7 +862,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
)
.arg(Arg::with_name(OPT_PATHS).multiple(true))
.help("Filesystem(s) to list")
.get_matches_from(&args);
.get_matches_from(args);
if matches.is_present(OPT_VERSION) {
println!("{} {}", executable!(), VERSION);

View file

@ -54,7 +54,9 @@ pub fn guess_syntax() -> OutputFmt {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("b", "sh", "output Bourne shell code to set LS_COLORS")
.optflag(

View file

@ -19,7 +19,9 @@ static LONG_HELP: &str = "
directory).
";
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("z", "zero", "separate output with NUL rather than newline")
.parse(args);

View file

@ -225,7 +225,9 @@ fn convert_size_other(size: u64, _multiplier: u64, block_size: u64) -> String {
}
#[allow(clippy::cognitive_complexity)]
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let syntax = format!(
"[OPTION]... [FILE]...
{0} [OPTION]... --files0-from=F",

View file

@ -102,7 +102,9 @@ fn print_escaped(input: &str, mut output: impl Write) -> io::Result<bool> {
Ok(should_stop)
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let matches = app!(SYNTAX, SUMMARY, HELP)
.optflag("n", "", "do not output the trailing newline")
.optflag("e", "", "enable interpretation of backslash escapes")

View file

@ -152,7 +152,7 @@ fn create_app() -> App<'static, 'static> {
.help("remove variable from the environment"))
}
fn run_env(args: Vec<String>) -> Result<(), i32> {
fn run_env(args: impl uucore::Args) -> Result<(), i32> {
let app = create_app();
let matches = app.get_matches_from(args);
@ -251,7 +251,7 @@ fn run_env(args: Vec<String>) -> Result<(), i32> {
Ok(())
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
match run_env(args) {
Ok(()) => 0,
Err(code) => code,

View file

@ -100,7 +100,9 @@ impl Options {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("i", "initial", "do not convert tabs after non blanks")
.optopt(

View file

@ -15,7 +15,9 @@ mod tokens;
static NAME: &str = "expr";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
// For expr utility we do not want getopts.
// The following usage should work without escaping hyphens: `expr -15 = 1 + 2 \* \( 3 - -4 \)`

View file

@ -115,8 +115,8 @@ fn print_factors_str(num_str: &str) {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
let matches = app!(SYNTAX, SUMMARY, LONG_HELP).parse(args);
pub fn uumain(args: impl uucore::Args) -> i32 {
let matches = app!(SYNTAX, SUMMARY, LONG_HELP).parse(args.collect_str());
if matches.free.is_empty() {
let stdin = stdin();

View file

@ -5,6 +5,6 @@
// * For the full copyright and license information, please view the LICENSE
// * file that was distributed with this source code.
pub fn uumain(_: Vec<String>) -> i32 {
pub fn uumain(_: impl uucore::Args) -> i32 {
1
}

View file

@ -57,7 +57,9 @@ pub struct FmtOptions {
}
#[allow(clippy::cognitive_complexity)]
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("c", "crown-margin", "First and second line of paragraph may have different indentations, in which case the first line's indentation is preserved, and each subsequent line's indentation matches the second line.")
.optflag("t", "tagged-paragraph", "Like -c, except that the first and second line of a paragraph *must* have different indentation or they are treated as separate paragraphs.")

View file

@ -19,7 +19,9 @@ static SUMMARY: &str = "Writes each file (or standard input if no files are give
to standard output whilst breaking long lines";
static LONG_HELP: &str = "";
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let (args, obs_width) = handle_obsolete(&args[..]);
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
.optflag(

View file

@ -23,7 +23,7 @@ fn get_usage() -> String {
format!("{0} [USERNAME]", executable!())
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let usage = get_usage();
let matches = App::new(executable!())
@ -31,7 +31,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
.about(ABOUT)
.usage(&usage[..])
.arg(Arg::with_name(OPT_USER))
.get_matches_from(&args);
.get_matches_from(args);
match matches.value_of(OPT_USER) {
None => {

View file

@ -234,7 +234,9 @@ fn detect_algo(
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let program = &args[0];
let binary_name = Path::new(program).file_name().unwrap().to_str().unwrap();

View file

@ -40,7 +40,9 @@ impl Default for Settings {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut settings: Settings = Default::default();
// handle obsolete -number syntax

View file

@ -23,8 +23,8 @@ extern "C" {
pub fn gethostid() -> c_long;
}
pub fn uumain(args: Vec<String>) -> i32 {
app!(SYNTAX, SUMMARY, LONG_HELP).parse(args);
pub fn uumain(args: impl uucore::Args) -> i32 {
app!(SYNTAX, SUMMARY, LONG_HELP).parse(args.collect_str());
hostid();
0
}

View file

@ -35,7 +35,7 @@ static OPT_FQDN: &str = "fqdn";
static OPT_SHORT: &str = "short";
static OPT_HOST: &str = "host";
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
#![allow(clippy::let_and_return)]
#[cfg(windows)]
unsafe {
@ -57,7 +57,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
fn get_usage() -> String {
format!("{0} [OPTION]... [HOSTNAME]", executable!())
}
fn execute(args: Vec<String>) -> i32 {
fn execute(args: impl uucore::Args) -> i32 {
let usage = get_usage();
let matches = App::new(executable!())
.version(VERSION)
@ -87,7 +87,7 @@ fn execute(args: Vec<String>) -> i32 {
possible",
))
.arg(Arg::with_name(OPT_HOST))
.get_matches_from(&args);
.get_matches_from(args);
match matches.value_of(OPT_HOST) {
None => display_hostname(&matches),

View file

@ -71,7 +71,9 @@ mod audit {
static SYNTAX: &str = "[OPTION]... [USER]";
static SUMMARY: &str = "Print user and group information for the specified USER,\n or (when USER omitted) for the current user.";
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = app!(SYNTAX, SUMMARY, "");
opts.optflag(
"A",

View file

@ -56,7 +56,9 @@ impl Behavior {
///
/// Returns a program return code.
///
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let matches = parse_opts(args);
if let Err(s) = check_unimplemented(&matches) {

View file

@ -444,7 +444,7 @@ impl<'a> State<'a> {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let matches = App::new(NAME)
.version(VERSION)
.about(

View file

@ -30,7 +30,9 @@ pub enum Mode {
List,
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let (args, obs_signal) = handle_obsolete(args);
let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
.optopt("s", "signal", "specify the <signal> to be sent", "SIGNAL")

View file

@ -23,8 +23,8 @@ pub fn normalize_error_message(e: Error) -> String {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
let matches = app!(SYNTAX, SUMMARY, LONG_HELP).parse(args);
pub fn uumain(args: impl uucore::Args) -> i32 {
let matches = app!(SYNTAX, SUMMARY, LONG_HELP).parse(args.collect_str());
if matches.free.len() != 2 {
crash!(1, "{}", msg_wrong_number_of_arguments!(2));
}

View file

@ -56,7 +56,9 @@ pub enum BackupMode {
ExistingBackup,
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let syntax = format!(
"[OPTION]... [-T] TARGET LINK_NAME (1st form)
{0} [OPTION]... TARGET (2nd form)

View file

@ -36,8 +36,8 @@ static SYNTAX: &str = "";
static SUMMARY: &str = "Print user's login name";
static LONG_HELP: &str = "";
pub fn uumain(args: Vec<String>) -> i32 {
app!(SYNTAX, SUMMARY, LONG_HELP).parse(args);
pub fn uumain(args: impl uucore::Args) -> i32 {
app!(SYNTAX, SUMMARY, LONG_HELP).parse(args.collect_str());
match get_userlogin() {
Some(userlogin) => println!("{}", userlogin),

View file

@ -76,7 +76,9 @@ lazy_static! {
static ref END_CODE: &'static str = COLOR_MAP.get("ec").unwrap_or(&"");
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let syntax = format!(
"[OPTION]... DIRECTORY
{0} [OPTION]... [FILE]...",

View file

@ -19,7 +19,9 @@ static VERSION: &str = env!("CARGO_PKG_VERSION");
/**
* Handles option parsing
*/
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
// Linux-specific options, not implemented

View file

@ -18,7 +18,9 @@ use std::io::Error;
static NAME: &str = "mkfifo";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optopt(

View file

@ -44,7 +44,9 @@ fn _makenod(path: CString, mode: mode_t, dev: dev_t) -> i32 {
}
#[allow(clippy::cognitive_complexity)]
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = Options::new();
// Linux-specific options, not implemented

View file

@ -29,7 +29,9 @@ static NAME: &str = "mktemp";
static VERSION: &str = env!("CARGO_PKG_VERSION");
static DEFAULT_TEMPLATE: &str = "tmp.XXXXXXXXXX";
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("d", "directory", "Make a directory instead of a file");
opts.optflag(

View file

@ -36,7 +36,9 @@ pub enum Mode {
static NAME: &str = "more";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = Options::new();
// FixME: fail without panic for now; but `more` should work with no arguments (ie, for piped input)

View file

@ -53,7 +53,9 @@ pub enum BackupMode {
ExistingBackup,
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflagopt(

View file

@ -29,7 +29,9 @@ extern "C" {
fn setpriority(which: c_int, who: c_int, prio: c_int) -> c_int;
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optopt(

View file

@ -73,7 +73,9 @@ enum NumberFormat {
RightZero,
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optopt(

View file

@ -36,7 +36,9 @@ unsafe fn _vprocmgr_detach_from_console(_: u32) -> *const libc::c_int {
std::ptr::null()
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("h", "help", "Show help and exit");

View file

@ -39,7 +39,7 @@ fn get_usage() -> String {
format!("{0} [OPTIONS]...", executable!())
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let usage = get_usage();
let matches = App::new(executable!())
.version(VERSION)
@ -58,7 +58,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
.takes_value(true)
.help("ignore up to N cores"),
)
.get_matches_from(&args);
.get_matches_from(args);
let mut ignore = match matches.value_of(OPT_IGNORE) {
Some(numstr) => match numstr.parse() {

View file

@ -280,7 +280,9 @@ fn handle_stdin(options: NumfmtOptions) -> Result<()> {
Ok(())
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = Options::new();
opts.optflag("h", "help", "display this help and exit");

View file

@ -290,7 +290,9 @@ impl OdOptions {
/// parses and validates command line parameters, prepares data structures,
/// opens the input and calls `odfunc` to process the input.
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let opts = create_getopts_options();
let matches = match opts.parse(&args[1..]) {

View file

@ -20,7 +20,9 @@ use std::path::Path;
static NAME: &str = "paste";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag(

View file

@ -36,7 +36,9 @@ static VERSION: &str = env!("CARGO_PKG_VERSION");
const POSIX_PATH_MAX: usize = 256;
const POSIX_NAME_MAX: usize = 14;
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
// add options
let mut opts = Options::new();
opts.optflag("p", "posix", "check for (most) POSIX systems");

View file

@ -27,7 +27,9 @@ static SUMMARY: &str = "A lightweight 'finger' program; print user information.
const BUFSIZE: usize = 1024;
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let long_help = &format!(
"
-l produce long format output for the specified USERs

View file

@ -17,7 +17,9 @@ use std::env;
static NAME: &str = "printenv";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag(
"0",

View file

@ -275,7 +275,9 @@ COPYRIGHT :
";
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let location = &args[0];
if args.len() <= 1 {
println!(

View file

@ -491,7 +491,9 @@ fn write_traditional_output(
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = Options::new();
opts.optflag(
"A",

View file

@ -32,7 +32,9 @@ pub fn absolute_path(path: &Path) -> io::Result<PathBuf> {
Ok(path_buf)
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("", "help", "display this help and exit");

View file

@ -20,7 +20,9 @@ use uucore::fs::{canonicalize, CanonicalizeMode};
const NAME: &str = "readlink";
const VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag(

View file

@ -19,7 +19,9 @@ use uucore::fs::{canonicalize, CanonicalizeMode};
static NAME: &str = "realpath";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("h", "help", "Show help and exit");

View file

@ -19,7 +19,9 @@ use uucore::fs::{canonicalize, CanonicalizeMode};
static NAME: &str = "relpath";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("h", "help", "Show help and exit");

View file

@ -43,7 +43,9 @@ struct Options {
static NAME: &str = "rm";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
// TODO: make getopts support -R in addition to -r
let mut opts = getopts::Options::new();

View file

@ -16,7 +16,9 @@ use std::path::Path;
static NAME: &str = "rmdir";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag(

View file

@ -170,7 +170,9 @@ fn print_version() {
println!("{} {}", NAME, VERSION);
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut options = SeqOptions {
separator: "\n".to_owned(),
terminator: None,

View file

@ -203,7 +203,9 @@ impl<'a> Iterator for BytesGenerator<'a> {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
// TODO: Add force option

View file

@ -27,7 +27,9 @@ enum Mode {
static NAME: &str = "shuf";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("e", "echo", "treat each ARG as an input line");
opts.optopt(

View file

@ -16,10 +16,13 @@ use std::time::Duration;
static NAME: &str = "sleep";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => {

View file

@ -143,7 +143,9 @@ impl<'a> Iterator for FileMerger<'a> {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut settings: Settings = Default::default();
let mut opts = getopts::Options::new();

View file

@ -20,7 +20,9 @@ use std::path::Path;
static NAME: &str = "split";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optopt(

View file

@ -872,7 +872,9 @@ impl Stater {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = Options::new();
opts.optflag("h", "help", "display this help and exit");

View file

@ -217,7 +217,9 @@ fn get_preload_env(tmp_dir: &mut TempDir) -> io::Result<(String, PathBuf)> {
Ok((preload.to_owned(), inject_path))
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = Options::new();
opts.optopt(

View file

@ -72,7 +72,9 @@ fn open(name: &str) -> Result<Box<dyn Read>> {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("r", "", "use the BSD compatible algorithm (default)");

View file

@ -118,7 +118,9 @@ mod platform {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("h", "help", "display this help and exit");

View file

@ -18,7 +18,9 @@ use std::io::{stdin, stdout, BufReader, Read, Stdout, Write};
static NAME: &str = "tac";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag(

View file

@ -56,7 +56,9 @@ impl Default for Settings {
}
#[allow(clippy::cognitive_complexity)]
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut settings: Settings = Default::default();
// handle obsolete -number syntax

View file

@ -16,7 +16,9 @@ use std::path::{Path, PathBuf};
static NAME: &str = "tee";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
match options(&args).and_then(exec) {
Ok(_) => 0,
Err(_) => 1,

View file

@ -12,16 +12,12 @@ extern crate libc;
extern crate syscall;
use std::collections::HashMap;
use std::env::args_os;
use std::ffi::OsString;
use std::str::from_utf8;
static NAME: &str = "test";
// TODO: decide how to handle non-UTF8 input for all the utils
// Definitely don't use [u8], try keeping it as OsStr or OsString instead
pub fn uumain(_: Vec<String>) -> i32 {
let args = args_os().collect::<Vec<OsString>>();
pub fn uumain(args: impl uucore::Args) -> i32 {
let args: Vec<_> = args.collect();
// This is completely disregarding valid windows paths that aren't valid unicode
let args = args
.iter()

View file

@ -24,7 +24,9 @@ static VERSION: &str = env!("CARGO_PKG_VERSION");
const ERR_EXIT_STATUS: i32 = 125;
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let program = args[0].clone();
let mut opts = getopts::Options::new();

View file

@ -41,7 +41,9 @@ macro_rules! local_tm_to_filetime(
})
);
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("a", "", "change only the access time");

View file

@ -183,7 +183,9 @@ fn usage(opts: &Options) {
println!("{}", opts.usage("Translate or delete characters."));
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = Options::new();
opts.optflag("c", "complement", "use the complement of SET1");

View file

@ -5,6 +5,6 @@
// * For the full copyright and license information, please view the LICENSE
// * file that was distributed with this source code.
pub fn uumain(_: Vec<String>) -> i32 {
pub fn uumain(_: impl uucore::Args) -> i32 {
0
}

View file

@ -30,7 +30,9 @@ enum TruncateMode {
static NAME: &str = "truncate";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("c", "no-create", "do not create files that do not exist");

View file

@ -19,7 +19,9 @@ use std::path::Path;
static NAME: &str = "tsort";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("h", "help", "display this help and exit");

View file

@ -25,7 +25,9 @@ extern "C" {
static NAME: &str = "tty";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag("s", "silent", "print nothing, only return an exit status");

View file

@ -48,7 +48,7 @@ const HOST_OS: &str = "Fuchsia";
#[cfg(target_os = "redox")]
const HOST_OS: &str = "Redox";
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let usage = format!("{} [OPTION]...", executable!());
let matches = App::new(executable!())
.version(VERSION)
@ -94,34 +94,43 @@ pub fn uumain(args: Vec<String>) -> i32 {
.short("o")
.long(OPT_OS)
.help("print the operating system name."))
.get_matches_from(&args);
.get_matches_from(args);
let argc = args.len();
let uname = return_if_err!(1, PlatformInfo::new());
let mut output = String::new();
if matches.is_present(OPT_KERNELNAME) || matches.is_present(OPT_ALL) || argc == 1 {
let all = matches.is_present(OPT_ALL);
let kernelname = matches.is_present(OPT_KERNELNAME);
let nodename = matches.is_present(OPT_NODENAME);
let kernelrelease = matches.is_present(OPT_KERNELRELEASE);
let kernelversion = matches.is_present(OPT_KERNELVERSION);
let machine = matches.is_present(OPT_MACHINE);
let os = matches.is_present(OPT_OS);
let none = !(all || kernelname || nodename || kernelrelease || kernelversion || machine || os);
if kernelname || all || none {
output.push_str(&uname.sysname());
output.push_str(" ");
}
if matches.is_present(OPT_NODENAME) || matches.is_present(OPT_ALL) {
if nodename || all {
output.push_str(&uname.nodename());
output.push_str(" ");
}
if matches.is_present(OPT_KERNELRELEASE) || matches.is_present(OPT_ALL) {
if kernelrelease || all {
output.push_str(&uname.release());
output.push_str(" ");
}
if matches.is_present(OPT_KERNELVERSION) || matches.is_present(OPT_ALL) {
if kernelversion || all {
output.push_str(&uname.version());
output.push_str(" ");
}
if matches.is_present(OPT_MACHINE) || matches.is_present(OPT_ALL) {
if machine || all {
output.push_str(&uname.machine());
output.push_str(" ");
}
if matches.is_present(OPT_OS) || matches.is_present(OPT_ALL) {
if os || all {
output.push_str(HOST_OS);
output.push_str(" ");
}

View file

@ -83,7 +83,9 @@ impl Options {
}
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = getopts::Options::new();
opts.optflag(

View file

@ -201,7 +201,9 @@ fn opt_parsed<T: FromStr>(opt_name: &str, matches: &Matches) -> Option<T> {
})
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = Options::new();
opts.optflag("c", "count", "prefix lines by the number of occurrences");

View file

@ -24,7 +24,9 @@ use std::io::{Error, ErrorKind};
static NAME: &str = "unlink";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = Options::new();
opts.optflag("h", "help", "display this help and exit");

View file

@ -41,7 +41,7 @@ fn get_usage() -> String {
format!("{0} [OPTION]...", executable!())
}
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let usage = get_usage();
let matches = App::new(executable!())
.version(VERSION)
@ -53,7 +53,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
.long("since")
.help("system up since"),
)
.get_matches_from(&args);
.get_matches_from(args);
let (boot_time, user_count) = process_utmpx();
let uptime = get_uptime(boot_time);

View file

@ -20,7 +20,9 @@ use getopts::Options;
static NAME: &str = "users";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = Options::new();
opts.optflag("h", "help", "display this help and exit");

View file

@ -69,7 +69,9 @@ struct Result {
static NAME: &str = "wc";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = Options::new();
opts.optflag("c", "bytes", "print the byte counts");

View file

@ -43,7 +43,9 @@ If FILE is not specified, use /var/run/utmp. /var/log/wtmp as FILE is common.
If ARG1 ARG2 given, -m presumed: 'am i' or 'mom likes' are usual.
";
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let args = args.collect_str();
let mut opts = app!(SYNTAX, SUMMARY, LONG_HELP);
opts.optflag("a", "all", "same as -b -d --login -p -r -t -T -u");
opts.optflag("b", "boot", "time of last system boot");

View file

@ -16,7 +16,7 @@ extern crate uucore;
mod platform;
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let app = app_from_crate!();
if let Err(err) = app.get_matches_from_safe(args) {

View file

@ -21,7 +21,7 @@ use uucore::zero_copy::ZeroCopyWriter;
// systems, but honestly this is good enough
const BUF_SIZE: usize = 16 * 1024;
pub fn uumain(args: Vec<String>) -> i32 {
pub fn uumain(args: impl uucore::Args) -> i32 {
let app = app_from_crate!().arg(Arg::with_name("STRING").index(1).multiple(true));
let matches = match app.get_matches_from_safe(args) {