From d0b901bb69bc38443ef97ad4bf17604d1a50c890 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Mon, 22 Aug 2016 04:45:30 -0500 Subject: [PATCH] Add do-block support for redirect_std[out,err,in] Fixes #7022. In particular, these simplify testing for warnings. --- base/docs/helpdb/Base.jl | 33 ------------------- base/stream.jl | 68 +++++++++++++++++++++++++++++++++++++++ doc/stdlib/io-network.rst | 18 +++++++++++ test/show.jl | 28 +++++++++++++++- 4 files changed, 113 insertions(+), 34 deletions(-) diff --git a/base/docs/helpdb/Base.jl b/base/docs/helpdb/Base.jl index f02519fb3f317..b1e51b084e6d2 100644 --- a/base/docs/helpdb/Base.jl +++ b/base/docs/helpdb/Base.jl @@ -3936,14 +3936,6 @@ Convert `x` from degrees to radians. """ deg2rad -""" - redirect_stdin([stream]) - -Like redirect_stdout, but for STDIN. Note that the order of the return tuple is still -(rd,wr), i.e. data to be read from STDIN, may be written to wr. -""" -redirect_stdin - """ mktemp([parent=tempdir()]) @@ -5196,13 +5188,6 @@ The result of an expression is too large for the specified type and will cause a """ OverflowError -""" - redirect_stderr([stream]) - -Like `redirect_stdout`, but for `STDERR`. -""" -redirect_stderr - """ ctranspose!(dest,src) @@ -6759,24 +6744,6 @@ General unescaping of traditional C and Unicode escape sequences. Reverse of """ unescape_string(s) -""" - redirect_stdout() - -Create a pipe to which all C and Julia level `STDOUT` output will be redirected. Returns a -tuple `(rd,wr)` representing the pipe ends. Data written to `STDOUT` may now be read from -the rd end of the pipe. The wr end is given for convenience in case the old `STDOUT` object -was cached by the user and needs to be replaced elsewhere. -""" -redirect_stdout - -""" - redirect_stdout(stream) - -Replace `STDOUT` by stream for all C and Julia level output to `STDOUT`. Note that `stream` -must be a TTY, a `Pipe` or a `TCPSocket`. -""" -redirect_stdout(stream) - """ print_with_color(color::Symbol, [io], strings...) diff --git a/base/stream.jl b/base/stream.jl index d57180fe7badb..f42af7b82c2ec 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -955,6 +955,74 @@ for (x, writable, unix_fd, c_symbol) in end end +""" + redirect_stdout() + +Create a pipe to which all C and Julia level `STDOUT` output will be redirected. Returns a +tuple `(rd,wr)` representing the pipe ends. Data written to `STDOUT` may now be read from +the rd end of the pipe. The wr end is given for convenience in case the old `STDOUT` object +was cached by the user and needs to be replaced elsewhere. +""" +redirect_stdout + +""" + redirect_stdout(stream) + +Replace `STDOUT` by stream for all C and Julia level output to `STDOUT`. Note that `stream` +must be a TTY, a `Pipe` or a `TCPSocket`. +""" +redirect_stdout(stream) + +""" + redirect_stderr([stream]) + +Like `redirect_stdout`, but for `STDERR`. +""" +redirect_stderr + +""" + redirect_stdin([stream]) + +Like redirect_stdout, but for STDIN. Note that the order of the return tuple is still +(rd,wr), i.e. data to be read from STDIN, may be written to wr. +""" +redirect_stdin + +for (F,S) in ((:redirect_stdin, :STDIN), (:redirect_stdout, :STDOUT), (:redirect_stderr, :STDERR)) + @eval function $F(f::Function, stream) + STDOLD = $S + local ret + $F(stream) + try + ret = f() + finally + $F(STDOLD) + end + ret + end +end + +""" + redirect_stdout(f::Function, stream) + +Run the function `f` while redirecting `STDOUT` to `stream`. Upon completion, `STDOUT` is restored to its prior setting. +""" +redirect_stdout(f::Function, stream) + +""" + redirect_stderr(f::Function, stream) + +Run the function `f` while redirecting `STDERR` to `stream`. Upon completion, `STDERR` is restored to its prior setting. +""" +redirect_stderr(f::Function, stream) + +""" + redirect_stdin(f::Function, stream) + +Run the function `f` while redirecting `STDIN` to `stream`. Upon completion, `STDIN` is restored to its prior setting. +""" +redirect_stdin(f::Function, stream) + mark(x::LibuvStream) = mark(x.buffer) unmark(x::LibuvStream) = unmark(x.buffer) reset(x::LibuvStream) = reset(x.buffer) diff --git a/doc/stdlib/io-network.rst b/doc/stdlib/io-network.rst index 67a1b123c57b6..b78e2d1e22b17 100644 --- a/doc/stdlib/io-network.rst +++ b/doc/stdlib/io-network.rst @@ -350,18 +350,36 @@ General I/O Replace ``STDOUT`` by stream for all C and Julia level output to ``STDOUT``\ . Note that ``stream`` must be a TTY, a ``Pipe`` or a ``TCPSocket``\ . +.. function:: redirect_stdout(f::Function, stream) + + .. Docstring generated from Julia source + + Run the function ``f`` while redirecting ``STDOUT`` to ``stream``\ . Upon completion, ``STDOUT`` is restored to its prior setting. + .. function:: redirect_stderr([stream]) .. Docstring generated from Julia source Like ``redirect_stdout``\ , but for ``STDERR``\ . +.. function:: redirect_stderr(f::Function, stream) + + .. Docstring generated from Julia source + + Run the function ``f`` while redirecting ``STDERR`` to ``stream``\ . Upon completion, ``STDERR`` is restored to its prior setting. + .. function:: redirect_stdin([stream]) .. Docstring generated from Julia source Like redirect_stdout, but for STDIN. Note that the order of the return tuple is still (rd,wr), i.e. data to be read from STDIN, may be written to wr. +.. function:: redirect_stdin(f::Function, stream) + + .. Docstring generated from Julia source + + Run the function ``f`` while redirecting ``STDIN`` to ``stream``\ . Upon completion, ``STDIN`` is restored to its prior setting. + .. function:: readchomp(x) .. Docstring generated from Julia source diff --git a/test/show.jl b/test/show.jl index 2d185d76fb379..d839f7ce8933c 100644 --- a/test/show.jl +++ b/test/show.jl @@ -318,6 +318,32 @@ let oldout = STDOUT, olderr = STDERR end end +let filename = tempname() + ret = open(filename, "w") do f + redirect_stdout(f) do + println("hello") + [1,3] + end + end + @test ret == [1,3] + @test chomp(readstring(filename)) == "hello" + ret = open(filename, "w") do f + redirect_stderr(f) do + warn("hello") + [2] + end + end + @test ret == [2] + @test contains(readstring(filename), "WARNING: hello") + ret = open(filename) do f + redirect_stdin(f) do + readline() + end + end + @test contains(ret, "WARNING: hello") + rm(filename) +end + # issue #12960 type T12960 end let @@ -576,4 +602,4 @@ end # Test compact printing of homogeneous tuples @test repr(NTuple{7,Int64}) == "NTuple{7,Int64}" @test repr(Tuple{Float64, Float64, Float64, Float64}) == "NTuple{4,Float64}" -@test repr(Tuple{Float32, Float32, Float32}) == "Tuple{Float32,Float32,Float32}" \ No newline at end of file +@test repr(Tuple{Float32, Float32, Float32}) == "Tuple{Float32,Float32,Float32}"