📄 auto.tcl
字号:
} } proc cleanup {} { variable parser interp delete $parser unset 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.## Arguments: # file Name of Tcl source file to be indexed.proc auto_mkindex_parser::mkindex {file} { variable parser variable index variable scriptFile variable contextStack variable imports set scriptFile $file set fid [open $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. regsub -all {\$} $contents "\0" contents set index "" set contextStack "" set imports "" $parser eval $contents foreach name $imports { catch {$parser eval [list _%@namespace forget $name]} } return $index}# 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 slaveproc auto_mkindex_parser::hook {cmd} { variable initCommands lappend initCommands $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.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. 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.## 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.# arglist Argument list for command.# body Implementation of command to handle indexing.proc auto_mkindex_parser::command {name arglist body} { hook [list auto_mkindex_parser::commandInit $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.## Arguments:# name Name of command recognized in Tcl files.# arglist Argument list for command.# body Implementation of command to handle indexing.proc auto_mkindex_parser::commandInit {name arglist body} { variable parser set ns [namespace qualifiers $name] set tail [namespace tail $name] if {[string equal $ns ""]} { set fakeName "[namespace current]::_%@fake_$tail" } else { set fakeName "_%@fake_$name" regsub -all {::} $fakeName "_" fakeName set fakeName "[namespace current]::$fakeName" } 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. if {[regexp {::} $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: # "_%@eval {$alias} \$args" # 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 set alias [namespace tail $fakeName] $parser invokehidden proc $name {args} "_%@eval {$alias} \$args" $parser alias $alias $fakeName } else { $parser alias $name $fakeName } return}# 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.## Arguments:# name - Name that is being added to index.proc auto_mkindex_parser::fullname {name} { variable contextStack if {![string match ::* $name]} { foreach ns $contextStack { set name "${ns}::$name" if {[string match ::* $name]} { break } } } if {[string equal [namespace qualifiers $name] ""]} { set name [namespace tail $name] } elseif {![string match ::* $name]} { set name "::$name" } # Earlier, mkindex replaced all $'s with \0. Now, we have to reverse # that replacement. regsub -all "\0" $name "\$" name return $name}# 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.auto_mkindex_parser::command proc {name args} { variable index variable scriptFile # Do some fancy reformatting on the "source" call to handle platform # differences with respect to pathnames. Use format just so that the # command is a little easier to read (otherwise it'd be full of # backslashed dollar signs, etc. append index [list set auto_index([fullname $name])] \ [format { [list source [file join $dir %s]]} \ [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 loadedauto_mkindex_parser::hook { if {![catch {package require tbcload}]} { if {[llength [info commands tbcload::bcproc]] == 0} { auto_load tbcload::bcproc } load {} tbcload $auto_mkindex_parser::parser # AUTO MKINDEX: tbcload::bcproc name arglist body # Adds an entry to the auto index list for the given pre-compiled # procedure name. auto_mkindex_parser::commandInit tbcload::bcproc {name args} { variable index variable scriptFile # Do some nice reformatting of the "source" call, to get around # path differences on different platforms. We use the format # command just so that the code is a little easier to read. append index [list set auto_index([fullname $name])] \ [format { [list source [file join $dir %s]]} \ [file split $scriptFile]] "\n" } }}# AUTO MKINDEX: namespace eval name command ?arg arg...?# 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.auto_mkindex_parser::command namespace {op args} { switch -- $op { eval { variable parser variable contextStack set name [lindex $args 0] set args [lrange $args 1 end] set contextStack [linsert $contextStack 0 $name] $parser eval [list _%@namespace eval $name] $args set contextStack [lrange $contextStack 1 end] } import { variable parser variable imports foreach pattern $args { if {[string compare $pattern "-force"]} { lappend imports $pattern } } catch {$parser eval "_%@namespace import $args"} } }}return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -