home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 1998 October
/
PCWorld_1998-10_cd.bin
/
software
/
prehled
/
komix
/
DATA.Z
/
procs.tcl
< prev
next >
Wrap
Text File
|
1997-09-26
|
17KB
|
657 lines
#---------------------------------------------------------------------------
#
# (c) Cayenne Software Inc. 1997
#
# File: @(#)procs.tcl /main/titanic/39
# Author: voyager
# Description:
#---------------------------------------------------------------------------
# SccsId = @(#)procs.tcl /main/titanic/39 26 Sep 1997 Copyright 1995 Westmount Technology
proc isReadOnly {obj} {
return [expr {[$obj readOnly] != 0}]
}
proc isOneLevel {obj} {
return [expr {[$obj oneLevel] != 0}]
}
# Execute $script while showing a busy cursor. Catch errors in $script,
# execute $epilog and either return or reraise the error if one occurred.
# $script (not $epilog) may contain 'break' or 'return' to jump out of the
# busy script. In those cases $epilog is still evaluated.
#
# We assume the following values for Tcl constants:
# TCL_OK 0
# TCL_ERROR 1
# TCL_RETURN 2
# TCL_BREAK 3
# TCL_CONTINUE 4
#
proc busy {script {epilog {}}} {
.main busy 1
set error 0
set retCode [catch {uplevel 1 $script} errMsg]
case $retCode in {
{1 4} {
set savedInfo $errorInfo
set savedCode $errorCode
set error 1
}
{3} {
set retCode 0
}}
if [catch {uplevel 1 $epilog} epilogMsg] {
if $error {
set errMsg "$epilogMsg\n$errMsg"
set savedInfo \
"$epilogMsg\nwhile recovering from\n$savedInfo"
} else {
set errMsg $epilogMsg
set savedInfo $errorInfo
set savedCode $errorCode
set error 1
}
}
.main busy 0
if $error {
error $errMsg $savedInfo $savedCode
}
return -code $retCode
}
proc blockOutput {script {epilog {}}} {
[.main editorArea] blockOutput
set error 0
set retCode [catch {uplevel 1 $script} errMsg]
case $retCode in {
{1 4} {
set savedInfo $errorInfo
set savedCode $errorCode
set error 1
}
{3} {
set retCode 0
}}
if [catch {uplevel 1 $epilog} epilogMsg] {
if $error {
set errMsg "$epilogMsg\n$errMsg"
set savedInfo \
"$epilogMsg\nwhile recovering from\n$savedInfo"
} else {
set errMsg $epilogMsg
set savedInfo $errorInfo
set savedCode $errorCode
set error 1
}
}
[.main editorArea] enableOutput
[.main editorArea] redraw
if $error {
error $errMsg $savedInfo $savedCode
}
return -code $retCode
}
proc interface {class name spec} {
set parent [getParent $name]
if { $parent != ""} {
if ![isCommand $parent] {
puts "parent $parent does not exist"
return ""
}
} else {
return ""
}
$class new $name
while {![lempty $spec]} {
set key [lvarpop spec]
if [isCommand $key] {
interface $key $name.[lvarpop spec] [lvarpop spec]
} else {
$name $key [lvarpop spec]
}
}
return $name
}
proc getParent { child } {
set parent ""
set index [string last "." $child]
if {$index != -1} {
incr index -1
set parent [string range $child 0 $index]
}
return $parent
}
# Return 1 when 'child' is within the tree with root 'parent'
#
proc inTree {child parent} {
if {(! [strncmp $child $parent]) &&
([string length $child] >= [string length $parent])} {
return 1
}
return 0
}
# Copy a file
#
proc copy_text_file {from to} {
set max 8092
set in [open $from r]
set out [open $to w]
while {[set result [read $in $max]] != ""} {
puts $out $result nonewline
}
close $in
close $out
}
# Return the maximum lengths of a set of lists in a list
#
proc maxLengthList {args} {
set arrayList [lindex $args 0]
set maxLengthList [lindex $args 1]
set lengthList {}
set count [llength [lindex $arrayList 0]]
for {set i [llength $maxLengthList]} {$i < $count} {incr i 1} {
lappend maxLengthList 0
}
for {set i 0} {$i < $count} {incr i 1} {
lappend lengthList 0
}
foreach array $arrayList {
for {set i 0} {$i < $count} {incr i 1} {
set len [string length [lindex $array $i]]
set maxLen [lindex $maxLengthList $i]
if {$maxLen && ($len > $maxLen)} {
set len $maxLen
}
if {$len > [lindex $lengthList $i]} {
set lengthList [lreplace $lengthList $i $i $len]
}
}
}
return $lengthList
}
# Return the context of a M4 variable
#
proc context {m4var} {
set index [string last "__" $m4var]
if {$index <= 0} {
return ""
}
return [string range $m4var [expr $index + 2] end]
}
# Cleanup the given directory
proc cleanDir {dir} {
# No tilde substitution!
set pattern [path_name concat $dir "*"]
if {! [catch {set files [otglob $pattern]}]} {
foreach file $files {
unlink $file
}
}
rmdir $dir
}
# return the type of the item referred by a file with the specified type
proc file2itemtype {type} {
case $type in {
{cad ccd ucd} {return cl}
{dfd mgd std} {return pe}
{etd} {return et}
{cod} {return ce}
}
}
global file2HasScopePhase
set file2HasScopePhase(cad) 1
set file2HasScopePhase(ccd) 1
set file2HasScopePhase(cod) 1
set file2HasScopePhase(dfd) 0
set file2HasScopePhase(etd) 1
set file2HasScopePhase(mgd) 0
set file2HasScopePhase(std) 1
set file2HasScopePhase(ucd) 1
proc fileHasScopePhase {type} {
global file2HasScopePhase
return $file2HasScopePhase($type)
}
# split file <name>.<type> into <name> and <type>
proc splitFileName {file {splitter .}} {
set dot [string last "$splitter" "$file"]
set len [string length "$file"]
if {$dot < 0} {
set name $file
} elseif {$dot == 0} {
set name ""
} else {
set name [string range $file 0 [expr $dot - 1]]
}
if {($dot < 0) || ($dot == [expr $len - 1])} {
set type ""
} else {
set type [string range $file [expr $dot + 1] end]
}
return [list "$name" "$type"]
}
# Initialize table for conversion from repository object to browser object
proc initRepObj2UiObjTable {} {
return {
ConfigVersion ConfVDbObj
Corporate CorpDbObj
CustomFiles HCustFUiObj
CustomFileVersion CustFVDbObj
CustomFileVersions CustFVUiObj
ExternalFile ExtFUiObj
ExternalFileVersion ExtFVDbObj
ExternalLink ExtLDbObj
Graph GraphVDbObj
Matrix MtrxVDbObj
None NoneUiObj
PhaseVersion PhaseVDbObj
SystemVersion SSysVDbObj
UserCustomFiles UCustFUiObj
WorkItem WItemDbObj
WorkItems WItemUiObj
}
}
# perform garbage-collection and display results
proc garbageCollection {} {
puts "========================================================"
puts "GC: GARBAGE COLLECTION"
GCControl collect
puts "GC: nrOfCollections = '[GCControl nrOfCollections]'"
puts "GC: totalCollectTime = '[GCControl totalCollectTime]'"
puts "GC: totalDestructTime = '[GCControl totalDestructTime]'"
puts "GC: totalNrOfCollected = '[GCControl totalNrOfCollected]'"
puts "GC: lastCollectTime = '[GCControl lastCollectTime]'"
puts "GC: lastDestructTime = '[GCControl lastDestructTime]'"
puts "GC: lastNrOfCollected = '[GCControl lastNrOfCollected]'"
puts "========================================================"
}
# Remove white space from 's'
#
proc rmWhiteSpace {s} {
regsub -all "\[ \t\n\]" $s {} s
return $s
}
# Source an optional tcl customization file. Name is the name of a tcl file,
# e.g. "u_desk". If the file exists in the user customization directory
# that one is sourced too, AFTER the customization file.
#
proc sourceOptional {name} {
set context [ClientContext::global]
if [$context customFileExists $name tcl tcl] {
eval [$context getCustomFileContents $name tcl tcl]
}
set userFile [path_name concat [location ~ icase] $name tcl]
if [file exists $userFile] {
source $userFile
}
}
# Find an object-type specification
proc getObjectSpec {objectHdlr repositoryType subType {showError 1}} {
set typeSpec [$objectHdlr getObjectSpec "$repositoryType" "$subType"]
if {$showError && "$typeSpec" == ""} {
set message "Could not find object-type specification '$repositoryType"
if {"$repositoryType" != "$subType"} {
append message " ($subType)"
}
append message "'"
wmtkerror "$message"
}
return "$typeSpec"
}
# Check if interperter is running
proc isRunning {interp {showError 0}} {
if [catch {send $interp get_comm_name} error] {
if $showError {
wmtkerror "Error: $error"
}
return 0
}
return 1
}
# Return ORB_class for a repository id
proc ORB_class {id} {
set ORB_class [[RepositoryObject new $id] ORB_class]
$ORB_class new $id
return $ORB_class
}
# Read phases file
proc getPhases {} {
global BrowserProcs::phases
# Download the phases file
set tmpFile [args_file {}]
set context [ClientContext::global]
$context downLoadCustomFile phases phases etc $tmpFile
# Check syntax:
# phases file must consist of a list of phase-name, phase-type tuples
# where the phase names are unique
set phases ""
set errorMsg ""
set fid [open $tmpFile]
foreach phase [read -nonewline $fid] {
if {[llength $phase] != 2} {
append errorMsg \
"line '{$phase}' ignored: invalid syntax\n"
continue
}
set phaseName [lindex $phase 0]
if [info exists definedPhase($phaseName)] {
append errorMsg \
"line '{$phase}' ignored: phase name '$phaseName' not unique\n"
continue
}
set definedPhase($phaseName) 1
lappend phases $phase
}
if {"$errorMsg" == "" && [lempty $phases]} {
append errorMsg "file is empty"
}
set BrowserProcs::phases $phases
close $fid
unlink $tmpFile
# Show warning if phases file exists at current level
set level [$context currentLevel]
if {"$errorMsg" != "" &&
[$context customFileExistsAt $level phases phases etc]} {
regsub -all "\t" $errorMsg " " errorMsg
wmtkwarning \
"Warning while loading phases file at $level level\n$errorMsg"
}
}
# Retrieve the possible file types from objectHdlr
proc getFileTypes {objectHdlr} {
global BrowserProcs::externalFileTypes
global BrowserProcs::diagramFileTypes
global BrowserProcs::programmerFileTypes
set BrowserProcs::externalFileTypes ""
set BrowserProcs::diagramFileTypes ""
set BrowserProcs::programmerFileTypes ""
foreach objectSpec [$objectHdlr currentObjectSpecSet] {
set browserType [$objectSpec browserType]
if {"$browserType" == ""} continue
case [$objectSpec repositoryType] in {
{ExternalFileVersion} {
lappend BrowserProcs::programmerFileTypes $browserType
}
{Graph Matrix} {
lappend BrowserProcs::diagramFileTypes $browserType
}
{ExternalLink} {
lappend BrowserProcs::externalFileTypes $browserType
}
}
}
}
# Break a line into parts of max 'limit' size
# try to look a the break char to perform a break
# if no break is found just break at 'limit'
# return a list of the parts
#
proc lineBreak {line limit breakChar} {
set l $line
set result {}
set limit_minus1 $limit
incr limit_minus1 -1
while {[string length $l] >= $limit} {
set part [string range $l 0 $limit_minus1]
set idx [string last $breakChar $part]
if { $idx == -1 } {
set l [string range $l $limit end]
} else {
set part [string range $l 0 $idx]
incr idx
set l [string range $l $idx end]
}
lappend result $part
}
lappend result $l
return $result
}
# returns quoted string if 'str' consists of more than on part
# intended use: pathnames with spaces
#
proc quoteIf {str} {
if {[llength $str] > 1} {
return \"$str\"
}
return $str
}
# common code for report invocation
#
proc startReportInMtool {file comment} {
set script "[quoteIf [m4_path_name bin otsh$EXE_EXT]] \
-f [quoteIf [m4_path_name reports startreport.tcl]] \
-- $file"
.main startCommand mtool "$script" "" \
"Starting 'Report $comment'" {0 0} 0
}
# common code for configure invocation
#
proc startConfigureInXtool {file comment} {
set otsh [quoteIf [m4_path_name bin otsh$EXE_EXT]]
set file [quoteIf [m4_path_name config $file]]
.main startCommand xtool "$otsh -f $file" "" \
"Starting '$comment'" {0 0} 0
}
# read module file:
# take the first module when no module is specified
#
proc read_module_file { file {moduleName ""} {sourceProc source}} {
if {"$moduleName" == ""} {
set files [$globalModuleHandler getSelectedFiles tcl $file]
if [lempty $files] return
$sourceProc [lindex $files 0]
return
}
set module [$globalModuleHandler getModuleSpec $moduleName]
if {"$module" == ""} {
wmtkerror "Module '$moduleName' not found."
return
}
set moduleFiles [$globalModuleHandler getFiles tcl $file $module]
if {"$moduleFiles" != ""} {
$sourceProc [lindex $moduleFiles 0]
} else {
wmtkerror "Module file '$file' not found in module '$moduleName'."
}
}
proc require_module_file {file {moduleName ""} } {
read_module_file $file $moduleName module_require
}
# source file only once (internal use only)
#
proc module_require {file} {
global required_module_files
if [info exists required_module_files($file)] {
return
}
set required_module_files($file) 1
source $file
}
# Read all promoter module files of the given object type (p_<class>.tcl)
#
global modulePromoterSet
set modulePromoterSet [Dictionary new]
proc module_promoter {class object} {
global modulePromoterSet
if {![$modulePromoterSet exists $class]} {
set moduleSet {}
# fill dictionary
set file [string range "p_[string tolower $class]" 0 9].tcl
foreach module [$globalModuleHandler moduleSpecSet] {
set moduleFiles [$globalModuleHandler getFiles tcl $file $module]
if {"$moduleFiles" == ""} continue
lappend moduleSet [$module name]
module_require [lindex $moduleFiles 0]
}
$modulePromoterSet set $class $moduleSet
} else {
set moduleSet [$modulePromoterSet set $class]
}
#set moduleSet [$modulePromoterSet set $class]
foreach module $moduleSet {
$class::${module}_promoter $object
}
}
# Check for module_proc
#
proc module_proc {args} {
set proc [lvarpop args]
foreach module [$globalModuleHandler moduleSpecSet] {
if [isCommand ${proc}_[$module name]] {
eval ${proc}_[$module name] $args
}
}
}
# make levelpath from config/phase/system version
#
proc mkLevelPath {cV pV sV} {
set cc [ClientContext::global]
set result "/"
append result [[$cc currentCorporate] name]/
append result [[$cc currentProject] name]/
append result [[$cV ConfigVersion::config] name]:[$cV versionNumber]/
append result [[$pV phase] name].[[$pV phase] type]/
append result [[$sV system] name].[[$sV system] type]
return $result
"Starting '$comment'" {1 0} 0
}
proc showActiveModules {} {
set mods ""
foreach mdl [$globalModuleHandler moduleSpecSet] {
lappend mods [$mdl name]
lappend mods [$mdl longName]
}
global classCount
set box .main.showObjectInfo$classCount
incr classCount
interface TemplateDialog $box {
title "Active Modules"
DlgColumn col {}
okPressed {%this delete}
}
$box modal $win95
$box delCancelButton
$box delHelpButton
set len [llength $mods]
for {set i 0} {$i < $len} {incr i 2} {
DlgRow new $box.col.row$i \
-spaceType NONE \
-justification RIGHT
Label new $box.col.row$i.header \
-text "[lindex $mods $i]:" \
-alignment RIGHT \
-horStretchFactor 10 \
-justification TOP \
-font "courier-bold-12"
DlgColumn new $box.col.row$i.col
set breakUpCnt 0
foreach part [lineBreak [lindex $mods [expr $i+1]] 50 " "] {
set text [format "%-50s" $part]
Label new $box.col.row$i.col.label$breakUpCnt \
-text $text \
-font "courier-normal-12"
incr breakUpCnt
}
}
$box popUp
}
proc checkModuleWarnings {{moduleHandler ""}} {
if {$moduleHandler == ""} {
set moduleHandler $globalModuleHandler
}
set warnings [$moduleHandler warningSet]
global globalWarning
set globalWarning ""
foreach warning $warnings {
if {$globalWarning != ""} {
append globalWarning "\n"
}
append globalWarning "$warning"
}
if {$globalWarning != ""} {
wmtkwarning $globalWarning
}
}
# compare the first 'n' characters of two strings (default: min length).
#
proc strncmp {str1 str2 {n -1}} {
if {$n == 0} {
return 0
}
set last $n
set len1 [string length $str1]
if {($last < 0) || ($len1 < $last)} {
set last $len1
}
set len2 [string length $str2]
if {$len2 < $last} {
set last $len2
}
incr last -1
if {$last < 0} {
return [string compare $str1 $str2]
}
return [string compare \
[string range $str1 0 $last] \
[string range $str2 0 $last] \
]
}