Major clean-up of std::io
Use ifaces instead of objs, stop wrapping everything in two (or three) layers of no-value-added indirection, and remove some of the more pointless/outdated idioms from the code.
This commit is contained in:
parent
807592e99f
commit
34d7f05292
31 changed files with 309 additions and 416 deletions
|
|
@ -10,6 +10,7 @@ import rustc::util::filesearch::get_cargo_root;
|
|||
import std::fs;
|
||||
import std::generic_os;
|
||||
import std::io;
|
||||
import io::writer_util;
|
||||
import std::json;
|
||||
import option;
|
||||
import option::{none, some};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
|
||||
// -*- rust -*-
|
||||
import metadata::{creader, cstore};
|
||||
import syntax::parse::{parser};
|
||||
|
|
@ -13,6 +12,7 @@ import back::link;
|
|||
import core::{option, str, int, result};
|
||||
import result::{ok, err};
|
||||
import std::{fs, io, getopts};
|
||||
import io::reader_util;
|
||||
import option::{some, none};
|
||||
import getopts::{optopt, optmulti, optflag, optflagopt, opt_present};
|
||||
import back::{x86, x86_64};
|
||||
|
|
@ -84,7 +84,7 @@ 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 != "-" {
|
||||
let src_stream = if infile != "-" {
|
||||
alt io::file_reader(infile) {
|
||||
result::ok(reader) { reader }
|
||||
result::err(e) {
|
||||
|
|
@ -93,7 +93,8 @@ fn parse_input_src(sess: session::session, cfg: ast::crate_cfg, infile: str)
|
|||
}
|
||||
} else {
|
||||
io::stdin()
|
||||
}.read_whole_stream();
|
||||
};
|
||||
let srcbytes = src_stream.read_whole_stream();
|
||||
let src = str::unsafe_from_bytes(srcbytes);
|
||||
let crate =
|
||||
parser::parse_crate_from_source_str(infile, src, cfg,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use rustc;
|
|||
import core::{option, str, vec, result};
|
||||
import result::{ok, err};
|
||||
import std::{io, getopts};
|
||||
import io::writer_util;
|
||||
import option::{some, none};
|
||||
import getopts::{opt_present};
|
||||
import rustc::driver::driver::*;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import front::attr;
|
|||
import syntax::visit;
|
||||
import syntax::codemap::span;
|
||||
import util::{filesearch};
|
||||
import core::{either, vec, str, option};
|
||||
import std::{io, fs};
|
||||
import io::writer_util;
|
||||
import option::{none, some};
|
||||
import std::map::{hashmap, new_int_hash};
|
||||
import syntax::print::pprust;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Decoding metadata from a single crate's metadata
|
||||
|
||||
import std::{ebml, io};
|
||||
import io::writer_util;
|
||||
import syntax::{ast, ast_util};
|
||||
import front::attr;
|
||||
import middle::ty;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Metadata encoding
|
||||
|
||||
import core::{vec, str, uint};
|
||||
import std::{io, ebml, map};
|
||||
import io::writer_util;
|
||||
import syntax::ast::*;
|
||||
import syntax::ast_util;
|
||||
import syntax::ast_util::local_def;
|
||||
|
|
@ -191,7 +191,7 @@ fn encode_type_param_bounds(ebml_w: ebml::writer, ecx: @encode_ctxt,
|
|||
for param in params {
|
||||
ebml::start_tag(ebml_w, tag_items_data_item_ty_param_bounds);
|
||||
let bs = ecx.ccx.tcx.ty_param_bounds.get(param.id);
|
||||
tyencode::enc_bounds(io::new_writer(ebml_w.writer), ty_str_ctxt, bs);
|
||||
tyencode::enc_bounds(ebml_w.writer, ty_str_ctxt, bs);
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
}
|
||||
|
|
@ -207,7 +207,7 @@ fn write_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
|
|||
@{ds: def_to_str,
|
||||
tcx: ecx.ccx.tcx,
|
||||
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
|
||||
tyencode::enc_ty(io::new_writer(ebml_w.writer), ty_str_ctxt, typ);
|
||||
tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
|
||||
}
|
||||
|
||||
fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
|
||||
|
|
@ -522,7 +522,7 @@ fn create_index<T: copy>(index: [entry<T>], hash_fn: fn(T) -> uint) ->
|
|||
|
||||
fn encode_index<T>(ebml_w: ebml::writer, buckets: [@[entry<T>]],
|
||||
write_fn: fn(io::writer, T)) {
|
||||
let writer = io::new_writer(ebml_w.writer);
|
||||
let writer = ebml_w.writer;
|
||||
ebml::start_tag(ebml_w, tag_index);
|
||||
let bucket_locs: [uint] = [];
|
||||
ebml::start_tag(ebml_w, tag_index_buckets);
|
||||
|
|
@ -702,8 +702,8 @@ fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> str {
|
|||
let abbrevs = ty::new_ty_hash();
|
||||
let ecx = @{ccx: cx, type_abbrevs: abbrevs};
|
||||
|
||||
let string_w = io::string_writer();
|
||||
let buf_w = string_w.get_writer().get_buf_writer();
|
||||
let buf = io::mk_mem_buffer();
|
||||
let buf_w = io::mem_buffer_writer(buf);
|
||||
let ebml_w = ebml::create_writer(buf_w);
|
||||
|
||||
encode_hash(ebml_w, cx.link_meta.extras_hash);
|
||||
|
|
@ -714,32 +714,31 @@ fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> str {
|
|||
encode_crate_deps(ebml_w, cx.sess.get_cstore());
|
||||
|
||||
// Encode and index the paths.
|
||||
|
||||
ebml::start_tag(ebml_w, tag_paths);
|
||||
let paths_index = encode_item_paths(ebml_w, ecx, crate);
|
||||
let paths_buckets = create_index(paths_index, hash_path);
|
||||
encode_index(ebml_w, paths_buckets, write_str);
|
||||
ebml::end_tag(ebml_w);
|
||||
// Encode and index the items.
|
||||
|
||||
// Encode and index the items.
|
||||
ebml::start_tag(ebml_w, tag_items);
|
||||
let items_index = encode_info_for_items(ecx, ebml_w, crate.node.module);
|
||||
let items_buckets = create_index(items_index, hash_node_id);
|
||||
encode_index(ebml_w, items_buckets, write_int);
|
||||
ebml::end_tag(ebml_w);
|
||||
|
||||
// Pad this, since something (LLVM, presumably) is cutting off the
|
||||
// remaining % 4 bytes.
|
||||
|
||||
buf_w.write([0u8, 0u8, 0u8, 0u8]);
|
||||
ret string_w.get_str();
|
||||
io::mem_buffer_str(buf)
|
||||
}
|
||||
|
||||
// Get the encoded string for a type
|
||||
fn encoded_ty(tcx: ty::ctxt, t: ty::t) -> str {
|
||||
let cx = @{ds: def_to_str, tcx: tcx, abbrevs: tyencode::ac_no_abbrevs};
|
||||
let sw = io::string_writer();
|
||||
tyencode::enc_ty(sw.get_writer(), cx, t);
|
||||
ret sw.get_str();
|
||||
let buf = io::mk_mem_buffer();
|
||||
tyencode::enc_ty(io::mem_buffer_writer(buf), cx, t);
|
||||
ret io::mem_buffer_str(buf);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Type encoding
|
||||
|
||||
import core::{int, uint};
|
||||
import std::io;
|
||||
import io::writer_util;
|
||||
import std::map::hashmap;
|
||||
import option::{some, none};
|
||||
import syntax::ast::*;
|
||||
|
|
@ -37,25 +37,24 @@ fn cx_uses_abbrevs(cx: @ctxt) -> bool {
|
|||
fn enc_ty(w: io::writer, cx: @ctxt, t: ty::t) {
|
||||
alt cx.abbrevs {
|
||||
ac_no_abbrevs. {
|
||||
let result_str: @str;
|
||||
alt cx.tcx.short_names_cache.find(t) {
|
||||
some(s) { result_str = s; }
|
||||
let result_str = alt cx.tcx.short_names_cache.find(t) {
|
||||
some(s) { *s }
|
||||
none. {
|
||||
let sw = io::string_writer();
|
||||
enc_sty(sw.get_writer(), cx, ty::struct(cx.tcx, t));
|
||||
result_str = @sw.get_str();
|
||||
cx.tcx.short_names_cache.insert(t, result_str);
|
||||
let buf = io::mk_mem_buffer();
|
||||
enc_sty(io::mem_buffer_writer(buf), cx, ty::struct(cx.tcx, t));
|
||||
cx.tcx.short_names_cache.insert(t, @io::mem_buffer_str(buf));
|
||||
io::mem_buffer_str(buf)
|
||||
}
|
||||
}
|
||||
w.write_str(*result_str);
|
||||
};
|
||||
w.write_str(result_str);
|
||||
}
|
||||
ac_use_abbrevs(abbrevs) {
|
||||
alt abbrevs.find(t) {
|
||||
some(a) { w.write_str(*a.s); ret; }
|
||||
none. {
|
||||
let pos = w.get_buf_writer().tell();
|
||||
let pos = w.tell();
|
||||
enc_sty(w, cx, ty::struct(cx.tcx, t));
|
||||
let end = w.get_buf_writer().tell();
|
||||
let end = w.tell();
|
||||
let len = end - pos;
|
||||
fn estimate_sz(u: uint) -> uint {
|
||||
let n = u;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import core::{vec, uint, str, option, result};
|
||||
import std::{term, io};
|
||||
import io::writer_util;
|
||||
import option::{some, none};
|
||||
|
||||
type filename = str;
|
||||
|
|
@ -126,11 +127,11 @@ fn print_diagnostic(topic: str, t: diagnostictype, msg: str) {
|
|||
io::stdout().write_str(#fmt["%s ", topic]);
|
||||
}
|
||||
if term::color_supported() {
|
||||
term::fg(io::stdout().get_buf_writer(), diagnosticcolor(t));
|
||||
term::fg(io::stdout(), diagnosticcolor(t));
|
||||
}
|
||||
io::stdout().write_str(#fmt["%s:", diagnosticstr(t)]);
|
||||
if term::color_supported() {
|
||||
term::reset(io::stdout().get_buf_writer());
|
||||
term::reset(io::stdout());
|
||||
}
|
||||
io::stdout().write_str(#fmt[" %s\n", msg]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import option;
|
||||
import base::*;
|
||||
import syntax::ast;
|
||||
import std::io::writer_util;
|
||||
|
||||
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: @ast::expr,
|
||||
_body: option::t<str>) -> @ast::expr {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
import core::{vec, str, option, either};
|
||||
import std::io;
|
||||
import io::reader_util;
|
||||
import option::{some, none};
|
||||
import util::interner;
|
||||
import util::interner::intern;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
import core::{vec, str};
|
||||
import std::io;
|
||||
import io::writer_util;
|
||||
|
||||
/*
|
||||
* This pretty-printer is a direct reimplementation of Philip Karlton's
|
||||
|
|
|
|||
|
|
@ -93,25 +93,23 @@ fn path_to_str(&&p: @ast::path) -> str {
|
|||
|
||||
fn fun_to_str(decl: ast::fn_decl, name: ast::ident,
|
||||
params: [ast::ty_param]) -> str {
|
||||
let writer = io::string_writer();
|
||||
let s = rust_printer(writer.get_writer());
|
||||
let buffer = io::mk_mem_buffer();
|
||||
let s = rust_printer(io::mem_buffer_writer(buffer));
|
||||
print_fn(s, decl, name, params);
|
||||
eof(s.s);
|
||||
ret writer.get_str();
|
||||
io::mem_buffer_str(buffer)
|
||||
}
|
||||
|
||||
fn block_to_str(blk: ast::blk) -> str {
|
||||
let writer = io::string_writer();
|
||||
let s = rust_printer(writer.get_writer());
|
||||
let buffer = io::mk_mem_buffer();
|
||||
let s = rust_printer(io::mem_buffer_writer(buffer));
|
||||
// containing cbox, will be closed by print-block at }
|
||||
|
||||
cbox(s, indent_unit);
|
||||
// head-ibox, will be closed by print-block after {
|
||||
|
||||
ibox(s, 0u);
|
||||
print_block(s, blk);
|
||||
eof(s.s);
|
||||
ret writer.get_str();
|
||||
io::mem_buffer_str(buffer)
|
||||
}
|
||||
|
||||
fn meta_item_to_str(mi: ast::meta_item) -> str {
|
||||
|
|
@ -1597,11 +1595,11 @@ fn escape_str(st: str, to_escape: char) -> str {
|
|||
}
|
||||
|
||||
fn to_str<T>(t: T, f: fn@(ps, T)) -> str {
|
||||
let writer = io::string_writer();
|
||||
let s = rust_printer(writer.get_writer());
|
||||
let buffer = io::mk_mem_buffer();
|
||||
let s = rust_printer(io::mem_buffer_writer(buffer));
|
||||
f(s, t);
|
||||
eof(s.s);
|
||||
ret writer.get_str();
|
||||
io::mem_buffer_str(buffer)
|
||||
}
|
||||
|
||||
fn next_comment(s: ps) -> option::t<lexer::cmnt> {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import option;
|
||||
import str;
|
||||
import std::io;
|
||||
import io::reader_util;
|
||||
import std::fs;
|
||||
|
||||
import common::config;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import option;
|
||||
import str;
|
||||
import std::io;
|
||||
import io::reader_util;
|
||||
import std::fs;
|
||||
|
||||
import common::config;
|
||||
|
|
|
|||
|
|
@ -4,16 +4,12 @@
|
|||
// child process. Because of that we have to use a complicated scheme with a
|
||||
// dedicated server for spawning processes.
|
||||
|
||||
import core::comm;
|
||||
import core::option;
|
||||
import task;
|
||||
import std::generic_os::setenv;
|
||||
import std::generic_os::getenv;
|
||||
import vec;
|
||||
import std::os;
|
||||
import std::run;
|
||||
import std::io;
|
||||
import str;
|
||||
import io::writer_util;
|
||||
import comm::chan;
|
||||
import comm::port;
|
||||
import comm::send;
|
||||
|
|
@ -75,7 +71,7 @@ fn run(handle: handle, lib_path: str, prog: str, args: [str],
|
|||
|
||||
fn writeclose(fd: fd_t, s: option::t<str>) {
|
||||
if option::is_some(s) {
|
||||
let writer = io::new_writer(io::fd_buf_writer(fd, option::none));
|
||||
let writer = io::fd_writer(fd, false);
|
||||
writer.write_str(option::get(s));
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +81,7 @@ fn writeclose(fd: fd_t, s: option::t<str>) {
|
|||
fn readclose(fd: fd_t) -> str {
|
||||
// Copied from run::program_output
|
||||
let file = os::fd_FILE(fd);
|
||||
let reader = io::new_reader(io::FILE_buf_reader(file, option::none));
|
||||
let reader = io::FILE_reader(file, false);
|
||||
let buf = "";
|
||||
while !reader.eof() {
|
||||
let bytes = reader.read_bytes(4096u);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
import std::io;
|
||||
import str;
|
||||
import option;
|
||||
import io::writer_util;
|
||||
import std::fs;
|
||||
import std::os;
|
||||
import vec;
|
||||
import result;
|
||||
|
||||
import common::mode_run_pass;
|
||||
import common::mode_run_fail;
|
||||
|
|
|
|||
|
|
@ -36,5 +36,5 @@ fn path_div() -> str { ";" }
|
|||
|
||||
fn logv(config: config, s: str) {
|
||||
log(debug, s);
|
||||
if config.verbose { io::stdout().write_line(s); }
|
||||
if config.verbose { io::println(s); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import std::{fs, io};
|
||||
import io::writer_util;
|
||||
|
||||
import rustc::syntax::{ast, ast_util, fold, visit, codemap};
|
||||
import rustc::syntax::parse::parser;
|
||||
|
|
@ -212,12 +213,12 @@ fn under(n: uint, it: block(uint)) {
|
|||
while i < n { it(i); i += 1u; }
|
||||
}
|
||||
|
||||
fn devnull() -> io::writer { std::io::string_writer().get_writer() }
|
||||
fn devnull() -> io::writer { io::mem_buffer_writer(io::mk_mem_buffer()) }
|
||||
|
||||
fn as_str(f: fn@(io::writer)) -> str {
|
||||
let w = std::io::string_writer();
|
||||
f(w.get_writer());
|
||||
ret w.get_str();
|
||||
let buf = io::mk_mem_buffer();
|
||||
f(io::mem_buffer_writer(buf));
|
||||
io::mem_buffer_str(buf)
|
||||
}
|
||||
|
||||
fn check_variants_of_ast(crate: ast::crate, codemap: codemap::codemap,
|
||||
|
|
|
|||
|
|
@ -153,22 +153,21 @@ Function: to_mut
|
|||
|
||||
Produces a mutable vector from an immutable vector.
|
||||
*/
|
||||
fn to_mut<T: copy>(v: [T]) -> [mutable T] {
|
||||
let vres = [mutable];
|
||||
for t: T in v { vres += [mutable t]; }
|
||||
ret vres;
|
||||
fn to_mut<T>(+v: [T]) -> [mutable T] unsafe {
|
||||
let r = ::unsafe::reinterpret_cast(v);
|
||||
::unsafe::leak(v);
|
||||
r
|
||||
}
|
||||
|
||||
// Same comment as from_mut
|
||||
/*
|
||||
Function: from_mut
|
||||
|
||||
Produces an immutable vector from a mutable vector.
|
||||
*/
|
||||
fn from_mut<T: copy>(v: [mutable T]) -> [T] {
|
||||
let vres = [];
|
||||
for t: T in v { vres += [t]; }
|
||||
ret vres;
|
||||
fn from_mut<T>(+v: [mutable T]) -> [T] unsafe {
|
||||
let r = ::unsafe::reinterpret_cast(v);
|
||||
::unsafe::leak(v);
|
||||
r
|
||||
}
|
||||
|
||||
// Accessors
|
||||
|
|
|
|||
|
|
@ -116,9 +116,9 @@ fn doc_as_uint(d: doc) -> uint {
|
|||
|
||||
|
||||
// ebml writing
|
||||
type writer = {writer: io::buf_writer, mutable size_positions: [uint]};
|
||||
type writer = {writer: io::writer, mutable size_positions: [uint]};
|
||||
|
||||
fn write_sized_vint(w: io::buf_writer, n: uint, size: uint) {
|
||||
fn write_sized_vint(w: io::writer, n: uint, size: uint) {
|
||||
let buf: [u8];
|
||||
alt size {
|
||||
1u { buf = [0x80u8 | (n as u8)]; }
|
||||
|
|
@ -138,7 +138,7 @@ fn write_sized_vint(w: io::buf_writer, n: uint, size: uint) {
|
|||
w.write(buf);
|
||||
}
|
||||
|
||||
fn write_vint(w: io::buf_writer, n: uint) {
|
||||
fn write_vint(w: io::writer, n: uint) {
|
||||
if n < 0x7fu { write_sized_vint(w, n, 1u); ret; }
|
||||
if n < 0x4000u { write_sized_vint(w, n, 2u); ret; }
|
||||
if n < 0x200000u { write_sized_vint(w, n, 3u); ret; }
|
||||
|
|
@ -147,7 +147,7 @@ fn write_vint(w: io::buf_writer, n: uint) {
|
|||
fail;
|
||||
}
|
||||
|
||||
fn create_writer(w: io::buf_writer) -> writer {
|
||||
fn create_writer(w: io::writer) -> writer {
|
||||
let size_positions: [uint] = [];
|
||||
ret {writer: w, mutable size_positions: size_positions};
|
||||
}
|
||||
|
|
|
|||
487
src/libstd/io.rs
487
src/libstd/io.rs
|
|
@ -4,8 +4,6 @@ Module: io
|
|||
Basic input/output
|
||||
*/
|
||||
|
||||
import core::option;
|
||||
import core::result;
|
||||
import core::ctypes::fd_t;
|
||||
import core::ctypes::c_int;
|
||||
|
||||
|
|
@ -22,86 +20,20 @@ native mod rustrt {
|
|||
tag seek_style { seek_set; seek_end; seek_cur; }
|
||||
|
||||
|
||||
// The raw underlying reader class. All readers must implement this.
|
||||
type buf_reader =
|
||||
// FIXME: Seekable really should be orthogonal. We will need
|
||||
// inheritance.
|
||||
obj {
|
||||
fn read(uint) -> [u8];
|
||||
fn read_byte() -> int;
|
||||
fn unread_byte(int);
|
||||
fn eof() -> bool;
|
||||
fn seek(int, seek_style);
|
||||
fn tell() -> uint;
|
||||
// Needed on readers in case one needs to flush metadata
|
||||
// changes (atime)
|
||||
fn fsync(level: fsync::level) -> int;
|
||||
};
|
||||
|
||||
|
||||
// Convenience methods for reading.
|
||||
type reader =
|
||||
// FIXME: This should inherit from buf_reader.
|
||||
// FIXME: eventually u64
|
||||
|
||||
obj {
|
||||
fn get_buf_reader() -> buf_reader;
|
||||
fn read_byte() -> int;
|
||||
fn unread_byte(int);
|
||||
fn read_bytes(uint) -> [u8];
|
||||
fn read_char() -> char;
|
||||
fn read_chars(uint) -> [char];
|
||||
fn eof() -> bool;
|
||||
fn read_line() -> str;
|
||||
fn read_c_str() -> str;
|
||||
fn read_le_uint(uint) -> uint;
|
||||
fn read_le_int(uint) -> int;
|
||||
fn read_be_uint(uint) -> uint;
|
||||
fn read_whole_stream() -> [u8];
|
||||
fn seek(int, seek_style);
|
||||
fn tell() -> uint;
|
||||
};
|
||||
|
||||
fn convert_whence(whence: seek_style) -> i32 {
|
||||
ret alt whence {
|
||||
seek_set. { 0i32 }
|
||||
seek_cur. { 1i32 }
|
||||
seek_end. { 2i32 }
|
||||
};
|
||||
// The raw underlying reader iface. All readers must implement this.
|
||||
iface reader {
|
||||
// FIXME: Seekable really should be orthogonal.
|
||||
fn read_bytes(uint) -> [u8];
|
||||
fn read_byte() -> int;
|
||||
fn unread_byte(int);
|
||||
fn eof() -> bool;
|
||||
fn seek(int, seek_style);
|
||||
fn tell() -> uint;
|
||||
}
|
||||
|
||||
resource FILE_res(f: os::libc::FILE) {
|
||||
os::libc::fclose(f);
|
||||
}
|
||||
// Generic utility functions defined on readers
|
||||
|
||||
obj FILE_buf_reader(f: os::libc::FILE, res: option::t<@FILE_res>) {
|
||||
fn read(len: uint) -> [u8] unsafe {
|
||||
let buf = [];
|
||||
vec::reserve::<u8>(buf, len);
|
||||
let read =
|
||||
os::libc::fread(vec::unsafe::to_ptr::<u8>(buf), 1u, len, f);
|
||||
vec::unsafe::set_len::<u8>(buf, read);
|
||||
ret buf;
|
||||
}
|
||||
fn read_byte() -> int { ret os::libc::fgetc(f) as int; }
|
||||
fn unread_byte(byte: int) { os::libc::ungetc(byte as i32, f); }
|
||||
fn eof() -> bool { ret os::libc::feof(f) != 0i32; }
|
||||
fn seek(offset: int, whence: seek_style) {
|
||||
assert (os::libc::fseek(f, offset, convert_whence(whence)) == 0i32);
|
||||
}
|
||||
fn tell() -> uint { ret os::libc::ftell(f) as uint; }
|
||||
fn fsync(level: fsync::level) -> int {
|
||||
ret os::fsync_fd(os::libc::fileno(f), level) as int;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// FIXME: Convert this into pseudomethods on buf_reader.
|
||||
obj new_reader(rdr: buf_reader) {
|
||||
fn get_buf_reader() -> buf_reader { ret rdr; }
|
||||
fn read_byte() -> int { ret rdr.read_byte(); }
|
||||
fn unread_byte(byte: int) { ret rdr.unread_byte(byte); }
|
||||
fn read_bytes(len: uint) -> [u8] { ret rdr.read(len); }
|
||||
impl reader_util for reader {
|
||||
fn read_chars(n: uint) -> [char] {
|
||||
// returns the (consumed offset, n_req), appends characters to &chars
|
||||
fn chars_from_buf(buf: [u8], &chars: [char]) -> (uint, uint) {
|
||||
|
|
@ -158,8 +90,9 @@ obj new_reader(rdr: buf_reader) {
|
|||
buf = vec::slice(buf, offset, vec::len(buf));
|
||||
}
|
||||
}
|
||||
ret chars;
|
||||
chars
|
||||
}
|
||||
|
||||
fn read_char() -> char {
|
||||
let c = self.read_chars(1u);
|
||||
if vec::len(c) == 0u {
|
||||
|
|
@ -168,75 +101,116 @@ obj new_reader(rdr: buf_reader) {
|
|||
assert(vec::len(c) == 1u);
|
||||
ret c[0];
|
||||
}
|
||||
fn eof() -> bool { ret rdr.eof(); }
|
||||
|
||||
fn read_line() -> str {
|
||||
let buf: [u8] = [];
|
||||
// No break yet in rustc
|
||||
|
||||
let go_on = true;
|
||||
while go_on {
|
||||
let ch = rdr.read_byte();
|
||||
if ch == -1 || ch == 10 {
|
||||
go_on = false;
|
||||
} else { buf += [ch as u8]; }
|
||||
while true {
|
||||
let ch = self.read_byte();
|
||||
if ch == -1 || ch == 10 { break; }
|
||||
buf += [ch as u8];
|
||||
}
|
||||
ret str::unsafe_from_bytes(buf);
|
||||
str::unsafe_from_bytes(buf)
|
||||
}
|
||||
|
||||
fn read_c_str() -> str {
|
||||
let buf: [u8] = [];
|
||||
let go_on = true;
|
||||
while go_on {
|
||||
let ch = rdr.read_byte();
|
||||
if ch < 1 { go_on = false; } else { buf += [ch as u8]; }
|
||||
while true {
|
||||
let ch = self.read_byte();
|
||||
if ch < 1 { break; } else { buf += [ch as u8]; }
|
||||
}
|
||||
ret str::unsafe_from_bytes(buf);
|
||||
str::unsafe_from_bytes(buf)
|
||||
}
|
||||
|
||||
// FIXME deal with eof?
|
||||
fn read_le_uint(size: uint) -> uint {
|
||||
let val = 0u;
|
||||
let pos = 0u;
|
||||
let i = size;
|
||||
let val = 0u, pos = 0u, i = size;
|
||||
while i > 0u {
|
||||
val += (rdr.read_byte() as uint) << pos;
|
||||
val += (self.read_byte() as uint) << pos;
|
||||
pos += 8u;
|
||||
i -= 1u;
|
||||
}
|
||||
ret val;
|
||||
val
|
||||
}
|
||||
fn read_le_int(size: uint) -> int {
|
||||
let val = 0u, pos = 0u, i = size;
|
||||
while i > 0u {
|
||||
val += (rdr.read_byte() as uint) << pos;
|
||||
val += (self.read_byte() as uint) << pos;
|
||||
pos += 8u;
|
||||
i -= 1u;
|
||||
}
|
||||
ret val as int;
|
||||
val as int
|
||||
}
|
||||
|
||||
// FIXME deal with eof?
|
||||
fn read_be_uint(sz: uint) -> uint {
|
||||
let val = 0u, i = sz;
|
||||
|
||||
fn read_be_uint(size: uint) -> uint {
|
||||
let val = 0u, i = size;
|
||||
while i > 0u {
|
||||
i -= 1u;
|
||||
val += (rdr.read_byte() as uint) << i * 8u;
|
||||
val += (self.read_byte() as uint) << i * 8u;
|
||||
}
|
||||
ret val;
|
||||
val
|
||||
}
|
||||
|
||||
fn read_whole_stream() -> [u8] {
|
||||
let buf: [u8] = [];
|
||||
while !rdr.eof() { buf += rdr.read(2048u); }
|
||||
ret buf;
|
||||
while !self.eof() { buf += self.read_bytes(2048u); }
|
||||
buf
|
||||
}
|
||||
fn seek(offset: int, whence: seek_style) { ret rdr.seek(offset, whence); }
|
||||
fn tell() -> uint { ret rdr.tell(); }
|
||||
}
|
||||
|
||||
fn stdin() -> reader {
|
||||
ret new_reader(FILE_buf_reader(rustrt::rust_get_stdin(), option::none));
|
||||
// Reader implementations
|
||||
|
||||
fn convert_whence(whence: seek_style) -> i32 {
|
||||
ret alt whence {
|
||||
seek_set. { 0i32 }
|
||||
seek_cur. { 1i32 }
|
||||
seek_end. { 2i32 }
|
||||
};
|
||||
}
|
||||
|
||||
impl of reader for os::libc::FILE {
|
||||
fn read_bytes(len: uint) -> [u8] unsafe {
|
||||
let buf = [];
|
||||
vec::reserve(buf, len);
|
||||
let read = os::libc::fread(vec::unsafe::to_ptr(buf), 1u, len, self);
|
||||
vec::unsafe::set_len(buf, read);
|
||||
ret buf;
|
||||
}
|
||||
fn read_byte() -> int { ret os::libc::fgetc(self) as int; }
|
||||
fn unread_byte(byte: int) { os::libc::ungetc(byte as i32, self); }
|
||||
fn eof() -> bool { ret os::libc::feof(self) != 0i32; }
|
||||
fn seek(offset: int, whence: seek_style) {
|
||||
assert os::libc::fseek(self, offset, convert_whence(whence)) == 0i32;
|
||||
}
|
||||
fn tell() -> uint { ret os::libc::ftell(self) as uint; }
|
||||
}
|
||||
|
||||
// A forwarding impl of reader that also holds on to a resource for the
|
||||
// duration of its lifetime.
|
||||
// FIXME there really should be a better way to do this
|
||||
impl <T: reader, C> of reader for {base: T, cleanup: C} {
|
||||
fn read_bytes(len: uint) -> [u8] { self.base.read_bytes(len) }
|
||||
fn read_byte() -> int { self.base.read_byte() }
|
||||
fn unread_byte(byte: int) { self.base.unread_byte(byte); }
|
||||
fn eof() -> bool { self.base.eof() }
|
||||
fn seek(off: int, whence: seek_style) { self.base.seek(off, whence) }
|
||||
fn tell() -> uint { self.base.tell() }
|
||||
}
|
||||
|
||||
resource FILE_res(f: os::libc::FILE) { os::libc::fclose(f); }
|
||||
|
||||
fn FILE_reader(f: os::libc::FILE, cleanup: bool) -> reader {
|
||||
if cleanup {
|
||||
{base: f, cleanup: FILE_res(f)} as reader
|
||||
} else {
|
||||
f as reader
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: this should either be an iface-less impl, a set of top-level
|
||||
// functions that take a reader, or a set of default methods on reader
|
||||
// (which can then be called reader)
|
||||
|
||||
fn stdin() -> reader { rustrt::rust_get_stdin() as reader }
|
||||
|
||||
fn file_reader(path: str) -> result::t<reader, str> {
|
||||
let f = str::as_buf(path, {|pathbuf|
|
||||
str::as_buf("r", {|modebuf|
|
||||
|
|
@ -245,7 +219,7 @@ fn file_reader(path: str) -> result::t<reader, str> {
|
|||
});
|
||||
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)))))
|
||||
result::ok(FILE_reader(f, true))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,90 +227,91 @@ fn file_reader(path: str) -> result::t<reader, str> {
|
|||
// Byte buffer readers
|
||||
|
||||
// TODO: const u8, but this fails with rustboot.
|
||||
type byte_buf = @{buf: [u8], mutable pos: uint};
|
||||
type byte_buf = {buf: [u8], mutable pos: uint};
|
||||
|
||||
obj byte_buf_reader(bbuf: byte_buf) {
|
||||
fn read(len: uint) -> [u8] {
|
||||
let rest = vec::len::<u8>(bbuf.buf) - bbuf.pos;
|
||||
impl of reader for byte_buf {
|
||||
fn read_bytes(len: uint) -> [u8] {
|
||||
let rest = vec::len(self.buf) - self.pos;
|
||||
let to_read = len;
|
||||
if rest < to_read { to_read = rest; }
|
||||
let range = vec::slice::<u8>(bbuf.buf, bbuf.pos, bbuf.pos + to_read);
|
||||
bbuf.pos += to_read;
|
||||
let range = vec::slice(self.buf, self.pos, self.pos + to_read);
|
||||
self.pos += to_read;
|
||||
ret range;
|
||||
}
|
||||
fn read_byte() -> int {
|
||||
if bbuf.pos == vec::len::<u8>(bbuf.buf) { ret -1; }
|
||||
let b = bbuf.buf[bbuf.pos];
|
||||
bbuf.pos += 1u;
|
||||
if self.pos == vec::len(self.buf) { ret -1; }
|
||||
let b = self.buf[self.pos];
|
||||
self.pos += 1u;
|
||||
ret b as int;
|
||||
}
|
||||
fn unread_byte(_byte: int) { #error("TODO: unread_byte"); fail; }
|
||||
fn eof() -> bool { ret bbuf.pos == vec::len::<u8>(bbuf.buf); }
|
||||
fn eof() -> bool { self.pos == vec::len(self.buf) }
|
||||
fn seek(offset: int, whence: seek_style) {
|
||||
let pos = bbuf.pos;
|
||||
let len = vec::len::<u8>(bbuf.buf);
|
||||
bbuf.pos = seek_in_buf(offset, pos, len, whence);
|
||||
let pos = self.pos;
|
||||
let len = vec::len(self.buf);
|
||||
self.pos = seek_in_buf(offset, pos, len, whence);
|
||||
}
|
||||
fn tell() -> uint { ret bbuf.pos; }
|
||||
fn fsync(_level: fsync::level) -> int { ret 0; }
|
||||
}
|
||||
|
||||
fn new_byte_buf_reader(buf: [u8]) -> buf_reader {
|
||||
ret byte_buf_reader(@{buf: buf, mutable pos: 0u});
|
||||
fn tell() -> uint { self.pos }
|
||||
}
|
||||
|
||||
fn bytes_reader(bytes: [u8]) -> reader {
|
||||
ret new_reader(new_byte_buf_reader(bytes));
|
||||
{buf: bytes, mutable pos: 0u} as reader
|
||||
}
|
||||
|
||||
fn string_reader(s: str) -> reader {
|
||||
ret new_reader(new_byte_buf_reader(str::bytes(s)));
|
||||
bytes_reader(str::bytes(s))
|
||||
}
|
||||
|
||||
|
||||
// Writing
|
||||
tag fileflag { append; create; truncate; none; }
|
||||
|
||||
type buf_writer =
|
||||
// FIXME: Seekable really should be orthogonal. We will need
|
||||
// inheritance.
|
||||
// FIXME: eventually u64
|
||||
// FIXME: Seekable really should be orthogonal.
|
||||
// FIXME: eventually u64
|
||||
iface writer {
|
||||
fn write([const u8]);
|
||||
fn seek(int, seek_style);
|
||||
fn tell() -> uint;
|
||||
fn flush() -> int;
|
||||
}
|
||||
|
||||
obj {
|
||||
fn write([const u8]);
|
||||
fn seek(int, seek_style);
|
||||
fn tell() -> uint;
|
||||
fn flush() -> int;
|
||||
fn fsync(level: fsync::level) -> int;
|
||||
};
|
||||
impl <T: writer, C> of writer for {base: T, cleanup: C} {
|
||||
fn write(bs: [const u8]) { self.base.write(bs); }
|
||||
fn seek(off: int, style: seek_style) { self.base.seek(off, style); }
|
||||
fn tell() -> uint { self.base.tell() }
|
||||
fn flush() -> int { self.base.flush() }
|
||||
}
|
||||
|
||||
obj FILE_writer(f: os::libc::FILE, res: option::t<@FILE_res>) {
|
||||
impl of writer for os::libc::FILE {
|
||||
fn write(v: [const u8]) unsafe {
|
||||
let len = vec::len::<u8>(v);
|
||||
let vbuf = vec::unsafe::to_ptr::<u8>(v);
|
||||
let nout = os::libc::fwrite(vbuf, len, 1u, f);
|
||||
let len = vec::len(v);
|
||||
let vbuf = vec::unsafe::to_ptr(v);
|
||||
let nout = os::libc::fwrite(vbuf, len, 1u, self);
|
||||
if nout < 1u { #error("error dumping buffer"); }
|
||||
}
|
||||
fn seek(offset: int, whence: seek_style) {
|
||||
assert (os::libc::fseek(f, offset, convert_whence(whence)) == 0i32);
|
||||
assert os::libc::fseek(self, offset, convert_whence(whence)) == 0i32;
|
||||
}
|
||||
fn tell() -> uint { ret os::libc::ftell(f) as uint; }
|
||||
fn flush() -> int { ret os::libc::fflush(f) as int; }
|
||||
fn fsync(level: fsync::level) -> int {
|
||||
ret os::fsync_fd(os::libc::fileno(f), level) as int;
|
||||
fn tell() -> uint { os::libc::ftell(self) as uint }
|
||||
fn flush() -> int { os::libc::fflush(self) as int }
|
||||
}
|
||||
|
||||
fn FILE_writer(f: os::libc::FILE, cleanup: bool) -> writer {
|
||||
if cleanup {
|
||||
{base: f, cleanup: FILE_res(f)} as writer
|
||||
} else {
|
||||
f as writer
|
||||
}
|
||||
}
|
||||
|
||||
resource fd_res(fd: fd_t) { os::libc::close(fd); }
|
||||
|
||||
obj fd_buf_writer(fd: fd_t, res: option::t<@fd_res>) {
|
||||
impl of writer for fd_t {
|
||||
fn write(v: [const u8]) unsafe {
|
||||
let len = vec::len::<u8>(v);
|
||||
let len = vec::len(v);
|
||||
let count = 0u;
|
||||
let vbuf;
|
||||
while count < len {
|
||||
vbuf = ptr::offset(vec::unsafe::to_ptr::<u8>(v), count);
|
||||
let nout = os::libc::write(fd, vbuf, len);
|
||||
vbuf = ptr::offset(vec::unsafe::to_ptr(v), count);
|
||||
let nout = os::libc::write(self, vbuf, len);
|
||||
if nout < 0 {
|
||||
#error("error dumping buffer");
|
||||
log(error, sys::last_os_error());
|
||||
|
|
@ -353,16 +328,21 @@ obj fd_buf_writer(fd: fd_t, res: option::t<@fd_res>) {
|
|||
#error("need 64-bit native calls for tell, sorry");
|
||||
fail;
|
||||
}
|
||||
fn flush() -> int { 0 }
|
||||
}
|
||||
|
||||
fn flush() -> int { ret 0; }
|
||||
resource fd_res(fd: fd_t) { os::libc::close(fd); }
|
||||
|
||||
fn fsync(level: fsync::level) -> int {
|
||||
ret os::fsync_fd(fd, level) as int;
|
||||
fn fd_writer(fd: fd_t, cleanup: bool) -> writer {
|
||||
if cleanup {
|
||||
{base: fd, cleanup: fd_res(fd)} as writer
|
||||
} else {
|
||||
fd as writer
|
||||
}
|
||||
}
|
||||
|
||||
fn file_buf_writer(path: str,
|
||||
flags: [fileflag]) -> result::t<buf_writer, str> {
|
||||
fn mk_file_writer(path: str, flags: [fileflag])
|
||||
-> result::t<writer, str> {
|
||||
let fflags: i32 =
|
||||
os::libc_constants::O_WRONLY | os::libc_constants::O_BINARY;
|
||||
for f: fileflag in flags {
|
||||
|
|
@ -373,37 +353,19 @@ fn file_buf_writer(path: str,
|
|||
none. { }
|
||||
}
|
||||
}
|
||||
let fd =
|
||||
str::as_buf(path,
|
||||
{|pathbuf|
|
||||
os::libc::open(pathbuf, fflags,
|
||||
os::libc_constants::S_IRUSR |
|
||||
os::libc_constants::S_IWUSR)
|
||||
});
|
||||
ret if fd < 0i32 {
|
||||
let fd = str::as_buf(path, {|pathbuf|
|
||||
os::libc::open(pathbuf, fflags, os::libc_constants::S_IRUSR |
|
||||
os::libc_constants::S_IWUSR)
|
||||
});
|
||||
if fd < 0i32 {
|
||||
// FIXME don't log this! put it in the returned error string
|
||||
log(error, sys::last_os_error());
|
||||
result::err("error opening " + path)
|
||||
} else {
|
||||
result::ok(fd_buf_writer(fd, option::some(@fd_res(fd))))
|
||||
result::ok(fd_writer(fd, true))
|
||||
}
|
||||
}
|
||||
|
||||
type writer =
|
||||
// write_str will continue to do utf-8 output only. an alternative
|
||||
// function will be provided for general encoded string output
|
||||
obj {
|
||||
fn get_buf_writer() -> buf_writer;
|
||||
fn write_str(str);
|
||||
fn write_line(str);
|
||||
fn write_char(char);
|
||||
fn write_int(int);
|
||||
fn write_uint(uint);
|
||||
fn write_bytes([const u8]);
|
||||
fn write_le_uint(uint, uint);
|
||||
fn write_le_int(int, uint);
|
||||
fn write_be_uint(uint, uint);
|
||||
};
|
||||
|
||||
fn uint_to_le_bytes(n: uint, size: uint) -> [u8] {
|
||||
let bytes: [u8] = [], i = size, n = n;
|
||||
while i > 0u { bytes += [n & 255u as u8]; n >>= 8u; i -= 1u; }
|
||||
|
|
@ -417,130 +379,89 @@ fn uint_to_be_bytes(n: uint, size: uint) -> [u8] {
|
|||
ret bytes;
|
||||
}
|
||||
|
||||
obj new_writer(out: buf_writer) {
|
||||
fn get_buf_writer() -> buf_writer { ret out; }
|
||||
fn write_str(s: str) { out.write(str::bytes(s)); }
|
||||
fn write_line(s: str) {
|
||||
out.write(str::bytes(s));
|
||||
out.write(str::bytes("\n"));
|
||||
}
|
||||
impl writer_util for writer {
|
||||
fn write_char(ch: char) {
|
||||
// FIXME needlessly consy
|
||||
|
||||
out.write(str::bytes(str::from_char(ch)));
|
||||
if ch as uint < 128u {
|
||||
self.write([ch as u8]);
|
||||
} else {
|
||||
self.write(str::bytes(str::from_char(ch)));
|
||||
}
|
||||
}
|
||||
fn write_int(n: int) { out.write(str::bytes(int::to_str(n, 10u))); }
|
||||
fn write_uint(n: uint) { out.write(str::bytes(uint::to_str(n, 10u))); }
|
||||
fn write_bytes(bytes: [const u8]) { out.write(bytes); }
|
||||
fn write_str(s: str) { self.write(str::bytes(s)); }
|
||||
fn write_line(s: str) { self.write(str::bytes(s + "\n")); }
|
||||
fn write_int(n: int) { self.write(str::bytes(int::to_str(n, 10u))); }
|
||||
fn write_uint(n: uint) { self.write(str::bytes(uint::to_str(n, 10u))); }
|
||||
|
||||
fn write_le_uint(n: uint, size: uint) {
|
||||
out.write(uint_to_le_bytes(n, size));
|
||||
self.write(uint_to_le_bytes(n, size));
|
||||
}
|
||||
fn write_le_int(n: int, size: uint) {
|
||||
out.write(uint_to_le_bytes(n as uint, size));
|
||||
self.write(uint_to_le_bytes(n as uint, size));
|
||||
}
|
||||
fn write_be_uint(n: uint, size: uint) {
|
||||
out.write(uint_to_be_bytes(n, size));
|
||||
self.write(uint_to_be_bytes(n, size));
|
||||
}
|
||||
}
|
||||
|
||||
fn file_writer(path: str, flags: [fileflag]) -> result::t<writer, str> {
|
||||
result::chain(file_buf_writer(path, flags), { |w|
|
||||
result::ok(new_writer(w))
|
||||
})
|
||||
result::chain(mk_file_writer(path, flags), { |w| result::ok(w)})
|
||||
}
|
||||
|
||||
|
||||
// FIXME: fileflags
|
||||
fn buffered_file_buf_writer(path: str) -> result::t<buf_writer, str> {
|
||||
let f =
|
||||
str::as_buf(path,
|
||||
{|pathbuf|
|
||||
str::as_buf("w",
|
||||
{|modebuf|
|
||||
os::libc::fopen(pathbuf, modebuf)
|
||||
})
|
||||
});
|
||||
fn buffered_file_writer(path: str) -> result::t<writer, str> {
|
||||
let f = str::as_buf(path, {|pathbuf|
|
||||
str::as_buf("w", {|modebuf| os::libc::fopen(pathbuf, modebuf) })
|
||||
});
|
||||
ret if f as uint == 0u { result::err("error opening " + path) }
|
||||
else { result::ok(FILE_writer(f, option::some(@FILE_res(f)))) }
|
||||
else { result::ok(FILE_writer(f, true)) }
|
||||
}
|
||||
|
||||
|
||||
// FIXME it would be great if this could be a const
|
||||
// Problem seems to be that new_writer is not pure
|
||||
fn stdout() -> writer { ret new_writer(fd_buf_writer(1i32, option::none)); }
|
||||
fn stderr() -> writer { ret new_writer(fd_buf_writer(2i32, option::none)); }
|
||||
fn stdout() -> writer { fd_writer(1i32, false) }
|
||||
fn stderr() -> writer { fd_writer(2i32, false) }
|
||||
|
||||
fn print(s: str) { stdout().write_str(s); }
|
||||
fn println(s: str) { stdout().write_str(s + "\n"); }
|
||||
fn println(s: str) { stdout().write_line(s); }
|
||||
|
||||
type bytes_writer =
|
||||
obj {
|
||||
fn get_writer() -> writer;
|
||||
fn get_bytes() -> [mutable u8];
|
||||
};
|
||||
type mem_buffer = @{mutable buf: [mutable u8],
|
||||
mutable pos: uint};
|
||||
|
||||
type str_writer =
|
||||
obj {
|
||||
fn get_writer() -> writer;
|
||||
fn get_str() -> str;
|
||||
};
|
||||
|
||||
type mutable_byte_buf = @{mutable buf: [mutable u8], mutable pos: uint};
|
||||
|
||||
obj byte_buf_writer(buf: mutable_byte_buf) {
|
||||
impl of writer for mem_buffer {
|
||||
fn write(v: [const u8]) {
|
||||
// Fast path.
|
||||
|
||||
if buf.pos == vec::len(buf.buf) {
|
||||
for b: u8 in v { buf.buf += [mutable b]; }
|
||||
buf.pos += vec::len::<u8>(v);
|
||||
if self.pos == vec::len(self.buf) {
|
||||
for b: u8 in v { self.buf += [mutable b]; }
|
||||
self.pos += vec::len(v);
|
||||
ret;
|
||||
}
|
||||
// FIXME: Optimize: These should be unique pointers.
|
||||
|
||||
let vlen = vec::len::<u8>(v);
|
||||
let vlen = vec::len(v);
|
||||
let vpos = 0u;
|
||||
while vpos < vlen {
|
||||
let b = v[vpos];
|
||||
if buf.pos == vec::len(buf.buf) {
|
||||
buf.buf += [mutable b];
|
||||
} else { buf.buf[buf.pos] = b; }
|
||||
buf.pos += 1u;
|
||||
if self.pos == vec::len(self.buf) {
|
||||
self.buf += [mutable b];
|
||||
} else { self.buf[self.pos] = b; }
|
||||
self.pos += 1u;
|
||||
vpos += 1u;
|
||||
}
|
||||
}
|
||||
fn seek(offset: int, whence: seek_style) {
|
||||
let pos = buf.pos;
|
||||
let len = vec::len(buf.buf);
|
||||
buf.pos = seek_in_buf(offset, pos, len, whence);
|
||||
let pos = self.pos;
|
||||
let len = vec::len(self.buf);
|
||||
self.pos = seek_in_buf(offset, pos, len, whence);
|
||||
}
|
||||
fn tell() -> uint { ret buf.pos; }
|
||||
fn flush() -> int { ret 0; }
|
||||
fn fsync(_level: fsync::level) -> int { ret 0; }
|
||||
fn tell() -> uint { self.pos }
|
||||
fn flush() -> int { 0 }
|
||||
}
|
||||
|
||||
fn bytes_writer() -> bytes_writer {
|
||||
// FIXME: yikes, this is bad. Needs fixing of mutable syntax.
|
||||
|
||||
let b: [mutable u8] = [mutable 0u8];
|
||||
vec::pop(b);
|
||||
let buf = @{mutable buf: b, mutable pos: 0u};
|
||||
obj byte_buf_writer_wrap(wr: writer, buf: mutable_byte_buf) {
|
||||
fn get_writer() -> writer { ret wr; }
|
||||
fn get_bytes() -> [mutable u8] { ret buf.buf; }
|
||||
}
|
||||
ret byte_buf_writer_wrap(new_writer(byte_buf_writer(buf)), buf);
|
||||
fn mk_mem_buffer() -> mem_buffer {
|
||||
@{mutable buf: [mutable], mutable pos: 0u}
|
||||
}
|
||||
|
||||
fn string_writer() -> str_writer {
|
||||
let writer = bytes_writer();
|
||||
obj str_writer_wrap(wr: bytes_writer) {
|
||||
fn get_writer() -> writer { wr.get_writer() }
|
||||
fn get_str() -> str { str::unsafe_from_bytes(wr.get_bytes()) }
|
||||
}
|
||||
str_writer_wrap(writer)
|
||||
}
|
||||
|
||||
fn mem_buffer_writer(b: mem_buffer) -> writer { b as writer }
|
||||
fn mem_buffer_buf(b: mem_buffer) -> [u8] { vec::from_mut(b.buf) }
|
||||
fn mem_buffer_str(b: mem_buffer) -> str { str::unsafe_from_bytes(b.buf) }
|
||||
|
||||
// Utility functions
|
||||
fn seek_in_buf(offset: int, pos: uint, len: uint, whence: seek_style) ->
|
||||
|
|
@ -562,9 +483,9 @@ fn read_whole_file_str(file: str) -> result::t<str, str> {
|
|||
})
|
||||
}
|
||||
|
||||
// FIXME implement this in a low-level way. Going through the abstractions is
|
||||
// pointless.
|
||||
fn read_whole_file(file: str) -> result::t<[u8], str> {
|
||||
|
||||
// FIXME: There's a lot of copying here
|
||||
result::chain(file_reader(file), { |rdr|
|
||||
result::ok(rdr.read_whole_stream())
|
||||
})
|
||||
|
|
@ -591,8 +512,8 @@ mod fsync {
|
|||
// Resource of artifacts that need to fsync on destruction
|
||||
resource res<t>(arg: arg<t>) {
|
||||
alt arg.opt_level {
|
||||
option::none::<level>. { }
|
||||
option::some::<level>(level) {
|
||||
option::none. { }
|
||||
option::some(level) {
|
||||
// fail hard if not succesful
|
||||
assert(arg.fsync_fn(arg.val, level) != -1);
|
||||
}
|
||||
|
|
@ -629,7 +550,7 @@ mod fsync {
|
|||
}
|
||||
|
||||
// Type of objects that may want to fsync
|
||||
type t = obj { fn fsync(l: level) -> int; };
|
||||
iface t { fn fsync(l: level) -> int; }
|
||||
|
||||
// Call o.fsync after executing blk
|
||||
fn obj_sync(&&o: t, opt_level: option::t<level>, blk: block(&&res<t>)) {
|
||||
|
|
|
|||
|
|
@ -197,15 +197,9 @@ fn start_program(prog: str, args: [str]) -> program {
|
|||
|
||||
impl of program for prog_res {
|
||||
fn get_id() -> pid_t { ret self.pid; }
|
||||
fn input() -> io::writer {
|
||||
ret io::new_writer(io::fd_buf_writer(self.in_fd, none));
|
||||
}
|
||||
fn output() -> io::reader {
|
||||
ret io::new_reader(io::FILE_buf_reader(self.out_file, none));
|
||||
}
|
||||
fn err() -> io::reader {
|
||||
ret io::new_reader(io::FILE_buf_reader(self.err_file, none));
|
||||
}
|
||||
fn input() -> io::writer { io::fd_writer(self.in_fd, false) }
|
||||
fn output() -> io::reader { io::FILE_reader(self.out_file, false) }
|
||||
fn err() -> io::reader { io::FILE_reader(self.err_file, false) }
|
||||
fn close_input() { close_repr_input(*self); }
|
||||
fn finish() -> int { finish_repr(*self) }
|
||||
fn destroy() { destroy_repr(*self); }
|
||||
|
|
|
|||
|
|
@ -45,14 +45,14 @@ const color_bright_cyan: u8 = 14u8;
|
|||
/* Const: color_bright_white */
|
||||
const color_bright_white: u8 = 15u8;
|
||||
|
||||
fn esc(writer: io::buf_writer) { writer.write([0x1bu8, '[' as u8]); }
|
||||
fn esc(writer: io::writer) { writer.write([0x1bu8, '[' as u8]); }
|
||||
|
||||
/*
|
||||
Function: reset
|
||||
|
||||
Reset the foreground and background colors to default
|
||||
*/
|
||||
fn reset(writer: io::buf_writer) {
|
||||
fn reset(writer: io::writer) {
|
||||
esc(writer);
|
||||
writer.write(['0' as u8, 'm' as u8]);
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ fn color_supported() -> bool {
|
|||
};
|
||||
}
|
||||
|
||||
fn set_color(writer: io::buf_writer, first_char: u8, color: u8) {
|
||||
fn set_color(writer: io::writer, first_char: u8, color: u8) {
|
||||
assert (color < 16u8);
|
||||
esc(writer);
|
||||
let color = color;
|
||||
|
|
@ -89,7 +89,7 @@ Function: fg
|
|||
|
||||
Set the foreground color
|
||||
*/
|
||||
fn fg(writer: io::buf_writer, color: u8) {
|
||||
fn fg(writer: io::writer, color: u8) {
|
||||
ret set_color(writer, '3' as u8, color);
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ Function: fg
|
|||
|
||||
Set the background color
|
||||
*/
|
||||
fn bg(writer: io::buf_writer, color: u8) {
|
||||
fn bg(writer: io::writer, color: u8) {
|
||||
ret set_color(writer, '4' as u8, color);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,13 +3,7 @@
|
|||
// simplest interface possible for representing and running tests
|
||||
// while providing a base that other test frameworks may build off of.
|
||||
|
||||
import core::comm;
|
||||
import core::task;
|
||||
import task::task;
|
||||
import core::option;
|
||||
import core::either;
|
||||
import core::vec;
|
||||
import core::result::{ok, err};
|
||||
import result::{ok, err};
|
||||
|
||||
export test_name;
|
||||
export test_fn;
|
||||
|
|
@ -36,6 +30,12 @@ native mod rustrt {
|
|||
fn sched_threads() -> uint;
|
||||
}
|
||||
|
||||
// FIXME Kludge to work around issue #1494 . Simply import io::writer_util
|
||||
// when that is fixed.
|
||||
impl writer_util for io::writer {
|
||||
fn write_str(s: str) { self.write(str::bytes(s)); }
|
||||
fn write_line(s: str) { self.write(str::bytes(s + "\n")); }
|
||||
}
|
||||
|
||||
// The name of a test. By convention this follows the rules for rust
|
||||
// paths; i.e. it should be a series of identifiers seperated by double
|
||||
|
|
@ -101,7 +101,7 @@ fn parse_opts(args: [str]) : vec::is_not_empty(args) -> opt_res {
|
|||
|
||||
tag test_result { tr_ok; tr_failed; tr_ignored; }
|
||||
|
||||
type joinable = (task, comm::port<task::task_notification>);
|
||||
type joinable = (task::task, comm::port<task::task_notification>);
|
||||
|
||||
// To get isolation and concurrency tests have to be run in their own tasks.
|
||||
// In cases where test functions are closures it is not ok to just dump them
|
||||
|
|
@ -203,11 +203,11 @@ fn run_tests_console_<T: copy>(opts: test_opts, tests: [test_desc<T>],
|
|||
|
||||
fn write_pretty(out: io::writer, word: str, color: u8, use_color: bool) {
|
||||
if use_color && term::color_supported() {
|
||||
term::fg(out.get_buf_writer(), color);
|
||||
term::fg(out, color);
|
||||
}
|
||||
out.write_str(word);
|
||||
if use_color && term::color_supported() {
|
||||
term::reset(out.get_buf_writer());
|
||||
term::reset(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import rustc::syntax::parse::parser;
|
|||
import rustc::syntax::print::pprust;
|
||||
import rustc::syntax::visit;
|
||||
import std::io;
|
||||
import io::writer_util;
|
||||
import std::map;
|
||||
|
||||
type rustdoc = {
|
||||
|
|
|
|||
|
|
@ -12,16 +12,9 @@
|
|||
|
||||
use std;
|
||||
|
||||
import vec;
|
||||
import uint;
|
||||
import std::time;
|
||||
import str;
|
||||
import std::{time, io, getopts};
|
||||
import io::writer_util;
|
||||
import int::range;
|
||||
import std::io;
|
||||
import std::getopts;
|
||||
import task;
|
||||
import u64;
|
||||
import comm;
|
||||
import comm::port;
|
||||
import comm::chan;
|
||||
import comm::send;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
use std;
|
||||
|
||||
import std::io;
|
||||
import str;
|
||||
import uint;
|
||||
import u8;
|
||||
import vec;
|
||||
import std::bitv;
|
||||
import std::{io, bitv};
|
||||
import io::{writer_util, reader_util};
|
||||
|
||||
// Computes a single solution to a given 9x9 sudoku
|
||||
//
|
||||
|
|
|
|||
|
|
@ -11,20 +11,11 @@
|
|||
use std;
|
||||
|
||||
import option = option::t;
|
||||
import option::some;
|
||||
import option::none;
|
||||
import str;
|
||||
import std::map;
|
||||
import vec;
|
||||
import std::io;
|
||||
import option::{some, none};
|
||||
import std::{map, io, time};
|
||||
import io::reader_util;
|
||||
|
||||
import std::time;
|
||||
import u64;
|
||||
import result;
|
||||
|
||||
import task;
|
||||
import task::joinable_task;
|
||||
import comm;
|
||||
import comm::chan;
|
||||
import comm::port;
|
||||
import comm::recv;
|
||||
|
|
@ -210,7 +201,6 @@ fn read_word(r: io::reader) -> option<str> {
|
|||
while !r.eof() {
|
||||
let c = r.read_char();
|
||||
|
||||
|
||||
if is_word_char(c) {
|
||||
w += str::from_char(c);
|
||||
} else { if w != "" { ret some(w); } }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import core::*;
|
|||
// -*- rust -*-
|
||||
use std;
|
||||
import std::io;
|
||||
import io::{writer_util, reader_util};
|
||||
import str;
|
||||
import result;
|
||||
|
||||
|
|
@ -82,8 +83,8 @@ fn file_reader_not_exist() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn file_buf_writer_bad_name() {
|
||||
alt io::file_buf_writer("?/?", []) {
|
||||
fn file_writer_bad_name() {
|
||||
alt io::file_writer("?/?", []) {
|
||||
result::err(e) {
|
||||
assert e == "error opening ?/?";
|
||||
}
|
||||
|
|
@ -92,8 +93,8 @@ fn file_buf_writer_bad_name() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn buffered_file_buf_writer_bad_name() {
|
||||
alt io::buffered_file_buf_writer("?/?") {
|
||||
fn buffered_file_writer_bad_name() {
|
||||
alt io::buffered_file_writer("?/?") {
|
||||
result::err(e) {
|
||||
assert e == "error opening ?/?";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ fn test() {
|
|||
}
|
||||
}
|
||||
|
||||
// Regression test for #705
|
||||
// Regression test for #750
|
||||
#[test]
|
||||
fn test_simple() {
|
||||
let names = [mutable 2, 1, 3];
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use std;
|
|||
import std::run;
|
||||
import std::os;
|
||||
import std::io;
|
||||
import io::writer_util;
|
||||
import option;
|
||||
import str;
|
||||
import ctypes::fd_t;
|
||||
|
|
@ -41,7 +42,7 @@ fn test_pipes() {
|
|||
|
||||
fn writeclose(fd: fd_t, s: str) {
|
||||
#error("writeclose %d, %s", fd as int, s);
|
||||
let writer = io::new_writer(io::fd_buf_writer(fd, option::none));
|
||||
let writer = io::fd_writer(fd, false);
|
||||
writer.write_str(s);
|
||||
|
||||
os::close(fd);
|
||||
|
|
@ -50,7 +51,7 @@ fn test_pipes() {
|
|||
fn readclose(fd: fd_t) -> str {
|
||||
// Copied from run::program_output
|
||||
let file = os::fd_FILE(fd);
|
||||
let reader = io::new_reader(io::FILE_buf_reader(file, option::none));
|
||||
let reader = io::FILE_reader(file, false);
|
||||
let buf = "";
|
||||
while !reader.eof() {
|
||||
let bytes = reader.read_bytes(4096u);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue