mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-15 08:23:26 +00:00
stdlib: Make io failures recoverable by returning a result
This commit is contained in:
parent
2b62a80202
commit
2cebef095e
@ -11,7 +11,7 @@ import syntax::print::{pp, pprust};
|
||||
import util::{ppaux, common, filesearch};
|
||||
import back::link;
|
||||
import lib::llvm;
|
||||
import std::{fs, option, str, vec, int, io, run, getopts};
|
||||
import std::{fs, option, str, vec, int, io, run, getopts, result};
|
||||
import std::map::mk_hashmap;
|
||||
import std::option::{some, none};
|
||||
import std::getopts::{optopt, optmulti, optflag, optflagopt, opt_present};
|
||||
@ -77,10 +77,16 @@ fn parse_input(sess: session::session, cfg: ast::crate_cfg, input: str) ->
|
||||
|
||||
fn parse_input_src(sess: session::session, cfg: ast::crate_cfg, infile: str)
|
||||
-> {crate: @ast::crate, src: str} {
|
||||
let srcbytes =
|
||||
if infile != "-" {
|
||||
io::file_reader(infile)
|
||||
} else { io::stdin() }.read_whole_stream();
|
||||
let srcbytes = if infile != "-" {
|
||||
alt io::file_reader(infile) {
|
||||
result::ok(reader) { reader }
|
||||
result::err(e) {
|
||||
sess.fatal(e)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
io::stdin()
|
||||
}.read_whole_stream();
|
||||
let src = str::unsafe_from_bytes(srcbytes);
|
||||
let crate =
|
||||
parser::parse_crate_from_source_str(infile, src, cfg,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import std::{vec, uint, str, term, io, option};
|
||||
import std::{vec, uint, str, term, io, option, result};
|
||||
import std::option::{some, none};
|
||||
|
||||
type filename = str;
|
||||
@ -154,7 +154,13 @@ fn maybe_highlight_lines(sp: option::t<span>, cm: codemap,
|
||||
|
||||
// FIXME: reading in the entire file is the worst possible way to
|
||||
// get access to the necessary lines.
|
||||
let file = io::read_whole_file_str(lines.name);
|
||||
let file = alt io::read_whole_file_str(lines.name) {
|
||||
result::ok(file) { file }
|
||||
result::err(e) {
|
||||
emit_error(none, e, cm);
|
||||
fail;
|
||||
}
|
||||
};
|
||||
let fm = get_filemap(cm, lines.name);
|
||||
|
||||
// arbitrarily only print up to six lines of the error
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
import std::{io, vec, str, option, either};
|
||||
import std::{io, vec, str, option, either, result};
|
||||
import std::option::{some, none};
|
||||
import std::either::{left, right};
|
||||
import std::map::{hashmap, new_str_hash};
|
||||
@ -53,7 +53,16 @@ type parser =
|
||||
fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: str,
|
||||
chpos: uint, byte_pos: uint, ftype: file_type) ->
|
||||
parser {
|
||||
let src = io::read_whole_file_str(path);
|
||||
let src = alt io::read_whole_file_str(path) {
|
||||
result::ok(src) {
|
||||
// FIXME: This copy is unfortunate
|
||||
src
|
||||
}
|
||||
result::err(e) {
|
||||
codemap::emit_error(none, e, sess.cm);
|
||||
fail;
|
||||
}
|
||||
};
|
||||
let filemap = codemap::new_filemap(path, chpos, byte_pos);
|
||||
sess.cm.files += [filemap];
|
||||
let itr = @interner::mk(str::hash, str::eq);
|
||||
|
@ -63,7 +63,7 @@ fn is_test_ignored(config: config, testfile: str) -> bool {
|
||||
}
|
||||
|
||||
fn iter_header(testfile: str, it: block(str)) {
|
||||
let rdr = io::file_reader(testfile);
|
||||
let rdr = std::result::get(io::file_reader(testfile));
|
||||
while !rdr.eof() {
|
||||
let ln = rdr.read_line();
|
||||
|
||||
|
@ -5,6 +5,7 @@ import std::fs;
|
||||
import std::os;
|
||||
import std::vec;
|
||||
import std::test;
|
||||
import std::result;
|
||||
|
||||
import common::mode_run_pass;
|
||||
import common::mode_run_fail;
|
||||
@ -92,7 +93,7 @@ fn run_pretty_test(cx: cx, props: test_props, testfile: str) {
|
||||
let rounds =
|
||||
alt props.pp_exact { option::some(_) { 1 } option::none. { 2 } };
|
||||
|
||||
let srcs = [io::read_whole_file_str(testfile)];
|
||||
let srcs = [result::get(io::read_whole_file_str(testfile))];
|
||||
|
||||
let round = 0;
|
||||
while round < rounds {
|
||||
@ -112,7 +113,7 @@ fn run_pretty_test(cx: cx, props: test_props, testfile: str) {
|
||||
alt props.pp_exact {
|
||||
option::some(file) {
|
||||
let filepath = fs::connect(fs::dirname(testfile), file);
|
||||
io::read_whole_file_str(filepath)
|
||||
result::get(io::read_whole_file_str(filepath))
|
||||
}
|
||||
option::none. { srcs[vec::len(srcs) - 2u] }
|
||||
};
|
||||
@ -339,7 +340,8 @@ fn dump_output(config: config, testfile: str, out: str, err: str) {
|
||||
#[cfg(target_os = "linux")]
|
||||
fn dump_output_file(config: config, testfile: str, out: str, extension: str) {
|
||||
let outfile = make_out_name(config, testfile, extension);
|
||||
let writer = io::file_writer(outfile, [io::create, io::truncate]);
|
||||
let writer = result::get(
|
||||
io::file_writer(outfile, [io::create, io::truncate]));
|
||||
writer.write_str(out);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std;
|
||||
use rustc;
|
||||
|
||||
import std::{fs, io, getopts, math, vec, str, int, uint, option};
|
||||
import std::{fs, io, getopts, math, vec, str, int, uint, option, result};
|
||||
import std::getopts::{optopt, opt_present, opt_str};
|
||||
import std::io::stdout;
|
||||
|
||||
@ -13,7 +13,9 @@ tag test_mode { tm_converge; tm_run; }
|
||||
type context = { mode: test_mode }; // + rng
|
||||
|
||||
fn write_file(filename: str, content: str) {
|
||||
io::file_writer(filename, [io::create, io::truncate]).write_str(content);
|
||||
result::get(
|
||||
io::file_writer(filename, [io::create, io::truncate]))
|
||||
.write_str(content);
|
||||
// Work around https://github.com/graydon/rust/issues/726
|
||||
std::run::run_program("chmod", ["644", filename]);
|
||||
}
|
||||
@ -517,7 +519,7 @@ fn check_convergence(files: [str]) {
|
||||
log_err #fmt["pp convergence tests: %u files", vec::len(files)];
|
||||
for file in files {
|
||||
if !file_might_not_converge(file) {
|
||||
let s = io::read_whole_file_str(file);
|
||||
let s = result::get(io::read_whole_file_str(file));
|
||||
if !content_might_not_converge(s) {
|
||||
log_err #fmt["pp converge: %s", file];
|
||||
// Change from 7u to 2u once https://github.com/graydon/rust/issues/850 is fixed
|
||||
@ -533,7 +535,7 @@ fn check_variants(files: [str], cx: context) {
|
||||
cont;
|
||||
}
|
||||
|
||||
let s = io::read_whole_file_str(file);
|
||||
let s = result::get(io::read_whole_file_str(file));
|
||||
if contains(s, "#") {
|
||||
cont; // Macros are confusing
|
||||
}
|
||||
|
@ -173,14 +173,16 @@ fn stdin() -> reader {
|
||||
ret new_reader(FILE_buf_reader(rustrt::rust_get_stdin(), option::none));
|
||||
}
|
||||
|
||||
fn file_reader(path: str) -> reader {
|
||||
fn file_reader(path: str) -> result::t<reader, str> {
|
||||
let f = str::as_buf(path, {|pathbuf|
|
||||
str::as_buf("r", {|modebuf|
|
||||
os::libc::fopen(pathbuf, modebuf)
|
||||
})
|
||||
});
|
||||
if f as uint == 0u { log_err "error opening " + path; fail; }
|
||||
ret new_reader(FILE_buf_reader(f, option::some(@FILE_res(f))));
|
||||
ret if f as uint == 0u { result::err("error opening " + path) }
|
||||
else {
|
||||
result::ok(new_reader(FILE_buf_reader(f, option::some(@FILE_res(f)))))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -278,7 +280,8 @@ obj fd_buf_writer(fd: int, res: option::t<@fd_res>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn file_buf_writer(path: str, flags: [fileflag]) -> buf_writer {
|
||||
fn file_buf_writer(path: str,
|
||||
flags: [fileflag]) -> result::t<buf_writer, str> {
|
||||
let fflags: int =
|
||||
os::libc_constants::O_WRONLY() | os::libc_constants::O_BINARY();
|
||||
for f: fileflag in flags {
|
||||
@ -296,12 +299,12 @@ fn file_buf_writer(path: str, flags: [fileflag]) -> buf_writer {
|
||||
os::libc_constants::S_IRUSR() |
|
||||
os::libc_constants::S_IWUSR())
|
||||
});
|
||||
if fd < 0 {
|
||||
log_err "error opening file for writing";
|
||||
ret if fd < 0 {
|
||||
log_err sys::last_os_error();
|
||||
fail;
|
||||
result::err("error opening " + path)
|
||||
} else {
|
||||
result::ok(fd_buf_writer(fd, option::some(@fd_res(fd))))
|
||||
}
|
||||
ret fd_buf_writer(fd, option::some(@fd_res(fd)));
|
||||
}
|
||||
|
||||
type writer =
|
||||
@ -359,13 +362,15 @@ obj new_writer(out: buf_writer) {
|
||||
}
|
||||
}
|
||||
|
||||
fn file_writer(path: str, flags: [fileflag]) -> writer {
|
||||
ret new_writer(file_buf_writer(path, flags));
|
||||
fn file_writer(path: str, flags: [fileflag]) -> result::t<writer, str> {
|
||||
result::chain(file_buf_writer(path, flags), { |w|
|
||||
result::ok(new_writer(w))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// FIXME: fileflags
|
||||
fn buffered_file_buf_writer(path: str) -> buf_writer {
|
||||
fn buffered_file_buf_writer(path: str) -> result::t<buf_writer, str> {
|
||||
let f =
|
||||
str::as_buf(path,
|
||||
{|pathbuf|
|
||||
@ -374,8 +379,8 @@ fn buffered_file_buf_writer(path: str) -> buf_writer {
|
||||
os::libc::fopen(pathbuf, modebuf)
|
||||
})
|
||||
});
|
||||
if f as uint == 0u { log_err "error opening " + path; fail; }
|
||||
ret FILE_writer(f, option::some(@FILE_res(f)));
|
||||
ret if f as uint == 0u { result::err("error opening " + path) }
|
||||
else { result::ok(FILE_writer(f, option::some(@FILE_res(f)))) }
|
||||
}
|
||||
|
||||
|
||||
@ -452,14 +457,18 @@ fn seek_in_buf(offset: int, pos: uint, len: uint, whence: seek_style) ->
|
||||
ret bpos as uint;
|
||||
}
|
||||
|
||||
fn read_whole_file_str(file: str) -> str {
|
||||
str::unsafe_from_bytes(read_whole_file(file))
|
||||
fn read_whole_file_str(file: str) -> result::t<str, str> {
|
||||
result::chain(read_whole_file(file), { |bytes|
|
||||
result::ok(str::unsafe_from_bytes(bytes))
|
||||
})
|
||||
}
|
||||
|
||||
fn read_whole_file(file: str) -> [u8] {
|
||||
fn read_whole_file(file: str) -> result::t<[u8], str> {
|
||||
|
||||
// FIXME: There's a lot of copying here
|
||||
file_reader(file).read_whole_stream()
|
||||
result::chain(file_reader(file), { |rdr|
|
||||
result::ok(rdr.read_whole_stream())
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,6 +41,8 @@ fn get<T, U>(res: t<T, U>) -> T {
|
||||
alt res {
|
||||
ok(t) { t }
|
||||
err(_) {
|
||||
// FIXME: Serialize the error value
|
||||
// and include it in the fail message
|
||||
fail "get called on error result";
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import std::io;
|
||||
|
||||
import std::time;
|
||||
import std::u64;
|
||||
import std::result;
|
||||
|
||||
import std::task;
|
||||
import std::task::joinable_task;
|
||||
@ -30,7 +31,7 @@ import std::comm::recv;
|
||||
import std::comm::send;
|
||||
|
||||
fn map(filename: str, emit: map_reduce::putter) {
|
||||
let f = io::file_reader(filename);
|
||||
let f = result::get(io::file_reader(filename));
|
||||
|
||||
|
||||
while true {
|
||||
|
3
src/test/compile-fail/missingmod.rc
Normal file
3
src/test/compile-fail/missingmod.rc
Normal file
@ -0,0 +1,3 @@
|
||||
// error-pattern:error opening
|
||||
|
||||
mod doesnotexist;
|
@ -2,6 +2,7 @@
|
||||
use std;
|
||||
import std::io;
|
||||
import std::str;
|
||||
import std::result;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "win32")]
|
||||
@ -13,10 +14,10 @@ fn test_simple() {
|
||||
log frood;
|
||||
{
|
||||
let out: io::writer =
|
||||
io::file_writer(tmpfile, [io::create, io::truncate]);
|
||||
result::get(io::file_writer(tmpfile, [io::create, io::truncate]));
|
||||
out.write_str(frood);
|
||||
}
|
||||
let inp: io::reader = io::file_reader(tmpfile);
|
||||
let inp: io::reader = result::get(io::file_reader(tmpfile));
|
||||
let frood2: str = inp.read_c_str();
|
||||
log frood2;
|
||||
assert (str::eq(frood, frood2));
|
||||
@ -28,3 +29,48 @@ fn test_simple() {
|
||||
#[ignore]
|
||||
fn test_simple() { }
|
||||
|
||||
#[test]
|
||||
fn file_reader_not_exist() {
|
||||
alt io::file_reader("not a file") {
|
||||
result::err(e) {
|
||||
assert e == "error opening not a file";
|
||||
}
|
||||
result::ok(_) { fail; }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "win32")]
|
||||
#[test]
|
||||
fn file_buf_writer_bad_name() {
|
||||
alt io::file_buf_writer("/?", []) {
|
||||
result::err(e) {
|
||||
assert e == "error opening /?";
|
||||
}
|
||||
result::ok(_) { fail; }
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME (726)
|
||||
#[cfg(target_os = "macos")]
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn file_buf_writer_bad_name() { }
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "win32")]
|
||||
#[test]
|
||||
fn buffered_file_buf_writer_bad_name() {
|
||||
alt io::buffered_file_buf_writer("/?") {
|
||||
result::err(e) {
|
||||
assert e == "error opening /?";
|
||||
}
|
||||
result::ok(_) { fail; }
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME (726)
|
||||
#[cfg(target_os = "macos")]
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn buffered_file_buf_writer_bad_name() { }
|
||||
|
Loading…
Reference in New Issue
Block a user