Skip to content

Towards removing std::io #9749

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Oct 10, 2013
Merged
15 changes: 10 additions & 5 deletions src/compiletest/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,29 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::io;

pub struct ExpectedError { line: uint, kind: ~str, msg: ~str }

// Load any test directives embedded in the file
pub fn load_errors(testfile: &Path) -> ~[ExpectedError] {
use std::rt::io::Open;
use std::rt::io::file::FileInfo;
use std::rt::io::buffered::BufferedReader;

let mut error_patterns = ~[];
let rdr = io::file_reader(testfile).unwrap();
let mut rdr = BufferedReader::new(testfile.open_reader(Open).unwrap());
let mut line_num = 1u;
while !rdr.eof() {
let ln = rdr.read_line();
loop {
let ln = match rdr.read_line() {
Some(ln) => ln, None => break,
};
error_patterns.push_all_move(parse_expected(line_num, ln));
line_num += 1u;
}
return error_patterns;
}

fn parse_expected(line_num: uint, line: ~str) -> ~[ExpectedError] {
let line = line.trim();
let error_tag = ~"//~";
let mut idx;
match line.find_str(error_tag) {
Expand Down
18 changes: 11 additions & 7 deletions src/compiletest/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ use common::config;
use common;
use util;

use std::io;

pub struct TestProps {
// Lines that should be expected, in order, on standard out
error_patterns: ~[~str],
Expand Down Expand Up @@ -104,17 +102,23 @@ pub fn is_test_ignored(config: &config, testfile: &Path) -> bool {
!val
}

fn iter_header(testfile: &Path, it: &fn(~str) -> bool) -> bool {
let rdr = io::file_reader(testfile).unwrap();
while !rdr.eof() {
let ln = rdr.read_line();
fn iter_header(testfile: &Path, it: &fn(&str) -> bool) -> bool {
use std::rt::io::Open;
use std::rt::io::file::FileInfo;
use std::rt::io::buffered::BufferedReader;

let mut rdr = BufferedReader::new(testfile.open_reader(Open).unwrap());
loop {
let ln = match rdr.read_line() {
Some(ln) => ln, None => break
};

// Assume that any directives will be found before the first
// module or function. This doesn't seem to be an optimization
// with a warm page cache. Maybe with a cold one.
if ln.starts_with("fn") || ln.starts_with("mod") {
return true;
} else { if !(it(ln)) { return false; } }
} else { if !(it(ln.trim())) { return false; } }
}
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/compiletest/procsrv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub fn run(lib_path: &str,
});

for input in input.iter() {
proc.input().write_str(*input);
proc.input().write(input.as_bytes());
}
let output = proc.finish_with_output();

Expand Down
17 changes: 5 additions & 12 deletions src/libstd/cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ fn debug_mem() -> bool {
/// Destroys all managed memory (i.e. @ boxes) held by the current task.
pub unsafe fn annihilate() {
use rt::local_heap::local_free;
use io::WriterUtil;
use io;
use libc;
use sys;
use managed;

Expand Down Expand Up @@ -126,14 +123,10 @@ pub unsafe fn annihilate() {

if debug_mem() {
// We do logging here w/o allocation.
let dbg = libc::STDERR_FILENO as io::fd_t;
dbg.write_str("annihilator stats:");
dbg.write_str("\n total_boxes: ");
dbg.write_uint(stats.n_total_boxes);
dbg.write_str("\n unique_boxes: ");
dbg.write_uint(stats.n_unique_boxes);
dbg.write_str("\n bytes_freed: ");
dbg.write_uint(stats.n_bytes_freed);
dbg.write_str("\n");
rterrln!("annihilator stats:\n \
total boxes: {}\n \
unique boxes: {}\n \
bytes freed: {}",
stats.n_total_boxes, stats.n_unique_boxes, stats.n_bytes_freed);
}
}
37 changes: 0 additions & 37 deletions src/libstd/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1233,14 +1233,6 @@ impl Writer for *libc::FILE {
}
}

pub fn FILE_writer(f: *libc::FILE, cleanup: bool) -> @Writer {
if cleanup {
@Wrapper { base: f, cleanup: FILERes::new(f) } as @Writer
} else {
@f as @Writer
}
}

impl Writer for fd_t {
fn write(&self, v: &[u8]) {
#[fixed_stack_segment]; #[inline(never)];
Expand Down Expand Up @@ -1618,25 +1610,6 @@ pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {
mk_file_writer(path, flags).and_then(|w| Ok(w))
}


// FIXME: fileflags // #2004
pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
#[fixed_stack_segment]; #[inline(never)];

unsafe {
let f = do path.with_c_str |pathbuf| {
do "w".with_c_str |modebuf| {
libc::fopen(pathbuf, modebuf)
}
};
return if f as uint == 0u {
Err(~"error opening " + path.to_str())
} else {
Ok(FILE_writer(f, true))
}
}
}

// FIXME (#2004) it would be great if this could be a const
// FIXME (#2004) why are these different from the way stdin() is
// implemented?
Expand Down Expand Up @@ -2086,16 +2059,6 @@ mod tests {
}
}

#[test]
fn buffered_file_writer_bad_name() {
match io::buffered_file_writer(&Path("?/?")) {
Err(e) => {
assert!(e.starts_with("error opening"));
}
Ok(_) => fail2!()
}
}

#[test]
fn bytes_buffer_overwrite() {
let wr = BytesWriter::new();
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

macro_rules! rterrln (
($($arg:tt)*) => ( {
::rt::util::dumb_println(format!($($arg)*));
format_args!(::rt::util::dumb_println, $($arg)*)
} )
)

Expand Down
2 changes: 1 addition & 1 deletion src/libstd/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub use option::{Option, Some, None};
pub use result::{Result, Ok, Err};

// Reexported functions
pub use io::{print, println};
pub use rt::io::stdio::{print, println};
pub use iter::range;
pub use from_str::from_str;

Expand Down
56 changes: 6 additions & 50 deletions src/libstd/rt/borrowck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@
// except according to those terms.

use cell::Cell;
use c_str::ToCStr;
use cast::transmute;
use io::{Writer, WriterUtil};
use io;
use libc::{c_char, size_t, STDERR_FILENO};
use c_str::{ToCStr, CString};
use libc::{c_char, size_t};
use option::{Option, None, Some};
use ptr::RawPtr;
use rt::env;
Expand Down Expand Up @@ -113,51 +110,10 @@ unsafe fn debug_borrow<T,P:RawPtr<T>>(tag: &'static str,
new_bits: uint,
filename: *c_char,
line: size_t) {
let dbg = STDERR_FILENO as io::fd_t;
dbg.write_str(tag);
dbg.write_hex(p.to_uint());
dbg.write_str(" ");
dbg.write_hex(old_bits);
dbg.write_str(" ");
dbg.write_hex(new_bits);
dbg.write_str(" ");
dbg.write_cstr(filename);
dbg.write_str(":");
dbg.write_hex(line as uint);
dbg.write_str("\n");
}
}

trait DebugPrints {
fn write_hex(&self, val: uint);
unsafe fn write_cstr(&self, str: *c_char);
}

impl DebugPrints for io::fd_t {
fn write_hex(&self, mut i: uint) {
let letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f'];
static UINT_NIBBLES: uint = ::uint::bytes << 1;
let mut buffer = [0_u8, ..UINT_NIBBLES+1];
let mut c = UINT_NIBBLES;
while c > 0 {
c -= 1;
buffer[c] = letters[i & 0xF] as u8;
i >>= 4;
}
self.write(buffer.slice(0, UINT_NIBBLES));
}

unsafe fn write_cstr(&self, p: *c_char) {
#[fixed_stack_segment]; #[inline(never)];
use libc::strlen;
use vec;

let len = strlen(p);
let p: *u8 = transmute(p);
do vec::raw::buf_as_slice(p, len as uint) |s| {
self.write(s);
}
let filename = CString::new(filename, false);
rterrln!("{}{:#x} {:x} {:x} {}:{}",
tag, p.to_uint(), old_bits, new_bits,
filename.as_str().unwrap(), line);
}
}

Expand Down
72 changes: 65 additions & 7 deletions src/libstd/rt/io/buffered.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ use prelude::*;

use num;
use vec;
use str;
use super::{Reader, Writer, Stream, Decorator};

// libuv recommends 64k buffers to maximize throughput
Expand Down Expand Up @@ -84,23 +85,69 @@ impl<R: Reader> BufferedReader<R> {
pub fn new(inner: R) -> BufferedReader<R> {
BufferedReader::with_capacity(DEFAULT_CAPACITY, inner)
}
}

impl<R: Reader> Reader for BufferedReader<R> {
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
/// Reads the next line of input, interpreted as a sequence of utf-8
/// encoded unicode codepoints. If a newline is encountered, then the
/// newline is contained in the returned string.
pub fn read_line(&mut self) -> Option<~str> {
self.read_until('\n' as u8).map(str::from_utf8_owned)
}

/// Reads a sequence of bytes leading up to a specified delimeter. Once the
/// specified byte is encountered, reading ceases and the bytes up to and
/// including the delimiter are returned.
pub fn read_until(&mut self, byte: u8) -> Option<~[u8]> {
let mut res = ~[];
let mut used;
loop {
{
let available = self.fill_buffer();
match available.iter().position(|&b| b == byte) {
Some(i) => {
res.push_all(available.slice_to(i + 1));
used = i + 1;
break
}
None => {
res.push_all(available);
used = available.len();
}
}
}
if used == 0 {
break
}
self.pos += used;
}
self.pos += used;
return if res.len() == 0 {None} else {Some(res)};
}

fn fill_buffer<'a>(&'a mut self) -> &'a [u8] {
if self.pos == self.cap {
match self.inner.read(self.buf) {
Some(cap) => {
self.pos = 0;
self.cap = cap;
}
None => return None
None => {}
}
}
return self.buf.slice(self.pos, self.cap);
}
}

let src = self.buf.slice(self.pos, self.cap);
let nread = num::min(src.len(), buf.len());
vec::bytes::copy_memory(buf, src, nread);
impl<R: Reader> Reader for BufferedReader<R> {
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
let nread = {
let available = self.fill_buffer();
if available.len() == 0 {
return None;
}
let nread = num::min(available.len(), buf.len());
vec::bytes::copy_memory(buf, available, nread);
nread
};
self.pos += nread;
Some(nread)
}
Expand Down Expand Up @@ -355,4 +402,15 @@ mod test {
stream.write(buf);
stream.flush();
}

#[test]
fn test_read_until() {
let inner = MemReader::new(~[0, 1, 2, 1, 0]);
let mut reader = BufferedReader::with_capacity(2, inner);
assert_eq!(reader.read_until(0), Some(~[0]));
assert_eq!(reader.read_until(2), Some(~[1, 2]));
assert_eq!(reader.read_until(1), Some(~[1]));
assert_eq!(reader.read_until(8), Some(~[0]));
assert_eq!(reader.read_until(9), None);
}
}
2 changes: 1 addition & 1 deletion src/libstd/rt/io/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ impl FileInfo for Path { }
/// else { fail2!("nope"); }
/// }
/// ```
trait DirectoryInfo : FileSystemInfo {
pub trait DirectoryInfo : FileSystemInfo {
/// Whether the underlying implemention (be it a file path,
/// or something else) is pointing at a directory in the underlying FS.
/// Will return false for paths to non-existent locations or if the item is
Expand Down
Loading