about summary refs log tree commit diff
path: root/src/libstd/io/stdio.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-15 21:16:04 +0000
committerbors <bors@rust-lang.org>2015-03-15 21:16:04 +0000
commitc62ae87db20cf070c5546f5aa814164d2445ec37 (patch)
treefa8658d0f9c77946d896eb91691f28dc4a25d114 /src/libstd/io/stdio.rs
parent542e2bb3910f8860d49b4b40bcd78d9c74e733ff (diff)
parent6e92f0580b0bfe8433df73a9139eaa72c47258b2 (diff)
downloadrust-c62ae87db20cf070c5546f5aa814164d2445ec37.tar.gz
rust-c62ae87db20cf070c5546f5aa814164d2445ec37.zip
Auto merge of #23206 - nagisa:print-io, r=alexcrichton
r? @alexcrichton or @aturon 

This still needs to somehow figure out how to avoid unstable warnings arising from the use of unstable functions. I tried to use `#[allow_internal_unstable]` but it still spits out warnings as far as I can see. @huonw (I think you implemented it) does `#[allow_internal_unstable]` not work for some reason or am I using it incorrectly?
Diffstat (limited to 'src/libstd/io/stdio.rs')
-rw-r--r--src/libstd/io/stdio.rs52
1 files changed, 47 insertions, 5 deletions
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 0e68be8d9e2..75d047d5c9c 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<Option<Box<Write + Send>>> = {
+        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
@@ -338,15 +346,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)]
@@ -360,3 +368,37 @@ pub fn set_panic(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
         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<Write + Send>) -> Option<Box<Write + Send>> {
+    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);
+    }
+}