| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| namespace eval tcl::Pkg {} |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| proc tcl::Pkg::CompareExtension {fileName {ext {}}} { |
| global tcl_platform |
| if {$ext eq ""} {set ext [info sharedlibextension]} |
| if {$tcl_platform(platform) eq "windows"} { |
| return [string equal -nocase [file extension $fileName] $ext] |
| } else { |
| |
| |
| set root $fileName |
| while {1} { |
| set currExt [file extension $root] |
| if {$currExt eq $ext} { |
| return 1 |
| } |
|
|
| |
| |
| |
| |
| |
|
|
| if {![string is integer -strict [string range $currExt 1 end]]} { |
| return 0 |
| } |
| set root [file rootname $root] |
| } |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| proc pkg_mkIndex {args} { |
| set usage {"pkg_mkIndex ?-direct? ?-lazy? ?-load pattern? ?-verbose? ?--? dir ?pattern ...?"} |
|
|
| set argCount [llength $args] |
| if {$argCount < 1} { |
| return -code error "wrong # args: should be\n$usage" |
| } |
|
|
| set more "" |
| set direct 1 |
| set doVerbose 0 |
| set loadPat "" |
| for {set idx 0} {$idx < $argCount} {incr idx} { |
| set flag [lindex $args $idx] |
| switch -glob -- $flag { |
| -- { |
| |
| incr idx |
| break |
| } |
| -verbose { |
| set doVerbose 1 |
| } |
| -lazy { |
| set direct 0 |
| append more " -lazy" |
| } |
| -direct { |
| append more " -direct" |
| } |
| -load { |
| incr idx |
| set loadPat [lindex $args $idx] |
| append more " -load $loadPat" |
| } |
| -* { |
| return -code error "unknown flag $flag: should be\n$usage" |
| } |
| default { |
| |
| break |
| } |
| } |
| } |
|
|
| set dir [lindex $args $idx] |
| set patternList [lrange $args [expr {$idx + 1}] end] |
| if {![llength $patternList]} { |
| set patternList [list "*.tcl" "*[info sharedlibextension]"] |
| } |
|
|
| try { |
| set fileList [glob -directory $dir -tails -types {r f} -- \ |
| {*}$patternList] |
| } on error {msg opt} { |
| return -options $opt $msg |
| } |
| foreach file $fileList { |
| |
| |
| |
| |
|
|
| if {$file eq "pkgIndex.tcl"} { |
| continue |
| } |
|
|
| set c [interp create] |
|
|
| |
| |
|
|
| if {$loadPat ne ""} { |
| if {$doVerbose} { |
| tclLog "currently loaded packages: '[info loaded]'" |
| tclLog "trying to load all packages matching $loadPat" |
| } |
| if {![llength [info loaded]]} { |
| tclLog "warning: no packages are currently loaded, nothing" |
| tclLog "can possibly match '$loadPat'" |
| } |
| } |
| foreach pkg [info loaded] { |
| if {![string match -nocase $loadPat [lindex $pkg 1]]} { |
| continue |
| } |
| if {$doVerbose} { |
| tclLog "package [lindex $pkg 1] matches '$loadPat'" |
| } |
| try { |
| load [lindex $pkg 0] [lindex $pkg 1] $c |
| } on error err { |
| if {$doVerbose} { |
| tclLog "warning: load [lindex $pkg 0]\ |
| [lindex $pkg 1]\nfailed with: $err" |
| } |
| } on ok {} { |
| if {$doVerbose} { |
| tclLog "loaded [lindex $pkg 0] [lindex $pkg 1]" |
| } |
| } |
| if {[lindex $pkg 1] eq "Tk"} { |
| |
| $c eval [list wm withdraw .] |
| } |
| } |
|
|
| $c eval { |
| |
| |
|
|
| rename package __package_orig |
| proc package {what args} { |
| switch -- $what { |
| require { |
| return |
| } |
| default { |
| __package_orig $what {*}$args |
| } |
| } |
| } |
| proc tclPkgUnknown args {} |
| package unknown tclPkgUnknown |
|
|
| |
| |
|
|
| proc unknown {args} {} |
|
|
| |
|
|
| proc auto_import {args} {} |
|
|
| |
| |
| |
|
|
| namespace eval ::tcl { |
| variable dir |
| variable file |
| variable direct |
| variable x |
| variable debug |
| variable type |
| variable namespaces |
| variable packages |
| variable origCmds |
| variable newCmds |
| variable newPkgs {} |
| } |
| } |
|
|
| $c eval [list set ::tcl::dir $dir] |
| $c eval [list set ::tcl::file $file] |
| $c eval [list set ::tcl::direct $direct] |
|
|
| |
| |
| |
|
|
| foreach p {::tcl::Pkg::CompareExtension} { |
| $c eval [list namespace eval [namespace qualifiers $p] {}] |
| $c eval [list proc $p [info args $p] [info body $p]] |
| } |
| |
| try { |
| $c eval { |
| set ::tcl::debug "loading or sourcing" |
|
|
| |
| |
| |
|
|
| proc ::tcl::GetAllNamespaces {{root ::}} { |
| set list $root |
| foreach ns [namespace children $root] { |
| lappend list {*}[::tcl::GetAllNamespaces $ns] |
| } |
| return $list |
| } |
|
|
| |
|
|
| foreach ::tcl::x [::tcl::GetAllNamespaces] { |
| set ::tcl::namespaces($::tcl::x) 1 |
| } |
| foreach ::tcl::x [package names] { |
| if {[package provide $::tcl::x] ne ""} { |
| set ::tcl::packages($::tcl::x) 1 |
| } |
| } |
| set ::tcl::origCmds [info commands] |
|
|
| |
| |
| |
| |
| |
|
|
| if {[::tcl::Pkg::CompareExtension $::tcl::file [info sharedlibextension]]} { |
| |
| |
| |
| |
|
|
| set ::tcl::debug loading |
| load [file join $::tcl::dir $::tcl::file] |
| set ::tcl::type load |
| } else { |
| set ::tcl::debug sourcing |
| source [file join $::tcl::dir $::tcl::file] |
| set ::tcl::type source |
| } |
|
|
| |
| |
| |
| |
| if {!$::tcl::direct} { |
| |
| |
|
|
| foreach ::tcl::x [::tcl::GetAllNamespaces] { |
| if {![info exists ::tcl::namespaces($::tcl::x)]} { |
| namespace import -force ${::tcl::x}::* |
| } |
|
|
| |
|
|
| foreach ::tcl::x [info commands] { |
| set ::tcl::newCmds($::tcl::x) 1 |
| } |
| foreach ::tcl::x $::tcl::origCmds { |
| unset -nocomplain ::tcl::newCmds($::tcl::x) |
| } |
| foreach ::tcl::x [array names ::tcl::newCmds] { |
| |
|
|
| set ::tcl::abs [namespace origin $::tcl::x] |
|
|
| |
| |
| |
|
|
| set ::tcl::abs \ |
| [lindex [auto_qualify $::tcl::abs ::] 0] |
|
|
| if {$::tcl::x ne $::tcl::abs} { |
| |
|
|
| set ::tcl::newCmds($::tcl::abs) 1 |
| unset ::tcl::newCmds($::tcl::x) |
| } |
| } |
| } |
| } |
|
|
| |
| |
|
|
| foreach ::tcl::x [package names] { |
| if {[package provide $::tcl::x] ne "" |
| && ![info exists ::tcl::packages($::tcl::x)]} { |
| lappend ::tcl::newPkgs \ |
| [list $::tcl::x [package provide $::tcl::x]] |
| } |
| } |
| } |
| } on error msg { |
| set what [$c eval set ::tcl::debug] |
| if {$doVerbose} { |
| tclLog "warning: error while $what $file: $msg" |
| } |
| } on ok {} { |
| set what [$c eval set ::tcl::debug] |
| if {$doVerbose} { |
| tclLog "successful $what of $file" |
| } |
| set type [$c eval set ::tcl::type] |
| set cmds [lsort [$c eval array names ::tcl::newCmds]] |
| set pkgs [$c eval set ::tcl::newPkgs] |
| if {$doVerbose} { |
| if {!$direct} { |
| tclLog "commands provided were $cmds" |
| } |
| tclLog "packages provided were $pkgs" |
| } |
| if {[llength $pkgs] > 1} { |
| tclLog "warning: \"$file\" provides more than one package ($pkgs)" |
| } |
| foreach pkg $pkgs { |
| |
| lappend files($pkg) [list $file $type $cmds] |
| } |
|
|
| if {$doVerbose} { |
| tclLog "processed $file" |
| } |
| } |
| interp delete $c |
| } |
|
|
| append index "# Tcl package index file, version 1.1\n" |
| append index "# This file is generated by the \"pkg_mkIndex$more\" command\n" |
| append index "# and sourced either when an application starts up or\n" |
| append index "# by a \"package unknown\" script. It invokes the\n" |
| append index "# \"package ifneeded\" command to set up package-related\n" |
| append index "# information so that packages will be loaded automatically\n" |
| append index "# in response to \"package require\" commands. When this\n" |
| append index "# script is sourced, the variable \$dir must contain the\n" |
| append index "# full path name of this file's directory.\n" |
|
|
| foreach pkg [lsort [array names files]] { |
| set cmd {} |
| lassign $pkg name version |
| lappend cmd ::tcl::Pkg::Create -name $name -version $version |
| foreach spec [lsort -index 0 $files($pkg)] { |
| foreach {file type procs} $spec { |
| if {$direct} { |
| set procs {} |
| } |
| lappend cmd "-$type" [list $file $procs] |
| } |
| } |
| append index "\n[eval $cmd]" |
| } |
|
|
| set f [open [file join $dir pkgIndex.tcl] w] |
| puts $f $index |
| close $f |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| proc tclPkgSetup {dir pkg version files} { |
| global auto_index |
|
|
| package provide $pkg $version |
| foreach fileInfo $files { |
| set f [lindex $fileInfo 0] |
| set type [lindex $fileInfo 1] |
| foreach cmd [lindex $fileInfo 2] { |
| if {$type eq "load"} { |
| set auto_index($cmd) [list load [file join $dir $f] $pkg] |
| } else { |
| set auto_index($cmd) [list source [file join $dir $f]] |
| } |
| } |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| proc tclPkgUnknown {name args} { |
| global auto_path env |
|
|
| if {![info exists auto_path]} { |
| return |
| } |
| |
| |
| set old_path [set use_path $auto_path] |
| while {[llength $use_path]} { |
| set dir [lindex $use_path end] |
|
|
| |
| if {[info exists tclSeenPath($dir)]} { |
| set use_path [lrange $use_path 0 end-1] |
| continue |
| } |
| set tclSeenPath($dir) 1 |
|
|
| |
| |
| |
| |
| |
| |
| catch { |
| foreach file [glob -directory $dir -join -nocomplain \ |
| * pkgIndex.tcl] { |
| set dir [file dirname $file] |
| if {![info exists procdDirs($dir)]} { |
| try { |
| source $file |
| } trap {POSIX EACCES} {} { |
| |
| continue |
| } on error msg { |
| tclLog "error reading package index file $file: $msg" |
| } on ok {} { |
| set procdDirs($dir) 1 |
| } |
| } |
| } |
| } |
| set dir [lindex $use_path end] |
| if {![info exists procdDirs($dir)]} { |
| set file [file join $dir pkgIndex.tcl] |
| |
| if {([interp issafe] || [file exists $file])} { |
| try { |
| source $file |
| } trap {POSIX EACCES} {} { |
| |
| continue |
| } on error msg { |
| tclLog "error reading package index file $file: $msg" |
| } on ok {} { |
| set procdDirs($dir) 1 |
| } |
| } |
| } |
|
|
| set use_path [lrange $use_path 0 end-1] |
|
|
| |
| |
| |
| |
| |
| set index 0 |
| if {[llength $old_path] == [llength $auto_path]} { |
| foreach dir $auto_path old $old_path { |
| if {$dir ne $old} { |
| |
| break |
| } |
| incr index |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| foreach dir [lrange $auto_path $index end] { |
| if {![info exists tclSeenPath($dir)] && ($dir ni $use_path)} { |
| lappend use_path $dir |
| } |
| } |
| set old_path $auto_path |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| proc tcl::MacOSXPkgUnknown {original name args} { |
| |
| uplevel 1 $original [linsert $args 0 $name] |
|
|
| |
| global auto_path |
|
|
| if {![info exists auto_path]} { |
| return |
| } |
| |
| |
| set old_path [set use_path $auto_path] |
| while {[llength $use_path]} { |
| set dir [lindex $use_path end] |
|
|
| |
| if {[info exists tclSeenPath($dir)]} { |
| set use_path [lrange $use_path 0 end-1] |
| continue |
| } |
| set tclSeenPath($dir) 1 |
|
|
| |
| |
| foreach file [glob -directory $dir -join -nocomplain \ |
| * Resources Scripts pkgIndex.tcl] { |
| set dir [file dirname $file] |
| if {![info exists procdDirs($dir)]} { |
| try { |
| source $file |
| } trap {POSIX EACCES} {} { |
| |
| continue |
| } on error msg { |
| tclLog "error reading package index file $file: $msg" |
| } on ok {} { |
| set procdDirs($dir) 1 |
| } |
| } |
| } |
| set use_path [lrange $use_path 0 end-1] |
|
|
| |
| |
| |
| |
| |
| set index 0 |
| if {[llength $old_path] == [llength $auto_path]} { |
| foreach dir $auto_path old $old_path { |
| if {$dir ne $old} { |
| |
| break |
| } |
| incr index |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| foreach dir [lrange $auto_path $index end] { |
| if {![info exists tclSeenPath($dir)] && ($dir ni $use_path)} { |
| lappend use_path $dir |
| } |
| } |
| set old_path $auto_path |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| proc ::tcl::Pkg::Create {args} { |
| append err(usage) "[lindex [info level 0] 0] " |
| append err(usage) "-name packageName -version packageVersion" |
| append err(usage) "?-load {filename ?{procs}?}? ... " |
| append err(usage) "?-source {filename ?{procs}?}? ..." |
|
|
| set err(wrongNumArgs) "wrong # args: should be \"$err(usage)\"" |
| set err(valueMissing) "value for \"%s\" missing: should be \"$err(usage)\"" |
| set err(unknownOpt) "unknown option \"%s\": should be \"$err(usage)\"" |
| set err(noLoadOrSource) "at least one of -load and -source must be given" |
|
|
| |
| set len [llength $args] |
| if {$len < 6} { |
| error $err(wrongNumArgs) |
| } |
|
|
| |
| array set opts {-name {} -version {} -source {} -load {}} |
|
|
| |
| for {set i 0} {$i < $len} {incr i} { |
| set flag [lindex $args $i] |
| incr i |
| switch -glob -- $flag { |
| "-name" - |
| "-version" { |
| if {$i >= $len} { |
| error [format $err(valueMissing) $flag] |
| } |
| set opts($flag) [lindex $args $i] |
| } |
| "-source" - |
| "-load" { |
| if {$i >= $len} { |
| error [format $err(valueMissing) $flag] |
| } |
| lappend opts($flag) [lindex $args $i] |
| } |
| default { |
| error [format $err(unknownOpt) [lindex $args $i]] |
| } |
| } |
| } |
|
|
| |
| if {![llength $opts(-name)]} { |
| error [format $err(valueMissing) "-name"] |
| } |
| if {![llength $opts(-version)]} { |
| error [format $err(valueMissing) "-version"] |
| } |
|
|
| if {!([llength $opts(-source)] || [llength $opts(-load)])} { |
| error $err(noLoadOrSource) |
| } |
|
|
| |
| set cmdline "package ifneeded $opts(-name) $opts(-version) " |
|
|
| set cmdList {} |
| set lazyFileList {} |
|
|
| |
| foreach key {load source} { |
| foreach filespec $opts(-$key) { |
| lassign $filespec filename proclist |
|
|
| if { [llength $proclist] == 0 } { |
| set cmd "\[list $key \[file join \$dir [list $filename]\]\]" |
| lappend cmdList $cmd |
| } else { |
| lappend lazyFileList [list $filename $key $proclist] |
| } |
| } |
| } |
|
|
| if {[llength $lazyFileList]} { |
| lappend cmdList "\[list tclPkgSetup \$dir $opts(-name)\ |
| $opts(-version) [list $lazyFileList]\]" |
| } |
| append cmdline [join $cmdList "\\n"] |
| return $cmdline |
| } |
|
|
| interp alias {} ::pkg::create {} ::tcl::Pkg::Create |
|
|