summaryrefslogtreecommitdiffstats
path: root/contrib/tcl/library/init.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tcl/library/init.tcl')
-rw-r--r--contrib/tcl/library/init.tcl106
1 files changed, 74 insertions, 32 deletions
diff --git a/contrib/tcl/library/init.tcl b/contrib/tcl/library/init.tcl
index 43bd37c..1985224 100644
--- a/contrib/tcl/library/init.tcl
+++ b/contrib/tcl/library/init.tcl
@@ -3,7 +3,7 @@
# Default system startup file for Tcl-based applications. Defines
# "unknown" procedure and auto-load facilities.
#
-# SCCS: @(#) init.tcl 1.79 97/06/24 17:18:54
+# SCCS: @(#) init.tcl 1.86 97/08/08 10:37:39
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
@@ -18,9 +18,11 @@ if {[info commands package] == ""} {
package require -exact Tcl 8.0
# Compute the auto path to use in this interpreter.
-
-if [catch {set auto_path $env(TCLLIBPATH)}] {
- set auto_path ""
+# (auto_path could be already set, in safe interps for instance)
+if {![info exists auto_path]} {
+ if [catch {set auto_path $env(TCLLIBPATH)}] {
+ set auto_path ""
+ }
}
if {[lsearch -exact $auto_path [info library]] < 0} {
lappend auto_path [info library]
@@ -47,6 +49,14 @@ if {[info commands exec] == ""} {
set errorCode ""
set errorInfo ""
+# Define a log command (which can be overwitten to log errors
+# differently, specially when stderr is not available)
+
+if {[info commands tclLog] == ""} {
+ proc tclLog {string} {
+ catch {puts stderr $string}
+ }
+}
# unknown --
# This procedure is called when a Tcl command is invoked that doesn't
@@ -132,14 +142,17 @@ proc unknown args {
set errorCode $savedErrorCode
set errorInfo $savedErrorInfo
if {$name == "!!"} {
-# return [uplevel {history redo}]
- return -code error "!! is disabled until history is fixed in Tcl8.0"
+ set newcmd [history event]
+ } elseif {[regexp {^!(.+)$} $name dummy event]} {
+ set newcmd [history event $event]
+ } elseif {[regexp {^\^([^^]*)\^([^^]*)\^?$} $name dummy old new]} {
+ set newcmd [history event -1]
+ catch {regsub -all -- $old $newcmd $new newcmd}
}
- if [regexp {^!(.+)$} $name dummy event] {
- return [uplevel [list history redo $event]]
- }
- if [regexp {^\^([^^]*)\^([^^]*)\^?$} $name dummy old new] {
- return [uplevel [list history substitute $old $new]]
+ if [info exists newcmd] {
+ tclLog $newcmd
+ history change $newcmd 0
+ return [uplevel $newcmd]
}
set ret [catch {set cmds [info commands $name*]} msg]
@@ -177,9 +190,11 @@ proc unknown args {
proc auto_load cmd {
global auto_index auto_oldpath auto_path env errorInfo errorCode
- if [info exists auto_index($cmd)] {
- uplevel #0 $auto_index($cmd)
- return [expr {[info commands $cmd] != ""}]
+ foreach name [list $cmd ::$cmd] {
+ if [info exists auto_index($name)] {
+ uplevel #0 $auto_index($name)
+ return [expr {[info commands $name] != ""}]
+ }
}
if ![info exists auto_path] {
return 0
@@ -455,6 +470,10 @@ proc auto_mkindex {dir args} {
proc pkg_mkIndex {dir args} {
global errorCode errorInfo
+ if {[llength $args] == 0} {
+ return -code error "wrong # args: should be\
+ \"pkg_mkIndex dir pattern ?pattern ...?\"";
+ }
append index "# Tcl package index file, version 1.0\n"
append index "# This file is generated by the \"pkg_mkIndex\" command\n"
append index "# and sourced either when an application starts up or\n"
@@ -489,6 +508,13 @@ proc pkg_mkIndex {dir args} {
if [catch {
$c eval {
proc dummy args {}
+ rename package package-orig
+ proc package {what args} {
+ switch -- $what {
+ require { return ; # ignore transitive requires }
+ default { eval package-orig {$what} $args }
+ }
+ }
package unknown dummy
set origCmds [info commands]
set dir "" ;# in case file is pkgIndex.tcl
@@ -514,11 +540,23 @@ proc pkg_mkIndex {dir args} {
source $file
set type source
}
+ foreach ns [namespace children] {
+ namespace import ${ns}::*
+ }
foreach i [info commands] {
set cmds($i) 1
}
foreach i $origCmds {
catch {unset cmds($i)}
+
+ }
+ foreach i [array names cmds] {
+ # reverse engineer which namespace a command comes from
+ set absolute [namespace origin $i]
+ if {[string compare ::$i $absolute] != 0} {
+ set cmds($absolute) 1
+ unset cmds($i)
+ }
}
foreach i [package names] {
if {([string compare [package provide $i] ""] != 0)
@@ -529,7 +567,7 @@ proc pkg_mkIndex {dir args} {
}
}
} msg] {
- puts "error while loading or sourcing $file: $msg"
+ tclLog "error while loading or sourcing $file: $msg"
}
foreach pkg [$c eval set pkgs] {
lappend files($pkg) [list $file [$c eval set type] \
@@ -623,33 +661,37 @@ proc tclPkgUnknown {name version {exact {}}} {
set save_dir $dir
}
for {set i [expr [llength $auto_path] - 1]} {$i >= 0} {incr i -1} {
- foreach file [glob -nocomplain [file join [lindex $auto_path $i] \
- * pkgIndex.tcl]] {
- set dir [file dirname $file]
- if [catch {source $file} msg] {
- puts stderr \
- "error reading package index file $file: $msg"
+ # we can't use glob in safe interps, so enclose the following
+ # in a catch statement
+ catch {
+ foreach file [glob -nocomplain [file join [lindex $auto_path $i] \
+ * pkgIndex.tcl]] {
+ set dir [file dirname $file]
+ if [catch {source $file} msg] {
+ tclLog "error reading package index file $file: $msg"
+ }
}
- }
+ }
set dir [lindex $auto_path $i]
set file [file join $dir pkgIndex.tcl]
- if [file readable $file] {
- if [catch {source $file} msg] {
- puts stderr \
- "error reading package index file $file: $msg"
+ # safe interps usually don't have "file readable", nor stderr channel
+ if {[interp issafe] || [file readable $file]} {
+ if {[catch {source $file} msg] && ![interp issafe]} {
+ tclLog "error reading package index file $file: $msg"
}
}
# On the Macintosh we also look in the resource fork
# of shared libraries
- if {$tcl_platform(platform) == "macintosh"} {
+ # We can't use tclMacPkgSearch in safe interps because it uses glob
+ if {(![interp issafe]) && ($tcl_platform(platform) == "macintosh")} {
set dir [lindex $auto_path $i]
tclMacPkgSearch $dir
- foreach x [glob -nocomplain [file join $dir *]] {
- if [file isdirectory $x] {
- set dir $x
- tclMacPkgSearch $dir
+ foreach x [glob -nocomplain [file join $dir *]] {
+ if [file isdirectory $x] {
+ set dir $x
+ tclMacPkgSearch $dir
+ }
}
- }
}
}
if {[info exists save_dir]} {
OpenPOWER on IntegriCloud