1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

Fix programs for latest Rust and begin usage of new utility macros

This commit is contained in:
Arcterus 2014-02-06 22:39:07 -08:00
parent bdb01f172c
commit 74df4d5a98
22 changed files with 433 additions and 405 deletions

View file

@ -3,7 +3,7 @@ RUSTC ?= rustc
RM := rm RM := rm
# Flags # Flags
RUSTCFLAGS := --opt-level=3 -A unused_must_use RUSTCFLAGS := --opt-level=3
RMFLAGS := RMFLAGS :=
# Possible programs # Possible programs

View file

@ -9,14 +9,17 @@
* that was distributed with this source code. * that was distributed with this source code.
*/ */
#[feature(macro_rules)];
extern mod extra; extern mod extra;
extern mod getopts;
use std::char; use std::char;
use std::io::{println, File, stdin, stdout}; use std::io::{println, File, stdin, stdout};
use std::os; use std::os;
use std::str; use std::str;
use extra::getopts::groups::{ use getopts::{
getopts, getopts,
optflag, optflag,
optopt, optopt,
@ -25,6 +28,11 @@ use extra::getopts::groups::{
use extra::base64; use extra::base64;
use extra::base64::{FromBase64, ToBase64}; use extra::base64::{FromBase64, ToBase64};
#[path = "../util.rs"]
mod util;
static NAME: &'static str = "base64";
fn main() { fn main() {
let args = ~os::args(); let args = ~os::args();
let opts = ~[ let opts = ~[
@ -104,8 +112,14 @@ fn decode(input: &mut Reader, ignore_garbage: bool) {
Ok(bytes) => { Ok(bytes) => {
let mut out = stdout(); let mut out = stdout();
out.write(bytes); match out.write(bytes) {
out.flush(); Ok(_) => {}
Err(f) => { crash!(1, "{}", f.to_str()); }
}
match out.flush() {
Ok(_) => {}
Err(f) => { crash!(1, "{}", f.to_str()); }
}
} }
Err(s) => { Err(s) => {
error!("error: {}", s.to_str()); error!("error: {}", s.to_str());

View file

@ -11,25 +11,19 @@
*/ */
extern mod extra; extern mod extra;
extern mod getopts;
use std::io::{print, println}; use std::io::{print, println};
use std::os; use std::os;
use std::str; use std::str;
use std::str::StrSlice; 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"; 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() { fn main() {
let args = os::args(); let args = os::args();
let program = strip_dir(&args[ 0 ].clone()); let program = strip_dir(&args[ 0 ].clone());
@ -38,11 +32,11 @@ fn main() {
// Argument parsing // Argument parsing
// //
let opts = ~[ let opts = ~[
groups::optflag("h", "help", "display this help and exit"), getopts::optflag("h", "help", "display this help and exit"),
groups::optflag("V", "version", "output version information 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, Ok(m) => m,
Err(f) => crash!(1, "Invalid options\n{}", f.to_err_msg()) 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!("Print NAME with any leading directory components removed.");
println!("If specified, also remove a trailing SUFFIX."); println!("If specified, also remove a trailing SUFFIX.");
print(groups::usage("", opts)); print(getopts::usage("", opts));
return; return;
} }

View file

@ -13,28 +13,28 @@
/* last synced with: cat (GNU coreutils) 8.13 */ /* last synced with: cat (GNU coreutils) 8.13 */
extern mod extra; extern mod extra;
extern mod getopts;
use std::os; use std::os;
use std::io::{print, stdin, stdout, File}; use std::io::{print, stdin, stdout, File};
use extra::getopts::groups;
fn main() { fn main() {
let args = os::args(); let args = os::args();
let program = args[0].clone(); let program = args[0].clone();
let opts = ~[ let opts = ~[
groups::optflag("A", "show-all", "equivalent to -vET"), getopts::optflag("A", "show-all", "equivalent to -vET"),
groups::optflag("b", "number-nonblank", "number nonempty output lines, overrides -n"), getopts::optflag("b", "number-nonblank", "number nonempty output lines, overrides -n"),
groups::optflag("e", "", "equivalent to -vE"), getopts::optflag("e", "", "equivalent to -vE"),
groups::optflag("E", "show-ends", "display $ at end of each line"), getopts::optflag("E", "show-ends", "display $ at end of each line"),
groups::optflag("n", "number", "number all output lines"), getopts::optflag("n", "number", "number all output lines"),
groups::optflag("s", "squeeze-blank", "suppress repeated empty output lines"), getopts::optflag("s", "squeeze-blank", "suppress repeated empty output lines"),
groups::optflag("t", "", "equivalent to -vT"), getopts::optflag("t", "", "equivalent to -vT"),
groups::optflag("T", "show-tabs", "display TAB characters as ^I"), getopts::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)"), getopts::optflag("v", "show-nonprinting", "use ^ and M- notation, except for LF (\\n) and TAB (\\t)"),
groups::optflag("h", "help", "display this help and exit"), getopts::optflag("h", "help", "display this help and exit"),
groups::optflag("V", "version", "output version information 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, Ok(m) => m,
Err(f) => fail!("Invalid options\n{}", f.to_err_msg()) Err(f) => fail!("Invalid options\n{}", f.to_err_msg())
}; };
@ -44,7 +44,7 @@ fn main() {
println!("Usage:"); println!("Usage:");
println!(" {0:s} [OPTION]... [FILE]...", program); println!(" {0:s} [OPTION]... [FILE]...", program);
println!(""); 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!("");
println!("With no FILE, or when FILE is -, read standard input."); println!("With no FILE, or when FILE is -, read standard input.");
return; return;

View file

@ -10,10 +10,10 @@
*/ */
extern mod extra; extern mod extra;
extern mod getopts;
use std::os; use std::os;
use std::io::print; use std::io::print;
use extra::getopts::groups;
static VERSION: &'static str = "1.0.0"; static VERSION: &'static str = "1.0.0";
@ -21,12 +21,12 @@ fn main() {
let args = os::args(); let args = os::args();
let program = args[0].clone(); let program = args[0].clone();
let opts = ~[ let opts = ~[
groups::optflag("z", "zero", "separate output with NUL rather than newline"), getopts::optflag("z", "zero", "separate output with NUL rather than newline"),
groups::optflag("", "help", "display this help and exit"), getopts::optflag("", "help", "display this help and exit"),
groups::optflag("", "version", "output version information 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, Ok(m) => m,
Err(f) => fail!("Invalid options\n{}", f.to_err_msg()) Err(f) => fail!("Invalid options\n{}", f.to_err_msg())
}; };
@ -37,7 +37,7 @@ fn main() {
println!("Usage:"); println!("Usage:");
println!(" {0:s} [OPTION] NAME...", program); println!(" {0:s} [OPTION] NAME...", program);
println!(""); 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 removed; if NAME contains no /'s, output '.' (meaning the current
directory).", opts)); directory).", opts));
return; return;

View file

@ -11,24 +11,18 @@
*/ */
extern mod extra; extern mod extra;
extern mod getopts;
use std::os; use std::os;
use std::io::{print, println}; use std::io::{print, println};
use std::uint; use std::uint;
use extra::getopts::groups;
#[path = "../util.rs"]
mod util;
static NAME: &'static str = "echo";
static VERSION: &'static str = "1.0.0"; 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) { fn print_char(c: char) {
print!("{}", c); print!("{}", c);
} }
@ -79,14 +73,14 @@ fn main() {
let args = os::args(); let args = os::args();
let program = args[0].clone(); let program = args[0].clone();
let opts = ~[ let opts = ~[
groups::optflag("n", "", "do not output the trailing newline"), getopts::optflag("n", "", "do not output the trailing newline"),
groups::optflag("e", "", "enable interpretation of backslash escapes"), getopts::optflag("e", "", "enable interpretation of backslash escapes"),
groups::optflag("E", "", "disable interpretation of backslash escapes (default)"), getopts::optflag("E", "", "disable interpretation of backslash escapes (default)"),
groups::optflag("h", "help", "display this help and exit"), getopts::optflag("h", "help", "display this help and exit"),
groups::optflag("V", "version", "output version information 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, Ok(m) => m,
Err(f) => crash!(1, "Invalid options\n{}", f.to_err_msg()) 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} [SHORT-OPTION]... [STRING]...", program);
println!(" {0:s} LONG-OPTION", program); println!(" {0:s} LONG-OPTION", program);
println!(""); 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: println("If -e is in effect, the following sequences are recognized:
\\\\ backslash \\\\ backslash

View file

@ -1,6 +1,6 @@
#[crate_id(name="mkdir", vers="1.0.0", author="Nicholas Juszczak")]; #[crate_id(name="mkdir", vers="1.0.0", author="Nicholas Juszczak")];
/** /*
* This file is part of the uutils coreutils package. * This file is part of the uutils coreutils package.
* *
* (c) Nicholas Juszczak <juszczakn@gmail.com> * (c) Nicholas Juszczak <juszczakn@gmail.com>
@ -9,13 +9,19 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
#[feature(macro_rules)];
extern mod extra; extern mod extra;
extern mod getopts;
use std::os; use std::os;
use std::io::{fs, stderr}; use std::io::fs;
use std::num::strconv; 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"; static VERSION: &'static str = "1.0.0";
/** /**
@ -26,23 +32,20 @@ fn main() {
let opts = ~[ let opts = ~[
// Linux-specific options, not implemented // 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"), // " of each created directory to CTX"),
groups::optopt("m", "mode", "set file mode", "755"), getopts::optopt("m", "mode", "set file mode", "755"),
groups::optflag("p", "parents", "make parent directories as needed"), getopts::optflag("p", "parents", "make parent directories as needed"),
groups::optflag("v", "verbose", getopts::optflag("v", "verbose",
"print a message for each printed directory"), "print a message for each printed directory"),
groups::optflag("h", "help", "display this help"), getopts::optflag("h", "help", "display this help"),
groups::optflag("V", "version", "display this version") 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, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, crash!(1, "Invalid options\n{}", f.to_err_msg());
"Invalid options\n{}", f.to_err_msg());
os::set_exit_status(1);
return;
} }
}; };
@ -68,10 +71,7 @@ fn main() {
if res.is_some() { if res.is_some() {
res.unwrap() res.unwrap()
} else { } else {
writeln!(&mut stderr() as &mut Writer, crash!(1, "no mode given");
"Error: no mode given");
os::set_exit_status(1);
return;
} }
} else { } else {
0o755 0o755
@ -81,11 +81,11 @@ fn main() {
exec(dirs, mk_parents, mode, verbose_flag); 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!("mkdir v{} - make a new directory with the given path", VERSION);
println!(""); println!("");
println!("Usage:"); println!("Usage:");
print!("{}", groups::usage("Create the given DIRECTORY(ies)" + print!("{}", getopts::usage("Create the given DIRECTORY(ies)" +
" if they do not exist", opts)); " 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(); let parent_exists = Path::new(parent).exists();
if parent_exists && !path.exists() { if parent_exists && !path.exists() {
// if mkdir failed return mkdir(&path, mode);
if !mkdir(&path, mode) {return;}
if verbose {println!("{}", *dir);} if verbose {println!("{}", *dir);}
} else { } else {
let mut error_msg = ~""; 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(*dir);
error_msg.push_str("' already exists"); error_msg.push_str("' already exists");
} }
writeln!(&mut stderr() as &mut Writer, show_error!(1, "{}", error_msg);
"{}", error_msg);
os::set_exit_status(1);
} }
} }
} }
@ -148,14 +145,11 @@ fn exec(dirs: ~[~str], mk_parents: bool, mode: u32, verbose: bool) {
/** /**
* Wrapper to catch errors, return false if failed * 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) { match fs::mkdir(path, mode) {
Ok(_) => true, Ok(_) => {},
Err(e) => { Err(e) => {
writeln!(&mut stderr() as &mut Writer, crash!(1, "test {}", e.to_str());
"mkdir: test {}", e.to_str());
os::set_exit_status(1);
false
} }
} }
} }

View file

@ -11,27 +11,31 @@
/* last synced with: printenv (GNU coreutils) 8.13 */ /* last synced with: printenv (GNU coreutils) 8.13 */
#[feature(macro_rules)];
extern mod extra; extern mod extra;
extern mod getopts;
use std::os; use std::os;
use std::io::{print, stderr}; use std::io::print;
use extra::getopts::groups;
#[path = "../util.rs"]
mod util;
static NAME: &'static str = "printenv";
fn main() { fn main() {
let args = os::args(); let args = os::args();
let program = args[0].clone(); let program = args[0].clone();
let opts = ~[ let opts = ~[
groups::optflag("0", "null", "end each output line with 0 byte rather than newline"), getopts::optflag("0", "null", "end each output line with 0 byte rather than newline"),
groups::optflag("h", "help", "display this help and exit"), getopts::optflag("h", "help", "display this help and exit"),
groups::optflag("V", "version", "output version information 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, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, crash!(1, "Invalid options\n{}", f.to_err_msg())
"Invalid options\n{}", f.to_err_msg());
os::set_exit_status(1);
return
} }
}; };
if matches.opt_present("help") { if matches.opt_present("help") {
@ -40,7 +44,7 @@ fn main() {
println!("Usage:"); println!("Usage:");
println!(" {0:s} [VARIABLE]... [OPTION]...", program); println!(" {0:s} [VARIABLE]... [OPTION]...", program);
println!(""); 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; return;
} }
if matches.opt_present("version") { if matches.opt_present("version") {

View file

@ -9,29 +9,32 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
#[feature(macro_rules)];
extern mod extra; extern mod extra;
extern mod getopts;
use std::os; use std::os;
use std::io::{print, stderr}; use std::io::print;
use extra::getopts::groups;
#[path = "../util.rs"]
mod util;
static NAME: &'static str = "pwd";
static VERSION: &'static str = "1.0.0"; static VERSION: &'static str = "1.0.0";
fn main() { fn main() {
let args = os::args(); let args = os::args();
let program = args[0].clone(); let program = args[0].clone();
let opts = ~[ let opts = ~[
groups::optflag("", "help", "display this help and exit"), getopts::optflag("", "help", "display this help and exit"),
groups::optflag("", "version", "output version information 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, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, crash!(1, "Invalid options\n{}", f.to_err_msg())
"Invalid options\n{}", f.to_err_msg());
os::set_exit_status(1);
return
} }
}; };
@ -41,7 +44,7 @@ fn main() {
println!("Usage:"); println!("Usage:");
println!(" {0:s} [OPTION] NAME...", program); println!(" {0:s} [OPTION] NAME...", program);
println!(""); 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") { } else if matches.opt_present("version") {
return println!("pwd version: {}", VERSION); return println!("pwd version: {}", VERSION);
} else { } else {

View file

@ -9,11 +9,16 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
#[feature(macro_rules)];
extern mod extra; extern mod extra;
extern mod getopts;
use std::os; use std::os;
use std::io::{print,stdin,stderr,stdio,fs,BufferedReader}; use std::io::{print, stdin, stdio, fs, BufferedReader};
use extra::getopts::groups;
#[path = "../util.rs"]
mod util;
#[deriving(Eq)] #[deriving(Eq)]
enum InteractiveMode { enum InteractiveMode {
@ -22,32 +27,31 @@ enum InteractiveMode {
InteractiveAlways InteractiveAlways
} }
static NAME: &'static str = "rm";
fn main() { fn main() {
let args = os::args(); let args = os::args();
let program = args[0].clone(); let program = args[0].clone();
// TODO: make getopts support -R in addition to -r // TODO: make getopts support -R in addition to -r
let opts = ~[ let opts = ~[
groups::optflag("f", "force", "ignore nonexistent files and arguments, never prompt"), getopts::optflag("f", "force", "ignore nonexistent files and arguments, never prompt"),
groups::optflag("i", "", "prompt before every removal"), getopts::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"), 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"),
groups::optflagopt("", "interactive", "prompt according to WHEN: never, once (-I), or always (-i). Without WHEN, prompts always", "WHEN"), getopts::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)"), 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)"),
groups::optflag("", "no-preserve-root", "do not treat '/' specially"), getopts::optflag("", "no-preserve-root", "do not treat '/' specially"),
groups::optflag("", "preserve-root", "do not remove '/' (default)"), getopts::optflag("", "preserve-root", "do not remove '/' (default)"),
groups::optflag("r", "recursive", "remove directories and their contents recursively"), getopts::optflag("r", "recursive", "remove directories and their contents recursively"),
groups::optflag("d", "dir", "remove empty directories"), getopts::optflag("d", "dir", "remove empty directories"),
groups::optflag("v", "verbose", "explain what is being done"), getopts::optflag("v", "verbose", "explain what is being done"),
groups::optflag("h", "help", "display this help and exit"), getopts::optflag("h", "help", "display this help and exit"),
groups::optflag("V", "version", "output version information 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, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, crash!(1, "{}", f.to_err_msg())
"{}", f.to_err_msg());
os::set_exit_status(1);
return
} }
}; };
if matches.opt_present("help") { if matches.opt_present("help") {
@ -56,7 +60,7 @@ fn main() {
println!("Usage:"); println!("Usage:");
println!(" {0:s} [OPTION]... [FILE]...", program); println!(" {0:s} [OPTION]... [FILE]...", program);
println!(""); println!("");
print(groups::usage("Remove (unlink) the FILE(s).", opts)); print(getopts::usage("Remove (unlink) the FILE(s).", opts));
println!(""); println!("");
println!("By default, rm does not remove directories. Use the --recursive (-r)"); 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"); 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") { } else if matches.opt_present("version") {
println!("rm 1.0.0"); println!("rm 1.0.0");
} else if matches.free.is_empty() { } else if matches.free.is_empty() {
writeln!(&mut stderr() as &mut Writer, "Missing an argument"); show_error!(1, "missing an argument");
writeln!(&mut stderr() as &mut Writer, show_error!(1, "for help, try '{0:s} --help'", program)
"For help, try '{0:s} --help'", program);
os::set_exit_status(1);
} else { } else {
let force = matches.opt_present("force"); let force = matches.opt_present("force");
let interactive = let interactive =
@ -90,10 +92,7 @@ fn main() {
~"once" => InteractiveOnce, ~"once" => InteractiveOnce,
~"always" => InteractiveAlways, ~"always" => InteractiveAlways,
val => { val => {
writeln!(&mut stderr() as &mut Writer, crash!(1, "Invalid argument to interactive ({})", val)
"Invalid argument to interactive ({})", val);
os::set_exit_status(1);
return
} }
} }
} else { } else {
@ -130,10 +129,7 @@ fn remove(files: &[~str], force: bool, interactive: InteractiveMode, one_fs: boo
let walk_dir = match fs::walk_dir(&file) { let walk_dir = match fs::walk_dir(&file) {
Ok(m) => m, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, crash!(1, "{}", f.to_str());
"{}", f.to_str());
os::set_exit_status(1);
return;
} }
}; };
remove(walk_dir.map(|x| x.as_str().unwrap().to_owned()).to_owned_vec(), force, interactive, one_fs, preserve_root, recursive, dir, verbose); 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); remove_dir(&file, *filename, interactive, verbose);
} else { } else {
if recursive { if recursive {
writeln!(&mut stderr() as &mut Writer, show_error!(1, "could not remove directory '{}'",
"Could not remove directory '{}'", *filename);
*filename);
} else { } else {
writeln!(&mut stderr() as &mut Writer, show_error!(1,
"Could not remove directory '{}' (did you mean to pass '-r'?)", "could not remove directory '{}' (did you mean to pass '-r'?)",
*filename); *filename);
} }
os::set_exit_status(1);
} }
} else { } else {
remove_file(&file, *filename, interactive, verbose); remove_file(&file, *filename, interactive, verbose);
} }
} else if !force { } else if !force {
writeln!(&mut stderr() as &mut Writer, show_error!(1, "no such file or directory '{}'", *filename);
"No such file or directory '{}'", *filename);
os::set_exit_status(1);
} }
} }
} }
@ -174,9 +166,7 @@ fn remove_dir(path: &Path, name: &str, interactive: InteractiveMode, verbose: bo
match fs::rmdir(path) { match fs::rmdir(path) {
Ok(_) => if verbose { println!("Removed '{}'", name); }, Ok(_) => if verbose { println!("Removed '{}'", name); },
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, show_error!(1, "{}", f.to_str());
"{}", f.to_str());
os::set_exit_status(1);
} }
} }
} }
@ -193,9 +183,7 @@ fn remove_file(path: &Path, name: &str, interactive: InteractiveMode, verbose: b
match fs::unlink(path) { match fs::unlink(path) {
Ok(_) => if verbose { println!("Removed '{}'", name); }, Ok(_) => if verbose { println!("Removed '{}'", name); },
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, show_error!(1, "{}", f.to_str());
"{}", f.to_str());
os::set_exit_status(1);
} }
} }
} }

View file

@ -9,29 +9,35 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
#[feature(macro_rules)];
extern mod extra; extern mod extra;
extern mod getopts;
use std::os; use std::os;
use std::io::{print, stderr, fs}; use std::io::{print, fs};
use extra::getopts::groups;
#[path = "../util.rs"]
mod util;
static NAME: &'static str = "rmdir";
fn main() { fn main() {
let args = os::args(); let args = os::args();
let program = args[0].clone(); let program = args[0].clone();
let opts = ~[ let opts = ~[
groups::optflag("", "ignore-fail-on-non-empty", "ignore each failure that is solely because a directory is non-empty"), getopts::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"), 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"),
groups::optflag("v", "verbose", "output a diagnostic for every directory processed"), getopts::optflag("v", "verbose", "output a diagnostic for every directory processed"),
groups::optflag("h", "help", "print this help and exit"), getopts::optflag("h", "help", "print this help and exit"),
groups::optflag("V", "version", "output version information 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, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, "{}", f.to_err_msg()); show_error!(1, "{}", f.to_err_msg());
os::set_exit_status(1); return;
return
} }
}; };
@ -41,14 +47,12 @@ fn main() {
println!("Usage:"); println!("Usage:");
println!(" {0:s} [OPTION]... DIRECTORY...", program); println!(" {0:s} [OPTION]... DIRECTORY...", program);
println!(""); 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") { } else if matches.opt_present("version") {
println!("rmdir 1.0.0"); println!("rmdir 1.0.0");
} else if matches.free.is_empty() { } else if matches.free.is_empty() {
writeln!(&mut stderr() as &mut Writer, "Missing an argument"); show_error!(1, "missing an argument");
writeln!(&mut stderr() as &mut Writer, show_error!(1, "for help, try '{0:s} --help'", program);
"For help, try '{0:s} --help'", program);
os::set_exit_status(1);
} else { } else {
let ignore = matches.opt_present("ignore-fail-on-non-empty"); let ignore = matches.opt_present("ignore-fail-on-non-empty");
let parents = matches.opt_present("parents"); let parents = matches.opt_present("parents");
@ -64,14 +68,10 @@ fn remove(dirs: &[~str], ignore: bool, parents: bool, verbose: bool) {
if path.is_dir() { if path.is_dir() {
remove_dir(&path, dir, ignore, parents, verbose); remove_dir(&path, dir, ignore, parents, verbose);
} else { } else {
writeln!(&mut stderr() as &mut Writer, show_error!(1, "failed to remove '{}' (file)", *dir);
"Failed to remove '{}' (file)", *dir);
os::set_exit_status(1);
} }
} else { } else {
writeln!(&mut stderr() as &mut Writer, show_error!(1, "no such file or directory '{}'", *dir);
"No such file or directory '{}'", *dir);
os::set_exit_status(1);
} }
} }
} }
@ -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) { let mut walk_dir = match fs::walk_dir(path) {
Ok(m) => m, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, show_error!(1, "{}", f.to_str());
"{}", f.to_str());
os::set_exit_status(1);
return; return;
} }
}; };
@ -100,15 +98,11 @@ fn remove_dir(path: &Path, dir: &~str, ignore: bool, parents: bool, verbose: boo
} }
} }
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, show_error!(1, "{}", f.to_str());
"{}", f.to_str());
os::set_exit_status(1);
} }
} }
} else if !ignore { } else if !ignore {
writeln!(&mut stderr() as &mut Writer, show_error!(1, "Failed to remove directory '{}' (non-empty)", *dir);
"Failed to remove directory '{}' (non-empty)", *dir);
os::set_exit_status(1);
} }
} }

View file

@ -1,18 +1,25 @@
#[crate_id(name="seq", vers="1.0.0", author="Daniel MacDougall")]; #[crate_id(name="seq", vers="1.0.0", author="Daniel MacDougall")];
#[feature(macro_rules)];
// TODO: Make -w flag work with decimals // TODO: Make -w flag work with decimals
// TODO: Support -f flag // TODO: Support -f flag
extern mod extra; extern mod extra;
extern mod getopts;
use std::os; use std::os;
use std::cmp::max; 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!("seq 1.0.0\n");
println!("Usage:\n seq [-w] [-s string] [-t string] [first [step]] last\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<f32, ~str>{ fn parse_float(s: &str) -> Result<f32, ~str>{
@ -30,16 +37,16 @@ fn escape_sequences(s: &str) -> ~str {
fn main() { fn main() {
let args = os::args(); let args = os::args();
let opts = ~[ let opts = ~[
groups::optopt("s", "separator", "Separator character (defaults to \\n)", ""), getopts::optopt("s", "separator", "Separator character (defaults to \\n)", ""),
groups::optopt("t", "terminator", "Terminator character (defaults to separator)", ""), getopts::optopt("t", "terminator", "Terminator character (defaults to separator)", ""),
groups::optflag("w", "widths", "Equalize widths of all numbers by padding with zeros"), getopts::optflag("w", "widths", "Equalize widths of all numbers by padding with zeros"),
groups::optflag("h", "help", "print this help text and exit"), getopts::optflag("h", "help", "print this help text and exit"),
groups::optflag("V", "version", "print version 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 } Ok(m) => { m }
Err(f) => { Err(f) => {
println!("{:s}", f.to_err_msg()); show_error!(1, "{:s}", f.to_err_msg());
print_usage(opts); print_usage(opts);
return; return;
} }
@ -53,13 +60,14 @@ fn main() {
return; return;
} }
if matches.free.len() < 1 || matches.free.len() > 3 { if matches.free.len() < 1 || matches.free.len() > 3 {
os::set_exit_status(1);
print_usage(opts); print_usage(opts);
return; return;
} }
let first = if matches.free.len() > 1 { let first = if matches.free.len() > 1 {
match parse_float(matches.free[0]) { match parse_float(matches.free[0]) {
Ok(n) => n, Ok(n) => n,
Err(s) => { println!("{:s}", s); return; } Err(s) => { show_error!(1, "{:s}", s); return; }
} }
} else { } else {
1.0 1.0
@ -67,14 +75,14 @@ fn main() {
let step = if matches.free.len() > 2 { let step = if matches.free.len() > 2 {
match parse_float(matches.free[1]) { match parse_float(matches.free[1]) {
Ok(n) => n, Ok(n) => n,
Err(s) => { println!("{:s}", s); return; } Err(s) => { show_error!(1, "{:s}", s); return; }
} }
} else { } else {
1.0 1.0
}; };
let last = match parse_float(matches.free[matches.free.len()-1]) { let last = match parse_float(matches.free[matches.free.len()-1]) {
Ok(n) => n, 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 separator = escape_sequences(matches.opt_str("s").unwrap_or(~"\n"));
let terminator = escape_sequences(matches.opt_str("t").unwrap_or(separator.clone())); let terminator = escape_sequences(matches.opt_str("t").unwrap_or(separator.clone()));

View file

@ -9,27 +9,33 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
#[feature(macro_rules)];
extern mod extra; extern mod extra;
extern mod getopts;
use std::num; use std::num;
use std::cast; use std::cast;
use std::os; use std::os;
use std::io::{print, stderr, timer}; use std::io::{print, timer};
use extra::getopts::groups;
#[path = "../util.rs"]
mod util;
static NAME: &'static str = "sleep";
fn main() { fn main() {
let args = os::args(); let args = os::args();
let program = args[0].clone(); let program = args[0].clone();
let opts = ~[ let opts = ~[
groups::optflag("h", "help", "display this help and exit"), getopts::optflag("h", "help", "display this help and exit"),
groups::optflag("V", "version", "output version information 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, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, "{}", f.to_err_msg()); show_error!(1, "{}", f.to_err_msg());
os::set_exit_status(1);
return return
} }
}; };
@ -42,7 +48,7 @@ fn main() {
println!("or"); println!("or");
println!(" {0:s} OPTION", program); println!(" {0:s} OPTION", program);
println!(""); 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 '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 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 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") { } else if matches.opt_present("version") {
println!("sleep 1.0.0"); println!("sleep 1.0.0");
} else if matches.free.is_empty() { } else if matches.free.is_empty() {
writeln!(&mut stderr() as &mut Writer, "Missing an argument"); show_error!(1, "missing an argument");
writeln!(&mut stderr() as &mut Writer, show_error!(1, "for help, try '{0:s} --help'", program);
"For help, try '{0:s} --help'", program);
os::set_exit_status(1);
} else { } else {
sleep(matches.free); sleep(matches.free);
} }
} }
fn sleep(args: &[~str]) { fn sleep(args: &[~str]) {
let mut failed = false;
let sleep_time = args.iter().fold(0.0, |result, arg| { let sleep_time = args.iter().fold(0.0, |result, arg| {
if failed { let suffix_time = match match_suffix(unsafe { cast::transmute(arg) }) {
0.0 Ok(m) => m,
} else { Err(f) => {
unsafe { crash!(1, "{}", f)
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::<f64>((*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 num =
if suffix_time == 0 {
0.0
} else {
match num::from_str_radix::<f64>((*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<int, ~str> { fn match_suffix(arg: &mut ~str) -> Result<int, ~str> {

View file

@ -11,13 +11,13 @@
*/ */
extern mod extra; extern mod extra;
extern mod getopts;
use std::io::{println, stdin, stdout, Append, File, Truncate, Write}; use std::io::{println, stdin, stdout, Append, File, Truncate, Write};
use std::io::{io_error, EndOfFile}; use std::io::{IoResult};
use std::io::signal::{Interrupt, Listener};
use std::io::util::{copy, NullWriter, MultiWriter}; use std::io::util::{copy, NullWriter, MultiWriter};
use std::os::{args, set_exit_status}; 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 NAME: &'static str = "tee";
static VERSION: &'static str = "1.0.0"; static VERSION: &'static str = "1.0.0";
@ -77,75 +77,73 @@ fn exec(options: Options) -> Result<(), ()> {
} }
fn tee(options: Options) -> Result<(), ()> { fn tee(options: Options) -> Result<(), ()> {
let mut handler = Listener::new(); let writers = options.files.map(|path| open(path, options.append));
if options.ignore_interrupts { let output = &mut MultiWriter::new(writers);
handler.register(Interrupt); 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 { 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 ~stdout() as ~Writer
} else { } else {
let mode = if append { Append } else { Truncate }; let mode = if append { Append } else { Truncate };
match File::open_mode(path, mode, Write) { match File::open_mode(path, mode, Write) {
Some(file) => ~file as ~Writer, Ok(file) => ~file as ~Writer,
None => ~NullWriter as ~Writer Err(_) => ~NullWriter as ~Writer
} }
}); };
~NamedWriter { inner: inner, path: ~path.clone() } as ~Writer ~NamedWriter { inner: inner, path: ~path.clone() } as ~Writer
} }
struct NamedWriter { struct NamedWriter {
priv inner: ~Writer, inner: ~Writer,
priv path: ~Path path: ~Path
} }
impl Writer for NamedWriter { impl Writer for NamedWriter {
fn write(&mut self, buf: &[u8]) { fn write(&mut self, buf: &[u8]) -> IoResult<()> {
with_path(self.path, || io_error::cond.trap(|e| { with_path(self.path, || {
self.inner = ~NullWriter as ~Writer; let val = self.inner.write(buf);
io_error::cond.raise(e); if val.is_err() {
}).inside(|| self.inner.write(buf))) self.inner = ~NullWriter as ~Writer;
}
val
})
} }
fn flush(&mut self) { fn flush(&mut self) -> IoResult<()> {
with_path(self.path, || io_error::cond.trap(|e| { with_path(self.path, || {
self.inner = ~NullWriter as ~Writer; let val = self.inner.flush();
io_error::cond.raise(e); if val.is_err() {
}).inside(|| self.inner.flush())) self.inner = ~NullWriter as ~Writer;
}
val
})
} }
} }
struct NamedReader { struct NamedReader {
priv inner: ~Reader inner: ~Reader
} }
impl Reader for NamedReader { impl Reader for NamedReader {
fn read(&mut self, buf: &mut [u8]) -> Option<uint> { fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
with_path(&Path::new("stdin"), || io_error::cond.trap(|e| { with_path(&Path::new("stdin"), || {
if e.kind != EndOfFile { self.inner.read(buf)
io_error::cond.raise(e) })
}
}).inside(|| self.inner.read(buf)))
} }
} }
fn with_path<T>(path: &Path, cb: || -> T) -> T { fn with_path<T>(path: &Path, cb: || -> IoResult<T>) -> IoResult<T> {
io_error::cond.trap(|e| { match cb() {
warn(format!("{}: {}", path.display(), e.desc)); Err(f) => { warn(format!("{}: {}", path.display(), f.to_str())); Err(f) }
io_error::cond.raise(e); okay => okay
}).inside(cb) }
} }
fn warn(message: &str) { fn warn(message: &str) {

View file

@ -1,11 +1,11 @@
use std::{run, io}; use std::{run, io};
static PROG: &'static str = "build/truncate"; 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 { fn make_file(name: &str) -> io::File {
while Path::new(TESTNAME).exists() { io::timer::sleep(1000); } match io::File::create(&Path::new(name)) {
match io::File::create(&Path::new(TESTNAME)) {
Ok(f) => f, Ok(f) => f,
Err(_) => fail!() Err(_) => fail!()
} }
@ -13,22 +13,22 @@ fn make_file() -> io::File {
#[test] #[test]
fn test_increase_file_size() { fn test_increase_file_size() {
let mut file = make_file(); let mut file = make_file(TFILE1);
if !run::process_status(PROG, [~"-s", ~"+5K", TESTNAME.to_owned()]).unwrap().success() { if !run::process_status(PROG, [~"-s", ~"+5K", TFILE1.to_owned()]).unwrap().success() {
fail!(); fail!();
} }
file.seek(0, io::SeekEnd); file.seek(0, io::SeekEnd);
if file.tell().unwrap() != 5 * 1024 { if file.tell().unwrap() != 5 * 1024 {
fail!(); fail!();
} }
io::fs::unlink(&Path::new(TESTNAME)); io::fs::unlink(&Path::new(TFILE1));
} }
#[test] #[test]
fn test_decrease_file_size() { fn test_decrease_file_size() {
let mut file = make_file(); let mut file = make_file(TFILE2);
file.write(bytes!("1234567890")); 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!(); fail!();
} }
file.seek(0, io::SeekEnd); file.seek(0, io::SeekEnd);
@ -36,5 +36,5 @@ fn test_decrease_file_size() {
println!("{}", file.tell()); println!("{}", file.tell());
fail!(); fail!();
} }
io::fs::unlink(&Path::new(TESTNAME)); io::fs::unlink(&Path::new(TFILE2));
} }

View file

@ -12,35 +12,35 @@
#[feature(macro_rules)]; #[feature(macro_rules)];
extern mod extra; 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::os;
use std::u64; use std::u64;
use extra::getopts::groups;
#[path = "../util.rs"]
mod util;
macro_rules! get_file_size( macro_rules! get_file_size(
($file:ident, $action:expr) => ({ ($file:ident, $action:expr) => ({
match $file.seek(0, SeekEnd) { match $file.seek(0, SeekEnd) {
Ok(_) => {} Ok(_) => {}
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, "{}", f.to_str()); show_error!(1, "{}", f.to_str());
os::set_exit_status(1);
$action $action
} }
} }
let size = match $file.tell() { let size = match $file.tell() {
Ok(m) => m, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, "{}", f.to_str()); show_error!(1, "{}", f.to_str());
os::set_exit_status(1);
$action $action
} }
}; };
match $file.seek(0, SeekSet) { match $file.seek(0, SeekSet) {
Ok(_) => {} Ok(_) => {}
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, "{}", f.to_str()); show_error!(1, "{}", f.to_str());
os::set_exit_status(1);
$action $action
} }
} }
@ -59,24 +59,24 @@ enum TruncateMode {
RoundUp RoundUp
} }
static NAME: &'static str = "truncate";
fn main() { fn main() {
let args = os::args(); let args = os::args();
let program = args[0].clone(); let program = args[0].clone();
let opts = ~[ let opts = ~[
groups::optflag("c", "no-create", "do not create files that do not exist"), getopts::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)"), getopts::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"), getopts::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"), 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"),
groups::optflag("h", "help", "display this help and exit"), getopts::optflag("h", "help", "display this help and exit"),
groups::optflag("V", "version", "output version information 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, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, "{}", f.to_err_msg()); crash!(1, "{}", f.to_err_msg())
os::set_exit_status(1);
return
} }
}; };
@ -86,7 +86,7 @@ fn main() {
println!("Usage:"); println!("Usage:");
println!(" {0:s} [OPTION]... FILE...", program); println!(" {0:s} [OPTION]... FILE...", program);
println!(""); 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!(" print!("
SIZE is an integer with an optional prefix and optional unit. 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: 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") { } else if matches.opt_present("version") {
println!("truncate 1.0.0"); println!("truncate 1.0.0");
} else if matches.free.is_empty() { } else if matches.free.is_empty() {
writeln!(&mut stderr() as &mut Writer, "Missing an argument"); show_error!(1, "missing an argument");
writeln!(&mut stderr() as &mut Writer, crash!(1, "for help, try '{0:s} --help'", program);
"For help, try '{0:s} --help'", program);
os::set_exit_status(1);
} else { } else {
let no_create = matches.opt_present("no-create"); let no_create = matches.opt_present("no-create");
let io_blocks = matches.opt_present("io-blocks"); let io_blocks = matches.opt_present("io-blocks");
let reference = matches.opt_str("reference"); let reference = matches.opt_str("reference");
let size = matches.opt_str("size"); let size = matches.opt_str("size");
if reference.is_none() && size.is_none() { if reference.is_none() && size.is_none() {
writeln!(&mut stderr() as &mut Writer, "You must specify either --reference or --size."); crash!(1, "you must specify either --reference or --size");
os::set_exit_status(1);
} else { } else {
truncate(no_create, io_blocks, reference, size, matches.free); 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())) { let mut rfile = match File::open(&Path::new(rfilename.clone())) {
Ok(m) => m, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, "{}", f.to_str()); crash!(1, "{}", f.to_str())
os::set_exit_status(1);
return
} }
}; };
(get_file_size!(rfile, return), Reference) (get_file_size!(rfile, return), Reference)
} }
None => { None => parse_size(size.unwrap())
match parse_size(size.unwrap()) {
Ok(szpair) => szpair,
Err(()) => return
}
}
}; };
for filename in filenames.iter() { for filename in filenames.iter() {
let filename: &str = *filename; 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) { match file.truncate(tsize as i64) {
Ok(_) => {} Ok(_) => {}
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, show_error!(1, "{}", f.to_str());
"{}", f.to_str());
os::set_exit_status(1);
} }
} }
} }
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, "{}", f.to_str()); show_error!(1, "{}", f.to_str());
os::set_exit_status(1);
} }
} }
} }
} }
} }
fn parse_size(size: ~str) -> Result<(u64, TruncateMode), ()> { fn parse_size(size: ~str) -> (u64, TruncateMode) {
let mut err = false;
let mode = match size.char_at(0) { let mode = match size.char_at(0) {
'+' => Extend, '+' => Extend,
'-' => Reduce, '-' => Reduce,
@ -210,14 +196,10 @@ fn parse_size(size: ~str) -> Result<(u64, TruncateMode), ()> {
let mut number = match u64::parse_bytes(bytes, 10) { let mut number = match u64::parse_bytes(bytes, 10) {
Some(num) => num, Some(num) => num,
None => { None => {
writeln!(&mut stderr() as &mut Writer, crash!(1, "'{}' is not a valid number.", size)
"'{}' is not a valid number.", size);
os::set_exit_status(1);
err = true;
0
} }
}; };
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() { 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() { 'B' => match size.char_at(size.len() - 2).to_ascii().to_upper().to_char() {
'K' => 1000, 'K' => 1000,
@ -229,11 +211,7 @@ fn parse_size(size: ~str) -> Result<(u64, TruncateMode), ()> {
'Z' => 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000, 'Z' => 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000,
'Y' => 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000, 'Y' => 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000,
letter => { letter => {
writeln!(&mut stderr() as &mut Writer, crash!(1, "'{}B' is not a valid suffix.", letter)
"'{}B' is not a valid suffix.", letter);
os::set_exit_status(1);
err = true;
1
} }
}, },
'K' => 1024, 'K' => 1024,
@ -245,18 +223,10 @@ fn parse_size(size: ~str) -> Result<(u64, TruncateMode), ()> {
'Z' => 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024, 'Z' => 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024,
'Y' => 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024, 'Y' => 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024,
letter => { letter => {
writeln!(&mut stderr() as &mut Writer, crash!(1, "'{}' is not a valid suffix.", letter)
"'{}' is not a valid suffix.", letter);
os::set_exit_status(1);
err = true;
1
} }
}; };
} }
if err { (number, mode)
Err(())
} else {
Ok((number, mode))
}
} }

View file

@ -12,23 +12,33 @@
* Synced with http://lingrok.org/xref/coreutils/src/tty.c * Synced with http://lingrok.org/xref/coreutils/src/tty.c
*/ */
#[allow(dead_code)];
#[feature(macro_rules)];
extern mod extra; extern mod extra;
extern mod getopts;
use std::{libc,str,os}; use std::{libc,str,os};
use std::io::println; use std::io::println;
use std::io::stdio::stderr; use std::io::stdio::stderr;
use extra::getopts::{optflag,getopts}; use getopts::{optflag,getopts};
#[path = "../util.rs"]
mod util;
extern { extern {
fn ttyname(filedesc: libc::c_int) -> *libc::c_char; fn ttyname(filedesc: libc::c_int) -> *libc::c_char;
fn isatty(filedesc: libc::c_int) -> libc::c_int; fn isatty(filedesc: libc::c_int) -> libc::c_int;
} }
static NAME: &'static str = "tty";
fn main () { fn main () {
let args = os::args(); let args = os::args();
let options = [ let options = [
optflag("s") optflag("s", "silent", "print nothing, only return an exit status")
]; ];
let silent = match getopts(args.tail(), options) { let silent = match getopts(args.tail(), options) {
@ -64,6 +74,6 @@ fn main () {
} }
fn usage () { 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); os::set_exit_status(2);
} }

View file

@ -14,7 +14,10 @@
// Allow dead code here in order to keep all fields, constants here, for consistency. // Allow dead code here in order to keep all fields, constants here, for consistency.
#[allow(dead_code)]; #[allow(dead_code)];
#[feature(macro_rules)];
extern mod extra; extern mod extra;
extern mod getopts;
use std::io::print; use std::io::print;
use std::cast; use std::cast;
@ -22,7 +25,9 @@ use std::libc;
use std::os; use std::os;
use std::ptr; use std::ptr;
use std::str; use std::str;
use extra::getopts::groups;
#[path = "../util.rs"]
mod util;
static DEFAULT_FILE: &'static str = "/var/run/utmp"; static DEFAULT_FILE: &'static str = "/var/run/utmp";
@ -75,15 +80,17 @@ extern {
fn utmpname(file: *libc::c_char) -> libc::c_int; fn utmpname(file: *libc::c_char) -> libc::c_int;
} }
static NAME: &'static str = "users";
fn main() { fn main() {
let args = os::args(); let args = os::args();
let program = args[0].as_slice(); let program = args[0].as_slice();
let opts = ~[ let opts = ~[
groups::optflag("h", "help", "display this help and exit"), getopts::optflag("h", "help", "display this help and exit"),
groups::optflag("V", "version", "output version information 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, Ok(m) => m,
Err(f) => fail!(f.to_err_msg()), Err(f) => fail!(f.to_err_msg()),
}; };
@ -94,7 +101,7 @@ fn main() {
println!("Usage:"); println!("Usage:");
println!(" {:s} [OPTION]... [FILE]", program); println!(" {:s} [OPTION]... [FILE]", program);
println!(""); 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; return;
} }

47
util.rs Normal file
View file

@ -0,0 +1,47 @@
/*
* This file is part of the uutils coreutils package.
*
* (c) Arcterus <arcterus@mail.com>
*
* 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()); }
}
)
)

View file

@ -9,12 +9,18 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
#[feature(macro_rules)];
extern mod extra; extern mod extra;
extern mod getopts;
use std::os; use std::os;
use std::str::from_utf8; use std::str::from_utf8;
use std::io::{print, stdin, stderr, File, BufferedReader}; use std::io::{print, stdin, File, BufferedReader};
use extra::getopts::{groups, Matches}; use getopts::Matches;
#[path = "../util.rs"]
mod util;
struct Result { struct Result {
filename: ~str, filename: ~str,
@ -25,26 +31,25 @@ struct Result {
max_line_length: uint, max_line_length: uint,
} }
static NAME: &'static str = "wc";
fn main() { fn main() {
let args = os::args(); let args = os::args();
let program = args[0].clone(); let program = args[0].clone();
let opts = ~[ let opts = ~[
groups::optflag("c", "bytes", "print the byte counts"), getopts::optflag("c", "bytes", "print the byte counts"),
groups::optflag("m", "chars", "print the character counts"), getopts::optflag("m", "chars", "print the character counts"),
groups::optflag("l", "lines", "print the newline counts"), getopts::optflag("l", "lines", "print the newline counts"),
groups::optflag("L", "max-line-length", "print the length of the longest line"), getopts::optflag("L", "max-line-length", "print the length of the longest line"),
groups::optflag("w", "words", "print the word counts"), getopts::optflag("w", "words", "print the word counts"),
groups::optflag("h", "help", "display this help and exit"), getopts::optflag("h", "help", "display this help and exit"),
groups::optflag("V", "version", "output version information 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, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, crash!(1, "Invalid options\n{}", f.to_err_msg())
"Invalid options\n{}", f.to_err_msg());
os::set_exit_status(1);
return
} }
}; };
@ -52,7 +57,7 @@ fn main() {
println!("Usage:"); println!("Usage:");
println!(" {0:s} [OPTION]... [FILE]...", program); println!(" {0:s} [OPTION]... [FILE]...", program);
println!(""); 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!("");
println!("With no FILE, or when FILE is -, read standard input."); println!("With no FILE, or when FILE is -, read standard input.");
return; return;
@ -229,8 +234,7 @@ fn open(path: ~str) -> Option<BufferedReader<~Reader>> {
return Some(BufferedReader::new(reader)); return Some(BufferedReader::new(reader));
}, },
Err(e) => { Err(e) => {
writeln!(&mut stderr() as &mut Writer, "wc: {0:s}: {1:s}", path, e.desc.to_str()); show_error!(1, "wc: {0:s}: {1:s}", path, e.desc.to_str());
os::set_exit_status(1);
} }
} }

View file

@ -11,13 +11,18 @@
/* last synced with: whoami (GNU coreutils) 8.21 */ /* last synced with: whoami (GNU coreutils) 8.21 */
#[feature(macro_rules)];
extern mod extra; extern mod extra;
extern mod getopts;
use std::io::print; use std::io::print;
use std::os; use std::os;
use std::str; use std::str;
use std::libc; use std::libc;
use extra::getopts::groups;
#[path = "../util.rs"]
mod util;
struct c_passwd { struct c_passwd {
pw_name: *libc::c_char, pw_name: *libc::c_char,
@ -38,16 +43,18 @@ unsafe fn getusername() -> ~str {
name name
} }
static NAME: &'static str = "whoami";
fn main() { fn main() {
let args = os::args(); let args = os::args();
let program = args[0].as_slice(); let program = args[0].as_slice();
let opts = ~[ let opts = ~[
groups::optflag("h", "help", "display this help and exit"), getopts::optflag("h", "help", "display this help and exit"),
groups::optflag("V", "version", "output version information 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, Ok(m) => m,
Err(f) => fail!(f.to_err_msg()), Err(f) => crash!(1, "{}", f.to_err_msg()),
}; };
if matches.opt_present("help") { if matches.opt_present("help") {
println!("whoami 1.0.0"); println!("whoami 1.0.0");
@ -55,7 +62,7 @@ fn main() {
println!("Usage:"); println!("Usage:");
println!(" {:s}", program); println!(" {:s}", program);
println!(""); println!("");
print(groups::usage("print effective userid", opts)); print(getopts::usage("print effective userid", opts));
return; return;
} }
if matches.opt_present("version") { if matches.opt_present("version") {

View file

@ -11,26 +11,30 @@
/* last synced with: yes (GNU coreutils) 8.13 */ /* last synced with: yes (GNU coreutils) 8.13 */
#[feature(macro_rules)];
extern mod extra; extern mod extra;
extern mod getopts;
use std::os; use std::os;
use std::io::{print, println, stderr}; use std::io::{print, println};
use extra::getopts::groups;
#[path = "../util.rs"]
mod util;
static NAME: &'static str = "yes";
fn main() { fn main() {
let args = os::args(); let args = os::args();
let program = args[0].clone(); let program = args[0].clone();
let opts = ~[ let opts = ~[
groups::optflag("h", "help", "display this help and exit"), getopts::optflag("h", "help", "display this help and exit"),
groups::optflag("V", "version", "output version information 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, Ok(m) => m,
Err(f) => { Err(f) => {
writeln!(&mut stderr() as &mut Writer, crash!(1, "invalid options\n{}", f.to_err_msg())
"Invalid options\n{}", f.to_err_msg());
os::set_exit_status(1);
return
} }
}; };
if matches.opt_present("help") { if matches.opt_present("help") {
@ -39,7 +43,7 @@ fn main() {
println!("Usage:"); println!("Usage:");
println!(" {0:s} [STRING]... [OPTION]...", program); println!(" {0:s} [STRING]... [OPTION]...", program);
println!(""); 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; return;
} }
if matches.opt_present("version") { if matches.opt_present("version") {