Version 3 of Read both a file and stdin

Updated 2002-04-20 17:01:40

When you start tclsh or wish (on Unix and perhaps a few other platforms) without a filename, you will get a prompt so you can interact with Tcl. (For wish on Windows, use console show instead). If you start them with a filename, that script is executed, but the interactive prompt does not appear.

What if you want both? Donald Porter presented this solution on the comp.lang.tcl newsgroup:

 set cmd ""
 while 1 {
    if { "$cmd" != "" } {
            # Why "format catch"?  It "is a legacy workaround
            #     for an old bytcode compiler bug."  We should
            #     find out when it's fixed, and "package require
            #     Tcl ..." appropriately.
        catch {[format catch] $::tcl_prompt2}
    } else {
        if {[catch {[format catch] $::tcl_prompt1}]} {
          puts -nonewline "% "
        }
    }
    flush stdout
    append cmd \n[gets stdin]
    if [ info complete $cmd ] {
        catch $cmd res
        puts $res
        set cmd ""
    }
 }

Other improvements that could still be made:

  • avoid using global variables cmd and res
  • properly handle scripts that return codes other than 0 (TCL_OK) or 1 (TCL_ERROR) (for example, [break])

Note that the code above is best understood as an improvement on the implementation developed in this Usenet thread: http://groups.google.com/groups?ic=1&th=8a12011a1057f516&seekd=931300072

Benjamin Riefenstahl: That URL doesn't seem to work. Did you mean http://groups.google.com/groups?hl=en&th=79c056a40deb476d&rnum=4 ?

Given the original problem description, the right solution in wish is [console show]. With a little hacking you can have a console for Unix, or better yet, make use of TkCon [L1 ].

For tclsh only, no console widget is available, so then I would go ahead and use [vwait forever] to get an event loop going and use [fileevent stdin readable] to collect and evaluate interactive commands from stdin rather than the [while] loop above.

DGP


Arts and crafts of Tcl-Tk programming