auto merge of #11946 : alexcrichton/rust/no-io-error, r=brson
Turns out this was a little more far-reaching than I thought it was. The first commit is the crux of this stack of commits. The `io::io_error` condition is completely removed and the `read` and `write` methods are altered to return `IoResult<T>`. This turned out to be an incredibly far-reaching change! Overall, I'm very happy with how this turned out (in addition with the `unused_must_use` lint). I had to almost rewrite the pretty printer in `libsyntax` as well as the the formatting in `librustdoc` (as one would expect). These two modules do *tons* of I/O, and I believe that it's definitely improved. This pull request also introduces the `if_ok!()` macro for returning-early from something that returns a result. I made quite liberal use of this in mostly the pretty printer and html renderer, and I found its usage generally quite pleasant and convenient to have. I didn't really feel like adding any other macro while I was using it, and I figured that pretty printing could be nicer, but it's nowhere near horrid today. This may be a controversial issue closing, but I'm going to say it. Closes #6163
This commit is contained in:
commit
cb40eba4b1
122 changed files with 4346 additions and 4233 deletions
|
|
@ -234,7 +234,13 @@ pub fn run_tests(config: &config) {
|
|||
// For context, see #8904
|
||||
io::test::raise_fd_limit();
|
||||
let res = test::run_tests_console(&opts, tests);
|
||||
if !res { fail!("Some tests failed"); }
|
||||
match res {
|
||||
Ok(true) => {}
|
||||
Ok(false) => fail!("Some tests failed"),
|
||||
Err(e) => {
|
||||
println!("I/O failure during tests: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_opts(config: &config) -> test::TestOpts {
|
||||
|
|
@ -255,7 +261,7 @@ pub fn make_tests(config: &config) -> ~[test::TestDescAndFn] {
|
|||
debug!("making tests from {}",
|
||||
config.src_base.display());
|
||||
let mut tests = ~[];
|
||||
let dirs = fs::readdir(&config.src_base);
|
||||
let dirs = fs::readdir(&config.src_base).unwrap();
|
||||
for file in dirs.iter() {
|
||||
let file = file.clone();
|
||||
debug!("inspecting file {}", file.display());
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ pub fn run(lib_path: &str,
|
|||
});
|
||||
|
||||
match opt_process {
|
||||
Some(ref mut process) => {
|
||||
Ok(ref mut process) => {
|
||||
for input in input.iter() {
|
||||
process.input().write(input.as_bytes());
|
||||
process.input().write(input.as_bytes()).unwrap();
|
||||
}
|
||||
let run::ProcessOutput { status, output, error } = process.finish_with_output();
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ pub fn run(lib_path: &str,
|
|||
err: str::from_utf8_owned(error).unwrap()
|
||||
})
|
||||
},
|
||||
None => None
|
||||
Err(..) => None
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,13 +90,13 @@ pub fn run_background(lib_path: &str,
|
|||
});
|
||||
|
||||
match opt_process {
|
||||
Some(mut process) => {
|
||||
Ok(mut process) => {
|
||||
for input in input.iter() {
|
||||
process.input().write(input.as_bytes());
|
||||
process.input().write(input.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
Some(process)
|
||||
},
|
||||
None => None
|
||||
Err(..) => None
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
|
|||
let rounds =
|
||||
match props.pp_exact { Some(_) => 1, None => 2 };
|
||||
|
||||
let src = File::open(testfile).read_to_end();
|
||||
let src = File::open(testfile).read_to_end().unwrap();
|
||||
let src = str::from_utf8_owned(src).unwrap();
|
||||
let mut srcs = ~[src];
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
|
|||
let mut expected = match props.pp_exact {
|
||||
Some(ref file) => {
|
||||
let filepath = testfile.dir_path().join(file);
|
||||
let s = File::open(&filepath).read_to_end();
|
||||
let s = File::open(&filepath).read_to_end().unwrap();
|
||||
str::from_utf8_owned(s).unwrap()
|
||||
}
|
||||
None => { srcs[srcs.len() - 2u].clone() }
|
||||
|
|
@ -318,8 +318,10 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
|
|||
//waiting 1 second for gdbserver start
|
||||
timer::sleep(1000);
|
||||
let result = task::try(proc() {
|
||||
tcp::TcpStream::connect(
|
||||
SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 5039 });
|
||||
tcp::TcpStream::connect(SocketAddr {
|
||||
ip: Ipv4Addr(127, 0, 0, 1),
|
||||
port: 5039,
|
||||
}).unwrap();
|
||||
});
|
||||
if result.is_err() {
|
||||
continue;
|
||||
|
|
@ -361,7 +363,7 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
|
|||
stdout: out,
|
||||
stderr: err,
|
||||
cmdline: cmdline};
|
||||
process.force_destroy();
|
||||
process.force_destroy().unwrap();
|
||||
}
|
||||
|
||||
_=> {
|
||||
|
|
@ -727,7 +729,7 @@ fn compose_and_run_compiler(
|
|||
|
||||
fn ensure_dir(path: &Path) {
|
||||
if path.is_dir() { return; }
|
||||
fs::mkdir(path, io::UserRWX);
|
||||
fs::mkdir(path, io::UserRWX).unwrap();
|
||||
}
|
||||
|
||||
fn compose_and_run(config: &config, testfile: &Path,
|
||||
|
|
@ -852,7 +854,7 @@ fn dump_output(config: &config, testfile: &Path, out: &str, err: &str) {
|
|||
fn dump_output_file(config: &config, testfile: &Path,
|
||||
out: &str, extension: &str) {
|
||||
let outfile = make_out_name(config, testfile, extension);
|
||||
File::create(&outfile).write(out.as_bytes());
|
||||
File::create(&outfile).write(out.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
fn make_out_name(config: &config, testfile: &Path, extension: &str) -> Path {
|
||||
|
|
@ -1003,7 +1005,7 @@ fn _arm_exec_compiled_test(config: &config, props: &TestProps,
|
|||
fn _arm_push_aux_shared_library(config: &config, testfile: &Path) {
|
||||
let tdir = aux_output_dir_name(config, testfile);
|
||||
|
||||
let dirs = fs::readdir(&tdir);
|
||||
let dirs = fs::readdir(&tdir).unwrap();
|
||||
for file in dirs.iter() {
|
||||
if file.extension_str() == Some("so") {
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
|
|
@ -1099,7 +1101,7 @@ fn disassemble_extract(config: &config, _props: &TestProps,
|
|||
|
||||
|
||||
fn count_extracted_lines(p: &Path) -> uint {
|
||||
let x = File::open(&p.with_extension("ll")).read_to_end();
|
||||
let x = File::open(&p.with_extension("ll")).read_to_end().unwrap();
|
||||
let x = str::from_utf8_owned(x).unwrap();
|
||||
x.lines().len()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ An example program that does this task reads like this:
|
|||
# #[allow(unused_imports)];
|
||||
use std::io::{BufferedReader, File};
|
||||
# mod BufferedReader {
|
||||
# use std::io::File;
|
||||
# use std::io::{File, IoResult};
|
||||
# use std::io::MemReader;
|
||||
# use std::io::BufferedReader;
|
||||
# static s : &'static [u8] = bytes!("1 2\n\
|
||||
|
|
@ -55,7 +55,7 @@ use std::io::{BufferedReader, File};
|
|||
# 789 123\n\
|
||||
# 45 67\n\
|
||||
# ");
|
||||
# pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
|
||||
# pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
|
||||
# BufferedReader::new(MemReader::new(s.to_owned()))
|
||||
# }
|
||||
# }
|
||||
|
|
@ -71,7 +71,6 @@ fn read_int_pairs() -> ~[(int,int)] {
|
|||
let mut pairs = ~[];
|
||||
|
||||
// Path takes a generic by-value, rather than by reference
|
||||
# let _g = std::io::ignore_io_error();
|
||||
let path = Path::new(&"foo.txt");
|
||||
let mut reader = BufferedReader::new(File::open(&path));
|
||||
|
||||
|
|
@ -245,7 +244,7 @@ and trapping its exit status using `task::try`:
|
|||
use std::io::{BufferedReader, File};
|
||||
use std::task;
|
||||
# mod BufferedReader {
|
||||
# use std::io::File;
|
||||
# use std::io::{File, IoResult};
|
||||
# use std::io::MemReader;
|
||||
# use std::io::BufferedReader;
|
||||
# static s : &'static [u8] = bytes!("1 2\n\
|
||||
|
|
@ -253,7 +252,7 @@ use std::task;
|
|||
# 789 123\n\
|
||||
# 45 67\n\
|
||||
# ");
|
||||
# pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
|
||||
# pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
|
||||
# BufferedReader::new(MemReader::new(s.to_owned()))
|
||||
# }
|
||||
# }
|
||||
|
|
@ -277,7 +276,6 @@ fn main() {
|
|||
|
||||
fn read_int_pairs() -> ~[(int,int)] {
|
||||
let mut pairs = ~[];
|
||||
# let _g = std::io::ignore_io_error();
|
||||
let path = Path::new(&"foo.txt");
|
||||
|
||||
let mut reader = BufferedReader::new(File::open(&path));
|
||||
|
|
@ -347,7 +345,7 @@ but similarly clear as the version that used `fail!` in the logic where the erro
|
|||
# #[allow(unused_imports)];
|
||||
use std::io::{BufferedReader, File};
|
||||
# mod BufferedReader {
|
||||
# use std::io::File;
|
||||
# use std::io::{File, IoResult};
|
||||
# use std::io::MemReader;
|
||||
# use std::io::BufferedReader;
|
||||
# static s : &'static [u8] = bytes!("1 2\n\
|
||||
|
|
@ -355,7 +353,7 @@ use std::io::{BufferedReader, File};
|
|||
# 789 123\n\
|
||||
# 45 67\n\
|
||||
# ");
|
||||
# pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
|
||||
# pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
|
||||
# BufferedReader::new(MemReader::new(s.to_owned()))
|
||||
# }
|
||||
# }
|
||||
|
|
@ -374,7 +372,6 @@ fn main() {
|
|||
|
||||
fn read_int_pairs() -> ~[(int,int)] {
|
||||
let mut pairs = ~[];
|
||||
# let _g = std::io::ignore_io_error();
|
||||
let path = Path::new(&"foo.txt");
|
||||
|
||||
let mut reader = BufferedReader::new(File::open(&path));
|
||||
|
|
@ -415,7 +412,7 @@ and replaces bad input lines with the pair `(-1,-1)`:
|
|||
# #[allow(unused_imports)];
|
||||
use std::io::{BufferedReader, File};
|
||||
# mod BufferedReader {
|
||||
# use std::io::File;
|
||||
# use std::io::{File, IoResult};
|
||||
# use std::io::MemReader;
|
||||
# use std::io::BufferedReader;
|
||||
# static s : &'static [u8] = bytes!("1 2\n\
|
||||
|
|
@ -423,7 +420,7 @@ use std::io::{BufferedReader, File};
|
|||
# 789 123\n\
|
||||
# 45 67\n\
|
||||
# ");
|
||||
# pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
|
||||
# pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
|
||||
# BufferedReader::new(MemReader::new(s.to_owned()))
|
||||
# }
|
||||
# }
|
||||
|
|
@ -447,7 +444,6 @@ fn main() {
|
|||
|
||||
fn read_int_pairs() -> ~[(int,int)] {
|
||||
let mut pairs = ~[];
|
||||
# let _g = std::io::ignore_io_error();
|
||||
let path = Path::new(&"foo.txt");
|
||||
|
||||
let mut reader = BufferedReader::new(File::open(&path));
|
||||
|
|
@ -489,7 +485,7 @@ Changing the condition's return type from `(int,int)` to `Option<(int,int)>` wil
|
|||
# #[allow(unused_imports)];
|
||||
use std::io::{BufferedReader, File};
|
||||
# mod BufferedReader {
|
||||
# use std::io::File;
|
||||
# use std::io::{IoResult, File};
|
||||
# use std::io::MemReader;
|
||||
# use std::io::BufferedReader;
|
||||
# static s : &'static [u8] = bytes!("1 2\n\
|
||||
|
|
@ -497,7 +493,7 @@ use std::io::{BufferedReader, File};
|
|||
# 789 123\n\
|
||||
# 45 67\n\
|
||||
# ");
|
||||
# pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
|
||||
# pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
|
||||
# BufferedReader::new(MemReader::new(s.to_owned()))
|
||||
# }
|
||||
# }
|
||||
|
|
@ -522,7 +518,6 @@ fn main() {
|
|||
|
||||
fn read_int_pairs() -> ~[(int,int)] {
|
||||
let mut pairs = ~[];
|
||||
# let _g = std::io::ignore_io_error();
|
||||
let path = Path::new(&"foo.txt");
|
||||
|
||||
let mut reader = BufferedReader::new(File::open(&path));
|
||||
|
|
@ -573,7 +568,7 @@ This can be encoded in the handler API by introducing a helper type: `enum Malfo
|
|||
# #[allow(unused_imports)];
|
||||
use std::io::{BufferedReader, File};
|
||||
# mod BufferedReader {
|
||||
# use std::io::File;
|
||||
# use std::io::{File, IoResult};
|
||||
# use std::io::MemReader;
|
||||
# use std::io::BufferedReader;
|
||||
# static s : &'static [u8] = bytes!("1 2\n\
|
||||
|
|
@ -581,7 +576,7 @@ use std::io::{BufferedReader, File};
|
|||
# 789 123\n\
|
||||
# 45 67\n\
|
||||
# ");
|
||||
# pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
|
||||
# pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
|
||||
# BufferedReader::new(MemReader::new(s.to_owned()))
|
||||
# }
|
||||
# }
|
||||
|
|
@ -615,7 +610,6 @@ fn main() {
|
|||
|
||||
fn read_int_pairs() -> ~[(int,int)] {
|
||||
let mut pairs = ~[];
|
||||
# let _g = std::io::ignore_io_error();
|
||||
let path = Path::new(&"foo.txt");
|
||||
|
||||
let mut reader = BufferedReader::new(File::open(&path));
|
||||
|
|
@ -696,7 +690,7 @@ a second condition and a helper function will suffice:
|
|||
# #[allow(unused_imports)];
|
||||
use std::io::{BufferedReader, File};
|
||||
# mod BufferedReader {
|
||||
# use std::io::File;
|
||||
# use std::io::{File, IoResult};
|
||||
# use std::io::MemReader;
|
||||
# use std::io::BufferedReader;
|
||||
# static s : &'static [u8] = bytes!("1 2\n\
|
||||
|
|
@ -704,7 +698,7 @@ use std::io::{BufferedReader, File};
|
|||
# 789 123\n\
|
||||
# 45 67\n\
|
||||
# ");
|
||||
# pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
|
||||
# pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
|
||||
# BufferedReader::new(MemReader::new(s.to_owned()))
|
||||
# }
|
||||
# }
|
||||
|
|
@ -752,7 +746,6 @@ fn parse_int(x: &str) -> int {
|
|||
|
||||
fn read_int_pairs() -> ~[(int,int)] {
|
||||
let mut pairs = ~[];
|
||||
# let _g = std::io::ignore_io_error();
|
||||
let path = Path::new(&"foo.txt");
|
||||
|
||||
let mut reader = BufferedReader::new(File::open(&path));
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ extern mod run_pass_stage2;
|
|||
use run_pass_stage2::*;
|
||||
use std::io;
|
||||
use std::io::Writer;
|
||||
#[allow(warnings)]
|
||||
fn main() {
|
||||
let mut out = io::stdout();
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -637,7 +637,7 @@ mod tests {
|
|||
fn test_mutex_arc_poison() {
|
||||
let arc = ~MutexArc::new(1);
|
||||
let arc2 = ~arc.clone();
|
||||
task::try(proc() {
|
||||
let _ = task::try(proc() {
|
||||
arc2.access(|one| {
|
||||
assert_eq!(*one, 2);
|
||||
})
|
||||
|
|
@ -668,7 +668,7 @@ mod tests {
|
|||
fn test_mutex_arc_access_in_unwind() {
|
||||
let arc = MutexArc::new(1i);
|
||||
let arc2 = arc.clone();
|
||||
task::try::<()>(proc() {
|
||||
let _ = task::try::<()>(proc() {
|
||||
struct Unwinder {
|
||||
i: MutexArc<int>
|
||||
}
|
||||
|
|
@ -687,7 +687,7 @@ mod tests {
|
|||
fn test_rw_arc_poison_wr() {
|
||||
let arc = RWArc::new(1);
|
||||
let arc2 = arc.clone();
|
||||
task::try(proc() {
|
||||
let _ = task::try(proc() {
|
||||
arc2.write(|one| {
|
||||
assert_eq!(*one, 2);
|
||||
})
|
||||
|
|
@ -701,7 +701,7 @@ mod tests {
|
|||
fn test_rw_arc_poison_ww() {
|
||||
let arc = RWArc::new(1);
|
||||
let arc2 = arc.clone();
|
||||
task::try(proc() {
|
||||
let _ = task::try(proc() {
|
||||
arc2.write(|one| {
|
||||
assert_eq!(*one, 2);
|
||||
})
|
||||
|
|
@ -714,7 +714,7 @@ mod tests {
|
|||
fn test_rw_arc_poison_dw() {
|
||||
let arc = RWArc::new(1);
|
||||
let arc2 = arc.clone();
|
||||
task::try(proc() {
|
||||
let _ = task::try(proc() {
|
||||
arc2.write_downgrade(|mut write_mode| {
|
||||
write_mode.write(|one| {
|
||||
assert_eq!(*one, 2);
|
||||
|
|
@ -729,7 +729,7 @@ mod tests {
|
|||
fn test_rw_arc_no_poison_rr() {
|
||||
let arc = RWArc::new(1);
|
||||
let arc2 = arc.clone();
|
||||
task::try(proc() {
|
||||
let _ = task::try(proc() {
|
||||
arc2.read(|one| {
|
||||
assert_eq!(*one, 2);
|
||||
})
|
||||
|
|
@ -742,7 +742,7 @@ mod tests {
|
|||
fn test_rw_arc_no_poison_rw() {
|
||||
let arc = RWArc::new(1);
|
||||
let arc2 = arc.clone();
|
||||
task::try(proc() {
|
||||
let _ = task::try(proc() {
|
||||
arc2.read(|one| {
|
||||
assert_eq!(*one, 2);
|
||||
})
|
||||
|
|
@ -755,7 +755,7 @@ mod tests {
|
|||
fn test_rw_arc_no_poison_dr() {
|
||||
let arc = RWArc::new(1);
|
||||
let arc2 = arc.clone();
|
||||
task::try(proc() {
|
||||
let _ = task::try(proc() {
|
||||
arc2.write_downgrade(|write_mode| {
|
||||
let read_mode = arc2.downgrade(write_mode);
|
||||
read_mode.read(|one| {
|
||||
|
|
@ -800,7 +800,7 @@ mod tests {
|
|||
|
||||
// Wait for children to pass their asserts
|
||||
for r in children.mut_iter() {
|
||||
r.recv();
|
||||
let _ = r.recv();
|
||||
}
|
||||
|
||||
// Wait for writer to finish
|
||||
|
|
@ -814,7 +814,7 @@ mod tests {
|
|||
fn test_rw_arc_access_in_unwind() {
|
||||
let arc = RWArc::new(1i);
|
||||
let arc2 = arc.clone();
|
||||
task::try::<()>(proc() {
|
||||
let _ = task::try::<()>(proc() {
|
||||
struct Unwinder {
|
||||
i: RWArc<int>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ mod test {
|
|||
ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
|
||||
let b = s.as_bytes().to_base64(STANDARD);
|
||||
bh.iter(|| {
|
||||
b.from_base64();
|
||||
b.from_base64().unwrap();
|
||||
});
|
||||
bh.bytes = b.len() as u64;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@
|
|||
|
||||
use std::str;
|
||||
|
||||
macro_rules! if_ok( ($e:expr) => (
|
||||
match $e { Ok(e) => e, Err(e) => { self.last_error = Err(e); return } }
|
||||
) )
|
||||
|
||||
// Simple Extensible Binary Markup Language (ebml) reader and writer on a
|
||||
// cursor model. See the specification here:
|
||||
// http://www.matroska.org/technical/specs/rfc/index.html
|
||||
|
|
@ -595,9 +599,15 @@ pub mod writer {
|
|||
|
||||
// ebml writing
|
||||
pub struct Encoder<'a> {
|
||||
// FIXME(#5665): this should take a trait object
|
||||
// FIXME(#5665): this should take a trait object. Note that if you
|
||||
// delete this comment you should consider removing the
|
||||
// unwrap()'s below of the results of the calls to
|
||||
// write(). We're guaranteed that writing into a MemWriter
|
||||
// won't fail, but this is not true for all I/O streams in
|
||||
// general.
|
||||
writer: &'a mut MemWriter,
|
||||
priv size_positions: ~[uint],
|
||||
last_error: io::IoResult<()>,
|
||||
}
|
||||
|
||||
fn write_sized_vuint(w: &mut MemWriter, n: uint, size: uint) {
|
||||
|
|
@ -609,7 +619,7 @@ pub mod writer {
|
|||
4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
|
||||
(n >> 8_u) as u8, n as u8]),
|
||||
_ => fail!("vint to write too big: {}", n)
|
||||
};
|
||||
}.unwrap()
|
||||
}
|
||||
|
||||
fn write_vuint(w: &mut MemWriter, n: uint) {
|
||||
|
|
@ -624,7 +634,8 @@ pub mod writer {
|
|||
let size_positions: ~[uint] = ~[];
|
||||
Encoder {
|
||||
writer: w,
|
||||
size_positions: size_positions
|
||||
size_positions: size_positions,
|
||||
last_error: Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -635,6 +646,7 @@ pub mod writer {
|
|||
Encoder {
|
||||
writer: cast::transmute_copy(&self.writer),
|
||||
size_positions: self.size_positions.clone(),
|
||||
last_error: Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -645,18 +657,18 @@ pub mod writer {
|
|||
write_vuint(self.writer, tag_id);
|
||||
|
||||
// Write a placeholder four-byte size.
|
||||
self.size_positions.push(self.writer.tell() as uint);
|
||||
self.size_positions.push(if_ok!(self.writer.tell()) as uint);
|
||||
let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
|
||||
self.writer.write(zeroes);
|
||||
if_ok!(self.writer.write(zeroes));
|
||||
}
|
||||
|
||||
pub fn end_tag(&mut self) {
|
||||
let last_size_pos = self.size_positions.pop().unwrap();
|
||||
let cur_pos = self.writer.tell();
|
||||
self.writer.seek(last_size_pos as i64, io::SeekSet);
|
||||
let cur_pos = if_ok!(self.writer.tell());
|
||||
if_ok!(self.writer.seek(last_size_pos as i64, io::SeekSet));
|
||||
let size = (cur_pos as uint - last_size_pos - 4);
|
||||
write_sized_vuint(self.writer, size, 4u);
|
||||
self.writer.seek(cur_pos as i64, io::SeekSet);
|
||||
if_ok!(self.writer.seek(cur_pos as i64, io::SeekSet));
|
||||
|
||||
debug!("End tag (size = {})", size);
|
||||
}
|
||||
|
|
@ -670,7 +682,7 @@ pub mod writer {
|
|||
pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) {
|
||||
write_vuint(self.writer, tag_id);
|
||||
write_vuint(self.writer, b.len());
|
||||
self.writer.write(b);
|
||||
self.writer.write(b).unwrap();
|
||||
}
|
||||
|
||||
pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) {
|
||||
|
|
@ -723,12 +735,12 @@ pub mod writer {
|
|||
|
||||
pub fn wr_bytes(&mut self, b: &[u8]) {
|
||||
debug!("Write {} bytes", b.len());
|
||||
self.writer.write(b);
|
||||
self.writer.write(b).unwrap();
|
||||
}
|
||||
|
||||
pub fn wr_str(&mut self, s: &str) {
|
||||
debug!("Write str: {}", s);
|
||||
self.writer.write(s.as_bytes());
|
||||
self.writer.write(s.as_bytes()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ mod tests {
|
|||
ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
|
||||
let b = s.as_bytes().to_hex();
|
||||
bh.iter(|| {
|
||||
b.from_hex();
|
||||
b.from_hex().unwrap();
|
||||
});
|
||||
bh.bytes = b.len() as u64;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,6 +234,10 @@ use serialize::Encodable;
|
|||
use serialize;
|
||||
use treemap::TreeMap;
|
||||
|
||||
macro_rules! if_ok( ($e:expr) => (
|
||||
match $e { Ok(e) => e, Err(e) => { self.error = Err(e); return } }
|
||||
) )
|
||||
|
||||
/// Represents a json value
|
||||
#[deriving(Clone, Eq)]
|
||||
pub enum Json {
|
||||
|
|
@ -260,6 +264,14 @@ pub struct Error {
|
|||
priv msg: ~str,
|
||||
}
|
||||
|
||||
fn io_error_to_error(io: io::IoError) -> Error {
|
||||
Error {
|
||||
line: 0,
|
||||
col: 0,
|
||||
msg: format!("io error: {}", io)
|
||||
}
|
||||
}
|
||||
|
||||
fn escape_str(s: &str) -> ~str {
|
||||
let mut escaped = ~"\"";
|
||||
for c in s.chars() {
|
||||
|
|
@ -289,13 +301,14 @@ fn spaces(n: uint) -> ~str {
|
|||
/// A structure for implementing serialization to JSON.
|
||||
pub struct Encoder<'a> {
|
||||
priv wr: &'a mut io::Writer,
|
||||
priv error: io::IoResult<()>,
|
||||
}
|
||||
|
||||
impl<'a> Encoder<'a> {
|
||||
/// Creates a new JSON encoder whose output will be written to the writer
|
||||
/// specified.
|
||||
pub fn new<'a>(wr: &'a mut io::Writer) -> Encoder<'a> {
|
||||
Encoder { wr: wr }
|
||||
Encoder { wr: wr, error: Ok(()) }
|
||||
}
|
||||
|
||||
/// Encode the specified struct into a json [u8]
|
||||
|
|
@ -317,7 +330,7 @@ impl<'a> Encoder<'a> {
|
|||
}
|
||||
|
||||
impl<'a> serialize::Encoder for Encoder<'a> {
|
||||
fn emit_nil(&mut self) { write!(self.wr, "null") }
|
||||
fn emit_nil(&mut self) { if_ok!(write!(self.wr, "null")) }
|
||||
|
||||
fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); }
|
||||
fn emit_u64(&mut self, v: u64) { self.emit_f64(v as f64); }
|
||||
|
|
@ -333,20 +346,20 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
|
||||
fn emit_bool(&mut self, v: bool) {
|
||||
if v {
|
||||
write!(self.wr, "true");
|
||||
if_ok!(write!(self.wr, "true"));
|
||||
} else {
|
||||
write!(self.wr, "false");
|
||||
if_ok!(write!(self.wr, "false"));
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_f64(&mut self, v: f64) {
|
||||
write!(self.wr, "{}", f64::to_str_digits(v, 6u))
|
||||
if_ok!(write!(self.wr, "{}", f64::to_str_digits(v, 6u)))
|
||||
}
|
||||
fn emit_f32(&mut self, v: f32) { self.emit_f64(v as f64); }
|
||||
|
||||
fn emit_char(&mut self, v: char) { self.emit_str(str::from_char(v)) }
|
||||
fn emit_str(&mut self, v: &str) {
|
||||
write!(self.wr, "{}", escape_str(v))
|
||||
if_ok!(write!(self.wr, "{}", escape_str(v)))
|
||||
}
|
||||
|
||||
fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'a>|) { f(self) }
|
||||
|
|
@ -360,19 +373,19 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
// Bunny => "Bunny"
|
||||
// Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
|
||||
if cnt == 0 {
|
||||
write!(self.wr, "{}", escape_str(name));
|
||||
if_ok!(write!(self.wr, "{}", escape_str(name)));
|
||||
} else {
|
||||
write!(self.wr, "\\{\"variant\":");
|
||||
write!(self.wr, "{}", escape_str(name));
|
||||
write!(self.wr, ",\"fields\":[");
|
||||
if_ok!(write!(self.wr, "\\{\"variant\":"));
|
||||
if_ok!(write!(self.wr, "{}", escape_str(name)));
|
||||
if_ok!(write!(self.wr, ",\"fields\":["));
|
||||
f(self);
|
||||
write!(self.wr, "]\\}");
|
||||
if_ok!(write!(self.wr, "]\\}"));
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_enum_variant_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
|
||||
if idx != 0 {
|
||||
write!(self.wr, ",");
|
||||
if_ok!(write!(self.wr, ","));
|
||||
}
|
||||
f(self);
|
||||
}
|
||||
|
|
@ -393,17 +406,17 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
}
|
||||
|
||||
fn emit_struct(&mut self, _: &str, _: uint, f: |&mut Encoder<'a>|) {
|
||||
write!(self.wr, r"\{");
|
||||
if_ok!(write!(self.wr, r"\{"));
|
||||
f(self);
|
||||
write!(self.wr, r"\}");
|
||||
if_ok!(write!(self.wr, r"\}"));
|
||||
}
|
||||
|
||||
fn emit_struct_field(&mut self,
|
||||
name: &str,
|
||||
idx: uint,
|
||||
f: |&mut Encoder<'a>|) {
|
||||
if idx != 0 { write!(self.wr, ",") }
|
||||
write!(self.wr, "{}:", escape_str(name));
|
||||
if idx != 0 { if_ok!(write!(self.wr, ",")) }
|
||||
if_ok!(write!(self.wr, "{}:", escape_str(name)));
|
||||
f(self);
|
||||
}
|
||||
|
||||
|
|
@ -429,31 +442,31 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
fn emit_option_some(&mut self, f: |&mut Encoder<'a>|) { f(self); }
|
||||
|
||||
fn emit_seq(&mut self, _len: uint, f: |&mut Encoder<'a>|) {
|
||||
write!(self.wr, "[");
|
||||
if_ok!(write!(self.wr, "["));
|
||||
f(self);
|
||||
write!(self.wr, "]");
|
||||
if_ok!(write!(self.wr, "]"));
|
||||
}
|
||||
|
||||
fn emit_seq_elt(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
|
||||
if idx != 0 {
|
||||
write!(self.wr, ",");
|
||||
if_ok!(write!(self.wr, ","));
|
||||
}
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'a>|) {
|
||||
write!(self.wr, r"\{");
|
||||
if_ok!(write!(self.wr, r"\{"));
|
||||
f(self);
|
||||
write!(self.wr, r"\}");
|
||||
if_ok!(write!(self.wr, r"\}"));
|
||||
}
|
||||
|
||||
fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
|
||||
if idx != 0 { write!(self.wr, ",") }
|
||||
if idx != 0 { if_ok!(write!(self.wr, ",")) }
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
|
||||
write!(self.wr, ":");
|
||||
if_ok!(write!(self.wr, ":"));
|
||||
f(self)
|
||||
}
|
||||
}
|
||||
|
|
@ -463,6 +476,7 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
pub struct PrettyEncoder<'a> {
|
||||
priv wr: &'a mut io::Writer,
|
||||
priv indent: uint,
|
||||
priv error: io::IoResult<()>,
|
||||
}
|
||||
|
||||
impl<'a> PrettyEncoder<'a> {
|
||||
|
|
@ -471,12 +485,13 @@ impl<'a> PrettyEncoder<'a> {
|
|||
PrettyEncoder {
|
||||
wr: wr,
|
||||
indent: 0,
|
||||
error: Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> serialize::Encoder for PrettyEncoder<'a> {
|
||||
fn emit_nil(&mut self) { write!(self.wr, "null") }
|
||||
fn emit_nil(&mut self) { if_ok!(write!(self.wr, "null")); }
|
||||
|
||||
fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); }
|
||||
fn emit_u64(&mut self, v: u64) { self.emit_f64(v as f64); }
|
||||
|
|
@ -492,19 +507,21 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
|
|||
|
||||
fn emit_bool(&mut self, v: bool) {
|
||||
if v {
|
||||
write!(self.wr, "true");
|
||||
if_ok!(write!(self.wr, "true"));
|
||||
} else {
|
||||
write!(self.wr, "false");
|
||||
if_ok!(write!(self.wr, "false"));
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_f64(&mut self, v: f64) {
|
||||
write!(self.wr, "{}", f64::to_str_digits(v, 6u))
|
||||
if_ok!(write!(self.wr, "{}", f64::to_str_digits(v, 6u)));
|
||||
}
|
||||
fn emit_f32(&mut self, v: f32) { self.emit_f64(v as f64); }
|
||||
|
||||
fn emit_char(&mut self, v: char) { self.emit_str(str::from_char(v)) }
|
||||
fn emit_str(&mut self, v: &str) { write!(self.wr, "{}", escape_str(v)); }
|
||||
fn emit_str(&mut self, v: &str) {
|
||||
if_ok!(write!(self.wr, "{}", escape_str(v)));
|
||||
}
|
||||
|
||||
fn emit_enum(&mut self, _name: &str, f: |&mut PrettyEncoder<'a>|) {
|
||||
f(self)
|
||||
|
|
@ -516,13 +533,14 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
|
|||
cnt: uint,
|
||||
f: |&mut PrettyEncoder<'a>|) {
|
||||
if cnt == 0 {
|
||||
write!(self.wr, "{}", escape_str(name));
|
||||
if_ok!(write!(self.wr, "{}", escape_str(name)));
|
||||
} else {
|
||||
self.indent += 2;
|
||||
write!(self.wr, "[\n{}{},\n", spaces(self.indent), escape_str(name));
|
||||
if_ok!(write!(self.wr, "[\n{}{},\n", spaces(self.indent),
|
||||
escape_str(name)));
|
||||
f(self);
|
||||
self.indent -= 2;
|
||||
write!(self.wr, "\n{}]", spaces(self.indent));
|
||||
if_ok!(write!(self.wr, "\n{}]", spaces(self.indent)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -530,9 +548,9 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
|
|||
idx: uint,
|
||||
f: |&mut PrettyEncoder<'a>|) {
|
||||
if idx != 0 {
|
||||
write!(self.wr, ",\n");
|
||||
if_ok!(write!(self.wr, ",\n"));
|
||||
}
|
||||
write!(self.wr, "{}", spaces(self.indent));
|
||||
if_ok!(write!(self.wr, "{}", spaces(self.indent)));
|
||||
f(self)
|
||||
}
|
||||
|
||||
|
|
@ -557,13 +575,13 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
|
|||
len: uint,
|
||||
f: |&mut PrettyEncoder<'a>|) {
|
||||
if len == 0 {
|
||||
write!(self.wr, "\\{\\}");
|
||||
if_ok!(write!(self.wr, "\\{\\}"));
|
||||
} else {
|
||||
write!(self.wr, "\\{");
|
||||
if_ok!(write!(self.wr, "\\{"));
|
||||
self.indent += 2;
|
||||
f(self);
|
||||
self.indent -= 2;
|
||||
write!(self.wr, "\n{}\\}", spaces(self.indent));
|
||||
if_ok!(write!(self.wr, "\n{}\\}", spaces(self.indent)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -572,11 +590,11 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
|
|||
idx: uint,
|
||||
f: |&mut PrettyEncoder<'a>|) {
|
||||
if idx == 0 {
|
||||
write!(self.wr, "\n");
|
||||
if_ok!(write!(self.wr, "\n"));
|
||||
} else {
|
||||
write!(self.wr, ",\n");
|
||||
if_ok!(write!(self.wr, ",\n"));
|
||||
}
|
||||
write!(self.wr, "{}{}: ", spaces(self.indent), escape_str(name));
|
||||
if_ok!(write!(self.wr, "{}{}: ", spaces(self.indent), escape_str(name)));
|
||||
f(self);
|
||||
}
|
||||
|
||||
|
|
@ -605,50 +623,50 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
|
|||
|
||||
fn emit_seq(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) {
|
||||
if len == 0 {
|
||||
write!(self.wr, "[]");
|
||||
if_ok!(write!(self.wr, "[]"));
|
||||
} else {
|
||||
write!(self.wr, "[");
|
||||
if_ok!(write!(self.wr, "["));
|
||||
self.indent += 2;
|
||||
f(self);
|
||||
self.indent -= 2;
|
||||
write!(self.wr, "\n{}]", spaces(self.indent));
|
||||
if_ok!(write!(self.wr, "\n{}]", spaces(self.indent)));
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_seq_elt(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) {
|
||||
if idx == 0 {
|
||||
write!(self.wr, "\n");
|
||||
if_ok!(write!(self.wr, "\n"));
|
||||
} else {
|
||||
write!(self.wr, ",\n");
|
||||
if_ok!(write!(self.wr, ",\n"));
|
||||
}
|
||||
write!(self.wr, "{}", spaces(self.indent));
|
||||
if_ok!(write!(self.wr, "{}", spaces(self.indent)));
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn emit_map(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) {
|
||||
if len == 0 {
|
||||
write!(self.wr, "\\{\\}");
|
||||
if_ok!(write!(self.wr, "\\{\\}"));
|
||||
} else {
|
||||
write!(self.wr, "\\{");
|
||||
if_ok!(write!(self.wr, "\\{"));
|
||||
self.indent += 2;
|
||||
f(self);
|
||||
self.indent -= 2;
|
||||
write!(self.wr, "\n{}\\}", spaces(self.indent));
|
||||
if_ok!(write!(self.wr, "\n{}\\}", spaces(self.indent)));
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_map_elt_key(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) {
|
||||
if idx == 0 {
|
||||
write!(self.wr, "\n");
|
||||
if_ok!(write!(self.wr, "\n"));
|
||||
} else {
|
||||
write!(self.wr, ",\n");
|
||||
if_ok!(write!(self.wr, ",\n"));
|
||||
}
|
||||
write!(self.wr, "{}", spaces(self.indent));
|
||||
if_ok!(write!(self.wr, "{}", spaces(self.indent)));
|
||||
f(self);
|
||||
}
|
||||
|
||||
fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut PrettyEncoder<'a>|) {
|
||||
write!(self.wr, ": ");
|
||||
if_ok!(write!(self.wr, ": "));
|
||||
f(self);
|
||||
}
|
||||
}
|
||||
|
|
@ -668,22 +686,24 @@ impl<E: serialize::Encoder> serialize::Encodable<E> for Json {
|
|||
|
||||
impl Json{
|
||||
/// Encodes a json value into a io::writer. Uses a single line.
|
||||
pub fn to_writer(&self, wr: &mut io::Writer) {
|
||||
pub fn to_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> {
|
||||
let mut encoder = Encoder::new(wr);
|
||||
self.encode(&mut encoder)
|
||||
self.encode(&mut encoder);
|
||||
encoder.error
|
||||
}
|
||||
|
||||
/// Encodes a json value into a io::writer.
|
||||
/// Pretty-prints in a more readable format.
|
||||
pub fn to_pretty_writer(&self, wr: &mut io::Writer) {
|
||||
pub fn to_pretty_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> {
|
||||
let mut encoder = PrettyEncoder::new(wr);
|
||||
self.encode(&mut encoder)
|
||||
self.encode(&mut encoder);
|
||||
encoder.error
|
||||
}
|
||||
|
||||
/// Encodes a json value into a string
|
||||
pub fn to_pretty_str(&self) -> ~str {
|
||||
let mut s = MemWriter::new();
|
||||
self.to_pretty_writer(&mut s as &mut io::Writer);
|
||||
self.to_pretty_writer(&mut s as &mut io::Writer).unwrap();
|
||||
str::from_utf8_owned(s.unwrap()).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
@ -1067,7 +1087,14 @@ impl<T : Iterator<char>> Parser<T> {
|
|||
|
||||
/// Decodes a json value from an `&mut io::Reader`
|
||||
pub fn from_reader(rdr: &mut io::Reader) -> Result<Json, Error> {
|
||||
let s = str::from_utf8_owned(rdr.read_to_end()).unwrap();
|
||||
let contents = match rdr.read_to_end() {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(io_error_to_error(e))
|
||||
};
|
||||
let s = match str::from_utf8_owned(contents) {
|
||||
Some(s) => s,
|
||||
None => return Err(Error { line: 0, col: 0, msg: ~"contents not utf-8" })
|
||||
};
|
||||
let mut parser = Parser::new(s.chars());
|
||||
parser.parse()
|
||||
}
|
||||
|
|
@ -1540,7 +1567,7 @@ impl to_str::ToStr for Json {
|
|||
/// Encodes a json value into a string
|
||||
fn to_str(&self) -> ~str {
|
||||
let mut s = MemWriter::new();
|
||||
self.to_writer(&mut s as &mut io::Writer);
|
||||
self.to_writer(&mut s as &mut io::Writer).unwrap();
|
||||
str::from_utf8_owned(s.unwrap()).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,11 @@ Rust extras are part of the standard Rust distribution.
|
|||
#[deny(non_camel_case_types)];
|
||||
#[deny(missing_doc)];
|
||||
|
||||
#[cfg(stage0)]
|
||||
macro_rules! if_ok (
|
||||
($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
|
||||
)
|
||||
|
||||
// Utility modules
|
||||
|
||||
pub mod c_vec;
|
||||
|
|
|
|||
|
|
@ -322,14 +322,15 @@ pub fn winsorize(samples: &mut [f64], pct: f64) {
|
|||
}
|
||||
|
||||
/// Render writes the min, max and quartiles of the provided `Summary` to the provided `Writer`.
|
||||
pub fn write_5_number_summary(w: &mut io::Writer, s: &Summary) {
|
||||
pub fn write_5_number_summary(w: &mut io::Writer,
|
||||
s: &Summary) -> io::IoResult<()> {
|
||||
let (q1,q2,q3) = s.quartiles;
|
||||
write!(w, "(min={}, q1={}, med={}, q3={}, max={})",
|
||||
s.min,
|
||||
q1,
|
||||
q2,
|
||||
q3,
|
||||
s.max);
|
||||
s.max)
|
||||
}
|
||||
|
||||
/// Render a boxplot to the provided writer. The boxplot shows the min, max and quartiles of the
|
||||
|
|
@ -344,7 +345,8 @@ pub fn write_5_number_summary(w: &mut io::Writer, s: &Summary) {
|
|||
/// 10 | [--****#******----------] | 40
|
||||
/// ~~~~
|
||||
|
||||
pub fn write_boxplot(w: &mut io::Writer, s: &Summary, width_hint: uint) {
|
||||
pub fn write_boxplot(w: &mut io::Writer, s: &Summary,
|
||||
width_hint: uint) -> io::IoResult<()> {
|
||||
|
||||
let (q1,q2,q3) = s.quartiles;
|
||||
|
||||
|
|
@ -374,48 +376,49 @@ pub fn write_boxplot(w: &mut io::Writer, s: &Summary, width_hint: uint) {
|
|||
let range_width = width_hint - overhead_width;;
|
||||
let char_step = range / (range_width as f64);
|
||||
|
||||
write!(w, "{} |", lostr);
|
||||
if_ok!(write!(w, "{} |", lostr));
|
||||
|
||||
let mut c = 0;
|
||||
let mut v = lo;
|
||||
|
||||
while c < range_width && v < s.min {
|
||||
write!(w, " ");
|
||||
if_ok!(write!(w, " "));
|
||||
v += char_step;
|
||||
c += 1;
|
||||
}
|
||||
write!(w, "[");
|
||||
if_ok!(write!(w, "["));
|
||||
c += 1;
|
||||
while c < range_width && v < q1 {
|
||||
write!(w, "-");
|
||||
if_ok!(write!(w, "-"));
|
||||
v += char_step;
|
||||
c += 1;
|
||||
}
|
||||
while c < range_width && v < q2 {
|
||||
write!(w, "*");
|
||||
if_ok!(write!(w, "*"));
|
||||
v += char_step;
|
||||
c += 1;
|
||||
}
|
||||
write!(w, r"\#");
|
||||
if_ok!(write!(w, r"\#"));
|
||||
c += 1;
|
||||
while c < range_width && v < q3 {
|
||||
write!(w, "*");
|
||||
if_ok!(write!(w, "*"));
|
||||
v += char_step;
|
||||
c += 1;
|
||||
}
|
||||
while c < range_width && v < s.max {
|
||||
write!(w, "-");
|
||||
if_ok!(write!(w, "-"));
|
||||
v += char_step;
|
||||
c += 1;
|
||||
}
|
||||
write!(w, "]");
|
||||
if_ok!(write!(w, "]"));
|
||||
while c < range_width {
|
||||
write!(w, " ");
|
||||
if_ok!(write!(w, " "));
|
||||
v += char_step;
|
||||
c += 1;
|
||||
}
|
||||
|
||||
write!(w, "| {}", histr);
|
||||
if_ok!(write!(w, "| {}", histr));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns a HashMap with the number of occurrences of every element in the
|
||||
|
|
@ -453,11 +456,11 @@ mod tests {
|
|||
|
||||
let mut w = io::stdout();
|
||||
let w = &mut w as &mut io::Writer;
|
||||
write!(w, "\n");
|
||||
write_5_number_summary(w, &summ2);
|
||||
write!(w, "\n");
|
||||
write_boxplot(w, &summ2, 50);
|
||||
write!(w, "\n");
|
||||
(write!(w, "\n")).unwrap();
|
||||
write_5_number_summary(w, &summ2).unwrap();
|
||||
(write!(w, "\n")).unwrap();
|
||||
write_boxplot(w, &summ2, 50).unwrap();
|
||||
(write!(w, "\n")).unwrap();
|
||||
|
||||
assert_eq!(summ.sum, summ2.sum);
|
||||
assert_eq!(summ.min, summ2.min);
|
||||
|
|
@ -1000,7 +1003,7 @@ mod tests {
|
|||
fn t(s: &Summary, expected: ~str) {
|
||||
use std::io::MemWriter;
|
||||
let mut m = MemWriter::new();
|
||||
write_boxplot(&mut m as &mut io::Writer, s, 30);
|
||||
write_boxplot(&mut m as &mut io::Writer, s, 30).unwrap();
|
||||
let out = str::from_utf8_owned(m.unwrap()).unwrap();
|
||||
assert_eq!(out, expected);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -959,7 +959,7 @@ mod tests {
|
|||
fn test_mutex_cond_no_waiter() {
|
||||
let m = Mutex::new();
|
||||
let m2 = m.clone();
|
||||
task::try(proc() {
|
||||
let _ = task::try(proc() {
|
||||
m.lock_cond(|_x| { })
|
||||
});
|
||||
m2.lock_cond(|cond| {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ impl TempDir {
|
|||
let mut r = rand::rng();
|
||||
for _ in range(0u, 1000) {
|
||||
let p = tmpdir.join(r.gen_ascii_str(16) + suffix);
|
||||
match io::result(|| fs::mkdir(&p, io::UserRWX)) {
|
||||
match fs::mkdir(&p, io::UserRWX) {
|
||||
Err(..) => {}
|
||||
Ok(()) => return Some(TempDir { path: Some(p) })
|
||||
}
|
||||
|
|
@ -73,7 +73,8 @@ impl Drop for TempDir {
|
|||
fn drop(&mut self) {
|
||||
for path in self.path.iter() {
|
||||
if path.exists() {
|
||||
fs::rmdir_recursive(path);
|
||||
// FIXME: is failing the right thing to do?
|
||||
fs::rmdir_recursive(path).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,7 +163,11 @@ pub fn test_main(args: &[~str], tests: ~[TestDescAndFn]) {
|
|||
Some(Err(msg)) => fail!("{}", msg),
|
||||
None => return
|
||||
};
|
||||
if !run_tests_console(&opts, tests) { fail!("Some tests failed"); }
|
||||
match run_tests_console(&opts, tests) {
|
||||
Ok(true) => {}
|
||||
Ok(false) => fail!("Some tests failed"),
|
||||
Err(e) => fail!("io error when running tests: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
// A variant optimized for invocation with a static test vector.
|
||||
|
|
@ -359,16 +363,17 @@ struct ConsoleTestState<T> {
|
|||
}
|
||||
|
||||
impl<T: Writer> ConsoleTestState<T> {
|
||||
pub fn new(opts: &TestOpts, _: Option<T>) -> ConsoleTestState<StdWriter> {
|
||||
pub fn new(opts: &TestOpts,
|
||||
_: Option<T>) -> io::IoResult<ConsoleTestState<StdWriter>> {
|
||||
let log_out = match opts.logfile {
|
||||
Some(ref path) => File::create(path),
|
||||
Some(ref path) => Some(if_ok!(File::create(path))),
|
||||
None => None
|
||||
};
|
||||
let out = match term::Terminal::new(io::stdout()) {
|
||||
Err(_) => Raw(io::stdout()),
|
||||
Ok(t) => Pretty(t)
|
||||
};
|
||||
ConsoleTestState {
|
||||
Ok(ConsoleTestState {
|
||||
out: out,
|
||||
log_out: log_out,
|
||||
use_color: use_color(),
|
||||
|
|
@ -380,100 +385,103 @@ impl<T: Writer> ConsoleTestState<T> {
|
|||
metrics: MetricMap::new(),
|
||||
failures: ~[],
|
||||
max_name_len: 0u,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn write_ok(&mut self) {
|
||||
self.write_pretty("ok", term::color::GREEN);
|
||||
pub fn write_ok(&mut self) -> io::IoResult<()> {
|
||||
self.write_pretty("ok", term::color::GREEN)
|
||||
}
|
||||
|
||||
pub fn write_failed(&mut self) {
|
||||
self.write_pretty("FAILED", term::color::RED);
|
||||
pub fn write_failed(&mut self) -> io::IoResult<()> {
|
||||
self.write_pretty("FAILED", term::color::RED)
|
||||
}
|
||||
|
||||
pub fn write_ignored(&mut self) {
|
||||
self.write_pretty("ignored", term::color::YELLOW);
|
||||
pub fn write_ignored(&mut self) -> io::IoResult<()> {
|
||||
self.write_pretty("ignored", term::color::YELLOW)
|
||||
}
|
||||
|
||||
pub fn write_metric(&mut self) {
|
||||
self.write_pretty("metric", term::color::CYAN);
|
||||
pub fn write_metric(&mut self) -> io::IoResult<()> {
|
||||
self.write_pretty("metric", term::color::CYAN)
|
||||
}
|
||||
|
||||
pub fn write_bench(&mut self) {
|
||||
self.write_pretty("bench", term::color::CYAN);
|
||||
pub fn write_bench(&mut self) -> io::IoResult<()> {
|
||||
self.write_pretty("bench", term::color::CYAN)
|
||||
}
|
||||
|
||||
pub fn write_added(&mut self) {
|
||||
self.write_pretty("added", term::color::GREEN);
|
||||
pub fn write_added(&mut self) -> io::IoResult<()> {
|
||||
self.write_pretty("added", term::color::GREEN)
|
||||
}
|
||||
|
||||
pub fn write_improved(&mut self) {
|
||||
self.write_pretty("improved", term::color::GREEN);
|
||||
pub fn write_improved(&mut self) -> io::IoResult<()> {
|
||||
self.write_pretty("improved", term::color::GREEN)
|
||||
}
|
||||
|
||||
pub fn write_removed(&mut self) {
|
||||
self.write_pretty("removed", term::color::YELLOW);
|
||||
pub fn write_removed(&mut self) -> io::IoResult<()> {
|
||||
self.write_pretty("removed", term::color::YELLOW)
|
||||
}
|
||||
|
||||
pub fn write_regressed(&mut self) {
|
||||
self.write_pretty("regressed", term::color::RED);
|
||||
pub fn write_regressed(&mut self) -> io::IoResult<()> {
|
||||
self.write_pretty("regressed", term::color::RED)
|
||||
}
|
||||
|
||||
pub fn write_pretty(&mut self,
|
||||
word: &str,
|
||||
color: term::color::Color) {
|
||||
color: term::color::Color) -> io::IoResult<()> {
|
||||
match self.out {
|
||||
Pretty(ref mut term) => {
|
||||
if self.use_color {
|
||||
term.fg(color);
|
||||
if_ok!(term.fg(color));
|
||||
}
|
||||
term.write(word.as_bytes());
|
||||
if_ok!(term.write(word.as_bytes()));
|
||||
if self.use_color {
|
||||
term.reset();
|
||||
if_ok!(term.reset());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Raw(ref mut stdout) => stdout.write(word.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_plain(&mut self, s: &str) {
|
||||
pub fn write_plain(&mut self, s: &str) -> io::IoResult<()> {
|
||||
match self.out {
|
||||
Pretty(ref mut term) => term.write(s.as_bytes()),
|
||||
Raw(ref mut stdout) => stdout.write(s.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_run_start(&mut self, len: uint) {
|
||||
pub fn write_run_start(&mut self, len: uint) -> io::IoResult<()> {
|
||||
self.total = len;
|
||||
let noun = if len != 1 { &"tests" } else { &"test" };
|
||||
self.write_plain(format!("\nrunning {} {}\n", len, noun));
|
||||
self.write_plain(format!("\nrunning {} {}\n", len, noun))
|
||||
}
|
||||
|
||||
pub fn write_test_start(&mut self, test: &TestDesc, align: NamePadding) {
|
||||
pub fn write_test_start(&mut self, test: &TestDesc,
|
||||
align: NamePadding) -> io::IoResult<()> {
|
||||
let name = test.padded_name(self.max_name_len, align);
|
||||
self.write_plain(format!("test {} ... ", name));
|
||||
self.write_plain(format!("test {} ... ", name))
|
||||
}
|
||||
|
||||
pub fn write_result(&mut self, result: &TestResult) {
|
||||
match *result {
|
||||
pub fn write_result(&mut self, result: &TestResult) -> io::IoResult<()> {
|
||||
if_ok!(match *result {
|
||||
TrOk => self.write_ok(),
|
||||
TrFailed => self.write_failed(),
|
||||
TrIgnored => self.write_ignored(),
|
||||
TrMetrics(ref mm) => {
|
||||
self.write_metric();
|
||||
self.write_plain(format!(": {}", fmt_metrics(mm)));
|
||||
if_ok!(self.write_metric());
|
||||
self.write_plain(format!(": {}", fmt_metrics(mm)))
|
||||
}
|
||||
TrBench(ref bs) => {
|
||||
self.write_bench();
|
||||
self.write_plain(format!(": {}", fmt_bench_samples(bs)));
|
||||
if_ok!(self.write_bench());
|
||||
self.write_plain(format!(": {}", fmt_bench_samples(bs)))
|
||||
}
|
||||
}
|
||||
self.write_plain("\n");
|
||||
});
|
||||
self.write_plain("\n")
|
||||
}
|
||||
|
||||
pub fn write_log(&mut self, test: &TestDesc, result: &TestResult) {
|
||||
pub fn write_log(&mut self, test: &TestDesc,
|
||||
result: &TestResult) -> io::IoResult<()> {
|
||||
match self.log_out {
|
||||
None => (),
|
||||
None => Ok(()),
|
||||
Some(ref mut o) => {
|
||||
let s = format!("{} {}\n", match *result {
|
||||
TrOk => ~"ok",
|
||||
|
|
@ -482,24 +490,25 @@ impl<T: Writer> ConsoleTestState<T> {
|
|||
TrMetrics(ref mm) => fmt_metrics(mm),
|
||||
TrBench(ref bs) => fmt_bench_samples(bs)
|
||||
}, test.name.to_str());
|
||||
o.write(s.as_bytes());
|
||||
o.write(s.as_bytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_failures(&mut self) {
|
||||
self.write_plain("\nfailures:\n");
|
||||
pub fn write_failures(&mut self) -> io::IoResult<()> {
|
||||
if_ok!(self.write_plain("\nfailures:\n"));
|
||||
let mut failures = ~[];
|
||||
for f in self.failures.iter() {
|
||||
failures.push(f.name.to_str());
|
||||
}
|
||||
failures.sort();
|
||||
for name in failures.iter() {
|
||||
self.write_plain(format!(" {}\n", name.to_str()));
|
||||
if_ok!(self.write_plain(format!(" {}\n", name.to_str())));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_metric_diff(&mut self, diff: &MetricDiff) {
|
||||
pub fn write_metric_diff(&mut self, diff: &MetricDiff) -> io::IoResult<()> {
|
||||
let mut noise = 0;
|
||||
let mut improved = 0;
|
||||
let mut regressed = 0;
|
||||
|
|
@ -511,77 +520,82 @@ impl<T: Writer> ConsoleTestState<T> {
|
|||
LikelyNoise => noise += 1,
|
||||
MetricAdded => {
|
||||
added += 1;
|
||||
self.write_added();
|
||||
self.write_plain(format!(": {}\n", *k));
|
||||
if_ok!(self.write_added());
|
||||
if_ok!(self.write_plain(format!(": {}\n", *k)));
|
||||
}
|
||||
MetricRemoved => {
|
||||
removed += 1;
|
||||
self.write_removed();
|
||||
self.write_plain(format!(": {}\n", *k));
|
||||
if_ok!(self.write_removed());
|
||||
if_ok!(self.write_plain(format!(": {}\n", *k)));
|
||||
}
|
||||
Improvement(pct) => {
|
||||
improved += 1;
|
||||
self.write_plain(format!(": {}", *k));
|
||||
self.write_improved();
|
||||
self.write_plain(format!(" by {:.2f}%\n", pct as f64));
|
||||
if_ok!(self.write_plain(format!(": {}", *k)));
|
||||
if_ok!(self.write_improved());
|
||||
if_ok!(self.write_plain(format!(" by {:.2f}%\n", pct as f64)));
|
||||
}
|
||||
Regression(pct) => {
|
||||
regressed += 1;
|
||||
self.write_plain(format!(": {}", *k));
|
||||
self.write_regressed();
|
||||
self.write_plain(format!(" by {:.2f}%\n", pct as f64));
|
||||
if_ok!(self.write_plain(format!(": {}", *k)));
|
||||
if_ok!(self.write_regressed());
|
||||
if_ok!(self.write_plain(format!(" by {:.2f}%\n", pct as f64)));
|
||||
}
|
||||
}
|
||||
}
|
||||
self.write_plain(format!("result of ratchet: {} matrics added, {} removed, \
|
||||
{} improved, {} regressed, {} noise\n",
|
||||
added, removed, improved, regressed, noise));
|
||||
if_ok!(self.write_plain(format!("result of ratchet: {} matrics added, \
|
||||
{} removed, {} improved, {} regressed, \
|
||||
{} noise\n",
|
||||
added, removed, improved, regressed,
|
||||
noise)));
|
||||
if regressed == 0 {
|
||||
self.write_plain("updated ratchet file\n");
|
||||
if_ok!(self.write_plain("updated ratchet file\n"));
|
||||
} else {
|
||||
self.write_plain("left ratchet file untouched\n");
|
||||
if_ok!(self.write_plain("left ratchet file untouched\n"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_run_finish(&mut self,
|
||||
ratchet_metrics: &Option<Path>,
|
||||
ratchet_pct: Option<f64>) -> bool {
|
||||
ratchet_pct: Option<f64>) -> io::IoResult<bool> {
|
||||
assert!(self.passed + self.failed + self.ignored + self.measured == self.total);
|
||||
|
||||
let ratchet_success = match *ratchet_metrics {
|
||||
None => true,
|
||||
Some(ref pth) => {
|
||||
self.write_plain(format!("\nusing metrics ratcher: {}\n", pth.display()));
|
||||
if_ok!(self.write_plain(format!("\nusing metrics ratcher: {}\n",
|
||||
pth.display())));
|
||||
match ratchet_pct {
|
||||
None => (),
|
||||
Some(pct) =>
|
||||
self.write_plain(format!("with noise-tolerance forced to: {}%\n",
|
||||
pct))
|
||||
if_ok!(self.write_plain(format!("with noise-tolerance \
|
||||
forced to: {}%\n",
|
||||
pct)))
|
||||
}
|
||||
let (diff, ok) = self.metrics.ratchet(pth, ratchet_pct);
|
||||
self.write_metric_diff(&diff);
|
||||
if_ok!(self.write_metric_diff(&diff));
|
||||
ok
|
||||
}
|
||||
};
|
||||
|
||||
let test_success = self.failed == 0u;
|
||||
if !test_success {
|
||||
self.write_failures();
|
||||
if_ok!(self.write_failures());
|
||||
}
|
||||
|
||||
let success = ratchet_success && test_success;
|
||||
|
||||
self.write_plain("\ntest result: ");
|
||||
if_ok!(self.write_plain("\ntest result: "));
|
||||
if success {
|
||||
// There's no parallelism at this point so it's safe to use color
|
||||
self.write_ok();
|
||||
if_ok!(self.write_ok());
|
||||
} else {
|
||||
self.write_failed();
|
||||
if_ok!(self.write_failed());
|
||||
}
|
||||
let s = format!(". {} passed; {} failed; {} ignored; {} measured\n\n",
|
||||
self.passed, self.failed, self.ignored, self.measured);
|
||||
self.write_plain(s);
|
||||
return success;
|
||||
if_ok!(self.write_plain(s));
|
||||
return Ok(success);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -611,15 +625,16 @@ pub fn fmt_bench_samples(bs: &BenchSamples) -> ~str {
|
|||
|
||||
// A simple console test runner
|
||||
pub fn run_tests_console(opts: &TestOpts,
|
||||
tests: ~[TestDescAndFn]) -> bool {
|
||||
fn callback<T: Writer>(event: &TestEvent, st: &mut ConsoleTestState<T>) {
|
||||
tests: ~[TestDescAndFn]) -> io::IoResult<bool> {
|
||||
fn callback<T: Writer>(event: &TestEvent,
|
||||
st: &mut ConsoleTestState<T>) -> io::IoResult<()> {
|
||||
debug!("callback(event={:?})", event);
|
||||
match (*event).clone() {
|
||||
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
|
||||
TeWait(ref test, padding) => st.write_test_start(test, padding),
|
||||
TeResult(test, result) => {
|
||||
st.write_log(&test, &result);
|
||||
st.write_result(&result);
|
||||
if_ok!(st.write_log(&test, &result));
|
||||
if_ok!(st.write_result(&result));
|
||||
match result {
|
||||
TrOk => st.passed += 1,
|
||||
TrIgnored => st.ignored += 1,
|
||||
|
|
@ -643,10 +658,11 @@ pub fn run_tests_console(opts: &TestOpts,
|
|||
st.failures.push(test);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut st = ConsoleTestState::new(opts, None::<StdWriter>);
|
||||
let mut st = if_ok!(ConsoleTestState::new(opts, None::<StdWriter>));
|
||||
fn len_if_padded(t: &TestDescAndFn) -> uint {
|
||||
match t.testfn.padding() {
|
||||
PadNone => 0u,
|
||||
|
|
@ -661,12 +677,13 @@ pub fn run_tests_console(opts: &TestOpts,
|
|||
},
|
||||
None => {}
|
||||
}
|
||||
run_tests(opts, tests, |x| callback(&x, &mut st));
|
||||
if_ok!(run_tests(opts, tests, |x| callback(&x, &mut st)));
|
||||
match opts.save_metrics {
|
||||
None => (),
|
||||
Some(ref pth) => {
|
||||
st.metrics.save(pth);
|
||||
st.write_plain(format!("\nmetrics saved to: {}", pth.display()));
|
||||
if_ok!(st.metrics.save(pth));
|
||||
if_ok!(st.write_plain(format!("\nmetrics saved to: {}",
|
||||
pth.display())));
|
||||
}
|
||||
}
|
||||
return st.write_run_finish(&opts.ratchet_metrics, opts.ratchet_noise_percent);
|
||||
|
|
@ -703,7 +720,7 @@ fn should_sort_failures_before_printing_them() {
|
|||
failures: ~[test_b, test_a]
|
||||
};
|
||||
|
||||
st.write_failures();
|
||||
st.write_failures().unwrap();
|
||||
let s = match st.out {
|
||||
Raw(ref m) => str::from_utf8(m.get_ref()).unwrap(),
|
||||
Pretty(_) => unreachable!()
|
||||
|
|
@ -728,11 +745,11 @@ pub type MonitorMsg = (TestDesc, TestResult);
|
|||
|
||||
fn run_tests(opts: &TestOpts,
|
||||
tests: ~[TestDescAndFn],
|
||||
callback: |e: TestEvent|) {
|
||||
callback: |e: TestEvent| -> io::IoResult<()>) -> io::IoResult<()> {
|
||||
let filtered_tests = filter_tests(opts, tests);
|
||||
let filtered_descs = filtered_tests.map(|t| t.desc.clone());
|
||||
|
||||
callback(TeFiltered(filtered_descs));
|
||||
if_ok!(callback(TeFiltered(filtered_descs)));
|
||||
|
||||
let (filtered_tests, filtered_benchs_and_metrics) =
|
||||
filtered_tests.partition(|e| {
|
||||
|
|
@ -760,7 +777,7 @@ fn run_tests(opts: &TestOpts,
|
|||
// We are doing one test at a time so we can print the name
|
||||
// of the test before we run it. Useful for debugging tests
|
||||
// that hang forever.
|
||||
callback(TeWait(test.desc.clone(), test.testfn.padding()));
|
||||
if_ok!(callback(TeWait(test.desc.clone(), test.testfn.padding())));
|
||||
}
|
||||
run_test(!opts.run_tests, test, ch.clone());
|
||||
pending += 1;
|
||||
|
|
@ -768,20 +785,21 @@ fn run_tests(opts: &TestOpts,
|
|||
|
||||
let (desc, result) = p.recv();
|
||||
if concurrency != 1 {
|
||||
callback(TeWait(desc.clone(), PadNone));
|
||||
if_ok!(callback(TeWait(desc.clone(), PadNone)));
|
||||
}
|
||||
callback(TeResult(desc, result));
|
||||
if_ok!(callback(TeResult(desc, result)));
|
||||
pending -= 1;
|
||||
}
|
||||
|
||||
// All benchmarks run at the end, in serial.
|
||||
// (this includes metric fns)
|
||||
for b in filtered_benchs_and_metrics.move_iter() {
|
||||
callback(TeWait(b.desc.clone(), b.testfn.padding()));
|
||||
if_ok!(callback(TeWait(b.desc.clone(), b.testfn.padding())));
|
||||
run_test(!opts.run_benchmarks, b, ch.clone());
|
||||
let (test, result) = p.recv();
|
||||
callback(TeResult(test, result));
|
||||
if_ok!(callback(TeResult(test, result)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_concurrency() -> uint {
|
||||
|
|
@ -943,17 +961,22 @@ impl MetricMap {
|
|||
}
|
||||
|
||||
/// Load MetricDiff from a file.
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// This function will fail if the path does not exist or the path does not
|
||||
/// contain a valid metric map.
|
||||
pub fn load(p: &Path) -> MetricMap {
|
||||
assert!(p.exists());
|
||||
let mut f = File::open(p);
|
||||
let mut f = File::open(p).unwrap();
|
||||
let value = json::from_reader(&mut f as &mut io::Reader).unwrap();
|
||||
let mut decoder = json::Decoder::new(value);
|
||||
MetricMap(Decodable::decode(&mut decoder))
|
||||
}
|
||||
|
||||
/// Write MetricDiff to a file.
|
||||
pub fn save(&self, p: &Path) {
|
||||
let mut file = File::create(p);
|
||||
pub fn save(&self, p: &Path) -> io::IoResult<()> {
|
||||
let mut file = if_ok!(File::create(p));
|
||||
let MetricMap(ref map) = *self;
|
||||
map.to_json().to_pretty_writer(&mut file)
|
||||
}
|
||||
|
|
@ -1060,7 +1083,7 @@ impl MetricMap {
|
|||
|
||||
if ok {
|
||||
debug!("rewriting file '{:?}' with updated metrics", p);
|
||||
self.save(p);
|
||||
self.save(p).unwrap();
|
||||
}
|
||||
return (diff, ok)
|
||||
}
|
||||
|
|
@ -1462,7 +1485,7 @@ mod tests {
|
|||
m2.insert_metric("runtime", 1100.0, 2.0);
|
||||
m2.insert_metric("throughput", 50.0, 2.0);
|
||||
|
||||
m1.save(&pth);
|
||||
m1.save(&pth).unwrap();
|
||||
|
||||
// Ask for a ratchet that should fail to advance.
|
||||
let (diff1, ok1) = m2.ratchet(&pth, None);
|
||||
|
|
|
|||
|
|
@ -766,14 +766,14 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
|||
|
||||
let mut buf = [0];
|
||||
let c = match rdr.read(buf) {
|
||||
Some(..) => buf[0] as char,
|
||||
None => break
|
||||
Ok(..) => buf[0] as char,
|
||||
Err(..) => break
|
||||
};
|
||||
match c {
|
||||
'%' => {
|
||||
let ch = match rdr.read(buf) {
|
||||
Some(..) => buf[0] as char,
|
||||
None => break
|
||||
Ok(..) => buf[0] as char,
|
||||
Err(..) => break
|
||||
};
|
||||
match parse_type(s, pos, ch, &mut tm) {
|
||||
Ok(next) => pos = next,
|
||||
|
|
@ -787,7 +787,7 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ~str> {
|
|||
}
|
||||
}
|
||||
|
||||
if pos == len && rdr.tell() as uint == format.len() {
|
||||
if pos == len && rdr.tell().unwrap() == format.len() as u64 {
|
||||
Ok(Tm {
|
||||
tm_sec: tm.tm_sec,
|
||||
tm_min: tm.tm_min,
|
||||
|
|
@ -1017,12 +1017,12 @@ pub fn strftime(format: &str, tm: &Tm) -> ~str {
|
|||
loop {
|
||||
let mut b = [0];
|
||||
let ch = match rdr.read(b) {
|
||||
Some(..) => b[0],
|
||||
None => break,
|
||||
Ok(..) => b[0],
|
||||
Err(..) => break,
|
||||
};
|
||||
match ch as char {
|
||||
'%' => {
|
||||
rdr.read(b);
|
||||
rdr.read(b).unwrap();
|
||||
let s = parse_type(b[0] as char, tm);
|
||||
buf.push_all(s.as_bytes());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,8 +102,8 @@ fn encode_inner(s: &str, full_url: bool) -> ~str {
|
|||
loop {
|
||||
let mut buf = [0];
|
||||
let ch = match rdr.read(buf) {
|
||||
None => break,
|
||||
Some(..) => buf[0] as char,
|
||||
Err(..) => break,
|
||||
Ok(..) => buf[0] as char,
|
||||
};
|
||||
|
||||
match ch {
|
||||
|
|
@ -166,14 +166,14 @@ fn decode_inner(s: &str, full_url: bool) -> ~str {
|
|||
loop {
|
||||
let mut buf = [0];
|
||||
let ch = match rdr.read(buf) {
|
||||
None => break,
|
||||
Some(..) => buf[0] as char
|
||||
Err(..) => break,
|
||||
Ok(..) => buf[0] as char
|
||||
};
|
||||
match ch {
|
||||
'%' => {
|
||||
let mut bytes = [0, 0];
|
||||
match rdr.read(bytes) {
|
||||
Some(2) => {}
|
||||
Ok(2) => {}
|
||||
_ => fail!() // FIXME: malformed url?
|
||||
}
|
||||
let ch = uint::parse_bytes(bytes, 16u).unwrap() as u8 as char;
|
||||
|
|
@ -228,8 +228,8 @@ fn encode_plus(s: &str) -> ~str {
|
|||
loop {
|
||||
let mut buf = [0];
|
||||
let ch = match rdr.read(buf) {
|
||||
Some(..) => buf[0] as char,
|
||||
None => break,
|
||||
Ok(..) => buf[0] as char,
|
||||
Err(..) => break,
|
||||
};
|
||||
match ch {
|
||||
'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '.' | '-' => {
|
||||
|
|
@ -282,8 +282,8 @@ pub fn decode_form_urlencoded(s: &[u8]) -> HashMap<~str, ~[~str]> {
|
|||
loop {
|
||||
let mut buf = [0];
|
||||
let ch = match rdr.read(buf) {
|
||||
Some(..) => buf[0] as char,
|
||||
None => break,
|
||||
Ok(..) => buf[0] as char,
|
||||
Err(..) => break,
|
||||
};
|
||||
match ch {
|
||||
'&' | ';' => {
|
||||
|
|
@ -307,7 +307,7 @@ pub fn decode_form_urlencoded(s: &[u8]) -> HashMap<~str, ~[~str]> {
|
|||
'%' => {
|
||||
let mut bytes = [0, 0];
|
||||
match rdr.read(bytes) {
|
||||
Some(2) => {}
|
||||
Ok(2) => {}
|
||||
_ => fail!() // FIXME: malformed?
|
||||
}
|
||||
uint::parse_bytes(bytes, 16u).unwrap() as u8 as char
|
||||
|
|
@ -347,12 +347,12 @@ fn split_char_first(s: &str, c: char) -> (~str, ~str) {
|
|||
loop {
|
||||
let mut buf = [0];
|
||||
let ch = match rdr.read(buf) {
|
||||
Some(..) => buf[0] as char,
|
||||
None => break,
|
||||
Ok(..) => buf[0] as char,
|
||||
Err(..) => break,
|
||||
};
|
||||
if ch == c {
|
||||
// found a match, adjust markers
|
||||
index = (rdr.tell() as uint) - 1;
|
||||
index = (rdr.tell().unwrap() as uint) - 1;
|
||||
mat = 1;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -821,7 +821,7 @@ mod bench {
|
|||
pub fn parse_str(bh: &mut BenchHarness) {
|
||||
let s = "urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4";
|
||||
bh.iter(|| {
|
||||
Uuid::parse_string(s);
|
||||
Uuid::parse_string(s).unwrap();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,20 +172,19 @@ impl Database {
|
|||
}
|
||||
|
||||
// FIXME #4330: This should have &mut self and should set self.db_dirty to false.
|
||||
fn save(&self) {
|
||||
fn save(&self) -> io::IoResult<()> {
|
||||
let mut f = File::create(&self.db_filename);
|
||||
self.db_cache.to_json().to_pretty_writer(&mut f);
|
||||
self.db_cache.to_json().to_pretty_writer(&mut f)
|
||||
}
|
||||
|
||||
fn load(&mut self) {
|
||||
assert!(!self.db_dirty);
|
||||
assert!(self.db_filename.exists());
|
||||
match io::result(|| File::open(&self.db_filename)) {
|
||||
match File::open(&self.db_filename) {
|
||||
Err(e) => fail!("Couldn't load workcache database {}: {}",
|
||||
self.db_filename.display(),
|
||||
e.desc),
|
||||
Ok(r) => {
|
||||
let mut stream = r.unwrap();
|
||||
e),
|
||||
Ok(mut stream) => {
|
||||
match json::from_reader(&mut stream) {
|
||||
Err(e) => fail!("Couldn't parse workcache database (from file {}): {}",
|
||||
self.db_filename.display(), e.to_str()),
|
||||
|
|
@ -203,7 +202,8 @@ impl Database {
|
|||
impl Drop for Database {
|
||||
fn drop(&mut self) {
|
||||
if self.db_dirty {
|
||||
self.save();
|
||||
// FIXME: is failing the right thing to do here
|
||||
self.save().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -473,13 +473,13 @@ fn test() {
|
|||
fn make_path(filename: ~str) -> Path {
|
||||
let pth = os::self_exe_path().expect("workcache::test failed").with_filename(filename);
|
||||
if pth.exists() {
|
||||
fs::unlink(&pth);
|
||||
fs::unlink(&pth).unwrap();
|
||||
}
|
||||
return pth;
|
||||
}
|
||||
|
||||
let pth = make_path(~"foo.c");
|
||||
File::create(&pth).write(bytes!("int main() { return 0; }"));
|
||||
File::create(&pth).write(bytes!("int main() { return 0; }")).unwrap();
|
||||
|
||||
let db_path = make_path(~"db.json");
|
||||
|
||||
|
|
@ -491,7 +491,8 @@ fn test() {
|
|||
let subcx = cx.clone();
|
||||
let pth = pth.clone();
|
||||
|
||||
let file_content = from_utf8_owned(File::open(&pth).read_to_end()).unwrap();
|
||||
let contents = File::open(&pth).read_to_end().unwrap();
|
||||
let file_content = from_utf8_owned(contents).unwrap();
|
||||
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
prep.declare_input("file", pth.as_str().unwrap(), file_content);
|
||||
|
|
@ -500,7 +501,7 @@ fn test() {
|
|||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
run::process_status("gcc", [pth.as_str().unwrap().to_owned(),
|
||||
~"-o",
|
||||
out.as_str().unwrap().to_owned()]);
|
||||
out.as_str().unwrap().to_owned()]).unwrap();
|
||||
|
||||
let _proof_of_concept = subcx.prep("subfn");
|
||||
// Could run sub-rules inside here.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
#[license = "MIT/ASL2"];
|
||||
|
||||
use std::{os, path};
|
||||
use std::io;
|
||||
use std::io::fs;
|
||||
use std::path::is_sep;
|
||||
|
||||
|
|
@ -153,7 +152,7 @@ impl Iterator<Path> for Paths {
|
|||
}
|
||||
|
||||
fn list_dir_sorted(path: &Path) -> ~[Path] {
|
||||
match io::result(|| fs::readdir(path)) {
|
||||
match fs::readdir(path) {
|
||||
Ok(mut children) => {
|
||||
children.sort_by(|p1, p2| p2.filename().cmp(&p1.filename()));
|
||||
children
|
||||
|
|
|
|||
|
|
@ -56,16 +56,17 @@ pub fn dumb_println(args: &fmt::Arguments) {
|
|||
|
||||
struct Stderr;
|
||||
impl io::Writer for Stderr {
|
||||
fn write(&mut self, data: &[u8]) {
|
||||
fn write(&mut self, data: &[u8]) -> io::IoResult<()> {
|
||||
unsafe {
|
||||
libc::write(libc::STDERR_FILENO,
|
||||
data.as_ptr() as *libc::c_void,
|
||||
data.len() as libc::size_t);
|
||||
}
|
||||
Ok(()) // just ignore the result
|
||||
}
|
||||
}
|
||||
let mut w = Stderr;
|
||||
fmt::writeln(&mut w as &mut io::Writer, args);
|
||||
let _ = fmt::writeln(&mut w as &mut io::Writer, args);
|
||||
}
|
||||
|
||||
pub fn abort(msg: &str) -> ! {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ static mut TASK_COUNT: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
|
|||
static mut TASK_LOCK: Mutex = MUTEX_INIT;
|
||||
|
||||
pub fn increment() {
|
||||
unsafe { TASK_COUNT.fetch_add(1, atomics::SeqCst); }
|
||||
let _ = unsafe { TASK_COUNT.fetch_add(1, atomics::SeqCst) };
|
||||
}
|
||||
|
||||
pub fn decrement() {
|
||||
|
|
|
|||
|
|
@ -111,17 +111,14 @@ impl FileDesc {
|
|||
}
|
||||
|
||||
impl io::Reader for FileDesc {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
match self.inner_read(buf) { Ok(n) => Some(n), Err(..) => None }
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
||||
self.inner_read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Writer for FileDesc {
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
match self.inner_write(buf) {
|
||||
Ok(()) => {}
|
||||
Err(e) => { io::io_error::cond.raise(e); }
|
||||
}
|
||||
fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
|
||||
self.inner_write(buf)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -425,7 +422,7 @@ impl rtio::RtioFileStream for CFile {
|
|||
|
||||
impl Drop for CFile {
|
||||
fn drop(&mut self) {
|
||||
unsafe { libc::fclose(self.file); }
|
||||
unsafe { let _ = libc::fclose(self.file); }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -515,7 +512,7 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
|
|||
paths.push(Path::new(cstr));
|
||||
entry_ptr = readdir(dir_ptr);
|
||||
}
|
||||
closedir(dir_ptr);
|
||||
assert_eq!(closedir(dir_ptr), 0);
|
||||
Ok(paths)
|
||||
} else {
|
||||
Err(super::last_error())
|
||||
|
|
@ -564,7 +561,7 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
|
|||
}
|
||||
more_files = FindNextFileW(find_handle, wfd_ptr as HANDLE);
|
||||
}
|
||||
FindClose(find_handle);
|
||||
assert!(FindClose(find_handle) != 0);
|
||||
free(wfd_ptr as *mut c_void);
|
||||
Ok(paths)
|
||||
} else {
|
||||
|
|
@ -686,7 +683,9 @@ pub fn readlink(p: &CString) -> IoResult<Path> {
|
|||
ptr::mut_null())
|
||||
})
|
||||
};
|
||||
if handle == ptr::mut_null() { return Err(super::last_error()) }
|
||||
if handle as int == libc::INVALID_HANDLE_VALUE as int {
|
||||
return Err(super::last_error())
|
||||
}
|
||||
let ret = fill_utf16_buf_and_decode(|buf, sz| {
|
||||
unsafe {
|
||||
libc::GetFinalPathNameByHandleW(handle, buf as *u16, sz,
|
||||
|
|
@ -697,7 +696,7 @@ pub fn readlink(p: &CString) -> IoResult<Path> {
|
|||
Some(s) => Ok(Path::new(s)),
|
||||
None => Err(super::last_error()),
|
||||
};
|
||||
unsafe { libc::CloseHandle(handle) };
|
||||
assert!(unsafe { libc::CloseHandle(handle) } != 0);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
|
@ -935,7 +934,7 @@ mod tests {
|
|||
let mut reader = FileDesc::new(input, true);
|
||||
let mut writer = FileDesc::new(out, true);
|
||||
|
||||
writer.inner_write(bytes!("test"));
|
||||
writer.inner_write(bytes!("test")).unwrap();
|
||||
let mut buf = [0u8, ..4];
|
||||
match reader.inner_read(buf) {
|
||||
Ok(4) => {
|
||||
|
|
@ -960,9 +959,9 @@ mod tests {
|
|||
assert!(!f.is_null());
|
||||
let mut file = CFile::new(f);
|
||||
|
||||
file.write(bytes!("test"));
|
||||
file.write(bytes!("test")).unwrap();
|
||||
let mut buf = [0u8, ..4];
|
||||
file.seek(0, io::SeekSet);
|
||||
let _ = file.seek(0, io::SeekSet).unwrap();
|
||||
match file.read(buf) {
|
||||
Ok(4) => {
|
||||
assert_eq!(buf[0], 't' as u8);
|
||||
|
|
|
|||
|
|
@ -112,8 +112,8 @@ fn setsockopt<T>(fd: sock_t, opt: libc::c_int, val: libc::c_int,
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)] unsafe fn close(sock: sock_t) { libc::closesocket(sock); }
|
||||
#[cfg(unix)] unsafe fn close(sock: sock_t) { libc::close(sock); }
|
||||
#[cfg(windows)] unsafe fn close(sock: sock_t) { let _ = libc::closesocket(sock); }
|
||||
#[cfg(unix)] unsafe fn close(sock: sock_t) { let _ = libc::close(sock); }
|
||||
|
||||
fn sockname(fd: sock_t,
|
||||
f: extern "system" unsafe fn(sock_t, *mut libc::sockaddr,
|
||||
|
|
|
|||
|
|
@ -102,9 +102,9 @@ impl Process {
|
|||
cwd.as_ref(), in_fd, out_fd, err_fd);
|
||||
|
||||
unsafe {
|
||||
for pipe in in_pipe.iter() { libc::close(pipe.input); }
|
||||
for pipe in out_pipe.iter() { libc::close(pipe.out); }
|
||||
for pipe in err_pipe.iter() { libc::close(pipe.out); }
|
||||
for pipe in in_pipe.iter() { let _ = libc::close(pipe.input); }
|
||||
for pipe in out_pipe.iter() { let _ = libc::close(pipe.out); }
|
||||
for pipe in err_pipe.iter() { let _ = libc::close(pipe.out); }
|
||||
}
|
||||
|
||||
match res {
|
||||
|
|
@ -149,9 +149,8 @@ impl rtio::RtioProcess for Process {
|
|||
unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
|
||||
match signal {
|
||||
io::process::PleaseExitSignal | io::process::MustDieSignal => {
|
||||
libc::funcs::extra::kernel32::TerminateProcess(
|
||||
cast::transmute(pid), 1);
|
||||
Ok(())
|
||||
let ret = libc::TerminateProcess(pid as libc::HANDLE, 1);
|
||||
super::mkerr_winbool(ret)
|
||||
}
|
||||
_ => Err(io::IoError {
|
||||
kind: io::OtherIoError,
|
||||
|
|
@ -163,8 +162,8 @@ impl rtio::RtioProcess for Process {
|
|||
|
||||
#[cfg(not(windows))]
|
||||
unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
|
||||
libc::funcs::posix88::signal::kill(pid, signal as c_int);
|
||||
Ok(())
|
||||
let r = libc::funcs::posix88::signal::kill(pid, signal as c_int);
|
||||
super::mkerr_libc(r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -255,9 +254,9 @@ fn spawn_process_os(prog: &str, args: &[~str],
|
|||
})
|
||||
});
|
||||
|
||||
CloseHandle(si.hStdInput);
|
||||
CloseHandle(si.hStdOutput);
|
||||
CloseHandle(si.hStdError);
|
||||
assert!(CloseHandle(si.hStdInput) != 0);
|
||||
assert!(CloseHandle(si.hStdOutput) != 0);
|
||||
assert!(CloseHandle(si.hStdError) != 0);
|
||||
|
||||
match create_err {
|
||||
Some(err) => return Err(err),
|
||||
|
|
@ -269,7 +268,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
|
|||
// able to close it later. We don't close the process handle however
|
||||
// because std::we want the process id to stay valid at least until the
|
||||
// calling code closes the process handle.
|
||||
CloseHandle(pi.hThread);
|
||||
assert!(CloseHandle(pi.hThread) != 0);
|
||||
|
||||
Ok(SpawnProcessResult {
|
||||
pid: pi.dwProcessId as pid_t,
|
||||
|
|
@ -445,24 +444,24 @@ fn spawn_process_os(prog: &str, args: &[~str],
|
|||
rustrt::rust_unset_sigprocmask();
|
||||
|
||||
if in_fd == -1 {
|
||||
libc::close(libc::STDIN_FILENO);
|
||||
let _ = libc::close(libc::STDIN_FILENO);
|
||||
} else if retry(|| dup2(in_fd, 0)) == -1 {
|
||||
fail!("failure in dup2(in_fd, 0): {}", os::last_os_error());
|
||||
}
|
||||
if out_fd == -1 {
|
||||
libc::close(libc::STDOUT_FILENO);
|
||||
let _ = libc::close(libc::STDOUT_FILENO);
|
||||
} else if retry(|| dup2(out_fd, 1)) == -1 {
|
||||
fail!("failure in dup2(out_fd, 1): {}", os::last_os_error());
|
||||
}
|
||||
if err_fd == -1 {
|
||||
libc::close(libc::STDERR_FILENO);
|
||||
let _ = libc::close(libc::STDERR_FILENO);
|
||||
} else if retry(|| dup2(err_fd, 2)) == -1 {
|
||||
fail!("failure in dup3(err_fd, 2): {}", os::last_os_error());
|
||||
}
|
||||
// close all other fds
|
||||
for fd in range(3, getdtablesize()).rev() {
|
||||
if fd != output.fd() {
|
||||
close(fd as c_int);
|
||||
let _ = close(fd as c_int);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -478,7 +477,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
|
|||
}
|
||||
});
|
||||
with_argv(prog, args, |argv| {
|
||||
execvp(*argv, argv);
|
||||
let _ = execvp(*argv, argv);
|
||||
let errno = os::errno();
|
||||
let bytes = [
|
||||
(errno << 24) as u8,
|
||||
|
|
@ -576,9 +575,9 @@ fn with_dirp<T>(d: Option<&Path>, cb: |*libc::c_char| -> T) -> T {
|
|||
|
||||
#[cfg(windows)]
|
||||
fn free_handle(handle: *()) {
|
||||
unsafe {
|
||||
libc::funcs::extra::kernel32::CloseHandle(cast::transmute(handle));
|
||||
}
|
||||
assert!(unsafe {
|
||||
libc::CloseHandle(cast::transmute(handle)) != 0
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
|
|
@ -629,15 +628,15 @@ fn waitpid(pid: pid_t) -> p::ProcessExit {
|
|||
loop {
|
||||
let mut status = 0;
|
||||
if GetExitCodeProcess(process, &mut status) == FALSE {
|
||||
CloseHandle(process);
|
||||
assert!(CloseHandle(process) != 0);
|
||||
fail!("failure in GetExitCodeProcess: {}", os::last_os_error());
|
||||
}
|
||||
if status != STILL_ACTIVE {
|
||||
CloseHandle(process);
|
||||
assert!(CloseHandle(process) != 0);
|
||||
return p::ExitStatus(status as int);
|
||||
}
|
||||
if WaitForSingleObject(process, INFINITE) == WAIT_FAILED {
|
||||
CloseHandle(process);
|
||||
assert!(CloseHandle(process) != 0);
|
||||
fail!("failure in WaitForSingleObject: {}", os::last_os_error());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,11 +126,11 @@ mod imp {
|
|||
}
|
||||
|
||||
pub fn signal(handle: HANDLE) {
|
||||
unsafe { SetEvent(handle); }
|
||||
assert!(unsafe { SetEvent(handle) != 0 });
|
||||
}
|
||||
|
||||
pub fn close(handle: HANDLE) {
|
||||
unsafe { CloseHandle(handle); }
|
||||
assert!(unsafe { CloseHandle(handle) != 0 });
|
||||
}
|
||||
|
||||
extern "system" {
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ fn helper(input: libc::c_int, messages: Port<Req>) {
|
|||
|
||||
// drain the file descriptor
|
||||
let mut buf = [0];
|
||||
fd.inner_read(buf).unwrap();
|
||||
assert_eq!(fd.inner_read(buf).unwrap(), 1);
|
||||
}
|
||||
|
||||
-1 if os::errno() == libc::EINTR as int => {}
|
||||
|
|
@ -216,7 +216,8 @@ impl Timer {
|
|||
}
|
||||
|
||||
pub fn sleep(ms: u64) {
|
||||
unsafe { libc::usleep((ms * 1000) as libc::c_uint); }
|
||||
// FIXME: this can fail because of EINTR, what do do?
|
||||
let _ = unsafe { libc::usleep((ms * 1000) as libc::c_uint) };
|
||||
}
|
||||
|
||||
fn inner(&mut self) -> ~Inner {
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ fn helper(input: libc::c_int, messages: Port<Req>) {
|
|||
if fd == input {
|
||||
let mut buf = [0, ..1];
|
||||
// drain the input file descriptor of its input
|
||||
FileDesc::new(fd, false).inner_read(buf).unwrap();
|
||||
let _ = FileDesc::new(fd, false).inner_read(buf).unwrap();
|
||||
incoming = true;
|
||||
} else {
|
||||
let mut bits = [0, ..8];
|
||||
|
|
@ -104,7 +104,7 @@ fn helper(input: libc::c_int, messages: Port<Req>) {
|
|||
//
|
||||
// FIXME: should this perform a send() this number of
|
||||
// times?
|
||||
FileDesc::new(fd, false).inner_read(bits).unwrap();
|
||||
let _ = FileDesc::new(fd, false).inner_read(bits).unwrap();
|
||||
let remove = {
|
||||
match map.find(&fd).expect("fd unregistered") {
|
||||
&(ref c, oneshot) => !c.try_send(()) || oneshot
|
||||
|
|
@ -166,7 +166,8 @@ impl Timer {
|
|||
}
|
||||
|
||||
pub fn sleep(ms: u64) {
|
||||
unsafe { libc::usleep((ms * 1000) as libc::c_uint); }
|
||||
// FIXME: this can fail because of EINTR, what do do?
|
||||
let _ = unsafe { libc::usleep((ms * 1000) as libc::c_uint) };
|
||||
}
|
||||
|
||||
fn remove(&mut self) {
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ fn helper(input: libc::HANDLE, messages: Port<Req>) {
|
|||
c.send(());
|
||||
match objs.iter().position(|&o| o == obj) {
|
||||
Some(i) => {
|
||||
objs.remove(i);
|
||||
chans.remove(i - 1);
|
||||
drop(objs.remove(i));
|
||||
drop(chans.remove(i - 1));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
|
@ -83,8 +83,8 @@ fn helper(input: libc::HANDLE, messages: Port<Req>) {
|
|||
}
|
||||
};
|
||||
if remove {
|
||||
objs.remove(idx as uint);
|
||||
chans.remove(idx as uint - 1);
|
||||
drop(objs.remove(idx as uint));
|
||||
drop(chans.remove(idx as uint - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -133,7 +133,7 @@ impl rtio::RtioTimer for Timer {
|
|||
ptr::mut_null(), 0)
|
||||
}, 1);
|
||||
|
||||
unsafe { imp::WaitForSingleObject(self.obj, libc::INFINITE); }
|
||||
let _ = unsafe { imp::WaitForSingleObject(self.obj, libc::INFINITE) };
|
||||
}
|
||||
|
||||
fn oneshot(&mut self, msecs: u64) -> Port<()> {
|
||||
|
|
@ -173,7 +173,7 @@ impl rtio::RtioTimer for Timer {
|
|||
impl Drop for Timer {
|
||||
fn drop(&mut self) {
|
||||
self.remove();
|
||||
unsafe { libc::CloseHandle(self.obj); }
|
||||
assert!(unsafe { libc::CloseHandle(self.obj) != 0 });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
#[deny(unused_result, unused_must_use)];
|
||||
|
||||
// NB this crate explicitly does *not* allow glob imports, please seriously
|
||||
// consider whether they're needed before adding that feature here (the
|
||||
|
|
@ -61,9 +62,10 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int {
|
|||
rt::init(argc, argv);
|
||||
let mut exit_code = None;
|
||||
let mut main = Some(main);
|
||||
task::new((my_stack_bottom, my_stack_top)).run(|| {
|
||||
let t = task::new((my_stack_bottom, my_stack_top)).run(|| {
|
||||
exit_code = Some(run(main.take_unwrap()));
|
||||
});
|
||||
drop(t);
|
||||
unsafe { rt::cleanup(); }
|
||||
// If the exit code wasn't set, then the task block must have failed.
|
||||
return exit_code.unwrap_or(rt::DEFAULT_ERROR_CODE);
|
||||
|
|
|
|||
|
|
@ -103,7 +103,8 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
|
|||
let mut f = Some(f);
|
||||
let mut task = task;
|
||||
task.put_runtime(ops as ~rt::Runtime);
|
||||
task.run(|| { f.take_unwrap()() });
|
||||
let t = task.run(|| { f.take_unwrap()() });
|
||||
drop(t);
|
||||
bookkeeping::decrement();
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ use lib::llvm::{ArchiveRef, llvm};
|
|||
|
||||
use std::cast;
|
||||
use std::io::fs;
|
||||
use std::io;
|
||||
use std::libc;
|
||||
use std::os;
|
||||
use std::run::{ProcessOptions, Process, ProcessOutput};
|
||||
|
|
@ -50,9 +51,8 @@ fn run_ar(sess: Session, args: &str, cwd: Option<&Path>,
|
|||
Some(p) => { debug!("inside {}", p.display()); }
|
||||
None => {}
|
||||
}
|
||||
let mut opt_prog = Process::new(ar, args.as_slice(), opts);
|
||||
match opt_prog {
|
||||
Some(ref mut prog) => {
|
||||
match Process::new(ar, args.as_slice(), opts) {
|
||||
Ok(mut prog) => {
|
||||
let o = prog.finish_with_output();
|
||||
if !o.status.success() {
|
||||
sess.err(format!("{} {} failed with: {}", ar, args.connect(" "),
|
||||
|
|
@ -63,8 +63,8 @@ fn run_ar(sess: Session, args: &str, cwd: Option<&Path>,
|
|||
}
|
||||
o
|
||||
},
|
||||
None => {
|
||||
sess.err(format!("could not exec `{}`", ar));
|
||||
Err(e) => {
|
||||
sess.err(format!("could not exec `{}`: {}", ar, e));
|
||||
sess.abort_if_errors();
|
||||
fail!("rustc::back::archive::run_ar() should not reach this point");
|
||||
}
|
||||
|
|
@ -94,7 +94,7 @@ impl Archive {
|
|||
let archive = os::make_absolute(&self.dst);
|
||||
run_ar(self.sess, "x", Some(loc.path()), [&archive,
|
||||
&Path::new(file)]);
|
||||
fs::File::open(&loc.path().join(file)).read_to_end()
|
||||
fs::File::open(&loc.path().join(file)).read_to_end().unwrap()
|
||||
} else {
|
||||
run_ar(self.sess, "p", None, [&self.dst, &Path::new(file)]).output
|
||||
}
|
||||
|
|
@ -102,9 +102,9 @@ impl Archive {
|
|||
|
||||
/// Adds all of the contents of a native library to this archive. This will
|
||||
/// search in the relevant locations for a library named `name`.
|
||||
pub fn add_native_library(&mut self, name: &str) {
|
||||
pub fn add_native_library(&mut self, name: &str) -> io::IoResult<()> {
|
||||
let location = self.find_library(name);
|
||||
self.add_archive(&location, name, []);
|
||||
self.add_archive(&location, name, [])
|
||||
}
|
||||
|
||||
/// Adds all of the contents of the rlib at the specified path to this
|
||||
|
|
@ -112,14 +112,15 @@ impl Archive {
|
|||
///
|
||||
/// This ignores adding the bytecode from the rlib, and if LTO is enabled
|
||||
/// then the object file also isn't added.
|
||||
pub fn add_rlib(&mut self, rlib: &Path, name: &str, lto: bool) {
|
||||
pub fn add_rlib(&mut self, rlib: &Path, name: &str,
|
||||
lto: bool) -> io::IoResult<()> {
|
||||
let object = format!("{}.o", name);
|
||||
let bytecode = format!("{}.bc", name);
|
||||
let mut ignore = ~[METADATA_FILENAME, bytecode.as_slice()];
|
||||
if lto {
|
||||
ignore.push(object.as_slice());
|
||||
}
|
||||
self.add_archive(rlib, name, ignore);
|
||||
self.add_archive(rlib, name, ignore)
|
||||
}
|
||||
|
||||
/// Adds an arbitrary file to this archive
|
||||
|
|
@ -144,7 +145,8 @@ impl Archive {
|
|||
str::from_utf8(output.output).unwrap().lines().map(|s| s.to_owned()).collect()
|
||||
}
|
||||
|
||||
fn add_archive(&mut self, archive: &Path, name: &str, skip: &[&str]) {
|
||||
fn add_archive(&mut self, archive: &Path, name: &str,
|
||||
skip: &[&str]) -> io::IoResult<()> {
|
||||
let loc = TempDir::new("rsar").unwrap();
|
||||
|
||||
// First, extract the contents of the archive to a temporary directory
|
||||
|
|
@ -159,7 +161,7 @@ impl Archive {
|
|||
// We skip any files explicitly desired for skipping, and we also skip
|
||||
// all SYMDEF files as these are just magical placeholders which get
|
||||
// re-created when we make a new archive anyway.
|
||||
let files = fs::readdir(loc.path());
|
||||
let files = if_ok!(fs::readdir(loc.path()));
|
||||
let mut inputs = ~[];
|
||||
for file in files.iter() {
|
||||
let filename = file.filename_str().unwrap();
|
||||
|
|
@ -168,7 +170,7 @@ impl Archive {
|
|||
|
||||
let filename = format!("r-{}-{}", name, filename);
|
||||
let new_filename = file.with_filename(filename);
|
||||
fs::rename(file, &new_filename);
|
||||
if_ok!(fs::rename(file, &new_filename));
|
||||
inputs.push(new_filename);
|
||||
}
|
||||
|
||||
|
|
@ -176,6 +178,7 @@ impl Archive {
|
|||
let mut args = ~[&self.dst];
|
||||
args.extend(&mut inputs.iter());
|
||||
run_ar(self.sess, "r", None, args.as_slice());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn find_library(&self, name: &str) -> Path {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ pub mod write {
|
|||
use util::common::time;
|
||||
|
||||
use std::c_str::ToCStr;
|
||||
use std::io;
|
||||
use std::libc::{c_uint, c_int};
|
||||
use std::path::Path;
|
||||
use std::run;
|
||||
|
|
@ -297,12 +296,8 @@ pub mod write {
|
|||
assembly.as_str().unwrap().to_owned()];
|
||||
|
||||
debug!("{} '{}'", cc, args.connect("' '"));
|
||||
let opt_prog = {
|
||||
let _guard = io::ignore_io_error();
|
||||
run::process_output(cc, args)
|
||||
};
|
||||
match opt_prog {
|
||||
Some(prog) => {
|
||||
match run::process_output(cc, args) {
|
||||
Ok(prog) => {
|
||||
if !prog.status.success() {
|
||||
sess.err(format!("linking with `{}` failed: {}", cc, prog.status));
|
||||
sess.note(format!("{} arguments: '{}'", cc, args.connect("' '")));
|
||||
|
|
@ -310,8 +305,8 @@ pub mod write {
|
|||
sess.abort_if_errors();
|
||||
}
|
||||
},
|
||||
None => {
|
||||
sess.err(format!("could not exec the linker `{}`", cc));
|
||||
Err(e) => {
|
||||
sess.err(format!("could not exec the linker `{}`: {}", cc, e));
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
}
|
||||
|
|
@ -768,6 +763,15 @@ fn get_system_tool(sess: Session, tool: &str) -> ~str {
|
|||
}
|
||||
}
|
||||
|
||||
fn remove(sess: Session, path: &Path) {
|
||||
match fs::unlink(path) {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
sess.err(format!("failed to remove {}: {}", path.display(), e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform the linkage portion of the compilation phase. This will generate all
|
||||
/// of the requested outputs for this compilation session.
|
||||
pub fn link_binary(sess: Session,
|
||||
|
|
@ -785,17 +789,15 @@ pub fn link_binary(sess: Session,
|
|||
|
||||
// Remove the temporary object file and metadata if we aren't saving temps
|
||||
if !sess.opts.save_temps {
|
||||
fs::unlink(obj_filename);
|
||||
fs::unlink(&obj_filename.with_extension("metadata.o"));
|
||||
remove(sess, obj_filename);
|
||||
remove(sess, &obj_filename.with_extension("metadata.o"));
|
||||
}
|
||||
|
||||
out_filenames
|
||||
}
|
||||
|
||||
fn is_writeable(p: &Path) -> bool {
|
||||
use std::io;
|
||||
|
||||
match io::result(|| p.stat()) {
|
||||
match p.stat() {
|
||||
Err(..) => true,
|
||||
Ok(m) => m.perm & io::UserWrite == io::UserWrite
|
||||
}
|
||||
|
|
@ -884,7 +886,7 @@ fn link_rlib(sess: Session,
|
|||
for &(ref l, kind) in used_libraries.get().iter() {
|
||||
match kind {
|
||||
cstore::NativeStatic => {
|
||||
a.add_native_library(l.as_slice());
|
||||
a.add_native_library(l.as_slice()).unwrap();
|
||||
}
|
||||
cstore::NativeFramework | cstore::NativeUnknown => {}
|
||||
}
|
||||
|
|
@ -919,16 +921,23 @@ fn link_rlib(sess: Session,
|
|||
// the same filename for metadata (stomping over one another)
|
||||
let tmpdir = TempDir::new("rustc").expect("needs a temp dir");
|
||||
let metadata = tmpdir.path().join(METADATA_FILENAME);
|
||||
fs::File::create(&metadata).write(trans.metadata);
|
||||
match fs::File::create(&metadata).write(trans.metadata) {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
sess.err(format!("failed to write {}: {}",
|
||||
metadata.display(), e));
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
}
|
||||
a.add_file(&metadata, false);
|
||||
fs::unlink(&metadata);
|
||||
remove(sess, &metadata);
|
||||
|
||||
// For LTO purposes, the bytecode of this library is also inserted
|
||||
// into the archive.
|
||||
let bc = obj_filename.with_extension("bc");
|
||||
a.add_file(&bc, false);
|
||||
if !sess.opts.save_temps {
|
||||
fs::unlink(&bc);
|
||||
remove(sess, &bc);
|
||||
}
|
||||
|
||||
// After adding all files to the archive, we need to update the
|
||||
|
|
@ -959,7 +968,7 @@ fn link_rlib(sess: Session,
|
|||
// metadata file).
|
||||
fn link_staticlib(sess: Session, obj_filename: &Path, out_filename: &Path) {
|
||||
let mut a = link_rlib(sess, None, obj_filename, out_filename);
|
||||
a.add_native_library("morestack");
|
||||
a.add_native_library("morestack").unwrap();
|
||||
|
||||
let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
|
||||
for &(cnum, ref path) in crates.iter() {
|
||||
|
|
@ -970,7 +979,7 @@ fn link_staticlib(sess: Session, obj_filename: &Path, out_filename: &Path) {
|
|||
continue
|
||||
}
|
||||
};
|
||||
a.add_rlib(&p, name, sess.lto());
|
||||
a.add_rlib(&p, name, sess.lto()).unwrap();
|
||||
let native_libs = csearch::get_native_libraries(sess.cstore, cnum);
|
||||
for &(kind, ref lib) in native_libs.iter() {
|
||||
let name = match kind {
|
||||
|
|
@ -1004,14 +1013,10 @@ fn link_natively(sess: Session, dylib: bool, obj_filename: &Path,
|
|||
|
||||
// Invoke the system linker
|
||||
debug!("{} {}", cc_prog, cc_args.connect(" "));
|
||||
let opt_prog = {
|
||||
let _guard = io::ignore_io_error();
|
||||
time(sess.time_passes(), "running linker", (), |()|
|
||||
run::process_output(cc_prog, cc_args))
|
||||
};
|
||||
|
||||
match opt_prog {
|
||||
Some(prog) => {
|
||||
let prog = time(sess.time_passes(), "running linker", (), |()|
|
||||
run::process_output(cc_prog, cc_args));
|
||||
match prog {
|
||||
Ok(prog) => {
|
||||
if !prog.status.success() {
|
||||
sess.err(format!("linking with `{}` failed: {}", cc_prog, prog.status));
|
||||
sess.note(format!("{} arguments: '{}'", cc_prog, cc_args.connect("' '")));
|
||||
|
|
@ -1019,8 +1024,8 @@ fn link_natively(sess: Session, dylib: bool, obj_filename: &Path,
|
|||
sess.abort_if_errors();
|
||||
}
|
||||
},
|
||||
None => {
|
||||
sess.err(format!("could not exec the linker `{}`", cc_prog));
|
||||
Err(e) => {
|
||||
sess.err(format!("could not exec the linker `{}`: {}", cc_prog, e));
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
}
|
||||
|
|
@ -1030,8 +1035,14 @@ fn link_natively(sess: Session, dylib: bool, obj_filename: &Path,
|
|||
// the symbols
|
||||
if sess.targ_cfg.os == abi::OsMacos && sess.opts.debuginfo {
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
run::process_status("dsymutil",
|
||||
[out_filename.as_str().unwrap().to_owned()]);
|
||||
match run::process_status("dsymutil",
|
||||
[out_filename.as_str().unwrap().to_owned()]) {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
sess.err(format!("failed to run dsymutil: {}", e));
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1225,7 +1236,16 @@ fn add_upstream_rust_crates(args: &mut ~[~str], sess: Session,
|
|||
time(sess.time_passes(), format!("altering {}.rlib", name),
|
||||
(), |()| {
|
||||
let dst = tmpdir.join(cratepath.filename().unwrap());
|
||||
fs::copy(&cratepath, &dst);
|
||||
match fs::copy(&cratepath, &dst) {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
sess.err(format!("failed to copy {} to {}: {}",
|
||||
cratepath.display(),
|
||||
dst.display(),
|
||||
e));
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
}
|
||||
let dst_str = dst.as_str().unwrap().to_owned();
|
||||
let mut archive = Archive::open(sess, dst);
|
||||
archive.remove_file(format!("{}.o", name));
|
||||
|
|
|
|||
|
|
@ -399,7 +399,7 @@ pub fn phase_5_run_llvm_passes(sess: Session,
|
|||
|
||||
// Remove assembly source, unless --save-temps was specified
|
||||
if !sess.opts.save_temps {
|
||||
fs::unlink(&asm_filename);
|
||||
fs::unlink(&asm_filename).unwrap();
|
||||
}
|
||||
} else {
|
||||
time(sess.time_passes(), "LLVM passes", (), |_|
|
||||
|
|
@ -455,33 +455,39 @@ pub fn stop_after_phase_5(sess: Session) -> bool {
|
|||
return false;
|
||||
}
|
||||
|
||||
fn write_out_deps(sess: Session, input: &Input, outputs: &OutputFilenames, crate: &ast::Crate)
|
||||
fn write_out_deps(sess: Session, input: &Input, outputs: &OutputFilenames,
|
||||
crate: &ast::Crate) -> io::IoResult<()>
|
||||
{
|
||||
let lm = link::build_link_meta(sess, crate.attrs, &outputs.obj_filename,
|
||||
&mut ::util::sha2::Sha256::new());
|
||||
&mut ::util::sha2::Sha256::new());
|
||||
|
||||
let sess_outputs = sess.outputs.borrow();
|
||||
let out_filenames = sess_outputs.get().iter()
|
||||
.map(|&output| link::filename_for_input(&sess, output, &lm, &outputs.out_filename))
|
||||
.map(|&output| link::filename_for_input(&sess, output, &lm,
|
||||
&outputs.out_filename))
|
||||
.to_owned_vec();
|
||||
|
||||
// Write out dependency rules to the dep-info file if requested with --dep-info
|
||||
// Write out dependency rules to the dep-info file if requested with
|
||||
// --dep-info
|
||||
let deps_filename = match sess.opts.write_dependency_info {
|
||||
// Use filename from --dep-file argument if given
|
||||
(true, Some(ref filename)) => filename.clone(),
|
||||
// Use default filename: crate source filename with extension replaced by ".d"
|
||||
// Use default filename: crate source filename with extension replaced
|
||||
// by ".d"
|
||||
(true, None) => match *input {
|
||||
FileInput(ref input_path) => {
|
||||
let filestem = input_path.filestem().expect("input file must have stem");
|
||||
let filename = out_filenames[0].dir_path().join(filestem).with_extension("d");
|
||||
filename
|
||||
let filestem = input_path.filestem().expect("input file must \
|
||||
have stem");
|
||||
let filename = out_filenames[0].dir_path().join(filestem);
|
||||
filename.with_extension("d")
|
||||
},
|
||||
StrInput(..) => {
|
||||
sess.warn("can not write --dep-info without a filename when compiling stdin.");
|
||||
return;
|
||||
sess.warn("can not write --dep-info without a filename \
|
||||
when compiling stdin.");
|
||||
return Ok(());
|
||||
},
|
||||
},
|
||||
_ => return,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
|
||||
// Build a list of files used to compile the output and
|
||||
|
|
@ -499,11 +505,12 @@ fn write_out_deps(sess: Session, input: &Input, outputs: &OutputFilenames, crate
|
|||
})
|
||||
.collect()
|
||||
};
|
||||
let mut file = io::File::create(&deps_filename);
|
||||
let mut file = if_ok!(io::File::create(&deps_filename));
|
||||
for path in out_filenames.iter() {
|
||||
write!(&mut file as &mut Writer,
|
||||
"{}: {}\n\n", path.display(), files.connect(" "));
|
||||
if_ok!(write!(&mut file as &mut Writer,
|
||||
"{}: {}\n\n", path.display(), files.connect(" ")));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input,
|
||||
|
|
@ -521,7 +528,7 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input,
|
|||
let outputs = build_output_filenames(input, outdir, output,
|
||||
expanded_crate.attrs, sess);
|
||||
|
||||
write_out_deps(sess, input, outputs, &expanded_crate);
|
||||
write_out_deps(sess, input, outputs, &expanded_crate).unwrap();
|
||||
|
||||
if stop_after_phase_2(sess) { return; }
|
||||
|
||||
|
|
@ -541,32 +548,33 @@ struct IdentifiedAnnotation {
|
|||
}
|
||||
|
||||
impl pprust::PpAnn for IdentifiedAnnotation {
|
||||
fn pre(&self, node: pprust::AnnNode) {
|
||||
fn pre(&self, node: pprust::AnnNode) -> io::IoResult<()> {
|
||||
match node {
|
||||
pprust::NodeExpr(s, _) => pprust::popen(s),
|
||||
_ => ()
|
||||
_ => Ok(())
|
||||
}
|
||||
}
|
||||
fn post(&self, node: pprust::AnnNode) {
|
||||
fn post(&self, node: pprust::AnnNode) -> io::IoResult<()> {
|
||||
match node {
|
||||
pprust::NodeItem(s, item) => {
|
||||
pp::space(&mut s.s);
|
||||
pprust::synth_comment(s, item.id.to_str());
|
||||
if_ok!(pp::space(&mut s.s));
|
||||
if_ok!(pprust::synth_comment(s, item.id.to_str()));
|
||||
}
|
||||
pprust::NodeBlock(s, blk) => {
|
||||
pp::space(&mut s.s);
|
||||
pprust::synth_comment(s, ~"block " + blk.id.to_str());
|
||||
if_ok!(pp::space(&mut s.s));
|
||||
if_ok!(pprust::synth_comment(s, ~"block " + blk.id.to_str()));
|
||||
}
|
||||
pprust::NodeExpr(s, expr) => {
|
||||
pp::space(&mut s.s);
|
||||
pprust::synth_comment(s, expr.id.to_str());
|
||||
pprust::pclose(s);
|
||||
if_ok!(pp::space(&mut s.s));
|
||||
if_ok!(pprust::synth_comment(s, expr.id.to_str()));
|
||||
if_ok!(pprust::pclose(s));
|
||||
}
|
||||
pprust::NodePat(s, pat) => {
|
||||
pp::space(&mut s.s);
|
||||
pprust::synth_comment(s, ~"pat " + pat.id.to_str());
|
||||
if_ok!(pp::space(&mut s.s));
|
||||
if_ok!(pprust::synth_comment(s, ~"pat " + pat.id.to_str()));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -575,24 +583,26 @@ struct TypedAnnotation {
|
|||
}
|
||||
|
||||
impl pprust::PpAnn for TypedAnnotation {
|
||||
fn pre(&self, node: pprust::AnnNode) {
|
||||
fn pre(&self, node: pprust::AnnNode) -> io::IoResult<()> {
|
||||
match node {
|
||||
pprust::NodeExpr(s, _) => pprust::popen(s),
|
||||
_ => ()
|
||||
_ => Ok(())
|
||||
}
|
||||
}
|
||||
fn post(&self, node: pprust::AnnNode) {
|
||||
fn post(&self, node: pprust::AnnNode) -> io::IoResult<()> {
|
||||
let tcx = self.analysis.ty_cx;
|
||||
match node {
|
||||
pprust::NodeExpr(s, expr) => {
|
||||
pp::space(&mut s.s);
|
||||
pp::word(&mut s.s, "as");
|
||||
pp::space(&mut s.s);
|
||||
pp::word(&mut s.s, ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr)));
|
||||
pprust::pclose(s);
|
||||
if_ok!(pp::space(&mut s.s));
|
||||
if_ok!(pp::word(&mut s.s, "as"));
|
||||
if_ok!(pp::space(&mut s.s));
|
||||
if_ok!(pp::word(&mut s.s,
|
||||
ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr))));
|
||||
if_ok!(pprust::pclose(s));
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -638,7 +648,7 @@ pub fn pretty_print_input(sess: Session,
|
|||
&mut rdr,
|
||||
~stdout as ~io::Writer,
|
||||
annotation,
|
||||
is_expanded);
|
||||
is_expanded).unwrap();
|
||||
}
|
||||
|
||||
pub fn get_os(triple: &str) -> Option<abi::Os> {
|
||||
|
|
@ -1167,10 +1177,11 @@ pub fn early_error(emitter: &diagnostic::Emitter, msg: &str) -> ! {
|
|||
fail!(diagnostic::FatalError);
|
||||
}
|
||||
|
||||
pub fn list_metadata(sess: Session, path: &Path, out: &mut io::Writer) {
|
||||
pub fn list_metadata(sess: Session, path: &Path,
|
||||
out: &mut io::Writer) -> io::IoResult<()> {
|
||||
metadata::loader::list_file_metadata(
|
||||
token::get_ident_interner(),
|
||||
session::sess_os_to_meta_os(sess.targ_cfg.os), path, out);
|
||||
session::sess_os_to_meta_os(sess.targ_cfg.os), path, out)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -54,6 +54,11 @@ use syntax::diagnostic::Emitter;
|
|||
use syntax::diagnostic;
|
||||
use syntax::parse;
|
||||
|
||||
#[cfg(stage0)]
|
||||
macro_rules! if_ok (
|
||||
($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
|
||||
)
|
||||
|
||||
pub mod middle {
|
||||
pub mod trans;
|
||||
pub mod ty;
|
||||
|
|
@ -236,8 +241,8 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
|
|||
1u => {
|
||||
let ifile = matches.free[0].as_slice();
|
||||
if ifile == "-" {
|
||||
let src =
|
||||
str::from_utf8_owned(io::stdin().read_to_end()).unwrap();
|
||||
let contents = io::stdin().read_to_end().unwrap();
|
||||
let src = str::from_utf8_owned(contents).unwrap();
|
||||
(d::StrInput(src), None)
|
||||
} else {
|
||||
(d::FileInput(Path::new(ifile)), Some(Path::new(ifile)))
|
||||
|
|
@ -267,7 +272,7 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
|
|||
d::FileInput(ref ifile) => {
|
||||
let mut stdout = io::stdout();
|
||||
d::list_metadata(sess, &(*ifile),
|
||||
&mut stdout as &mut io::Writer);
|
||||
&mut stdout as &mut io::Writer).unwrap();
|
||||
}
|
||||
d::StrInput(_) => {
|
||||
d::early_error(demitter, "can not list metadata for stdin");
|
||||
|
|
|
|||
|
|
@ -1111,15 +1111,15 @@ fn get_attributes(md: ebml::Doc) -> ~[ast::Attribute] {
|
|||
}
|
||||
|
||||
fn list_crate_attributes(intr: @IdentInterner, md: ebml::Doc, hash: &str,
|
||||
out: &mut io::Writer) {
|
||||
write!(out, "=Crate Attributes ({})=\n", hash);
|
||||
out: &mut io::Writer) -> io::IoResult<()> {
|
||||
if_ok!(write!(out, "=Crate Attributes ({})=\n", hash));
|
||||
|
||||
let r = get_attributes(md);
|
||||
for attr in r.iter() {
|
||||
write!(out, "{}\n", pprust::attribute_to_str(attr, intr));
|
||||
if_ok!(write!(out, "{}\n", pprust::attribute_to_str(attr, intr)));
|
||||
}
|
||||
|
||||
write!(out, "\n\n");
|
||||
write!(out, "\n\n")
|
||||
}
|
||||
|
||||
pub fn get_crate_attributes(data: &[u8]) -> ~[ast::Attribute] {
|
||||
|
|
@ -1154,21 +1154,22 @@ pub fn get_crate_deps(data: &[u8]) -> ~[CrateDep] {
|
|||
return deps;
|
||||
}
|
||||
|
||||
fn list_crate_deps(data: &[u8], out: &mut io::Writer) {
|
||||
write!(out, "=External Dependencies=\n");
|
||||
fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
|
||||
if_ok!(write!(out, "=External Dependencies=\n"));
|
||||
|
||||
let r = get_crate_deps(data);
|
||||
for dep in r.iter() {
|
||||
let string = token::get_ident(dep.name.name);
|
||||
write!(out,
|
||||
"{} {}-{}-{}\n",
|
||||
dep.cnum,
|
||||
string.get(),
|
||||
dep.hash,
|
||||
dep.vers);
|
||||
if_ok!(write!(out,
|
||||
"{} {}-{}-{}\n",
|
||||
dep.cnum,
|
||||
string.get(),
|
||||
dep.hash,
|
||||
dep.vers));
|
||||
}
|
||||
|
||||
write!(out, "\n");
|
||||
if_ok!(write!(out, "\n"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_crate_hash(data: &[u8]) -> ~str {
|
||||
|
|
@ -1186,11 +1187,11 @@ pub fn get_crate_vers(data: &[u8]) -> ~str {
|
|||
}
|
||||
|
||||
pub fn list_crate_metadata(intr: @IdentInterner, bytes: &[u8],
|
||||
out: &mut io::Writer) {
|
||||
out: &mut io::Writer) -> io::IoResult<()> {
|
||||
let hash = get_crate_hash(bytes);
|
||||
let md = reader::Doc(bytes);
|
||||
list_crate_attributes(intr, md, hash, out);
|
||||
list_crate_deps(bytes, out);
|
||||
if_ok!(list_crate_attributes(intr, md, hash, out));
|
||||
list_crate_deps(bytes, out)
|
||||
}
|
||||
|
||||
// Translates a def_id from an external crate to a def_id for the current
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
// Metadata encoding
|
||||
|
||||
#[allow(unused_must_use)]; // everything is just a MemWriter, can't fail
|
||||
|
||||
use metadata::common::*;
|
||||
use metadata::cstore;
|
||||
|
|
@ -350,7 +351,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
|
|||
let mut index = index.borrow_mut();
|
||||
index.get().push(entry {
|
||||
val: variant.node.id as i64,
|
||||
pos: ebml_w.writer.tell(),
|
||||
pos: ebml_w.writer.tell().unwrap(),
|
||||
});
|
||||
}
|
||||
ebml_w.start_tag(tag_items_data_item);
|
||||
|
|
@ -668,10 +669,10 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::Explic
|
|||
|
||||
// Encode the base self type.
|
||||
match explicit_self {
|
||||
SelfStatic => ebml_w.writer.write(&[ 's' as u8 ]),
|
||||
SelfValue => ebml_w.writer.write(&[ 'v' as u8 ]),
|
||||
SelfBox => ebml_w.writer.write(&[ '@' as u8 ]),
|
||||
SelfUniq => ebml_w.writer.write(&[ '~' as u8 ]),
|
||||
SelfStatic => { ebml_w.writer.write(&[ 's' as u8 ]); }
|
||||
SelfValue => { ebml_w.writer.write(&[ 'v' as u8 ]); }
|
||||
SelfBox => { ebml_w.writer.write(&[ '@' as u8 ]); }
|
||||
SelfUniq => { ebml_w.writer.write(&[ '~' as u8 ]); }
|
||||
SelfRegion(_, m) => {
|
||||
// FIXME(#4846) encode custom lifetime
|
||||
ebml_w.writer.write(&['&' as u8]);
|
||||
|
|
@ -684,8 +685,8 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::Explic
|
|||
fn encode_mutability(ebml_w: &writer::Encoder,
|
||||
m: ast::Mutability) {
|
||||
match m {
|
||||
MutImmutable => ebml_w.writer.write(&[ 'i' as u8 ]),
|
||||
MutMutable => ebml_w.writer.write(&[ 'm' as u8 ]),
|
||||
MutImmutable => { ebml_w.writer.write(&[ 'i' as u8 ]); }
|
||||
MutMutable => { ebml_w.writer.write(&[ 'm' as u8 ]); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -726,12 +727,12 @@ fn encode_info_for_struct(ecx: &EncodeContext,
|
|||
};
|
||||
|
||||
let id = field.node.id;
|
||||
index.push(entry {val: id as i64, pos: ebml_w.writer.tell()});
|
||||
index.push(entry {val: id as i64, pos: ebml_w.writer.tell().unwrap()});
|
||||
{
|
||||
let mut global_index = global_index.borrow_mut();
|
||||
global_index.get().push(entry {
|
||||
val: id as i64,
|
||||
pos: ebml_w.writer.tell(),
|
||||
pos: ebml_w.writer.tell().unwrap(),
|
||||
});
|
||||
}
|
||||
ebml_w.start_tag(tag_items_data_item);
|
||||
|
|
@ -758,7 +759,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
|
|||
let mut index = index.borrow_mut();
|
||||
index.get().push(entry {
|
||||
val: ctor_id as i64,
|
||||
pos: ebml_w.writer.tell(),
|
||||
pos: ebml_w.writer.tell().unwrap(),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -921,7 +922,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
let mut index = index.borrow_mut();
|
||||
index.get().push(entry {
|
||||
val: item.id as i64,
|
||||
pos: ebml_w.writer.tell(),
|
||||
pos: ebml_w.writer.tell().unwrap(),
|
||||
});
|
||||
}
|
||||
let add_to_index: || = || add_to_index(item, ebml_w, index);
|
||||
|
|
@ -1157,7 +1158,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
let mut index = index.borrow_mut();
|
||||
index.get().push(entry {
|
||||
val: m.def_id.node as i64,
|
||||
pos: ebml_w.writer.tell(),
|
||||
pos: ebml_w.writer.tell().unwrap(),
|
||||
});
|
||||
}
|
||||
encode_info_for_method(ecx,
|
||||
|
|
@ -1219,7 +1220,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
let mut index = index.borrow_mut();
|
||||
index.get().push(entry {
|
||||
val: method_def_id.node as i64,
|
||||
pos: ebml_w.writer.tell(),
|
||||
pos: ebml_w.writer.tell().unwrap(),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1294,7 +1295,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
|
|||
let mut index = index.borrow_mut();
|
||||
index.get().push(entry {
|
||||
val: nitem.id as i64,
|
||||
pos: ebml_w.writer.tell(),
|
||||
pos: ebml_w.writer.tell().unwrap(),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1418,7 +1419,7 @@ fn encode_info_for_items(ecx: &EncodeContext,
|
|||
let mut index = index.borrow_mut();
|
||||
index.get().push(entry {
|
||||
val: CRATE_NODE_ID as i64,
|
||||
pos: ebml_w.writer.tell(),
|
||||
pos: ebml_w.writer.tell().unwrap(),
|
||||
});
|
||||
}
|
||||
encode_info_for_mod(ecx,
|
||||
|
|
@ -1478,7 +1479,7 @@ fn encode_index<T:'static>(
|
|||
let mut bucket_locs = ~[];
|
||||
ebml_w.start_tag(tag_index_buckets);
|
||||
for bucket in buckets.iter() {
|
||||
bucket_locs.push(ebml_w.writer.tell());
|
||||
bucket_locs.push(ebml_w.writer.tell().unwrap());
|
||||
ebml_w.start_tag(tag_index_buckets_bucket);
|
||||
for elt in (**bucket).iter() {
|
||||
ebml_w.start_tag(tag_index_buckets_bucket_elt);
|
||||
|
|
@ -1895,58 +1896,58 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, crate: &Crate)
|
|||
|
||||
encode_hash(&mut ebml_w, ecx.link_meta.crate_hash);
|
||||
|
||||
let mut i = ebml_w.writer.tell();
|
||||
let mut i = ebml_w.writer.tell().unwrap();
|
||||
let crate_attrs = synthesize_crate_attrs(&ecx, crate);
|
||||
encode_attributes(&mut ebml_w, crate_attrs);
|
||||
ecx.stats.attr_bytes.set(ebml_w.writer.tell() - i);
|
||||
ecx.stats.attr_bytes.set(ebml_w.writer.tell().unwrap() - i);
|
||||
|
||||
i = ebml_w.writer.tell();
|
||||
i = ebml_w.writer.tell().unwrap();
|
||||
encode_crate_deps(&ecx, &mut ebml_w, ecx.cstore);
|
||||
ecx.stats.dep_bytes.set(ebml_w.writer.tell() - i);
|
||||
ecx.stats.dep_bytes.set(ebml_w.writer.tell().unwrap() - i);
|
||||
|
||||
// Encode the language items.
|
||||
i = ebml_w.writer.tell();
|
||||
i = ebml_w.writer.tell().unwrap();
|
||||
encode_lang_items(&ecx, &mut ebml_w);
|
||||
ecx.stats.lang_item_bytes.set(ebml_w.writer.tell() - i);
|
||||
ecx.stats.lang_item_bytes.set(ebml_w.writer.tell().unwrap() - i);
|
||||
|
||||
// Encode the native libraries used
|
||||
i = ebml_w.writer.tell();
|
||||
i = ebml_w.writer.tell().unwrap();
|
||||
encode_native_libraries(&ecx, &mut ebml_w);
|
||||
ecx.stats.native_lib_bytes.set(ebml_w.writer.tell() - i);
|
||||
ecx.stats.native_lib_bytes.set(ebml_w.writer.tell().unwrap() - i);
|
||||
|
||||
// Encode the macro registrar function
|
||||
i = ebml_w.writer.tell();
|
||||
i = ebml_w.writer.tell().unwrap();
|
||||
encode_macro_registrar_fn(&ecx, &mut ebml_w);
|
||||
ecx.stats.macro_registrar_fn_bytes.set(ebml_w.writer.tell() - i);
|
||||
ecx.stats.macro_registrar_fn_bytes.set(ebml_w.writer.tell().unwrap() - i);
|
||||
|
||||
// Encode macro definitions
|
||||
i = ebml_w.writer.tell();
|
||||
i = ebml_w.writer.tell().unwrap();
|
||||
encode_macro_defs(&ecx, crate, &mut ebml_w);
|
||||
ecx.stats.macro_defs_bytes.set(ebml_w.writer.tell() - i);
|
||||
ecx.stats.macro_defs_bytes.set(ebml_w.writer.tell().unwrap() - i);
|
||||
|
||||
// Encode the def IDs of impls, for coherence checking.
|
||||
i = ebml_w.writer.tell();
|
||||
i = ebml_w.writer.tell().unwrap();
|
||||
encode_impls(&ecx, crate, &mut ebml_w);
|
||||
ecx.stats.impl_bytes.set(ebml_w.writer.tell() - i);
|
||||
ecx.stats.impl_bytes.set(ebml_w.writer.tell().unwrap() - i);
|
||||
|
||||
// Encode miscellaneous info.
|
||||
i = ebml_w.writer.tell();
|
||||
i = ebml_w.writer.tell().unwrap();
|
||||
encode_misc_info(&ecx, crate, &mut ebml_w);
|
||||
ecx.stats.misc_bytes.set(ebml_w.writer.tell() - i);
|
||||
ecx.stats.misc_bytes.set(ebml_w.writer.tell().unwrap() - i);
|
||||
|
||||
// Encode and index the items.
|
||||
ebml_w.start_tag(tag_items);
|
||||
i = ebml_w.writer.tell();
|
||||
i = ebml_w.writer.tell().unwrap();
|
||||
let items_index = encode_info_for_items(&ecx, &mut ebml_w, crate);
|
||||
ecx.stats.item_bytes.set(ebml_w.writer.tell() - i);
|
||||
ecx.stats.item_bytes.set(ebml_w.writer.tell().unwrap() - i);
|
||||
|
||||
i = ebml_w.writer.tell();
|
||||
i = ebml_w.writer.tell().unwrap();
|
||||
let items_buckets = create_index(items_index);
|
||||
encode_index(&mut ebml_w, items_buckets, write_i64);
|
||||
ecx.stats.index_bytes.set(ebml_w.writer.tell() - i);
|
||||
ecx.stats.index_bytes.set(ebml_w.writer.tell().unwrap() - i);
|
||||
ebml_w.end_tag();
|
||||
|
||||
ecx.stats.total_bytes.set(ebml_w.writer.tell());
|
||||
ecx.stats.total_bytes.set(ebml_w.writer.tell().unwrap());
|
||||
|
||||
if tcx.sess.meta_stats() {
|
||||
for e in ebml_w.writer.get_ref().iter() {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
use std::cell::RefCell;
|
||||
use std::option;
|
||||
use std::os;
|
||||
use std::io;
|
||||
use std::io::fs;
|
||||
use std::hashmap::HashSet;
|
||||
|
||||
|
|
@ -93,7 +92,7 @@ impl FileSearch {
|
|||
pub fn search(&self, pick: pick) {
|
||||
self.for_each_lib_search_path(|lib_search_path| {
|
||||
debug!("searching {}", lib_search_path.display());
|
||||
match io::result(|| fs::readdir(lib_search_path)) {
|
||||
match fs::readdir(lib_search_path) {
|
||||
Ok(files) => {
|
||||
let mut rslt = FileDoesntMatch;
|
||||
let is_rlib = |p: & &Path| {
|
||||
|
|
@ -163,8 +162,8 @@ pub fn get_or_default_sysroot() -> Path {
|
|||
// Follow symlinks. If the resolved path is relative, make it absolute.
|
||||
fn canonicalize(path: Option<Path>) -> Option<Path> {
|
||||
path.and_then(|mut path|
|
||||
match io::io_error::cond.trap(|_| ()).inside(|| fs::readlink(&path)) {
|
||||
Some(canon) => {
|
||||
match fs::readlink(&path) {
|
||||
Ok(canon) => {
|
||||
if canon.is_absolute() {
|
||||
Some(canon)
|
||||
} else {
|
||||
|
|
@ -172,7 +171,7 @@ pub fn get_or_default_sysroot() -> Path {
|
|||
Some(path.join(canon))
|
||||
}
|
||||
},
|
||||
None => Some(path),
|
||||
Err(..) => Some(path),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -381,13 +381,13 @@ pub fn read_meta_section_name(os: Os) -> &'static str {
|
|||
pub fn list_file_metadata(intr: @IdentInterner,
|
||||
os: Os,
|
||||
path: &Path,
|
||||
out: &mut io::Writer) {
|
||||
out: &mut io::Writer) -> io::IoResult<()> {
|
||||
match get_metadata_section(os, path) {
|
||||
option::Some(bytes) => decoder::list_crate_metadata(intr,
|
||||
bytes.as_slice(),
|
||||
out),
|
||||
option::None => {
|
||||
write!(out, "could not find metadata in {}.\n", path.display())
|
||||
write!(out, "could not find metadata in {}.\n", path.display())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
// Type encoding
|
||||
|
||||
#[allow(unused_must_use)]; // as with encoding, everything is a no-fail MemWriter
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::hashmap::HashMap;
|
||||
use std::io;
|
||||
|
|
@ -92,9 +94,9 @@ pub fn enc_ty(w: &mut MemWriter, cx: @ctxt, t: ty::t) {
|
|||
None => {}
|
||||
}
|
||||
}
|
||||
let pos = w.tell();
|
||||
let pos = w.tell().unwrap();
|
||||
enc_sty(w, cx, &ty::get(t).sty);
|
||||
let end = w.tell();
|
||||
let end = w.tell().unwrap();
|
||||
let len = end - pos;
|
||||
fn estimate_sz(u: u64) -> u64 {
|
||||
let mut n = u;
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ struct LoopScope<'a> {
|
|||
}
|
||||
|
||||
impl<O:DataFlowOperator> pprust::PpAnn for DataFlowContext<O> {
|
||||
fn pre(&self, node: pprust::AnnNode) {
|
||||
fn pre(&self, node: pprust::AnnNode) -> io::IoResult<()> {
|
||||
let (ps, id) = match node {
|
||||
pprust::NodeExpr(ps, expr) => (ps, expr.id),
|
||||
pprust::NodeBlock(ps, blk) => (ps, blk.id),
|
||||
|
|
@ -117,9 +117,10 @@ impl<O:DataFlowOperator> pprust::PpAnn for DataFlowContext<O> {
|
|||
|
||||
let comment_str = format!("id {}: {}{}{}",
|
||||
id, entry_str, gens_str, kills_str);
|
||||
pprust::synth_comment(ps, comment_str);
|
||||
pp::space(&mut ps.s);
|
||||
if_ok!(pprust::synth_comment(ps, comment_str));
|
||||
if_ok!(pp::space(&mut ps.s));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -347,18 +348,20 @@ impl<O:DataFlowOperator+Clone+'static> DataFlowContext<O> {
|
|||
debug!("Dataflow result:");
|
||||
debug!("{}", {
|
||||
let this = @(*self).clone();
|
||||
this.pretty_print_to(~io::stderr() as ~io::Writer, blk);
|
||||
this.pretty_print_to(~io::stderr() as ~io::Writer, blk).unwrap();
|
||||
""
|
||||
});
|
||||
}
|
||||
|
||||
fn pretty_print_to(@self, wr: ~io::Writer, blk: &ast::Block) {
|
||||
fn pretty_print_to(@self, wr: ~io::Writer,
|
||||
blk: &ast::Block) -> io::IoResult<()> {
|
||||
let mut ps = pprust::rust_printer_annotated(wr, self.tcx.sess.intr(),
|
||||
self as @pprust::PpAnn);
|
||||
pprust::cbox(&mut ps, pprust::indent_unit);
|
||||
pprust::ibox(&mut ps, 0u);
|
||||
pprust::print_block(&mut ps, blk);
|
||||
pp::eof(&mut ps.s);
|
||||
if_ok!(pprust::cbox(&mut ps, pprust::indent_unit));
|
||||
if_ok!(pprust::ibox(&mut ps, 0u));
|
||||
if_ok!(pprust::print_block(&mut ps, blk));
|
||||
if_ok!(pp::eof(&mut ps.s));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -736,14 +736,15 @@ impl Liveness {
|
|||
pub fn write_vars(&self,
|
||||
wr: &mut io::Writer,
|
||||
ln: LiveNode,
|
||||
test: |uint| -> LiveNode) {
|
||||
test: |uint| -> LiveNode) -> io::IoResult<()> {
|
||||
let node_base_idx = self.idx(ln, Variable(0));
|
||||
for var_idx in range(0u, self.ir.num_vars.get()) {
|
||||
let idx = node_base_idx + var_idx;
|
||||
if test(idx).is_valid() {
|
||||
write!(wr, " {}", Variable(var_idx).to_str());
|
||||
if_ok!(write!(wr, " {}", Variable(var_idx).to_str()));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn find_loop_scope(&self,
|
||||
|
|
@ -781,6 +782,7 @@ impl Liveness {
|
|||
*loop_scope.get().last().unwrap()
|
||||
}
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
pub fn ln_str(&self, ln: LiveNode) -> ~str {
|
||||
let mut wr = io::MemWriter::new();
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use std::fmt;
|
|||
pub struct Escape<'a>(&'a str);
|
||||
|
||||
impl<'a> fmt::Show for Escape<'a> {
|
||||
fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) {
|
||||
fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
// Because the internet is always right, turns out there's not that many
|
||||
// characters to escape: http://stackoverflow.com/questions/7381974
|
||||
let Escape(s) = *s;
|
||||
|
|
@ -29,7 +29,7 @@ impl<'a> fmt::Show for Escape<'a> {
|
|||
for (i, ch) in s.bytes().enumerate() {
|
||||
match ch as char {
|
||||
'<' | '>' | '&' | '\'' | '"' => {
|
||||
fmt.buf.write(pile_o_bits.slice(last, i).as_bytes());
|
||||
if_ok!(fmt.buf.write(pile_o_bits.slice(last, i).as_bytes()));
|
||||
let s = match ch as char {
|
||||
'>' => ">",
|
||||
'<' => "<",
|
||||
|
|
@ -38,7 +38,7 @@ impl<'a> fmt::Show for Escape<'a> {
|
|||
'"' => """,
|
||||
_ => unreachable!()
|
||||
};
|
||||
fmt.buf.write(s.as_bytes());
|
||||
if_ok!(fmt.buf.write(s.as_bytes()));
|
||||
last = i + 1;
|
||||
}
|
||||
_ => {}
|
||||
|
|
@ -46,7 +46,8 @@ impl<'a> fmt::Show for Escape<'a> {
|
|||
}
|
||||
|
||||
if last < s.len() {
|
||||
fmt.buf.write(pile_o_bits.slice_from(last).as_bytes());
|
||||
if_ok!(fmt.buf.write(pile_o_bits.slice_from(last).as_bytes()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,85 +48,104 @@ impl PuritySpace {
|
|||
}
|
||||
|
||||
impl fmt::Show for clean::Generics {
|
||||
fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) {
|
||||
if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return }
|
||||
f.buf.write("<".as_bytes());
|
||||
fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return Ok(()) }
|
||||
if_ok!(f.buf.write("<".as_bytes()));
|
||||
|
||||
for (i, life) in g.lifetimes.iter().enumerate() {
|
||||
if i > 0 { f.buf.write(", ".as_bytes()); }
|
||||
write!(f.buf, "{}", *life);
|
||||
if i > 0 {
|
||||
if_ok!(f.buf.write(", ".as_bytes()));
|
||||
}
|
||||
if_ok!(write!(f.buf, "{}", *life));
|
||||
}
|
||||
|
||||
if g.type_params.len() > 0 {
|
||||
if g.lifetimes.len() > 0 { f.buf.write(", ".as_bytes()); }
|
||||
if g.lifetimes.len() > 0 {
|
||||
if_ok!(f.buf.write(", ".as_bytes()));
|
||||
}
|
||||
|
||||
for (i, tp) in g.type_params.iter().enumerate() {
|
||||
if i > 0 { f.buf.write(", ".as_bytes()) }
|
||||
f.buf.write(tp.name.as_bytes());
|
||||
if i > 0 {
|
||||
if_ok!(f.buf.write(", ".as_bytes()))
|
||||
}
|
||||
if_ok!(f.buf.write(tp.name.as_bytes()));
|
||||
|
||||
if tp.bounds.len() > 0 {
|
||||
f.buf.write(": ".as_bytes());
|
||||
if_ok!(f.buf.write(": ".as_bytes()));
|
||||
for (i, bound) in tp.bounds.iter().enumerate() {
|
||||
if i > 0 { f.buf.write(" + ".as_bytes()); }
|
||||
write!(f.buf, "{}", *bound);
|
||||
if i > 0 {
|
||||
if_ok!(f.buf.write(" + ".as_bytes()));
|
||||
}
|
||||
if_ok!(write!(f.buf, "{}", *bound));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
f.buf.write(">".as_bytes());
|
||||
if_ok!(f.buf.write(">".as_bytes()));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::Lifetime {
|
||||
fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) {
|
||||
f.buf.write("'".as_bytes());
|
||||
f.buf.write(l.get_ref().as_bytes());
|
||||
fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if_ok!(f.buf.write("'".as_bytes()));
|
||||
if_ok!(f.buf.write(l.get_ref().as_bytes()));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::TyParamBound {
|
||||
fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) {
|
||||
fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *bound {
|
||||
clean::RegionBound => {
|
||||
f.buf.write("'static".as_bytes())
|
||||
}
|
||||
clean::TraitBound(ref ty) => {
|
||||
write!(f.buf, "{}", *ty);
|
||||
write!(f.buf, "{}", *ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::Path {
|
||||
fn fmt(path: &clean::Path, f: &mut fmt::Formatter) {
|
||||
if path.global { f.buf.write("::".as_bytes()) }
|
||||
fn fmt(path: &clean::Path, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if path.global {
|
||||
if_ok!(f.buf.write("::".as_bytes()))
|
||||
}
|
||||
for (i, seg) in path.segments.iter().enumerate() {
|
||||
if i > 0 { f.buf.write("::".as_bytes()) }
|
||||
f.buf.write(seg.name.as_bytes());
|
||||
if i > 0 {
|
||||
if_ok!(f.buf.write("::".as_bytes()))
|
||||
}
|
||||
if_ok!(f.buf.write(seg.name.as_bytes()));
|
||||
|
||||
if seg.lifetimes.len() > 0 || seg.types.len() > 0 {
|
||||
f.buf.write("<".as_bytes());
|
||||
if_ok!(f.buf.write("<".as_bytes()));
|
||||
let mut comma = false;
|
||||
for lifetime in seg.lifetimes.iter() {
|
||||
if comma { f.buf.write(", ".as_bytes()); }
|
||||
if comma {
|
||||
if_ok!(f.buf.write(", ".as_bytes()));
|
||||
}
|
||||
comma = true;
|
||||
write!(f.buf, "{}", *lifetime);
|
||||
if_ok!(write!(f.buf, "{}", *lifetime));
|
||||
}
|
||||
for ty in seg.types.iter() {
|
||||
if comma { f.buf.write(", ".as_bytes()); }
|
||||
if comma {
|
||||
if_ok!(f.buf.write(", ".as_bytes()));
|
||||
}
|
||||
comma = true;
|
||||
write!(f.buf, "{}", *ty);
|
||||
if_ok!(write!(f.buf, "{}", *ty));
|
||||
}
|
||||
f.buf.write(">".as_bytes());
|
||||
if_ok!(f.buf.write(">".as_bytes()));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Used when rendering a `ResolvedPath` structure. This invokes the `path`
|
||||
/// rendering function with the necessary arguments for linking to a local path.
|
||||
fn resolved_path(w: &mut io::Writer, id: ast::NodeId, p: &clean::Path,
|
||||
print_all: bool) {
|
||||
print_all: bool) -> fmt::Result {
|
||||
path(w, p, print_all,
|
||||
|_cache, loc| { Some("../".repeat(loc.len())) },
|
||||
|cache| {
|
||||
|
|
@ -134,13 +153,14 @@ fn resolved_path(w: &mut io::Writer, id: ast::NodeId, p: &clean::Path,
|
|||
None => None,
|
||||
Some(&(ref fqp, shortty)) => Some((fqp.clone(), shortty))
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/// Used when rendering an `ExternalPath` structure. Like `resolved_path` this
|
||||
/// will invoke `path` with proper linking-style arguments.
|
||||
fn external_path(w: &mut io::Writer, p: &clean::Path, print_all: bool,
|
||||
fqn: &[~str], kind: clean::TypeKind, crate: ast::CrateNum) {
|
||||
fqn: &[~str], kind: clean::TypeKind,
|
||||
crate: ast::CrateNum) -> fmt::Result {
|
||||
path(w, p, print_all,
|
||||
|cache, loc| {
|
||||
match *cache.extern_locations.get(&crate) {
|
||||
|
|
@ -161,7 +181,9 @@ fn external_path(w: &mut io::Writer, p: &clean::Path, print_all: bool,
|
|||
|
||||
fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
|
||||
root: |&render::Cache, &[~str]| -> Option<~str>,
|
||||
info: |&render::Cache| -> Option<(~[~str], &'static str)>) {
|
||||
info: |&render::Cache| -> Option<(~[~str], &'static str)>)
|
||||
-> fmt::Result
|
||||
{
|
||||
// The generics will get written to both the title and link
|
||||
let mut generics = ~"";
|
||||
let last = path.segments.last().unwrap();
|
||||
|
|
@ -200,20 +222,20 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
|
|||
let mut root = root;
|
||||
for seg in path.segments.slice_to(amt).iter() {
|
||||
if "super" == seg.name || "self" == seg.name {
|
||||
write!(w, "{}::", seg.name);
|
||||
if_ok!(write!(w, "{}::", seg.name));
|
||||
} else {
|
||||
root.push_str(seg.name);
|
||||
root.push_str("/");
|
||||
write!(w, "<a class='mod'
|
||||
href='{}index.html'>{}</a>::",
|
||||
root,
|
||||
seg.name);
|
||||
if_ok!(write!(w, "<a class='mod'
|
||||
href='{}index.html'>{}</a>::",
|
||||
root,
|
||||
seg.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
for seg in path.segments.slice_to(amt).iter() {
|
||||
write!(w, "{}::", seg.name);
|
||||
if_ok!(write!(w, "{}::", seg.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -241,51 +263,57 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
|
|||
}
|
||||
}
|
||||
|
||||
write!(w, "<a class='{}' href='{}' title='{}'>{}</a>",
|
||||
shortty, url, fqp.connect("::"), last.name);
|
||||
if_ok!(write!(w, "<a class='{}' href='{}' title='{}'>{}</a>",
|
||||
shortty, url, fqp.connect("::"), last.name));
|
||||
}
|
||||
|
||||
_ => {
|
||||
write!(w, "{}", last.name);
|
||||
if_ok!(write!(w, "{}", last.name));
|
||||
}
|
||||
}
|
||||
write!(w, "{}", generics);
|
||||
if_ok!(write!(w, "{}", generics));
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Helper to render type parameters
|
||||
fn typarams(w: &mut io::Writer, typarams: &Option<~[clean::TyParamBound]>) {
|
||||
fn typarams(w: &mut io::Writer,
|
||||
typarams: &Option<~[clean::TyParamBound]>) -> fmt::Result {
|
||||
match *typarams {
|
||||
Some(ref params) => {
|
||||
write!(w, "<");
|
||||
if_ok!(write!(w, "<"));
|
||||
for (i, param) in params.iter().enumerate() {
|
||||
if i > 0 { write!(w, ", "); }
|
||||
write!(w, "{}", *param);
|
||||
if i > 0 {
|
||||
if_ok!(write!(w, ", "));
|
||||
}
|
||||
if_ok!(write!(w, "{}", *param));
|
||||
}
|
||||
write!(w, ">");
|
||||
if_ok!(write!(w, ">"));
|
||||
Ok(())
|
||||
}
|
||||
None => {}
|
||||
None => Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::Type {
|
||||
fn fmt(g: &clean::Type, f: &mut fmt::Formatter) {
|
||||
fn fmt(g: &clean::Type, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *g {
|
||||
clean::TyParamBinder(id) | clean::Generic(id) => {
|
||||
local_data::get(cache_key, |cache| {
|
||||
let m = cache.unwrap().get();
|
||||
f.buf.write(m.typarams.get(&id).as_bytes());
|
||||
f.buf.write(m.typarams.get(&id).as_bytes())
|
||||
})
|
||||
}
|
||||
clean::ResolvedPath{id, typarams: ref tp, path: ref path} => {
|
||||
resolved_path(f.buf, id, path, false);
|
||||
typarams(f.buf, tp);
|
||||
if_ok!(resolved_path(f.buf, id, path, false));
|
||||
typarams(f.buf, tp)
|
||||
}
|
||||
clean::ExternalPath{path: ref path, typarams: ref tp,
|
||||
fqn: ref fqn, kind, crate} => {
|
||||
external_path(f.buf, path, false, fqn.as_slice(), kind, crate);
|
||||
typarams(f.buf, tp);
|
||||
if_ok!(external_path(f.buf, path, false, fqn.as_slice(), kind,
|
||||
crate))
|
||||
typarams(f.buf, tp)
|
||||
}
|
||||
clean::Self(..) => f.buf.write("Self".as_bytes()),
|
||||
clean::Primitive(prim) => {
|
||||
|
|
@ -306,7 +334,7 @@ impl fmt::Show for clean::Type {
|
|||
ast::TyBool => "bool",
|
||||
ast::TyChar => "char",
|
||||
};
|
||||
f.buf.write(s.as_bytes());
|
||||
f.buf.write(s.as_bytes())
|
||||
}
|
||||
clean::Closure(ref decl) => {
|
||||
let region = match decl.region {
|
||||
|
|
@ -322,7 +350,7 @@ impl fmt::Show for clean::Type {
|
|||
ast::ManagedSigil => format!("@{}fn({})", region, decl.decl.inputs),
|
||||
},
|
||||
arrow = match decl.decl.output { clean::Unit => "no", _ => "yes" },
|
||||
ret = decl.decl.output);
|
||||
ret = decl.decl.output)
|
||||
// FIXME: where are bounds and lifetimes printed?!
|
||||
}
|
||||
clean::BareFunction(ref decl) => {
|
||||
|
|
@ -333,19 +361,21 @@ impl fmt::Show for clean::Type {
|
|||
ref s => " " + *s + " ",
|
||||
},
|
||||
decl.generics,
|
||||
decl.decl);
|
||||
decl.decl)
|
||||
}
|
||||
clean::Tuple(ref typs) => {
|
||||
f.buf.write("(".as_bytes());
|
||||
if_ok!(f.buf.write("(".as_bytes()));
|
||||
for (i, typ) in typs.iter().enumerate() {
|
||||
if i > 0 { f.buf.write(", ".as_bytes()) }
|
||||
write!(f.buf, "{}", *typ);
|
||||
if i > 0 {
|
||||
if_ok!(f.buf.write(", ".as_bytes()))
|
||||
}
|
||||
if_ok!(write!(f.buf, "{}", *typ));
|
||||
}
|
||||
f.buf.write(")".as_bytes());
|
||||
f.buf.write(")".as_bytes())
|
||||
}
|
||||
clean::Vector(ref t) => write!(f.buf, "[{}]", **t),
|
||||
clean::FixedVector(ref t, ref s) => {
|
||||
write!(f.buf, "[{}, ..{}]", **t, *s);
|
||||
write!(f.buf, "[{}, ..{}]", **t, *s)
|
||||
}
|
||||
clean::String => f.buf.write("str".as_bytes()),
|
||||
clean::Bool => f.buf.write("bool".as_bytes()),
|
||||
|
|
@ -368,23 +398,23 @@ impl fmt::Show for clean::Type {
|
|||
clean::Mutable => "mut ",
|
||||
clean::Immutable => "",
|
||||
},
|
||||
**ty);
|
||||
**ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::FnDecl {
|
||||
fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) {
|
||||
fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}",
|
||||
args = d.inputs,
|
||||
arrow = match d.output { clean::Unit => "no", _ => "yes" },
|
||||
ret = d.output);
|
||||
ret = d.output)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for ~[clean::Argument] {
|
||||
fn fmt(inputs: &~[clean::Argument], f: &mut fmt::Formatter) {
|
||||
fn fmt(inputs: &~[clean::Argument], f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut args = ~"";
|
||||
for (i, input) in inputs.iter().enumerate() {
|
||||
if i > 0 { args.push_str(", "); }
|
||||
|
|
@ -393,12 +423,12 @@ impl fmt::Show for ~[clean::Argument] {
|
|||
}
|
||||
args.push_str(format!("{}", input.type_));
|
||||
}
|
||||
f.buf.write(args.as_bytes());
|
||||
f.buf.write(args.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Show for Method<'a> {
|
||||
fn fmt(m: &Method<'a>, f: &mut fmt::Formatter) {
|
||||
fn fmt(m: &Method<'a>, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Method(selfty, d) = *m;
|
||||
let mut args = ~"";
|
||||
match *selfty {
|
||||
|
|
@ -429,74 +459,79 @@ impl<'a> fmt::Show for Method<'a> {
|
|||
write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}",
|
||||
args = args,
|
||||
arrow = match d.output { clean::Unit => "no", _ => "yes" },
|
||||
ret = d.output);
|
||||
ret = d.output)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for VisSpace {
|
||||
fn fmt(v: &VisSpace, f: &mut fmt::Formatter) {
|
||||
fn fmt(v: &VisSpace, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match v.get() {
|
||||
Some(ast::Public) => { write!(f.buf, "pub "); }
|
||||
Some(ast::Private) => { write!(f.buf, "priv "); }
|
||||
Some(ast::Inherited) | None => {}
|
||||
Some(ast::Public) => write!(f.buf, "pub "),
|
||||
Some(ast::Private) => write!(f.buf, "priv "),
|
||||
Some(ast::Inherited) | None => Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for PuritySpace {
|
||||
fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) {
|
||||
fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match p.get() {
|
||||
ast::UnsafeFn => write!(f.buf, "unsafe "),
|
||||
ast::ExternFn => write!(f.buf, "extern "),
|
||||
ast::ImpureFn => {}
|
||||
ast::ImpureFn => Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::ViewPath {
|
||||
fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) {
|
||||
fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *v {
|
||||
clean::SimpleImport(ref name, ref src) => {
|
||||
if *name == src.path.segments.last().unwrap().name {
|
||||
write!(f.buf, "use {};", *src);
|
||||
write!(f.buf, "use {};", *src)
|
||||
} else {
|
||||
write!(f.buf, "use {} = {};", *name, *src);
|
||||
write!(f.buf, "use {} = {};", *name, *src)
|
||||
}
|
||||
}
|
||||
clean::GlobImport(ref src) => {
|
||||
write!(f.buf, "use {}::*;", *src);
|
||||
write!(f.buf, "use {}::*;", *src)
|
||||
}
|
||||
clean::ImportList(ref src, ref names) => {
|
||||
write!(f.buf, "use {}::\\{", *src);
|
||||
if_ok!(write!(f.buf, "use {}::\\{", *src));
|
||||
for (i, n) in names.iter().enumerate() {
|
||||
if i > 0 { write!(f.buf, ", "); }
|
||||
write!(f.buf, "{}", *n);
|
||||
if i > 0 {
|
||||
if_ok!(write!(f.buf, ", "));
|
||||
}
|
||||
if_ok!(write!(f.buf, "{}", *n));
|
||||
}
|
||||
write!(f.buf, "\\};");
|
||||
write!(f.buf, "\\};")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::ImportSource {
|
||||
fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) {
|
||||
fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match v.did {
|
||||
// FIXME: shouldn't be restricted to just local imports
|
||||
Some(did) if ast_util::is_local(did) => {
|
||||
resolved_path(f.buf, did.node, &v.path, true);
|
||||
resolved_path(f.buf, did.node, &v.path, true)
|
||||
}
|
||||
_ => {
|
||||
for (i, seg) in v.path.segments.iter().enumerate() {
|
||||
if i > 0 { write!(f.buf, "::") }
|
||||
write!(f.buf, "{}", seg.name);
|
||||
if i > 0 {
|
||||
if_ok!(write!(f.buf, "::"))
|
||||
}
|
||||
if_ok!(write!(f.buf, "{}", seg.name));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for clean::ViewListIdent {
|
||||
fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) {
|
||||
fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match v.source {
|
||||
// FIXME: shouldn't be limited to just local imports
|
||||
Some(did) if ast_util::is_local(did) => {
|
||||
|
|
@ -508,7 +543,7 @@ impl fmt::Show for clean::ViewListIdent {
|
|||
types: ~[],
|
||||
}]
|
||||
};
|
||||
resolved_path(f.buf, did.node, &path, false);
|
||||
resolved_path(f.buf, did.node, &path, false)
|
||||
}
|
||||
_ => write!(f.buf, "{}", v.name),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ pub struct Page<'a> {
|
|||
|
||||
pub fn render<T: fmt::Show, S: fmt::Show>(
|
||||
dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
|
||||
-> fmt::Result
|
||||
{
|
||||
write!(dst,
|
||||
"<!DOCTYPE html>
|
||||
|
|
@ -121,7 +122,7 @@ pub fn render<T: fmt::Show, S: fmt::Show>(
|
|||
favicon = nonestr(layout.favicon),
|
||||
sidebar = *sidebar,
|
||||
crate = layout.crate,
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
fn nonestr<'a>(s: &'a str) -> &'a str {
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn render(w: &mut io::Writer, s: &str) {
|
||||
pub fn render(w: &mut io::Writer, s: &str) -> fmt::Result {
|
||||
extern fn block(ob: *buf, text: *buf, lang: *buf, opaque: *libc::c_void) {
|
||||
unsafe {
|
||||
let my_opaque: &my_opaque = cast::transmute(opaque);
|
||||
|
|
@ -159,11 +159,12 @@ pub fn render(w: &mut io::Writer, s: &str) {
|
|||
sd_markdown_render(ob, s.as_ptr(), s.len() as libc::size_t, markdown);
|
||||
sd_markdown_free(markdown);
|
||||
|
||||
vec::raw::buf_as_slice((*ob).data, (*ob).size as uint, |buf| {
|
||||
w.write(buf);
|
||||
let ret = vec::raw::buf_as_slice((*ob).data, (*ob).size as uint, |buf| {
|
||||
w.write(buf)
|
||||
});
|
||||
|
||||
bufrelease(ob);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -210,10 +211,10 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
|
|||
}
|
||||
|
||||
impl<'a> fmt::Show for Markdown<'a> {
|
||||
fn fmt(md: &Markdown<'a>, fmt: &mut fmt::Formatter) {
|
||||
fn fmt(md: &Markdown<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Markdown(md) = *md;
|
||||
// This is actually common enough to special-case
|
||||
if md.len() == 0 { return; }
|
||||
render(fmt.buf, md.as_slice());
|
||||
if md.len() == 0 { return Ok(()) }
|
||||
render(fmt.buf, md.as_slice())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -162,10 +162,16 @@ pub fn main_args(args: &[~str]) -> int {
|
|||
let output = matches.opt_str("o").map(|s| Path::new(s));
|
||||
match matches.opt_str("w") {
|
||||
Some(~"html") | None => {
|
||||
html::render::run(crate, output.unwrap_or(Path::new("doc")))
|
||||
match html::render::run(crate, output.unwrap_or(Path::new("doc"))) {
|
||||
Ok(()) => {}
|
||||
Err(e) => fail!("failed to generate documentation: {}", e),
|
||||
}
|
||||
}
|
||||
Some(~"json") => {
|
||||
json_output(crate, res, output.unwrap_or(Path::new("doc.json")))
|
||||
match json_output(crate, res, output.unwrap_or(Path::new("doc.json"))) {
|
||||
Ok(()) => {}
|
||||
Err(e) => fail!("failed to write json: {}", e),
|
||||
}
|
||||
}
|
||||
Some(s) => {
|
||||
println!("unknown output format: {}", s);
|
||||
|
|
@ -276,8 +282,8 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output {
|
|||
/// run over the deserialized output.
|
||||
fn json_input(input: &str) -> Result<Output, ~str> {
|
||||
let mut input = match File::open(&Path::new(input)) {
|
||||
Some(f) => f,
|
||||
None => return Err(format!("couldn't open {} for reading", input)),
|
||||
Ok(f) => f,
|
||||
Err(e) => return Err(format!("couldn't open {}: {}", input, e)),
|
||||
};
|
||||
match json::from_reader(&mut input) {
|
||||
Err(s) => Err(s.to_str()),
|
||||
|
|
@ -312,7 +318,8 @@ fn json_input(input: &str) -> Result<Output, ~str> {
|
|||
|
||||
/// Outputs the crate/plugin json as a giant json blob at the specified
|
||||
/// destination.
|
||||
fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
|
||||
fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson],
|
||||
dst: Path) -> io::IoResult<()> {
|
||||
// {
|
||||
// "schema": version,
|
||||
// "crate": { parsed crate ... },
|
||||
|
|
@ -340,6 +347,7 @@ fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
|
|||
json.insert(~"crate", crate_json);
|
||||
json.insert(~"plugins", json::Object(plugins_json));
|
||||
|
||||
let mut file = File::create(&dst).unwrap();
|
||||
json::Object(json).to_writer(&mut file);
|
||||
let mut file = if_ok!(File::create(&dst));
|
||||
if_ok!(json::Object(json).to_writer(&mut file));
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>) {
|
|||
let exe = outdir.path().join("rust_out");
|
||||
let out = run::process_output(exe.as_str().unwrap(), []);
|
||||
match out {
|
||||
None => fail!("couldn't run the test"),
|
||||
Some(out) => {
|
||||
Err(e) => fail!("couldn't run the test: {}", e),
|
||||
Ok(out) => {
|
||||
if !out.status.success() {
|
||||
fail!("test executable failed:\n{}",
|
||||
str::from_utf8(out.error));
|
||||
|
|
|
|||
|
|
@ -140,9 +140,9 @@ impl FsRequest {
|
|||
let mut paths = ~[];
|
||||
let path = CString::new(path.with_ref(|p| p), false);
|
||||
let parent = Path::new(path);
|
||||
c_str::from_c_multistring(req.get_ptr() as *libc::c_char,
|
||||
Some(req.get_result() as uint),
|
||||
|rel| {
|
||||
let _ = c_str::from_c_multistring(req.get_ptr() as *libc::c_char,
|
||||
Some(req.get_result() as uint),
|
||||
|rel| {
|
||||
let p = rel.as_bytes();
|
||||
paths.push(parent.join(p.slice_to(rel.len())));
|
||||
});
|
||||
|
|
@ -378,7 +378,8 @@ impl Drop for FileWatcher {
|
|||
rtio::CloseAsynchronously => {
|
||||
unsafe {
|
||||
let req = uvll::malloc_req(uvll::UV_FS);
|
||||
uvll::uv_fs_close(self.loop_.handle, req, self.fd, close_cb);
|
||||
assert_eq!(uvll::uv_fs_close(self.loop_.handle, req,
|
||||
self.fd, close_cb), 0);
|
||||
}
|
||||
|
||||
extern fn close_cb(req: *uvll::uv_fs_t) {
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ mod test {
|
|||
});
|
||||
|
||||
let task = pool.task(TaskOpts::new(), proc() {
|
||||
port.recv();
|
||||
drop(port.recv());
|
||||
});
|
||||
pool.spawn_sched().send(sched::TaskFromFriend(task));
|
||||
|
||||
|
|
@ -197,7 +197,7 @@ mod test {
|
|||
let listener = UdpWatcher::bind(local_loop(), addr2);
|
||||
chan.send((listener.unwrap(), addr1));
|
||||
let mut listener = UdpWatcher::bind(local_loop(), addr1).unwrap();
|
||||
listener.sendto([1, 2, 3, 4], addr2);
|
||||
listener.sendto([1, 2, 3, 4], addr2).unwrap();
|
||||
});
|
||||
|
||||
let task = pool.task(TaskOpts::new(), proc() {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ impl IdleWatcher {
|
|||
let data = uvll::get_data_for_uv_handle(handle);
|
||||
let f: ~proc() = cast::transmute(data);
|
||||
(*f)();
|
||||
uvll::uv_idle_stop(handle);
|
||||
assert_eq!(uvll::uv_idle_stop(handle), 0);
|
||||
uvll::uv_close(handle, close_cb);
|
||||
}
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ mod test {
|
|||
}
|
||||
}
|
||||
};
|
||||
task.wake().map(|t| t.reawaken(true));
|
||||
let _ = task.wake().map(|t| t.reawaken(true));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ via `close` and `delete` methods.
|
|||
#[crate_type = "dylib"];
|
||||
|
||||
#[feature(macro_rules)];
|
||||
#[deny(unused_result, unused_must_use)];
|
||||
|
||||
#[cfg(test)] extern mod green;
|
||||
|
||||
|
|
@ -207,7 +208,7 @@ fn wait_until_woken_after(slot: *mut Option<BlockedTask>, f: ||) {
|
|||
|
||||
fn wakeup(slot: &mut Option<BlockedTask>) {
|
||||
assert!(slot.is_some());
|
||||
slot.take_unwrap().wake().map(|t| t.reawaken(true));
|
||||
let _ = slot.take_unwrap().wake().map(|t| t.reawaken(true));
|
||||
}
|
||||
|
||||
pub struct Request {
|
||||
|
|
@ -276,7 +277,7 @@ impl Loop {
|
|||
pub fn wrap(handle: *uvll::uv_loop_t) -> Loop { Loop { handle: handle } }
|
||||
|
||||
pub fn run(&mut self) {
|
||||
unsafe { uvll::uv_run(self.handle, uvll::RUN_DEFAULT) };
|
||||
assert_eq!(unsafe { uvll::uv_run(self.handle, uvll::RUN_DEFAULT) }, 0);
|
||||
}
|
||||
|
||||
pub fn close(&mut self) {
|
||||
|
|
|
|||
|
|
@ -33,14 +33,15 @@ pub fn dumb_println(args: &fmt::Arguments) {
|
|||
|
||||
struct Stderr;
|
||||
impl io::Writer for Stderr {
|
||||
fn write(&mut self, data: &[u8]) {
|
||||
unsafe {
|
||||
fn write(&mut self, data: &[u8]) -> io::IoResult<()> {
|
||||
let _ = unsafe {
|
||||
libc::write(libc::STDERR_FILENO,
|
||||
data.as_ptr() as *libc::c_void,
|
||||
data.len() as libc::size_t);
|
||||
}
|
||||
data.len() as libc::size_t)
|
||||
};
|
||||
Ok(()) // just ignore the errors
|
||||
}
|
||||
}
|
||||
let mut w = Stderr;
|
||||
fmt::writeln(&mut w as &mut io::Writer, args);
|
||||
let _ = fmt::writeln(&mut w as &mut io::Writer, args);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -953,11 +953,11 @@ mod test {
|
|||
spawn(proc() {
|
||||
let port2 = port.recv();
|
||||
let mut stream = TcpWatcher::connect(local_loop(), addr).unwrap();
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
|
||||
port2.recv();
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
|
||||
port2.recv();
|
||||
});
|
||||
|
||||
|
|
@ -1008,7 +1008,7 @@ mod test {
|
|||
while stream.is_err() {
|
||||
stream = TcpWatcher::connect(local_loop(), addr);
|
||||
}
|
||||
stream.unwrap().write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
stream.unwrap().write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
|
||||
}
|
||||
|
||||
#[should_fail] #[test]
|
||||
|
|
@ -1028,7 +1028,7 @@ mod test {
|
|||
let w = TcpListener::bind(local_loop(), addr).unwrap();
|
||||
let mut w = w.listen().unwrap();
|
||||
chan.send(());
|
||||
w.accept();
|
||||
drop(w.accept().unwrap());
|
||||
});
|
||||
port.recv();
|
||||
let _w = TcpWatcher::connect(local_loop(), addr).unwrap();
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ mod tests {
|
|||
let p = PipeListener::bind(local_loop(), &path2.to_c_str()).unwrap();
|
||||
let mut p = p.listen().unwrap();
|
||||
chan.send(());
|
||||
p.accept();
|
||||
drop(p.accept().unwrap());
|
||||
});
|
||||
port.recv();
|
||||
let _c = PipeWatcher::connect(local_loop(), &path.to_c_str()).unwrap();
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ extern fn async_cb(handle: *uvll::uv_async_t, status: c_int) {
|
|||
loop {
|
||||
match state.consumer.pop() {
|
||||
mpsc::Data(Task(task)) => {
|
||||
task.wake().map(|t| t.reawaken(true));
|
||||
let _ = task.wake().map(|t| t.reawaken(true));
|
||||
}
|
||||
mpsc::Data(Increment) => unsafe {
|
||||
if state.refcnt == 0 {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ mod test {
|
|||
chan);
|
||||
|
||||
spawn(proc() {
|
||||
port.try_recv();
|
||||
let _ = port.recv_opt();
|
||||
});
|
||||
|
||||
// when we drop the SignalWatcher we're going to destroy the channel,
|
||||
|
|
|
|||
|
|
@ -138,11 +138,11 @@ extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) {
|
|||
|
||||
match timer.action.take_unwrap() {
|
||||
WakeTask(task) => {
|
||||
task.wake().map(|t| t.reawaken(true));
|
||||
let _ = task.wake().map(|t| t.reawaken(true));
|
||||
}
|
||||
SendOnce(chan) => { chan.try_send(()); }
|
||||
SendOnce(chan) => { let _ = chan.try_send(()); }
|
||||
SendMany(chan, id) => {
|
||||
chan.try_send(());
|
||||
let _ = chan.try_send(());
|
||||
|
||||
// Note that the above operation could have performed some form of
|
||||
// scheduling. This means that the timer may have decided to insert
|
||||
|
|
@ -246,7 +246,7 @@ mod test {
|
|||
let timer_port = timer.period(1000);
|
||||
|
||||
spawn(proc() {
|
||||
timer_port.recv_opt();
|
||||
let _ = timer_port.recv_opt();
|
||||
});
|
||||
|
||||
// when we drop the TimerWatcher we're going to destroy the channel,
|
||||
|
|
@ -260,10 +260,10 @@ mod test {
|
|||
let timer_port = timer.period(1000);
|
||||
|
||||
spawn(proc() {
|
||||
timer_port.recv_opt();
|
||||
let _ = timer_port.recv_opt();
|
||||
});
|
||||
|
||||
timer.oneshot(1);
|
||||
drop(timer.oneshot(1));
|
||||
}
|
||||
#[test]
|
||||
fn reset_doesnt_switch_tasks2() {
|
||||
|
|
@ -272,7 +272,7 @@ mod test {
|
|||
let timer_port = timer.period(1000);
|
||||
|
||||
spawn(proc() {
|
||||
timer_port.recv_opt();
|
||||
let _ = timer_port.recv_opt();
|
||||
});
|
||||
|
||||
timer.sleep(1);
|
||||
|
|
@ -299,7 +299,7 @@ mod test {
|
|||
#[test]
|
||||
fn receiver_goes_away_oneshot() {
|
||||
let mut timer1 = TimerWatcher::new(local_loop());
|
||||
timer1.oneshot(1);
|
||||
drop(timer1.oneshot(1));
|
||||
let mut timer2 = TimerWatcher::new(local_loop());
|
||||
// while sleeping, the prevous timer should fire and not have its
|
||||
// callback do something terrible.
|
||||
|
|
@ -309,7 +309,7 @@ mod test {
|
|||
#[test]
|
||||
fn receiver_goes_away_period() {
|
||||
let mut timer1 = TimerWatcher::new(local_loop());
|
||||
timer1.period(1);
|
||||
drop(timer1.period(1));
|
||||
let mut timer2 = TimerWatcher::new(local_loop());
|
||||
// while sleeping, the prevous timer should fire and not have its
|
||||
// callback do something terrible.
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ impl Drop for UvEventLoop {
|
|||
// after the loop has been closed because during the closing of the loop
|
||||
// the handle is required to be used apparently.
|
||||
let handle = self.uvio.handle_pool.get_ref().handle();
|
||||
self.uvio.handle_pool.take();
|
||||
drop(self.uvio.handle_pool.take());
|
||||
self.uvio.loop_.close();
|
||||
unsafe { uvll::free_handle(handle) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1252,7 +1252,7 @@ mod test {
|
|||
spawn(proc() {
|
||||
let _p = port;
|
||||
});
|
||||
task::try(proc() {
|
||||
let _ = task::try(proc() {
|
||||
chan.send(1);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,9 +163,10 @@ method of the signature:
|
|||
|
||||
```rust
|
||||
# use std;
|
||||
# mod fmt { pub type Result = (); }
|
||||
# struct T;
|
||||
# trait SomeName<T> {
|
||||
fn fmt(value: &T, f: &mut std::fmt::Formatter);
|
||||
fn fmt(value: &T, f: &mut std::fmt::Formatter) -> fmt::Result;
|
||||
# }
|
||||
```
|
||||
|
||||
|
|
@ -174,7 +175,14 @@ emit output into the `f.buf` stream. It is up to each format trait
|
|||
implementation to correctly adhere to the requested formatting parameters. The
|
||||
values of these parameters will be listed in the fields of the `Formatter`
|
||||
struct. In order to help with this, the `Formatter` struct also provides some
|
||||
helper methods. An example of implementing the formatting traits would look
|
||||
helper methods.
|
||||
|
||||
Additionally, the return value of this function is `fmt::Result` which is a
|
||||
typedef to `Result<(), IoError>` (also known as `IoError<()>`). Formatting
|
||||
implementations should ensure that they return errors from `write!` correctly
|
||||
(propagating errors upward).
|
||||
|
||||
An example of implementing the formatting traits would look
|
||||
like:
|
||||
|
||||
```rust
|
||||
|
|
@ -187,7 +195,7 @@ struct Vector2D {
|
|||
}
|
||||
|
||||
impl fmt::Show for Vector2D {
|
||||
fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) {
|
||||
fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// The `f.buf` value is of the type `&mut io::Writer`, which is what th
|
||||
// write! macro is expecting. Note that this formatting ignores the
|
||||
// various flags provided to format strings.
|
||||
|
|
@ -198,7 +206,7 @@ impl fmt::Show for Vector2D {
|
|||
// Different traits allow different forms of output of a type. The meaning of
|
||||
// this format is to print the magnitude of a vector.
|
||||
impl fmt::Binary for Vector2D {
|
||||
fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) {
|
||||
fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let magnitude = (obj.x * obj.x + obj.y * obj.y) as f64;
|
||||
let magnitude = magnitude.sqrt();
|
||||
|
||||
|
|
@ -207,7 +215,7 @@ impl fmt::Binary for Vector2D {
|
|||
// for details, and the function `pad` can be used to pad strings.
|
||||
let decimals = f.precision.unwrap_or(3);
|
||||
let string = f64::to_str_exact(magnitude, decimals);
|
||||
f.pad_integral(string.as_bytes(), "", true);
|
||||
f.pad_integral(string.as_bytes(), "", true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -242,6 +250,7 @@ strings and instead directly write the output. Under the hood, this function is
|
|||
actually invoking the `write` function defined in this module. Example usage is:
|
||||
|
||||
```rust
|
||||
# #[allow(unused_must_use)];
|
||||
use std::io;
|
||||
|
||||
let mut w = io::MemWriter::new();
|
||||
|
|
@ -468,16 +477,20 @@ will look like `"\\{"`.
|
|||
|
||||
*/
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
use prelude::*;
|
||||
|
||||
use cast;
|
||||
use char::Char;
|
||||
use container::Container;
|
||||
use io::MemWriter;
|
||||
use io;
|
||||
use str;
|
||||
use iter::{Iterator, range};
|
||||
use num::Signed;
|
||||
use option::{Option,Some,None};
|
||||
use repr;
|
||||
use result::{Ok, Err};
|
||||
use str::StrSlice;
|
||||
use str;
|
||||
use util;
|
||||
use vec::ImmutableVector;
|
||||
use vec;
|
||||
|
||||
// NOTE this is just because the `prelude::*` import above includes
|
||||
|
|
@ -485,22 +498,11 @@ use vec;
|
|||
#[cfg(stage0)]
|
||||
pub use Default = fmt::Show; // export required for `format!()` etc.
|
||||
|
||||
#[cfg(stage0)]
|
||||
use container::Container;
|
||||
#[cfg(stage0)]
|
||||
use iter::{Iterator, range};
|
||||
#[cfg(stage0)]
|
||||
use option::{Option,Some,None};
|
||||
#[cfg(stage0)]
|
||||
use vec::ImmutableVector;
|
||||
#[cfg(stage0)]
|
||||
use str::StrSlice;
|
||||
#[cfg(stage0)]
|
||||
use num::Signed;
|
||||
|
||||
pub mod parse;
|
||||
pub mod rt;
|
||||
|
||||
pub type Result = io::IoResult<()>;
|
||||
|
||||
/// A struct to represent both where to emit formatting strings to and how they
|
||||
/// should be formatted. A mutable version of this is passed to all formatting
|
||||
/// traits.
|
||||
|
|
@ -527,7 +529,7 @@ pub struct Formatter<'a> {
|
|||
/// compile time it is ensured that the function and the value have the correct
|
||||
/// types, and then this struct is used to canonicalize arguments to one type.
|
||||
pub struct Argument<'a> {
|
||||
priv formatter: extern "Rust" fn(&util::Void, &mut Formatter),
|
||||
priv formatter: extern "Rust" fn(&util::Void, &mut Formatter) -> Result,
|
||||
priv value: &'a util::Void,
|
||||
}
|
||||
|
||||
|
|
@ -561,50 +563,50 @@ pub struct Arguments<'a> {
|
|||
/// to this trait. There is not an explicit way of selecting this trait to be
|
||||
/// used for formatting, it is only if no other format is specified.
|
||||
#[allow(missing_doc)]
|
||||
pub trait Show { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait Show { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
|
||||
/// Format trait for the `b` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Bool { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait Bool { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `c` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Char { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait Char { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `i` and `d` characters
|
||||
#[allow(missing_doc)]
|
||||
pub trait Signed { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait Signed { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `u` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Unsigned { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait Unsigned { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `o` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Octal { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait Octal { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `b` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Binary { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait Binary { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `x` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait LowerHex { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait LowerHex { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `X` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait UpperHex { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait UpperHex { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `s` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait String { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait String { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `?` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Poly { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait Poly { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `p` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Pointer { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait Pointer { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `f` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait Float { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait Float { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `e` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait LowerExp { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait LowerExp { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
/// Format trait for the `E` character
|
||||
#[allow(missing_doc)]
|
||||
pub trait UpperExp { fn fmt(&Self, &mut Formatter); }
|
||||
pub trait UpperExp { fn fmt(&Self, &mut Formatter) -> Result; }
|
||||
|
||||
// FIXME #11938 - UFCS would make us able call the above methods
|
||||
// directly Show::show(x, fmt).
|
||||
|
|
@ -617,7 +619,7 @@ macro_rules! uniform_fn_call_workaround {
|
|||
($( $name: ident, $trait_: ident; )*) => {
|
||||
$(
|
||||
#[doc(hidden)]
|
||||
pub fn $name<T: $trait_>(x: &T, fmt: &mut Formatter) {
|
||||
pub fn $name<T: $trait_>(x: &T, fmt: &mut Formatter) -> Result {
|
||||
$trait_::fmt(x, fmt)
|
||||
}
|
||||
)*
|
||||
|
|
@ -653,21 +655,22 @@ uniform_fn_call_workaround! {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[allow(unused_must_use)];
|
||||
/// use std::fmt;
|
||||
/// use std::io;
|
||||
///
|
||||
/// let w = &mut io::stdout() as &mut io::Writer;
|
||||
/// format_args!(|args| { fmt::write(w, args) }, "Hello, {}!", "world");
|
||||
/// format_args!(|args| { fmt::write(w, args); }, "Hello, {}!", "world");
|
||||
/// ```
|
||||
pub fn write(output: &mut io::Writer, args: &Arguments) {
|
||||
pub fn write(output: &mut io::Writer, args: &Arguments) -> Result {
|
||||
unsafe { write_unsafe(output, args.fmt, args.args) }
|
||||
}
|
||||
|
||||
/// The `writeln` function takes the same arguments as `write`, except that it
|
||||
/// will also write a newline (`\n`) character at the end of the format string.
|
||||
pub fn writeln(output: &mut io::Writer, args: &Arguments) {
|
||||
unsafe { write_unsafe(output, args.fmt, args.args) }
|
||||
output.write(['\n' as u8]);
|
||||
pub fn writeln(output: &mut io::Writer, args: &Arguments) -> Result {
|
||||
let first = unsafe { write_unsafe(output, args.fmt, args.args) };
|
||||
first.and_then(|()| output.write(['\n' as u8]))
|
||||
}
|
||||
|
||||
/// The `write_unsafe` function takes an output stream, a precompiled format
|
||||
|
|
@ -692,7 +695,7 @@ pub fn writeln(output: &mut io::Writer, args: &Arguments) {
|
|||
/// format string.
|
||||
pub unsafe fn write_unsafe(output: &mut io::Writer,
|
||||
fmt: &[rt::Piece],
|
||||
args: &[Argument]) {
|
||||
args: &[Argument]) -> Result {
|
||||
let mut formatter = Formatter {
|
||||
flags: 0,
|
||||
width: None,
|
||||
|
|
@ -704,8 +707,9 @@ pub unsafe fn write_unsafe(output: &mut io::Writer,
|
|||
curarg: args.iter(),
|
||||
};
|
||||
for piece in fmt.iter() {
|
||||
formatter.run(piece, None);
|
||||
if_ok!(formatter.run(piece, None));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The format function takes a precompiled format string and a list of
|
||||
|
|
@ -752,7 +756,7 @@ pub fn format(args: &Arguments) -> ~str {
|
|||
/// format string.
|
||||
pub unsafe fn format_unsafe(fmt: &[rt::Piece], args: &[Argument]) -> ~str {
|
||||
let mut output = MemWriter::new();
|
||||
write_unsafe(&mut output as &mut io::Writer, fmt, args);
|
||||
write_unsafe(&mut output as &mut io::Writer, fmt, args).unwrap();
|
||||
return str::from_utf8_owned(output.unwrap()).unwrap();
|
||||
}
|
||||
|
||||
|
|
@ -762,10 +766,10 @@ impl<'a> Formatter<'a> {
|
|||
// at runtime. This consumes all of the compile-time statics generated by
|
||||
// the format! syntax extension.
|
||||
|
||||
fn run(&mut self, piece: &rt::Piece, cur: Option<&str>) {
|
||||
fn run(&mut self, piece: &rt::Piece, cur: Option<&str>) -> Result {
|
||||
match *piece {
|
||||
rt::String(s) => { self.buf.write(s.as_bytes()); }
|
||||
rt::CurrentArgument(()) => { self.buf.write(cur.unwrap().as_bytes()); }
|
||||
rt::String(s) => self.buf.write(s.as_bytes()),
|
||||
rt::CurrentArgument(()) => self.buf.write(cur.unwrap().as_bytes()),
|
||||
rt::Argument(ref arg) => {
|
||||
// Fill in the format parameters into the formatter
|
||||
self.fill = arg.format.fill;
|
||||
|
|
@ -782,8 +786,8 @@ impl<'a> Formatter<'a> {
|
|||
|
||||
// Then actually do some printing
|
||||
match arg.method {
|
||||
None => { (value.formatter)(value.value, self); }
|
||||
Some(ref method) => { self.execute(*method, value); }
|
||||
None => (value.formatter)(value.value, self),
|
||||
Some(ref method) => self.execute(*method, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -804,7 +808,7 @@ impl<'a> Formatter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn execute(&mut self, method: &rt::Method, arg: Argument) {
|
||||
fn execute(&mut self, method: &rt::Method, arg: Argument) -> Result {
|
||||
match *method {
|
||||
// Pluralization is selection upon a numeric value specified as the
|
||||
// parameter.
|
||||
|
|
@ -847,7 +851,7 @@ impl<'a> Formatter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
self.runplural(value, *default);
|
||||
self.runplural(value, *default)
|
||||
}
|
||||
|
||||
// Select is just a matching against the string specified.
|
||||
|
|
@ -860,24 +864,26 @@ impl<'a> Formatter<'a> {
|
|||
for s in selectors.iter() {
|
||||
if s.selector == value {
|
||||
for piece in s.result.iter() {
|
||||
self.run(piece, Some(value));
|
||||
if_ok!(self.run(piece, Some(value)));
|
||||
}
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
for piece in default.iter() {
|
||||
self.run(piece, Some(value));
|
||||
if_ok!(self.run(piece, Some(value)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn runplural(&mut self, value: uint, pieces: &[rt::Piece]) {
|
||||
fn runplural(&mut self, value: uint, pieces: &[rt::Piece]) -> Result {
|
||||
::uint::to_str_bytes(value, 10, |buf| {
|
||||
let valuestr = str::from_utf8(buf).unwrap();
|
||||
for piece in pieces.iter() {
|
||||
self.run(piece, Some(valuestr));
|
||||
if_ok!(self.run(piece, Some(valuestr)));
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -899,7 +905,7 @@ impl<'a> Formatter<'a> {
|
|||
/// This function will correctly account for the flags provided as well as
|
||||
/// the minimum width. It will not take precision into account.
|
||||
pub fn pad_integral(&mut self, s: &[u8], alternate_prefix: &str,
|
||||
positive: bool) {
|
||||
positive: bool) -> Result {
|
||||
use fmt::parse::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad};
|
||||
|
||||
let mut actual_len = s.len();
|
||||
|
|
@ -916,32 +922,32 @@ impl<'a> Formatter<'a> {
|
|||
let sign = |this: &mut Formatter| {
|
||||
if !signprinted {
|
||||
if this.flags & 1 << (FlagSignPlus as uint) != 0 && positive {
|
||||
this.buf.write(['+' as u8]);
|
||||
if_ok!(this.buf.write(['+' as u8]));
|
||||
} else if !positive {
|
||||
this.buf.write(['-' as u8]);
|
||||
if_ok!(this.buf.write(['-' as u8]));
|
||||
}
|
||||
if this.flags & 1 << (FlagAlternate as uint) != 0 {
|
||||
this.buf.write(alternate_prefix.as_bytes());
|
||||
if_ok!(this.buf.write(alternate_prefix.as_bytes()));
|
||||
}
|
||||
signprinted = true;
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let emit = |this: &mut Formatter| {
|
||||
sign(this);
|
||||
this.buf.write(s);
|
||||
sign(this).and_then(|()| this.buf.write(s))
|
||||
};
|
||||
|
||||
match self.width {
|
||||
None => { emit(self) }
|
||||
Some(min) if actual_len >= min => { emit(self) }
|
||||
None => emit(self),
|
||||
Some(min) if actual_len >= min => emit(self),
|
||||
Some(min) => {
|
||||
if self.flags & 1 << (FlagSignAwareZeroPad as uint) != 0 {
|
||||
self.fill = '0';
|
||||
sign(self);
|
||||
if_ok!(sign(self));
|
||||
}
|
||||
self.with_padding(min - actual_len, parse::AlignRight, |me| {
|
||||
emit(me);
|
||||
emit(me)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -958,11 +964,10 @@ impl<'a> Formatter<'a> {
|
|||
/// is longer than this length
|
||||
///
|
||||
/// Notably this function ignored the `flag` parameters
|
||||
pub fn pad(&mut self, s: &str) {
|
||||
pub fn pad(&mut self, s: &str) -> Result {
|
||||
// Make sure there's a fast path up front
|
||||
if self.width.is_none() && self.precision.is_none() {
|
||||
self.buf.write(s.as_bytes());
|
||||
return
|
||||
return self.buf.write(s.as_bytes());
|
||||
}
|
||||
// The `precision` field can be interpreted as a `max-width` for the
|
||||
// string being formatted
|
||||
|
|
@ -974,8 +979,7 @@ impl<'a> Formatter<'a> {
|
|||
let char_len = s.char_len();
|
||||
if char_len >= max {
|
||||
let nchars = ::cmp::min(max, char_len);
|
||||
self.buf.write(s.slice_chars(0, nchars).as_bytes());
|
||||
return
|
||||
return self.buf.write(s.slice_chars(0, nchars).as_bytes());
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
|
|
@ -985,7 +989,7 @@ impl<'a> Formatter<'a> {
|
|||
match self.width {
|
||||
// If we're under the maximum length, and there's no minimum length
|
||||
// requirements, then we can just emit the string
|
||||
None => { self.buf.write(s.as_bytes()) }
|
||||
None => self.buf.write(s.as_bytes()),
|
||||
|
||||
// If we're under the maximum width, check if we're over the minimum
|
||||
// width, if so it's as easy as just emitting the string.
|
||||
|
|
@ -997,7 +1001,7 @@ impl<'a> Formatter<'a> {
|
|||
// up the minimum width with the specified string + some alignment.
|
||||
Some(width) => {
|
||||
self.with_padding(width - s.len(), parse::AlignLeft, |me| {
|
||||
me.buf.write(s.as_bytes());
|
||||
me.buf.write(s.as_bytes())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1006,29 +1010,30 @@ impl<'a> Formatter<'a> {
|
|||
fn with_padding(&mut self,
|
||||
padding: uint,
|
||||
default: parse::Alignment,
|
||||
f: |&mut Formatter|) {
|
||||
f: |&mut Formatter| -> Result) -> Result {
|
||||
let align = match self.align {
|
||||
parse::AlignUnknown => default,
|
||||
parse::AlignLeft | parse::AlignRight => self.align
|
||||
};
|
||||
if align == parse::AlignLeft {
|
||||
f(self);
|
||||
if_ok!(f(self));
|
||||
}
|
||||
let mut fill = [0u8, ..4];
|
||||
let len = self.fill.encode_utf8(fill);
|
||||
for _ in range(0, padding) {
|
||||
self.buf.write(fill.slice_to(len));
|
||||
if_ok!(self.buf.write(fill.slice_to(len)));
|
||||
}
|
||||
if align == parse::AlignRight {
|
||||
f(self);
|
||||
if_ok!(f(self));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// This is a function which calls are emitted to by the compiler itself to
|
||||
/// create the Argument structures that are passed into the `format` function.
|
||||
#[doc(hidden)] #[inline]
|
||||
pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter),
|
||||
pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result,
|
||||
t: &'a T) -> Argument<'a> {
|
||||
unsafe {
|
||||
Argument {
|
||||
|
|
@ -1055,41 +1060,41 @@ pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
|
|||
// Implementations of the core formatting traits
|
||||
|
||||
impl Bool for bool {
|
||||
fn fmt(b: &bool, f: &mut Formatter) {
|
||||
String::fmt(&(if *b {"true"} else {"false"}), f);
|
||||
fn fmt(b: &bool, f: &mut Formatter) -> Result {
|
||||
String::fmt(&(if *b {"true"} else {"false"}), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: str::Str> String for T {
|
||||
fn fmt(s: &T, f: &mut Formatter) {
|
||||
f.pad(s.as_slice());
|
||||
fn fmt(s: &T, f: &mut Formatter) -> Result {
|
||||
f.pad(s.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
impl Char for char {
|
||||
fn fmt(c: &char, f: &mut Formatter) {
|
||||
fn fmt(c: &char, f: &mut Formatter) -> Result {
|
||||
let mut utf8 = [0u8, ..4];
|
||||
let amt = c.encode_utf8(utf8);
|
||||
let s: &str = unsafe { cast::transmute(utf8.slice_to(amt)) };
|
||||
String::fmt(&s, f);
|
||||
String::fmt(&s, f)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! int_base(($ty:ident, $into:ident, $base:expr,
|
||||
$name:ident, $prefix:expr) => {
|
||||
impl $name for $ty {
|
||||
fn fmt(c: &$ty, f: &mut Formatter) {
|
||||
fn fmt(c: &$ty, f: &mut Formatter) -> Result {
|
||||
::$into::to_str_bytes(*c as $into, $base, |buf| {
|
||||
f.pad_integral(buf, $prefix, true);
|
||||
f.pad_integral(buf, $prefix, true)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
macro_rules! upper_hex(($ty:ident, $into:ident) => {
|
||||
impl UpperHex for $ty {
|
||||
fn fmt(c: &$ty, f: &mut Formatter) {
|
||||
fn fmt(c: &$ty, f: &mut Formatter) -> Result {
|
||||
::$into::to_str_bytes(*c as $into, 16, |buf| {
|
||||
upperhex(buf, f);
|
||||
upperhex(buf, f)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1097,7 +1102,7 @@ macro_rules! upper_hex(($ty:ident, $into:ident) => {
|
|||
// Not sure why, but this causes an "unresolved enum variant, struct or const"
|
||||
// when inlined into the above macro...
|
||||
#[doc(hidden)]
|
||||
pub fn upperhex(buf: &[u8], f: &mut Formatter) {
|
||||
pub fn upperhex(buf: &[u8], f: &mut Formatter) -> Result {
|
||||
let mut local = [0u8, ..16];
|
||||
for i in ::iter::range(0, buf.len()) {
|
||||
local[i] = match buf[i] as char {
|
||||
|
|
@ -1105,16 +1110,16 @@ pub fn upperhex(buf: &[u8], f: &mut Formatter) {
|
|||
c => c as u8,
|
||||
}
|
||||
}
|
||||
f.pad_integral(local.slice_to(buf.len()), "0x", true);
|
||||
f.pad_integral(local.slice_to(buf.len()), "0x", true)
|
||||
}
|
||||
|
||||
macro_rules! integer(($signed:ident, $unsigned:ident) => {
|
||||
// Signed is special because it actuall emits the negative sign,
|
||||
// nothing else should do that, however.
|
||||
impl Signed for $signed {
|
||||
fn fmt(c: &$signed, f: &mut Formatter) {
|
||||
fn fmt(c: &$signed, f: &mut Formatter) -> Result {
|
||||
::$unsigned::to_str_bytes(c.abs() as $unsigned, 10, |buf| {
|
||||
f.pad_integral(buf, "", *c >= 0);
|
||||
f.pad_integral(buf, "", *c >= 0)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1138,35 +1143,35 @@ integer!(i64, u64)
|
|||
|
||||
macro_rules! floating(($ty:ident) => {
|
||||
impl Float for $ty {
|
||||
fn fmt(f: &$ty, fmt: &mut Formatter) {
|
||||
fn fmt(f: &$ty, fmt: &mut Formatter) -> Result {
|
||||
// FIXME: this shouldn't perform an allocation
|
||||
let s = match fmt.precision {
|
||||
Some(i) => ::$ty::to_str_exact(f.abs(), i),
|
||||
None => ::$ty::to_str_digits(f.abs(), 6)
|
||||
};
|
||||
fmt.pad_integral(s.as_bytes(), "", *f >= 0.0);
|
||||
fmt.pad_integral(s.as_bytes(), "", *f >= 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl LowerExp for $ty {
|
||||
fn fmt(f: &$ty, fmt: &mut Formatter) {
|
||||
fn fmt(f: &$ty, fmt: &mut Formatter) -> Result {
|
||||
// FIXME: this shouldn't perform an allocation
|
||||
let s = match fmt.precision {
|
||||
Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, false),
|
||||
None => ::$ty::to_str_exp_digits(f.abs(), 6, false)
|
||||
};
|
||||
fmt.pad_integral(s.as_bytes(), "", *f >= 0.0);
|
||||
fmt.pad_integral(s.as_bytes(), "", *f >= 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl UpperExp for $ty {
|
||||
fn fmt(f: &$ty, fmt: &mut Formatter) {
|
||||
fn fmt(f: &$ty, fmt: &mut Formatter) -> Result {
|
||||
// FIXME: this shouldn't perform an allocation
|
||||
let s = match fmt.precision {
|
||||
Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, true),
|
||||
None => ::$ty::to_str_exp_digits(f.abs(), 6, true)
|
||||
};
|
||||
fmt.pad_integral(s.as_bytes(), "", *f >= 0.0);
|
||||
fmt.pad_integral(s.as_bytes(), "", *f >= 0.0)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -1174,39 +1179,41 @@ floating!(f32)
|
|||
floating!(f64)
|
||||
|
||||
impl<T> Poly for T {
|
||||
fn fmt(t: &T, f: &mut Formatter) {
|
||||
fn fmt(t: &T, f: &mut Formatter) -> Result {
|
||||
match (f.width, f.precision) {
|
||||
(None, None) => {
|
||||
repr::write_repr(f.buf, t);
|
||||
repr::write_repr(f.buf, t)
|
||||
}
|
||||
|
||||
// If we have a specified width for formatting, then we have to make
|
||||
// this allocation of a new string
|
||||
_ => {
|
||||
let s = repr::repr_to_str(t);
|
||||
f.pad(s);
|
||||
f.pad(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Pointer for *T {
|
||||
fn fmt(t: &*T, f: &mut Formatter) {
|
||||
fn fmt(t: &*T, f: &mut Formatter) -> Result {
|
||||
f.flags |= 1 << (parse::FlagAlternate as uint);
|
||||
::uint::to_str_bytes(*t as uint, 16, |buf| {
|
||||
f.pad_integral(buf, "0x", true);
|
||||
f.pad_integral(buf, "0x", true)
|
||||
})
|
||||
}
|
||||
}
|
||||
impl<T> Pointer for *mut T {
|
||||
fn fmt(t: &*mut T, f: &mut Formatter) { Pointer::fmt(&(*t as *T), f) }
|
||||
fn fmt(t: &*mut T, f: &mut Formatter) -> Result {
|
||||
Pointer::fmt(&(*t as *T), f)
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of Show for various core types
|
||||
|
||||
macro_rules! delegate(($ty:ty to $other:ident) => {
|
||||
impl<'a> Show for $ty {
|
||||
fn fmt(me: &$ty, f: &mut Formatter) {
|
||||
fn fmt(me: &$ty, f: &mut Formatter) -> Result {
|
||||
$other::fmt(me, f)
|
||||
}
|
||||
}
|
||||
|
|
@ -1229,10 +1236,10 @@ delegate!(f32 to Float)
|
|||
delegate!(f64 to Float)
|
||||
|
||||
impl<T> Show for *T {
|
||||
fn fmt(me: &*T, f: &mut Formatter) { Pointer::fmt(me, f) }
|
||||
fn fmt(me: &*T, f: &mut Formatter) -> Result { Pointer::fmt(me, f) }
|
||||
}
|
||||
impl<T> Show for *mut T {
|
||||
fn fmt(me: &*mut T, f: &mut Formatter) { Pointer::fmt(me, f) }
|
||||
fn fmt(me: &*mut T, f: &mut Formatter) -> Result { Pointer::fmt(me, f) }
|
||||
}
|
||||
|
||||
// If you expected tests to be here, look instead at the run-pass/ifmt.rs test,
|
||||
|
|
|
|||
|
|
@ -27,13 +27,14 @@
|
|||
#[allow(missing_doc)];
|
||||
|
||||
use container::Container;
|
||||
use io::{Writer, IoResult};
|
||||
use iter::Iterator;
|
||||
use num::ToStrRadix;
|
||||
use option::{Some, None};
|
||||
use io::Writer;
|
||||
use result::Ok;
|
||||
use str::OwnedStr;
|
||||
use to_bytes::IterBytes;
|
||||
use vec::ImmutableVector;
|
||||
use num::ToStrRadix;
|
||||
|
||||
// Alias `SipState` to `State`.
|
||||
pub use State = hash::SipState;
|
||||
|
|
@ -164,7 +165,7 @@ macro_rules! compress (
|
|||
impl Writer for SipState {
|
||||
// Methods for io::writer
|
||||
#[inline]
|
||||
fn write(&mut self, msg: &[u8]) {
|
||||
fn write(&mut self, msg: &[u8]) -> IoResult<()> {
|
||||
let length = msg.len();
|
||||
self.length += length;
|
||||
|
||||
|
|
@ -180,7 +181,7 @@ impl Writer for SipState {
|
|||
t += 1;
|
||||
}
|
||||
self.ntail += length;
|
||||
return;
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
let mut t = 0;
|
||||
|
|
@ -222,17 +223,14 @@ impl Writer for SipState {
|
|||
t += 1
|
||||
}
|
||||
self.ntail = left;
|
||||
}
|
||||
|
||||
fn flush(&mut self) {
|
||||
// No-op
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Streaming for SipState {
|
||||
#[inline]
|
||||
fn input(&mut self, buf: &[u8]) {
|
||||
self.write(buf);
|
||||
self.write(buf).unwrap();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -11,10 +11,11 @@
|
|||
//! Buffering wrappers for I/O traits
|
||||
|
||||
use container::Container;
|
||||
use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE};
|
||||
use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
|
||||
use iter::ExactSize;
|
||||
use num;
|
||||
use option::{Option, Some, None};
|
||||
use option::{Some, None};
|
||||
use result::{Ok, Err};
|
||||
use vec::{OwnedVector, ImmutableVector, MutableVector};
|
||||
use vec;
|
||||
|
||||
|
|
@ -30,14 +31,13 @@ use vec;
|
|||
/// ```rust
|
||||
/// use std::io::{BufferedReader, File};
|
||||
///
|
||||
/// # let _g = ::std::io::ignore_io_error();
|
||||
/// let file = File::open(&Path::new("message.txt"));
|
||||
/// let mut reader = BufferedReader::new(file);
|
||||
///
|
||||
/// let mut buf = [0, ..100];
|
||||
/// match reader.read(buf) {
|
||||
/// Some(nread) => println!("Read {} bytes", nread),
|
||||
/// None => println!("At the end of the file!")
|
||||
/// Ok(nread) => println!("Read {} bytes", nread),
|
||||
/// Err(e) => println!("error reading: {}", e)
|
||||
/// }
|
||||
/// ```
|
||||
pub struct BufferedReader<R> {
|
||||
|
|
@ -86,17 +86,12 @@ impl<R: Reader> BufferedReader<R> {
|
|||
}
|
||||
|
||||
impl<R: Reader> Buffer for BufferedReader<R> {
|
||||
fn fill<'a>(&'a mut self) -> &'a [u8] {
|
||||
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
||||
if self.pos == self.cap {
|
||||
match self.inner.read(self.buf) {
|
||||
Some(cap) => {
|
||||
self.pos = 0;
|
||||
self.cap = cap;
|
||||
}
|
||||
None => { self.eof = true; }
|
||||
}
|
||||
self.cap = if_ok!(self.inner.read(self.buf));
|
||||
self.pos = 0;
|
||||
}
|
||||
return self.buf.slice(self.pos, self.cap);
|
||||
Ok(self.buf.slice(self.pos, self.cap))
|
||||
}
|
||||
|
||||
fn consume(&mut self, amt: uint) {
|
||||
|
|
@ -106,18 +101,15 @@ impl<R: Reader> Buffer for BufferedReader<R> {
|
|||
}
|
||||
|
||||
impl<R: Reader> Reader for BufferedReader<R> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
let nread = {
|
||||
let available = self.fill();
|
||||
let available = if_ok!(self.fill());
|
||||
let nread = num::min(available.len(), buf.len());
|
||||
vec::bytes::copy_memory(buf, available.slice_to(nread));
|
||||
nread
|
||||
};
|
||||
self.pos += nread;
|
||||
if nread == 0 && buf.len() != 0 && self.eof {
|
||||
return None;
|
||||
}
|
||||
Some(nread)
|
||||
Ok(nread)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -128,9 +120,9 @@ impl<R: Reader> Reader for BufferedReader<R> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[allow(unused_must_use)];
|
||||
/// use std::io::{BufferedWriter, File};
|
||||
///
|
||||
/// # let _g = ::std::io::ignore_io_error();
|
||||
/// let file = File::open(&Path::new("message.txt"));
|
||||
/// let mut writer = BufferedWriter::new(file);
|
||||
///
|
||||
|
|
@ -161,10 +153,13 @@ impl<W: Writer> BufferedWriter<W> {
|
|||
BufferedWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
|
||||
}
|
||||
|
||||
fn flush_buf(&mut self) {
|
||||
fn flush_buf(&mut self) -> IoResult<()> {
|
||||
if self.pos != 0 {
|
||||
self.inner.write(self.buf.slice_to(self.pos));
|
||||
let ret = self.inner.write(self.buf.slice_to(self.pos));
|
||||
self.pos = 0;
|
||||
ret
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,29 +173,30 @@ impl<W: Writer> BufferedWriter<W> {
|
|||
///
|
||||
/// The buffer is flushed before returning the writer.
|
||||
pub fn unwrap(mut self) -> W {
|
||||
self.flush_buf();
|
||||
// FIXME: is failing the right thing to do if flushing fails?
|
||||
self.flush_buf().unwrap();
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Writer> Writer for BufferedWriter<W> {
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
if self.pos + buf.len() > self.buf.len() {
|
||||
self.flush_buf();
|
||||
if_ok!(self.flush_buf());
|
||||
}
|
||||
|
||||
if buf.len() > self.buf.len() {
|
||||
self.inner.write(buf);
|
||||
self.inner.write(buf)
|
||||
} else {
|
||||
let dst = self.buf.mut_slice_from(self.pos);
|
||||
vec::bytes::copy_memory(dst, buf);
|
||||
self.pos += buf.len();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) {
|
||||
self.flush_buf();
|
||||
self.inner.flush();
|
||||
fn flush(&mut self) -> IoResult<()> {
|
||||
self.flush_buf().and_then(|()| self.inner.flush())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -234,18 +230,19 @@ impl<W: Writer> LineBufferedWriter<W> {
|
|||
}
|
||||
|
||||
impl<W: Writer> Writer for LineBufferedWriter<W> {
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
match buf.iter().rposition(|&b| b == '\n' as u8) {
|
||||
Some(i) => {
|
||||
self.inner.write(buf.slice_to(i + 1));
|
||||
self.inner.flush();
|
||||
self.inner.write(buf.slice_from(i + 1));
|
||||
if_ok!(self.inner.write(buf.slice_to(i + 1)));
|
||||
if_ok!(self.inner.flush());
|
||||
if_ok!(self.inner.write(buf.slice_from(i + 1)));
|
||||
Ok(())
|
||||
}
|
||||
None => self.inner.write(buf),
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) { self.inner.flush() }
|
||||
fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
|
||||
}
|
||||
|
||||
struct InternalBufferedWriter<W>(BufferedWriter<W>);
|
||||
|
|
@ -258,7 +255,9 @@ impl<W> InternalBufferedWriter<W> {
|
|||
}
|
||||
|
||||
impl<W: Reader> Reader for InternalBufferedWriter<W> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.get_mut_ref().inner.read(buf) }
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
self.get_mut_ref().inner.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps a Stream and buffers input and output to and from it
|
||||
|
|
@ -268,9 +267,9 @@ impl<W: Reader> Reader for InternalBufferedWriter<W> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[allow(unused_must_use)];
|
||||
/// use std::io::{BufferedStream, File};
|
||||
///
|
||||
/// # let _g = ::std::io::ignore_io_error();
|
||||
/// let file = File::open(&Path::new("message.txt"));
|
||||
/// let mut stream = BufferedStream::new(file);
|
||||
///
|
||||
|
|
@ -279,8 +278,8 @@ impl<W: Reader> Reader for InternalBufferedWriter<W> {
|
|||
///
|
||||
/// let mut buf = [0, ..100];
|
||||
/// match stream.read(buf) {
|
||||
/// Some(nread) => println!("Read {} bytes", nread),
|
||||
/// None => println!("At the end of the stream!")
|
||||
/// Ok(nread) => println!("Read {} bytes", nread),
|
||||
/// Err(e) => println!("error reading: {}", e)
|
||||
/// }
|
||||
/// ```
|
||||
pub struct BufferedStream<S> {
|
||||
|
|
@ -326,17 +325,23 @@ impl<S: Stream> BufferedStream<S> {
|
|||
}
|
||||
|
||||
impl<S: Stream> Buffer for BufferedStream<S> {
|
||||
fn fill<'a>(&'a mut self) -> &'a [u8] { self.inner.fill() }
|
||||
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill() }
|
||||
fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
|
||||
}
|
||||
|
||||
impl<S: Stream> Reader for BufferedStream<S> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.inner.read(buf) }
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Stream> Writer for BufferedStream<S> {
|
||||
fn write(&mut self, buf: &[u8]) { self.inner.inner.get_mut_ref().write(buf) }
|
||||
fn flush(&mut self) { self.inner.inner.get_mut_ref().flush() }
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
self.inner.inner.get_mut_ref().write(buf)
|
||||
}
|
||||
fn flush(&mut self) -> IoResult<()> {
|
||||
self.inner.inner.get_mut_ref().flush()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -354,13 +359,13 @@ mod test {
|
|||
pub struct NullStream;
|
||||
|
||||
impl Reader for NullStream {
|
||||
fn read(&mut self, _: &mut [u8]) -> Option<uint> {
|
||||
None
|
||||
fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
|
||||
Err(io::standard_error(io::EndOfFile))
|
||||
}
|
||||
}
|
||||
|
||||
impl Writer for NullStream {
|
||||
fn write(&mut self, _: &[u8]) { }
|
||||
fn write(&mut self, _: &[u8]) -> io::IoResult<()> { Ok(()) }
|
||||
}
|
||||
|
||||
/// A dummy reader intended at testing short-reads propagation.
|
||||
|
|
@ -369,8 +374,11 @@ mod test {
|
|||
}
|
||||
|
||||
impl Reader for ShortReader {
|
||||
fn read(&mut self, _: &mut [u8]) -> Option<uint> {
|
||||
self.lengths.shift()
|
||||
fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
|
||||
match self.lengths.shift() {
|
||||
Some(i) => Ok(i),
|
||||
None => Err(io::standard_error(io::EndOfFile))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -381,24 +389,24 @@ mod test {
|
|||
|
||||
let mut buf = [0, 0, 0];
|
||||
let nread = reader.read(buf);
|
||||
assert_eq!(Some(2), nread);
|
||||
assert_eq!(Ok(2), nread);
|
||||
assert_eq!([0, 1, 0], buf);
|
||||
|
||||
let mut buf = [0];
|
||||
let nread = reader.read(buf);
|
||||
assert_eq!(Some(1), nread);
|
||||
assert_eq!(Ok(1), nread);
|
||||
assert_eq!([2], buf);
|
||||
|
||||
let mut buf = [0, 0, 0];
|
||||
let nread = reader.read(buf);
|
||||
assert_eq!(Some(1), nread);
|
||||
assert_eq!(Ok(1), nread);
|
||||
assert_eq!([3, 0, 0], buf);
|
||||
|
||||
let nread = reader.read(buf);
|
||||
assert_eq!(Some(1), nread);
|
||||
assert_eq!(Ok(1), nread);
|
||||
assert_eq!([4, 0, 0], buf);
|
||||
|
||||
assert_eq!(None, reader.read(buf));
|
||||
assert!(reader.read(buf).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -406,35 +414,35 @@ mod test {
|
|||
let inner = MemWriter::new();
|
||||
let mut writer = BufferedWriter::with_capacity(2, inner);
|
||||
|
||||
writer.write([0, 1]);
|
||||
writer.write([0, 1]).unwrap();
|
||||
assert_eq!([], writer.get_ref().get_ref());
|
||||
|
||||
writer.write([2]);
|
||||
writer.write([2]).unwrap();
|
||||
assert_eq!([0, 1], writer.get_ref().get_ref());
|
||||
|
||||
writer.write([3]);
|
||||
writer.write([3]).unwrap();
|
||||
assert_eq!([0, 1], writer.get_ref().get_ref());
|
||||
|
||||
writer.flush();
|
||||
writer.flush().unwrap();
|
||||
assert_eq!([0, 1, 2, 3], writer.get_ref().get_ref());
|
||||
|
||||
writer.write([4]);
|
||||
writer.write([5]);
|
||||
writer.write([4]).unwrap();
|
||||
writer.write([5]).unwrap();
|
||||
assert_eq!([0, 1, 2, 3], writer.get_ref().get_ref());
|
||||
|
||||
writer.write([6]);
|
||||
writer.write([6]).unwrap();
|
||||
assert_eq!([0, 1, 2, 3, 4, 5],
|
||||
writer.get_ref().get_ref());
|
||||
|
||||
writer.write([7, 8]);
|
||||
writer.write([7, 8]).unwrap();
|
||||
assert_eq!([0, 1, 2, 3, 4, 5, 6],
|
||||
writer.get_ref().get_ref());
|
||||
|
||||
writer.write([9, 10, 11]);
|
||||
writer.write([9, 10, 11]).unwrap();
|
||||
assert_eq!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
|
||||
writer.get_ref().get_ref());
|
||||
|
||||
writer.flush();
|
||||
writer.flush().unwrap();
|
||||
assert_eq!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
|
||||
writer.get_ref().get_ref());
|
||||
}
|
||||
|
|
@ -442,7 +450,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_buffered_writer_inner_flushes() {
|
||||
let mut w = BufferedWriter::with_capacity(3, MemWriter::new());
|
||||
w.write([0, 1]);
|
||||
w.write([0, 1]).unwrap();
|
||||
assert_eq!([], w.get_ref().get_ref());
|
||||
let w = w.unwrap();
|
||||
assert_eq!([0, 1], w.get_ref());
|
||||
|
|
@ -455,47 +463,49 @@ mod test {
|
|||
struct S;
|
||||
|
||||
impl io::Writer for S {
|
||||
fn write(&mut self, _: &[u8]) {}
|
||||
fn write(&mut self, _: &[u8]) -> io::IoResult<()> { Ok(()) }
|
||||
}
|
||||
|
||||
impl io::Reader for S {
|
||||
fn read(&mut self, _: &mut [u8]) -> Option<uint> { None }
|
||||
fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
|
||||
Err(io::standard_error(io::EndOfFile))
|
||||
}
|
||||
}
|
||||
|
||||
let mut stream = BufferedStream::new(S);
|
||||
let mut buf = [];
|
||||
stream.read(buf);
|
||||
stream.write(buf);
|
||||
stream.flush();
|
||||
assert!(stream.read(buf).is_err());
|
||||
stream.write(buf).unwrap();
|
||||
stream.flush().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_until() {
|
||||
let inner = MemReader::new(~[0, 1, 2, 1, 0]);
|
||||
let mut reader = BufferedReader::with_capacity(2, inner);
|
||||
assert_eq!(reader.read_until(0), Some(~[0]));
|
||||
assert_eq!(reader.read_until(2), Some(~[1, 2]));
|
||||
assert_eq!(reader.read_until(1), Some(~[1]));
|
||||
assert_eq!(reader.read_until(8), Some(~[0]));
|
||||
assert_eq!(reader.read_until(9), None);
|
||||
assert_eq!(reader.read_until(0), Ok(~[0]));
|
||||
assert_eq!(reader.read_until(2), Ok(~[1, 2]));
|
||||
assert_eq!(reader.read_until(1), Ok(~[1]));
|
||||
assert_eq!(reader.read_until(8), Ok(~[0]));
|
||||
assert!(reader.read_until(9).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_line_buffer() {
|
||||
let mut writer = LineBufferedWriter::new(MemWriter::new());
|
||||
writer.write([0]);
|
||||
writer.write([0]).unwrap();
|
||||
assert_eq!(writer.get_ref().get_ref(), []);
|
||||
writer.write([1]);
|
||||
writer.write([1]).unwrap();
|
||||
assert_eq!(writer.get_ref().get_ref(), []);
|
||||
writer.flush();
|
||||
writer.flush().unwrap();
|
||||
assert_eq!(writer.get_ref().get_ref(), [0, 1]);
|
||||
writer.write([0, '\n' as u8, 1, '\n' as u8, 2]);
|
||||
writer.write([0, '\n' as u8, 1, '\n' as u8, 2]).unwrap();
|
||||
assert_eq!(writer.get_ref().get_ref(),
|
||||
[0, 1, 0, '\n' as u8, 1, '\n' as u8]);
|
||||
writer.flush();
|
||||
writer.flush().unwrap();
|
||||
assert_eq!(writer.get_ref().get_ref(),
|
||||
[0, 1, 0, '\n' as u8, 1, '\n' as u8, 2]);
|
||||
writer.write([3, '\n' as u8]);
|
||||
writer.write([3, '\n' as u8]).unwrap();
|
||||
assert_eq!(writer.get_ref().get_ref(),
|
||||
[0, 1, 0, '\n' as u8, 1, '\n' as u8, 2, 3, '\n' as u8]);
|
||||
}
|
||||
|
|
@ -504,10 +514,10 @@ mod test {
|
|||
fn test_read_line() {
|
||||
let in_buf = MemReader::new(bytes!("a\nb\nc").to_owned());
|
||||
let mut reader = BufferedReader::with_capacity(2, in_buf);
|
||||
assert_eq!(reader.read_line(), Some(~"a\n"));
|
||||
assert_eq!(reader.read_line(), Some(~"b\n"));
|
||||
assert_eq!(reader.read_line(), Some(~"c"));
|
||||
assert_eq!(reader.read_line(), None);
|
||||
assert_eq!(reader.read_line(), Ok(~"a\n"));
|
||||
assert_eq!(reader.read_line(), Ok(~"b\n"));
|
||||
assert_eq!(reader.read_line(), Ok(~"c"));
|
||||
assert!(reader.read_line().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -526,20 +536,20 @@ mod test {
|
|||
let inner = ShortReader{lengths: ~[0, 1, 2, 0, 1, 0]};
|
||||
let mut reader = BufferedReader::new(inner);
|
||||
let mut buf = [0, 0];
|
||||
assert_eq!(reader.read(buf), Some(0));
|
||||
assert_eq!(reader.read(buf), Some(1));
|
||||
assert_eq!(reader.read(buf), Some(2));
|
||||
assert_eq!(reader.read(buf), Some(0));
|
||||
assert_eq!(reader.read(buf), Some(1));
|
||||
assert_eq!(reader.read(buf), Some(0));
|
||||
assert_eq!(reader.read(buf), None);
|
||||
assert_eq!(reader.read(buf), Ok(0));
|
||||
assert_eq!(reader.read(buf), Ok(1));
|
||||
assert_eq!(reader.read(buf), Ok(2));
|
||||
assert_eq!(reader.read(buf), Ok(0));
|
||||
assert_eq!(reader.read(buf), Ok(1));
|
||||
assert_eq!(reader.read(buf), Ok(0));
|
||||
assert!(reader.read(buf).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_char_buffered() {
|
||||
let buf = [195u8, 159u8];
|
||||
let mut reader = BufferedReader::with_capacity(1, BufReader::new(buf));
|
||||
assert_eq!(reader.read_char(), Some('ß'));
|
||||
assert_eq!(reader.read_char(), Ok('ß'));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use comm::{Port, Chan};
|
|||
use cmp;
|
||||
use io;
|
||||
use option::{None, Option, Some};
|
||||
use super::{Reader, Writer};
|
||||
use super::{Reader, Writer, IoResult};
|
||||
use vec::{bytes, CloneableVector, MutableVector, ImmutableVector};
|
||||
|
||||
/// Allows reading from a port.
|
||||
|
|
@ -49,7 +49,7 @@ impl PortReader {
|
|||
}
|
||||
|
||||
impl Reader for PortReader {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
let mut num_read = 0;
|
||||
loop {
|
||||
match self.buf {
|
||||
|
|
@ -71,10 +71,9 @@ impl Reader for PortReader {
|
|||
self.closed = self.buf.is_none();
|
||||
}
|
||||
if self.closed && num_read == 0 {
|
||||
io::io_error::cond.raise(io::standard_error(io::EndOfFile));
|
||||
None
|
||||
Err(io::standard_error(io::EndOfFile))
|
||||
} else {
|
||||
Some(num_read)
|
||||
Ok(num_read)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -98,13 +97,15 @@ impl ChanWriter {
|
|||
}
|
||||
|
||||
impl Writer for ChanWriter {
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
if !self.chan.try_send(buf.to_owned()) {
|
||||
io::io_error::cond.raise(io::IoError {
|
||||
Err(io::IoError {
|
||||
kind: io::BrokenPipe,
|
||||
desc: "Pipe closed",
|
||||
detail: None
|
||||
});
|
||||
})
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -132,36 +133,28 @@ mod test {
|
|||
let mut buf = ~[0u8, ..3];
|
||||
|
||||
|
||||
assert_eq!(Some(0), reader.read([]));
|
||||
assert_eq!(Ok(0), reader.read([]));
|
||||
|
||||
assert_eq!(Some(3), reader.read(buf));
|
||||
assert_eq!(Ok(3), reader.read(buf));
|
||||
assert_eq!(~[1,2,3], buf);
|
||||
|
||||
assert_eq!(Some(3), reader.read(buf));
|
||||
assert_eq!(Ok(3), reader.read(buf));
|
||||
assert_eq!(~[4,5,6], buf);
|
||||
|
||||
assert_eq!(Some(2), reader.read(buf));
|
||||
assert_eq!(Ok(2), reader.read(buf));
|
||||
assert_eq!(~[7,8,6], buf);
|
||||
|
||||
let mut err = None;
|
||||
let result = io::io_error::cond.trap(|io::standard_error(k, _, _)| {
|
||||
err = Some(k)
|
||||
}).inside(|| {
|
||||
reader.read(buf)
|
||||
});
|
||||
assert_eq!(Some(io::EndOfFile), err);
|
||||
assert_eq!(None, result);
|
||||
match reader.read(buf) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, io::EndOfFile),
|
||||
}
|
||||
assert_eq!(~[7,8,6], buf);
|
||||
|
||||
// Ensure it continues to fail in the same way.
|
||||
err = None;
|
||||
let result = io::io_error::cond.trap(|io::standard_error(k, _, _)| {
|
||||
err = Some(k)
|
||||
}).inside(|| {
|
||||
reader.read(buf)
|
||||
});
|
||||
assert_eq!(Some(io::EndOfFile), err);
|
||||
assert_eq!(None, result);
|
||||
match reader.read(buf) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, io::EndOfFile),
|
||||
}
|
||||
assert_eq!(~[7,8,6], buf);
|
||||
}
|
||||
|
||||
|
|
@ -169,18 +162,15 @@ mod test {
|
|||
fn test_chan_writer() {
|
||||
let (port, chan) = Chan::new();
|
||||
let mut writer = ChanWriter::new(chan);
|
||||
writer.write_be_u32(42);
|
||||
writer.write_be_u32(42).unwrap();
|
||||
|
||||
let wanted = ~[0u8, 0u8, 0u8, 42u8];
|
||||
let got = task::try(proc() { port.recv() }).unwrap();
|
||||
assert_eq!(wanted, got);
|
||||
|
||||
let mut err = None;
|
||||
io::io_error::cond.trap(|io::IoError { kind, .. } | {
|
||||
err = Some(kind)
|
||||
}).inside(|| {
|
||||
writer.write_u8(1)
|
||||
});
|
||||
assert_eq!(Some(io::BrokenPipe), err);
|
||||
match writer.write_u8(1) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, io::BrokenPipe),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ impl<'r, R: Reader> Bytes<'r, R> {
|
|||
impl<'r, R: Reader> Iterator<u8> for Bytes<'r, R> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<u8> {
|
||||
self.reader.read_byte()
|
||||
self.reader.read_byte().ok()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -125,23 +125,22 @@ pub fn u64_from_be_bytes(data: &[u8],
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use unstable::finally::Finally;
|
||||
use prelude::*;
|
||||
use io;
|
||||
use io::{MemReader, MemWriter};
|
||||
use io::{io_error, placeholder_error};
|
||||
|
||||
struct InitialZeroByteReader {
|
||||
count: int,
|
||||
}
|
||||
|
||||
impl Reader for InitialZeroByteReader {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
||||
if self.count == 0 {
|
||||
self.count = 1;
|
||||
Some(0)
|
||||
Ok(0)
|
||||
} else {
|
||||
buf[0] = 10;
|
||||
Some(1)
|
||||
Ok(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -149,17 +148,16 @@ mod test {
|
|||
struct EofReader;
|
||||
|
||||
impl Reader for EofReader {
|
||||
fn read(&mut self, _: &mut [u8]) -> Option<uint> {
|
||||
None
|
||||
fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
|
||||
Err(io::standard_error(io::EndOfFile))
|
||||
}
|
||||
}
|
||||
|
||||
struct ErroringReader;
|
||||
|
||||
impl Reader for ErroringReader {
|
||||
fn read(&mut self, _: &mut [u8]) -> Option<uint> {
|
||||
io_error::cond.raise(placeholder_error());
|
||||
None
|
||||
fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
|
||||
Err(io::standard_error(io::InvalidInput))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -168,16 +166,16 @@ mod test {
|
|||
}
|
||||
|
||||
impl Reader for PartialReader {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
||||
if self.count == 0 {
|
||||
self.count = 1;
|
||||
buf[0] = 10;
|
||||
buf[1] = 11;
|
||||
Some(2)
|
||||
Ok(2)
|
||||
} else {
|
||||
buf[0] = 12;
|
||||
buf[1] = 13;
|
||||
Some(2)
|
||||
Ok(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -187,14 +185,13 @@ mod test {
|
|||
}
|
||||
|
||||
impl Reader for ErroringLaterReader {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
||||
if self.count == 0 {
|
||||
self.count = 1;
|
||||
buf[0] = 10;
|
||||
Some(1)
|
||||
Ok(1)
|
||||
} else {
|
||||
io_error::cond.raise(placeholder_error());
|
||||
None
|
||||
Err(io::standard_error(io::InvalidInput))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -204,19 +201,19 @@ mod test {
|
|||
}
|
||||
|
||||
impl Reader for ThreeChunkReader {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
||||
if self.count == 0 {
|
||||
self.count = 1;
|
||||
buf[0] = 10;
|
||||
buf[1] = 11;
|
||||
Some(2)
|
||||
Ok(2)
|
||||
} else if self.count == 1 {
|
||||
self.count = 2;
|
||||
buf[0] = 12;
|
||||
buf[1] = 13;
|
||||
Some(2)
|
||||
Ok(2)
|
||||
} else {
|
||||
None
|
||||
Err(io::standard_error(io::EndOfFile))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -225,7 +222,7 @@ mod test {
|
|||
fn read_byte() {
|
||||
let mut reader = MemReader::new(~[10]);
|
||||
let byte = reader.read_byte();
|
||||
assert!(byte == Some(10));
|
||||
assert!(byte == Ok(10));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -234,24 +231,21 @@ mod test {
|
|||
count: 0,
|
||||
};
|
||||
let byte = reader.read_byte();
|
||||
assert!(byte == Some(10));
|
||||
assert!(byte == Ok(10));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_byte_eof() {
|
||||
let mut reader = EofReader;
|
||||
let byte = reader.read_byte();
|
||||
assert!(byte == None);
|
||||
assert!(byte.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_byte_error() {
|
||||
let mut reader = ErroringReader;
|
||||
io_error::cond.trap(|_| {
|
||||
}).inside(|| {
|
||||
let byte = reader.read_byte();
|
||||
assert!(byte == None);
|
||||
});
|
||||
let byte = reader.read_byte();
|
||||
assert!(byte.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -267,23 +261,21 @@ mod test {
|
|||
fn bytes_eof() {
|
||||
let mut reader = EofReader;
|
||||
let byte = reader.bytes().next();
|
||||
assert!(byte == None);
|
||||
assert!(byte.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bytes_error() {
|
||||
let mut reader = ErroringReader;
|
||||
let mut it = reader.bytes();
|
||||
io_error::cond.trap(|_| ()).inside(|| {
|
||||
let byte = it.next();
|
||||
assert!(byte == None);
|
||||
})
|
||||
let byte = it.next();
|
||||
assert!(byte.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_bytes() {
|
||||
let mut reader = MemReader::new(~[10, 11, 12, 13]);
|
||||
let bytes = reader.read_bytes(4);
|
||||
let bytes = reader.read_bytes(4).unwrap();
|
||||
assert!(bytes == ~[10, 11, 12, 13]);
|
||||
}
|
||||
|
||||
|
|
@ -292,24 +284,21 @@ mod test {
|
|||
let mut reader = PartialReader {
|
||||
count: 0,
|
||||
};
|
||||
let bytes = reader.read_bytes(4);
|
||||
let bytes = reader.read_bytes(4).unwrap();
|
||||
assert!(bytes == ~[10, 11, 12, 13]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_bytes_eof() {
|
||||
let mut reader = MemReader::new(~[10, 11]);
|
||||
io_error::cond.trap(|_| {
|
||||
}).inside(|| {
|
||||
assert!(reader.read_bytes(4) == ~[10, 11]);
|
||||
})
|
||||
assert!(reader.read_bytes(4).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn push_bytes() {
|
||||
let mut reader = MemReader::new(~[10, 11, 12, 13]);
|
||||
let mut buf = ~[8, 9];
|
||||
reader.push_bytes(&mut buf, 4);
|
||||
reader.push_bytes(&mut buf, 4).unwrap();
|
||||
assert!(buf == ~[8, 9, 10, 11, 12, 13]);
|
||||
}
|
||||
|
||||
|
|
@ -319,7 +308,7 @@ mod test {
|
|||
count: 0,
|
||||
};
|
||||
let mut buf = ~[8, 9];
|
||||
reader.push_bytes(&mut buf, 4);
|
||||
reader.push_bytes(&mut buf, 4).unwrap();
|
||||
assert!(buf == ~[8, 9, 10, 11, 12, 13]);
|
||||
}
|
||||
|
||||
|
|
@ -327,11 +316,8 @@ mod test {
|
|||
fn push_bytes_eof() {
|
||||
let mut reader = MemReader::new(~[10, 11]);
|
||||
let mut buf = ~[8, 9];
|
||||
io_error::cond.trap(|_| {
|
||||
}).inside(|| {
|
||||
reader.push_bytes(&mut buf, 4);
|
||||
assert!(buf == ~[8, 9, 10, 11]);
|
||||
})
|
||||
assert!(reader.push_bytes(&mut buf, 4).is_err());
|
||||
assert!(buf == ~[8, 9, 10, 11]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -340,38 +326,16 @@ mod test {
|
|||
count: 0,
|
||||
};
|
||||
let mut buf = ~[8, 9];
|
||||
io_error::cond.trap(|_| { } ).inside(|| {
|
||||
reader.push_bytes(&mut buf, 4);
|
||||
});
|
||||
assert!(reader.push_bytes(&mut buf, 4).is_err());
|
||||
assert!(buf == ~[8, 9, 10]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
#[ignore] // borrow issues with RefCell
|
||||
fn push_bytes_fail_reset_len() {
|
||||
// push_bytes unsafely sets the vector length. This is testing that
|
||||
// upon failure the length is reset correctly.
|
||||
let _reader = ErroringLaterReader {
|
||||
count: 0,
|
||||
};
|
||||
// FIXME (#7049): Figure out some other way to do this.
|
||||
//let buf = RefCell::new(~[8, 9]);
|
||||
(|| {
|
||||
//reader.push_bytes(buf.borrow_mut().get(), 4);
|
||||
}).finally(|| {
|
||||
// NB: Using rtassert here to trigger abort on failure since this is a should_fail test
|
||||
// FIXME: #7049 This fails because buf is still borrowed
|
||||
//rtassert!(buf.borrow().get() == ~[8, 9, 10]);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_to_end() {
|
||||
let mut reader = ThreeChunkReader {
|
||||
count: 0,
|
||||
};
|
||||
let buf = reader.read_to_end();
|
||||
let buf = reader.read_to_end().unwrap();
|
||||
assert!(buf == ~[10, 11, 12, 13]);
|
||||
}
|
||||
|
||||
|
|
@ -381,7 +345,7 @@ mod test {
|
|||
let mut reader = ThreeChunkReader {
|
||||
count: 0,
|
||||
};
|
||||
let buf = reader.read_to_end();
|
||||
let buf = reader.read_to_end().unwrap();
|
||||
assert!(buf == ~[10, 11]);
|
||||
}
|
||||
|
||||
|
|
@ -391,12 +355,12 @@ mod test {
|
|||
|
||||
let mut writer = MemWriter::new();
|
||||
for i in uints.iter() {
|
||||
writer.write_le_u64(*i);
|
||||
writer.write_le_u64(*i).unwrap();
|
||||
}
|
||||
|
||||
let mut reader = MemReader::new(writer.unwrap());
|
||||
for i in uints.iter() {
|
||||
assert!(reader.read_le_u64() == *i);
|
||||
assert!(reader.read_le_u64().unwrap() == *i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -407,12 +371,12 @@ mod test {
|
|||
|
||||
let mut writer = MemWriter::new();
|
||||
for i in uints.iter() {
|
||||
writer.write_be_u64(*i);
|
||||
writer.write_be_u64(*i).unwrap();
|
||||
}
|
||||
|
||||
let mut reader = MemReader::new(writer.unwrap());
|
||||
for i in uints.iter() {
|
||||
assert!(reader.read_be_u64() == *i);
|
||||
assert!(reader.read_be_u64().unwrap() == *i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -422,14 +386,14 @@ mod test {
|
|||
|
||||
let mut writer = MemWriter::new();
|
||||
for i in ints.iter() {
|
||||
writer.write_be_i32(*i);
|
||||
writer.write_be_i32(*i).unwrap();
|
||||
}
|
||||
|
||||
let mut reader = MemReader::new(writer.unwrap());
|
||||
for i in ints.iter() {
|
||||
// this tests that the sign extension is working
|
||||
// (comparing the values as i32 would not test this)
|
||||
assert!(reader.read_be_int_n(4) == *i as i64);
|
||||
assert!(reader.read_be_int_n(4).unwrap() == *i as i64);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -439,10 +403,10 @@ mod test {
|
|||
let buf = ~[0x41, 0x02, 0x00, 0x00];
|
||||
|
||||
let mut writer = MemWriter::new();
|
||||
writer.write(buf);
|
||||
writer.write(buf).unwrap();
|
||||
|
||||
let mut reader = MemReader::new(writer.unwrap());
|
||||
let f = reader.read_be_f32();
|
||||
let f = reader.read_be_f32().unwrap();
|
||||
assert!(f == 8.1250);
|
||||
}
|
||||
|
||||
|
|
@ -451,12 +415,12 @@ mod test {
|
|||
let f:f32 = 8.1250;
|
||||
|
||||
let mut writer = MemWriter::new();
|
||||
writer.write_be_f32(f);
|
||||
writer.write_le_f32(f);
|
||||
writer.write_be_f32(f).unwrap();
|
||||
writer.write_le_f32(f).unwrap();
|
||||
|
||||
let mut reader = MemReader::new(writer.unwrap());
|
||||
assert!(reader.read_be_f32() == 8.1250);
|
||||
assert!(reader.read_le_f32() == 8.1250);
|
||||
assert!(reader.read_be_f32().unwrap() == 8.1250);
|
||||
assert!(reader.read_le_f32().unwrap() == 8.1250);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -13,9 +13,10 @@
|
|||
use cmp::max;
|
||||
use cmp::min;
|
||||
use container::Container;
|
||||
use option::{Option, Some, None};
|
||||
use super::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, io_error,
|
||||
OtherIoError};
|
||||
use option::None;
|
||||
use result::{Err, Ok};
|
||||
use io;
|
||||
use io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult};
|
||||
use vec;
|
||||
use vec::{Vector, ImmutableVector, MutableVector, OwnedCloneableVector};
|
||||
|
||||
|
|
@ -24,6 +25,7 @@ use vec::{Vector, ImmutableVector, MutableVector, OwnedCloneableVector};
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[allow(unused_must_use)];
|
||||
/// use std::io::MemWriter;
|
||||
///
|
||||
/// let mut w = MemWriter::new();
|
||||
|
|
@ -59,7 +61,7 @@ impl MemWriter {
|
|||
}
|
||||
|
||||
impl Writer for MemWriter {
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
// Make sure the internal buffer is as least as big as where we
|
||||
// currently are
|
||||
let difference = self.pos as i64 - self.buf.len() as i64;
|
||||
|
|
@ -86,14 +88,15 @@ impl Writer for MemWriter {
|
|||
|
||||
// Bump us forward
|
||||
self.pos += buf.len();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(#10432)
|
||||
impl Seek for MemWriter {
|
||||
fn tell(&self) -> u64 { self.pos as u64 }
|
||||
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
|
||||
|
||||
fn seek(&mut self, pos: i64, style: SeekStyle) {
|
||||
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
|
||||
// compute offset as signed and clamp to prevent overflow
|
||||
let offset = match style {
|
||||
SeekSet => { 0 }
|
||||
|
|
@ -102,6 +105,7 @@ impl Seek for MemWriter {
|
|||
} as i64;
|
||||
|
||||
self.pos = max(0, offset+pos) as uint;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -110,11 +114,12 @@ impl Seek for MemWriter {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[allow(unused_must_use)];
|
||||
/// use std::io::MemReader;
|
||||
///
|
||||
/// let mut r = MemReader::new(~[0, 1, 2]);
|
||||
///
|
||||
/// assert_eq!(r.read_to_end(), ~[0, 1, 2]);
|
||||
/// assert_eq!(r.read_to_end().unwrap(), ~[0, 1, 2]);
|
||||
/// ```
|
||||
pub struct MemReader {
|
||||
priv buf: ~[u8],
|
||||
|
|
@ -148,8 +153,8 @@ impl MemReader {
|
|||
}
|
||||
|
||||
impl Reader for MemReader {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
if self.eof() { return None }
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
if self.eof() { return Err(io::standard_error(io::EndOfFile)) }
|
||||
|
||||
let write_len = min(buf.len(), self.buf.len() - self.pos);
|
||||
{
|
||||
|
|
@ -161,28 +166,31 @@ impl Reader for MemReader {
|
|||
self.pos += write_len;
|
||||
assert!(self.pos <= self.buf.len());
|
||||
|
||||
return Some(write_len);
|
||||
return Ok(write_len);
|
||||
}
|
||||
}
|
||||
|
||||
impl Seek for MemReader {
|
||||
fn tell(&self) -> u64 { self.pos as u64 }
|
||||
fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
|
||||
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
|
||||
fn seek(&mut self, _pos: i64, _style: SeekStyle) -> IoResult<()> { fail!() }
|
||||
}
|
||||
|
||||
impl Buffer for MemReader {
|
||||
fn fill<'a>(&'a mut self) -> &'a [u8] { self.buf.slice_from(self.pos) }
|
||||
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
||||
Ok(self.buf.slice_from(self.pos))
|
||||
}
|
||||
fn consume(&mut self, amt: uint) { self.pos += amt; }
|
||||
}
|
||||
|
||||
/// Writes to a fixed-size byte slice
|
||||
///
|
||||
/// If a write will not fit in the buffer, it raises the `io_error`
|
||||
/// condition and does not write any data.
|
||||
/// If a write will not fit in the buffer, it returns an error and does not
|
||||
/// write any data.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[allow(unused_must_use)];
|
||||
/// use std::io::BufWriter;
|
||||
///
|
||||
/// let mut buf = [0, ..4];
|
||||
|
|
@ -207,28 +215,28 @@ impl<'a> BufWriter<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Writer for BufWriter<'a> {
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
// raises a condition if the entire write does not fit in the buffer
|
||||
let max_size = self.buf.len();
|
||||
if self.pos >= max_size || (self.pos + buf.len()) > max_size {
|
||||
io_error::cond.raise(IoError {
|
||||
kind: OtherIoError,
|
||||
return Err(IoError {
|
||||
kind: io::OtherIoError,
|
||||
desc: "Trying to write past end of buffer",
|
||||
detail: None
|
||||
});
|
||||
return;
|
||||
})
|
||||
}
|
||||
|
||||
vec::bytes::copy_memory(self.buf.mut_slice_from(self.pos), buf);
|
||||
self.pos += buf.len();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(#10432)
|
||||
impl<'a> Seek for BufWriter<'a> {
|
||||
fn tell(&self) -> u64 { self.pos as u64 }
|
||||
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
|
||||
|
||||
fn seek(&mut self, pos: i64, style: SeekStyle) {
|
||||
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
|
||||
// compute offset as signed and clamp to prevent overflow
|
||||
let offset = match style {
|
||||
SeekSet => { 0 }
|
||||
|
|
@ -237,6 +245,7 @@ impl<'a> Seek for BufWriter<'a> {
|
|||
} as i64;
|
||||
|
||||
self.pos = max(0, offset+pos) as uint;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,12 +255,13 @@ impl<'a> Seek for BufWriter<'a> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[allow(unused_must_use)];
|
||||
/// use std::io::BufReader;
|
||||
///
|
||||
/// let mut buf = [0, 1, 2, 3];
|
||||
/// let mut r = BufReader::new(buf);
|
||||
///
|
||||
/// assert_eq!(r.read_to_end(), ~[0, 1, 2, 3]);
|
||||
/// assert_eq!(r.read_to_end().unwrap(), ~[0, 1, 2, 3]);
|
||||
/// ```
|
||||
pub struct BufReader<'a> {
|
||||
priv buf: &'a [u8],
|
||||
|
|
@ -274,8 +284,8 @@ impl<'a> BufReader<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Reader for BufReader<'a> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
if self.eof() { return None }
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
if self.eof() { return Err(io::standard_error(io::EndOfFile)) }
|
||||
|
||||
let write_len = min(buf.len(), self.buf.len() - self.pos);
|
||||
{
|
||||
|
|
@ -287,18 +297,19 @@ impl<'a> Reader for BufReader<'a> {
|
|||
self.pos += write_len;
|
||||
assert!(self.pos <= self.buf.len());
|
||||
|
||||
return Some(write_len);
|
||||
return Ok(write_len);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Seek for BufReader<'a> {
|
||||
fn tell(&self) -> u64 { self.pos as u64 }
|
||||
|
||||
fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
|
||||
fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
|
||||
fn seek(&mut self, _pos: i64, _style: SeekStyle) -> IoResult<()> { fail!() }
|
||||
}
|
||||
|
||||
impl<'a> Buffer for BufReader<'a> {
|
||||
fn fill<'a>(&'a mut self) -> &'a [u8] { self.buf.slice_from(self.pos) }
|
||||
fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
||||
Ok(self.buf.slice_from(self.pos))
|
||||
}
|
||||
fn consume(&mut self, amt: uint) { self.pos += amt; }
|
||||
}
|
||||
|
||||
|
|
@ -307,33 +318,34 @@ mod test {
|
|||
use prelude::*;
|
||||
use super::*;
|
||||
use io::*;
|
||||
use io;
|
||||
|
||||
#[test]
|
||||
fn test_mem_writer() {
|
||||
let mut writer = MemWriter::new();
|
||||
assert_eq!(writer.tell(), 0);
|
||||
writer.write([0]);
|
||||
assert_eq!(writer.tell(), 1);
|
||||
writer.write([1, 2, 3]);
|
||||
writer.write([4, 5, 6, 7]);
|
||||
assert_eq!(writer.tell(), 8);
|
||||
assert_eq!(writer.tell(), Ok(0));
|
||||
writer.write([0]).unwrap();
|
||||
assert_eq!(writer.tell(), Ok(1));
|
||||
writer.write([1, 2, 3]).unwrap();
|
||||
writer.write([4, 5, 6, 7]).unwrap();
|
||||
assert_eq!(writer.tell(), Ok(8));
|
||||
assert_eq!(writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
|
||||
writer.seek(0, SeekSet);
|
||||
assert_eq!(writer.tell(), 0);
|
||||
writer.write([3, 4]);
|
||||
writer.seek(0, SeekSet).unwrap();
|
||||
assert_eq!(writer.tell(), Ok(0));
|
||||
writer.write([3, 4]).unwrap();
|
||||
assert_eq!(writer.get_ref(), [3, 4, 2, 3, 4, 5, 6, 7]);
|
||||
|
||||
writer.seek(1, SeekCur);
|
||||
writer.write([0, 1]);
|
||||
writer.seek(1, SeekCur).unwrap();
|
||||
writer.write([0, 1]).unwrap();
|
||||
assert_eq!(writer.get_ref(), [3, 4, 2, 0, 1, 5, 6, 7]);
|
||||
|
||||
writer.seek(-1, SeekEnd);
|
||||
writer.write([1, 2]);
|
||||
writer.seek(-1, SeekEnd).unwrap();
|
||||
writer.write([1, 2]).unwrap();
|
||||
assert_eq!(writer.get_ref(), [3, 4, 2, 0, 1, 5, 6, 1, 2]);
|
||||
|
||||
writer.seek(1, SeekEnd);
|
||||
writer.write([1]);
|
||||
writer.seek(1, SeekEnd).unwrap();
|
||||
writer.write([1]).unwrap();
|
||||
assert_eq!(writer.get_ref(), [3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1]);
|
||||
}
|
||||
|
||||
|
|
@ -342,12 +354,12 @@ mod test {
|
|||
let mut buf = [0 as u8, ..8];
|
||||
{
|
||||
let mut writer = BufWriter::new(buf);
|
||||
assert_eq!(writer.tell(), 0);
|
||||
writer.write([0]);
|
||||
assert_eq!(writer.tell(), 1);
|
||||
writer.write([1, 2, 3]);
|
||||
writer.write([4, 5, 6, 7]);
|
||||
assert_eq!(writer.tell(), 8);
|
||||
assert_eq!(writer.tell(), Ok(0));
|
||||
writer.write([0]).unwrap();
|
||||
assert_eq!(writer.tell(), Ok(1));
|
||||
writer.write([1, 2, 3]).unwrap();
|
||||
writer.write([4, 5, 6, 7]).unwrap();
|
||||
assert_eq!(writer.tell(), Ok(8));
|
||||
}
|
||||
assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
}
|
||||
|
|
@ -357,24 +369,24 @@ mod test {
|
|||
let mut buf = [0 as u8, ..8];
|
||||
{
|
||||
let mut writer = BufWriter::new(buf);
|
||||
assert_eq!(writer.tell(), 0);
|
||||
writer.write([1]);
|
||||
assert_eq!(writer.tell(), 1);
|
||||
assert_eq!(writer.tell(), Ok(0));
|
||||
writer.write([1]).unwrap();
|
||||
assert_eq!(writer.tell(), Ok(1));
|
||||
|
||||
writer.seek(2, SeekSet);
|
||||
assert_eq!(writer.tell(), 2);
|
||||
writer.write([2]);
|
||||
assert_eq!(writer.tell(), 3);
|
||||
writer.seek(2, SeekSet).unwrap();
|
||||
assert_eq!(writer.tell(), Ok(2));
|
||||
writer.write([2]).unwrap();
|
||||
assert_eq!(writer.tell(), Ok(3));
|
||||
|
||||
writer.seek(-2, SeekCur);
|
||||
assert_eq!(writer.tell(), 1);
|
||||
writer.write([3]);
|
||||
assert_eq!(writer.tell(), 2);
|
||||
writer.seek(-2, SeekCur).unwrap();
|
||||
assert_eq!(writer.tell(), Ok(1));
|
||||
writer.write([3]).unwrap();
|
||||
assert_eq!(writer.tell(), Ok(2));
|
||||
|
||||
writer.seek(-1, SeekEnd);
|
||||
assert_eq!(writer.tell(), 7);
|
||||
writer.write([4]);
|
||||
assert_eq!(writer.tell(), 8);
|
||||
writer.seek(-1, SeekEnd).unwrap();
|
||||
assert_eq!(writer.tell(), Ok(7));
|
||||
writer.write([4]).unwrap();
|
||||
assert_eq!(writer.tell(), Ok(8));
|
||||
|
||||
}
|
||||
assert_eq!(buf, [1, 3, 2, 0, 0, 0, 0, 4]);
|
||||
|
|
@ -384,35 +396,31 @@ mod test {
|
|||
fn test_buf_writer_error() {
|
||||
let mut buf = [0 as u8, ..2];
|
||||
let mut writer = BufWriter::new(buf);
|
||||
writer.write([0]);
|
||||
writer.write([0]).unwrap();
|
||||
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|err| {
|
||||
assert_eq!(err.kind, OtherIoError);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
writer.write([0, 0]);
|
||||
});
|
||||
assert!(called);
|
||||
match writer.write([0, 0]) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, io::OtherIoError),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mem_reader() {
|
||||
let mut reader = MemReader::new(~[0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
let mut buf = [];
|
||||
assert_eq!(reader.read(buf), Some(0));
|
||||
assert_eq!(reader.tell(), 0);
|
||||
assert_eq!(reader.read(buf), Ok(0));
|
||||
assert_eq!(reader.tell(), Ok(0));
|
||||
let mut buf = [0];
|
||||
assert_eq!(reader.read(buf), Some(1));
|
||||
assert_eq!(reader.tell(), 1);
|
||||
assert_eq!(reader.read(buf), Ok(1));
|
||||
assert_eq!(reader.tell(), Ok(1));
|
||||
assert_eq!(buf, [0]);
|
||||
let mut buf = [0, ..4];
|
||||
assert_eq!(reader.read(buf), Some(4));
|
||||
assert_eq!(reader.tell(), 5);
|
||||
assert_eq!(reader.read(buf), Ok(4));
|
||||
assert_eq!(reader.tell(), Ok(5));
|
||||
assert_eq!(buf, [1, 2, 3, 4]);
|
||||
assert_eq!(reader.read(buf), Some(3));
|
||||
assert_eq!(reader.read(buf), Ok(3));
|
||||
assert_eq!(buf.slice(0, 3), [5, 6, 7]);
|
||||
assert_eq!(reader.read(buf), None);
|
||||
assert!(reader.read(buf).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -420,64 +428,64 @@ mod test {
|
|||
let in_buf = ~[0, 1, 2, 3, 4, 5, 6, 7];
|
||||
let mut reader = BufReader::new(in_buf);
|
||||
let mut buf = [];
|
||||
assert_eq!(reader.read(buf), Some(0));
|
||||
assert_eq!(reader.tell(), 0);
|
||||
assert_eq!(reader.read(buf), Ok(0));
|
||||
assert_eq!(reader.tell(), Ok(0));
|
||||
let mut buf = [0];
|
||||
assert_eq!(reader.read(buf), Some(1));
|
||||
assert_eq!(reader.tell(), 1);
|
||||
assert_eq!(reader.read(buf), Ok(1));
|
||||
assert_eq!(reader.tell(), Ok(1));
|
||||
assert_eq!(buf, [0]);
|
||||
let mut buf = [0, ..4];
|
||||
assert_eq!(reader.read(buf), Some(4));
|
||||
assert_eq!(reader.tell(), 5);
|
||||
assert_eq!(reader.read(buf), Ok(4));
|
||||
assert_eq!(reader.tell(), Ok(5));
|
||||
assert_eq!(buf, [1, 2, 3, 4]);
|
||||
assert_eq!(reader.read(buf), Some(3));
|
||||
assert_eq!(reader.read(buf), Ok(3));
|
||||
assert_eq!(buf.slice(0, 3), [5, 6, 7]);
|
||||
assert_eq!(reader.read(buf), None);
|
||||
assert!(reader.read(buf).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_char() {
|
||||
let b = bytes!("Việt");
|
||||
let mut r = BufReader::new(b);
|
||||
assert_eq!(r.read_char(), Some('V'));
|
||||
assert_eq!(r.read_char(), Some('i'));
|
||||
assert_eq!(r.read_char(), Some('ệ'));
|
||||
assert_eq!(r.read_char(), Some('t'));
|
||||
assert_eq!(r.read_char(), None);
|
||||
assert_eq!(r.read_char(), Ok('V'));
|
||||
assert_eq!(r.read_char(), Ok('i'));
|
||||
assert_eq!(r.read_char(), Ok('ệ'));
|
||||
assert_eq!(r.read_char(), Ok('t'));
|
||||
assert!(r.read_char().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_bad_char() {
|
||||
let b = bytes!(0x80);
|
||||
let mut r = BufReader::new(b);
|
||||
assert_eq!(r.read_char(), None);
|
||||
assert!(r.read_char().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_strings() {
|
||||
let mut writer = MemWriter::new();
|
||||
writer.write_str("testing");
|
||||
writer.write_line("testing");
|
||||
writer.write_str("testing");
|
||||
writer.write_str("testing").unwrap();
|
||||
writer.write_line("testing").unwrap();
|
||||
writer.write_str("testing").unwrap();
|
||||
let mut r = BufReader::new(writer.get_ref());
|
||||
assert_eq!(r.read_to_str(), ~"testingtesting\ntesting");
|
||||
assert_eq!(r.read_to_str().unwrap(), ~"testingtesting\ntesting");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_char() {
|
||||
let mut writer = MemWriter::new();
|
||||
writer.write_char('a');
|
||||
writer.write_char('\n');
|
||||
writer.write_char('ệ');
|
||||
writer.write_char('a').unwrap();
|
||||
writer.write_char('\n').unwrap();
|
||||
writer.write_char('ệ').unwrap();
|
||||
let mut r = BufReader::new(writer.get_ref());
|
||||
assert_eq!(r.read_to_str(), ~"a\nệ");
|
||||
assert_eq!(r.read_to_str().unwrap(), ~"a\nệ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_whole_string_bad() {
|
||||
let buf = [0xff];
|
||||
let mut r = BufReader::new(buf);
|
||||
match result(|| r.read_to_str()) {
|
||||
match r.read_to_str() {
|
||||
Ok(..) => fail!(),
|
||||
Err(..) => {}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -17,8 +17,9 @@ getaddrinfo()
|
|||
|
||||
*/
|
||||
|
||||
use option::{Option, Some, None};
|
||||
use io::IoResult;
|
||||
use io::net::ip::{SocketAddr, IpAddr};
|
||||
use option::{Option, Some, None};
|
||||
use rt::rtio::{IoFactory, LocalIo};
|
||||
use vec::ImmutableVector;
|
||||
|
||||
|
|
@ -69,11 +70,7 @@ pub struct Info {
|
|||
|
||||
/// Easy name resolution. Given a hostname, returns the list of IP addresses for
|
||||
/// that hostname.
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// On failure, this will raise on the `io_error` condition.
|
||||
pub fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
|
||||
pub fn get_host_addresses(host: &str) -> IoResult<~[IpAddr]> {
|
||||
lookup(Some(host), None, None).map(|a| a.map(|i| i.address.ip))
|
||||
}
|
||||
|
||||
|
|
@ -87,14 +84,10 @@ pub fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
|
|||
/// * hint - see the hint structure, and "man -s 3 getaddrinfo", for how this
|
||||
/// controls lookup
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// On failure, this will raise on the `io_error` condition.
|
||||
///
|
||||
/// FIXME: this is not public because the `Hint` structure is not ready for public
|
||||
/// consumption just yet.
|
||||
fn lookup(hostname: Option<&str>, servname: Option<&str>, hint: Option<Hint>)
|
||||
-> Option<~[Info]> {
|
||||
-> IoResult<~[Info]> {
|
||||
LocalIo::maybe_raise(|io| io.get_host_addresses(hostname, servname, hint))
|
||||
}
|
||||
|
||||
|
|
@ -115,6 +108,6 @@ mod test {
|
|||
iotest!(fn issue_10663() {
|
||||
// Something should happen here, but this certainly shouldn't cause
|
||||
// everything to die. The actual outcome we don't care too much about.
|
||||
get_host_addresses("example.com");
|
||||
get_host_addresses("example.com").unwrap();
|
||||
} #[ignore])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use option::{Option, Some, None};
|
||||
use result::{Ok, Err};
|
||||
use io::net::ip::SocketAddr;
|
||||
use io::{Reader, Writer, Listener, Acceptor};
|
||||
use io::{io_error, EndOfFile};
|
||||
use io::{Reader, Writer, Listener, Acceptor, IoResult};
|
||||
use rt::rtio::{IoFactory, LocalIo, RtioSocket, RtioTcpListener};
|
||||
use rt::rtio::{RtioTcpAcceptor, RtioTcpStream};
|
||||
|
||||
|
|
@ -25,57 +22,27 @@ impl TcpStream {
|
|||
TcpStream { obj: s }
|
||||
}
|
||||
|
||||
pub fn connect(addr: SocketAddr) -> Option<TcpStream> {
|
||||
pub fn connect(addr: SocketAddr) -> IoResult<TcpStream> {
|
||||
LocalIo::maybe_raise(|io| {
|
||||
io.tcp_connect(addr).map(TcpStream::new)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn peer_name(&mut self) -> Option<SocketAddr> {
|
||||
match self.obj.peer_name() {
|
||||
Ok(pn) => Some(pn),
|
||||
Err(ioerr) => {
|
||||
debug!("failed to get peer name: {:?}", ioerr);
|
||||
io_error::cond.raise(ioerr);
|
||||
None
|
||||
}
|
||||
}
|
||||
pub fn peer_name(&mut self) -> IoResult<SocketAddr> {
|
||||
self.obj.peer_name()
|
||||
}
|
||||
|
||||
pub fn socket_name(&mut self) -> Option<SocketAddr> {
|
||||
match self.obj.socket_name() {
|
||||
Ok(sn) => Some(sn),
|
||||
Err(ioerr) => {
|
||||
debug!("failed to get socket name: {:?}", ioerr);
|
||||
io_error::cond.raise(ioerr);
|
||||
None
|
||||
}
|
||||
}
|
||||
pub fn socket_name(&mut self) -> IoResult<SocketAddr> {
|
||||
self.obj.socket_name()
|
||||
}
|
||||
}
|
||||
|
||||
impl Reader for TcpStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
match self.obj.read(buf) {
|
||||
Ok(read) => Some(read),
|
||||
Err(ioerr) => {
|
||||
// EOF is indicated by returning None
|
||||
if ioerr.kind != EndOfFile {
|
||||
io_error::cond.raise(ioerr);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.obj.read(buf) }
|
||||
}
|
||||
|
||||
impl Writer for TcpStream {
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
match self.obj.write(buf) {
|
||||
Ok(_) => (),
|
||||
Err(ioerr) => io_error::cond.raise(ioerr),
|
||||
}
|
||||
}
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.obj.write(buf) }
|
||||
}
|
||||
|
||||
pub struct TcpListener {
|
||||
|
|
@ -83,33 +50,20 @@ pub struct TcpListener {
|
|||
}
|
||||
|
||||
impl TcpListener {
|
||||
pub fn bind(addr: SocketAddr) -> Option<TcpListener> {
|
||||
pub fn bind(addr: SocketAddr) -> IoResult<TcpListener> {
|
||||
LocalIo::maybe_raise(|io| {
|
||||
io.tcp_bind(addr).map(|l| TcpListener { obj: l })
|
||||
})
|
||||
}
|
||||
|
||||
pub fn socket_name(&mut self) -> Option<SocketAddr> {
|
||||
match self.obj.socket_name() {
|
||||
Ok(sn) => Some(sn),
|
||||
Err(ioerr) => {
|
||||
debug!("failed to get socket name: {:?}", ioerr);
|
||||
io_error::cond.raise(ioerr);
|
||||
None
|
||||
}
|
||||
}
|
||||
pub fn socket_name(&mut self) -> IoResult<SocketAddr> {
|
||||
self.obj.socket_name()
|
||||
}
|
||||
}
|
||||
|
||||
impl Listener<TcpStream, TcpAcceptor> for TcpListener {
|
||||
fn listen(self) -> Option<TcpAcceptor> {
|
||||
match self.obj.listen() {
|
||||
Ok(acceptor) => Some(TcpAcceptor { obj: acceptor }),
|
||||
Err(ioerr) => {
|
||||
io_error::cond.raise(ioerr);
|
||||
None
|
||||
}
|
||||
}
|
||||
fn listen(self) -> IoResult<TcpAcceptor> {
|
||||
self.obj.listen().map(|acceptor| TcpAcceptor { obj: acceptor })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -118,14 +72,8 @@ pub struct TcpAcceptor {
|
|||
}
|
||||
|
||||
impl Acceptor<TcpStream> for TcpAcceptor {
|
||||
fn accept(&mut self) -> Option<TcpStream> {
|
||||
match self.obj.accept() {
|
||||
Ok(s) => Some(TcpStream::new(s)),
|
||||
Err(ioerr) => {
|
||||
io_error::cond.raise(ioerr);
|
||||
None
|
||||
}
|
||||
}
|
||||
fn accept(&mut self) -> IoResult<TcpStream> {
|
||||
self.obj.accept().map(TcpStream::new)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -138,29 +86,19 @@ mod test {
|
|||
|
||||
// FIXME #11530 this fails on android because tests are run as root
|
||||
iotest!(fn bind_error() {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert!(e.kind == PermissionDenied);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
let listener = TcpListener::bind(addr);
|
||||
assert!(listener.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
match TcpListener::bind(addr) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, PermissionDenied),
|
||||
}
|
||||
} #[ignore(cfg(windows))] #[ignore(cfg(target_os = "android"))])
|
||||
|
||||
iotest!(fn connect_error() {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert_eq!(e.kind, ConnectionRefused);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
let stream = TcpStream::connect(addr);
|
||||
assert!(stream.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
match TcpStream::connect(addr) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, ConnectionRefused),
|
||||
}
|
||||
})
|
||||
|
||||
iotest!(fn smoke_test_ip4() {
|
||||
|
|
@ -170,14 +108,14 @@ mod test {
|
|||
spawn(proc() {
|
||||
port.recv();
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
stream.write([99]);
|
||||
stream.write([99]).unwrap();
|
||||
});
|
||||
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
stream.read(buf).unwrap();
|
||||
assert!(buf[0] == 99);
|
||||
})
|
||||
|
||||
|
|
@ -188,14 +126,14 @@ mod test {
|
|||
spawn(proc() {
|
||||
port.recv();
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
stream.write([99]);
|
||||
stream.write([99]).unwrap();
|
||||
});
|
||||
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
stream.read(buf).unwrap();
|
||||
assert!(buf[0] == 99);
|
||||
})
|
||||
|
||||
|
|
@ -214,7 +152,7 @@ mod test {
|
|||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
assert!(nread.is_err());
|
||||
})
|
||||
|
||||
iotest!(fn read_eof_ip6() {
|
||||
|
|
@ -232,7 +170,7 @@ mod test {
|
|||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
assert!(nread.is_err());
|
||||
})
|
||||
|
||||
iotest!(fn read_eof_twice_ip4() {
|
||||
|
|
@ -250,17 +188,15 @@ mod test {
|
|||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
io_error::cond.trap(|e| {
|
||||
if cfg!(windows) {
|
||||
assert_eq!(e.kind, NotConnected);
|
||||
} else {
|
||||
fail!();
|
||||
assert!(nread.is_err());
|
||||
|
||||
match stream.read(buf) {
|
||||
Ok(..) => fail!(),
|
||||
Err(ref e) => {
|
||||
assert!(e.kind == NotConnected || e.kind == EndOfFile,
|
||||
"unknown kind: {:?}", e.kind);
|
||||
}
|
||||
}).inside(|| {
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
iotest!(fn read_eof_twice_ip6() {
|
||||
|
|
@ -278,17 +214,15 @@ mod test {
|
|||
let mut stream = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
io_error::cond.trap(|e| {
|
||||
if cfg!(windows) {
|
||||
assert_eq!(e.kind, NotConnected);
|
||||
} else {
|
||||
fail!();
|
||||
assert!(nread.is_err());
|
||||
|
||||
match stream.read(buf) {
|
||||
Ok(..) => fail!(),
|
||||
Err(ref e) => {
|
||||
assert!(e.kind == NotConnected || e.kind == EndOfFile,
|
||||
"unknown kind: {:?}", e.kind);
|
||||
}
|
||||
}).inside(|| {
|
||||
let nread = stream.read(buf);
|
||||
assert!(nread.is_none());
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
iotest!(fn write_close_ip4() {
|
||||
|
|
@ -306,19 +240,16 @@ mod test {
|
|||
let mut stream = acceptor.accept();
|
||||
let buf = [0];
|
||||
loop {
|
||||
let mut stop = false;
|
||||
io_error::cond.trap(|e| {
|
||||
// NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED
|
||||
// on windows
|
||||
assert!(e.kind == ConnectionReset ||
|
||||
e.kind == BrokenPipe ||
|
||||
e.kind == ConnectionAborted,
|
||||
"unknown error: {:?}", e);
|
||||
stop = true;
|
||||
}).inside(|| {
|
||||
stream.write(buf);
|
||||
});
|
||||
if stop { break }
|
||||
match stream.write(buf) {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
assert!(e.kind == ConnectionReset ||
|
||||
e.kind == BrokenPipe ||
|
||||
e.kind == ConnectionAborted,
|
||||
"unknown error: {:?}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -337,19 +268,16 @@ mod test {
|
|||
let mut stream = acceptor.accept();
|
||||
let buf = [0];
|
||||
loop {
|
||||
let mut stop = false;
|
||||
io_error::cond.trap(|e| {
|
||||
// NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED
|
||||
// on windows
|
||||
assert!(e.kind == ConnectionReset ||
|
||||
e.kind == BrokenPipe ||
|
||||
e.kind == ConnectionAborted,
|
||||
"unknown error: {:?}", e);
|
||||
stop = true;
|
||||
}).inside(|| {
|
||||
stream.write(buf);
|
||||
});
|
||||
if stop { break }
|
||||
match stream.write(buf) {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
assert!(e.kind == ConnectionReset ||
|
||||
e.kind == BrokenPipe ||
|
||||
e.kind == ConnectionAborted,
|
||||
"unknown error: {:?}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -362,7 +290,7 @@ mod test {
|
|||
port.recv();
|
||||
for _ in range(0, max) {
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
stream.write([99]);
|
||||
stream.write([99]).unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -370,7 +298,7 @@ mod test {
|
|||
chan.send(());
|
||||
for ref mut stream in acceptor.incoming().take(max) {
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
stream.read(buf).unwrap();
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
})
|
||||
|
|
@ -384,7 +312,7 @@ mod test {
|
|||
port.recv();
|
||||
for _ in range(0, max) {
|
||||
let mut stream = TcpStream::connect(addr);
|
||||
stream.write([99]);
|
||||
stream.write([99]).unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -392,7 +320,7 @@ mod test {
|
|||
chan.send(());
|
||||
for ref mut stream in acceptor.incoming().take(max) {
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
stream.read(buf).unwrap();
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
})
|
||||
|
|
@ -410,7 +338,7 @@ mod test {
|
|||
spawn(proc() {
|
||||
let mut stream = stream;
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
stream.read(buf).unwrap();
|
||||
assert!(buf[0] == i as u8);
|
||||
debug!("read");
|
||||
});
|
||||
|
|
@ -429,7 +357,7 @@ mod test {
|
|||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
stream.write([i as u8]);
|
||||
stream.write([i as u8]).unwrap();
|
||||
});
|
||||
}
|
||||
})
|
||||
|
|
@ -447,7 +375,7 @@ mod test {
|
|||
spawn(proc() {
|
||||
let mut stream = stream;
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
stream.read(buf).unwrap();
|
||||
assert!(buf[0] == i as u8);
|
||||
debug!("read");
|
||||
});
|
||||
|
|
@ -466,7 +394,7 @@ mod test {
|
|||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
stream.write([i as u8]);
|
||||
stream.write([i as u8]).unwrap();
|
||||
});
|
||||
}
|
||||
})
|
||||
|
|
@ -484,7 +412,7 @@ mod test {
|
|||
spawn(proc() {
|
||||
let mut stream = stream;
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
stream.read(buf).unwrap();
|
||||
assert!(buf[0] == 99);
|
||||
debug!("read");
|
||||
});
|
||||
|
|
@ -503,7 +431,7 @@ mod test {
|
|||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
stream.write([99]);
|
||||
stream.write([99]).unwrap();
|
||||
});
|
||||
}
|
||||
})
|
||||
|
|
@ -521,7 +449,7 @@ mod test {
|
|||
spawn(proc() {
|
||||
let mut stream = stream;
|
||||
let mut buf = [0];
|
||||
stream.read(buf);
|
||||
stream.read(buf).unwrap();
|
||||
assert!(buf[0] == 99);
|
||||
debug!("read");
|
||||
});
|
||||
|
|
@ -540,7 +468,7 @@ mod test {
|
|||
// Connect again before writing
|
||||
connect(i + 1, addr);
|
||||
debug!("writing");
|
||||
stream.write([99]);
|
||||
stream.write([99]).unwrap();
|
||||
});
|
||||
}
|
||||
})
|
||||
|
|
@ -551,7 +479,7 @@ mod test {
|
|||
// Make sure socket_name gives
|
||||
// us the socket we binded to.
|
||||
let so_name = listener.socket_name();
|
||||
assert!(so_name.is_some());
|
||||
assert!(so_name.is_ok());
|
||||
assert_eq!(addr, so_name.unwrap());
|
||||
}
|
||||
|
||||
|
|
@ -561,20 +489,20 @@ mod test {
|
|||
spawn(proc() {
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
acceptor.accept();
|
||||
acceptor.accept().unwrap();
|
||||
});
|
||||
|
||||
port.recv();
|
||||
let stream = TcpStream::connect(addr);
|
||||
|
||||
assert!(stream.is_some());
|
||||
assert!(stream.is_ok());
|
||||
let mut stream = stream.unwrap();
|
||||
|
||||
// Make sure peer_name gives us the
|
||||
// address/port of the peer we've
|
||||
// connected to.
|
||||
let peer_name = stream.peer_name();
|
||||
assert!(peer_name.is_some());
|
||||
assert!(peer_name.is_ok());
|
||||
assert_eq!(addr, peer_name.unwrap());
|
||||
}
|
||||
|
||||
|
|
@ -593,37 +521,33 @@ mod test {
|
|||
let addr = next_test_ip4();
|
||||
let (p, c) = Chan::new();
|
||||
spawn(proc() {
|
||||
let mut srv = TcpListener::bind(addr).listen();
|
||||
let mut srv = TcpListener::bind(addr).listen().unwrap();
|
||||
c.send(());
|
||||
let mut cl = srv.accept().unwrap();
|
||||
cl.write([10]);
|
||||
cl.write([10]).unwrap();
|
||||
let mut b = [0];
|
||||
cl.read(b);
|
||||
cl.read(b).unwrap();
|
||||
c.send(());
|
||||
});
|
||||
|
||||
p.recv();
|
||||
let mut c = TcpStream::connect(addr).unwrap();
|
||||
let mut b = [0, ..10];
|
||||
assert_eq!(c.read(b), Some(1));
|
||||
c.write([1]);
|
||||
assert_eq!(c.read(b), Ok(1));
|
||||
c.write([1]).unwrap();
|
||||
p.recv();
|
||||
})
|
||||
|
||||
iotest!(fn double_bind() {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert!(e.kind == ConnectionRefused || e.kind == OtherIoError);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let addr = next_test_ip4();
|
||||
let listener = TcpListener::bind(addr).unwrap().listen();
|
||||
assert!(listener.is_some());
|
||||
let listener2 = TcpListener::bind(addr).and_then(|l|
|
||||
l.listen());
|
||||
assert!(listener2.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
let addr = next_test_ip4();
|
||||
let listener = TcpListener::bind(addr).unwrap().listen();
|
||||
assert!(listener.is_ok());
|
||||
match TcpListener::bind(addr).listen() {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => {
|
||||
assert!(e.kind == ConnectionRefused || e.kind == OtherIoError);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
iotest!(fn fast_rebind() {
|
||||
|
|
@ -632,7 +556,7 @@ mod test {
|
|||
|
||||
spawn(proc() {
|
||||
port.recv();
|
||||
let _stream = TcpStream::connect(addr);
|
||||
let _stream = TcpStream::connect(addr).unwrap();
|
||||
// Close
|
||||
port.recv();
|
||||
});
|
||||
|
|
@ -641,7 +565,7 @@ mod test {
|
|||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
chan.send(());
|
||||
{
|
||||
let _stream = acceptor.accept();
|
||||
let _stream = acceptor.accept().unwrap();
|
||||
// Close client
|
||||
chan.send(());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use option::{Option, Some, None};
|
||||
use result::{Ok, Err};
|
||||
use io::net::ip::SocketAddr;
|
||||
use io::{Reader, Writer};
|
||||
use io::{io_error, EndOfFile};
|
||||
use io::{Reader, Writer, IoResult};
|
||||
use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, LocalIo};
|
||||
|
||||
pub struct UdpSocket {
|
||||
|
|
@ -20,45 +18,26 @@ pub struct UdpSocket {
|
|||
}
|
||||
|
||||
impl UdpSocket {
|
||||
pub fn bind(addr: SocketAddr) -> Option<UdpSocket> {
|
||||
pub fn bind(addr: SocketAddr) -> IoResult<UdpSocket> {
|
||||
LocalIo::maybe_raise(|io| {
|
||||
io.udp_bind(addr).map(|s| UdpSocket { obj: s })
|
||||
})
|
||||
}
|
||||
|
||||
pub fn recvfrom(&mut self, buf: &mut [u8]) -> Option<(uint, SocketAddr)> {
|
||||
match self.obj.recvfrom(buf) {
|
||||
Ok((nread, src)) => Some((nread, src)),
|
||||
Err(ioerr) => {
|
||||
// EOF is indicated by returning None
|
||||
if ioerr.kind != EndOfFile {
|
||||
io_error::cond.raise(ioerr);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
pub fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)> {
|
||||
self.obj.recvfrom(buf)
|
||||
}
|
||||
|
||||
pub fn sendto(&mut self, buf: &[u8], dst: SocketAddr) {
|
||||
match self.obj.sendto(buf, dst) {
|
||||
Ok(_) => (),
|
||||
Err(ioerr) => io_error::cond.raise(ioerr),
|
||||
}
|
||||
pub fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()> {
|
||||
self.obj.sendto(buf, dst)
|
||||
}
|
||||
|
||||
pub fn connect(self, other: SocketAddr) -> UdpStream {
|
||||
UdpStream { socket: self, connectedTo: other }
|
||||
}
|
||||
|
||||
pub fn socket_name(&mut self) -> Option<SocketAddr> {
|
||||
match self.obj.socket_name() {
|
||||
Ok(sn) => Some(sn),
|
||||
Err(ioerr) => {
|
||||
debug!("failed to get socket name: {:?}", ioerr);
|
||||
io_error::cond.raise(ioerr);
|
||||
None
|
||||
}
|
||||
}
|
||||
pub fn socket_name(&mut self) -> IoResult<SocketAddr> {
|
||||
self.obj.socket_name()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -76,21 +55,21 @@ impl UdpStream {
|
|||
}
|
||||
|
||||
impl Reader for UdpStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
let peer = self.connectedTo;
|
||||
self.as_socket(|sock| {
|
||||
match sock.recvfrom(buf) {
|
||||
Some((_nread, src)) if src != peer => Some(0),
|
||||
Some((nread, _src)) => Some(nread),
|
||||
None => None,
|
||||
Ok((_nread, src)) if src != peer => Ok(0),
|
||||
Ok((nread, _src)) => Ok(nread),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Writer for UdpStream {
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
self.as_socket(|sock| sock.sendto(buf, self.connectedTo));
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
self.as_socket(|sock| sock.sendto(buf, self.connectedTo))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,16 +80,11 @@ mod test {
|
|||
|
||||
// FIXME #11530 this fails on android because tests are run as root
|
||||
iotest!(fn bind_error() {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert_eq!(e.kind, PermissionDenied);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
let socket = UdpSocket::bind(addr);
|
||||
assert!(socket.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
match UdpSocket::bind(addr) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, PermissionDenied),
|
||||
}
|
||||
} #[ignore(cfg(windows))] #[ignore(cfg(target_os = "android"))])
|
||||
|
||||
iotest!(fn socket_smoke_test_ip4() {
|
||||
|
|
@ -121,29 +95,29 @@ mod test {
|
|||
|
||||
spawn(proc() {
|
||||
match UdpSocket::bind(client_ip) {
|
||||
Some(ref mut client) => {
|
||||
Ok(ref mut client) => {
|
||||
port.recv();
|
||||
client.sendto([99], server_ip)
|
||||
client.sendto([99], server_ip).unwrap()
|
||||
}
|
||||
None => fail!()
|
||||
Err(..) => fail!()
|
||||
}
|
||||
chan2.send(());
|
||||
});
|
||||
|
||||
match UdpSocket::bind(server_ip) {
|
||||
Some(ref mut server) => {
|
||||
Ok(ref mut server) => {
|
||||
chan.send(());
|
||||
let mut buf = [0];
|
||||
match server.recvfrom(buf) {
|
||||
Some((nread, src)) => {
|
||||
Ok((nread, src)) => {
|
||||
assert_eq!(nread, 1);
|
||||
assert_eq!(buf[0], 99);
|
||||
assert_eq!(src, client_ip);
|
||||
}
|
||||
None => fail!()
|
||||
Err(..) => fail!()
|
||||
}
|
||||
}
|
||||
None => fail!()
|
||||
Err(..) => fail!()
|
||||
}
|
||||
port2.recv();
|
||||
})
|
||||
|
|
@ -155,28 +129,28 @@ mod test {
|
|||
|
||||
spawn(proc() {
|
||||
match UdpSocket::bind(client_ip) {
|
||||
Some(ref mut client) => {
|
||||
Ok(ref mut client) => {
|
||||
port.recv();
|
||||
client.sendto([99], server_ip)
|
||||
client.sendto([99], server_ip).unwrap()
|
||||
}
|
||||
None => fail!()
|
||||
Err(..) => fail!()
|
||||
}
|
||||
});
|
||||
|
||||
match UdpSocket::bind(server_ip) {
|
||||
Some(ref mut server) => {
|
||||
Ok(ref mut server) => {
|
||||
chan.send(());
|
||||
let mut buf = [0];
|
||||
match server.recvfrom(buf) {
|
||||
Some((nread, src)) => {
|
||||
Ok((nread, src)) => {
|
||||
assert_eq!(nread, 1);
|
||||
assert_eq!(buf[0], 99);
|
||||
assert_eq!(src, client_ip);
|
||||
}
|
||||
None => fail!()
|
||||
Err(..) => fail!()
|
||||
}
|
||||
}
|
||||
None => fail!()
|
||||
Err(..) => fail!()
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -188,32 +162,32 @@ mod test {
|
|||
|
||||
spawn(proc() {
|
||||
match UdpSocket::bind(client_ip) {
|
||||
Some(client) => {
|
||||
Ok(client) => {
|
||||
let client = ~client;
|
||||
let mut stream = client.connect(server_ip);
|
||||
port.recv();
|
||||
stream.write([99]);
|
||||
stream.write([99]).unwrap();
|
||||
}
|
||||
None => fail!()
|
||||
Err(..) => fail!()
|
||||
}
|
||||
chan2.send(());
|
||||
});
|
||||
|
||||
match UdpSocket::bind(server_ip) {
|
||||
Some(server) => {
|
||||
Ok(server) => {
|
||||
let server = ~server;
|
||||
let mut stream = server.connect(client_ip);
|
||||
chan.send(());
|
||||
let mut buf = [0];
|
||||
match stream.read(buf) {
|
||||
Some(nread) => {
|
||||
Ok(nread) => {
|
||||
assert_eq!(nread, 1);
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
None => fail!()
|
||||
Err(..) => fail!()
|
||||
}
|
||||
}
|
||||
None => fail!()
|
||||
Err(..) => fail!()
|
||||
}
|
||||
port2.recv();
|
||||
})
|
||||
|
|
@ -226,32 +200,32 @@ mod test {
|
|||
|
||||
spawn(proc() {
|
||||
match UdpSocket::bind(client_ip) {
|
||||
Some(client) => {
|
||||
Ok(client) => {
|
||||
let client = ~client;
|
||||
let mut stream = client.connect(server_ip);
|
||||
port.recv();
|
||||
stream.write([99]);
|
||||
stream.write([99]).unwrap();
|
||||
}
|
||||
None => fail!()
|
||||
Err(..) => fail!()
|
||||
}
|
||||
chan2.send(());
|
||||
});
|
||||
|
||||
match UdpSocket::bind(server_ip) {
|
||||
Some(server) => {
|
||||
Ok(server) => {
|
||||
let server = ~server;
|
||||
let mut stream = server.connect(client_ip);
|
||||
chan.send(());
|
||||
let mut buf = [0];
|
||||
match stream.read(buf) {
|
||||
Some(nread) => {
|
||||
Ok(nread) => {
|
||||
assert_eq!(nread, 1);
|
||||
assert_eq!(buf[0], 99);
|
||||
}
|
||||
None => fail!()
|
||||
Err(..) => fail!()
|
||||
}
|
||||
}
|
||||
None => fail!()
|
||||
Err(..) => fail!()
|
||||
}
|
||||
port2.recv();
|
||||
})
|
||||
|
|
@ -259,13 +233,13 @@ mod test {
|
|||
pub fn socket_name(addr: SocketAddr) {
|
||||
let server = UdpSocket::bind(addr);
|
||||
|
||||
assert!(server.is_some());
|
||||
assert!(server.is_ok());
|
||||
let mut server = server.unwrap();
|
||||
|
||||
// Make sure socket_name gives
|
||||
// us the socket we binded to.
|
||||
let so_name = server.socket_name();
|
||||
assert!(so_name.is_some());
|
||||
assert!(so_name.is_ok());
|
||||
assert_eq!(addr, so_name.unwrap());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ use c_str::ToCStr;
|
|||
use rt::rtio::{IoFactory, LocalIo, RtioUnixListener};
|
||||
use rt::rtio::{RtioUnixAcceptor, RtioPipe};
|
||||
use io::pipe::PipeStream;
|
||||
use io::{io_error, Listener, Acceptor, Reader, Writer};
|
||||
use io::{Listener, Acceptor, Reader, Writer, IoResult};
|
||||
|
||||
/// A stream which communicates over a named pipe.
|
||||
pub struct UnixStream {
|
||||
|
|
@ -45,20 +45,17 @@ impl UnixStream {
|
|||
///
|
||||
/// The returned stream will be closed when the object falls out of scope.
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// This function will raise on the `io_error` condition if the connection
|
||||
/// could not be made.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// use std::io::net::unix::UnixStream;
|
||||
/// ```rust
|
||||
/// # #[allow(unused_must_use)];
|
||||
/// use std::io::net::unix::UnixStream;
|
||||
///
|
||||
/// let server = Path("path/to/my/socket");
|
||||
/// let mut stream = UnixStream::connect(&server);
|
||||
/// stream.write([1, 2, 3]);
|
||||
///
|
||||
pub fn connect<P: ToCStr>(path: &P) -> Option<UnixStream> {
|
||||
/// let server = Path::new("path/to/my/socket");
|
||||
/// let mut stream = UnixStream::connect(&server);
|
||||
/// stream.write([1, 2, 3]);
|
||||
/// ```
|
||||
pub fn connect<P: ToCStr>(path: &P) -> IoResult<UnixStream> {
|
||||
LocalIo::maybe_raise(|io| {
|
||||
io.unix_connect(&path.to_c_str()).map(UnixStream::new)
|
||||
})
|
||||
|
|
@ -66,11 +63,11 @@ impl UnixStream {
|
|||
}
|
||||
|
||||
impl Reader for UnixStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.obj.read(buf) }
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.obj.read(buf) }
|
||||
}
|
||||
|
||||
impl Writer for UnixStream {
|
||||
fn write(&mut self, buf: &[u8]) { self.obj.write(buf) }
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.obj.write(buf) }
|
||||
}
|
||||
|
||||
pub struct UnixListener {
|
||||
|
|
@ -84,23 +81,20 @@ impl UnixListener {
|
|||
///
|
||||
/// This listener will be closed when it falls out of scope.
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// This function will raise on the `io_error` condition if the specified
|
||||
/// path could not be bound.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// use std::io::net::unix::UnixListener;
|
||||
/// ```
|
||||
/// use std::io::net::unix::UnixListener;
|
||||
/// use std::io::Listener;
|
||||
///
|
||||
/// let server = Path("path/to/my/socket");
|
||||
/// let mut stream = UnixListener::bind(&server);
|
||||
/// for client in stream.incoming() {
|
||||
/// let mut client = client;
|
||||
/// client.write([1, 2, 3, 4]);
|
||||
/// }
|
||||
///
|
||||
pub fn bind<P: ToCStr>(path: &P) -> Option<UnixListener> {
|
||||
/// let server = Path::new("path/to/my/socket");
|
||||
/// let mut stream = UnixListener::bind(&server);
|
||||
/// for client in stream.incoming() {
|
||||
/// let mut client = client;
|
||||
/// client.write([1, 2, 3, 4]);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn bind<P: ToCStr>(path: &P) -> IoResult<UnixListener> {
|
||||
LocalIo::maybe_raise(|io| {
|
||||
io.unix_bind(&path.to_c_str()).map(|s| UnixListener { obj: s })
|
||||
})
|
||||
|
|
@ -108,14 +102,8 @@ impl UnixListener {
|
|||
}
|
||||
|
||||
impl Listener<UnixStream, UnixAcceptor> for UnixListener {
|
||||
fn listen(self) -> Option<UnixAcceptor> {
|
||||
match self.obj.listen() {
|
||||
Ok(acceptor) => Some(UnixAcceptor { obj: acceptor }),
|
||||
Err(ioerr) => {
|
||||
io_error::cond.raise(ioerr);
|
||||
None
|
||||
}
|
||||
}
|
||||
fn listen(self) -> IoResult<UnixAcceptor> {
|
||||
self.obj.listen().map(|obj| UnixAcceptor { obj: obj })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -124,14 +112,8 @@ pub struct UnixAcceptor {
|
|||
}
|
||||
|
||||
impl Acceptor<UnixStream> for UnixAcceptor {
|
||||
fn accept(&mut self) -> Option<UnixStream> {
|
||||
match self.obj.accept() {
|
||||
Ok(s) => Some(UnixStream::new(s)),
|
||||
Err(ioerr) => {
|
||||
io_error::cond.raise(ioerr);
|
||||
None
|
||||
}
|
||||
}
|
||||
fn accept(&mut self) -> IoResult<UnixStream> {
|
||||
self.obj.accept().map(UnixStream::new)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,39 +141,29 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn bind_error() {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert!(e.kind == PermissionDenied);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let listener = UnixListener::bind(&("path/to/nowhere"));
|
||||
assert!(listener.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
match UnixListener::bind(&("path/to/nowhere")) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, PermissionDenied),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn connect_error() {
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|e| {
|
||||
assert_eq!(e.kind,
|
||||
if cfg!(windows) {OtherIoError} else {FileNotFound});
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
let stream = UnixStream::connect(&("path/to/nowhere"));
|
||||
assert!(stream.is_none());
|
||||
});
|
||||
assert!(called);
|
||||
match UnixStream::connect(&("path/to/nowhere")) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind,
|
||||
if cfg!(windows) {OtherIoError} else {FileNotFound})
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke() {
|
||||
smalltest(proc(mut server) {
|
||||
let mut buf = [0];
|
||||
server.read(buf);
|
||||
server.read(buf).unwrap();
|
||||
assert!(buf[0] == 99);
|
||||
}, proc(mut client) {
|
||||
client.write([99]);
|
||||
client.write([99]).unwrap();
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -199,8 +171,8 @@ mod tests {
|
|||
fn read_eof() {
|
||||
smalltest(proc(mut server) {
|
||||
let mut buf = [0];
|
||||
assert!(server.read(buf).is_none());
|
||||
assert!(server.read(buf).is_none());
|
||||
assert!(server.read(buf).is_err());
|
||||
assert!(server.read(buf).is_err());
|
||||
}, proc(_client) {
|
||||
// drop the client
|
||||
})
|
||||
|
|
@ -210,15 +182,15 @@ mod tests {
|
|||
fn write_begone() {
|
||||
smalltest(proc(mut server) {
|
||||
let buf = [0];
|
||||
let mut stop = false;
|
||||
while !stop{
|
||||
io_error::cond.trap(|e| {
|
||||
assert!(e.kind == BrokenPipe || e.kind == NotConnected,
|
||||
"unknown error {:?}", e);
|
||||
stop = true;
|
||||
}).inside(|| {
|
||||
server.write(buf);
|
||||
})
|
||||
loop {
|
||||
match server.write(buf) {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
assert!(e.kind == BrokenPipe || e.kind == NotConnected,
|
||||
"unknown error {:?}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, proc(_client) {
|
||||
// drop the client
|
||||
|
|
@ -236,7 +208,7 @@ mod tests {
|
|||
port.recv();
|
||||
for _ in range(0, times) {
|
||||
let mut stream = UnixStream::connect(&path2);
|
||||
stream.write([100]);
|
||||
stream.write([100]).unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -245,7 +217,7 @@ mod tests {
|
|||
for _ in range(0, times) {
|
||||
let mut client = acceptor.accept();
|
||||
let mut buf = [0];
|
||||
client.read(buf);
|
||||
client.read(buf).unwrap();
|
||||
assert_eq!(buf[0], 100);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,154 +0,0 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementations of I/O traits for the Option type
|
||||
//!
|
||||
//! I/O constructors return option types to allow errors to be handled.
|
||||
//! These implementations allow e.g. `Option<File>` to be used
|
||||
//! as a `Reader` without unwrapping the option first.
|
||||
|
||||
use option::*;
|
||||
use super::{Reader, Writer, Listener, Acceptor, Seek, SeekStyle};
|
||||
use super::{standard_error, PreviousIoError, io_error, IoError};
|
||||
|
||||
fn prev_io_error() -> IoError {
|
||||
standard_error(PreviousIoError)
|
||||
}
|
||||
|
||||
impl<W: Writer> Writer for Option<W> {
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
match *self {
|
||||
Some(ref mut writer) => writer.write(buf),
|
||||
None => io_error::cond.raise(prev_io_error())
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) {
|
||||
match *self {
|
||||
Some(ref mut writer) => writer.flush(),
|
||||
None => io_error::cond.raise(prev_io_error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Reader> Reader for Option<R> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
match *self {
|
||||
Some(ref mut reader) => reader.read(buf),
|
||||
None => {
|
||||
io_error::cond.raise(prev_io_error());
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Seek> Seek for Option<S> {
|
||||
fn tell(&self) -> u64 {
|
||||
match *self {
|
||||
Some(ref seeker) => seeker.tell(),
|
||||
None => {
|
||||
io_error::cond.raise(prev_io_error());
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
fn seek(&mut self, pos: i64, style: SeekStyle) {
|
||||
match *self {
|
||||
Some(ref mut seeker) => seeker.seek(pos, style),
|
||||
None => io_error::cond.raise(prev_io_error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A: Acceptor<T>, L: Listener<T, A>> Listener<T, A> for Option<L> {
|
||||
fn listen(self) -> Option<A> {
|
||||
match self {
|
||||
Some(listener) => listener.listen(),
|
||||
None => {
|
||||
io_error::cond.raise(prev_io_error());
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A: Acceptor<T>> Acceptor<T> for Option<A> {
|
||||
fn accept(&mut self) -> Option<T> {
|
||||
match *self {
|
||||
Some(ref mut acceptor) => acceptor.accept(),
|
||||
None => {
|
||||
io_error::cond.raise(prev_io_error());
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use prelude::*;
|
||||
use super::super::mem::*;
|
||||
use super::super::{PreviousIoError, io_error};
|
||||
|
||||
#[test]
|
||||
fn test_option_writer() {
|
||||
let mut writer: Option<MemWriter> = Some(MemWriter::new());
|
||||
writer.write([0, 1, 2]);
|
||||
writer.flush();
|
||||
assert_eq!(writer.unwrap().unwrap(), ~[0, 1, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_writer_error() {
|
||||
let mut writer: Option<MemWriter> = None;
|
||||
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|err| {
|
||||
assert_eq!(err.kind, PreviousIoError);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
writer.write([0, 0, 0]);
|
||||
});
|
||||
assert!(called);
|
||||
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|err| {
|
||||
assert_eq!(err.kind, PreviousIoError);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
writer.flush();
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_reader() {
|
||||
let mut reader: Option<MemReader> = Some(MemReader::new(~[0, 1, 2, 3]));
|
||||
let mut buf = [0, 0];
|
||||
reader.read(buf);
|
||||
assert_eq!(buf, [0, 1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_reader_error() {
|
||||
let mut reader: Option<MemReader> = None;
|
||||
let mut buf = [];
|
||||
|
||||
let mut called = false;
|
||||
io_error::cond.trap(|err| {
|
||||
assert_eq!(err.kind, PreviousIoError);
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
reader.read(buf);
|
||||
});
|
||||
assert!(called);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
//! enough so that pipes can be created to child processes.
|
||||
|
||||
use prelude::*;
|
||||
use io::{io_error, EndOfFile};
|
||||
use io::IoResult;
|
||||
use libc;
|
||||
use rt::rtio::{RtioPipe, LocalIo};
|
||||
|
||||
|
|
@ -32,17 +32,15 @@ impl PipeStream {
|
|||
///
|
||||
/// # Example
|
||||
///
|
||||
/// use std::libc;
|
||||
/// use std::io::pipe;
|
||||
/// ```rust
|
||||
/// # #[allow(unused_must_use)];
|
||||
/// use std::libc;
|
||||
/// use std::io::pipe::PipeStream;
|
||||
///
|
||||
/// let mut pipe = PipeStream::open(libc::STDERR_FILENO);
|
||||
/// pipe.write(bytes!("Hello, stderr!"));
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// If the pipe cannot be created, an error will be raised on the
|
||||
/// `io_error` condition.
|
||||
pub fn open(fd: libc::c_int) -> Option<PipeStream> {
|
||||
/// let mut pipe = PipeStream::open(libc::STDERR_FILENO);
|
||||
/// pipe.write(bytes!("Hello, stderr!"));
|
||||
/// ```
|
||||
pub fn open(fd: libc::c_int) -> IoResult<PipeStream> {
|
||||
LocalIo::maybe_raise(|io| {
|
||||
io.pipe_open(fd).map(|obj| PipeStream { obj: obj })
|
||||
})
|
||||
|
|
@ -54,29 +52,11 @@ impl PipeStream {
|
|||
}
|
||||
|
||||
impl Reader for PipeStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
match self.obj.read(buf) {
|
||||
Ok(read) => Some(read),
|
||||
Err(ioerr) => {
|
||||
// EOF is indicated by returning None
|
||||
if ioerr.kind != EndOfFile {
|
||||
io_error::cond.raise(ioerr);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.obj.read(buf) }
|
||||
}
|
||||
|
||||
impl Writer for PipeStream {
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
match self.obj.write(buf) {
|
||||
Ok(_) => (),
|
||||
Err(ioerr) => {
|
||||
io_error::cond.raise(ioerr);
|
||||
}
|
||||
}
|
||||
}
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.obj.write(buf) }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -91,12 +71,12 @@ mod test {
|
|||
let (p, c) = Chan::new();
|
||||
spawn(proc() {
|
||||
let mut out = out;
|
||||
out.write([10]);
|
||||
out.write([10]).unwrap();
|
||||
p.recv(); // don't close the pipe until the other read has finished
|
||||
});
|
||||
|
||||
let mut buf = [0, ..10];
|
||||
input.read(buf);
|
||||
input.read(buf).unwrap();
|
||||
c.send(());
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use prelude::*;
|
|||
|
||||
use libc;
|
||||
use io;
|
||||
use io::io_error;
|
||||
use io::IoResult;
|
||||
use rt::rtio::{RtioProcess, IoFactory, LocalIo};
|
||||
|
||||
use fmt;
|
||||
|
|
@ -93,7 +93,7 @@ pub enum ProcessExit {
|
|||
|
||||
impl fmt::Show for ProcessExit {
|
||||
/// Format a ProcessExit enum, to nicely present the information.
|
||||
fn fmt(obj: &ProcessExit, f: &mut fmt::Formatter) {
|
||||
fn fmt(obj: &ProcessExit, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *obj {
|
||||
ExitStatus(code) => write!(f.buf, "exit code: {}", code),
|
||||
ExitSignal(code) => write!(f.buf, "signal: {}", code),
|
||||
|
|
@ -118,7 +118,7 @@ impl ProcessExit {
|
|||
impl Process {
|
||||
/// Creates a new pipe initialized, but not bound to any particular
|
||||
/// source/destination
|
||||
pub fn new(config: ProcessConfig) -> Option<Process> {
|
||||
pub fn new(config: ProcessConfig) -> IoResult<Process> {
|
||||
let mut config = Some(config);
|
||||
LocalIo::maybe_raise(|io| {
|
||||
io.spawn(config.take_unwrap()).map(|(p, io)| {
|
||||
|
|
@ -141,14 +141,9 @@ impl Process {
|
|||
/// Note that this is purely a wrapper around libuv's `uv_process_kill`
|
||||
/// function.
|
||||
///
|
||||
/// If the signal delivery fails, then the `io_error` condition is raised on
|
||||
pub fn signal(&mut self, signal: int) {
|
||||
match self.handle.kill(signal) {
|
||||
Ok(()) => {}
|
||||
Err(err) => {
|
||||
io_error::cond.raise(err)
|
||||
}
|
||||
}
|
||||
/// If the signal delivery fails, the corresponding error is returned.
|
||||
pub fn signal(&mut self, signal: int) -> IoResult<()> {
|
||||
self.handle.kill(signal)
|
||||
}
|
||||
|
||||
/// Wait for the child to exit completely, returning the status that it
|
||||
|
|
@ -176,7 +171,6 @@ impl Drop for Process {
|
|||
mod tests {
|
||||
use io::process::{ProcessConfig, Process};
|
||||
use prelude::*;
|
||||
use str;
|
||||
|
||||
// FIXME(#10380)
|
||||
#[cfg(unix, not(target_os="android"))]
|
||||
|
|
@ -190,7 +184,7 @@ mod tests {
|
|||
io: io,
|
||||
};
|
||||
let p = Process::new(args);
|
||||
assert!(p.is_some());
|
||||
assert!(p.is_ok());
|
||||
let mut p = p.unwrap();
|
||||
assert!(p.wait().success());
|
||||
})
|
||||
|
|
@ -206,7 +200,7 @@ mod tests {
|
|||
cwd: None,
|
||||
io: io,
|
||||
};
|
||||
match io::result(|| Process::new(args)) {
|
||||
match Process::new(args) {
|
||||
Ok(..) => fail!(),
|
||||
Err(..) => {}
|
||||
}
|
||||
|
|
@ -224,7 +218,7 @@ mod tests {
|
|||
io: io,
|
||||
};
|
||||
let p = Process::new(args);
|
||||
assert!(p.is_some());
|
||||
assert!(p.is_ok());
|
||||
let mut p = p.unwrap();
|
||||
assert!(p.wait().matches_exit_status(1));
|
||||
})
|
||||
|
|
@ -240,7 +234,7 @@ mod tests {
|
|||
io: io,
|
||||
};
|
||||
let p = Process::new(args);
|
||||
assert!(p.is_some());
|
||||
assert!(p.is_ok());
|
||||
let mut p = p.unwrap();
|
||||
match p.wait() {
|
||||
process::ExitSignal(1) => {},
|
||||
|
|
@ -249,20 +243,12 @@ mod tests {
|
|||
})
|
||||
|
||||
pub 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.push_str(str::from_utf8(buf.slice_to(n)).unwrap()); }
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
input.read_to_str().unwrap()
|
||||
}
|
||||
|
||||
pub fn run_output(args: ProcessConfig) -> ~str {
|
||||
let p = Process::new(args);
|
||||
assert!(p.is_some());
|
||||
assert!(p.is_ok());
|
||||
let mut p = p.unwrap();
|
||||
assert!(p.io[0].is_none());
|
||||
assert!(p.io[1].is_some());
|
||||
|
|
@ -312,8 +298,8 @@ mod tests {
|
|||
cwd: None,
|
||||
io: io,
|
||||
};
|
||||
let mut p = Process::new(args).expect("didn't create a proces?!");
|
||||
p.io[0].get_mut_ref().write("foobar".as_bytes());
|
||||
let mut p = Process::new(args).unwrap();
|
||||
p.io[0].get_mut_ref().write("foobar".as_bytes()).unwrap();
|
||||
p.io[0] = None; // close stdin;
|
||||
let out = read_all(p.io[1].get_mut_ref() as &mut Reader);
|
||||
assert!(p.wait().success());
|
||||
|
|
|
|||
128
src/libstd/io/result.rs
Normal file
128
src/libstd/io/result.rs
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementations of I/O traits for the IoResult type
|
||||
//!
|
||||
//! I/O constructors return option types to allow errors to be handled.
|
||||
//! These implementations allow e.g. `IoResult<File>` to be used
|
||||
//! as a `Reader` without unwrapping the result first.
|
||||
|
||||
use clone::Clone;
|
||||
use result::{Ok, Err};
|
||||
use super::{Reader, Writer, Listener, Acceptor, Seek, SeekStyle, IoResult};
|
||||
|
||||
impl<W: Writer> Writer for IoResult<W> {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
match *self {
|
||||
Ok(ref mut writer) => writer.write(buf),
|
||||
Err(ref e) => Err((*e).clone())
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> IoResult<()> {
|
||||
match *self {
|
||||
Ok(ref mut writer) => writer.flush(),
|
||||
Err(ref e) => Err(e.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Reader> Reader for IoResult<R> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
match *self {
|
||||
Ok(ref mut reader) => reader.read(buf),
|
||||
Err(ref e) => Err(e.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Seek> Seek for IoResult<S> {
|
||||
fn tell(&self) -> IoResult<u64> {
|
||||
match *self {
|
||||
Ok(ref seeker) => seeker.tell(),
|
||||
Err(ref e) => Err(e.clone()),
|
||||
}
|
||||
}
|
||||
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
|
||||
match *self {
|
||||
Ok(ref mut seeker) => seeker.seek(pos, style),
|
||||
Err(ref e) => Err(e.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A: Acceptor<T>, L: Listener<T, A>> Listener<T, A> for IoResult<L> {
|
||||
fn listen(self) -> IoResult<A> {
|
||||
match self {
|
||||
Ok(listener) => listener.listen(),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A: Acceptor<T>> Acceptor<T> for IoResult<A> {
|
||||
fn accept(&mut self) -> IoResult<T> {
|
||||
match *self {
|
||||
Ok(ref mut acceptor) => acceptor.accept(),
|
||||
Err(ref e) => Err(e.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use prelude::*;
|
||||
use super::super::mem::*;
|
||||
use io;
|
||||
|
||||
#[test]
|
||||
fn test_option_writer() {
|
||||
let mut writer: io::IoResult<MemWriter> = Ok(MemWriter::new());
|
||||
writer.write([0, 1, 2]).unwrap();
|
||||
writer.flush().unwrap();
|
||||
assert_eq!(writer.unwrap().unwrap(), ~[0, 1, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_writer_error() {
|
||||
let mut writer: io::IoResult<MemWriter> =
|
||||
Err(io::standard_error(io::EndOfFile));
|
||||
|
||||
match writer.write([0, 0, 0]) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, io::EndOfFile),
|
||||
}
|
||||
match writer.flush() {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, io::EndOfFile),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_reader() {
|
||||
let mut reader: io::IoResult<MemReader> =
|
||||
Ok(MemReader::new(~[0, 1, 2, 3]));
|
||||
let mut buf = [0, 0];
|
||||
reader.read(buf).unwrap();
|
||||
assert_eq!(buf, [0, 1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_reader_error() {
|
||||
let mut reader: io::IoResult<MemReader> =
|
||||
Err(io::standard_error(io::EndOfFile));
|
||||
let mut buf = [];
|
||||
|
||||
match reader.read(buf) {
|
||||
Ok(..) => fail!(),
|
||||
Err(e) => assert_eq!(e.kind, io::EndOfFile),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,10 +20,11 @@ definitions for a number of signals.
|
|||
*/
|
||||
|
||||
use clone::Clone;
|
||||
use result::{Ok, Err};
|
||||
use comm::{Port, SharedChan};
|
||||
use container::{Map, MutableMap};
|
||||
use hashmap;
|
||||
use option::{Some, None};
|
||||
use io;
|
||||
use rt::rtio::{IoFactory, LocalIo, RtioSignal};
|
||||
|
||||
#[repr(int)]
|
||||
|
|
@ -112,23 +113,22 @@ impl Listener {
|
|||
/// a signal, and a later call to `recv` will return the signal that was
|
||||
/// received while no task was waiting on it.
|
||||
///
|
||||
/// # Failure
|
||||
/// # Error
|
||||
///
|
||||
/// If this function fails to register a signal handler, then an error will
|
||||
/// be raised on the `io_error` condition and the function will return
|
||||
/// false.
|
||||
pub fn register(&mut self, signum: Signum) -> bool {
|
||||
/// be returned.
|
||||
pub fn register(&mut self, signum: Signum) -> io::IoResult<()> {
|
||||
if self.handles.contains_key(&signum) {
|
||||
return true; // self is already listening to signum, so succeed
|
||||
return Ok(()); // self is already listening to signum, so succeed
|
||||
}
|
||||
match LocalIo::maybe_raise(|io| {
|
||||
io.signal(signum, self.chan.clone())
|
||||
}) {
|
||||
Some(handle) => {
|
||||
Ok(handle) => {
|
||||
self.handles.insert(signum, handle);
|
||||
true
|
||||
Ok(())
|
||||
}
|
||||
None => false
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +159,7 @@ mod test {
|
|||
#[test] #[cfg(unix, not(target_os="android"))] // FIXME(#10378)
|
||||
fn test_io_signal_smoketest() {
|
||||
let mut signal = Listener::new();
|
||||
signal.register(Interrupt);
|
||||
signal.register(Interrupt).unwrap();
|
||||
sigint();
|
||||
timer::sleep(10);
|
||||
match signal.port.recv() {
|
||||
|
|
@ -172,8 +172,8 @@ mod test {
|
|||
fn test_io_signal_two_signal_one_signum() {
|
||||
let mut s1 = Listener::new();
|
||||
let mut s2 = Listener::new();
|
||||
s1.register(Interrupt);
|
||||
s2.register(Interrupt);
|
||||
s1.register(Interrupt).unwrap();
|
||||
s2.register(Interrupt).unwrap();
|
||||
sigint();
|
||||
timer::sleep(10);
|
||||
match s1.port.recv() {
|
||||
|
|
@ -190,8 +190,8 @@ mod test {
|
|||
fn test_io_signal_unregister() {
|
||||
let mut s1 = Listener::new();
|
||||
let mut s2 = Listener::new();
|
||||
s1.register(Interrupt);
|
||||
s2.register(Interrupt);
|
||||
s1.register(Interrupt).unwrap();
|
||||
s2.register(Interrupt).unwrap();
|
||||
s2.unregister(Interrupt);
|
||||
sigint();
|
||||
timer::sleep(10);
|
||||
|
|
@ -203,15 +203,14 @@ mod test {
|
|||
fn test_io_signal_invalid_signum() {
|
||||
use io;
|
||||
use super::User1;
|
||||
use result::{Ok, Err};
|
||||
let mut s = Listener::new();
|
||||
let mut called = false;
|
||||
io::io_error::cond.trap(|_| {
|
||||
called = true;
|
||||
}).inside(|| {
|
||||
if s.register(User1) {
|
||||
match s.register(User1) {
|
||||
Ok(..) => {
|
||||
fail!("Unexpected successful registry of signum {:?}", User1);
|
||||
}
|
||||
});
|
||||
assert!(called);
|
||||
Err(..) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ about the stream or terminal that it is attached to.
|
|||
# Example
|
||||
|
||||
```rust
|
||||
# #[allow(unused_must_use)];
|
||||
use std::io;
|
||||
|
||||
let mut out = io::stdout();
|
||||
|
|
@ -28,7 +29,7 @@ out.write(bytes!("Hello, world!"));
|
|||
|
||||
use container::Container;
|
||||
use fmt;
|
||||
use io::{Reader, Writer, io_error, IoError, OtherIoError,
|
||||
use io::{Reader, Writer, IoResult, IoError, OtherIoError,
|
||||
standard_error, EndOfFile, LineBufferedWriter};
|
||||
use libc;
|
||||
use option::{Option, Some, None};
|
||||
|
|
@ -114,7 +115,8 @@ fn reset_helper(w: ~Writer,
|
|||
match f(t.get(), w) {
|
||||
Some(mut w) => {
|
||||
drop(t);
|
||||
w.flush();
|
||||
// FIXME: is failing right here?
|
||||
w.flush().unwrap();
|
||||
Some(w)
|
||||
}
|
||||
None => None
|
||||
|
|
@ -155,9 +157,9 @@ pub fn set_stderr(stderr: ~Writer) -> Option<~Writer> {
|
|||
// // io1 aliases io2
|
||||
// })
|
||||
// })
|
||||
fn with_task_stdout(f: |&mut Writer|) {
|
||||
fn with_task_stdout(f: |&mut Writer| -> IoResult<()> ) {
|
||||
let task: Option<~Task> = Local::try_take();
|
||||
match task {
|
||||
let result = match task {
|
||||
Some(mut task) => {
|
||||
// Printing may run arbitrary code, so ensure that the task is in
|
||||
// TLS to allow all std services. Note that this means a print while
|
||||
|
|
@ -169,7 +171,7 @@ fn with_task_stdout(f: |&mut Writer|) {
|
|||
if my_stdout.is_none() {
|
||||
my_stdout = Some(~LineBufferedWriter::new(stdout()) as ~Writer);
|
||||
}
|
||||
f(*my_stdout.get_mut_ref());
|
||||
let ret = f(*my_stdout.get_mut_ref());
|
||||
|
||||
// Note that we need to be careful when putting the stdout handle
|
||||
// back into the task. If the handle was set to `Some` while
|
||||
|
|
@ -184,22 +186,29 @@ fn with_task_stdout(f: |&mut Writer|) {
|
|||
let prev = util::replace(&mut t.get().stdout, my_stdout);
|
||||
drop(t);
|
||||
drop(prev);
|
||||
ret
|
||||
}
|
||||
|
||||
None => {
|
||||
struct Stdout;
|
||||
impl Writer for Stdout {
|
||||
fn write(&mut self, data: &[u8]) {
|
||||
fn write(&mut self, data: &[u8]) -> IoResult<()> {
|
||||
unsafe {
|
||||
libc::write(libc::STDOUT_FILENO,
|
||||
data.as_ptr() as *libc::c_void,
|
||||
data.len() as libc::size_t);
|
||||
}
|
||||
Ok(()) // just ignore the results
|
||||
}
|
||||
}
|
||||
let mut io = Stdout;
|
||||
f(&mut io as &mut Writer);
|
||||
f(&mut io as &mut Writer)
|
||||
}
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(()) => {}
|
||||
Err(e) => fail!("failed printing to stdout: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -226,8 +235,7 @@ pub fn print(s: &str) {
|
|||
/// `\n` character is printed to the console after the string.
|
||||
pub fn println(s: &str) {
|
||||
with_task_stdout(|io| {
|
||||
io.write(s.as_bytes());
|
||||
io.write(['\n' as u8]);
|
||||
io.write(s.as_bytes()).and_then(|()| io.write(['\n' as u8]))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -249,7 +257,7 @@ pub struct StdReader {
|
|||
}
|
||||
|
||||
impl Reader for StdReader {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||
let ret = match self.inner {
|
||||
TTY(ref mut tty) => tty.read(buf),
|
||||
File(ref mut file) => file.read(buf).map(|i| i as uint),
|
||||
|
|
@ -260,15 +268,8 @@ impl Reader for StdReader {
|
|||
// return an actual EOF error, but apparently for stdin it's a
|
||||
// little different. Hence, here we convert a 0 length read to an
|
||||
// end-of-file indicator so the caller knows to stop reading.
|
||||
Ok(0) => {
|
||||
io_error::cond.raise(standard_error(EndOfFile));
|
||||
None
|
||||
}
|
||||
Ok(amt) => Some(amt),
|
||||
Err(e) => {
|
||||
io_error::cond.raise(e);
|
||||
None
|
||||
}
|
||||
Ok(0) => { Err(standard_error(EndOfFile)) }
|
||||
ret @ Ok(..) | ret @ Err(..) => ret,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -283,30 +284,21 @@ impl StdWriter {
|
|||
/// when the writer is attached to something like a terminal, this is used
|
||||
/// to fetch the dimensions of the terminal.
|
||||
///
|
||||
/// If successful, returns Some((width, height)).
|
||||
/// If successful, returns `Ok((width, height))`.
|
||||
///
|
||||
/// # Failure
|
||||
/// # Error
|
||||
///
|
||||
/// This function will raise on the `io_error` condition if an error
|
||||
/// happens.
|
||||
pub fn winsize(&mut self) -> Option<(int, int)> {
|
||||
/// This function will return an error if the output stream is not actually
|
||||
/// connected to a TTY instance, or if querying the TTY instance fails.
|
||||
pub fn winsize(&mut self) -> IoResult<(int, int)> {
|
||||
match self.inner {
|
||||
TTY(ref mut tty) => {
|
||||
match tty.get_winsize() {
|
||||
Ok(p) => Some(p),
|
||||
Err(e) => {
|
||||
io_error::cond.raise(e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
TTY(ref mut tty) => tty.get_winsize(),
|
||||
File(..) => {
|
||||
io_error::cond.raise(IoError {
|
||||
Err(IoError {
|
||||
kind: OtherIoError,
|
||||
desc: "stream is not a tty",
|
||||
detail: None,
|
||||
});
|
||||
None
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -314,24 +306,19 @@ impl StdWriter {
|
|||
/// Controls whether this output stream is a "raw stream" or simply a normal
|
||||
/// stream.
|
||||
///
|
||||
/// # Failure
|
||||
/// # Error
|
||||
///
|
||||
/// This function will raise on the `io_error` condition if an error
|
||||
/// happens.
|
||||
pub fn set_raw(&mut self, raw: bool) {
|
||||
/// This function will return an error if the output stream is not actually
|
||||
/// connected to a TTY instance, or if querying the TTY instance fails.
|
||||
pub fn set_raw(&mut self, raw: bool) -> IoResult<()> {
|
||||
match self.inner {
|
||||
TTY(ref mut tty) => {
|
||||
match tty.set_raw(raw) {
|
||||
Ok(()) => {},
|
||||
Err(e) => io_error::cond.raise(e),
|
||||
}
|
||||
}
|
||||
TTY(ref mut tty) => tty.set_raw(raw),
|
||||
File(..) => {
|
||||
io_error::cond.raise(IoError {
|
||||
Err(IoError {
|
||||
kind: OtherIoError,
|
||||
desc: "stream is not a tty",
|
||||
detail: None,
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -346,14 +333,10 @@ impl StdWriter {
|
|||
}
|
||||
|
||||
impl Writer for StdWriter {
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
let ret = match self.inner {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
match self.inner {
|
||||
TTY(ref mut tty) => tty.write(buf),
|
||||
File(ref mut file) => file.write(buf),
|
||||
};
|
||||
match ret {
|
||||
Ok(()) => {}
|
||||
Err(e) => io_error::cond.raise(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -376,7 +359,7 @@ mod tests {
|
|||
set_stdout(~w as ~Writer);
|
||||
println!("hello!");
|
||||
});
|
||||
assert_eq!(r.read_to_str(), ~"hello!\n");
|
||||
assert_eq!(r.read_to_str().unwrap(), ~"hello!\n");
|
||||
})
|
||||
|
||||
iotest!(fn capture_stderr() {
|
||||
|
|
@ -388,7 +371,7 @@ mod tests {
|
|||
set_stderr(~w as ~Writer);
|
||||
fail!("my special message");
|
||||
});
|
||||
let s = r.read_to_str();
|
||||
let s = r.read_to_str().unwrap();
|
||||
assert!(s.contains("my special message"));
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ loop {
|
|||
*/
|
||||
|
||||
use comm::Port;
|
||||
use option::Option;
|
||||
use rt::rtio::{IoFactory, LocalIo, RtioTimer};
|
||||
use io::IoResult;
|
||||
|
||||
pub struct Timer {
|
||||
priv obj: ~RtioTimer
|
||||
|
|
@ -48,7 +48,8 @@ pub struct Timer {
|
|||
|
||||
/// Sleep the current task for `msecs` milliseconds.
|
||||
pub fn sleep(msecs: u64) {
|
||||
let mut timer = Timer::new().expect("timer::sleep: could not create a Timer");
|
||||
let timer = Timer::new();
|
||||
let mut timer = timer.ok().expect("timer::sleep: could not create a Timer");
|
||||
|
||||
timer.sleep(msecs)
|
||||
}
|
||||
|
|
@ -57,7 +58,7 @@ impl Timer {
|
|||
/// Creates a new timer which can be used to put the current task to sleep
|
||||
/// for a number of milliseconds, or to possibly create channels which will
|
||||
/// get notified after an amount of time has passed.
|
||||
pub fn new() -> Option<Timer> {
|
||||
pub fn new() -> IoResult<Timer> {
|
||||
LocalIo::maybe_raise(|io| io.timer_init().map(|t| Timer { obj: t }))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@
|
|||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use prelude::*;
|
||||
use cmp;
|
||||
use io;
|
||||
use vec::bytes::MutableByteVector;
|
||||
|
||||
/// Wraps a `Reader`, limiting the number of bytes that can be read from it.
|
||||
|
|
@ -25,9 +27,9 @@ impl<'a, R: Reader> LimitReader<'a, R> {
|
|||
}
|
||||
|
||||
impl<'a, R: Reader> Reader for LimitReader<'a, R> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
||||
if self.limit == 0 {
|
||||
return None;
|
||||
return Err(io::standard_error(io::EndOfFile));
|
||||
}
|
||||
|
||||
let len = cmp::min(self.limit, buf.len());
|
||||
|
|
@ -43,7 +45,7 @@ pub struct NullWriter;
|
|||
|
||||
impl Writer for NullWriter {
|
||||
#[inline]
|
||||
fn write(&mut self, _buf: &[u8]) { }
|
||||
fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> { Ok(()) }
|
||||
}
|
||||
|
||||
/// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
|
||||
|
|
@ -51,9 +53,9 @@ pub struct ZeroReader;
|
|||
|
||||
impl Reader for ZeroReader {
|
||||
#[inline]
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
||||
buf.set_memory(0);
|
||||
Some(buf.len())
|
||||
Ok(buf.len())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,8 +64,8 @@ pub struct NullReader;
|
|||
|
||||
impl Reader for NullReader {
|
||||
#[inline]
|
||||
fn read(&mut self, _buf: &mut [u8]) -> Option<uint> {
|
||||
None
|
||||
fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
|
||||
Err(io::standard_error(io::EndOfFile))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,17 +83,21 @@ impl MultiWriter {
|
|||
|
||||
impl Writer for MultiWriter {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
|
||||
let mut ret = Ok(());
|
||||
for writer in self.writers.mut_iter() {
|
||||
writer.write(buf);
|
||||
ret = ret.and(writer.write(buf));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) {
|
||||
fn flush(&mut self) -> io::IoResult<()> {
|
||||
let mut ret = Ok(());
|
||||
for writer in self.writers.mut_iter() {
|
||||
writer.flush();
|
||||
ret = ret.and(writer.flush());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -111,20 +117,25 @@ impl<R: Reader, I: Iterator<R>> ChainedReader<I, R> {
|
|||
}
|
||||
|
||||
impl<R: Reader, I: Iterator<R>> Reader for ChainedReader<I, R> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
||||
loop {
|
||||
match self.cur_reader {
|
||||
let err = match self.cur_reader {
|
||||
Some(ref mut r) => {
|
||||
match r.read(buf) {
|
||||
Some(len) => return Some(len),
|
||||
None => {}
|
||||
Ok(len) => return Ok(len),
|
||||
Err(ref e) if e.kind == io::EndOfFile => None,
|
||||
Err(e) => Some(e),
|
||||
}
|
||||
}
|
||||
None => break
|
||||
};
|
||||
self.cur_reader = self.readers.next();
|
||||
match err {
|
||||
Some(e) => return Err(e),
|
||||
None => {}
|
||||
}
|
||||
self.cur_reader = self.readers.next()
|
||||
}
|
||||
None
|
||||
Err(io::standard_error(io::EndOfFile))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,27 +161,29 @@ impl<R: Reader, W: Writer> TeeReader<R, W> {
|
|||
}
|
||||
|
||||
impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
|
||||
self.reader.read(buf).map(|len| {
|
||||
self.writer.write(buf.slice_to(len));
|
||||
len
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
|
||||
self.reader.read(buf).and_then(|len| {
|
||||
self.writer.write(buf.slice_to(len)).map(|()| len)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Copies all data from a `Reader` to a `Writer`.
|
||||
pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) {
|
||||
pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
|
||||
let mut buf = [0, ..super::DEFAULT_BUF_SIZE];
|
||||
loop {
|
||||
match r.read(buf) {
|
||||
Some(len) => w.write(buf.slice_to(len)),
|
||||
None => break
|
||||
}
|
||||
let len = match r.read(buf) {
|
||||
Ok(len) => len,
|
||||
Err(ref e) if e.kind == io::EndOfFile => return Ok(()),
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
if_ok!(w.write(buf.slice_to(len)));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use io;
|
||||
use io::{MemReader, MemWriter};
|
||||
use super::*;
|
||||
use prelude::*;
|
||||
|
|
@ -180,7 +193,7 @@ mod test {
|
|||
let mut r = MemReader::new(~[0, 1, 2]);
|
||||
{
|
||||
let mut r = LimitReader::new(&mut r, 4);
|
||||
assert_eq!(~[0, 1, 2], r.read_to_end());
|
||||
assert_eq!(~[0, 1, 2], r.read_to_end().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -189,24 +202,24 @@ mod test {
|
|||
let mut r = MemReader::new(~[0, 1, 2]);
|
||||
{
|
||||
let mut r = LimitReader::new(&mut r, 2);
|
||||
assert_eq!(~[0, 1], r.read_to_end());
|
||||
assert_eq!(~[0, 1], r.read_to_end().unwrap());
|
||||
}
|
||||
assert_eq!(~[2], r.read_to_end());
|
||||
assert_eq!(~[2], r.read_to_end().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_null_writer() {
|
||||
let mut s = NullWriter;
|
||||
let buf = ~[0, 0, 0];
|
||||
s.write(buf);
|
||||
s.flush();
|
||||
s.write(buf).unwrap();
|
||||
s.flush().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero_reader() {
|
||||
let mut s = ZeroReader;
|
||||
let mut buf = ~[1, 2, 3];
|
||||
assert_eq!(s.read(buf), Some(3));
|
||||
assert_eq!(s.read(buf), Ok(3));
|
||||
assert_eq!(~[0, 0, 0], buf);
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +227,7 @@ mod test {
|
|||
fn test_null_reader() {
|
||||
let mut r = NullReader;
|
||||
let mut buf = ~[0];
|
||||
assert_eq!(r.read(buf), None);
|
||||
assert!(r.read(buf).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -224,21 +237,23 @@ mod test {
|
|||
|
||||
struct TestWriter;
|
||||
impl Writer for TestWriter {
|
||||
fn write(&mut self, _buf: &[u8]) {
|
||||
fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> {
|
||||
unsafe { writes += 1 }
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn flush(&mut self) {
|
||||
fn flush(&mut self) -> io::IoResult<()> {
|
||||
unsafe { flushes += 1 }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
let mut multi = MultiWriter::new(~[~TestWriter as ~Writer,
|
||||
~TestWriter as ~Writer]);
|
||||
multi.write([1, 2, 3]);
|
||||
multi.write([1, 2, 3]).unwrap();
|
||||
assert_eq!(2, unsafe { writes });
|
||||
assert_eq!(0, unsafe { flushes });
|
||||
multi.flush();
|
||||
multi.flush().unwrap();
|
||||
assert_eq!(2, unsafe { writes });
|
||||
assert_eq!(2, unsafe { flushes });
|
||||
}
|
||||
|
|
@ -248,14 +263,14 @@ mod test {
|
|||
let rs = ~[MemReader::new(~[0, 1]), MemReader::new(~[]),
|
||||
MemReader::new(~[2, 3])];
|
||||
let mut r = ChainedReader::new(rs.move_iter());
|
||||
assert_eq!(~[0, 1, 2, 3], r.read_to_end());
|
||||
assert_eq!(~[0, 1, 2, 3], r.read_to_end().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tee_reader() {
|
||||
let mut r = TeeReader::new(MemReader::new(~[0, 1, 2]),
|
||||
MemWriter::new());
|
||||
assert_eq!(~[0, 1, 2], r.read_to_end());
|
||||
assert_eq!(~[0, 1, 2], r.read_to_end().unwrap());
|
||||
let (_, w) = r.unwrap();
|
||||
assert_eq!(~[0, 1, 2], w.unwrap());
|
||||
}
|
||||
|
|
@ -264,7 +279,7 @@ mod test {
|
|||
fn test_copy() {
|
||||
let mut r = MemReader::new(~[0, 1, 2, 3, 4]);
|
||||
let mut w = MemWriter::new();
|
||||
copy(&mut r, &mut w);
|
||||
copy(&mut r, &mut w).unwrap();
|
||||
assert_eq!(~[0, 1, 2, 3, 4], w.unwrap());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ use io::Writer;
|
|||
use ops::Drop;
|
||||
use option::{Some, None, Option};
|
||||
use prelude::drop;
|
||||
use result::{Ok, Err};
|
||||
use rt::local::Local;
|
||||
use rt::task::Task;
|
||||
use util;
|
||||
|
|
@ -131,13 +132,19 @@ struct DefaultLogger {
|
|||
impl Logger for DefaultLogger {
|
||||
// by default, just ignore the level
|
||||
fn log(&mut self, _level: u32, args: &fmt::Arguments) {
|
||||
fmt::writeln(&mut self.handle, args);
|
||||
match fmt::writeln(&mut self.handle, args) {
|
||||
Err(e) => fail!("failed to log: {}", e),
|
||||
Ok(()) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DefaultLogger {
|
||||
fn drop(&mut self) {
|
||||
self.handle.flush();
|
||||
match self.handle.flush() {
|
||||
Err(e) => fail!("failed to flush a logger: {}", e),
|
||||
Ok(()) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -197,3 +197,8 @@ macro_rules! local_data_key (
|
|||
pub static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
|
||||
)
|
||||
)
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! if_ok (
|
||||
($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
|
||||
)
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ impl<T: Default> Option<T> {
|
|||
|
||||
impl<T: fmt::Show> fmt::Show for Option<T> {
|
||||
#[inline]
|
||||
fn fmt(s: &Option<T>, f: &mut fmt::Formatter) {
|
||||
fn fmt(s: &Option<T>, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *s {
|
||||
Some(ref t) => write!(f.buf, "Some({})", *t),
|
||||
None => write!(f.buf, "None")
|
||||
|
|
|
|||
|
|
@ -372,9 +372,9 @@ pub fn self_exe_name() -> Option<Path> {
|
|||
fn load_self() -> Option<~[u8]> {
|
||||
use std::io;
|
||||
|
||||
match io::result(|| io::fs::readlink(&Path::new("/proc/self/exe"))) {
|
||||
Ok(Some(path)) => Some(path.as_vec().to_owned()),
|
||||
Ok(None) | Err(..) => None
|
||||
match io::fs::readlink(&Path::new("/proc/self/exe")) {
|
||||
Ok(path) => Some(path.as_vec().to_owned()),
|
||||
Err(..) => None
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -929,7 +929,7 @@ pub enum MapError {
|
|||
}
|
||||
|
||||
impl fmt::Show for MapError {
|
||||
fn fmt(val: &MapError, out: &mut fmt::Formatter) {
|
||||
fn fmt(val: &MapError, out: &mut fmt::Formatter) -> fmt::Result {
|
||||
let str = match *val {
|
||||
ErrFdNotAvail => "fd not available for reading or writing",
|
||||
ErrInvalidFd => "Invalid fd",
|
||||
|
|
@ -944,23 +944,19 @@ impl fmt::Show for MapError {
|
|||
ErrAlreadyExists => "File mapping for specified file already exists",
|
||||
ErrZeroLength => "Zero-length mapping not allowed",
|
||||
ErrUnknown(code) => {
|
||||
write!(out.buf, "Unknown error = {}", code);
|
||||
return
|
||||
return write!(out.buf, "Unknown error = {}", code)
|
||||
},
|
||||
ErrVirtualAlloc(code) => {
|
||||
write!(out.buf, "VirtualAlloc failure = {}", code);
|
||||
return
|
||||
return write!(out.buf, "VirtualAlloc failure = {}", code)
|
||||
},
|
||||
ErrCreateFileMappingW(code) => {
|
||||
format!("CreateFileMappingW failure = {}", code);
|
||||
return
|
||||
return write!(out.buf, "CreateFileMappingW failure = {}", code)
|
||||
},
|
||||
ErrMapViewOfFile(code) => {
|
||||
write!(out.buf, "MapViewOfFile failure = {}", code);
|
||||
return
|
||||
return write!(out.buf, "MapViewOfFile failure = {}", code)
|
||||
}
|
||||
};
|
||||
write!(out.buf, "{}", str);
|
||||
write!(out.buf, "{}", str)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1496,7 +1492,6 @@ mod tests {
|
|||
use result::{Ok, Err};
|
||||
use os::*;
|
||||
use libc::*;
|
||||
use io;
|
||||
use io::fs;
|
||||
|
||||
#[cfg(unix)]
|
||||
|
|
@ -1540,9 +1535,9 @@ mod tests {
|
|||
assert!(*chunk.data == 0xbe);
|
||||
close(fd);
|
||||
}
|
||||
drop(chunk);
|
||||
|
||||
let _guard = io::ignore_io_error();
|
||||
fs::unlink(&path);
|
||||
fs::unlink(&path).unwrap();
|
||||
}
|
||||
|
||||
// More recursive_mkdir tests are in extra::tempfile
|
||||
|
|
|
|||
|
|
@ -533,7 +533,7 @@ pub struct Display<'a, P> {
|
|||
}
|
||||
|
||||
impl<'a, P: GenericPath> fmt::Show for Display<'a, P> {
|
||||
fn fmt(d: &Display<P>, f: &mut fmt::Formatter) {
|
||||
fn fmt(d: &Display<P>, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
d.with_str(|s| f.pad(s))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ impl OSRng {
|
|||
pub fn new() -> OSRng {
|
||||
use path::Path;
|
||||
let reader = File::open(&Path::new("/dev/urandom"));
|
||||
let reader = reader.expect("Error opening /dev/urandom");
|
||||
let reader = reader.ok().expect("Error opening /dev/urandom");
|
||||
let reader_rng = ReaderRng::new(reader);
|
||||
|
||||
OSRng { inner: reader_rng }
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
//! A wrapper around any Reader to treat it as an RNG.
|
||||
|
||||
use container::Container;
|
||||
use option::{Some, None};
|
||||
use result::{Ok, Err};
|
||||
use io::Reader;
|
||||
|
||||
use rand::Rng;
|
||||
|
|
@ -49,26 +49,26 @@ impl<R: Reader> Rng for ReaderRng<R> {
|
|||
// platform just involves blitting the bytes into the memory
|
||||
// of the u32, similarly for BE on BE; avoiding byteswapping.
|
||||
if cfg!(target_endian="little") {
|
||||
self.reader.read_le_u32()
|
||||
self.reader.read_le_u32().unwrap()
|
||||
} else {
|
||||
self.reader.read_be_u32()
|
||||
self.reader.read_be_u32().unwrap()
|
||||
}
|
||||
}
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
// see above for explanation.
|
||||
if cfg!(target_endian="little") {
|
||||
self.reader.read_le_u64()
|
||||
self.reader.read_le_u64().unwrap()
|
||||
} else {
|
||||
self.reader.read_be_u64()
|
||||
self.reader.read_be_u64().unwrap()
|
||||
}
|
||||
}
|
||||
fn fill_bytes(&mut self, v: &mut [u8]) {
|
||||
if v.len() == 0 { return }
|
||||
match self.reader.read(v) {
|
||||
Some(n) if n == v.len() => return,
|
||||
Some(n) => fail!("ReaderRng.fill_bytes could not fill buffer: \
|
||||
read {} out of {} bytes.", n, v.len()),
|
||||
None => fail!("ReaderRng.fill_bytes reached eof.")
|
||||
Ok(n) if n == v.len() => return,
|
||||
Ok(n) => fail!("ReaderRng.fill_bytes could not fill buffer: \
|
||||
read {} out of {} bytes.", n, v.len()),
|
||||
Err(e) => fail!("ReaderRng.fill_bytes error: {}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ impl<V:TyVisitor + MovePtr> MovePtrAdaptor<V> {
|
|||
pub fn bump_past<T>(&mut self) {
|
||||
self.bump(mem::size_of::<T>());
|
||||
}
|
||||
|
||||
pub fn unwrap(self) -> V { self.inner }
|
||||
}
|
||||
|
||||
/// Abstract type-directed pointer-movement using the MovePtr trait
|
||||
|
|
|
|||
|
|
@ -21,48 +21,57 @@ use char;
|
|||
use container::Container;
|
||||
use io;
|
||||
use iter::Iterator;
|
||||
use option::{Some, None};
|
||||
use option::{Some, None, Option};
|
||||
use ptr;
|
||||
use reflect;
|
||||
use reflect::{MovePtr, align};
|
||||
use result::{Ok, Err};
|
||||
use str::StrSlice;
|
||||
use to_str::ToStr;
|
||||
use vec::OwnedVector;
|
||||
use unstable::intrinsics::{Disr, Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
|
||||
use unstable::raw;
|
||||
|
||||
macro_rules! if_ok( ($me:expr, $e:expr) => (
|
||||
match $e {
|
||||
Ok(()) => {},
|
||||
Err(e) => { $me.last_err = Some(e); return false; }
|
||||
}
|
||||
) )
|
||||
|
||||
/// Representations
|
||||
|
||||
trait Repr {
|
||||
fn write_repr(&self, writer: &mut io::Writer);
|
||||
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()>;
|
||||
}
|
||||
|
||||
impl Repr for () {
|
||||
fn write_repr(&self, writer: &mut io::Writer) {
|
||||
writer.write("()".as_bytes());
|
||||
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
|
||||
writer.write("()".as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl Repr for bool {
|
||||
fn write_repr(&self, writer: &mut io::Writer) {
|
||||
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
|
||||
let s = if *self { "true" } else { "false" };
|
||||
writer.write(s.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl Repr for int {
|
||||
fn write_repr(&self, writer: &mut io::Writer) {
|
||||
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
|
||||
::int::to_str_bytes(*self, 10u, |bits| {
|
||||
writer.write(bits);
|
||||
writer.write(bits)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! int_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty {
|
||||
fn write_repr(&self, writer: &mut io::Writer) {
|
||||
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
|
||||
::$ty::to_str_bytes(*self, 10u, |bits| {
|
||||
writer.write(bits);
|
||||
writer.write(bytes!($suffix));
|
||||
writer.write(bits).and_then(|()| {
|
||||
writer.write(bytes!($suffix))
|
||||
})
|
||||
})
|
||||
}
|
||||
}))
|
||||
|
|
@ -78,10 +87,11 @@ int_repr!(u32, "u32")
|
|||
int_repr!(u64, "u64")
|
||||
|
||||
macro_rules! num_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty {
|
||||
fn write_repr(&self, writer: &mut io::Writer) {
|
||||
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
|
||||
let s = self.to_str();
|
||||
writer.write(s.as_bytes());
|
||||
writer.write(bytes!($suffix));
|
||||
writer.write(s.as_bytes()).and_then(|()| {
|
||||
writer.write(bytes!($suffix))
|
||||
})
|
||||
}
|
||||
}))
|
||||
|
||||
|
|
@ -100,7 +110,8 @@ pub struct ReprVisitor<'a> {
|
|||
priv ptr: *u8,
|
||||
priv ptr_stk: ~[*u8],
|
||||
priv var_stk: ~[VariantState],
|
||||
priv writer: &'a mut io::Writer
|
||||
priv writer: &'a mut io::Writer,
|
||||
priv last_err: Option<io::IoError>,
|
||||
}
|
||||
|
||||
pub fn ReprVisitor<'a>(ptr: *u8,
|
||||
|
|
@ -110,6 +121,7 @@ pub fn ReprVisitor<'a>(ptr: *u8,
|
|||
ptr_stk: ~[],
|
||||
var_stk: ~[],
|
||||
writer: writer,
|
||||
last_err: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,11 +142,10 @@ impl<'a> ReprVisitor<'a> {
|
|||
// Various helpers for the TyVisitor impl
|
||||
|
||||
#[inline]
|
||||
pub fn get<T>(&mut self, f: |&mut ReprVisitor, &T|) -> bool {
|
||||
pub fn get<T>(&mut self, f: |&mut ReprVisitor, &T| -> bool) -> bool {
|
||||
unsafe {
|
||||
f(self, transmute::<*u8,&T>(self.ptr));
|
||||
f(self, transmute::<*u8,&T>(self.ptr))
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -152,43 +163,53 @@ impl<'a> ReprVisitor<'a> {
|
|||
ptr_stk: ~[],
|
||||
var_stk: ~[],
|
||||
writer: ::cast::transmute_copy(&self.writer),
|
||||
last_err: None,
|
||||
};
|
||||
let mut v = reflect::MovePtrAdaptor(u);
|
||||
// Obviously this should not be a thing, but blame #8401 for now
|
||||
visit_tydesc(inner, &mut v as &mut TyVisitor);
|
||||
true
|
||||
match v.unwrap().last_err {
|
||||
Some(e) => {
|
||||
self.last_err = Some(e);
|
||||
false
|
||||
}
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn write<T:Repr>(&mut self) -> bool {
|
||||
self.get(|this, v:&T| {
|
||||
v.write_repr(unsafe { ::cast::transmute_copy(&this.writer) });
|
||||
if_ok!(this, v.write_repr(this.writer));
|
||||
true
|
||||
})
|
||||
}
|
||||
|
||||
pub fn write_escaped_slice(&mut self, slice: &str) {
|
||||
self.writer.write(['"' as u8]);
|
||||
pub fn write_escaped_slice(&mut self, slice: &str) -> bool {
|
||||
if_ok!(self, self.writer.write(['"' as u8]));
|
||||
for ch in slice.chars() {
|
||||
self.write_escaped_char(ch, true);
|
||||
if !self.write_escaped_char(ch, true) { return false }
|
||||
}
|
||||
self.writer.write(['"' as u8]);
|
||||
if_ok!(self, self.writer.write(['"' as u8]));
|
||||
true
|
||||
}
|
||||
|
||||
pub fn write_mut_qualifier(&mut self, mtbl: uint) {
|
||||
pub fn write_mut_qualifier(&mut self, mtbl: uint) -> bool {
|
||||
if mtbl == 0 {
|
||||
self.writer.write("mut ".as_bytes());
|
||||
if_ok!(self, self.writer.write("mut ".as_bytes()));
|
||||
} else if mtbl == 1 {
|
||||
// skip, this is ast::m_imm
|
||||
} else {
|
||||
fail!("invalid mutability value");
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
pub fn write_vec_range(&mut self, ptr: *(), len: uint, inner: *TyDesc) -> bool {
|
||||
let mut p = ptr as *u8;
|
||||
let (sz, al) = unsafe { ((*inner).size, (*inner).align) };
|
||||
self.writer.write(['[' as u8]);
|
||||
if_ok!(self, self.writer.write(['[' as u8]));
|
||||
let mut first = true;
|
||||
let mut left = len;
|
||||
// unit structs have 0 size, and don't loop forever.
|
||||
|
|
@ -197,13 +218,13 @@ impl<'a> ReprVisitor<'a> {
|
|||
if first {
|
||||
first = false;
|
||||
} else {
|
||||
self.writer.write(", ".as_bytes());
|
||||
if_ok!(self, self.writer.write(", ".as_bytes()));
|
||||
}
|
||||
self.visit_ptr_inner(p as *u8, inner);
|
||||
p = align(unsafe { ptr::offset(p, sz as int) as uint }, al) as *u8;
|
||||
left -= dec;
|
||||
}
|
||||
self.writer.write([']' as u8]);
|
||||
if_ok!(self, self.writer.write([']' as u8]));
|
||||
true
|
||||
}
|
||||
|
||||
|
|
@ -211,8 +232,8 @@ impl<'a> ReprVisitor<'a> {
|
|||
self.write_vec_range(ptr::to_unsafe_ptr(&v.data), v.fill, inner)
|
||||
}
|
||||
|
||||
fn write_escaped_char(&mut self, ch: char, is_str: bool) {
|
||||
match ch {
|
||||
fn write_escaped_char(&mut self, ch: char, is_str: bool) -> bool {
|
||||
if_ok!(self, match ch {
|
||||
'\t' => self.writer.write("\\t".as_bytes()),
|
||||
'\r' => self.writer.write("\\r".as_bytes()),
|
||||
'\n' => self.writer.write("\\n".as_bytes()),
|
||||
|
|
@ -234,16 +255,18 @@ impl<'a> ReprVisitor<'a> {
|
|||
'\x20'..'\x7e' => self.writer.write([ch as u8]),
|
||||
_ => {
|
||||
char::escape_unicode(ch, |c| {
|
||||
self.writer.write([c as u8]);
|
||||
})
|
||||
let _ = self.writer.write([c as u8]);
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TyVisitor for ReprVisitor<'a> {
|
||||
fn visit_bot(&mut self) -> bool {
|
||||
self.writer.write("!".as_bytes());
|
||||
if_ok!(self, self.writer.write("!".as_bytes()));
|
||||
true
|
||||
}
|
||||
fn visit_nil(&mut self) -> bool { self.write::<()>() }
|
||||
|
|
@ -265,9 +288,10 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
|
||||
fn visit_char(&mut self) -> bool {
|
||||
self.get::<char>(|this, &ch| {
|
||||
this.writer.write(['\'' as u8]);
|
||||
this.write_escaped_char(ch, false);
|
||||
this.writer.write(['\'' as u8]);
|
||||
if_ok!(this, this.writer.write(['\'' as u8]));
|
||||
if !this.write_escaped_char(ch, false) { return false }
|
||||
if_ok!(this, this.writer.write(['\'' as u8]));
|
||||
true
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -277,8 +301,8 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
|
||||
fn visit_estr_uniq(&mut self) -> bool {
|
||||
self.get::<~str>(|this, s| {
|
||||
this.writer.write(['~' as u8]);
|
||||
this.write_escaped_slice(*s);
|
||||
if_ok!(this, this.writer.write(['~' as u8]));
|
||||
this.write_escaped_slice(*s)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -291,34 +315,35 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
_align: uint) -> bool { fail!(); }
|
||||
|
||||
fn visit_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
self.writer.write(['@' as u8]);
|
||||
if_ok!(self, self.writer.write(['@' as u8]));
|
||||
self.write_mut_qualifier(mtbl);
|
||||
self.get::<&raw::Box<()>>(|this, b| {
|
||||
let p = ptr::to_unsafe_ptr(&b.data) as *u8;
|
||||
this.visit_ptr_inner(p, inner);
|
||||
this.visit_ptr_inner(p, inner)
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_uniq(&mut self, _mtbl: uint, inner: *TyDesc) -> bool {
|
||||
self.writer.write(['~' as u8]);
|
||||
if_ok!(self, self.writer.write(['~' as u8]));
|
||||
self.get::<*u8>(|this, b| {
|
||||
this.visit_ptr_inner(*b, inner);
|
||||
this.visit_ptr_inner(*b, inner)
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_ptr(&mut self, mtbl: uint, _inner: *TyDesc) -> bool {
|
||||
self.get::<*u8>(|this, p| {
|
||||
write!(this.writer, "({} as *", *p);
|
||||
if_ok!(this, write!(this.writer, "({} as *", *p));
|
||||
this.write_mut_qualifier(mtbl);
|
||||
this.writer.write("())".as_bytes());
|
||||
if_ok!(this, this.writer.write("())".as_bytes()));
|
||||
true
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_rptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
self.writer.write(['&' as u8]);
|
||||
if_ok!(self, self.writer.write(['&' as u8]));
|
||||
self.write_mut_qualifier(mtbl);
|
||||
self.get::<*u8>(|this, p| {
|
||||
this.visit_ptr_inner(*p, inner);
|
||||
this.visit_ptr_inner(*p, inner)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -327,33 +352,33 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
|
||||
fn visit_unboxed_vec(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
self.get::<raw::Vec<()>>(|this, b| {
|
||||
this.write_unboxed_vec_repr(mtbl, b, inner);
|
||||
this.write_unboxed_vec_repr(mtbl, b, inner)
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_evec_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
self.get::<&raw::Box<raw::Vec<()>>>(|this, b| {
|
||||
this.writer.write(['@' as u8]);
|
||||
if_ok!(this, this.writer.write(['@' as u8]));
|
||||
this.write_mut_qualifier(mtbl);
|
||||
this.write_unboxed_vec_repr(mtbl, &b.data, inner);
|
||||
this.write_unboxed_vec_repr(mtbl, &b.data, inner)
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_evec_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
self.get::<&raw::Vec<()>>(|this, b| {
|
||||
this.writer.write(['~' as u8]);
|
||||
this.write_unboxed_vec_repr(mtbl, *b, inner);
|
||||
if_ok!(this, this.writer.write(['~' as u8]));
|
||||
this.write_unboxed_vec_repr(mtbl, *b, inner)
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
self.get::<raw::Slice<()>>(|this, s| {
|
||||
this.writer.write(['&' as u8]);
|
||||
if_ok!(this, this.writer.write(['&' as u8]));
|
||||
this.write_mut_qualifier(mtbl);
|
||||
let size = unsafe {
|
||||
if (*inner).size == 0 { 1 } else { (*inner).size }
|
||||
};
|
||||
this.write_vec_range(s.data, s.len * size, inner);
|
||||
this.write_vec_range(s.data, s.len * size, inner)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -361,42 +386,42 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
_: uint, inner: *TyDesc) -> bool {
|
||||
let assumed_size = if sz == 0 { n } else { sz };
|
||||
self.get::<()>(|this, b| {
|
||||
this.write_vec_range(ptr::to_unsafe_ptr(b), assumed_size, inner);
|
||||
this.write_vec_range(ptr::to_unsafe_ptr(b), assumed_size, inner)
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_enter_rec(&mut self, _n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool {
|
||||
self.writer.write(['{' as u8]);
|
||||
if_ok!(self, self.writer.write(['{' as u8]));
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_rec_field(&mut self, i: uint, name: &str,
|
||||
mtbl: uint, inner: *TyDesc) -> bool {
|
||||
if i != 0 {
|
||||
self.writer.write(", ".as_bytes());
|
||||
if_ok!(self, self.writer.write(", ".as_bytes()));
|
||||
}
|
||||
self.write_mut_qualifier(mtbl);
|
||||
self.writer.write(name.as_bytes());
|
||||
self.writer.write(": ".as_bytes());
|
||||
if_ok!(self, self.writer.write(name.as_bytes()));
|
||||
if_ok!(self, self.writer.write(": ".as_bytes()));
|
||||
self.visit_inner(inner);
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_rec(&mut self, _n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool {
|
||||
self.writer.write(['}' as u8]);
|
||||
if_ok!(self, self.writer.write(['}' as u8]));
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_class(&mut self, name: &str, named_fields: bool, n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool {
|
||||
self.writer.write(name.as_bytes());
|
||||
if_ok!(self, self.writer.write(name.as_bytes()));
|
||||
if n_fields != 0 {
|
||||
if named_fields {
|
||||
self.writer.write(['{' as u8]);
|
||||
if_ok!(self, self.writer.write(['{' as u8]));
|
||||
} else {
|
||||
self.writer.write(['(' as u8]);
|
||||
if_ok!(self, self.writer.write(['(' as u8]));
|
||||
}
|
||||
}
|
||||
true
|
||||
|
|
@ -405,11 +430,11 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
fn visit_class_field(&mut self, i: uint, name: &str, named: bool,
|
||||
_mtbl: uint, inner: *TyDesc) -> bool {
|
||||
if i != 0 {
|
||||
self.writer.write(", ".as_bytes());
|
||||
if_ok!(self, self.writer.write(", ".as_bytes()));
|
||||
}
|
||||
if named {
|
||||
self.writer.write(name.as_bytes());
|
||||
self.writer.write(": ".as_bytes());
|
||||
if_ok!(self, self.writer.write(name.as_bytes()));
|
||||
if_ok!(self, self.writer.write(": ".as_bytes()));
|
||||
}
|
||||
self.visit_inner(inner);
|
||||
true
|
||||
|
|
@ -419,9 +444,9 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
_sz: uint, _align: uint) -> bool {
|
||||
if n_fields != 0 {
|
||||
if named_fields {
|
||||
self.writer.write(['}' as u8]);
|
||||
if_ok!(self, self.writer.write(['}' as u8]));
|
||||
} else {
|
||||
self.writer.write([')' as u8]);
|
||||
if_ok!(self, self.writer.write([')' as u8]));
|
||||
}
|
||||
}
|
||||
true
|
||||
|
|
@ -429,13 +454,13 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
|
||||
fn visit_enter_tup(&mut self, _n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool {
|
||||
self.writer.write(['(' as u8]);
|
||||
if_ok!(self, self.writer.write(['(' as u8]));
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_tup_field(&mut self, i: uint, inner: *TyDesc) -> bool {
|
||||
if i != 0 {
|
||||
self.writer.write(", ".as_bytes());
|
||||
if_ok!(self, self.writer.write(", ".as_bytes()));
|
||||
}
|
||||
self.visit_inner(inner);
|
||||
true
|
||||
|
|
@ -444,9 +469,9 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
fn visit_leave_tup(&mut self, _n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool {
|
||||
if _n_fields == 1 {
|
||||
self.writer.write([',' as u8]);
|
||||
if_ok!(self, self.writer.write([',' as u8]));
|
||||
}
|
||||
self.writer.write([')' as u8]);
|
||||
if_ok!(self, self.writer.write([')' as u8]));
|
||||
true
|
||||
}
|
||||
|
||||
|
|
@ -482,9 +507,9 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
}
|
||||
|
||||
if write {
|
||||
self.writer.write(name.as_bytes());
|
||||
if_ok!(self, self.writer.write(name.as_bytes()));
|
||||
if n_fields > 0 {
|
||||
self.writer.write(['(' as u8]);
|
||||
if_ok!(self, self.writer.write(['(' as u8]));
|
||||
}
|
||||
}
|
||||
true
|
||||
|
|
@ -498,7 +523,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
match self.var_stk[self.var_stk.len() - 1] {
|
||||
Matched => {
|
||||
if i != 0 {
|
||||
self.writer.write(", ".as_bytes());
|
||||
if_ok!(self, self.writer.write(", ".as_bytes()));
|
||||
}
|
||||
if ! self.visit_inner(inner) {
|
||||
return false;
|
||||
|
|
@ -516,7 +541,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
match self.var_stk[self.var_stk.len() - 1] {
|
||||
Matched => {
|
||||
if n_fields > 0 {
|
||||
self.writer.write([')' as u8]);
|
||||
if_ok!(self, self.writer.write([')' as u8]));
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
|
|
@ -538,28 +563,29 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
|
||||
fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
|
||||
_n_inputs: uint, _retstyle: uint) -> bool {
|
||||
self.writer.write("fn(".as_bytes());
|
||||
if_ok!(self, self.writer.write("fn(".as_bytes()));
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_fn_input(&mut self, i: uint, _mode: uint, inner: *TyDesc) -> bool {
|
||||
if i != 0 {
|
||||
self.writer.write(", ".as_bytes());
|
||||
if_ok!(self, self.writer.write(", ".as_bytes()));
|
||||
}
|
||||
let name = unsafe { (*inner).name };
|
||||
self.writer.write(name.as_bytes());
|
||||
if_ok!(self, self.writer.write(name.as_bytes()));
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_fn_output(&mut self, _retstyle: uint, variadic: bool, inner: *TyDesc) -> bool {
|
||||
fn visit_fn_output(&mut self, _retstyle: uint, variadic: bool,
|
||||
inner: *TyDesc) -> bool {
|
||||
if variadic {
|
||||
self.writer.write(", ...".as_bytes());
|
||||
if_ok!(self, self.writer.write(", ...".as_bytes()));
|
||||
}
|
||||
self.writer.write(")".as_bytes());
|
||||
if_ok!(self, self.writer.write(")".as_bytes()));
|
||||
let name = unsafe { (*inner).name };
|
||||
if name != "()" {
|
||||
self.writer.write(" -> ".as_bytes());
|
||||
self.writer.write(name.as_bytes());
|
||||
if_ok!(self, self.writer.write(" -> ".as_bytes()));
|
||||
if_ok!(self, self.writer.write(name.as_bytes()));
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
@ -569,7 +595,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
|
||||
|
||||
fn visit_trait(&mut self, name: &str) -> bool {
|
||||
self.writer.write(name.as_bytes());
|
||||
if_ok!(self, self.writer.write(name.as_bytes()));
|
||||
true
|
||||
}
|
||||
|
||||
|
|
@ -582,13 +608,17 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
fn visit_closure_ptr(&mut self, _ck: uint) -> bool { true }
|
||||
}
|
||||
|
||||
pub fn write_repr<T>(writer: &mut io::Writer, object: &T) {
|
||||
pub fn write_repr<T>(writer: &mut io::Writer, object: &T) -> io::IoResult<()> {
|
||||
unsafe {
|
||||
let ptr = ptr::to_unsafe_ptr(object) as *u8;
|
||||
let tydesc = get_tydesc::<T>();
|
||||
let u = ReprVisitor(ptr, writer);
|
||||
let mut v = reflect::MovePtrAdaptor(u);
|
||||
visit_tydesc(tydesc, &mut v as &mut TyVisitor);
|
||||
match v.unwrap().last_err {
|
||||
Some(e) => Err(e),
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +627,7 @@ pub fn repr_to_str<T>(t: &T) -> ~str {
|
|||
use io;
|
||||
|
||||
let mut result = io::MemWriter::new();
|
||||
write_repr(&mut result as &mut io::Writer, t);
|
||||
write_repr(&mut result as &mut io::Writer, t).unwrap();
|
||||
str::from_utf8_owned(result.unwrap()).unwrap()
|
||||
}
|
||||
|
||||
|
|
@ -615,7 +645,7 @@ fn test_repr() {
|
|||
|
||||
fn exact_test<T>(t: &T, e:&str) {
|
||||
let mut m = io::MemWriter::new();
|
||||
write_repr(&mut m as &mut io::Writer, t);
|
||||
write_repr(&mut m as &mut io::Writer, t).unwrap();
|
||||
let s = str::from_utf8_owned(m.unwrap()).unwrap();
|
||||
assert_eq!(s.as_slice(), e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ impl<T, E> Result<T, E> {
|
|||
|
||||
impl<T: fmt::Show, E: fmt::Show> fmt::Show for Result<T, E> {
|
||||
#[inline]
|
||||
fn fmt(s: &Result<T, E>, f: &mut fmt::Formatter) {
|
||||
fn fmt(s: &Result<T, E>, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *s {
|
||||
Ok(ref t) => write!(f.buf, "Ok({})", *t),
|
||||
Err(ref e) => write!(f.buf, "Err({})", *e)
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ use libc;
|
|||
use ops::Drop;
|
||||
use option::{Option, Some, None};
|
||||
use path::Path;
|
||||
use result::{Result, Ok, Err};
|
||||
use result::{Result, Err};
|
||||
use rt::task::Task;
|
||||
use rt::local::Local;
|
||||
|
||||
use ai = io::net::addrinfo;
|
||||
use io;
|
||||
use io::IoError;
|
||||
use io::{IoError, IoResult};
|
||||
use io::net::ip::{IpAddr, SocketAddr};
|
||||
use io::process::{ProcessConfig, ProcessExit};
|
||||
use io::signal::Signum;
|
||||
|
|
@ -116,23 +116,12 @@ impl<'a> LocalIo<'a> {
|
|||
return ret;
|
||||
}
|
||||
|
||||
pub fn maybe_raise<T>(f: |io: &mut IoFactory| -> Result<T, IoError>)
|
||||
-> Option<T>
|
||||
pub fn maybe_raise<T>(f: |io: &mut IoFactory| -> IoResult<T>)
|
||||
-> IoResult<T>
|
||||
{
|
||||
match LocalIo::borrow() {
|
||||
None => {
|
||||
io::io_error::cond.raise(io::standard_error(io::IoUnavailable));
|
||||
None
|
||||
}
|
||||
Some(mut io) => {
|
||||
match f(io.get()) {
|
||||
Ok(t) => Some(t),
|
||||
Err(ioerr) => {
|
||||
io::io_error::cond.raise(ioerr);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
None => Err(io::standard_error(io::IoUnavailable)),
|
||||
Some(mut io) => f(io.get()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ impl Task {
|
|||
|
||||
// Run the task main function, then do some cleanup.
|
||||
f.finally(|| {
|
||||
#[allow(unused_must_use)]
|
||||
fn close_outputs() {
|
||||
let mut task = Local::borrow(None::<Task>);
|
||||
let logger = task.get().logger.take();
|
||||
|
|
@ -126,8 +127,8 @@ impl Task {
|
|||
let stdout = task.get().stdout.take();
|
||||
drop(task);
|
||||
drop(logger); // loggers are responsible for flushing
|
||||
match stdout { Some(mut w) => w.flush(), None => {} }
|
||||
match stderr { Some(mut w) => w.flush(), None => {} }
|
||||
match stdout { Some(mut w) => { w.flush(); }, None => {} }
|
||||
match stderr { Some(mut w) => { w.flush(); }, None => {} }
|
||||
}
|
||||
|
||||
// First, flush/destroy the user stdout/logger because these
|
||||
|
|
|
|||
|
|
@ -464,9 +464,10 @@ fn begin_unwind_inner(msg: ~Any, file: &'static str, line: uint) -> ! {
|
|||
match task.stderr.take() {
|
||||
Some(mut stderr) => {
|
||||
Local::put(task);
|
||||
format_args!(|args| ::fmt::writeln(stderr, args),
|
||||
"task '{}' failed at '{}', {}:{}",
|
||||
n, msg_s, file, line);
|
||||
// FIXME: what to do when the task printing fails?
|
||||
let _err = format_args!(|args| ::fmt::writeln(stderr, args),
|
||||
"task '{}' failed at '{}', {}:{}",
|
||||
n, msg_s, file, line);
|
||||
task = Local::take();
|
||||
|
||||
match util::replace(&mut task.stderr, Some(stderr)) {
|
||||
|
|
|
|||
|
|
@ -11,10 +11,12 @@
|
|||
use container::Container;
|
||||
use fmt;
|
||||
use from_str::FromStr;
|
||||
use io::IoResult;
|
||||
use iter::Iterator;
|
||||
use libc;
|
||||
use option::{Some, None, Option};
|
||||
use os;
|
||||
use result::Ok;
|
||||
use str::StrSlice;
|
||||
use unstable::running_on_valgrind;
|
||||
use vec::ImmutableVector;
|
||||
|
|
@ -73,16 +75,17 @@ pub fn dumb_println(args: &fmt::Arguments) {
|
|||
|
||||
struct Stderr;
|
||||
impl io::Writer for Stderr {
|
||||
fn write(&mut self, data: &[u8]) {
|
||||
fn write(&mut self, data: &[u8]) -> IoResult<()> {
|
||||
unsafe {
|
||||
libc::write(libc::STDERR_FILENO,
|
||||
data.as_ptr() as *libc::c_void,
|
||||
data.len() as libc::size_t);
|
||||
}
|
||||
Ok(()) // yes, we're lying
|
||||
}
|
||||
}
|
||||
let mut w = Stderr;
|
||||
fmt::writeln(&mut w as &mut io::Writer, args);
|
||||
let _ = fmt::writeln(&mut w as &mut io::Writer, args);
|
||||
}
|
||||
|
||||
pub fn abort(msg: &str) -> ! {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
//! Utilities for spawning and managing processes
|
||||
|
||||
#[allow(missing_doc)];
|
||||
#[deny(unused_must_use)];
|
||||
|
||||
use comm::SharedChan;
|
||||
use io::Reader;
|
||||
|
|
@ -119,7 +120,8 @@ impl Process {
|
|||
* * options - Options to configure the environment of the process,
|
||||
* the working directory and the standard IO streams.
|
||||
*/
|
||||
pub fn new(prog: &str, args: &[~str], options: ProcessOptions) -> Option<Process> {
|
||||
pub fn new(prog: &str, args: &[~str],
|
||||
options: ProcessOptions) -> io::IoResult<Process> {
|
||||
let ProcessOptions { env, dir, in_fd, out_fd, err_fd } = options;
|
||||
let env = env.as_ref().map(|a| a.as_slice());
|
||||
let cwd = dir.as_ref().map(|a| a.as_str().unwrap());
|
||||
|
|
@ -138,10 +140,7 @@ impl Process {
|
|||
cwd: cwd,
|
||||
io: rtio,
|
||||
};
|
||||
match process::Process::new(rtconfig) {
|
||||
Some(inner) => Some(Process { inner: inner }),
|
||||
None => None
|
||||
}
|
||||
process::Process::new(rtconfig).map(|p| Process { inner: p })
|
||||
}
|
||||
|
||||
/// Returns the unique id of the process
|
||||
|
|
@ -224,19 +223,17 @@ impl Process {
|
|||
let ch_clone = ch.clone();
|
||||
|
||||
spawn(proc() {
|
||||
let _guard = io::ignore_io_error();
|
||||
let mut error = error;
|
||||
match error {
|
||||
Some(ref mut e) => ch.send((2, e.read_to_end())),
|
||||
None => ch.send((2, ~[]))
|
||||
None => ch.send((2, Ok(~[])))
|
||||
}
|
||||
});
|
||||
spawn(proc() {
|
||||
let _guard = io::ignore_io_error();
|
||||
let mut output = output;
|
||||
match output {
|
||||
Some(ref mut e) => ch_clone.send((1, e.read_to_end())),
|
||||
None => ch_clone.send((1, ~[]))
|
||||
None => ch_clone.send((1, Ok(~[])))
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -251,8 +248,8 @@ impl Process {
|
|||
};
|
||||
|
||||
return ProcessOutput {status: status,
|
||||
output: outs,
|
||||
error: errs};
|
||||
output: outs.ok().unwrap_or(~[]),
|
||||
error: errs.ok().unwrap_or(~[]) };
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -262,9 +259,10 @@ impl Process {
|
|||
* On Posix OSs SIGTERM will be sent to the process. On Win32
|
||||
* TerminateProcess(..) will be called.
|
||||
*/
|
||||
pub fn destroy(&mut self) {
|
||||
self.inner.signal(io::process::PleaseExitSignal);
|
||||
pub fn destroy(&mut self) -> io::IoResult<()> {
|
||||
let ret = self.inner.signal(io::process::PleaseExitSignal);
|
||||
self.finish();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -274,9 +272,12 @@ impl Process {
|
|||
* On Posix OSs SIGKILL will be sent to the process. On Win32
|
||||
* TerminateProcess(..) will be called.
|
||||
*/
|
||||
pub fn force_destroy(&mut self) {
|
||||
self.inner.signal(io::process::MustDieSignal);
|
||||
pub fn force_destroy(&mut self) -> io::IoResult<()> {
|
||||
// This should never fail because we own the process
|
||||
let ret = self.inner.signal(io::process::MustDieSignal);
|
||||
self.finish();
|
||||
return ret;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -293,18 +294,14 @@ impl Process {
|
|||
*
|
||||
* The process's exit code, or None if the child process could not be started
|
||||
*/
|
||||
pub fn process_status(prog: &str, args: &[~str]) -> Option<ProcessExit> {
|
||||
let mut opt_prog = Process::new(prog, args, ProcessOptions {
|
||||
pub fn process_status(prog: &str, args: &[~str]) -> io::IoResult<ProcessExit> {
|
||||
Process::new(prog, args, ProcessOptions {
|
||||
env: None,
|
||||
dir: None,
|
||||
in_fd: Some(unsafe { libc::dup(libc::STDIN_FILENO) }),
|
||||
out_fd: Some(unsafe { libc::dup(libc::STDOUT_FILENO) }),
|
||||
err_fd: Some(unsafe { libc::dup(libc::STDERR_FILENO) })
|
||||
});
|
||||
match opt_prog {
|
||||
Some(ref mut prog) => Some(prog.finish()),
|
||||
None => None
|
||||
}
|
||||
}).map(|mut p| p.finish())
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -320,12 +317,10 @@ pub fn process_status(prog: &str, args: &[~str]) -> Option<ProcessExit> {
|
|||
* The process's stdout/stderr output and exit code, or None if the child process could not be
|
||||
* started.
|
||||
*/
|
||||
pub fn process_output(prog: &str, args: &[~str]) -> Option<ProcessOutput> {
|
||||
let mut opt_prog = Process::new(prog, args, ProcessOptions::new());
|
||||
match opt_prog {
|
||||
Some(ref mut prog) => Some(prog.finish_with_output()),
|
||||
None => None
|
||||
}
|
||||
pub fn process_output(prog: &str, args: &[~str]) -> io::IoResult<ProcessOutput> {
|
||||
Process::new(prog, args, ProcessOptions::new()).map(|mut p| {
|
||||
p.finish_with_output()
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -337,33 +332,25 @@ mod tests {
|
|||
use task::spawn;
|
||||
use unstable::running_on_valgrind;
|
||||
use io::pipe::PipeStream;
|
||||
use io::{io_error, FileNotFound};
|
||||
use io::{FileNotFound};
|
||||
use libc::c_int;
|
||||
|
||||
#[test]
|
||||
#[cfg(not(target_os="android"))] // FIXME(#10380)
|
||||
fn test_process_status() {
|
||||
let mut status = run::process_status("false", []).expect("failed to exec `false`");
|
||||
let mut status = run::process_status("false", []).unwrap();
|
||||
assert!(status.matches_exit_status(1));
|
||||
|
||||
status = run::process_status("true", []).expect("failed to exec `true`");
|
||||
status = run::process_status("true", []).unwrap();
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_process_output_fail_to_start() {
|
||||
// If the executable does not exist, then the io_error condition should be raised with
|
||||
// IoErrorKind FileNotFound.
|
||||
|
||||
let mut trapped_io_error = false;
|
||||
let opt_outp = io_error::cond.trap(|e| {
|
||||
trapped_io_error = true;
|
||||
assert_eq!(e.kind, FileNotFound);
|
||||
}).inside(|| -> Option<run::ProcessOutput> {
|
||||
run::process_output("/no-binary-by-this-name-should-exist", [])
|
||||
});
|
||||
assert!(trapped_io_error);
|
||||
assert!(opt_outp.is_none());
|
||||
match run::process_output("/no-binary-by-this-name-should-exist", []) {
|
||||
Err(e) => assert_eq!(e.kind, FileNotFound),
|
||||
Ok(..) => fail!()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -371,7 +358,7 @@ mod tests {
|
|||
fn test_process_output_output() {
|
||||
|
||||
let run::ProcessOutput {status, output, error}
|
||||
= run::process_output("echo", [~"hello"]).expect("failed to exec `echo`");
|
||||
= run::process_output("echo", [~"hello"]).unwrap();
|
||||
let output_str = str::from_utf8_owned(output).unwrap();
|
||||
|
||||
assert!(status.success());
|
||||
|
|
@ -387,7 +374,7 @@ mod tests {
|
|||
fn test_process_output_error() {
|
||||
|
||||
let run::ProcessOutput {status, output, error}
|
||||
= run::process_output("mkdir", [~"."]).expect("failed to exec `mkdir`");
|
||||
= run::process_output("mkdir", [~"."]).unwrap();
|
||||
|
||||
assert!(status.matches_exit_status(1));
|
||||
assert_eq!(output, ~[]);
|
||||
|
|
@ -408,7 +395,7 @@ mod tests {
|
|||
in_fd: Some(pipe_in.input),
|
||||
out_fd: Some(pipe_out.out),
|
||||
err_fd: Some(pipe_err.out)
|
||||
}).expect("failed to exec `cat`");
|
||||
}).unwrap();
|
||||
|
||||
os::close(pipe_in.input as int);
|
||||
os::close(pipe_out.out as int);
|
||||
|
|
@ -426,27 +413,18 @@ mod tests {
|
|||
|
||||
fn writeclose(fd: c_int, s: &str) {
|
||||
let mut writer = PipeStream::open(fd);
|
||||
writer.write(s.as_bytes());
|
||||
writer.write(s.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
fn readclose(fd: c_int) -> ~str {
|
||||
let mut res = ~[];
|
||||
let mut reader = PipeStream::open(fd);
|
||||
let mut buf = [0, ..1024];
|
||||
loop {
|
||||
match reader.read(buf) {
|
||||
Some(n) => { res.push_all(buf.slice_to(n)); }
|
||||
None => break
|
||||
}
|
||||
}
|
||||
str::from_utf8_owned(res).unwrap()
|
||||
PipeStream::open(fd).read_to_str().unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(target_os="android"))] // FIXME(#10380)
|
||||
fn test_finish_once() {
|
||||
let mut prog = run::Process::new("false", [], run::ProcessOptions::new())
|
||||
.expect("failed to exec `false`");
|
||||
.unwrap();
|
||||
assert!(prog.finish().matches_exit_status(1));
|
||||
}
|
||||
|
||||
|
|
@ -454,7 +432,7 @@ mod tests {
|
|||
#[cfg(not(target_os="android"))] // FIXME(#10380)
|
||||
fn test_finish_twice() {
|
||||
let mut prog = run::Process::new("false", [], run::ProcessOptions::new())
|
||||
.expect("failed to exec `false`");
|
||||
.unwrap();
|
||||
assert!(prog.finish().matches_exit_status(1));
|
||||
assert!(prog.finish().matches_exit_status(1));
|
||||
}
|
||||
|
|
@ -464,7 +442,7 @@ mod tests {
|
|||
fn test_finish_with_output_once() {
|
||||
|
||||
let mut prog = run::Process::new("echo", [~"hello"], run::ProcessOptions::new())
|
||||
.expect("failed to exec `echo`");
|
||||
.unwrap();
|
||||
let run::ProcessOutput {status, output, error}
|
||||
= prog.finish_with_output();
|
||||
let output_str = str::from_utf8_owned(output).unwrap();
|
||||
|
|
@ -482,7 +460,7 @@ mod tests {
|
|||
fn test_finish_with_output_twice() {
|
||||
|
||||
let mut prog = run::Process::new("echo", [~"hello"], run::ProcessOptions::new())
|
||||
.expect("failed to exec `echo`");
|
||||
.unwrap();
|
||||
let run::ProcessOutput {status, output, error}
|
||||
= prog.finish_with_output();
|
||||
|
||||
|
|
@ -511,14 +489,14 @@ mod tests {
|
|||
run::Process::new("pwd", [], run::ProcessOptions {
|
||||
dir: dir,
|
||||
.. run::ProcessOptions::new()
|
||||
}).expect("failed to exec `pwd`")
|
||||
}).unwrap()
|
||||
}
|
||||
#[cfg(unix,target_os="android")]
|
||||
fn run_pwd(dir: Option<&Path>) -> run::Process {
|
||||
run::Process::new("/system/bin/sh", [~"-c",~"pwd"], run::ProcessOptions {
|
||||
dir: dir,
|
||||
.. run::ProcessOptions::new()
|
||||
}).expect("failed to exec `/system/bin/sh`")
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
|
|
@ -526,7 +504,7 @@ mod tests {
|
|||
run::Process::new("cmd", [~"/c", ~"cd"], run::ProcessOptions {
|
||||
dir: dir,
|
||||
.. run::ProcessOptions::new()
|
||||
}).expect("failed to run `cmd`")
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -537,8 +515,8 @@ mod tests {
|
|||
let parent_dir = os::getcwd();
|
||||
let child_dir = Path::new(output.trim());
|
||||
|
||||
let parent_stat = parent_dir.stat();
|
||||
let child_stat = child_dir.stat();
|
||||
let parent_stat = parent_dir.stat().unwrap();
|
||||
let child_stat = child_dir.stat().unwrap();
|
||||
|
||||
assert_eq!(parent_stat.unstable.device, child_stat.unstable.device);
|
||||
assert_eq!(parent_stat.unstable.inode, child_stat.unstable.inode);
|
||||
|
|
@ -554,8 +532,8 @@ mod tests {
|
|||
let output = str::from_utf8_owned(prog.finish_with_output().output).unwrap();
|
||||
let child_dir = Path::new(output.trim());
|
||||
|
||||
let parent_stat = parent_dir.stat();
|
||||
let child_stat = child_dir.stat();
|
||||
let parent_stat = parent_dir.stat().unwrap();
|
||||
let child_stat = child_dir.stat().unwrap();
|
||||
|
||||
assert_eq!(parent_stat.unstable.device, child_stat.unstable.device);
|
||||
assert_eq!(parent_stat.unstable.inode, child_stat.unstable.inode);
|
||||
|
|
@ -566,14 +544,14 @@ mod tests {
|
|||
run::Process::new("env", [], run::ProcessOptions {
|
||||
env: env,
|
||||
.. run::ProcessOptions::new()
|
||||
}).expect("failed to exec `env`")
|
||||
}).unwrap()
|
||||
}
|
||||
#[cfg(unix,target_os="android")]
|
||||
fn run_env(env: Option<~[(~str, ~str)]>) -> run::Process {
|
||||
run::Process::new("/system/bin/sh", [~"-c",~"set"], run::ProcessOptions {
|
||||
env: env,
|
||||
.. run::ProcessOptions::new()
|
||||
}).expect("failed to exec `/system/bin/sh`")
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
|
|
@ -581,7 +559,7 @@ mod tests {
|
|||
run::Process::new("cmd", [~"/c", ~"set"], run::ProcessOptions {
|
||||
env: env,
|
||||
.. run::ProcessOptions::new()
|
||||
}).expect("failed to run `cmd`")
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -541,7 +541,7 @@ fn test_avoid_copying_the_body_task_spawn() {
|
|||
#[test]
|
||||
fn test_avoid_copying_the_body_try() {
|
||||
avoid_copying_the_body(|f| {
|
||||
try(proc() {
|
||||
let _ = try(proc() {
|
||||
f()
|
||||
});
|
||||
})
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ impl<A:IterBytes> ToBytes for A {
|
|||
|
||||
let mut m = ::io::MemWriter::new();
|
||||
self.iter_bytes(lsb0, |bytes| {
|
||||
m.write(bytes);
|
||||
m.write(bytes).unwrap();
|
||||
true
|
||||
});
|
||||
m.unwrap()
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ mod tests {
|
|||
// accesses will also fail.
|
||||
let x = Exclusive::new(1);
|
||||
let x2 = x.clone();
|
||||
task::try(proc() {
|
||||
let _ = task::try(proc() {
|
||||
x2.with(|one| assert_eq!(*one, 2))
|
||||
});
|
||||
x.with(|one| assert_eq!(*one, 1));
|
||||
|
|
|
|||
|
|
@ -189,58 +189,61 @@ impl Level {
|
|||
}
|
||||
}
|
||||
|
||||
fn print_maybe_styled(msg: &str, color: term::attr::Attr) {
|
||||
local_data_key!(tls_terminal: ~Option<term::Terminal<StdWriter>>)
|
||||
fn print_maybe_styled(msg: &str, color: term::attr::Attr) -> io::IoResult<()> {
|
||||
local_data_key!(tls_terminal: Option<term::Terminal<StdWriter>>)
|
||||
|
||||
|
||||
fn is_stderr_screen() -> bool {
|
||||
use std::libc;
|
||||
unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
|
||||
}
|
||||
fn write_pretty<T: Writer>(term: &mut term::Terminal<T>, s: &str, c: term::attr::Attr) {
|
||||
term.attr(c);
|
||||
term.write(s.as_bytes());
|
||||
term.reset();
|
||||
fn write_pretty<T: Writer>(term: &mut term::Terminal<T>, s: &str,
|
||||
c: term::attr::Attr) -> io::IoResult<()> {
|
||||
if_ok!(term.attr(c));
|
||||
if_ok!(term.write(s.as_bytes()));
|
||||
if_ok!(term.reset());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
if is_stderr_screen() {
|
||||
local_data::get_mut(tls_terminal, |term| {
|
||||
match term {
|
||||
Some(term) => {
|
||||
match **term {
|
||||
match *term {
|
||||
Some(ref mut term) => write_pretty(term, msg, color),
|
||||
None => io::stderr().write(msg.as_bytes())
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let t = ~match term::Terminal::new(io::stderr()) {
|
||||
let (t, ret) = match term::Terminal::new(io::stderr()) {
|
||||
Ok(mut term) => {
|
||||
write_pretty(&mut term, msg, color);
|
||||
Some(term)
|
||||
let r = write_pretty(&mut term, msg, color);
|
||||
(Some(term), r)
|
||||
}
|
||||
Err(_) => {
|
||||
io::stderr().write(msg.as_bytes());
|
||||
None
|
||||
(None, io::stderr().write(msg.as_bytes()))
|
||||
}
|
||||
};
|
||||
local_data::set(tls_terminal, t);
|
||||
ret
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
} else {
|
||||
io::stderr().write(msg.as_bytes());
|
||||
io::stderr().write(msg.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
fn print_diagnostic(topic: &str, lvl: Level, msg: &str) {
|
||||
let mut stderr = io::stderr();
|
||||
|
||||
fn print_diagnostic(topic: &str, lvl: Level, msg: &str) -> io::IoResult<()> {
|
||||
if !topic.is_empty() {
|
||||
write!(&mut stderr as &mut io::Writer, "{} ", topic);
|
||||
let mut stderr = io::stderr();
|
||||
if_ok!(write!(&mut stderr as &mut io::Writer, "{} ", topic));
|
||||
}
|
||||
|
||||
print_maybe_styled(format!("{}: ", lvl.to_str()),
|
||||
term::attr::ForegroundColor(lvl.color()));
|
||||
print_maybe_styled(format!("{}\n", msg), term::attr::Bold);
|
||||
if_ok!(print_maybe_styled(format!("{}: ", lvl.to_str()),
|
||||
term::attr::ForegroundColor(lvl.color())));
|
||||
if_ok!(print_maybe_styled(format!("{}\n", msg), term::attr::Bold));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub struct DefaultEmitter;
|
||||
|
|
@ -250,20 +253,28 @@ impl Emitter for DefaultEmitter {
|
|||
cmsp: Option<(&codemap::CodeMap, Span)>,
|
||||
msg: &str,
|
||||
lvl: Level) {
|
||||
match cmsp {
|
||||
let error = match cmsp {
|
||||
Some((cm, sp)) => emit(cm, sp, msg, lvl, false),
|
||||
None => print_diagnostic("", lvl, msg),
|
||||
};
|
||||
|
||||
match error {
|
||||
Ok(()) => {}
|
||||
Err(e) => fail!("failed to print diagnostics: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
fn custom_emit(&self, cm: &codemap::CodeMap,
|
||||
sp: Span, msg: &str, lvl: Level) {
|
||||
emit(cm, sp, msg, lvl, true);
|
||||
match emit(cm, sp, msg, lvl, true) {
|
||||
Ok(()) => {}
|
||||
Err(e) => fail!("failed to print diagnostics: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn emit(cm: &codemap::CodeMap, sp: Span,
|
||||
msg: &str, lvl: Level, custom: bool) {
|
||||
msg: &str, lvl: Level, custom: bool) -> io::IoResult<()> {
|
||||
let ss = cm.span_to_str(sp);
|
||||
let lines = cm.span_to_lines(sp);
|
||||
if custom {
|
||||
|
|
@ -272,19 +283,19 @@ fn emit(cm: &codemap::CodeMap, sp: Span,
|
|||
// the span)
|
||||
let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info};
|
||||
let ses = cm.span_to_str(span_end);
|
||||
print_diagnostic(ses, lvl, msg);
|
||||
custom_highlight_lines(cm, sp, lvl, lines);
|
||||
if_ok!(print_diagnostic(ses, lvl, msg));
|
||||
if_ok!(custom_highlight_lines(cm, sp, lvl, lines));
|
||||
} else {
|
||||
print_diagnostic(ss, lvl, msg);
|
||||
highlight_lines(cm, sp, lvl, lines);
|
||||
if_ok!(print_diagnostic(ss, lvl, msg));
|
||||
if_ok!(highlight_lines(cm, sp, lvl, lines));
|
||||
}
|
||||
print_macro_backtrace(cm, sp);
|
||||
print_macro_backtrace(cm, sp)
|
||||
}
|
||||
|
||||
fn highlight_lines(cm: &codemap::CodeMap,
|
||||
sp: Span,
|
||||
lvl: Level,
|
||||
lines: &codemap::FileLines) {
|
||||
lines: &codemap::FileLines) -> io::IoResult<()> {
|
||||
let fm = lines.file;
|
||||
let mut err = io::stderr();
|
||||
let err = &mut err as &mut io::Writer;
|
||||
|
|
@ -297,12 +308,13 @@ fn highlight_lines(cm: &codemap::CodeMap,
|
|||
}
|
||||
// Print the offending lines
|
||||
for line in display_lines.iter() {
|
||||
write!(err, "{}:{} {}\n", fm.name, *line + 1, fm.get_line(*line as int));
|
||||
if_ok!(write!(err, "{}:{} {}\n", fm.name, *line + 1,
|
||||
fm.get_line(*line as int)));
|
||||
}
|
||||
if elided {
|
||||
let last_line = display_lines[display_lines.len() - 1u];
|
||||
let s = format!("{}:{} ", fm.name, last_line + 1u);
|
||||
write!(err, "{0:1$}...\n", "", s.len());
|
||||
if_ok!(write!(err, "{0:1$}...\n", "", s.len()));
|
||||
}
|
||||
|
||||
// FIXME (#3260)
|
||||
|
|
@ -334,7 +346,7 @@ fn highlight_lines(cm: &codemap::CodeMap,
|
|||
_ => s.push_char(' '),
|
||||
};
|
||||
}
|
||||
write!(err, "{}", s);
|
||||
if_ok!(write!(err, "{}", s));
|
||||
let mut s = ~"^";
|
||||
let hi = cm.lookup_char_pos(sp.hi);
|
||||
if hi.col != lo.col {
|
||||
|
|
@ -342,8 +354,10 @@ fn highlight_lines(cm: &codemap::CodeMap,
|
|||
let num_squigglies = hi.col.to_uint()-lo.col.to_uint()-1u;
|
||||
for _ in range(0, num_squigglies) { s.push_char('~'); }
|
||||
}
|
||||
print_maybe_styled(s + "\n", term::attr::ForegroundColor(lvl.color()));
|
||||
if_ok!(print_maybe_styled(s + "\n",
|
||||
term::attr::ForegroundColor(lvl.color())));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Here are the differences between this and the normal `highlight_lines`:
|
||||
|
|
@ -355,23 +369,23 @@ fn highlight_lines(cm: &codemap::CodeMap,
|
|||
fn custom_highlight_lines(cm: &codemap::CodeMap,
|
||||
sp: Span,
|
||||
lvl: Level,
|
||||
lines: &codemap::FileLines) {
|
||||
lines: &codemap::FileLines) -> io::IoResult<()> {
|
||||
let fm = lines.file;
|
||||
let mut err = io::stderr();
|
||||
let err = &mut err as &mut io::Writer;
|
||||
|
||||
let lines = lines.lines.as_slice();
|
||||
if lines.len() > MAX_LINES {
|
||||
write!(err, "{}:{} {}\n", fm.name,
|
||||
lines[0] + 1, fm.get_line(lines[0] as int));
|
||||
write!(err, "...\n");
|
||||
if_ok!(write!(err, "{}:{} {}\n", fm.name,
|
||||
lines[0] + 1, fm.get_line(lines[0] as int)));
|
||||
if_ok!(write!(err, "...\n"));
|
||||
let last_line = lines[lines.len()-1];
|
||||
write!(err, "{}:{} {}\n", fm.name,
|
||||
last_line + 1, fm.get_line(last_line as int));
|
||||
if_ok!(write!(err, "{}:{} {}\n", fm.name,
|
||||
last_line + 1, fm.get_line(last_line as int)));
|
||||
} else {
|
||||
for line in lines.iter() {
|
||||
write!(err, "{}:{} {}\n", fm.name,
|
||||
*line + 1, fm.get_line(*line as int));
|
||||
if_ok!(write!(err, "{}:{} {}\n", fm.name,
|
||||
*line + 1, fm.get_line(*line as int)));
|
||||
}
|
||||
}
|
||||
let last_line_start = format!("{}:{} ", fm.name, lines[lines.len()-1]+1);
|
||||
|
|
@ -381,22 +395,24 @@ fn custom_highlight_lines(cm: &codemap::CodeMap,
|
|||
let mut s = ~"";
|
||||
for _ in range(0, skip) { s.push_char(' '); }
|
||||
s.push_char('^');
|
||||
print_maybe_styled(s + "\n", term::attr::ForegroundColor(lvl.color()));
|
||||
print_maybe_styled(s + "\n", term::attr::ForegroundColor(lvl.color()))
|
||||
}
|
||||
|
||||
fn print_macro_backtrace(cm: &codemap::CodeMap, sp: Span) {
|
||||
fn print_macro_backtrace(cm: &codemap::CodeMap, sp: Span) -> io::IoResult<()> {
|
||||
for ei in sp.expn_info.iter() {
|
||||
let ss = ei.callee.span.as_ref().map_or(~"", |span| cm.span_to_str(*span));
|
||||
let (pre, post) = match ei.callee.format {
|
||||
codemap::MacroAttribute => ("#[", "]"),
|
||||
codemap::MacroBang => ("", "!")
|
||||
};
|
||||
print_diagnostic(ss, Note,
|
||||
format!("in expansion of {}{}{}", pre, ei.callee.name, post));
|
||||
if_ok!(print_diagnostic(ss, Note,
|
||||
format!("in expansion of {}{}{}", pre,
|
||||
ei.callee.name, post)));
|
||||
let ss = cm.span_to_str(ei.call_site);
|
||||
print_diagnostic(ss, Note, "expansion site");
|
||||
print_macro_backtrace(cm, ei.call_site);
|
||||
if_ok!(print_diagnostic(ss, Note, "expansion site"));
|
||||
if_ok!(print_macro_backtrace(cm, ei.call_site));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn expect<T:Clone>(diag: @SpanHandler, opt: Option<T>, msg: || -> ~str)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue