Version 5 of cmdSplit

Updated 2010-02-12 05:17:08 by fut

dgp wrote a proc to support parsing of class bodies in an itcl-like, pure Tcl, OO framework into Tcl commands. It handles the "semicolon in a comment" problem.

It returns a list of the commands in a script. The original post is here: [L1 ]

 proc cmdSplit {body} { 
    set commands {} 
    set chunk "" 
    foreach line [split $body "\n"] { 
        append chunk $line 
        if {[info complete "$chunk\n"]} { 
            # $chunk ends in a complete Tcl command, and none of the 
            # newlines within it end a complete Tcl command.  If there 
            # are multiple Tcl commands in $chunk, they must be 
            # separated by semi-colons. 
            set cmd "" 
            foreach part [split $chunk ";"] { 
                append cmd $part 
                if {[info complete "$cmd\n"]} { 
                    set cmd [string trimleft $cmd] 
                    # Drop empty commands and comments 
                    if {![string match {} $cmd] \ 
                            && ![string match \#* $cmd]} { 
                        lappend commands $cmd 
                    } 
                    if {[string match \#* $cmd]} { 
                        set cmd "\#;" 
                    } else { 
                        set cmd "" 
                    } 
                } else { 
                    # No complete command yet. 
                    # Replace semicolon and continue 
                    append cmd ";" 
                } 
            }     
            set chunk "" 
        } else { 
            # No end of command yet.  Put the newline back and continue 
            append chunk "\n" 
        } 
    }
     if {![string match {} [string trimright $chunk]]} { 
        return -code error "Can't parse body into a\ 
                sequence of commands.\n\tIncomplete\ 
                command:\n-----\n$chunk\n-----" 
    } 
    return $commands 
 }

AMG: See also Config file using slave interp for more-or-less the same thing, implemented using a slave interpreter.


Sarnold Here is wordSplit which takes a command and returns its arguments as a list.

proc wordSplit {command} {
        if {![info complete $command]} {error "non complete command"}
        set res ""; # the list of words
        set chunk ""
        foreach word [split $command " "] {
                # testing each word until the word being tested makes the
                # command up to it complete
                # example:
                # set "a b"
                # set -> complete, 1 word
                # set "a -> not complete
                # set "a b" -> complete, 2 words
                append chunk $word
                if {[info complete "$res $chunk"]} {
                        lappend res $chunk
                        set chunk ""
                } else {
                        append chunk " "
                }
        }
        set res
}

fut Tabs are word separators also, so perhaps foreach word split $command " \t".