Synopsis edit
- info complete script
Description edit
Returns 1 if script is a complete in the sense that the following things are syntactically complete:- braced words
- quoted words
- command substitutions (brackets)
- array element names
- commands
info complete \\\n # -> 0However, a script ending in just a backslash may be complete:
info complete \\ # -> 1Therefore, when using info complete on a line that has been read from a channel using gets, the \n stripped off by gets should be re-added first. See also issue 1775878.info complete is not a full Tcl syntax checker, and there are some values that it considers complete even though they contain syntax errors. As previously stated, the purpose of info complete is to determine whether enough of the script has been read to parse it as a sequence of complete commands.
Examples edit
- Tool Protocol Language
- uses info complete to parse data that is formatted as a syntactically valid Tcl script.
Not for Validating Lists edit
RS: Could it be that info complete can be used generally to check whether a string can be parsed as a list? I used to use expr {![catch {llength $x}]} for that purpose...The answer: "no". It is possible for a string to be "info complete" but not be a list. To wit:[medranocalvo]: One can use string is list.% set foo "{this is a test}{more stuff}" {this is a test}{more stuff} % llength $foo list element in braces followed by "{more" instead of space % info complete $foo 1
Trailing Backslash edit
AMG: It seems odd to me that info complete doesn't return false when its argument has a trailing backslash (or an odd number of trailing backslashes), since that's normally used to signify that the command is continued onto the next line. An interactive shell relying on info complete likely has to implement its own check for trailing backslashes, e.g.:
[TMH] 2017-10-18: Is there a way to differentiate between a string/list/dict and a anonymous proc you are passing to the apply command? My use case is that Im trying to build a proc where the first parameter is a list and the second parameter is either a string or an anonymous proc. The string version is a shorthand, and will define the anonymous proc for you. Otherwise run the anonymous proc. Trick is that the string isnt a constant, so I cant just say is arg2=="predefined string".AMG: No, because everything is a string. Therefore all lambdas (argument to the [apply] command) are also strings. You can write some heuristic to guess, e.g. lambdas are always two- or three-element lists, but many single-command scripts are as well.
proc complete {script} { expr {[info complete $script] && [regexp {(?:^|[^\\])(?:\\\\)*$} $script]} }Example usage:
# single word info complete a ;# 1 complete a ;# 1 # two words info complete a\ b ;# 1 complete a\ b ;# 1 # unclosed quote info complete \"a ;# 0 complete \"a ;# 0 # closed quote info complete \"a\" ;# 1 complete \"a\" ;# 1 # unclosed brace info complete \{a ;# 0 complete \{a ;# 0 # closed brace info complete \{a\} ;# 1 complete \{a\} ;# 1 # unclosed nested brace info complete \{\{a\} ;# 0 complete \{\{a\} ;# 0 # line ends in double backslash info complete a\\\\ ;# 1 complete a\\\\ ;# 1 # line ends in single backslash info complete a\\ ;# 1 complete a\\ ;# 0DKF: The key is that info complete in those cases sees a backslash at the end of a string which is OK, complete. It's when the backslash is followed by a newline that things are magically different:
puts [info complete "abc\\"] ;# 1 puts [info complete "abc\\\n"] ;# 0 puts [info complete "abc\\\ndef"] ;# 1 puts [info complete "abc\\\n "] ;# 1AMG: Therefore, the desired functionality (for the use case described at the top of this page) can be had simply:
proc complete {script} { info complete $script\n }That's cool. As far as I know, this version of complete gives exactly the same results as the one involving regexp.PYK 2014-04-23: It's also the solution implemented to fix issue 1775878
[TMH] 2017-10-18: Is there a way to differentiate between a string/list/dict and a anonymous proc you are passing to the apply command? My use case is that Im trying to build a proc where the first parameter is a list and the second parameter is either a string or an anonymous proc. The string version is a shorthand, and will define the anonymous proc for you. Otherwise run the anonymous proc. Trick is that the string isnt a constant, so I cant just say is arg2=="predefined string".AMG: No, because everything is a string. Therefore all lambdas (argument to the [apply] command) are also strings. You can write some heuristic to guess, e.g. lambdas are always two- or three-element lists, but many single-command scripts are as well.