Richard Suchenwirth 2007-02-15 - A colleague wanted a way to capture
stdout of a Tcl process temporarily redirected into a variable. Here's my solution, another
puts workaround done by briefly
overloading
puts, and restoring it afterwards:
proc getputs body {
variable putsbuffer ""
if {[info commands puts_] eq ""} {
rename puts puts_
}
proc puts args {
set str [lindex $args end]
set arg1 [lindex $args 0]
set nonew [string equal $arg1 -nonewline]
switch -glob [llength $args],$nonew {
1,* {set chan stdout; append str \n}
2,0 {set chan $arg1; append str \n}
2,1 {set chan stdout}
3,1 {set chan [lindex $args 1]}
default {
error {wrong \# args: should be "puts ?-nonewline? ?channelId? string"}
}
}
if {$chan ne "stdout"} {
puts_ -nonewline $chan $str
} else {append ::putsbuffer $str}
return
}
set code [catch {uplevel 1 $body} res]
if {$code} {append putsbuffer $code:$res}
rename puts {}
rename puts_ puts
return -code $code $putsbuffer
}
#--- Testing:
puts before
set var [getputs {
puts -nonewline hello,
puts world
puts stdout inside!
puts stderr stderr...
#expr 1/0
}]
puts after:[string toupper $var]
which shows on stdout:
before
stderr...
after:HELLO,WORLD
INSIDE!