mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
uutils: move clap::App creation to separate functions
This commit is contained in:
parent
5981351222
commit
0531153fa6
105 changed files with 3571 additions and 3253 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -1959,6 +1959,7 @@ dependencies = [
|
|||
name = "uu_expr"
|
||||
version = "0.0.6"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
|
@ -1986,6 +1987,7 @@ dependencies = [
|
|||
name = "uu_false"
|
||||
version = "0.0.6"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
"uucore_procs",
|
||||
]
|
||||
|
@ -2051,6 +2053,7 @@ dependencies = [
|
|||
name = "uu_hostid"
|
||||
version = "0.0.6"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
"uucore",
|
||||
"uucore_procs",
|
||||
|
@ -2327,6 +2330,7 @@ name = "uu_pr"
|
|||
version = "0.0.6"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"getopts",
|
||||
"itertools 0.10.0",
|
||||
"quick-error 2.0.1",
|
||||
|
@ -2349,6 +2353,7 @@ dependencies = [
|
|||
name = "uu_printf"
|
||||
version = "0.0.6"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"itertools 0.8.2",
|
||||
"uucore",
|
||||
"uucore_procs",
|
||||
|
@ -2585,6 +2590,7 @@ dependencies = [
|
|||
name = "uu_test"
|
||||
version = "0.0.6"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
"redox_syscall 0.1.57",
|
||||
"uucore",
|
||||
|
@ -2628,6 +2634,7 @@ dependencies = [
|
|||
name = "uu_true"
|
||||
version = "0.0.6"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
"uucore_procs",
|
||||
]
|
||||
|
|
|
@ -17,13 +17,16 @@ static ABOUT: &str = "Display machine architecture";
|
|||
static SUMMARY: &str = "Determine architecture name for current machine.";
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.after_help(SUMMARY)
|
||||
.get_matches_from(args);
|
||||
uu_app().get_matches_from(args);
|
||||
|
||||
let uts = return_if_err!(1, PlatformInfo::new());
|
||||
println!("{}", uts.machine().trim());
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.after_help(SUMMARY)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ extern crate uucore;
|
|||
|
||||
use std::io::{stdin, Read};
|
||||
|
||||
use clap::App;
|
||||
use uucore::encoding::Format;
|
||||
|
||||
pub mod base_common;
|
||||
|
@ -56,3 +57,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
base_common::base_app(executable!(), VERSION, ABOUT)
|
||||
}
|
||||
|
|
|
@ -78,10 +78,17 @@ pub fn parse_base_cmd_args(
|
|||
about: &str,
|
||||
usage: &str,
|
||||
) -> Result<Config, String> {
|
||||
let app = App::new(name)
|
||||
let app = base_app(name, version, about).usage(usage);
|
||||
let arg_list = args
|
||||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
Config::from(app.get_matches_from(arg_list))
|
||||
}
|
||||
|
||||
pub fn base_app<'a>(name: &str, version: &'a str, about: &'a str) -> App<'static, 'a> {
|
||||
App::new(name)
|
||||
.version(version)
|
||||
.about(about)
|
||||
.usage(usage)
|
||||
// Format arguments.
|
||||
.arg(
|
||||
Arg::with_name(options::DECODE)
|
||||
|
@ -106,11 +113,7 @@ pub fn parse_base_cmd_args(
|
|||
)
|
||||
// "multiple" arguments are used to check whether there is more than one
|
||||
// file passed in.
|
||||
.arg(Arg::with_name(options::FILE).index(1).multiple(true));
|
||||
let arg_list = args
|
||||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
Config::from(app.get_matches_from(arg_list))
|
||||
.arg(Arg::with_name(options::FILE).index(1).multiple(true))
|
||||
}
|
||||
|
||||
pub fn get_input<'a>(config: &Config, stdin_ref: &'a Stdin) -> Box<dyn Read + 'a> {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
extern crate uucore;
|
||||
|
||||
use uu_base32::base_common;
|
||||
pub use uu_base32::uu_app;
|
||||
|
||||
use uucore::encoding::Format;
|
||||
|
||||
|
|
|
@ -40,31 +40,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
//
|
||||
// Argument parsing
|
||||
//
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::MULTIPLE)
|
||||
.short("a")
|
||||
.long(options::MULTIPLE)
|
||||
.help("support multiple arguments and treat each as a NAME"),
|
||||
)
|
||||
.arg(Arg::with_name(options::NAME).multiple(true).hidden(true))
|
||||
.arg(
|
||||
Arg::with_name(options::SUFFIX)
|
||||
.short("s")
|
||||
.long(options::SUFFIX)
|
||||
.value_name("SUFFIX")
|
||||
.help("remove a trailing SUFFIX; implies -a"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ZERO)
|
||||
.short("z")
|
||||
.long(options::ZERO)
|
||||
.help("end each output line with NUL, not newline"),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
// too few arguments
|
||||
if !matches.is_present(options::NAME) {
|
||||
|
@ -116,6 +92,32 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
.arg(
|
||||
Arg::with_name(options::MULTIPLE)
|
||||
.short("a")
|
||||
.long(options::MULTIPLE)
|
||||
.help("support multiple arguments and treat each as a NAME"),
|
||||
)
|
||||
.arg(Arg::with_name(options::NAME).multiple(true).hidden(true))
|
||||
.arg(
|
||||
Arg::with_name(options::SUFFIX)
|
||||
.short("s")
|
||||
.long(options::SUFFIX)
|
||||
.value_name("SUFFIX")
|
||||
.help("remove a trailing SUFFIX; implies -a"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ZERO)
|
||||
.short("z")
|
||||
.long(options::ZERO)
|
||||
.help("end each output line with NUL, not newline"),
|
||||
)
|
||||
}
|
||||
|
||||
fn basename(fullname: &str, suffix: &str) -> String {
|
||||
// Remove all platform-specific path separators from the end
|
||||
let path = fullname.trim_end_matches(is_separator);
|
||||
|
|
|
@ -169,7 +169,65 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::Ignore)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let number_mode = if matches.is_present(options::NUMBER_NONBLANK) {
|
||||
NumberingMode::NonEmpty
|
||||
} else if matches.is_present(options::NUMBER) {
|
||||
NumberingMode::All
|
||||
} else {
|
||||
NumberingMode::None
|
||||
};
|
||||
|
||||
let show_nonprint = vec![
|
||||
options::SHOW_ALL.to_owned(),
|
||||
options::SHOW_NONPRINTING_ENDS.to_owned(),
|
||||
options::SHOW_NONPRINTING_TABS.to_owned(),
|
||||
options::SHOW_NONPRINTING.to_owned(),
|
||||
]
|
||||
.iter()
|
||||
.any(|v| matches.is_present(v));
|
||||
|
||||
let show_ends = vec![
|
||||
options::SHOW_ENDS.to_owned(),
|
||||
options::SHOW_ALL.to_owned(),
|
||||
options::SHOW_NONPRINTING_ENDS.to_owned(),
|
||||
]
|
||||
.iter()
|
||||
.any(|v| matches.is_present(v));
|
||||
|
||||
let show_tabs = vec![
|
||||
options::SHOW_ALL.to_owned(),
|
||||
options::SHOW_TABS.to_owned(),
|
||||
options::SHOW_NONPRINTING_TABS.to_owned(),
|
||||
]
|
||||
.iter()
|
||||
.any(|v| matches.is_present(v));
|
||||
|
||||
let squeeze_blank = matches.is_present(options::SQUEEZE_BLANK);
|
||||
let files: Vec<String> = match matches.values_of(options::FILE) {
|
||||
Some(v) => v.clone().map(|v| v.to_owned()).collect(),
|
||||
None => vec!["-".to_owned()],
|
||||
};
|
||||
|
||||
let options = OutputOptions {
|
||||
show_ends,
|
||||
number: number_mode,
|
||||
show_nonprint,
|
||||
show_tabs,
|
||||
squeeze_blank,
|
||||
};
|
||||
let success = cat_files(files, &options).is_ok();
|
||||
|
||||
if success {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.usage(SYNTAX)
|
||||
|
@ -229,61 +287,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.long(options::SHOW_NONPRINTING)
|
||||
.help("use ^ and M- notation, except for LF (\\n) and TAB (\\t)"),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let number_mode = if matches.is_present(options::NUMBER_NONBLANK) {
|
||||
NumberingMode::NonEmpty
|
||||
} else if matches.is_present(options::NUMBER) {
|
||||
NumberingMode::All
|
||||
} else {
|
||||
NumberingMode::None
|
||||
};
|
||||
|
||||
let show_nonprint = vec![
|
||||
options::SHOW_ALL.to_owned(),
|
||||
options::SHOW_NONPRINTING_ENDS.to_owned(),
|
||||
options::SHOW_NONPRINTING_TABS.to_owned(),
|
||||
options::SHOW_NONPRINTING.to_owned(),
|
||||
]
|
||||
.iter()
|
||||
.any(|v| matches.is_present(v));
|
||||
|
||||
let show_ends = vec![
|
||||
options::SHOW_ENDS.to_owned(),
|
||||
options::SHOW_ALL.to_owned(),
|
||||
options::SHOW_NONPRINTING_ENDS.to_owned(),
|
||||
]
|
||||
.iter()
|
||||
.any(|v| matches.is_present(v));
|
||||
|
||||
let show_tabs = vec![
|
||||
options::SHOW_ALL.to_owned(),
|
||||
options::SHOW_TABS.to_owned(),
|
||||
options::SHOW_NONPRINTING_TABS.to_owned(),
|
||||
]
|
||||
.iter()
|
||||
.any(|v| matches.is_present(v));
|
||||
|
||||
let squeeze_blank = matches.is_present(options::SQUEEZE_BLANK);
|
||||
let files: Vec<String> = match matches.values_of(options::FILE) {
|
||||
Some(v) => v.clone().map(|v| v.to_owned()).collect(),
|
||||
None => vec!["-".to_owned()],
|
||||
};
|
||||
|
||||
let options = OutputOptions {
|
||||
show_ends,
|
||||
number: number_mode,
|
||||
show_nonprint,
|
||||
show_tabs,
|
||||
squeeze_blank,
|
||||
};
|
||||
let success = cat_files(files, &options).is_ok();
|
||||
|
||||
if success {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
fn cat_handle<R: Read>(
|
||||
|
|
|
@ -73,84 +73,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
let usage = get_usage();
|
||||
|
||||
let mut app = App::new(executable!())
|
||||
.version(VERSION)
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::CHANGES)
|
||||
.short("c")
|
||||
.long(options::verbosity::CHANGES)
|
||||
.help("like verbose but report only when a change is made"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::SILENT)
|
||||
.short("f")
|
||||
.long(options::verbosity::SILENT),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::QUIET)
|
||||
.long(options::verbosity::QUIET)
|
||||
.help("suppress most error messages"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::VERBOSE)
|
||||
.short("v")
|
||||
.long(options::verbosity::VERBOSE)
|
||||
.help("output a diagnostic for every file processed"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::dereference::DEREFERENCE)
|
||||
.long(options::dereference::DEREFERENCE),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::dereference::NO_DEREFERENCE)
|
||||
.short("h")
|
||||
.long(options::dereference::NO_DEREFERENCE)
|
||||
.help(
|
||||
"affect symbolic links instead of any referenced file (useful only on systems that can change the ownership of a symlink)",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::preserve_root::PRESERVE)
|
||||
.long(options::preserve_root::PRESERVE)
|
||||
.help("fail to operate recursively on '/'"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::preserve_root::NO_PRESERVE)
|
||||
.long(options::preserve_root::NO_PRESERVE)
|
||||
.help("do not treat '/' specially (the default)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::REFERENCE)
|
||||
.long(options::REFERENCE)
|
||||
.value_name("RFILE")
|
||||
.help("use RFILE's group rather than specifying GROUP values")
|
||||
.takes_value(true)
|
||||
.multiple(false),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::RECURSIVE)
|
||||
.short("R")
|
||||
.long(options::RECURSIVE)
|
||||
.help("operate on files and directories recursively"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::traverse::TRAVERSE)
|
||||
.short(options::traverse::TRAVERSE)
|
||||
.help("if a command line argument is a symbolic link to a directory, traverse it"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::traverse::NO_TRAVERSE)
|
||||
.short(options::traverse::NO_TRAVERSE)
|
||||
.help("do not traverse any symbolic links (default)")
|
||||
.overrides_with_all(&[options::traverse::TRAVERSE, options::traverse::EVERY]),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::traverse::EVERY)
|
||||
.short(options::traverse::EVERY)
|
||||
.help("traverse every symbolic link to a directory encountered"),
|
||||
);
|
||||
let mut app = uu_app().usage(&usage[..]);
|
||||
|
||||
// we change the positional args based on whether
|
||||
// --reference was used.
|
||||
|
@ -274,6 +197,86 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
executor.exec()
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(VERSION)
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::CHANGES)
|
||||
.short("c")
|
||||
.long(options::verbosity::CHANGES)
|
||||
.help("like verbose but report only when a change is made"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::SILENT)
|
||||
.short("f")
|
||||
.long(options::verbosity::SILENT),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::QUIET)
|
||||
.long(options::verbosity::QUIET)
|
||||
.help("suppress most error messages"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::VERBOSE)
|
||||
.short("v")
|
||||
.long(options::verbosity::VERBOSE)
|
||||
.help("output a diagnostic for every file processed"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::dereference::DEREFERENCE)
|
||||
.long(options::dereference::DEREFERENCE),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::dereference::NO_DEREFERENCE)
|
||||
.short("h")
|
||||
.long(options::dereference::NO_DEREFERENCE)
|
||||
.help(
|
||||
"affect symbolic links instead of any referenced file (useful only on systems that can change the ownership of a symlink)",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::preserve_root::PRESERVE)
|
||||
.long(options::preserve_root::PRESERVE)
|
||||
.help("fail to operate recursively on '/'"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::preserve_root::NO_PRESERVE)
|
||||
.long(options::preserve_root::NO_PRESERVE)
|
||||
.help("do not treat '/' specially (the default)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::REFERENCE)
|
||||
.long(options::REFERENCE)
|
||||
.value_name("RFILE")
|
||||
.help("use RFILE's group rather than specifying GROUP values")
|
||||
.takes_value(true)
|
||||
.multiple(false),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::RECURSIVE)
|
||||
.short("R")
|
||||
.long(options::RECURSIVE)
|
||||
.help("operate on files and directories recursively"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::traverse::TRAVERSE)
|
||||
.short(options::traverse::TRAVERSE)
|
||||
.help("if a command line argument is a symbolic link to a directory, traverse it"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::traverse::NO_TRAVERSE)
|
||||
.short(options::traverse::NO_TRAVERSE)
|
||||
.help("do not traverse any symbolic links (default)")
|
||||
.overrides_with_all(&[options::traverse::TRAVERSE, options::traverse::EVERY]),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::traverse::EVERY)
|
||||
.short(options::traverse::EVERY)
|
||||
.help("traverse every symbolic link to a directory encountered"),
|
||||
)
|
||||
}
|
||||
|
||||
struct Chgrper {
|
||||
dest_gid: gid_t,
|
||||
bit_flag: u8,
|
||||
|
|
|
@ -61,11 +61,64 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let usage = get_usage();
|
||||
let after_help = get_long_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
let matches = uu_app()
|
||||
.usage(&usage[..])
|
||||
.after_help(&after_help[..])
|
||||
.get_matches_from(args);
|
||||
|
||||
let changes = matches.is_present(options::CHANGES);
|
||||
let quiet = matches.is_present(options::QUIET);
|
||||
let verbose = matches.is_present(options::VERBOSE);
|
||||
let preserve_root = matches.is_present(options::PRESERVE_ROOT);
|
||||
let recursive = matches.is_present(options::RECURSIVE);
|
||||
let fmode = matches
|
||||
.value_of(options::REFERENCE)
|
||||
.and_then(|fref| match fs::metadata(fref) {
|
||||
Ok(meta) => Some(meta.mode()),
|
||||
Err(err) => crash!(1, "cannot stat attributes of '{}': {}", fref, err),
|
||||
});
|
||||
let modes = matches.value_of(options::MODE).unwrap(); // should always be Some because required
|
||||
let cmode = if mode_had_minus_prefix {
|
||||
// clap parsing is finished, now put prefix back
|
||||
format!("-{}", modes)
|
||||
} else {
|
||||
modes.to_string()
|
||||
};
|
||||
let mut files: Vec<String> = matches
|
||||
.values_of(options::FILE)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
let cmode = if fmode.is_some() {
|
||||
// "--reference" and MODE are mutually exclusive
|
||||
// if "--reference" was used MODE needs to be interpreted as another FILE
|
||||
// it wasn't possible to implement this behavior directly with clap
|
||||
files.push(cmode);
|
||||
None
|
||||
} else {
|
||||
Some(cmode)
|
||||
};
|
||||
|
||||
let chmoder = Chmoder {
|
||||
changes,
|
||||
quiet,
|
||||
verbose,
|
||||
preserve_root,
|
||||
recursive,
|
||||
fmode,
|
||||
cmode,
|
||||
};
|
||||
match chmoder.chmod(files) {
|
||||
Ok(()) => {}
|
||||
Err(e) => return e,
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::CHANGES)
|
||||
.long(options::CHANGES)
|
||||
|
@ -120,55 +173,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.required_unless(options::MODE)
|
||||
.multiple(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let changes = matches.is_present(options::CHANGES);
|
||||
let quiet = matches.is_present(options::QUIET);
|
||||
let verbose = matches.is_present(options::VERBOSE);
|
||||
let preserve_root = matches.is_present(options::PRESERVE_ROOT);
|
||||
let recursive = matches.is_present(options::RECURSIVE);
|
||||
let fmode = matches
|
||||
.value_of(options::REFERENCE)
|
||||
.and_then(|fref| match fs::metadata(fref) {
|
||||
Ok(meta) => Some(meta.mode()),
|
||||
Err(err) => crash!(1, "cannot stat attributes of '{}': {}", fref, err),
|
||||
});
|
||||
let modes = matches.value_of(options::MODE).unwrap(); // should always be Some because required
|
||||
let cmode = if mode_had_minus_prefix {
|
||||
// clap parsing is finished, now put prefix back
|
||||
format!("-{}", modes)
|
||||
} else {
|
||||
modes.to_string()
|
||||
};
|
||||
let mut files: Vec<String> = matches
|
||||
.values_of(options::FILE)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
let cmode = if fmode.is_some() {
|
||||
// "--reference" and MODE are mutually exclusive
|
||||
// if "--reference" was used MODE needs to be interpreted as another FILE
|
||||
// it wasn't possible to implement this behavior directly with clap
|
||||
files.push(cmode);
|
||||
None
|
||||
} else {
|
||||
Some(cmode)
|
||||
};
|
||||
|
||||
let chmoder = Chmoder {
|
||||
changes,
|
||||
quiet,
|
||||
verbose,
|
||||
preserve_root,
|
||||
recursive,
|
||||
fmode,
|
||||
cmode,
|
||||
};
|
||||
match chmoder.chmod(files) {
|
||||
Ok(()) => {}
|
||||
Err(e) => return e,
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
// Iterate 'args' and delete the first occurrence
|
||||
|
|
|
@ -73,101 +73,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::CHANGES)
|
||||
.short("c")
|
||||
.long(options::verbosity::CHANGES)
|
||||
.help("like verbose but report only when a change is made"),
|
||||
)
|
||||
.arg(Arg::with_name(options::dereference::DEREFERENCE).long(options::dereference::DEREFERENCE).help(
|
||||
"affect the referent of each symbolic link (this is the default), rather than the symbolic link itself",
|
||||
))
|
||||
.arg(
|
||||
Arg::with_name(options::dereference::NO_DEREFERENCE)
|
||||
.short("h")
|
||||
.long(options::dereference::NO_DEREFERENCE)
|
||||
.help(
|
||||
"affect symbolic links instead of any referenced file (useful only on systems that can change the ownership of a symlink)",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FROM)
|
||||
.long(options::FROM)
|
||||
.help(
|
||||
"change the owner and/or group of each file only if its current owner and/or group match those specified here. Either may be omitted, in which case a match is not required for the omitted attribute",
|
||||
)
|
||||
.value_name("CURRENT_OWNER:CURRENT_GROUP"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::preserve_root::PRESERVE)
|
||||
.long(options::preserve_root::PRESERVE)
|
||||
.help("fail to operate recursively on '/'"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::preserve_root::NO_PRESERVE)
|
||||
.long(options::preserve_root::NO_PRESERVE)
|
||||
.help("do not treat '/' specially (the default)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::QUIET)
|
||||
.long(options::verbosity::QUIET)
|
||||
.help("suppress most error messages"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::RECURSIVE)
|
||||
.short("R")
|
||||
.long(options::RECURSIVE)
|
||||
.help("operate on files and directories recursively"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::REFERENCE)
|
||||
.long(options::REFERENCE)
|
||||
.help("use RFILE's owner and group rather than specifying OWNER:GROUP values")
|
||||
.value_name("RFILE")
|
||||
.min_values(1),
|
||||
)
|
||||
.arg(Arg::with_name(options::verbosity::SILENT).short("f").long(options::verbosity::SILENT))
|
||||
.arg(
|
||||
Arg::with_name(options::traverse::TRAVERSE)
|
||||
.short(options::traverse::TRAVERSE)
|
||||
.help("if a command line argument is a symbolic link to a directory, traverse it")
|
||||
.overrides_with_all(&[options::traverse::EVERY, options::traverse::NO_TRAVERSE]),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::traverse::EVERY)
|
||||
.short(options::traverse::EVERY)
|
||||
.help("traverse every symbolic link to a directory encountered")
|
||||
.overrides_with_all(&[options::traverse::TRAVERSE, options::traverse::NO_TRAVERSE]),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::traverse::NO_TRAVERSE)
|
||||
.short(options::traverse::NO_TRAVERSE)
|
||||
.help("do not traverse any symbolic links (default)")
|
||||
.overrides_with_all(&[options::traverse::TRAVERSE, options::traverse::EVERY]),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::VERBOSE)
|
||||
.long(options::verbosity::VERBOSE)
|
||||
.help("output a diagnostic for every file processed"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_OWNER)
|
||||
.multiple(false)
|
||||
.takes_value(true)
|
||||
.required(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_FILES)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.min_values(1),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
/* First arg is the owner/group */
|
||||
let owner = matches.value_of(ARG_OWNER).unwrap();
|
||||
|
@ -273,6 +179,102 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
executor.exec()
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::CHANGES)
|
||||
.short("c")
|
||||
.long(options::verbosity::CHANGES)
|
||||
.help("like verbose but report only when a change is made"),
|
||||
)
|
||||
.arg(Arg::with_name(options::dereference::DEREFERENCE).long(options::dereference::DEREFERENCE).help(
|
||||
"affect the referent of each symbolic link (this is the default), rather than the symbolic link itself",
|
||||
))
|
||||
.arg(
|
||||
Arg::with_name(options::dereference::NO_DEREFERENCE)
|
||||
.short("h")
|
||||
.long(options::dereference::NO_DEREFERENCE)
|
||||
.help(
|
||||
"affect symbolic links instead of any referenced file (useful only on systems that can change the ownership of a symlink)",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FROM)
|
||||
.long(options::FROM)
|
||||
.help(
|
||||
"change the owner and/or group of each file only if its current owner and/or group match those specified here. Either may be omitted, in which case a match is not required for the omitted attribute",
|
||||
)
|
||||
.value_name("CURRENT_OWNER:CURRENT_GROUP"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::preserve_root::PRESERVE)
|
||||
.long(options::preserve_root::PRESERVE)
|
||||
.help("fail to operate recursively on '/'"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::preserve_root::NO_PRESERVE)
|
||||
.long(options::preserve_root::NO_PRESERVE)
|
||||
.help("do not treat '/' specially (the default)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::QUIET)
|
||||
.long(options::verbosity::QUIET)
|
||||
.help("suppress most error messages"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::RECURSIVE)
|
||||
.short("R")
|
||||
.long(options::RECURSIVE)
|
||||
.help("operate on files and directories recursively"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::REFERENCE)
|
||||
.long(options::REFERENCE)
|
||||
.help("use RFILE's owner and group rather than specifying OWNER:GROUP values")
|
||||
.value_name("RFILE")
|
||||
.min_values(1),
|
||||
)
|
||||
.arg(Arg::with_name(options::verbosity::SILENT).short("f").long(options::verbosity::SILENT))
|
||||
.arg(
|
||||
Arg::with_name(options::traverse::TRAVERSE)
|
||||
.short(options::traverse::TRAVERSE)
|
||||
.help("if a command line argument is a symbolic link to a directory, traverse it")
|
||||
.overrides_with_all(&[options::traverse::EVERY, options::traverse::NO_TRAVERSE]),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::traverse::EVERY)
|
||||
.short(options::traverse::EVERY)
|
||||
.help("traverse every symbolic link to a directory encountered")
|
||||
.overrides_with_all(&[options::traverse::TRAVERSE, options::traverse::NO_TRAVERSE]),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::traverse::NO_TRAVERSE)
|
||||
.short(options::traverse::NO_TRAVERSE)
|
||||
.help("do not traverse any symbolic links (default)")
|
||||
.overrides_with_all(&[options::traverse::TRAVERSE, options::traverse::EVERY]),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::VERBOSE)
|
||||
.long(options::verbosity::VERBOSE)
|
||||
.help("output a diagnostic for every file processed"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_OWNER)
|
||||
.multiple(false)
|
||||
.takes_value(true)
|
||||
.required(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_FILES)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.min_values(1),
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_spec(spec: &str) -> Result<(Option<u32>, Option<u32>), String> {
|
||||
let args = spec.split_terminator(':').collect::<Vec<_>>();
|
||||
let usr_only = args.len() == 1 && !args[0].is_empty();
|
||||
|
|
|
@ -36,54 +36,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(SYNTAX)
|
||||
.arg(
|
||||
Arg::with_name(options::NEWROOT)
|
||||
.hidden(true)
|
||||
.required(true)
|
||||
.index(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::USER)
|
||||
.short("u")
|
||||
.long(options::USER)
|
||||
.help("User (ID or name) to switch before running the program")
|
||||
.value_name("USER"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::GROUP)
|
||||
.short("g")
|
||||
.long(options::GROUP)
|
||||
.help("Group (ID or name) to switch to")
|
||||
.value_name("GROUP"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::GROUPS)
|
||||
.short("G")
|
||||
.long(options::GROUPS)
|
||||
.help("Comma-separated list of groups to switch to")
|
||||
.value_name("GROUP1,GROUP2..."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::USERSPEC)
|
||||
.long(options::USERSPEC)
|
||||
.help(
|
||||
"Colon-separated user and group to switch to. \
|
||||
Same as -u USER -g GROUP. \
|
||||
Userspec has higher preference than -u and/or -g",
|
||||
)
|
||||
.value_name("USER:GROUP"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::COMMAND)
|
||||
.hidden(true)
|
||||
.multiple(true)
|
||||
.index(2),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let default_shell: &'static str = "/bin/sh";
|
||||
let default_option: &'static str = "-i";
|
||||
|
@ -138,6 +91,56 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(SYNTAX)
|
||||
.arg(
|
||||
Arg::with_name(options::NEWROOT)
|
||||
.hidden(true)
|
||||
.required(true)
|
||||
.index(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::USER)
|
||||
.short("u")
|
||||
.long(options::USER)
|
||||
.help("User (ID or name) to switch before running the program")
|
||||
.value_name("USER"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::GROUP)
|
||||
.short("g")
|
||||
.long(options::GROUP)
|
||||
.help("Group (ID or name) to switch to")
|
||||
.value_name("GROUP"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::GROUPS)
|
||||
.short("G")
|
||||
.long(options::GROUPS)
|
||||
.help("Comma-separated list of groups to switch to")
|
||||
.value_name("GROUP1,GROUP2..."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::USERSPEC)
|
||||
.long(options::USERSPEC)
|
||||
.help(
|
||||
"Colon-separated user and group to switch to. \
|
||||
Same as -u USER -g GROUP. \
|
||||
Userspec has higher preference than -u and/or -g",
|
||||
)
|
||||
.value_name("USER:GROUP"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::COMMAND)
|
||||
.hidden(true)
|
||||
.multiple(true)
|
||||
.index(2),
|
||||
)
|
||||
}
|
||||
|
||||
fn set_context(root: &Path, options: &clap::ArgMatches) {
|
||||
let userspec_str = options.value_of(options::USERSPEC);
|
||||
let user_str = options.value_of(options::USER).unwrap_or_default();
|
||||
|
|
|
@ -180,13 +180,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::Ignore)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
.usage(SYNTAX)
|
||||
.arg(Arg::with_name(options::FILE).hidden(true).multiple(true))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let files: Vec<String> = match matches.values_of(options::FILE) {
|
||||
Some(v) => v.clone().map(|v| v.to_owned()).collect(),
|
||||
|
@ -217,3 +211,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
exit_code
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
.usage(SYNTAX)
|
||||
.arg(Arg::with_name(options::FILE).hidden(true).multiple(true))
|
||||
}
|
||||
|
|
|
@ -137,10 +137,20 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let mut f1 = open_file(matches.value_of(options::FILE_1).unwrap()).unwrap();
|
||||
let mut f2 = open_file(matches.value_of(options::FILE_2).unwrap()).unwrap();
|
||||
|
||||
comm(&mut f1, &mut f2, &matches);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.after_help(LONG_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::COLUMN_1)
|
||||
|
@ -167,12 +177,4 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
)
|
||||
.arg(Arg::with_name(options::FILE_1).required(true))
|
||||
.arg(Arg::with_name(options::FILE_2).required(true))
|
||||
.get_matches_from(args);
|
||||
|
||||
let mut f1 = open_file(matches.value_of(options::FILE_1).unwrap()).unwrap();
|
||||
let mut f2 = open_file(matches.value_of(options::FILE_2).unwrap()).unwrap();
|
||||
|
||||
comm(&mut f1, &mut f2, &matches);
|
||||
|
||||
0
|
||||
}
|
||||
|
|
|
@ -290,13 +290,10 @@ static DEFAULT_ATTRIBUTES: &[Attribute] = &[
|
|||
Attribute::Timestamps,
|
||||
];
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let matches = App::new(executable!())
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.after_help(&*format!("{}\n{}", LONG_HELP, backup_control::BACKUP_CONTROL_LONG_HELP))
|
||||
.usage(&usage[..])
|
||||
.arg(Arg::with_name(options::TARGET_DIRECTORY)
|
||||
.short("t")
|
||||
.conflicts_with(options::NO_TARGET_DIRECTORY)
|
||||
|
@ -464,6 +461,17 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
.arg(Arg::with_name(options::PATHS)
|
||||
.multiple(true))
|
||||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let matches = uu_app()
|
||||
.after_help(&*format!(
|
||||
"{}\n{}",
|
||||
LONG_HELP,
|
||||
backup_control::BACKUP_CONTROL_LONG_HELP
|
||||
))
|
||||
.usage(&usage[..])
|
||||
.get_matches_from(args);
|
||||
|
||||
let options = crash_if_err!(EXIT_ERR, Options::from_matches(&matches));
|
||||
|
|
|
@ -711,10 +711,37 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::Ignore)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
// get the file to split
|
||||
let file_name = matches.value_of(options::FILE).unwrap();
|
||||
|
||||
// get the patterns to split on
|
||||
let patterns: Vec<String> = matches
|
||||
.values_of(options::PATTERN)
|
||||
.unwrap()
|
||||
.map(str::to_string)
|
||||
.collect();
|
||||
let patterns = return_if_err!(1, patterns::get_patterns(&patterns[..]));
|
||||
let options = CsplitOptions::new(&matches);
|
||||
if file_name == "-" {
|
||||
let stdin = io::stdin();
|
||||
crash_if_err!(1, csplit(&options, patterns, stdin.lock()));
|
||||
} else {
|
||||
let file = return_if_err!(1, File::open(file_name));
|
||||
let file_metadata = return_if_err!(1, file.metadata());
|
||||
if !file_metadata.is_file() {
|
||||
crash!(1, "'{}' is not a regular file", file_name);
|
||||
}
|
||||
crash_if_err!(1, csplit(&options, patterns, BufReader::new(file)));
|
||||
};
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::SUFFIX_FORMAT)
|
||||
.short("b")
|
||||
|
@ -768,29 +795,4 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.required(true),
|
||||
)
|
||||
.after_help(LONG_HELP)
|
||||
.get_matches_from(args);
|
||||
|
||||
// get the file to split
|
||||
let file_name = matches.value_of(options::FILE).unwrap();
|
||||
|
||||
// get the patterns to split on
|
||||
let patterns: Vec<String> = matches
|
||||
.values_of(options::PATTERN)
|
||||
.unwrap()
|
||||
.map(str::to_string)
|
||||
.collect();
|
||||
let patterns = return_if_err!(1, patterns::get_patterns(&patterns[..]));
|
||||
let options = CsplitOptions::new(&matches);
|
||||
if file_name == "-" {
|
||||
let stdin = io::stdin();
|
||||
crash_if_err!(1, csplit(&options, patterns, stdin.lock()));
|
||||
} else {
|
||||
let file = return_if_err!(1, File::open(file_name));
|
||||
let file_metadata = return_if_err!(1, file.metadata());
|
||||
if !file_metadata.is_file() {
|
||||
crash!(1, "'{}' is not a regular file", file_name);
|
||||
}
|
||||
crash_if_err!(1, csplit(&options, patterns, BufReader::new(file)));
|
||||
};
|
||||
0
|
||||
}
|
||||
|
|
|
@ -396,88 +396,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::Ignore)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.usage(SYNTAX)
|
||||
.about(SUMMARY)
|
||||
.after_help(LONG_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::BYTES)
|
||||
.short("b")
|
||||
.long(options::BYTES)
|
||||
.takes_value(true)
|
||||
.help("filter byte columns from the input source")
|
||||
.allow_hyphen_values(true)
|
||||
.value_name("LIST")
|
||||
.display_order(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::CHARACTERS)
|
||||
.short("c")
|
||||
.long(options::CHARACTERS)
|
||||
.help("alias for character mode")
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.value_name("LIST")
|
||||
.display_order(2),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::DELIMITER)
|
||||
.short("d")
|
||||
.long(options::DELIMITER)
|
||||
.help("specify the delimiter character that separates fields in the input source. Defaults to Tab.")
|
||||
.takes_value(true)
|
||||
.value_name("DELIM")
|
||||
.display_order(3),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FIELDS)
|
||||
.short("f")
|
||||
.long(options::FIELDS)
|
||||
.help("filter field columns from the input source")
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.value_name("LIST")
|
||||
.display_order(4),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::COMPLEMENT)
|
||||
.long(options::COMPLEMENT)
|
||||
.help("invert the filter - instead of displaying only the filtered columns, display all but those columns")
|
||||
.takes_value(false)
|
||||
.display_order(5),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ONLY_DELIMITED)
|
||||
.short("s")
|
||||
.long(options::ONLY_DELIMITED)
|
||||
.help("in field mode, only print lines which contain the delimiter")
|
||||
.takes_value(false)
|
||||
.display_order(6),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ZERO_TERMINATED)
|
||||
.short("z")
|
||||
.long(options::ZERO_TERMINATED)
|
||||
.help("instead of filtering columns based on line, filter columns based on \\0 (NULL character)")
|
||||
.takes_value(false)
|
||||
.display_order(8),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OUTPUT_DELIMITER)
|
||||
.long(options::OUTPUT_DELIMITER)
|
||||
.help("in field mode, replace the delimiter in output lines with this option's argument")
|
||||
.takes_value(true)
|
||||
.value_name("NEW_DELIM")
|
||||
.display_order(7),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FILE)
|
||||
.hidden(true)
|
||||
.multiple(true)
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let complement = matches.is_present(options::COMPLEMENT);
|
||||
|
||||
|
@ -627,3 +546,87 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.usage(SYNTAX)
|
||||
.about(SUMMARY)
|
||||
.after_help(LONG_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::BYTES)
|
||||
.short("b")
|
||||
.long(options::BYTES)
|
||||
.takes_value(true)
|
||||
.help("filter byte columns from the input source")
|
||||
.allow_hyphen_values(true)
|
||||
.value_name("LIST")
|
||||
.display_order(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::CHARACTERS)
|
||||
.short("c")
|
||||
.long(options::CHARACTERS)
|
||||
.help("alias for character mode")
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.value_name("LIST")
|
||||
.display_order(2),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::DELIMITER)
|
||||
.short("d")
|
||||
.long(options::DELIMITER)
|
||||
.help("specify the delimiter character that separates fields in the input source. Defaults to Tab.")
|
||||
.takes_value(true)
|
||||
.value_name("DELIM")
|
||||
.display_order(3),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FIELDS)
|
||||
.short("f")
|
||||
.long(options::FIELDS)
|
||||
.help("filter field columns from the input source")
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.value_name("LIST")
|
||||
.display_order(4),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::COMPLEMENT)
|
||||
.long(options::COMPLEMENT)
|
||||
.help("invert the filter - instead of displaying only the filtered columns, display all but those columns")
|
||||
.takes_value(false)
|
||||
.display_order(5),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ONLY_DELIMITED)
|
||||
.short("s")
|
||||
.long(options::ONLY_DELIMITED)
|
||||
.help("in field mode, only print lines which contain the delimiter")
|
||||
.takes_value(false)
|
||||
.display_order(6),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ZERO_TERMINATED)
|
||||
.short("z")
|
||||
.long(options::ZERO_TERMINATED)
|
||||
.help("instead of filtering columns based on line, filter columns based on \\0 (NULL character)")
|
||||
.takes_value(false)
|
||||
.display_order(8),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OUTPUT_DELIMITER)
|
||||
.long(options::OUTPUT_DELIMITER)
|
||||
.help("in field mode, replace the delimiter in output lines with this option's argument")
|
||||
.takes_value(true)
|
||||
.value_name("NEW_DELIM")
|
||||
.display_order(7),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FILE)
|
||||
.hidden(true)
|
||||
.multiple(true)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -142,71 +142,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
{0} [OPTION]... [MMDDhhmm[[CC]YY][.ss]]",
|
||||
NAME
|
||||
);
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&syntax[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_DATE)
|
||||
.short("d")
|
||||
.long(OPT_DATE)
|
||||
.takes_value(true)
|
||||
.help("display time described by STRING, not 'now'"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_FILE)
|
||||
.short("f")
|
||||
.long(OPT_FILE)
|
||||
.takes_value(true)
|
||||
.help("like --date; once for each line of DATEFILE"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_ISO_8601)
|
||||
.short("I")
|
||||
.long(OPT_ISO_8601)
|
||||
.takes_value(true)
|
||||
.help(ISO_8601_HELP_STRING),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_RFC_EMAIL)
|
||||
.short("R")
|
||||
.long(OPT_RFC_EMAIL)
|
||||
.help(RFC_5322_HELP_STRING),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_RFC_3339)
|
||||
.long(OPT_RFC_3339)
|
||||
.takes_value(true)
|
||||
.help(RFC_3339_HELP_STRING),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_DEBUG)
|
||||
.long(OPT_DEBUG)
|
||||
.help("annotate the parsed date, and warn about questionable usage to stderr"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_REFERENCE)
|
||||
.short("r")
|
||||
.long(OPT_REFERENCE)
|
||||
.takes_value(true)
|
||||
.help("display the last modification time of FILE"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SET)
|
||||
.short("s")
|
||||
.long(OPT_SET)
|
||||
.takes_value(true)
|
||||
.help(OPT_SET_HELP_STRING),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_UNIVERSAL)
|
||||
.short("u")
|
||||
.long(OPT_UNIVERSAL)
|
||||
.alias(OPT_UNIVERSAL_2)
|
||||
.help("print or set Coordinated Universal Time (UTC)"),
|
||||
)
|
||||
.arg(Arg::with_name(OPT_FORMAT).multiple(false))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&syntax[..]).get_matches_from(args);
|
||||
|
||||
let format = if let Some(form) = matches.value_of(OPT_FORMAT) {
|
||||
if !form.starts_with('+') {
|
||||
|
@ -314,6 +250,72 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(OPT_DATE)
|
||||
.short("d")
|
||||
.long(OPT_DATE)
|
||||
.takes_value(true)
|
||||
.help("display time described by STRING, not 'now'"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_FILE)
|
||||
.short("f")
|
||||
.long(OPT_FILE)
|
||||
.takes_value(true)
|
||||
.help("like --date; once for each line of DATEFILE"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_ISO_8601)
|
||||
.short("I")
|
||||
.long(OPT_ISO_8601)
|
||||
.takes_value(true)
|
||||
.help(ISO_8601_HELP_STRING),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_RFC_EMAIL)
|
||||
.short("R")
|
||||
.long(OPT_RFC_EMAIL)
|
||||
.help(RFC_5322_HELP_STRING),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_RFC_3339)
|
||||
.long(OPT_RFC_3339)
|
||||
.takes_value(true)
|
||||
.help(RFC_3339_HELP_STRING),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_DEBUG)
|
||||
.long(OPT_DEBUG)
|
||||
.help("annotate the parsed date, and warn about questionable usage to stderr"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_REFERENCE)
|
||||
.short("r")
|
||||
.long(OPT_REFERENCE)
|
||||
.takes_value(true)
|
||||
.help("display the last modification time of FILE"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SET)
|
||||
.short("s")
|
||||
.long(OPT_SET)
|
||||
.takes_value(true)
|
||||
.help(OPT_SET_HELP_STRING),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_UNIVERSAL)
|
||||
.short("u")
|
||||
.long(OPT_UNIVERSAL)
|
||||
.alias(OPT_UNIVERSAL_2)
|
||||
.help("print or set Coordinated Universal Time (UTC)"),
|
||||
)
|
||||
.arg(Arg::with_name(OPT_FORMAT).multiple(false))
|
||||
}
|
||||
|
||||
/// Return the appropriate format string for the given settings.
|
||||
fn make_format_string(settings: &Settings) -> &str {
|
||||
match settings.format {
|
||||
|
|
|
@ -258,120 +258,7 @@ fn use_size(free_size: u64, total_size: u64) -> String {
|
|||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_ALL)
|
||||
.short("a")
|
||||
.long("all")
|
||||
.help("include dummy file systems"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_BLOCKSIZE)
|
||||
.short("B")
|
||||
.long("block-size")
|
||||
.takes_value(true)
|
||||
.help(
|
||||
"scale sizes by SIZE before printing them; e.g.\
|
||||
'-BM' prints sizes in units of 1,048,576 bytes",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_DIRECT)
|
||||
.long("direct")
|
||||
.help("show statistics for a file instead of mount point"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_TOTAL)
|
||||
.long("total")
|
||||
.help("produce a grand total"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_HUMAN_READABLE)
|
||||
.short("h")
|
||||
.long("human-readable")
|
||||
.conflicts_with(OPT_HUMAN_READABLE_2)
|
||||
.help("print sizes in human readable format (e.g., 1K 234M 2G)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_HUMAN_READABLE_2)
|
||||
.short("H")
|
||||
.long("si")
|
||||
.conflicts_with(OPT_HUMAN_READABLE)
|
||||
.help("likewise, but use powers of 1000 not 1024"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_INODES)
|
||||
.short("i")
|
||||
.long("inodes")
|
||||
.help("list inode information instead of block usage"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_KILO)
|
||||
.short("k")
|
||||
.help("like --block-size=1K"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_LOCAL)
|
||||
.short("l")
|
||||
.long("local")
|
||||
.help("limit listing to local file systems"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_NO_SYNC)
|
||||
.long("no-sync")
|
||||
.conflicts_with(OPT_SYNC)
|
||||
.help("do not invoke sync before getting usage info (default)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_OUTPUT)
|
||||
.long("output")
|
||||
.takes_value(true)
|
||||
.use_delimiter(true)
|
||||
.help(
|
||||
"use the output format defined by FIELD_LIST,\
|
||||
or print all fields if FIELD_LIST is omitted.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_PORTABILITY)
|
||||
.short("P")
|
||||
.long("portability")
|
||||
.help("use the POSIX output format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SYNC)
|
||||
.long("sync")
|
||||
.conflicts_with(OPT_NO_SYNC)
|
||||
.help("invoke sync before getting usage info"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_TYPE)
|
||||
.short("t")
|
||||
.long("type")
|
||||
.takes_value(true)
|
||||
.use_delimiter(true)
|
||||
.help("limit listing to file systems of type TYPE"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_PRINT_TYPE)
|
||||
.short("T")
|
||||
.long("print-type")
|
||||
.help("print file system type"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_EXCLUDE_TYPE)
|
||||
.short("x")
|
||||
.long("exclude-type")
|
||||
.takes_value(true)
|
||||
.use_delimiter(true)
|
||||
.help("limit listing to file systems not of type TYPE"),
|
||||
)
|
||||
.arg(Arg::with_name(OPT_PATHS).multiple(true))
|
||||
.help("Filesystem(s) to list")
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let paths: Vec<String> = matches
|
||||
.values_of(OPT_PATHS)
|
||||
|
@ -511,3 +398,118 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
EXIT_OK
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(OPT_ALL)
|
||||
.short("a")
|
||||
.long("all")
|
||||
.help("include dummy file systems"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_BLOCKSIZE)
|
||||
.short("B")
|
||||
.long("block-size")
|
||||
.takes_value(true)
|
||||
.help(
|
||||
"scale sizes by SIZE before printing them; e.g.\
|
||||
'-BM' prints sizes in units of 1,048,576 bytes",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_DIRECT)
|
||||
.long("direct")
|
||||
.help("show statistics for a file instead of mount point"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_TOTAL)
|
||||
.long("total")
|
||||
.help("produce a grand total"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_HUMAN_READABLE)
|
||||
.short("h")
|
||||
.long("human-readable")
|
||||
.conflicts_with(OPT_HUMAN_READABLE_2)
|
||||
.help("print sizes in human readable format (e.g., 1K 234M 2G)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_HUMAN_READABLE_2)
|
||||
.short("H")
|
||||
.long("si")
|
||||
.conflicts_with(OPT_HUMAN_READABLE)
|
||||
.help("likewise, but use powers of 1000 not 1024"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_INODES)
|
||||
.short("i")
|
||||
.long("inodes")
|
||||
.help("list inode information instead of block usage"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_KILO)
|
||||
.short("k")
|
||||
.help("like --block-size=1K"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_LOCAL)
|
||||
.short("l")
|
||||
.long("local")
|
||||
.help("limit listing to local file systems"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_NO_SYNC)
|
||||
.long("no-sync")
|
||||
.conflicts_with(OPT_SYNC)
|
||||
.help("do not invoke sync before getting usage info (default)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_OUTPUT)
|
||||
.long("output")
|
||||
.takes_value(true)
|
||||
.use_delimiter(true)
|
||||
.help(
|
||||
"use the output format defined by FIELD_LIST,\
|
||||
or print all fields if FIELD_LIST is omitted.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_PORTABILITY)
|
||||
.short("P")
|
||||
.long("portability")
|
||||
.help("use the POSIX output format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SYNC)
|
||||
.long("sync")
|
||||
.conflicts_with(OPT_NO_SYNC)
|
||||
.help("invoke sync before getting usage info"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_TYPE)
|
||||
.short("t")
|
||||
.long("type")
|
||||
.takes_value(true)
|
||||
.use_delimiter(true)
|
||||
.help("limit listing to file systems of type TYPE"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_PRINT_TYPE)
|
||||
.short("T")
|
||||
.long("print-type")
|
||||
.help("print file system type"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_EXCLUDE_TYPE)
|
||||
.short("x")
|
||||
.long("exclude-type")
|
||||
.takes_value(true)
|
||||
.use_delimiter(true)
|
||||
.help("limit listing to file systems not of type TYPE"),
|
||||
)
|
||||
.arg(Arg::with_name(OPT_PATHS).multiple(true))
|
||||
.help("Filesystem(s) to list")
|
||||
}
|
||||
|
|
|
@ -73,36 +73,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
.usage(&usage[..])
|
||||
.after_help(LONG_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::BOURNE_SHELL)
|
||||
.long("sh")
|
||||
.short("b")
|
||||
.visible_alias("bourne-shell")
|
||||
.help("output Bourne shell code to set LS_COLORS")
|
||||
.display_order(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::C_SHELL)
|
||||
.long("csh")
|
||||
.short("c")
|
||||
.visible_alias("c-shell")
|
||||
.help("output C shell code to set LS_COLORS")
|
||||
.display_order(2),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::PRINT_DATABASE)
|
||||
.long("print-database")
|
||||
.short("p")
|
||||
.help("print the byte counts")
|
||||
.display_order(3),
|
||||
)
|
||||
.arg(Arg::with_name(options::FILE).hidden(true).multiple(true))
|
||||
.get_matches_from(&args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(&args);
|
||||
|
||||
let files = matches
|
||||
.values_of(options::FILE)
|
||||
|
@ -181,6 +152,37 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
.after_help(LONG_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::BOURNE_SHELL)
|
||||
.long("sh")
|
||||
.short("b")
|
||||
.visible_alias("bourne-shell")
|
||||
.help("output Bourne shell code to set LS_COLORS")
|
||||
.display_order(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::C_SHELL)
|
||||
.long("csh")
|
||||
.short("c")
|
||||
.visible_alias("c-shell")
|
||||
.help("output C shell code to set LS_COLORS")
|
||||
.display_order(2),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::PRINT_DATABASE)
|
||||
.long("print-database")
|
||||
.short("p")
|
||||
.help("print the byte counts")
|
||||
.display_order(3),
|
||||
)
|
||||
.arg(Arg::with_name(options::FILE).hidden(true).multiple(true))
|
||||
}
|
||||
|
||||
pub trait StrUtils {
|
||||
/// Remove comments and trim whitespace
|
||||
fn purify(&self) -> &Self;
|
||||
|
|
|
@ -38,18 +38,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let usage = get_usage();
|
||||
let after_help = get_long_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.about(ABOUT)
|
||||
let matches = uu_app()
|
||||
.usage(&usage[..])
|
||||
.after_help(&after_help[..])
|
||||
.version(crate_version!())
|
||||
.arg(
|
||||
Arg::with_name(options::ZERO)
|
||||
.long(options::ZERO)
|
||||
.short("z")
|
||||
.help("separate output with NUL rather than newline"),
|
||||
)
|
||||
.arg(Arg::with_name(options::DIR).hidden(true).multiple(true))
|
||||
.get_matches_from(args);
|
||||
|
||||
let separator = if matches.is_present(options::ZERO) {
|
||||
|
@ -92,3 +83,16 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.about(ABOUT)
|
||||
.version(crate_version!())
|
||||
.arg(
|
||||
Arg::with_name(options::ZERO)
|
||||
.long(options::ZERO)
|
||||
.short("z")
|
||||
.help("separate output with NUL rather than newline"),
|
||||
)
|
||||
.arg(Arg::with_name(options::DIR).hidden(true).multiple(true))
|
||||
}
|
||||
|
|
|
@ -387,182 +387,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
.usage(&usage[..])
|
||||
.after_help(LONG_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::ALL)
|
||||
.short("a")
|
||||
.long(options::ALL)
|
||||
.help("write counts for all files, not just directories"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::APPARENT_SIZE)
|
||||
.long(options::APPARENT_SIZE)
|
||||
.help(
|
||||
"print apparent sizes, rather than disk usage \
|
||||
although the apparent size is usually smaller, it may be larger due to holes \
|
||||
in ('sparse') files, internal fragmentation, indirect blocks, and the like"
|
||||
)
|
||||
.alias("app") // The GNU test suite uses this alias
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::BLOCK_SIZE)
|
||||
.short("B")
|
||||
.long(options::BLOCK_SIZE)
|
||||
.value_name("SIZE")
|
||||
.help(
|
||||
"scale sizes by SIZE before printing them. \
|
||||
E.g., '-BM' prints sizes in units of 1,048,576 bytes. See SIZE format below."
|
||||
)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::BYTES)
|
||||
.short("b")
|
||||
.long("bytes")
|
||||
.help("equivalent to '--apparent-size --block-size=1'")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TOTAL)
|
||||
.long("total")
|
||||
.short("c")
|
||||
.help("produce a grand total")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::MAX_DEPTH)
|
||||
.short("d")
|
||||
.long("max-depth")
|
||||
.value_name("N")
|
||||
.help(
|
||||
"print the total for a directory (or file, with --all) \
|
||||
only if it is N or fewer levels below the command \
|
||||
line argument; --max-depth=0 is the same as --summarize"
|
||||
)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::HUMAN_READABLE)
|
||||
.long("human-readable")
|
||||
.short("h")
|
||||
.help("print sizes in human readable format (e.g., 1K 234M 2G)")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("inodes")
|
||||
.long("inodes")
|
||||
.help(
|
||||
"list inode usage information instead of block usage like --block-size=1K"
|
||||
)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::BLOCK_SIZE_1K)
|
||||
.short("k")
|
||||
.help("like --block-size=1K")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::COUNT_LINKS)
|
||||
.short("l")
|
||||
.long("count-links")
|
||||
.help("count sizes many times if hard linked")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::DEREFERENCE)
|
||||
.short("L")
|
||||
.long(options::DEREFERENCE)
|
||||
.help("dereference all symbolic links")
|
||||
)
|
||||
// .arg(
|
||||
// Arg::with_name("no-dereference")
|
||||
// .short("P")
|
||||
// .long("no-dereference")
|
||||
// .help("don't follow any symbolic links (this is the default)")
|
||||
// )
|
||||
.arg(
|
||||
Arg::with_name(options::BLOCK_SIZE_1M)
|
||||
.short("m")
|
||||
.help("like --block-size=1M")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NULL)
|
||||
.short("0")
|
||||
.long("null")
|
||||
.help("end each output line with 0 byte rather than newline")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SEPARATE_DIRS)
|
||||
.short("S")
|
||||
.long("separate-dirs")
|
||||
.help("do not include size of subdirectories")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SUMMARIZE)
|
||||
.short("s")
|
||||
.long("summarize")
|
||||
.help("display only a total for each argument")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SI)
|
||||
.long(options::SI)
|
||||
.help("like -h, but use powers of 1000 not 1024")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ONE_FILE_SYSTEM)
|
||||
.short("x")
|
||||
.long(options::ONE_FILE_SYSTEM)
|
||||
.help("skip directories on different file systems")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::THRESHOLD)
|
||||
.short("t")
|
||||
.long(options::THRESHOLD)
|
||||
.alias("th")
|
||||
.value_name("SIZE")
|
||||
.number_of_values(1)
|
||||
.allow_hyphen_values(true)
|
||||
.help("exclude entries smaller than SIZE if positive, \
|
||||
or entries greater than SIZE if negative")
|
||||
)
|
||||
// .arg(
|
||||
// Arg::with_name("")
|
||||
// .short("x")
|
||||
// .long("exclude-from")
|
||||
// .value_name("FILE")
|
||||
// .help("exclude files that match any pattern in FILE")
|
||||
// )
|
||||
// .arg(
|
||||
// Arg::with_name("exclude")
|
||||
// .long("exclude")
|
||||
// .value_name("PATTERN")
|
||||
// .help("exclude files that match PATTERN")
|
||||
// )
|
||||
.arg(
|
||||
Arg::with_name(options::TIME)
|
||||
.long(options::TIME)
|
||||
.value_name("WORD")
|
||||
.require_equals(true)
|
||||
.min_values(0)
|
||||
.possible_values(&["atime", "access", "use", "ctime", "status", "birth", "creation"])
|
||||
.help(
|
||||
"show time of the last modification of any file in the \
|
||||
directory, or any of its subdirectories. If WORD is given, show time as WORD instead \
|
||||
of modification time: atime, access, use, ctime, status, birth or creation"
|
||||
)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TIME_STYLE)
|
||||
.long(options::TIME_STYLE)
|
||||
.value_name("STYLE")
|
||||
.help(
|
||||
"show times using style STYLE: \
|
||||
full-iso, long-iso, iso, +FORMAT FORMAT is interpreted like 'date'"
|
||||
)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FILE)
|
||||
.hidden(true)
|
||||
.multiple(true)
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let summarize = matches.is_present(options::SUMMARIZE);
|
||||
|
||||
|
@ -743,6 +568,183 @@ Try '{} --help' for more information.",
|
|||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
.after_help(LONG_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::ALL)
|
||||
.short("a")
|
||||
.long(options::ALL)
|
||||
.help("write counts for all files, not just directories"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::APPARENT_SIZE)
|
||||
.long(options::APPARENT_SIZE)
|
||||
.help(
|
||||
"print apparent sizes, rather than disk usage \
|
||||
although the apparent size is usually smaller, it may be larger due to holes \
|
||||
in ('sparse') files, internal fragmentation, indirect blocks, and the like"
|
||||
)
|
||||
.alias("app") // The GNU test suite uses this alias
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::BLOCK_SIZE)
|
||||
.short("B")
|
||||
.long(options::BLOCK_SIZE)
|
||||
.value_name("SIZE")
|
||||
.help(
|
||||
"scale sizes by SIZE before printing them. \
|
||||
E.g., '-BM' prints sizes in units of 1,048,576 bytes. See SIZE format below."
|
||||
)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::BYTES)
|
||||
.short("b")
|
||||
.long("bytes")
|
||||
.help("equivalent to '--apparent-size --block-size=1'")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TOTAL)
|
||||
.long("total")
|
||||
.short("c")
|
||||
.help("produce a grand total")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::MAX_DEPTH)
|
||||
.short("d")
|
||||
.long("max-depth")
|
||||
.value_name("N")
|
||||
.help(
|
||||
"print the total for a directory (or file, with --all) \
|
||||
only if it is N or fewer levels below the command \
|
||||
line argument; --max-depth=0 is the same as --summarize"
|
||||
)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::HUMAN_READABLE)
|
||||
.long("human-readable")
|
||||
.short("h")
|
||||
.help("print sizes in human readable format (e.g., 1K 234M 2G)")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("inodes")
|
||||
.long("inodes")
|
||||
.help(
|
||||
"list inode usage information instead of block usage like --block-size=1K"
|
||||
)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::BLOCK_SIZE_1K)
|
||||
.short("k")
|
||||
.help("like --block-size=1K")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::COUNT_LINKS)
|
||||
.short("l")
|
||||
.long("count-links")
|
||||
.help("count sizes many times if hard linked")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::DEREFERENCE)
|
||||
.short("L")
|
||||
.long(options::DEREFERENCE)
|
||||
.help("dereference all symbolic links")
|
||||
)
|
||||
// .arg(
|
||||
// Arg::with_name("no-dereference")
|
||||
// .short("P")
|
||||
// .long("no-dereference")
|
||||
// .help("don't follow any symbolic links (this is the default)")
|
||||
// )
|
||||
.arg(
|
||||
Arg::with_name(options::BLOCK_SIZE_1M)
|
||||
.short("m")
|
||||
.help("like --block-size=1M")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NULL)
|
||||
.short("0")
|
||||
.long("null")
|
||||
.help("end each output line with 0 byte rather than newline")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SEPARATE_DIRS)
|
||||
.short("S")
|
||||
.long("separate-dirs")
|
||||
.help("do not include size of subdirectories")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SUMMARIZE)
|
||||
.short("s")
|
||||
.long("summarize")
|
||||
.help("display only a total for each argument")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SI)
|
||||
.long(options::SI)
|
||||
.help("like -h, but use powers of 1000 not 1024")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ONE_FILE_SYSTEM)
|
||||
.short("x")
|
||||
.long(options::ONE_FILE_SYSTEM)
|
||||
.help("skip directories on different file systems")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::THRESHOLD)
|
||||
.short("t")
|
||||
.long(options::THRESHOLD)
|
||||
.alias("th")
|
||||
.value_name("SIZE")
|
||||
.number_of_values(1)
|
||||
.allow_hyphen_values(true)
|
||||
.help("exclude entries smaller than SIZE if positive, \
|
||||
or entries greater than SIZE if negative")
|
||||
)
|
||||
// .arg(
|
||||
// Arg::with_name("")
|
||||
// .short("x")
|
||||
// .long("exclude-from")
|
||||
// .value_name("FILE")
|
||||
// .help("exclude files that match any pattern in FILE")
|
||||
// )
|
||||
// .arg(
|
||||
// Arg::with_name("exclude")
|
||||
// .long("exclude")
|
||||
// .value_name("PATTERN")
|
||||
// .help("exclude files that match PATTERN")
|
||||
// )
|
||||
.arg(
|
||||
Arg::with_name(options::TIME)
|
||||
.long(options::TIME)
|
||||
.value_name("WORD")
|
||||
.require_equals(true)
|
||||
.min_values(0)
|
||||
.possible_values(&["atime", "access", "use", "ctime", "status", "birth", "creation"])
|
||||
.help(
|
||||
"show time of the last modification of any file in the \
|
||||
directory, or any of its subdirectories. If WORD is given, show time as WORD instead \
|
||||
of modification time: atime, access, use, ctime, status, birth or creation"
|
||||
)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TIME_STYLE)
|
||||
.long(options::TIME_STYLE)
|
||||
.value_name("STYLE")
|
||||
.help(
|
||||
"show times using style STYLE: \
|
||||
full-iso, long-iso, iso, +FORMAT FORMAT is interpreted like 'date'"
|
||||
)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FILE)
|
||||
.hidden(true)
|
||||
.multiple(true)
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum Threshold {
|
||||
Lower(u64),
|
||||
|
|
|
@ -117,7 +117,26 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let args = args
|
||||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let no_newline = matches.is_present(options::NO_NEWLINE);
|
||||
let escaped = matches.is_present(options::ENABLE_BACKSLASH_ESCAPE);
|
||||
let values: Vec<String> = match matches.values_of(options::STRING) {
|
||||
Some(s) => s.map(|s| s.to_string()).collect(),
|
||||
None => vec!["".to_string()],
|
||||
};
|
||||
|
||||
match execute(no_newline, escaped, values) {
|
||||
Ok(_) => 0,
|
||||
Err(f) => {
|
||||
show_error!("{}", f);
|
||||
1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.name(NAME)
|
||||
// TrailingVarArg specifies the final positional argument is a VarArg
|
||||
// and it doesn't attempts the parse any further args.
|
||||
|
@ -154,22 +173,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.multiple(true)
|
||||
.allow_hyphen_values(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let no_newline = matches.is_present(options::NO_NEWLINE);
|
||||
let escaped = matches.is_present(options::ENABLE_BACKSLASH_ESCAPE);
|
||||
let values: Vec<String> = match matches.values_of(options::STRING) {
|
||||
Some(s) => s.map(|s| s.to_string()).collect(),
|
||||
None => vec!["".to_string()],
|
||||
};
|
||||
|
||||
match execute(no_newline, escaped, values) {
|
||||
Ok(_) => 0,
|
||||
Err(f) => {
|
||||
show_error!("{}", f);
|
||||
1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn execute(no_newline: bool, escaped: bool, free: Vec<String>) -> io::Result<()> {
|
||||
|
|
4
src/uu/env/src/env.rs
vendored
4
src/uu/env/src/env.rs
vendored
|
@ -114,7 +114,7 @@ fn build_command<'a, 'b>(args: &'a mut Vec<&'b str>) -> (Cow<'b, str>, &'a [&'b
|
|||
(progname, &args[..])
|
||||
}
|
||||
|
||||
fn create_app() -> App<'static, 'static> {
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(crate_name!())
|
||||
.version(crate_version!())
|
||||
.author(crate_authors!())
|
||||
|
@ -158,7 +158,7 @@ fn create_app() -> App<'static, 'static> {
|
|||
}
|
||||
|
||||
fn run_env(args: impl uucore::Args) -> Result<(), i32> {
|
||||
let app = create_app();
|
||||
let app = uu_app();
|
||||
let matches = app.get_matches_from(args);
|
||||
|
||||
let ignore_env = matches.is_present("ignore-environment");
|
||||
|
|
|
@ -108,10 +108,16 @@ impl Options {
|
|||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
expand(Options::new(&matches));
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.after_help(LONG_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::INITIAL)
|
||||
|
@ -138,10 +144,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.hidden(true)
|
||||
.takes_value(true)
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
expand(Options::new(&matches));
|
||||
0
|
||||
}
|
||||
|
||||
fn open(path: String) -> BufReader<Box<dyn Read + 'static>> {
|
||||
|
|
|
@ -15,6 +15,7 @@ edition = "2018"
|
|||
path = "src/expr.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.3"
|
||||
libc = "0.2.42"
|
||||
num-bigint = "0.4.0"
|
||||
num-traits = "0.2.14"
|
||||
|
|
|
@ -8,13 +8,20 @@
|
|||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
||||
use clap::{crate_version, App, Arg};
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
mod syntax_tree;
|
||||
mod tokens;
|
||||
|
||||
static NAME: &str = "expr";
|
||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
const VERSION: &str = "version";
|
||||
const HELP: &str = "help";
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.arg(Arg::with_name(VERSION).long(VERSION))
|
||||
.arg(Arg::with_name(HELP).long(HELP))
|
||||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let args = args
|
||||
|
@ -133,5 +140,5 @@ Environment variables:
|
|||
}
|
||||
|
||||
fn print_version() {
|
||||
println!("{} {}", NAME, VERSION);
|
||||
println!("{} {}", executable!(), crate_version!());
|
||||
}
|
||||
|
|
|
@ -36,11 +36,7 @@ fn print_factors_str(num_str: &str, w: &mut impl io::Write) -> Result<(), Box<dy
|
|||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
.arg(Arg::with_name(options::NUMBER).multiple(true))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
let stdout = stdout();
|
||||
let mut w = io::BufWriter::new(stdout.lock());
|
||||
|
||||
|
@ -68,3 +64,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
.arg(Arg::with_name(options::NUMBER).multiple(true))
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ edition = "2018"
|
|||
path = "src/false.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.3"
|
||||
uucore = { version=">=0.0.8", package="uucore", path="../../uucore" }
|
||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||
|
||||
|
|
|
@ -5,6 +5,15 @@
|
|||
// * For the full copyright and license information, please view the LICENSE
|
||||
// * file that was distributed with this source code.
|
||||
|
||||
use clap::{App, AppSettings};
|
||||
use uucore::executable;
|
||||
|
||||
pub fn uumain(_: impl uucore::Args) -> i32 {
|
||||
1
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.setting(AppSettings::DisableHelpFlags)
|
||||
.setting(AppSettings::DisableVersion)
|
||||
}
|
||||
|
|
|
@ -77,129 +77,7 @@ pub struct FmtOptions {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_CROWN_MARGIN)
|
||||
.short("c")
|
||||
.long(OPT_CROWN_MARGIN)
|
||||
.help(
|
||||
"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.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_TAGGED_PARAGRAPH)
|
||||
.short("t")
|
||||
.long("tagged-paragraph")
|
||||
.help(
|
||||
"Like -c, except that the first and second line of a paragraph *must*
|
||||
have different indentation or they are treated as separate paragraphs.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_PRESERVE_HEADERS)
|
||||
.short("m")
|
||||
.long("preserve-headers")
|
||||
.help(
|
||||
"Attempt to detect and preserve mail headers in the input.
|
||||
Be careful when combining this flag with -p.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SPLIT_ONLY)
|
||||
.short("s")
|
||||
.long("split-only")
|
||||
.help("Split lines only, do not reflow."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_UNIFORM_SPACING)
|
||||
.short("u")
|
||||
.long("uniform-spacing")
|
||||
.help(
|
||||
"Insert exactly one
|
||||
space between words, and two between sentences.
|
||||
Sentence breaks in the input are detected as [?!.]
|
||||
followed by two spaces or a newline; other punctuation
|
||||
is not interpreted as a sentence break.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_PREFIX)
|
||||
.short("p")
|
||||
.long("prefix")
|
||||
.help(
|
||||
"Reformat only lines
|
||||
beginning with PREFIX, reattaching PREFIX to reformatted lines.
|
||||
Unless -x is specified, leading whitespace will be ignored
|
||||
when matching PREFIX.",
|
||||
)
|
||||
.value_name("PREFIX"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SKIP_PREFIX)
|
||||
.short("P")
|
||||
.long("skip-prefix")
|
||||
.help(
|
||||
"Do not reformat lines
|
||||
beginning with PSKIP. Unless -X is specified, leading whitespace
|
||||
will be ignored when matching PSKIP",
|
||||
)
|
||||
.value_name("PSKIP"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_EXACT_PREFIX)
|
||||
.short("x")
|
||||
.long("exact-prefix")
|
||||
.help(
|
||||
"PREFIX must match at the
|
||||
beginning of the line with no preceding whitespace.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_EXACT_SKIP_PREFIX)
|
||||
.short("X")
|
||||
.long("exact-skip-prefix")
|
||||
.help(
|
||||
"PSKIP must match at the
|
||||
beginning of the line with no preceding whitespace.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_WIDTH)
|
||||
.short("w")
|
||||
.long("width")
|
||||
.help("Fill output lines up to a maximum of WIDTH columns, default 79.")
|
||||
.value_name("WIDTH"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_GOAL)
|
||||
.short("g")
|
||||
.long("goal")
|
||||
.help("Goal width, default ~0.94*WIDTH. Must be less than WIDTH.")
|
||||
.value_name("GOAL"),
|
||||
)
|
||||
.arg(Arg::with_name(OPT_QUICK).short("q").long("quick").help(
|
||||
"Break lines more quickly at the
|
||||
expense of a potentially more ragged appearance.",
|
||||
))
|
||||
.arg(
|
||||
Arg::with_name(OPT_TAB_WIDTH)
|
||||
.short("T")
|
||||
.long("tab-width")
|
||||
.help(
|
||||
"Treat tabs as TABWIDTH spaces for
|
||||
determining line length, default 8. Note that this is used only for
|
||||
calculating line lengths; tabs are preserved in the output.",
|
||||
)
|
||||
.value_name("TABWIDTH"),
|
||||
)
|
||||
.arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let mut files: Vec<String> = matches
|
||||
.values_of(ARG_FILES)
|
||||
|
@ -331,3 +209,127 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(OPT_CROWN_MARGIN)
|
||||
.short("c")
|
||||
.long(OPT_CROWN_MARGIN)
|
||||
.help(
|
||||
"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.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_TAGGED_PARAGRAPH)
|
||||
.short("t")
|
||||
.long("tagged-paragraph")
|
||||
.help(
|
||||
"Like -c, except that the first and second line of a paragraph *must*
|
||||
have different indentation or they are treated as separate paragraphs.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_PRESERVE_HEADERS)
|
||||
.short("m")
|
||||
.long("preserve-headers")
|
||||
.help(
|
||||
"Attempt to detect and preserve mail headers in the input.
|
||||
Be careful when combining this flag with -p.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SPLIT_ONLY)
|
||||
.short("s")
|
||||
.long("split-only")
|
||||
.help("Split lines only, do not reflow."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_UNIFORM_SPACING)
|
||||
.short("u")
|
||||
.long("uniform-spacing")
|
||||
.help(
|
||||
"Insert exactly one
|
||||
space between words, and two between sentences.
|
||||
Sentence breaks in the input are detected as [?!.]
|
||||
followed by two spaces or a newline; other punctuation
|
||||
is not interpreted as a sentence break.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_PREFIX)
|
||||
.short("p")
|
||||
.long("prefix")
|
||||
.help(
|
||||
"Reformat only lines
|
||||
beginning with PREFIX, reattaching PREFIX to reformatted lines.
|
||||
Unless -x is specified, leading whitespace will be ignored
|
||||
when matching PREFIX.",
|
||||
)
|
||||
.value_name("PREFIX"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SKIP_PREFIX)
|
||||
.short("P")
|
||||
.long("skip-prefix")
|
||||
.help(
|
||||
"Do not reformat lines
|
||||
beginning with PSKIP. Unless -X is specified, leading whitespace
|
||||
will be ignored when matching PSKIP",
|
||||
)
|
||||
.value_name("PSKIP"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_EXACT_PREFIX)
|
||||
.short("x")
|
||||
.long("exact-prefix")
|
||||
.help(
|
||||
"PREFIX must match at the
|
||||
beginning of the line with no preceding whitespace.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_EXACT_SKIP_PREFIX)
|
||||
.short("X")
|
||||
.long("exact-skip-prefix")
|
||||
.help(
|
||||
"PSKIP must match at the
|
||||
beginning of the line with no preceding whitespace.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_WIDTH)
|
||||
.short("w")
|
||||
.long("width")
|
||||
.help("Fill output lines up to a maximum of WIDTH columns, default 79.")
|
||||
.value_name("WIDTH"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_GOAL)
|
||||
.short("g")
|
||||
.long("goal")
|
||||
.help("Goal width, default ~0.94*WIDTH. Must be less than WIDTH.")
|
||||
.value_name("GOAL"),
|
||||
)
|
||||
.arg(Arg::with_name(OPT_QUICK).short("q").long("quick").help(
|
||||
"Break lines more quickly at the
|
||||
expense of a potentially more ragged appearance.",
|
||||
))
|
||||
.arg(
|
||||
Arg::with_name(OPT_TAB_WIDTH)
|
||||
.short("T")
|
||||
.long("tab-width")
|
||||
.help(
|
||||
"Treat tabs as TABWIDTH spaces for
|
||||
determining line length, default 8. Note that this is used only for
|
||||
calculating line lengths; tabs are preserved in the output.",
|
||||
)
|
||||
.value_name("TABWIDTH"),
|
||||
)
|
||||
.arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true))
|
||||
}
|
||||
|
|
|
@ -36,7 +36,35 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.accept_any();
|
||||
|
||||
let (args, obs_width) = handle_obsolete(&args[..]);
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let bytes = matches.is_present(options::BYTES);
|
||||
let spaces = matches.is_present(options::SPACES);
|
||||
let poss_width = match matches.value_of(options::WIDTH) {
|
||||
Some(v) => Some(v.to_owned()),
|
||||
None => obs_width,
|
||||
};
|
||||
|
||||
let width = match poss_width {
|
||||
Some(inp_width) => match inp_width.parse::<usize>() {
|
||||
Ok(width) => width,
|
||||
Err(e) => crash!(1, "illegal width value (\"{}\"): {}", inp_width, e),
|
||||
},
|
||||
None => 80,
|
||||
};
|
||||
|
||||
let files = match matches.values_of(options::FILE) {
|
||||
Some(v) => v.map(|v| v.to_owned()).collect(),
|
||||
None => vec!["-".to_owned()],
|
||||
};
|
||||
|
||||
fold(files, bytes, spaces, width);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.usage(SYNTAX)
|
||||
|
@ -68,31 +96,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.takes_value(true),
|
||||
)
|
||||
.arg(Arg::with_name(options::FILE).hidden(true).multiple(true))
|
||||
.get_matches_from(args);
|
||||
|
||||
let bytes = matches.is_present(options::BYTES);
|
||||
let spaces = matches.is_present(options::SPACES);
|
||||
let poss_width = match matches.value_of(options::WIDTH) {
|
||||
Some(v) => Some(v.to_owned()),
|
||||
None => obs_width,
|
||||
};
|
||||
|
||||
let width = match poss_width {
|
||||
Some(inp_width) => match inp_width.parse::<usize>() {
|
||||
Ok(width) => width,
|
||||
Err(e) => crash!(1, "illegal width value (\"{}\"): {}", inp_width, e),
|
||||
},
|
||||
None => 80,
|
||||
};
|
||||
|
||||
let files = match matches.values_of(options::FILE) {
|
||||
Some(v) => v.map(|v| v.to_owned()).collect(),
|
||||
None => vec!["-".to_owned()],
|
||||
};
|
||||
|
||||
fold(files, bytes, spaces, width);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
fn handle_obsolete(args: &[String]) -> (Vec<String>, Option<String>) {
|
||||
|
|
|
@ -35,17 +35,7 @@ fn get_usage() -> String {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::USERS)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.value_name(options::USERS),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let users: Vec<String> = matches
|
||||
.values_of(options::USERS)
|
||||
|
@ -93,3 +83,15 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
exit_code
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::USERS)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.value_name(options::USERS),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -285,119 +285,7 @@ pub fn uumain(mut args: impl uucore::Args) -> i32 {
|
|||
// Default binary in Windows, text mode otherwise
|
||||
let binary_flag_default = cfg!(windows);
|
||||
|
||||
let binary_help = format!(
|
||||
"read in binary mode{}",
|
||||
if binary_flag_default {
|
||||
" (default)"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
);
|
||||
|
||||
let text_help = format!(
|
||||
"read in text mode{}",
|
||||
if binary_flag_default {
|
||||
""
|
||||
} else {
|
||||
" (default)"
|
||||
}
|
||||
);
|
||||
|
||||
let mut app = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about("Compute and check message digests.")
|
||||
.arg(
|
||||
Arg::with_name("binary")
|
||||
.short("b")
|
||||
.long("binary")
|
||||
.help(&binary_help),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("check")
|
||||
.short("c")
|
||||
.long("check")
|
||||
.help("read hashsums from the FILEs and check them"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("tag")
|
||||
.long("tag")
|
||||
.help("create a BSD-style checksum"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("text")
|
||||
.short("t")
|
||||
.long("text")
|
||||
.help(&text_help)
|
||||
.conflicts_with("binary"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("quiet")
|
||||
.short("q")
|
||||
.long("quiet")
|
||||
.help("don't print OK for each successfully verified file"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("status")
|
||||
.short("s")
|
||||
.long("status")
|
||||
.help("don't output anything, status code shows success"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("strict")
|
||||
.long("strict")
|
||||
.help("exit non-zero for improperly formatted checksum lines"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("warn")
|
||||
.short("w")
|
||||
.long("warn")
|
||||
.help("warn about improperly formatted checksum lines"),
|
||||
)
|
||||
// Needed for variable-length output sums (e.g. SHAKE)
|
||||
.arg(
|
||||
Arg::with_name("bits")
|
||||
.long("bits")
|
||||
.help("set the size of the output (only for SHAKE)")
|
||||
.takes_value(true)
|
||||
.value_name("BITS")
|
||||
// XXX: should we actually use validators? they're not particularly efficient
|
||||
.validator(is_valid_bit_num),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("FILE")
|
||||
.index(1)
|
||||
.multiple(true)
|
||||
.value_name("FILE"),
|
||||
);
|
||||
|
||||
if !is_custom_binary(&binary_name) {
|
||||
let algorithms = &[
|
||||
("md5", "work with MD5"),
|
||||
("sha1", "work with SHA1"),
|
||||
("sha224", "work with SHA224"),
|
||||
("sha256", "work with SHA256"),
|
||||
("sha384", "work with SHA384"),
|
||||
("sha512", "work with SHA512"),
|
||||
("sha3", "work with SHA3"),
|
||||
("sha3-224", "work with SHA3-224"),
|
||||
("sha3-256", "work with SHA3-256"),
|
||||
("sha3-384", "work with SHA3-384"),
|
||||
("sha3-512", "work with SHA3-512"),
|
||||
(
|
||||
"shake128",
|
||||
"work with SHAKE128 using BITS for the output size",
|
||||
),
|
||||
(
|
||||
"shake256",
|
||||
"work with SHAKE256 using BITS for the output size",
|
||||
),
|
||||
("b2sum", "work with BLAKE2"),
|
||||
];
|
||||
|
||||
for (name, desc) in algorithms {
|
||||
app = app.arg(Arg::with_name(name).long(name).help(desc));
|
||||
}
|
||||
}
|
||||
let app = uu_app(&binary_name);
|
||||
|
||||
// FIXME: this should use get_matches_from_safe() and crash!(), but at the moment that just
|
||||
// causes "error: " to be printed twice (once from crash!() and once from clap). With
|
||||
|
@ -445,6 +333,124 @@ pub fn uumain(mut args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn uu_app_common() -> App<'static, 'static> {
|
||||
#[cfg(windows)]
|
||||
const BINARY_HELP: &str = "read in binary mode (default)";
|
||||
#[cfg(not(windows))]
|
||||
const BINARY_HELP: &str = "read in binary mode";
|
||||
#[cfg(windows)]
|
||||
const TEXT_HELP: &str = "read in text mode";
|
||||
#[cfg(not(windows))]
|
||||
const TEXT_HELP: &str = "read in text mode (default)";
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about("Compute and check message digests.")
|
||||
.arg(
|
||||
Arg::with_name("binary")
|
||||
.short("b")
|
||||
.long("binary")
|
||||
.help(BINARY_HELP),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("check")
|
||||
.short("c")
|
||||
.long("check")
|
||||
.help("read hashsums from the FILEs and check them"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("tag")
|
||||
.long("tag")
|
||||
.help("create a BSD-style checksum"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("text")
|
||||
.short("t")
|
||||
.long("text")
|
||||
.help(TEXT_HELP)
|
||||
.conflicts_with("binary"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("quiet")
|
||||
.short("q")
|
||||
.long("quiet")
|
||||
.help("don't print OK for each successfully verified file"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("status")
|
||||
.short("s")
|
||||
.long("status")
|
||||
.help("don't output anything, status code shows success"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("strict")
|
||||
.long("strict")
|
||||
.help("exit non-zero for improperly formatted checksum lines"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("warn")
|
||||
.short("w")
|
||||
.long("warn")
|
||||
.help("warn about improperly formatted checksum lines"),
|
||||
)
|
||||
// Needed for variable-length output sums (e.g. SHAKE)
|
||||
.arg(
|
||||
Arg::with_name("bits")
|
||||
.long("bits")
|
||||
.help("set the size of the output (only for SHAKE)")
|
||||
.takes_value(true)
|
||||
.value_name("BITS")
|
||||
// XXX: should we actually use validators? they're not particularly efficient
|
||||
.validator(is_valid_bit_num),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("FILE")
|
||||
.index(1)
|
||||
.multiple(true)
|
||||
.value_name("FILE"),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn uu_app_custom() -> App<'static, 'static> {
|
||||
let mut app = uu_app_common();
|
||||
let algorithms = &[
|
||||
("md5", "work with MD5"),
|
||||
("sha1", "work with SHA1"),
|
||||
("sha224", "work with SHA224"),
|
||||
("sha256", "work with SHA256"),
|
||||
("sha384", "work with SHA384"),
|
||||
("sha512", "work with SHA512"),
|
||||
("sha3", "work with SHA3"),
|
||||
("sha3-224", "work with SHA3-224"),
|
||||
("sha3-256", "work with SHA3-256"),
|
||||
("sha3-384", "work with SHA3-384"),
|
||||
("sha3-512", "work with SHA3-512"),
|
||||
(
|
||||
"shake128",
|
||||
"work with SHAKE128 using BITS for the output size",
|
||||
),
|
||||
(
|
||||
"shake256",
|
||||
"work with SHAKE256 using BITS for the output size",
|
||||
),
|
||||
("b2sum", "work with BLAKE2"),
|
||||
];
|
||||
|
||||
for (name, desc) in algorithms {
|
||||
app = app.arg(Arg::with_name(name).long(name).help(desc));
|
||||
}
|
||||
app
|
||||
}
|
||||
|
||||
// hashsum is handled differently in build.rs, therefore this is not the same
|
||||
// as in other utilities.
|
||||
fn uu_app(binary_name: &str) -> App<'static, 'static> {
|
||||
if !is_custom_binary(binary_name) {
|
||||
uu_app_custom()
|
||||
} else {
|
||||
uu_app_common()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn hashsum<'a, I>(mut options: Options, files: I) -> Result<(), i32>
|
||||
where
|
||||
|
|
|
@ -40,7 +40,7 @@ mod take;
|
|||
use lines::zlines;
|
||||
use take::take_all_but;
|
||||
|
||||
fn app<'a>() -> App<'a, 'a> {
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
|
@ -167,7 +167,7 @@ impl HeadOptions {
|
|||
|
||||
///Construct options from matches
|
||||
pub fn get_from(args: impl uucore::Args) -> Result<Self, String> {
|
||||
let matches = app().get_matches_from(arg_iterate(args)?);
|
||||
let matches = uu_app().get_matches_from(arg_iterate(args)?);
|
||||
|
||||
let mut options = HeadOptions::new();
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ edition = "2018"
|
|||
path = "src/hostid.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.3"
|
||||
libc = "0.2.42"
|
||||
uucore = { version=">=0.0.8", package="uucore", path="../../uucore" }
|
||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||
|
|
|
@ -10,12 +10,10 @@
|
|||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
||||
use clap::{crate_version, App};
|
||||
use libc::c_long;
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
static SYNTAX: &str = "[options]";
|
||||
static SUMMARY: &str = "";
|
||||
static LONG_HELP: &str = "";
|
||||
|
||||
// currently rust libc interface doesn't include gethostid
|
||||
extern "C" {
|
||||
|
@ -23,14 +21,17 @@ extern "C" {
|
|||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
app!(SYNTAX, SUMMARY, LONG_HELP).parse(
|
||||
args.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any(),
|
||||
);
|
||||
uu_app().get_matches_from(args);
|
||||
hostid();
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.usage(SYNTAX)
|
||||
}
|
||||
|
||||
fn hostid() {
|
||||
/*
|
||||
* POSIX says gethostid returns a "32-bit identifier" but is silent
|
||||
|
|
|
@ -52,10 +52,25 @@ fn get_usage() -> String {
|
|||
}
|
||||
fn execute(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
match matches.value_of(OPT_HOST) {
|
||||
None => display_hostname(&matches),
|
||||
Some(host) => {
|
||||
if let Err(err) = hostname::set(host) {
|
||||
show_error!("{}", err);
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_DOMAIN)
|
||||
.short("d")
|
||||
|
@ -80,19 +95,6 @@ fn execute(args: impl uucore::Args) -> i32 {
|
|||
possible",
|
||||
))
|
||||
.arg(Arg::with_name(OPT_HOST))
|
||||
.get_matches_from(args);
|
||||
|
||||
match matches.value_of(OPT_HOST) {
|
||||
None => display_hostname(&matches),
|
||||
Some(host) => {
|
||||
if let Err(err) = hostname::set(host) {
|
||||
show_error!("{}", err);
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn display_hostname(matches: &ArgMatches) -> i32 {
|
||||
|
|
|
@ -115,106 +115,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let usage = get_usage();
|
||||
let after_help = get_description();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
let matches = uu_app()
|
||||
.usage(&usage[..])
|
||||
.after_help(&after_help[..])
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_AUDIT)
|
||||
.short("A")
|
||||
.conflicts_with_all(&[
|
||||
options::OPT_GROUP,
|
||||
options::OPT_EFFECTIVE_USER,
|
||||
options::OPT_HUMAN_READABLE,
|
||||
options::OPT_PASSWORD,
|
||||
options::OPT_GROUPS,
|
||||
options::OPT_ZERO,
|
||||
])
|
||||
.help(
|
||||
"Display the process audit user ID and other process audit properties,\n\
|
||||
which requires privilege (not available on Linux).",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_EFFECTIVE_USER)
|
||||
.short("u")
|
||||
.long(options::OPT_EFFECTIVE_USER)
|
||||
.conflicts_with(options::OPT_GROUP)
|
||||
.help("Display only the effective user ID as a number."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_GROUP)
|
||||
.short("g")
|
||||
.long(options::OPT_GROUP)
|
||||
.help("Display only the effective group ID as a number"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_GROUPS)
|
||||
.short("G")
|
||||
.long(options::OPT_GROUPS)
|
||||
.conflicts_with_all(&[
|
||||
options::OPT_GROUP,
|
||||
options::OPT_EFFECTIVE_USER,
|
||||
options::OPT_HUMAN_READABLE,
|
||||
options::OPT_PASSWORD,
|
||||
options::OPT_AUDIT,
|
||||
])
|
||||
.help(
|
||||
"Display only the different group IDs as white-space separated numbers, \
|
||||
in no particular order.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_HUMAN_READABLE)
|
||||
.short("p")
|
||||
.help("Make the output human-readable. Each display is on a separate line."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_NAME)
|
||||
.short("n")
|
||||
.long(options::OPT_NAME)
|
||||
.help(
|
||||
"Display the name of the user or group ID for the -G, -g and -u options \
|
||||
instead of the number.\nIf any of the ID numbers cannot be mapped into \
|
||||
names, the number will be displayed as usual.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_PASSWORD)
|
||||
.short("P")
|
||||
.help("Display the id as a password file entry."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_REAL_ID)
|
||||
.short("r")
|
||||
.long(options::OPT_REAL_ID)
|
||||
.help(
|
||||
"Display the real ID for the -G, -g and -u options instead of \
|
||||
the effective ID.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_ZERO)
|
||||
.short("z")
|
||||
.long(options::OPT_ZERO)
|
||||
.help(
|
||||
"delimit entries with NUL characters, not whitespace;\n\
|
||||
not permitted in default format",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_CONTEXT)
|
||||
.short("Z")
|
||||
.long(options::OPT_CONTEXT)
|
||||
.help("NotImplemented: print only the security context of the process"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ARG_USERS)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.value_name(options::ARG_USERS),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let users: Vec<String> = matches
|
||||
|
@ -385,6 +288,107 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
exit_code
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_AUDIT)
|
||||
.short("A")
|
||||
.conflicts_with_all(&[
|
||||
options::OPT_GROUP,
|
||||
options::OPT_EFFECTIVE_USER,
|
||||
options::OPT_HUMAN_READABLE,
|
||||
options::OPT_PASSWORD,
|
||||
options::OPT_GROUPS,
|
||||
options::OPT_ZERO,
|
||||
])
|
||||
.help(
|
||||
"Display the process audit user ID and other process audit properties,\n\
|
||||
which requires privilege (not available on Linux).",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_EFFECTIVE_USER)
|
||||
.short("u")
|
||||
.long(options::OPT_EFFECTIVE_USER)
|
||||
.conflicts_with(options::OPT_GROUP)
|
||||
.help("Display only the effective user ID as a number."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_GROUP)
|
||||
.short("g")
|
||||
.long(options::OPT_GROUP)
|
||||
.help("Display only the effective group ID as a number"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_GROUPS)
|
||||
.short("G")
|
||||
.long(options::OPT_GROUPS)
|
||||
.conflicts_with_all(&[
|
||||
options::OPT_GROUP,
|
||||
options::OPT_EFFECTIVE_USER,
|
||||
options::OPT_HUMAN_READABLE,
|
||||
options::OPT_PASSWORD,
|
||||
options::OPT_AUDIT,
|
||||
])
|
||||
.help(
|
||||
"Display only the different group IDs as white-space separated numbers, \
|
||||
in no particular order.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_HUMAN_READABLE)
|
||||
.short("p")
|
||||
.help("Make the output human-readable. Each display is on a separate line."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_NAME)
|
||||
.short("n")
|
||||
.long(options::OPT_NAME)
|
||||
.help(
|
||||
"Display the name of the user or group ID for the -G, -g and -u options \
|
||||
instead of the number.\nIf any of the ID numbers cannot be mapped into \
|
||||
names, the number will be displayed as usual.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_PASSWORD)
|
||||
.short("P")
|
||||
.help("Display the id as a password file entry."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_REAL_ID)
|
||||
.short("r")
|
||||
.long(options::OPT_REAL_ID)
|
||||
.help(
|
||||
"Display the real ID for the -G, -g and -u options instead of \
|
||||
the effective ID.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_ZERO)
|
||||
.short("z")
|
||||
.long(options::OPT_ZERO)
|
||||
.help(
|
||||
"delimit entries with NUL characters, not whitespace;\n\
|
||||
not permitted in default format",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OPT_CONTEXT)
|
||||
.short("Z")
|
||||
.long(options::OPT_CONTEXT)
|
||||
.help("NotImplemented: print only the security context of the process"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ARG_USERS)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.value_name(options::ARG_USERS),
|
||||
)
|
||||
}
|
||||
|
||||
fn pretty(possible_pw: Option<Passwd>) {
|
||||
if let Some(p) = possible_pw {
|
||||
print!("uid\t{}\ngroups\t", p.name());
|
||||
|
|
|
@ -98,10 +98,35 @@ fn get_usage() -> String {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let paths: Vec<String> = matches
|
||||
.values_of(ARG_FILES)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
if let Err(s) = check_unimplemented(&matches) {
|
||||
show_error!("Unimplemented feature: {}", s);
|
||||
return 2;
|
||||
}
|
||||
|
||||
let behavior = match behavior(&matches) {
|
||||
Ok(x) => x,
|
||||
Err(ret) => {
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
match behavior.main_function {
|
||||
MainFunction::Directory => directory(paths, behavior),
|
||||
MainFunction::Standard => standard(paths, behavior),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_BACKUP)
|
||||
.long(OPT_BACKUP)
|
||||
|
@ -228,29 +253,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.value_name("CONTEXT")
|
||||
)
|
||||
.arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true).min_values(1))
|
||||
.get_matches_from(args);
|
||||
|
||||
let paths: Vec<String> = matches
|
||||
.values_of(ARG_FILES)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
if let Err(s) = check_unimplemented(&matches) {
|
||||
show_error!("Unimplemented feature: {}", s);
|
||||
return 2;
|
||||
}
|
||||
|
||||
let behavior = match behavior(&matches) {
|
||||
Ok(x) => x,
|
||||
Err(ret) => {
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
match behavior.main_function {
|
||||
MainFunction::Directory => directory(paths, behavior),
|
||||
MainFunction::Standard => standard(paths, behavior),
|
||||
}
|
||||
}
|
||||
|
||||
/// Check for unimplemented command line arguments.
|
||||
|
|
|
@ -442,7 +442,72 @@ impl<'a> State<'a> {
|
|||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let matches = App::new(NAME)
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let keys = parse_field_number_option(matches.value_of("j"));
|
||||
let key1 = parse_field_number_option(matches.value_of("1"));
|
||||
let key2 = parse_field_number_option(matches.value_of("2"));
|
||||
|
||||
let mut settings: Settings = Default::default();
|
||||
|
||||
if let Some(value) = matches.value_of("v") {
|
||||
settings.print_unpaired = parse_file_number(value);
|
||||
settings.print_joined = false;
|
||||
} else if let Some(value) = matches.value_of("a") {
|
||||
settings.print_unpaired = parse_file_number(value);
|
||||
}
|
||||
|
||||
settings.ignore_case = matches.is_present("i");
|
||||
settings.key1 = get_field_number(keys, key1);
|
||||
settings.key2 = get_field_number(keys, key2);
|
||||
|
||||
if let Some(value) = matches.value_of("t") {
|
||||
settings.separator = match value.len() {
|
||||
0 => Sep::Line,
|
||||
1 => Sep::Char(value.chars().next().unwrap()),
|
||||
_ => crash!(1, "multi-character tab {}", value),
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(format) = matches.value_of("o") {
|
||||
if format == "auto" {
|
||||
settings.autoformat = true;
|
||||
} else {
|
||||
settings.format = format
|
||||
.split(|c| c == ' ' || c == ',' || c == '\t')
|
||||
.map(Spec::parse)
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(empty) = matches.value_of("e") {
|
||||
settings.empty = empty.to_string();
|
||||
}
|
||||
|
||||
if matches.is_present("nocheck-order") {
|
||||
settings.check_order = CheckOrder::Disabled;
|
||||
}
|
||||
|
||||
if matches.is_present("check-order") {
|
||||
settings.check_order = CheckOrder::Enabled;
|
||||
}
|
||||
|
||||
if matches.is_present("header") {
|
||||
settings.headers = true;
|
||||
}
|
||||
|
||||
let file1 = matches.value_of("file1").unwrap();
|
||||
let file2 = matches.value_of("file2").unwrap();
|
||||
|
||||
if file1 == "-" && file2 == "-" {
|
||||
crash!(1, "both files cannot be standard input");
|
||||
}
|
||||
|
||||
exec(file1, file2, &settings)
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(NAME)
|
||||
.version(crate_version!())
|
||||
.about(
|
||||
"For each pair of input lines with identical join fields, write a line to
|
||||
|
@ -542,68 +607,6 @@ FILENUM is 1 or 2, corresponding to FILE1 or FILE2",
|
|||
.value_name("FILE2")
|
||||
.hidden(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let keys = parse_field_number_option(matches.value_of("j"));
|
||||
let key1 = parse_field_number_option(matches.value_of("1"));
|
||||
let key2 = parse_field_number_option(matches.value_of("2"));
|
||||
|
||||
let mut settings: Settings = Default::default();
|
||||
|
||||
if let Some(value) = matches.value_of("v") {
|
||||
settings.print_unpaired = parse_file_number(value);
|
||||
settings.print_joined = false;
|
||||
} else if let Some(value) = matches.value_of("a") {
|
||||
settings.print_unpaired = parse_file_number(value);
|
||||
}
|
||||
|
||||
settings.ignore_case = matches.is_present("i");
|
||||
settings.key1 = get_field_number(keys, key1);
|
||||
settings.key2 = get_field_number(keys, key2);
|
||||
|
||||
if let Some(value) = matches.value_of("t") {
|
||||
settings.separator = match value.len() {
|
||||
0 => Sep::Line,
|
||||
1 => Sep::Char(value.chars().next().unwrap()),
|
||||
_ => crash!(1, "multi-character tab {}", value),
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(format) = matches.value_of("o") {
|
||||
if format == "auto" {
|
||||
settings.autoformat = true;
|
||||
} else {
|
||||
settings.format = format
|
||||
.split(|c| c == ' ' || c == ',' || c == '\t')
|
||||
.map(Spec::parse)
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(empty) = matches.value_of("e") {
|
||||
settings.empty = empty.to_string();
|
||||
}
|
||||
|
||||
if matches.is_present("nocheck-order") {
|
||||
settings.check_order = CheckOrder::Disabled;
|
||||
}
|
||||
|
||||
if matches.is_present("check-order") {
|
||||
settings.check_order = CheckOrder::Enabled;
|
||||
}
|
||||
|
||||
if matches.is_present("header") {
|
||||
settings.headers = true;
|
||||
}
|
||||
|
||||
let file1 = matches.value_of("file1").unwrap();
|
||||
let file2 = matches.value_of("file2").unwrap();
|
||||
|
||||
if file1 == "-" && file2 == "-" {
|
||||
crash!(1, "both files cannot be standard input");
|
||||
}
|
||||
|
||||
exec(file1, file2, &settings)
|
||||
}
|
||||
|
||||
fn exec(file1: &str, file2: &str, settings: &Settings) -> i32 {
|
||||
|
|
|
@ -43,38 +43,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let (args, obs_signal) = handle_obsolete(args);
|
||||
|
||||
let usage = format!("{} [OPTIONS]... PID...", executable!());
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::LIST)
|
||||
.short("l")
|
||||
.long(options::LIST)
|
||||
.help("Lists signals")
|
||||
.conflicts_with(options::TABLE)
|
||||
.conflicts_with(options::TABLE_OLD),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TABLE)
|
||||
.short("t")
|
||||
.long(options::TABLE)
|
||||
.help("Lists table of signals"),
|
||||
)
|
||||
.arg(Arg::with_name(options::TABLE_OLD).short("L").hidden(true))
|
||||
.arg(
|
||||
Arg::with_name(options::SIGNAL)
|
||||
.short("s")
|
||||
.long(options::SIGNAL)
|
||||
.help("Sends given signal")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::PIDS_OR_SIGNALS)
|
||||
.hidden(true)
|
||||
.multiple(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let mode = if matches.is_present(options::TABLE) || matches.is_present(options::TABLE_OLD) {
|
||||
Mode::Table
|
||||
|
@ -106,6 +75,39 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
EXIT_OK
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::LIST)
|
||||
.short("l")
|
||||
.long(options::LIST)
|
||||
.help("Lists signals")
|
||||
.conflicts_with(options::TABLE)
|
||||
.conflicts_with(options::TABLE_OLD),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TABLE)
|
||||
.short("t")
|
||||
.long(options::TABLE)
|
||||
.help("Lists table of signals"),
|
||||
)
|
||||
.arg(Arg::with_name(options::TABLE_OLD).short("L").hidden(true))
|
||||
.arg(
|
||||
Arg::with_name(options::SIGNAL)
|
||||
.short("s")
|
||||
.long(options::SIGNAL)
|
||||
.help("Sends given signal")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::PIDS_OR_SIGNALS)
|
||||
.hidden(true)
|
||||
.multiple(true),
|
||||
)
|
||||
}
|
||||
|
||||
fn handle_obsolete(mut args: Vec<String>) -> (Vec<String>, Option<String>) {
|
||||
let mut i = 0;
|
||||
while i < args.len() {
|
||||
|
|
|
@ -32,19 +32,7 @@ pub fn normalize_error_message(e: Error) -> String {
|
|||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::FILES)
|
||||
.hidden(true)
|
||||
.required(true)
|
||||
.min_values(2)
|
||||
.max_values(2)
|
||||
.takes_value(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let files: Vec<_> = matches
|
||||
.values_of_os(options::FILES)
|
||||
|
@ -61,3 +49,17 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::FILES)
|
||||
.hidden(true)
|
||||
.required(true)
|
||||
.min_values(2)
|
||||
.max_values(2)
|
||||
.takes_value(true),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -97,11 +97,71 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let usage = get_usage();
|
||||
let long_usage = get_long_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
let matches = uu_app()
|
||||
.usage(&usage[..])
|
||||
.after_help(&long_usage[..])
|
||||
.get_matches_from(args);
|
||||
|
||||
/* the list of files */
|
||||
|
||||
let paths: Vec<PathBuf> = matches
|
||||
.values_of(ARG_FILES)
|
||||
.unwrap()
|
||||
.map(PathBuf::from)
|
||||
.collect();
|
||||
|
||||
let overwrite_mode = if matches.is_present(options::FORCE) {
|
||||
OverwriteMode::Force
|
||||
} else if matches.is_present(options::INTERACTIVE) {
|
||||
OverwriteMode::Interactive
|
||||
} else {
|
||||
OverwriteMode::NoClobber
|
||||
};
|
||||
|
||||
let backup_mode = if matches.is_present(options::B) {
|
||||
BackupMode::ExistingBackup
|
||||
} else if matches.is_present(options::BACKUP) {
|
||||
match matches.value_of(options::BACKUP) {
|
||||
None => BackupMode::ExistingBackup,
|
||||
Some(mode) => match mode {
|
||||
"simple" | "never" => BackupMode::SimpleBackup,
|
||||
"numbered" | "t" => BackupMode::NumberedBackup,
|
||||
"existing" | "nil" => BackupMode::ExistingBackup,
|
||||
"none" | "off" => BackupMode::NoBackup,
|
||||
_ => panic!(), // cannot happen as it is managed by clap
|
||||
},
|
||||
}
|
||||
} else {
|
||||
BackupMode::NoBackup
|
||||
};
|
||||
|
||||
let backup_suffix = if matches.is_present(options::SUFFIX) {
|
||||
matches.value_of(options::SUFFIX).unwrap()
|
||||
} else {
|
||||
"~"
|
||||
};
|
||||
|
||||
let settings = Settings {
|
||||
overwrite: overwrite_mode,
|
||||
backup: backup_mode,
|
||||
suffix: backup_suffix.to_string(),
|
||||
symbolic: matches.is_present(options::SYMBOLIC),
|
||||
relative: matches.is_present(options::RELATIVE),
|
||||
target_dir: matches
|
||||
.value_of(options::TARGET_DIRECTORY)
|
||||
.map(String::from),
|
||||
no_target_dir: matches.is_present(options::NO_TARGET_DIRECTORY),
|
||||
no_dereference: matches.is_present(options::NO_DEREFERENCE),
|
||||
verbose: matches.is_present(options::VERBOSE),
|
||||
};
|
||||
|
||||
exec(&paths[..], &settings)
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(Arg::with_name(options::B).short(options::B).help(
|
||||
"make a backup of each file that would otherwise be overwritten or \
|
||||
removed",
|
||||
|
@ -198,62 +258,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.required(true)
|
||||
.min_values(1),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
/* the list of files */
|
||||
|
||||
let paths: Vec<PathBuf> = matches
|
||||
.values_of(ARG_FILES)
|
||||
.unwrap()
|
||||
.map(PathBuf::from)
|
||||
.collect();
|
||||
|
||||
let overwrite_mode = if matches.is_present(options::FORCE) {
|
||||
OverwriteMode::Force
|
||||
} else if matches.is_present(options::INTERACTIVE) {
|
||||
OverwriteMode::Interactive
|
||||
} else {
|
||||
OverwriteMode::NoClobber
|
||||
};
|
||||
|
||||
let backup_mode = if matches.is_present(options::B) {
|
||||
BackupMode::ExistingBackup
|
||||
} else if matches.is_present(options::BACKUP) {
|
||||
match matches.value_of(options::BACKUP) {
|
||||
None => BackupMode::ExistingBackup,
|
||||
Some(mode) => match mode {
|
||||
"simple" | "never" => BackupMode::SimpleBackup,
|
||||
"numbered" | "t" => BackupMode::NumberedBackup,
|
||||
"existing" | "nil" => BackupMode::ExistingBackup,
|
||||
"none" | "off" => BackupMode::NoBackup,
|
||||
_ => panic!(), // cannot happen as it is managed by clap
|
||||
},
|
||||
}
|
||||
} else {
|
||||
BackupMode::NoBackup
|
||||
};
|
||||
|
||||
let backup_suffix = if matches.is_present(options::SUFFIX) {
|
||||
matches.value_of(options::SUFFIX).unwrap()
|
||||
} else {
|
||||
"~"
|
||||
};
|
||||
|
||||
let settings = Settings {
|
||||
overwrite: overwrite_mode,
|
||||
backup: backup_mode,
|
||||
suffix: backup_suffix.to_string(),
|
||||
symbolic: matches.is_present(options::SYMBOLIC),
|
||||
relative: matches.is_present(options::RELATIVE),
|
||||
target_dir: matches
|
||||
.value_of(options::TARGET_DIRECTORY)
|
||||
.map(String::from),
|
||||
no_target_dir: matches.is_present(options::NO_TARGET_DIRECTORY),
|
||||
no_dereference: matches.is_present(options::NO_DEREFERENCE),
|
||||
verbose: matches.is_present(options::VERBOSE),
|
||||
};
|
||||
|
||||
exec(&paths[..], &settings)
|
||||
}
|
||||
|
||||
fn exec(files: &[PathBuf], settings: &Settings) -> i32 {
|
||||
|
|
|
@ -45,11 +45,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.accept_any();
|
||||
|
||||
let usage = get_usage();
|
||||
let _ = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
.usage(&usage[..])
|
||||
.get_matches_from(args);
|
||||
let _ = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
match get_userlogin() {
|
||||
Some(userlogin) => println!("{}", userlogin),
|
||||
|
@ -58,3 +54,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(SUMMARY)
|
||||
}
|
||||
|
|
|
@ -558,10 +558,22 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
let usage = get_usage();
|
||||
|
||||
let app = App::new(executable!())
|
||||
let app = uu_app().usage(&usage[..]);
|
||||
|
||||
let matches = app.get_matches_from(args);
|
||||
|
||||
let locs = matches
|
||||
.values_of(options::PATHS)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_else(|| vec![String::from(".")]);
|
||||
|
||||
list(locs, Config::from(matches))
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
|
||||
// Format arguments
|
||||
.arg(
|
||||
|
@ -1095,16 +1107,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
// Positional arguments
|
||||
.arg(Arg::with_name(options::PATHS).multiple(true).takes_value(true))
|
||||
|
||||
.after_help(AFTER_HELP);
|
||||
|
||||
let matches = app.get_matches_from(args);
|
||||
|
||||
let locs = matches
|
||||
.values_of(options::PATHS)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_else(|| vec![String::from(".")]);
|
||||
|
||||
list(locs, Config::from(matches))
|
||||
.after_help(AFTER_HELP)
|
||||
}
|
||||
|
||||
/// Represents a Path along with it's associated data
|
||||
|
|
|
@ -32,10 +32,37 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
// Linux-specific options, not implemented
|
||||
// opts.optflag("Z", "context", "set SELinux security context" +
|
||||
// " of each created directory to CTX"),
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let dirs: Vec<String> = matches
|
||||
.values_of(ARG_DIRS)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let verbose = matches.is_present(OPT_VERBOSE);
|
||||
let recursive = matches.is_present(OPT_PARENTS);
|
||||
|
||||
// Translate a ~str in octal form to u16, default to 755
|
||||
// Not tested on Windows
|
||||
let mode_match = matches.value_of(OPT_MODE);
|
||||
let mode: u16 = match mode_match {
|
||||
Some(m) => {
|
||||
let res: Option<u16> = u16::from_str_radix(m, 8).ok();
|
||||
match res {
|
||||
Some(r) => r,
|
||||
_ => crash!(1, "no mode given"),
|
||||
}
|
||||
}
|
||||
_ => 0o755_u16,
|
||||
};
|
||||
|
||||
exec(dirs, recursive, mode, verbose)
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_MODE)
|
||||
.short("m")
|
||||
|
@ -62,31 +89,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.takes_value(true)
|
||||
.min_values(1),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let dirs: Vec<String> = matches
|
||||
.values_of(ARG_DIRS)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let verbose = matches.is_present(OPT_VERBOSE);
|
||||
let recursive = matches.is_present(OPT_PARENTS);
|
||||
|
||||
// Translate a ~str in octal form to u16, default to 755
|
||||
// Not tested on Windows
|
||||
let mode_match = matches.value_of(OPT_MODE);
|
||||
let mode: u16 = match mode_match {
|
||||
Some(m) => {
|
||||
let res: Option<u16> = u16::from_str_radix(m, 8).ok();
|
||||
match res {
|
||||
Some(r) => r,
|
||||
_ => crash!(1, "no mode given"),
|
||||
}
|
||||
}
|
||||
_ => 0o755_u16,
|
||||
};
|
||||
|
||||
exec(dirs, recursive, mode, verbose)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,27 +29,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::Ignore)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.usage(USAGE)
|
||||
.about(SUMMARY)
|
||||
.arg(
|
||||
Arg::with_name(options::MODE)
|
||||
.short("m")
|
||||
.long(options::MODE)
|
||||
.help("file permissions for the fifo")
|
||||
.default_value("0666")
|
||||
.value_name("0666"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SE_LINUX_SECURITY_CONTEXT)
|
||||
.short(options::SE_LINUX_SECURITY_CONTEXT)
|
||||
.help("set the SELinux security context to default type")
|
||||
)
|
||||
.arg(Arg::with_name(options::CONTEXT).long(options::CONTEXT).value_name("CTX").help("like -Z, or if CTX is specified then set the SELinux\nor SMACK security context to CTX"))
|
||||
.arg(Arg::with_name(options::FIFO).hidden(true).multiple(true))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
if matches.is_present(options::CONTEXT) {
|
||||
crash!(1, "--context is not implemented");
|
||||
|
@ -88,3 +68,26 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
exit_code
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.usage(USAGE)
|
||||
.about(SUMMARY)
|
||||
.arg(
|
||||
Arg::with_name(options::MODE)
|
||||
.short("m")
|
||||
.long(options::MODE)
|
||||
.help("file permissions for the fifo")
|
||||
.default_value("0666")
|
||||
.value_name("0666"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SE_LINUX_SECURITY_CONTEXT)
|
||||
.short(options::SE_LINUX_SECURITY_CONTEXT)
|
||||
.help("set the SELinux security context to default type")
|
||||
)
|
||||
.arg(Arg::with_name(options::CONTEXT).long(options::CONTEXT).value_name("CTX").help("like -Z, or if CTX is specified then set the SELinux\nor SMACK security context to CTX"))
|
||||
.arg(Arg::with_name(options::FIFO).hidden(true).multiple(true))
|
||||
}
|
||||
|
|
|
@ -89,48 +89,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
// opts.optflag("Z", "", "set the SELinux security context to default type");
|
||||
// opts.optopt("", "context", "like -Z, or if CTX is specified then set the SELinux or SMACK security context to CTX");
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.usage(USAGE)
|
||||
.after_help(LONG_HELP)
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name("mode")
|
||||
.short("m")
|
||||
.long("mode")
|
||||
.value_name("MODE")
|
||||
.help("set file permission bits to MODE, not a=rw - umask"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("name")
|
||||
.value_name("NAME")
|
||||
.help("name of the new file")
|
||||
.required(true)
|
||||
.index(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("type")
|
||||
.value_name("TYPE")
|
||||
.help("type of the new file (b, c, u or p)")
|
||||
.required(true)
|
||||
.validator(valid_type)
|
||||
.index(2),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("major")
|
||||
.value_name("MAJOR")
|
||||
.help("major file type")
|
||||
.validator(valid_u64)
|
||||
.index(3),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("minor")
|
||||
.value_name("MINOR")
|
||||
.help("minor file type")
|
||||
.validator(valid_u64)
|
||||
.index(4),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let mode = match get_mode(&matches) {
|
||||
Ok(mode) => mode,
|
||||
|
@ -185,6 +144,50 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.usage(USAGE)
|
||||
.after_help(LONG_HELP)
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name("mode")
|
||||
.short("m")
|
||||
.long("mode")
|
||||
.value_name("MODE")
|
||||
.help("set file permission bits to MODE, not a=rw - umask"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("name")
|
||||
.value_name("NAME")
|
||||
.help("name of the new file")
|
||||
.required(true)
|
||||
.index(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("type")
|
||||
.value_name("TYPE")
|
||||
.help("type of the new file (b, c, u or p)")
|
||||
.required(true)
|
||||
.validator(valid_type)
|
||||
.index(2),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("major")
|
||||
.value_name("MAJOR")
|
||||
.help("major file type")
|
||||
.validator(valid_u64)
|
||||
.index(3),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("minor")
|
||||
.value_name("MINOR")
|
||||
.help("minor file type")
|
||||
.validator(valid_u64)
|
||||
.index(4),
|
||||
)
|
||||
}
|
||||
|
||||
fn get_mode(matches: &ArgMatches) -> Result<mode_t, String> {
|
||||
match matches.value_of("mode") {
|
||||
None => Ok(MODE_RW_UGO),
|
||||
|
|
|
@ -40,61 +40,7 @@ fn get_usage() -> String {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_DIRECTORY)
|
||||
.short("d")
|
||||
.long(OPT_DIRECTORY)
|
||||
.help("Make a directory instead of a file"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_DRY_RUN)
|
||||
.short("u")
|
||||
.long(OPT_DRY_RUN)
|
||||
.help("do not create anything; merely print a name (unsafe)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_QUIET)
|
||||
.short("q")
|
||||
.long("quiet")
|
||||
.help("Fail silently if an error occurs."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SUFFIX)
|
||||
.long(OPT_SUFFIX)
|
||||
.help(
|
||||
"append SUFFIX to TEMPLATE; SUFFIX must not contain a path separator. \
|
||||
This option is implied if TEMPLATE does not end with X.",
|
||||
)
|
||||
.value_name("SUFFIX"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_TMPDIR)
|
||||
.short("p")
|
||||
.long(OPT_TMPDIR)
|
||||
.help(
|
||||
"interpret TEMPLATE relative to DIR; if DIR is not specified, use \
|
||||
$TMPDIR ($TMP on windows) if set, else /tmp. With this option, TEMPLATE must not \
|
||||
be an absolute name; unlike with -t, TEMPLATE may contain \
|
||||
slashes, but mktemp creates only the final component",
|
||||
)
|
||||
.value_name("DIR"),
|
||||
)
|
||||
.arg(Arg::with_name(OPT_T).short(OPT_T).help(
|
||||
"Generate a template (using the supplied prefix and TMPDIR (TMP on windows) if set) \
|
||||
to create a filename template [deprecated]",
|
||||
))
|
||||
.arg(
|
||||
Arg::with_name(ARG_TEMPLATE)
|
||||
.multiple(false)
|
||||
.takes_value(true)
|
||||
.max_values(1)
|
||||
.default_value(DEFAULT_TEMPLATE),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let template = matches.value_of(ARG_TEMPLATE).unwrap();
|
||||
let tmpdir = matches.value_of(OPT_TMPDIR).unwrap_or_default();
|
||||
|
@ -171,6 +117,62 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(OPT_DIRECTORY)
|
||||
.short("d")
|
||||
.long(OPT_DIRECTORY)
|
||||
.help("Make a directory instead of a file"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_DRY_RUN)
|
||||
.short("u")
|
||||
.long(OPT_DRY_RUN)
|
||||
.help("do not create anything; merely print a name (unsafe)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_QUIET)
|
||||
.short("q")
|
||||
.long("quiet")
|
||||
.help("Fail silently if an error occurs."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SUFFIX)
|
||||
.long(OPT_SUFFIX)
|
||||
.help(
|
||||
"append SUFFIX to TEMPLATE; SUFFIX must not contain a path separator. \
|
||||
This option is implied if TEMPLATE does not end with X.",
|
||||
)
|
||||
.value_name("SUFFIX"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_TMPDIR)
|
||||
.short("p")
|
||||
.long(OPT_TMPDIR)
|
||||
.help(
|
||||
"interpret TEMPLATE relative to DIR; if DIR is not specified, use \
|
||||
$TMPDIR ($TMP on windows) if set, else /tmp. With this option, TEMPLATE must not \
|
||||
be an absolute name; unlike with -t, TEMPLATE may contain \
|
||||
slashes, but mktemp creates only the final component",
|
||||
)
|
||||
.value_name("DIR"),
|
||||
)
|
||||
.arg(Arg::with_name(OPT_T).short(OPT_T).help(
|
||||
"Generate a template (using the supplied prefix and TMPDIR (TMP on windows) if set) \
|
||||
to create a filename template [deprecated]",
|
||||
))
|
||||
.arg(
|
||||
Arg::with_name(ARG_TEMPLATE)
|
||||
.multiple(false)
|
||||
.takes_value(true)
|
||||
.max_values(1)
|
||||
.default_value(DEFAULT_TEMPLATE),
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_template(temp: &str) -> Option<(&str, usize, &str)> {
|
||||
let right = match temp.rfind('X') {
|
||||
Some(r) => r + 1,
|
||||
|
|
|
@ -51,7 +51,49 @@ pub mod options {
|
|||
const MULTI_FILE_TOP_PROMPT: &str = "::::::::::::::\n{}\n::::::::::::::\n";
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let mut buff = String::new();
|
||||
let silent = matches.is_present(options::SILENT);
|
||||
if let Some(files) = matches.values_of(options::FILES) {
|
||||
let mut stdout = setup_term();
|
||||
let length = files.len();
|
||||
|
||||
let mut files_iter = files.peekable();
|
||||
while let (Some(file), next_file) = (files_iter.next(), files_iter.peek()) {
|
||||
let file = Path::new(file);
|
||||
if file.is_dir() {
|
||||
terminal::disable_raw_mode().unwrap();
|
||||
show_usage_error!("'{}' is a directory.", file.display());
|
||||
return 1;
|
||||
}
|
||||
if !file.exists() {
|
||||
terminal::disable_raw_mode().unwrap();
|
||||
show_error!("cannot open {}: No such file or directory", file.display());
|
||||
return 1;
|
||||
}
|
||||
if length > 1 {
|
||||
buff.push_str(&MULTI_FILE_TOP_PROMPT.replace("{}", file.to_str().unwrap()));
|
||||
}
|
||||
let mut reader = BufReader::new(File::open(file).unwrap());
|
||||
reader.read_to_string(&mut buff).unwrap();
|
||||
more(&buff, &mut stdout, next_file.copied(), silent);
|
||||
buff.clear();
|
||||
}
|
||||
reset_term(&mut stdout);
|
||||
} else if atty::isnt(atty::Stream::Stdin) {
|
||||
stdin().read_to_string(&mut buff).unwrap();
|
||||
let mut stdout = setup_term();
|
||||
more(&buff, &mut stdout, None, silent);
|
||||
reset_term(&mut stdout);
|
||||
} else {
|
||||
show_usage_error!("bad usage");
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.about("A file perusal filter for CRT viewing.")
|
||||
.version(crate_version!())
|
||||
.arg(
|
||||
|
@ -138,45 +180,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.multiple(true)
|
||||
.help("Path to the files to be read"),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let mut buff = String::new();
|
||||
let silent = matches.is_present(options::SILENT);
|
||||
if let Some(files) = matches.values_of(options::FILES) {
|
||||
let mut stdout = setup_term();
|
||||
let length = files.len();
|
||||
|
||||
let mut files_iter = files.peekable();
|
||||
while let (Some(file), next_file) = (files_iter.next(), files_iter.peek()) {
|
||||
let file = Path::new(file);
|
||||
if file.is_dir() {
|
||||
terminal::disable_raw_mode().unwrap();
|
||||
show_usage_error!("'{}' is a directory.", file.display());
|
||||
return 1;
|
||||
}
|
||||
if !file.exists() {
|
||||
terminal::disable_raw_mode().unwrap();
|
||||
show_error!("cannot open {}: No such file or directory", file.display());
|
||||
return 1;
|
||||
}
|
||||
if length > 1 {
|
||||
buff.push_str(&MULTI_FILE_TOP_PROMPT.replace("{}", file.to_str().unwrap()));
|
||||
}
|
||||
let mut reader = BufReader::new(File::open(file).unwrap());
|
||||
reader.read_to_string(&mut buff).unwrap();
|
||||
more(&buff, &mut stdout, next_file.copied(), silent);
|
||||
buff.clear();
|
||||
}
|
||||
reset_term(&mut stdout);
|
||||
} else if atty::isnt(atty::Stream::Stdin) {
|
||||
stdin().read_to_string(&mut buff).unwrap();
|
||||
let mut stdout = setup_term();
|
||||
more(&buff, &mut stdout, None, silent);
|
||||
reset_term(&mut stdout);
|
||||
} else {
|
||||
show_usage_error!("bad usage");
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "fuchsia"))]
|
||||
|
|
|
@ -70,11 +70,64 @@ fn get_usage() -> String {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app()
|
||||
.after_help(&*format!(
|
||||
"{}\n{}",
|
||||
LONG_HELP,
|
||||
backup_control::BACKUP_CONTROL_LONG_HELP
|
||||
))
|
||||
.usage(&usage[..])
|
||||
.get_matches_from(args);
|
||||
|
||||
let files: Vec<String> = matches
|
||||
.values_of(ARG_FILES)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let overwrite_mode = determine_overwrite_mode(&matches);
|
||||
let backup_mode = backup_control::determine_backup_mode(
|
||||
matches.is_present(OPT_BACKUP_NO_ARG) || matches.is_present(OPT_BACKUP),
|
||||
matches.value_of(OPT_BACKUP),
|
||||
);
|
||||
|
||||
if overwrite_mode == OverwriteMode::NoClobber && backup_mode != BackupMode::NoBackup {
|
||||
show_usage_error!("options --backup and --no-clobber are mutually exclusive");
|
||||
return 1;
|
||||
}
|
||||
|
||||
let backup_suffix = backup_control::determine_backup_suffix(matches.value_of(OPT_SUFFIX));
|
||||
|
||||
let behavior = Behavior {
|
||||
overwrite: overwrite_mode,
|
||||
backup: backup_mode,
|
||||
suffix: backup_suffix,
|
||||
update: matches.is_present(OPT_UPDATE),
|
||||
target_dir: matches.value_of(OPT_TARGET_DIRECTORY).map(String::from),
|
||||
no_target_dir: matches.is_present(OPT_NO_TARGET_DIRECTORY),
|
||||
verbose: matches.is_present(OPT_VERBOSE),
|
||||
};
|
||||
|
||||
let paths: Vec<PathBuf> = {
|
||||
fn strip_slashes(p: &Path) -> &Path {
|
||||
p.components().as_path()
|
||||
}
|
||||
let to_owned = |p: &Path| p.to_owned();
|
||||
let paths = files.iter().map(Path::new);
|
||||
|
||||
if matches.is_present(OPT_STRIP_TRAILING_SLASHES) {
|
||||
paths.map(strip_slashes).map(to_owned).collect()
|
||||
} else {
|
||||
paths.map(to_owned).collect()
|
||||
}
|
||||
};
|
||||
|
||||
exec(&paths[..], behavior)
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.after_help(&*format!("{}\n{}", LONG_HELP, backup_control::BACKUP_CONTROL_LONG_HELP))
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_BACKUP)
|
||||
.long(OPT_BACKUP)
|
||||
|
@ -153,51 +206,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.min_values(2)
|
||||
.required(true)
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let files: Vec<String> = matches
|
||||
.values_of(ARG_FILES)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let overwrite_mode = determine_overwrite_mode(&matches);
|
||||
let backup_mode = backup_control::determine_backup_mode(
|
||||
matches.is_present(OPT_BACKUP_NO_ARG) || matches.is_present(OPT_BACKUP),
|
||||
matches.value_of(OPT_BACKUP),
|
||||
);
|
||||
|
||||
if overwrite_mode == OverwriteMode::NoClobber && backup_mode != BackupMode::NoBackup {
|
||||
show_usage_error!("options --backup and --no-clobber are mutually exclusive");
|
||||
return 1;
|
||||
}
|
||||
|
||||
let backup_suffix = backup_control::determine_backup_suffix(matches.value_of(OPT_SUFFIX));
|
||||
|
||||
let behavior = Behavior {
|
||||
overwrite: overwrite_mode,
|
||||
backup: backup_mode,
|
||||
suffix: backup_suffix,
|
||||
update: matches.is_present(OPT_UPDATE),
|
||||
target_dir: matches.value_of(OPT_TARGET_DIRECTORY).map(String::from),
|
||||
no_target_dir: matches.is_present(OPT_NO_TARGET_DIRECTORY),
|
||||
verbose: matches.is_present(OPT_VERBOSE),
|
||||
};
|
||||
|
||||
let paths: Vec<PathBuf> = {
|
||||
fn strip_slashes(p: &Path) -> &Path {
|
||||
p.components().as_path()
|
||||
}
|
||||
let to_owned = |p: &Path| p.to_owned();
|
||||
let paths = files.iter().map(Path::new);
|
||||
|
||||
if matches.is_present(OPT_STRIP_TRAILING_SLASHES) {
|
||||
paths.map(strip_slashes).map(to_owned).collect()
|
||||
} else {
|
||||
paths.map(to_owned).collect()
|
||||
}
|
||||
};
|
||||
|
||||
exec(&paths[..], behavior)
|
||||
}
|
||||
|
||||
fn determine_overwrite_mode(matches: &ArgMatches) -> OverwriteMode {
|
||||
|
|
|
@ -46,20 +46,7 @@ process).",
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.version(crate_version!())
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::ADJUSTMENT)
|
||||
.short("n")
|
||||
.long(options::ADJUSTMENT)
|
||||
.help("add N to the niceness (default is 10)")
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true),
|
||||
)
|
||||
.arg(Arg::with_name(options::COMMAND).multiple(true))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let mut niceness = unsafe {
|
||||
nix::errno::Errno::clear();
|
||||
|
@ -120,3 +107,18 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
126
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.version(crate_version!())
|
||||
.arg(
|
||||
Arg::with_name(options::ADJUSTMENT)
|
||||
.short("n")
|
||||
.long(options::ADJUSTMENT)
|
||||
.help("add N to the niceness (default is 10)")
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true),
|
||||
)
|
||||
.arg(Arg::with_name(options::COMMAND).multiple(true))
|
||||
}
|
||||
|
|
|
@ -88,7 +88,62 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
// A mutable settings object, initialized with the defaults.
|
||||
let mut settings = Settings {
|
||||
header_numbering: NumberingStyle::NumberForNone,
|
||||
body_numbering: NumberingStyle::NumberForAll,
|
||||
footer_numbering: NumberingStyle::NumberForNone,
|
||||
section_delimiter: ['\\', ':'],
|
||||
starting_line_number: 1,
|
||||
line_increment: 1,
|
||||
join_blank_lines: 1,
|
||||
number_width: 6,
|
||||
number_format: NumberFormat::Right,
|
||||
renumber: true,
|
||||
number_separator: String::from("\t"),
|
||||
};
|
||||
|
||||
// Update the settings from the command line options, and terminate the
|
||||
// program if some options could not successfully be parsed.
|
||||
let parse_errors = helper::parse_options(&mut settings, &matches);
|
||||
if !parse_errors.is_empty() {
|
||||
show_error!("Invalid arguments supplied.");
|
||||
for message in &parse_errors {
|
||||
println!("{}", message);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
let mut read_stdin = false;
|
||||
let files: Vec<String> = match matches.values_of(options::FILE) {
|
||||
Some(v) => v.clone().map(|v| v.to_owned()).collect(),
|
||||
None => vec!["-".to_owned()],
|
||||
};
|
||||
|
||||
for file in &files {
|
||||
if file == "-" {
|
||||
// If both file names and '-' are specified, we choose to treat first all
|
||||
// regular files, and then read from stdin last.
|
||||
read_stdin = true;
|
||||
continue;
|
||||
}
|
||||
let path = Path::new(file);
|
||||
let reader = File::open(path).unwrap();
|
||||
let mut buffer = BufReader::new(reader);
|
||||
nl(&mut buffer, &settings);
|
||||
}
|
||||
|
||||
if read_stdin {
|
||||
let mut buffer = BufReader::new(stdin());
|
||||
nl(&mut buffer, &settings);
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.usage(USAGE)
|
||||
|
@ -169,58 +224,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.help("use NUMBER columns for line numbers")
|
||||
.value_name("NUMBER"),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
// A mutable settings object, initialized with the defaults.
|
||||
let mut settings = Settings {
|
||||
header_numbering: NumberingStyle::NumberForNone,
|
||||
body_numbering: NumberingStyle::NumberForAll,
|
||||
footer_numbering: NumberingStyle::NumberForNone,
|
||||
section_delimiter: ['\\', ':'],
|
||||
starting_line_number: 1,
|
||||
line_increment: 1,
|
||||
join_blank_lines: 1,
|
||||
number_width: 6,
|
||||
number_format: NumberFormat::Right,
|
||||
renumber: true,
|
||||
number_separator: String::from("\t"),
|
||||
};
|
||||
|
||||
// Update the settings from the command line options, and terminate the
|
||||
// program if some options could not successfully be parsed.
|
||||
let parse_errors = helper::parse_options(&mut settings, &matches);
|
||||
if !parse_errors.is_empty() {
|
||||
show_error!("Invalid arguments supplied.");
|
||||
for message in &parse_errors {
|
||||
println!("{}", message);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
let mut read_stdin = false;
|
||||
let files: Vec<String> = match matches.values_of(options::FILE) {
|
||||
Some(v) => v.clone().map(|v| v.to_owned()).collect(),
|
||||
None => vec!["-".to_owned()],
|
||||
};
|
||||
|
||||
for file in &files {
|
||||
if file == "-" {
|
||||
// If both file names and '-' are specified, we choose to treat first all
|
||||
// regular files, and then read from stdin last.
|
||||
read_stdin = true;
|
||||
continue;
|
||||
}
|
||||
let path = Path::new(file);
|
||||
let reader = File::open(path).unwrap();
|
||||
let mut buffer = BufReader::new(reader);
|
||||
nl(&mut buffer, &settings);
|
||||
}
|
||||
|
||||
if read_stdin {
|
||||
let mut buffer = BufReader::new(stdin());
|
||||
nl(&mut buffer, &settings);
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
// nl implements the main functionality for an individual buffer.
|
||||
|
|
|
@ -45,19 +45,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.after_help(LONG_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::CMD)
|
||||
.hidden(true)
|
||||
.required(true)
|
||||
.multiple(true),
|
||||
)
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
replace_fds();
|
||||
|
||||
|
@ -82,6 +70,20 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.after_help(LONG_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::CMD)
|
||||
.hidden(true)
|
||||
.required(true)
|
||||
.multiple(true),
|
||||
)
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
}
|
||||
|
||||
fn replace_fds() {
|
||||
if atty::is(atty::Stream::Stdin) {
|
||||
let new_stdin = match File::open(Path::new("/dev/null")) {
|
||||
|
|
|
@ -33,24 +33,7 @@ fn get_usage() -> String {
|
|||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_ALL)
|
||||
.short("")
|
||||
.long(OPT_ALL)
|
||||
.help("print the number of cores available to the system"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_IGNORE)
|
||||
.short("")
|
||||
.long(OPT_IGNORE)
|
||||
.takes_value(true)
|
||||
.help("ignore up to N cores"),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let mut ignore = match matches.value_of(OPT_IGNORE) {
|
||||
Some(numstr) => match numstr.parse() {
|
||||
|
@ -86,6 +69,25 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(OPT_ALL)
|
||||
.short("")
|
||||
.long(OPT_ALL)
|
||||
.help("print the number of cores available to the system"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_IGNORE)
|
||||
.short("")
|
||||
.long(OPT_IGNORE)
|
||||
.takes_value(true)
|
||||
.help("ignore up to N cores"),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_vendor = "apple",
|
||||
|
|
|
@ -156,10 +156,28 @@ fn parse_options(args: &ArgMatches) -> Result<NumfmtOptions> {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let result =
|
||||
parse_options(&matches).and_then(|options| match matches.values_of(options::NUMBER) {
|
||||
Some(values) => handle_args(values, options),
|
||||
None => handle_stdin(options),
|
||||
});
|
||||
|
||||
match result {
|
||||
Err(e) => {
|
||||
std::io::stdout().flush().expect("error flushing stdout");
|
||||
show_error!("{}", e);
|
||||
1
|
||||
}
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.after_help(LONG_HELP)
|
||||
.setting(AppSettings::AllowNegativeNumbers)
|
||||
.arg(
|
||||
|
@ -224,20 +242,4 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.possible_values(&["up", "down", "from-zero", "towards-zero", "nearest"]),
|
||||
)
|
||||
.arg(Arg::with_name(options::NUMBER).hidden(true).multiple(true))
|
||||
.get_matches_from(args);
|
||||
|
||||
let result =
|
||||
parse_options(&matches).and_then(|options| match matches.values_of(options::NUMBER) {
|
||||
Some(values) => handle_args(values, options),
|
||||
None => handle_stdin(options),
|
||||
});
|
||||
|
||||
match result {
|
||||
Err(e) => {
|
||||
std::io::stdout().flush().expect("error flushing stdout");
|
||||
show_error!("{}", e);
|
||||
1
|
||||
}
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,7 +214,45 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::Ignore)
|
||||
.accept_any();
|
||||
|
||||
let clap_opts = clap::App::new(executable!())
|
||||
let clap_opts = uu_app();
|
||||
|
||||
let clap_matches = clap_opts
|
||||
.clone() // Clone to reuse clap_opts to print help
|
||||
.get_matches_from(args.clone());
|
||||
|
||||
let od_options = match OdOptions::new(clap_matches, args) {
|
||||
Err(s) => {
|
||||
crash!(1, "{}", s);
|
||||
}
|
||||
Ok(o) => o,
|
||||
};
|
||||
|
||||
let mut input_offset =
|
||||
InputOffset::new(od_options.radix, od_options.skip_bytes, od_options.label);
|
||||
|
||||
let mut input = open_input_peek_reader(
|
||||
&od_options.input_strings,
|
||||
od_options.skip_bytes,
|
||||
od_options.read_bytes,
|
||||
);
|
||||
let mut input_decoder = InputDecoder::new(
|
||||
&mut input,
|
||||
od_options.line_bytes,
|
||||
PEEK_BUFFER_SIZE,
|
||||
od_options.byte_order,
|
||||
);
|
||||
|
||||
let output_info = OutputInfo::new(
|
||||
od_options.line_bytes,
|
||||
&od_options.formats[..],
|
||||
od_options.output_duplicates,
|
||||
);
|
||||
|
||||
odfunc(&mut input_offset, &mut input_decoder, &output_info)
|
||||
}
|
||||
|
||||
pub fn uu_app() -> clap::App<'static, 'static> {
|
||||
clap::App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(USAGE)
|
||||
|
@ -434,41 +472,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
AppSettings::DontDelimitTrailingValues,
|
||||
AppSettings::DisableVersion,
|
||||
AppSettings::DeriveDisplayOrder,
|
||||
]);
|
||||
|
||||
let clap_matches = clap_opts
|
||||
.clone() // Clone to reuse clap_opts to print help
|
||||
.get_matches_from(args.clone());
|
||||
|
||||
let od_options = match OdOptions::new(clap_matches, args) {
|
||||
Err(s) => {
|
||||
crash!(1, "{}", s);
|
||||
}
|
||||
Ok(o) => o,
|
||||
};
|
||||
|
||||
let mut input_offset =
|
||||
InputOffset::new(od_options.radix, od_options.skip_bytes, od_options.label);
|
||||
|
||||
let mut input = open_input_peek_reader(
|
||||
&od_options.input_strings,
|
||||
od_options.skip_bytes,
|
||||
od_options.read_bytes,
|
||||
);
|
||||
let mut input_decoder = InputDecoder::new(
|
||||
&mut input,
|
||||
od_options.line_bytes,
|
||||
PEEK_BUFFER_SIZE,
|
||||
od_options.byte_order,
|
||||
);
|
||||
|
||||
let output_info = OutputInfo::new(
|
||||
od_options.line_bytes,
|
||||
&od_options.formats[..],
|
||||
od_options.output_duplicates,
|
||||
);
|
||||
|
||||
odfunc(&mut input_offset, &mut input_decoder, &output_info)
|
||||
])
|
||||
}
|
||||
|
||||
/// Loops through the input line by line, calling print_bytes to take care of the output.
|
||||
|
|
|
@ -37,7 +37,22 @@ fn read_line<R: Read>(
|
|||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let serial = matches.is_present(options::SERIAL);
|
||||
let delimiters = matches.value_of(options::DELIMITER).unwrap().to_owned();
|
||||
let files = matches
|
||||
.values_of(options::FILE)
|
||||
.unwrap()
|
||||
.map(|s| s.to_owned())
|
||||
.collect();
|
||||
paste(files, serial, delimiters);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
|
@ -61,18 +76,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.multiple(true)
|
||||
.default_value("-"),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let serial = matches.is_present(options::SERIAL);
|
||||
let delimiters = matches.value_of(options::DELIMITER).unwrap().to_owned();
|
||||
let files = matches
|
||||
.values_of(options::FILE)
|
||||
.unwrap()
|
||||
.map(|s| s.to_owned())
|
||||
.collect();
|
||||
paste(files, serial, delimiters);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
fn paste(filenames: Vec<String>, serial: bool, delimiters: String) {
|
||||
|
|
|
@ -49,27 +49,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::POSIX)
|
||||
.short("p")
|
||||
.help("check for most POSIX systems"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::POSIX_SPECIAL)
|
||||
.short("P")
|
||||
.help(r#"check for empty names and leading "-""#),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::PORTABILITY)
|
||||
.long(options::PORTABILITY)
|
||||
.help("check for all POSIX systems (equivalent to -p -P)"),
|
||||
)
|
||||
.arg(Arg::with_name(options::PATH).hidden(true).multiple(true))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
// set working mode
|
||||
let is_posix = matches.values_of(options::POSIX).is_some();
|
||||
|
@ -115,6 +95,28 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::POSIX)
|
||||
.short("p")
|
||||
.help("check for most POSIX systems"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::POSIX_SPECIAL)
|
||||
.short("P")
|
||||
.help(r#"check for empty names and leading "-""#),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::PORTABILITY)
|
||||
.long(options::PORTABILITY)
|
||||
.help("check for all POSIX systems (equivalent to -p -P)"),
|
||||
)
|
||||
.arg(Arg::with_name(options::PATH).hidden(true).multiple(true))
|
||||
}
|
||||
|
||||
// check a path, given as a slice of it's components and an operating mode
|
||||
fn check_path(mode: &Mode, path: &[String]) -> bool {
|
||||
match *mode {
|
||||
|
|
|
@ -60,62 +60,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let usage = get_usage();
|
||||
let after_help = get_long_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
let matches = uu_app()
|
||||
.usage(&usage[..])
|
||||
.after_help(&after_help[..])
|
||||
.arg(
|
||||
Arg::with_name(options::LONG_FORMAT)
|
||||
.short("l")
|
||||
.requires(options::USER)
|
||||
.help("produce long format output for the specified USERs"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_HOME_DIR)
|
||||
.short("b")
|
||||
.help("omit the user's home directory and shell in long format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_PROJECT_FILE)
|
||||
.short("h")
|
||||
.help("omit the user's project file in long format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_PLAN_FILE)
|
||||
.short("p")
|
||||
.help("omit the user's plan file in long format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SHORT_FORMAT)
|
||||
.short("s")
|
||||
.help("do short format output, this is the default"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_HEADINGS)
|
||||
.short("f")
|
||||
.help("omit the line of column headings in short format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_NAME)
|
||||
.short("w")
|
||||
.help("omit the user's full name in short format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_NAME_HOST)
|
||||
.short("i")
|
||||
.help("omit the user's full name and remote host in short format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_NAME_HOST_TIME)
|
||||
.short("q")
|
||||
.help("omit the user's full name, remote host and idle time in short format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::USER)
|
||||
.takes_value(true)
|
||||
.multiple(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let users: Vec<String> = matches
|
||||
|
@ -182,6 +129,63 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::LONG_FORMAT)
|
||||
.short("l")
|
||||
.requires(options::USER)
|
||||
.help("produce long format output for the specified USERs"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_HOME_DIR)
|
||||
.short("b")
|
||||
.help("omit the user's home directory and shell in long format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_PROJECT_FILE)
|
||||
.short("h")
|
||||
.help("omit the user's project file in long format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_PLAN_FILE)
|
||||
.short("p")
|
||||
.help("omit the user's plan file in long format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SHORT_FORMAT)
|
||||
.short("s")
|
||||
.help("do short format output, this is the default"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_HEADINGS)
|
||||
.short("f")
|
||||
.help("omit the line of column headings in short format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_NAME)
|
||||
.short("w")
|
||||
.help("omit the user's full name in short format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_NAME_HOST)
|
||||
.short("i")
|
||||
.help("omit the user's full name and remote host in short format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::OMIT_NAME_HOST_TIME)
|
||||
.short("q")
|
||||
.help("omit the user's full name, remote host and idle time in short format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::USER)
|
||||
.takes_value(true)
|
||||
.multiple(true),
|
||||
)
|
||||
}
|
||||
|
||||
struct Pinky {
|
||||
include_idle: bool,
|
||||
include_heading: bool,
|
||||
|
|
|
@ -15,6 +15,7 @@ edition = "2018"
|
|||
path = "src/pr.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.3"
|
||||
uucore = { version=">=0.0.7", package="uucore", path="../../uucore", features=["utmpx", "entries"] }
|
||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||
getopts = "0.2.21"
|
||||
|
|
|
@ -23,6 +23,7 @@ use std::fs::{metadata, File};
|
|||
use std::io::{stdin, stdout, BufRead, BufReader, Lines, Read, Stdout, Write};
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::fs::FileTypeExt;
|
||||
use uucore::executable;
|
||||
|
||||
type IOError = std::io::Error;
|
||||
|
||||
|
@ -167,6 +168,11 @@ quick_error! {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> clap::App<'static, 'static> {
|
||||
// TODO: migrate to clap to get more shell completions
|
||||
clap::App::new(executable!())
|
||||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let args = args
|
||||
.collect_str(uucore::InvalidEncodingHandling::Ignore)
|
||||
|
|
|
@ -26,23 +26,7 @@ fn get_usage() -> String {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_NULL)
|
||||
.short("0")
|
||||
.long(OPT_NULL)
|
||||
.help("end each output line with 0 byte rather than newline"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_VARIABLES)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.min_values(1),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let variables: Vec<String> = matches
|
||||
.values_of(ARG_VARIABLES)
|
||||
|
@ -69,3 +53,21 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(OPT_NULL)
|
||||
.short("0")
|
||||
.long(OPT_NULL)
|
||||
.help("end each output line with 0 byte rather than newline"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_VARIABLES)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.min_values(1),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ edition = "2018"
|
|||
path = "src/printf.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.3"
|
||||
itertools = "0.8.0"
|
||||
uucore = { version=">=0.0.8", package="uucore", path="../../uucore" }
|
||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||
|
|
|
@ -2,14 +2,18 @@
|
|||
// spell-checker:ignore (change!) each's
|
||||
// spell-checker:ignore (ToDO) LONGHELP FORMATSTRING templating parameterizing formatstr
|
||||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
||||
use clap::{crate_version, App, Arg};
|
||||
use uucore::InvalidEncodingHandling;
|
||||
|
||||
mod cli;
|
||||
mod memo;
|
||||
mod tokenize;
|
||||
|
||||
static NAME: &str = "printf";
|
||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
const VERSION: &str = "version";
|
||||
const HELP: &str = "help";
|
||||
static LONGHELP_LEAD: &str = "printf
|
||||
|
||||
USAGE: printf FORMATSTRING [ARGUMENT]...
|
||||
|
@ -290,10 +294,16 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
if formatstr == "--help" {
|
||||
print!("{} {}", LONGHELP_LEAD, LONGHELP_BODY);
|
||||
} else if formatstr == "--version" {
|
||||
println!("{} {}", NAME, VERSION);
|
||||
println!("{} {}", executable!(), crate_version!());
|
||||
} else {
|
||||
let printf_args = &args[2..];
|
||||
memo::Memo::run_all(formatstr, printf_args);
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.arg(Arg::with_name(VERSION).long(VERSION))
|
||||
.arg(Arg::with_name(HELP).long(HELP))
|
||||
}
|
||||
|
|
|
@ -638,7 +638,28 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.accept_any();
|
||||
|
||||
// let mut opts = Options::new();
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let input_files: Vec<String> = match &matches.values_of(options::FILE) {
|
||||
Some(v) => v.clone().map(|v| v.to_owned()).collect(),
|
||||
None => vec!["-".to_string()],
|
||||
};
|
||||
|
||||
let config = get_config(&matches);
|
||||
let word_filter = WordFilter::new(&matches, &config);
|
||||
let file_map = read_input(&input_files, &config);
|
||||
let word_set = create_word_set(&config, &word_filter, &file_map);
|
||||
let output_file = if !config.gnu_ext && matches.args.len() == 2 {
|
||||
matches.value_of(options::FILE).unwrap_or("-").to_string()
|
||||
} else {
|
||||
"-".to_owned()
|
||||
};
|
||||
write_traditional_output(&config, &file_map, &word_set, &output_file);
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.usage(BRIEF)
|
||||
|
@ -762,22 +783,4 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.value_name("NUMBER")
|
||||
.takes_value(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let input_files: Vec<String> = match &matches.values_of(options::FILE) {
|
||||
Some(v) => v.clone().map(|v| v.to_owned()).collect(),
|
||||
None => vec!["-".to_string()],
|
||||
};
|
||||
|
||||
let config = get_config(&matches);
|
||||
let word_filter = WordFilter::new(&matches, &config);
|
||||
let file_map = read_input(&input_files, &config);
|
||||
let word_set = create_word_set(&config, &word_filter, &file_map);
|
||||
let output_file = if !config.gnu_ext && matches.args.len() == 2 {
|
||||
matches.value_of(options::FILE).unwrap_or("-").to_string()
|
||||
} else {
|
||||
"-".to_owned()
|
||||
};
|
||||
write_traditional_output(&config, &file_map, &word_set, &output_file);
|
||||
0
|
||||
}
|
||||
|
|
|
@ -39,23 +39,7 @@ fn get_usage() -> String {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_LOGICAL)
|
||||
.short("L")
|
||||
.long(OPT_LOGICAL)
|
||||
.help("use PWD from environment, even if it contains symlinks"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_PHYSICAL)
|
||||
.short("P")
|
||||
.long(OPT_PHYSICAL)
|
||||
.help("avoid all symlinks"),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
match env::current_dir() {
|
||||
Ok(logical_path) => {
|
||||
|
@ -73,3 +57,21 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(OPT_LOGICAL)
|
||||
.short("L")
|
||||
.long(OPT_LOGICAL)
|
||||
.help("use PWD from environment, even if it contains symlinks"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_PHYSICAL)
|
||||
.short("P")
|
||||
.long(OPT_PHYSICAL)
|
||||
.help("avoid all symlinks"),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -35,69 +35,7 @@ fn get_usage() -> String {
|
|||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_CANONICALIZE)
|
||||
.short("f")
|
||||
.long(OPT_CANONICALIZE)
|
||||
.help(
|
||||
"canonicalize by following every symlink in every component of the \
|
||||
given name recursively; all but the last component must exist",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_CANONICALIZE_EXISTING)
|
||||
.short("e")
|
||||
.long("canonicalize-existing")
|
||||
.help(
|
||||
"canonicalize by following every symlink in every component of the \
|
||||
given name recursively, all components must exist",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_CANONICALIZE_MISSING)
|
||||
.short("m")
|
||||
.long(OPT_CANONICALIZE_MISSING)
|
||||
.help(
|
||||
"canonicalize by following every symlink in every component of the \
|
||||
given name recursively, without requirements on components existence",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_NO_NEWLINE)
|
||||
.short("n")
|
||||
.long(OPT_NO_NEWLINE)
|
||||
.help("do not output the trailing delimiter"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_QUIET)
|
||||
.short("q")
|
||||
.long(OPT_QUIET)
|
||||
.help("suppress most error messages"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SILENT)
|
||||
.short("s")
|
||||
.long(OPT_SILENT)
|
||||
.help("suppress most error messages"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_VERBOSE)
|
||||
.short("v")
|
||||
.long(OPT_VERBOSE)
|
||||
.help("report error message"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_ZERO)
|
||||
.short("z")
|
||||
.long(OPT_ZERO)
|
||||
.help("separate output with NUL rather than newline"),
|
||||
)
|
||||
.arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let mut no_newline = matches.is_present(OPT_NO_NEWLINE);
|
||||
let use_zero = matches.is_present(OPT_ZERO);
|
||||
|
@ -159,6 +97,70 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(OPT_CANONICALIZE)
|
||||
.short("f")
|
||||
.long(OPT_CANONICALIZE)
|
||||
.help(
|
||||
"canonicalize by following every symlink in every component of the \
|
||||
given name recursively; all but the last component must exist",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_CANONICALIZE_EXISTING)
|
||||
.short("e")
|
||||
.long("canonicalize-existing")
|
||||
.help(
|
||||
"canonicalize by following every symlink in every component of the \
|
||||
given name recursively, all components must exist",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_CANONICALIZE_MISSING)
|
||||
.short("m")
|
||||
.long(OPT_CANONICALIZE_MISSING)
|
||||
.help(
|
||||
"canonicalize by following every symlink in every component of the \
|
||||
given name recursively, without requirements on components existence",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_NO_NEWLINE)
|
||||
.short("n")
|
||||
.long(OPT_NO_NEWLINE)
|
||||
.help("do not output the trailing delimiter"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_QUIET)
|
||||
.short("q")
|
||||
.long(OPT_QUIET)
|
||||
.help("suppress most error messages"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SILENT)
|
||||
.short("s")
|
||||
.long(OPT_SILENT)
|
||||
.help("suppress most error messages"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_VERBOSE)
|
||||
.short("v")
|
||||
.long(OPT_VERBOSE)
|
||||
.help("report error message"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_ZERO)
|
||||
.short("z")
|
||||
.long(OPT_ZERO)
|
||||
.help("separate output with NUL rather than newline"),
|
||||
)
|
||||
.arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true))
|
||||
}
|
||||
|
||||
fn show(path: &Path, no_newline: bool, use_zero: bool) {
|
||||
let path = path.to_str().unwrap();
|
||||
if use_zero {
|
||||
|
|
|
@ -29,10 +29,35 @@ fn get_usage() -> String {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
/* the list of files */
|
||||
|
||||
let paths: Vec<PathBuf> = matches
|
||||
.values_of(ARG_FILES)
|
||||
.unwrap()
|
||||
.map(PathBuf::from)
|
||||
.collect();
|
||||
|
||||
let strip = matches.is_present(OPT_STRIP);
|
||||
let zero = matches.is_present(OPT_ZERO);
|
||||
let quiet = matches.is_present(OPT_QUIET);
|
||||
let mut retcode = 0;
|
||||
for path in &paths {
|
||||
if let Err(e) = resolve_path(path, strip, zero) {
|
||||
if !quiet {
|
||||
show_error!("{}: {}", e, path.display());
|
||||
}
|
||||
retcode = 1
|
||||
};
|
||||
}
|
||||
retcode
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_QUIET)
|
||||
.short("q")
|
||||
|
@ -58,29 +83,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.required(true)
|
||||
.min_values(1),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
/* the list of files */
|
||||
|
||||
let paths: Vec<PathBuf> = matches
|
||||
.values_of(ARG_FILES)
|
||||
.unwrap()
|
||||
.map(PathBuf::from)
|
||||
.collect();
|
||||
|
||||
let strip = matches.is_present(OPT_STRIP);
|
||||
let zero = matches.is_present(OPT_ZERO);
|
||||
let quiet = matches.is_present(OPT_QUIET);
|
||||
let mut retcode = 0;
|
||||
for path in &paths {
|
||||
if let Err(e) = resolve_path(path, strip, zero) {
|
||||
if !quiet {
|
||||
show_error!("{}: {}", e, path.display());
|
||||
}
|
||||
retcode = 1
|
||||
};
|
||||
}
|
||||
retcode
|
||||
}
|
||||
|
||||
/// Resolve a path to an absolute form and print it.
|
||||
|
|
|
@ -35,26 +35,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.accept_any();
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::DIR)
|
||||
.short("d")
|
||||
.takes_value(true)
|
||||
.help("If any of FROM and TO is not subpath of DIR, output absolute path instead of relative"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TO)
|
||||
.required(true)
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FROM)
|
||||
.takes_value(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let to = Path::new(matches.value_of(options::TO).unwrap()).to_path_buf(); // required
|
||||
let from = match matches.value_of(options::FROM) {
|
||||
|
@ -99,3 +80,24 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
println!("{}", result.display());
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::DIR)
|
||||
.short("d")
|
||||
.takes_value(true)
|
||||
.help("If any of FROM and TO is not subpath of DIR, output absolute path instead of relative"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TO)
|
||||
.required(true)
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FROM)
|
||||
.takes_value(true),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -77,11 +77,72 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let usage = get_usage();
|
||||
let long_usage = get_long_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
let matches = uu_app()
|
||||
.usage(&usage[..])
|
||||
.after_help(&long_usage[..])
|
||||
.get_matches_from(args);
|
||||
|
||||
let files: Vec<String> = matches
|
||||
.values_of(ARG_FILES)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let force = matches.is_present(OPT_FORCE);
|
||||
|
||||
if files.is_empty() && !force {
|
||||
// Still check by hand and not use clap
|
||||
// Because "rm -f" is a thing
|
||||
show_error!("missing an argument");
|
||||
show_error!("for help, try '{0} --help'", executable!());
|
||||
return 1;
|
||||
} else {
|
||||
let options = Options {
|
||||
force,
|
||||
interactive: {
|
||||
if matches.is_present(OPT_PROMPT) {
|
||||
InteractiveMode::Always
|
||||
} else if matches.is_present(OPT_PROMPT_MORE) {
|
||||
InteractiveMode::Once
|
||||
} else if matches.is_present(OPT_INTERACTIVE) {
|
||||
match matches.value_of(OPT_INTERACTIVE).unwrap() {
|
||||
"none" => InteractiveMode::None,
|
||||
"once" => InteractiveMode::Once,
|
||||
"always" => InteractiveMode::Always,
|
||||
val => crash!(1, "Invalid argument to interactive ({})", val),
|
||||
}
|
||||
} else {
|
||||
InteractiveMode::None
|
||||
}
|
||||
},
|
||||
one_fs: matches.is_present(OPT_ONE_FILE_SYSTEM),
|
||||
preserve_root: !matches.is_present(OPT_NO_PRESERVE_ROOT),
|
||||
recursive: matches.is_present(OPT_RECURSIVE) || matches.is_present(OPT_RECURSIVE_R),
|
||||
dir: matches.is_present(OPT_DIR),
|
||||
verbose: matches.is_present(OPT_VERBOSE),
|
||||
};
|
||||
if options.interactive == InteractiveMode::Once && (options.recursive || files.len() > 3) {
|
||||
let msg = if options.recursive {
|
||||
"Remove all arguments recursively? "
|
||||
} else {
|
||||
"Remove all arguments? "
|
||||
};
|
||||
if !prompt(msg) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if remove(files, options) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
|
||||
.arg(
|
||||
Arg::with_name(OPT_FORCE)
|
||||
|
@ -151,63 +212,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.takes_value(true)
|
||||
.min_values(1)
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let files: Vec<String> = matches
|
||||
.values_of(ARG_FILES)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let force = matches.is_present(OPT_FORCE);
|
||||
|
||||
if files.is_empty() && !force {
|
||||
// Still check by hand and not use clap
|
||||
// Because "rm -f" is a thing
|
||||
show_error!("missing an argument");
|
||||
show_error!("for help, try '{0} --help'", executable!());
|
||||
return 1;
|
||||
} else {
|
||||
let options = Options {
|
||||
force,
|
||||
interactive: {
|
||||
if matches.is_present(OPT_PROMPT) {
|
||||
InteractiveMode::Always
|
||||
} else if matches.is_present(OPT_PROMPT_MORE) {
|
||||
InteractiveMode::Once
|
||||
} else if matches.is_present(OPT_INTERACTIVE) {
|
||||
match matches.value_of(OPT_INTERACTIVE).unwrap() {
|
||||
"none" => InteractiveMode::None,
|
||||
"once" => InteractiveMode::Once,
|
||||
"always" => InteractiveMode::Always,
|
||||
val => crash!(1, "Invalid argument to interactive ({})", val),
|
||||
}
|
||||
} else {
|
||||
InteractiveMode::None
|
||||
}
|
||||
},
|
||||
one_fs: matches.is_present(OPT_ONE_FILE_SYSTEM),
|
||||
preserve_root: !matches.is_present(OPT_NO_PRESERVE_ROOT),
|
||||
recursive: matches.is_present(OPT_RECURSIVE) || matches.is_present(OPT_RECURSIVE_R),
|
||||
dir: matches.is_present(OPT_DIR),
|
||||
verbose: matches.is_present(OPT_VERBOSE),
|
||||
};
|
||||
if options.interactive == InteractiveMode::Once && (options.recursive || files.len() > 3) {
|
||||
let msg = if options.recursive {
|
||||
"Remove all arguments recursively? "
|
||||
} else {
|
||||
"Remove all arguments? "
|
||||
};
|
||||
if !prompt(msg) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if remove(files, options) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
// TODO: implement one-file-system (this may get partially implemented in walkdir)
|
||||
|
|
|
@ -33,10 +33,29 @@ fn get_usage() -> String {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let dirs: Vec<String> = matches
|
||||
.values_of(ARG_DIRS)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let ignore = matches.is_present(OPT_IGNORE_FAIL_NON_EMPTY);
|
||||
let parents = matches.is_present(OPT_PARENTS);
|
||||
let verbose = matches.is_present(OPT_VERBOSE);
|
||||
|
||||
match remove(dirs, ignore, parents, verbose) {
|
||||
Ok(()) => ( /* pass */ ),
|
||||
Err(e) => return e,
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_IGNORE_FAIL_NON_EMPTY)
|
||||
.long(OPT_IGNORE_FAIL_NON_EMPTY)
|
||||
|
@ -64,23 +83,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.min_values(1)
|
||||
.required(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let dirs: Vec<String> = matches
|
||||
.values_of(ARG_DIRS)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let ignore = matches.is_present(OPT_IGNORE_FAIL_NON_EMPTY);
|
||||
let parents = matches.is_present(OPT_PARENTS);
|
||||
let verbose = matches.is_present(OPT_VERBOSE);
|
||||
|
||||
match remove(dirs, ignore, parents, verbose) {
|
||||
Ok(()) => ( /* pass */ ),
|
||||
Err(e) => return e,
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
fn remove(dirs: Vec<String>, ignore: bool, parents: bool, verbose: bool) -> Result<(), i32> {
|
||||
|
|
|
@ -87,42 +87,7 @@ impl FromStr for Number {
|
|||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let matches = App::new(executable!())
|
||||
.setting(AppSettings::AllowLeadingHyphen)
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(OPT_SEPARATOR)
|
||||
.short("s")
|
||||
.long("separator")
|
||||
.help("Separator character (defaults to \\n)")
|
||||
.takes_value(true)
|
||||
.number_of_values(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_TERMINATOR)
|
||||
.short("t")
|
||||
.long("terminator")
|
||||
.help("Terminator character (defaults to \\n)")
|
||||
.takes_value(true)
|
||||
.number_of_values(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_WIDTHS)
|
||||
.short("w")
|
||||
.long("widths")
|
||||
.help("Equalize widths of all numbers by padding with zeros"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_NUMBERS)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.max_values(3)
|
||||
.required(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let numbers = matches.values_of(ARG_NUMBERS).unwrap().collect::<Vec<_>>();
|
||||
|
||||
|
@ -197,6 +162,43 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.setting(AppSettings::AllowLeadingHyphen)
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SEPARATOR)
|
||||
.short("s")
|
||||
.long("separator")
|
||||
.help("Separator character (defaults to \\n)")
|
||||
.takes_value(true)
|
||||
.number_of_values(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_TERMINATOR)
|
||||
.short("t")
|
||||
.long("terminator")
|
||||
.help("Terminator character (defaults to \\n)")
|
||||
.takes_value(true)
|
||||
.number_of_values(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_WIDTHS)
|
||||
.short("w")
|
||||
.long("widths")
|
||||
.help("Equalize widths of all numbers by padding with zeros"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_NUMBERS)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.max_values(3)
|
||||
.required(true),
|
||||
)
|
||||
}
|
||||
|
||||
fn done_printing<T: Num + PartialOrd>(next: &T, increment: &T, last: &T) -> bool {
|
||||
if increment >= &T::zero() {
|
||||
next > last
|
||||
|
|
|
@ -272,62 +272,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
let usage = get_usage();
|
||||
|
||||
let app = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.after_help(AFTER_HELP)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::FORCE)
|
||||
.long(options::FORCE)
|
||||
.short("f")
|
||||
.help("change permissions to allow writing if necessary"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ITERATIONS)
|
||||
.long(options::ITERATIONS)
|
||||
.short("n")
|
||||
.help("overwrite N times instead of the default (3)")
|
||||
.value_name("NUMBER")
|
||||
.default_value("3"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SIZE)
|
||||
.long(options::SIZE)
|
||||
.short("s")
|
||||
.takes_value(true)
|
||||
.value_name("N")
|
||||
.help("shred this many bytes (suffixes like K, M, G accepted)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::REMOVE)
|
||||
.short("u")
|
||||
.long(options::REMOVE)
|
||||
.help("truncate and remove file after overwriting; See below"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::VERBOSE)
|
||||
.long(options::VERBOSE)
|
||||
.short("v")
|
||||
.help("show progress"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::EXACT)
|
||||
.long(options::EXACT)
|
||||
.short("x")
|
||||
.help(
|
||||
"do not round file sizes up to the next full block;\n\
|
||||
this is the default for non-regular files",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ZERO)
|
||||
.long(options::ZERO)
|
||||
.short("z")
|
||||
.help("add a final overwrite with zeros to hide shredding"),
|
||||
)
|
||||
// Positional arguments
|
||||
.arg(Arg::with_name(options::FILE).hidden(true).multiple(true));
|
||||
let app = uu_app().usage(&usage[..]);
|
||||
|
||||
let matches = app.get_matches_from(args);
|
||||
|
||||
|
@ -384,6 +329,64 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.after_help(AFTER_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::FORCE)
|
||||
.long(options::FORCE)
|
||||
.short("f")
|
||||
.help("change permissions to allow writing if necessary"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ITERATIONS)
|
||||
.long(options::ITERATIONS)
|
||||
.short("n")
|
||||
.help("overwrite N times instead of the default (3)")
|
||||
.value_name("NUMBER")
|
||||
.default_value("3"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SIZE)
|
||||
.long(options::SIZE)
|
||||
.short("s")
|
||||
.takes_value(true)
|
||||
.value_name("N")
|
||||
.help("shred this many bytes (suffixes like K, M, G accepted)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::REMOVE)
|
||||
.short("u")
|
||||
.long(options::REMOVE)
|
||||
.help("truncate and remove file after overwriting; See below"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::VERBOSE)
|
||||
.long(options::VERBOSE)
|
||||
.short("v")
|
||||
.help("show progress"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::EXACT)
|
||||
.long(options::EXACT)
|
||||
.short("x")
|
||||
.help(
|
||||
"do not round file sizes up to the next full block;\n\
|
||||
this is the default for non-regular files",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ZERO)
|
||||
.long(options::ZERO)
|
||||
.short("z")
|
||||
.help("add a final overwrite with zeros to hide shredding"),
|
||||
)
|
||||
// Positional arguments
|
||||
.arg(Arg::with_name(options::FILE).hidden(true).multiple(true))
|
||||
}
|
||||
|
||||
// TODO: Add support for all postfixes here up to and including EiB
|
||||
// http://www.gnu.org/software/coreutils/manual/coreutils.html#Block-size
|
||||
fn get_size(size_str_opt: Option<String>) -> Option<u64> {
|
||||
|
|
|
@ -56,7 +56,66 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let mode = if let Some(args) = matches.values_of(options::ECHO) {
|
||||
Mode::Echo(args.map(String::from).collect())
|
||||
} else if let Some(range) = matches.value_of(options::INPUT_RANGE) {
|
||||
match parse_range(range) {
|
||||
Ok(m) => Mode::InputRange(m),
|
||||
Err(msg) => {
|
||||
crash!(1, "{}", msg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Mode::Default(matches.value_of(options::FILE).unwrap_or("-").to_string())
|
||||
};
|
||||
|
||||
let options = Options {
|
||||
head_count: match matches.value_of(options::HEAD_COUNT) {
|
||||
Some(count) => match count.parse::<usize>() {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
show_error!("invalid line count: '{}'", count);
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
None => std::usize::MAX,
|
||||
},
|
||||
output: matches.value_of(options::OUTPUT).map(String::from),
|
||||
random_source: matches.value_of(options::RANDOM_SOURCE).map(String::from),
|
||||
repeat: matches.is_present(options::REPEAT),
|
||||
sep: if matches.is_present(options::ZERO_TERMINATED) {
|
||||
0x00_u8
|
||||
} else {
|
||||
0x0a_u8
|
||||
},
|
||||
};
|
||||
|
||||
match mode {
|
||||
Mode::Echo(args) => {
|
||||
let mut evec = args.iter().map(String::as_bytes).collect::<Vec<_>>();
|
||||
find_seps(&mut evec, options.sep);
|
||||
shuf_bytes(&mut evec, options);
|
||||
}
|
||||
Mode::InputRange((b, e)) => {
|
||||
let rvec = (b..e).map(|x| format!("{}", x)).collect::<Vec<String>>();
|
||||
let mut rvec = rvec.iter().map(String::as_bytes).collect::<Vec<&[u8]>>();
|
||||
shuf_bytes(&mut rvec, options);
|
||||
}
|
||||
Mode::Default(filename) => {
|
||||
let fdata = read_input_file(&filename);
|
||||
let mut fdata = vec![&fdata[..]];
|
||||
find_seps(&mut fdata, options.sep);
|
||||
shuf_bytes(&mut fdata, options);
|
||||
}
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.template(TEMPLATE)
|
||||
|
@ -118,62 +177,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.help("line delimiter is NUL, not newline"),
|
||||
)
|
||||
.arg(Arg::with_name(options::FILE).takes_value(true))
|
||||
.get_matches_from(args);
|
||||
|
||||
let mode = if let Some(args) = matches.values_of(options::ECHO) {
|
||||
Mode::Echo(args.map(String::from).collect())
|
||||
} else if let Some(range) = matches.value_of(options::INPUT_RANGE) {
|
||||
match parse_range(range) {
|
||||
Ok(m) => Mode::InputRange(m),
|
||||
Err(msg) => {
|
||||
crash!(1, "{}", msg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Mode::Default(matches.value_of(options::FILE).unwrap_or("-").to_string())
|
||||
};
|
||||
|
||||
let options = Options {
|
||||
head_count: match matches.value_of(options::HEAD_COUNT) {
|
||||
Some(count) => match count.parse::<usize>() {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
show_error!("invalid line count: '{}'", count);
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
None => std::usize::MAX,
|
||||
},
|
||||
output: matches.value_of(options::OUTPUT).map(String::from),
|
||||
random_source: matches.value_of(options::RANDOM_SOURCE).map(String::from),
|
||||
repeat: matches.is_present(options::REPEAT),
|
||||
sep: if matches.is_present(options::ZERO_TERMINATED) {
|
||||
0x00_u8
|
||||
} else {
|
||||
0x0a_u8
|
||||
},
|
||||
};
|
||||
|
||||
match mode {
|
||||
Mode::Echo(args) => {
|
||||
let mut evec = args.iter().map(String::as_bytes).collect::<Vec<_>>();
|
||||
find_seps(&mut evec, options.sep);
|
||||
shuf_bytes(&mut evec, options);
|
||||
}
|
||||
Mode::InputRange((b, e)) => {
|
||||
let rvec = (b..e).map(|x| format!("{}", x)).collect::<Vec<String>>();
|
||||
let mut rvec = rvec.iter().map(String::as_bytes).collect::<Vec<&[u8]>>();
|
||||
shuf_bytes(&mut rvec, options);
|
||||
}
|
||||
Mode::Default(filename) => {
|
||||
let fdata = read_input_file(&filename);
|
||||
let mut fdata = vec![&fdata[..]];
|
||||
find_seps(&mut fdata, options.sep);
|
||||
shuf_bytes(&mut fdata, options);
|
||||
}
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
fn read_input_file(filename: &str) -> Vec<u8> {
|
||||
|
|
|
@ -35,10 +35,20 @@ fn get_usage() -> String {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
if let Some(values) = matches.values_of(options::NUMBER) {
|
||||
let numbers = values.collect();
|
||||
sleep(numbers);
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.after_help(LONG_HELP)
|
||||
.arg(
|
||||
Arg::with_name(options::NUMBER)
|
||||
|
@ -49,14 +59,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.multiple(true)
|
||||
.required(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
if let Some(values) = matches.values_of(options::NUMBER) {
|
||||
let numbers = values.collect();
|
||||
sleep(numbers);
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
fn sleep(args: Vec<&str>) {
|
||||
|
|
|
@ -944,10 +944,170 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let usage = get_usage();
|
||||
let mut settings: GlobalSettings = Default::default();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
settings.debug = matches.is_present(options::DEBUG);
|
||||
|
||||
// check whether user specified a zero terminated list of files for input, otherwise read files from args
|
||||
let mut files: Vec<String> = if matches.is_present(options::FILES0_FROM) {
|
||||
let files0_from: Vec<String> = matches
|
||||
.values_of(options::FILES0_FROM)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut files = Vec::new();
|
||||
for path in &files0_from {
|
||||
let reader = open(path.as_str());
|
||||
let buf_reader = BufReader::new(reader);
|
||||
for line in buf_reader.split(b'\0').flatten() {
|
||||
files.push(
|
||||
std::str::from_utf8(&line)
|
||||
.expect("Could not parse string from zero terminated input.")
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
files
|
||||
} else {
|
||||
matches
|
||||
.values_of(options::FILES)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default()
|
||||
};
|
||||
|
||||
settings.mode = if matches.is_present(options::modes::HUMAN_NUMERIC)
|
||||
|| matches.value_of(options::modes::SORT) == Some("human-numeric")
|
||||
{
|
||||
SortMode::HumanNumeric
|
||||
} else if matches.is_present(options::modes::MONTH)
|
||||
|| matches.value_of(options::modes::SORT) == Some("month")
|
||||
{
|
||||
SortMode::Month
|
||||
} else if matches.is_present(options::modes::GENERAL_NUMERIC)
|
||||
|| matches.value_of(options::modes::SORT) == Some("general-numeric")
|
||||
{
|
||||
SortMode::GeneralNumeric
|
||||
} else if matches.is_present(options::modes::NUMERIC)
|
||||
|| matches.value_of(options::modes::SORT) == Some("numeric")
|
||||
{
|
||||
SortMode::Numeric
|
||||
} else if matches.is_present(options::modes::VERSION)
|
||||
|| matches.value_of(options::modes::SORT) == Some("version")
|
||||
{
|
||||
SortMode::Version
|
||||
} else if matches.is_present(options::modes::RANDOM)
|
||||
|| matches.value_of(options::modes::SORT) == Some("random")
|
||||
{
|
||||
settings.salt = get_rand_string();
|
||||
SortMode::Random
|
||||
} else {
|
||||
SortMode::Default
|
||||
};
|
||||
|
||||
settings.dictionary_order = matches.is_present(options::DICTIONARY_ORDER);
|
||||
settings.ignore_non_printing = matches.is_present(options::IGNORE_NONPRINTING);
|
||||
if matches.is_present(options::PARALLEL) {
|
||||
// "0" is default - threads = num of cores
|
||||
settings.threads = matches
|
||||
.value_of(options::PARALLEL)
|
||||
.map(String::from)
|
||||
.unwrap_or_else(|| "0".to_string());
|
||||
env::set_var("RAYON_NUM_THREADS", &settings.threads);
|
||||
}
|
||||
|
||||
settings.buffer_size = matches
|
||||
.value_of(options::BUF_SIZE)
|
||||
.map_or(DEFAULT_BUF_SIZE, |s| {
|
||||
GlobalSettings::parse_byte_count(s)
|
||||
.unwrap_or_else(|e| crash!(2, "{}", format_error_message(e, s, options::BUF_SIZE)))
|
||||
});
|
||||
|
||||
settings.tmp_dir = matches
|
||||
.value_of(options::TMP_DIR)
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(env::temp_dir);
|
||||
|
||||
settings.compress_prog = matches.value_of(options::COMPRESS_PROG).map(String::from);
|
||||
|
||||
if let Some(n_merge) = matches.value_of(options::BATCH_SIZE) {
|
||||
settings.merge_batch_size = n_merge
|
||||
.parse()
|
||||
.unwrap_or_else(|_| crash!(2, "invalid --batch-size argument '{}'", n_merge));
|
||||
}
|
||||
|
||||
settings.zero_terminated = matches.is_present(options::ZERO_TERMINATED);
|
||||
settings.merge = matches.is_present(options::MERGE);
|
||||
|
||||
settings.check = matches.is_present(options::check::CHECK);
|
||||
if matches.is_present(options::check::CHECK_SILENT)
|
||||
|| matches!(
|
||||
matches.value_of(options::check::CHECK),
|
||||
Some(options::check::SILENT) | Some(options::check::QUIET)
|
||||
)
|
||||
{
|
||||
settings.check_silent = true;
|
||||
settings.check = true;
|
||||
};
|
||||
|
||||
settings.ignore_case = matches.is_present(options::IGNORE_CASE);
|
||||
|
||||
settings.ignore_leading_blanks = matches.is_present(options::IGNORE_LEADING_BLANKS);
|
||||
|
||||
settings.output_file = matches.value_of(options::OUTPUT).map(String::from);
|
||||
settings.reverse = matches.is_present(options::REVERSE);
|
||||
settings.stable = matches.is_present(options::STABLE);
|
||||
settings.unique = matches.is_present(options::UNIQUE);
|
||||
|
||||
if files.is_empty() {
|
||||
/* if no file, default to stdin */
|
||||
files.push("-".to_owned());
|
||||
} else if settings.check && files.len() != 1 {
|
||||
crash!(1, "extra operand `{}' not allowed with -c", files[1])
|
||||
}
|
||||
|
||||
if let Some(arg) = matches.args.get(options::SEPARATOR) {
|
||||
let separator = arg.vals[0].to_string_lossy();
|
||||
let separator = separator;
|
||||
if separator.len() != 1 {
|
||||
crash!(1, "separator must be exactly one character long");
|
||||
}
|
||||
settings.separator = Some(separator.chars().next().unwrap())
|
||||
}
|
||||
|
||||
if let Some(values) = matches.values_of(options::KEY) {
|
||||
for value in values {
|
||||
settings
|
||||
.selectors
|
||||
.push(FieldSelector::parse(value, &settings));
|
||||
}
|
||||
}
|
||||
|
||||
if !matches.is_present(options::KEY) {
|
||||
// add a default selector matching the whole line
|
||||
let key_settings = KeySettings::from(&settings);
|
||||
settings.selectors.push(
|
||||
FieldSelector::new(
|
||||
KeyPosition {
|
||||
field: 1,
|
||||
char: 1,
|
||||
ignore_blanks: key_settings.ignore_blanks,
|
||||
},
|
||||
None,
|
||||
key_settings,
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
settings.init_precomputed();
|
||||
|
||||
exec(&files, &settings)
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::modes::SORT)
|
||||
.long(options::modes::SORT)
|
||||
|
@ -1169,164 +1329,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.help("underline the parts of the line that are actually used for sorting"),
|
||||
)
|
||||
.arg(Arg::with_name(options::FILES).multiple(true).takes_value(true))
|
||||
.get_matches_from(args);
|
||||
|
||||
settings.debug = matches.is_present(options::DEBUG);
|
||||
|
||||
// check whether user specified a zero terminated list of files for input, otherwise read files from args
|
||||
let mut files: Vec<String> = if matches.is_present(options::FILES0_FROM) {
|
||||
let files0_from: Vec<String> = matches
|
||||
.values_of(options::FILES0_FROM)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut files = Vec::new();
|
||||
for path in &files0_from {
|
||||
let reader = open(path.as_str());
|
||||
let buf_reader = BufReader::new(reader);
|
||||
for line in buf_reader.split(b'\0').flatten() {
|
||||
files.push(
|
||||
std::str::from_utf8(&line)
|
||||
.expect("Could not parse string from zero terminated input.")
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
files
|
||||
} else {
|
||||
matches
|
||||
.values_of(options::FILES)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default()
|
||||
};
|
||||
|
||||
settings.mode = if matches.is_present(options::modes::HUMAN_NUMERIC)
|
||||
|| matches.value_of(options::modes::SORT) == Some("human-numeric")
|
||||
{
|
||||
SortMode::HumanNumeric
|
||||
} else if matches.is_present(options::modes::MONTH)
|
||||
|| matches.value_of(options::modes::SORT) == Some("month")
|
||||
{
|
||||
SortMode::Month
|
||||
} else if matches.is_present(options::modes::GENERAL_NUMERIC)
|
||||
|| matches.value_of(options::modes::SORT) == Some("general-numeric")
|
||||
{
|
||||
SortMode::GeneralNumeric
|
||||
} else if matches.is_present(options::modes::NUMERIC)
|
||||
|| matches.value_of(options::modes::SORT) == Some("numeric")
|
||||
{
|
||||
SortMode::Numeric
|
||||
} else if matches.is_present(options::modes::VERSION)
|
||||
|| matches.value_of(options::modes::SORT) == Some("version")
|
||||
{
|
||||
SortMode::Version
|
||||
} else if matches.is_present(options::modes::RANDOM)
|
||||
|| matches.value_of(options::modes::SORT) == Some("random")
|
||||
{
|
||||
settings.salt = get_rand_string();
|
||||
SortMode::Random
|
||||
} else {
|
||||
SortMode::Default
|
||||
};
|
||||
|
||||
settings.dictionary_order = matches.is_present(options::DICTIONARY_ORDER);
|
||||
settings.ignore_non_printing = matches.is_present(options::IGNORE_NONPRINTING);
|
||||
if matches.is_present(options::PARALLEL) {
|
||||
// "0" is default - threads = num of cores
|
||||
settings.threads = matches
|
||||
.value_of(options::PARALLEL)
|
||||
.map(String::from)
|
||||
.unwrap_or_else(|| "0".to_string());
|
||||
env::set_var("RAYON_NUM_THREADS", &settings.threads);
|
||||
}
|
||||
|
||||
settings.buffer_size = matches
|
||||
.value_of(options::BUF_SIZE)
|
||||
.map_or(DEFAULT_BUF_SIZE, |s| {
|
||||
GlobalSettings::parse_byte_count(s)
|
||||
.unwrap_or_else(|e| crash!(2, "{}", format_error_message(e, s, options::BUF_SIZE)))
|
||||
});
|
||||
|
||||
settings.tmp_dir = matches
|
||||
.value_of(options::TMP_DIR)
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(env::temp_dir);
|
||||
|
||||
settings.compress_prog = matches.value_of(options::COMPRESS_PROG).map(String::from);
|
||||
|
||||
if let Some(n_merge) = matches.value_of(options::BATCH_SIZE) {
|
||||
settings.merge_batch_size = n_merge
|
||||
.parse()
|
||||
.unwrap_or_else(|_| crash!(2, "invalid --batch-size argument '{}'", n_merge));
|
||||
}
|
||||
|
||||
settings.zero_terminated = matches.is_present(options::ZERO_TERMINATED);
|
||||
settings.merge = matches.is_present(options::MERGE);
|
||||
|
||||
settings.check = matches.is_present(options::check::CHECK);
|
||||
if matches.is_present(options::check::CHECK_SILENT)
|
||||
|| matches!(
|
||||
matches.value_of(options::check::CHECK),
|
||||
Some(options::check::SILENT) | Some(options::check::QUIET)
|
||||
)
|
||||
{
|
||||
settings.check_silent = true;
|
||||
settings.check = true;
|
||||
};
|
||||
|
||||
settings.ignore_case = matches.is_present(options::IGNORE_CASE);
|
||||
|
||||
settings.ignore_leading_blanks = matches.is_present(options::IGNORE_LEADING_BLANKS);
|
||||
|
||||
settings.output_file = matches.value_of(options::OUTPUT).map(String::from);
|
||||
settings.reverse = matches.is_present(options::REVERSE);
|
||||
settings.stable = matches.is_present(options::STABLE);
|
||||
settings.unique = matches.is_present(options::UNIQUE);
|
||||
|
||||
if files.is_empty() {
|
||||
/* if no file, default to stdin */
|
||||
files.push("-".to_owned());
|
||||
} else if settings.check && files.len() != 1 {
|
||||
crash!(1, "extra operand `{}' not allowed with -c", files[1])
|
||||
}
|
||||
|
||||
if let Some(arg) = matches.args.get(options::SEPARATOR) {
|
||||
let separator = arg.vals[0].to_string_lossy();
|
||||
let separator = separator;
|
||||
if separator.len() != 1 {
|
||||
crash!(1, "separator must be exactly one character long");
|
||||
}
|
||||
settings.separator = Some(separator.chars().next().unwrap())
|
||||
}
|
||||
|
||||
if let Some(values) = matches.values_of(options::KEY) {
|
||||
for value in values {
|
||||
settings
|
||||
.selectors
|
||||
.push(FieldSelector::parse(value, &settings));
|
||||
}
|
||||
}
|
||||
|
||||
if !matches.is_present(options::KEY) {
|
||||
// add a default selector matching the whole line
|
||||
let key_settings = KeySettings::from(&settings);
|
||||
settings.selectors.push(
|
||||
FieldSelector::new(
|
||||
KeyPosition {
|
||||
field: 1,
|
||||
char: 1,
|
||||
ignore_blanks: key_settings.ignore_blanks,
|
||||
},
|
||||
None,
|
||||
key_settings,
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
settings.init_precomputed();
|
||||
|
||||
exec(&files, &settings)
|
||||
}
|
||||
|
||||
fn exec(files: &[String], settings: &GlobalSettings) -> i32 {
|
||||
|
|
|
@ -30,7 +30,7 @@ static OPT_ADDITIONAL_SUFFIX: &str = "additional-suffix";
|
|||
static OPT_FILTER: &str = "filter";
|
||||
static OPT_NUMERIC_SUFFIXES: &str = "numeric-suffixes";
|
||||
static OPT_SUFFIX_LENGTH: &str = "suffix-length";
|
||||
static OPT_DEFAULT_SUFFIX_LENGTH: usize = 2;
|
||||
static OPT_DEFAULT_SUFFIX_LENGTH: &str = "2";
|
||||
static OPT_VERBOSE: &str = "verbose";
|
||||
|
||||
static ARG_INPUT: &str = "input";
|
||||
|
@ -54,85 +54,10 @@ size is 1000, and default PREFIX is 'x'. With no INPUT, or when INPUT is
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let long_usage = get_long_usage();
|
||||
let default_suffix_length_str = OPT_DEFAULT_SUFFIX_LENGTH.to_string();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about("Create output files containing consecutive or interleaved sections of input")
|
||||
let matches = uu_app()
|
||||
.usage(&usage[..])
|
||||
.after_help(&long_usage[..])
|
||||
// strategy (mutually exclusive)
|
||||
.arg(
|
||||
Arg::with_name(OPT_BYTES)
|
||||
.short("b")
|
||||
.long(OPT_BYTES)
|
||||
.takes_value(true)
|
||||
.default_value("2")
|
||||
.help("use suffixes of length N (default 2)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_LINE_BYTES)
|
||||
.short("C")
|
||||
.long(OPT_LINE_BYTES)
|
||||
.takes_value(true)
|
||||
.default_value("2")
|
||||
.help("put at most SIZE bytes of lines per output file"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_LINES)
|
||||
.short("l")
|
||||
.long(OPT_LINES)
|
||||
.takes_value(true)
|
||||
.default_value("1000")
|
||||
.help("write to shell COMMAND file name is $FILE (Currently not implemented for Windows)"),
|
||||
)
|
||||
// rest of the arguments
|
||||
.arg(
|
||||
Arg::with_name(OPT_ADDITIONAL_SUFFIX)
|
||||
.long(OPT_ADDITIONAL_SUFFIX)
|
||||
.takes_value(true)
|
||||
.default_value("")
|
||||
.help("additional suffix to append to output file names"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_FILTER)
|
||||
.long(OPT_FILTER)
|
||||
.takes_value(true)
|
||||
.help("write to shell COMMAND file name is $FILE (Currently not implemented for Windows)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_NUMERIC_SUFFIXES)
|
||||
.short("d")
|
||||
.long(OPT_NUMERIC_SUFFIXES)
|
||||
.takes_value(true)
|
||||
.default_value("0")
|
||||
.help("use numeric suffixes instead of alphabetic"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SUFFIX_LENGTH)
|
||||
.short("a")
|
||||
.long(OPT_SUFFIX_LENGTH)
|
||||
.takes_value(true)
|
||||
.default_value(default_suffix_length_str.as_str())
|
||||
.help("use suffixes of length N (default 2)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_VERBOSE)
|
||||
.long(OPT_VERBOSE)
|
||||
.help("print a diagnostic just before each output file is opened"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_INPUT)
|
||||
.takes_value(true)
|
||||
.default_value("-")
|
||||
.index(1)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_PREFIX)
|
||||
.takes_value(true)
|
||||
.default_value("x")
|
||||
.index(2)
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let mut settings = Settings {
|
||||
|
@ -201,6 +126,84 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
split(&settings)
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about("Create output files containing consecutive or interleaved sections of input")
|
||||
// strategy (mutually exclusive)
|
||||
.arg(
|
||||
Arg::with_name(OPT_BYTES)
|
||||
.short("b")
|
||||
.long(OPT_BYTES)
|
||||
.takes_value(true)
|
||||
.default_value("2")
|
||||
.help("use suffixes of length N (default 2)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_LINE_BYTES)
|
||||
.short("C")
|
||||
.long(OPT_LINE_BYTES)
|
||||
.takes_value(true)
|
||||
.default_value("2")
|
||||
.help("put at most SIZE bytes of lines per output file"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_LINES)
|
||||
.short("l")
|
||||
.long(OPT_LINES)
|
||||
.takes_value(true)
|
||||
.default_value("1000")
|
||||
.help("write to shell COMMAND file name is $FILE (Currently not implemented for Windows)"),
|
||||
)
|
||||
// rest of the arguments
|
||||
.arg(
|
||||
Arg::with_name(OPT_ADDITIONAL_SUFFIX)
|
||||
.long(OPT_ADDITIONAL_SUFFIX)
|
||||
.takes_value(true)
|
||||
.default_value("")
|
||||
.help("additional suffix to append to output file names"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_FILTER)
|
||||
.long(OPT_FILTER)
|
||||
.takes_value(true)
|
||||
.help("write to shell COMMAND file name is $FILE (Currently not implemented for Windows)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_NUMERIC_SUFFIXES)
|
||||
.short("d")
|
||||
.long(OPT_NUMERIC_SUFFIXES)
|
||||
.takes_value(true)
|
||||
.default_value("0")
|
||||
.help("use numeric suffixes instead of alphabetic"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_SUFFIX_LENGTH)
|
||||
.short("a")
|
||||
.long(OPT_SUFFIX_LENGTH)
|
||||
.takes_value(true)
|
||||
.default_value(OPT_DEFAULT_SUFFIX_LENGTH)
|
||||
.help("use suffixes of length N (default 2)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(OPT_VERBOSE)
|
||||
.long(OPT_VERBOSE)
|
||||
.help("print a diagnostic just before each output file is opened"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_INPUT)
|
||||
.takes_value(true)
|
||||
.default_value("-")
|
||||
.index(1)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_PREFIX)
|
||||
.takes_value(true)
|
||||
.default_value("x")
|
||||
.index(2)
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Settings {
|
||||
prefix: String,
|
||||
|
|
|
@ -947,11 +947,24 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let usage = get_usage();
|
||||
let long_usage = get_long_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
let matches = uu_app()
|
||||
.usage(&usage[..])
|
||||
.after_help(&long_usage[..])
|
||||
.get_matches_from(args);
|
||||
|
||||
match Stater::new(matches) {
|
||||
Ok(stater) => stater.exec(),
|
||||
Err(e) => {
|
||||
show_error!("{}", e);
|
||||
1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::DEREFERENCE)
|
||||
.short("L")
|
||||
|
@ -996,13 +1009,4 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.takes_value(true)
|
||||
.min_values(1),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
match Stater::new(matches) {
|
||||
Ok(stater) => stater.exec(),
|
||||
Err(e) => {
|
||||
show_error!("{}", e);
|
||||
1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,10 +154,40 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.accept_any();
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let options = ProgramOptions::try_from(&matches)
|
||||
.unwrap_or_else(|e| crash!(125, "{}\nTry 'stdbuf --help' for more information.", e.0));
|
||||
|
||||
let mut command_values = matches.values_of::<&str>(options::COMMAND).unwrap();
|
||||
let mut command = Command::new(command_values.next().unwrap());
|
||||
let command_params: Vec<&str> = command_values.collect();
|
||||
|
||||
let mut tmp_dir = tempdir().unwrap();
|
||||
let (preload_env, libstdbuf) = return_if_err!(1, get_preload_env(&mut tmp_dir));
|
||||
command.env(preload_env, libstdbuf);
|
||||
set_command_env(&mut command, "_STDBUF_I", options.stdin);
|
||||
set_command_env(&mut command, "_STDBUF_O", options.stdout);
|
||||
set_command_env(&mut command, "_STDBUF_E", options.stderr);
|
||||
command.args(command_params);
|
||||
|
||||
let mut process = match command.spawn() {
|
||||
Ok(p) => p,
|
||||
Err(e) => crash!(1, "failed to execute process: {}", e),
|
||||
};
|
||||
match process.wait() {
|
||||
Ok(status) => match status.code() {
|
||||
Some(i) => i,
|
||||
None => crash!(1, "process killed by signal {}", status.signal().unwrap()),
|
||||
},
|
||||
Err(e) => crash!(1, "{}", e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.after_help(LONG_HELP)
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.arg(
|
||||
|
@ -191,32 +221,4 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.hidden(true)
|
||||
.required(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let options = ProgramOptions::try_from(&matches)
|
||||
.unwrap_or_else(|e| crash!(125, "{}\nTry 'stdbuf --help' for more information.", e.0));
|
||||
|
||||
let mut command_values = matches.values_of::<&str>(options::COMMAND).unwrap();
|
||||
let mut command = Command::new(command_values.next().unwrap());
|
||||
let command_params: Vec<&str> = command_values.collect();
|
||||
|
||||
let mut tmp_dir = tempdir().unwrap();
|
||||
let (preload_env, libstdbuf) = return_if_err!(1, get_preload_env(&mut tmp_dir));
|
||||
command.env(preload_env, libstdbuf);
|
||||
set_command_env(&mut command, "_STDBUF_I", options.stdin);
|
||||
set_command_env(&mut command, "_STDBUF_O", options.stdout);
|
||||
set_command_env(&mut command, "_STDBUF_E", options.stderr);
|
||||
command.args(command_params);
|
||||
|
||||
let mut process = match command.spawn() {
|
||||
Ok(p) => p,
|
||||
Err(e) => crash!(1, "failed to execute process: {}", e),
|
||||
};
|
||||
match process.wait() {
|
||||
Ok(status) => match status.code() {
|
||||
Some(i) => i,
|
||||
None => crash!(1, "process killed by signal {}", status.signal().unwrap()),
|
||||
},
|
||||
Err(e) => crash!(1, "{}", e),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,24 +98,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.usage(USAGE)
|
||||
.about(SUMMARY)
|
||||
.arg(Arg::with_name(options::FILE).multiple(true).hidden(true))
|
||||
.arg(
|
||||
Arg::with_name(options::BSD_COMPATIBLE)
|
||||
.short(options::BSD_COMPATIBLE)
|
||||
.help("use the BSD sum algorithm, use 1K blocks (default)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SYSTEM_V_COMPATIBLE)
|
||||
.short("s")
|
||||
.long(options::SYSTEM_V_COMPATIBLE)
|
||||
.help("use System V sum algorithm, use 512 bytes blocks"),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let files: Vec<String> = match matches.values_of(options::FILE) {
|
||||
Some(v) => v.clone().map(|v| v.to_owned()).collect(),
|
||||
|
@ -155,3 +138,23 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
exit_code
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.usage(USAGE)
|
||||
.about(SUMMARY)
|
||||
.arg(Arg::with_name(options::FILE).multiple(true).hidden(true))
|
||||
.arg(
|
||||
Arg::with_name(options::BSD_COMPATIBLE)
|
||||
.short(options::BSD_COMPATIBLE)
|
||||
.help("use the BSD sum algorithm, use 1K blocks (default)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SYSTEM_V_COMPATIBLE)
|
||||
.short("s")
|
||||
.long(options::SYSTEM_V_COMPATIBLE)
|
||||
.help("use System V sum algorithm, use 512 bytes blocks"),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -166,26 +166,7 @@ fn get_usage() -> String {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::FILE_SYSTEM)
|
||||
.short("f")
|
||||
.long(options::FILE_SYSTEM)
|
||||
.conflicts_with(options::DATA)
|
||||
.help("sync the file systems that contain the files (Linux and Windows only)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::DATA)
|
||||
.short("d")
|
||||
.long(options::DATA)
|
||||
.conflicts_with(options::FILE_SYSTEM)
|
||||
.help("sync only file data, no unneeded metadata (Linux only)"),
|
||||
)
|
||||
.arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let files: Vec<String> = matches
|
||||
.values_of(ARG_FILES)
|
||||
|
@ -211,6 +192,27 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::FILE_SYSTEM)
|
||||
.short("f")
|
||||
.long(options::FILE_SYSTEM)
|
||||
.conflicts_with(options::DATA)
|
||||
.help("sync the file systems that contain the files (Linux and Windows only)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::DATA)
|
||||
.short("d")
|
||||
.long(options::DATA)
|
||||
.conflicts_with(options::FILE_SYSTEM)
|
||||
.help("sync only file data, no unneeded metadata (Linux only)"),
|
||||
)
|
||||
.arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true))
|
||||
}
|
||||
|
||||
fn sync() -> isize {
|
||||
unsafe { platform::do_sync() }
|
||||
}
|
||||
|
|
|
@ -31,7 +31,31 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let before = matches.is_present(options::BEFORE);
|
||||
let regex = matches.is_present(options::REGEX);
|
||||
let separator = match matches.value_of(options::SEPARATOR) {
|
||||
Some(m) => {
|
||||
if m.is_empty() {
|
||||
crash!(1, "separator cannot be empty")
|
||||
} else {
|
||||
m.to_owned()
|
||||
}
|
||||
}
|
||||
None => "\n".to_owned(),
|
||||
};
|
||||
|
||||
let files: Vec<String> = match matches.values_of(options::FILE) {
|
||||
Some(v) => v.map(|v| v.to_owned()).collect(),
|
||||
None => vec!["-".to_owned()],
|
||||
};
|
||||
|
||||
tac(files, before, regex, &separator[..])
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.usage(USAGE)
|
||||
|
@ -58,27 +82,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.takes_value(true),
|
||||
)
|
||||
.arg(Arg::with_name(options::FILE).hidden(true).multiple(true))
|
||||
.get_matches_from(args);
|
||||
|
||||
let before = matches.is_present(options::BEFORE);
|
||||
let regex = matches.is_present(options::REGEX);
|
||||
let separator = match matches.value_of(options::SEPARATOR) {
|
||||
Some(m) => {
|
||||
if m.is_empty() {
|
||||
crash!(1, "separator cannot be empty")
|
||||
} else {
|
||||
m.to_owned()
|
||||
}
|
||||
}
|
||||
None => "\n".to_owned(),
|
||||
};
|
||||
|
||||
let files: Vec<String> = match matches.values_of(options::FILE) {
|
||||
Some(v) => v.map(|v| v.to_owned()).collect(),
|
||||
None => vec!["-".to_owned()],
|
||||
};
|
||||
|
||||
tac(files, before, regex, &separator[..])
|
||||
}
|
||||
|
||||
fn tac(filenames: Vec<String>, before: bool, _: bool, separator: &str) -> i32 {
|
||||
|
|
|
@ -72,74 +72,7 @@ impl Default for Settings {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let mut settings: Settings = Default::default();
|
||||
|
||||
let app = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about("output the last part of files")
|
||||
// TODO: add usage
|
||||
.arg(
|
||||
Arg::with_name(options::BYTES)
|
||||
.short("c")
|
||||
.long(options::BYTES)
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.overrides_with_all(&[options::BYTES, options::LINES])
|
||||
.help("Number of bytes to print"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FOLLOW)
|
||||
.short("f")
|
||||
.long(options::FOLLOW)
|
||||
.help("Print the file as it grows"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::LINES)
|
||||
.short("n")
|
||||
.long(options::LINES)
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.overrides_with_all(&[options::BYTES, options::LINES])
|
||||
.help("Number of lines to print"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::PID)
|
||||
.long(options::PID)
|
||||
.takes_value(true)
|
||||
.help("with -f, terminate after process ID, PID dies"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::QUIET)
|
||||
.short("q")
|
||||
.long(options::verbosity::QUIET)
|
||||
.visible_alias("silent")
|
||||
.overrides_with_all(&[options::verbosity::QUIET, options::verbosity::VERBOSE])
|
||||
.help("never output headers giving file names"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SLEEP_INT)
|
||||
.short("s")
|
||||
.takes_value(true)
|
||||
.long(options::SLEEP_INT)
|
||||
.help("Number or seconds to sleep between polling the file when running with -f"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::VERBOSE)
|
||||
.short("v")
|
||||
.long(options::verbosity::VERBOSE)
|
||||
.overrides_with_all(&[options::verbosity::QUIET, options::verbosity::VERBOSE])
|
||||
.help("always output headers giving file names"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ZERO_TERM)
|
||||
.short("z")
|
||||
.long(options::ZERO_TERM)
|
||||
.help("Line delimiter is NUL, not newline"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ARG_FILES)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.min_values(1),
|
||||
);
|
||||
let app = uu_app();
|
||||
|
||||
let matches = app.get_matches_from(args);
|
||||
|
||||
|
@ -244,6 +177,77 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about("output the last part of files")
|
||||
// TODO: add usage
|
||||
.arg(
|
||||
Arg::with_name(options::BYTES)
|
||||
.short("c")
|
||||
.long(options::BYTES)
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.overrides_with_all(&[options::BYTES, options::LINES])
|
||||
.help("Number of bytes to print"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::FOLLOW)
|
||||
.short("f")
|
||||
.long(options::FOLLOW)
|
||||
.help("Print the file as it grows"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::LINES)
|
||||
.short("n")
|
||||
.long(options::LINES)
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.overrides_with_all(&[options::BYTES, options::LINES])
|
||||
.help("Number of lines to print"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::PID)
|
||||
.long(options::PID)
|
||||
.takes_value(true)
|
||||
.help("with -f, terminate after process ID, PID dies"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::QUIET)
|
||||
.short("q")
|
||||
.long(options::verbosity::QUIET)
|
||||
.visible_alias("silent")
|
||||
.overrides_with_all(&[options::verbosity::QUIET, options::verbosity::VERBOSE])
|
||||
.help("never output headers giving file names"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SLEEP_INT)
|
||||
.short("s")
|
||||
.takes_value(true)
|
||||
.long(options::SLEEP_INT)
|
||||
.help("Number or seconds to sleep between polling the file when running with -f"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::verbosity::VERBOSE)
|
||||
.short("v")
|
||||
.long(options::verbosity::VERBOSE)
|
||||
.overrides_with_all(&[options::verbosity::QUIET, options::verbosity::VERBOSE])
|
||||
.help("always output headers giving file names"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ZERO_TERM)
|
||||
.short("z")
|
||||
.long(options::ZERO_TERM)
|
||||
.help("Line delimiter is NUL, not newline"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::ARG_FILES)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.min_values(1),
|
||||
)
|
||||
}
|
||||
|
||||
fn follow<T: Read>(readers: &mut [BufReader<T>], filenames: &[String], settings: &Settings) {
|
||||
assert!(settings.follow);
|
||||
let mut last = readers.len() - 1;
|
||||
|
|
|
@ -39,25 +39,7 @@ fn get_usage() -> String {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.after_help("If a FILE is -, it refers to a file named - .")
|
||||
.arg(
|
||||
Arg::with_name(options::APPEND)
|
||||
.long(options::APPEND)
|
||||
.short("a")
|
||||
.help("append to the given FILEs, do not overwrite"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::IGNORE_INTERRUPTS)
|
||||
.long(options::IGNORE_INTERRUPTS)
|
||||
.short("i")
|
||||
.help("ignore interrupt signals (ignored on non-Unix platforms)"),
|
||||
)
|
||||
.arg(Arg::with_name(options::FILE).multiple(true))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let options = Options {
|
||||
append: matches.is_present(options::APPEND),
|
||||
|
@ -74,6 +56,26 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.after_help("If a FILE is -, it refers to a file named - .")
|
||||
.arg(
|
||||
Arg::with_name(options::APPEND)
|
||||
.long(options::APPEND)
|
||||
.short("a")
|
||||
.help("append to the given FILEs, do not overwrite"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::IGNORE_INTERRUPTS)
|
||||
.long(options::IGNORE_INTERRUPTS)
|
||||
.short("i")
|
||||
.help("ignore interrupt signals (ignored on non-Unix platforms)"),
|
||||
)
|
||||
.arg(Arg::with_name(options::FILE).multiple(true))
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn ignore_interrupts() -> Result<()> {
|
||||
let ret = unsafe { libc::signal(libc::SIGINT, libc::SIG_IGN) };
|
||||
|
|
|
@ -15,6 +15,7 @@ edition = "2018"
|
|||
path = "src/test.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.3"
|
||||
libc = "0.2.42"
|
||||
uucore = { version=">=0.0.8", package="uucore", path="../../uucore" }
|
||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||
|
|
|
@ -10,9 +10,17 @@
|
|||
|
||||
mod parser;
|
||||
|
||||
use clap::{App, AppSettings};
|
||||
use parser::{parse, Symbol};
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::path::Path;
|
||||
use uucore::executable;
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.setting(AppSettings::DisableHelpFlags)
|
||||
.setting(AppSettings::DisableVersion)
|
||||
}
|
||||
|
||||
pub fn uumain(mut args: impl uucore::Args) -> i32 {
|
||||
let program = args.next().unwrap_or_else(|| OsString::from("test"));
|
||||
|
|
|
@ -102,9 +102,25 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
let usage = get_usage();
|
||||
|
||||
let app = App::new("timeout")
|
||||
let app = uu_app().usage(&usage[..]);
|
||||
|
||||
let matches = app.get_matches_from(args);
|
||||
|
||||
let config = Config::from(matches);
|
||||
timeout(
|
||||
&config.command,
|
||||
config.duration,
|
||||
config.signal,
|
||||
config.kill_after,
|
||||
config.foreground,
|
||||
config.preserve_status,
|
||||
config.verbose,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new("timeout")
|
||||
.version(crate_version!())
|
||||
.usage(&usage[..])
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::FOREGROUND)
|
||||
|
@ -144,20 +160,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.required(true)
|
||||
.multiple(true)
|
||||
)
|
||||
.setting(AppSettings::TrailingVarArg);
|
||||
|
||||
let matches = app.get_matches_from(args);
|
||||
|
||||
let config = Config::from(matches);
|
||||
timeout(
|
||||
&config.command,
|
||||
config.duration,
|
||||
config.signal,
|
||||
config.kill_after,
|
||||
config.foreground,
|
||||
config.preserve_status,
|
||||
config.verbose,
|
||||
)
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
}
|
||||
|
||||
/// Remove pre-existing SIGCHLD handlers that would make waiting for the child's exit code fail.
|
||||
|
|
|
@ -55,80 +55,7 @@ fn get_usage() -> String {
|
|||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::ACCESS)
|
||||
.short("a")
|
||||
.help("change only the access time"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::sources::CURRENT)
|
||||
.short("t")
|
||||
.help("use [[CC]YY]MMDDhhmm[.ss] instead of the current time")
|
||||
.value_name("STAMP")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::sources::DATE)
|
||||
.short("d")
|
||||
.long(options::sources::DATE)
|
||||
.help("parse argument and use it instead of current time")
|
||||
.value_name("STRING"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::MODIFICATION)
|
||||
.short("m")
|
||||
.help("change only the modification time"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NO_CREATE)
|
||||
.short("c")
|
||||
.long(options::NO_CREATE)
|
||||
.help("do not create any files"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NO_DEREF)
|
||||
.short("h")
|
||||
.long(options::NO_DEREF)
|
||||
.help(
|
||||
"affect each symbolic link instead of any referenced file \
|
||||
(only for systems that can change the timestamps of a symlink)",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::sources::REFERENCE)
|
||||
.short("r")
|
||||
.long(options::sources::REFERENCE)
|
||||
.help("use this file's times instead of the current time")
|
||||
.value_name("FILE"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TIME)
|
||||
.long(options::TIME)
|
||||
.help(
|
||||
"change only the specified time: \"access\", \"atime\", or \
|
||||
\"use\" are equivalent to -a; \"modify\" or \"mtime\" are \
|
||||
equivalent to -m",
|
||||
)
|
||||
.value_name("WORD")
|
||||
.possible_values(&["access", "atime", "use"])
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_FILES)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.min_values(1),
|
||||
)
|
||||
.group(ArgGroup::with_name(options::SOURCES).args(&[
|
||||
options::sources::CURRENT,
|
||||
options::sources::DATE,
|
||||
options::sources::REFERENCE,
|
||||
]))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let files: Vec<String> = matches
|
||||
.values_of(ARG_FILES)
|
||||
|
@ -236,6 +163,81 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
error_code
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::ACCESS)
|
||||
.short("a")
|
||||
.help("change only the access time"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::sources::CURRENT)
|
||||
.short("t")
|
||||
.help("use [[CC]YY]MMDDhhmm[.ss] instead of the current time")
|
||||
.value_name("STAMP")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::sources::DATE)
|
||||
.short("d")
|
||||
.long(options::sources::DATE)
|
||||
.help("parse argument and use it instead of current time")
|
||||
.value_name("STRING"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::MODIFICATION)
|
||||
.short("m")
|
||||
.help("change only the modification time"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NO_CREATE)
|
||||
.short("c")
|
||||
.long(options::NO_CREATE)
|
||||
.help("do not create any files"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NO_DEREF)
|
||||
.short("h")
|
||||
.long(options::NO_DEREF)
|
||||
.help(
|
||||
"affect each symbolic link instead of any referenced file \
|
||||
(only for systems that can change the timestamps of a symlink)",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::sources::REFERENCE)
|
||||
.short("r")
|
||||
.long(options::sources::REFERENCE)
|
||||
.help("use this file's times instead of the current time")
|
||||
.value_name("FILE"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TIME)
|
||||
.long(options::TIME)
|
||||
.help(
|
||||
"change only the specified time: \"access\", \"atime\", or \
|
||||
\"use\" are equivalent to -a; \"modify\" or \"mtime\" are \
|
||||
equivalent to -m",
|
||||
)
|
||||
.value_name("WORD")
|
||||
.possible_values(&["access", "atime", "use"])
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(ARG_FILES)
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.min_values(1),
|
||||
)
|
||||
.group(ArgGroup::with_name(options::SOURCES).args(&[
|
||||
options::sources::CURRENT,
|
||||
options::sources::DATE,
|
||||
options::sources::REFERENCE,
|
||||
]))
|
||||
}
|
||||
|
||||
fn stat(path: &str, follow: bool) -> (FileTime, FileTime) {
|
||||
let metadata = if follow {
|
||||
fs::symlink_metadata(path)
|
||||
|
|
|
@ -249,46 +249,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let usage = get_usage();
|
||||
let after_help = get_long_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
let matches = uu_app()
|
||||
.usage(&usage[..])
|
||||
.after_help(&after_help[..])
|
||||
.arg(
|
||||
Arg::with_name(options::COMPLEMENT)
|
||||
// .visible_short_alias('C') // TODO: requires clap "3.0.0-beta.2"
|
||||
.short("c")
|
||||
.long(options::COMPLEMENT)
|
||||
.help("use the complement of SET1"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("C") // work around for `Arg::visible_short_alias`
|
||||
.short("C")
|
||||
.help("same as -c"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::DELETE)
|
||||
.short("d")
|
||||
.long(options::DELETE)
|
||||
.help("delete characters in SET1, do not translate"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SQUEEZE)
|
||||
.long(options::SQUEEZE)
|
||||
.short("s")
|
||||
.help(
|
||||
"replace each sequence of a repeated character that is
|
||||
listed in the last specified SET, with a single occurrence
|
||||
of that character",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TRUNCATE)
|
||||
.long(options::TRUNCATE)
|
||||
.short("t")
|
||||
.help("first truncate SET1 to length of SET2"),
|
||||
)
|
||||
.arg(Arg::with_name(options::SETS).multiple(true))
|
||||
.get_matches_from(args);
|
||||
|
||||
let delete_flag = matches.is_present(options::DELETE);
|
||||
|
@ -358,3 +321,44 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::COMPLEMENT)
|
||||
// .visible_short_alias('C') // TODO: requires clap "3.0.0-beta.2"
|
||||
.short("c")
|
||||
.long(options::COMPLEMENT)
|
||||
.help("use the complement of SET1"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("C") // work around for `Arg::visible_short_alias`
|
||||
.short("C")
|
||||
.help("same as -c"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::DELETE)
|
||||
.short("d")
|
||||
.long(options::DELETE)
|
||||
.help("delete characters in SET1, do not translate"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SQUEEZE)
|
||||
.long(options::SQUEEZE)
|
||||
.short("s")
|
||||
.help(
|
||||
"replace each sequence of a repeated character that is
|
||||
listed in the last specified SET, with a single occurrence
|
||||
of that character",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::TRUNCATE)
|
||||
.long(options::TRUNCATE)
|
||||
.short("t")
|
||||
.help("first truncate SET1 to length of SET2"),
|
||||
)
|
||||
.arg(Arg::with_name(options::SETS).multiple(true))
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ edition = "2018"
|
|||
path = "src/true.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.33.3"
|
||||
uucore = { version=">=0.0.8", package="uucore", path="../../uucore" }
|
||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||
|
||||
|
|
|
@ -5,6 +5,15 @@
|
|||
// * For the full copyright and license information, please view the LICENSE
|
||||
// * file that was distributed with this source code.
|
||||
|
||||
use clap::{App, AppSettings};
|
||||
use uucore::executable;
|
||||
|
||||
pub fn uumain(_: impl uucore::Args) -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.setting(AppSettings::DisableHelpFlags)
|
||||
.setting(AppSettings::DisableVersion)
|
||||
}
|
||||
|
|
|
@ -93,45 +93,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let usage = get_usage();
|
||||
let long_usage = get_long_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
let matches = uu_app()
|
||||
.usage(&usage[..])
|
||||
.after_help(&long_usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::IO_BLOCKS)
|
||||
.short("o")
|
||||
.long(options::IO_BLOCKS)
|
||||
.help("treat SIZE as the number of I/O blocks of the file rather than bytes (NOT IMPLEMENTED)")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NO_CREATE)
|
||||
.short("c")
|
||||
.long(options::NO_CREATE)
|
||||
.help("do not create files that do not exist")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::REFERENCE)
|
||||
.short("r")
|
||||
.long(options::REFERENCE)
|
||||
.required_unless(options::SIZE)
|
||||
.help("base the size of each file on the size of RFILE")
|
||||
.value_name("RFILE")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SIZE)
|
||||
.short("s")
|
||||
.long(options::SIZE)
|
||||
.required_unless(options::REFERENCE)
|
||||
.help("set or adjust the size of each file according to SIZE, which is in bytes unless --io-blocks is specified")
|
||||
.value_name("SIZE")
|
||||
)
|
||||
.arg(Arg::with_name(options::ARG_FILES)
|
||||
.value_name("FILE")
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.min_values(1))
|
||||
.get_matches_from(args);
|
||||
|
||||
let files: Vec<String> = matches
|
||||
|
@ -168,6 +132,46 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::IO_BLOCKS)
|
||||
.short("o")
|
||||
.long(options::IO_BLOCKS)
|
||||
.help("treat SIZE as the number of I/O blocks of the file rather than bytes (NOT IMPLEMENTED)")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::NO_CREATE)
|
||||
.short("c")
|
||||
.long(options::NO_CREATE)
|
||||
.help("do not create files that do not exist")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::REFERENCE)
|
||||
.short("r")
|
||||
.long(options::REFERENCE)
|
||||
.required_unless(options::SIZE)
|
||||
.help("base the size of each file on the size of RFILE")
|
||||
.value_name("RFILE")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(options::SIZE)
|
||||
.short("s")
|
||||
.long(options::SIZE)
|
||||
.required_unless(options::REFERENCE)
|
||||
.help("set or adjust the size of each file according to SIZE, which is in bytes unless --io-blocks is specified")
|
||||
.value_name("SIZE")
|
||||
)
|
||||
.arg(Arg::with_name(options::ARG_FILES)
|
||||
.value_name("FILE")
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.min_values(1))
|
||||
}
|
||||
|
||||
/// Truncate the named file to the specified size.
|
||||
///
|
||||
/// If `create` is true, then the file will be created if it does not
|
||||
|
|
|
@ -30,16 +30,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.usage(USAGE)
|
||||
.about(SUMMARY)
|
||||
.arg(
|
||||
Arg::with_name(options::FILE)
|
||||
.default_value("-")
|
||||
.hidden(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
let input = matches
|
||||
.value_of(options::FILE)
|
||||
|
@ -98,6 +89,18 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.usage(USAGE)
|
||||
.about(SUMMARY)
|
||||
.arg(
|
||||
Arg::with_name(options::FILE)
|
||||
.default_value("-")
|
||||
.hidden(true),
|
||||
)
|
||||
}
|
||||
|
||||
// We use String as a representation of node here
|
||||
// but using integer may improve performance.
|
||||
struct Graph {
|
||||
|
|
|
@ -33,19 +33,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::SILENT)
|
||||
.long(options::SILENT)
|
||||
.visible_alias("quiet")
|
||||
.short("s")
|
||||
.help("print nothing, only return an exit status")
|
||||
.required(false),
|
||||
)
|
||||
.get_matches_from_safe(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from_safe(args);
|
||||
|
||||
let matches = match matches {
|
||||
Ok(m) => m,
|
||||
|
@ -88,3 +76,17 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
libc::EXIT_FAILURE
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::SILENT)
|
||||
.long(options::SILENT)
|
||||
.visible_alias("quiet")
|
||||
.short("s")
|
||||
.help("print nothing, only return an exit status")
|
||||
.required(false),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -47,49 +47,7 @@ const HOST_OS: &str = "Redox";
|
|||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = format!("{} [OPTION]...", executable!());
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(Arg::with_name(options::ALL)
|
||||
.short("a")
|
||||
.long(options::ALL)
|
||||
.help("Behave as though all of the options -mnrsv were specified."))
|
||||
.arg(Arg::with_name(options::KERNELNAME)
|
||||
.short("s")
|
||||
.long(options::KERNELNAME)
|
||||
.alias("sysname") // Obsolescent option in GNU uname
|
||||
.help("print the kernel name."))
|
||||
.arg(Arg::with_name(options::NODENAME)
|
||||
.short("n")
|
||||
.long(options::NODENAME)
|
||||
.help("print the nodename (the nodename may be a name that the system is known by to a communications network)."))
|
||||
.arg(Arg::with_name(options::KERNELRELEASE)
|
||||
.short("r")
|
||||
.long(options::KERNELRELEASE)
|
||||
.alias("release") // Obsolescent option in GNU uname
|
||||
.help("print the operating system release."))
|
||||
.arg(Arg::with_name(options::KERNELVERSION)
|
||||
.short("v")
|
||||
.long(options::KERNELVERSION)
|
||||
.help("print the operating system version."))
|
||||
.arg(Arg::with_name(options::HWPLATFORM)
|
||||
.short("i")
|
||||
.long(options::HWPLATFORM)
|
||||
.help("print the hardware platform (non-portable)"))
|
||||
.arg(Arg::with_name(options::MACHINE)
|
||||
.short("m")
|
||||
.long(options::MACHINE)
|
||||
.help("print the machine hardware name."))
|
||||
.arg(Arg::with_name(options::PROCESSOR)
|
||||
.short("p")
|
||||
.long(options::PROCESSOR)
|
||||
.help("print the processor type (non-portable)"))
|
||||
.arg(Arg::with_name(options::OS)
|
||||
.short("o")
|
||||
.long(options::OS)
|
||||
.help("print the operating system name."))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let uname = return_if_err!(1, PlatformInfo::new());
|
||||
let mut output = String::new();
|
||||
|
@ -155,3 +113,47 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(Arg::with_name(options::ALL)
|
||||
.short("a")
|
||||
.long(options::ALL)
|
||||
.help("Behave as though all of the options -mnrsv were specified."))
|
||||
.arg(Arg::with_name(options::KERNELNAME)
|
||||
.short("s")
|
||||
.long(options::KERNELNAME)
|
||||
.alias("sysname") // Obsolescent option in GNU uname
|
||||
.help("print the kernel name."))
|
||||
.arg(Arg::with_name(options::NODENAME)
|
||||
.short("n")
|
||||
.long(options::NODENAME)
|
||||
.help("print the nodename (the nodename may be a name that the system is known by to a communications network)."))
|
||||
.arg(Arg::with_name(options::KERNELRELEASE)
|
||||
.short("r")
|
||||
.long(options::KERNELRELEASE)
|
||||
.alias("release") // Obsolescent option in GNU uname
|
||||
.help("print the operating system release."))
|
||||
.arg(Arg::with_name(options::KERNELVERSION)
|
||||
.short("v")
|
||||
.long(options::KERNELVERSION)
|
||||
.help("print the operating system version."))
|
||||
.arg(Arg::with_name(options::HWPLATFORM)
|
||||
.short("i")
|
||||
.long(options::HWPLATFORM)
|
||||
.help("print the hardware platform (non-portable)"))
|
||||
.arg(Arg::with_name(options::MACHINE)
|
||||
.short("m")
|
||||
.long(options::MACHINE)
|
||||
.help("print the machine hardware name."))
|
||||
.arg(Arg::with_name(options::PROCESSOR)
|
||||
.short("p")
|
||||
.long(options::PROCESSOR)
|
||||
.help("print the processor type (non-portable)"))
|
||||
.arg(Arg::with_name(options::OS)
|
||||
.short("o")
|
||||
.long(options::OS)
|
||||
.help("print the operating system name."))
|
||||
}
|
||||
|
|
|
@ -94,7 +94,15 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.collect_str(InvalidEncodingHandling::Ignore)
|
||||
.accept_any();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
|
||||
unexpand(Options::new(matches));
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.usage(USAGE)
|
||||
|
@ -126,11 +134,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.long(options::NO_UTF8)
|
||||
.takes_value(false)
|
||||
.help("interpret input file as 8-bit ASCII rather than UTF-8"))
|
||||
.get_matches_from(args);
|
||||
|
||||
unexpand(Options::new(matches));
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
fn open(path: String) -> BufReader<Box<dyn Read + 'static>> {
|
||||
|
|
|
@ -238,11 +238,52 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let usage = get_usage();
|
||||
let long_usage = get_long_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
let matches = uu_app()
|
||||
.usage(&usage[..])
|
||||
.after_help(&long_usage[..])
|
||||
.get_matches_from(args);
|
||||
|
||||
let files: Vec<String> = matches
|
||||
.values_of(ARG_FILES)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let (in_file_name, out_file_name) = match files.len() {
|
||||
0 => ("-".to_owned(), "-".to_owned()),
|
||||
1 => (files[0].clone(), "-".to_owned()),
|
||||
2 => (files[0].clone(), files[1].clone()),
|
||||
_ => {
|
||||
// Cannot happen as clap will fail earlier
|
||||
crash!(1, "Extra operand: {}", files[2]);
|
||||
}
|
||||
};
|
||||
|
||||
let uniq = Uniq {
|
||||
repeats_only: matches.is_present(options::REPEATED)
|
||||
|| matches.is_present(options::ALL_REPEATED),
|
||||
uniques_only: matches.is_present(options::UNIQUE),
|
||||
all_repeated: matches.is_present(options::ALL_REPEATED)
|
||||
|| matches.is_present(options::GROUP),
|
||||
delimiters: get_delimiter(&matches),
|
||||
show_counts: matches.is_present(options::COUNT),
|
||||
skip_fields: opt_parsed(options::SKIP_FIELDS, &matches),
|
||||
slice_start: opt_parsed(options::SKIP_CHARS, &matches),
|
||||
slice_stop: opt_parsed(options::CHECK_CHARS, &matches),
|
||||
ignore_case: matches.is_present(options::IGNORE_CASE),
|
||||
zero_terminated: matches.is_present(options::ZERO_TERMINATED),
|
||||
};
|
||||
uniq.print_uniq(
|
||||
&mut open_input_file(in_file_name),
|
||||
&mut open_output_file(out_file_name),
|
||||
);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::ALL_REPEATED)
|
||||
.short("D")
|
||||
|
@ -329,43 +370,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.takes_value(true)
|
||||
.max_values(2),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
let files: Vec<String> = matches
|
||||
.values_of(ARG_FILES)
|
||||
.map(|v| v.map(ToString::to_string).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let (in_file_name, out_file_name) = match files.len() {
|
||||
0 => ("-".to_owned(), "-".to_owned()),
|
||||
1 => (files[0].clone(), "-".to_owned()),
|
||||
2 => (files[0].clone(), files[1].clone()),
|
||||
_ => {
|
||||
// Cannot happen as clap will fail earlier
|
||||
crash!(1, "Extra operand: {}", files[2]);
|
||||
}
|
||||
};
|
||||
|
||||
let uniq = Uniq {
|
||||
repeats_only: matches.is_present(options::REPEATED)
|
||||
|| matches.is_present(options::ALL_REPEATED),
|
||||
uniques_only: matches.is_present(options::UNIQUE),
|
||||
all_repeated: matches.is_present(options::ALL_REPEATED)
|
||||
|| matches.is_present(options::GROUP),
|
||||
delimiters: get_delimiter(&matches),
|
||||
show_counts: matches.is_present(options::COUNT),
|
||||
skip_fields: opt_parsed(options::SKIP_FIELDS, &matches),
|
||||
slice_start: opt_parsed(options::SKIP_CHARS, &matches),
|
||||
slice_stop: opt_parsed(options::CHECK_CHARS, &matches),
|
||||
ignore_case: matches.is_present(options::IGNORE_CASE),
|
||||
zero_terminated: matches.is_present(options::ZERO_TERMINATED),
|
||||
};
|
||||
uniq.print_uniq(
|
||||
&mut open_input_file(in_file_name),
|
||||
&mut open_output_file(out_file_name),
|
||||
);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
fn get_delimiter(matches: &ArgMatches) -> Delimiters {
|
||||
|
|
|
@ -33,12 +33,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
let usage = get_usage();
|
||||
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(Arg::with_name(OPT_PATH).hidden(true).multiple(true))
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let paths: Vec<String> = matches
|
||||
.values_of(OPT_PATH)
|
||||
|
@ -98,3 +93,10 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
|
||||
0
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(Arg::with_name(OPT_PATH).hidden(true).multiple(true))
|
||||
}
|
||||
|
|
|
@ -38,17 +38,7 @@ fn get_usage() -> String {
|
|||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let matches = App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.usage(&usage[..])
|
||||
.arg(
|
||||
Arg::with_name(options::SINCE)
|
||||
.short("s")
|
||||
.long(options::SINCE)
|
||||
.help("system up since"),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
let matches = uu_app().usage(&usage[..]).get_matches_from(args);
|
||||
|
||||
let (boot_time, user_count) = process_utmpx();
|
||||
let uptime = get_uptime(boot_time);
|
||||
|
@ -73,6 +63,18 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> App<'static, 'static> {
|
||||
App::new(executable!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.arg(
|
||||
Arg::with_name(options::SINCE)
|
||||
.short("s")
|
||||
.long(options::SINCE)
|
||||
.help("system up since"),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn print_loadavg() {
|
||||
use uucore::libc::c_double;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue