Version 1 of tclConfig.sh

Updated 2004-06-17 15:54:50 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.

Update: jenglish has pointed out that this information is definitely either not portable between build machine and installation machine (if they differ, as they often will) or is derivable from info or tcl::pkgconfig

    #! /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]
    }