| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | if {[info commands package] == ""} { |
| | error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]" |
| | } |
| | package require -exact Tcl 8.6.14 |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | if {![info exists auto_path]} { |
| | if {[info exists env(TCLLIBPATH)] && (![interp issafe])} { |
| | set auto_path $env(TCLLIBPATH) |
| | } else { |
| | set auto_path "" |
| | } |
| | } |
| | namespace eval tcl { |
| | if {![interp issafe]} { |
| | variable Dir |
| | foreach Dir [list $::tcl_library [file dirname $::tcl_library]] { |
| | if {$Dir ni $::auto_path} { |
| | lappend ::auto_path $Dir |
| | } |
| | } |
| | set Dir [file join [file dirname [file dirname \ |
| | [info nameofexecutable]]] lib] |
| | if {$Dir ni $::auto_path} { |
| | lappend ::auto_path $Dir |
| | } |
| | if {[info exists ::tcl_pkgPath]} { catch { |
| | foreach Dir $::tcl_pkgPath { |
| | if {$Dir ni $::auto_path} { |
| | lappend ::auto_path $Dir |
| | } |
| | } |
| | }} |
| |
|
| | variable Path [encoding dirs] |
| | set Dir [file join $::tcl_library encoding] |
| | if {$Dir ni $Path} { |
| | lappend Path $Dir |
| | encoding dirs $Path |
| | } |
| | unset Dir Path |
| | } |
| |
|
| | |
| | namespace eval mathfunc { |
| | proc min {args} { |
| | if {![llength $args]} { |
| | return -code error \ |
| | "not enough arguments to math function \"min\"" |
| | } |
| | set val Inf |
| | foreach arg $args { |
| | |
| | |
| | if {[catch {expr {double($arg)}} err]} { |
| | return -code error $err |
| | } |
| | if {$arg < $val} {set val $arg} |
| | } |
| | return $val |
| | } |
| | proc max {args} { |
| | if {![llength $args]} { |
| | return -code error \ |
| | "not enough arguments to math function \"max\"" |
| | } |
| | set val -Inf |
| | foreach arg $args { |
| | |
| | |
| | if {[catch {expr {double($arg)}} err]} { |
| | return -code error $err |
| | } |
| | if {$arg > $val} {set val $arg} |
| | } |
| | return $val |
| | } |
| | namespace export min max |
| | } |
| | } |
| |
|
| | |
| |
|
| | if {(![interp issafe]) && ($tcl_platform(platform) eq "windows")} { |
| | namespace eval tcl { |
| | proc EnvTraceProc {lo n1 n2 op} { |
| | global env |
| | set x $env($n2) |
| | set env($lo) $x |
| | set env([string toupper $lo]) $x |
| | } |
| | proc InitWinEnv {} { |
| | global env tcl_platform |
| | foreach p [array names env] { |
| | set u [string toupper $p] |
| | if {$u ne $p} { |
| | switch -- $u { |
| | COMSPEC - |
| | PATH { |
| | set temp $env($p) |
| | unset env($p) |
| | set env($u) $temp |
| | trace add variable env($p) write \ |
| | [namespace code [list EnvTraceProc $p]] |
| | trace add variable env($u) write \ |
| | [namespace code [list EnvTraceProc $p]] |
| | } |
| | } |
| | } |
| | } |
| | if {![info exists env(COMSPEC)]} { |
| | set env(COMSPEC) cmd.exe |
| | } |
| | } |
| | InitWinEnv |
| | } |
| | } |
| |
|
| | |
| |
|
| |
|
| | if {[interp issafe]} { |
| | package unknown {::tcl::tm::UnknownHandler ::tclPkgUnknown} |
| | } else { |
| | |
| | |
| | if {$tcl_platform(os) eq "Darwin" |
| | && $tcl_platform(platform) eq "unix"} { |
| | package unknown {::tcl::tm::UnknownHandler \ |
| | {::tcl::MacOSXPkgUnknown ::tclPkgUnknown}} |
| | } else { |
| | package unknown {::tcl::tm::UnknownHandler ::tclPkgUnknown} |
| | } |
| |
|
| | |
| |
|
| | namespace eval ::tcl::clock [list variable TclLibDir $::tcl_library] |
| |
|
| | proc ::tcl::initClock {} { |
| | |
| |
|
| | foreach cmd {add format scan} { |
| | proc ::tcl::clock::$cmd args { |
| | variable TclLibDir |
| | source -encoding utf-8 [file join $TclLibDir clock.tcl] |
| | return [uplevel 1 [info level 0]] |
| | } |
| | } |
| |
|
| | rename ::tcl::initClock {} |
| | } |
| | ::tcl::initClock |
| | } |
| |
|
| | |
| |
|
| | if {[namespace which -command exec] eq ""} { |
| |
|
| | |
| | |
| |
|
| | set auto_noexec 1 |
| | } |
| |
|
| | |
| | |
| |
|
| | if {[namespace which -command tclLog] eq ""} { |
| | proc tclLog {string} { |
| | catch {puts stderr $string} |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc unknown args { |
| | variable ::tcl::UnknownPending |
| | global auto_noexec auto_noload env tcl_interactive errorInfo errorCode |
| |
|
| | if {[info exists errorInfo]} { |
| | set savedErrorInfo $errorInfo |
| | } |
| | if {[info exists errorCode]} { |
| | set savedErrorCode $errorCode |
| | } |
| |
|
| | set name [lindex $args 0] |
| | if {![info exists auto_noload]} { |
| | |
| | |
| | |
| | if {[info exists UnknownPending($name)]} { |
| | return -code error "self-referential recursion\ |
| | in \"unknown\" for command \"$name\"" |
| | } |
| | set UnknownPending($name) pending |
| | set ret [catch { |
| | auto_load $name [uplevel 1 {::namespace current}] |
| | } msg opts] |
| | unset UnknownPending($name) |
| | if {$ret != 0} { |
| | dict append opts -errorinfo "\n (autoloading \"$name\")" |
| | return -options $opts $msg |
| | } |
| | if {![array size UnknownPending]} { |
| | unset UnknownPending |
| | } |
| | if {$msg} { |
| | if {[info exists savedErrorCode]} { |
| | set ::errorCode $savedErrorCode |
| | } else { |
| | unset -nocomplain ::errorCode |
| | } |
| | if {[info exists savedErrorInfo]} { |
| | set errorInfo $savedErrorInfo |
| | } else { |
| | unset -nocomplain errorInfo |
| | } |
| | set code [catch {uplevel 1 $args} msg opts] |
| | if {$code == 1} { |
| | |
| | |
| | |
| | |
| | |
| | set errInfo [dict get $opts -errorinfo] |
| | set errCode [dict get $opts -errorcode] |
| | set cinfo $args |
| | if {[string bytelength $cinfo] > 150} { |
| | set cinfo [string range $cinfo 0 150] |
| | while {[string bytelength $cinfo] > 150} { |
| | set cinfo [string range $cinfo 0 end-1] |
| | } |
| | append cinfo ... |
| | } |
| | set tail "\n (\"uplevel\" body line 1)\n invoked\ |
| | from within\n\"uplevel 1 \$args\"" |
| | set expect "$msg\n while executing\n\"$cinfo\"$tail" |
| | if {$errInfo eq $expect} { |
| | |
| | |
| | |
| | |
| | dict unset opts -errorinfo |
| | dict incr opts -level |
| | return -options $opts $msg |
| | } |
| | |
| | |
| | |
| | |
| | set last [string last $tail $errInfo] |
| | if {$last + [string length $tail] != [string length $errInfo]} { |
| | |
| | return -options $opts $msg |
| | } |
| | set errInfo [string range $errInfo 0 $last-1] |
| | set tail "\"$cinfo\"" |
| | set last [string last $tail $errInfo] |
| | if {$last < 0 || $last + [string length $tail] != [string length $errInfo]} { |
| | return -code error -errorcode $errCode \ |
| | -errorinfo $errInfo $msg |
| | } |
| | set errInfo [string range $errInfo 0 $last-1] |
| | set tail "\n invoked from within\n" |
| | set last [string last $tail $errInfo] |
| | if {$last + [string length $tail] == [string length $errInfo]} { |
| | return -code error -errorcode $errCode \ |
| | -errorinfo [string range $errInfo 0 $last-1] $msg |
| | } |
| | set tail "\n while executing\n" |
| | set last [string last $tail $errInfo] |
| | if {$last + [string length $tail] == [string length $errInfo]} { |
| | return -code error -errorcode $errCode \ |
| | -errorinfo [string range $errInfo 0 $last-1] $msg |
| | } |
| | return -options $opts $msg |
| | } else { |
| | dict incr opts -level |
| | return -options $opts $msg |
| | } |
| | } |
| | } |
| |
|
| | if {([info level] == 1) && ([info script] eq "") |
| | && [info exists tcl_interactive] && $tcl_interactive} { |
| | if {![info exists auto_noexec]} { |
| | set new [auto_execok $name] |
| | if {$new ne ""} { |
| | set redir "" |
| | if {[namespace which -command console] eq ""} { |
| | set redir ">&@stdout <@stdin" |
| | } |
| | uplevel 1 [list ::catch \ |
| | [concat exec $redir $new [lrange $args 1 end]] \ |
| | ::tcl::UnknownResult ::tcl::UnknownOptions] |
| | dict incr ::tcl::UnknownOptions -level |
| | return -options $::tcl::UnknownOptions $::tcl::UnknownResult |
| | } |
| | } |
| | if {$name eq "!!"} { |
| | set newcmd [history event] |
| | } elseif {[regexp {^!(.+)$} $name -> event]} { |
| | set newcmd [history event $event] |
| | } elseif {[regexp {^\^([^^]*)\^([^^]*)\^?$} $name -> old new]} { |
| | set newcmd [history event -1] |
| | catch {regsub -all -- $old $newcmd $new newcmd} |
| | } |
| | if {[info exists newcmd]} { |
| | tclLog $newcmd |
| | history change $newcmd 0 |
| | uplevel 1 [list ::catch $newcmd \ |
| | ::tcl::UnknownResult ::tcl::UnknownOptions] |
| | dict incr ::tcl::UnknownOptions -level |
| | return -options $::tcl::UnknownOptions $::tcl::UnknownResult |
| | } |
| |
|
| | set ret [catch [list uplevel 1 [list info commands $name*]] candidates] |
| | if {$name eq "::"} { |
| | set name "" |
| | } |
| | if {$ret != 0} { |
| | dict append opts -errorinfo \ |
| | "\n (expanding command prefix \"$name\" in unknown)" |
| | return -options $opts $candidates |
| | } |
| | |
| | |
| | if {$name eq ""} { |
| | |
| | |
| | set cmds $candidates |
| | } else { |
| | set cmds [list] |
| | foreach x $candidates { |
| | if {[string first $name $x] == 0} { |
| | lappend cmds $x |
| | } |
| | } |
| | } |
| | if {[llength $cmds] == 1} { |
| | uplevel 1 [list ::catch [lreplace $args 0 0 [lindex $cmds 0]] \ |
| | ::tcl::UnknownResult ::tcl::UnknownOptions] |
| | dict incr ::tcl::UnknownOptions -level |
| | return -options $::tcl::UnknownOptions $::tcl::UnknownResult |
| | } |
| | if {[llength $cmds]} { |
| | return -code error "ambiguous command name \"$name\": [lsort $cmds]" |
| | } |
| | } |
| | return -code error -errorcode [list TCL LOOKUP COMMAND $name] \ |
| | "invalid command name \"$name\"" |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc auto_load {cmd {namespace {}}} { |
| | global auto_index auto_path |
| |
|
| | if {$namespace eq ""} { |
| | set namespace [uplevel 1 [list ::namespace current]] |
| | } |
| | set nameList [auto_qualify $cmd $namespace] |
| | |
| | |
| | lappend nameList $cmd |
| | foreach name $nameList { |
| | if {[info exists auto_index($name)]} { |
| | namespace eval :: $auto_index($name) |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | if {[namespace which -command $name] ne ""} { |
| | return 1 |
| | } |
| | } |
| | } |
| | if {![info exists auto_path]} { |
| | return 0 |
| | } |
| |
|
| | if {![auto_load_index]} { |
| | return 0 |
| | } |
| | foreach name $nameList { |
| | if {[info exists auto_index($name)]} { |
| | namespace eval :: $auto_index($name) |
| | if {[namespace which -command $name] ne ""} { |
| | return 1 |
| | } |
| | } |
| | } |
| | return 0 |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc auto_load_index {} { |
| | variable ::tcl::auto_oldpath |
| | global auto_index auto_path |
| |
|
| | if {[info exists auto_oldpath] && ($auto_oldpath eq $auto_path)} { |
| | return 0 |
| | } |
| | set auto_oldpath $auto_path |
| |
|
| | |
| | |
| |
|
| | set issafe [interp issafe] |
| | for {set i [expr {[llength $auto_path] - 1}]} {$i >= 0} {incr i -1} { |
| | set dir [lindex $auto_path $i] |
| | set f "" |
| | if {$issafe} { |
| | catch {source [file join $dir tclIndex]} |
| | } elseif {[catch {set f [open [file join $dir tclIndex]]}]} { |
| | continue |
| | } else { |
| | set error [catch { |
| | fconfigure $f -eofchar "\x1A {}" |
| | set id [gets $f] |
| | if {$id eq "# Tcl autoload index file, version 2.0"} { |
| | eval [read $f] |
| | } elseif {$id eq "# Tcl autoload index file: each line identifies a Tcl"} { |
| | while {[gets $f line] >= 0} { |
| | if {([string index $line 0] eq "#") \ |
| | || ([llength $line] != 2)} { |
| | continue |
| | } |
| | set name [lindex $line 0] |
| | set auto_index($name) \ |
| | "source [file join $dir [lindex $line 1]]" |
| | } |
| | } else { |
| | error "[file join $dir tclIndex] isn't a proper Tcl index file" |
| | } |
| | } msg opts] |
| | if {$f ne ""} { |
| | close $f |
| | } |
| | if {$error} { |
| | return -options $opts $msg |
| | } |
| | } |
| | } |
| | return 1 |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc auto_qualify {cmd namespace} { |
| |
|
| | |
| | |
| | set n [regsub -all {::+} $cmd :: cmd] |
| |
|
| | |
| | |
| |
|
| | |
| | |
| | |
| |
|
| | if {[string match ::* $cmd]} { |
| | if {$n > 1} { |
| | |
| | return [list $cmd] |
| | } else { |
| | |
| | return [list [string range $cmd 2 end]] |
| | } |
| | } |
| |
|
| | |
| | |
| |
|
| | if {$n == 0} { |
| | if {$namespace eq "::"} { |
| | |
| | return [list $cmd] |
| | } else { |
| | |
| | return [list ${namespace}::$cmd $cmd] |
| | } |
| | } elseif {$namespace eq "::"} { |
| | |
| | return [list ::$cmd] |
| | } else { |
| | |
| | return [list ${namespace}::$cmd ::$cmd] |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | proc auto_import {pattern} { |
| | global auto_index |
| |
|
| | |
| |
|
| | if {![string match *::* $pattern]} { |
| | return |
| | } |
| |
|
| | set ns [uplevel 1 [list ::namespace current]] |
| | set patternList [auto_qualify $pattern $ns] |
| |
|
| | auto_load_index |
| |
|
| | foreach pattern $patternList { |
| | foreach name [array names auto_index $pattern] { |
| | if {([namespace which -command $name] eq "") |
| | && ([namespace qualifiers $pattern] eq [namespace qualifiers $name])} { |
| | namespace eval :: $auto_index($name) |
| | } |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | if {$tcl_platform(platform) eq "windows"} { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | proc auto_execok name { |
| | global auto_execs env tcl_platform |
| |
|
| | if {[info exists auto_execs($name)]} { |
| | return $auto_execs($name) |
| | } |
| | set auto_execs($name) "" |
| |
|
| | set shellBuiltins [list assoc cls copy date del dir echo erase exit ftype \ |
| | md mkdir mklink move rd ren rename rmdir start time type ver vol] |
| | if {[info exists env(PATHEXT)]} { |
| | |
| | set execExtensions [split ";$env(PATHEXT)" ";"] |
| | } else { |
| | set execExtensions [list {} .com .exe .bat .cmd] |
| | } |
| |
|
| | if {[string tolower $name] in $shellBuiltins} { |
| | |
| | |
| | |
| | set cmd $env(COMSPEC) |
| | if {[file exists $cmd]} { |
| | set cmd [file attributes $cmd -shortname] |
| | } |
| | return [set auto_execs($name) [list $cmd /c $name]] |
| | } |
| |
|
| | if {[llength [file split $name]] != 1} { |
| | foreach ext $execExtensions { |
| | set file ${name}${ext} |
| | if {[file exists $file] && ![file isdirectory $file]} { |
| | return [set auto_execs($name) [list $file]] |
| | } |
| | } |
| | return "" |
| | } |
| |
|
| | set path "[file dirname [info nameof]];.;" |
| | if {[info exists env(SystemRoot)]} { |
| | set windir $env(SystemRoot) |
| | } elseif {[info exists env(WINDIR)]} { |
| | set windir $env(WINDIR) |
| | } |
| | if {[info exists windir]} { |
| | if {$tcl_platform(os) eq "Windows NT"} { |
| | append path "$windir/system32;" |
| | } |
| | append path "$windir/system;$windir;" |
| | } |
| |
|
| | foreach var {PATH Path path} { |
| | if {[info exists env($var)]} { |
| | append path ";$env($var)" |
| | } |
| | } |
| |
|
| | foreach ext $execExtensions { |
| | unset -nocomplain checked |
| | foreach dir [split $path {;}] { |
| | |
| | if {[info exists checked($dir)] || ($dir eq "")} { |
| | continue |
| | } |
| | set checked($dir) {} |
| | set file [file join $dir ${name}${ext}] |
| | if {[file exists $file] && ![file isdirectory $file]} { |
| | return [set auto_execs($name) [list $file]] |
| | } |
| | } |
| | } |
| | return "" |
| | } |
| |
|
| | } else { |
| | |
| | |
| | proc auto_execok name { |
| | global auto_execs env |
| |
|
| | if {[info exists auto_execs($name)]} { |
| | return $auto_execs($name) |
| | } |
| | set auto_execs($name) "" |
| | if {[llength [file split $name]] != 1} { |
| | if {[file executable $name] && ![file isdirectory $name]} { |
| | set auto_execs($name) [list $name] |
| | } |
| | return $auto_execs($name) |
| | } |
| | foreach dir [split $env(PATH) :] { |
| | if {$dir eq ""} { |
| | set dir . |
| | } |
| | set file [file join $dir $name] |
| | if {[file executable $file] && ![file isdirectory $file]} { |
| | set auto_execs($name) [list $file] |
| | return $auto_execs($name) |
| | } |
| | } |
| | return "" |
| | } |
| |
|
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | proc tcl::CopyDirectory {action src dest} { |
| | set nsrc [file normalize $src] |
| | set ndest [file normalize $dest] |
| |
|
| | if {$action eq "renaming"} { |
| | |
| | |
| | if {$nsrc in [file volumes]} { |
| | return -code error "error $action \"$src\" to\ |
| | \"$dest\": trying to rename a volume or move a directory\ |
| | into itself" |
| | } |
| | } |
| | if {[file exists $dest]} { |
| | if {$nsrc eq $ndest} { |
| | return -code error "error $action \"$src\" to\ |
| | \"$dest\": trying to rename a volume or move a directory\ |
| | into itself" |
| | } |
| | if {$action eq "copying"} { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | } else { |
| | |
| | |
| | |
| | |
| | set existing [glob -nocomplain -directory $dest * .*] |
| | lappend existing {*}[glob -nocomplain -directory $dest \ |
| | -type hidden * .*] |
| | foreach s $existing { |
| | if {[file tail $s] ni {. ..}} { |
| | return -code error "error $action \"$src\" to\ |
| | \"$dest\": file already exists" |
| | } |
| | } |
| | } |
| | } else { |
| | if {[string first $nsrc $ndest] >= 0} { |
| | set srclen [expr {[llength [file split $nsrc]] - 1}] |
| | set ndest [lindex [file split $ndest] $srclen] |
| | if {$ndest eq [file tail $nsrc]} { |
| | return -code error "error $action \"$src\" to\ |
| | \"$dest\": trying to rename a volume or move a directory\ |
| | into itself" |
| | } |
| | } |
| | file mkdir $dest |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | set filelist [concat [glob -nocomplain -directory $src *] \ |
| | [glob -nocomplain -directory $src -types hidden *]] |
| |
|
| | foreach s [lsort -unique $filelist] { |
| | if {[file tail $s] ni {. ..}} { |
| | file copy -force -- $s [file join $dest [file tail $s]] |
| | } |
| | } |
| | return |
| | } |
| |
|