From 6e92f0580b0bfe8433df73a9139eaa72c47258b2 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Mon, 9 Mar 2015 00:30:15 +0200 Subject: [PATCH] Use new io in print and println macroses --- src/librustc_driver/lib.rs | 2 +- src/librustdoc/lib.rs | 2 +- src/libstd/io/mod.rs | 4 +-- src/libstd/io/stdio.rs | 52 ++++++++++++++++++++++++++++++++++---- src/libstd/macros.rs | 15 ++++++----- src/libstd/old_io/stdio.rs | 14 ---------- src/libtest/lib.rs | 11 ++------ src/libtest/stats.rs | 19 -------------- 8 files changed, 62 insertions(+), 57 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index e0261606ef1..e132e9833c1 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -37,7 +37,7 @@ #![feature(staged_api)] #![feature(exit_status)] #![feature(io)] -#![feature(set_panic)] +#![feature(set_stdio)] extern crate arena; extern crate flate; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 152b6f5c80a..bd4177861dd 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -26,7 +26,7 @@ #![feature(core)] #![feature(exit_status)] #![feature(int_uint)] -#![feature(set_panic)] +#![feature(set_stdio)] #![feature(libc)] #![feature(old_path)] #![feature(rustc_private)] diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 3fddaaad807..aadc2dc83af 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -37,10 +37,10 @@ pub use self::buffered::IntoInnerError; pub use self::cursor::Cursor; pub use self::error::{Result, Error, ErrorKind}; 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::{stdin, stdout, stderr, _print, Stdin, Stdout, Stderr}; pub use self::stdio::{StdoutLock, StderrLock, StdinLock}; #[doc(no_inline, hidden)] -pub use self::stdio::set_panic; +pub use self::stdio::{set_panic, set_print}; #[macro_use] mod lazy; diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 3b4e396953d..fed58ed4b64 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -11,6 +11,7 @@ use prelude::v1::*; use io::prelude::*; +use cell::RefCell; use cmp; use fmt; use io::lazy::Lazy; @@ -18,6 +19,13 @@ use io::{self, BufReader, LineWriter}; use sync::{Arc, Mutex, MutexGuard}; use sys::stdio; +/// Stdout used by print! and println! macroses +thread_local! { + static LOCAL_STDOUT: RefCell>> = { + RefCell::new(None) + } +} + /// A handle to a raw instance of the standard input stream of this process. /// /// This handle is not synchronized or buffered in any fashion. Constructed via @@ -347,15 +355,15 @@ impl<'a> Write for StderrLock<'a> { fn flush(&mut self) -> io::Result<()> { self.inner.flush() } } -/// Resets the task-local stdout handle to the specified writer +/// Resets the task-local stderr 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 will replace the current task's stderr handle, returning the old +/// handle. All future calls to `panic!` 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", +/// output handle is to the process's stderr stream. +#[unstable(feature = "set_stdio", reason = "this function may disappear completely or be replaced \ with a more general mechanism")] #[doc(hidden)] @@ -369,3 +377,37 @@ pub fn set_panic(sink: Box) -> Option> { Some(s) }) } + +/// 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_stdio", + reason = "this function may disappear completely or be replaced \ + with a more general mechanism")] +#[doc(hidden)] +pub fn set_print(sink: Box) -> Option> { + use mem; + LOCAL_STDOUT.with(move |slot| { + mem::replace(&mut *slot.borrow_mut(), Some(sink)) + }).and_then(|mut s| { + let _ = s.flush(); + Some(s) + }) +} + +#[unstable(feature = "print", + reason = "implementation detail which may disappear or be replaced at any time")] +#[doc(hidden)] +pub fn _print(args: fmt::Arguments) { + if let Err(e) = LOCAL_STDOUT.with(|s| match s.borrow_mut().as_mut() { + Some(w) => w.write_fmt(args), + None => stdout().write_fmt(args) + }) { + panic!("failed printing to stdout: {}", e); + } +} diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index a5022943267..7378f43f757 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -60,19 +60,21 @@ macro_rules! panic { }); } +/// Macro for printing to the standard output. +/// /// Equivalent to the `println!` macro except that a newline is not printed at /// the end of the message. #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] +#[allow_internal_unstable] macro_rules! print { - ($($arg:tt)*) => ($crate::old_io::stdio::print_args(format_args!($($arg)*))) + ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*))); } -/// Macro for printing to a task's stdout handle. +/// Macro for printing to the standard output. /// -/// Each task can override its stdout handle via `std::old_io::stdio::set_stdout`. -/// The syntax of this macro is the same as that used for `format!`. For more -/// information, see `std::fmt` and `std::old_io::stdio`. +/// Use the `format!` syntax to write data to the standard output. +/// See `std::fmt` for more information. /// /// # Examples /// @@ -83,7 +85,8 @@ macro_rules! print { #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] macro_rules! println { - ($($arg:tt)*) => ($crate::old_io::stdio::println_args(format_args!($($arg)*))) + ($fmt:expr) => (print!(concat!($fmt, "\n"))); + ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); } /// Helper macro for unwrapping `Result` values while returning early with an diff --git a/src/libstd/old_io/stdio.rs b/src/libstd/old_io/stdio.rs index 34b4ec94a44..dcc34505730 100644 --- a/src/libstd/old_io/stdio.rs +++ b/src/libstd/old_io/stdio.rs @@ -535,18 +535,4 @@ mod tests { stdout(); stderr(); } - - #[test] - fn capture_stdout() { - use old_io::{ChanReader, ChanWriter}; - - 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_stdout(Box::new(w)); - println!("hello!"); - }); - assert_eq!(r.read_to_string().unwrap(), "hello!\n"); - } } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index ca8a60553ab..1f6341f4955 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -39,13 +39,12 @@ #![feature(collections)] #![feature(core)] #![feature(int_uint)] -#![feature(old_io)] #![feature(rustc_private)] #![feature(staged_api)] #![feature(std_misc)] #![feature(io)] #![feature(libc)] -#![feature(set_panic)] +#![feature(set_stdio)] extern crate getopts; extern crate serialize; @@ -909,7 +908,6 @@ pub fn run_test(opts: &TestOpts, return; } - #[allow(deprecated)] // set_stdout fn run_test_inner(desc: TestDesc, monitor_ch: Sender, nocapture: bool, @@ -921,11 +919,6 @@ pub fn run_test(opts: &TestOpts, } 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 data = Arc::new(Mutex::new(Vec::new())); @@ -937,7 +930,7 @@ pub fn run_test(opts: &TestOpts, let result_guard = cfg.spawn(move || { if !nocapture { - std::old_io::stdio::set_stdout(box Sink(data2.clone())); + io::set_print(box Sink(data2.clone())); io::set_panic(box Sink(data2)); } testfn.invoke(()) diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 42812e1e597..84d86c5746c 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -11,9 +11,6 @@ #![allow(missing_docs)] use std::cmp::Ordering::{self, Less, Greater, Equal}; -use std::collections::hash_map::Entry::{Occupied, Vacant}; -use std::collections::hash_map; -use std::hash::Hash; use std::mem; use std::num::{Float, FromPrimitive}; @@ -330,22 +327,6 @@ pub fn winsorize(samples: &mut [T], pct: T) { } } -/// Returns a HashMap with the number of occurrences of every element in the -/// sequence that the iterator exposes. -#[cfg(not(stage0))] -pub fn freq_count(iter: T) -> hash_map::HashMap - where T: Iterator, U: Eq + Clone + Hash -{ - let mut map: hash_map::HashMap = hash_map::HashMap::new(); - for elem in iter { - match map.entry(elem) { - Occupied(mut entry) => { *entry.get_mut() += 1; }, - Vacant(entry) => { entry.insert(1); }, - } - } - map -} - // Test vectors generated from R, using the script src/etc/stat-test-vectors.r. #[cfg(test)]