Version 0 of tclConfig.sh

Updated 2004-06-17 09:31:51 by CMCc

20040617 CMcC: Here's a parser for tclConfig.sh - useful for introspection in things like critcl. tclConfig.sh is emitted as part of the build, capturing useful data about the build.

    #! /usr/bin/env tclsh

    # Some code to parse the tclConfig.sh file into namespace vars
    # in ::tclConfig.  Merely sourcing this file will do all the work

    namespace eval tclConfig {
        namespace eval v {
            variable top ::tclConfig
            variable sect_re "\[\\\[\]\[ \t\]*(\[A-Za-z0-9_\]+)\[ \t\]*\[\\\]\]"
            variable comment_re {^(.*)#.*$}
            variable comment_match {#*}
            variable def_re {[ \t]*([A-Za-z0-9_]+)[ \t]*=[ \t]*(.*)(#.*)?$}
        }

        variable VERSION $::tcl_version
    }

    proc tclConfig::unparse {} {
        set result ""
        foreach var [info vars ::tclConfig::*] {
            append result "[namespace tail $var] = \"[set $var]\"" " "
        }
        return $result
    }

    proc tclConfig::parse {dir} {
        set fd [open [file join $dir tclConfig.sh]]
        namespace eval $v::top {}
        set section ""
        foreach line [split [read $fd] \n] {
            set line [string trim $line " \t"]
            regexp $v::comment_re $line x line
            if {[string match $v::comment_match $line] || ($line eq "")} {
                # comment
                continue
            } elseif {[regexp $v::def_re $line x var val]} {
                # definition
                set val [string trim $val " \t"]
                regsub -all {[$]ENV::([A-Za-z0-9_]+)} $val {$::env(\1)} val
                set val [string trim $val ']
                if {[catch {namespace eval $v::top "set $var \"$val\""}]} {
                    set vars($var) $val
                } elseif {$var eq "TCL_DBGX"} {
                    namespace eval $v::top set DBGX "$val"
                }
            } else {
                error "Can't parse '$line'"
            }
        }

        set change 1
        while {$change && [array size vars]} {
            set change 0
            foreach {var val} [array get vars] {
                if {![catch {
                    namespace eval $v::top "set $var \"$val\""
                } result]} {
                    set change 1
                    unset vars($var)
                }
            }
        }
        foreach {var val} [array get vars] {
            namespace eval $v::top set $var [list $val]
        }
    }

    tclConfig::parse $::tcl_library

    if {[info exists argv0] && ([info script] == $argv0)} {
        puts [tclConfig::unparse]
    }