diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index 5bbea491ac2..1900313ab6c 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -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(); } } diff --git a/src/libextra/json.rs b/src/libextra/json.rs index f8b1c216529..ef8e0999521 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -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 serialize::Encodable 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> Parser { /// Decodes a json value from an `&mut io::Reader` pub fn from_reader(rdr: &mut io::Reader) -> Result { - 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() } } diff --git a/src/libextra/lib.rs b/src/libextra/lib.rs index e2a4b52c810..358dca5e5ac 100644 --- a/src/libextra/lib.rs +++ b/src/libextra/lib.rs @@ -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; diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs index 096e5882774..8c7b7f4a736 100644 --- a/src/libextra/stats.rs +++ b/src/libextra/stats.rs @@ -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 diff --git a/src/libextra/tempfile.rs b/src/libextra/tempfile.rs index c9ea556f23a..5948f356a65 100644 --- a/src/libextra/tempfile.rs +++ b/src/libextra/tempfile.rs @@ -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(); } } } diff --git a/src/libextra/test.rs b/src/libextra/test.rs index ef5a05b6a3e..f562c50935b 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -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 { } impl ConsoleTestState { - pub fn new(opts: &TestOpts, _: Option) -> ConsoleTestState { + pub fn new(opts: &TestOpts, + _: Option) -> io::IoResult> { 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 ConsoleTestState { 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 ConsoleTestState { 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 ConsoleTestState { 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, - ratchet_pct: Option) -> bool { + ratchet_pct: Option) -> io::IoResult { 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(event: &TestEvent, st: &mut ConsoleTestState) { + tests: ~[TestDescAndFn]) -> io::IoResult { + fn callback(event: &TestEvent, + st: &mut ConsoleTestState) -> 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::); + let mut st = if_ok!(ConsoleTestState::new(opts, None::)); 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); @@ -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) } diff --git a/src/libextra/time.rs b/src/libextra/time.rs index 3e5b9b797d3..0a122ad58bd 100644 --- a/src/libextra/time.rs +++ b/src/libextra/time.rs @@ -766,14 +766,14 @@ pub fn strptime(s: &str, format: &str) -> Result { 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 { } } - 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()); } diff --git a/src/libextra/url.rs b/src/libextra/url.rs index 35c53c9307c..6138c5416f2 100644 --- a/src/libextra/url.rs +++ b/src/libextra/url.rs @@ -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; } diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index 70bbe02d32f..3d91ccda189 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -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(); } } } diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 01ebf58628f..98dd2b20a5f 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -141,45 +141,48 @@ impl Terminal { /// If the color is a bright color, but the terminal only supports 8 colors, /// the corresponding normal color will be used instead. /// - /// Returns true if the color was set, false otherwise. - pub fn fg(&mut self, color: color::Color) -> bool { + /// Returns Ok(true) if the color was set, Ok(false) otherwise, and Err(e) + /// if there was an I/O error + pub fn fg(&mut self, color: color::Color) -> io::IoResult { let color = self.dim_if_necessary(color); if self.num_colors > color { let s = expand(*self.ti.strings.find_equiv(&("setaf")).unwrap(), [Number(color as int)], &mut Variables::new()); if s.is_ok() { - self.out.write(s.unwrap()); - return true + if_ok!(self.out.write(s.unwrap())); + return Ok(true) } else { warn!("{}", s.unwrap_err()); } } - false + Ok(false) } /// Sets the background color to the given color. /// /// If the color is a bright color, but the terminal only supports 8 colors, /// the corresponding normal color will be used instead. /// - /// Returns true if the color was set, false otherwise. - pub fn bg(&mut self, color: color::Color) -> bool { + /// Returns Ok(true) if the color was set, Ok(false) otherwise, and Err(e) + /// if there was an I/O error + pub fn bg(&mut self, color: color::Color) -> io::IoResult { let color = self.dim_if_necessary(color); if self.num_colors > color { let s = expand(*self.ti.strings.find_equiv(&("setab")).unwrap(), [Number(color as int)], &mut Variables::new()); if s.is_ok() { - self.out.write(s.unwrap()); - return true + if_ok!(self.out.write(s.unwrap())); + return Ok(true) } else { warn!("{}", s.unwrap_err()); } } - false + Ok(false) } /// Sets the given terminal attribute, if supported. - /// Returns true if the attribute was supported, false otherwise. - pub fn attr(&mut self, attr: attr::Attr) -> bool { + /// Returns Ok(true) if the attribute was supported, Ok(false) otherwise, + /// and Err(e) if there was an I/O error. + pub fn attr(&mut self, attr: attr::Attr) -> io::IoResult { match attr { attr::ForegroundColor(c) => self.fg(c), attr::BackgroundColor(c) => self.bg(c), @@ -189,13 +192,13 @@ impl Terminal { if parm.is_some() { let s = expand(*parm.unwrap(), [], &mut Variables::new()); if s.is_ok() { - self.out.write(s.unwrap()); - return true + if_ok!(self.out.write(s.unwrap())); + return Ok(true) } else { warn!("{}", s.unwrap_err()); } } - false + Ok(false) } } } @@ -214,7 +217,7 @@ impl Terminal { } /// Resets all terminal attributes and color to the default. - pub fn reset(&mut self) { + pub fn reset(&mut self) -> io::IoResult<()> { let mut cap = self.ti.strings.find_equiv(&("sgr0")); if cap.is_none() { // are there any terminals that have color/attrs and not sgr0? @@ -228,7 +231,7 @@ impl Terminal { expand(*op, [], &mut Variables::new()) }); if s.is_ok() { - self.out.write(s.unwrap()); + return self.out.write(s.unwrap()) } else if self.num_colors > 0 { warn!("{}", s.unwrap_err()); } else { @@ -236,6 +239,7 @@ impl Terminal { // but it's not worth testing all known attributes just for this. debug!("{}", s.unwrap_err()); } + Ok(()) } fn dim_if_necessary(&self, color: color::Color) -> color::Color { @@ -252,11 +256,11 @@ impl Terminal { } impl Writer for Terminal { - fn write(&mut self, buf: &[u8]) { - self.out.write(buf); + fn write(&mut self, buf: &[u8]) -> io::IoResult<()> { + self.out.write(buf) } - fn flush(&mut self) { - self.out.flush(); + fn flush(&mut self) -> io::IoResult<()> { + self.out.flush() } } diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs index b0104faf4b5..31f12bd45e6 100644 --- a/src/libterm/terminfo/parser/compiled.rs +++ b/src/libterm/terminfo/parser/compiled.rs @@ -162,6 +162,10 @@ pub static stringnames: &'static[&'static str] = &'static[ "cbt", "_", "cr", "cs /// Parse a compiled terminfo entry, using long capability names if `longnames` is true pub fn parse(file: &mut io::Reader, longnames: bool) -> Result<~TermInfo, ~str> { + macro_rules! if_ok( ($e:expr) => ( + match $e { Ok(e) => e, Err(e) => return Err(format!("{}", e)) } + ) ) + let bnames; let snames; let nnames; @@ -177,17 +181,17 @@ pub fn parse(file: &mut io::Reader, } // Check magic number - let magic = file.read_le_u16(); + let magic = if_ok!(file.read_le_u16()); if magic != 0x011A { return Err(format!("invalid magic number: expected {:x} but found {:x}", 0x011A, magic as uint)); } - let names_bytes = file.read_le_i16() as int; - let bools_bytes = file.read_le_i16() as int; - let numbers_count = file.read_le_i16() as int; - let string_offsets_count = file.read_le_i16() as int; - let string_table_bytes = file.read_le_i16() as int; + let names_bytes = if_ok!(file.read_le_i16()) as int; + let bools_bytes = if_ok!(file.read_le_i16()) as int; + let numbers_count = if_ok!(file.read_le_i16()) as int; + let string_offsets_count = if_ok!(file.read_le_i16()) as int; + let string_table_bytes = if_ok!(file.read_le_i16()) as int; assert!(names_bytes > 0); @@ -216,18 +220,21 @@ pub fn parse(file: &mut io::Reader, } // don't read NUL - let names_str = str::from_utf8_owned(file.read_bytes(names_bytes as uint - 1)).unwrap(); + let bytes = if_ok!(file.read_bytes(names_bytes as uint - 1)); + let names_str = match str::from_utf8_owned(bytes) { + Some(s) => s, None => return Err(~"input not utf-8"), + }; let term_names: ~[~str] = names_str.split('|').map(|s| s.to_owned()).collect(); - file.read_byte(); // consume NUL + if_ok!(file.read_byte()); // consume NUL debug!("term names: {:?}", term_names); let mut bools_map = HashMap::new(); if bools_bytes != 0 { for i in range(0, bools_bytes) { - let b = file.read_byte().unwrap(); + let b = if_ok!(file.read_byte()); if b < 0 { error!("EOF reading bools after {} entries", i); return Err(~"error: expected more bools but hit EOF"); @@ -242,13 +249,13 @@ pub fn parse(file: &mut io::Reader, if (bools_bytes + names_bytes) % 2 == 1 { debug!("adjusting for padding between bools and numbers"); - file.read_byte(); // compensate for padding + if_ok!(file.read_byte()); // compensate for padding } let mut numbers_map = HashMap::new(); if numbers_count != 0 { for i in range(0, numbers_count) { - let n = file.read_le_u16(); + let n = if_ok!(file.read_le_u16()); if n != 0xFFFF { debug!("{}\\#{}", nnames[i], n); numbers_map.insert(nnames[i].to_owned(), n); @@ -263,12 +270,12 @@ pub fn parse(file: &mut io::Reader, if string_offsets_count != 0 { let mut string_offsets = vec::with_capacity(10); for _ in range(0, string_offsets_count) { - string_offsets.push(file.read_le_u16()); + string_offsets.push(if_ok!(file.read_le_u16())); } debug!("offsets: {:?}", string_offsets); - let string_table = file.read_bytes(string_table_bytes as uint); + let string_table = if_ok!(file.read_bytes(string_table_bytes as uint)); if string_table.len() != string_table_bytes as uint { error!("EOF reading string table after {} bytes, wanted {}", string_table.len(), diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs index 8cbb0902697..421f8581b58 100644 --- a/src/libterm/terminfo/searcher.rs +++ b/src/libterm/terminfo/searcher.rs @@ -77,8 +77,8 @@ pub fn open(term: &str) -> Result { match get_dbpath_for_term(term) { Some(x) => { match File::open(x) { - Some(file) => Ok(file), - None => Err(~"error opening file"), + Ok(file) => Ok(file), + Err(e) => Err(format!("error opening file: {}", e)), } } None => Err(format!("could not find terminfo entry for {}", term))