home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 1997 November
/
PCWorld_1997-11_cd.bin
/
software
/
programy
/
komix
/
DATA.Z
/
wmt_util.tcl
< prev
next >
Wrap
Text File
|
1997-02-17
|
11KB
|
438 lines
#---------------------------------------------------------------------------
#
# Copyright (c) 1992-1995 by Cadre Technologies Inc.
#
# This software is furnished under a license and may be used only in
# accordance with the terms of such license and with the inclusion of
# the above copyright notice. This software or any other copies thereof
# may not be provided or otherwise made available to any other person.
# No title to and ownership of the software is hereby transferred.
#
# The information in this software is subject to change without notice
# and should not be construed as a commitment by Cadre Technologies Inc.
#
#---------------------------------------------------------------------------
#
# File : @(#)wmt_util.tcl /main/hindenburg/3 (1.8)
# Original date : Wed Aug 5 12:04:46 MET DST 1992
# Description : Cadre TCL utilities
#
#---------------------------------------------------------------------------
#
# @(#)wmt_util.tcl /main/hindenburg/3 17 Feb 1997 Copyright 1992-1995 Cadre Technologies Inc.
#
#---------------------------------------------------------------------------
require caynutil.tcl
require fstorage.tcl
require libsql_msg.tcl
require tdbop_msg.tcl
#
# Unpack the package-string e.g. ObjectTeam-OMT/Informix
#
# product will be OBJECTTEAM
# method will be OMT
# target will be INFORMIX
#
global product; set product ""
global method; set method ""
global target; set target ""
proc unpack_package {} {
global product
global method
global target
set package [m4_var get M4_package]
set spl_package [split $package /-]
set product [string toupper [lindex $spl_package 0]]
set method [string toupper [lindex $spl_package 1]]
set target [string toupper [lindex $spl_package 2]]
}
# This proc is still defined for compatibility reasons
proc find_file_types {} {
}
#
# topological sort, input 'dep_list' output 'sorted_list', 'unsortables'
#
# (a topological sort algorithm of the famous Ellis Horowitz.)
#
# 'dep_list' is an array indexed by (sort-object) name
# an array element is a list with the first element being a count
# on how many other objects this object depends.
# the rest of the list enumerates the objects which depend
# on his one.
# e.g. obj1: { 0 obj2 obj3 obj4 } means
# object 1 does not depend on any other object
# object 2, 3 and 4 depend on object 1
# e.g. obj5: { 3 }
# object 5 depends on three other objects,
# no other object depends on object 5
#
# 'sorted_list' is a list of object names that can be sorted
# 'unsortables' is a list of object names that cannot be sorted due to one or
# more cycles
#
proc topo_sort {dep_list sl us} {
upvar $dep_list dep
upvar $sl sorted_list
upvar $us unsortables
set top 0
set sorted_list ""
set unsortables ""
# create a linked stack of nodes with no predecessors
# i.e. nodes with no dependency
foreach index [array names dep] {
if {[lindex $dep($index) 0]==0} {
lvarpop dep($index)
set dep($index) [linsert $dep($index) 0 $top]
set top $index
}
}
# fill 'sorted' in topological order
foreach index [array names dep] {
if {$top==0} {
set unsortables [array names dep]
return
}
set j $top
set top [lindex $dep($top) 0]
lappend sorted_list $j
set links [lrange $dep($j) 1 end]
while {![lempty $links]} {
set elem [lvarpop links]
set count [expr {[lvarpop dep($elem)] - 1}]
set dep($elem) [linsert $dep($elem) 0 $count]
if {$count==0} {
lvarpop dep($elem)
set dep($elem) [linsert $dep($elem) 0 $top]
set top $elem
}
}
catch {unset dep($j)}
}
return
}
#
# Search for file 'file' with type 'type' in system 'System' and
# yank the contents of the file into the current section
#
proc @include {file type {System ""} {Phase ""}} {
# Global array containing the already included files
#
global included_files
upvar current_section current_section
if { $current_section == ""} {
m4_error $E_TCL_NO_SECTION "@include"
}
set clientCont [ClientContext::global]
set orgSys [$clientCont levelNameAt System]
set orgPhase [$clientCont levelNameAt Phase]
#set orgSys [OTShContext::getSystemName]
#set orgPhase [OTShContext::getPhaseName]
if { $Phase == ""} {
set Phase $orgPhase
}
if { $System == "" } {
set System $orgSys
}
if { $System != $orgSys} {
if {[catch {fstorage::goto_system $System $Phase} reason]} {
puts stderr $reason
return
}
}
#
# Check if the file does exist
#
set line_nr [$current_section lineNr]
if {[catch {set fp [fstorage::get_uenv_path $file.$type absolute]}]} {
m4_error $E_NO_INCL $line_nr $type $file $System
if { $System != $orgSys} {
fstorage::goto_system $orgSys $orgPhase
}
return
}
if { [get included_files($fp)] == 1 } {
return
} else {
set included_files($fp) 1
}
#
# Return to the original system
#
if { $System != $orgSys} {
fstorage::goto_system $orgSys $orgPhase
}
#
# Yank the contents of the include file into the current section
#
set txt ""
read_file_into_text $fp txt
expand_text $current_section "$txt" current_section $current_section
return
}
proc string_to_oopl_comment {section str {commentIndicator "--"}} {
if {$commentIndicator == "--"} {
set t_lang [m4_var get M4_target_lang]
if {[info exists comment_string($t_lang)]} {
set commentIndicator $comment_string($t_lang)
}
}
set lines [split $str "\n"]
foreach line $lines {
$section append "$commentIndicator $line\n"
}
}
proc file_to_oopl_comment {section file {commentIndicator "--"}} {
set fd [open $file r]
set string [read $fd nonewline]
close $fd
string_to_oopl_comment $section $string $commentIndicator
}
# rm -rf function with verbose option
# requires extended Tcl commands 'unlink' and 'rmdir'
proc rm_rf {entries {verbose 0}} {
foreach e $entries {
if [file isdirectory $e] {
rm_rf [glob $e/*] $verbose
if $verbose {
puts "rmdir $e"
}
rmdir -nocomplain $e
} else {
if {$verbose && [file exists $e]} {
puts "rm $e"
}
unlink -nocomplain $e
}
}
}
#
# Test whether the contents of a section equals the contents of a file
#
proc section_equals_file {sect file} {
if [catch {set fd [fstorage::open $file r]}] {
return 0
}
set result [string compare [$sect contents] [read $fd]]
fstorage::close $fd
return [expr {$result == 0}]
}
#
# Returns a new section with the contents of oldSect where double lines are
# removed.
# Note: empty lines are not removed.
#
proc removeDoubleLinesFromSection {oldSect} {
set lst [split [$oldSect contents] "\n"]
# remove double elements
for {set i 0} {$i < [llength $lst]} {incr i} {
for {set j [expr [llength $lst] - 1]} {$j > $i} {incr j -1} {
if {[lindex $lst $i] == ""} {
# keep empty lines
continue
}
if {[lindex $lst $i] == [lindex $lst $j]} {
set lst [lreplace $lst $j $j]
incr j -1
}
}
}
# put in new section
set newSect [TextSection new]
$newSect append [join $lst "\n"]
return $newSect
}
#
# Proc getPartString is used by proc padString.
# It returns a part of $str starting at $startIdx.
# The length of the returned string is $maxLen characters, or less in which
# case it was truncated after the space character closest to index $maxLen.
# startIdx is set to the index at which the partial string was truncated.
#
proc getPartString {str startIdx maxLen} {
upvar $startIdx start
set end [expr $start + $maxLen - 1]
set restStr [string range $str $start end]
if {[string length $restStr] <= $maxLen} {
set start [string length $str]
return $restStr
}
set partStr [string range $restStr 0 [expr $maxLen - 1]]
set idx [string last " " $partStr]
if {$idx == -1 || [string index $str [expr $end + 1]] == " "} {
set start [expr $end + 1]
return $partStr
}
set partStr [string range $partStr 0 $idx]
set start [expr $start + $idx + 1]
return $partStr
}
#
# Proc padString first concatenates $beginStr, $str and $endStr.
# This string is padded with $padStr at intervals with a maximum length $maxLen.
# The resulting string is returned.
#
proc padString {beginStr str endStr padStr {maxLen 80}} {
set totalStr $beginStr$str$endStr
set length [string length $totalStr]
set startIdx 0
set newStr [getPartString $totalStr startIdx $maxLen]
while {$startIdx < $length} {
set partStr [getPartString $totalStr startIdx $maxLen]
set newStr $newStr$padStr$partStr
}
return $newStr
}
#
# To make a proper selection of the oopl classes the get_selected_classes
# procedure can be used.
# This function takes a list of sources as argument.
# Sources can be class names or diagrams
#
proc getSelectedOoplClasses {ooplModel {sources ""}} {
global ooplClassFilter
global ooplExclClassFilter
set classes ""
if {$sources == ""} {
set sources $ooplClassFilter
}
if {$sources == ""} {
foreach className [$ooplModel getClassNames] {
if {[lsearch $classes $className] == -1 &&
[lsearch $ooplExclClassFilter $className] == -1} {
lappend classes $className
}
}
} else {
foreach source $sources {
if {[string first "." $source] == -1} {
# obj is a class
if {[lsearch $classes $source] == -1 &&
[lsearch $ooplExclClassFilter $source] == -1} {
lappend classes $source
}
} else {
foreach class [get_diagram_classes $source] {
if {[lsearch $classes $class] == -1} {
lappend classes $class
}
}
if {[lindex [split $source '.'] 1] == "std" } {
set stdName [lindex [split $source '.'] 0]
if {[lsearch $classes $stdName] == -1 } {
lappend classes [lindex [split $stdName '/'] 0]
}
}
}
}
}
set ooplClasses ""
foreach sourceClass $classes {
if {$sourceClass == ""} {
puts stderr "Skipping class '$sourceClass'"
continue
}
set class [$ooplModel classByName $sourceClass]
if {$class == ""} {
puts stderr "Unable to load class '$sourceClass'"
continue
}
if {[lsearch $ooplClasses $class] == -1 &&
[lsearch $ooplExclClassFilter $class] == -1} {
lappend ooplClasses $class
}
}
return $ooplClasses
}
proc getSelectedOoplSubjects {ooplModel {sources ""}} {
global ooplClassFilter
set subjects ""
if {$sources == ""} {
set sources $ooplClassFilter
}
foreach source $sources {
if {[string first "." $source] != -1} {
# obj is a class
lappend subjects [get_diagram_subjects $source]
}
}
set ooplSubjects ""
foreach subject [$ooplModel subjectSet] {
if {[lsearch $ooplSubjects [$subject getName]] != -1} {
lappend ooplSubjects $subject
}
}
return $ooplSubjects
}
proc getCurrentSystemName {} {
set clientCont [ClientContext::global]
set currentSystem [$clientCont currentSystem]
if ![$currentSystem isNil] {
return [[$currentSystem system] name]
} else {
return ""
}
}