diff --git a/Makefile b/Makefile index 59c1ad1be..9f68e1a64 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ endef # Test exe built rules define TEST_BUILD -test_$(1): tmp/$(1)_test +test_$(1): tmp/$(1)_test build/$(1) $(call command,tmp/$(1)_test) tmp/$(1)_test: $(1)/test.rs @@ -49,4 +49,3 @@ $(foreach exe,$(EXES),$(eval $(call EXE_BUILD,$(exe)))) $(foreach test,$(TESTS),$(eval $(call TEST_BUILD,$(test)))) .PHONY: all test clean - diff --git a/cat/cat.rs b/cat/cat.rs index e8a3348a9..2d7e82446 100644 --- a/cat/cat.rs +++ b/cat/cat.rs @@ -15,7 +15,7 @@ extern mod extra; use std::os; -use std::io::{stdin, stderr, stdout, Writer, Reader}; +use std::rt::io::{stdin, stderr, stdout, File, result}; use extra::getopts::groups; fn main() { @@ -37,8 +37,8 @@ fn main() { let matches = match groups::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - stderr().write_line("Invalid options"); - stderr().write_line(f.to_err_msg()); + writeln!(&mut stderr() as &mut Writer, + "Invalid options\n{}", f.to_err_msg()); os::set_exit_status(1); return } @@ -47,7 +47,7 @@ fn main() { println("cat 1.0.0"); println(""); println("Usage:"); - println(format!(" {0:s} [OPTION]... [FILE]...", program)); + println!(" {0:s} [OPTION]... [FILE]...", program); println(""); print(groups::usage("Concatenate FILE(s), or standard input, to standard output.", opts)); println(""); @@ -100,54 +100,57 @@ fn is_newline_char(byte: u8) -> bool { } pub fn exec(files: ~[~str], number: NumberingMode, show_nonprint: bool, show_ends: bool, show_tabs: bool, squeeze_blank: bool) { - let writer = stdout(); + let mut writer = stdout(); if NumberNone != number || show_nonprint || show_ends || show_tabs || squeeze_blank { let mut counter: uint = 1; let is_numbering = number == NumberAll || number == NumberNonEmpty; for path in files.iter() { - let reader = match open(path.to_owned()) { + let mut reader = match open(path.to_owned()) { Some(f) => f, None => { continue } }; let mut at_line_start = true; + let mut buf = [0, .. 2]; loop { - let buf = reader.read_bytes(2); - for byte in buf.iter() { - if at_line_start && (number == NumberAll || (number == NumberNonEmpty && !is_newline_char(*byte))) { - writer.write_str(format!("{0:6u}\t", counter)); - counter += 1; - at_line_start = false; - } - if is_numbering && *byte == LF { - at_line_start = true; - } - if show_tabs && *byte == TAB { - writer.write(bytes!("^I")); - } else if show_ends && *byte == LF { - writer.write(bytes!("$\n")); - } else if show_nonprint && (*byte < 32 || *byte >= 127) && !is_newline_char(*byte) { - let mut byte = *byte; - if byte >= 128 { - writer.write(bytes!("M-")); - byte = byte - 128; + // reading from a TTY seems to raise a condition on + // EOF, rather than return Some(0) like a file. + match result(|| reader.read(buf)) { + Ok(Some(n)) if n != 0 => { + for byte in buf.slice_to(n).iter() { + if at_line_start && (number == NumberAll || (number == NumberNonEmpty && !is_newline_char(*byte))) { + write!(&mut writer as &mut Writer, "{0:6u}\t", counter); + counter += 1; + at_line_start = false; + } + if is_numbering && *byte == LF { + at_line_start = true; + } + if show_tabs && *byte == TAB { + writer.write(bytes!("^I")); + } else if show_ends && *byte == LF { + writer.write(bytes!("$\n")); + } else if show_nonprint && (*byte < 32 || *byte >= 127) && !is_newline_char(*byte) { + let mut byte = *byte; + if byte >= 128 { + writer.write(bytes!("M-")); + byte = byte - 128; + } + if byte < 32 { + writer.write(['^' as u8, byte + 64]); + } else if byte == 127 { + writer.write(['^' as u8, byte - 64]); + } else { + writer.write([byte]); + } + } else { + writer.write([*byte]); + } } - if byte < 32 { - writer.write(['^' as u8, byte + 64]); - } else if byte == 127 { - writer.write(['^' as u8, byte - 64]); - } else { - writer.write([byte]); - } - } else { - writer.write([*byte]); } - } - - if reader.eof() { - break; + _ => break } } } @@ -155,31 +158,35 @@ pub fn exec(files: ~[~str], number: NumberingMode, show_nonprint: bool, show_end return; } + let mut buf = [0, .. 100000]; // passthru mode for path in files.iter() { - let reader = match open(path.to_owned()) { + let mut reader = match open(path.to_owned()) { Some(f) => f, None => { continue } }; loop { - writer.write(reader.read_bytes(100000)); - if reader.eof() { - break; + // reading from a TTY seems to raise a condition on EOF, + // rather than return Some(0) like a file. + match result(|| reader.read(buf)) { + Ok(Some(n)) if n != 0 => writer.write(buf.slice_to(n)), + _ => break } } } } -fn open(path: ~str) -> Option<@Reader> { +fn open(path: ~str) -> Option<~Reader> { if "-" == path { - return Some(stdin()); + return Some(~stdin() as ~Reader); } - match std::io::file_reader(&std::path::Path::new(path.as_slice())) { - Ok(fd) => return Some(fd), + match result(|| File::open(&std::path::Path::new(path.as_slice()))) { + Ok(fd) => return Some(~fd as ~Reader), Err(e) => { - stderr().write_line(format!("cat: {0:s}: {1:s}", path, e)); + writeln!(&mut stderr() as &mut Writer, + "cat: {0:s}: {1:s}", path, e.to_str()); os::set_exit_status(1); } } diff --git a/cat/test.rs b/cat/test.rs index cc07b0cd7..080e4eeee 100644 --- a/cat/test.rs +++ b/cat/test.rs @@ -1,7 +1,4 @@ -use std::rt::io::process::{Process, ProcessConfig, CreatePipe, Ignored}; -use std::rt::io::{Reader, Writer}; -use std::rt::io::pipe::PipeStream; -use std::str; +use std::{run, str}; fn main() { test_output_multi_files_print_all_chars(); @@ -9,71 +6,31 @@ fn main() { test_stdin_number_non_blank(); } -fn read_all(input: &mut Reader) -> ~str { - let mut ret = ~""; - let mut buf = [0, ..1024]; - loop { - match input.read(buf) { - None => { break } - Some(n) => { ret = ret + str::from_utf8(buf.slice_to(n)); } - } - } - return ret; -} - fn test_output_multi_files_print_all_chars() { - let output = PipeStream::new().unwrap(); - let io = ~[Ignored, - CreatePipe(output, false, true)]; - let args = ProcessConfig { - program: "build/cat", - args: [~"cat/fixtures/alpha.txt", ~"cat/fixtures/256.txt", ~"-A", ~"-n"], - env: None, - cwd: None, - io: io, - }; - let mut p = Process::new(args).expect("proc fail"); - let out = read_all(p.io[1].get_mut_ref() as &mut Reader); - assert_eq!(p.wait(), 0); - assert_eq!(out, ~" 1\tabcde$\n 2\tfghij$\n 3\tklmno$\n 4\tpqrst$\n 5\tuvwxyz$\n 6\t^@^A^B^C^D^E^F^G^H^I$\n 7\t^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\\^]^^^_ !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~^?M-^@M-^AM-^BM-^CM-^DM-^EM-^FM-^GM-^HM-^IM-^JM-^KM-^LM-^MM-^NM-^OM-^PM-^QM-^RM-^SM-^TM-^UM-^VM-^WM-^XM-^YM-^ZM-^[M-^\\M-^]M-^^M-^_M- M-!M-\"M-#M-$M-%M-&M-\'M-(M-)M-*M-+M-,M--M-.M-/M-0M-1M-2M-3M-4M-5M-6M-7M-8M-9M-:M-;M-M-?M-@M-AM-BM-CM-DM-EM-FM-GM-HM-IM-JM-KM-LM-MM-NM-OM-PM-QM-RM-SM-TM-UM-VM-WM-XM-YM-ZM-[M-\\M-]M-^M-_M-`M-aM-bM-cM-dM-eM-fM-gM-hM-iM-jM-kM-lM-mM-nM-oM-pM-qM-rM-sM-tM-uM-vM-wM-xM-yM-zM-{M-|M-}M-~M-^?"); + let prog = run::process_output("build/cat", + [~"cat/fixtures/alpha.txt", ~"cat/fixtures/256.txt", + ~"-A", ~"-n"]); + let out = str::from_utf8_owned(prog.output); + assert_eq!(out, + ~" 1\tabcde$\n 2\tfghij$\n 3\tklmno$\n 4\tpqrst$\n 5\tuvwxyz$\n 6\t^@^A^B^C^D^E^F^G^H^I$\n 7\t^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\\^]^^^_ !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~^?M-^@M-^AM-^BM-^CM-^DM-^EM-^FM-^GM-^HM-^IM-^JM-^KM-^LM-^MM-^NM-^OM-^PM-^QM-^RM-^SM-^TM-^UM-^VM-^WM-^XM-^YM-^ZM-^[M-^\\M-^]M-^^M-^_M- M-!M-\"M-#M-$M-%M-&M-\'M-(M-)M-*M-+M-,M--M-.M-/M-0M-1M-2M-3M-4M-5M-6M-7M-8M-9M-:M-;M-M-?M-@M-AM-BM-CM-DM-EM-FM-GM-HM-IM-JM-KM-LM-MM-NM-OM-PM-QM-RM-SM-TM-UM-VM-WM-XM-YM-ZM-[M-\\M-]M-^M-_M-`M-aM-bM-cM-dM-eM-fM-gM-hM-iM-jM-kM-lM-mM-nM-oM-pM-qM-rM-sM-tM-uM-vM-wM-xM-yM-zM-{M-|M-}M-~M-^?"); } fn test_stdin_squeeze() { - let input = PipeStream::new().unwrap(); - let output = PipeStream::new().unwrap(); - let io = ~[CreatePipe(input, true, false), - CreatePipe(output, false, true)]; - let args = ProcessConfig { - program: "build/cat", - args: [~"-A"], - env: None, - cwd: None, - io: io, - }; - let mut p = Process::new(args).expect("proc fail"); - p.io[0].get_mut_ref().write("\x00\x01\x02".as_bytes()); - p.io[0] = None; // close stdin; - let out = read_all(p.io[1].get_mut_ref() as &mut Reader); - assert_eq!(p.wait(), 0); + let mut prog = run::Process::new("build/cat", [~"-A"], run::ProcessOptions::new()); + + prog.input().write(bytes!("\x00\x01\x02")); + prog.close_input(); + + let out = str::from_utf8_owned(prog.finish_with_output().output); assert_eq!(out, ~"^@^A^B"); } fn test_stdin_number_non_blank() { - let input = PipeStream::new().unwrap(); - let output = PipeStream::new().unwrap(); - let io = ~[CreatePipe(input, true, false), - CreatePipe(output, false, true)]; - let args = ProcessConfig { - program: "build/cat", - args: [~"-b", ~"-"], - env: None, - cwd: None, - io: io, - }; - let mut p = Process::new(args).expect("proc fail"); - p.io[0].get_mut_ref().write("\na\nb\n\n\nc".as_bytes()); - p.io[0] = None; // close stdin; - let out = read_all(p.io[1].get_mut_ref() as &mut Reader); - assert_eq!(p.wait(), 0); + let mut prog = run::Process::new("build/cat", [~"-b", ~"-"], run::ProcessOptions::new()); + + prog.input().write(bytes!("\na\nb\n\n\nc")); + prog.close_input(); + + let out = str::from_utf8_owned(prog.finish_with_output().output); assert_eq!(out, ~"\n 1\ta\n 2\tb\n\n\n 3\tc"); } diff --git a/printenv/printenv.rs b/printenv/printenv.rs index 5be5aadc3..17338a26f 100644 --- a/printenv/printenv.rs +++ b/printenv/printenv.rs @@ -14,7 +14,7 @@ extern mod extra; use std::os; -use std::io::stderr; +use std::rt::io::stderr; use extra::getopts::groups; fn main() { @@ -28,8 +28,8 @@ fn main() { let matches = match groups::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - stderr().write_line("Invalid options"); - stderr().write_line(f.to_err_msg()); + writeln!(&mut stderr() as &mut Writer, + "Invalid options\n{}", f.to_err_msg()); os::set_exit_status(1); return } @@ -38,7 +38,7 @@ fn main() { println("printenv 1.0.0"); println(""); println("Usage:"); - println(format!(" {0:s} [VARIABLE]... [OPTION]...", program)); + println!(" {0:s} [VARIABLE]... [OPTION]...", program); println(""); print(groups::usage("Prints the given environment VARIABLE(s), otherwise prints them all.", opts)); return; @@ -59,7 +59,7 @@ pub fn exec(args: ~[~str], separator: &str) { if args.is_empty() { let vars = os::env(); for (env_var, value) in vars.move_iter() { - print(format!("{0:s}={1:s}", env_var, value)); + print!("{0:s}={1:s}", env_var, value); print(separator); } return; diff --git a/whoami/whoami.rs b/whoami/whoami.rs index 8af54c39a..54e73695a 100644 --- a/whoami/whoami.rs +++ b/whoami/whoami.rs @@ -48,7 +48,7 @@ fn main() { ]; let matches = match groups::getopts(args.tail(), opts) { Ok(m) => m, - Err(f) => fail2!(f.to_err_msg()), + Err(f) => fail!(f.to_err_msg()), }; if matches.opt_present("help") { println("whoami 1.0.0"); diff --git a/yes/yes.rs b/yes/yes.rs index cf237ece0..a08e91cb9 100644 --- a/yes/yes.rs +++ b/yes/yes.rs @@ -14,7 +14,7 @@ extern mod extra; use std::os; -use std::io::stderr; +use std::rt::io::stderr; use extra::getopts::groups; fn main() { @@ -27,8 +27,8 @@ fn main() { let matches = match groups::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - stderr().write_line("Invalid options"); - stderr().write_line(f.to_err_msg()); + writeln!(&mut stderr() as &mut Writer, + "Invalid options\n{}", f.to_err_msg()); os::set_exit_status(1); return } @@ -37,7 +37,7 @@ fn main() { println("yes 1.0.0"); println(""); println("Usage:"); - println(format!(" {0:s} [STRING]... [OPTION]...", program)); + println!(" {0:s} [STRING]... [OPTION]...", program); println(""); print(groups::usage("Repeatedly output a line with all specified STRING(s), or 'y'.", opts)); return;