How to check if stdin is pending in TCL?

2019-05-30 08:42发布

问题:

Consider the following code:

chan configure stdin -blocking false
while { true } {
    chan gets stdin
    if { chan blocked stdin } { break }
}

Here at the last line of the loop chan blocked stdin returns true in either cases: when there is no more input available at stdin, and when there there is some input available at stdin, but it doesn't end with a newline character. I need to distinguish these two cases.

How can I do that?

chan pending input stdin also returns 0 in both cases.


Here is the context where the above code is used.

proc prompt { } { puts -nonewline stdout "MyShell > "; flush stdout }

proc evaluate { } \
{
    chan configure stdin -blocking false
    while { true } {
        # for "stdin -blocking false" "read stdin" acts like "gets stdin"
        set part [chan read stdin 100]
        append command $part
        if { $part eq "" } { break }
    }
    chan configure stdin -blocking true
    # Here I want test if there are pending characters at stdin,
    # and while so, I want to wait for newline character.
    # It should be like this:
    # while { *the required test goes here* } {
    #    append command [chan gets stdin]\n
    # }
    while { ! [info complete $command] } { 
        append command [chan gets stdin]\n
    }
    catch { uplevel #0 $command } got
    if { $got ne "" } {
        puts stderr $got
        flush stderr
    }
    prompt
}

chan event stdin readable evaluate 
prompt
while { true } { update; after 100 }

回答1:

Running an interactive command interpreter with the event loop is quite possible, and is described in some detail on the Tcler's Wiki. However, if you're really just running Tcl commands then you should consider using the commandloop command from the TclX package, as that takes care of the details for you.



标签: buffer tcl stdin