if {[info command tcl::gets] eq ""} {rename gets tcl::gets}
# This is the substitute (workaround) which discriminates use cases:
proc gets {chan {varN ""}} {
if {$varN ne ""} {upvar 1 $varN var}
if {$chan ne "stdin"} {
if {$varN ne ""} {
tcl::gets $chan $var ;# return character count
} else {
tcl::gets $chan ;# return the string
}
} else {
set var [gets_window] ;# always return string
}
}
# And now for the minimal dialog window:
proc gets_window {{echo 1}} {
set w [toplevel .[clock clicks]]
wm title $w gets:
pack [entry $w.e -textvar gets_w -width 42]
set ::gets_w ""
raise $w
focus $w.e
bind $w <Return> {set getsw_done 1}
vwait ::getsw_done
destroy $w
if $echo {puts $::gets_w}
set ::gets_w
}Here is a simpler rewrite, all in one proc (and this returns string length if called with a variable name): proc gets {channel {var {}}} {
if {$var ne ""} {upvar 1 $var v}
if {$channel eq "stdin"} {
toplevel .gets
pack [entry .gets.e -width 45]
bind .gets.e <Return> {set gets 1}
set f [focus]
focus .gets.e
vwait ::gets
set res [.gets.e get]
destroy .gets
focus $f
if {$var ne ""} {
set v $res; string length $v
} else {set res}
} else {
uplevel 1 tcl::[info level 0]
}
}RS 2005-02-09: As today's breakfast fun project, here's a variant that uses the Windows/Mac console, tested to work on Win 95 and XP:
if {[info command tcl::gets] eq ""} {rename gets tcl::gets}
proc gets {chan {varN ""}} {
if {$varN ne ""} {upvar 1 $varN var}
if {$chan ne "stdin"} {
if {$varN ne ""} {
tcl::gets $chan $var ;# return character count
} else {
tcl::gets $chan ;# return the string
}
} else {
gets_window
set var [console eval {set ::consolegets}] ;# always return string
}
}
proc gets_window {} {
console show
console eval {
.console insert end \n
.console see end
.console mark set insert end-1c
.console mark set begin end-2c
focus .console
bind .console <Return> {
set consolegets [.console get begin+1c end-1c];break
}
vwait ::consolegets
consoleinterp eval {raise .}
}
}
