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

Merge pull request #88 from Arcterus/master

Fix programs for latest Rust and begin usage of new utility macros
This commit is contained in:
Heather 2014-02-07 12:11:54 +03:00
commit 8a04ee296b
22 changed files with 433 additions and 405 deletions

View file

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

View file

@ -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());

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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 <juszczakn@gmail.com>
@ -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());
}
}
}

View file

@ -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") {

View file

@ -9,29 +9,32 @@
* 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())
}
};
@ -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 {

View file

@ -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());
}
}
}

View file

@ -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);
}
}

View file

@ -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<f32, ~str>{
@ -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()));

View file

@ -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::<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 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::<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> {

View file

@ -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<uint> {
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<uint> {
with_path(&Path::new("stdin"), || {
self.inner.read(buf)
})
}
}
fn with_path<T>(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<T>(path: &Path, cb: || -> IoResult<T>) -> IoResult<T> {
match cb() {
Err(f) => { warn(format!("{}: {}", path.display(), f.to_str())); Err(f) }
okay => okay
}
}
fn warn(message: &str) {

View file

@ -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));
}

View file

@ -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)
}

View file

@ -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);
}

View file

@ -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;
}

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.
*/
#[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<BufferedReader<~Reader>> {
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());
}
}

View file

@ -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") {

View file

@ -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") {