Version 0 of paren checker

Updated 2003-03-09 18:43:31

This is a little script I Dan Smart use to check that my brackets balance, there are numerous more powerful tools around, but this quickly finds my most common mistake.

 proc K {x y} {set x}

 proc popBack {lst} {
    upvar 1 $lst l
    if {[llength $l]} {
        set r [lindex $l end]
        set l [lreplace [K $l [set l {}]] end end]
    } else {
        error "pop of empty list"
    }
    return $r
 }

 proc main {argv} {
    foreach {oparen cparen osquare csquare obrace cbrace} {
        \( \) \[ \] \{ \}
    } {}

    set script [::ds_utils::file::read $argv]
    set ie [string length $script]
    set ln 1
    set plist [list]
    for {set is 0} {$is < $ie} {incr is} {
        set char [string index $script $is]
        switch -exact -- $char $oparen {
            lappend plist [list $oparen $cparen $ln]
        } $osquare {
            lappend plist [list $osquare $csquare $ln]
        } $obrace {
            lappend plist [list $obrace $cbrace $ln]
        } $cparen - $csquare - $cbrace {
            if {[catch {::ds_utils::list::popBack plist} last]} {
                puts "No matching open for $char on $ln"
            } elseif {![string equal [lindex $last 1] $char]} {
                puts "Mismatched [lindex $last 0]$char open: [lindex $last 2] close: $ln"
                exit 1
            }
        } "\n" {
            incr ln
        }
    }
    if {[llength $plist]} {
        puts "Missing closes for: "
        while {[llength $plist]} {
            set last [::ds_utils::list::popBack plist]
            puts "[lindex $last 0] on line $ln"
        }
    }
 }

 main $argv