extra: Remove io_error usage

This commit is contained in:
Alex Crichton 2014-01-29 17:39:12 -08:00
parent ece8a8f520
commit ef00c6a278
12 changed files with 324 additions and 242 deletions

View File

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

View File

@ -234,6 +234,10 @@ use serialize::Encodable;
use serialize;
use treemap::TreeMap;
macro_rules! if_ok( ($e:expr) => (
match $e { Ok(e) => e, Err(e) => { self.error = Err(e); return } }
) )
/// Represents a json value
#[deriving(Clone, Eq)]
pub enum Json {
@ -260,6 +264,14 @@ pub struct Error {
priv msg: ~str,
}
fn io_error_to_error(io: io::IoError) -> Error {
Error {
line: 0,
col: 0,
msg: format!("io error: {}", io)
}
}
fn escape_str(s: &str) -> ~str {
let mut escaped = ~"\"";
for c in s.chars() {
@ -289,13 +301,14 @@ fn spaces(n: uint) -> ~str {
/// A structure for implementing serialization to JSON.
pub struct Encoder<'a> {
priv wr: &'a mut io::Writer,
priv error: io::IoResult<()>,
}
impl<'a> Encoder<'a> {
/// Creates a new JSON encoder whose output will be written to the writer
/// specified.
pub fn new<'a>(wr: &'a mut io::Writer) -> Encoder<'a> {
Encoder { wr: wr }
Encoder { wr: wr, error: Ok(()) }
}
/// Encode the specified struct into a json [u8]
@ -317,7 +330,7 @@ impl<'a> Encoder<'a> {
}
impl<'a> serialize::Encoder for Encoder<'a> {
fn emit_nil(&mut self) { write!(self.wr, "null") }
fn emit_nil(&mut self) { if_ok!(write!(self.wr, "null")) }
fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); }
fn emit_u64(&mut self, v: u64) { self.emit_f64(v as f64); }
@ -333,20 +346,20 @@ impl<'a> serialize::Encoder for Encoder<'a> {
fn emit_bool(&mut self, v: bool) {
if v {
write!(self.wr, "true");
if_ok!(write!(self.wr, "true"));
} else {
write!(self.wr, "false");
if_ok!(write!(self.wr, "false"));
}
}
fn emit_f64(&mut self, v: f64) {
write!(self.wr, "{}", f64::to_str_digits(v, 6u))
if_ok!(write!(self.wr, "{}", f64::to_str_digits(v, 6u)))
}
fn emit_f32(&mut self, v: f32) { self.emit_f64(v as f64); }
fn emit_char(&mut self, v: char) { self.emit_str(str::from_char(v)) }
fn emit_str(&mut self, v: &str) {
write!(self.wr, "{}", escape_str(v))
if_ok!(write!(self.wr, "{}", escape_str(v)))
}
fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'a>|) { f(self) }
@ -360,19 +373,19 @@ impl<'a> serialize::Encoder for Encoder<'a> {
// Bunny => "Bunny"
// Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
if cnt == 0 {
write!(self.wr, "{}", escape_str(name));
if_ok!(write!(self.wr, "{}", escape_str(name)));
} else {
write!(self.wr, "\\{\"variant\":");
write!(self.wr, "{}", escape_str(name));
write!(self.wr, ",\"fields\":[");
if_ok!(write!(self.wr, "\\{\"variant\":"));
if_ok!(write!(self.wr, "{}", escape_str(name)));
if_ok!(write!(self.wr, ",\"fields\":["));
f(self);
write!(self.wr, "]\\}");
if_ok!(write!(self.wr, "]\\}"));
}
}
fn emit_enum_variant_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
if idx != 0 {
write!(self.wr, ",");
if_ok!(write!(self.wr, ","));
}
f(self);
}
@ -393,17 +406,17 @@ impl<'a> serialize::Encoder for Encoder<'a> {
}
fn emit_struct(&mut self, _: &str, _: uint, f: |&mut Encoder<'a>|) {
write!(self.wr, r"\{");
if_ok!(write!(self.wr, r"\{"));
f(self);
write!(self.wr, r"\}");
if_ok!(write!(self.wr, r"\}"));
}
fn emit_struct_field(&mut self,
name: &str,
idx: uint,
f: |&mut Encoder<'a>|) {
if idx != 0 { write!(self.wr, ",") }
write!(self.wr, "{}:", escape_str(name));
if idx != 0 { if_ok!(write!(self.wr, ",")) }
if_ok!(write!(self.wr, "{}:", escape_str(name)));
f(self);
}
@ -429,31 +442,31 @@ impl<'a> serialize::Encoder for Encoder<'a> {
fn emit_option_some(&mut self, f: |&mut Encoder<'a>|) { f(self); }
fn emit_seq(&mut self, _len: uint, f: |&mut Encoder<'a>|) {
write!(self.wr, "[");
if_ok!(write!(self.wr, "["));
f(self);
write!(self.wr, "]");
if_ok!(write!(self.wr, "]"));
}
fn emit_seq_elt(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
if idx != 0 {
write!(self.wr, ",");
if_ok!(write!(self.wr, ","));
}
f(self)
}
fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'a>|) {
write!(self.wr, r"\{");
if_ok!(write!(self.wr, r"\{"));
f(self);
write!(self.wr, r"\}");
if_ok!(write!(self.wr, r"\}"));
}
fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
if idx != 0 { write!(self.wr, ",") }
if idx != 0 { if_ok!(write!(self.wr, ",")) }
f(self)
}
fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
write!(self.wr, ":");
if_ok!(write!(self.wr, ":"));
f(self)
}
}
@ -463,6 +476,7 @@ impl<'a> serialize::Encoder for Encoder<'a> {
pub struct PrettyEncoder<'a> {
priv wr: &'a mut io::Writer,
priv indent: uint,
priv error: io::IoResult<()>,
}
impl<'a> PrettyEncoder<'a> {
@ -471,12 +485,13 @@ impl<'a> PrettyEncoder<'a> {
PrettyEncoder {
wr: wr,
indent: 0,
error: Ok(())
}
}
}
impl<'a> serialize::Encoder for PrettyEncoder<'a> {
fn emit_nil(&mut self) { write!(self.wr, "null") }
fn emit_nil(&mut self) { if_ok!(write!(self.wr, "null")); }
fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); }
fn emit_u64(&mut self, v: u64) { self.emit_f64(v as f64); }
@ -492,19 +507,21 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
fn emit_bool(&mut self, v: bool) {
if v {
write!(self.wr, "true");
if_ok!(write!(self.wr, "true"));
} else {
write!(self.wr, "false");
if_ok!(write!(self.wr, "false"));
}
}
fn emit_f64(&mut self, v: f64) {
write!(self.wr, "{}", f64::to_str_digits(v, 6u))
if_ok!(write!(self.wr, "{}", f64::to_str_digits(v, 6u)));
}
fn emit_f32(&mut self, v: f32) { self.emit_f64(v as f64); }
fn emit_char(&mut self, v: char) { self.emit_str(str::from_char(v)) }
fn emit_str(&mut self, v: &str) { write!(self.wr, "{}", escape_str(v)); }
fn emit_str(&mut self, v: &str) {
if_ok!(write!(self.wr, "{}", escape_str(v)));
}
fn emit_enum(&mut self, _name: &str, f: |&mut PrettyEncoder<'a>|) {
f(self)
@ -516,13 +533,14 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
cnt: uint,
f: |&mut PrettyEncoder<'a>|) {
if cnt == 0 {
write!(self.wr, "{}", escape_str(name));
if_ok!(write!(self.wr, "{}", escape_str(name)));
} else {
self.indent += 2;
write!(self.wr, "[\n{}{},\n", spaces(self.indent), escape_str(name));
if_ok!(write!(self.wr, "[\n{}{},\n", spaces(self.indent),
escape_str(name)));
f(self);
self.indent -= 2;
write!(self.wr, "\n{}]", spaces(self.indent));
if_ok!(write!(self.wr, "\n{}]", spaces(self.indent)));
}
}
@ -530,9 +548,9 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
idx: uint,
f: |&mut PrettyEncoder<'a>|) {
if idx != 0 {
write!(self.wr, ",\n");
if_ok!(write!(self.wr, ",\n"));
}
write!(self.wr, "{}", spaces(self.indent));
if_ok!(write!(self.wr, "{}", spaces(self.indent)));
f(self)
}
@ -557,13 +575,13 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
len: uint,
f: |&mut PrettyEncoder<'a>|) {
if len == 0 {
write!(self.wr, "\\{\\}");
if_ok!(write!(self.wr, "\\{\\}"));
} else {
write!(self.wr, "\\{");
if_ok!(write!(self.wr, "\\{"));
self.indent += 2;
f(self);
self.indent -= 2;
write!(self.wr, "\n{}\\}", spaces(self.indent));
if_ok!(write!(self.wr, "\n{}\\}", spaces(self.indent)));
}
}
@ -572,11 +590,11 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
idx: uint,
f: |&mut PrettyEncoder<'a>|) {
if idx == 0 {
write!(self.wr, "\n");
if_ok!(write!(self.wr, "\n"));
} else {
write!(self.wr, ",\n");
if_ok!(write!(self.wr, ",\n"));
}
write!(self.wr, "{}{}: ", spaces(self.indent), escape_str(name));
if_ok!(write!(self.wr, "{}{}: ", spaces(self.indent), escape_str(name)));
f(self);
}
@ -605,50 +623,50 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
fn emit_seq(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) {
if len == 0 {
write!(self.wr, "[]");
if_ok!(write!(self.wr, "[]"));
} else {
write!(self.wr, "[");
if_ok!(write!(self.wr, "["));
self.indent += 2;
f(self);
self.indent -= 2;
write!(self.wr, "\n{}]", spaces(self.indent));
if_ok!(write!(self.wr, "\n{}]", spaces(self.indent)));
}
}
fn emit_seq_elt(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) {
if idx == 0 {
write!(self.wr, "\n");
if_ok!(write!(self.wr, "\n"));
} else {
write!(self.wr, ",\n");
if_ok!(write!(self.wr, ",\n"));
}
write!(self.wr, "{}", spaces(self.indent));
if_ok!(write!(self.wr, "{}", spaces(self.indent)));
f(self)
}
fn emit_map(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) {
if len == 0 {
write!(self.wr, "\\{\\}");
if_ok!(write!(self.wr, "\\{\\}"));
} else {
write!(self.wr, "\\{");
if_ok!(write!(self.wr, "\\{"));
self.indent += 2;
f(self);
self.indent -= 2;
write!(self.wr, "\n{}\\}", spaces(self.indent));
if_ok!(write!(self.wr, "\n{}\\}", spaces(self.indent)));
}
}
fn emit_map_elt_key(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) {
if idx == 0 {
write!(self.wr, "\n");
if_ok!(write!(self.wr, "\n"));
} else {
write!(self.wr, ",\n");
if_ok!(write!(self.wr, ",\n"));
}
write!(self.wr, "{}", spaces(self.indent));
if_ok!(write!(self.wr, "{}", spaces(self.indent)));
f(self);
}
fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut PrettyEncoder<'a>|) {
write!(self.wr, ": ");
if_ok!(write!(self.wr, ": "));
f(self);
}
}
@ -668,22 +686,24 @@ impl<E: serialize::Encoder> serialize::Encodable<E> for Json {
impl Json{
/// Encodes a json value into a io::writer. Uses a single line.
pub fn to_writer(&self, wr: &mut io::Writer) {
pub fn to_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> {
let mut encoder = Encoder::new(wr);
self.encode(&mut encoder)
self.encode(&mut encoder);
encoder.error
}
/// Encodes a json value into a io::writer.
/// Pretty-prints in a more readable format.
pub fn to_pretty_writer(&self, wr: &mut io::Writer) {
pub fn to_pretty_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> {
let mut encoder = PrettyEncoder::new(wr);
self.encode(&mut encoder)
self.encode(&mut encoder);
encoder.error
}
/// Encodes a json value into a string
pub fn to_pretty_str(&self) -> ~str {
let mut s = MemWriter::new();
self.to_pretty_writer(&mut s as &mut io::Writer);
self.to_pretty_writer(&mut s as &mut io::Writer).unwrap();
str::from_utf8_owned(s.unwrap()).unwrap()
}
}
@ -1067,7 +1087,14 @@ impl<T : Iterator<char>> Parser<T> {
/// Decodes a json value from an `&mut io::Reader`
pub fn from_reader(rdr: &mut io::Reader) -> Result<Json, Error> {
let s = str::from_utf8_owned(rdr.read_to_end()).unwrap();
let contents = match rdr.read_to_end() {
Ok(c) => c,
Err(e) => return Err(io_error_to_error(e))
};
let s = match str::from_utf8_owned(contents) {
Some(s) => s,
None => return Err(Error { line: 0, col: 0, msg: ~"contents not utf-8" })
};
let mut parser = Parser::new(s.chars());
parser.parse()
}
@ -1540,7 +1567,7 @@ impl to_str::ToStr for Json {
/// Encodes a json value into a string
fn to_str(&self) -> ~str {
let mut s = MemWriter::new();
self.to_writer(&mut s as &mut io::Writer);
self.to_writer(&mut s as &mut io::Writer).unwrap();
str::from_utf8_owned(s.unwrap()).unwrap()
}
}

View File

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

View 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

View File

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

View 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 @@ impl<T: Writer> ConsoleTestState<T> {
metrics: MetricMap::new(),
failures: ~[],
max_name_len: 0u,
}
})
}
pub fn write_ok(&mut self) {
self.write_pretty("ok", term::color::GREEN);
pub fn write_ok(&mut self) -> io::IoResult<()> {
self.write_pretty("ok", term::color::GREEN)
}
pub fn write_failed(&mut self) {
self.write_pretty("FAILED", term::color::RED);
pub fn write_failed(&mut self) -> io::IoResult<()> {
self.write_pretty("FAILED", term::color::RED)
}
pub fn write_ignored(&mut self) {
self.write_pretty("ignored", term::color::YELLOW);
pub fn write_ignored(&mut self) -> io::IoResult<()> {
self.write_pretty("ignored", term::color::YELLOW)
}
pub fn write_metric(&mut self) {
self.write_pretty("metric", term::color::CYAN);
pub fn write_metric(&mut self) -> io::IoResult<()> {
self.write_pretty("metric", term::color::CYAN)
}
pub fn write_bench(&mut self) {
self.write_pretty("bench", term::color::CYAN);
pub fn write_bench(&mut self) -> io::IoResult<()> {
self.write_pretty("bench", term::color::CYAN)
}
pub fn write_added(&mut self) {
self.write_pretty("added", term::color::GREEN);
pub fn write_added(&mut self) -> io::IoResult<()> {
self.write_pretty("added", term::color::GREEN)
}
pub fn write_improved(&mut self) {
self.write_pretty("improved", term::color::GREEN);
pub fn write_improved(&mut self) -> io::IoResult<()> {
self.write_pretty("improved", term::color::GREEN)
}
pub fn write_removed(&mut self) {
self.write_pretty("removed", term::color::YELLOW);
pub fn write_removed(&mut self) -> io::IoResult<()> {
self.write_pretty("removed", term::color::YELLOW)
}
pub fn write_regressed(&mut self) {
self.write_pretty("regressed", term::color::RED);
pub fn write_regressed(&mut self) -> io::IoResult<()> {
self.write_pretty("regressed", term::color::RED)
}
pub fn write_pretty(&mut self,
word: &str,
color: term::color::Color) {
color: term::color::Color) -> io::IoResult<()> {
match self.out {
Pretty(ref mut term) => {
if self.use_color {
term.fg(color);
if_ok!(term.fg(color));
}
term.write(word.as_bytes());
if_ok!(term.write(word.as_bytes()));
if self.use_color {
term.reset();
if_ok!(term.reset());
}
Ok(())
}
Raw(ref mut stdout) => stdout.write(word.as_bytes())
}
}
pub fn write_plain(&mut self, s: &str) {
pub fn write_plain(&mut self, s: &str) -> io::IoResult<()> {
match self.out {
Pretty(ref mut term) => term.write(s.as_bytes()),
Raw(ref mut stdout) => stdout.write(s.as_bytes())
}
}
pub fn write_run_start(&mut self, len: uint) {
pub fn write_run_start(&mut self, len: uint) -> io::IoResult<()> {
self.total = len;
let noun = if len != 1 { &"tests" } else { &"test" };
self.write_plain(format!("\nrunning {} {}\n", len, noun));
self.write_plain(format!("\nrunning {} {}\n", len, noun))
}
pub fn write_test_start(&mut self, test: &TestDesc, align: NamePadding) {
pub fn write_test_start(&mut self, test: &TestDesc,
align: NamePadding) -> io::IoResult<()> {
let name = test.padded_name(self.max_name_len, align);
self.write_plain(format!("test {} ... ", name));
self.write_plain(format!("test {} ... ", name))
}
pub fn write_result(&mut self, result: &TestResult) {
match *result {
pub fn write_result(&mut self, result: &TestResult) -> io::IoResult<()> {
if_ok!(match *result {
TrOk => self.write_ok(),
TrFailed => self.write_failed(),
TrIgnored => self.write_ignored(),
TrMetrics(ref mm) => {
self.write_metric();
self.write_plain(format!(": {}", fmt_metrics(mm)));
if_ok!(self.write_metric());
self.write_plain(format!(": {}", fmt_metrics(mm)))
}
TrBench(ref bs) => {
self.write_bench();
self.write_plain(format!(": {}", fmt_bench_samples(bs)));
if_ok!(self.write_bench());
self.write_plain(format!(": {}", fmt_bench_samples(bs)))
}
}
self.write_plain("\n");
});
self.write_plain("\n")
}
pub fn write_log(&mut self, test: &TestDesc, result: &TestResult) {
pub fn write_log(&mut self, test: &TestDesc,
result: &TestResult) -> io::IoResult<()> {
match self.log_out {
None => (),
None => Ok(()),
Some(ref mut o) => {
let s = format!("{} {}\n", match *result {
TrOk => ~"ok",
@ -482,24 +490,25 @@ impl<T: Writer> ConsoleTestState<T> {
TrMetrics(ref mm) => fmt_metrics(mm),
TrBench(ref bs) => fmt_bench_samples(bs)
}, test.name.to_str());
o.write(s.as_bytes());
o.write(s.as_bytes())
}
}
}
pub fn write_failures(&mut self) {
self.write_plain("\nfailures:\n");
pub fn write_failures(&mut self) -> io::IoResult<()> {
if_ok!(self.write_plain("\nfailures:\n"));
let mut failures = ~[];
for f in self.failures.iter() {
failures.push(f.name.to_str());
}
failures.sort();
for name in failures.iter() {
self.write_plain(format!(" {}\n", name.to_str()));
if_ok!(self.write_plain(format!(" {}\n", name.to_str())));
}
Ok(())
}
pub fn write_metric_diff(&mut self, diff: &MetricDiff) {
pub fn write_metric_diff(&mut self, diff: &MetricDiff) -> io::IoResult<()> {
let mut noise = 0;
let mut improved = 0;
let mut regressed = 0;
@ -511,77 +520,82 @@ impl<T: Writer> ConsoleTestState<T> {
LikelyNoise => noise += 1,
MetricAdded => {
added += 1;
self.write_added();
self.write_plain(format!(": {}\n", *k));
if_ok!(self.write_added());
if_ok!(self.write_plain(format!(": {}\n", *k)));
}
MetricRemoved => {
removed += 1;
self.write_removed();
self.write_plain(format!(": {}\n", *k));
if_ok!(self.write_removed());
if_ok!(self.write_plain(format!(": {}\n", *k)));
}
Improvement(pct) => {
improved += 1;
self.write_plain(format!(": {}", *k));
self.write_improved();
self.write_plain(format!(" by {:.2f}%\n", pct as f64));
if_ok!(self.write_plain(format!(": {}", *k)));
if_ok!(self.write_improved());
if_ok!(self.write_plain(format!(" by {:.2f}%\n", pct as f64)));
}
Regression(pct) => {
regressed += 1;
self.write_plain(format!(": {}", *k));
self.write_regressed();
self.write_plain(format!(" by {:.2f}%\n", pct as f64));
if_ok!(self.write_plain(format!(": {}", *k)));
if_ok!(self.write_regressed());
if_ok!(self.write_plain(format!(" by {:.2f}%\n", pct as f64)));
}
}
}
self.write_plain(format!("result of ratchet: {} matrics added, {} removed, \
{} improved, {} regressed, {} noise\n",
added, removed, improved, regressed, noise));
if_ok!(self.write_plain(format!("result of ratchet: {} matrics added, \
{} removed, {} improved, {} regressed, \
{} noise\n",
added, removed, improved, regressed,
noise)));
if regressed == 0 {
self.write_plain("updated ratchet file\n");
if_ok!(self.write_plain("updated ratchet file\n"));
} else {
self.write_plain("left ratchet file untouched\n");
if_ok!(self.write_plain("left ratchet file untouched\n"));
}
Ok(())
}
pub fn write_run_finish(&mut self,
ratchet_metrics: &Option<Path>,
ratchet_pct: Option<f64>) -> bool {
ratchet_pct: Option<f64>) -> io::IoResult<bool> {
assert!(self.passed + self.failed + self.ignored + self.measured == self.total);
let ratchet_success = match *ratchet_metrics {
None => true,
Some(ref pth) => {
self.write_plain(format!("\nusing metrics ratcher: {}\n", pth.display()));
if_ok!(self.write_plain(format!("\nusing metrics ratcher: {}\n",
pth.display())));
match ratchet_pct {
None => (),
Some(pct) =>
self.write_plain(format!("with noise-tolerance forced to: {}%\n",
pct))
if_ok!(self.write_plain(format!("with noise-tolerance \
forced to: {}%\n",
pct)))
}
let (diff, ok) = self.metrics.ratchet(pth, ratchet_pct);
self.write_metric_diff(&diff);
if_ok!(self.write_metric_diff(&diff));
ok
}
};
let test_success = self.failed == 0u;
if !test_success {
self.write_failures();
if_ok!(self.write_failures());
}
let success = ratchet_success && test_success;
self.write_plain("\ntest result: ");
if_ok!(self.write_plain("\ntest result: "));
if success {
// There's no parallelism at this point so it's safe to use color
self.write_ok();
if_ok!(self.write_ok());
} else {
self.write_failed();
if_ok!(self.write_failed());
}
let s = format!(". {} passed; {} failed; {} ignored; {} measured\n\n",
self.passed, self.failed, self.ignored, self.measured);
self.write_plain(s);
return success;
if_ok!(self.write_plain(s));
return Ok(success);
}
}
@ -611,15 +625,16 @@ pub fn fmt_bench_samples(bs: &BenchSamples) -> ~str {
// A simple console test runner
pub fn run_tests_console(opts: &TestOpts,
tests: ~[TestDescAndFn]) -> bool {
fn callback<T: Writer>(event: &TestEvent, st: &mut ConsoleTestState<T>) {
tests: ~[TestDescAndFn]) -> io::IoResult<bool> {
fn callback<T: Writer>(event: &TestEvent,
st: &mut ConsoleTestState<T>) -> io::IoResult<()> {
debug!("callback(event={:?})", event);
match (*event).clone() {
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
TeWait(ref test, padding) => st.write_test_start(test, padding),
TeResult(test, result) => {
st.write_log(&test, &result);
st.write_result(&result);
if_ok!(st.write_log(&test, &result));
if_ok!(st.write_result(&result));
match result {
TrOk => st.passed += 1,
TrIgnored => st.ignored += 1,
@ -643,10 +658,11 @@ pub fn run_tests_console(opts: &TestOpts,
st.failures.push(test);
}
}
Ok(())
}
}
}
let mut st = ConsoleTestState::new(opts, None::<StdWriter>);
let mut st = if_ok!(ConsoleTestState::new(opts, None::<StdWriter>));
fn len_if_padded(t: &TestDescAndFn) -> uint {
match t.testfn.padding() {
PadNone => 0u,
@ -661,12 +677,13 @@ pub fn run_tests_console(opts: &TestOpts,
},
None => {}
}
run_tests(opts, tests, |x| callback(&x, &mut st));
if_ok!(run_tests(opts, tests, |x| callback(&x, &mut st)));
match opts.save_metrics {
None => (),
Some(ref pth) => {
st.metrics.save(pth);
st.write_plain(format!("\nmetrics saved to: {}", pth.display()));
if_ok!(st.metrics.save(pth));
if_ok!(st.write_plain(format!("\nmetrics saved to: {}",
pth.display())));
}
}
return st.write_run_finish(&opts.ratchet_metrics, opts.ratchet_noise_percent);
@ -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)
}

View File

@ -766,14 +766,14 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ~str> {
let mut buf = [0];
let c = match rdr.read(buf) {
Some(..) => buf[0] as char,
None => break
Ok(..) => buf[0] as char,
Err(..) => break
};
match c {
'%' => {
let ch = match rdr.read(buf) {
Some(..) => buf[0] as char,
None => break
Ok(..) => buf[0] as char,
Err(..) => break
};
match parse_type(s, pos, ch, &mut tm) {
Ok(next) => pos = next,
@ -787,7 +787,7 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ~str> {
}
}
if pos == len && rdr.tell() as uint == format.len() {
if pos == len && rdr.tell().unwrap() == format.len() as u64 {
Ok(Tm {
tm_sec: tm.tm_sec,
tm_min: tm.tm_min,
@ -1017,12 +1017,12 @@ pub fn strftime(format: &str, tm: &Tm) -> ~str {
loop {
let mut b = [0];
let ch = match rdr.read(b) {
Some(..) => b[0],
None => break,
Ok(..) => b[0],
Err(..) => break,
};
match ch as char {
'%' => {
rdr.read(b);
rdr.read(b).unwrap();
let s = parse_type(b[0] as char, tm);
buf.push_all(s.as_bytes());
}

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

View File

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

View File

@ -141,45 +141,48 @@ impl<T: Writer> Terminal<T> {
/// 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 @@ impl<T: Writer> Terminal<T> {
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<T: Writer> Terminal<T> {
}
/// 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<T: Writer> Terminal<T> {
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<T: Writer> Terminal<T> {
// 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<T: Writer> Terminal<T> {
}
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()
}
}

View File

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

View 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))