diff options
-rw-r--r-- | ChangeLog | 43 | ||||
-rw-r--r-- | library/auto.tcl | 262 | ||||
-rw-r--r-- | library/package.tcl | 252 | ||||
-rw-r--r-- | library/safe.tcl | 452 | ||||
-rw-r--r-- | library/tm.tcl | 214 |
5 files changed, 612 insertions, 611 deletions
@@ -1,13 +1,22 @@ +2009-07-26 Donal K. Fellows <dkf@users.sf.net> + + * library/auto.tcl (tcl_findLibrary, auto_mkindex): + * library/package.tcl (pkg_mkIndex, tclPkgUnknown, MacOSXPkgUnknown): + * library/safe.tcl (interpAddToAccessPath, interpDelete, AliasGlob): + (AliasSource, AliasLoad, AliasEncoding): + * library/tm.tcl (UnknownHandler): Simplify by swapping some [catch] + gymnastics for use of [try]. + 2009-07-26 Alexandre Ferrieux <ferrieux@users.sourceforge.net> - * tools/genStubs.tcl: Forced LF translation when generating .h's - to avoid spurious diffs when regenerating on a Windows box. + * tools/genStubs.tcl: Forced LF translation when generating .h's to + avoid spurious diffs when regenerating on a Windows box. 2009-07-26 Jan Nijtmans <nijtmans@users.sf.net> - * win/Makefile.in: [Bug 2827066] msys build --enable-symbols broken - * win/tcl.m4 And modified the same for unicows.dll, as a - * win/configure preparation for [Enh 2819611] + * win/Makefile.in: [Bug 2827066]: msys build --enable-symbols broken + * win/tcl.m4: And modified the same for unicows.dll, as a + * win/configure: preparation for [Enh 2819611]. 2009-07-25 Donal K. Fellows <dkf@users.sf.net> @@ -52,9 +61,9 @@ 2009-07-21 Kevin B. Kenny <kennykb@acm.org> - * library/tzdata/Asia/Dhaka: + * library/tzdata/Asia/Dhaka: * library/tzdata/Indian/Mauritius: Olson's tzdata2009k. - + 2009-07-20 Donal K. Fellows <dkf@users.sf.net> * generic/tclCmdMZ.c (StringIsCmd): Reorganize so that [string is] is @@ -109,13 +118,13 @@ * generic/tclCmdMZ.c (Tcl_SwitchObjCmd): * tests/switch.test (switch-15.1): [Bug 2821401]: Make non-bytecoded [switch] command aware of NRE. - + 2009-07-13 Andreas Kupries <andreask@activestate.com> * generic/tclCompile.c (TclInitCompileEnv, EnterCmdWordIndex) (TclCleanupByteCode, TclCompileScript): - * generic/tclExecute.c (TclCompileObj, TclExecuteByteCode): - * tclCompile.h (ExtCmdLoc): + * generic/tclExecute.c (TclCompileObj, TclExecuteByteCode): + * tclCompile.h (ExtCmdLoc): * tclInt.h (ExtIndex, CFWordBC, CmdFrame): * tclBasic.c (DeleteInterpProc, TclArgumentBCEnter) (TclArgumentBCRelease, TclArgumentGet, SAVE_CONTEXT) @@ -183,8 +192,8 @@ * tests/zlib.test: ZlibTransformClose may be called with a NULL * generic/tclZlib.c: interpreter during finalization and - Tcl_SetChannelError requires a list. Added some tests to ensure - error propagation from the zlib library to the interp. + Tcl_SetChannelError requires a list. Added some tests to ensure error + propagation from the zlib library to the interp. 2009-07-09 Pat Thoyts <patthoyts@users.sourceforge.net> @@ -242,9 +251,9 @@ 2009-06-18 Donal K. Fellows <dkf@users.sf.net> * generic/tclCkalloc.c (MemoryCmd): [Bug 988703]: - * generic/tclObj.c (ObjData, TclFinalizeThreadObjects): Add - mechanism for discovering what Tcl_Objs are allocated when built - for memory debugging. Developed by Joe Mistachkin. + * generic/tclObj.c (ObjData, TclFinalizeThreadObjects): Add mechanism + for discovering what Tcl_Objs are allocated when built for memory + debugging. Developed by Joe Mistachkin. 2009-06-17 Alexandre Ferrieux <ferrieux@users.sourceforge.net> @@ -305,7 +314,7 @@ to the Tcl caller in the event of a syntax error, so did so. * generic/tclDate.c: bison 2.3 - + 2006-06-08 Kevin B. Kenny <kennykb@acm.org> * library/tzdata/Asia/Dhaka: New DST rule for Bangladesh. (Olson's @@ -333,7 +342,7 @@ * library/tzdata/Africa/Cairo: * library/tzdata/Asia/Amman: Olson's tzdata2009h. - + 2009-05-29 Andreas Kupries <andreask@activestate.com> * library/platform/platform.tcl: Fixed handling of cpu ia64, diff --git a/library/auto.tcl b/library/auto.tcl index 881e6b9..7d4c340 100644 --- a/library/auto.tcl +++ b/library/auto.tcl @@ -1,22 +1,22 @@ # auto.tcl -- # -# utility procs formerly in init.tcl dealing with auto execution -# of commands and can be auto loaded themselves. +# utility procs formerly in init.tcl dealing with auto execution of commands +# and can be auto loaded themselves. # -# RCS: @(#) $Id: auto.tcl,v 1.28 2006/11/03 00:34:52 hobbs Exp $ +# RCS: @(#) $Id: auto.tcl,v 1.29 2009/07/26 11:40:23 dkf Exp $ # # Copyright (c) 1991-1993 The Regents of the University of California. # Copyright (c) 1994-1998 Sun Microsystems, Inc. # -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# See the file "license.terms" for information on usage and redistribution of +# this file, and for a DISCLAIMER OF ALL WARRANTIES. # # auto_reset -- # -# Destroy all cached information for auto-loading and auto-execution, -# so that the information gets recomputed the next time it's needed. -# Also delete any commands that are listed in the auto-load index. +# Destroy all cached information for auto-loading and auto-execution, so that +# the information gets recomputed the next time it's needed. Also delete any +# commands that are listed in the auto-load index. # # Arguments: # None. @@ -32,18 +32,16 @@ proc auto_reset {} { unset -nocomplain ::auto_execs ::auto_index ::tcl::auto_oldpath if {[catch {llength $::auto_path}]} { set ::auto_path [list [info library]] - } else { - if {[info library] ni $::auto_path} { - lappend ::auto_path [info library] - } + } elseif {[info library] ni $::auto_path} { + lappend ::auto_path [info library] } } # tcl_findLibrary -- # # This is a utility for extensions that searches for a library directory -# using a canonical searching algorithm. A side effect is to source -# the initialization script and set a global library variable. +# using a canonical searching algorithm. A side effect is to source the +# initialization script and set a global library variable. # # Arguments: # basename Prefix of the directory name, (e.g., "tk") @@ -68,21 +66,25 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { # Do the canonical search - # 1. From an environment variable, if it exists. - # Placing this first gives the end-user ultimate control - # to work-around any bugs, or to customize. + # 1. From an environment variable, if it exists. Placing this first + # gives the end-user ultimate control to work-around any bugs, or + # to customize. if {[info exists env($enVarName)]} { lappend dirs $env($enVarName) } - # 2. In the package script directory registered within - # the configuration of the package itself. + # 2. In the package script directory registered within the + # configuration of the package itself. - if {[catch { + try { ::${basename}::pkgconfig get scriptdir,runtime - } value] == 0} { + } on ok value { lappend dirs $value + } on error {msg opts} { + if {![string match "invalid command name *" $msg]} { + return -options $opts $msg + } } # 3. Relative to auto_path directories. This checks relative to the @@ -90,8 +92,10 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { # auto_path that is not relative to the core library or binary paths. foreach d $::auto_path { lappend dirs [file join $d $basename$version] - if {$::tcl_platform(platform) eq "unix" - && $::tcl_platform(os) eq "Darwin"} { + if { + $::tcl_platform(platform) eq "unix" + && $::tcl_platform(os) eq "Darwin" + } then { # 4. On MacOSX, check the Resources/Scripts subdir too lappend dirs [file join $d $basename$version Resources Scripts] } @@ -102,8 +106,8 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { # ../../lib/foo1.0 (From bin/arch directory in install hierarchy) # ../library (From unix directory in build hierarchy) # - # Remaining locations are out of date (when relevant, they ought - # to be covered by the $::auto_path seach above) and disabled. + # Remaining locations are out of date (when relevant, they ought to be + # covered by the $::auto_path seach above) and disabled. # # ../../library (From unix/arch directory in build hierarchy) # ../../foo1.0.1/library @@ -126,10 +130,10 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { # uniquify $dirs in order array set seen {} foreach i $dirs { - # Take note that the [file normalize] below has been noted to - # cause difficulties for the freewrap utility. See Bug 1072136. - # Until freewrap resolves the matter, one might work around the - # problem by disabling that branch. + # Take note that the [file normalize] below has been noted to cause + # difficulties for the freewrap utility. See Bug 1072136. Until + # freewrap resolves the matter, one might work around the problem by + # disabling that branch. if {[interp issafe]} { set norm $i } else { @@ -144,16 +148,15 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { set the_library $i set file [file join $i $initScript] - # source everything when in a safe interpreter because - # we have a source command, but no file exists command + # source everything when in a safe interpreter because we have a + # source command, but no file exists command if {[interp issafe] || [file exists $file]} { if {![catch {uplevel #0 [list source $file]} msg opts]} { return - } else { - append errors "$file: $msg\n" - append errors [dict get $opts -errorinfo]\n } + append errors "$file: $msg\n" + append errors [dict get $opts -errorinfo]\n } } unset -nocomplain the_library @@ -168,28 +171,28 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { # ---------------------------------------------------------------------- # auto_mkindex # ---------------------------------------------------------------------- -# The following procedures are used to generate the tclIndex file -# from Tcl source files. They use a special safe interpreter to -# parse Tcl source files, writing out index entries as "proc" -# commands are encountered. This implementation won't work in a -# safe interpreter, since a safe interpreter can't create the -# special parser and mess with its commands. +# The following procedures are used to generate the tclIndex file from Tcl +# source files. They use a special safe interpreter to parse Tcl source +# files, writing out index entries as "proc" commands are encountered. This +# implementation won't work in a safe interpreter, since a safe interpreter +# can't create the special parser and mess with its commands. if {[interp issafe]} { return ;# Stop sourcing the file here } # auto_mkindex -- -# Regenerate a tclIndex file from Tcl source files. Takes as argument -# the name of the directory in which the tclIndex file is to be placed, -# followed by any number of glob patterns to use in that directory to -# locate all of the relevant files. +# Regenerate a tclIndex file from Tcl source files. Takes as argument the +# name of the directory in which the tclIndex file is to be placed, followed +# by any number of glob patterns to use in that directory to locate all of the +# relevant files. # # Arguments: # dir - Name of the directory in which to create an index. -# args - Any number of additional arguments giving the -# names of files within dir. If no additional -# are given auto_mkindex will look for *.tcl. + +# args - Any number of additional arguments giving the names of files +# within dir. If no additional are given auto_mkindex will look +# for *.tcl. proc auto_mkindex {dir args} { if {[interp issafe]} { @@ -198,7 +201,6 @@ proc auto_mkindex {dir args} { set oldDir [pwd] cd $dir - set dir [pwd] append index "# Tcl autoload index file, version 2.0\n" append index "# This file is generated by the \"auto_mkindex\" command\n" @@ -213,12 +215,12 @@ proc auto_mkindex {dir args} { auto_mkindex_parser::init foreach file [glob -- {*}$args] { - if {[catch {auto_mkindex_parser::mkindex $file} msg opts] == 0} { - append index $msg - } else { - cd $oldDir + try { + append index [auto_mkindex_parser::mkindex $file] + } on error {msg opts} { + cd $oldDir return -options $opts $msg - } + } } auto_mkindex_parser::cleanup @@ -228,8 +230,8 @@ proc auto_mkindex {dir args} { cd $oldDir } -# Original version of auto_mkindex that just searches the source -# code for "proc" at the beginning of the line. +# Original version of auto_mkindex that just searches the source code for +# "proc" at the beginning of the line. proc auto_mkindex_old {dir args} { set oldDir [pwd] @@ -280,9 +282,9 @@ proc auto_mkindex_old {dir args} { } # Create a safe interpreter that can be used to parse Tcl source files -# generate a tclIndex file for autoloading. This interp contains -# commands for things that need index entries. Each time a command -# is executed, it writes an entry out to the index file. +# generate a tclIndex file for autoloading. This interp contains commands for +# things that need index entries. Each time a command is executed, it writes +# an entry out to the index file. namespace eval auto_mkindex_parser { variable parser "" ;# parser used to build index @@ -334,10 +336,10 @@ namespace eval auto_mkindex_parser { # auto_mkindex_parser::mkindex -- # -# Used by the "auto_mkindex" command to create a "tclIndex" file for -# the given Tcl source file. Executes the commands in the file, and -# handles things like the "proc" command by adding an entry for the -# index file. Returns a string that represents the index file. +# Used by the "auto_mkindex" command to create a "tclIndex" file for the given +# Tcl source file. Executes the commands in the file, and handles things like +# the "proc" command by adding an entry for the index file. Returns a string +# that represents the index file. # # Arguments: # file Name of Tcl source file to be indexed. @@ -355,14 +357,13 @@ proc auto_mkindex_parser::mkindex {file} { set contents [read $fid] close $fid - # There is one problem with sourcing files into the safe - # interpreter: references like "$x" will fail since code is not - # really being executed and variables do not really exist. - # To avoid this, we replace all $ with \0 (literally, the null char) - # later, when getting proc names we will have to reverse this replacement, - # in case there were any $ in the proc name. This will cause a problem - # if somebody actually tries to have a \0 in their proc name. Too bad - # for them. + # There is one problem with sourcing files into the safe interpreter: + # references like "$x" will fail since code is not really being executed + # and variables do not really exist. To avoid this, we replace all $ with + # \0 (literally, the null char) later, when getting proc names we will + # have to reverse this replacement, in case there were any $ in the proc + # name. This will cause a problem if somebody actually tries to have a \0 + # in their proc name. Too bad for them. set contents [string map [list \$ \0] $contents] set index "" @@ -379,10 +380,10 @@ proc auto_mkindex_parser::mkindex {file} { # auto_mkindex_parser::hook command # -# Registers a Tcl command to evaluate when initializing the -# slave interpreter used by the mkindex parser. -# The command is evaluated in the master interpreter, and can -# use the variable auto_mkindex_parser::parser to get to the slave +# Registers a Tcl command to evaluate when initializing the slave interpreter +# used by the mkindex parser. The command is evaluated in the master +# interpreter, and can use the variable auto_mkindex_parser::parser to get to +# the slave proc auto_mkindex_parser::hook {cmd} { variable initCommands @@ -392,30 +393,30 @@ proc auto_mkindex_parser::hook {cmd} { # auto_mkindex_parser::slavehook command # -# Registers a Tcl command to evaluate when initializing the -# slave interpreter used by the mkindex parser. -# The command is evaluated in the slave interpreter. +# Registers a Tcl command to evaluate when initializing the slave interpreter +# used by the mkindex parser. The command is evaluated in the slave +# interpreter. proc auto_mkindex_parser::slavehook {cmd} { variable initCommands - # The $parser variable is defined to be the name of the - # slave interpreter when this command is used later. + # The $parser variable is defined to be the name of the slave interpreter + # when this command is used later. lappend initCommands "\$parser eval [list $cmd]" } # auto_mkindex_parser::command -- # -# Registers a new command with the "auto_mkindex_parser" interpreter -# that parses Tcl files. These commands are fake versions of things -# like the "proc" command. When you execute them, they simply write -# out an entry to a "tclIndex" file for auto-loading. +# Registers a new command with the "auto_mkindex_parser" interpreter that +# parses Tcl files. These commands are fake versions of things like the +# "proc" command. When you execute them, they simply write out an entry to a +# "tclIndex" file for auto-loading. # -# This procedure allows extensions to register their own commands -# with the auto_mkindex facility. For example, a package like -# [incr Tcl] might register a "class" command so that class definitions -# could be added to a "tclIndex" file for auto-loading. +# This procedure allows extensions to register their own commands with the +# auto_mkindex facility. For example, a package like [incr Tcl] might +# register a "class" command so that class definitions could be added to a +# "tclIndex" file for auto-loading. # # Arguments: # name Name of command recognized in Tcl files. @@ -428,8 +429,8 @@ proc auto_mkindex_parser::command {name arglist body} { # auto_mkindex_parser::commandInit -- # -# This does the actual work set up by auto_mkindex_parser::command -# This is called when the interpreter used by the parser is created. +# This does the actual work set up by auto_mkindex_parser::command. This is +# called when the interpreter used by the parser is created. # # Arguments: # name Name of command recognized in Tcl files. @@ -448,25 +449,23 @@ proc auto_mkindex_parser::commandInit {name arglist body} { } proc $fakeName $arglist $body - # YUK! Tcl won't let us alias fully qualified command names, - # so we can't handle names like "::itcl::class". Instead, - # we have to build procs with the fully qualified names, and - # have the procs point to the aliases. + # YUK! Tcl won't let us alias fully qualified command names, so we can't + # handle names like "::itcl::class". Instead, we have to build procs with + # the fully qualified names, and have the procs point to the aliases. if {[string match *::* $name]} { set exportCmd [list _%@namespace export [namespace tail $name]] $parser eval [list _%@namespace eval $ns $exportCmd] - # The following proc definition does not work if you - # want to tolerate space or something else diabolical - # in the procedure name, (i.e., space in $alias) - # The following does not work: + # The following proc definition does not work if you want to tolerate + # space or something else diabolical in the procedure name, (i.e., + # space in $alias). The following does not work: # "_%@eval {$alias} \$args" - # because $alias gets concat'ed to $args. - # The following does not work because $cmd is somehow undefined + # because $alias gets concat'ed to $args. The following does not work + # because $cmd is somehow undefined # "set cmd {$alias} \; _%@eval {\$cmd} \$args" - # A gold star to someone that can make test - # autoMkindex-3.3 work properly + # A gold star to someone that can make test autoMkindex-3.3 work + # properly set alias [namespace tail $fakeName] $parser invokehidden proc $name {args} "_%@eval {$alias} \$args" @@ -478,15 +477,14 @@ proc auto_mkindex_parser::commandInit {name arglist body} { } # auto_mkindex_parser::fullname -- -# Used by commands like "proc" within the auto_mkindex parser. -# Returns the qualified namespace name for the "name" argument. -# If the "name" does not start with "::", elements are added from -# the current namespace stack to produce a qualified name. Then, -# the name is examined to see whether or not it should really be -# qualified. If the name has more than the leading "::", it is -# returned as a fully qualified name. Otherwise, it is returned -# as a simple name. That way, the Tcl autoloader will recognize -# it properly. +# +# Used by commands like "proc" within the auto_mkindex parser. Returns the +# qualified namespace name for the "name" argument. If the "name" does not +# start with "::", elements are added from the current namespace stack to +# produce a qualified name. Then, the name is examined to see whether or not +# it should really be qualified. If the name has more than the leading "::", +# it is returned as a fully qualified name. Otherwise, it is returned as a +# simple name. That way, the Tcl autoloader will recognize it properly. # # Arguments: # name - Name that is being added to index. @@ -509,8 +507,8 @@ proc auto_mkindex_parser::fullname {name} { set name "::$name" } - # Earlier, mkindex replaced all $'s with \0. Now, we have to reverse - # that replacement. + # Earlier, mkindex replaced all $'s with \0. Now, we have to reverse that + # replacement. return [string map [list \0 \$] $name] } @@ -518,8 +516,8 @@ if {[llength $::auto_mkindex_parser::initCommands]} { return } -# Register all of the procedures for the auto_mkindex parser that -# will build the "tclIndex" file. +# Register all of the procedures for the auto_mkindex parser that will build +# the "tclIndex" file. # AUTO MKINDEX: proc name arglist body # Adds an entry to the auto index list for the given procedure name. @@ -536,17 +534,20 @@ auto_mkindex_parser::command proc {name args} { [file split $scriptFile]] "\n" } -# Conditionally add support for Tcl byte code files. There are some -# tricky details here. First, we need to get the tbcload library -# initialized in the current interpreter. We cannot load tbcload into the -# slave until we have done so because it needs access to the tcl_patchLevel -# variable. Second, because the package index file may defer loading the -# library until we invoke a command, we need to explicitly invoke auto_load -# to force it to be loaded. This should be a noop if the package has -# already been loaded +# Conditionally add support for Tcl byte code files. There are some tricky +# details here. First, we need to get the tbcload library initialized in the +# current interpreter. We cannot load tbcload into the slave until we have +# done so because it needs access to the tcl_patchLevel variable. Second, +# because the package index file may defer loading the library until we invoke +# a command, we need to explicitly invoke auto_load to force it to be loaded. +# This should be a noop if the package has already been loaded auto_mkindex_parser::hook { - if {![catch {package require tbcload}]} { + try { + package require tbcload + } on error {} { + # OK, don't have it so do nothing + } on ok {} { if {[namespace which -command tbcload::bcproc] eq ""} { auto_load tbcload::bcproc } @@ -570,16 +571,15 @@ auto_mkindex_parser::hook { } # AUTO MKINDEX: namespace eval name command ?arg arg...? -# Adds the namespace name onto the context stack and evaluates the -# associated body of commands. +# Adds the namespace name onto the context stack and evaluates the associated +# body of commands. # # AUTO MKINDEX: namespace import ?-force? pattern ?pattern...? -# Performs the "import" action in the parser interpreter. This is -# important for any commands contained in a namespace that affect -# the index. For example, a script may say "itcl::class ...", -# or it may import "itcl::*" and then say "class ...". This -# procedure does the import operation, but keeps track of imported -# patterns so we can remove the imports later. +# Performs the "import" action in the parser interpreter. This is important +# for any commands contained in a namespace that affect the index. For +# example, a script may say "itcl::class ...", or it may import "itcl::*" and +# then say "class ...". This procedure does the import operation, but keeps +# track of imported patterns so we can remove the imports later. auto_mkindex_parser::command namespace {op args} { switch -- $op { diff --git a/library/package.tcl b/library/package.tcl index 56dccd0..d8729b2 100644 --- a/library/package.tcl +++ b/library/package.tcl @@ -3,7 +3,7 @@ # utility procs formerly in init.tcl which can be loaded on demand # for package management. # -# RCS: @(#) $Id: package.tcl,v 1.36 2008/07/03 17:28:46 dgp Exp $ +# RCS: @(#) $Id: package.tcl,v 1.37 2009/07/26 11:40:23 dkf Exp $ # # Copyright (c) 1991-1993 The Regents of the University of California. # Copyright (c) 1994-1998 Sun Microsystems, Inc. @@ -16,9 +16,9 @@ namespace eval tcl::Pkg {} # ::tcl::Pkg::CompareExtension -- # -# Used internally by pkg_mkIndex to compare the extension of a file to -# a given extension. On Windows, it uses a case-insensitive comparison -# because the file system can be file insensitive. +# Used internally by pkg_mkIndex to compare the extension of a file to a given +# extension. On Windows, it uses a case-insensitive comparison because the +# file system can be file insensitive. # # Arguments: # fileName name of a file whose extension is compared @@ -59,11 +59,10 @@ proc tcl::Pkg::CompareExtension { fileName {ext {}} } { } # pkg_mkIndex -- -# This procedure creates a package index in a given directory. The -# package index consists of a "pkgIndex.tcl" file whose contents are -# a Tcl script that sets up package information with "package require" -# commands. The commands describe all of the packages defined by the -# files given as arguments. +# This procedure creates a package index in a given directory. The package +# index consists of a "pkgIndex.tcl" file whose contents are a Tcl script that +# sets up package information with "package require" commands. The commands +# describe all of the packages defined by the files given as arguments. # # Arguments: # -direct (optional) If this flag is present, the generated @@ -134,16 +133,17 @@ proc pkg_mkIndex {args} { set patternList [list "*.tcl" "*[info sharedlibextension]"] } - if {[catch { - glob -directory $dir -tails -types {r f} -- {*}$patternList - } fileList o]} { - return -options $o $fileList + try { + set fileList [glob -directory $dir -tails -types {r f} -- \ + {*}$patternList] + } on error {msg opt} { + return -options $opt $msg } foreach file $fileList { # For each file, figure out what commands and packages it provides. # To do this, create a child interpreter, load the file into the - # interpreter, and get a list of the new commands and packages - # that are defined. + # interpreter, and get a list of the new commands and packages that + # are defined. if {$file eq "pkgIndex.tcl"} { continue @@ -171,14 +171,17 @@ proc pkg_mkIndex {args} { if {$doVerbose} { tclLog "package [lindex $pkg 1] matches '$loadPat'" } - if {[catch { + try { load [lindex $pkg 0] [lindex $pkg 1] $c - } err]} { + } on error err { if {$doVerbose} { - tclLog "warning: load [lindex $pkg 0] [lindex $pkg 1]\nfailed with: $err" + tclLog "warning: load [lindex $pkg 0]\ + [lindex $pkg 1]\nfailed with: $err" + } + } on ok {} { + if {$doVerbose} { + tclLog "loaded [lindex $pkg 0] [lindex $pkg 1]" } - } elseif {$doVerbose} { - tclLog "loaded [lindex $pkg 0] [lindex $pkg 1]" } if {[lindex $pkg 1] eq "Tk"} { # Withdraw . if Tk was loaded, to avoid showing a window. @@ -187,21 +190,25 @@ proc pkg_mkIndex {args} { } $c eval { - # Stub out the package command so packages can - # require other packages. + # Stub out the package command so packages can require other + # packages. rename package __package_orig proc package {what args} { switch -- $what { - require { return ; # ignore transitive requires } - default { __package_orig $what {*}$args } + require { + return; # Ignore transitive requires + } + default { + __package_orig $what {*}$args + } } } proc tclPkgUnknown args {} package unknown tclPkgUnknown - # Stub out the unknown command so package can call - # into each other during their initialilzation. + # Stub out the unknown command so package can call into each other + # during their initialilzation. proc unknown {args} {} @@ -209,9 +216,9 @@ proc pkg_mkIndex {args} { proc auto_import {args} {} - # reserve the ::tcl namespace for support procs - # and temporary variables. This might make it awkward - # to generate a pkgIndex.tcl file for the ::tcl namespace. + # reserve the ::tcl namespace for support procs and temporary + # variables. This might make it awkward to generate a + # pkgIndex.tcl file for the ::tcl namespace. namespace eval ::tcl { variable dir ;# Current directory being processed @@ -232,22 +239,22 @@ proc pkg_mkIndex {args} { $c eval [list set ::tcl::file $file] $c eval [list set ::tcl::direct $direct] - # Download needed procedures into the slave because we've - # just deleted the unknown procedure. This doesn't handle - # procedures with default arguments. + # Download needed procedures into the slave because we've just deleted + # the unknown procedure. This doesn't handle procedures with default + # arguments. foreach p {::tcl::Pkg::CompareExtension} { $c eval [list namespace eval [namespace qualifiers $p] {}] $c eval [list proc $p [info args $p] [info body $p]] } - if {[catch { + try { $c eval { set ::tcl::debug "loading or sourcing" - # we need to track command defined by each package even in - # the -direct case, because they are needed internally by - # the "partial pkgIndex.tcl" step above. + # we need to track command defined by each package even in the + # -direct case, because they are needed internally by the + # "partial pkgIndex.tcl" step above. proc ::tcl::GetAllNamespaces {{root ::}} { set list $root @@ -269,18 +276,17 @@ proc pkg_mkIndex {args} { } set ::tcl::origCmds [info commands] - # Try to load the file if it has the shared library - # extension, otherwise source it. It's important not to - # try to load files that aren't shared libraries, because - # on some systems (like SunOS) the loader will abort the - # whole application when it gets an error. + # Try to load the file if it has the shared library extension, + # otherwise source it. It's important not to try to load + # files that aren't shared libraries, because on some systems + # (like SunOS) the loader will abort the whole application + # when it gets an error. if {[::tcl::Pkg::CompareExtension $::tcl::file [info sharedlibextension]]} { - # The "file join ." command below is necessary. - # Without it, if the file name has no \'s and we're - # on UNIX, the load command will invoke the - # LD_LIBRARY_PATH search mechanism, which could cause - # the wrong file to be used. + # The "file join ." command below is necessary. Without + # it, if the file name has no \'s and we're on UNIX, the + # load command will invoke the LD_LIBRARY_PATH search + # mechanism, which could cause the wrong file to be used. set ::tcl::debug loading load [file join $::tcl::dir $::tcl::file] @@ -291,11 +297,10 @@ proc pkg_mkIndex {args} { set ::tcl::type source } - # As a performance optimization, if we are creating - # direct load packages, don't bother figuring out the - # set of commands created by the new packages. We - # only need that list for setting up the autoloading - # used in the non-direct case. + # As a performance optimization, if we are creating direct + # load packages, don't bother figuring out the set of commands + # created by the new packages. We only need that list for + # setting up the autoloading used in the non-direct case. if { !$::tcl::direct } { # See what new namespaces appeared, and import commands # from them. Only exported commands go into the index. @@ -318,8 +323,9 @@ proc pkg_mkIndex {args} { set ::tcl::abs [namespace origin $::tcl::x] - # special case so that global names have no leading - # ::, this is required by the unknown command + # special case so that global names have no + # leading ::, this is required by the unknown + # command set ::tcl::abs \ [lindex [auto_qualify $::tcl::abs ::] 0] @@ -334,8 +340,8 @@ proc pkg_mkIndex {args} { } } - # Look through the packages that appeared, and if there is - # a version provided, then record it + # Look through the packages that appeared, and if there is a + # version provided, then record it foreach ::tcl::x [package names] { if {[package provide $::tcl::x] ne "" @@ -345,12 +351,12 @@ proc pkg_mkIndex {args} { } } } - } msg] == 1} { + } on error msg { set what [$c eval set ::tcl::debug] if {$doVerbose} { tclLog "warning: error while $what $file: $msg" } - } else { + } on ok {} { set what [$c eval set ::tcl::debug] if {$doVerbose} { tclLog "successful $what of $file" @@ -412,11 +418,10 @@ proc pkg_mkIndex {args} { } # tclPkgSetup -- -# This is a utility procedure use by pkgIndex.tcl files. It is invoked -# as part of a "package ifneeded" script. It calls "package provide" -# to indicate that a package is available, then sets entries in the -# auto_index array so that the package's files will be auto-loaded when -# the commands are used. +# This is a utility procedure use by pkgIndex.tcl files. It is invoked as +# part of a "package ifneeded" script. It calls "package provide" to indicate +# that a package is available, then sets entries in the auto_index array so +# that the package's files will be auto-loaded when the commands are used. # # Arguments: # dir - Directory containing all the files for this package. @@ -447,12 +452,12 @@ proc tclPkgSetup {dir pkg version files} { } # tclPkgUnknown -- -# This procedure provides the default for the "package unknown" function. -# It is invoked when a package that's needed can't be found. It scans -# the auto_path directories and their immediate children looking for -# pkgIndex.tcl files and sources any such files that are found to setup -# the package database. As it searches, it will recognize changes -# to the auto_path and scan any new directories. +# This procedure provides the default for the "package unknown" function. It +# is invoked when a package that's needed can't be found. It scans the +# auto_path directories and their immediate children looking for pkgIndex.tcl +# files and sources any such files that are found to setup the package +# database. As it searches, it will recognize changes to the auto_path and +# scan any new directories. # # Arguments: # name - Name of desired package. Not used. @@ -465,8 +470,8 @@ proc tclPkgUnknown {name args} { if {![info exists auto_path]} { return } - # Cache the auto_path, because it may change while we run through - # the first set of pkgIndex.tcl files + # Cache the auto_path, because it may change while we run through the + # first set of pkgIndex.tcl files set old_path [set use_path $auto_path] while {[llength $use_path]} { set dir [lindex $use_path end] @@ -478,24 +483,22 @@ proc tclPkgUnknown {name args} { } set tclSeenPath($dir) 1 - # we can't use glob in safe interps, so enclose the following - # in a catch statement, where we get the pkgIndex files out - # of the subdirectories + # we can't use glob in safe interps, so enclose the following in a + # catch statement, where we get the pkgIndex files out of the + # subdirectories catch { foreach file [glob -directory $dir -join -nocomplain \ * pkgIndex.tcl] { set dir [file dirname $file] if {![info exists procdDirs($dir)]} { - set code [catch {source $file} msg opt] - if {$code == 1 && - [lindex [dict get $opt -errorcode] 0] eq "POSIX" && - [lindex [dict get $opt -errorcode] 1] eq "EACCES"} { + try { + source $file + } trap {POSIX EACCES} {} { # $file was not readable; silently ignore continue - } - if {$code} { + } on error msg { tclLog "error reading package index file $file: $msg" - } else { + } on ok {} { set procdDirs($dir) 1 } } @@ -506,16 +509,14 @@ proc tclPkgUnknown {name args} { set file [file join $dir pkgIndex.tcl] # safe interps usually don't have "file exists", if {([interp issafe] || [file exists $file])} { - set code [catch {source $file} msg opt] - if {$code == 1 && - [lindex [dict get $opt -errorcode] 0] eq "POSIX" && - [lindex [dict get $opt -errorcode] 1] eq "EACCES"} { + try { + source $file + } trap {POSIX EACCES} {} { # $file was not readable; silently ignore continue - } - if {$code} { + } on error msg { tclLog "error reading package index file $file: $msg" - } else { + } on ok {} { set procdDirs($dir) 1 } } @@ -523,12 +524,11 @@ proc tclPkgUnknown {name args} { set use_path [lrange $use_path 0 end-1] - # Check whether any of the index scripts we [source]d above - # set a new value for $::auto_path. If so, then find any - # new directories on the $::auto_path, and lappend them to - # the $use_path we are working from. This gives index scripts - # the (arguably unwise) power to expand the index script search - # path while the search is in progress. + # Check whether any of the index scripts we [source]d above set a new + # value for $::auto_path. If so, then find any new directories on the + # $::auto_path, and lappend them to the $use_path we are working from. + # This gives index scripts the (arguably unwise) power to expand the + # index script search path while the search is in progress. set index 0 if {[llength $old_path] == [llength $auto_path]} { foreach dir $auto_path old $old_path { @@ -540,11 +540,11 @@ proc tclPkgUnknown {name args} { } } - # $index now points to the first element of $auto_path that - # has changed, or the beginning if $auto_path has changed length - # Scan the new elements of $auto_path for directories to add to - # $use_path. Don't add directories we've already seen, or ones - # already on the $use_path. + # $index now points to the first element of $auto_path that has + # changed, or the beginning if $auto_path has changed length Scan the + # new elements of $auto_path for directories to add to $use_path. + # Don't add directories we've already seen, or ones already on the + # $use_path. foreach dir [lrange $auto_path $index end] { if {![info exists tclSeenPath($dir)] && ([lsearch -exact $use_path $dir] == -1) } { @@ -556,9 +556,9 @@ proc tclPkgUnknown {name args} { } # tcl::MacOSXPkgUnknown -- -# This procedure extends the "package unknown" function for MacOSX. -# It scans the Resources/Scripts directories of the immediate children -# of the auto_path directories for pkgIndex files. +# This procedure extends the "package unknown" function for MacOSX. It scans +# the Resources/Scripts directories of the immediate children of the auto_path +# directories for pkgIndex files. # # Arguments: # original - original [package unknown] procedure @@ -567,7 +567,6 @@ proc tclPkgUnknown {name args} { # exact - Either "-exact" or omitted. Not used. proc tcl::MacOSXPkgUnknown {original name args} { - # First do the cross-platform default search uplevel 1 $original [linsert $args 0 $name] @@ -577,8 +576,8 @@ proc tcl::MacOSXPkgUnknown {original name args} { if {![info exists auto_path]} { return } - # Cache the auto_path, because it may change while we run through - # the first set of pkgIndex.tcl files + # Cache the auto_path, because it may change while we run through the + # first set of pkgIndex.tcl files set old_path [set use_path $auto_path] while {[llength $use_path]} { set dir [lindex $use_path end] @@ -595,28 +594,25 @@ proc tcl::MacOSXPkgUnknown {original name args} { * Resources Scripts pkgIndex.tcl] { set dir [file dirname $file] if {![info exists procdDirs($dir)]} { - set code [catch {source $file} msg opt] - if {$code == 1 && - [lindex [dict get $opt -errorcode] 0] eq "POSIX" && - [lindex [dict get $opt -errorcode] 1] eq "EACCES"} { + try { + source $file + } trap {POSIX EACCES} {} { # $file was not readable; silently ignore continue - } - if {$code} { + } on error msg { tclLog "error reading package index file $file: $msg" - } else { + } on ok {} { set procdDirs($dir) 1 } } } set use_path [lrange $use_path 0 end-1] - # Check whether any of the index scripts we [source]d above - # set a new value for $::auto_path. If so, then find any - # new directories on the $::auto_path, and lappend them to - # the $use_path we are working from. This gives index scripts - # the (arguably unwise) power to expand the index script search - # path while the search is in progress. + # Check whether any of the index scripts we [source]d above set a new + # value for $::auto_path. If so, then find any new directories on the + # $::auto_path, and lappend them to the $use_path we are working from. + # This gives index scripts the (arguably unwise) power to expand the + # index script search path while the search is in progress. set index 0 if {[llength $old_path] == [llength $auto_path]} { foreach dir $auto_path old $old_path { @@ -628,11 +624,11 @@ proc tcl::MacOSXPkgUnknown {original name args} { } } - # $index now points to the first element of $auto_path that - # has changed, or the beginning if $auto_path has changed length - # Scan the new elements of $auto_path for directories to add to - # $use_path. Don't add directories we've already seen, or ones - # already on the $use_path. + # $index now points to the first element of $auto_path that has + # changed, or the beginning if $auto_path has changed length Scan the + # new elements of $auto_path for directories to add to $use_path. + # Don't add directories we've already seen, or ones already on the + # $use_path. foreach dir [lrange $auto_path $index end] { if {![info exists tclSeenPath($dir)] && ([lsearch -exact $use_path $dir] == -1) } { @@ -659,12 +655,12 @@ proc tcl::MacOSXPkgUnknown {original name args} { # # Any number of -load and -source parameters may be # specified, so long as there is at least one -load or -# -source parameter. If the procs component of a -# module specifier is left off, that module will be -# set up for direct loading; otherwise, it will be -# set up for lazy loading. If both -source and -load -# are specified, the -load'ed files will be loaded -# first, followed by the -source'd files. +# -source parameter. If the procs component of a module +# specifier is left off, that module will be set up for +# direct loading; otherwise, it will be set up for lazy +# loading. If both -source and -load are specified, the +# -load'ed files will be loaded first, followed by the +# -source'd files. # # Results: # An appropriate "package ifneeded" statement for the package. diff --git a/library/safe.tcl b/library/safe.tcl index afdf639..5a3d4d0 100644 --- a/library/safe.tcl +++ b/library/safe.tcl @@ -9,20 +9,20 @@ # # Copyright (c) 1996-1997 Sun Microsystems, Inc. # -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# See the file "license.terms" for information on usage and redistribution of +# this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: safe.tcl,v 1.17 2008/06/25 17:40:03 andreas_kupries Exp $ +# RCS: @(#) $Id: safe.tcl,v 1.18 2009/07/26 11:40:24 dkf Exp $ # -# The implementation is based on namespaces. These naming conventions -# are followed: +# The implementation is based on namespaces. These naming conventions are +# followed: # Private procs starts with uppercase. # Public procs are exported and starts with lowercase # # Needed utilities package -package require opt 0.4.1; +package require opt 0.4.1 # Create the safe namespace namespace eval ::safe { @@ -37,8 +37,8 @@ namespace eval ::safe { # #### - # Make sure that our temporary variable is local to this - # namespace. [Bug 981733] + # Make sure that our temporary variable is local to this namespace. [Bug + # 981733] variable temp # Share the descriptions @@ -55,28 +55,27 @@ namespace eval ::safe { ::tcl::OptKeyRegister { {?slave? -name {} "name of the slave (optional)"} } ::safe::interpCreate - # adding the flags sub programs to the command program - # (relying on Opt's internal implementation details) + # adding the flags sub programs to the command program (relying on Opt's + # internal implementation details) lappend ::tcl::OptDesc(::safe::interpCreate) $::tcl::OptDesc($temp) # init and configure (slave is needed) ::tcl::OptKeyRegister { {slave -name {} "name of the slave"} } ::safe::interpIC - # adding the flags sub programs to the command program - # (relying on Opt's internal implementation details) + # adding the flags sub programs to the command program (relying on Opt's + # internal implementation details) lappend ::tcl::OptDesc(::safe::interpIC) $::tcl::OptDesc($temp) # temp not needed anymore ::tcl::OptKeyDelete $temp - - # Helper function to resolve the dual way of specifying staticsok - # (either by -noStatics or -statics 0) + # Helper function to resolve the dual way of specifying staticsok (either + # by -noStatics or -statics 0) proc InterpStatics {} { foreach v {Args statics noStatics} { upvar $v $v } - set flag [::tcl::OptProcArgGiven -noStatics]; + set flag [::tcl::OptProcArgGiven -noStatics] if {$flag && (!$noStatics == !$statics) && ([::tcl::OptProcArgGiven -statics])} { return -code error\ @@ -95,9 +94,9 @@ namespace eval ::safe { foreach v {Args nested nestedLoadOk} { upvar $v $v } - set flag [::tcl::OptProcArgGiven -nestedLoadOk]; - # note that the test here is the opposite of the "InterpStatics" - # one (it is not -noNested... because of the wanted default value) + set flag [::tcl::OptProcArgGiven -nestedLoadOk] + # note that the test here is the opposite of the "InterpStatics" one + # (it is not -noNested... because of the wanted default value) if {$flag && (!$nestedLoadOk != !$nested) && ([::tcl::OptProcArgGiven -nested])} { return -code error\ @@ -117,7 +116,6 @@ namespace eval ::safe { # #### - # Interface/entry point function and front end for "Create" proc interpCreate {args} { set Args [::tcl::OptKeyParse ::safe::interpCreate $args] @@ -131,7 +129,7 @@ namespace eval ::safe { return -code error "\"$slave\" is not an interpreter" } InterpInit $slave $accessPath \ - [InterpStatics] [InterpNested] $deleteHook; + [InterpStatics] [InterpNested] $deleteHook } proc CheckInterp {slave} { @@ -141,27 +139,26 @@ namespace eval ::safe { } } - # Interface/entry point function and front end for "Configure" - # This code is awfully pedestrian because it would need - # more coupling and support between the way we store the - # configuration values in safe::interp's and the Opt package - # Obviously we would like an OptConfigure - # to avoid duplicating all this code everywhere. -> TODO - # (the app should share or access easily the program/value - # stored by opt) - # This is even more complicated by the boolean flags with no values - # that we had the bad idea to support for the sake of user simplicity - # in create/init but which makes life hard in configure... + # Interface/entry point function and front end for "Configure". This code + # is awfully pedestrian because it would need more coupling and support + # between the way we store the configuration values in safe::interp's and + # the Opt package. Obviously we would like an OptConfigure to avoid + # duplicating all this code everywhere. + # -> TODO (the app should share or access easily the program/value stored + # by opt) + + # This is even more complicated by the boolean flags with no values that + # we had the bad idea to support for the sake of user simplicity in + # create/init but which makes life hard in configure... # So this will be hopefully written and some integrated with opt1.0 # (hopefully for tcl8.1 ?) proc interpConfigure {args} { switch [llength $args] { 1 { - # If we have exactly 1 argument - # the semantic is to return all the current configuration - # We still call OptKeyParse though we know that "slave" - # is our given argument because it also checks - # for the "-help" option. + # If we have exactly 1 argument the semantic is to return all + # the current configuration. We still call OptKeyParse though + # we know that "slave" is our given argument because it also + # checks for the "-help" option. set Args [::tcl::OptKeyParse ::safe::interpIC $args] CheckInterp $slave set res {} @@ -172,9 +169,10 @@ namespace eval ::safe { join $res } 2 { - # If we have exactly 2 arguments - # the semantic is a "configure get" + # If we have exactly 2 arguments the semantic is a "configure + # get" ::tcl::Lassign $args slave arg + # get the flag sub program (we 'know' about Opt's internal # representation of data) set desc [lindex [::tcl::OptKeyGetDesc ::safe::interpIC] 2] @@ -201,11 +199,10 @@ namespace eval ::safe { return [list -deleteHook [Set [DeleteHookName $slave]]] } -noStatics { - # it is most probably a set in fact - # but we would need then to jump to the set part - # and it is not *sure* that it is a set action - # that the user want, so force it to use the - # unambigous -statics ?value? instead: + # it is most probably a set in fact but we would need + # then to jump to the set part and it is not *sure* + # that it is a set action that the user want, so force + # it to use the unambigous -statics ?value? instead: return -code error\ "ambigous query (get or set -noStatics ?)\ use -statics instead" @@ -221,26 +218,31 @@ namespace eval ::safe { } } default { - # Otherwise we want to parse the arguments like init and create - # did + # Otherwise we want to parse the arguments like init and + # create did set Args [::tcl::OptKeyParse ::safe::interpIC $args] CheckInterp $slave - # Get the current (and not the default) values of - # whatever has not been given: + + # Get the current (and not the default) values of whatever has + # not been given: if {![::tcl::OptProcArgGiven -accessPath]} { set doreset 1 set accessPath [Set [PathListName $slave]] } else { set doreset 0 } - if {(![::tcl::OptProcArgGiven -statics]) \ - && (![::tcl::OptProcArgGiven -noStatics]) } { + if { + ![::tcl::OptProcArgGiven -statics] + && ![::tcl::OptProcArgGiven -noStatics] + } then { set statics [Set [StaticsOkName $slave]] } else { set statics [InterpStatics] } - if {([::tcl::OptProcArgGiven -nested]) \ - || ([::tcl::OptProcArgGiven -nestedLoadOk]) } { + if { + [::tcl::OptProcArgGiven -nested] || + [::tcl::OptProcArgGiven -nestedLoadOk] + } then { set nested [InterpNested] } else { set nested [Set [NestedOkName $slave]] @@ -262,21 +264,19 @@ namespace eval ::safe { } } - #### # # Functions that actually implements the exported APIs # #### - # # safe::InterpCreate : doing the real job # - # This procedure creates a safe slave and initializes it with the - # safe base aliases. - # NB: slave name must be simple alphanumeric string, no spaces, - # no (), no {},... {because the state array is stored as part of the name} + # This procedure creates a safe slave and initializes it with the safe + # base aliases. + # NB: slave name must be simple alphanumeric string, no spaces, no (), no + # {},... {because the state array is stored as part of the name} # # Returns the slave name. # @@ -310,24 +310,22 @@ namespace eval ::safe { InterpInit $slave $access_path $staticsok $nestedok $deletehook } - # # InterpSetConfig (was setAccessPath) : - # Sets up slave virtual auto_path and corresponding structure - # within the master. Also sets the tcl_library in the slave - # to be the first directory in the path. - # Nb: If you change the path after the slave has been initialized - # you probably need to call "auto_reset" in the slave in order that it - # gets the right auto_index() array values. + # Sets up slave virtual auto_path and corresponding structure within + # the master. Also sets the tcl_library in the slave to be the first + # directory in the path. + # NB: If you change the path after the slave has been initialized you + # probably need to call "auto_reset" in the slave in order that it gets + # the right auto_index() array values. proc ::safe::InterpSetConfig {slave access_path staticsok\ nestedok deletehook} { - # determine and store the access path if empty if {$access_path eq ""} { set access_path [uplevel \#0 set auto_path] - # Make sure that tcl_library is in auto_path - # and at the first position (needed by setAccessPath) + # Make sure that tcl_library is in auto_path and at the first + # position (needed by setAccessPath) set where [lsearch -exact $access_path [info library]] if {$where == -1} { # not found, add it. @@ -344,8 +342,8 @@ namespace eval ::safe { } # Add 1st level sub dirs (will searched by auto loading from tcl - # code in the slave using glob and thus fail, so we add them - # here so by default it works the same). + # code in the slave using glob and thus fail, so we add them here + # so by default it works the same). set access_path [AddSubDirs $access_path] } @@ -369,10 +367,10 @@ namespace eval ::safe { lappend slave_auto_path "\$[PathToken $i]" incr i } - # Extend the access list with the paths used to look for Tcl - # Modules. We safe the virtual form separately as well, as - # syncing it with the slave has to be defered until the - # necessary commands are present for setup. + # Extend the access list with the paths used to look for Tcl Modules. + # We save the virtual form separately as well, as syncing it with the + # slave has to be defered until the necessary commands are present for + # setup. foreach dir [::tcl::tm::list] { lappend access_path $dir Set [PathToken $i $slave] $dir @@ -395,8 +393,8 @@ namespace eval ::safe { # # # FindInAccessPath: - # Search for a real directory and returns its virtual Id - # (including the "$") + # Search for a real directory and returns its virtual Id (including the + # "$") proc ::safe::interpFindInAccessPath {slave path} { set access_path [GetAccessPath $slave] set where [lsearch -exact $access_path $path] @@ -408,32 +406,33 @@ proc ::safe::interpFindInAccessPath {slave path} { # # addToAccessPath: - # add (if needed) a real directory to access path - # and return its virtual token (including the "$"). + # add (if needed) a real directory to access path and return its + # virtual token (including the "$"). proc ::safe::interpAddToAccessPath {slave path} { # first check if the directory is already in there - if {![catch {interpFindInAccessPath $slave $path} res]} { - return $res - } - # new one, add it: - set nname [PathNumberName $slave] - set n [Set $nname] - Set [PathToken $n $slave] $path + try { + return [interpFindInAccessPath $slave $path] + } on error {} { + # new one, add it: + set nname [PathNumberName $slave] + set n [Set $nname] + Set [PathToken $n $slave] $path - set token "\$[PathToken $n]" + set token "\$[PathToken $n]" - Lappend [VirtualPathListName $slave] $token - Lappend [PathListName $slave] $path - Set $nname [expr {$n+1}] + Lappend [VirtualPathListName $slave] $token + Lappend [PathListName $slave] $path + Set $nname [expr {$n+1}] - SyncAccessPath $slave + SyncAccessPath $slave - return $token + return $token + } } # This procedure applies the initializations to an already existing - # interpreter. It is useful when you want to install the safe base - # aliases into a preexisting safe interpreter. + # interpreter. It is useful when you want to install the safe base aliases + # into a preexisting safe interpreter. proc ::safe::InterpInit { slave access_path @@ -441,76 +440,77 @@ proc ::safe::interpAddToAccessPath {slave path} { nestedok deletehook } { - - # Configure will generate an access_path when access_path is - # empty. + # Configure will generate an access_path when access_path is empty. InterpSetConfig $slave $access_path $staticsok $nestedok $deletehook # These aliases let the slave load files to define new commands - # NB we need to add [namespace current], aliases are always - # absolute paths. - ::interp alias $slave source {} [namespace current]::AliasSource $slave - ::interp alias $slave load {} [namespace current]::AliasLoad $slave + # NB we need to add [namespace current], aliases are always absolute + # paths. + ::interp alias $slave source {} \ + [namespace current]::AliasSource $slave + ::interp alias $slave load {} \ + [namespace current]::AliasLoad $slave # This alias lets the slave use the encoding names, convertfrom, - # convertto, and system, but not "encoding system <name>" to set - # the system encoding. + # convertto, and system, but not "encoding system <name>" to set the + # system encoding. - ::interp alias $slave encoding {} [namespace current]::AliasEncoding \ - $slave + ::interp alias $slave encoding {} \ + [namespace current]::AliasEncoding $slave # Handling Tcl Modules, we need a restricted form of Glob. - ::interp alias $slave glob {} [namespace current]::AliasGlob \ - $slave + ::interp alias $slave glob {} \ + [namespace current]::AliasGlob $slave # This alias lets the slave have access to a subset of the 'file' # command functionality. - AliasSubset $slave file file dir.* join root.* ext.* tail \ - path.* split + AliasSubset $slave file \ + file dir.* join root.* ext.* tail path.* split # This alias interposes on the 'exit' command and cleanly terminates # the slave. - ::interp alias $slave exit {} [namespace current]::interpDelete $slave + ::interp alias $slave exit {} \ + [namespace current]::interpDelete $slave - # The allowed slave variables already have been set - # by Tcl_MakeSafe(3) + # The allowed slave variables already have been set by Tcl_MakeSafe(3) + # Source init.tcl and tm.tcl into the slave, to get auto_load and + # other procedures defined: - # Source init.tcl and tm.tcl into the slave, to get auto_load - # and other procedures defined: - - if {[catch {::interp eval $slave\ - {source [file join $tcl_library init.tcl]}} msg]} { + if {[catch {::interp eval $slave { + source [file join $tcl_library init.tcl] + }} msg]} then { Log $slave "can't source init.tcl ($msg)" error "can't source init.tcl into slave $slave ($msg)" } - if {[catch {::interp eval $slave \ - {source [file join $tcl_library tm.tcl]}} msg]} { + if {[catch {::interp eval $slave { + source [file join $tcl_library tm.tcl] + }} msg]} then { Log $slave "can't source tm.tcl ($msg)" error "can't source tm.tcl into slave $slave ($msg)" } - # Sync the paths used to search for Tcl modules. This can be - # done only now, after tm.tcl was loaded. - ::interp eval $slave [list ::tcl::tm::add {*}[Set [TmPathListName $slave]]] + # Sync the paths used to search for Tcl modules. This can be done only + # now, after tm.tcl was loaded. + ::interp eval $slave [list \ + ::tcl::tm::add {*}[Set [TmPathListName $slave]] ] return $slave } - - # Add (only if needed, avoid duplicates) 1 level of - # sub directories to an existing path list. - # Also removes non directories from the returned list. + # Add (only if needed, avoid duplicates) 1 level of sub directories to an + # existing path list. Also removes non directories from the returned + # list. proc AddSubDirs {pathList} { set res {} foreach dir $pathList { if {[file isdirectory $dir]} { - # check that we don't have it yet as a children - # of a previous dir + # check that we don't have it yet as a children of a previous + # dir if {[lsearch -exact $res $dir]<0} { lappend res $dir } @@ -526,24 +526,25 @@ proc ::safe::interpAddToAccessPath {slave path} { return $res } - # This procedure deletes a safe slave managed by Safe Tcl and - # cleans up associated state: + # This procedure deletes a safe slave managed by Safe Tcl and cleans up + # associated state: proc ::safe::interpDelete {slave} { - Log $slave "About to delete" NOTICE - # If the slave has a cleanup hook registered, call it. - # check the existance because we might be called to delete an interp - # which has not been registered with us at all + # If the slave has a cleanup hook registered, call it. Check the + # existance because we might be called to delete an interp which has + # not been registered with us at all set hookname [DeleteHookName $slave] if {[Exists $hookname]} { set hook [Set $hookname] if {![::tcl::Lempty $hook]} { - # remove the hook now, otherwise if the hook - # calls us somehow, we'll loop + # remove the hook now, otherwise if the hook calls us somehow, + # we'll loop Unset $hookname - if {[catch {{*}$hook $slave} err]} { + try { + {*}$hook $slave + } on error err { Log $slave "Delete hook error ($err)" } } @@ -570,27 +571,24 @@ proc ::safe::interpDelete {slave} { # Set (or get) the loging mecanism proc ::safe::setLogCmd {args} { - variable Log - if {[llength $args] == 0} { - return $Log - } else { - if {[llength $args] == 1} { + variable Log + if {[llength $args] == 0} { + return $Log + } elseif {[llength $args] == 1} { set Log [lindex $args 0] } else { set Log $args } } -} # internal variable variable Log {} # ------------------- END OF PUBLIC METHODS ------------ - # - # sets the slave auto_path to the master recorded value. - # also sets tcl_library to the first token of the virtual path. + # Sets the slave auto_path to the master recorded value. Also sets + # tcl_library to the first token of the virtual path. # proc SyncAccessPath {slave} { set slave_auto_path [Set [VirtualPathListName $slave]] @@ -600,12 +598,10 @@ proc ::safe::setLogCmd {args} { ::interp eval $slave [list set tcl_library [lindex $slave_auto_path 0]] } - # base name for storing all the slave states - # the array variable name for slave foo is thus "Sfoo" - # and for sub slave {foo bar} "Sfoo bar" (spaces are handled - # ok everywhere (or should)) - # We add the S prefix to avoid that a slave interp called "Log" - # would smash our "Log" variable. + # Base name for storing all the slave states. The array variable name for + # slave foo is thus "Sfoo" and for sub slave {foo bar} "Sfoo bar" (spaces + # are handled ok everywhere (or should)). We add the S prefix to avoid + # that a slave interp called "Log" would smash our "Log" variable. proc InterpStateName {slave} { return "S$slave" } @@ -615,16 +611,14 @@ proc ::safe::setLogCmd {args} { expr {[Exists [InterpStateName $slave]] && [::interp exists $slave]} } - # returns the virtual token for directory number N - # if the slave argument is given, - # it will return the corresponding master global variable name + # Returns the virtual token for directory number N. If the slave argument + # is given, it will return the corresponding master global variable name proc PathToken {n {slave ""}} { if {$slave ne ""} { return "[InterpStateName $slave](access_path,$n)" } else { - # We need to have a ":" in the token string so - # [file join] on the mac won't turn it into a relative - # path. + # We need to have a ":" in the token string so [file join] on the + # mac won't turn it into a relative path. return "p(:$n:)" } } @@ -693,8 +687,8 @@ proc ::safe::setLogCmd {args} { # translate virtual path into real path # proc TranslatePath {slave path} { - # somehow strip the namespaces 'functionality' out (the danger - # is that we would strip valid macintosh "../" queries... : + # somehow strip the namespaces 'functionality' out (the danger is that + # we would strip valid macintosh "../" queries... : if {[string match "*::*" $path] || [string match "*..*" $path]} { error "invalid characters in path $path" } @@ -708,8 +702,8 @@ proc ::safe::setLogCmd {args} { } - # Log eventually log an error - # to enable error logging, set Log to {puts stderr} for instance + # Log eventually log an error; to enable error logging, set Log to {puts + # stderr} for instance proc Log {slave msg {type ERROR}} { variable Log if {[info exists Log] && [llength $Log]} { @@ -718,13 +712,13 @@ proc ::safe::setLogCmd {args} { } - # file name control (limit access to files/ressources that should be - # a valid tcl source file) + # file name control (limit access to files/resources that should be a + # valid tcl source file) proc CheckFileName {slave file} { # This used to limit what can be sourced to ".tcl" and forbid files # with more than 1 dot and longer than 14 chars, but I changed that - # for 8.4 as a safe interp has enough internal protection already - # to allow sourcing anything. - hobbs + # for 8.4 as a safe interp has enough internal protection already to + # allow sourcing anything. - hobbs if {![file exists $file]} { # don't tell the file path @@ -750,29 +744,37 @@ proc ::safe::setLogCmd {args} { while {$at < [llength $args]} { switch -glob -- [set opt [lindex $args $at]] { -nocomplain - - -join { lappend cmd $opt ; incr at } + -join { + lappend cmd $opt + incr at + } -directory { - lappend cmd $opt ; incr at + lappend cmd $opt + incr at set virtualdir [lindex $args $at] # get the real path from the virtual one. - if {[catch {set dir [TranslatePath $slave $virtualdir]} msg]} { + try { + set dir [TranslatePath $slave $virtualdir] + } on error msg { Log $slave $msg return -code error "permission denied" } # check that the path is in the access path of that slave - if {[catch {DirInAccessPath $slave $dir} msg]} { + try { + DirInAccessPath $slave $dir + } on error msg { Log $slave $msg return -code error "permission denied" } - lappend cmd $dir ; incr at + lappend cmd $dir + incr at } pkgIndex.tcl { - # Oops, this is globbing a subdirectory in regular - # package search. That is not wanted. Abort, - # handler does catch already (because glob was not - # defined before). See package.tcl, lines 484ff in - # tclPkgUnknown. + # Oops, this is globbing a subdirectory in regular package + # search. That is not wanted. Abort, handler does catch + # already (because glob was not defined before). See + # package.tcl, lines 484ff in tclPkgUnknown. error "unknown command glob" } -* { @@ -780,14 +782,17 @@ proc ::safe::setLogCmd {args} { error "Safe base rejecting glob option '$opt'" } default { - lappend cmd $opt ; incr at + lappend cmd $opt + incr at } } } Log $slave "GLOB = $cmd" NOTICE - if {[catch {::interp invokehidden $slave glob {*}$cmd} msg]} { + try { + ::interp invokehidden $slave glob {*}$cmd + } on error msg { Log $slave $msg return -code error "script error" } @@ -808,11 +813,9 @@ proc ::safe::setLogCmd {args} { # AliasSource is the target of the "source" alias in safe interpreters. proc AliasSource {slave args} { - set argc [llength $args] - # Extended for handling of Tcl Modules to allow not only - # "source filename", but "source -encoding E filename" as - # well. + # Extended for handling of Tcl Modules to allow not only "source + # filename", but "source -encoding E filename" as well. if {[lindex $args 0] eq "-encoding"} { incr argc -2 set encoding [lrange $args 0 1] @@ -829,25 +832,34 @@ proc ::safe::setLogCmd {args} { set file [lindex $args $at] # get the real path from the virtual one. - if {[catch {set file [TranslatePath $slave $file]} msg]} { + try { + set file [TranslatePath $slave $file] + } on error msg { Log $slave $msg return -code error "permission denied" } # check that the path is in the access path of that slave - if {[catch {FileInAccessPath $slave $file} msg]} { + try { + FileInAccessPath $slave $file + } on error msg { Log $slave $msg return -code error "permission denied" } # do the checks on the filename : - if {[catch {CheckFileName $slave $file} msg]} { + try { + CheckFileName $slave $file + } on error msg { Log $slave "$file:$msg" return -code error $msg } # passed all the tests , lets source it: - if {[catch {::interp invokehidden $slave source {*}$encoding $file} msg]} { + if {[catch { + # We use catch here because we want to catch non-error/ok too + ::interp invokehidden $slave source {*}$encoding $file + } msg]} then { Log $slave $msg return -code error "script error" } @@ -857,7 +869,6 @@ proc ::safe::setLogCmd {args} { # AliasLoad is the target of the "load" alias in safe interpreters. proc AliasLoad {slave file args} { - set argc [llength $args] if {$argc > 2} { set msg "load error: too many arguments" @@ -868,18 +879,17 @@ proc ::safe::setLogCmd {args} { # package name (can be empty if file is not). set package [lindex $args 0] - # Determine where to load. load use a relative interp path - # and {} means self, so we can directly and safely use passed arg. + # Determine where to load. load use a relative interp path and {} + # means self, so we can directly and safely use passed arg. set target [lindex $args 1] if {$target ne ""} { - # we will try to load into a sub sub interp - # check that we want to authorize that. + # we will try to load into a sub sub interp; check that we want to + # authorize that. if {![NestedOk $slave]} { Log $slave "loading to a sub interp (nestedok)\ disabled (trying to load $package to $target)" return -code error "permission denied (nested load)" } - } # Determine what kind of load is requested @@ -899,20 +909,25 @@ proc ::safe::setLogCmd {args} { # file loading # get the real path from the virtual one. - if {[catch {set file [TranslatePath $slave $file]} msg]} { + try { + set file [TranslatePath $slave $file] + } on error msg { Log $slave $msg return -code error "permission denied" } # check the translated path - if {[catch {FileInAccessPath $slave $file} msg]} { + try { + FileInAccessPath $slave $file + } on error msg { Log $slave $msg return -code error "permission denied (path)" } } - if {[catch {::interp invokehidden\ - $slave load $file $package $target} msg]} { + try { + ::interp invokehidden $slave load $file $package $target + } on error msg { Log $slave $msg return -code error $msg } @@ -920,14 +935,12 @@ proc ::safe::setLogCmd {args} { return $msg } - # FileInAccessPath raises an error if the file is not found in - # the list of directories contained in the (master side recorded) slave's - # access path. + # FileInAccessPath raises an error if the file is not found in the list of + # directories contained in the (master side recorded) slave's access path. # the security here relies on "file dirname" answering the proper - # result.... needs checking ? + # result... needs checking ? proc FileInAccessPath {slave file} { - set access_path [GetAccessPath $slave] if {[file isdirectory $file]} { @@ -942,7 +955,7 @@ proc ::safe::setLogCmd {args} { lappend norm_access_path [file normalize $path] } - if {[lsearch -exact $norm_access_path $norm_parent] == -1} { + if {$norm_parent ni $norm_access_path} { error "\"$file\": not in access_path" } } @@ -961,13 +974,13 @@ proc ::safe::setLogCmd {args} { lappend norm_access_path [file normalize $path] } - if {[lsearch -exact $norm_access_path $norm_dir] == -1} { + if {$norm_dir ni $norm_access_path} { error "\"$dir\": not in access_path" } } - # This procedure enables access from a safe interpreter to only a subset of - # the subcommands of a command: + # This procedure enables access from a safe interpreter to only a subset + # of the subcommands of a command: proc Subset {slave command okpat args} { set subcommand [lindex $args 0] @@ -979,20 +992,21 @@ proc ::safe::setLogCmd {args} { error $msg } - # This procedure installs an alias in a slave that invokes "safesubset" - # in the master to execute allowed subcommands. It precomputes the pattern - # of allowed subcommands; you can use wildcards in the pattern if you wish - # to allow subcommand abbreviation. + # This procedure installs an alias in a slave that invokes "safesubset" in + # the master to execute allowed subcommands. It precomputes the pattern of + # allowed subcommands; you can use wildcards in the pattern if you wish to + # allow subcommand abbreviation. # # Syntax is: AliasSubset slave alias target subcommand1 subcommand2... proc AliasSubset {slave alias target args} { - set pat ^(; set sep "" + set pat "^(" + set sep "" foreach sub $args { append pat $sep$sub set sep | } - append pat )\$ + append pat ")\$" ::interp alias $slave $alias {}\ [namespace current]::Subset $slave $target $pat } @@ -1000,7 +1014,6 @@ proc ::safe::setLogCmd {args} { # AliasEncoding is the target of the "encoding" alias in safe interpreters. proc AliasEncoding {slave args} { - set argc [llength $args] set okpat "^(name.*|convert.*)\$" @@ -1013,23 +1026,18 @@ proc ::safe::setLogCmd {args} { if {[string first $subcommand system] == 0} { if {$argc == 1} { # passed all the tests , lets source it: - if {[catch {::interp invokehidden \ - $slave encoding system} msg]} { + try { + return [::interp invokehidden $slave encoding system] + } on error msg { Log $slave $msg return -code error "script error" } - } else { - set msg "wrong # args: should be \"encoding system\"" - Log $slave $msg - error $msg } + set msg "wrong # args: should be \"encoding system\"" } else { set msg "wrong # args: should be \"encoding option ?arg ...?\"" - Log $slave $msg - error $msg } - - return $msg + Log $slave $msg + error $msg } - } diff --git a/library/tm.tcl b/library/tm.tcl index a2476ce..ca0bbf7 100644 --- a/library/tm.tcl +++ b/library/tm.tcl @@ -1,48 +1,44 @@ # -*- tcl -*- # -# Searching for Tcl Modules. Defines a procedure, declares it as the -# primary command for finding packages, however also uses the former -# 'package unknown' command as a fallback. +# Searching for Tcl Modules. Defines a procedure, declares it as the primary +# command for finding packages, however also uses the former 'package unknown' +# command as a fallback. # -# Locates all possible packages in a directory via a less restricted -# glob. The targeted directory is derived from the name of the -# requested package. I.e. the TM scan will look only at directories -# which can contain the requested package. It will register all -# packages it found in the directory so that future requests have a -# higher chance of being fulfilled by the ifneeded database without -# having to come to us again. +# Locates all possible packages in a directory via a less restricted glob. The +# targeted directory is derived from the name of the requested package, i.e. +# the TM scan will look only at directories which can contain the requested +# package. It will register all packages it found in the directory so that +# future requests have a higher chance of being fulfilled by the ifneeded +# database without having to come to us again. # -# We do not remember where we have been and simply rescan targeted -# directories when invoked again. The reasoning is this: +# We do not remember where we have been and simply rescan targeted directories +# when invoked again. The reasoning is this: # -# - The only way we get back to the same directory is if someone is -# trying to [package require] something that wasn't there on the -# first scan. +# - The only way we get back to the same directory is if someone is trying to +# [package require] something that wasn't there on the first scan. # # Either # 1) It is there now: If we rescan, you get it; if not you don't. # -# This covers the possibility that the application asked for a -# package late, and the package was actually added to the -# installation after the application was started. It shoukld -# still be able to find it. +# This covers the possibility that the application asked for a package +# late, and the package was actually added to the installation after the +# application was started. It shoukld still be able to find it. # -# 2) It still is not there: Either way, you don't get it, but the -# rescan takes time. This is however an error case and we dont't -# care that much about it +# 2) It still is not there: Either way, you don't get it, but the rescan +# takes time. This is however an error case and we dont't care that much +# about it # -# 3) It was there the first time; but for some reason a "package -# forget" has been run, and "package" doesn't know about it -# anymore. +# 3) It was there the first time; but for some reason a "package forget" has +# been run, and "package" doesn't know about it anymore. # -# This can be an indication that the application wishes to reload -# some functionality. And should work as well. +# This can be an indication that the application wishes to reload some +# functionality. And should work as well. # -# Note that this also strikes a balance between doing a glob targeting -# a single package, and thus most likely requiring multiple globs of -# the same directory when the application is asking for many packages, -# and trying to glob for _everything_ in all subdirectories when -# looking for a package, which comes with a heavy startup cost. +# Note that this also strikes a balance between doing a glob targeting a +# single package, and thus most likely requiring multiple globs of the same +# directory when the application is asking for many packages, and trying to +# glob for _everything_ in all subdirectories when looking for a package, +# which comes with a heavy startup cost. # # We scan for regular packages only if no satisfying module was found. @@ -71,35 +67,33 @@ namespace eval ::tcl::tm { # path with 'list'. # # Results -# No result for subcommands 'add' and 'remove'. A list of paths -# for 'list'. +# No result for subcommands 'add' and 'remove'. A list of paths for +# 'list'. # # Sideeffects -# The subcommands 'add' and 'remove' manipulate the list of -# paths to search for Tcl Modules. The subcommand 'list' has no -# sideeffects. +# The subcommands 'add' and 'remove' manipulate the list of paths to +# search for Tcl Modules. The subcommand 'list' has no sideeffects. proc ::tcl::tm::add {args} { # PART OF THE ::tcl::tm::path ENSEMBLE # # The path is added at the head to the list of module paths. # - # The command enforces the restriction that no path may be an - # ancestor directory of any other path on the list. If the new - # path violates this restriction an error wil be raised. + # The command enforces the restriction that no path may be an ancestor + # directory of any other path on the list. If the new path violates this + # restriction an error wil be raised. # - # If the path is already present as is no error will be raised and - # no action will be taken. + # If the path is already present as is no error will be raised and no + # action will be taken. variable paths - # We use a copy of the path as source during validation, and - # extend it as well. Because we not only have to detect if the new - # paths are bogus with respect to the existing paths, but also - # between themselves. Otherwise we can still add bogus paths, by - # specifying them in a single call. This makes the use of the new - # paths simpler as well, a trivial assignment of the collected - # paths to the official state var. + # We use a copy of the path as source during validation, and extend it as + # well. Because we not only have to detect if the new paths are bogus with + # respect to the existing paths, but also between themselves. Otherwise we + # can still add bogus paths, by specifying them in a single call. This + # makes the use of the new paths simpler as well, a trivial assignment of + # the collected paths to the official state var. set newpaths $paths foreach p $args { @@ -108,9 +102,8 @@ proc ::tcl::tm::add {args} { continue } - # Search for paths which are subdirectories of the new one. If - # there are any then the new path violates the restriction - # about ancestors. + # Search for paths which are subdirectories of the new one. If there + # are any then the new path violates the restriction about ancestors. set pos [lsearch -glob $newpaths ${p}/*] # Cannot use "in", we need the position for the message. @@ -119,10 +112,9 @@ proc ::tcl::tm::add {args} { "$p is ancestor of existing module path [lindex $newpaths $pos]." } - # Now look for existing paths which are ancestors of the new - # one. This reverse question forces us to loop over the - # existing paths, as each element is the pattern, not the new - # path :( + # Now look for existing paths which are ancestors of the new one. This + # reverse question forces us to loop over the existing paths, as each + # element is the pattern, not the new path :( foreach ep $newpaths { if {[string match ${ep}/* $p]} { @@ -134,10 +126,9 @@ proc ::tcl::tm::add {args} { set newpaths [linsert $newpaths 0 $p] } - # The validation of the input is complete and successful, and - # everything in newpaths is either an old path, or added. We can - # now extend the official list of paths, a simple assignment is - # sufficient. + # The validation of the input is complete and successful, and everything + # in newpaths is either an old path, or added. We can now extend the + # official list of paths, a simple assignment is sufficient. set paths $newpaths return @@ -146,8 +137,8 @@ proc ::tcl::tm::add {args} { proc ::tcl::tm::remove {args} { # PART OF THE ::tcl::tm::path ENSEMBLE # - # Removes the path from the list of module paths. The command is - # silently ignored if the path is not on the list. + # Removes the path from the list of module paths. The command is silently + # ignored if the path is not on the list. variable paths @@ -177,17 +168,16 @@ proc ::tcl::tm::list {} { # empty string. # exact - Either -exact or ommitted. # -# Name, version, and exact are used to determine -# satisfaction. The original is called iff no satisfaction was -# achieved. The name is also used to compute the directory to -# target in the search. +# Name, version, and exact are used to determine satisfaction. The +# original is called iff no satisfaction was achieved. The name is also +# used to compute the directory to target in the search. # # Results # None. # # Sideeffects -# May populate the package ifneeded database with additional -# provide scripts. +# May populate the package ifneeded database with additional provide +# scripts. proc ::tcl::tm::UnknownHandler {original name args} { # Import the list of paths to search for packages in module form. @@ -196,8 +186,8 @@ proc ::tcl::tm::UnknownHandler {original name args} { variable paths variable pkgpattern - # Without paths to search we can do nothing. (Except falling back - # to the regular search). + # Without paths to search we can do nothing. (Except falling back to the + # regular search). if {[llength $paths]} { set pkgpath [string map {:: /} $name] @@ -206,11 +196,10 @@ proc ::tcl::tm::UnknownHandler {original name args} { set pkgroot "" } - # We don't remember a copy of the paths while looping. Tcl - # Modules are unable to change the list while we are searching - # for them. This also simplifies the loop, as we cannot get - # additional directories while iterating over the list. A - # simple foreach is sufficient. + # We don't remember a copy of the paths while looping. Tcl Modules are + # unable to change the list while we are searching for them. This also + # simplifies the loop, as we cannot get additional directories while + # iterating over the list. A simple foreach is sufficient. set satisfied 0 foreach path $paths { @@ -223,12 +212,11 @@ proc ::tcl::tm::UnknownHandler {original name args} { } set strip [llength [file split $path]] - # We can't use glob in safe interps, so enclose the following - # in a catch statement, where we get the module files out - # of the subdirectories. In other words, Tcl Modules are - # not-functional in such an interpreter. This is the same - # as for the command "tclPkgUnknown", i.e. the search for - # regular packages. + # We can't use glob in safe interps, so enclose the following in a + # catch statement, where we get the module files out of the + # subdirectories. In other words, Tcl Modules are not-functional + # in such an interpreter. This is the same as for the command + # "tclPkgUnknown", i.e. the search for regular packages. catch { # We always look for _all_ possible modules in the current @@ -238,50 +226,50 @@ proc ::tcl::tm::UnknownHandler {original name args} { set pkgfilename [join [lrange [file split $file] $strip end] ::] if {![regexp -- $pkgpattern $pkgfilename --> pkgname pkgversion]} { - # Ignore everything not matching our pattern - # for package names. + # Ignore everything not matching our pattern for + # package names. continue } - if {[catch {package vcompare $pkgversion 0}]} { - # Ignore everything where the version part is - # not acceptable to "package vcompare". + try { + package vcompare $pkgversion 0 + } on error {} { + # Ignore everything where the version part is not + # acceptable to "package vcompare". continue } - # We have found a candidate, generate a "provide - # script" for it, and remember it. Note that we - # are using ::list to do this; locally [list] - # means something else without the namespace - # specifier. - - # NOTE. When making changes to the format of the - # provide command generated below CHECK that the - # 'LOCATE' procedure in core file - # 'platform/shell.tcl' still understands it, or, - # if not, update its implementation appropriately. + # We have found a candidate, generate a "provide script" + # for it, and remember it. Note that we are using ::list + # to do this; locally [list] means something else without + # the namespace specifier. + + # NOTE. When making changes to the format of the provide + # command generated below CHECK that the 'LOCATE' + # procedure in core file 'platform/shell.tcl' still + # understands it, or, if not, update its implementation + # appropriately. # - # Right now LOCATE's implementation assumes that - # the path of the package file is the last element - # in the list. + # Right now LOCATE's implementation assumes that the path + # of the package file is the last element in the list. package ifneeded $pkgname $pkgversion \ "[::list package provide $pkgname $pkgversion];[::list source -encoding utf-8 $file]" - # We abort in this unknown handler only if we got - # a satisfying candidate for the requested - # package. Otherwise we still have to fallback to - # the regular package search to complete the - # processing. + # We abort in this unknown handler only if we got a + # satisfying candidate for the requested package. + # Otherwise we still have to fallback to the regular + # package search to complete the processing. if { ($pkgname eq $name) && [package vsatisfies $pkgversion {*}$args] } then { set satisfied 1 - # We do not abort the loop, and keep adding - # provide scripts for every candidate in the - # directory, just remember to not fall back to - # the regular search anymore. + + # We do not abort the loop, and keep adding provide + # scripts for every candidate in the directory, just + # remember to not fall back to the regular search + # anymore. } } } @@ -292,8 +280,8 @@ proc ::tcl::tm::UnknownHandler {original name args} { } } - # Fallback to previous command, if existing. See comment above - # about ::list... + # Fallback to previous command, if existing. See comment above about + # ::list... if {[llength $original]} { uplevel 1 $original [::linsert $args 0 $name] @@ -374,7 +362,7 @@ proc ::tcl::tm::roots {paths} { return } -# Initialization. Set up the default paths, then insert the new -# handler into the chain. +# Initialization. Set up the default paths, then insert the new handler into +# the chain. if {![interp issafe]} { ::tcl::tm::Defaults } |