]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #23292 - alexcrichton:stabilize-io, r=aturon
authorbors <bors@rust-lang.org>
Fri, 13 Mar 2015 20:22:16 +0000 (20:22 +0000)
committerbors <bors@rust-lang.org>
Fri, 13 Mar 2015 20:22:16 +0000 (20:22 +0000)
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.

This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.

Stable APIs:

* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
  for the number of bytes read.
* `ReadExt`
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `WriteExt`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
  for the number of bytes read.
* `BufReadExt`
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`

Unstable APIs:

(reasons can be found in the commit itself)

* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`

Deprecated APIs

* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`

Changes in functionality:

* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
  backtraces has migrated to `std::io`.

[breaking-change]

69 files changed:
src/compiletest/compiletest.rs
src/compiletest/runtest.rs
src/libgraphviz/lib.rs
src/liblog/lib.rs
src/librbml/io.rs [deleted file]
src/librbml/lib.rs
src/librustc/lib.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/astencode.rs
src/librustc/middle/liveness.rs
src/librustc_back/fs.rs
src/librustc_driver/lib.rs
src/librustc_driver/pretty.rs
src/librustc_trans/lib.rs
src/librustdoc/externalfiles.rs
src/librustdoc/flock.rs
src/librustdoc/html/highlight.rs
src/librustdoc/lib.rs
src/librustdoc/markdown.rs
src/librustdoc/test.rs
src/libserialize/json.rs
src/libserialize/lib.rs
src/libstd/ffi/c_str.rs
src/libstd/io/buffered.rs
src/libstd/io/error.rs
src/libstd/io/impls.rs
src/libstd/io/mod.rs
src/libstd/io/prelude.rs
src/libstd/io/stdio.rs
src/libstd/lib.rs
src/libstd/old_io/mod.rs
src/libstd/old_io/stdio.rs
src/libstd/os.rs
src/libstd/panicking.rs
src/libstd/rt/util.rs
src/libstd/sys/common/backtrace.rs
src/libstd/sys/common/mod.rs
src/libstd/sys/unix/backtrace.rs
src/libstd/sys/unix/ext.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/helper_signal.rs
src/libstd/sys/unix/mod.rs
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/pipe.rs
src/libstd/sys/unix/stdio.rs
src/libstd/sys/unix/timer.rs
src/libstd/sys/unix/tty.rs
src/libstd/sys/windows/backtrace.rs
src/libstd/sys/windows/condvar.rs
src/libstd/sys/windows/ext.rs
src/libstd/sys/windows/mod.rs
src/libstd/sys/windows/os.rs
src/libstd/sys/windows/pipe.rs
src/libstd/sys/windows/stdio.rs
src/libstd/sys/windows/timer.rs
src/libstd/sys/windows/tty.rs
src/libstd/thread.rs
src/libsyntax/diagnostic.rs
src/libsyntax/lib.rs
src/libsyntax/parse/lexer/mod.rs
src/libterm/lib.rs
src/libterm/terminfo/mod.rs
src/libterm/win.rs
src/libtest/lib.rs
src/rustbook/main.rs
src/rustbook/term.rs
src/test/run-pass/issue-11881.rs
src/test/run-pass/task-stderr.rs

index a2bb3defe31071eeb057eb159e1238eb543823dc..50e74a13ee2b76c9378c2f05076429e1633151ef 100644 (file)
@@ -20,7 +20,6 @@
 #![feature(std_misc)]
 #![feature(test)]
 #![feature(core)]
-#![feature(io)]
 #![feature(net)]
 #![feature(path_ext)]
 
@@ -34,7 +33,6 @@
 
 use std::env;
 use std::fs;
-use std::old_io;
 use std::path::{Path, PathBuf};
 use std::thunk::Thunk;
 use getopts::{optopt, optflag, reqopt};
@@ -246,7 +244,11 @@ pub fn run_tests(config: &Config) {
     // sadly osx needs some file descriptor limits raised for running tests in
     // parallel (especially when we have lots and lots of child processes).
     // For context, see #8904
-    old_io::test::raise_fd_limit();
+    #[allow(deprecated)]
+    fn raise_fd_limit() {
+        std::old_io::test::raise_fd_limit();
+    }
+    raise_fd_limit();
     // Prevent issue #21352 UAC blocking .exe containing 'patch' etc. on Windows
     // If #11207 is resolved (adding manifest to .exe) this becomes unnecessary
     env::set_var("__COMPAT_LAYER", "RunAsInvoker");
index 04714b50fc027b78215777f4f388b3eec326e9bc..475c0410135004278a83dc4400325c95d9325d54 100644 (file)
@@ -26,7 +26,6 @@
 use std::io::prelude::*;
 use std::iter::repeat;
 use std::net::TcpStream;
-use std::old_io::timer;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Output, ExitStatus};
 use std::str;
@@ -452,7 +451,11 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                 .expect(&format!("failed to exec `{:?}`", config.adb_path));
             loop {
                 //waiting 1 second for gdbserver start
-                timer::sleep(Duration::milliseconds(1000));
+                #[allow(deprecated)]
+                fn sleep() {
+                    ::std::old_io::timer::sleep(Duration::milliseconds(1000));
+                }
+                sleep();
                 if TcpStream::connect("127.0.0.1:5039").is_ok() {
                     break
                 }
index 5f6bfd196f031304caa18a06c52aad0dfe8ac8c8..0e0804593443d5d733bb4e16b51fa1939b31d937 100644 (file)
 //!
 //! ```rust
 //! use std::borrow::IntoCow;
+//! use std::io::Write;
 //! use graphviz as dot;
 //!
 //! type Nd = int;
 //! type Ed = (int,int);
 //! struct Edges(Vec<Ed>);
 //!
-//! pub fn render_to<W:Writer>(output: &mut W) {
+//! pub fn render_to<W: Write>(output: &mut W) {
 //!     let edges = Edges(vec!((0,1), (0,2), (1,3), (2,3), (3,4), (4,4)));
 //!     dot::render(&edges, output).unwrap()
 //! }
 //! ```
 //!
 //! ```no_run
-//! # pub fn render_to<W:Writer>(output: &mut W) { unimplemented!() }
+//! # pub fn render_to<W:std::io::Write>(output: &mut W) { unimplemented!() }
 //! pub fn main() {
-//!     use std::old_io::File;
-//!     let mut f = File::create(&Path::new("example1.dot"));
+//!     use std::fs::File;
+//!     let mut f = File::create("example1.dot").unwrap();
 //!     render_to(&mut f)
 //! }
 //! ```
 //!
 //! ```rust
 //! use std::borrow::IntoCow;
+//! use std::io::Write;
 //! use graphviz as dot;
 //!
 //! type Nd = uint;
 //! type Ed<'a> = &'a (uint, uint);
 //! struct Graph { nodes: Vec<&'static str>, edges: Vec<(uint,uint)> }
 //!
-//! pub fn render_to<W:Writer>(output: &mut W) {
+//! pub fn render_to<W: Write>(output: &mut W) {
 //!     let nodes = vec!("{x,y}","{x}","{y}","{}");
 //!     let edges = vec!((0,1), (0,2), (1,3), (2,3));
 //!     let graph = Graph { nodes: nodes, edges: edges };
 //! ```
 //!
 //! ```no_run
-//! # pub fn render_to<W:Writer>(output: &mut W) { unimplemented!() }
+//! # pub fn render_to<W:std::io::Write>(output: &mut W) { unimplemented!() }
 //! pub fn main() {
-//!     use std::old_io::File;
-//!     let mut f = File::create(&Path::new("example2.dot"));
+//!     use std::fs::File;
+//!     let mut f = File::create("example2.dot").unwrap();
 //!     render_to(&mut f)
 //! }
 //! ```
 //!
 //! ```rust
 //! use std::borrow::IntoCow;
+//! use std::io::Write;
 //! use graphviz as dot;
 //!
 //! type Nd<'a> = (uint, &'a str);
 //! type Ed<'a> = (Nd<'a>, Nd<'a>);
 //! struct Graph { nodes: Vec<&'static str>, edges: Vec<(uint,uint)> }
 //!
-//! pub fn render_to<W:Writer>(output: &mut W) {
+//! pub fn render_to<W: Write>(output: &mut W) {
 //!     let nodes = vec!("{x,y}","{x}","{y}","{}");
 //!     let edges = vec!((0,1), (0,2), (1,3), (2,3));
 //!     let graph = Graph { nodes: nodes, edges: edges };
 //! ```
 //!
 //! ```no_run
-//! # pub fn render_to<W:Writer>(output: &mut W) { unimplemented!() }
+//! # pub fn render_to<W:std::io::Write>(output: &mut W) { unimplemented!() }
 //! pub fn main() {
-//!     use std::old_io::File;
-//!     let mut f = File::create(&Path::new("example3.dot"));
+//!     use std::fs::File;
+//!     let mut f = File::create("example3.dot").unwrap();
 //!     render_to(&mut f)
 //! }
 //! ```
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 #![feature(int_uint)]
 #![feature(collections)]
-#![feature(old_io)]
 
 use self::LabelText::*;
 
 use std::borrow::{IntoCow, Cow};
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
 
 /// The text for a graphviz label on a node or edge.
 pub enum LabelText<'a> {
@@ -529,26 +532,26 @@ pub fn default_options() -> Vec<RenderOption> { vec![] }
 
 /// Renders directed graph `g` into the writer `w` in DOT syntax.
 /// (Simple wrapper around `render_opts` that passes a default set of options.)
-pub fn render<'a, N:Clone+'a, E:Clone+'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Writer>(
+pub fn render<'a, N:Clone+'a, E:Clone+'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Write>(
               g: &'a G,
-              w: &mut W) -> old_io::IoResult<()> {
+              w: &mut W) -> io::Result<()> {
     render_opts(g, w, &[])
 }
 
 /// Renders directed graph `g` into the writer `w` in DOT syntax.
 /// (Main entry point for the library.)
-pub fn render_opts<'a, N:Clone+'a, E:Clone+'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Writer>(
+pub fn render_opts<'a, N:Clone+'a, E:Clone+'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Write>(
               g: &'a G,
               w: &mut W,
-              options: &[RenderOption]) -> old_io::IoResult<()>
+              options: &[RenderOption]) -> io::Result<()>
 {
-    fn writeln<W:Writer>(w: &mut W, arg: &[&str]) -> old_io::IoResult<()> {
-        for &s in arg { try!(w.write_str(s)); }
-        w.write_char('\n')
+    fn writeln<W:Write>(w: &mut W, arg: &[&str]) -> io::Result<()> {
+        for &s in arg { try!(w.write_all(s.as_bytes())); }
+        write!(w, "\n")
     }
 
-    fn indent<W:Writer>(w: &mut W) -> old_io::IoResult<()> {
-        w.write_str("    ")
+    fn indent<W:Write>(w: &mut W) -> io::Result<()> {
+        w.write_all(b"    ")
     }
 
     try!(writeln(w, &["digraph ", g.graph_id().as_slice(), " {"]));
@@ -589,7 +592,8 @@ mod tests {
     use self::NodeLabels::*;
     use super::{Id, Labeller, Nodes, Edges, GraphWalk, render};
     use super::LabelText::{self, LabelStr, EscStr};
-    use std::old_io::IoResult;
+    use std::io;
+    use std::io::prelude::*;
     use std::borrow::IntoCow;
     use std::iter::repeat;
 
@@ -738,10 +742,12 @@ fn target(&'a self, edge: & &'a Edge) -> Node {
         }
     }
 
-    fn test_input(g: LabelledGraph) -> IoResult<String> {
+    fn test_input(g: LabelledGraph) -> io::Result<String> {
         let mut writer = Vec::new();
         render(&g, &mut writer).unwrap();
-        (&mut &*writer).read_to_string()
+        let mut s = String::new();
+        try!(Read::read_to_string(&mut &*writer, &mut s));
+        Ok(s)
     }
 
     // All of the tests use raw-strings as the format for the expected outputs,
@@ -853,9 +859,10 @@ fn left_aligned_text() {
                  edge(1, 3, ";"),    edge(2, 3, ";"   )));
 
         render(&g, &mut writer).unwrap();
-        let r = (&mut &*writer).read_to_string();
+        let mut r = String::new();
+        Read::read_to_string(&mut &*writer, &mut r).unwrap();
 
-        assert_eq!(r.unwrap(),
+        assert_eq!(r,
 r#"digraph syntax_tree {
     N0[label="if test {\l    branch1\l} else {\l    branch2\l}\lafterward\l"];
     N1[label="branch1"];
index 3b6e1d0469148eaf404aed34b26e1c7b8dc793c7..b03d77db4ec9c29e57f3abcc8c73547d1e88472c 100644 (file)
 #![feature(box_syntax)]
 #![feature(int_uint)]
 #![feature(core)]
-#![feature(old_io)]
 #![feature(std_misc)]
+#![feature(io)]
 
 use std::boxed;
 use std::cell::RefCell;
 use std::fmt;
-use std::old_io::LineBufferedWriter;
-use std::old_io;
+use std::io::{self, Stderr};
+use std::io::prelude::*;
 use std::mem;
 use std::env;
 use std::ptr;
@@ -237,9 +237,7 @@ pub trait Logger {
     fn log(&mut self, record: &LogRecord);
 }
 
-struct DefaultLogger {
-    handle: LineBufferedWriter<old_io::stdio::StdWriter>,
-}
+struct DefaultLogger { handle: Stderr }
 
 /// Wraps the log level with fmt implementations.
 #[derive(Copy, PartialEq, PartialOrd, Debug)]
@@ -300,7 +298,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
     let mut logger = LOCAL_LOGGER.with(|s| {
         s.borrow_mut().take()
     }).unwrap_or_else(|| {
-        box DefaultLogger { handle: old_io::stderr() } as Box<Logger + Send>
+        box DefaultLogger { handle: io::stderr() } as Box<Logger + Send>
     });
     logger.log(&LogRecord {
         level: LogLevel(level),
diff --git a/src/librbml/io.rs b/src/librbml/io.rs
deleted file mode 100644 (file)
index bf4b5ee..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::old_io::{IoError, IoResult, SeekStyle};
-use std::old_io;
-use std::slice;
-use std::iter::repeat;
-
-const BUF_CAPACITY: uint = 128;
-
-fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64> {
-    // compute offset as signed and clamp to prevent overflow
-    let pos = match seek {
-        old_io::SeekSet => 0,
-        old_io::SeekEnd => end,
-        old_io::SeekCur => cur,
-    } as i64;
-
-    if offset + pos < 0 {
-        Err(IoError {
-            kind: old_io::InvalidInput,
-            desc: "invalid seek to a negative offset",
-            detail: None
-        })
-    } else {
-        Ok((offset + pos) as u64)
-    }
-}
-
-/// Writes to an owned, growable byte vector that supports seeking.
-///
-/// # Examples
-///
-/// ```rust
-/// # #![allow(unused_must_use)]
-/// use rbml::io::SeekableMemWriter;
-///
-/// let mut w = SeekableMemWriter::new();
-/// w.write(&[0, 1, 2]);
-///
-/// assert_eq!(w.unwrap(), [0, 1, 2]);
-/// ```
-pub struct SeekableMemWriter {
-    buf: Vec<u8>,
-    pos: uint,
-}
-
-impl SeekableMemWriter {
-    /// Create a new `SeekableMemWriter`.
-    #[inline]
-    pub fn new() -> SeekableMemWriter {
-        SeekableMemWriter::with_capacity(BUF_CAPACITY)
-    }
-    /// Create a new `SeekableMemWriter`, allocating at least `n` bytes for
-    /// the internal buffer.
-    #[inline]
-    pub fn with_capacity(n: uint) -> SeekableMemWriter {
-        SeekableMemWriter { buf: Vec::with_capacity(n), pos: 0 }
-    }
-
-    /// Acquires an immutable reference to the underlying buffer of this
-    /// `SeekableMemWriter`.
-    ///
-    /// No method is exposed for acquiring a mutable reference to the buffer
-    /// because it could corrupt the state of this `MemWriter`.
-    #[inline]
-    pub fn get_ref<'a>(&'a self) -> &'a [u8] { &self.buf }
-
-    /// Unwraps this `SeekableMemWriter`, returning the underlying buffer
-    #[inline]
-    pub fn unwrap(self) -> Vec<u8> { self.buf }
-}
-
-impl Writer for SeekableMemWriter {
-    #[inline]
-    fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
-        if self.pos == self.buf.len() {
-            self.buf.push_all(buf)
-        } else {
-            // Make sure the internal buffer is as least as big as where we
-            // currently are
-            let difference = self.pos as i64 - self.buf.len() as i64;
-            if difference > 0 {
-                self.buf.extend(repeat(0).take(difference as uint));
-            }
-
-            // Figure out what bytes will be used to overwrite what's currently
-            // there (left), and what will be appended on the end (right)
-            let cap = self.buf.len() - self.pos;
-            let (left, right) = if cap <= buf.len() {
-                (&buf[..cap], &buf[cap..])
-            } else {
-                let result: (_, &[_]) = (buf, &[]);
-                result
-            };
-
-            // Do the necessary writes
-            if left.len() > 0 {
-                slice::bytes::copy_memory(&mut self.buf[self.pos..], left);
-            }
-            if right.len() > 0 {
-                self.buf.push_all(right);
-            }
-        }
-
-        // Bump us forward
-        self.pos += buf.len();
-        Ok(())
-    }
-}
-
-impl Seek for SeekableMemWriter {
-    #[inline]
-    fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
-
-    #[inline]
-    fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
-        let new = try!(combine(style, self.pos, self.buf.len(), pos));
-        self.pos = new as uint;
-        Ok(())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    extern crate test;
-    use super::SeekableMemWriter;
-    use std::old_io;
-    use std::iter::repeat;
-    use test::Bencher;
-
-    #[test]
-    fn test_seekable_mem_writer() {
-        let mut writer = SeekableMemWriter::new();
-        assert_eq!(writer.tell(), Ok(0));
-        writer.write_all(&[0]).unwrap();
-        assert_eq!(writer.tell(), Ok(1));
-        writer.write_all(&[1, 2, 3]).unwrap();
-        writer.write_all(&[4, 5, 6, 7]).unwrap();
-        assert_eq!(writer.tell(), Ok(8));
-        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
-        assert_eq!(writer.get_ref(), b);
-
-        writer.seek(0, old_io::SeekSet).unwrap();
-        assert_eq!(writer.tell(), Ok(0));
-        writer.write_all(&[3, 4]).unwrap();
-        let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7];
-        assert_eq!(writer.get_ref(), b);
-
-        writer.seek(1, old_io::SeekCur).unwrap();
-        writer.write_all(&[0, 1]).unwrap();
-        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7];
-        assert_eq!(writer.get_ref(), b);
-
-        writer.seek(-1, old_io::SeekEnd).unwrap();
-        writer.write_all(&[1, 2]).unwrap();
-        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2];
-        assert_eq!(writer.get_ref(), b);
-
-        writer.seek(1, old_io::SeekEnd).unwrap();
-        writer.write_all(&[1]).unwrap();
-        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1];
-        assert_eq!(writer.get_ref(), b);
-    }
-
-    #[test]
-    fn seek_past_end() {
-        let mut r = SeekableMemWriter::new();
-        r.seek(10, old_io::SeekSet).unwrap();
-        assert!(r.write_all(&[3]).is_ok());
-    }
-
-    #[test]
-    fn seek_before_0() {
-        let mut r = SeekableMemWriter::new();
-        assert!(r.seek(-1, old_io::SeekSet).is_err());
-    }
-
-    fn do_bench_seekable_mem_writer(b: &mut Bencher, times: uint, len: uint) {
-        let src: Vec<u8> = repeat(5).take(len).collect();
-
-        b.bytes = (times * len) as u64;
-        b.iter(|| {
-            let mut wr = SeekableMemWriter::new();
-            for _ in 0..times {
-                wr.write_all(&src).unwrap();
-            }
-
-            let v = wr.unwrap();
-            assert_eq!(v.len(), times * len);
-            assert!(v.iter().all(|x| *x == 5));
-        });
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_001_0000(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 1, 0)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_001_0010(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 1, 10)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_001_0100(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 1, 100)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_001_1000(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 1, 1000)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_100_0000(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 100, 0)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_100_0010(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 100, 10)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_100_0100(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 100, 100)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_100_1000(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 100, 1000)
-    }
-}
index d71bcdf29243ccad490604262f3700c883672409..5d1fbc32f14b75e37977ca6ff3dfb85e1eba59c8 100644 (file)
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
 
-#![feature(collections)]
+#![feature(io)]
 #![feature(core)]
 #![feature(int_uint)]
-#![feature(old_io)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 
 use std::str;
 use std::fmt;
 
-pub mod io;
-
 /// Common data structures
 #[derive(Clone, Copy)]
 pub struct Doc<'a> {
@@ -228,7 +225,7 @@ pub enum Error {
     IntTooBig(uint),
     InvalidTag(uint),
     Expected(String),
-    IoError(std::old_io::IoError),
+    IoError(std::io::Error),
     ApplicationError(String)
 }
 
@@ -840,8 +837,8 @@ fn error(&mut self, err: &str) -> Error {
 pub mod writer {
     use std::mem;
     use std::num::Int;
-    use std::old_io::{Writer, Seek};
-    use std::old_io;
+    use std::io::prelude::*;
+    use std::io::{self, SeekFrom, Cursor};
     use std::slice::bytes;
     use std::num::ToPrimitive;
 
@@ -849,35 +846,31 @@ pub mod writer {
         EsU64, EsU32, EsU16, EsU8, EsI64, EsI32, EsI16, EsI8,
         EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
         EsOpaque, NUM_IMPLICIT_TAGS, NUM_TAGS };
-    use super::io::SeekableMemWriter;
 
     use serialize;
 
 
-    pub type EncodeResult = old_io::IoResult<()>;
+    pub type EncodeResult = io::Result<()>;
 
     // rbml writing
     pub struct Encoder<'a> {
-        pub writer: &'a mut SeekableMemWriter,
-        size_positions: Vec<uint>,
+        pub writer: &'a mut Cursor<Vec<u8>>,
+        size_positions: Vec<u64>,
         relax_limit: u64, // do not move encoded bytes before this position
     }
 
-    fn write_tag<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
+    fn write_tag<W: Write>(w: &mut W, n: uint) -> EncodeResult {
         if n < 0xf0 {
             w.write_all(&[n as u8])
         } else if 0x100 <= n && n < NUM_TAGS {
             w.write_all(&[0xf0 | (n >> 8) as u8, n as u8])
         } else {
-            Err(old_io::IoError {
-                kind: old_io::OtherIoError,
-                desc: "invalid tag",
-                detail: Some(format!("{}", n))
-            })
+            Err(io::Error::new(io::ErrorKind::Other, "invalid tag",
+                               Some(n.to_string())))
         }
     }
 
-    fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
+    fn write_sized_vuint<W: Write>(w: &mut W, n: uint, size: uint) -> EncodeResult {
         match size {
             1 => w.write_all(&[0x80 | (n as u8)]),
             2 => w.write_all(&[0x40 | ((n >> 8) as u8), n as u8]),
@@ -885,28 +878,22 @@ fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult
                             n as u8]),
             4 => w.write_all(&[0x10 | ((n >> 24) as u8), (n >> 16) as u8,
                             (n >> 8) as u8, n as u8]),
-            _ => Err(old_io::IoError {
-                kind: old_io::OtherIoError,
-                desc: "int too big",
-                detail: Some(format!("{}", n))
-            })
+            _ => Err(io::Error::new(io::ErrorKind::Other,
+                                    "int too big", Some(n.to_string())))
         }
     }
 
-    fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
+    fn write_vuint<W: Write>(w: &mut W, n: uint) -> EncodeResult {
         if n < 0x7f { return write_sized_vuint(w, n, 1); }
         if n < 0x4000 { return write_sized_vuint(w, n, 2); }
         if n < 0x200000 { return write_sized_vuint(w, n, 3); }
         if n < 0x10000000 { return write_sized_vuint(w, n, 4); }
-        Err(old_io::IoError {
-            kind: old_io::OtherIoError,
-            desc: "int too big",
-            detail: Some(format!("{}", n))
-        })
+        Err(io::Error::new(io::ErrorKind::Other, "int too big",
+                           Some(n.to_string())))
     }
 
     impl<'a> Encoder<'a> {
-        pub fn new(w: &'a mut SeekableMemWriter) -> Encoder<'a> {
+        pub fn new(w: &'a mut Cursor<Vec<u8>>) -> Encoder<'a> {
             Encoder {
                 writer: w,
                 size_positions: vec!(),
@@ -931,24 +918,26 @@ pub fn start_tag(&mut self, tag_id: uint) -> EncodeResult {
             try!(write_tag(self.writer, tag_id));
 
             // Write a placeholder four-byte size.
-            self.size_positions.push(try!(self.writer.tell()) as uint);
+            let cur_pos = try!(self.writer.seek(SeekFrom::Current(0)));
+            self.size_positions.push(cur_pos);
             let zeroes: &[u8] = &[0, 0, 0, 0];
             self.writer.write_all(zeroes)
         }
 
         pub fn end_tag(&mut self) -> EncodeResult {
             let last_size_pos = self.size_positions.pop().unwrap();
-            let cur_pos = try!(self.writer.tell());
-            try!(self.writer.seek(last_size_pos as i64, old_io::SeekSet));
-            let size = cur_pos as uint - last_size_pos - 4;
+            let cur_pos = try!(self.writer.seek(SeekFrom::Current(0)));
+            try!(self.writer.seek(SeekFrom::Start(last_size_pos)));
+            let size = (cur_pos - last_size_pos - 4) as usize;
 
             // relax the size encoding for small tags (bigger tags are costly to move).
             // we should never try to move the stable positions, however.
             const RELAX_MAX_SIZE: uint = 0x100;
-            if size <= RELAX_MAX_SIZE && last_size_pos >= self.relax_limit as uint {
+            if size <= RELAX_MAX_SIZE && last_size_pos >= self.relax_limit {
                 // we can't alter the buffer in place, so have a temporary buffer
                 let mut buf = [0u8; RELAX_MAX_SIZE];
                 {
+                    let last_size_pos = last_size_pos as usize;
                     let data = &self.writer.get_ref()[last_size_pos+4..cur_pos as uint];
                     bytes::copy_memory(&mut buf, data);
                 }
@@ -959,7 +948,7 @@ pub fn end_tag(&mut self) -> EncodeResult {
             } else {
                 // overwrite the size with an overlong encoding and skip past the data
                 try!(write_sized_vuint(self.writer, size, 4));
-                try!(self.writer.seek(cur_pos as i64, old_io::SeekSet));
+                try!(self.writer.seek(SeekFrom::Start(cur_pos)));
             }
 
             debug!("End tag (size = {:?})", size);
@@ -1074,7 +1063,7 @@ pub fn wr_str(&mut self, s: &str) -> EncodeResult {
         /// Returns the current position while marking it stable, i.e.
         /// generated bytes so far woundn't be affected by relaxation.
         pub fn mark_stable_position(&mut self) -> u64 {
-            let pos = self.writer.tell().unwrap();
+            let pos = self.writer.seek(SeekFrom::Current(0)).unwrap();
             if self.relax_limit < pos {
                 self.relax_limit = pos;
             }
@@ -1090,11 +1079,9 @@ fn _emit_tagged_sub(&mut self, v: uint) -> EncodeResult {
             } else if let Some(v) = v.to_u32() {
                 self.wr_tagged_raw_u32(EsSub32 as uint, v)
             } else {
-                Err(old_io::IoError {
-                    kind: old_io::OtherIoError,
-                    desc: "length or variant id too big",
-                    detail: Some(format!("{}", v))
-                })
+                Err(io::Error::new(io::ErrorKind::Other,
+                                   "length or variant id too big",
+                                   Some(v.to_string())))
             }
         }
 
@@ -1108,7 +1095,7 @@ pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
     }
 
     impl<'a> serialize::Encoder for Encoder<'a> {
-        type Error = old_io::IoError;
+        type Error = io::Error;
 
         fn emit_nil(&mut self) -> EncodeResult {
             Ok(())
@@ -1339,12 +1326,10 @@ fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
 #[cfg(test)]
 mod tests {
     use super::{Doc, reader, writer};
-    use super::io::SeekableMemWriter;
 
     use serialize::{Encodable, Decodable};
 
-    use std::option::Option;
-    use std::option::Option::{None, Some};
+    use std::io::Cursor;
 
     #[test]
     fn test_vuint_at() {
@@ -1398,7 +1383,7 @@ fn test_vuint_at() {
     fn test_option_int() {
         fn test_v(v: Option<int>) {
             debug!("v == {:?}", v);
-            let mut wr = SeekableMemWriter::new();
+            let mut wr = Cursor::new(Vec::new());
             {
                 let mut rbml_w = writer::Encoder::new(&mut wr);
                 let _ = v.encode(&mut rbml_w);
index 444b050952fa4c6707fcc01f4ebedadbdb71952f..60102040bcad8d0e9b71afdd18702fb0cc77488b 100644 (file)
@@ -31,7 +31,6 @@
 #![feature(core)]
 #![feature(hash)]
 #![feature(int_uint)]
-#![feature(old_io)]
 #![feature(libc)]
 #![feature(old_path)]
 #![feature(quote)]
index 611d8bc27d19d5fa849827a7d0cd1b9e18714411..10461e3d2aedfc38b2f51f9a0bd78f6fe97e5bde 100644 (file)
@@ -30,6 +30,8 @@
 use serialize::Encodable;
 use std::cell::RefCell;
 use std::hash::{Hash, Hasher, SipHasher};
+use std::io::prelude::*;
+use std::io::{Cursor, SeekFrom};
 use syntax::abi;
 use syntax::ast::{self, DefId, NodeId};
 use syntax::ast_map::{PathElem, PathElems};
@@ -47,7 +49,6 @@
 use syntax::visit;
 use syntax;
 use rbml::writer::Encoder;
-use rbml::io::SeekableMemWriter;
 
 /// A borrowed version of `ast::InlinedItem`.
 pub enum InlinedItemRef<'a> {
@@ -1530,7 +1531,7 @@ fn encode_info_for_items(ecx: &EncodeContext,
 // Path and definition ID indexing
 
 fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn: F) where
-    F: FnMut(&mut SeekableMemWriter, &T),
+    F: FnMut(&mut Cursor<Vec<u8>>, &T),
     T: Hash,
 {
     let mut buckets: Vec<Vec<entry<T>>> = (0..256u16).map(|_| Vec::new()).collect();
@@ -1551,8 +1552,8 @@ fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn:
             rbml_w.start_tag(tag_index_buckets_bucket_elt);
             assert!(elt.pos < 0xffff_ffff);
             {
-                let wr: &mut SeekableMemWriter = rbml_w.writer;
-                wr.write_be_u32(elt.pos as u32);
+                let wr: &mut Cursor<Vec<u8>> = rbml_w.writer;
+                write_be_u32(wr, elt.pos as u32);
             }
             write_fn(rbml_w.writer, &elt.val);
             rbml_w.end_tag();
@@ -1563,17 +1564,26 @@ fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn:
     rbml_w.start_tag(tag_index_table);
     for pos in &bucket_locs {
         assert!(*pos < 0xffff_ffff);
-        let wr: &mut SeekableMemWriter = rbml_w.writer;
-        wr.write_be_u32(*pos as u32);
+        let wr: &mut Cursor<Vec<u8>> = rbml_w.writer;
+        write_be_u32(wr, *pos as u32);
     }
     rbml_w.end_tag();
     rbml_w.end_tag();
 }
 
-fn write_i64(writer: &mut SeekableMemWriter, &n: &i64) {
-    let wr: &mut SeekableMemWriter = writer;
+fn write_i64(writer: &mut Cursor<Vec<u8>>, &n: &i64) {
+    let wr: &mut Cursor<Vec<u8>> = writer;
     assert!(n < 0x7fff_ffff);
-    wr.write_be_u32(n as u32);
+    write_be_u32(wr, n as u32);
+}
+
+fn write_be_u32(w: &mut Write, u: u32) {
+    w.write_all(&[
+        (u >> 24) as u8,
+        (u >> 16) as u8,
+        (u >>  8) as u8,
+        (u >>  0) as u8,
+    ]);
 }
 
 fn encode_meta_item(rbml_w: &mut Encoder, mi: &ast::MetaItem) {
@@ -1929,13 +1939,13 @@ fn encode_dylib_dependency_formats(rbml_w: &mut Encoder, ecx: &EncodeContext) {
 pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 2 ];
 
 pub fn encode_metadata(parms: EncodeParams, krate: &ast::Crate) -> Vec<u8> {
-    let mut wr = SeekableMemWriter::new();
+    let mut wr = Cursor::new(Vec::new());
     encode_metadata_inner(&mut wr, parms, krate);
 
     // RBML compacts the encoded bytes whenever appropriate,
     // so there are some garbages left after the end of the data.
-    let metalen = wr.tell().unwrap() as uint;
-    let mut v = wr.unwrap();
+    let metalen = wr.seek(SeekFrom::Current(0)).unwrap() as uint;
+    let mut v = wr.into_inner();
     v.truncate(metalen);
     assert_eq!(v.len(), metalen);
 
@@ -1965,7 +1975,7 @@ pub fn encode_metadata(parms: EncodeParams, krate: &ast::Crate) -> Vec<u8> {
     return v;
 }
 
-fn encode_metadata_inner(wr: &mut SeekableMemWriter,
+fn encode_metadata_inner(wr: &mut Cursor<Vec<u8>>,
                          parms: EncodeParams,
                          krate: &ast::Crate) {
     struct Stats {
@@ -2032,64 +2042,64 @@ struct Stats {
     encode_hash(&mut rbml_w, &ecx.link_meta.crate_hash);
     encode_dylib_dependency_formats(&mut rbml_w, &ecx);
 
-    let mut i = rbml_w.writer.tell().unwrap();
+    let mut i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_attributes(&mut rbml_w, &krate.attrs);
-    stats.attr_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.attr_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_crate_deps(&mut rbml_w, ecx.cstore);
-    stats.dep_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.dep_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode the language items.
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_lang_items(&ecx, &mut rbml_w);
-    stats.lang_item_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.lang_item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode the native libraries used
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_native_libraries(&ecx, &mut rbml_w);
-    stats.native_lib_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.native_lib_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode the plugin registrar function
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_plugin_registrar_fn(&ecx, &mut rbml_w);
-    stats.plugin_registrar_fn_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.plugin_registrar_fn_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode codemap
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_codemap(&ecx, &mut rbml_w);
-    stats.codemap_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.codemap_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode macro definitions
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_macro_defs(&mut rbml_w, krate);
-    stats.macro_defs_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.macro_defs_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode the def IDs of impls, for coherence checking.
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_impls(&ecx, krate, &mut rbml_w);
-    stats.impl_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.impl_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode miscellaneous info.
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_misc_info(&ecx, krate, &mut rbml_w);
     encode_reachable_extern_fns(&ecx, &mut rbml_w);
-    stats.misc_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.misc_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode and index the items.
     rbml_w.start_tag(tag_items);
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     let items_index = encode_info_for_items(&ecx, &mut rbml_w, krate);
-    stats.item_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_index(&mut rbml_w, items_index, write_i64);
-    stats.index_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.index_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
     rbml_w.end_tag();
 
     encode_struct_field_attrs(&mut rbml_w, krate);
 
-    stats.total_bytes = rbml_w.writer.tell().unwrap();
+    stats.total_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
 
     if tcx.sess.meta_stats() {
         for e in rbml_w.writer.get_ref() {
@@ -2117,12 +2127,12 @@ struct Stats {
 
 // Get the encoded string for a type
 pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> String {
-    let mut wr = SeekableMemWriter::new();
+    let mut wr = Cursor::new(Vec::new());
     tyencode::enc_ty(&mut Encoder::new(&mut wr), &tyencode::ctxt {
         diag: tcx.sess.diagnostic(),
         ds: def_to_string,
         tcx: tcx,
         abbrevs: &RefCell::new(FnvHashMap())
     }, t);
-    String::from_utf8(wr.unwrap()).unwrap()
+    String::from_utf8(wr.into_inner()).unwrap()
 }
index 86f1605b8bfaa706fa0de0f511703893d3f1c9a6..b0fa0e757fe05b1f0a644e230653574cf9d8da8b 100644 (file)
@@ -14,6 +14,7 @@
 #![allow(non_camel_case_types)]
 
 use std::cell::RefCell;
+use std::io::prelude::*;
 
 use middle::region;
 use middle::subst;
index fb5b934c2cd8d9b4010dceca1fd0d60aaa7f8630..ed1d876d83619040457d081243ee4777ab6601a0 100644 (file)
 use syntax::ptr::P;
 use syntax;
 
-use std::old_io::Seek;
+use std::cell::Cell;
+use std::io::SeekFrom;
+use std::io::prelude::*;
 use std::num::FromPrimitive;
 use std::rc::Rc;
-use std::cell::Cell;
 
 use rbml::reader;
 use rbml::writer::Encoder;
@@ -50,7 +51,7 @@
 use serialize::{Decodable, Decoder, DecoderHelpers, Encodable};
 use serialize::{EncoderHelpers};
 
-#[cfg(test)] use rbml::io::SeekableMemWriter;
+#[cfg(test)] use std::io::Cursor;
 #[cfg(test)] use syntax::parse;
 #[cfg(test)] use syntax::print::pprust;
 
@@ -85,7 +86,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
     };
     debug!("> Encoding inlined item: {} ({:?})",
            ecx.tcx.map.path_to_string(id),
-           rbml_w.writer.tell());
+           rbml_w.writer.seek(SeekFrom::Current(0)));
 
     // Folding could be avoided with a smarter encoder.
     let ii = simplify_ast(ii);
@@ -99,7 +100,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
 
     debug!("< Encoded inlined fn: {} ({:?})",
            ecx.tcx.map.path_to_string(id),
-           rbml_w.writer.tell());
+           rbml_w.writer.seek(SeekFrom::Current(0)));
 }
 
 impl<'a, 'b, 'c, 'tcx> ast_map::FoldOps for &'a DecodeContext<'b, 'c, 'tcx> {
@@ -1974,7 +1975,7 @@ fn mk_ctxt() -> parse::ParseSess {
 #[cfg(test)]
 fn roundtrip(in_item: Option<P<ast::Item>>) {
     let in_item = in_item.unwrap();
-    let mut wr = SeekableMemWriter::new();
+    let mut wr = Cursor::new(Vec::new());
     encode_item_ast(&mut Encoder::new(&mut wr), &*in_item);
     let rbml_doc = rbml::Doc::new(wr.get_ref());
     let out_item = decode_item_ast(rbml_doc);
index 892452ccc1c29d3b348a94ec1880a33baa562c55..932c9c61ef1fbb53ef4006201de88feea96f0f31 100644 (file)
 use lint;
 use util::nodemap::NodeMap;
 
-use std::{fmt, old_io, usize};
-use std::rc::Rc;
+use std::{fmt, usize};
+use std::io::prelude::*;
+use std::io;
 use std::iter::repeat;
+use std::rc::Rc;
 use syntax::ast::{self, NodeId, Expr};
 use syntax::codemap::{BytePos, original_sp, Span};
 use syntax::parse::token::{self, special_idents};
@@ -680,10 +682,10 @@ fn indices2<F>(&mut self, ln: LiveNode, succ_ln: LiveNode, mut op: F) where
     }
 
     fn write_vars<F>(&self,
-                     wr: &mut old_io::Writer,
+                     wr: &mut Write,
                      ln: LiveNode,
                      mut test: F)
-                     -> old_io::IoResult<()> where
+                     -> io::Result<()> where
         F: FnMut(usize) -> LiveNode,
     {
         let node_base_idx = self.idx(ln, Variable(0));
@@ -727,7 +729,7 @@ fn find_loop_scope(&self,
     fn ln_str(&self, ln: LiveNode) -> String {
         let mut wr = Vec::new();
         {
-            let wr = &mut wr as &mut old_io::Writer;
+            let wr = &mut wr as &mut Write;
             write!(wr, "[ln({:?}) of kind {:?} reads", ln.get(), self.ir.lnk(ln));
             self.write_vars(wr, ln, |idx| self.users[idx].reader);
             write!(wr, "  writes");
index 20335bc8c09a95bd5b960dffae5a6b3eb043210d..6a6502800f683e17bec25099fd490f4683f36ca6 100644 (file)
@@ -9,11 +9,8 @@
 // except according to those terms.
 
 use std::io;
-use std::old_io::fs;
-use std::old_io;
-#[allow(deprecated)]
-use std::old_path;
-use std::os;
+#[allow(deprecated)] use std::old_path;
+#[allow(deprecated)] use std::old_io;
 use std::path::{Path, PathBuf};
 
 /// Returns an absolute path in the filesystem that `path` points to. The
@@ -31,6 +28,8 @@ pub fn realpath(original: &Path) -> io::Result<PathBuf> {
 
 #[allow(deprecated)]
 fn old_realpath(original: &old_path::Path) -> old_io::IoResult<old_path::Path> {
+    use std::old_io::fs;
+    use std::os;
     const MAX_LINKS_FOLLOWED: usize = 256;
     let original = try!(os::getcwd()).join(original);
 
index cdea84e4a37456d5e9b14f0d96d212638fca4585..e0261606ef12fb21e944bea7851c19d701b74493 100644 (file)
@@ -29,7 +29,6 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(int_uint)]
-#![feature(old_io)]
 #![feature(libc)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
@@ -38,6 +37,7 @@
 #![feature(staged_api)]
 #![feature(exit_status)]
 #![feature(io)]
+#![feature(set_panic)]
 
 extern crate arena;
 extern crate flate;
 
 use std::cmp::Ordering::Equal;
 use std::env;
+use std::io::{self, Read, Write};
 use std::iter::repeat;
-use std::old_io::{self, stdio};
 use std::path::PathBuf;
-use std::sync::mpsc::channel;
+use std::str;
+use std::sync::{Arc, Mutex};
 use std::thread;
 
 use rustc::session::early_error;
@@ -171,8 +172,8 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>)> {
     if free_matches.len() == 1 {
         let ifile = &free_matches[0][..];
         if ifile == "-" {
-            let contents = old_io::stdin().read_to_end().unwrap();
-            let src = String::from_utf8(contents).unwrap();
+            let mut src = String::new();
+            io::stdin().read_to_string(&mut src).unwrap();
             Some((Input::Str(src), None))
         } else {
             Some((Input::File(PathBuf::new(ifile)), Some(PathBuf::new(ifile))))
@@ -794,9 +795,16 @@ fn parse_crate_attrs(sess: &Session, input: &Input) ->
 pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
     const STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB
 
-    let (tx, rx) = channel();
-    let w = old_io::ChanWriter::new(tx);
-    let mut r = old_io::ChanReader::new(rx);
+    struct Sink(Arc<Mutex<Vec<u8>>>);
+    impl Write for Sink {
+        fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+            Write::write(&mut *self.0.lock().unwrap(), data)
+        }
+        fn flush(&mut self) -> io::Result<()> { Ok(()) }
+    }
+
+    let data = Arc::new(Mutex::new(Vec::new()));
+    let err = Sink(data.clone());
 
     let mut cfg = thread::Builder::new().name("rustc".to_string());
 
@@ -806,7 +814,7 @@ pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
         cfg = cfg.stack_size(STACK_SIZE);
     }
 
-    match cfg.spawn(move || { stdio::set_stderr(box w); f() }).unwrap().join() {
+    match cfg.spawn(move || { io::set_panic(box err); f() }).unwrap().join() {
         Ok(()) => { /* fallthrough */ }
         Err(value) => {
             // Thread panicked without emitting a fatal diagnostic
@@ -833,22 +841,13 @@ pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
                     emitter.emit(None, &note[..], None, diagnostic::Note)
                 }
 
-                match r.read_to_string() {
-                    Ok(s) => println!("{}", s),
-                    Err(e) => {
-                        emitter.emit(None,
-                                     &format!("failed to read internal \
-                                              stderr: {}", e),
-                                     None,
-                                     diagnostic::Error)
-                    }
-                }
+                println!("{}", str::from_utf8(&data.lock().unwrap()).unwrap());
             }
 
             // Panic so the process returns a failure code, but don't pollute the
             // output with some unnecessary panic messages, we've already
             // printed everything that we needed to.
-            old_io::stdio::set_stderr(box old_io::util::NullWriter);
+            io::set_panic(box io::sink());
             panic!();
         }
     }
index ffb2a05e4374920caea984151cfd91c1b135aa00..9e693a64ef0a2bf5710e77d22c5b513da98a806d 100644 (file)
@@ -40,7 +40,6 @@
 
 use std::fs::File;
 use std::io::{self, Write};
-use std::old_io;
 use std::option;
 use std::path::PathBuf;
 use std::str::FromStr;
@@ -615,7 +614,7 @@ pub fn pretty_print_input(sess: Session,
             });
 
             let code = blocks::Code::from_node(node);
-            let out: &mut Writer = &mut out;
+            let out: &mut Write = &mut out;
             match code {
                 Some(code) => {
                     let variants = gather_flowgraph_variants(&sess);
@@ -654,11 +653,11 @@ pub fn pretty_print_input(sess: Session,
     }
 }
 
-fn print_flowgraph<W:old_io::Writer>(variants: Vec<borrowck_dot::Variant>,
-                                 analysis: ty::CrateAnalysis,
-                                 code: blocks::Code,
-                                 mode: PpFlowGraphMode,
-                                 mut out: W) -> io::Result<()> {
+fn print_flowgraph<W: Write>(variants: Vec<borrowck_dot::Variant>,
+                             analysis: ty::CrateAnalysis,
+                             code: blocks::Code,
+                             mode: PpFlowGraphMode,
+                             mut out: W) -> io::Result<()> {
     let ty_cx = &analysis.ty_cx;
     let cfg = match code {
         blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block),
@@ -698,7 +697,7 @@ fn print_flowgraph<W:old_io::Writer>(variants: Vec<borrowck_dot::Variant>,
         }
     }
 
-    fn expand_err_details(r: old_io::IoResult<()>) -> io::Result<()> {
+    fn expand_err_details(r: io::Result<()>) -> io::Result<()> {
         r.map_err(|ioerr| {
             io::Error::new(io::ErrorKind::Other, "graphviz::render failed",
                            Some(ioerr.to_string()))
index 66dd49f241fbe7224a368c2f70a104cd83bf8978..efc81da560b6e262e0cc9ed52f9eaa50fe4781ad 100644 (file)
@@ -38,7 +38,6 @@
 #![feature(unsafe_destructor)]
 #![feature(staged_api)]
 #![feature(unicode)]
-#![feature(io)]
 #![feature(path_ext)]
 #![feature(fs)]
 #![feature(hash)]
index 6cfe7a33dd4f366b285c4991f29f755dabec38d5..c2b6c940caea29291b36fa179c28d706e05b315c 100644 (file)
@@ -11,7 +11,6 @@
 use std::fs::File;
 use std::io::prelude::*;
 use std::io;
-use std::old_io;
 use std::path::{PathBuf, Path};
 use std::str;
 
@@ -51,12 +50,12 @@ macro_rules! load_or_return {
             let input = PathBuf::new($input);
             match ::externalfiles::load_string(&input) {
                 Err(e) => {
-                    let _ = writeln!(&mut old_io::stderr(),
+                    let _ = writeln!(&mut io::stderr(),
                                      "error reading `{}`: {}", input.display(), e);
                     return $cant_read;
                 }
                 Ok(None) => {
-                    let _ = writeln!(&mut old_io::stderr(),
+                    let _ = writeln!(&mut io::stderr(),
                                      "error reading `{}`: not UTF-8", input.display());
                     return $not_utf8;
                 }
index 51c58861b4b252b66ea31d3b4d9a78de7a3e45ae..8c85eaff23ce5610646d337a94d837d878859b1c 100644 (file)
@@ -23,8 +23,8 @@ mod imp {
     use std::ffi::{AsOsStr, CString};
     use std::os::unix::prelude::*;
     use std::path::Path;
+    use std::io;
     use libc;
-    use std::os as stdos;
 
     #[cfg(target_os = "linux")]
     mod os {
@@ -121,8 +121,8 @@ pub fn new(p: &Path) -> Lock {
                 libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT,
                            libc::S_IRWXU)
             };
-            assert!(fd > 0, "failed to open lockfile: [{}] {}",
-                    stdos::errno(), stdos::last_os_error());
+            assert!(fd > 0, "failed to open lockfile: {}",
+                    io::Error::last_os_error());
             let flock = os::flock {
                 l_start: 0,
                 l_len: 0,
@@ -135,10 +135,9 @@ pub fn new(p: &Path) -> Lock {
                 libc::fcntl(fd, os::F_SETLKW, &flock)
             };
             if ret == -1 {
-                let errno = stdos::errno();
+                let err = io::Error::last_os_error();
                 unsafe { libc::close(fd); }
-                panic!("could not lock `{}`: [{}] {}", p.display(),
-                       errno, stdos::error_string(errno))
+                panic!("could not lock `{}`: {}", p.display(), err);
             }
             Lock { fd: fd }
         }
@@ -166,9 +165,9 @@ fn drop(&mut self) {
 mod imp {
     use libc;
     use std::ffi::AsOsStr;
+    use std::io;
     use std::mem;
     use std::os::windows::prelude::*;
-    use std::os;
     use std::path::Path;
     use std::ptr;
 
@@ -210,8 +209,7 @@ pub fn new(p: &Path) -> Lock {
                                   ptr::null_mut())
             };
             if handle == libc::INVALID_HANDLE_VALUE {
-                panic!("create file error: [{}] {}",
-                       os::errno(), os::last_os_error());
+                panic!("create file error: {}", io::Error::last_os_error());
             }
             let mut overlapped: libc::OVERLAPPED = unsafe { mem::zeroed() };
             let ret = unsafe {
@@ -219,10 +217,9 @@ pub fn new(p: &Path) -> Lock {
                            &mut overlapped)
             };
             if ret == 0 {
-                let errno = os::errno();
+                let err = io::Error::last_os_error();
                 unsafe { libc::CloseHandle(handle); }
-                panic!("could not lock `{}`: [{}] {}", p.display(),
-                       errno, os::error_string(errno));
+                panic!("could not lock `{}`: {}", p.display(), err);
             }
             Lock { handle: handle }
         }
index b88e5065b4f9c82b77f2801a82529010b039e446..d19ccabed478efdb392b7830ad67def89cbf81f3 100644 (file)
@@ -15,7 +15,8 @@
 
 use html::escape::Escape;
 
-use std::old_io;
+use std::io;
+use std::io::prelude::*;
 use syntax::parse::lexer;
 use syntax::parse::token;
 use syntax::parse;
@@ -46,7 +47,7 @@ pub fn highlight(src: &str, class: Option<&str>, id: Option<&str>) -> String {
 /// source.
 fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
         class: Option<&str>, id: Option<&str>,
-        out: &mut Writer) -> old_io::IoResult<()> {
+        out: &mut Write) -> io::Result<()> {
     use syntax::parse::lexer::Reader;
 
     try!(write!(out, "<pre "));
index 246004751c58e6b25d57992be9a363a06695a752..152b6f5c80a628ea3f9cac4562fcdf259748c887 100644 (file)
@@ -26,9 +26,8 @@
 #![feature(core)]
 #![feature(exit_status)]
 #![feature(int_uint)]
-#![feature(old_io)]
+#![feature(set_panic)]
 #![feature(libc)]
-#![feature(os)]
 #![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
@@ -465,7 +464,7 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
 fn json_input(input: &str) -> Result<Output, String> {
     let mut bytes = Vec::new();
     match File::open(input).and_then(|mut f| f.read_to_end(&mut bytes)) {
-        Ok(()) => {}
+        Ok(_) => {}
         Err(e) => return Err(format!("couldn't open {}: {}", input, e)),
     };
     match json::from_reader(&mut &bytes[..]) {
index 7d635c8b2327481f609130157e366566004403a5..09b4915222b3902ec3c6d49ea904a1be381fb2ca 100644 (file)
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 use std::fs::File;
-use std::io::Write;
-use std::old_io;
+use std::io;
+use std::io::prelude::*;
 use std::path::{PathBuf, Path};
 
 use core;
@@ -64,7 +64,7 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
 
     let mut out = match File::create(&output) {
         Err(e) => {
-            let _ = writeln!(&mut old_io::stderr(),
+            let _ = writeln!(&mut io::stderr(),
                              "error opening `{}` for writing: {}",
                              output.display(), e);
             return 4;
@@ -74,7 +74,7 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
 
     let (metadata, text) = extract_leading_metadata(&input_str);
     if metadata.len() == 0 {
-        let _ = writeln!(&mut old_io::stderr(),
+        let _ = writeln!(&mut io::stderr(),
                          "invalid markdown file: expecting initial line with `% ...TITLE...`");
         return 5;
     }
@@ -129,7 +129,7 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
 
     match err {
         Err(e) => {
-            let _ = writeln!(&mut old_io::stderr(),
+            let _ = writeln!(&mut io::stderr(),
                              "error writing to `{}`: {}",
                              output.display(), e);
             6
index e7312d6548e9f5798a811923818389ecad43b141..e2f8a6f82c6442df51e271223ddc4e82b91fa95b 100644 (file)
 use std::dynamic_lib::DynamicLibrary;
 use std::env;
 use std::ffi::OsString;
-use std::old_io;
+use std::io::prelude::*;
 use std::io;
 use std::path::PathBuf;
 use std::process::Command;
 use std::str;
-use std::sync::mpsc::channel;
-use std::thread;
+use std::sync::{Arc, Mutex};
 use std::thunk::Thunk;
 
 use testing;
@@ -140,30 +139,29 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
     // an explicit handle into rustc to collect output messages, but we also
     // want to catch the error message that rustc prints when it fails.
     //
-    // We take our task-local stderr (likely set by the test runner), and move
-    // it into another task. This helper task then acts as a sink for both the
-    // stderr of this task and stderr of rustc itself, copying all the info onto
-    // the stderr channel we originally started with.
+    // We take our task-local stderr (likely set by the test runner) and replace
+    // it with a sink that is also passed to rustc itself. When this function
+    // returns the output of the sink is copied onto the output of our own task.
     //
     // The basic idea is to not use a default_handler() for rustc, and then also
     // not print things by default to the actual stderr.
-    let (tx, rx) = channel();
-    let w1 = old_io::ChanWriter::new(tx);
-    let w2 = w1.clone();
-    let old = old_io::stdio::set_stderr(box w1);
-    thread::spawn(move || {
-        let mut p = old_io::ChanReader::new(rx);
-        let mut err = match old {
-            Some(old) => {
-                // Chop off the `Send` bound.
-                let old: Box<Writer> = old;
-                old
-            }
-            None => box old_io::stderr() as Box<Writer>,
-        };
-        old_io::util::copy(&mut p, &mut err).unwrap();
-    });
-    let emitter = diagnostic::EmitterWriter::new(box w2, None);
+    struct Sink(Arc<Mutex<Vec<u8>>>);
+    impl Write for Sink {
+        fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+            Write::write(&mut *self.0.lock().unwrap(), data)
+        }
+        fn flush(&mut self) -> io::Result<()> { Ok(()) }
+    }
+    struct Bomb(Arc<Mutex<Vec<u8>>>, Box<Write+Send>);
+    impl Drop for Bomb {
+        fn drop(&mut self) {
+            let _ = self.1.write_all(&self.0.lock().unwrap());
+        }
+    }
+    let data = Arc::new(Mutex::new(Vec::new()));
+    let emitter = diagnostic::EmitterWriter::new(box Sink(data.clone()), None);
+    let old = io::set_panic(box Sink(data.clone()));
+    let _bomb = Bomb(data, old.unwrap_or(box io::stdout()));
 
     // Compile the code
     let codemap = CodeMap::new();
index 6fc56522c6af1dbaa7198a214416b4388535449d..d0ef89e811bd46563d596aa8602d8b6da069d208 100644 (file)
 use self::ParserState::*;
 use self::InternalStackElement::*;
 
-use std;
 use std::collections::{HashMap, BTreeMap};
-use std::{char, f64, fmt, old_io, num, str};
+use std::io::prelude::*;
+use std::io;
 use std::mem::{swap};
-use std::num::{Float, Int};
 use std::num::FpCategory as Fp;
+use std::num::{Float, Int};
+use std::ops::Index;
 use std::str::FromStr;
 use std::string;
-use std::ops::Index;
+use std::{char, f64, fmt, num, str};
+use std;
 use unicode::str as unicode_str;
 use unicode::str::Utf16Item;
 
@@ -256,11 +258,11 @@ pub enum ErrorCode {
     NotUtf8,
 }
 
-#[derive(Clone, Copy, PartialEq, Debug)]
+#[derive(Clone, PartialEq, Debug)]
 pub enum ParserError {
     /// msg, line, col
     SyntaxError(ErrorCode, uint, uint),
-    IoError(old_io::IoErrorKind, &'static str),
+    IoError(io::ErrorKind, String),
 }
 
 // Builder and Parser have the same errors.
@@ -331,8 +333,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-fn io_error_to_error(io: old_io::IoError) -> ParserError {
-    IoError(io.kind, io.desc)
+fn io_error_to_error(io: io::Error) -> ParserError {
+    IoError(io.kind(), io.to_string())
 }
 
 impl fmt::Display for ParserError {
@@ -1982,7 +1984,7 @@ pub fn build(&mut self) -> Result<Json, BuilderError> {
         self.bump();
         match self.token {
             None => {}
-            Some(Error(e)) => { return Err(e); }
+            Some(Error(ref e)) => { return Err(e.clone()); }
             ref tok => { panic!("unexpected token {:?}", tok.clone()); }
         }
         result
@@ -2004,7 +2006,7 @@ fn build_value(&mut self) -> Result<Json, BuilderError> {
                 swap(s, &mut temp);
                 Ok(Json::String(temp))
             }
-            Some(Error(e)) => Err(e),
+            Some(Error(ref e)) => Err(e.clone()),
             Some(ArrayStart) => self.build_array(),
             Some(ObjectStart) => self.build_object(),
             Some(ObjectEnd) => self.parser.error(InvalidSyntax),
@@ -2037,7 +2039,7 @@ fn build_object(&mut self) -> Result<Json, BuilderError> {
         loop {
             match self.token {
                 Some(ObjectEnd) => { return Ok(Json::Object(values)); }
-                Some(Error(e)) => { return Err(e); }
+                Some(Error(ref e)) => { return Err(e.clone()); }
                 None => { break; }
                 _ => {}
             }
@@ -2056,8 +2058,9 @@ fn build_object(&mut self) -> Result<Json, BuilderError> {
 }
 
 /// Decodes a json value from an `&mut old_io::Reader`
-pub fn from_reader(rdr: &mut old_io::Reader) -> Result<Json, BuilderError> {
-    let contents = match rdr.read_to_end() {
+pub fn from_reader(rdr: &mut Read) -> Result<Json, BuilderError> {
+    let mut contents = Vec::new();
+    match rdr.read_to_end(&mut contents) {
         Ok(c)  => c,
         Err(e) => return Err(io_error_to_error(e))
     };
index 8d58ba99e13138268c3176989fc883a386eda668..49e44a6d45563e4080f23c7f8f3b59cbf80e9dd0 100644 (file)
@@ -31,7 +31,7 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(int_uint)]
-#![feature(old_io)]
+#![feature(io)]
 #![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
index 44564ebf53d5828024a37b58cd4645f97d16c842..677894ba6e4c450cf8711639cdf24b91fc54529a 100644 (file)
@@ -17,6 +17,7 @@
 use iter::IteratorExt;
 use libc;
 use mem;
+#[allow(deprecated)]
 use old_io;
 use ops::Deref;
 use option::Option::{self, Some, None};
@@ -298,6 +299,7 @@ fn from_error(_: NulError) -> io::Error {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
 impl FromError<NulError> for old_io::IoError {
     fn from_error(_: NulError) -> old_io::IoError {
         old_io::IoError {
index 3603f1275048d9fda1fe4210f1ad32f0ba7b9db7..03416eb86a0eb92427ec54b12d53c0e2ecd6af8e 100644 (file)
@@ -16,8 +16,7 @@
 use io::prelude::*;
 
 use cmp;
-use error::Error as StdError;
-use error::FromError;
+use error::{self, FromError};
 use fmt;
 use io::{self, Cursor, DEFAULT_BUF_SIZE, Error, ErrorKind};
 use ptr;
@@ -28,6 +27,7 @@
 /// For example, every call to `read` on `TcpStream` results in a system call.
 /// A `BufReader` performs large, infrequent reads on the underlying `Read`
 /// and maintains an in-memory buffer of the results.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct BufReader<R> {
     inner: R,
     buf: Cursor<Vec<u8>>,
@@ -35,11 +35,13 @@ pub struct BufReader<R> {
 
 impl<R: Read> BufReader<R> {
     /// Creates a new `BufReader` with a default buffer capacity
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: R) -> BufReader<R> {
         BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
     }
 
     /// Creates a new `BufReader` with the specified buffer capacity
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(cap: usize, inner: R) -> BufReader<R> {
         BufReader {
             inner: inner,
@@ -48,6 +50,7 @@ pub fn with_capacity(cap: usize, inner: R) -> BufReader<R> {
     }
 
     /// Gets a reference to the underlying reader.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_ref(&self) -> &R { &self.inner }
 
     /// Gets a mutable reference to the underlying reader.
@@ -55,14 +58,17 @@ pub fn get_ref(&self) -> &R { &self.inner }
     /// # Warning
     ///
     /// It is inadvisable to directly read from the underlying reader.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut R { &mut self.inner }
 
     /// Unwraps this `BufReader`, returning the underlying reader.
     ///
     /// Note that any leftover data in the internal buffer is lost.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> R { self.inner }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<R: Read> Read for BufReader<R> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         // If we don't have any buffered data and we're doing a massive read
@@ -77,6 +83,7 @@ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<R: Read> BufRead for BufReader<R> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> {
         // If we've reached the end of our internal buffer then we need to fetch
@@ -112,6 +119,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 /// underlying `Write` in large, infrequent batches.
 ///
 /// This writer will be flushed when it is dropped.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct BufWriter<W> {
     inner: Option<W>,
     buf: Vec<u8>,
@@ -120,15 +128,18 @@ pub struct BufWriter<W> {
 /// An error returned by `into_inner` which indicates whether a flush error
 /// happened or not.
 #[derive(Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoInnerError<W>(W, Error);
 
 impl<W: Write> BufWriter<W> {
     /// Creates a new `BufWriter` with a default buffer capacity
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: W) -> BufWriter<W> {
         BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
     }
 
     /// Creates a new `BufWriter` with the specified buffer capacity
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(cap: usize, inner: W) -> BufWriter<W> {
         BufWriter {
             inner: Some(inner),
@@ -148,6 +159,7 @@ fn flush_buf(&mut self) -> io::Result<()> {
                     break;
                 }
                 Ok(n) => written += n,
+                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
                 Err(e) => { ret = Err(e); break }
 
             }
@@ -165,6 +177,7 @@ fn flush_buf(&mut self) -> io::Result<()> {
     }
 
     /// Gets a reference to the underlying writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
 
     /// Gets a mutable reference to the underlying write.
@@ -172,11 +185,13 @@ pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
     /// # Warning
     ///
     /// It is inadvisable to directly read from the underlying writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut W { self.inner.as_mut().unwrap() }
 
     /// Unwraps this `BufWriter`, returning the underlying writer.
     ///
     /// The buffer is flushed before returning the writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
         match self.flush_buf() {
             Err(e) => Err(IntoInnerError(self, e)),
@@ -185,6 +200,7 @@ pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<W: Write> Write for BufWriter<W> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         if self.buf.len() + buf.len() > self.buf.capacity() {
@@ -224,23 +240,30 @@ impl<W> IntoInnerError<W> {
     /// Returns the error which caused the call to `into_inner` to fail.
     ///
     /// This error was returned when attempting to flush the internal buffer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn error(&self) -> &Error { &self.1 }
 
     /// Returns the underlying `BufWriter` instance which generated the error.
     ///
     /// The returned object can be used to retry a flush or re-inspect the
     /// buffer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> W { self.0 }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<W> FromError<IntoInnerError<W>> for Error {
     fn from_error(iie: IntoInnerError<W>) -> Error { iie.1 }
 }
 
-impl<W> StdError for IntoInnerError<W> {
-    fn description(&self) -> &str { self.error().description() }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<W> error::Error for IntoInnerError<W> {
+    fn description(&self) -> &str {
+        error::Error::description(self.error())
+    }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<W> fmt::Display for IntoInnerError<W> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.error().fmt(f)
@@ -251,26 +274,41 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// (`0x0a`, `'\n'`) is detected.
 ///
 /// This writer will be flushed when it is dropped.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct LineWriter<W> {
     inner: BufWriter<W>,
 }
 
 impl<W: Write> LineWriter<W> {
     /// Creates a new `LineWriter`
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: W) -> LineWriter<W> {
         // Lines typically aren't that long, don't use a giant buffer
-        LineWriter { inner: BufWriter::with_capacity(1024, inner) }
+        LineWriter::with_capacity(1024, inner)
+    }
+
+    /// Creates a new `LineWriter` with a specified capacity for the internal
+    /// buffer.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn with_capacity(cap: usize, inner: W) -> LineWriter<W> {
+        LineWriter { inner: BufWriter::with_capacity(cap, inner) }
     }
 
     /// Gets a reference to the underlying writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get_ref(&self) -> &W { self.inner.get_ref() }
+
+    /// Gets a mutable reference to the underlying writer.
     ///
-    /// This type does not expose the ability to get a mutable reference to the
-    /// underlying reader because that could possibly corrupt the buffer.
-    pub fn get_ref<'a>(&'a self) -> &'a W { self.inner.get_ref() }
+    /// Caution must be taken when calling methods on the mutable reference
+    /// returned as extra writes could corrupt the output stream.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get_mut(&mut self) -> &mut W { self.inner.get_mut() }
 
     /// Unwraps this `LineWriter`, returning the underlying writer.
     ///
     /// The internal buffer is flushed before returning the writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> Result<W, IntoInnerError<LineWriter<W>>> {
         self.inner.into_inner().map_err(|IntoInnerError(buf, e)| {
             IntoInnerError(LineWriter { inner: buf }, e)
@@ -278,6 +316,7 @@ pub fn into_inner(self) -> Result<W, IntoInnerError<LineWriter<W>>> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<W: Write> Write for LineWriter<W> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         match buf.rposition_elem(&b'\n') {
@@ -320,12 +359,13 @@ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
 
 /// Wraps a Stream and buffers input and output to and from it.
 ///
-/// It can be excessively inefficient to work directly with a `Stream`. For
+/// It can be excessively inefficient to work directly with a `Read+Write`. For
 /// example, every call to `read` or `write` on `TcpStream` results in a system
 /// call. A `BufStream` keeps in memory buffers of data, making large,
-/// infrequent calls to `read` and `write` on the underlying `Stream`.
+/// infrequent calls to `read` and `write` on the underlying `Read+Write`.
 ///
 /// The output half will be flushed when this stream is dropped.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct BufStream<S> {
     inner: BufReader<InternalBufWriter<S>>
 }
@@ -333,6 +373,7 @@ pub struct BufStream<S> {
 impl<S: Read + Write> BufStream<S> {
     /// Creates a new buffered stream with explicitly listed capacities for the
     /// reader/writer buffer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacities(reader_cap: usize, writer_cap: usize, inner: S)
                            -> BufStream<S> {
         let writer = BufWriter::with_capacity(writer_cap, inner);
@@ -343,11 +384,13 @@ pub fn with_capacities(reader_cap: usize, writer_cap: usize, inner: S)
 
     /// Creates a new buffered stream with the default reader/writer buffer
     /// capacities.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: S) -> BufStream<S> {
         BufStream::with_capacities(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE, inner)
     }
 
     /// Gets a reference to the underlying stream.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_ref(&self) -> &S {
         let InternalBufWriter(ref w) = self.inner.inner;
         w.get_ref()
@@ -359,6 +402,7 @@ pub fn get_ref(&self) -> &S {
     ///
     /// It is inadvisable to read directly from or write directly to the
     /// underlying stream.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut S {
         let InternalBufWriter(ref mut w) = self.inner.inner;
         w.get_mut()
@@ -368,6 +412,7 @@ pub fn get_mut(&mut self) -> &mut S {
     ///
     /// The internal buffer is flushed before returning the stream. Any leftover
     /// data in the read buffer is lost.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> Result<S, IntoInnerError<BufStream<S>>> {
         let BufReader { inner: InternalBufWriter(w), buf } = self.inner;
         w.into_inner().map_err(|IntoInnerError(w, e)| {
@@ -378,17 +423,20 @@ pub fn into_inner(self) -> Result<S, IntoInnerError<BufStream<S>>> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<S: Read + Write> BufRead for BufStream<S> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
     fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<S: Read + Write> Read for BufStream<S> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<S: Read + Write> Write for BufStream<S> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.inner.get_mut().write(buf)
index 9f3cd8c8b15deb4b68978d0df8c8343fe8486831..530c672810723a26ae7c59cfd1c6535a3e6a9105 100644 (file)
@@ -10,7 +10,7 @@
 
 use boxed::Box;
 use clone::Clone;
-use error::Error as StdError;
+use error;
 use fmt;
 use option::Option::{self, Some, None};
 use result;
@@ -22,6 +22,7 @@
 ///
 /// This typedef is generally used to avoid writing out `io::Error` directly and
 /// is otherwise a direct mapping to `std::result::Result`.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub type Result<T> = result::Result<T, Error>;
 
 /// The error type for I/O operations of the `Read`, `Write`, `Seek`, and
@@ -31,6 +32,7 @@
 /// `Error` can be created with crafted error messages and a particular value of
 /// `ErrorKind`.
 #[derive(PartialEq, Eq, Clone, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Error {
     repr: Repr,
 }
@@ -50,6 +52,10 @@ struct Custom {
 
 /// A list specifying general categories of I/O error.
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
+#[unstable(feature = "io",
+           reason = "the interaction between OS error codes and how they map to \
+                     these names (as well as the names themselves) has not \
+                     been thoroughly thought out")]
 pub enum ErrorKind {
     /// The file was not found.
     FileNotFound,
@@ -96,6 +102,9 @@ pub enum ErrorKind {
 
 impl Error {
     /// Creates a new custom error from a specified kind/description/detail.
+    #[unstable(feature = "io", reason = "the exact makeup of an Error may
+                                         change to include `Box<Error>` for \
+                                         example")]
     pub fn new(kind: ErrorKind,
                description: &'static str,
                detail: Option<String>) -> Error {
@@ -113,16 +122,20 @@ pub fn new(kind: ErrorKind,
     /// This function reads the value of `errno` for the target platform (e.g.
     /// `GetLastError` on Windows) and will return a corresponding instance of
     /// `Error` for the error code.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn last_os_error() -> Error {
         Error::from_os_error(sys::os::errno() as i32)
     }
 
     /// Creates a new instance of an `Error` from a particular OS error code.
+    #[unstable(feature = "io",
+               reason = "unclear whether this function is necessary")]
     pub fn from_os_error(code: i32) -> Error {
         Error { repr: Repr::Os(code) }
     }
 
     /// Return the corresponding `ErrorKind` for this error.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn kind(&self) -> ErrorKind {
         match self.repr {
             Repr::Os(code) => sys::decode_error_kind(code),
@@ -131,6 +144,9 @@ pub fn kind(&self) -> ErrorKind {
     }
 
     /// Returns a short description for this error message
+    #[unstable(feature = "io")]
+    #[deprecated(since = "1.0.0", reason = "use the Error trait's description \
+                                            method instead")]
     pub fn description(&self) -> &str {
         match self.repr {
             Repr::Os(..) => "os error",
@@ -139,6 +155,8 @@ pub fn description(&self) -> &str {
     }
 
     /// Returns a detailed error message for this error (if one is available)
+    #[unstable(feature = "io")]
+    #[deprecated(since = "1.0.0", reason = "use the to_string() method instead")]
     pub fn detail(&self) -> Option<String> {
         match self.repr {
             Repr::Os(code) => Some(sys::os::error_string(code)),
@@ -147,6 +165,7 @@ pub fn detail(&self) -> Option<String> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for Error {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         match self.repr {
@@ -173,7 +192,8 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl StdError for Error {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl error::Error for Error {
     fn description(&self) -> &str {
         match self.repr {
             Repr::Os(..) => "os error",
index c968415d3efdc5670cdee690fb3cea0c6bf60032..16298240acfbed7e9968ade38f5f875c7f70e9a2 100644 (file)
@@ -27,10 +27,10 @@ impl<'a, R: Read + ?Sized> Read for &'a mut R {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         (**self).read(buf)
     }
-    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
         (**self).read_to_end(buf)
     }
-    fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
         (**self).read_to_string(buf)
     }
 }
@@ -53,10 +53,10 @@ fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
 impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B {
     fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
     fn consume(&mut self, amt: usize) { (**self).consume(amt) }
-    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<()> {
+    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
         (**self).read_until(byte, buf)
     }
-    fn read_line(&mut self, buf: &mut String) -> io::Result<()> {
+    fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
         (**self).read_line(buf)
     }
 }
@@ -66,10 +66,10 @@ impl<R: Read + ?Sized> Read for Box<R> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         (**self).read(buf)
     }
-    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
         (**self).read_to_end(buf)
     }
-    fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
         (**self).read_to_string(buf)
     }
 }
@@ -92,10 +92,10 @@ fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
 impl<B: BufRead + ?Sized> BufRead for Box<B> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
     fn consume(&mut self, amt: usize) { (**self).consume(amt) }
-    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<()> {
+    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
         (**self).read_until(byte, buf)
     }
-    fn read_line(&mut self, buf: &mut String) -> io::Result<()> {
+    fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
         (**self).read_line(buf)
     }
 }
index 9137068076b46818d30eb55a5d5cf77d5a0845a9..3fddaaad807911b532c0e4eef1f56845a898883b 100644 (file)
 //! > development. At this time it is still recommended to use the `old_io`
 //! > module while the details of this module shake out.
 
-#![unstable(feature = "io",
-            reason = "this new I/O module is still under active development and \
-                      APIs are subject to tweaks fairly regularly")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
 use cmp;
 use unicode::str as core_str;
-use error::Error as StdError;
+use error as std_error;
 use fmt;
 use iter::Iterator;
 use marker::Sized;
@@ -41,6 +39,8 @@
 pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat};
 pub use self::stdio::{stdin, stdout, stderr, Stdin, Stdout, Stderr};
 pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
+#[doc(no_inline, hidden)]
+pub use self::stdio::set_panic;
 
 #[macro_use] mod lazy;
 
@@ -111,8 +111,8 @@ unsafe fn black_box<T>(mut dummy: T) -> T {
 // 2. We're passing a raw buffer to the function `f`, and it is expected that
 //    the function only *appends* bytes to the buffer. We'll get undefined
 //    behavior if existing bytes are overwritten to have non-UTF-8 data.
-fn append_to_string<F>(buf: &mut String, f: F) -> Result<()>
-    where F: FnOnce(&mut Vec<u8>) -> Result<()>
+fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
+    where F: FnOnce(&mut Vec<u8>) -> Result<usize>
 {
     struct Guard<'a> { s: &'a mut Vec<u8>, len: usize }
     #[unsafe_destructor]
@@ -126,7 +126,7 @@ fn drop(&mut self) {
         let mut g = Guard { len: buf.len(), s: buf.as_mut_vec() };
         let ret = f(g.s);
         if str::from_utf8(&g.s[g.len..]).is_err() {
-            ret.and_then(|()| {
+            ret.and_then(|_| {
                 Err(Error::new(ErrorKind::InvalidInput,
                                "stream did not contain valid UTF-8", None))
             })
@@ -137,14 +137,15 @@ fn drop(&mut self) {
     }
 }
 
-fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<()> {
+fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
+    let mut read = 0;
     loop {
         if buf.capacity() == buf.len() {
             buf.reserve(DEFAULT_BUF_SIZE);
         }
         match with_end_to_cap(buf, |b| r.read(b)) {
-            Ok(0) => return Ok(()),
-            Ok(_) => {}
+            Ok(0) => return Ok(read),
+            Ok(n) => read += n,
             Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
             Err(e) => return Err(e),
         }
@@ -159,6 +160,7 @@ fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<()> {
 /// Readers are intended to be composable with one another. Many objects
 /// throughout the I/O and related libraries take and provide types which
 /// implement the `Read` trait.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Read {
     /// Pull some bytes from this source into the specified buffer, returning
     /// how many bytes were read.
@@ -187,6 +189,7 @@ pub trait Read {
     /// If this function encounters any form of I/O or other error, an error
     /// variant will be returned. If an error is returned then it must be
     /// guaranteed that no bytes were read.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
 
     /// Read all bytes until EOF in this source, placing them into `buf`.
@@ -198,7 +201,8 @@ pub trait Read {
     /// 2. Returns an error which is not of the kind `ErrorKind::Interrupted`.
     ///
     /// Until one of these conditions is met the function will continuously
-    /// invoke `read` to append more data to `buf`.
+    /// invoke `read` to append more data to `buf`. If successful, this function
+    /// will return the total number of bytes read.
     ///
     /// # Errors
     ///
@@ -209,19 +213,24 @@ pub trait Read {
     /// If any other read error is encountered then this function immediately
     /// returns. Any bytes which have already been read will be appended to
     /// `buf`.
-    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<()> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
         read_to_end(self, buf)
     }
 
     /// Read all bytes until EOF in this source, placing them into `buf`.
     ///
+    /// If successful, this function returns the number of bytes which were read
+    /// and appended to `buf`.
+    ///
     /// # Errors
     ///
     /// If the data in this stream is *not* valid UTF-8 then an error is
     /// returned and `buf` is unchanged.
     ///
     /// See `read_to_end` for other error semantics.
-    fn read_to_string(&mut self, buf: &mut String) -> Result<()> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
         // Note that we do *not* call `.read_to_end()` here. We are passing
         // `&mut Vec<u8>` (the raw contents of `buf`) into the `read_to_end`
         // method to fill it up. An arbitrary implementation could overwrite the
@@ -233,18 +242,13 @@ fn read_to_string(&mut self, buf: &mut String) -> Result<()> {
         // know is guaranteed to only read data into the end of the buffer.
         append_to_string(buf, |b| read_to_end(self, b))
     }
-}
 
-/// Extension methods for all instances of `Read`, typically imported through
-/// `std::io::prelude::*`.
-#[unstable(feature = "io", reason = "may merge into the Read trait")]
-pub trait ReadExt: Read + Sized {
     /// Create a "by reference" adaptor for this instance of `Read`.
     ///
     /// The returned adaptor also implements `Read` and will simply borrow this
     /// current reader.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn by_ref(&mut self) -> &mut Self { self }
+    fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
 
     /// Transform this `Read` instance to an `Iterator` over its bytes.
     ///
@@ -253,7 +257,7 @@ fn by_ref(&mut self) -> &mut Self { self }
     /// `Err` otherwise for I/O errors. EOF is mapped to returning `None` from
     /// this iterator.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn bytes(self) -> Bytes<Self> {
+    fn bytes(self) -> Bytes<Self> where Self: Sized {
         Bytes { inner: self }
     }
 
@@ -270,7 +274,7 @@ fn bytes(self) -> Bytes<Self> {
     #[unstable(feature = "io", reason = "the semantics of a partial read/write \
                                          of where errors happen is currently \
                                          unclear and may change")]
-    fn chars(self) -> Chars<Self> {
+    fn chars(self) -> Chars<Self> where Self: Sized {
         Chars { inner: self }
     }
 
@@ -280,7 +284,7 @@ fn chars(self) -> Chars<Self> {
     /// until EOF is encountered. Afterwards the output is equivalent to the
     /// output of `next`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn chain<R: Read>(self, next: R) -> Chain<Self, R> {
+    fn chain<R: Read>(self, next: R) -> Chain<Self, R> where Self: Sized {
         Chain { first: self, second: next, done_first: false }
     }
 
@@ -291,7 +295,7 @@ fn chain<R: Read>(self, next: R) -> Chain<Self, R> {
     /// read errors will not count towards the number of bytes read and future
     /// calls to `read` may succeed.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn take(self, limit: u64) -> Take<Self> {
+    fn take(self, limit: u64) -> Take<Self> where Self: Sized {
         Take { inner: self, limit: limit }
     }
 
@@ -304,13 +308,11 @@ fn take(self, limit: u64) -> Take<Self> {
     #[unstable(feature = "io", reason = "the semantics of a partial read/write \
                                          of where errors happen is currently \
                                          unclear and may change")]
-    fn tee<W: Write>(self, out: W) -> Tee<Self, W> {
+    fn tee<W: Write>(self, out: W) -> Tee<Self, W> where Self: Sized {
         Tee { reader: self, writer: out }
     }
 }
 
-impl<T: Read> ReadExt for T {}
-
 /// A trait for objects which are byte-oriented sinks.
 ///
 /// The `write` method will attempt to write some data into the object,
@@ -322,6 +324,7 @@ impl<T: Read> ReadExt for T {}
 /// Writers are intended to be composable with one another. Many objects
 /// throughout the I/O and related libraries take and provide types which
 /// implement the `Write` trait.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Write {
     /// Write a buffer into this object, returning how many bytes were written.
     ///
@@ -347,6 +350,7 @@ pub trait Write {
     ///
     /// It is **not** considered an error if the entire buffer could not be
     /// written to this writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn write(&mut self, buf: &[u8]) -> Result<usize>;
 
     /// Flush this output stream, ensuring that all intermediately buffered
@@ -356,6 +360,7 @@ pub trait Write {
     ///
     /// It is considered an error if not all bytes could be written due to
     /// I/O errors or EOF being reached.
+    #[unstable(feature = "io", reason = "waiting for RFC 950")]
     fn flush(&mut self) -> Result<()>;
 
     /// Attempts to write an entire buffer into this write.
@@ -368,6 +373,7 @@ pub trait Write {
     /// # Errors
     ///
     /// This function will return the first error that `write` returns.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
         while buf.len() > 0 {
             match self.write(buf) {
@@ -396,6 +402,7 @@ fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
     /// # Errors
     ///
     /// This function will return any I/O error reported while formatting.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<()> {
         // Create a shim which translates a Write to a fmt::Write and saves
         // off I/O errors. instead of discarding them
@@ -422,18 +429,13 @@ fn write_str(&mut self, s: &str) -> fmt::Result {
             Err(..) => output.error
         }
     }
-}
 
-/// Extension methods for all instances of `Write`, typically imported through
-/// `std::io::prelude::*`.
-#[unstable(feature = "io", reason = "may merge into the Read trait")]
-pub trait WriteExt: Write + Sized {
     /// Create a "by reference" adaptor for this instance of `Write`.
     ///
     /// The returned adaptor also implements `Write` and will simply borrow this
     /// current writer.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn by_ref(&mut self) -> &mut Self { self }
+    fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
 
     /// Creates a new writer which will write all data to both this writer and
     /// another writer.
@@ -446,19 +448,21 @@ fn by_ref(&mut self) -> &mut Self { self }
     #[unstable(feature = "io", reason = "the semantics of a partial read/write \
                                          of where errors happen is currently \
                                          unclear and may change")]
-    fn broadcast<W: Write>(self, other: W) -> Broadcast<Self, W> {
+    fn broadcast<W: Write>(self, other: W) -> Broadcast<Self, W>
+        where Self: Sized
+    {
         Broadcast { first: self, second: other }
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Write> WriteExt for T {}
-
 /// An object implementing `Seek` internally has some form of cursor which can
 /// be moved within a stream of bytes.
 ///
 /// The stream typically has a fixed size, allowing seeking relative to either
 /// end or the current offset.
+#[unstable(feature = "io", reason = "the central `seek` method may be split \
+                                     into multiple methods instead of taking \
+                                     an enum as an argument")]
 pub trait Seek {
     /// Seek to an offset, in bytes, in a stream
     ///
@@ -479,6 +483,7 @@ pub trait Seek {
 
 /// Enumeration of possible methods to seek within an I/O object.
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
+#[unstable(feature = "io", reason = "awaiting the stability of Seek")]
 pub enum SeekFrom {
     /// Set the offset to the provided number of bytes.
     Start(u64),
@@ -499,7 +504,8 @@ pub enum SeekFrom {
 }
 
 fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
-                                   -> Result<()> {
+                                   -> Result<usize> {
+    let mut read = 0;
     loop {
         let (done, used) = {
             let available = match r.fill_buf() {
@@ -519,8 +525,9 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
             }
         };
         r.consume(used);
+        read += used;
         if done || used == 0 {
-            return Ok(());
+            return Ok(read);
         }
     }
 }
@@ -530,6 +537,7 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
 ///
 /// This type extends the `Read` trait with a few methods that are not
 /// possible to reasonably implement with purely a read interface.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait BufRead: Read {
     /// Fills the internal buffer of this object, returning the buffer contents.
     ///
@@ -546,10 +554,16 @@ pub trait BufRead: Read {
     ///
     /// This function will return an I/O error if the underlying reader was
     /// read, but returned an error.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn fill_buf(&mut self) -> Result<&[u8]>;
 
     /// Tells this buffer that `amt` bytes have been consumed from the buffer,
     /// so they should no longer be returned in calls to `read`.
+    ///
+    /// This function does not perform any I/O, it simply informs this object
+    /// that some amount of its buffer, returned from `fill_buf`, has been
+    /// consumed and should no longer be returned.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn consume(&mut self, amt: usize);
 
     /// Read all bytes until the delimiter `byte` is reached.
@@ -560,7 +574,8 @@ pub trait BufRead: Read {
     /// `buf`.
     ///
     /// If this buffered reader is currently at EOF, then this function will not
-    /// place any more bytes into `buf` and will return `Ok(())`.
+    /// place any more bytes into `buf` and will return `Ok(n)` where `n` is the
+    /// number of bytes which were read.
     ///
     /// # Errors
     ///
@@ -569,7 +584,8 @@ pub trait BufRead: Read {
     ///
     /// If an I/O error is encountered then all bytes read so far will be
     /// present in `buf` and its length will have been adjusted appropriately.
-    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<()> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
         read_until(self, byte, buf)
     }
 
@@ -581,7 +597,8 @@ fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<()> {
     /// found) will be appended to `buf`.
     ///
     /// If this reader is currently at EOF then this function will not modify
-    /// `buf` and will return `Ok(())`.
+    /// `buf` and will return `Ok(n)` where `n` is the number of bytes which
+    /// were read.
     ///
     /// # Errors
     ///
@@ -589,17 +606,14 @@ fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<()> {
     /// return an error if the read bytes are not valid UTF-8. If an I/O error
     /// is encountered then `buf` may contain some bytes already read in the
     /// event that all data read so far was valid UTF-8.
-    fn read_line(&mut self, buf: &mut String) -> Result<()> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn read_line(&mut self, buf: &mut String) -> Result<usize> {
         // Note that we are not calling the `.read_until` method here, but
         // rather our hardcoded implementation. For more details as to why, see
         // the comments in `read_to_end`.
         append_to_string(buf, |b| read_until(self, b'\n', b))
     }
-}
 
-/// Extension methods for all instances of `BufRead`, typically imported through
-/// `std::io::prelude::*`.
-pub trait BufReadExt: BufRead + Sized {
     /// Returns an iterator over the contents of this reader split on the byte
     /// `byte`.
     ///
@@ -611,7 +625,7 @@ pub trait BufReadExt: BufRead + Sized {
     /// yielded an error.
     #[unstable(feature = "io", reason = "may be renamed to not conflict with \
                                          SliceExt::split")]
-    fn split(self, byte: u8) -> Split<Self> {
+    fn split(self, byte: u8) -> Split<Self> where Self: Sized {
         Split { buf: self, delim: byte }
     }
 
@@ -624,22 +638,21 @@ fn split(self, byte: u8) -> Split<Self> {
     /// This function will yield errors whenever `read_string` would have also
     /// yielded an error.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn lines(self) -> Lines<Self> {
+    fn lines(self) -> Lines<Self> where Self: Sized {
         Lines { buf: self }
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: BufRead> BufReadExt for T {}
-
 /// A `Write` adaptor which will write data to multiple locations.
 ///
 /// For more information, see `WriteExt::broadcast`.
+#[unstable(feature = "io", reason = "awaiting stability of WriteExt::broadcast")]
 pub struct Broadcast<T, U> {
     first: T,
     second: U,
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of WriteExt::broadcast")]
 impl<T: Write, U: Write> Write for Broadcast<T, U> {
     fn write(&mut self, data: &[u8]) -> Result<usize> {
         let n = try!(self.first.write(data));
@@ -732,11 +745,13 @@ fn consume(&mut self, amt: usize) {
 /// An adaptor which will emit all read data to a specified writer as well.
 ///
 /// For more information see `ReadExt::tee`
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::tee")]
 pub struct Tee<R, W> {
     reader: R,
     writer: W,
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::tee")]
 impl<R: Read, W: Write> Read for Tee<R, W> {
     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
         let n = try!(self.reader.read(buf));
@@ -771,6 +786,7 @@ fn next(&mut self) -> Option<Result<u8>> {
 /// A bridge from implementations of `Read` to an `Iterator` of `char`.
 ///
 /// See `ReadExt::chars` for more information.
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::chars")]
 pub struct Chars<R> {
     inner: R,
 }
@@ -778,6 +794,7 @@ pub struct Chars<R> {
 /// An enumeration of possible errors that can be generated from the `Chars`
 /// adapter.
 #[derive(PartialEq, Clone, Debug)]
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::chars")]
 pub enum CharsError {
     /// Variant representing that the underlying stream was read successfully
     /// but it did not contain valid utf8 data.
@@ -787,6 +804,7 @@ pub enum CharsError {
     Other(Error),
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::chars")]
 impl<R: Read> Iterator for Chars<R> {
     type Item = result::Result<char, CharsError>;
 
@@ -818,14 +836,15 @@ fn next(&mut self) -> Option<result::Result<char, CharsError>> {
     }
 }
 
-impl StdError for CharsError {
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::chars")]
+impl std_error::Error for CharsError {
     fn description(&self) -> &str {
         match *self {
             CharsError::NotUtf8 => "invalid utf8 encoding",
-            CharsError::Other(ref e) => e.description(),
+            CharsError::Other(ref e) => std_error::Error::description(e),
         }
     }
-    fn cause(&self) -> Option<&StdError> {
+    fn cause(&self) -> Option<&std_error::Error> {
         match *self {
             CharsError::NotUtf8 => None,
             CharsError::Other(ref e) => e.cause(),
@@ -833,6 +852,7 @@ fn cause(&self) -> Option<&StdError> {
     }
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::chars")]
 impl fmt::Display for CharsError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
@@ -848,19 +868,21 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// particular byte.
 ///
 /// See `BufReadExt::split` for more information.
+#[unstable(feature = "io", reason = "awaiting stability of BufReadExt::split")]
 pub struct Split<B> {
     buf: B,
     delim: u8,
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of BufReadExt::split")]
 impl<B: BufRead> Iterator for Split<B> {
     type Item = Result<Vec<u8>>;
 
     fn next(&mut self) -> Option<Result<Vec<u8>>> {
         let mut buf = Vec::new();
         match self.buf.read_until(self.delim, &mut buf) {
-            Ok(()) if buf.len() == 0 => None,
-            Ok(()) => {
+            Ok(0) => None,
+            Ok(_n) => {
                 if buf[buf.len() - 1] == self.delim {
                     buf.pop();
                 }
@@ -887,8 +909,8 @@ impl<B: BufRead> Iterator for Lines<B> {
     fn next(&mut self) -> Option<Result<String>> {
         let mut buf = String::new();
         match self.buf.read_line(&mut buf) {
-            Ok(()) if buf.len() == 0 => None,
-            Ok(()) => {
+            Ok(0) => None,
+            Ok(_n) => {
                 if buf.ends_with("\n") {
                     buf.pop();
                 }
@@ -910,18 +932,18 @@ mod tests {
     fn read_until() {
         let mut buf = Cursor::new(b"12");
         let mut v = Vec::new();
-        assert_eq!(buf.read_until(b'3', &mut v), Ok(()));
+        assert_eq!(buf.read_until(b'3', &mut v), Ok(2));
         assert_eq!(v, b"12");
 
         let mut buf = Cursor::new(b"1233");
         let mut v = Vec::new();
-        assert_eq!(buf.read_until(b'3', &mut v), Ok(()));
+        assert_eq!(buf.read_until(b'3', &mut v), Ok(3));
         assert_eq!(v, b"123");
         v.truncate(0);
-        assert_eq!(buf.read_until(b'3', &mut v), Ok(()));
+        assert_eq!(buf.read_until(b'3', &mut v), Ok(1));
         assert_eq!(v, b"3");
         v.truncate(0);
-        assert_eq!(buf.read_until(b'3', &mut v), Ok(()));
+        assert_eq!(buf.read_until(b'3', &mut v), Ok(0));
         assert_eq!(v, []);
     }
 
@@ -943,18 +965,18 @@ fn split() {
     fn read_line() {
         let mut buf = Cursor::new(b"12");
         let mut v = String::new();
-        assert_eq!(buf.read_line(&mut v), Ok(()));
+        assert_eq!(buf.read_line(&mut v), Ok(2));
         assert_eq!(v, "12");
 
         let mut buf = Cursor::new(b"12\n\n");
         let mut v = String::new();
-        assert_eq!(buf.read_line(&mut v), Ok(()));
+        assert_eq!(buf.read_line(&mut v), Ok(3));
         assert_eq!(v, "12\n");
         v.truncate(0);
-        assert_eq!(buf.read_line(&mut v), Ok(()));
+        assert_eq!(buf.read_line(&mut v), Ok(1));
         assert_eq!(v, "\n");
         v.truncate(0);
-        assert_eq!(buf.read_line(&mut v), Ok(()));
+        assert_eq!(buf.read_line(&mut v), Ok(0));
         assert_eq!(v, "");
     }
 
@@ -976,12 +998,12 @@ fn lines() {
     fn read_to_end() {
         let mut c = Cursor::new(b"");
         let mut v = Vec::new();
-        assert_eq!(c.read_to_end(&mut v), Ok(()));
+        assert_eq!(c.read_to_end(&mut v), Ok(0));
         assert_eq!(v, []);
 
         let mut c = Cursor::new(b"1");
         let mut v = Vec::new();
-        assert_eq!(c.read_to_end(&mut v), Ok(()));
+        assert_eq!(c.read_to_end(&mut v), Ok(1));
         assert_eq!(v, b"1");
     }
 
@@ -989,12 +1011,12 @@ fn read_to_end() {
     fn read_to_string() {
         let mut c = Cursor::new(b"");
         let mut v = String::new();
-        assert_eq!(c.read_to_string(&mut v), Ok(()));
+        assert_eq!(c.read_to_string(&mut v), Ok(0));
         assert_eq!(v, "");
 
         let mut c = Cursor::new(b"1");
         let mut v = String::new();
-        assert_eq!(c.read_to_string(&mut v), Ok(()));
+        assert_eq!(c.read_to_string(&mut v), Ok(1));
         assert_eq!(v, "1");
 
         let mut c = Cursor::new(b"\xff");
index 637b1950985fd79f2e9e5c278192aead8c048157..6bf0ebd1a59e9c8b0a744e7be449f6f83c2d18ef 100644 (file)
@@ -21,7 +21,9 @@
 //! `Write`, `ReadExt`, and `WriteExt`. Structures and functions are not
 //! contained in this module.
 
-pub use super::{Read, ReadExt, Write, WriteExt, BufRead, BufReadExt};
+#![stable(feature = "rust1", since = "1.0.0")]
+
+pub use super::{Read, Write, BufRead};
 pub use fs::PathExt;
 
 // FIXME: pub use as `Seek` when the name isn't in the actual prelude any more
index 4027f741654b66bbbf57c9644f06e66bb7866b30..3b4e396953d0821672e286372c45f7e8079f1364 100644 (file)
@@ -86,6 +86,7 @@ fn flush(&mut self) -> io::Result<()> { Ok(()) }
 ///
 /// This handle implements the `Read` trait, but beware that concurrent reads
 /// of `Stdin` must be executed with care.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdin {
     inner: Arc<Mutex<BufReader<StdinRaw>>>,
 }
@@ -94,6 +95,7 @@ pub struct Stdin {
 ///
 /// This handle implements both the `Read` and `BufRead` traits and is
 /// constructed via the `lock` method on `Stdin`.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct StdinLock<'a> {
     inner: MutexGuard<'a, BufReader<StdinRaw>>,
 }
@@ -110,6 +112,7 @@ pub struct StdinLock<'a> {
 ///
 /// To avoid locking and buffering altogether, it is recommended to use the
 /// `stdin_raw` constructor.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdin() -> Stdin {
     static INSTANCE: Lazy<Mutex<BufReader<StdinRaw>>> = lazy_init!(stdin_init);
     return Stdin {
@@ -136,30 +139,41 @@ impl Stdin {
     /// The lock is released when the returned lock goes out of scope. The
     /// returned guard also implements the `Read` and `BufRead` traits for
     /// accessing the underlying data.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdinLock {
         StdinLock { inner: self.inner.lock().unwrap() }
     }
+
+    /// Locks this handle and reads a line of input into the specified buffer.
+    ///
+    /// For detailed semantics of this method, see the documentation on
+    /// `BufRead::read_line`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
+        self.lock().read_line(buf)
+    }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Read for Stdin {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.lock().read(buf)
     }
-
-    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
         self.lock().read_to_end(buf)
     }
-
-    fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
         self.lock().read_to_string(buf)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Read for StdinLock<'a> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> BufRead for StdinLock<'a> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
     fn consume(&mut self, n: usize) { self.inner.consume(n) }
@@ -186,6 +200,7 @@ fn consume(&mut self, n: usize) { self.inner.consume(n) }
 /// Each handle shares a global buffer of data to be written to the standard
 /// output stream. Access is also synchronized via a lock and explicit control
 /// over locking is available via the `lock` method.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdout {
     // FIXME: this should be LineWriter or BufWriter depending on the state of
     //        stdout (tty or not). Note that if this is not line buffered it
@@ -197,6 +212,7 @@ pub struct Stdout {
 ///
 /// This handle implements the `Write` trait and is constructed via the `lock`
 /// method on `Stdout`.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct StdoutLock<'a> {
     inner: MutexGuard<'a, LineWriter<StdoutRaw>>,
 }
@@ -211,6 +227,7 @@ pub struct StdoutLock<'a> {
 ///
 /// To avoid locking and buffering altogether, it is recommended to use the
 /// `stdout_raw` constructor.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdout() -> Stdout {
     static INSTANCE: Lazy<Mutex<LineWriter<StdoutRaw>>> = lazy_init!(stdout_init);
     return Stdout {
@@ -228,11 +245,13 @@ impl Stdout {
     ///
     /// The lock is released when the returned lock goes out of scope. The
     /// returned guard also implements the `Write` trait for writing data.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdoutLock {
         StdoutLock { inner: self.inner.lock().unwrap() }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Write for Stdout {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.lock().write(buf)
@@ -247,6 +266,7 @@ fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
         self.lock().write_fmt(fmt)
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for StdoutLock<'a> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
@@ -257,6 +277,7 @@ fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
 /// A handle to the standard error stream of a process.
 ///
 /// For more information, see `stderr`
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stderr {
     inner: Arc<Mutex<StderrRaw>>,
 }
@@ -265,6 +286,7 @@ pub struct Stderr {
 ///
 /// This handle implements the `Write` trait and is constructed via the `lock`
 /// method on `Stderr`.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct StderrLock<'a> {
     inner: MutexGuard<'a, StderrRaw>,
 }
@@ -278,6 +300,7 @@ pub struct StderrLock<'a> {
 ///
 /// To avoid locking altogether, it is recommended to use the `stderr_raw`
 /// constructor.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn stderr() -> Stderr {
     static INSTANCE: Lazy<Mutex<StderrRaw>> = lazy_init!(stderr_init);
     return Stderr {
@@ -295,11 +318,13 @@ impl Stderr {
     ///
     /// The lock is released when the returned lock goes out of scope. The
     /// returned guard also implements the `Write` trait for writing data.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StderrLock {
         StderrLock { inner: self.inner.lock().unwrap() }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Write for Stderr {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.lock().write(buf)
@@ -314,9 +339,33 @@ fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
         self.lock().write_fmt(fmt)
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for StderrLock<'a> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
     }
     fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
 }
+
+/// Resets the task-local stdout handle to the specified writer
+///
+/// This will replace the current task's stdout handle, returning the old
+/// handle. All future calls to `print` and friends will emit their output to
+/// this specified handle.
+///
+/// Note that this does not need to be called for all new tasks; the default
+/// output handle is to the process's stdout stream.
+#[unstable(feature = "set_panic",
+           reason = "this function may disappear completely or be replaced \
+                     with a more general mechanism")]
+#[doc(hidden)]
+pub fn set_panic(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
+    use panicking::LOCAL_STDERR;
+    use mem;
+    LOCAL_STDERR.with(move |slot| {
+        mem::replace(&mut *slot.borrow_mut(), Some(sink))
+    }).and_then(|mut s| {
+        let _ = s.flush();
+        Some(s)
+    })
+}
index a05d6752073af4f7139445d4ab5550eab938edc6..81e2113cfdfc1b5a7d9262473ddf39ffbab438c3 100644 (file)
@@ -298,6 +298,7 @@ mod std {
     pub use sync; // used for select!()
     pub use error; // used for try!()
     pub use fmt; // used for any formatting strings
+    #[allow(deprecated)]
     pub use old_io; // used for println!()
     pub use option; // used for bitflags!{}
     pub use rt; // used for panic!()
index f71698fa72586db925a904eaa4f805c21c1ad156..9d438978f4211e67f5dd787689220f9e7ffea5d4 100644 (file)
 #![deny(unused_must_use)]
 #![allow(deprecated)] // seriously this is all deprecated
 #![allow(unused_imports)]
+#![deprecated(since = "1.0.0",
+              reasons = "APIs have been replaced with new I/O modules such as \
+                         std::{io, fs, net, process}")]
 
 pub use self::SeekStyle::*;
 pub use self::FileMode::*;
index 70e8a4ceff0a0e3d8053befeace1961ef529bd74..34b4ec94a4484ccd1a872180bc424771347162f7 100644 (file)
 use boxed::Box;
 use cell::RefCell;
 use clone::Clone;
-use panicking::LOCAL_STDERR;
 use fmt;
 use old_io::{Reader, Writer, IoResult, IoError, OtherIoError, Buffer,
-         standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
+             standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
 use marker::{Sync, Send};
 use libc;
 use mem;
@@ -319,14 +318,10 @@ pub fn set_stdout(stdout: Box<Writer + Send>) -> Option<Box<Writer + Send>> {
 ///
 /// Note that this does not need to be called for all new tasks; the default
 /// output handle is to the process's stderr stream.
-pub fn set_stderr(stderr: Box<Writer + Send>) -> Option<Box<Writer + Send>> {
-    let mut new = Some(stderr);
-    LOCAL_STDERR.with(|slot| {
-        mem::replace(&mut *slot.borrow_mut(), new.take())
-    }).and_then(|mut s| {
-        let _ = s.flush();
-        Some(s)
-    })
+#[unstable(feature = "old_io")]
+#[deprecated(since = "1.0.0", reason = "replaced with std::io::set_panic")]
+pub fn set_stderr(_stderr: Box<Writer + Send>) -> Option<Box<Writer + Send>> {
+    None
 }
 
 // Helper to access the local task's stdout handle
@@ -554,19 +549,4 @@ fn capture_stdout() {
         });
         assert_eq!(r.read_to_string().unwrap(), "hello!\n");
     }
-
-    #[test]
-    fn capture_stderr() {
-        use old_io::{ChanReader, ChanWriter, Reader};
-
-        let (tx, rx) = channel();
-        let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
-        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
-        let _t = thread::spawn(move || -> () {
-            set_stderr(Box::new(w));
-            panic!("my special message");
-        });
-        let s = r.read_to_string().unwrap();
-        assert!(s.contains("my special message"));
-    }
 }
index 53882c7b833720c88a59084e1b9bc203c6f1de1e..866f7caffe86de07689988e79c636cf44e23224a 100644 (file)
@@ -25,6 +25,7 @@
 //! OS-ignorant code by default.
 
 #![unstable(feature = "os")]
+#![deprecated(since = "1.0.0", reason = "replaced with std::env APIs")]
 
 #![allow(missing_docs)]
 #![allow(non_snake_case)]
index 2e05f6d974e3ed9492917d5e8335413261e9c6bc..3e0584d9ab4f538a0016bb267825dec440b2ace3 100644 (file)
 #![unstable(feature = "std_misc")]
 
 use prelude::v1::*;
+use io::prelude::*;
 
 use any::Any;
 use cell::RefCell;
-use old_io::IoResult;
 use rt::{backtrace, unwind};
-use rt::util::{Stderr, Stdio};
+use sys::stdio::Stderr;
 use thread;
 
 // Defined in this module instead of old_io::stdio so that the unwinding
 thread_local! {
-    pub static LOCAL_STDERR: RefCell<Option<Box<Writer + Send>>> = {
+    pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
         RefCell::new(None)
     }
 }
 
-impl Writer for Stdio {
-    fn write_all(&mut self, bytes: &[u8]) -> IoResult<()> {
-        let _ = self.write_bytes(bytes);
-        Ok(())
-    }
-}
-
-pub fn on_panic(obj: &(Any+Send), file: &'static str, line: uint) {
+pub fn on_panic(obj: &(Any+Send), file: &'static str, line: usize) {
     let msg = match obj.downcast_ref::<&'static str>() {
         Some(s) => *s,
         None => match obj.downcast_ref::<String>() {
@@ -41,7 +34,7 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: uint) {
             None => "Box<Any>",
         }
     };
-    let mut err = Stderr;
+    let mut err = Stderr::new();
     let thread = thread::current();
     let name = thread.name().unwrap_or("<unnamed>");
     let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take());
index dc55740315349b56c87d4042f3e209e81050c34b..e72fd7b33202dab64a063d2acb39ac67462e25b6 100644 (file)
 // ignore-lexer-test FIXME #15677
 
 use prelude::v1::*;
+use io::prelude::*;
 
-use cmp;
 use env;
 use fmt;
 use intrinsics;
-use libc::{self, uintptr_t};
-use os;
-use slice;
-use str;
+use libc::uintptr_t;
 use sync::atomic::{self, Ordering};
+use sys::stdio::Stderr;
 
 /// Dynamically inquire about whether we're running under V.
 /// You should usually not use this unless your test definitely
@@ -62,7 +60,9 @@ pub fn min_stack() -> uint {
 
 /// Get's the number of scheduler threads requested by the environment
 /// either `RUST_THREADS` or `num_cpus`.
+#[allow(deprecated)]
 pub fn default_sched_threads() -> uint {
+    use os;
     match env::var("RUST_THREADS") {
         Ok(nstr) => {
             let opt_n: Option<uint> = nstr.parse().ok();
@@ -88,76 +88,17 @@ pub fn default_sched_threads() -> uint {
 pub const ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) ||
                                   cfg!(rtassert);
 
-pub struct Stdio(libc::c_int);
-
-#[allow(non_upper_case_globals)]
-pub const Stdout: Stdio = Stdio(libc::STDOUT_FILENO);
-#[allow(non_upper_case_globals)]
-pub const Stderr: Stdio = Stdio(libc::STDERR_FILENO);
-
-impl Stdio {
-    pub fn write_bytes(&mut self, data: &[u8]) {
-        #[cfg(unix)]
-        type WriteLen = libc::size_t;
-        #[cfg(windows)]
-        type WriteLen = libc::c_uint;
-        unsafe {
-            let Stdio(fd) = *self;
-            libc::write(fd,
-                        data.as_ptr() as *const libc::c_void,
-                        data.len() as WriteLen);
-        }
-    }
-}
-
-impl fmt::Write for Stdio {
-    fn write_str(&mut self, data: &str) -> fmt::Result {
-        self.write_bytes(data.as_bytes());
-        Ok(()) // yes, we're lying
-    }
-}
-
 pub fn dumb_print(args: fmt::Arguments) {
-    let _ = Stderr.write_fmt(args);
+    let _ = write!(&mut Stderr::new(), "{}", args);
 }
 
 pub fn abort(args: fmt::Arguments) -> ! {
-    use fmt::Write;
-
-    struct BufWriter<'a> {
-        buf: &'a mut [u8],
-        pos: uint,
-    }
-    impl<'a> fmt::Write for BufWriter<'a> {
-        fn write_str(&mut self, bytes: &str) -> fmt::Result {
-            let left = &mut self.buf[self.pos..];
-            let to_write = &bytes.as_bytes()[..cmp::min(bytes.len(), left.len())];
-            slice::bytes::copy_memory(left, to_write);
-            self.pos += to_write.len();
-            Ok(())
-        }
-    }
-
-    // Convert the arguments into a stack-allocated string
-    let mut msg = [0; 512];
-    let mut w = BufWriter { buf: &mut msg, pos: 0 };
-    let _ = write!(&mut w, "{}", args);
-    let msg = str::from_utf8(&w.buf[..w.pos]).unwrap_or("aborted");
-    let msg = if msg.is_empty() {"aborted"} else {msg};
-    rterrln!("fatal runtime error: {}", msg);
+    rterrln!("fatal runtime error: {}", args);
     unsafe { intrinsics::abort(); }
 }
 
 pub unsafe fn report_overflow() {
     use thread;
-
-    // See the message below for why this is not emitted to the
-    // ^ Where did the message below go?
-    // task's logger. This has the additional conundrum of the
-    // logger may not be initialized just yet, meaning that an FFI
-    // call would happen to initialized it (calling out to libuv),
-    // and the FFI call needs 2MB of stack when we just ran out.
-
     rterrln!("\nthread '{}' has overflowed its stack",
              thread::current().name().unwrap_or("<unknown>"));
 }
index 50a9f204799e9f0dc1662ac1e86fb7e7eea0d63a..c42a755b444d8605e3f8dc79a34e5199befc7f77 100644 (file)
@@ -9,8 +9,9 @@
 // except according to those terms.
 
 use prelude::v1::*;
+use io::prelude::*;
 
-use old_io::IoResult;
+use io;
 
 #[cfg(target_pointer_width = "64")]
 pub const HEX_WIDTH: uint = 18;
@@ -35,7 +36,7 @@
 // Note that this demangler isn't quite as fancy as it could be. We have lots
 // of other information in our symbols like hashes, version, type information,
 // etc. Additionally, this doesn't handle glue symbols at all.
-pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
+pub fn demangle(writer: &mut Write, s: &str) -> io::Result<()> {
     // First validate the symbol. If it doesn't look like anything we're
     // expecting, we just print it literally. Note that we must handle non-rust
     // symbols because we could have any function in the backtrace.
@@ -72,12 +73,12 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
 
     // Alright, let's do this.
     if !valid {
-        try!(writer.write_str(s));
+        try!(writer.write_all(s.as_bytes()));
     } else {
         let mut first = true;
         while inner.len() > 0 {
             if !first {
-                try!(writer.write_str("::"));
+                try!(writer.write_all(b"::"));
             } else {
                 first = false;
             }
@@ -93,11 +94,11 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
                     macro_rules! demangle {
                         ($($pat:expr, => $demangled:expr),*) => ({
                             $(if rest.starts_with($pat) {
-                                try!(writer.write_str($demangled));
+                                try!(writer.write_all($demangled));
                                 rest = &rest[$pat.len()..];
                               } else)*
                             {
-                                try!(writer.write_str(rest));
+                                try!(writer.write_all(rest.as_bytes()));
                                 break;
                             }
 
@@ -106,29 +107,29 @@ macro_rules! demangle {
 
                     // see src/librustc/back/link.rs for these mappings
                     demangle! (
-                        "$SP$", => "@",
-                        "$BP$", => "*",
-                        "$RF$", => "&",
-                        "$LT$", => "<",
-                        "$GT$", => ">",
-                        "$LP$", => "(",
-                        "$RP$", => ")",
-                        "$C$", => ",",
+                        "$SP$", => b"@",
+                        "$BP$", => b"*",
+                        "$RF$", => b"&",
+                        "$LT$", => b"<",
+                        "$GT$", => b">",
+                        "$LP$", => b"(",
+                        "$RP$", => b")",
+                        "$C$", => b",",
 
                         // in theory we can demangle any Unicode code point, but
                         // for simplicity we just catch the common ones.
-                        "$u7e$", => "~",
-                        "$u20$", => " ",
-                        "$u27$", => "'",
-                        "$u5b$", => "[",
-                        "$u5d$", => "]"
+                        "$u7e$", => b"~",
+                        "$u20$", => b" ",
+                        "$u27$", => b"'",
+                        "$u5b$", => b"[",
+                        "$u5d$", => b"]"
                     )
                 } else {
                     let idx = match rest.find('$') {
                         None => rest.len(),
                         Some(i) => i,
                     };
-                    try!(writer.write_str(&rest[..idx]));
+                    try!(writer.write_all(rest[..idx].as_bytes()));
                     rest = &rest[idx..];
                 }
             }
index 9a89b290980126967c22d0ed400c2d0d8e64f40a..29c05b1e0d883c50be44e7db9c2830f3bb9b2d0f 100644 (file)
@@ -37,6 +37,7 @@
 
 // common error constructors
 
+#[allow(deprecated)]
 pub fn eof() -> IoError {
     IoError {
         kind: old_io::EndOfFile,
@@ -45,6 +46,7 @@ pub fn eof() -> IoError {
     }
 }
 
+#[allow(deprecated)]
 pub fn timeout(desc: &'static str) -> IoError {
     IoError {
         kind: old_io::TimedOut,
@@ -53,6 +55,7 @@ pub fn timeout(desc: &'static str) -> IoError {
     }
 }
 
+#[allow(deprecated)]
 pub fn short_write(n: uint, desc: &'static str) -> IoError {
     IoError {
         kind: if n == 0 { old_io::TimedOut } else { old_io::ShortWrite(n) },
@@ -61,6 +64,7 @@ pub fn short_write(n: uint, desc: &'static str) -> IoError {
     }
 }
 
+#[allow(deprecated)]
 pub fn unimpl() -> IoError {
     IoError {
         kind: old_io::IoUnavailable,
@@ -70,6 +74,7 @@ pub fn unimpl() -> IoError {
 }
 
 // unix has nonzero values as errors
+#[allow(deprecated)]
 pub fn mkerr_libc<T: Int>(ret: T) -> IoResult<()> {
     if ret != Int::zero() {
         Err(last_error())
index 24d709e9928b66336a694ee4be4f9fbe879e5a16..3fa9f5d07aa20239d14f902fbc9cd2b40e6e93a1 100644 (file)
 /// all unix platforms we support right now, so it at least gets the job done.
 
 use prelude::v1::*;
+use io::prelude::*;
 
 use ffi::CStr;
-use old_io::IoResult;
+use io;
 use libc;
 use mem;
 use str;
 /// only viable option.
 #[cfg(all(target_os = "ios", target_arch = "arm"))]
 #[inline(never)]
-pub fn write(w: &mut Writer) -> IoResult<()> {
+pub fn write(w: &mut Write) -> io::Result<()> {
     use result;
 
     extern {
@@ -135,13 +136,11 @@ fn backtrace(buf: *mut *mut libc::c_void,
 #[cfg(not(all(target_os = "ios", target_arch = "arm")))]
 #[inline(never)] // if we know this is a function call, we can skip it when
                  // tracing
-pub fn write(w: &mut Writer) -> IoResult<()> {
-    use old_io::IoError;
-
+pub fn write(w: &mut Write) -> io::Result<()> {
     struct Context<'a> {
         idx: int,
-        writer: &'a mut (Writer+'a),
-        last_error: Option<IoError>,
+        writer: &'a mut (Write+'a),
+        last_error: Option<io::Error>,
     }
 
     // When using libbacktrace, we use some necessary global state, so we
@@ -223,8 +222,8 @@ struct Context<'a> {
 }
 
 #[cfg(any(target_os = "macos", target_os = "ios"))]
-fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void,
-         _symaddr: *mut libc::c_void) -> IoResult<()> {
+fn print(w: &mut Write, idx: int, addr: *mut libc::c_void,
+         _symaddr: *mut libc::c_void) -> io::Result<()> {
     use intrinsics;
     #[repr(C)]
     struct Dl_info {
@@ -249,8 +248,8 @@ fn dladdr(addr: *const libc::c_void,
 }
 
 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
-fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void,
-         symaddr: *mut libc::c_void) -> IoResult<()> {
+fn print(w: &mut Write, idx: int, addr: *mut libc::c_void,
+         symaddr: *mut libc::c_void) -> io::Result<()> {
     use env;
     use ffi::AsOsStr;
     use os::unix::prelude::*;
@@ -442,8 +441,8 @@ unsafe fn init_state() -> *mut backtrace_state {
 }
 
 // Finally, after all that work above, we can emit a symbol.
-fn output(w: &mut Writer, idx: int, addr: *mut libc::c_void,
-          s: Option<&[u8]>) -> IoResult<()> {
+fn output(w: &mut Write, idx: int, addr: *mut libc::c_void,
+          s: Option<&[u8]>) -> io::Result<()> {
     try!(write!(w, "  {:2}: {:2$?} - ", idx, addr, HEX_WIDTH));
     match s.and_then(|s| str::from_utf8(s).ok()) {
         Some(string) => try!(demangle(w, string)),
@@ -453,8 +452,8 @@ fn output(w: &mut Writer, idx: int, addr: *mut libc::c_void,
 }
 
 #[allow(dead_code)]
-fn output_fileline(w: &mut Writer, file: &[u8], line: libc::c_int,
-                   more: bool) -> IoResult<()> {
+fn output_fileline(w: &mut Write, file: &[u8], line: libc::c_int,
+                   more: bool) -> io::Result<()> {
     let file = str::from_utf8(file).ok().unwrap_or("<unknown>");
     // prior line: "  ##: {:2$} - func"
     try!(write!(w, "      {:3$}at {}:{}", "", file, line, HEX_WIDTH));
index ca7f7c4c0ca4446521eb2072efcffe6a7151c2f0..3dd05319194b14c6336a2ecc4c30f0b8ca6b2645 100644 (file)
@@ -43,7 +43,7 @@
 use sys_common::{AsInner, AsInnerMut, IntoInner, FromInner};
 use libc::{self, gid_t, uid_t};
 
-use old_io;
+#[allow(deprecated)] use old_io;
 
 /// Raw file descriptors.
 pub type Fd = libc::c_int;
@@ -67,6 +67,7 @@ fn as_raw_fd(&self) -> Fd {
     }
 }
 
+#[allow(deprecated)]
 impl AsRawFd for old_io::pipe::PipeStream {
     fn as_raw_fd(&self) -> Fd {
         self.as_inner().fd()
index f23619955e2dd71c5eb72a7376db6165b9d7aca4..c839ce65298721cea9d8d678f02aff6629d2f153 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 //! Blocking posix-based file I/O
+#![allow(deprecated)]
 
 #![allow(deprecated)] // this module itself is essentially deprecated
 
index ed9bd0a239f11b30056db8ad240ce397a2f5c740..ff29dea254fc42031c0169a1e029de1bfbd3f590 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(deprecated)]
+
 use libc;
 use os;
 
index 865ea9872792b7e1ff66b7dca645527b00889552..a8cee74828d3496c433f07bcf73b202a32f9d03c 100644 (file)
@@ -60,10 +60,12 @@ pub mod addrinfo {
 pub type msglen_t = libc::size_t;
 pub unsafe fn close_sock(sock: sock_t) { let _ = libc::close(sock); }
 
+#[allow(deprecated)]
 pub fn last_error() -> IoError {
     decode_error_detailed(os::errno() as i32)
 }
 
+#[allow(deprecated)]
 pub fn last_net_error() -> IoError {
     last_error()
 }
@@ -72,6 +74,7 @@ pub fn last_net_error() -> IoError {
     fn gai_strerror(errcode: libc::c_int) -> *const libc::c_char;
 }
 
+#[allow(deprecated)]
 pub fn last_gai_error(s: libc::c_int) -> IoError {
 
     let mut err = decode_error(s);
@@ -83,6 +86,7 @@ pub fn last_gai_error(s: libc::c_int) -> IoError {
 }
 
 /// Convert an `errno` value into a high-level error variant and description.
+#[allow(deprecated)]
 pub fn decode_error(errno: i32) -> IoError {
     // FIXME: this should probably be a bit more descriptive...
     let (kind, desc) = match errno {
@@ -119,12 +123,14 @@ pub fn decode_error(errno: i32) -> IoError {
     IoError { kind: kind, desc: desc, detail: None }
 }
 
+#[allow(deprecated)]
 pub fn decode_error_detailed(errno: i32) -> IoError {
     let mut err = decode_error(errno);
     err.detail = Some(os::error_string(errno));
     err
 }
 
+#[allow(deprecated)]
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
     match errno as libc::c_int {
         libc::ECONNREFUSED => ErrorKind::ConnectionRefused,
@@ -155,6 +161,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
 }
 
 #[inline]
+#[allow(deprecated)]
 pub fn retry<T, F> (mut f: F) -> T where
     T: SignedInt,
     F: FnMut() -> T,
@@ -194,11 +201,13 @@ pub fn ms_to_timeval(ms: u64) -> libc::timeval {
     }
 }
 
+#[allow(deprecated)]
 pub fn wouldblock() -> bool {
     let err = os::errno();
     err == libc::EWOULDBLOCK as i32 || err == libc::EAGAIN as i32
 }
 
+#[allow(deprecated)]
 pub fn set_nonblocking(fd: sock_t, nb: bool) {
     let set = nb as libc::c_int;
     mkerr_libc(retry(|| unsafe { c::ioctl(fd, c::FIONBIO, &set) })).unwrap();
index 3266da5eb31cb8a283a7a75e875f3bf28cedb72f..d332556d188a7120a6912005198404c246bb9093 100644 (file)
@@ -22,7 +22,7 @@
 use iter;
 use libc::{self, c_int, c_char, c_void};
 use mem;
-use old_io::{IoError, IoResult};
+#[allow(deprecated)] use old_io::{IoError, IoResult};
 use ptr;
 use path::{self, PathBuf};
 use slice;
@@ -398,7 +398,7 @@ pub fn env() -> Env {
         let mut environ = *environ();
         if environ as usize == 0 {
             panic!("os::env() failure getting env string from OS: {}",
-                   IoError::last_error());
+                   io::Error::last_os_error());
         }
         let mut result = Vec::new();
         while *environ != ptr::null() {
@@ -434,7 +434,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) {
         let k = k.to_cstring().unwrap();
         let v = v.to_cstring().unwrap();
         if libc::funcs::posix01::unistd::setenv(k.as_ptr(), v.as_ptr(), 1) != 0 {
-            panic!("failed setenv: {}", IoError::last_error());
+            panic!("failed setenv: {}", io::Error::last_os_error());
         }
     }
 }
@@ -443,11 +443,12 @@ pub fn unsetenv(n: &OsStr) {
     unsafe {
         let nbuf = n.to_cstring().unwrap();
         if libc::funcs::posix01::unistd::unsetenv(nbuf.as_ptr()) != 0 {
-            panic!("failed unsetenv: {}", IoError::last_error());
+            panic!("failed unsetenv: {}", io::Error::last_os_error());
         }
     }
 }
 
+#[allow(deprecated)]
 pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> {
     let mut fds = [0; 2];
     if libc::pipe(fds.as_mut_ptr()) == 0 {
index 9cddfca69cbdd048752c620cc81e64f242e87b9c..daa981720f6da45faf6913446e253909c6af49b5 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 
 use ffi::CString;
index 2f9610fa5b5a8a9702c98374cdd536bd7e6f774f..5f5101e96d7c485ec61ac0bdbc2f44d5a139a45a 100644 (file)
@@ -50,3 +50,13 @@ pub fn write(&self, data: &[u8]) -> io::Result<usize> {
         return ret;
     }
 }
+
+// FIXME: right now this raw stderr handle is used in a few places because
+//        std::io::stderr_raw isn't exposed, but once that's exposed this impl
+//        should go away
+impl io::Write for Stderr {
+    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+        Stderr::write(self, data)
+    }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
index ce9748ede85647c9ce882f809bf34f7d0ca80642..ef0274fdda92dc223d4e0ae42993a259bd06e82f 100644 (file)
@@ -46,6 +46,8 @@
 //!
 //! Note that all time units in this file are in *milliseconds*.
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 use self::Req::*;
 
index 1d74b36a62517d24518a13a42c1527200febd3fe..f607f7c6a2f5ac76bf4465bd7e2f366f96ceba2a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 
 use sys::fs::FileDesc;
index b464ba70911f84bda6b2e7c0a75ca855239ed3ec..8638099ca695a721b1e5ba59434b04e173ed140a 100644 (file)
 use prelude::v1::*;
 
 use dynamic_lib::DynamicLibrary;
+use io;
+use io::prelude::*;
 use ffi::CStr;
 use intrinsics;
-use old_io::IoResult;
 use libc;
 use mem;
 use ptr;
@@ -292,7 +293,7 @@ impl Drop for Cleanup {
     fn drop(&mut self) { (self.SymCleanup)(self.handle); }
 }
 
-pub fn write(w: &mut Writer) -> IoResult<()> {
+pub fn write(w: &mut Write) -> io::Result<()> {
     // According to windows documentation, all dbghelp functions are
     // single-threaded.
     static LOCK: StaticMutex = MUTEX_INIT;
index 071637e3a939f82eda497d497dabdbef9e72ea31..67552255fdbeb50e0c5a294059606ccfbd31722a 100644 (file)
@@ -12,7 +12,7 @@
 
 use cell::UnsafeCell;
 use libc::{self, DWORD};
-use os;
+use sys::os;
 use sys::mutex::{self, Mutex};
 use sys::sync as ffi;
 use time::Duration;
@@ -46,7 +46,7 @@ pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
                                                0);
         if r == 0 {
             const ERROR_TIMEOUT: DWORD = 0x5B4;
-            debug_assert_eq!(os::errno() as uint, ERROR_TIMEOUT as uint);
+            debug_assert_eq!(os::errno() as usize, ERROR_TIMEOUT as usize);
             false
         } else {
             true
index 1d63da813c9837a201d574cf4bc646fbb320a456..dc820a4ce45d903db48343ce22668b4841b458f1 100644 (file)
@@ -25,6 +25,7 @@
 use sys::os_str::Buf;
 use sys_common::{AsInner, FromInner, AsInnerMut};
 
+#[allow(deprecated)]
 use old_io;
 
 /// Raw HANDLEs.
@@ -52,6 +53,7 @@ fn as_raw_handle(&self) -> Handle {
     }
 }
 
+#[allow(deprecated)]
 impl AsRawHandle for old_io::pipe::PipeStream {
     fn as_raw_handle(&self) -> Handle {
         self.as_inner().handle()
index 46085826e60db09a66c35fe7c3fe2364eb20fa43..6b0f6a78c85e10711da04ec03520dc02752ad044 100644 (file)
@@ -64,6 +64,7 @@ pub mod addrinfo {
 pub unsafe fn close_sock(sock: sock_t) { let _ = libc::closesocket(sock); }
 
 // windows has zero values as errors
+#[allow(deprecated)]
 fn mkerr_winbool(ret: libc::c_int) -> IoResult<()> {
     if ret == 0 {
         Err(last_error())
@@ -72,6 +73,7 @@ fn mkerr_winbool(ret: libc::c_int) -> IoResult<()> {
     }
 }
 
+#[allow(deprecated)]
 pub fn last_error() -> IoError {
     let errno = os::errno() as i32;
     let mut err = decode_error(errno);
@@ -79,6 +81,7 @@ pub fn last_error() -> IoError {
     err
 }
 
+#[allow(deprecated)]
 pub fn last_net_error() -> IoError {
     let errno = unsafe { c::WSAGetLastError() as i32 };
     let mut err = decode_error(errno);
@@ -86,11 +89,13 @@ pub fn last_net_error() -> IoError {
     err
 }
 
+#[allow(deprecated)]
 pub fn last_gai_error(_errno: i32) -> IoError {
     last_net_error()
 }
 
 /// Convert an `errno` value into a high-level error variant and description.
+#[allow(deprecated)]
 pub fn decode_error(errno: i32) -> IoError {
     let (kind, desc) = match errno {
         libc::EOF => (old_io::EndOfFile, "end of file"),
@@ -134,6 +139,7 @@ pub fn decode_error(errno: i32) -> IoError {
     IoError { kind: kind, desc: desc, detail: None }
 }
 
+#[allow(deprecated)]
 pub fn decode_error_detailed(errno: i32) -> IoError {
     let mut err = decode_error(errno);
     err.detail = Some(os::error_string(errno));
@@ -178,11 +184,13 @@ pub fn ms_to_timeval(ms: u64) -> libc::timeval {
     }
 }
 
+#[allow(deprecated)]
 pub fn wouldblock() -> bool {
     let err = os::errno();
     err == libc::WSAEWOULDBLOCK as i32
 }
 
+#[allow(deprecated)]
 pub fn set_nonblocking(fd: sock_t, nb: bool) {
     let mut set = nb as libc::c_ulong;
     if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) } != 0 {
@@ -205,6 +213,7 @@ pub fn init_net() {
     }
 }
 
+#[allow(deprecated)]
 pub fn to_utf16(s: Option<&str>) -> IoResult<Vec<u16>> {
     match s {
         Some(s) => Ok(to_utf16_os(OsStr::from_str(s))),
@@ -283,6 +292,7 @@ fn fill_utf16_buf_base<F1, F2, T>(mut f1: F1, f2: F2) -> Result<T, ()>
     }
 }
 
+#[allow(deprecated)]
 fn fill_utf16_buf<F1, F2, T>(f1: F1, f2: F2) -> IoResult<T>
     where F1: FnMut(*mut u16, libc::DWORD) -> libc::DWORD,
           F2: FnOnce(&[u16]) -> T
index 89cf8a08a68f9448dffb18582f02d8672a68bda8..ecd538abfb4817ba88dd327c0b3675cb871060b0 100644 (file)
@@ -22,6 +22,7 @@
 use libc::types::os::arch::extra::LPWCH;
 use libc::{self, c_int, c_void};
 use mem;
+#[allow(deprecated)]
 use old_io::{IoError, IoResult};
 use ops::Range;
 use path::{self, PathBuf};
@@ -134,7 +135,7 @@ pub fn env() -> Env {
         let ch = GetEnvironmentStringsW();
         if ch as usize == 0 {
             panic!("failure getting env string from OS: {}",
-                   IoError::last_error());
+                   io::Error::last_os_error());
         }
         Env { base: ch, cur: ch }
     }
@@ -269,7 +270,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) {
 
     unsafe {
         if libc::SetEnvironmentVariableW(k.as_ptr(), v.as_ptr()) == 0 {
-            panic!("failed to set env: {}", IoError::last_error());
+            panic!("failed to set env: {}", io::Error::last_os_error());
         }
     }
 }
@@ -278,7 +279,7 @@ pub fn unsetenv(n: &OsStr) {
     let v = super::to_utf16_os(n);
     unsafe {
         if libc::SetEnvironmentVariableW(v.as_ptr(), ptr::null()) == 0 {
-            panic!("failed to unset env: {}", IoError::last_error());
+            panic!("failed to unset env: {}", io::Error::last_os_error());
         }
     }
 }
@@ -333,6 +334,7 @@ pub fn page_size() -> usize {
     }
 }
 
+#[allow(deprecated)]
 pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> {
     // Windows pipes work subtly differently than unix pipes, and their
     // inheritance has to be handled in a different way that I do not
index 1f228b7d32e35042131cefcbce51e8fab742409a..2b03e9e743172a80f9898473d3844a78936c9ae5 100644 (file)
@@ -84,6 +84,8 @@
 //! the test suite passing (the suite is in libstd), and that's good enough for
 //! me!
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 
 use libc;
index 72ce8b7c6e30c5fb1d12c732c48a2ff97f20521a..d1bff0e135dd697aa2c7f2eb1139200ffd7b903c 100644 (file)
@@ -135,6 +135,16 @@ pub fn write(&self, data: &[u8]) -> io::Result<usize> {
     }
 }
 
+// FIXME: right now this raw stderr handle is used in a few places because
+//        std::io::stderr_raw isn't exposed, but once that's exposed this impl
+//        should go away
+impl io::Write for Stderr {
+    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+        Stderr::write(self, data)
+    }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+
 impl NoClose {
     fn new(handle: libc::HANDLE) -> NoClose {
         NoClose(Some(Handle::new(handle)))
index a23a90a9cf8f897b03c281687fe5e46ce44dfbd2..91a7f694181f1e2ef5d34345057f489aa519a7f1 100644 (file)
@@ -20,6 +20,8 @@
 //! Other than that, the implementation is pretty straightforward in terms of
 //! the other two implementations of timers with nothing *that* new showing up.
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 use self::Req::*;
 
index 37dce423a687f6f38118d1ef9c53db40bbf4aacd..f542cb2323ebc4839f7747aabd8c0418c6c9da10 100644 (file)
@@ -25,6 +25,8 @@
 //! wrapper that performs encoding/decoding, this implementation should switch
 //! to working in raw UTF-16, with such a wrapper around it.
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 
 use old_io::{self, IoError, IoResult, MemReader};
index 5c5f9f75fd9dbda818ec949e845869be9e19ee0e..adc3b77407a6121a48952d3321388ffe45473555 100644 (file)
 use fmt;
 use io;
 use marker::PhantomData;
-use old_io::stdio;
 use rt::{self, unwind};
 use sync::{Mutex, Condvar, Arc};
 use thunk::Thunk;
@@ -165,10 +164,6 @@ pub struct Builder {
     name: Option<String>,
     // The size of the stack for the spawned thread
     stack_size: Option<usize>,
-    // Thread-local stdout
-    stdout: Option<Box<Writer + Send + 'static>>,
-    // Thread-local stderr
-    stderr: Option<Box<Writer + Send + 'static>>,
 }
 
 impl Builder {
@@ -179,8 +174,6 @@ pub fn new() -> Builder {
         Builder {
             name: None,
             stack_size: None,
-            stdout: None,
-            stderr: None,
         }
     }
 
@@ -202,16 +195,22 @@ pub fn stack_size(mut self, size: usize) -> Builder {
     /// Redirect thread-local stdout.
     #[unstable(feature = "std_misc",
                reason = "Will likely go away after proc removal")]
-    pub fn stdout(mut self, stdout: Box<Writer + Send + 'static>) -> Builder {
-        self.stdout = Some(stdout);
+    #[deprecated(since = "1.0.0",
+                 reason = "the old I/O module is deprecated and this function \
+                           will be removed with no replacement")]
+    #[allow(deprecated)]
+    pub fn stdout(self, _stdout: Box<Writer + Send + 'static>) -> Builder {
         self
     }
 
     /// Redirect thread-local stderr.
     #[unstable(feature = "std_misc",
                reason = "Will likely go away after proc removal")]
-    pub fn stderr(mut self, stderr: Box<Writer + Send + 'static>) -> Builder {
-        self.stderr = Some(stderr);
+    #[deprecated(since = "1.0.0",
+                 reason = "the old I/O module is deprecated and this function \
+                           will be removed with no replacement")]
+    #[allow(deprecated)]
+    pub fn stderr(self, _stderr: Box<Writer + Send + 'static>) -> Builder {
         self
     }
 
@@ -259,7 +258,7 @@ pub fn scoped<'a, T, F>(self, f: F) -> io::Result<JoinGuard<'a, T>> where
     }
 
     fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> {
-        let Builder { name, stack_size, stdout, stderr } = self;
+        let Builder { name, stack_size } = self;
 
         let stack_size = stack_size.unwrap_or(rt::min_stack());
 
@@ -290,16 +289,6 @@ fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> {
             }
 
             let mut output = None;
-            let f: Thunk<(), T> = if stdout.is_some() || stderr.is_some() {
-                Thunk::new(move || {
-                    let _ = stdout.map(stdio::set_stdout);
-                    let _ = stderr.map(stdio::set_stderr);
-                    f.invoke(())
-                })
-            } else {
-                f
-            };
-
             let try_result = {
                 let ptr = &mut output;
 
@@ -915,20 +904,6 @@ fn test_try_panic_message_unit_struct() {
         }
     }
 
-    #[test]
-    fn test_stdout() {
-        let (tx, rx) = channel();
-        let mut reader = ChanReader::new(rx);
-        let stdout = ChanWriter::new(tx);
-
-        Builder::new().stdout(box stdout as Box<Writer + Send>).scoped(move|| {
-            print!("Hello, world!");
-        }).unwrap().join();
-
-        let output = reader.read_to_string().unwrap();
-        assert_eq!(output, "Hello, world!".to_string());
-    }
-
     #[test]
     fn test_park_timeout_unpark_before() {
         for _ in 0..10 {
index e094cbcac5378a8b3aa59ab8332e13057c12d596..32857769acf4a34ab2a08989981bba8167fd9ed1 100644 (file)
 
 use std::cell::{RefCell, Cell};
 use std::fmt;
-use std::old_io;
-use std::string::String;
+use std::io::prelude::*;
+use std::io;
 use term::WriterWrapper;
 use term;
+use libc;
 
 /// maximum number of lines we will print for each error; arbitrary.
 const MAX_LINES: usize = 6;
@@ -271,7 +272,7 @@ fn color(self) -> term::color::Color {
 
 fn print_maybe_styled(w: &mut EmitterWriter,
                       msg: &str,
-                      color: term::attr::Attr) -> old_io::IoResult<()> {
+                      color: term::attr::Attr) -> io::Result<()> {
     match w.dst {
         Terminal(ref mut t) => {
             try!(t.attr(color));
@@ -289,23 +290,21 @@ fn print_maybe_styled(w: &mut EmitterWriter,
             // to be miscolored. We assume this is rare enough that we don't
             // have to worry about it.
             if msg.ends_with("\n") {
-                try!(t.write_str(&msg[..msg.len()-1]));
+                try!(t.write_all(msg[..msg.len()-1].as_bytes()));
                 try!(t.reset());
-                try!(t.write_str("\n"));
+                try!(t.write_all(b"\n"));
             } else {
-                try!(t.write_str(msg));
+                try!(t.write_all(msg.as_bytes()));
                 try!(t.reset());
             }
             Ok(())
         }
-        Raw(ref mut w) => {
-            w.write_str(msg)
-        }
+        Raw(ref mut w) => w.write_all(msg.as_bytes()),
     }
 }
 
 fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,
-                    msg: &str, code: Option<&str>) -> old_io::IoResult<()> {
+                    msg: &str, code: Option<&str>) -> io::Result<()> {
     if !topic.is_empty() {
         try!(write!(&mut dst.dst, "{} ", topic));
     }
@@ -324,7 +323,7 @@ fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,
         }
         None => ()
     }
-    try!(dst.dst.write_char('\n'));
+    try!(write!(&mut dst.dst, "\n"));
     Ok(())
 }
 
@@ -335,18 +334,18 @@ pub struct EmitterWriter {
 
 enum Destination {
     Terminal(Box<term::Terminal<WriterWrapper> + Send>),
-    Raw(Box<Writer + Send>),
+    Raw(Box<Write + Send>),
 }
 
 impl EmitterWriter {
     pub fn stderr(color_config: ColorConfig,
                   registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
-        let stderr = old_io::stderr();
+        let stderr = io::stderr();
 
         let use_color = match color_config {
             Always => true,
             Never  => false,
-            Auto   => stderr.get_ref().isatty()
+            Auto   => stderr_isatty(),
         };
 
         if use_color {
@@ -360,17 +359,42 @@ pub fn stderr(color_config: ColorConfig,
         }
     }
 
-    pub fn new(dst: Box<Writer + Send>,
+    pub fn new(dst: Box<Write + Send>,
                registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
         EmitterWriter { dst: Raw(dst), registry: registry }
     }
 }
 
-impl Writer for Destination {
-    fn write_all(&mut self, bytes: &[u8]) -> old_io::IoResult<()> {
+#[cfg(unix)]
+fn stderr_isatty() -> bool {
+    unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
+}
+#[cfg(windows)]
+fn stderr_isatty() -> bool {
+    const STD_ERROR_HANDLE: libc::DWORD = -12;
+    extern "system" {
+        fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
+        fn GetConsoleMode(hConsoleHandle: libc::HANDLE,
+                          lpMode: libc::LPDWORD) -> libc::BOOL;
+    }
+    unsafe {
+        let handle = GetStdHandle(STD_ERROR_HANDLE);
+        let mut out = 0;
+        GetConsoleMode(handle, &mut out) != 0
+    }
+}
+
+impl Write for Destination {
+    fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
+        match *self {
+            Terminal(ref mut t) => t.write(bytes),
+            Raw(ref mut w) => w.write(bytes),
+        }
+    }
+    fn flush(&mut self) -> io::Result<()> {
         match *self {
-            Terminal(ref mut t) => t.write_all(bytes),
-            Raw(ref mut w) => w.write_all(bytes),
+            Terminal(ref mut t) => t.flush(),
+            Raw(ref mut w) => w.flush(),
         }
     }
 }
@@ -403,7 +427,7 @@ fn custom_emit(&mut self, cm: &codemap::CodeMap,
 }
 
 fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
-        msg: &str, code: Option<&str>, lvl: Level, custom: bool) -> old_io::IoResult<()> {
+        msg: &str, code: Option<&str>, lvl: Level, custom: bool) -> io::Result<()> {
     let sp = rsp.span();
 
     // We cannot check equality directly with COMMAND_LINE_SP
@@ -451,7 +475,7 @@ fn highlight_lines(err: &mut EmitterWriter,
                    cm: &codemap::CodeMap,
                    sp: Span,
                    lvl: Level,
-                   lines: codemap::FileLines) -> old_io::IoResult<()> {
+                   lines: codemap::FileLines) -> io::Result<()> {
     let fm = &*lines.file;
 
     let mut elided = false;
@@ -560,7 +584,7 @@ fn custom_highlight_lines(w: &mut EmitterWriter,
                           sp: Span,
                           lvl: Level,
                           lines: codemap::FileLines)
-                          -> old_io::IoResult<()> {
+                          -> io::Result<()> {
     let fm = &*lines.file;
 
     let lines = &lines.lines[..];
@@ -617,8 +641,8 @@ fn custom_highlight_lines(w: &mut EmitterWriter,
 fn print_macro_backtrace(w: &mut EmitterWriter,
                          cm: &codemap::CodeMap,
                          sp: Span)
-                         -> old_io::IoResult<()> {
-    let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| -> old_io::IoResult<_> {
+                         -> io::Result<()> {
+    let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| -> io::Result<_> {
         match expn_info {
             Some(ei) => {
                 let ss = ei.callee.span.map_or(String::new(),
index 90f0dc30c75fe4bf829c26becb971d41f5f999bc..f60ac8f3f33b2f4976589555830e46bd9503f925 100644 (file)
@@ -30,7 +30,6 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(int_uint)]
-#![feature(old_io)]
 #![feature(libc)]
 #![feature(old_path)]
 #![feature(quote, unsafe_destructor)]
index f5781e0587d245f7d5c6a404a9d634e97a414c3f..d9887c28e5c4d01ca482199c5dd939199f3163ab 100644 (file)
@@ -1470,11 +1470,11 @@ mod test {
     use diagnostic;
     use parse::token;
     use parse::token::{str_to_ident};
-    use std::old_io::util;
+    use std::io;
 
     fn mk_sh() -> diagnostic::SpanHandler {
         // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
-        let emitter = diagnostic::EmitterWriter::new(Box::new(util::NullWriter), None);
+        let emitter = diagnostic::EmitterWriter::new(Box::new(io::sink()), None);
         let handler = diagnostic::mk_handler(true, Box::new(emitter));
         diagnostic::mk_span_handler(handler, CodeMap::new())
     }
index be467c1f1fb30844c9d490933616f0192ac2bcf2..36225fad2211e4d7b81171b2fcb82d415e03cd8d 100644 (file)
@@ -21,6 +21,8 @@
 //! ```no_run
 //! extern crate term;
 //!
+//! use std::io::prelude::*;
+//!
 //! fn main() {
 //!     let mut t = term::stdout().unwrap();
 //!
@@ -56,7 +58,6 @@
 #![feature(collections)]
 #![feature(int_uint)]
 #![feature(io)]
-#![feature(old_io)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(std_misc)]
 #[cfg(windows)]
 pub use win::WinConsole;
 
-use std::old_io::IoResult;
+use std::io::prelude::*;
+use std::io;
 
 pub mod terminfo;
 
 #[cfg(windows)]
 mod win;
 
-/// A hack to work around the fact that `Box<Writer + Send>` does not
-/// currently implement `Writer`.
+/// A hack to work around the fact that `Box<Write + Send>` does not
+/// currently implement `Write`.
 pub struct WriterWrapper {
-    wrapped: Box<Writer + Send>,
+    wrapped: Box<Write + Send>,
 }
 
-impl Writer for WriterWrapper {
+impl Write for WriterWrapper {
     #[inline]
-    fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
-        self.wrapped.write_all(buf)
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.wrapped.write(buf)
     }
 
     #[inline]
-    fn flush(&mut self) -> IoResult<()> {
+    fn flush(&mut self) -> io::Result<()> {
         self.wrapped.flush()
     }
 }
@@ -99,7 +101,7 @@ fn flush(&mut self) -> IoResult<()> {
 /// opened.
 pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
     TerminfoTerminal::new(WriterWrapper {
-        wrapped: box std::old_io::stdout() as Box<Writer + Send>,
+        wrapped: box std::io::stdout() as Box<Write + Send>,
     })
 }
 
@@ -108,14 +110,14 @@ pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
 /// opened.
 pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
     let ti = TerminfoTerminal::new(WriterWrapper {
-        wrapped: box std::old_io::stdout() as Box<Writer + Send>,
+        wrapped: box std::io::stdout() as Box<Write + Send>,
     });
 
     match ti {
         Some(t) => Some(t),
         None => {
             WinConsole::new(WriterWrapper {
-                wrapped: box std::old_io::stdout() as Box<Writer + Send>,
+                wrapped: box std::io::stdout() as Box<Write + Send>,
             })
         }
     }
@@ -126,7 +128,7 @@ pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
 /// opened.
 pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send>> {
     TerminfoTerminal::new(WriterWrapper {
-        wrapped: box std::old_io::stderr() as Box<Writer + Send>,
+        wrapped: box std::io::stderr() as Box<Write + Send>,
     })
 }
 
@@ -135,14 +137,14 @@ pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send>> {
 /// opened.
 pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send>> {
     let ti = TerminfoTerminal::new(WriterWrapper {
-        wrapped: box std::old_io::stderr() as Box<Writer + Send>,
+        wrapped: box std::io::stderr() as Box<Write + Send>,
     });
 
     match ti {
         Some(t) => Some(t),
         None => {
             WinConsole::new(WriterWrapper {
-                wrapped: box std::old_io::stderr() as Box<Writer + Send>,
+                wrapped: box std::io::stderr() as Box<Write + Send>,
             })
         }
     }
@@ -209,7 +211,7 @@ pub enum Attr {
 
 /// A terminal with similar capabilities to an ANSI Terminal
 /// (foreground/background colors etc).
-pub trait Terminal<T: Writer>: Writer {
+pub trait Terminal<T: Write>: Write {
     /// Sets the foreground color to the given color.
     ///
     /// If the color is a bright color, but the terminal only supports 8 colors,
@@ -217,7 +219,7 @@ pub trait Terminal<T: Writer>: Writer {
     ///
     /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
     /// if there was an I/O error.
-    fn fg(&mut self, color: color::Color) -> IoResult<bool>;
+    fn fg(&mut self, color: color::Color) -> io::Result<bool>;
 
     /// Sets the background color to the given color.
     ///
@@ -226,19 +228,19 @@ pub trait Terminal<T: Writer>: Writer {
     ///
     /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
     /// if there was an I/O error.
-    fn bg(&mut self, color: color::Color) -> IoResult<bool>;
+    fn bg(&mut self, color: color::Color) -> io::Result<bool>;
 
     /// Sets the given terminal attribute, if supported.  Returns `Ok(true)`
     /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
     /// there was an I/O error.
-    fn attr(&mut self, attr: attr::Attr) -> IoResult<bool>;
+    fn attr(&mut self, attr: attr::Attr) -> io::Result<bool>;
 
     /// Returns whether the given terminal attribute is supported.
     fn supports_attr(&self, attr: attr::Attr) -> bool;
 
     /// Resets all terminal attributes and color to the default.
     /// Returns `Ok()`.
-    fn reset(&mut self) -> IoResult<()>;
+    fn reset(&mut self) -> io::Result<()>;
 
     /// Gets an immutable reference to the stream inside
     fn get_ref<'a>(&'a self) -> &'a T;
@@ -248,7 +250,7 @@ pub trait Terminal<T: Writer>: Writer {
 }
 
 /// A terminal which can be unwrapped.
-pub trait UnwrappableTerminal<T: Writer>: Terminal<T> {
+pub trait UnwrappableTerminal<T: Write>: Terminal<T> {
     /// Returns the contained stream, destroying the `Terminal`
     fn unwrap(self) -> T;
 }
index be1c623c8590512c1f699aed09e7bc496039bd57..3c269cc485dad908aec4fda4bb09a50625460ad1 100644 (file)
@@ -11,8 +11,9 @@
 //! Terminfo database interface.
 
 use std::collections::HashMap;
-use std::old_io::IoResult;
 use std::env;
+use std::io::prelude::*;
+use std::io;
 
 use attr;
 use color;
@@ -72,8 +73,8 @@ pub struct TerminfoTerminal<T> {
     ti: Box<TermInfo>
 }
 
-impl<T: Writer+Send+'static> Terminal<T> for TerminfoTerminal<T> {
-    fn fg(&mut self, color: color::Color) -> IoResult<bool> {
+impl<T: Write+Send+'static> Terminal<T> for TerminfoTerminal<T> {
+    fn fg(&mut self, color: color::Color) -> io::Result<bool> {
         let color = self.dim_if_necessary(color);
         if self.num_colors > color {
             let s = expand(self.ti
@@ -90,7 +91,7 @@ fn fg(&mut self, color: color::Color) -> IoResult<bool> {
         Ok(false)
     }
 
-    fn bg(&mut self, color: color::Color) -> IoResult<bool> {
+    fn bg(&mut self, color: color::Color) -> io::Result<bool> {
         let color = self.dim_if_necessary(color);
         if self.num_colors > color {
             let s = expand(self.ti
@@ -107,7 +108,7 @@ fn bg(&mut self, color: color::Color) -> IoResult<bool> {
         Ok(false)
     }
 
-    fn attr(&mut self, attr: attr::Attr) -> IoResult<bool> {
+    fn attr(&mut self, attr: attr::Attr) -> io::Result<bool> {
         match attr {
             attr::ForegroundColor(c) => self.fg(c),
             attr::BackgroundColor(c) => self.bg(c),
@@ -140,7 +141,7 @@ fn supports_attr(&self, attr: attr::Attr) -> bool {
         }
     }
 
-    fn reset(&mut self) -> IoResult<()> {
+    fn reset(&mut self) -> io::Result<()> {
         let mut cap = self.ti.strings.get("sgr0");
         if cap.is_none() {
             // are there any terminals that have color/attrs and not sgr0?
@@ -164,11 +165,11 @@ fn get_ref<'a>(&'a self) -> &'a T { &self.out }
     fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.out }
 }
 
-impl<T: Writer+Send+'static> UnwrappableTerminal<T> for TerminfoTerminal<T> {
+impl<T: Write+Send+'static> UnwrappableTerminal<T> for TerminfoTerminal<T> {
     fn unwrap(self) -> T { self.out }
 }
 
-impl<T: Writer+Send+'static> TerminfoTerminal<T> {
+impl<T: Write+Send+'static> TerminfoTerminal<T> {
     /// Returns `None` whenever the terminal cannot be created for some
     /// reason.
     pub fn new(out: T) -> Option<Box<Terminal<T>+Send+'static>> {
@@ -220,12 +221,12 @@ fn dim_if_necessary(&self, color: color::Color) -> color::Color {
 }
 
 
-impl<T: Writer> Writer for TerminfoTerminal<T> {
-    fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
-        self.out.write_all(buf)
+impl<T: Write> Write for TerminfoTerminal<T> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.out.write(buf)
     }
 
-    fn flush(&mut self) -> IoResult<()> {
+    fn flush(&mut self) -> io::Result<()> {
         self.out.flush()
     }
 }
index e93b956dc7c835eaee3f11af0606a8bcf7437ba2..e29e0e27394db93a3103fc149c9baf424cbf930f 100644 (file)
@@ -14,7 +14,8 @@
 
 extern crate libc;
 
-use std::old_io::IoResult;
+use std::io;
+use std::io::prelude::*;
 
 use attr;
 use color;
@@ -86,7 +87,7 @@ fn bits_to_color(bits: u16) -> color::Color {
     color | (bits & 0x8) // copy the hi-intensity bit
 }
 
-impl<T: Writer+Send+'static> WinConsole<T> {
+impl<T: Write+Send+'static> WinConsole<T> {
     fn apply(&mut self) {
         let _unused = self.buf.flush();
         let mut accum: libc::WORD = 0;
@@ -129,32 +130,32 @@ pub fn new(out: T) -> Option<Box<Terminal<T>+Send+'static>> {
     }
 }
 
-impl<T: Writer> Writer for WinConsole<T> {
-    fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
-        self.buf.write_all(buf)
+impl<T: Write> Write for WinConsole<T> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.buf.write(buf)
     }
 
-    fn flush(&mut self) -> IoResult<()> {
+    fn flush(&mut self) -> io::Result<()> {
         self.buf.flush()
     }
 }
 
-impl<T: Writer+Send+'static> Terminal<T> for WinConsole<T> {
-    fn fg(&mut self, color: color::Color) -> IoResult<bool> {
+impl<T: Write+Send+'static> Terminal<T> for WinConsole<T> {
+    fn fg(&mut self, color: color::Color) -> io::Result<bool> {
         self.foreground = color;
         self.apply();
 
         Ok(true)
     }
 
-    fn bg(&mut self, color: color::Color) -> IoResult<bool> {
+    fn bg(&mut self, color: color::Color) -> io::Result<bool> {
         self.background = color;
         self.apply();
 
         Ok(true)
     }
 
-    fn attr(&mut self, attr: attr::Attr) -> IoResult<bool> {
+    fn attr(&mut self, attr: attr::Attr) -> io::Result<bool> {
         match attr {
             attr::ForegroundColor(f) => {
                 self.foreground = f;
@@ -179,7 +180,7 @@ fn supports_attr(&self, attr: attr::Attr) -> bool {
         }
     }
 
-    fn reset(&mut self) -> IoResult<()> {
+    fn reset(&mut self) -> io::Result<()> {
         self.foreground = self.def_foreground;
         self.background = self.def_background;
         self.apply();
@@ -192,6 +193,6 @@ fn get_ref<'a>(&'a self) -> &'a T { &self.buf }
     fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.buf }
 }
 
-impl<T: Writer+Send+'static> UnwrappableTerminal<T> for WinConsole<T> {
+impl<T: Write+Send+'static> UnwrappableTerminal<T> for WinConsole<T> {
     fn unwrap(self) -> T { self.buf }
 }
index 80d5ab5baf3df2b2eebd49c219a67626984b7768..ca8a60553ab3cf752a1acc9a744d41a3f07cf041 100644 (file)
 #![feature(staged_api)]
 #![feature(std_misc)]
 #![feature(io)]
+#![feature(libc)]
+#![feature(set_panic)]
 
 extern crate getopts;
 extern crate serialize;
 extern crate "serialize" as rustc_serialize;
 extern crate term;
+extern crate libc;
 
 pub use self::TestFn::*;
 pub use self::ColorConfig::*;
 use std::env;
 use std::fmt;
 use std::fs::File;
-use std::io::{self, Write};
+use std::io::prelude::*;
+use std::io;
 use std::iter::repeat;
 use std::num::{Float, Int};
-use std::old_io::stdio::StdWriter;
-use std::old_io::{ChanReader, ChanWriter};
-use std::old_io;
 use std::path::{PathBuf};
 use std::sync::mpsc::{channel, Sender};
+use std::sync::{Arc, Mutex};
 use std::thread;
 use std::thunk::{Thunk, Invoke};
 use std::time::Duration;
@@ -452,23 +454,15 @@ struct ConsoleTestState<T> {
     max_name_len: uint, // number of columns to fill when aligning names
 }
 
-fn new2old(new: io::Error) -> old_io::IoError {
-    old_io::IoError {
-        kind: old_io::OtherIoError,
-        desc: "other error",
-        detail: Some(new.to_string()),
-    }
-}
-
-impl<T: Writer> ConsoleTestState<T> {
+impl<T: Write> ConsoleTestState<T> {
     pub fn new(opts: &TestOpts,
-               _: Option<T>) -> old_io::IoResult<ConsoleTestState<StdWriter>> {
+               _: Option<T>) -> io::Result<ConsoleTestState<io::Stdout>> {
         let log_out = match opts.logfile {
-            Some(ref path) => Some(try!(File::create(path).map_err(new2old))),
+            Some(ref path) => Some(try!(File::create(path))),
             None => None
         };
         let out = match term::stdout() {
-            None => Raw(old_io::stdio::stdout_raw()),
+            None => Raw(io::stdout()),
             Some(t) => Pretty(t)
         };
 
@@ -487,29 +481,29 @@ pub fn new(opts: &TestOpts,
         })
     }
 
-    pub fn write_ok(&mut self) -> old_io::IoResult<()> {
+    pub fn write_ok(&mut self) -> io::Result<()> {
         self.write_pretty("ok", term::color::GREEN)
     }
 
-    pub fn write_failed(&mut self) -> old_io::IoResult<()> {
+    pub fn write_failed(&mut self) -> io::Result<()> {
         self.write_pretty("FAILED", term::color::RED)
     }
 
-    pub fn write_ignored(&mut self) -> old_io::IoResult<()> {
+    pub fn write_ignored(&mut self) -> io::Result<()> {
         self.write_pretty("ignored", term::color::YELLOW)
     }
 
-    pub fn write_metric(&mut self) -> old_io::IoResult<()> {
+    pub fn write_metric(&mut self) -> io::Result<()> {
         self.write_pretty("metric", term::color::CYAN)
     }
 
-    pub fn write_bench(&mut self) -> old_io::IoResult<()> {
+    pub fn write_bench(&mut self) -> io::Result<()> {
         self.write_pretty("bench", term::color::CYAN)
     }
 
     pub fn write_pretty(&mut self,
                         word: &str,
-                        color: term::color::Color) -> old_io::IoResult<()> {
+                        color: term::color::Color) -> io::Result<()> {
         match self.out {
             Pretty(ref mut term) => {
                 if self.use_color {
@@ -528,7 +522,7 @@ pub fn write_pretty(&mut self,
         }
     }
 
-    pub fn write_plain(&mut self, s: &str) -> old_io::IoResult<()> {
+    pub fn write_plain(&mut self, s: &str) -> io::Result<()> {
         match self.out {
             Pretty(ref mut term) => {
                 try!(term.write_all(s.as_bytes()));
@@ -541,19 +535,19 @@ pub fn write_plain(&mut self, s: &str) -> old_io::IoResult<()> {
         }
     }
 
-    pub fn write_run_start(&mut self, len: uint) -> old_io::IoResult<()> {
+    pub fn write_run_start(&mut self, len: uint) -> io::Result<()> {
         self.total = len;
         let noun = if len != 1 { "tests" } else { "test" };
         self.write_plain(&format!("\nrunning {} {}\n", len, noun))
     }
 
     pub fn write_test_start(&mut self, test: &TestDesc,
-                            align: NamePadding) -> old_io::IoResult<()> {
+                            align: NamePadding) -> io::Result<()> {
         let name = test.padded_name(self.max_name_len, align);
         self.write_plain(&format!("test {} ... ", name))
     }
 
-    pub fn write_result(&mut self, result: &TestResult) -> old_io::IoResult<()> {
+    pub fn write_result(&mut self, result: &TestResult) -> io::Result<()> {
         try!(match *result {
             TrOk => self.write_ok(),
             TrFailed => self.write_failed(),
@@ -590,7 +584,7 @@ pub fn write_log(&mut self, test: &TestDesc,
         }
     }
 
-    pub fn write_failures(&mut self) -> old_io::IoResult<()> {
+    pub fn write_failures(&mut self) -> io::Result<()> {
         try!(self.write_plain("\nfailures:\n"));
         let mut failures = Vec::new();
         let mut fail_out = String::new();
@@ -616,7 +610,7 @@ pub fn write_failures(&mut self) -> old_io::IoResult<()> {
         Ok(())
     }
 
-    pub fn write_run_finish(&mut self) -> old_io::IoResult<bool> {
+    pub fn write_run_finish(&mut self) -> io::Result<bool> {
         assert!(self.passed + self.failed + self.ignored + self.measured == self.total);
 
         let success = self.failed == 0;
@@ -652,15 +646,15 @@ pub fn fmt_bench_samples(bs: &BenchSamples) -> String {
 }
 
 // A simple console test runner
-pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn> ) -> old_io::IoResult<bool> {
+pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn> ) -> io::Result<bool> {
 
-    fn callback<T: Writer>(event: &TestEvent,
-                           st: &mut ConsoleTestState<T>) -> old_io::IoResult<()> {
+    fn callback<T: Write>(event: &TestEvent,
+                          st: &mut ConsoleTestState<T>) -> io::Result<()> {
         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, stdout) => {
-                try!(st.write_log(&test, &result).map_err(new2old));
+                try!(st.write_log(&test, &result));
                 try!(st.write_result(&result));
                 match result {
                     TrOk => st.passed += 1,
@@ -694,7 +688,7 @@ fn callback<T: Writer>(event: &TestEvent,
         }
     }
 
-    let mut st = try!(ConsoleTestState::new(opts, None::<StdWriter>));
+    let mut st = try!(ConsoleTestState::new(opts, None::<io::Stdout>));
     fn len_if_padded(t: &TestDescAndFn) -> uint {
         match t.testfn.padding() {
             PadNone => 0,
@@ -753,12 +747,31 @@ fn should_sort_failures_before_printing_them() {
 
 fn use_color(opts: &TestOpts) -> bool {
     match opts.color {
-        AutoColor => get_concurrency() == 1 && old_io::stdout().get_ref().isatty(),
+        AutoColor => get_concurrency() == 1 && stdout_isatty(),
         AlwaysColor => true,
         NeverColor => false,
     }
 }
 
+#[cfg(unix)]
+fn stdout_isatty() -> bool {
+    unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 }
+}
+#[cfg(windows)]
+fn stdout_isatty() -> bool {
+    const STD_OUTPUT_HANDLE: libc::DWORD = -11;
+    extern "system" {
+        fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
+        fn GetConsoleMode(hConsoleHandle: libc::HANDLE,
+                          lpMode: libc::LPDWORD) -> libc::BOOL;
+    }
+    unsafe {
+        let handle = GetStdHandle(STD_OUTPUT_HANDLE);
+        let mut out = 0;
+        GetConsoleMode(handle, &mut out) != 0
+    }
+}
+
 #[derive(Clone)]
 enum TestEvent {
     TeFiltered(Vec<TestDesc> ),
@@ -771,8 +784,8 @@ enum TestEvent {
 
 fn run_tests<F>(opts: &TestOpts,
                 tests: Vec<TestDescAndFn> ,
-                mut callback: F) -> old_io::IoResult<()> where
-    F: FnMut(TestEvent) -> old_io::IoResult<()>,
+                mut callback: F) -> io::Result<()> where
+    F: FnMut(TestEvent) -> io::Result<()>,
 {
     let filtered_tests = filter_tests(opts, tests);
     let filtered_descs = filtered_tests.iter()
@@ -896,29 +909,41 @@ pub fn run_test(opts: &TestOpts,
         return;
     }
 
+    #[allow(deprecated)] // set_stdout
     fn run_test_inner(desc: TestDesc,
                       monitor_ch: Sender<MonitorMsg>,
                       nocapture: bool,
                       testfn: Thunk<'static>) {
+        struct Sink(Arc<Mutex<Vec<u8>>>);
+        impl Write for Sink {
+            fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+                Write::write(&mut *self.0.lock().unwrap(), data)
+            }
+            fn flush(&mut self) -> io::Result<()> { Ok(()) }
+        }
+        impl Writer for Sink {
+            fn write_all(&mut self, data: &[u8]) -> std::old_io::IoResult<()> {
+                Writer::write_all(&mut *self.0.lock().unwrap(), data)
+            }
+        }
+
         thread::spawn(move || {
-            let (tx, rx) = channel();
-            let mut reader = ChanReader::new(rx);
-            let stdout = ChanWriter::new(tx.clone());
-            let stderr = ChanWriter::new(tx);
-            let mut cfg = thread::Builder::new().name(match desc.name {
+            let data = Arc::new(Mutex::new(Vec::new()));
+            let data2 = data.clone();
+            let cfg = thread::Builder::new().name(match desc.name {
                 DynTestName(ref name) => name.clone().to_string(),
                 StaticTestName(name) => name.to_string(),
             });
-            if nocapture {
-                drop((stdout, stderr));
-            } else {
-                cfg = cfg.stdout(box stdout as Box<Writer + Send>);
-                cfg = cfg.stderr(box stderr as Box<Writer + Send>);
-            }
 
-            let result_guard = cfg.spawn(move || { testfn.invoke(()) }).unwrap();
-            let stdout = reader.read_to_end().unwrap().into_iter().collect();
+            let result_guard = cfg.spawn(move || {
+                if !nocapture {
+                    std::old_io::stdio::set_stdout(box Sink(data2.clone()));
+                    io::set_panic(box Sink(data2));
+                }
+                testfn.invoke(())
+            }).unwrap();
             let test_result = calc_result(&desc, result_guard.join());
+            let stdout = data.lock().unwrap().to_vec();
             monitor_ch.send((desc.clone(), test_result, stdout)).unwrap();
         });
     }
index dadea634bf0eef4182e4f3d24957c4d736907842..84d510294efe4906354ca1b6799333d53baf7c67 100644 (file)
@@ -12,8 +12,6 @@
 
 #![feature(core)]
 #![feature(exit_status)]
-#![feature(io)]
-#![feature(old_io)]
 #![feature(rustdoc)]
 #![feature(rustc_private)]
 
index 06595cb0455a31d1bb4cecc50bbd546688bcb952..060297beb758bc37da200710b716e19036b6ac9a 100644 (file)
 //! verbosity support. For now, just a wrapper around stdout/stderr.
 
 use std::env;
-use std::old_io::stdio;
+use std::io;
+use std::io::prelude::*;
 
 pub struct Term {
-    err: Box<Writer + 'static>
+    err: Box<Write + 'static>
 }
 
 impl Term {
     pub fn new() -> Term {
         Term {
-            err: Box::new(stdio::stderr())
+            err: Box::new(io::stderr())
         }
     }
 
     pub fn err(&mut self, msg: &str) {
         // swallow any errors
-        let _ = self.err.write_line(msg);
+        let _ = writeln!(&mut self.err, "{}", msg);
         env::set_exit_status(101);
     }
 }
index 10d694957f57e10101d7eea864cf81af06a458fc..bc907787c7cc014314e051d2418ea10917fb55b9 100644 (file)
 extern crate rbml;
 extern crate serialize;
 
-use std::old_io;
+use std::io::Cursor;
+use std::io::prelude::*;
 use std::fmt;
-use std::old_io::{IoResult, SeekStyle};
 use std::slice;
 
 use serialize::{Encodable, Encoder};
 use serialize::json;
 
 use rbml::writer;
-use rbml::io::SeekableMemWriter;
 
 #[derive(Encodable)]
 struct Foo {
@@ -40,17 +39,17 @@ enum WireProtocol {
     // ...
 }
 
-fn encode_json<T: Encodable>(val: &T, wr: &mut SeekableMemWriter) {
+fn encode_json<T: Encodable>(val: &T, wr: &mut Cursor<Vec<u8>>) {
     write!(wr, "{}", json::as_json(val));
 }
-fn encode_rbml<T: Encodable>(val: &T, wr: &mut SeekableMemWriter) {
+fn encode_rbml<T: Encodable>(val: &T, wr: &mut Cursor<Vec<u8>>) {
     let mut encoder = writer::Encoder::new(wr);
     val.encode(&mut encoder);
 }
 
 pub fn main() {
     let target = Foo{baz: false,};
-    let mut wr = SeekableMemWriter::new();
+    let mut wr = Cursor::new(Vec::new());
     let proto = WireProtocol::JSON;
     match proto {
         WireProtocol::JSON => encode_json(&target, &mut wr),
index 1c263b19dd182cb25cba0ada0777b688aaad37df..3131cda1dbc3aa7a89b72b067191c524c9c58863 100644 (file)
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-use std::sync::mpsc::channel;
-use std::old_io::{ChanReader, ChanWriter};
+use std::io::prelude::*;
+use std::io;
+use std::str;
+use std::sync::{Arc, Mutex};
 use std::thread;
 
-fn main() {
-    let (tx, rx) = channel();
-    let mut reader = ChanReader::new(rx);
-    let stderr = ChanWriter::new(tx);
+struct Sink(Arc<Mutex<Vec<u8>>>);
+impl Write for Sink {
+    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+        Write::write(&mut *self.0.lock().unwrap(), data)
+    }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
 
-    let res = thread::Builder::new().stderr(box stderr as Box<Writer + Send>)
-                                    .spawn(move|| -> () {
+fn main() {
+    let data = Arc::new(Mutex::new(Vec::new()));
+    let sink = Sink(data.clone());
+    let res = thread::Builder::new().spawn(move|| -> () {
+        io::set_panic(Box::new(sink));
         panic!("Hello, world!")
     }).unwrap().join();
     assert!(res.is_err());
 
-    let output = reader.read_to_string().unwrap();
+    let output = data.lock().unwrap();
+    let output = str::from_utf8(&output).unwrap();
     assert!(output.contains("Hello, world!"));
 }