]> git.lizzy.rs Git - rust.git/commitdiff
extra: Remove io_error usage
authorAlex Crichton <alex@alexcrichton.com>
Thu, 30 Jan 2014 01:39:12 +0000 (17:39 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 3 Feb 2014 17:32:33 +0000 (09:32 -0800)
12 files changed:
src/libextra/ebml.rs
src/libextra/json.rs
src/libextra/lib.rs
src/libextra/stats.rs
src/libextra/tempfile.rs
src/libextra/test.rs
src/libextra/time.rs
src/libextra/url.rs
src/libextra/workcache.rs
src/libterm/lib.rs
src/libterm/terminfo/parser/compiled.rs
src/libterm/terminfo/searcher.rs

index 5bbea491ac208be083e0e96e7a1199226edb1904..1900313ab6c8e7d11bc3b98728680a5e66241417 100644 (file)
 
 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 @@ fn write_sized_vuint(w: &mut MemWriter, n: uint, size: uint) {
             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 fn Encoder<'a>(w: &'a mut MemWriter) -> Encoder<'a> {
         let size_positions: ~[uint] = ~[];
         Encoder {
             writer: w,
-            size_positions: size_positions
+            size_positions: size_positions,
+            last_error: Ok(()),
         }
     }
 
@@ -635,6 +646,7 @@ pub unsafe fn unsafe_clone(&self) -> Encoder<'a> {
             Encoder {
                 writer: cast::transmute_copy(&self.writer),
                 size_positions: self.size_positions.clone(),
+                last_error: Ok(()),
             }
         }
 
@@ -645,18 +657,18 @@ pub fn start_tag(&mut self, tag_id: uint) {
             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 fn wr_tag(&mut self, tag_id: uint, blk: ||) {
         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 fn wr_tagged_str(&mut self, tag_id: uint, v: &str) {
 
         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();
         }
     }
 
index f8b1c216529b1bcfb0a44db98d87488f6d24293a..ef8e0999521b85567e0d9e148436973893752510 100644 (file)
@@ -234,6 +234,10 @@ fn main() {
 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 @@ pub fn str_encode<T:Encodable<Encoder<'a>>>(to_encode_object: &T) -> ~str  {
 }
 
 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 @@ fn emit_nil(&mut self) { write!(self.wr, "null") }
 
     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 @@ fn emit_enum_variant(&mut self,
         // 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 @@ fn emit_enum_struct_variant_field(&mut self,
     }
 
     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 @@ fn emit_tuple_struct_arg(&mut self, idx: uint, f: |&mut 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 @@ fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut 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 @@ pub fn new<'a>(wr: &'a mut io::Writer) -> 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 @@ fn emit_nil(&mut self) { write!(self.wr, "null") }
 
     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 @@ fn emit_enum_variant(&mut self,
                          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 @@ fn emit_enum_variant_arg(&mut self,
                              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 @@ fn emit_struct(&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)));
         }
     }
 
@@ -572,11 +590,11 @@ fn emit_struct_field(&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), escape_str(name));
+        if_ok!(write!(self.wr, "{}{}: ", spaces(self.indent), escape_str(name)));
         f(self);
     }
 
@@ -605,50 +623,50 @@ fn emit_tuple_struct_arg(&mut self,
 
     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 @@ fn encode(&self, e: &mut E) {
 
 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 @@ fn parse_object(&mut self) -> Result<Json, Error> {
 
 /// 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()
     }
 }
index e2a4b52c810d240bdd5c06cbb6731f1efe97a4a0..358dca5e5ac4767c21413faf1a9c283f501c7ae8 100644 (file)
 #[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;
index 096e588277468d78473d285efdef21340f1594d0..8c7b7f4a736ff049ac615dd59847196409fe0b06 100644 (file)
@@ -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
index c9ea556f23a50e85ec541bdcf58724a3d596ec9e..5948f356a651d6c0384c691dded84ae711261daf 100644 (file)
@@ -38,7 +38,7 @@ pub fn new_in(tmpdir: &Path, suffix: &str) -> Option<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();
             }
         }
     }
index ef5a05b6a3e51ddafb92523749933313223e7acd..f562c50935b8c7f2f9f90ddc17b24b7f4b994aa7 100644 (file)
@@ -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 @@ pub fn new(opts: &TestOpts, _: Option<T>) -> ConsoleTestState<StdWriter> {
             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 @@ pub fn write_log(&mut self, test: &TestDesc, result: &TestResult) {
                         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 @@ pub fn write_metric_diff(&mut self, diff: &MetricDiff) {
                 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 @@ fn callback<T: Writer>(event: &TestEvent, st: &mut ConsoleTestState<T>) {
                         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 @@ fn len_if_padded(t: &TestDescAndFn) -> uint {
         },
         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 @@ enum TestEvent {
 
 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 @@ pub fn new() -> 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 @@ pub fn ratchet(&self, p: &Path, pct: Option<f64>) -> (MetricDiff, bool) {
 
         if ok {
             debug!("rewriting file '{:?}' with updated metrics", p);
-            self.save(p);
+            self.save(p).unwrap();
         }
         return (diff, ok)
     }
index 3e5b9b797d31b6a3e3b38f1a2cb6d19bb4ba08a9..0a122ad58bd33a3a728d91fc2cd914e9762dcfcc 100644 (file)
@@ -766,14 +766,14 @@ fn parse_type(s: &str, pos: uint, ch: char, tm: &mut Tm)
 
         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 @@ fn parse_type(s: &str, pos: uint, ch: char, tm: &mut Tm)
         }
     }
 
-    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 @@ fn parse_type(ch: char, 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());
             }
index 35c53c9307c49fdee13a7345a5cc0c64d8cd1332..6138c5416f2b456bb5448c5d2a30617a005e50c7 100644 (file)
@@ -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;
         }
index 70bbe02d32f1769839b08021c8a3706d45d93033..3d91ccda189a284eb4a885d4a04c056cabc423eb 100644 (file)
@@ -172,20 +172,19 @@ pub fn cache(&mut self,
     }
 
     // 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 @@ fn load(&mut self) {
 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();
         }
     }
 }
index 01ebf58628fa8b662a11a7c919d330f2931b6558..98dd2b20a5fa30bb4007f0e0ae94c53b7147b678 100644 (file)
@@ -141,45 +141,48 @@ pub fn new(out: T) -> Result<Terminal<T>, ~str> {
     /// 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<bool> {
         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<bool> {
         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<bool> {
         match attr {
             attr::ForegroundColor(c) => self.fg(c),
             attr::BackgroundColor(c) => self.bg(c),
@@ -189,13 +192,13 @@ pub fn attr(&mut self, attr: attr::Attr) -> bool {
                 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 @@ pub fn supports_attr(&self, attr: attr::Attr) -> bool {
     }
 
     /// 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 @@ pub fn reset(&mut self) {
             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 @@ pub fn reset(&mut self) {
             // 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 @@ pub fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.out }
 }
 
 impl<T: Writer> Writer for Terminal<T> {
-    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()
     }
 }
index b0104faf4b5e608d21e1e1a9c6e45b56ca0a4a12..31f12bd45e69243093c7862336940c436ebfaaca 100644 (file)
 /// 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(),
index 8cbb090269783c16f3697b95d5bf0f4576365cff..421f8581b5836f0b238101d6b2836a7fd9d255b1 100644 (file)
@@ -77,8 +77,8 @@ pub fn open(term: &str) -> Result<File, ~str> {
     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))