| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | 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 |
| |
|