#§
#§ Compiler2 - Config - Values
#§
#§ (C) IPN - Ingenieurbuero fuer Praezisionsnumerik
#§
#§ Dipl.-Ing. Andreas Otto
#§ Ulmenstrasse 3
#§ D-34289 Zierenberg
#§ mailto:aotto@t-online.de
#§ http://tclcompiler.sourceforge.net
#§
#§ Alle Rechte vorbehalten
#§
package require StdLib
package require StackLib
namespace eval ::Config::Values {
namespace import ::Config::Default::*
}
##
## -----------------------------------------------------------------
##
proc ::Config::Values::Create { {Key ROOT} } {
#CUM
variable DATA
variable SDATA
set _DATA {}
foreach SKey [ GetKey $Key ] {
set Grp [ list $Key $SKey ]
switch -exact [ GetAction $Grp ] {
%SLINK% {
::Stack::Push SDATA $SKey:DEFAULT
Create $SKey
::Stack::Pop SDATA
}
%HLINK% {
::Stack::Push SDATA $SKey
Create $SKey
::Stack::Pop SDATA
}
default {
lappend _DATA [ concat $SDATA $SKey ] [ GetDefa $Grp ]
}
}
}
array set DATA $_DATA
::Config::Interp::Alias Env ::Config::Values::Env
::Config::Interp::Alias Debug ::Config::Values::Debug
::Config::Interp::Alias Package ::Config::Values::Package
::Config::Interp::Alias ReadFile ::ReadFile
}
proc ::Config::Values::Delete {} {
variable SDATA {} ; ## the current DATA-VALUE tree as list
variable SDEFA {} ; ## the current DATA-DEFAULT tree as list
variable FKEY ROOT ; ## the current FATHER-KEY
variable DATA ; ## array of data
variable TARGET ; ## array of SLINK data
array unset DATA
array unset TARGET
::Config::Interp::UnAlias Env
::Config::Interp::UnAlias Debug
::Config::Interp::UnAlias Package
}
proc ::Config::Values::Env { Name } {
global env
return $env($Name)
}
proc ::Config::Values::Package { Cmd Pkg } {
set P [ package provide $Pkg ]
if {![ string length $P ]} {
set P [ lindex [ lsort [ package versions $Pkg ] ] end ]
if {![ string length $P ]} {
::StdLib::ErrorN {Config} [ list \
"can't figure out the release number of package \"$Pkg\"" \
"please check your installation" \
]
}
}
if { $Cmd != "major" && $Cmd != "minor" } {
::StdLib::ErrorN {Config} [ list \
"expect \"major\" or \"minor\" as command for \"Package\"" \
]
}
return [ lindex [ split $P . ] [ expr { $Cmd == "major" ? 0 : 1 } ] ]
}
proc ::Config::Values::Debug { Str } {
##CUM
return $Str
}
proc ::Config::Values::Format { Grp Val } {
if {[ string equal $Val {DEFAULT} ]} { return DEFAULT }
switch -exact -- [ GetType $Grp ] {
%FILE% -
%DIR% { return [ ::Config::MkAbs $Val ] }
%REP% { return [ ::Config::MkRep $Val ] }
%SLIST% {
return [ ::Config::MkList $Val ]
}
}
return $Val
}
##
## -----------------------------------------------------------------
##
proc ::Config::Values::Init { {Key ROOT} } {
#CUM
foreach SKey [ GetKey $Key ] {
::Config::Interp::Alias $SKey ::Config::Values::Read $SKey
}
}
proc ::Config::Values::Exit {} {
#CUM
variable FKEY
foreach SKey [ GetKey $FKEY ] {
::Config::Interp::UnAlias $SKey
}
}
proc ::Config::Values::Parse { Key Defa Code } {
variable DATA
variable FKEY
variable SDATA
variable SDEFA
set Grp [ list $FKEY $Key ]
set BT [string equal [ GetAction $Grp ] {%SLINK%}]
## test
if {$BT} {
if {![ string equal $Defa DEFAULT ]} {
variable TARGET
upvar 0 ::Config::Values::TARGET([ concat $SDATA $Key ]) _TARGET
if {![info exists _TARGET] || [lsearch $_TARGET $Defa] == -1} {
lappend _TARGET $Defa
foreach Arg [ GetArgs $Grp ] {
lappend TARGET([ concat $SDATA $Arg ]) $Defa
}
}
}
::Stack::Push SDATA $Key:$Defa
::Stack::Push SDEFA $Key:DEFAULT
} else {
::Stack::Push SDATA $Defa
::Stack::Push SDEFA $Defa
}
## stack in
::Stack::LPush FKEY $Key
## DATA init
if {$BT} {
set _T {}
set L1 [ llength $SDATA ]
foreach {K V} [ array get DATA $SDEFA* ] {
set List [ lrange $K $L1 end ]
if {[ lsearch -glob $List *:DEFAULT ] != -1 } continue
set K [ concat $SDATA $List ]
lappend _T $K $V
}
array set DATA $_T
}
## source the code
Init $Key
Eval $Code
## stack down
::Stack::Pop SDEFA
::Stack::Pop SDATA
::Stack::LPop FKEY
}
##
## -----------------------------------------------------------------
##
proc ::Config::Values::Read { Key args } {
variable FKEY
variable DATA
variable SDATA
## no ROOT group
set Grp [ list $FKEY $Key ]
set NGrp [ concat $SDATA $Key ]
## test on length
set LArgs [ llength $args ]
switch -exact -- [ GetAction $Grp ] {
%SLINK% {
if { $LArgs != 2 } {
::Config::Error "group \"$Grp\" -> \"$args\" only two argument's are supported"
return
}
foreach { A0 A1 } $args break
::Config::Is::Test $Grp $A0 $A1
}
default {
if { $LArgs != 1 } {
::Config::Error "group \"$Grp\" -> \"$args\" only one argument is supported"
return
}
foreach { A0 } $args break
## test on type
::Config::Is::Test $Grp $A0
}
}
## do some modification
switch -exact -- [ GetType $Grp ] {
%BOOL% { set A0 [ string is true $A0 ] }
}
## set the values
switch -exact [ GetAction $Grp ] {
%SLINK% { Parse $Key $A0 $A1 }
%HLINK% { Parse $Key $Key $A0 }
default { array set DATA [ list $NGrp [ Format $Grp $A0 ] ] }
}
}
##
## -----------------------------------------------------------------
##
proc ::Config::Values::Eval { Str } {
variable SDATA
variable FKEY
if {[ catch { ::Config::Interp::Eval $Str } ERR ]} {
::Config::Error "reading group \"$SDATA\" -> $ERR\n only \"[ GetKey $FKEY ]\" are suported"
return
}
}
proc ::Config::Values::Source { File } {
if {![ file readable $File ]} {
::Config::Error "file \"$File\" is not readable"
return
}
if {[ catch { ::Config::Interp::Source $File } ERR ]} {
::Config::Error "reading \"$File\" -> $ERR\n only \"[ GetKey ROOT ]\" is suported"
return
}
}
##
## -----------------------------------------------------------------
##
proc ::Config::Values::Test {} {
variable DATA
if {![ string equal $DATA(CCT_VERSION) [ package require Config ] ]} {
::Config::NError \
"expect version \"[ package require Config ]\" but got \"$DATA(CCT_VERSION)\"" \
"please delete your \".project.config\""
}
foreach {K V} [ array get DATA ] {
if {[ string match DEFAULT* $K ]} continue
if {[ string equal $V %NULL% ]} {
::Config::Error "group \"$K\" not defined"
return
}
}
}
##
## -----------------------------------------------------------------
##
proc ::Config::Values::FWrite { TFile } {
variable DATA
variable TARGET
if {[ catch { open $TFile w } FH ]} {
::Config::Error "can't open file \"$TFile\" for writing"
}
puts $FH "DATA [ array get DATA ]"
puts $FH "TARGET [ array get TARGET ]"
close $FH
}
proc ::Config::Values::FRead { TFile } {
::Config::Interp::Alias DATA ::Config::Values::FParse DATA
::Config::Interp::Alias TARGET ::Config::Values::FParse TARGET
Source $TFile
::Config::Interp::UnAlias DATA
::Config::Interp::UnAlias TARGET
}
proc ::Config::Values::FParse { Var args } {
variable $Var
array set $Var $args
}