"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "tcl/subcmd.tcl.in" between
modules-5.1.1.tar.bz2 and modules-5.2.0.tar.bz2

About: The Environment Modules package provides for the dynamic modification of a user’s environment via modulefiles.

subcmd.tcl.in  (modules-5.1.1.tar.bz2):subcmd.tcl.in  (modules-5.2.0.tar.bz2)
skipping to change at line 33 skipping to change at line 33
proc cmdModuleList {show_oneperline show_mtime search_match args} { proc cmdModuleList {show_oneperline show_mtime search_match args} {
set json [isStateEqual report_format json] set json [isStateEqual report_format json]
# load tags from loaded modules # load tags from loaded modules
cacheCurrentModules cacheCurrentModules
if {[llength $args] > 0} { if {[llength $args] > 0} {
defineModEqProc [isIcase] [getConf extended_default] defineModEqProc [isIcase] [getConf extended_default]
# match passed name against any part of loaded module names # match passed name against any part of loaded module names
set mtest [expr {{contains} in $search_match ? {matchin} : {match}}] set mtest [expr {{contains} in $search_match ? {matchin} : {match}}]
# use first arg as query to highlight as reportModules only accepts one set search_queries $args
# search specification
set searchquery [lindex $args 0]
# prepare header message which depend if search is performed # prepare header message which depend if search is performed
set loadedmsg {Currently Loaded Matching Modulefiles} set loadedmsg {Currently Loaded Matching Modulefiles}
} else { } else {
set searchquery {} set search_queries {}
set loadedmsg {Currently Loaded Modulefiles} set loadedmsg {Currently Loaded Modulefiles}
} }
# filter-out hidden loaded modules unless all module should be seen # filter-out hidden loaded modules unless all module should be seen
if {[getState hiding_threshold] > 1} { if {[getState hiding_threshold] > 1} {
set loadedmodlist [getLoadedModuleList] set loadedmodlist [getLoadedModulePropertyList name]
} else { } else {
set loadedmodlist [list] set loadedmodlist [list]
foreach mod [getLoadedModuleList] { foreach mod [getLoadedModulePropertyList name] {
if {![isModuleTagged $mod hidden-loaded 1]} { if {![isModuleTagged $mod hidden-loaded 1]} {
lappend loadedmodlist $mod lappend loadedmodlist $mod
} }
} }
} }
# same header msg if no module loaded at all whether search is made or not # same header msg if no module loaded at all whether search is made or not
set noloadedmsg [expr {[llength $loadedmodlist] == 0 ? {No Modulefiles\ set noloadedmsg [expr {[llength $loadedmodlist] == 0 ? {No Modulefiles\
Currently Loaded.} : {No Matching Modulefiles Currently Loaded.}}] Currently Loaded.} : {No Matching Modulefiles Currently Loaded.}}]
skipping to change at line 105 skipping to change at line 103
} }
set ::g_symbolHash($mod) [lsort -dictionary $sym_list] set ::g_symbolHash($mod) [lsort -dictionary $sym_list]
} }
set one_per_line [expr {$show_mtime || $show_oneperline}] set one_per_line [expr {$show_mtime || $show_oneperline}]
set show_idx [expr {!$show_mtime && [isEltInReport idx]}] set show_idx [expr {!$show_mtime && [isEltInReport idx]}]
set header [expr {!$json && [isEltInReport header] ? $loadedmsg :\ set header [expr {!$json && [isEltInReport header] ? $loadedmsg :\
{noheader}}] {noheader}}]
set theader_cols [list hi Package 39 Versions 19 {Last mod.} 19] set theader_cols [list hi Package 39 Versions 19 {Last mod.} 19]
reportModules $searchquery $header {} terse $show_mtime $show_idx\ reportModules $search_queries $header {} terse $show_mtime $show_idx\
$one_per_line $theader_cols loaded $loadedmodlist $one_per_line $theader_cols loaded $loadedmodlist
# display output key # display output key
if {!$show_mtime && !$json && [isEltInReport key]} { if {!$show_mtime && !$json && [isEltInReport key]} {
displayKey displayKey
} }
} }
} }
proc cmdModuleDisplay {args} { proc cmdModuleDisplay {args} {
skipping to change at line 282 skipping to change at line 280
$elt]] $elt]]
# register resolution error if alias name matches search # register resolution error if alias name matches search
} elseif {[modEq $mod $elt]} { } elseif {[modEq $mod $elt]} {
set err_list($modname) [list $issuetype $issuemsg] set err_list($modname) [list $issuetype $issuemsg]
} }
} }
} }
} }
version { version {
# report error of version target if matching query # report error of version target if matching query
set elt_target [getArrayKey mod_list [lindex $mod_list($elt) 1]\ set elt_target [getArrayKey mod_list [lindex $mod_list($elt)\
$icase] 1] $icase]
if {[info exists mod_list($elt_target)] && [lindex\ if {[info exists mod_list($elt_target)] && [lindex\
$mod_list($elt_target) 0] in [list invalid accesserr] &&\ $mod_list($elt_target) 0] in [list invalid accesserr] &&\
[modEq $mod $elt]} { [modEq $mod $elt]} {
set err_list($elt_target) $mod_list($elt_target) set err_list($elt_target) $mod_list($elt_target)
} elseif {![info exists mod_list($elt_target)]} { } elseif {![info exists mod_list($elt_target)]} {
set extra_search($elt_target) [list $dir [modEq $mod $elt]] set extra_search($elt_target) [list $dir [modEq $mod $elt]]
} }
} }
invalid - accesserr { invalid - accesserr {
# register any error occurring on element matching search # register any error occurring on element matching search
skipping to change at line 367 skipping to change at line 365
# interpret all modulefile we got for each modulepath # interpret all modulefile we got for each modulepath
foreach dir $dir_list { foreach dir $dir_list {
if {[info exists interp_save($dir)]} { if {[info exists interp_save($dir)]} {
array unset interp_list array unset interp_list
array set interp_list $interp_save($dir) array set interp_list $interp_save($dir)
set foundmod 1 set foundmod 1
set display_list {} set display_list {}
# interpret every modulefiles obtained to get their whatis text # interpret every modulefiles obtained to get their whatis text
foreach elt [lsort -dictionary [array names interp_list]] { foreach elt [lsort -dictionary [array names interp_list]] {
set ::g_whatis {} set ::g_whatis {}
##nagelfar ignore Suspicious variable name
execute-modulefile $interp_list($elt) $elt $elt $elt 0 execute-modulefile $interp_list($elt) $elt $elt $elt 0
# treat whatis as a multi-line text # treat whatis as a multi-line text
if {$search eq {} || [regexp -nocase $search $::g_whatis]} { if {$search eq {} || [regexp -nocase $search $::g_whatis]} {
if {$json} { if {$json} {
lappend display_list [formatListEltToJsonDisplay $elt\ lappend display_list [formatListEltToJsonDisplay $elt\
whatis a $::g_whatis 1] whatis a $::g_whatis 1]
} else { } else {
set eltsgr [string map $matchmodmap $elt] set eltsgr [string map $matchmodmap $elt]
foreach line $::g_whatis { foreach line $::g_whatis {
set linesgr [string map $matchsearchmap $line] set linesgr [string map $matchsearchmap $line]
lappend display_list "[string repeat { } [expr {20 -\ lappend display_list "[string repeat { } [expr {20 -\
[string length $elt]}]]$eltsgr: $linesgr" [string length $elt]}]]$eltsgr: $linesgr"
} }
} }
} }
} }
displayElementList $dir mp sepline 1 0 $display_list displayElementList $dir mp sepline 1 0 0 $display_list
} }
} }
lpopState mode lpopState mode
setState inhibit_errreport 0 setState inhibit_errreport 0
# report errors if a modulefile was searched but not found # report errors if a modulefile was searched but not found
if {$mod ne {} && !$foundmod} { if {$mod ne {} && !$foundmod} {
# no error registered means nothing was found to match search # no error registered means nothing was found to match search
if {![array exists err_list]} { if {![array exists err_list]} {
skipping to change at line 447 skipping to change at line 446
# enable unload of sticky mod if stickiness is preserved on swapped-on mod # enable unload of sticky mod if stickiness is preserved on swapped-on mod
# need to resolve swapped-off module here to get stickiness details # need to resolve swapped-off module here to get stickiness details
lassign [getPathToModule $old {} 0 $unload_match] modfile oldmod oldmodvr lassign [getPathToModule $old {} 0 $unload_match] modfile oldmod oldmodvr
if {[set sticky_reload [isStickinessReloading $oldmodvr [list $new]]]} { if {[set sticky_reload [isStickinessReloading $oldmodvr [list $new]]]} {
lappendState reloading_sticky $oldmod lappendState reloading_sticky $oldmod
} }
if {[set supersticky_reload [isStickinessReloading $oldmodvr [list $new]\ if {[set supersticky_reload [isStickinessReloading $oldmodvr [list $new]\
super-sticky]]} { super-sticky]]} {
lappendState reloading_supersticky $oldmod lappendState reloading_supersticky $oldmod
} }
##nagelfar implicitvarcmd {cmdModuleUnload swunload *} oldhidden olduasked\
oldmsgrecid deprelist depreisuasked deprevr depreextratag
set ret [cmdModuleUnload swunload $unload_match 1 0 0 0 $old] set ret [cmdModuleUnload swunload $unload_match 1 0 0 0 $old]
if {$sticky_reload} { if {$sticky_reload} {
lpopState reloading_sticky lpopState reloading_sticky
} }
if {$supersticky_reload} { if {$supersticky_reload} {
lpopState reloading_supersticky lpopState reloading_supersticky
} }
# register modulefile to unload as conflict if an unload module is # register modulefile to unload as conflict if an unload module is
# mentioned on this module switch command set in a modulefile # mentioned on this module switch command set in a modulefile
skipping to change at line 478 skipping to change at line 479
} }
} }
# attempt load and depre reload only if unload succeed # attempt load and depre reload only if unload succeed
if {!$ret} { if {!$ret} {
if {[info exists depreisuasked]} { if {[info exists depreisuasked]} {
set undepreisuasked $depreisuasked set undepreisuasked $depreisuasked
set undeprevr $deprevr set undeprevr $deprevr
set undepreextratag $depreextratag set undepreextratag $depreextratag
} }
cmdModuleLoad swload $uasked $tag_list $new ##nagelfar implicitvarcmd {cmdModuleLoad swload *} newhidden newmsgrecid
cmdModuleLoad swload $uasked 0 0 $tag_list $new
# merge depre info of unload and load phases # merge depre info of unload and load phases
if {[info exists undepreisuasked]} { if {[info exists undepreisuasked]} {
set depreisuasked [list {*}$undepreisuasked {*}$depreisuasked] set depreisuasked [list {*}$undepreisuasked {*}$depreisuasked]
set deprevr [list {*}$undeprevr {*}$deprevr] set deprevr [list {*}$undeprevr {*}$deprevr]
set depreextratag [list {*}$undepreextratag {*}$depreextratag] set depreextratag [list {*}$undepreextratag {*}$depreextratag]
} }
if {[getConf auto_handling] && [info exists deprelist] && [llength\ if {[getConf auto_handling] && [info exists deprelist] && [llength\
$deprelist] > 0} { $deprelist] > 0} {
skipping to change at line 518 skipping to change at line 520
reportMsgRecord "Switching from [getModuleDesignation $oldmsgrecid {} 2]\ reportMsgRecord "Switching from [getModuleDesignation $oldmsgrecid {} 2]\
to [getModuleDesignation $newmsgrecid $new 2]" [expr {$oldhidden &&\ to [getModuleDesignation $newmsgrecid $new 2]" [expr {$oldhidden &&\
!$olduasked && $newhidden && !$uasked}] !$olduasked && $newhidden && !$uasked}]
popMsgRecordId popMsgRecordId
if {$inhibit_req_rec} { if {$inhibit_req_rec} {
lpopState inhibit_req_record lpopState inhibit_req_record
} }
# register modulefile to load as prereq when called from modulefile # register modulefile to load as prereq when called from modulefile
if {!$uasked && !$ret && $argnew ne {}} { if {!$uasked && !$ret && $argnew ne {}} {
setConf auto_handling 0 prereqAnyModfileCmd 0 0 $argnew
prereq $argnew
setConf auto_handling $orig_auto_handling
} }
} }
proc cmdModuleSave {{coll default}} { proc cmdModuleSave {{coll default}} {
if {![areModuleConstraintsSatisfied]} { if {![areModuleConstraintsSatisfied]} {
reportErrorAndExit {Cannot save collection, some module constraints are\ reportErrorAndExit {Cannot save collection, some module constraints are\
not satistied} not satistied}
} }
# format collection content, version number of modulefile are saved if # format collection content, version number of modulefile are saved if
skipping to change at line 572 skipping to change at line 572
if {[catch { if {[catch {
set fid [open $collfile w] set fid [open $collfile w]
puts $fid $save puts $fid $save
close $fid close $fid
} errMsg ]} { } errMsg ]} {
reportErrorAndExit "Collection $colldesc cannot be saved.\n$errMsg" reportErrorAndExit "Collection $colldesc cannot be saved.\n$errMsg"
} }
} }
proc cmdModuleRestore {{coll default}} { proc cmdModuleRestore {args} {
# get corresponding collection, raise error if it does not exist # distinguish between zero and one argument provided
lassign [findCollections $coll exact 1] collfile colldesc if {[llength $args] == 0} {
set arg_provided 0
# read collection set coll default
lassign [readCollectionContent $collfile $colldesc] coll_path_list\ } else {
coll_mod_list coll_tag_arrser set arg_provided 1
set coll [lindex $args 0]
# build list of module tagged auto-loaded in collection
array set coll_tag_arr $coll_tag_arrser
set coll_nuasked_list {}
foreach mod [array names coll_tag_arr] {
if {{auto-loaded} in $coll_tag_arr($mod)} {
lappend coll_nuasked_list $mod
}
} }
# collection should at least define a path or a mod # get corresponding collection, raise error if it does not exist unless
if {[llength $coll_path_list] == 0 && [llength $coll_mod_list] == 0} { # if no collection name has been provided or if __init__
reportErrorAndExit "$colldesc is not a valid collection" lassign [findCollections $coll exact [expr {!$arg_provided}]\
} $arg_provided] collfile colldesc
# forcibly enable implicit_default to restore colls saved in this mode # forcibly enable implicit_default to restore colls saved in this mode
setConf implicit_default 1 setConf implicit_default 1
# load tags from loaded modules # fetch collection content and differences compared current environment
cacheCurrentModules lassign [getDiffBetweenCurEnvAndColl $collfile $colldesc] coll_path_list\
coll_mod_list coll_tag_arrser coll_nuasked_list mod_to_unload\
defineModEqProc [isIcase] [getConf extended_default] mod_to_load path_to_unuse path_to_use is_tags_diff
array set coll_tag_arr $coll_tag_arrser
# fetch what is currently loaded
set curr_path_list [getModulePathList returnempty 0]
# get current loaded module list
set curr_mod_list [getLoadedModuleList]
set curr_nuasked_list [getTaggedLoadedModuleList auto-loaded]
# determine what module to unload to restore collection from current
# situation with preservation of the load order (asking for a modeq
# comparison will help to check against simplified mod name and variants)
lassign [getMovementBetweenList $curr_mod_list $coll_mod_list\
$curr_nuasked_list $coll_nuasked_list modeq] mod_to_unload mod_to_load
# proceed as well for modulepath
lassign [getMovementBetweenList $curr_path_list $coll_path_list] \
path_to_unuse path_to_use
# create an eval id to track successful/failed module evaluations # create an eval id to track successful/failed module evaluations
pushMsgRecordId restore-$coll-[depthState modulename] 0 pushMsgRecordId restore-$coll-[depthState modulename] 0
# unload modules one by one (no dependency auto unload) # unload modules one by one (no dependency auto unload)
foreach mod [lreverse $mod_to_unload] { foreach mod [lreverse $mod_to_unload] {
# test stickiness over full module name version variant designation # test stickiness over full module name version variant designation
if {[set vr [getVariantList $mod 1]] ne {}} { if {[set vr [getVariantList $mod 1]] ne {}} {
lassign [parseModuleSpecification 0 $mod {*}$vr] modvr lassign [parseModuleSpecification 0 $mod {*}$vr] modvr
} else { } else {
set modvr $mod set modvr $mod
} }
if {[set sticky_reload [isStickinessReloading $modvr $mod_to_load]]} { # sticky modules can be unloaded when restoring collection
lappendState reloading_sticky $mod lappendState unloading_sticky $mod
}
if {[set supersticky_reload [isStickinessReloading $modvr $mod_to_load\ if {[set supersticky_reload [isStickinessReloading $modvr $mod_to_load\
super-sticky]]} { super-sticky]]} {
lappendState reloading_supersticky $mod lappendState reloading_supersticky $mod
} }
cmdModuleUnload unload match 0 0 0 0 $mod cmdModuleUnload unload match 0 0 0 0 $mod
if {$sticky_reload} { lpopState unloading_sticky
lpopState reloading_sticky
}
if {$supersticky_reload} { if {$supersticky_reload} {
lpopState reloading_supersticky lpopState reloading_supersticky
} }
} }
# unuse paths # unuse paths
if {[llength $path_to_unuse] > 0} { if {[llength $path_to_unuse] > 0} {
cmdModuleUnuse load {*}[lreverse $path_to_unuse] cmdModuleUnuse load {*}[lreverse $path_to_unuse]
} }
# since unloading a module may unload other modules or # since unloading a module may unload other modules or
# paths, what to load/use has to be determined after # paths, what to load/use has to be determined after
# the undo phase, so current situation is fetched again # the undo phase, so current situation is fetched again
set curr_path_list [getModulePathList returnempty 0] set curr_path_list [getModulePathList returnempty 0]
set curr_mod_list [getLoadedModuleList] set curr_mod_list [getLoadedModulePropertyList name]
set curr_nuasked_list [getTaggedLoadedModuleList auto-loaded] set curr_nuasked_list [getTaggedLoadedModuleList auto-loaded]
# update tags sets on the modules already loaded at correct position # update tags sets on the modules already loaded at correct position
# remove extra tags that are not defined in collection # remove extra tags that are not defined in collection
foreach modvr [getLoadedModuleWithVariantList] { foreach modvr [getLoadedModuleWithVariantList] {
if {[info exists coll_tag_arr($modvr)]} { if {[info exists coll_tag_arr($modvr)]} {
set tag_list $coll_tag_arr($modvr) set tag_list $coll_tag_arr($modvr)
} else { } else {
set tag_list {} set tag_list {}
} }
skipping to change at line 695 skipping to change at line 670
# use paths # use paths
if {[llength $path_to_use] > 0} { if {[llength $path_to_use] > 0} {
# always append path here to guaranty the order # always append path here to guaranty the order
# computed above in the movement lists # computed above in the movement lists
cmdModuleUse load append {*}$path_to_use cmdModuleUse load append {*}$path_to_use
} }
# load modules one by one with user asked state preserved # load modules one by one with user asked state preserved
foreach mod $mod_to_load { foreach mod $mod_to_load {
cmdModuleLoad load [expr {$mod ni $coll_nuasked_list}]\ cmdModuleLoad load [expr {$mod ni $coll_nuasked_list}] 0 0\
$coll_tag_arr($mod) $mod $coll_tag_arr($mod) $mod
} }
popMsgRecordId 0 popMsgRecordId 0
} }
proc cmdModuleSaverm {{coll default}} { proc cmdModuleSaverm {{coll default}} {
# avoid to remove any kind of file with this command # avoid to remove any kind of file with this command
if {[string first / $coll] > -1} { if {[string first / $coll] > -1} {
reportErrorAndExit {Command does not remove collection specified as\ reportErrorAndExit {Command does not remove collection specified as\
filepath} filepath}
} }
# get corresponding collection, raise error if it does not exist, but do # get corresponding collection, raise error if it does not exist, but do
# not check if collection is valid # not check if collection is valid
lassign [findCollections $coll exact 1 0] collfile colldesc lassign [findCollections $coll exact 0 1 0] collfile colldesc
# attempt to delete specified collection # attempt to delete specified collection
if {[catch { if {[catch {
file delete $collfile file delete $collfile
} errMsg ]} { } errMsg ]} {
reportErrorAndExit "Collection $colldesc cannot be removed.\n$errMsg" reportErrorAndExit "Collection $colldesc cannot be removed.\n$errMsg"
} }
} }
proc cmdModuleSaveshow {{coll default}} { proc cmdModuleSaveshow {args} {
# get corresponding collection, raise error if it does not exist # distinguish between zero and one argument provided
lassign [findCollections $coll exact 1] collfile colldesc if {[llength $args] == 0} {
set arg_provided 0
# read collection set coll default
lassign [readCollectionContent $collfile $colldesc] coll_path_list\ } else {
coll_mod_list coll_tag_arrser set arg_provided 1
set coll [lindex $args 0]
}
# get corresponding collection, raise error if it does not exist unless
# if no collection name has been provided or if __init__
lassign [findCollections $coll exact [expr {!$arg_provided}]\
$arg_provided] collfile colldesc
# read specific __init__ collection from __MODULES_LMINIT env var
if {$collfile eq {__init__}} {
lassign [parseCollectionContent [getLoadedModulePropertyList init]]\
coll_path_list coll_mod_list coll_tag_arrser
set collfile {initial environment}
set coll __init__
} else {
lassign [readCollectionContent $collfile $colldesc] coll_path_list\
coll_mod_list coll_tag_arrser
}
# collection should at least define a path or a mod # collection should at least define a path or a mod, but initial env may be
if {[llength $coll_path_list] == 0 && [llength $coll_mod_list] == 0} { # totally empty
if {$coll ne {__init__} && [llength $coll_path_list] == 0 && [llength\
$coll_mod_list] == 0} {
reportErrorAndExit "$colldesc is not a valid collection" reportErrorAndExit "$colldesc is not a valid collection"
} }
displaySeparatorLine displaySeparatorLine
report [sgr hi $collfile]:\n report [sgr hi $collfile]:\n
report [formatCollectionContent $coll_path_list $coll_mod_list\ report [formatCollectionContent $coll_path_list $coll_mod_list\
$coll_tag_arrser {} 1] $coll_tag_arrser {} 1]
displaySeparatorLine displaySeparatorLine
} }
proc cmdModuleSavelist {show_oneperline show_mtime} { proc cmdModuleSavelist {show_oneperline show_mtime search_match args} {
# if a target is set, only list collection matching this # if a target is set, only list collection matching this target (means
# target (means having target as suffix in their name) # having target as suffix in their name) unless if --all option is set
set colltarget [getConf collection_target] set colltarget [getConf collection_target]
if {$colltarget ne {}} { if {$colltarget ne {} && [getState hiding_threshold] < 2} {
set suffix .$colltarget set suffix .$colltarget
set targetdesc " (for target \"$colltarget\")" set targetdesc " (for target \"$colltarget\")"
} else { } else {
set suffix {} set suffix {}
set targetdesc {} set targetdesc {}
} }
set json [isStateEqual report_format json] set json [isStateEqual report_format json]
reportDebug "list collections for target \"$colltarget\"" reportDebug "list collections$targetdesc"
# if only stash collection are expected, start result index at 0, sort
# results in reverse order (latest first) and ensure only collection from
# current target (and no-target if none set) are returned.
if {[getCallingProcName] eq {cmdModuleStashlist}} {
set start_idx 0
set sort_opts [list -dictionary -decreasing]
set find_no_other_target 1
set typedesc stash
# no icase match as stash collections are only lowercases
set icase 0
} else {
set start_idx 1
set sort_opts [list -dictionary]
set find_no_other_target 0
set typedesc named
set icase [isIcase]
}
if {[llength $args] > 0} {
defineModEqProc $icase 0
# match passed name against any part of collection names
set mtest [expr {{contains} in $search_match ? {matchin} : {match}}]
}
# prepare header message which depend if search is performed (no search
# considered if listing stash collections)
if {[llength $args] > 0 && $typedesc ne {stash}} {
set collmsg "Matching $typedesc collection list$targetdesc:"
} else {
set collmsg "[string totitle $typedesc] collection list$targetdesc:"
}
foreach collfile [findCollections * glob 0 0 1 $find_no_other_target] {
# remove target suffix from names to display
regsub $suffix$ [file tail $collfile] {} coll
# filter stash collections unless called by stashlist or --all opt set
if {$typedesc ne {named} || ![regexp {stash-\d+} $coll] || [getState\
hiding_threshold] >= 2} {
set coll_arr($coll) $collfile
}
}
# same header msg if no collection at all whether search is made or not
if {![array exists coll_arr] || $typedesc eq {stash}} {
set nocollmsg "No $typedesc collection$targetdesc."
} else {
set nocollmsg "No matching $typedesc collection$targetdesc."
}
set coll_list [findCollections] # filter collection not matching any of the passed specification
if {[llength $args] > 0} {
set matchlist [list]
foreach coll [array names coll_arr] {
set match 0
foreach pattern $args {
# compare pattern against collections using comparison module proc
# useful for suffix/prefix/icase checks, disabling module-specific
# checks (variants, alternative names, etc)
if {[modEq $pattern $coll $mtest 0 0 0 0 *]} {
set match 1
break
}
}
if {!$match} {
unset coll_arr($coll)
}
}
}
if { [llength $coll_list] == 0} { if {[array size coll_arr] == 0} {
if {!$json} { if {!$json} {
report "No named collection$targetdesc." report $nocollmsg
} }
} else { } else {
set list {}
if {!$json} { if {!$json} {
if {$show_mtime} { if {$show_mtime} {
displayTableHeader hi Collection 59 {Last mod.} 19 displayTableHeader hi Collection 59 {Last mod.} 19
} }
report "Named collection list$targetdesc:" report $collmsg
} }
set display_list {} set display_list {}
set len_list {} set len_list {}
set max_len 0 set max_len 0
if {$show_mtime || $show_oneperline} { set one_per_line [expr {$show_mtime || $show_oneperline}]
set display_idx 0 set show_idx [expr {!$one_per_line}]
set one_per_line 1 # prepare query to highlight
} else { set himatchmap [prepareMapToHightlightSubstr {*}$args]
set display_idx 1
set one_per_line 0
}
foreach coll [lsort -dictionary $coll_list] { foreach coll [lsort {*}$sort_opts [array names coll_arr]] {
# remove target suffix from names to display
regsub $suffix$ [file tail $coll] {} mod
if {$json} { if {$json} {
lappend display_list [formatListEltToJsonDisplay $mod target s\ lappend display_list [formatListEltToJsonDisplay $coll target s\
$colltarget 1 pathname s $coll 1] $colltarget 1 pathname s $coll_arr($coll) 1]
# no need to test mod consistency as findCollections does not return # no need to test coll consistency as findCollections does not return
# collection whose name starts with "." # collection whose name starts with "."
} elseif {$show_mtime} {
set filetime [clock format [getFileMtime $coll]\
-format {%Y/%m/%d %H:%M:%S}]
lappend display_list [format %-60s%19s $mod $filetime]
} else { } else {
lappend display_list $mod set collsgr [sgr {} $coll $himatchmap]
lappend len_list [set len [string length $mod]] if {$show_mtime} {
if {$len > $max_len} { set filetime [clock format [getFileMtime $coll_arr($coll)]\
set max_len $len -format {%Y/%m/%d %H:%M:%S}]
lappend display_list [format %-60s%19s $collsgr $filetime]
} else {
lappend display_list $collsgr
lappend len_list [set len [string length $coll]]
if {$len > $max_len} {
set max_len $len
}
} }
} }
} }
displayElementList noheader {} {} $one_per_line $display_idx\ displayElementList noheader {} {} $one_per_line $show_idx $start_idx\
$display_list $len_list $max_len $display_list $len_list $max_len
} }
} }
proc cmdModuleSource {mode args} { proc cmdModuleSource {mode args} {
foreach fpath $args { foreach mod $args {
set absfpath [getAbsolutePath $fpath] set rawarg [getRawArgumentFromVersSpec $mod]
if {$fpath eq {}} { if {$mod eq {}} {
reportErrorAndExit {File name empty} reportErrorAndExit {File name empty}
} elseif {[file exists $absfpath]} { # first check if raw specification is an existing file
lappendState mode $mode } elseif {[file exists [set absfpath [getAbsolutePath $rawarg]]]} {
# sourced file must also have a magic cookie set at their start set modfile $absfpath
execute-modulefile $absfpath $absfpath $absfpath $absfpath 0 0 set modname $absfpath
lpopState mode set modnamevr $absfpath
# unset module specification not to confuse specific char in file
# path (like '+') with variant specification
unsetModuleVersSpec $mod
set mod $absfpath
# if not a path specification, try to resolve a modulefile
} elseif {![isModuleFullPath $rawarg]} {
lassign [getPathToModule $mod] modfile modname modnamevr
# stop if no module found, issue has been reported by getPathToModule
if {$modfile eq {}} {
break
}
} else { } else {
reportErrorAndExit "File $fpath does not exist" reportErrorAndExit "File $rawarg does not exist"
} }
##nagelfar ignore Found constant
lappendState mode $mode
# sourced file must also have a magic cookie set at their start
##nagelfar ignore Suspicious variable name
execute-modulefile $modfile $modname $modnamevr $mod 0 0
##nagelfar ignore Found constant
lpopState mode
} }
} }
proc cmdModuleLoad {context uasked tag_list args} { proc cmdModuleLoad {context uasked tryload loadany tag_list args} {
reportDebug "loading $args (context=$context, uasked=$uasked)" reportDebug "loading $args (context=$context, uasked=$uasked,\
tryload=$tryload, loadany=$loadany)"
set ret 0 set ret 0
set loadok 0 set loadok 0
lappendState mode load lappendState mode load
foreach mod $args { foreach mod $args {
# stop when first module in list is loaded if processing load-any cmd # stop when first module in list is loaded if any mode enabled
if {$loadok && [currentState any_modulefile]} { if {$loadok && $loadany} {
break break
} }
# if a switch action is ongoing... # if a switch action is ongoing...
if {$context eq {swload}} { if {$context eq {swload}} {
set swprocessing 1 set swprocessing 1
# context is ReqLo if switch is called from a modulefile # context is ReqLo if switch is called from a modulefile
if {![isMsgRecordIdTop]} { if {![isMsgRecordIdTop]} {
set context reqlo set context reqlo
} }
upvar newhidden hidden upvar newhidden hidden
upvar newmsgrecid msgrecid upvar newmsgrecid msgrecid
} }
# loading module is visible by default # loading module is visible by default
set hidden 0 set hidden 0
# error if module not found or forbidden # error if module not found or forbidden
set notfounderr [expr {![currentState try_modulefile]}] set notfounderr [expr {!$tryload}]
# record evaluation attempt on specified module name # record evaluation attempt on specified module name
registerModuleEvalAttempt $context $mod registerModuleEvalAttempt $context $mod
lassign [getPathToModule $mod {} $notfounderr] modfile modname modnamevr lassign [getPathToModule $mod {} $notfounderr] modfile modname modnamevr
# set a unique id to record messages related to this evaluation. # set a unique id to record messages related to this evaluation.
set msgrecid load-$modnamevr-[depthState modulename] set msgrecid load-$modnamevr-[depthState modulename]
# go to next module to load if not matching module found # go to next module to load if not matching module found
if {$modfile eq {}} { if {$modfile eq {}} {
skipping to change at line 1074 skipping to change at line 1153
} }
} }
# loading visibility depends on hidden-loaded tag # loading visibility depends on hidden-loaded tag
set hidden [isModuleTagged $modnamevr hidden-loaded 1] set hidden [isModuleTagged $modnamevr hidden-loaded 1]
append-path LOADEDMODULES $modname append-path LOADEDMODULES $modname
# allow duplicate modfile entries for virtual modules # allow duplicate modfile entries for virtual modules
append-path --duplicates _LMFILES_ $modfile append-path --duplicates _LMFILES_ $modfile
# update cache arrays # update cache arrays
setLoadedModule $modname $modfile $uasked $modnamevr setLoadedModule $modname $modfile $uasked $modnamevr [expr {$modname\
in [getState refresh_qualified]}]
# register declared source-sh in environment # register declared source-sh in environment
if {[set modsrcsh [getLoadedSourceSh $modname 1]] ne {}} { if {[set modsrcsh [getLoadedSourceSh $modname 1]] ne {}} {
append-path __MODULES_LMSOURCESH $modsrcsh append-path __MODULES_LMSOURCESH $modsrcsh
} }
# register declared conflict in environment # register declared conflict in environment
if {[set modcon [getLoadedConflict $modname 1]] ne {}} { if {[set modcon [getLoadedConflict $modname 1]] ne {}} {
append-path __MODULES_LMCONFLICT $modcon append-path __MODULES_LMCONFLICT $modcon
} }
skipping to change at line 1109 skipping to change at line 1189
} }
# declare the tags of this module # declare the tags of this module
if {[set modtag [getExportTagList $modnamevr 1]] ne {}} { if {[set modtag [getExportTagList $modnamevr 1]] ne {}} {
append-path __MODULES_LMTAG $modtag append-path __MODULES_LMTAG $modtag
} }
if {[set modtag [getExtraTagList $modnamevr 1]] ne {}} { if {[set modtag [getExtraTagList $modnamevr 1]] ne {}} {
append-path __MODULES_LMEXTRATAG $modtag append-path __MODULES_LMEXTRATAG $modtag
} }
# declare module qualified for refresh evaluation
if {[isModuleRefreshQualified $modname]} {
append-path __MODULES_LMREFRESH $modname
}
# Load phase of dependent module reloading. These modules can adapt # Load phase of dependent module reloading. These modules can adapt
# now that mod is seen loaded. Except if switch action ongoing (DepRe # now that mod is seen loaded. Except if switch action ongoing (DepRe
# load phase will occur from switch) # load phase will occur from switch)
if {[getConf auto_handling] && [llength $deprelist] > 0 && ![info\ if {[getConf auto_handling] && [llength $deprelist] > 0 && ![info\
exists swprocessing]} { exists swprocessing]} {
reloadModuleListLoadPhase deprelist $depreisuasked $deprevr\ reloadModuleListLoadPhase deprelist $depreisuasked $deprevr\
$depreextratag [getState force] {Reload of dependent _MOD_\ $depreextratag [getState force] {Reload of dependent _MOD_\
failed} depre failed} depre
} }
skipping to change at line 1169 skipping to change at line 1254
} }
popMsgRecordId popMsgRecordId
if {$errCode == 0} { if {$errCode == 0} {
set loadok 1 set loadok 1
} }
} }
lpopState mode lpopState mode
# raise error if no module has been loaded or has produced an error during # raise error if no module has been loaded or has produced an error during
# its load attempt in case of load-any sub-command # its load attempt in case of top-level load-any sub-command
if {!$ret && !$loadok && $context eq {load} && [currentState\ if {!$ret && !$loadok && $context eq {load} && $loadany} {
any_modulefile]} {
knerror "No module has been loaded" knerror "No module has been loaded"
} }
return $ret return $ret
} }
proc cmdModuleUnload {context match auto force onlyureq onlyndep args} { proc cmdModuleUnload {context match auto force onlyureq onlyndep args} {
reportDebug "unloading $args (context=$context, match=$match, auto=$auto,\ reportDebug "unloading $args (context=$context, match=$match, auto=$auto,\
force=$force, onlyureq=$onlyureq, onlyndep=$onlyndep)" force=$force, onlyureq=$onlyureq, onlyndep=$onlyndep)"
skipping to change at line 1257 skipping to change at line 1341
continue continue
} }
if {$onlyureq && ![isModuleUnloadable $modname]} { if {$onlyureq && ![isModuleUnloadable $modname]} {
reportDebug "$modname ($modfile) is required by loaded module or\ reportDebug "$modname ($modfile) is required by loaded module or\
asked by user" asked by user"
continue continue
} }
if {[isModuleEvalFailed unload $modnamevr]} { if {[isModuleEvalFailed unload $modnamevr]} {
reportDebug "$modnamevr ($modfile) unload was already tried and failed" reportDebug "$modnamevr ($modfile) unload was already tried and\
failed"
# nullify this evaluation attempt to avoid duplicate issue report # nullify this evaluation attempt to avoid duplicate issue report
unregisterModuleEvalAttempt $context $mod unregisterModuleEvalAttempt $context $mod
continue continue
} }
# register record message unique id (now we know mod will be evaluated) # register record message unique id (now we know mod will be evaluated)
pushMsgRecordId $msgrecid pushMsgRecordId $msgrecid
# record evaluation attempt on actual module name # record evaluation attempt on actual module name
registerModuleEvalAttempt $context $modnamevr registerModuleEvalAttempt $context $modnamevr
skipping to change at line 1282 skipping to change at line 1367
1] [getExportTagList $modname] 1] [getExportTagList $modname]
pushSettings pushSettings
if {[set errCode [catch { if {[set errCode [catch {
# error if unloading module violates a registered prereq # error if unloading module violates a registered prereq
# and auto handling mode is disabled # and auto handling mode is disabled
set prereq_list [getDependentLoadedModuleList [list $modname]] set prereq_list [getDependentLoadedModuleList [list $modname]]
if {[llength $prereq_list] > 0 && (![getConf auto_handling] ||\ if {[llength $prereq_list] > 0 && (![getConf auto_handling] ||\
!$auto)} { !$auto)} {
# force mode should not affect if we only look for mods w/o dep # force mode should not affect if we only look for mods w/o dep
##nagelfar ignore Found constant
if {([getState force] || $force) && !$onlyndep} { if {([getState force] || $force) && !$onlyndep} {
# in case unload is called for a DepRe mechanism do not warn # in case unload is called for a DepRe mechanism do not warn
# about prereq violation enforced as it is due to the dependent # about prereq violation enforced as it is due to the dependent
# module which is already in a violation state # module which is already in a violation state
# warn in case of a purge # warn in case of a purge
if {$auto || !$force || [currentState commandname] eq {purge}} { if {$auto || !$force || [currentState commandname] eq\
{purge}} {
reportWarning [getDepLoadedMsg $prereq_list] reportWarning [getDepLoadedMsg $prereq_list]
} }
} else { } else {
set errlocalreport 1 set errlocalreport 1
# exit treatment but no need to set return code to error if # exit treatment but no need to set return code to error if
# called from a 'module unload' command in a modulefile in a # called from a 'module unload' command in a modulefile in a
# load evaluation mode, as set conflict will raise error at end # load evaluation mode, as set conflict will raise error at end
# of modulefile evaluation # of modulefile evaluation
if {$onlyndep} { if {$onlyndep} {
set errharmless 1 set errharmless 1
skipping to change at line 1313 skipping to change at line 1400
} }
if {[getConf auto_handling] && $auto} { if {[getConf auto_handling] && $auto} {
# compute lists of modules to update due to modname unload prior # compute lists of modules to update due to modname unload prior
# unload to get requirement info before it vanishes # unload to get requirement info before it vanishes
# DepUn: Dependent to Unload (modules actively requiring modname # DepUn: Dependent to Unload (modules actively requiring modname
# or a module part of this DepUn batch) # or a module part of this DepUn batch)
set depunnpolist [getDependentLoadedModuleList [list $modname] 1\ set depunnpolist [getDependentLoadedModuleList [list $modname] 1\
0 1 0] 0 1 0]
set depunlist [getDependentLoadedModuleList [list $modname] 1 0 0 0] set depunlist [getDependentLoadedModuleList [list $modname] 1 0 0\
0]
# look at both regular dependencies or No Particular Order # look at both regular dependencies or No Particular Order
# dependencies: use NPO result if situation can be healed with NPO # dependencies: use NPO result if situation can be healed with NPO
# dependencies, which will be part of DepRe list to restore the # dependencies, which will be part of DepRe list to restore the
# correct loading order for them # correct loading order for them
if {[llength $depunnpolist] <= [llength $depunlist]} { if {[llength $depunnpolist] <= [llength $depunlist]} {
set depunlist $depunnpolist set depunlist $depunnpolist
} }
reportDebug "depun mod list is '$depunlist'" reportDebug "depun mod list is '$depunlist'"
# do not check for UReqUn mods coming from DepUn modules as these # do not check for UReqUn mods coming from DepUn modules as these
skipping to change at line 1357 skipping to change at line 1445
{*}$depunlist {*}$deprelist] 1] {*}$depunlist {*}$deprelist] 1]
set depunlist {} set depunlist {}
} }
# Reload of all DepRe mods, as they may adapt from the mod unloads # Reload of all DepRe mods, as they may adapt from the mod unloads
# happening here. First perform unload phase of the reload, prior # happening here. First perform unload phase of the reload, prior
# mod unloads to ensure these dependent mods are unloaded with the # mod unloads to ensure these dependent mods are unloaded with the
# same loaded prereq as when they were loaded. Avoid modules not # same loaded prereq as when they were loaded. Avoid modules not
# satisfying their constraint. # satisfying their constraint.
if {[llength $deprelist] > 0} { if {[llength $deprelist] > 0} {
##nagelfar ignore +2 Found constant
lassign [reloadModuleListUnloadPhase deprelist [getState\ lassign [reloadModuleListUnloadPhase deprelist [getState\
force] {Unload of dependent _MOD_ failed} depun]\ force] {Unload of dependent _MOD_ failed} depun]\
depreisuasked deprevr depreextratag depreisuasked deprevr depreextratag
} }
# DepUn modules unload prior main mod unload # DepUn modules unload prior main mod unload
if {[llength $depunlist] > 0} { if {[llength $depunlist] > 0} {
foreach unmod [lreverse $depunlist] { foreach unmod [lreverse $depunlist] {
##nagelfar ignore Found constant
if {[cmdModuleUnload depun match 0 0 0 0 $unmod]} { if {[cmdModuleUnload depun match 0 0 0 0 $unmod]} {
# stop if one unload fails unless force mode enabled # stop if one unload fails unless force mode enabled
set errMsg "Unload of dependent [getModuleDesignation\ set errMsg "Unload of dependent [getModuleDesignation\
loaded $unmod] failed" loaded $unmod] failed"
##nagelfar ignore Found constant
if {[getState force] || $force} { if {[getState force] || $force} {
reportWarning $errMsg 1 reportWarning $errMsg 1
} else { } else {
knerror $errMsg knerror $errMsg
} }
} }
} }
} }
} }
# register this evaluation on the main one that triggered it (prior # register this evaluation on the main one that triggered it (prior
# unload evaluation to report correct order with other evaluations) # unload evaluation to report correct order with other evaluations)
registerModuleEval $context $msgrecid registerModuleEval $context $msgrecid
# no need to update modnamevr and tags after evaluation as these # no need to update modnamevr and tags after evaluation as these
# information were already complete in persistent environment # information were already complete in persistent environment
##nagelfar ignore Suspicious variable name
if {[execute-modulefile $modfile $modname $modnamevr $mod 0 0]} { if {[execute-modulefile $modfile $modname $modnamevr $mod 0 0]} {
break break
} }
# unloading visibility depends on hidden-loaded tag # unloading visibility depends on hidden-loaded tag
set hidden [isModuleTagged $modname hidden-loaded 1] set hidden [isModuleTagged $modname hidden-loaded 1]
# module was asked by user if tagged loaded instead of auto-loaded # module was asked by user if tagged loaded instead of auto-loaded
set uasked [isModuleTagged $modname loaded 1] set uasked [isModuleTagged $modname loaded 1]
# unset module from list of loaded modules qualified for refresh eval
if {[isModuleRefreshQualified $modname]} {
remove-path __MODULES_LMREFRESH $modname
}
# get module position in loaded list to remove corresponding loaded # get module position in loaded list to remove corresponding loaded
# modulefile (entry at same position in _LMFILES_) # modulefile (entry at same position in _LMFILES_)
# need the unfiltered loaded module list to get correct index # need the unfiltered loaded module list to get correct index
set lmidx [lsearch -exact [getLoadedModuleList 0] $modname] set lmidx [lsearch -exact [getLoadedModulePropertyList name 0]\
$modname]
remove-path LOADEDMODULES $modname remove-path LOADEDMODULES $modname
remove-path --index _LMFILES_ $lmidx remove-path --index _LMFILES_ $lmidx
# update cache arrays # update cache arrays
unsetLoadedModule $modname $modfile unsetLoadedModule $modname $modfile
# unregister declared source-sh # unregister declared source-sh
if {[set modsrcsh [getLoadedSourceSh $modname 1]] ne {}} { if {[set modsrcsh [getLoadedSourceSh $modname 1]] ne {}} {
remove-path __MODULES_LMSOURCESH $modsrcsh remove-path __MODULES_LMSOURCESH $modsrcsh
} }
unsetLoadedSourceSh $modname unsetLoadedSourceSh $modname
skipping to change at line 1464 skipping to change at line 1562
unsetModuleExtraTag $modnamevr {*}$extratag_list unsetModuleExtraTag $modnamevr {*}$extratag_list
} }
} }
if {[getConf auto_handling] && $auto} { if {[getConf auto_handling] && $auto} {
# UReqUn modules unload now DepUn+main mods are unloaded # UReqUn modules unload now DepUn+main mods are unloaded
if {[llength $urequnlist] > 0} { if {[llength $urequnlist] > 0} {
set urequnlist [lreverse $urequnlist] set urequnlist [lreverse $urequnlist]
for {set i 0} {$i < [llength $urequnlist]} {incr i 1} { for {set i 0} {$i < [llength $urequnlist]} {incr i 1} {
set unmod [lindex $urequnlist $i] set unmod [lindex $urequnlist $i]
##nagelfar ignore Found constant
if {[cmdModuleUnload urequn match 0 0 0 0 $unmod]} { if {[cmdModuleUnload urequn match 0 0 0 0 $unmod]} {
# just warn if UReqUn module cannot be unloaded, main # just warn if UReqUn module cannot be unloaded, main
# unload process continues, just the UReqUn modules that # unload process continues, just the UReqUn modules that
# are required by unmod (whose unload failed) are # are required by unmod (whose unload failed) are
# withdrawn from UReqUn module list # withdrawn from UReqUn module list
reportWarning "Unload of useless requirement\ reportWarning "Unload of useless requirement\
[getModuleDesignation loaded $unmod] failed" 1 [getModuleDesignation loaded $unmod] failed" 1
lassign [getDiffBetweenList $urequnlist\ lassign [getDiffBetweenList $urequnlist\
[getRequiredLoadedModuleList [list $unmod]]]\ [getRequiredLoadedModuleList [list $unmod]]]\
urequnlist urequnlist
} }
} }
} }
# DepRe modules load phase now DepUn+UReqUn+main mods are unloaded # DepRe modules load phase now DepUn+UReqUn+main mods are unloaded
# except if a switch action is ongoing as this DepRe load phase # except if a switch action is ongoing as this DepRe load phase
# will occur after the new mod load # will occur after the new mod load
if {[llength $deprelist] > 0 && ![info exists swprocessing]} { if {[llength $deprelist] > 0 && ![info exists swprocessing]} {
##nagelfar ignore +2 Found constant
reloadModuleListLoadPhase deprelist $depreisuasked $deprevr\ reloadModuleListLoadPhase deprelist $depreisuasked $deprevr\
$depreextratag [getState force] {Reload of dependent _MOD_\ $depreextratag [getState force] {Reload of dependent _MOD_\
failed} depre failed} depre
} }
} }
# consider evaluation hidden if hidden loaded module was auto loaded # consider evaluation hidden if hidden loaded module was auto loaded
# and no specific messages are recorded for this evaluation # and no specific messages are recorded for this evaluation
if {$hidden && !$uasked && ![isMsgRecorded]} { if {$hidden && !$uasked && ![isMsgRecorded]} {
registerModuleEvalHidden $context $msgrecid registerModuleEvalHidden $context $msgrecid
skipping to change at line 1540 skipping to change at line 1640
proc cmdModulePurge {} { proc cmdModulePurge {} {
# create an eval id to track successful/failed module evaluations # create an eval id to track successful/failed module evaluations
pushMsgRecordId purge-[depthState modulename] 0 pushMsgRecordId purge-[depthState modulename] 0
# unload one by one to ensure same behavior whatever auto_handling state # unload one by one to ensure same behavior whatever auto_handling state
# force it to handle loaded modules in violation state # force it to handle loaded modules in violation state
# remove dependent modules if force mode enabled # remove dependent modules if force mode enabled
set onlyndep [expr {![getState force]}] set onlyndep [expr {![getState force]}]
cmdModuleUnload unload match 0 1 0 $onlyndep {*}[lreverse\ cmdModuleUnload unload match 0 1 0 $onlyndep {*}[lreverse\
[getLoadedModuleList]] [getLoadedModulePropertyList name]]
popMsgRecordId 0 popMsgRecordId 0
} }
proc cmdModuleReload {args} { proc cmdModuleReload {args} {
# reload all loaded modules if no module list passed # reload all loaded modules if no module list passed
if {[llength $args] == 0} { if {[llength $args] == 0} {
set lmlist [getLoadedModuleList] set lmlist [getLoadedModulePropertyList name]
} else { } else {
set lmlist $args set lmlist $args
} }
reportDebug "reloading $lmlist" reportDebug "reloading $lmlist"
# create an eval id to track successful/failed module evaluations # create an eval id to track successful/failed module evaluations
pushMsgRecordId reload-[depthState modulename] 0 pushMsgRecordId reload-[depthState modulename] 0
# no reload of all loaded modules attempt if constraints are violated # no reload of all loaded modules attempt if constraints are violated
if {[llength $args] == 0 && ![areModuleConstraintsSatisfied]} { if {[llength $args] == 0 && ![areModuleConstraintsSatisfied]} {
skipping to change at line 1596 skipping to change at line 1696
setState inhibit_errreport 0 setState inhibit_errreport 0
set display_list {} set display_list {}
foreach name [lsort -dictionary [array names ::g_moduleAlias]] { foreach name [lsort -dictionary [array names ::g_moduleAlias]] {
# exclude hidden aliases from result # exclude hidden aliases from result
if {![isModuleHidden $name]} { if {![isModuleHidden $name]} {
lappend display_list "[sgr al $name] -> $::g_moduleAlias($name)" lappend display_list "[sgr al $name] -> $::g_moduleAlias($name)"
} }
} }
displayElementList Aliases hi sepline 1 0 $display_list displayElementList Aliases hi sepline 1 0 0 $display_list
set display_list {} set display_list {}
foreach name [lsort -dictionary [array names ::g_moduleVersion]] { foreach name [lsort -dictionary [array names ::g_moduleVersion]] {
# exclude hidden versions or versions targeting an hidden module # exclude hidden versions or versions targeting an hidden module
if {![isModuleHidden $name] && ![isModuleHidden\ if {![isModuleHidden $name] && ![isModuleHidden\
$::g_moduleVersion($name)]} { $::g_moduleVersion($name)]} {
lappend display_list "[sgr sy $name] -> $::g_moduleVersion($name)" lappend display_list "[sgr sy $name] -> $::g_moduleVersion($name)"
} }
} }
displayElementList Versions hi sepline 1 0 $display_list displayElementList Versions hi sepline 1 0 0 $display_list
} }
proc cmdModuleAvail {show_oneperline show_mtime show_filter search_filter\ proc cmdModuleAvail {show_oneperline show_mtime show_filter search_filter\
search_match args} { search_match args} {
if {[llength $args] == 0} { if {[llength $args] == 0} {
lappend args * lappend args *
} }
if {$show_mtime || $show_oneperline} { if {$show_mtime || $show_oneperline} {
set one_per_line 1 set one_per_line 1
skipping to change at line 1643 skipping to change at line 1743
# consolidate search filters # consolidate search filters
lappend search_filter $search_match wild lappend search_filter $search_match wild
set search_rc_filter $search_filter set search_rc_filter $search_filter
lappend search_rc_filter rc_alias_only lappend search_rc_filter rc_alias_only
# disable error reporting to avoid modulefile errors # disable error reporting to avoid modulefile errors
# to mix with avail results # to mix with avail results
inhibitErrorReport inhibitErrorReport
foreach mod $args { foreach mod $args {
set search_queries [list $mod]
array unset mod_list array unset mod_list
# look if aliases have been defined in the global or user-specific # look if aliases have been defined in the global or user-specific
# modulerc and display them if any in a dedicated list # modulerc and display them if any in a dedicated list
array set mod_list [getModules {} $mod $show_mtime $search_rc_filter\ array set mod_list [getModules {} $mod $show_mtime $search_rc_filter\
$show_filter] $show_filter]
if {$report_modulepath} { if {$report_modulepath} {
reportModules $mod {global/user modulerc} hi $hstyle $show_mtime 0\ reportModules $search_queries {global/user modulerc} hi $hstyle\
$one_per_line $theader_cols hidden-loaded $show_mtime 0 $one_per_line $theader_cols hidden-loaded
} }
foreach dir [getModulePathList exiterronundef] { foreach dir [getModulePathList exiterronundef] {
if {$report_modulepath} { if {$report_modulepath} {
array unset mod_list array unset mod_list
# get module list (process full dir content and do not exit when # get module list (process full dir content and do not exit when
# err is raised from a modulerc) # err is raised from a modulerc)
array set mod_list [getModules $dir $mod $show_mtime\ array set mod_list [getModules $dir $mod $show_mtime\
$search_filter $show_filter] $search_filter $show_filter]
reportModules $mod $dir mp $hstyle $show_mtime 0 $one_per_line\ reportModules $search_queries $dir mp $hstyle $show_mtime 0\
$theader_cols hidden-loaded $one_per_line $theader_cols hidden-loaded
} else { } else {
# add result if not already added from an upper priority modpath # add result if not already added from an upper priority modpath
foreach {elt props} [getModules $dir $mod $show_mtime\ foreach {elt props} [getModules $dir $mod $show_mtime\
$search_filter $show_filter] { $search_filter $show_filter] {
if {![info exists mod_list($elt)]} { if {![info exists mod_list($elt)]} {
set mod_list($elt) $props set mod_list($elt) $props
} }
} }
} }
} }
# no report by modulepath, mix all aggregated results # no report by modulepath, mix all aggregated results
if {!$report_modulepath} { if {!$report_modulepath} {
reportModules $mod noheader {} {} $show_mtime 0 $one_per_line\ reportModules $search_queries noheader {} {} $show_mtime 0\
$theader_cols hidden-loaded $one_per_line $theader_cols hidden-loaded
} }
} }
# display output key # display output key
if {!$show_mtime && ![isStateEqual report_format json] && [isEltInReport\ if {!$show_mtime && ![isStateEqual report_format json] && [isEltInReport\
key]} { key]} {
displayKey displayKey
} }
setState inhibit_errreport 0 setState inhibit_errreport 0
skipping to change at line 1759 skipping to change at line 1860
# define path command to call # define path command to call
set pathcmd [expr {$pos eq {remove} ? {unload-path} : {add-path}}] set pathcmd [expr {$pos eq {remove} ? {unload-path} : {add-path}}]
# by-pass any reference counter in case use is called from top level # by-pass any reference counter in case use is called from top level
# not to increase reference counter if paths are already defined # not to increase reference counter if paths are already defined
if {[isTopEvaluation]} { if {[isTopEvaluation]} {
lappend optlist --ignore-refcount lappend optlist --ignore-refcount
} }
if {[isTopEvaluation]} { if {[isTopEvaluation]} {
##nagelfar ignore Found constant
lappendState mode load lappendState mode load
} }
$pathcmd $pos-path $mode $pos {*}$optlist MODULEPATH {*}$pathlist $pathcmd $pos-path $mode $pos {*}$optlist MODULEPATH {*}$pathlist
if {[isTopEvaluation]} { if {[isTopEvaluation]} {
##nagelfar ignore Found constant
lpopState mode lpopState mode
} }
} }
} }
} }
proc cmdModuleUse {mode pos args} { proc cmdModuleUse {mode pos args} {
if {$mode eq {unload}} { if {$mode eq {unload}} {
set pos remove set pos remove
} }
skipping to change at line 1817 skipping to change at line 1920
} }
if {![info exists ::env(LOADEDMODULES)]} { if {![info exists ::env(LOADEDMODULES)]} {
setenv LOADEDMODULES {} setenv LOADEDMODULES {}
} }
# initialize user environment if found undefined (both MODULEPATH and # initialize user environment if found undefined (both MODULEPATH and
# LOADEDMODULES empty) # LOADEDMODULES empty)
if {[get-env MODULEPATH] eq {} && [get-env LOADEDMODULES] eq {}} { if {[get-env MODULEPATH] eq {} && [get-env LOADEDMODULES] eq {}} {
# set modpaths defined in modulespath config file if it exists # set modpaths defined in modulespath config file if it exists
# use .modulespath file in initdir if conf file are located in this dir # use .modulespath file in initdir if conf file are located in this dir
if {[file readable @modulespath@]} { if {[file readable {@modulespath@}]} {
set fdata [split [readFile @modulespath@] \n] set fdata [split [readFile {@modulespath@}] \n]
foreach fline $fdata { foreach fline $fdata {
if {[regexp {^\s*(.*?)\s*(#.*|)$} $fline match patharg] == 1\ if {[regexp {^\s*(.*?)\s*(#.*|)$} $fline match patharg] == 1\
&& $patharg ne {}} { && $patharg ne {}} {
foreach path [split $patharg :] { foreach path [split $patharg :] {
# resolve path directory in case wildcard character used # resolve path directory in case wildcard character used
set globlist [glob -types d -nocomplain $path] set globlist [glob -types d -nocomplain $path]
if {[llength $globlist] == 0} { if {[llength $globlist] == 0} {
lappend pathlist $path lappend pathlist $path
} else { } else {
lappend pathlist {*}$globlist lappend pathlist {*}$globlist
skipping to change at line 1840 skipping to change at line 1943
} }
} }
} }
if {[info exists pathlist]} { if {[info exists pathlist]} {
cmdModuleUse load append {*}$pathlist cmdModuleUse load append {*}$pathlist
} }
} }
# source initialization initrc after modulespaths if it exists # source initialization initrc after modulespaths if it exists
# use modulerc file in initdir if conf files are located in this dir # use modulerc file in initdir if conf files are located in this dir
if {[file exists @initrc@]} { if {[file exists {@initrc@}]} {
lappendState commandname source lappendState commandname source
cmdModuleSource load @initrc@ cmdModuleSource load {@initrc@}
lpopState commandname lpopState commandname
} }
# record what has just been loaded in the virtual init collection
setenv __MODULES_LMINIT [getLoadedInit]
# if user environment is already initialized, refresh the already loaded # if user environment is already initialized, refresh the already loaded
# modules unless if environment is inconsistent # modules unless if environment is inconsistent
} elseif {![catch {cacheCurrentModules}]} { } elseif {![catch {cacheCurrentModules}]} {
cmdModuleRefresh cmdModuleRefresh
} }
# default MODULESHOME # default MODULESHOME
setenv MODULESHOME [getConf home] setenv MODULESHOME [getConf home]
# append dir where to find module function for ksh (to get it defined in # append dir where to find module function for ksh (to get it defined in
# interactive and non-interactive sub-shells). also applies for shells # interactive and non-interactive sub-shells). also applies for shells
# listed in shells_with_ksh_fpath conf # listed in shells_with_ksh_fpath conf
if {[getState shell] in [list {*}[split [getConf shells_with_ksh_fpath] :]\ if {[getState shell] in [list {*}[split [getConf shells_with_ksh_fpath] :]\
ksh]} { ksh]} {
append-path FPATH @initdir@/ksh-functions append-path FPATH {@initdir@/ksh-functions}
} }
# define Modules init script as shell startup file # define Modules init script as shell startup file
if {[getConf set_shell_startup] && [getState shelltype] in [list sh csh\ if {[getConf set_shell_startup] && [getState shelltype] in [list sh csh\
fish]} { fish]} {
# setup ENV variables to get module defined in sub-shells (works for # setup ENV variables to get module defined in sub-shells (works for
# 'sh' and 'ksh' in interactive mode and 'sh' (zsh-compat), 'bash' and # 'sh' and 'ksh' in interactive mode and 'sh' (zsh-compat), 'bash' and
# 'ksh' (zsh-compat) in non-interactive mode. # 'ksh' (zsh-compat) in non-interactive mode.
setenv ENV @initdir@/profile.sh setenv ENV {@initdir@/profile.sh}
setenv BASH_ENV @initdir@/bash setenv BASH_ENV {@initdir@/bash}
}
if {[getState shelltype] in {sh csh fish}} {
# add Modules bin directory to PATH if enabled but do not increase ref
# counter variable if already there
@setbinpath@if {{@bindir@} ni [split [get-env PATH] :]} {
@setbinpath@@appendbinpath@-path --ignore-refcount PATH {@bindir@}
@setbinpath@}
# add Modules man directory to MANPATH if enabled
# initialize MANPATH if not set with a value that preserves manpath
# system configuration even after addition of paths to this variable by
# modulefiles
@setmanpath@set manpath {}
# use manpath tool if found at configure step, use MANPATH otherwise
##nagelfar ignore +2 Too long line
##nagelfar ignore Found constant
@setmanpath@@usemanpath@catch {set manpath [exec -ignorestderr 2>/dev/null
manpath]}
@setmanpath@@notusemanpath@if {[info exists ::env(MANPATH)]} {
@setmanpath@@notusemanpath@ set manpath $::env(MANPATH)
@setmanpath@@notusemanpath@}
@setmanpath@if {{@mandir@} ni [split $manpath :]} {
@setmanpath@ if {![info exists ::env(MANPATH)]} {
@setmanpath@ append-path MANPATH {}
@setmanpath@ # ensure no duplicate ':' is set
@setmanpath@ } elseif {[get-env MANPATH] eq {:}} {
@setmanpath@ remove-path MANPATH {}
@setmanpath@ append-path MANPATH {}
@setmanpath@ }
@setmanpath@ @appendmanpath@-path MANPATH {@mandir@}
@setmanpath@}
}
# source shell completion script if available, not installed in default
# completion locations and only if shell is interactive
if {[getState shell] in {@shellcompsource@} && [getState is_stderr_tty]} {
set compfile "@initdir@/[getState shell]_completion"
if {[file readable $compfile]} {
putsModfileCmd dummy "source '$compfile';"
}
} }
# clear in progress flag # clear in progress flag
unsetenv __MODULES_AUTOINIT_INPROGRESS unsetenv __MODULES_AUTOINIT_INPROGRESS
lpopState mode lpopState mode
} }
proc cmdModuleInit {args} { proc cmdModuleInit {args} {
set init_cmd [lindex $args 0] set init_cmd [lindex $args 0]
skipping to change at line 2071 skipping to change at line 2217
report "Are you sure you want to clear all loaded modules!? \[n\] " 1 report "Are you sure you want to clear all loaded modules!? \[n\] " 1
flush [getState reportfd] flush [getState reportfd]
} }
# fetch stdin content even if not attached to terminal in case some # fetch stdin content even if not attached to terminal in case some
# content has been piped to this channel # content has been piped to this channel
set doit [gets stdin] set doit [gets stdin]
} }
# should be confirmed or forced to proceed # should be confirmed or forced to proceed
if {[string equal -nocase -length 1 $doit y] || [getState force]} { if {[string equal -nocase -length 1 $doit y] || [getState force]} {
set vartoclear [list LOADEDMODULES __MODULES_LMALTNAME\
__MODULES_LMCONFLICT __MODULES_LMPREREQ __MODULES_LMSOURCESH \
__MODULES_LMTAG __MODULES_LMEXTRATAG __MODULES_LMVARIANT _LMFILES_]
# add any reference counter variable to the list to unset
lappend vartoclear {*}[array names ::env -glob __MODULES_SHARE_*]
# unset all Modules runtime variables
lappendState mode load lappendState mode load
foreach var $vartoclear { # unset all Modules runtime variables
unset-env $var foreach globvar [getModulesEnvVarGlobList 1] {
foreach var [array names ::env -glob $globvar] {
unset-env $var
}
} }
lpopState mode lpopState mode
} else { } else {
reportInfo "Modules runtime information were not cleared" reportInfo "Modules runtime information were not cleared"
} }
} }
proc cmdModuleState {args} { proc cmdModuleState {args} {
if {[llength $args] > 0} { if {[llength $args] > 0} {
set name [lindex $args 0] set name [lindex $args 0]
} }
if {[info exists name] && $name ni [concat [array names ::g_state_defs]\ if {[info exists name] && $name ni [concat [array names ::g_state_defs]\
[array names ::g_states]]} { [array names ::g_states]]} {
knerror "State '$name' does not exist" knerror "State '$name' does not exist"
} }
# report module version unless if called by cmdModuleConfig # report module version unless if called by cmdModuleConfig
if {[lindex [info level -1] 0] ne {cmdModuleConfig}} { if {[getCallingProcName] ne {cmdModuleConfig}} {
reportVersion reportVersion
reportSeparateNextContent reportSeparateNextContent
} }
displayTableHeader hi {State name} 24 {Value} 54 displayTableHeader hi {State name} 24 {Value} 54
# fetch specified state or all states # fetch specified state or all states
if {[info exists name]} { if {[info exists name]} {
if {$name in [array names ::g_state_defs]} { if {$name in [array names ::g_state_defs]} {
set stateval($name) [getState $name <undef> 1] set stateval($name) [getState $name <undef> 1]
skipping to change at line 2141 skipping to change at line 2282
reportSeparateNextContent reportSeparateNextContent
# only report specified state if any # only report specified state if any
if {[info exists name]} { if {[info exists name]} {
return return
} }
# report environment variable set related to Modules # report environment variable set related to Modules
displayTableHeader hi {Env. variable} 24 {Value} 54 displayTableHeader hi {Env. variable} 24 {Value} 54
set envvar_list {} set envvar_list {}
foreach var [list LOADEDMODULES _LMFILES_ MODULE* __MODULES_* *_module*] { foreach var [getModulesEnvVarGlobList] {
lappend envvar_list {*}[array names ::env -glob $var] lappend envvar_list {*}[array names ::env -glob $var]
} }
unset displist unset displist
foreach var [lsort -unique $envvar_list] { foreach var [lsort -unique $envvar_list] {
append displist [format {%-25s %s} $var $::env($var)] \n append displist [format {%-25s %s} $var $::env($var)] \n
} }
report $displist 1 report $displist 1
} }
proc cmdModuleConfig {dump_state args} { proc cmdModuleConfig {dump_state args} {
skipping to change at line 2235 skipping to change at line 2376
1]} { 1]} {
set validval 1 set validval 1
} else { } else {
reportErrorAndExit "Invalid value for configuration option\ reportErrorAndExit "Invalid value for configuration option\
'$name'\nValue should be an integer comprised between\ '$name'\nValue should be an integer comprised between\
[lindex $confvalid($name) 0] and [lindex\ [lindex $confvalid($name) 0] and [lindex\
$confvalid($name) 1]" $confvalid($name) 1]"
} }
} }
{} { {} {
##nagelfar ignore +2 Non static subcommand
if {([llength $confvalid($name)] == 1 && ![string is\ if {([llength $confvalid($name)] == 1 && ![string is\
$confvalid($name) -strict $value]) || ([llength\ $confvalid($name) -strict $value]) || ([llength\
$confvalid($name)] > 1 && $value ni $confvalid($name))} { $confvalid($name)] > 1 && $value ni $confvalid($name))} {
reportErrorAndExit "Valid values for configuration option\ reportErrorAndExit "Valid values for configuration option\
'$name' are: $confvalid($name)" '$name' are: $confvalid($name)"
} else { } else {
set validval 1 set validval 1
} }
} }
} }
skipping to change at line 2272 skipping to change at line 2414
overridden)} 54 overridden)} 54
# report all configs or just queried one # report all configs or just queried one
if {[info exists name]} { if {[info exists name]} {
set varlist [list $name] set varlist [list $name]
} else { } else {
set varlist [lsort [array names confval]] set varlist [lsort [array names confval]]
} }
foreach var $varlist { foreach var $varlist {
##nagelfar ignore +2 Suspicious variable name
set valrep [displayConfig $confval($var) $confvar($var) [info exists\ set valrep [displayConfig $confval($var) $confvar($var) [info exists\
::asked_$var] $confvtrans($var) [expr {$conflockable($var) eq {1}\ ::asked_$var] $confvtrans($var) [expr {$conflockable($var) eq {1}\
&& [isConfigLocked $var]}]] && [isConfigLocked $var]}]]
append displist [format {%-25s %s} $var $valrep] \n append displist [format {%-25s %s} $var $valrep] \n
} }
report $displist 1 report $displist 1
reportSeparateNextContent reportSeparateNextContent
if {$dump_state} { if {$dump_state} {
cmdModuleState cmdModuleState
skipping to change at line 2325 skipping to change at line 2468
} }
proc cmdModuleRefresh {} { proc cmdModuleRefresh {} {
lappendState mode refresh lappendState mode refresh
# create an eval id to track successful/failed module evaluations # create an eval id to track successful/failed module evaluations
pushMsgRecordId refresh-[depthState modulename] 0 pushMsgRecordId refresh-[depthState modulename] 0
# load variants from loaded modules # load variants from loaded modules
cacheCurrentModules cacheCurrentModules
foreach lm [getLoadedModuleList] { foreach lm [getLoadedModulePropertyList refresh] {
# prepare info to execute modulefile # prepare info to execute modulefile
set vrlist [getVariantList $lm 1] set vrlist [getVariantList $lm 1]
if {[llength $vrlist] > 0} { if {[llength $vrlist] > 0} {
lassign [parseModuleSpecification 0 $lm {*}$vrlist] lmvr lassign [parseModuleSpecification 0 $lm {*}$vrlist] lmvr
} else { } else {
set lmvr $lm set lmvr $lm
} }
set lmfile [getModulefileFromLoadedModule $lm] set lmfile [getModulefileFromLoadedModule $lm]
set taglist [getExportTagList $lm] set taglist [getExportTagList $lm]
skipping to change at line 2503 skipping to change at line 2646
popMsgRecordId popMsgRecordId
# indicates that new tags have been applied # indicates that new tags have been applied
set ret 2 set ret 2
} }
} }
return $ret return $ret
} }
proc cmdModuleLint {args} {
# stop if no linter defined
if {[llength [getConf tcl_linter]] == 0} {
knerror {No Tcl linter program configured}
}
# extract linter program name
set linter [file rootname [file tail [lindex [getConf tcl_linter] 0]]]
# build command line
set linter_mfile [getConf tcl_linter]
set linter_mrc [getConf tcl_linter]
set linter_gmrc [getConf tcl_linter]
# add module-specific syntax database in addition to regular Tcl one
@nagelfaraddons@if {$linter eq {nagelfar}} {
@nagelfaraddons@ lappend linter_mfile -s _\
@nagelfaraddons@ -s {@nagelfardatadir@/syntaxdb_modulefile.tcl}\
@nagelfaraddons@ -plugin {@nagelfardatadir@/plugin_modulefile.tcl}
@nagelfaraddons@ lappend linter_mrc -s _\
@nagelfaraddons@ -s {@nagelfardatadir@/syntaxdb_modulerc.tcl}\
@nagelfaraddons@ -plugin {@nagelfardatadir@/plugin_modulerc.tcl}
@nagelfaraddons@ lappend linter_gmrc -s _\
@nagelfaraddons@ -s {@nagelfardatadir@/syntaxdb_modulefile.tcl}\
@nagelfaraddons@ -plugin {@nagelfardatadir@/plugin_globalrc.tcl}
@nagelfaraddons@}
set global_rclist [getGlobalRcFileList]
set modfilelist {}
# fetch every available modulefiles if no argument provided
if {[llength $args] == 0} {
# add global RC files
foreach rc $global_rclist {
set tolint($rc) gmrc
}
inhibitErrorReport
foreach dir [getModulePathList exiterronundef] {
# fetch all existing rc file current user has access to
foreach {elt props} [findModules $dir * 0 0] {
switch -- [lindex $props 0] {
modulerc {
set tolint($dir/$elt) mrc
}
}
}
# collect all modulefile from dir that current user has access to
# getModules will reuse the result collected for findModules
foreach {elt props} [getModules $dir *] {
switch -- [lindex $props 0] {
modulefile - virtual {
set tolint([lindex $props 2]) mfile
}
}
}
}
setState inhibit_errreport 0
} else {
foreach mod $args {
lassign [getPathToModule $mod] modfile modname modnamevr
# error mesg has already been produced if mod not found or forbidden
if {$modfile ne {}} {
if {$modfile in $global_rclist} {
set mkind gmrc
} elseif {[file tail $modfile] in {.modulerc .version}} {
set mkind mrc
} else {
set mkind mfile
}
set tolint($modfile) $mkind
}
}
}
# execute linter program over every gathered file
foreach lintfile [lsort -dictionary [array names tolint]] {
# set a record message unique id and record modulefile title
set msgrecid lint-$lintfile
pushMsgRecordId $msgrecid
registerModuleDesignation $msgrecid $lintfile {} {}
##nagelfar ignore Suspicious variable name
if {[catch {set out [runCommand {*}[set linter_$tolint($lintfile)]\
$lintfile]} errMsg]} {
# re-throw error but as an external one (not as a module issue)
knerror $errMsg
}
# report linting messages
displayLinterOutput $linter $out
# report all lint messages for this modulefile
reportMsgRecord "Linting [getModuleDesignation $msgrecid {} 2]"
popMsgRecordId
}
}
proc cmdModuleModToSh {shell args} {
# save shell modulecmd is initialized to
##nagelfar ignore Found constant
setState modtosh_real_shell [getState shell]
# set shell and shellType states to mod-to-sh target value
if {$shell ni [getState supported_shells]} {
reportErrorAndExit "Unsupported shell type \'$shell\'"
}
##nagelfar ignore Found constant
setState shell $shell
unsetState shelltype
# silence message report (avoid mix with produced shell code) unless if
# a debugging mode is set
if {![isVerbosityLevel trace]} {
unsetConf verbosity
set ::asked_verbosity silent
}
# modulefile evaluation is done against mod-to-sh target shell which means
# module-info will return mod-to-sh shell value
return [cmdModuleLoad load 1 0 0 {} {*}$args]
# after evaluation, renderSettings will produce shell code for mod-to-sh
# target shell. modtosh_real_shell state helps to know that shell code has
# to be output on report message channel
}
proc cmdModuleReset {} {
# use reset_target_state configuration option to know the environment state
# to restore
if {[getConf reset_target_state] eq {__purge__}} {
cmdModulePurge
} else {
cmdModuleRestore [getConf reset_target_state]
}
}
proc cmdModuleStash {} {
# check if there is something to stash
if {[getConf reset_target_state] eq {__purge__}} {
# load tags from loaded modules
cacheCurrentModules
# current environment differs from initial 'purge' state when at least
# a module is loaded and it is not super-sticky and not sticky or force
# mode is enabled to allow sticky tag unload
set diff_from_init 0
foreach mod [getLoadedModulePropertyList name] {
if {![isModuleTagged $mod super-sticky 1] && (![isModuleTagged $mod\
sticky 1] || [getState force])} {
set diff_from_init 1
break
}
}
} else {
# compare current environment against initial collection to check if
# something differ
set coll [getConf reset_target_state]
# get corresponding collection or init, raise error if it does not exist
lassign [findCollections $coll exact 0 1] collfile colldesc
# fetch collection content and differences compared current environment
lassign [getDiffBetweenCurEnvAndColl $collfile $colldesc]\
coll_path_list coll_mod_list coll_tag_arrser coll_nuasked_list\
mod_to_unload mod_to_load path_to_unuse path_to_use is_tags_diff
array set coll_tag_arr $coll_tag_arrser
set diff_from_init [expr {[llength $mod_to_unload] > 0 || [llength\
$mod_to_load] > 0 || [llength $path_to_unuse] > 0 || [llength\
$path_to_use] > 0 || $is_tags_diff}]
}
if {!$diff_from_init} {
reportWarning {No specific environment to save}
return
}
# record current environment
cmdModuleSave stash-[clock milliseconds]
# restore initial environment
cmdModuleReset
}
proc cmdModuleStashpop {{stash 0}} {
# determine stash collection name from argument
set coll [getCollectionFromStash $stash]
# restore stash collection environment state
cmdModuleRestore $coll
# delete stash collection file
cmdModuleSaverm $coll
}
proc cmdModuleStashrm {{stash 0}} {
# determine stash collection name from argument
set coll [getCollectionFromStash $stash]
# delete stash collection file
cmdModuleSaverm $coll
}
proc cmdModuleStashshow {{stash 0}} {
# determine stash collection name from argument
set coll [getCollectionFromStash $stash]
# display stash collection file
cmdModuleSaveshow $coll
}
proc cmdModuleStashclear {} {
# get all stash collections (only from current target)
set collfile_list [findCollections stash-* glob 0 0 1 1]
# delete all stash collections starting from most recent
foreach collfile [lsort -decreasing $collfile_list] {
# extract collection name (without path and target extension)
set coll [file rootname [file tail $collfile]]
# delete stash collection file
cmdModuleSaverm $coll
}
}
proc cmdModuleStashlist {show_oneperline show_mtime} {
cmdModuleSavelist $show_oneperline $show_mtime {} stash-*
}
# ;;; Local Variables: *** # ;;; Local Variables: ***
# ;;; mode:tcl *** # ;;; mode:tcl ***
# ;;; End: *** # ;;; End: ***
# vim:set tabstop=3 shiftwidth=3 expandtab autoindent: # vim:set tabstop=3 shiftwidth=3 expandtab autoindent:
 End of changes. 81 change blocks. 
155 lines changed or deleted 525 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)