diff --git a/Makefile b/Makefile index 513c05d26..f03f3067e 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ RUSTC ?= rustc RM := rm # Flags -RUSTCFLAGS := --opt-level=3 -A unused_must_use +RUSTCFLAGS := --opt-level=3 RMFLAGS := # Possible programs diff --git a/base64/base64.rs b/base64/base64.rs index 801154d65..54608cb8a 100644 --- a/base64/base64.rs +++ b/base64/base64.rs @@ -9,14 +9,17 @@ * that was distributed with this source code. */ +#[feature(macro_rules)]; + extern mod extra; +extern mod getopts; use std::char; use std::io::{println, File, stdin, stdout}; use std::os; use std::str; -use extra::getopts::groups::{ +use getopts::{ getopts, optflag, optopt, @@ -25,6 +28,11 @@ use extra::getopts::groups::{ use extra::base64; use extra::base64::{FromBase64, ToBase64}; +#[path = "../util.rs"] +mod util; + +static NAME: &'static str = "base64"; + fn main() { let args = ~os::args(); let opts = ~[ @@ -104,8 +112,14 @@ fn decode(input: &mut Reader, ignore_garbage: bool) { Ok(bytes) => { let mut out = stdout(); - out.write(bytes); - out.flush(); + match out.write(bytes) { + Ok(_) => {} + Err(f) => { crash!(1, "{}", f.to_str()); } + } + match out.flush() { + Ok(_) => {} + Err(f) => { crash!(1, "{}", f.to_str()); } + } } Err(s) => { error!("error: {}", s.to_str()); diff --git a/basename/basename.rs b/basename/basename.rs index e0693a97f..88839a98c 100644 --- a/basename/basename.rs +++ b/basename/basename.rs @@ -11,25 +11,19 @@ */ extern mod extra; +extern mod getopts; use std::io::{print, println}; use std::os; use std::str; use std::str::StrSlice; -use extra::getopts::groups; +#[path = "../util.rs"] +mod util; + +static NAME: &'static str = "basename"; static VERSION: &'static str = "1.0.0"; -#[macro_export] -macro_rules! crash( - ($exitcode:expr, $($args:expr),+) => ( - { ::std::os::set_exit_status($exitcode); - let _unused = write!(&mut ::std::io::stderr(), $($args),+); - return; - } - ) -) - fn main() { let args = os::args(); let program = strip_dir(&args[ 0 ].clone()); @@ -38,11 +32,11 @@ fn main() { // Argument parsing // let opts = ~[ - groups::optflag("h", "help", "display this help and exit"), - groups::optflag("V", "version", "output version information and exit"), + getopts::optflag("h", "help", "display this help and exit"), + getopts::optflag("V", "version", "output version information and exit"), ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => crash!(1, "Invalid options\n{}", f.to_err_msg()) }; @@ -53,7 +47,7 @@ fn main() { println!("Print NAME with any leading directory components removed."); println!("If specified, also remove a trailing SUFFIX."); - print(groups::usage("", opts)); + print(getopts::usage("", opts)); return; } diff --git a/cat/cat.rs b/cat/cat.rs index 41b9e670c..4e5b937a0 100644 --- a/cat/cat.rs +++ b/cat/cat.rs @@ -13,28 +13,28 @@ /* last synced with: cat (GNU coreutils) 8.13 */ extern mod extra; +extern mod getopts; use std::os; use std::io::{print, stdin, stdout, File}; -use extra::getopts::groups; fn main() { let args = os::args(); let program = args[0].clone(); let opts = ~[ - groups::optflag("A", "show-all", "equivalent to -vET"), - groups::optflag("b", "number-nonblank", "number nonempty output lines, overrides -n"), - groups::optflag("e", "", "equivalent to -vE"), - groups::optflag("E", "show-ends", "display $ at end of each line"), - groups::optflag("n", "number", "number all output lines"), - groups::optflag("s", "squeeze-blank", "suppress repeated empty output lines"), - groups::optflag("t", "", "equivalent to -vT"), - groups::optflag("T", "show-tabs", "display TAB characters as ^I"), - groups::optflag("v", "show-nonprinting", "use ^ and M- notation, except for LF (\\n) and TAB (\\t)"), - groups::optflag("h", "help", "display this help and exit"), - groups::optflag("V", "version", "output version information and exit"), + getopts::optflag("A", "show-all", "equivalent to -vET"), + getopts::optflag("b", "number-nonblank", "number nonempty output lines, overrides -n"), + getopts::optflag("e", "", "equivalent to -vE"), + getopts::optflag("E", "show-ends", "display $ at end of each line"), + getopts::optflag("n", "number", "number all output lines"), + getopts::optflag("s", "squeeze-blank", "suppress repeated empty output lines"), + getopts::optflag("t", "", "equivalent to -vT"), + getopts::optflag("T", "show-tabs", "display TAB characters as ^I"), + getopts::optflag("v", "show-nonprinting", "use ^ and M- notation, except for LF (\\n) and TAB (\\t)"), + getopts::optflag("h", "help", "display this help and exit"), + getopts::optflag("V", "version", "output version information and exit"), ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => fail!("Invalid options\n{}", f.to_err_msg()) }; @@ -44,7 +44,7 @@ fn main() { println!("Usage:"); println!(" {0:s} [OPTION]... [FILE]...", program); println!(""); - print(groups::usage("Concatenate FILE(s), or standard input, to standard output.", opts)); + print(getopts::usage("Concatenate FILE(s), or standard input, to standard output.", opts)); println!(""); println!("With no FILE, or when FILE is -, read standard input."); return; diff --git a/dirname/dirname.rs b/dirname/dirname.rs index f2ba61139..1fe84fb97 100644 --- a/dirname/dirname.rs +++ b/dirname/dirname.rs @@ -10,10 +10,10 @@ */ extern mod extra; +extern mod getopts; use std::os; use std::io::print; -use extra::getopts::groups; static VERSION: &'static str = "1.0.0"; @@ -21,12 +21,12 @@ fn main() { let args = os::args(); let program = args[0].clone(); let opts = ~[ - groups::optflag("z", "zero", "separate output with NUL rather than newline"), - groups::optflag("", "help", "display this help and exit"), - groups::optflag("", "version", "output version information and exit"), + getopts::optflag("z", "zero", "separate output with NUL rather than newline"), + getopts::optflag("", "help", "display this help and exit"), + getopts::optflag("", "version", "output version information and exit"), ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => fail!("Invalid options\n{}", f.to_err_msg()) }; @@ -37,7 +37,7 @@ fn main() { println!("Usage:"); println!(" {0:s} [OPTION] NAME...", program); println!(""); - print(groups::usage("Output each NAME with its last non-slash component and trailing slashes + print(getopts::usage("Output each NAME with its last non-slash component and trailing slashes removed; if NAME contains no /'s, output '.' (meaning the current directory).", opts)); return; diff --git a/echo/echo.rs b/echo/echo.rs index ddd7f7a92..b680fbf93 100644 --- a/echo/echo.rs +++ b/echo/echo.rs @@ -11,24 +11,18 @@ */ extern mod extra; +extern mod getopts; use std::os; use std::io::{print, println}; use std::uint; -use extra::getopts::groups; +#[path = "../util.rs"] +mod util; + +static NAME: &'static str = "echo"; static VERSION: &'static str = "1.0.0"; -#[macro_export] -macro_rules! crash( - ($exitcode:expr, $($args:expr),+) => ( - { ::std::os::set_exit_status($exitcode); - let _unused = write!(&mut ::std::io::stderr(), $($args),+); - return; - } - ) -) - fn print_char(c: char) { print!("{}", c); } @@ -79,14 +73,14 @@ fn main() { let args = os::args(); let program = args[0].clone(); let opts = ~[ - groups::optflag("n", "", "do not output the trailing newline"), - groups::optflag("e", "", "enable interpretation of backslash escapes"), - groups::optflag("E", "", "disable interpretation of backslash escapes (default)"), - groups::optflag("h", "help", "display this help and exit"), - groups::optflag("V", "version", "output version information and exit"), + getopts::optflag("n", "", "do not output the trailing newline"), + getopts::optflag("e", "", "enable interpretation of backslash escapes"), + getopts::optflag("E", "", "disable interpretation of backslash escapes (default)"), + getopts::optflag("h", "help", "display this help and exit"), + getopts::optflag("V", "version", "output version information and exit"), ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => crash!(1, "Invalid options\n{}", f.to_err_msg()) }; @@ -98,7 +92,7 @@ fn main() { println!(" {0:s} [SHORT-OPTION]... [STRING]...", program); println!(" {0:s} LONG-OPTION", program); println!(""); - println(groups::usage("Echo the STRING(s) to standard output.", opts)); + println(getopts::usage("Echo the STRING(s) to standard output.", opts)); println("If -e is in effect, the following sequences are recognized: \\\\ backslash diff --git a/mkdir/mkdir.rs b/mkdir/mkdir.rs index 226c8c8bd..f6084dd3b 100644 --- a/mkdir/mkdir.rs +++ b/mkdir/mkdir.rs @@ -1,6 +1,6 @@ #[crate_id(name="mkdir", vers="1.0.0", author="Nicholas Juszczak")]; -/** +/* * This file is part of the uutils coreutils package. * * (c) Nicholas Juszczak @@ -9,13 +9,19 @@ * file that was distributed with this source code. */ +#[feature(macro_rules)]; + extern mod extra; +extern mod getopts; use std::os; -use std::io::{fs, stderr}; +use std::io::fs; use std::num::strconv; -use extra::getopts::groups; +#[path = "../util.rs"] +mod util; + +static NAME: &'static str = "mkdir"; static VERSION: &'static str = "1.0.0"; /** @@ -26,23 +32,20 @@ fn main() { let opts = ~[ // Linux-specific options, not implemented - // groups::optflag("Z", "context", "set SELinux secutiry context" + + // getopts::optflag("Z", "context", "set SELinux secutiry context" + // " of each created directory to CTX"), - groups::optopt("m", "mode", "set file mode", "755"), - groups::optflag("p", "parents", "make parent directories as needed"), - groups::optflag("v", "verbose", + getopts::optopt("m", "mode", "set file mode", "755"), + getopts::optflag("p", "parents", "make parent directories as needed"), + getopts::optflag("v", "verbose", "print a message for each printed directory"), - groups::optflag("h", "help", "display this help"), - groups::optflag("V", "version", "display this version") + getopts::optflag("h", "help", "display this help"), + getopts::optflag("V", "version", "display this version") ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, - "Invalid options\n{}", f.to_err_msg()); - os::set_exit_status(1); - return; + crash!(1, "Invalid options\n{}", f.to_err_msg()); } }; @@ -68,10 +71,7 @@ fn main() { if res.is_some() { res.unwrap() } else { - writeln!(&mut stderr() as &mut Writer, - "Error: no mode given"); - os::set_exit_status(1); - return; + crash!(1, "no mode given"); } } else { 0o755 @@ -81,11 +81,11 @@ fn main() { exec(dirs, mk_parents, mode, verbose_flag); } -fn print_help(opts: &[groups::OptGroup]) { +fn print_help(opts: &[getopts::OptGroup]) { println!("mkdir v{} - make a new directory with the given path", VERSION); println!(""); println!("Usage:"); - print!("{}", groups::usage("Create the given DIRECTORY(ies)" + + print!("{}", getopts::usage("Create the given DIRECTORY(ies)" + " if they do not exist", opts)); } @@ -124,8 +124,7 @@ fn exec(dirs: ~[~str], mk_parents: bool, mode: u32, verbose: bool) { }; let parent_exists = Path::new(parent).exists(); if parent_exists && !path.exists() { - // if mkdir failed return - if !mkdir(&path, mode) {return;} + mkdir(&path, mode); if verbose {println!("{}", *dir);} } else { let mut error_msg = ~""; @@ -138,9 +137,7 @@ fn exec(dirs: ~[~str], mk_parents: bool, mode: u32, verbose: bool) { error_msg.push_str(*dir); error_msg.push_str("' already exists"); } - writeln!(&mut stderr() as &mut Writer, - "{}", error_msg); - os::set_exit_status(1); + show_error!(1, "{}", error_msg); } } } @@ -148,14 +145,11 @@ fn exec(dirs: ~[~str], mk_parents: bool, mode: u32, verbose: bool) { /** * Wrapper to catch errors, return false if failed */ -fn mkdir(path: &Path, mode: u32) -> bool { +fn mkdir(path: &Path, mode: u32) { match fs::mkdir(path, mode) { - Ok(_) => true, + Ok(_) => {}, Err(e) => { - writeln!(&mut stderr() as &mut Writer, - "mkdir: test {}", e.to_str()); - os::set_exit_status(1); - false + crash!(1, "test {}", e.to_str()); } } } diff --git a/printenv/printenv.rs b/printenv/printenv.rs index 4b9614d54..2db559d8e 100644 --- a/printenv/printenv.rs +++ b/printenv/printenv.rs @@ -11,27 +11,31 @@ /* last synced with: printenv (GNU coreutils) 8.13 */ +#[feature(macro_rules)]; + extern mod extra; +extern mod getopts; use std::os; -use std::io::{print, stderr}; -use extra::getopts::groups; +use std::io::print; + +#[path = "../util.rs"] +mod util; + +static NAME: &'static str = "printenv"; fn main() { let args = os::args(); let program = args[0].clone(); let opts = ~[ - groups::optflag("0", "null", "end each output line with 0 byte rather than newline"), - groups::optflag("h", "help", "display this help and exit"), - groups::optflag("V", "version", "output version information and exit"), + getopts::optflag("0", "null", "end each output line with 0 byte rather than newline"), + getopts::optflag("h", "help", "display this help and exit"), + getopts::optflag("V", "version", "output version information and exit"), ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, - "Invalid options\n{}", f.to_err_msg()); - os::set_exit_status(1); - return + crash!(1, "Invalid options\n{}", f.to_err_msg()) } }; if matches.opt_present("help") { @@ -40,7 +44,7 @@ fn main() { println!("Usage:"); println!(" {0:s} [VARIABLE]... [OPTION]...", program); println!(""); - print(groups::usage("Prints the given environment VARIABLE(s), otherwise prints them all.", opts)); + print(getopts::usage("Prints the given environment VARIABLE(s), otherwise prints them all.", opts)); return; } if matches.opt_present("version") { diff --git a/pwd/pwd.rs b/pwd/pwd.rs index e17010919..5f29d81bd 100644 --- a/pwd/pwd.rs +++ b/pwd/pwd.rs @@ -9,30 +9,33 @@ * file that was distributed with this source code. */ +#[feature(macro_rules)]; + extern mod extra; +extern mod getopts; use std::os; -use std::io::{print, stderr}; -use extra::getopts::groups; +use std::io::print; +#[path = "../util.rs"] +mod util; + +static NAME: &'static str = "pwd"; static VERSION: &'static str = "1.0.0"; fn main() { let args = os::args(); let program = args[0].clone(); let opts = ~[ - groups::optflag("", "help", "display this help and exit"), - groups::optflag("", "version", "output version information and exit"), + getopts::optflag("", "help", "display this help and exit"), + getopts::optflag("", "version", "output version information and exit"), ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, - "Invalid options\n{}", f.to_err_msg()); - os::set_exit_status(1); - return - } + crash!(1, "Invalid options\n{}", f.to_err_msg()) + } }; if matches.opt_present("help") { @@ -41,7 +44,7 @@ fn main() { println!("Usage:"); println!(" {0:s} [OPTION] NAME...", program); println!(""); - print(groups::usage("Print the full filename of the current working directory.", opts)); + print(getopts::usage("Print the full filename of the current working directory.", opts)); } else if matches.opt_present("version") { return println!("pwd version: {}", VERSION); } else { diff --git a/rm/rm.rs b/rm/rm.rs index 06367e314..f9056cfc3 100644 --- a/rm/rm.rs +++ b/rm/rm.rs @@ -9,11 +9,16 @@ * file that was distributed with this source code. */ +#[feature(macro_rules)]; + extern mod extra; +extern mod getopts; use std::os; -use std::io::{print,stdin,stderr,stdio,fs,BufferedReader}; -use extra::getopts::groups; +use std::io::{print, stdin, stdio, fs, BufferedReader}; + +#[path = "../util.rs"] +mod util; #[deriving(Eq)] enum InteractiveMode { @@ -22,32 +27,31 @@ enum InteractiveMode { InteractiveAlways } +static NAME: &'static str = "rm"; + fn main() { let args = os::args(); let program = args[0].clone(); // TODO: make getopts support -R in addition to -r let opts = ~[ - groups::optflag("f", "force", "ignore nonexistent files and arguments, never prompt"), - groups::optflag("i", "", "prompt before every removal"), - groups::optflag("I", "", "prompt once before removing more than three files, or when removing recursively. Less intrusive than -i, while still giving some protection against most mistakes"), - groups::optflagopt("", "interactive", "prompt according to WHEN: never, once (-I), or always (-i). Without WHEN, prompts always", "WHEN"), - groups::optflag("", "one-file-system", "when removing a hierarchy recursively, skip any directory that is on a file system different from that of the corresponding command line argument (NOT IMPLEMENTED)"), - groups::optflag("", "no-preserve-root", "do not treat '/' specially"), - groups::optflag("", "preserve-root", "do not remove '/' (default)"), - groups::optflag("r", "recursive", "remove directories and their contents recursively"), - groups::optflag("d", "dir", "remove empty directories"), - groups::optflag("v", "verbose", "explain what is being done"), - groups::optflag("h", "help", "display this help and exit"), - groups::optflag("V", "version", "output version information and exit") + getopts::optflag("f", "force", "ignore nonexistent files and arguments, never prompt"), + getopts::optflag("i", "", "prompt before every removal"), + getopts::optflag("I", "", "prompt once before removing more than three files, or when removing recursively. Less intrusive than -i, while still giving some protection against most mistakes"), + getopts::optflagopt("", "interactive", "prompt according to WHEN: never, once (-I), or always (-i). Without WHEN, prompts always", "WHEN"), + getopts::optflag("", "one-file-system", "when removing a hierarchy recursively, skip any directory that is on a file system different from that of the corresponding command line argument (NOT IMPLEMENTED)"), + getopts::optflag("", "no-preserve-root", "do not treat '/' specially"), + getopts::optflag("", "preserve-root", "do not remove '/' (default)"), + getopts::optflag("r", "recursive", "remove directories and their contents recursively"), + getopts::optflag("d", "dir", "remove empty directories"), + getopts::optflag("v", "verbose", "explain what is being done"), + getopts::optflag("h", "help", "display this help and exit"), + getopts::optflag("V", "version", "output version information and exit") ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, - "{}", f.to_err_msg()); - os::set_exit_status(1); - return + crash!(1, "{}", f.to_err_msg()) } }; if matches.opt_present("help") { @@ -56,7 +60,7 @@ fn main() { println!("Usage:"); println!(" {0:s} [OPTION]... [FILE]...", program); println!(""); - print(groups::usage("Remove (unlink) the FILE(s).", opts)); + print(getopts::usage("Remove (unlink) the FILE(s).", opts)); println!(""); println!("By default, rm does not remove directories. Use the --recursive (-r)"); println!("option to remove each listed directory, too, along with all of its contents"); @@ -73,10 +77,8 @@ fn main() { } else if matches.opt_present("version") { println!("rm 1.0.0"); } else if matches.free.is_empty() { - writeln!(&mut stderr() as &mut Writer, "Missing an argument"); - writeln!(&mut stderr() as &mut Writer, - "For help, try '{0:s} --help'", program); - os::set_exit_status(1); + show_error!(1, "missing an argument"); + show_error!(1, "for help, try '{0:s} --help'", program) } else { let force = matches.opt_present("force"); let interactive = @@ -90,10 +92,7 @@ fn main() { ~"once" => InteractiveOnce, ~"always" => InteractiveAlways, val => { - writeln!(&mut stderr() as &mut Writer, - "Invalid argument to interactive ({})", val); - os::set_exit_status(1); - return + crash!(1, "Invalid argument to interactive ({})", val) } } } else { @@ -130,10 +129,7 @@ fn remove(files: &[~str], force: bool, interactive: InteractiveMode, one_fs: boo let walk_dir = match fs::walk_dir(&file) { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, - "{}", f.to_str()); - os::set_exit_status(1); - return; + crash!(1, "{}", f.to_str()); } }; remove(walk_dir.map(|x| x.as_str().unwrap().to_owned()).to_owned_vec(), force, interactive, one_fs, preserve_root, recursive, dir, verbose); @@ -142,23 +138,19 @@ fn remove(files: &[~str], force: bool, interactive: InteractiveMode, one_fs: boo remove_dir(&file, *filename, interactive, verbose); } else { if recursive { - writeln!(&mut stderr() as &mut Writer, - "Could not remove directory '{}'", - *filename); + show_error!(1, "could not remove directory '{}'", + *filename); } else { - writeln!(&mut stderr() as &mut Writer, - "Could not remove directory '{}' (did you mean to pass '-r'?)", - *filename); + show_error!(1, + "could not remove directory '{}' (did you mean to pass '-r'?)", + *filename); } - os::set_exit_status(1); } } else { remove_file(&file, *filename, interactive, verbose); } } else if !force { - writeln!(&mut stderr() as &mut Writer, - "No such file or directory '{}'", *filename); - os::set_exit_status(1); + show_error!(1, "no such file or directory '{}'", *filename); } } } @@ -174,9 +166,7 @@ fn remove_dir(path: &Path, name: &str, interactive: InteractiveMode, verbose: bo match fs::rmdir(path) { Ok(_) => if verbose { println!("Removed '{}'", name); }, Err(f) => { - writeln!(&mut stderr() as &mut Writer, - "{}", f.to_str()); - os::set_exit_status(1); + show_error!(1, "{}", f.to_str()); } } } @@ -193,9 +183,7 @@ fn remove_file(path: &Path, name: &str, interactive: InteractiveMode, verbose: b match fs::unlink(path) { Ok(_) => if verbose { println!("Removed '{}'", name); }, Err(f) => { - writeln!(&mut stderr() as &mut Writer, - "{}", f.to_str()); - os::set_exit_status(1); + show_error!(1, "{}", f.to_str()); } } } diff --git a/rmdir/rmdir.rs b/rmdir/rmdir.rs index f82b3b691..86121cdb8 100644 --- a/rmdir/rmdir.rs +++ b/rmdir/rmdir.rs @@ -9,29 +9,35 @@ * file that was distributed with this source code. */ +#[feature(macro_rules)]; + extern mod extra; +extern mod getopts; use std::os; -use std::io::{print, stderr, fs}; -use extra::getopts::groups; +use std::io::{print, fs}; + +#[path = "../util.rs"] +mod util; + +static NAME: &'static str = "rmdir"; fn main() { let args = os::args(); let program = args[0].clone(); let opts = ~[ - groups::optflag("", "ignore-fail-on-non-empty", "ignore each failure that is solely because a directory is non-empty"), - groups::optflag("p", "parents", "remove DIRECTORY and its ancestors; e.g., 'rmdir -p a/b/c' is similar to rmdir a/b/c a/b a"), - groups::optflag("v", "verbose", "output a diagnostic for every directory processed"), - groups::optflag("h", "help", "print this help and exit"), - groups::optflag("V", "version", "output version information and exit") + getopts::optflag("", "ignore-fail-on-non-empty", "ignore each failure that is solely because a directory is non-empty"), + getopts::optflag("p", "parents", "remove DIRECTORY and its ancestors; e.g., 'rmdir -p a/b/c' is similar to rmdir a/b/c a/b a"), + getopts::optflag("v", "verbose", "output a diagnostic for every directory processed"), + getopts::optflag("h", "help", "print this help and exit"), + getopts::optflag("V", "version", "output version information and exit") ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, "{}", f.to_err_msg()); - os::set_exit_status(1); - return + show_error!(1, "{}", f.to_err_msg()); + return; } }; @@ -41,14 +47,12 @@ fn main() { println!("Usage:"); println!(" {0:s} [OPTION]... DIRECTORY...", program); println!(""); - print(groups::usage("Remove the DIRECTORY(ies), if they are empty.", opts)); + print(getopts::usage("Remove the DIRECTORY(ies), if they are empty.", opts)); } else if matches.opt_present("version") { println!("rmdir 1.0.0"); } else if matches.free.is_empty() { - writeln!(&mut stderr() as &mut Writer, "Missing an argument"); - writeln!(&mut stderr() as &mut Writer, - "For help, try '{0:s} --help'", program); - os::set_exit_status(1); + show_error!(1, "missing an argument"); + show_error!(1, "for help, try '{0:s} --help'", program); } else { let ignore = matches.opt_present("ignore-fail-on-non-empty"); let parents = matches.opt_present("parents"); @@ -64,14 +68,10 @@ fn remove(dirs: &[~str], ignore: bool, parents: bool, verbose: bool) { if path.is_dir() { remove_dir(&path, dir, ignore, parents, verbose); } else { - writeln!(&mut stderr() as &mut Writer, - "Failed to remove '{}' (file)", *dir); - os::set_exit_status(1); + show_error!(1, "failed to remove '{}' (file)", *dir); } } else { - writeln!(&mut stderr() as &mut Writer, - "No such file or directory '{}'", *dir); - os::set_exit_status(1); + show_error!(1, "no such file or directory '{}'", *dir); } } } @@ -80,9 +80,7 @@ fn remove_dir(path: &Path, dir: &~str, ignore: bool, parents: bool, verbose: boo let mut walk_dir = match fs::walk_dir(path) { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, - "{}", f.to_str()); - os::set_exit_status(1); + show_error!(1, "{}", f.to_str()); return; } }; @@ -100,15 +98,11 @@ fn remove_dir(path: &Path, dir: &~str, ignore: bool, parents: bool, verbose: boo } } Err(f) => { - writeln!(&mut stderr() as &mut Writer, - "{}", f.to_str()); - os::set_exit_status(1); + show_error!(1, "{}", f.to_str()); } } } else if !ignore { - writeln!(&mut stderr() as &mut Writer, - "Failed to remove directory '{}' (non-empty)", *dir); - os::set_exit_status(1); + show_error!(1, "Failed to remove directory '{}' (non-empty)", *dir); } } diff --git a/seq/seq.rs b/seq/seq.rs index bc2214f1a..c9ea54a43 100644 --- a/seq/seq.rs +++ b/seq/seq.rs @@ -1,18 +1,25 @@ #[crate_id(name="seq", vers="1.0.0", author="Daniel MacDougall")]; +#[feature(macro_rules)]; + // TODO: Make -w flag work with decimals // TODO: Support -f flag extern mod extra; +extern mod getopts; use std::os; use std::cmp::max; -use extra::getopts::groups; -fn print_usage(opts: ~[groups::OptGroup]) { +#[path = "../util.rs"] +mod util; + +static NAME: &'static str = "seq"; + +fn print_usage(opts: ~[getopts::OptGroup]) { println!("seq 1.0.0\n"); println!("Usage:\n seq [-w] [-s string] [-t string] [first [step]] last\n"); - println!("{:s}", groups::usage("Print sequences of numbers", opts)); + println!("{:s}", getopts::usage("Print sequences of numbers", opts)); } fn parse_float(s: &str) -> Result{ @@ -30,16 +37,16 @@ fn escape_sequences(s: &str) -> ~str { fn main() { let args = os::args(); let opts = ~[ - groups::optopt("s", "separator", "Separator character (defaults to \\n)", ""), - groups::optopt("t", "terminator", "Terminator character (defaults to separator)", ""), - groups::optflag("w", "widths", "Equalize widths of all numbers by padding with zeros"), - groups::optflag("h", "help", "print this help text and exit"), - groups::optflag("V", "version", "print version and exit"), + getopts::optopt("s", "separator", "Separator character (defaults to \\n)", ""), + getopts::optopt("t", "terminator", "Terminator character (defaults to separator)", ""), + getopts::optflag("w", "widths", "Equalize widths of all numbers by padding with zeros"), + getopts::optflag("h", "help", "print this help text and exit"), + getopts::optflag("V", "version", "print version and exit"), ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => { m } Err(f) => { - println!("{:s}", f.to_err_msg()); + show_error!(1, "{:s}", f.to_err_msg()); print_usage(opts); return; } @@ -53,13 +60,14 @@ fn main() { return; } if matches.free.len() < 1 || matches.free.len() > 3 { + os::set_exit_status(1); print_usage(opts); return; } let first = if matches.free.len() > 1 { match parse_float(matches.free[0]) { Ok(n) => n, - Err(s) => { println!("{:s}", s); return; } + Err(s) => { show_error!(1, "{:s}", s); return; } } } else { 1.0 @@ -67,14 +75,14 @@ fn main() { let step = if matches.free.len() > 2 { match parse_float(matches.free[1]) { Ok(n) => n, - Err(s) => { println!("{:s}", s); return; } + Err(s) => { show_error!(1, "{:s}", s); return; } } } else { 1.0 }; let last = match parse_float(matches.free[matches.free.len()-1]) { Ok(n) => n, - Err(s) => { println!("{:s}", s); return; } + Err(s) => { show_error!(1, "{:s}", s); return; } }; let separator = escape_sequences(matches.opt_str("s").unwrap_or(~"\n")); let terminator = escape_sequences(matches.opt_str("t").unwrap_or(separator.clone())); diff --git a/sleep/sleep.rs b/sleep/sleep.rs index b1cab4e23..b0318b780 100644 --- a/sleep/sleep.rs +++ b/sleep/sleep.rs @@ -9,27 +9,33 @@ * file that was distributed with this source code. */ +#[feature(macro_rules)]; + extern mod extra; +extern mod getopts; use std::num; use std::cast; use std::os; -use std::io::{print, stderr, timer}; -use extra::getopts::groups; +use std::io::{print, timer}; + +#[path = "../util.rs"] +mod util; + +static NAME: &'static str = "sleep"; fn main() { let args = os::args(); let program = args[0].clone(); let opts = ~[ - groups::optflag("h", "help", "display this help and exit"), - groups::optflag("V", "version", "output version information and exit") + getopts::optflag("h", "help", "display this help and exit"), + getopts::optflag("V", "version", "output version information and exit") ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, "{}", f.to_err_msg()); - os::set_exit_status(1); + show_error!(1, "{}", f.to_err_msg()); return } }; @@ -42,7 +48,7 @@ fn main() { println!("or"); println!(" {0:s} OPTION", program); println!(""); - print(groups::usage("Pause for NUMBER seconds. SUFFIX may be 's' for seconds (the default), + print(getopts::usage("Pause for NUMBER seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days. Unlike most implementations that require NUMBER be an integer, here NUMBER may be an arbitrary floating point number. Given two or more arguments, pause for the amount of time @@ -50,53 +56,35 @@ specified by the sum of their values.", opts)); } else if matches.opt_present("version") { println!("sleep 1.0.0"); } else if matches.free.is_empty() { - writeln!(&mut stderr() as &mut Writer, "Missing an argument"); - writeln!(&mut stderr() as &mut Writer, - "For help, try '{0:s} --help'", program); - os::set_exit_status(1); + show_error!(1, "missing an argument"); + show_error!(1, "for help, try '{0:s} --help'", program); } else { sleep(matches.free); } } fn sleep(args: &[~str]) { - let mut failed = false; let sleep_time = args.iter().fold(0.0, |result, arg| { - if failed { - 0.0 - } else { - unsafe { - let suffix_time = match match_suffix(cast::transmute(arg)) { - Ok(m) => m, - Err(f) => { - writeln!(&mut stderr() as &mut Writer, "{}", f); - failed = true; - os::set_exit_status(1); - 0 - } - }; - let num = - if suffix_time == 0 { - 0.0 - } else { - match num::from_str_radix::((*arg), 10) { - Some(m) => m, - None => { - writeln!(&mut stderr() as &mut Writer, - "Invalid time interval '{}'", *arg); - failed = true; - os::set_exit_status(1); - 0.0 - } - } - }; - result + num * suffix_time as f64 + let suffix_time = match match_suffix(unsafe { cast::transmute(arg) }) { + Ok(m) => m, + Err(f) => { + crash!(1, "{}", f) } - } + }; + let num = + if suffix_time == 0 { + 0.0 + } else { + match num::from_str_radix::((*arg), 10) { + Some(m) => m, + None => { + crash!(1, "Invalid time interval '{}'", *arg) + } + } + }; + result + num * suffix_time as f64 }); - if !failed { - timer::sleep((sleep_time * 1000.0) as u64); - } + timer::sleep((sleep_time * 1000.0) as u64); } fn match_suffix(arg: &mut ~str) -> Result { diff --git a/tee/tee.rs b/tee/tee.rs index d59b7fd78..64842c4aa 100644 --- a/tee/tee.rs +++ b/tee/tee.rs @@ -11,13 +11,13 @@ */ extern mod extra; +extern mod getopts; use std::io::{println, stdin, stdout, Append, File, Truncate, Write}; -use std::io::{io_error, EndOfFile}; -use std::io::signal::{Interrupt, Listener}; +use std::io::{IoResult}; use std::io::util::{copy, NullWriter, MultiWriter}; use std::os::{args, set_exit_status}; -use extra::getopts::groups::{getopts, optflag, usage}; +use getopts::{getopts, optflag, usage}; static NAME: &'static str = "tee"; static VERSION: &'static str = "1.0.0"; @@ -77,75 +77,73 @@ fn exec(options: Options) -> Result<(), ()> { } fn tee(options: Options) -> Result<(), ()> { - let mut handler = Listener::new(); - if options.ignore_interrupts { - handler.register(Interrupt); + let writers = options.files.map(|path| open(path, options.append)); + let output = &mut MultiWriter::new(writers); + let input = &mut NamedReader { inner: ~stdin() as ~Reader }; + if copy(input, output).is_err() || output.flush().is_err() { + Err(()) + } else { + Ok(()) } - let mut ok = true; - io_error::cond.trap(|_| ok = false).inside(|| { - let writers = options.files.map(|path| open(path, options.append)); - let output = &mut MultiWriter::new(writers); - let input = &mut NamedReader { inner: ~stdin() as ~Reader }; - copy(input, output); - output.flush(); - }); - if ok { Ok(()) } else { Err(()) } } fn open(path: &Path, append: bool) -> ~Writer { - let inner = with_path(path, || if *path == Path::new("-") { + let inner = if *path == Path::new("-") { ~stdout() as ~Writer } else { let mode = if append { Append } else { Truncate }; match File::open_mode(path, mode, Write) { - Some(file) => ~file as ~Writer, - None => ~NullWriter as ~Writer + Ok(file) => ~file as ~Writer, + Err(_) => ~NullWriter as ~Writer } - }); + }; ~NamedWriter { inner: inner, path: ~path.clone() } as ~Writer } struct NamedWriter { - priv inner: ~Writer, - priv path: ~Path + inner: ~Writer, + path: ~Path } impl Writer for NamedWriter { - fn write(&mut self, buf: &[u8]) { - with_path(self.path, || io_error::cond.trap(|e| { - self.inner = ~NullWriter as ~Writer; - io_error::cond.raise(e); - }).inside(|| self.inner.write(buf))) + fn write(&mut self, buf: &[u8]) -> IoResult<()> { + with_path(self.path, || { + let val = self.inner.write(buf); + if val.is_err() { + self.inner = ~NullWriter as ~Writer; + } + val + }) } - fn flush(&mut self) { - with_path(self.path, || io_error::cond.trap(|e| { - self.inner = ~NullWriter as ~Writer; - io_error::cond.raise(e); - }).inside(|| self.inner.flush())) + fn flush(&mut self) -> IoResult<()> { + with_path(self.path, || { + let val = self.inner.flush(); + if val.is_err() { + self.inner = ~NullWriter as ~Writer; + } + val + }) } } struct NamedReader { - priv inner: ~Reader + inner: ~Reader } impl Reader for NamedReader { - fn read(&mut self, buf: &mut [u8]) -> Option { - with_path(&Path::new("stdin"), || io_error::cond.trap(|e| { - if e.kind != EndOfFile { - io_error::cond.raise(e) - } - }).inside(|| self.inner.read(buf))) - + fn read(&mut self, buf: &mut [u8]) -> IoResult { + with_path(&Path::new("stdin"), || { + self.inner.read(buf) + }) } } -fn with_path(path: &Path, cb: || -> T) -> T { - io_error::cond.trap(|e| { - warn(format!("{}: {}", path.display(), e.desc)); - io_error::cond.raise(e); - }).inside(cb) +fn with_path(path: &Path, cb: || -> IoResult) -> IoResult { + match cb() { + Err(f) => { warn(format!("{}: {}", path.display(), f.to_str())); Err(f) } + okay => okay + } } fn warn(message: &str) { diff --git a/truncate/test.rs b/truncate/test.rs index 712152176..2bfe4ae8c 100644 --- a/truncate/test.rs +++ b/truncate/test.rs @@ -1,11 +1,11 @@ use std::{run, io}; static PROG: &'static str = "build/truncate"; -static TESTNAME: &'static str = "THISISARANDOMFILENAME"; +static TFILE1: &'static str = "truncate_test_1"; +static TFILE2: &'static str = "truncate_test_2"; -fn make_file() -> io::File { - while Path::new(TESTNAME).exists() { io::timer::sleep(1000); } - match io::File::create(&Path::new(TESTNAME)) { +fn make_file(name: &str) -> io::File { + match io::File::create(&Path::new(name)) { Ok(f) => f, Err(_) => fail!() } @@ -13,22 +13,22 @@ fn make_file() -> io::File { #[test] fn test_increase_file_size() { - let mut file = make_file(); - if !run::process_status(PROG, [~"-s", ~"+5K", TESTNAME.to_owned()]).unwrap().success() { + let mut file = make_file(TFILE1); + if !run::process_status(PROG, [~"-s", ~"+5K", TFILE1.to_owned()]).unwrap().success() { fail!(); } file.seek(0, io::SeekEnd); if file.tell().unwrap() != 5 * 1024 { fail!(); } - io::fs::unlink(&Path::new(TESTNAME)); + io::fs::unlink(&Path::new(TFILE1)); } #[test] fn test_decrease_file_size() { - let mut file = make_file(); + let mut file = make_file(TFILE2); file.write(bytes!("1234567890")); - if !run::process_status(PROG, [~"--size=-4", TESTNAME.to_owned()]).unwrap().success() { + if !run::process_status(PROG, [~"--size=-4", TFILE2.to_owned()]).unwrap().success() { fail!(); } file.seek(0, io::SeekEnd); @@ -36,5 +36,5 @@ fn test_decrease_file_size() { println!("{}", file.tell()); fail!(); } - io::fs::unlink(&Path::new(TESTNAME)); + io::fs::unlink(&Path::new(TFILE2)); } diff --git a/truncate/truncate.rs b/truncate/truncate.rs index 2b698204f..dc82ab64e 100644 --- a/truncate/truncate.rs +++ b/truncate/truncate.rs @@ -12,35 +12,35 @@ #[feature(macro_rules)]; extern mod extra; +extern mod getopts; -use std::io::{stderr, File, Open, ReadWrite, Writer, SeekEnd, SeekSet}; +use std::io::{File, Open, ReadWrite, SeekEnd, SeekSet}; use std::os; use std::u64; -use extra::getopts::groups; + +#[path = "../util.rs"] +mod util; macro_rules! get_file_size( ($file:ident, $action:expr) => ({ match $file.seek(0, SeekEnd) { Ok(_) => {} Err(f) => { - writeln!(&mut stderr() as &mut Writer, "{}", f.to_str()); - os::set_exit_status(1); + show_error!(1, "{}", f.to_str()); $action } } let size = match $file.tell() { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, "{}", f.to_str()); - os::set_exit_status(1); + show_error!(1, "{}", f.to_str()); $action } }; match $file.seek(0, SeekSet) { Ok(_) => {} Err(f) => { - writeln!(&mut stderr() as &mut Writer, "{}", f.to_str()); - os::set_exit_status(1); + show_error!(1, "{}", f.to_str()); $action } } @@ -59,24 +59,24 @@ enum TruncateMode { RoundUp } +static NAME: &'static str = "truncate"; + fn main() { let args = os::args(); let program = args[0].clone(); let opts = ~[ - groups::optflag("c", "no-create", "do not create files that do not exist"), - groups::optflag("o", "io-blocks", "treat SIZE as the number of I/O blocks of the file rather than bytes (NOT IMPLEMENTED)"), - groups::optopt("r", "reference", "base the size of each file on the size of RFILE", "RFILE"), - groups::optopt("s", "size", "set or adjust the size of each file according to SIZE, which is in bytes unless --io-blocks is specified", "SIZE"), - groups::optflag("h", "help", "display this help and exit"), - groups::optflag("V", "version", "output version information and exit") + getopts::optflag("c", "no-create", "do not create files that do not exist"), + getopts::optflag("o", "io-blocks", "treat SIZE as the number of I/O blocks of the file rather than bytes (NOT IMPLEMENTED)"), + getopts::optopt("r", "reference", "base the size of each file on the size of RFILE", "RFILE"), + getopts::optopt("s", "size", "set or adjust the size of each file according to SIZE, which is in bytes unless --io-blocks is specified", "SIZE"), + getopts::optflag("h", "help", "display this help and exit"), + getopts::optflag("V", "version", "output version information and exit") ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, "{}", f.to_err_msg()); - os::set_exit_status(1); - return + crash!(1, "{}", f.to_err_msg()) } }; @@ -86,7 +86,7 @@ fn main() { println!("Usage:"); println!(" {0:s} [OPTION]... FILE...", program); println!(""); - print!("{}", groups::usage("Shrink or extend the size of each file to the specified size.", opts)); + print!("{}", getopts::usage("Shrink or extend the size of each file to the specified size.", opts)); print!(" SIZE is an integer with an optional prefix and optional unit. The available units (K, M, G, T, P, E, Z, and Y) use the following format: @@ -108,18 +108,15 @@ file based on its current size: } else if matches.opt_present("version") { println!("truncate 1.0.0"); } else if matches.free.is_empty() { - writeln!(&mut stderr() as &mut Writer, "Missing an argument"); - writeln!(&mut stderr() as &mut Writer, - "For help, try '{0:s} --help'", program); - os::set_exit_status(1); + show_error!(1, "missing an argument"); + crash!(1, "for help, try '{0:s} --help'", program); } else { let no_create = matches.opt_present("no-create"); let io_blocks = matches.opt_present("io-blocks"); let reference = matches.opt_str("reference"); let size = matches.opt_str("size"); if reference.is_none() && size.is_none() { - writeln!(&mut stderr() as &mut Writer, "You must specify either --reference or --size."); - os::set_exit_status(1); + crash!(1, "you must specify either --reference or --size"); } else { truncate(no_create, io_blocks, reference, size, matches.free); } @@ -132,19 +129,12 @@ fn truncate(no_create: bool, io_blocks: bool, reference: Option<~str>, size: Opt let mut rfile = match File::open(&Path::new(rfilename.clone())) { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, "{}", f.to_str()); - os::set_exit_status(1); - return + crash!(1, "{}", f.to_str()) } }; (get_file_size!(rfile, return), Reference) } - None => { - match parse_size(size.unwrap()) { - Ok(szpair) => szpair, - Err(()) => return - } - } + None => parse_size(size.unwrap()) }; for filename in filenames.iter() { let filename: &str = *filename; @@ -165,23 +155,19 @@ fn truncate(no_create: bool, io_blocks: bool, reference: Option<~str>, size: Opt match file.truncate(tsize as i64) { Ok(_) => {} Err(f) => { - writeln!(&mut stderr() as &mut Writer, - "{}", f.to_str()); - os::set_exit_status(1); + show_error!(1, "{}", f.to_str()); } } } Err(f) => { - writeln!(&mut stderr() as &mut Writer, "{}", f.to_str()); - os::set_exit_status(1); + show_error!(1, "{}", f.to_str()); } } } } } -fn parse_size(size: ~str) -> Result<(u64, TruncateMode), ()> { - let mut err = false; +fn parse_size(size: ~str) -> (u64, TruncateMode) { let mode = match size.char_at(0) { '+' => Extend, '-' => Reduce, @@ -210,14 +196,10 @@ fn parse_size(size: ~str) -> Result<(u64, TruncateMode), ()> { let mut number = match u64::parse_bytes(bytes, 10) { Some(num) => num, None => { - writeln!(&mut stderr() as &mut Writer, - "'{}' is not a valid number.", size); - os::set_exit_status(1); - err = true; - 0 + crash!(1, "'{}' is not a valid number.", size) } }; - if !err && size.char_at(size.len() - 1).is_alphabetic() { + if size.char_at(size.len() - 1).is_alphabetic() { number *= match size.char_at(size.len() - 1).to_ascii().to_upper().to_char() { 'B' => match size.char_at(size.len() - 2).to_ascii().to_upper().to_char() { 'K' => 1000, @@ -229,11 +211,7 @@ fn parse_size(size: ~str) -> Result<(u64, TruncateMode), ()> { 'Z' => 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000, 'Y' => 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000, letter => { - writeln!(&mut stderr() as &mut Writer, - "'{}B' is not a valid suffix.", letter); - os::set_exit_status(1); - err = true; - 1 + crash!(1, "'{}B' is not a valid suffix.", letter) } }, 'K' => 1024, @@ -245,18 +223,10 @@ fn parse_size(size: ~str) -> Result<(u64, TruncateMode), ()> { 'Z' => 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024, 'Y' => 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024, letter => { - writeln!(&mut stderr() as &mut Writer, - "'{}' is not a valid suffix.", letter); - os::set_exit_status(1); - err = true; - 1 + crash!(1, "'{}' is not a valid suffix.", letter) } }; } - if err { - Err(()) - } else { - Ok((number, mode)) - } + (number, mode) } diff --git a/tty/tty.rs b/tty/tty.rs index c04dc9c2a..883d73448 100644 --- a/tty/tty.rs +++ b/tty/tty.rs @@ -12,23 +12,33 @@ * Synced with http://lingrok.org/xref/coreutils/src/tty.c */ +#[allow(dead_code)]; + +#[feature(macro_rules)]; + extern mod extra; +extern mod getopts; use std::{libc,str,os}; use std::io::println; use std::io::stdio::stderr; -use extra::getopts::{optflag,getopts}; +use getopts::{optflag,getopts}; + +#[path = "../util.rs"] +mod util; extern { fn ttyname(filedesc: libc::c_int) -> *libc::c_char; fn isatty(filedesc: libc::c_int) -> libc::c_int; } +static NAME: &'static str = "tty"; + fn main () { let args = os::args(); let options = [ - optflag("s") + optflag("s", "silent", "print nothing, only return an exit status") ]; let silent = match getopts(args.tail(), options) { @@ -64,6 +74,6 @@ fn main () { } fn usage () { - writeln!(&mut stderr() as &mut Writer, "usage: tty [-s]"); + safe_writeln!(&mut stderr() as &mut Writer, "usage: tty [-s]"); os::set_exit_status(2); } diff --git a/users/users.rs b/users/users.rs index 496db81b9..3ecf79e7b 100644 --- a/users/users.rs +++ b/users/users.rs @@ -14,7 +14,10 @@ // Allow dead code here in order to keep all fields, constants here, for consistency. #[allow(dead_code)]; +#[feature(macro_rules)]; + extern mod extra; +extern mod getopts; use std::io::print; use std::cast; @@ -22,7 +25,9 @@ use std::libc; use std::os; use std::ptr; use std::str; -use extra::getopts::groups; + +#[path = "../util.rs"] +mod util; static DEFAULT_FILE: &'static str = "/var/run/utmp"; @@ -75,15 +80,17 @@ extern { fn utmpname(file: *libc::c_char) -> libc::c_int; } +static NAME: &'static str = "users"; + fn main() { let args = os::args(); let program = args[0].as_slice(); let opts = ~[ - groups::optflag("h", "help", "display this help and exit"), - groups::optflag("V", "version", "output version information and exit"), + getopts::optflag("h", "help", "display this help and exit"), + getopts::optflag("V", "version", "output version information and exit"), ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => fail!(f.to_err_msg()), }; @@ -94,7 +101,7 @@ fn main() { println!("Usage:"); println!(" {:s} [OPTION]... [FILE]", program); println!(""); - print(groups::usage("Output who is currently logged in according to FILE.", opts)); + print(getopts::usage("Output who is currently logged in according to FILE.", opts)); return; } diff --git a/util.rs b/util.rs new file mode 100644 index 000000000..7e851ddf4 --- /dev/null +++ b/util.rs @@ -0,0 +1,47 @@ +/* + * This file is part of the uutils coreutils package. + * + * (c) Arcterus + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#[macro_escape]; + +#[macro_export] +macro_rules! show_error( + ($exitcode:expr, $($args:expr),+) => ({ + ::std::os::set_exit_status($exitcode); + safe_write!(&mut ::std::io::stderr(), "{}: error: ", NAME); + safe_writeln!(&mut ::std::io::stderr(), $($args),+); + }) +) + +#[macro_export] +macro_rules! crash( + ($exitcode:expr, $($args:expr),+) => ({ + show_error!($exitcode, $($args),+); + unsafe { ::std::libc::exit($exitcode); } + }) +) + +#[macro_export] +macro_rules! safe_write( + ($fd:expr, $($args:expr),+) => ( + match write!($fd, $($args),+) { + Ok(_) => {} + Err(f) => { fail!(f.to_str()); } + } + ) +) + +#[macro_export] +macro_rules! safe_writeln( + ($fd:expr, $($args:expr),+) => ( + match writeln!($fd, $($args),+) { + Ok(_) => {} + Err(f) => { fail!(f.to_str()); } + } + ) +) diff --git a/wc/wc.rs b/wc/wc.rs index 47d852d41..f53ce4334 100644 --- a/wc/wc.rs +++ b/wc/wc.rs @@ -9,12 +9,18 @@ * file that was distributed with this source code. */ +#[feature(macro_rules)]; + extern mod extra; +extern mod getopts; use std::os; use std::str::from_utf8; -use std::io::{print, stdin, stderr, File, BufferedReader}; -use extra::getopts::{groups, Matches}; +use std::io::{print, stdin, File, BufferedReader}; +use getopts::Matches; + +#[path = "../util.rs"] +mod util; struct Result { filename: ~str, @@ -25,26 +31,25 @@ struct Result { max_line_length: uint, } +static NAME: &'static str = "wc"; + fn main() { let args = os::args(); let program = args[0].clone(); let opts = ~[ - groups::optflag("c", "bytes", "print the byte counts"), - groups::optflag("m", "chars", "print the character counts"), - groups::optflag("l", "lines", "print the newline counts"), - groups::optflag("L", "max-line-length", "print the length of the longest line"), - groups::optflag("w", "words", "print the word counts"), - groups::optflag("h", "help", "display this help and exit"), - groups::optflag("V", "version", "output version information and exit"), + getopts::optflag("c", "bytes", "print the byte counts"), + getopts::optflag("m", "chars", "print the character counts"), + getopts::optflag("l", "lines", "print the newline counts"), + getopts::optflag("L", "max-line-length", "print the length of the longest line"), + getopts::optflag("w", "words", "print the word counts"), + getopts::optflag("h", "help", "display this help and exit"), + getopts::optflag("V", "version", "output version information and exit"), ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, - "Invalid options\n{}", f.to_err_msg()); - os::set_exit_status(1); - return + crash!(1, "Invalid options\n{}", f.to_err_msg()) } }; @@ -52,7 +57,7 @@ fn main() { println!("Usage:"); println!(" {0:s} [OPTION]... [FILE]...", program); println!(""); - print(groups::usage("Print newline, word and byte counts for each FILE", opts)); + print(getopts::usage("Print newline, word and byte counts for each FILE", opts)); println!(""); println!("With no FILE, or when FILE is -, read standard input."); return; @@ -229,8 +234,7 @@ fn open(path: ~str) -> Option> { return Some(BufferedReader::new(reader)); }, Err(e) => { - writeln!(&mut stderr() as &mut Writer, "wc: {0:s}: {1:s}", path, e.desc.to_str()); - os::set_exit_status(1); + show_error!(1, "wc: {0:s}: {1:s}", path, e.desc.to_str()); } } diff --git a/whoami/whoami.rs b/whoami/whoami.rs index 520ef0f89..dc393ad77 100644 --- a/whoami/whoami.rs +++ b/whoami/whoami.rs @@ -11,13 +11,18 @@ /* last synced with: whoami (GNU coreutils) 8.21 */ +#[feature(macro_rules)]; + extern mod extra; +extern mod getopts; use std::io::print; use std::os; use std::str; use std::libc; -use extra::getopts::groups; + +#[path = "../util.rs"] +mod util; struct c_passwd { pw_name: *libc::c_char, @@ -38,16 +43,18 @@ unsafe fn getusername() -> ~str { name } +static NAME: &'static str = "whoami"; + fn main() { let args = os::args(); let program = args[0].as_slice(); let opts = ~[ - groups::optflag("h", "help", "display this help and exit"), - groups::optflag("V", "version", "output version information and exit"), + getopts::optflag("h", "help", "display this help and exit"), + getopts::optflag("V", "version", "output version information and exit"), ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, - Err(f) => fail!(f.to_err_msg()), + Err(f) => crash!(1, "{}", f.to_err_msg()), }; if matches.opt_present("help") { println!("whoami 1.0.0"); @@ -55,7 +62,7 @@ fn main() { println!("Usage:"); println!(" {:s}", program); println!(""); - print(groups::usage("print effective userid", opts)); + print(getopts::usage("print effective userid", opts)); return; } if matches.opt_present("version") { diff --git a/yes/yes.rs b/yes/yes.rs index 02dfbddc7..0a2c84db9 100644 --- a/yes/yes.rs +++ b/yes/yes.rs @@ -11,26 +11,30 @@ /* last synced with: yes (GNU coreutils) 8.13 */ +#[feature(macro_rules)]; + extern mod extra; +extern mod getopts; use std::os; -use std::io::{print, println, stderr}; -use extra::getopts::groups; +use std::io::{print, println}; + +#[path = "../util.rs"] +mod util; + +static NAME: &'static str = "yes"; fn main() { let args = os::args(); let program = args[0].clone(); let opts = ~[ - groups::optflag("h", "help", "display this help and exit"), - groups::optflag("V", "version", "output version information and exit"), + getopts::optflag("h", "help", "display this help and exit"), + getopts::optflag("V", "version", "output version information and exit"), ]; - let matches = match groups::getopts(args.tail(), opts) { + let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - writeln!(&mut stderr() as &mut Writer, - "Invalid options\n{}", f.to_err_msg()); - os::set_exit_status(1); - return + crash!(1, "invalid options\n{}", f.to_err_msg()) } }; if matches.opt_present("help") { @@ -39,7 +43,7 @@ fn main() { println!("Usage:"); println!(" {0:s} [STRING]... [OPTION]...", program); println!(""); - print(groups::usage("Repeatedly output a line with all specified STRING(s), or 'y'.", opts)); + print(getopts::usage("Repeatedly output a line with all specified STRING(s), or 'y'.", opts)); return; } if matches.opt_present("version") {