impl: use coreopts for brevity and consistent UX

This commit is contained in:
Nathan Ross 2016-08-13 21:37:48 -04:00
parent edc3bf7c08
commit 36503a77c7
50 changed files with 445 additions and 1154 deletions

View file

@ -8,7 +8,6 @@ name = "uu_base32"
path = "base32.rs"
[dependencies]
getopts = "*"
uucore = { path="../uucore" }
[dependencies.clippy]

View file

@ -8,46 +8,38 @@
#![crate_name = "uu_base32"]
extern crate getopts;
#[macro_use]
extern crate uucore;
use uucore::encoding::{Data, Format, wrap_print};
use getopts::Options;
use std::fs::File;
use std::io::{BufReader, Read, stdin, Write};
use std::path::Path;
static NAME: &'static str = "base32";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTION]... [FILE]";
static SUMMARY: &'static str = "Base32 encode or decode FILE, or standard input, to standard output.";
static LONG_HELP: &'static str = "
With no FILE, or when FILE is -, read standard input.
The data are encoded as described for the base32 alphabet in RFC
4648. When decoding, the input may contain newlines in addition
to the bytes of the formal base32 alphabet. Use --ignore-garbage
to attempt to recover from any other non-alphabet bytes in the
encoded stream.
";
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = Options::new();
opts.optflag("d", "decode", "decode data");
opts.optflag("i",
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("d", "decode", "decode data")
.optflag("i",
"ignore-garbage",
"when decoding, ignore non-alphabetic characters");
opts.optopt("w",
"when decoding, ignore non-alphabetic characters")
.optopt("w",
"wrap",
"wrap encoded lines after COLS character (default 76, 0 to disable wrapping)",
"COLS");
opts.optflag("", "help", "display this help text and exit");
opts.optflag("", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(e) => {
disp_err!("{}", e);
return 1;
}
};
if matches.opt_present("help") {
return help(&opts);
} else if matches.opt_present("version") {
return version();
}
"COLS")
.parse(args);
let line_wrap = match matches.opt_str("wrap") {
Some(s) => {
match s.parse() {
@ -88,23 +80,3 @@ pub fn uumain(args: Vec<String>) -> i32 {
0
}
fn help(opts: &Options) -> i32 {
let msg = format!("Usage: {} [OPTION]... [FILE]\n\n\
Base32 encode or decode FILE, or standard input, to standard output.\n\
With no FILE, or when FILE is -, read standard input.\n\n\
The data are encoded as described for the base32 alphabet in RFC \
4648.\nWhen decoding, the input may contain newlines in addition \
to the bytes of the formal\nbase32 alphabet. Use --ignore-garbage \
to attempt to recover from any other\nnon-alphabet bytes in the \
encoded stream.",
NAME);
print!("{}", opts.usage(&msg));
0
}
fn version() -> i32 {
println!("{} {}", NAME, VERSION);
0
}

View file

@ -8,7 +8,6 @@ name = "uu_base64"
path = "base64.rs"
[dependencies]
getopts = "*"
uucore = { path="../uucore" }
[[bin]]

View file

@ -9,45 +9,38 @@
// that was distributed with this source code.
//
extern crate getopts;
#[macro_use]
extern crate uucore;
use uucore::encoding::{Data, Format, wrap_print};
use getopts::Options;
use std::fs::File;
use std::io::{BufReader, Read, stdin, Write};
use std::path::Path;
static NAME: &'static str = "base64";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTION]... [FILE]";
static SUMMARY: &'static str = "Base64 encode or decode FILE, or standard input, to standard output.";
static LONG_HELP: &'static str = "
With no FILE, or when FILE is -, read standard input.
The data are encoded as described for the base64 alphabet in RFC
3548. When decoding, the input may contain newlines in addition
to the bytes of the formal base64 alphabet. Use --ignore-garbage
to attempt to recover from any other non-alphabet bytes in the
encoded stream.
";
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = Options::new();
opts.optflag("d", "decode", "decode data");
opts.optflag("i",
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("d", "decode", "decode data")
.optflag("i",
"ignore-garbage",
"when decoding, ignore non-alphabetic characters");
opts.optopt("w",
"when decoding, ignore non-alphabetic characters")
.optopt("w",
"wrap",
"wrap encoded lines after COLS character (default 76, 0 to disable wrapping)",
"COLS");
opts.optflag("", "help", "display this help text and exit");
opts.optflag("", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(e) => {
disp_err!("{}", e);
return 1;
}
};
if matches.opt_present("help") {
return help(&opts);
} else if matches.opt_present("version") {
return version();
}
"COLS")
.parse(args);
let line_wrap = match matches.opt_str("wrap") {
Some(s) => {
@ -89,23 +82,3 @@ pub fn uumain(args: Vec<String>) -> i32 {
0
}
fn help(opts: &Options) -> i32 {
let msg = format!("Usage: {} [OPTION]... [FILE]\n\n\
Base64 encode or decode FILE, or standard input, to standard output.\n\
With no FILE, or when FILE is -, read standard input.\n\n\
The data are encoded as described for the base64 alphabet in RFC \
3548. When\ndecoding, the input may contain newlines in addition \
to the bytes of the formal\nbase64 alphabet. Use --ignore-garbage \
to attempt to recover from any other\nnon-alphabet bytes in the \
encoded stream.",
NAME);
print!("{}", opts.usage(&msg));
0
}
fn version() -> i32 {
println!("{} {}", NAME, VERSION);
0
}

View file

@ -8,7 +8,6 @@ name = "uu_basename"
path = "basename.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }

View file

@ -9,49 +9,29 @@
* file that was distributed with this source code.
*/
extern crate getopts;
extern crate libc;
#[macro_use]
extern crate uucore;
use getopts::Options;
use std::io::Write;
use std::path::{is_separator, PathBuf};
static NAME: &'static str = "basename";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "NAME [SUFFIX]";
static SUMMARY: &'static str = "Print NAME with any leading directory components removed
If specified, also remove a trailing SUFFIX";
static LONG_HELP: &'static str = "";
pub fn uumain(args: Vec<String>) -> i32 {
//
// Argument parsing
//
let mut opts = Options::new();
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => crash!(1, "Invalid options\n{}", f)
};
if matches.opt_present("help") {
let msg = format!("Usage: {0} NAME [SUFFIX]\n or: {0} OPTION\n\n\
Print NAME with any leading directory components removed.\n\
If specified, also remove a trailing SUFFIX.", NAME);
print!("{}", opts.usage(&msg));
return 0;
}
if matches.opt_present("version") {
println!("{} {}", NAME, VERSION);
return 0;
}
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.parse(args);
// too few arguments
if args.len() < 2 {
if matches.free.len() < 1 {
crash!(
1,
"{0}: {1}\nTry '{0} --help' for more information.",
@ -60,12 +40,12 @@ pub fn uumain(args: Vec<String>) -> i32 {
);
}
// too many arguments
else if args.len() > 3 {
else if matches.free.len() > 2 {
crash!(
1,
"{0}: extra operand '{1}'\nTry '{0} --help' for more information.",
NAME,
args[3]
matches.free[2]
);
}
@ -73,10 +53,10 @@ pub fn uumain(args: Vec<String>) -> i32 {
// Main Program Processing
//
let mut name = strip_dir(&args[1]);
let mut name = strip_dir(&matches.free[0]);
if args.len() > 2 {
let suffix = args[2].clone();
if matches.free.len() > 1 {
let suffix = matches.free[1].clone();
name = strip_suffix(name.as_ref(), suffix.as_ref());
}

View file

@ -8,7 +8,6 @@ name = "uu_cat"
path = "cat.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }

View file

@ -11,53 +11,35 @@
/* last synced with: cat (GNU coreutils) 8.13 */
extern crate getopts;
extern crate libc;
#[macro_use]
extern crate uucore;
use getopts::Options;
use std::fs::File;
use std::intrinsics::{copy_nonoverlapping};
use std::io::{stdout, stdin, stderr, Write, Read, Result};
use uucore::fs::is_stdin_interactive;
static NAME: &'static str = "cat";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTION]... [FILE]...";
static SUMMARY: &'static str = "Concatenate FILE(s), or standard input, to standard output
With no FILE, or when FILE is -, read standard input.";
static LONG_HELP: &'static str = "";
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = Options::new();
opts.optflag("A", "show-all", "equivalent to -vET");
opts.optflag("b", "number-nonblank",
"number nonempty output lines, overrides -n");
opts.optflag("e", "", "equivalent to -vE");
opts.optflag("E", "show-ends", "display $ at end of each line");
opts.optflag("n", "number", "number all output lines");
opts.optflag("s", "squeeze-blank", "suppress repeated empty output lines");
opts.optflag("t", "", "equivalent to -vT");
opts.optflag("T", "show-tabs", "display TAB characters as ^I");
opts.optflag("v", "show-nonprinting",
"use ^ and M- notation, except for LF (\\n) and TAB (\\t)");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => panic!("Invalid options\n{}", f)
};
if matches.opt_present("help") {
let msg = format!("{} {}\n\n\
Usage:\n {0} [OPTION]... [FILE]...\n\n\
Concatenate FILE(s), or standard input, to standard output.\n\n\
With no FILE, or when FILE is -, read standard input.", NAME, VERSION);
print!("{}", opts.usage(&msg));
return 0;
}
if matches.opt_present("version") {
println!("{} {}", NAME, VERSION);
return 0;
}
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("A", "show-all", "equivalent to -vET")
.optflag("b", "number-nonblank",
"number nonempty output lines, overrides -n")
.optflag("e", "", "equivalent to -vE")
.optflag("E", "show-ends", "display $ at end of each line")
.optflag("n", "number", "number all output lines")
.optflag("s", "squeeze-blank", "suppress repeated empty output lines")
.optflag("t", "", "equivalent to -vT")
.optflag("T", "show-tabs", "display TAB characters as ^I")
.optflag("v", "show-nonprinting",
"use ^ and M- notation, except for LF (\\n) and TAB (\\t)")
.parse(args);
let number_mode = if matches.opt_present("b") {
NumberingMode::NumberNonEmpty

View file

@ -8,7 +8,6 @@ name = "uu_chmod"
path = "chmod.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }
walker = "*"

View file

@ -9,14 +9,12 @@
* file that was distributed with this source code.
*/
extern crate getopts;
extern crate libc;
extern crate walker;
#[macro_use]
extern crate uucore;
use getopts::Options;
use std::error::Error;
use std::ffi::CString;
use std::io::{self, Write};
@ -25,19 +23,25 @@ use std::path::Path;
use walker::Walker;
const NAME: &'static str = "chmod";
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SUMMARY: &'static str = "Change the mode of each FILE to MODE.
With --reference, change the mode of each FILE to that of RFILE.";
static LONG_HELP: &'static str = "
Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'.
";
pub fn uumain(mut args: Vec<String>) -> i32 {
let mut opts = Options::new();
opts.optflag("c", "changes", "like verbose but report only when a change is made (unimplemented)");
opts.optflag("f", "quiet", "suppress most error messages (unimplemented)"); // TODO: support --silent
opts.optflag("v", "verbose", "output a diagnostic for every file processed (unimplemented)");
opts.optflag("", "no-preserve-root", "do not treat '/' specially (the default)");
opts.optflag("", "preserve-root", "fail to operate recursively on '/'");
opts.optopt("", "reference", "use RFILE's mode instead of MODE values", "RFILE");
opts.optflag("R", "recursive", "change files and directories recursively");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let syntax = format!("[OPTION]... MODE[,MODE]... FILE...
{0} [OPTION]... OCTAL-MODE FILE...
{0} [OPTION]... --reference=RFILE FILE...", NAME);
let mut opts = new_coreopts!(&syntax, SUMMARY, LONG_HELP);
opts.optflag("c", "changes", "like verbose but report only when a change is made (unimplemented)")
.optflag("f", "quiet", "suppress most error messages (unimplemented)") // TODO: support --silent
.optflag("v", "verbose", "output a diagnostic for every file processed (unimplemented)")
.optflag("", "no-preserve-root", "do not treat '/' specially (the default)")
.optflag("", "preserve-root", "fail to operate recursively on '/'")
.optopt("", "reference", "use RFILE's mode instead of MODE values", "RFILE")
.optflag("R", "recursive", "change files and directories recursively");
// sanitize input for - at beginning (e.g. chmod -x testfile). Remove
// the option and save it for later, after parsing is finished.
let mut negative_option = None;
@ -59,28 +63,8 @@ pub fn uumain(mut args: Vec<String>) -> i32 {
}
}
let mut matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => { crash!(1, "{}", f) }
};
if matches.opt_present("help") {
let msg = format!("{name} {version}
Usage:
{program} [OPTION]... MODE[,MODE]... FILE...
{program} [OPTION]... OCTAL-MODE FILE...
{program} [OPTION]... --reference=RFILE FILE...
Change the mode of each FILE to MODE.
With --reference, change the mode of each FILE to that of RFILE.
Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'.",
name = NAME, version = VERSION, program = NAME);
print!("{}", opts.usage(&msg));
return 0;
} else if matches.opt_present("version") {
println!("{} {}", NAME, VERSION);
} else if matches.free.is_empty() {
let mut matches = opts.parse(args);
if matches.free.is_empty() {
show_error!("missing an argument");
show_error!("for help, try '{} --help'", NAME);
return 1;

View file

@ -17,7 +17,6 @@ extern crate uucore;
use uucore::libc::{self, setgid, setuid, chroot, setgroups};
use uucore::entries;
use getopts::Options;
use std::ffi::CString;
use std::io::{Error, Write};
use std::iter::FromIterator;
@ -25,31 +24,22 @@ use std::path::Path;
use std::process::Command;
static NAME: &'static str = "chroot";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTION]... NEWROOT [COMMAND [ARG]...]";
static SUMMARY: &'static str = "Run COMMAND with root directory set to NEWROOT.";
static LONG_HELP: &'static str = "
If COMMAND is not specified, it defaults to '$(SHELL) -i'.
If $(SHELL) is not set, /bin/sh is used.
";
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = Options::new();
opts.optopt("u", "user", "User (ID or name) to switch before running the program", "USER");
opts.optopt("g", "group", "Group (ID or name) to switch to", "GROUP");
opts.optopt("G", "groups", "Comma-separated list of groups to switch to", "GROUP1,GROUP2...");
opts.optopt("", "userspec", "Colon-separated user and group to switch to. \
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optopt("u", "user", "User (ID or name) to switch before running the program", "USER")
.optopt("g", "group", "Group (ID or name) to switch to", "GROUP")
.optopt("G", "groups", "Comma-separated list of groups to switch to", "GROUP1,GROUP2...")
.optopt("", "userspec", "Colon-separated user and group to switch to. \
Same as -u USER -g GROUP. \
Userspec has higher preference than -u and/or -g", "USER:GROUP");
opts.optflag("h", "help", "Show help");
opts.optflag("V", "version", "Show program's version");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => {
show_error!("{}", f);
help_menu(opts);
return 1
}
};
if matches.opt_present("V") { version(); return 0 }
if matches.opt_present("h") { help_menu(opts); return 0 }
Userspec has higher preference than -u and/or -g", "USER:GROUP")
.parse(args);
if matches.free.is_empty() {
println!("Missing operand: NEWROOT");
@ -184,20 +174,3 @@ fn set_user(user: &str) {
}
}
}
fn version() {
println!("{} {}", NAME, VERSION)
}
fn help_menu(options: Options) {
let msg = format!("{0} {1}
Usage:
{0} [OPTION]... NEWROOT [COMMAND [ARG]...]
Run COMMAND with root directory set to NEWROOT.
If COMMAND is not specified, it defaults to '$(SHELL) -i'.
If $(SHELL) is not set, /bin/sh is used.", NAME, VERSION);
print!("{}", options.usage(&msg));
}

View file

@ -8,7 +8,6 @@ name = "uu_cksum"
path = "cksum.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }

View file

@ -9,12 +9,10 @@
* file that was distributed with this source code.
*/
extern crate getopts;
#[macro_use]
extern crate uucore;
use getopts::Options;
use std::fs::File;
use std::io::{self, stdin, Read, Write, BufReader};
#[cfg(not(windows))]
@ -25,8 +23,9 @@ use crc_table::CRC_TABLE;
mod crc_table;
static NAME: &'static str = "cksum";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTIONS] [FILE]...";
static SUMMARY: &'static str = "Print CRC and size for each file";
static LONG_HELP: &'static str = "";
#[inline]
fn crc_update(crc: u32, input: u8) -> u32 {
@ -88,31 +87,8 @@ fn cksum(fname: &str) -> io::Result<(u32, usize)> {
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = Options::new();
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(err) => panic!("{}", err),
};
if matches.opt_present("help") {
let msg = format!("{0} {1}
Usage:
{0} [OPTIONS] [FILE]...
Print CRC and size for each file.", NAME, VERSION);
print!("{}", opts.usage(&msg));
return 0;
}
if matches.opt_present("version") {
println!("{} {}", NAME, VERSION);
return 0;
}
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.parse(args);
let files = matches.free;

View file

@ -8,8 +8,9 @@ name = "uu_comm"
path = "comm.rs"
[dependencies]
getopts = "*"
libc = "*"
getopts = "*"
uucore = { path="../uucore" }
[[bin]]
name = "comm"

View file

@ -11,14 +11,17 @@
extern crate getopts;
use getopts::Options;
#[macro_use]
extern crate uucore;
use std::cmp::Ordering;
use std::fs::File;
use std::io::{self, BufRead, BufReader, stdin, Stdin};
use std::path::Path;
static NAME: &'static str = "comm";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTIONS] FILE1 FILE2";
static SUMMARY: &'static str = "Compare sorted files line by line";
static LONG_HELP: &'static str = "";
fn mkdelim(col: usize, opts: &getopts::Matches) -> String {
let mut s = String::new();
@ -122,39 +125,12 @@ fn open_file(name: &str) -> io::Result<LineReader> {
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = Options::new();
opts.optflag("1", "", "suppress column 1 (lines uniq to FILE1)");
opts.optflag("2", "", "suppress column 2 (lines uniq to FILE2)");
opts.optflag("3", "", "suppress column 3 (lines that appear in both files)");
opts.optopt("", "output-delimiter", "separate columns with STR", "STR");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(err) => panic!("{}", err),
};
if matches.opt_present("version") {
println!("{} {}", NAME, VERSION);
return 0;
}
if matches.opt_present("help") || matches.free.len() != 2 {
let msg = format!("{0} {1}
Usage:
{0} [OPTIONS] FILE1 FILE2
Compare sorted files line by line.", NAME, VERSION);
print!("{}", opts.usage(&msg));
if matches.free.len() != 2 {
return 1;
}
return 0;
}
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("1", "", "suppress column 1 (lines uniq to FILE1)")
.optflag("2", "", "suppress column 2 (lines uniq to FILE2)")
.optflag("3", "", "suppress column 3 (lines that appear in both files)")
.optopt("", "output-delimiter", "separate columns with STR", "STR")
.parse(args);
let mut f1 = open_file(matches.free[0].as_ref()).unwrap();
let mut f2 = open_file(matches.free[1].as_ref()).unwrap();

View file

@ -8,7 +8,6 @@ name = "uu_dircolors"
path = "dircolors.rs"
[dependencies]
getopts = "*"
glob = "*"
libc = "*"
uucore = { path="../uucore" }

View file

@ -10,20 +10,23 @@
extern crate libc;
extern crate glob;
extern crate getopts;
#[macro_use]
extern crate uucore;
use getopts::Options;
use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::borrow::Borrow;
use std::env;
static NAME: &'static str = "dircolors";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTION]... [FILE]";
static SUMMARY: &'static str = "Output commands to set the LS_COLORS environment variable.";
static LONG_HELP: &'static str = "
If FILE is specified, read it to determine which colors to use for which
file types and extensions. Otherwise, a precompiled database is used.
For details on the format of these files, run 'dircolors --print-database'
";
mod colors;
use colors::INTERNAL_DB;
@ -55,49 +58,15 @@ pub fn guess_syntax() -> OutputFmt {
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = Options::new();
opts.optflag("b", "sh", "output Bourne shell code to set LS_COLORS");
opts.optflag("",
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("b", "sh", "output Bourne shell code to set LS_COLORS")
.optflag("",
"bourne-shell",
"output Bourne shell code to set LS_COLORS");
opts.optflag("c", "csh", "output C shell code to set LS_COLORS");
opts.optflag("", "c-shell", "output C shell code to set LS_COLORS");
opts.optflag("p", "print-database", "print the byte counts");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => {
disp_err!("{}", f);
return 1;
}
};
if matches.opt_present("help") {
println!("Usage: {} [OPTION]... [FILE]
Output commands to set the LS_COLORS environment variable.
Determine format of output:
-b, --sh, --bourne-shell output Bourne shell code to set LS_COLORS
-c, --csh, --c-shell output C shell code to set LS_COLORS
-p, --print-database output defaults
--help display this help and exit
--version output version information and exit
If FILE is specified, read it to determine which colors to use for which
file types and extensions. Otherwise, a precompiled database is used.
For details on the format of these files, run 'dircolors --print-database'.",
NAME);
return 0;
}
if matches.opt_present("version") {
println!("{} {}", NAME, VERSION);
return 0;
}
"output Bourne shell code to set LS_COLORS")
.optflag("c", "csh", "output C shell code to set LS_COLORS")
.optflag("", "c-shell", "output C shell code to set LS_COLORS")
.optflag("p", "print-database", "print the byte counts")
.parse(args);
if (matches.opt_present("csh") || matches.opt_present("c-shell") ||
matches.opt_present("sh") || matches.opt_present("bourne-shell")) &&

View file

@ -8,8 +8,8 @@ name = "uu_dirname"
path = "dirname.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }
[[bin]]
name = "dirname"

View file

@ -9,42 +9,24 @@
* file that was distributed with this source code.
*/
extern crate getopts;
#[macro_use]
extern crate uucore;
use std::path::Path;
static NAME: &'static str = "dirname";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static NAME: &'static str = "dirname";
static SYNTAX: &'static str = "[OPTION] NAME...";
static SUMMARY: &'static str = "strip last component from file name";
static LONG_HELP: &'static str = "
Output each NAME with its last non-slash component and trailing slashes
removed; if NAME contains no /'s, output '.' (meaning the current
directory).
";
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = getopts::Options::new();
opts.optflag("z", "zero", "separate output with NUL rather than newline");
opts.optflag("", "help", "display this help and exit");
opts.optflag("", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => panic!("Invalid options\n{}", f)
};
if matches.opt_present("help") {
let msg = format!("{0} {1} - strip last component from file name
Usage:
{0} [OPTION] NAME...
Output each NAME with its last non-slash component and trailing slashes
removed; if NAME contains no /'s, output '.' (meaning the current
directory).", NAME, VERSION);
print!("{}", opts.usage(&msg));
return 0;
}
if matches.opt_present("version") {
println!("{} {}", NAME, VERSION);
return 0;
}
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("z", "zero", "separate output with NUL rather than newline")
.parse(args);
let separator = if matches.opt_present("zero") {"\0"} else {"\n"};

View file

@ -8,7 +8,6 @@ name = "uu_du"
path = "du.rs"
[dependencies]
getopts = "*"
libc = "*"
time = "*"
uucore = { path="../uucore" }

View file

@ -11,7 +11,6 @@
#![allow(non_snake_case)]
extern crate getopts;
extern crate libc;
extern crate time;
@ -27,8 +26,18 @@ use time::Timespec;
use std::sync::mpsc::channel;
use std::thread;
static NAME: &'static str = "du";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static NAME: &'static str = "du";
static SUMMARY: &'static str = "estimate file space usage";
static LONG_HELP: &'static str = "
Display values are in units of the first available SIZE from
--block-size, and the DU_BLOCK_SIZE, BLOCK_SIZE and BLOCKSIZE environ
ment variables. Otherwise, units default to 1024 bytes (or 512 if
POSIXLY_CORRECT is set).
SIZE is an integer and optional unit (example: 10M is 10*1024*1024).
Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB, ... (pow
ers of 1000).
";
struct Options {
all: bool,
@ -119,22 +128,23 @@ fn du(path: &PathBuf, mut my_stat: Stat, options: Arc<Options>, depth: usize) ->
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = getopts::Options::new();
let syntax = format!("[OPTION]... [FILE]...
{0} [OPTION]... --files0-from=F", NAME);
let matches = new_coreopts!(&syntax, SUMMARY, LONG_HELP)
// In task
opts.optflag("a", "all", " write counts for all files, not just directories");
.optflag("a", "all", " write counts for all files, not just directories")
// In main
opts.optflag("", "apparent-size", "print apparent sizes, rather than disk usage;
.optflag("", "apparent-size", "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");
in ('sparse') files, internal fragmentation, indirect blocks, and the like")
// In main
opts.optopt("B", "block-size", "scale sizes by SIZE before printing them.
.optopt("B", "block-size", "scale sizes by SIZE before printing them.
E.g., '-BM' prints sizes in units of 1,048,576 bytes. See SIZE format below.",
"SIZE");
"SIZE")
// In main
opts.optflag("b", "bytes", "equivalent to '--apparent-size --block-size=1'");
.optflag("b", "bytes", "equivalent to '--apparent-size --block-size=1'")
// In main
opts.optflag("c", "total", "produce a grand total");
.optflag("c", "total", "produce a grand total")
// In task
// opts.optflag("D", "dereference-args", "dereference only symlinks that are listed
// on the command line"),
@ -145,25 +155,25 @@ pub fn uumain(args: Vec<String>) -> i32 {
// // In task
// opts.optflag("H", "", "equivalent to --dereference-args (-D)"),
// In main
opts.optflag("h", "human-readable", "print sizes in human readable format (e.g., 1K 234M 2G)");
.optflag("h", "human-readable", "print sizes in human readable format (e.g., 1K 234M 2G)")
// In main
opts.optflag("", "si", "like -h, but use powers of 1000 not 1024");
.optflag("", "si", "like -h, but use powers of 1000 not 1024")
// In main
opts.optflag("k", "", "like --block-size=1K");
.optflag("k", "", "like --block-size=1K")
// In task
opts.optflag("l", "count-links", "count sizes many times if hard linked");
.optflag("l", "count-links", "count sizes many times if hard linked")
// // In main
opts.optflag("m", "", "like --block-size=1M");
.optflag("m", "", "like --block-size=1M")
// // In task
// opts.optflag("L", "dereference", "dereference all symbolic links"),
// // In task
// opts.optflag("P", "no-dereference", "don't follow any symbolic links (this is the default)"),
// // In main
opts.optflag("0", "null", "end each output line with 0 byte rather than newline");
.optflag("0", "null", "end each output line with 0 byte rather than newline")
// In main
opts.optflag("S", "separate-dirs", "do not include size of subdirectories");
.optflag("S", "separate-dirs", "do not include size of subdirectories")
// In main
opts.optflag("s", "summarize", "display only a total for each argument");
.optflag("s", "summarize", "display only a total for each argument")
// // In task
// opts.optflag("x", "one-file-system", "skip directories on different file systems"),
// // In task
@ -171,52 +181,17 @@ pub fn uumain(args: Vec<String>) -> i32 {
// // In task
// opts.optopt("", "exclude", "exclude files that match PATTERN", "PATTERN"),
// In main
opts.optopt("d", "max-depth", "print the total for a directory (or file, with --all)
.optopt("d", "max-depth", "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", "N");
line argument; --max-depth=0 is the same as --summarize", "N")
// In main
opts.optflagopt("", "time", "show time of the last modification of any file in the
.optflagopt("", "time", "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 or status", "WORD");
atime, access, use, ctime or status", "WORD")
// In main
opts.optopt("", "time-style", "show times using style STYLE:
full-iso, long-iso, iso, +FORMAT FORMAT is interpreted like 'date'", "STYLE");
opts.optflag("", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => {
show_error!("Invalid options\n{}", f);
return 1;
}
};
if matches.opt_present("help") {
println!("{program} {version} - estimate file space usage
Usage
{program} [OPTION]... [FILE]...
{program} [OPTION]... --files0-from=F
{usage}
Display values are in units of the first available SIZE from
--block-size, and the DU_BLOCK_SIZE, BLOCK_SIZE and BLOCKSIZE environ
ment variables. Otherwise, units default to 1024 bytes (or 512 if
POSIXLY_CORRECT is set).
SIZE is an integer and optional unit (example: 10M is 10*1024*1024).
Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB, ... (pow
ers of 1000).",
program = NAME,
version = VERSION,
usage = opts.usage("Summarize disk usage of each FILE, recursively for directories."));
return 0;
} else if matches.opt_present("version") {
println!("{} {}", NAME, VERSION);
return 0;
}
.optopt("", "time-style", "show times using style STYLE:
full-iso, long-iso, iso, +FORMAT FORMAT is interpreted like 'date'", "STYLE")
.parse(args);
let summarize = matches.opt_present("summarize");

View file

@ -8,7 +8,6 @@ name = "uu_echo"
path = "echo.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }

View file

@ -9,7 +9,6 @@
* file that was distributed with this source code.
*/
extern crate getopts;
extern crate libc;
#[macro_use]
@ -19,8 +18,25 @@ use std::io::Write;
use std::str::from_utf8;
#[allow(dead_code)]
static NAME: &'static str = "echo";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTIONS]... [STRING]...";
static SUMMARY: &'static str = "display a line of text";
static LONG_HELP: &'static str = r#"
Echo the STRING(s) to standard output.
If -e is in effect, the following sequences are recognized:
\\\\ backslash
\\a alert (BEL)
\\b backspace
\\c produce no further output
\\e escape
\\f form feed
\\n new line
\\r carriage return
\\t horizontal tab
\\v vertical tab
\\0NNN byte with octal value NNN (1 to 3 digits)
\\xHH byte with hexadecimal value HH (1 to 2 digits)
"#;
#[derive(Clone)]
struct EchoOptions {
@ -77,101 +93,21 @@ fn convert_str(string: &[u8], index: usize, base: u32) -> (char, usize) {
}
}
fn parse_options(args: Vec<String>, options: &mut EchoOptions) -> Option<Vec<String>> {
let mut echo_args = vec!();
'argloop: for arg in args.into_iter().skip(1) {
match arg.as_ref() {
"--help" | "-h" => {
print_help();
return None;
}
"--version" | "-V" => {
print_version();
return None;
}
"-n" => options.newline = true,
"-e" => options.escape = true,
"-E" => options.escape = false,
_ => {
if arg.len() > 1 && arg.chars().next().unwrap_or('_') == '-' {
let mut newopts = options.clone();
for ch in arg.chars().skip(1) {
match ch {
'h' => {
print_help();
return None;
}
'V' => {
print_version();
return None;
}
'n' => newopts.newline = true,
'e' => newopts.escape = true,
'E' => newopts.escape = false,
_ => {
echo_args.push(arg.clone());
continue 'argloop;
}
}
}
*options = newopts;
} else {
echo_args.push(arg);
}
}
}
}
Some(echo_args)
}
fn print_help() {
let mut opts = getopts::Options::new();
opts.optflag("n", "", "do not output the trailing newline");
opts.optflag("e", "", "enable interpretation of backslash escapes");
opts.optflag("E", "", "disable interpretation of backslash escapes (default)");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let msg = format!("{0} {1} - display a line of text
Usage:
{0} [SHORT-OPTION]... [STRING]...
{0} LONG-OPTION
Echo the STRING(s) to standard output.
If -e is in effect, the following sequences are recognized:
\\\\ backslash
\\a alert (BEL)
\\b backspace
\\c produce no further output
\\e escape
\\f form feed
\\n new line
\\r carriage return
\\t horizontal tab
\\v vertical tab
\\0NNN byte with octal value NNN (1 to 3 digits)
\\xHH byte with hexadecimal value HH (1 to 2 digits)", NAME, VERSION);
print!("{}", opts.usage(&msg));
}
fn print_version() {
println!("{} {}", NAME, VERSION);
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut options = EchoOptions {
newline: false,
escape: false
};
let free = match parse_options(args, &mut options) {
Some(vec) => vec,
None => return 0
};
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("n", "", "do not output the trailing newline")
.optflag("e", "", "enable interpretation of backslash escapes")
.optflag("E", "", "disable interpretation of backslash escapes (default)")
.parse(args);
options.newline = matches.opt_present("n");
options.escape = matches.opt_present("e");
let free = matches.free;
if !free.is_empty() {
let string = free.join(" ");
if options.escape {

1
src/env/Cargo.toml vendored
View file

@ -8,7 +8,6 @@ name = "uu_env"
path = "env.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }

38
src/env/env.rs vendored
View file

@ -20,8 +20,12 @@ use std::env;
use std::io::Write;
use std::process::Command;
static NAME: &'static str = "env";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static NAME: &'static str = "env";
static SYNTAX: &'static str = "[OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]";
static SUMMARY: &'static str = "Set each NAME to VALUE in the environment and run COMMAND";
static LONG_HELP: &'static str = "
A mere - implies -i. If no COMMAND, print the resulting environment
";
struct options {
ignore_env: bool,
@ -31,22 +35,6 @@ struct options {
program: Vec<String>
}
fn usage() {
println!("Usage: {} [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]", NAME);
println!("Set each NAME to VALUE in the environment and run COMMAND\n");
println!("Possible options are:");
println!(" -i --ignore-environment\t start with an empty environment");
println!(" -0 --null \t end each output line with a 0 byte rather than newline");
println!(" -u --unset NAME \t remove variable from the environment");
println!(" -h --help \t display this help and exit");
println!(" -V --version \t output version information and exit\n");
println!("A mere - implies -i. If no COMMAND, print the resulting environment");
}
fn version() {
println!("{} {}", NAME, VERSION);
}
// print name=value env pairs on screen
// if null is true, separate pairs with a \0, \n otherwise
fn print_env(null: bool) {
@ -56,7 +44,11 @@ fn print_env(null: bool) {
}
pub fn uumain(args: Vec<String>) -> i32 {
// to handle arguments the same way than GNU env, we can't use getopts
let mut core_opts = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP);
core_opts.optflag("i", "ignore-environment", "start with an empty environment")
.optflag("0", "null", "end each output line with a 0 byte rather than newline")
.optopt("u", "unset", "remove variable from the environment", "NAME");
let mut opts = Box::new(options {
ignore_env: false,
null: false,
@ -94,8 +86,8 @@ pub fn uumain(args: Vec<String>) -> i32 {
}
} else if opt.starts_with("--") {
match opt.as_ref() {
"--help" => { usage(); return 0; }
"--version" => { version(); return 0; }
"--help" => { core_opts.parse(vec![String::from("--help")]); return 0; }
"--version" => { core_opts.parse(vec![String::from("--version")]); return 0; }
"--ignore-environment" => opts.ignore_env = true,
"--null" => opts.null = true,
@ -128,8 +120,6 @@ pub fn uumain(args: Vec<String>) -> i32 {
for c in chars {
// short versions of options
match c {
'h' => { usage(); return 0; }
'V' => { version(); return 0; }
'i' => opts.ignore_env = true,
'0' => opts.null = true,
'u' => {
@ -172,7 +162,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
// read program arguments
for opt in iter {
opts.program.push(opt.clone());
opts.program.push(opt.clone())
}
if opts.ignore_env {

View file

@ -8,9 +8,9 @@ name = "uu_expand"
path = "expand.rs"
[dependencies]
getopts = "*"
libc = "*"
unicode-width = "*"
getopts = "*"
uucore = { path="../uucore" }
[[bin]]

View file

@ -11,9 +11,9 @@
* file that was distributed with this source code.
*/
extern crate getopts;
extern crate libc;
extern crate unicode_width;
extern crate getopts;
#[macro_use]
extern crate uucore;
@ -24,8 +24,10 @@ use std::iter::repeat;
use std::str::from_utf8;
use unicode_width::UnicodeWidthChar;
static NAME: &'static str = "expand";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTION]... [FILE]...";
static SUMMARY: &'static str = "Convert tabs in each FILE to spaces, writing to standard output.
With no FILE, or when FILE is -, read standard input.";
static LONG_HELP: &'static str = "";
static DEFAULT_TABSTOP: usize = 8;
@ -89,32 +91,12 @@ impl Options {
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = getopts::Options::new();
opts.optflag("i", "initial", "do not convert tabs after non blanks");
opts.optopt("t", "tabs", "have tabs NUMBER characters apart, not 8", "NUMBER");
opts.optopt("t", "tabs", "use comma separated list of explicit tab positions", "LIST");
opts.optflag("U", "no-utf8", "interpret input file as 8-bit ASCII rather than UTF-8");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => crash!(1, "{}", f)
};
if matches.opt_present("help") {
println!("Usage: {} [OPTION]... [FILE]...", NAME);
println!("{}", opts.usage(
"Convert tabs in each FILE to spaces, writing to standard output.\n\
With no FILE, or when FILE is -, read standard input."));
return 0;
}
if matches.opt_present("V") {
println!("{} {}", NAME, VERSION);
return 0;
}
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("i", "initial", "do not convert tabs after non blanks")
.optopt("t", "tabs", "have tabs NUMBER characters apart, not 8", "NUMBER")
.optopt("t", "tabs", "use comma separated list of explicit tab positions", "LIST")
.optflag("U", "no-utf8", "interpret input file as 8-bit ASCII rather than UTF-8")
.parse(args);
expand(Options::new(matches));

View file

@ -8,7 +8,6 @@ name = "uu_factor"
path = "factor.rs"
[dependencies]
getopts = "*"
libc = "*"
rand = "*"
uucore = { path="../uucore" }

View file

@ -13,7 +13,6 @@
* that was distributed with this source code.
*/
extern crate getopts;
extern crate libc;
extern crate rand;
@ -31,8 +30,10 @@ use std::mem::swap;
mod numeric;
mod prime_table;
static NAME: &'static str = "factor";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTION] [NUMBER]...";
static SUMMARY: &'static str = "Print the prime factors of the given number(s).
If none are specified, read from standard input.";
static LONG_HELP: &'static str = "";
fn rho_pollard_pseudorandom_function(x: u64, a: u64, b: u64, num: u64) -> u64 {
if num < 1 << 63 {
@ -158,33 +159,8 @@ fn print_factors_str(num_str: &str) {
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = getopts::Options::new();
opts.optflag("h", "help", "show this help message");
opts.optflag("v", "version", "print the version and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => crash!(1, "Invalid options\n{}", f)
};
if matches.opt_present("help") {
let msg = format!("{0} {1}
Usage:
\t{0} [NUMBER]...
\t{0} [OPTION]
Print the prime factors of the given number(s). If none are specified,
read from standard input.", NAME, VERSION);
print!("{}", opts.usage(&msg));
return 1;
}
if matches.opt_present("version") {
println!("{} {}", NAME, VERSION);
return 0;
}
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.parse(args);
if matches.free.is_empty() {
for line in BufReader::new(stdin()).lines() {

View file

@ -8,7 +8,6 @@ name = "uu_fmt"
path = "fmt.rs"
[dependencies]
getopts = "*"
libc = "*"
unicode-width = "*"
uucore = { path="../uucore" }

View file

@ -9,7 +9,6 @@
* file that was distributed with this source code.
*/
extern crate getopts;
extern crate unicode_width;
#[macro_use]
@ -35,8 +34,9 @@ mod linebreak;
mod parasplit;
// program's NAME and VERSION are used for -V and -h
static NAME: &'static str = "fmt";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTION]... [FILE]...";
static SUMMARY: &'static str = "Reformat paragraphs from input files (or stdin) to stdout.";
static LONG_HELP: &'static str = "";
pub type FileOrStdReader = BufReader<Box<Read+'static>>;
pub struct FmtOptions {
@ -58,43 +58,21 @@ pub struct FmtOptions {
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = getopts::Options::new();
opts.optflag("c", "crown-margin", "First and second line of paragraph may have different indentations, in which case the first line's indentation is preserved, and each subsequent line's indentation matches the second line.");
opts.optflag("t", "tagged-paragraph", "Like -c, except that the first and second line of a paragraph *must* have different indentation or they are treated as separate paragraphs.");
opts.optflag("m", "preserve-headers", "Attempt to detect and preserve mail headers in the input. Be careful when combining this flag with -p.");
opts.optflag("s", "split-only", "Split lines only, do not reflow.");
opts.optflag("u", "uniform-spacing", "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.");
opts.optopt("p", "prefix", "Reformat only lines beginning with PREFIX, reattaching PREFIX to reformatted lines. Unless -x is specified, leading whitespace will be ignored when matching PREFIX.", "PREFIX");
opts.optopt("P", "skip-prefix", "Do not reformat lines beginning with PSKIP. Unless -X is specified, leading whitespace will be ignored when matching PSKIP", "PSKIP");
opts.optflag("x", "exact-prefix", "PREFIX must match at the beginning of the line with no preceding whitespace.");
opts.optflag("X", "exact-skip-prefix", "PSKIP must match at the beginning of the line with no preceding whitespace.");
opts.optopt("w", "width", "Fill output lines up to a maximum of WIDTH columns, default 79.", "WIDTH");
opts.optopt("g", "goal", "Goal width, default ~0.94*WIDTH. Must be less than WIDTH.", "GOAL");
opts.optflag("q", "quick", "Break lines more quickly at the expense of a potentially more ragged appearance.");
opts.optopt("T", "tab-width", "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.", "TABWIDTH");
opts.optflag("V", "version", "Output version information and exit.");
opts.optflag("h", "help", "Display this help message and exit.");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => crash!(1, "{}\nTry `{} --help' for more information.", f, NAME)
};
if matches.opt_present("h") {
println!("Usage: {} [OPTION]... [FILE]...\n\n{}", NAME, opts.usage("Reformat paragraphs from input files (or stdin) to stdout."));
}
if matches.opt_present("V") || matches.opt_present("h") {
println!("{} {}", NAME, VERSION);
return 0
}
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("c", "crown-margin", "First and second line of paragraph may have different indentations, in which case the first line's indentation is preserved, and each subsequent line's indentation matches the second line.")
.optflag("t", "tagged-paragraph", "Like -c, except that the first and second line of a paragraph *must* have different indentation or they are treated as separate paragraphs.")
.optflag("m", "preserve-headers", "Attempt to detect and preserve mail headers in the input. Be careful when combining this flag with -p.")
.optflag("s", "split-only", "Split lines only, do not reflow.")
.optflag("u", "uniform-spacing", "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.")
.optopt("p", "prefix", "Reformat only lines beginning with PREFIX, reattaching PREFIX to reformatted lines. Unless -x is specified, leading whitespace will be ignored when matching PREFIX.", "PREFIX")
.optopt("P", "skip-prefix", "Do not reformat lines beginning with PSKIP. Unless -X is specified, leading whitespace will be ignored when matching PSKIP", "PSKIP")
.optflag("x", "exact-prefix", "PREFIX must match at the beginning of the line with no preceding whitespace.")
.optflag("X", "exact-skip-prefix", "PSKIP must match at the beginning of the line with no preceding whitespace.")
.optopt("w", "width", "Fill output lines up to a maximum of WIDTH columns, default 79.", "WIDTH")
.optopt("g", "goal", "Goal width, default ~0.94*WIDTH. Must be less than WIDTH.", "GOAL")
.optflag("q", "quick", "Break lines more quickly at the expense of a potentially more ragged appearance.")
.optopt("T", "tab-width", "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.", "TABWIDTH")
.parse(args);
let mut fmt_opts = FmtOptions {
crown : false,

View file

@ -8,7 +8,6 @@ name = "uu_fold"
path = "fold.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }

View file

@ -9,7 +9,6 @@
* file that was distributed with this source code.
*/
extern crate getopts;
extern crate libc;
#[macro_use]
@ -19,56 +18,40 @@ use std::fs::File;
use std::io::{BufRead, BufReader, Read, stdin, Write};
use std::path::Path;
static NAME: &'static str = "fold";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTION]... [FILE]...";
static SUMMARY: &'static str = "Writes each file (or standard input if no files are given)
to standard output whilst breaking long lines";
static LONG_HELP: &'static str = "";
pub fn uumain(args: Vec<String>) -> i32 {
let (args, obs_width) = handle_obsolete(&args[..]);
let mut opts = getopts::Options::new();
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("b", "bytes", "count using bytes rather than columns (meaning control characters such as newline are not treated specially)")
.optflag("s", "spaces", "break lines at word boundaries rather than a hard cut-off")
.optopt("w", "width", "set WIDTH as the maximum line width rather than 80", "WIDTH")
.parse(args);
opts.optflag("b", "bytes", "count using bytes rather than columns (meaning control characters such as newline are not treated specially)");
opts.optflag("s", "spaces", "break lines at word boundaries rather than a hard cut-off");
opts.optopt("w", "width", "set WIDTH as the maximum line width rather than 80", "WIDTH");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => crash!(1, "{}", f)
};
if matches.opt_present("h") {
println!("{} {}", NAME, VERSION);
println!("");
println!("Usage:");
println!(" {} [OPTION]... [FILE]...", NAME);
println!("");
print!("{}", opts.usage("Writes each file (or standard input if no files are given) to standard output whilst breaking long lines"));
} else if matches.opt_present("V") {
println!("{} {}", NAME, VERSION);
} else {
let bytes = matches.opt_present("b");
let spaces = matches.opt_present("s");
let poss_width =
if matches.opt_present("w") {
matches.opt_str("w")
} else {
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 = if matches.free.is_empty() {
vec!("-".to_owned())
let bytes = matches.opt_present("b");
let spaces = matches.opt_present("s");
let poss_width =
if matches.opt_present("w") {
matches.opt_str("w")
} else {
matches.free
obs_width
};
fold(files, bytes, spaces, 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 = if matches.free.is_empty() {
vec!("-".to_owned())
} else {
matches.free
};
fold(files, bytes, spaces, width);
0
}

View file

@ -21,8 +21,9 @@ use std::fs::File;
use std::path::Path;
use std::str::from_utf8;
static NAME: &'static str = "head";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "";
static SUMMARY: &'static str = "";
static LONG_HELP: &'static str = "";
enum FilterMode {
Bytes(usize),
@ -47,35 +48,19 @@ pub fn uumain(args: Vec<String>) -> i32 {
let mut settings: Settings = Default::default();
// handle obsolete -number syntax
let options = match obsolete(&args[1..]) {
let new_args = match obsolete(&args[0..]) {
(args, Some(n)) => { settings.mode = FilterMode::Lines(n); args },
(args, None) => args
};
let args = options;
let mut opts = getopts::Options::new();
opts.optopt("c", "bytes", "Print the first K bytes. With the leading '-', print all but the last K bytes", "[-]K");
opts.optopt("n", "lines", "Print the first K lines. With the leading '-', print all but the last K lines", "[-]K");
opts.optflag("q", "quiet", "never print headers giving file names");
opts.optflag("v", "verbose", "always print headers giving file names");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = match opts.parse(&args) {
Ok (m) => { m }
Err(_) => {
println!("{}", opts.usage(""));
return 1;
}
};
if matches.opt_present("h") {
println!("{}", opts.usage(""));
return 0;
}
if matches.opt_present("V") { version(); return 0 }
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optopt("c", "bytes", "Print the first K bytes. With the leading '-', print all but the last K bytes", "[-]K")
.optopt("n", "lines", "Print the first K lines. With the leading '-', print all but the last K lines", "[-]K")
.optflag("q", "quiet", "never print headers giving file names")
.optflag("v", "verbose", "always print headers giving file names")
.optflag("h", "help", "display this help and exit")
.optflag("V", "version", "output version information and exit")
.parse(new_args);
let use_bytes = matches.opt_present("c");
@ -155,7 +140,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
// getopts works correctly.
fn obsolete(options: &[String]) -> (Vec<String>, Option<usize>) {
let mut options: Vec<String> = options.to_vec();
let mut a = 0;
let mut a = 1;
let b = options.len();
while a < b {
@ -203,7 +188,3 @@ fn head<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> bool {
}
true
}
fn version() {
println!("{} {}", NAME, VERSION);
}

View file

@ -8,7 +8,6 @@ name = "uu_hostid"
path = "hostid.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }

View file

@ -9,7 +9,6 @@
* that was distributed with this source code.
*/
extern crate getopts;
extern crate libc;
#[macro_use]
@ -17,10 +16,9 @@ extern crate uucore;
use libc::c_long;
static NAME: &'static str = "hostid";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static EXIT_ERR: i32 = 1;
static SYNTAX: &'static str = "[options]";
static SUMMARY: &'static str = "";
static LONG_HELP: &'static str = "";
pub enum Mode {
HostId,
@ -34,44 +32,12 @@ extern {
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = getopts::Options::new();
opts.optflag("", "help", "display this help and exit");
opts.optflag("", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(_) => {
help(&opts);
return EXIT_ERR;
},
};
let mode = if matches.opt_present("version") {
Mode::Version
} else if matches.opt_present("help") {
Mode::Help
} else {
Mode::HostId
};
match mode {
Mode::HostId => hostid(),
Mode::Help => help(&opts),
Mode::Version => version(),
}
new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.parse(args);
hostid();
0
}
fn version() {
println!("{} {}", NAME, VERSION);
}
fn help(opts: &getopts::Options) {
let msg = format!("Usage:\n {} [options]", NAME);
print!("{}", opts.usage(&msg));
}
fn hostid() {
/*
* POSIX says gethostid returns a "32-bit identifier" but is silent

View file

@ -8,7 +8,6 @@ name = "uu_hostname"
path = "hostname.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }

View file

@ -13,21 +13,20 @@
* https://www.opensource.apple.com/source/shell_cmds/shell_cmds-170/hostname/hostname.c?txt
*/
extern crate getopts;
extern crate libc;
#[macro_use]
extern crate uucore;
use getopts::Options;
use std::collections::hash_set::HashSet;
use std::iter::repeat;
use std::str;
use std::io::Write;
use std::net::ToSocketAddrs;
static NAME: &'static str = "hostname";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTION]... [HOSTNAME]";
static SUMMARY: &'static str = "Print or set the system's host name.";
static LONG_HELP: &'static str = "";
extern {
fn gethostname(name: *mut libc::c_char, namelen: libc::size_t) -> libc::c_int;
@ -44,26 +43,12 @@ extern {
}
pub fn uumain(args: Vec<String>) -> i32 {
let program = &args[0];
let mut opts = Options::new();
opts.optflag("d", "domain", "Display the name of the DNS domain if possible");
opts.optflag("i", "ip-address", "Display the network address(es) of the host");
opts.optflag("f", "fqdn", "Display the FQDN (Fully Qualified Domain Name) (default)"); // TODO: support --long
opts.optflag("s", "short", "Display the short hostname (the portion before the first dot) if possible");
opts.optflag("h", "help", "Show help");
opts.optflag("V", "version", "Show program's version");
let matches = match opts.parse(&args[1..]) {
Ok(m) => { m }
_ => { help_menu(program, opts); return 0; }
};
if matches.opt_present("h") {
help_menu(program, opts);
return 0
}
if matches.opt_present("V") { version(); return 0 }
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optflag("d", "domain", "Display the name of the DNS domain if possible")
.optflag("i", "ip-address", "Display the network address(es) of the host")
.optflag("f", "fqdn", "Display the FQDN (Fully Qualified Domain Name) (default)") // TODO: support --long
.optflag("s", "short", "Display the short hostname (the portion before the first dot) if possible")
.parse(args);
match matches.free.len() {
0 => {
@ -120,25 +105,12 @@ pub fn uumain(args: Vec<String>) -> i32 {
}
}
1 => xsethostname(matches.free.last().unwrap()),
_ => help_menu(program, opts)
_ => crash!(1, "{}", msg_wrong_number_of_arguments!(0, 1))
};
0
}
fn version() {
println!("{} {}", NAME, VERSION);
}
fn help_menu(program: &str, options: Options) {
version();
println!("");
println!("Usage:");
println!(" {} [OPTION]... [HOSTNAME]", program);
println!("");
print!("{}", options.usage("Print or set the system's host name."));
}
fn xgethostname() -> String {
let namelen = 256usize;
let mut name : Vec<u8> = repeat(0).take(namelen).collect();

View file

@ -23,10 +23,13 @@ use std::path::{Path, PathBuf};
use std::result::Result;
static NAME: &'static str = "install";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SUMMARY: &'static str = "Copy SOURCE to DEST or multiple SOURCE(s) to the existing
DIRECTORY, while setting permission modes and owner/group";
static LONG_HELP: &'static str = "";
const DEFAULT_MODE: libc::mode_t = 755;
#[allow(dead_code)]
pub struct Behaviour {
main_function: MainFunction,
specified_mode: Option<libc::mode_t>,
@ -36,10 +39,6 @@ pub struct Behaviour {
#[derive(Clone, Eq, PartialEq)]
pub enum MainFunction {
/// Display version information.
Version,
/// Display help, including command line arguments.
Help,
/// Create directories
Directory,
/// Install files to locations (primary functionality)
@ -61,18 +60,7 @@ impl Behaviour {
/// Returns a program return code.
///
pub fn uumain(args: Vec<String>) -> i32 {
let opts = opts();
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => {
show_error!("Invalid options\n{}", f);
return 1;
}
};
let usage = opts.usage("Copy SOURCE to DEST or multiple SOURCE(s) to the existing\n \
DIRECTORY, while setting permission modes and owner/group");
let matches = parse_opts(args);
if let Err(s) = check_unimplemented(&matches) {
show_error!("Unimplemented feature: {}", s);
@ -97,14 +85,6 @@ pub fn uumain(args: Vec<String>) -> i32 {
};
match behaviour.main_function {
MainFunction::Version => {
println!("{} {}", NAME, VERSION);
0
},
MainFunction::Help => {
help(&usage);
0
},
MainFunction::Directory => {
directory(&paths[..], behaviour)
},
@ -118,74 +98,54 @@ pub fn uumain(args: Vec<String>) -> i32 {
///
/// Returns a getopts::Options struct.
///
fn opts() -> getopts::Options {
let mut opts = getopts::Options::new();
fn parse_opts(args: Vec<String>) -> getopts::Matches {
let syntax = format!("SOURCE DEST
{} SOURCE... DIRECTORY", NAME);
new_coreopts!(&syntax, SUMMARY, LONG_HELP)
// TODO implement flag
opts.optflagopt("", "backup", "(unimplemented) make a backup of each existing destination\n \
file", "CONTROL");
.optflagopt("", "backup", "(unimplemented) make a backup of each existing destination\n \
file", "CONTROL")
// TODO implement flag
opts.optflag("b", "", "(unimplemented) like --backup but does not accept an argument");
.optflag("b", "", "(unimplemented) like --backup but does not accept an argument")
// TODO implement flag
opts.optflag("C", "compare", "(unimplemented) compare each pair of source and destination\n \
files, and in some cases, do not modify the destination at all");
opts.optflag("d", "directory", "treat all arguments as directory names;\n \
create all components of the specified directories");
.optflag("C", "compare", "(unimplemented) compare each pair of source and destination\n \
files, and in some cases, do not modify the destination at all")
.optflag("d", "directory", "treat all arguments as directory names\n \
create all components of the specified directories")
// TODO implement flag
opts.optflag("D", "", "(unimplemented) create all leading components of DEST except the\n \
last, then copy SOURCE to DEST");
.optflag("D", "", "(unimplemented) create all leading components of DEST except the\n \
last, then copy SOURCE to DEST")
// TODO implement flag
opts.optflagopt("g", "group", "(unimplemented) set group ownership, instead of process'\n \
current group", "GROUP");
opts.optflagopt("m", "mode", "set permission mode (as in chmod), instead\n \
of rwxr-xr-x", "MODE");
.optflagopt("g", "group", "(unimplemented) set group ownership, instead of process'\n \
current group", "GROUP")
.optflagopt("m", "mode", "set permission mode (as in chmod), instead\n \
of rwxr-xr-x", "MODE")
// TODO implement flag
opts.optflagopt("o", "owner", "(unimplemented) set ownership (super-user only)",
"OWNER");
.optflagopt("o", "owner", "(unimplemented) set ownership (super-user only)",
"OWNER")
// TODO implement flag
opts.optflag("p", "preserve-timestamps", "(unimplemented) apply access/modification times\n \
of SOURCE files to corresponding destination files");
.optflag("p", "preserve-timestamps", "(unimplemented) apply access/modification times\n \
of SOURCE files to corresponding destination files")
// TODO implement flag
opts.optflag("s", "strip", "(unimplemented) strip symbol tables");
.optflag("s", "strip", "(unimplemented) strip symbol tables")
// TODO implement flag
opts.optflagopt("", "strip-program", "(unimplemented) program used to strip binaries",
"PROGRAM");
.optflagopt("", "strip-program", "(unimplemented) program used to strip binaries",
"PROGRAM")
// TODO implement flag
opts.optopt("S", "suffix", "(unimplemented) override the usual backup suffix", "SUFFIX");
.optopt("S", "suffix", "(unimplemented) override the usual backup suffix", "SUFFIX")
// TODO implement flag
opts.optopt("t", "target-directory", "(unimplemented) move all SOURCE arguments into\n \
DIRECTORY", "DIRECTORY");
.optopt("t", "target-directory", "(unimplemented) move all SOURCE arguments into\n \
DIRECTORY", "DIRECTORY")
// TODO implement flag
opts.optflag("T", "no-target-directory", "(unimplemented) treat DEST as a normal file");
.optflag("T", "no-target-directory", "(unimplemented) treat DEST as a normal file")
// TODO implement flag
opts.optflag("v", "verbose", "(unimplemented) explain what is being done");
.optflag("v", "verbose", "(unimplemented) explain what is being done")
// TODO implement flag
opts.optflag("P", "preserve-context", "(unimplemented) preserve security context");
.optflag("P", "preserve-context", "(unimplemented) preserve security context")
// TODO implement flag
opts.optflagopt("Z", "context", "(unimplemented) set security context of files and\n \
directories", "CONTEXT");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
opts
.optflagopt("Z", "context", "(unimplemented) set security context of files and\n \
directories", "CONTEXT")
.parse(args)
}
/// Check for unimplemented command line arguments.
@ -241,11 +201,7 @@ fn check_unimplemented(matches: &getopts::Matches) -> Result<(), &str> {
/// In event of failure, returns an integer intended as a program return code.
///
fn behaviour(matches: &getopts::Matches) -> Result<Behaviour, i32> {
let main_function = if matches.opt_present("version") {
MainFunction::Version
} else if matches.opt_present("help") {
MainFunction::Help
} else if matches.opt_present("directory") {
let main_function = if matches.opt_present("directory") {
MainFunction::Directory
} else {
MainFunction::Standard
@ -295,15 +251,6 @@ fn behaviour(matches: &getopts::Matches) -> Result<Behaviour, i32> {
})
}
/// Print utility help to stdout.
///
fn help(usage: &str) {
println!("{0} {1}\n\n\
Usage: {0} SOURCE DEST\n \
or: {0} SOURCE... DIRECTORY\n\n\
{2}", NAME, VERSION, usage);
}
/// Creates directories.
///
/// GNU man pages describe this functionality as creating 'all components of

View file

@ -8,7 +8,6 @@ name = "uu_kill"
path = "kill.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }

View file

@ -9,7 +9,6 @@
* that was distributed with this source code.
*/
extern crate getopts;
extern crate libc;
#[macro_use]
@ -19,8 +18,9 @@ use libc::{c_int, pid_t};
use std::io::{Error, Write};
use uucore::signals::ALL_SIGNALS;
static NAME: &'static str = "kill";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[options] <pid> [...]";
static SUMMARY: &'static str = "";
static LONG_HELP: &'static str = "";
static EXIT_OK: i32 = 0;
static EXIT_ERR: i32 = 1;
@ -30,34 +30,17 @@ pub enum Mode {
Kill,
Table,
List,
Help,
Version,
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = getopts::Options::new();
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
opts.optopt("s", "signal", "specify the <signal> to be sent", "SIGNAL");
opts.optflagopt("l", "list", "list all signal names, or convert one to a name", "LIST");
opts.optflag("L", "table", "list all signal names in a nice table");
let (args, obs_signal) = handle_obsolete(args);
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.optopt("s", "signal", "specify the <signal> to be sent", "SIGNAL")
.optflagopt("l", "list", "list all signal names, or convert one to a name", "LIST")
.optflag("L", "table", "list all signal names in a nice table")
.parse(args);
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(_) => {
help(&opts);
return EXIT_ERR;
},
};
let mode = if matches.opt_present("version") {
Mode::Version
} else if matches.opt_present("help") {
Mode::Help
} else if matches.opt_present("table") {
let mode = if matches.opt_present("table") {
Mode::Table
} else if matches.opt_present("list") {
Mode::List
@ -69,17 +52,11 @@ pub fn uumain(args: Vec<String>) -> i32 {
Mode::Kill => return kill(&matches.opt_str("signal").unwrap_or(obs_signal.unwrap_or("9".to_owned())), matches.free),
Mode::Table => table(),
Mode::List => list(matches.opt_str("list")),
Mode::Help => help(&opts),
Mode::Version => version(),
}
0
}
fn version() {
println!("{} {}", NAME, VERSION);
}
fn handle_obsolete(mut args: Vec<String>) -> (Vec<String>, Option<String>) {
let mut i = 0;
while i < args.len() {
@ -156,15 +133,6 @@ fn list(arg: Option<String>) {
};
}
fn help(opts: &getopts::Options) {
let msg = format!("{0} {1}
Usage:
{0} [options] <pid> [...]", NAME, VERSION);
println!("{}", opts.usage(&msg));
}
fn kill(signalname: &str, pids: std::vec::Vec<String>) -> i32 {
let mut status = 0;
let optional_signal_value = uucore::signals::signal_by_name_or_value(signalname);

View file

@ -8,7 +8,6 @@ name = "uu_link"
path = "link.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }

View file

@ -9,8 +9,6 @@
* file that was distributed with this source code.
*/
extern crate getopts;
#[macro_use]
extern crate uucore;
@ -19,8 +17,9 @@ use std::io::Write;
use std::path::Path;
use std::io::Error;
static NAME: &'static str = "link";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "[OPTIONS] FILE1 FILE2";
static SUMMARY: &'static str = "Create a link named FILE2 to FILE1";
static LONG_HELP: &'static str = "";
pub fn normalize_error_message(e: Error) -> String {
match e.raw_os_error() {
@ -30,34 +29,10 @@ pub fn normalize_error_message(e: Error) -> String {
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = getopts::Options::new();
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(err) => panic!("{}", err),
};
if matches.opt_present("version") {
println!("{} {}", NAME, VERSION);
return 0;
}
if matches.opt_present("help") || matches.free.len() != 2 {
let msg = format!("{0} {1}
Usage:
{0} [OPTIONS] FILE1 FILE2
Create a link named FILE2 to FILE1.", NAME, VERSION);
println!("{}", opts.usage(&msg));
if matches.free.len() != 2 {
return 1;
}
return 0;
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP)
.parse(args);
if matches.free.len() != 2 {
crash!(1, "{}", msg_wrong_number_of_arguments!(2));
}
let old = Path::new(&matches.free[0]);

View file

@ -8,7 +8,6 @@ name = "uu_ln"
path = "ln.rs"
[dependencies]
getopts = "*"
libc = "*"
uucore = { path="../uucore" }

View file

@ -9,7 +9,6 @@
* file that was distributed with this source code.
*/
extern crate getopts;
#[macro_use]
extern crate uucore;
@ -20,8 +19,18 @@ use std::io::{BufRead, BufReader, Result, stdin, Write};
#[cfg(windows)] use std::os::windows::fs::symlink_file;
use std::path::{Path, PathBuf};
static NAME: &'static str = "ln";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static NAME: &'static str = "ln";
static SUMMARY: &'static str = "";
static LONG_HELP: &'static str = "
In the 1st form, create a link to TARGET with the name LINK_NAME.
In the 2nd form, create a link to TARGET in the current directory.
In the 3rd and 4th forms, create links to each TARGET in DIRECTORY.
Create hard links by default, symbolic links with --symbolic.
By default, each destination (name of new link) should not already exist.
When creating hard links, each TARGET must exist. Symbolic links
can hold arbitrary text; if later resolved, a relative link is
interpreted in relation to its parent directory.
";
pub struct Settings {
overwrite: OverwriteMode,
@ -49,29 +58,26 @@ pub enum BackupMode {
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = getopts::Options::new();
opts.optflag("b", "", "make a backup of each file that would otherwise be overwritten or removed");
opts.optflagopt("", "backup", "make a backup of each file that would otherwise be overwritten or removed", "METHOD");
let syntax = format!("[OPTION]... [-T] TARGET LINK_NAME (1st form)
{0} [OPTION]... TARGET (2nd form)
{0} [OPTION]... TARGET... DIRECTORY (3rd form)
{0} [OPTION]... -t DIRECTORY TARGET... (4th form)", NAME);
let matches = new_coreopts!(&syntax, SUMMARY, LONG_HELP)
.optflag("b", "", "make a backup of each file that would otherwise be overwritten or removed")
.optflagopt("", "backup", "make a backup of each file that would otherwise be overwritten or removed", "METHOD")
// TODO: opts.optflag("d", "directory", "allow users with appropriate privileges to attempt to make hard links to directories");
opts.optflag("f", "force", "remove existing destination files");
opts.optflag("i", "interactive", "prompt whether to remove existing destination files");
.optflag("f", "force", "remove existing destination files")
.optflag("i", "interactive", "prompt whether to remove existing destination files")
// TODO: opts.optflag("L", "logical", "dereference TARGETs that are symbolic links");
// TODO: opts.optflag("n", "no-dereference", "treat LINK_NAME as a normal file if it is a symbolic link to a directory");
// TODO: opts.optflag("P", "physical", "make hard links directly to symbolic links");
// TODO: opts.optflag("r", "relative", "create symbolic links relative to link location");
opts.optflag("s", "symbolic", "make symbolic links instead of hard links");
opts.optopt("S", "suffix", "override the usual backup suffix", "SUFFIX");
opts.optopt("t", "target-directory", "specify the DIRECTORY in which to create the links", "DIRECTORY");
opts.optflag("T", "no-target-directory", "treat LINK_NAME as a normal file always");
opts.optflag("v", "verbose", "print name of each linked file");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(e) => crash!(1, "{}", e),
};
.optflag("s", "symbolic", "make symbolic links instead of hard links")
.optopt("S", "suffix", "override the usual backup suffix", "SUFFIX")
.optopt("t", "target-directory", "specify the DIRECTORY in which to create the links", "DIRECTORY")
.optflag("T", "no-target-directory", "treat LINK_NAME as a normal file always")
.optflag("v", "verbose", "print name of each linked file")
.parse(args);
let overwrite_mode = if matches.opt_present("force") {
OverwriteMode::Force
@ -133,31 +139,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
let string_to_path = |s: &String| { PathBuf::from(s) };
let paths: Vec<PathBuf> = matches.free.iter().map(string_to_path).collect();
if matches.opt_present("version") {
println!("{} {}", NAME, VERSION);
0
} else if matches.opt_present("help") {
let msg = format!("{0} {1}
Usage: {0} [OPTION]... [-T] TARGET LINK_NAME (1st form)
or: {0} [OPTION]... TARGET (2nd form)
or: {0} [OPTION]... TARGET... DIRECTORY (3rd form)
or: {0} [OPTION]... -t DIRECTORY TARGET... (4th form)
In the 1st form, create a link to TARGET with the name LINK_NAME.
In the 2nd form, create a link to TARGET in the current directory.
In the 3rd and 4th forms, create links to each TARGET in DIRECTORY.
Create hard links by default, symbolic links with --symbolic.
By default, each destination (name of new link) should not already exist.
When creating hard links, each TARGET must exist. Symbolic links
can hold arbitrary text; if later resolved, a relative link is
interpreted in relation to its parent directory.", NAME, VERSION);
print!("{}", opts.usage(&msg));
0
} else {
exec(&paths[..], &settings)
}
exec(&paths[..], &settings)
}
fn exec(files: &[PathBuf], settings: &Settings) -> i32 {

View file

@ -11,7 +11,6 @@
/* last synced with: logname (GNU coreutils) 8.22 */
extern crate getopts;
extern crate libc;
#[macro_use]
@ -36,38 +35,12 @@ fn get_userlogin() -> Option<String> {
}
}
static NAME: &'static str = "logname";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static SYNTAX: &'static str = "";
static SUMMARY: &'static str = "Print user's login name";
static LONG_HELP: &'static str = "";
pub fn uumain(args: Vec<String>) -> i32 {
//
// Argument parsing
//
let mut opts = getopts::Options::new();
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => crash!(1, "Invalid options\n{}", f)
};
if matches.opt_present("help") {
let msg = format!("{0} {1}
Usage:
{0}
Print user's login name.", NAME, VERSION);
print!("{}", opts.usage(&msg));
return 0;
}
if matches.opt_present("version") {
println!("{} {}", NAME, VERSION);
return 0;
}
new_coreopts!(SYNTAX, SUMMARY, LONG_HELP).parse(args);
exec();
@ -77,6 +50,6 @@ Print user's login name.", NAME, VERSION);
fn exec() {
match get_userlogin() {
Some(userlogin) => println!("{}", userlogin),
None => println!("{}: no login name", NAME)
None => show_error!("no login name")
}
}

View file

@ -27,7 +27,6 @@ extern crate uucore;
use uucore::libc::{S_ISUID, S_ISGID, S_ISVTX, S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP,
S_IROTH, S_IWOTH, S_IXOTH, mode_t};
use getopts::Options;
use std::fs;
use std::fs::{DirEntry, FileType, Metadata};
use std::path::{Path, PathBuf};
@ -44,15 +43,13 @@ use unicode_width::UnicodeWidthStr;
#[cfg(windows)]
use std::os::windows::fs::MetadataExt;
#[derive(Copy, Clone, PartialEq)]
enum Mode {
Help,
Version,
List,
}
static NAME: &'static str = "ls";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static NAME: &'static str = "ls";
static SUMMARY: &'static str = "";
static LONG_HELP: &'static str = "
By default, ls will list the files and contents of any directories on
the command line, expect that it will ignore files and directories
whose names start with '.'
";
static DEFAULT_COLORS: &'static str = "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:";
@ -76,105 +73,65 @@ lazy_static! {
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = Options::new();
opts.optflag("", "help", "display this help and exit");
opts.optflag("", "version", "output version information and exit");
opts.optflag("a",
let syntax = format!("[OPTION]... DIRECTORY
{0} [OPTION]... [FILE]...", NAME);
let matches = new_coreopts!(&syntax, SUMMARY, LONG_HELP)
.optflag("a",
"all",
"Do not ignore hidden files (files with names that start with '.').");
opts.optflag("A",
"Do not ignore hidden files (files with names that start with '.').")
.optflag("A",
"almost-all",
"In a directory, do not ignore all file names that start with '.', only ignore \
'.' and '..'.");
opts.optflag("c",
'.' and '..'.")
.optflag("c",
"",
"If the long listing format (e.g., -l, -o) is being used, print the status \
change time (the ctime in the inode) instead of the modification time. When \
explicitly sorting by time (--sort=time or -t) or when not using a long listing \
format, sort according to the status change time.");
opts.optflag("d",
format, sort according to the status change time.")
.optflag("d",
"directory",
"Only list the names of directories, rather than listing directory contents. \
This will not follow symbolic links unless one of `--dereference-command-line \
(-H)`, `--dereference (-L)`, or `--dereference-command-line-symlink-to-dir` is \
specified.");
opts.optflag("F",
specified.")
.optflag("F",
"classify",
"Append a character to each file name indicating the file type. Also, for \
regular files that are executable, append '*'. The file type indicators are \
'/' for directories, '@' for symbolic links, '|' for FIFOs, '=' for sockets, \
'>' for doors, and nothing for regular files.");
opts.optflag("h",
'>' for doors, and nothing for regular files.")
.optflag("h",
"human-readable",
"Print human readable file sizes (e.g. 1K 234M 56G).");
opts.optflag("L",
"Print human readable file sizes (e.g. 1K 234M 56G).")
.optflag("L",
"dereference",
"When showing file information for a symbolic link, show information for the \
file the link references rather than the link itself.");
opts.optflag("l", "long", "Display detailed information.");
opts.optflag("r",
file the link references rather than the link itself.")
.optflag("l", "long", "Display detailed information.")
.optflag("r",
"reverse",
"Reverse whatever the sorting method is--e.g., list files in reverse \
alphabetical order, youngest first, smallest first, or whatever.");
opts.optflag("R",
alphabetical order, youngest first, smallest first, or whatever.")
.optflag("R",
"recursive",
"List the contents of all directories recursively.");
opts.optflag("S", "", "Sort by file size, largest first.");
opts.optflag("t",
"List the contents of all directories recursively.")
.optflag("S", "", "Sort by file size, largest first.")
.optflag("t",
"",
"Sort by modification time (the 'mtime' in the inode), newest first.");
opts.optflag("U",
"Sort by modification time (the 'mtime' in the inode), newest first.")
.optflag("U",
"",
"Do not sort; list the files in whatever order they are stored in the \
directory. This is especially useful when listing very large directories, \
since not doing any sorting can be noticeably faster.");
opts.optflag("", "color", "Color output based on file type.");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(e) => {
disp_err!("{}", e);
return 1;
}
};
let mode = if matches.opt_present("version") {
Mode::Version
} else if matches.opt_present("help") {
Mode::Help
} else {
Mode::List
};
match mode {
Mode::Version => version(),
Mode::Help => help(),
Mode::List => list(matches),
}
since not doing any sorting can be noticeably faster.")
.optflag("", "color", "Color output based on file type.")
.parse(args);
list(matches);
0
}
fn version() {
println!("{} {}", NAME, VERSION);
}
fn help() {
let msg = format!("{0} {1}\n\n\
Usage: {0} [OPTION]... DIRECTORY\n \
or: {0} [OPTION]... [FILE]...\n \
\n \
By default, ls will list the files and contents of any directories on \
the command line, expect that it will ignore files and directories \
whose names start with '.'. \n\
\n",
NAME,
VERSION);
println!("{}", msg);
}
fn list(options: getopts::Matches) {
let locs: Vec<String> = if options.free.is_empty() {
vec![String::from(".")]

View file

@ -76,7 +76,7 @@ fn test_wrap_no_arg() {
new_ucmd()
.arg(wrap_param)
.fails()
.stderr_only(format!("base32: Argument to option '{}' missing.\nTry 'base32 --help' for more information.\n",
.stderr_only(format!("base32: error: Argument to option '{}' missing.\n",
if wrap_param == "-w" { "w" } else { "wrap" }));
}
}

View file

@ -68,7 +68,7 @@ fn test_wrap_no_arg() {
new_ucmd()
.arg(wrap_param)
.fails()
.stderr_only(format!("base64: Argument to option '{}' missing.\nTry 'base64 --help' for more information.\n",
.stderr_only(format!("base64: error: Argument to option '{}' missing.\n",
if wrap_param == "-w" { "w" } else { "wrap" }));
}
}

View file

@ -13,7 +13,7 @@ fn test_install_help() {
let (_, mut ucmd) = at_and_ucmd();
assert!(
ucmd.arg("--help").succeeds().no_stderr().stdout.contains("Usage:"));
ucmd.arg("--help").succeeds().no_stderr().stdout.contains("Options:"));
}
#[test]