##
## Compiler2 - PkgLib -Db
##
## (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
##
## ----------------------------------------------------------
##
namespace eval ::PkgLib::Db {
variable FILE [ file join [ ::PkgLib::COMPILER_HOME ] var pkg DB ]
variable LIST {}
variable KEY {MAJOR MINOR}
variable KEYCHECK {{\d} {\d}}
variable KEYVAL ; ## the key values
variable KEYRESOLV
variable ITEMS [ list \
Desc {n.a.} Author {n.a.} Title {n.a.} Mail {n.a.} \
Street {n.a.} Zip {n.a.} City {n.a.} State {n.a.} \
Country {n.a.} Base {} Force no Index no \
CctCfg no CgiCfg no External {} Arch {}
]
namespace export -clear DbTOK DbPKG DbITEMS DbLIST PkgIsAvailable ResolvTPkgName ResolvDbName
}
proc ::PkgLib::Db::ErrorN { args } {
lappend args {please check your environment}
::StdLib::ErrorN {PKG DB} $args
}
proc ::PkgLib::Db::Open { t } {
variable FILE
if {[ catch { open $FILE $t } FH ]} {
ErrorN "can't open package database [ ::Print::AbsPath $FILE ] -> $t\n$FH"
}
seek $FH 0 start
return $FH
}
##
## ----------------------------------------------------------
##
proc ::PkgLib::Db::Read {} {
variable LIST
variable ITEMS
variable FILE
if {![ file exists $FILE ]} return
set FH [ Open r ]
seek $FH 0 start
while {1} {
gets $FH List
if {[ eof $FH ]} break
set PKG [ lindex $List 0 ]
lappend LIST $PKG
variable INFO_$PKG
array set INFO_$PKG [ concat $ITEMS [ lindex $List 1 ] ]
}
close $FH
}
proc ::PkgLib::Db::Write {} {
variable LIST
set FH [ Open w ]
foreach L [ lsort $LIST ] {
variable INFO_$L
puts $FH [ list $L [ array get INFO_$L ] ]
unset INFO_$L
}
close $FH
unset LIST
}
##
## ----------------------------------------------------------
##
proc ::PkgLib::Db::ResolvTPkgName { NAME } {
variable KEY
variable KEYCHECK
variable KEYVAL
set RET $NAME
::StdLib::Push ERROR ERROR
if {[ catch { ::FileLib::Check { exist readable file } $NAME.tpkg VERSION } File ]} {
ErrorN $NAME $File \
"please check your installation"
}
::StdLib::Pop ERROR
set LVAL [ split [ string trim [ ReadFile $File ] ] ]
if {[ llength $LVAL ] != [ llength $KEY ]} {
ErrorN $NAME $File \
"length mismatch between source \"$LVAL\"" \
"and target \"$KEY\""
}
foreach Key $KEY Check $KEYCHECK VAL $LVAL {
set KEYVAL($Key) $VAL
if {![ regexp $Check $VAL ]} {
ErrorN $NAME "$Key does not match regexp \"$Check\"," \
"in file \"$File\""
}
append RET _ $VAL
}
return $RET
}
proc ::PkgLib::Db::Search { PKG } {
variable LIST
set RET {}
foreach L $LIST {
if {[ string match $PKG $L ]} { lappend RET $L }
}
return $RET
}
proc ::PkgLib::Db::ResolvDbName { PKG } {
variable KEYRESOLV
if {[ info exists KEYRESOLV ]} { return $KEYRESOLV }
set FLAG TOO_LESS
foreach P [ list $PKG $PKG* ] {
set L1 [ Search $P ]
set Len [ llength $L1 ]
if {!$Len} continue
if {$Len == 1} {
set FLAG OK
} else {
set FLAG TOO_MUCH
}
break
}
if { $FLAG == "OK" } {
set KEYRESOLV $L1
return $L1
} elseif { $FLAG == "TOO_MUCH" } {
eval ErrorN {{can't resolve unique package name:}} \
$L1 \
{{please provide more informations}}
} elseif { $FLAG == "TOO_LESS" } {
ErrorN "package \"$PKG\" is not available," \
"use \"cct -a pkg --list\" to get all available packages" \
"or use the format \"NAME_MAJOR_MINOR\" as package name"
}
}
##
## ----------------------------------------------------------
##
proc ::PkgLib::Db::GetKeys {} {
variable KEY
variable KEYVAL
set RET {}
foreach Key $KEY {
lappend RET $Key $KEYVAL($Key)
}
return $RET
}
proc ::PkgLib::Db::PkgIsAvailable { PKG } {
variable LIST
return [ expr {[ lsearch -glob $LIST $PKG ] != -1} ]
}
proc ::PkgLib::Db::PkgPatGet { PKG } {
variable LIST
set RET {}
foreach L $LIST {
if {![ string match $PKG $L ]} continue
lappend RET $L
}
return $RET
}
proc ::PkgLib::Db::Add { PKG } {
global tcl_platform
variable LIST
variable INFO
variable ITEMS
variable INFO_$PKG
set DATE [ list Date [ clock seconds ] User $tcl_platform(user) ]
set Idx [ lsearch -glob $LIST $PKG ]
if { $Idx == -1 } {
lappend LIST $PKG
} else {
set LIST [ lreplace $LIST $Idx $Idx $PKG ]
unset INFO_$PKG
}
array set INFO_$PKG [ concat $DATE $ITEMS ]
}
proc ::PkgLib::Db::Del { PKG } {
variable LIST
variable INFO_$PKG
set IDX [ lsearch -exact $LIST $PKG ]
set LIST [ lreplace $LIST $IDX $IDX ]
unset INFO_$PKG
}
proc ::PkgLib::Db::Info { PKG Cmd Val } {
variable INFO_$PKG
array set INFO_$PKG [ list $Cmd $Val ]
}
##
## -----------------------------------------------------------
## public interface
##
proc ::PkgLib::Db::DbTOK { PKG TOK } {
variable INFO_$PKG
return [ set INFO_${PKG}($TOK) ]
}
proc ::PkgLib::Db::DbPKG { PKG } {
variable LIST
return [ FilterList [lsort $LIST] $PKG ]
}
proc ::PkgLib::Db::DbLIST {} {
variable LIST
return $LIST
}
proc ::PkgLib::Db::DbITEMS { PKG } {
variable ITEMS
variable INFO_$PKG
set RET {}
lappend RET Package $PKG
lappend RET Date [ clock format [ set INFO_${PKG}(Date) ] ]
lappend RET User [ set INFO_${PKG}(User) ]
foreach { I D } $ITEMS {
lappend RET $I [ set INFO_${PKG}($I) ]
}
return $RET
}
##
## -----------------------------------------------------------
## .FILE_LIST interface
##
proc ::PkgLib::Db::Read-FILE_LIST { INSTDIR } {
set DIR [ file dirname $INSTDIR ]
set FILE .[ file tail $INSTDIR ]
set FILE_LIST [ file join $DIR $FILE ]
set RET {}
if {![ file exists $FILE_LIST ]} return
if {[ catch { open $FILE_LIST r } FH ]} {
ErrorN "can't open file database:" \
"\"$FILE_LIST\"" \
"for reading"
}
while {![eof $FH]} {
gets $FH LINE
if {![ string length $LINE ]} continue
lappend RET $LINE
}
if {[ catch { close $FH } ERR ]} {
ErrorN "can't close file database:" \
"\"$FILE_LIST\"" \
}
return $RET
}
proc ::PkgLib::Db::Write-FILE_LIST { INSTDIR Data { Typ w } } {
set DIR [ file dirname $INSTDIR ]
set FILE .[ file tail $INSTDIR ]
set FILE_LIST [ file join $DIR $FILE ]
if {[ catch { open $FILE_LIST $Typ } FH ]} {
ErrorN "can't open file database:" \
"\"$FILE_LIST\"" \
"for writing"
}
foreach D $Data {
puts $FH $D
}
if {[ catch { close $FH } ERR ]} {
ErrorN "can't close file database:" \
"\"$FILE_LIST\"" \
}
}