os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/library/auto.tcl
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
# auto.tcl --
sl@0
     2
#
sl@0
     3
# utility procs formerly in init.tcl dealing with auto execution
sl@0
     4
# of commands and can be auto loaded themselves.
sl@0
     5
#
sl@0
     6
# RCS: @(#) $Id: auto.tcl,v 1.12.2.10 2005/07/23 03:31:41 dgp Exp $
sl@0
     7
#
sl@0
     8
# Copyright (c) 1991-1993 The Regents of the University of California.
sl@0
     9
# Copyright (c) 1994-1998 Sun Microsystems, Inc.
sl@0
    10
#
sl@0
    11
# See the file "license.terms" for information on usage and redistribution
sl@0
    12
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
sl@0
    13
#
sl@0
    14
sl@0
    15
# auto_reset --
sl@0
    16
#
sl@0
    17
# Destroy all cached information for auto-loading and auto-execution,
sl@0
    18
# so that the information gets recomputed the next time it's needed.
sl@0
    19
# Also delete any procedures that are listed in the auto-load index
sl@0
    20
# except those defined in this file.
sl@0
    21
#
sl@0
    22
# Arguments: 
sl@0
    23
# None.
sl@0
    24
sl@0
    25
proc auto_reset {} {
sl@0
    26
    global auto_execs auto_index auto_oldpath
sl@0
    27
    foreach p [info procs] {
sl@0
    28
	if {[info exists auto_index($p)] && ![string match auto_* $p]
sl@0
    29
		&& ([lsearch -exact {unknown pkg_mkIndex tclPkgSetup
sl@0
    30
			tcl_findLibrary pkg_compareExtension
sl@0
    31
			tclPkgUnknown tcl::MacOSXPkgUnknown
sl@0
    32
			tcl::MacPkgUnknown} $p] < 0)} {
sl@0
    33
	    rename $p {}
sl@0
    34
	}
sl@0
    35
    }
sl@0
    36
    unset -nocomplain auto_execs auto_index auto_oldpath
sl@0
    37
}
sl@0
    38
sl@0
    39
# tcl_findLibrary --
sl@0
    40
#
sl@0
    41
#	This is a utility for extensions that searches for a library directory
sl@0
    42
#	using a canonical searching algorithm. A side effect is to source
sl@0
    43
#	the initialization script and set a global library variable.
sl@0
    44
#
sl@0
    45
# Arguments:
sl@0
    46
# 	basename	Prefix of the directory name, (e.g., "tk")
sl@0
    47
#	version		Version number of the package, (e.g., "8.0")
sl@0
    48
#	patch		Patchlevel of the package, (e.g., "8.0.3")
sl@0
    49
#	initScript	Initialization script to source (e.g., tk.tcl)
sl@0
    50
#	enVarName	environment variable to honor (e.g., TK_LIBRARY)
sl@0
    51
#	varName		Global variable to set when done (e.g., tk_library)
sl@0
    52
sl@0
    53
proc tcl_findLibrary {basename version patch initScript enVarName varName} {
sl@0
    54
    upvar #0 $varName the_library
sl@0
    55
    global env errorInfo
sl@0
    56
sl@0
    57
    set dirs {}
sl@0
    58
    set errors {}
sl@0
    59
sl@0
    60
    # The C application may have hardwired a path, which we honor
sl@0
    61
sl@0
    62
    if {[info exists the_library] && $the_library ne ""} {
sl@0
    63
	lappend dirs $the_library
sl@0
    64
    } else {
sl@0
    65
sl@0
    66
	# Do the canonical search
sl@0
    67
sl@0
    68
	# 1. From an environment variable, if it exists.
sl@0
    69
	#    Placing this first gives the end-user ultimate control
sl@0
    70
	#    to work-around any bugs, or to customize.
sl@0
    71
sl@0
    72
        if {[info exists env($enVarName)]} {
sl@0
    73
            lappend dirs $env($enVarName)
sl@0
    74
        }
sl@0
    75
sl@0
    76
	# 2. In the package script directory registered within
sl@0
    77
	#    the configuration of the package itself.
sl@0
    78
	#
sl@0
    79
	# Only do this for Tcl 8.5+, when Tcl_RegsiterConfig() is available.
sl@0
    80
	#if {[catch {
sl@0
    81
	#    ::${basename}::pkgconfig get scriptdir,runtime
sl@0
    82
	#} value] == 0} {
sl@0
    83
	#    lappend dirs $value
sl@0
    84
	#}
sl@0
    85
sl@0
    86
	# 3. Relative to auto_path directories.  This checks relative to the
sl@0
    87
	# Tcl library as well as allowing loading of libraries added to the
sl@0
    88
	# auto_path that is not relative to the core library or binary paths.
sl@0
    89
	foreach d $::auto_path {
sl@0
    90
	    lappend dirs [file join $d $basename$version]
sl@0
    91
	    if {$::tcl_platform(platform) eq "unix"
sl@0
    92
		&& $::tcl_platform(os) eq "Darwin"} {
sl@0
    93
		# 4. On MacOSX, check the Resources/Scripts subdir too
sl@0
    94
		lappend dirs [file join $d $basename$version Resources Scripts]
sl@0
    95
	    }
sl@0
    96
	}
sl@0
    97
sl@0
    98
	# 3. Various locations relative to the executable
sl@0
    99
	# ../lib/foo1.0		(From bin directory in install hierarchy)
sl@0
   100
	# ../../lib/foo1.0	(From bin/arch directory in install hierarchy)
sl@0
   101
	# ../library		(From unix directory in build hierarchy)
sl@0
   102
        set parentDir [file dirname [file dirname [info nameofexecutable]]]
sl@0
   103
        set grandParentDir [file dirname $parentDir]
sl@0
   104
        lappend dirs [file join $parentDir lib $basename$version]
sl@0
   105
        lappend dirs [file join $grandParentDir lib $basename$version]
sl@0
   106
        lappend dirs [file join $parentDir library]
sl@0
   107
sl@0
   108
	# Remaining locations are out of date (when relevant, they ought
sl@0
   109
	# to be covered by the $::auto_path seach above).
sl@0
   110
	#
sl@0
   111
	# ../../library		(From unix/arch directory in build hierarchy)
sl@0
   112
	# ../../foo1.0.1/library
sl@0
   113
	#		(From unix directory in parallel build hierarchy)
sl@0
   114
	# ../../../foo1.0.1/library
sl@0
   115
	#		(From unix/arch directory in parallel build hierarchy)
sl@0
   116
	#
sl@0
   117
	# For the sake of extra compatibility safety, we keep adding these
sl@0
   118
	# paths during the 8.4.* release series.
sl@0
   119
	if {1} {
sl@0
   120
	    lappend dirs [file join $grandParentDir library]
sl@0
   121
	    lappend dirs [file join $grandParentDir $basename$patch library]
sl@0
   122
	    lappend dirs [file join [file dirname $grandParentDir] \
sl@0
   123
			      $basename$patch library]
sl@0
   124
	}
sl@0
   125
    }
sl@0
   126
    # uniquify $dirs in order
sl@0
   127
    array set seen {}
sl@0
   128
    foreach i $dirs {
sl@0
   129
	# For Tcl 8.4.9, we've disabled the use of [file normalize] here.
sl@0
   130
	# This means that two different path names that are the same path
sl@0
   131
	# in normalized form, will both remain on the search path.  There
sl@0
   132
	# should be no harm in that, just a bit more file system access
sl@0
   133
	# than is strictly necessary.
sl@0
   134
	#
sl@0
   135
	# [file normalize] has been disabled because of reports it has
sl@0
   136
	# caused difficulties with the freewrap utility.  To keep
sl@0
   137
	# compatibility with freewrap's needs, we'll keep this disabled
sl@0
   138
	# throughout the 8.4.x (x >= 9) releases.  See Bug 1072136.
sl@0
   139
	if {1 || [interp issafe]} {
sl@0
   140
	    set norm $i
sl@0
   141
	} else {
sl@0
   142
	    set norm [file normalize $i]
sl@0
   143
	}
sl@0
   144
	if {[info exists seen($norm)]} { continue }
sl@0
   145
	set seen($norm) ""
sl@0
   146
	lappend uniqdirs $i
sl@0
   147
    }
sl@0
   148
    set dirs $uniqdirs
sl@0
   149
    foreach i $dirs {
sl@0
   150
        set the_library $i
sl@0
   151
        set file [file join $i $initScript]
sl@0
   152
sl@0
   153
	# source everything when in a safe interpreter because
sl@0
   154
	# we have a source command, but no file exists command
sl@0
   155
sl@0
   156
        if {[interp issafe] || [file exists $file]} {
sl@0
   157
            if {![catch {uplevel #0 [list source $file]} msg]} {
sl@0
   158
                return
sl@0
   159
            } else {
sl@0
   160
                append errors "$file: $msg\n$errorInfo\n"
sl@0
   161
            }
sl@0
   162
        }
sl@0
   163
    }
sl@0
   164
    unset -nocomplain the_library
sl@0
   165
    set msg "Can't find a usable $initScript in the following directories: \n"
sl@0
   166
    append msg "    $dirs\n\n"
sl@0
   167
    append msg "$errors\n\n"
sl@0
   168
    append msg "This probably means that $basename wasn't installed properly.\n"
sl@0
   169
    error $msg
sl@0
   170
}
sl@0
   171
sl@0
   172
sl@0
   173
# ----------------------------------------------------------------------
sl@0
   174
# auto_mkindex
sl@0
   175
# ----------------------------------------------------------------------
sl@0
   176
# The following procedures are used to generate the tclIndex file
sl@0
   177
# from Tcl source files.  They use a special safe interpreter to
sl@0
   178
# parse Tcl source files, writing out index entries as "proc"
sl@0
   179
# commands are encountered.  This implementation won't work in a
sl@0
   180
# safe interpreter, since a safe interpreter can't create the
sl@0
   181
# special parser and mess with its commands.  
sl@0
   182
sl@0
   183
if {[interp issafe]} {
sl@0
   184
    return	;# Stop sourcing the file here
sl@0
   185
}
sl@0
   186
sl@0
   187
# auto_mkindex --
sl@0
   188
# Regenerate a tclIndex file from Tcl source files.  Takes as argument
sl@0
   189
# the name of the directory in which the tclIndex file is to be placed,
sl@0
   190
# followed by any number of glob patterns to use in that directory to
sl@0
   191
# locate all of the relevant files.
sl@0
   192
#
sl@0
   193
# Arguments: 
sl@0
   194
# dir -		Name of the directory in which to create an index.
sl@0
   195
# args -	Any number of additional arguments giving the
sl@0
   196
#		names of files within dir.  If no additional
sl@0
   197
#		are given auto_mkindex will look for *.tcl.
sl@0
   198
sl@0
   199
proc auto_mkindex {dir args} {
sl@0
   200
    global errorCode errorInfo
sl@0
   201
sl@0
   202
    if {[interp issafe]} {
sl@0
   203
        error "can't generate index within safe interpreter"
sl@0
   204
    }
sl@0
   205
sl@0
   206
    set oldDir [pwd]
sl@0
   207
    cd $dir
sl@0
   208
    set dir [pwd]
sl@0
   209
sl@0
   210
    append index "# Tcl autoload index file, version 2.0\n"
sl@0
   211
    append index "# This file is generated by the \"auto_mkindex\" command\n"
sl@0
   212
    append index "# and sourced to set up indexing information for one or\n"
sl@0
   213
    append index "# more commands.  Typically each line is a command that\n"
sl@0
   214
    append index "# sets an element in the auto_index array, where the\n"
sl@0
   215
    append index "# element name is the name of a command and the value is\n"
sl@0
   216
    append index "# a script that loads the command.\n\n"
sl@0
   217
    if {[llength $args] == 0} {
sl@0
   218
	set args *.tcl
sl@0
   219
    }
sl@0
   220
sl@0
   221
    auto_mkindex_parser::init
sl@0
   222
    foreach file [eval [linsert $args 0 glob --]] {
sl@0
   223
        if {[catch {auto_mkindex_parser::mkindex $file} msg] == 0} {
sl@0
   224
            append index $msg
sl@0
   225
        } else {
sl@0
   226
            set code $errorCode
sl@0
   227
            set info $errorInfo
sl@0
   228
            cd $oldDir
sl@0
   229
            error $msg $info $code
sl@0
   230
        }
sl@0
   231
    }
sl@0
   232
    auto_mkindex_parser::cleanup
sl@0
   233
sl@0
   234
    set fid [open "tclIndex" w]
sl@0
   235
    puts -nonewline $fid $index
sl@0
   236
    close $fid
sl@0
   237
    cd $oldDir
sl@0
   238
}
sl@0
   239
sl@0
   240
# Original version of auto_mkindex that just searches the source
sl@0
   241
# code for "proc" at the beginning of the line.
sl@0
   242
sl@0
   243
proc auto_mkindex_old {dir args} {
sl@0
   244
    global errorCode errorInfo
sl@0
   245
    set oldDir [pwd]
sl@0
   246
    cd $dir
sl@0
   247
    set dir [pwd]
sl@0
   248
    append index "# Tcl autoload index file, version 2.0\n"
sl@0
   249
    append index "# This file is generated by the \"auto_mkindex\" command\n"
sl@0
   250
    append index "# and sourced to set up indexing information for one or\n"
sl@0
   251
    append index "# more commands.  Typically each line is a command that\n"
sl@0
   252
    append index "# sets an element in the auto_index array, where the\n"
sl@0
   253
    append index "# element name is the name of a command and the value is\n"
sl@0
   254
    append index "# a script that loads the command.\n\n"
sl@0
   255
    if {[llength $args] == 0} {
sl@0
   256
	set args *.tcl
sl@0
   257
    }
sl@0
   258
    foreach file [eval [linsert $args 0 glob --]] {
sl@0
   259
	set f ""
sl@0
   260
	set error [catch {
sl@0
   261
	    set f [open $file]
sl@0
   262
	    while {[gets $f line] >= 0} {
sl@0
   263
		if {[regexp {^proc[ 	]+([^ 	]*)} $line match procName]} {
sl@0
   264
		    set procName [lindex [auto_qualify $procName "::"] 0]
sl@0
   265
		    append index "set [list auto_index($procName)]"
sl@0
   266
		    append index " \[list source \[file join \$dir [list $file]\]\]\n"
sl@0
   267
		}
sl@0
   268
	    }
sl@0
   269
	    close $f
sl@0
   270
	} msg]
sl@0
   271
	if {$error} {
sl@0
   272
	    set code $errorCode
sl@0
   273
	    set info $errorInfo
sl@0
   274
	    catch {close $f}
sl@0
   275
	    cd $oldDir
sl@0
   276
	    error $msg $info $code
sl@0
   277
	}
sl@0
   278
    }
sl@0
   279
    set f ""
sl@0
   280
    set error [catch {
sl@0
   281
	set f [open tclIndex w]
sl@0
   282
	puts -nonewline $f $index
sl@0
   283
	close $f
sl@0
   284
	cd $oldDir
sl@0
   285
    } msg]
sl@0
   286
    if {$error} {
sl@0
   287
	set code $errorCode
sl@0
   288
	set info $errorInfo
sl@0
   289
	catch {close $f}
sl@0
   290
	cd $oldDir
sl@0
   291
	error $msg $info $code
sl@0
   292
    }
sl@0
   293
}
sl@0
   294
sl@0
   295
# Create a safe interpreter that can be used to parse Tcl source files
sl@0
   296
# generate a tclIndex file for autoloading.  This interp contains
sl@0
   297
# commands for things that need index entries.  Each time a command
sl@0
   298
# is executed, it writes an entry out to the index file.
sl@0
   299
sl@0
   300
namespace eval auto_mkindex_parser {
sl@0
   301
    variable parser ""          ;# parser used to build index
sl@0
   302
    variable index ""           ;# maintains index as it is built
sl@0
   303
    variable scriptFile ""      ;# name of file being processed
sl@0
   304
    variable contextStack ""    ;# stack of namespace scopes
sl@0
   305
    variable imports ""         ;# keeps track of all imported cmds
sl@0
   306
    variable initCommands ""    ;# list of commands that create aliases
sl@0
   307
sl@0
   308
    proc init {} {
sl@0
   309
	variable parser
sl@0
   310
	variable initCommands
sl@0
   311
sl@0
   312
	if {![interp issafe]} {
sl@0
   313
	    set parser [interp create -safe]
sl@0
   314
	    $parser hide info
sl@0
   315
	    $parser hide rename
sl@0
   316
	    $parser hide proc
sl@0
   317
	    $parser hide namespace
sl@0
   318
	    $parser hide eval
sl@0
   319
	    $parser hide puts
sl@0
   320
	    $parser invokehidden namespace delete ::
sl@0
   321
	    $parser invokehidden proc unknown {args} {}
sl@0
   322
sl@0
   323
	    # We'll need access to the "namespace" command within the
sl@0
   324
	    # interp.  Put it back, but move it out of the way.
sl@0
   325
sl@0
   326
	    $parser expose namespace
sl@0
   327
	    $parser invokehidden rename namespace _%@namespace
sl@0
   328
	    $parser expose eval
sl@0
   329
	    $parser invokehidden rename eval _%@eval
sl@0
   330
sl@0
   331
	    # Install all the registered psuedo-command implementations
sl@0
   332
sl@0
   333
	    foreach cmd $initCommands {
sl@0
   334
		eval $cmd
sl@0
   335
	    }
sl@0
   336
	}
sl@0
   337
    }
sl@0
   338
    proc cleanup {} {
sl@0
   339
	variable parser
sl@0
   340
	interp delete $parser
sl@0
   341
	unset parser
sl@0
   342
    }
sl@0
   343
}
sl@0
   344
sl@0
   345
# auto_mkindex_parser::mkindex --
sl@0
   346
#
sl@0
   347
# Used by the "auto_mkindex" command to create a "tclIndex" file for
sl@0
   348
# the given Tcl source file.  Executes the commands in the file, and
sl@0
   349
# handles things like the "proc" command by adding an entry for the
sl@0
   350
# index file.  Returns a string that represents the index file.
sl@0
   351
#
sl@0
   352
# Arguments: 
sl@0
   353
#	file	Name of Tcl source file to be indexed.
sl@0
   354
sl@0
   355
proc auto_mkindex_parser::mkindex {file} {
sl@0
   356
    variable parser
sl@0
   357
    variable index
sl@0
   358
    variable scriptFile
sl@0
   359
    variable contextStack
sl@0
   360
    variable imports
sl@0
   361
sl@0
   362
    set scriptFile $file
sl@0
   363
sl@0
   364
    set fid [open $file]
sl@0
   365
    set contents [read $fid]
sl@0
   366
    close $fid
sl@0
   367
sl@0
   368
    # There is one problem with sourcing files into the safe
sl@0
   369
    # interpreter:  references like "$x" will fail since code is not
sl@0
   370
    # really being executed and variables do not really exist.
sl@0
   371
    # To avoid this, we replace all $ with \0 (literally, the null char)
sl@0
   372
    # later, when getting proc names we will have to reverse this replacement,
sl@0
   373
    # in case there were any $ in the proc name.  This will cause a problem
sl@0
   374
    # if somebody actually tries to have a \0 in their proc name.  Too bad
sl@0
   375
    # for them.
sl@0
   376
    set contents [string map "$ \u0000" $contents]
sl@0
   377
    
sl@0
   378
    set index ""
sl@0
   379
    set contextStack ""
sl@0
   380
    set imports ""
sl@0
   381
sl@0
   382
    $parser eval $contents
sl@0
   383
sl@0
   384
    foreach name $imports {
sl@0
   385
        catch {$parser eval [list _%@namespace forget $name]}
sl@0
   386
    }
sl@0
   387
    return $index
sl@0
   388
}
sl@0
   389
sl@0
   390
# auto_mkindex_parser::hook command
sl@0
   391
#
sl@0
   392
# Registers a Tcl command to evaluate when initializing the
sl@0
   393
# slave interpreter used by the mkindex parser.
sl@0
   394
# The command is evaluated in the master interpreter, and can
sl@0
   395
# use the variable auto_mkindex_parser::parser to get to the slave
sl@0
   396
sl@0
   397
proc auto_mkindex_parser::hook {cmd} {
sl@0
   398
    variable initCommands
sl@0
   399
sl@0
   400
    lappend initCommands $cmd
sl@0
   401
}
sl@0
   402
sl@0
   403
# auto_mkindex_parser::slavehook command
sl@0
   404
#
sl@0
   405
# Registers a Tcl command to evaluate when initializing the
sl@0
   406
# slave interpreter used by the mkindex parser.
sl@0
   407
# The command is evaluated in the slave interpreter.
sl@0
   408
sl@0
   409
proc auto_mkindex_parser::slavehook {cmd} {
sl@0
   410
    variable initCommands
sl@0
   411
sl@0
   412
    # The $parser variable is defined to be the name of the
sl@0
   413
    # slave interpreter when this command is used later.
sl@0
   414
sl@0
   415
    lappend initCommands "\$parser eval [list $cmd]"
sl@0
   416
}
sl@0
   417
sl@0
   418
# auto_mkindex_parser::command --
sl@0
   419
#
sl@0
   420
# Registers a new command with the "auto_mkindex_parser" interpreter
sl@0
   421
# that parses Tcl files.  These commands are fake versions of things
sl@0
   422
# like the "proc" command.  When you execute them, they simply write
sl@0
   423
# out an entry to a "tclIndex" file for auto-loading.
sl@0
   424
#
sl@0
   425
# This procedure allows extensions to register their own commands
sl@0
   426
# with the auto_mkindex facility.  For example, a package like
sl@0
   427
# [incr Tcl] might register a "class" command so that class definitions
sl@0
   428
# could be added to a "tclIndex" file for auto-loading.
sl@0
   429
#
sl@0
   430
# Arguments:
sl@0
   431
#	name 	Name of command recognized in Tcl files.
sl@0
   432
#	arglist	Argument list for command.
sl@0
   433
#	body 	Implementation of command to handle indexing.
sl@0
   434
sl@0
   435
proc auto_mkindex_parser::command {name arglist body} {
sl@0
   436
    hook [list auto_mkindex_parser::commandInit $name $arglist $body]
sl@0
   437
}
sl@0
   438
sl@0
   439
# auto_mkindex_parser::commandInit --
sl@0
   440
#
sl@0
   441
# This does the actual work set up by auto_mkindex_parser::command
sl@0
   442
# This is called when the interpreter used by the parser is created.
sl@0
   443
#
sl@0
   444
# Arguments:
sl@0
   445
#	name 	Name of command recognized in Tcl files.
sl@0
   446
#	arglist	Argument list for command.
sl@0
   447
#	body 	Implementation of command to handle indexing.
sl@0
   448
sl@0
   449
proc auto_mkindex_parser::commandInit {name arglist body} {
sl@0
   450
    variable parser
sl@0
   451
sl@0
   452
    set ns [namespace qualifiers $name]
sl@0
   453
    set tail [namespace tail $name]
sl@0
   454
    if {$ns eq ""} {
sl@0
   455
        set fakeName [namespace current]::_%@fake_$tail
sl@0
   456
    } else {
sl@0
   457
        set fakeName [namespace current]::[string map {:: _} _%@fake_$name]
sl@0
   458
    }
sl@0
   459
    proc $fakeName $arglist $body
sl@0
   460
sl@0
   461
    # YUK!  Tcl won't let us alias fully qualified command names,
sl@0
   462
    # so we can't handle names like "::itcl::class".  Instead,
sl@0
   463
    # we have to build procs with the fully qualified names, and
sl@0
   464
    # have the procs point to the aliases.
sl@0
   465
sl@0
   466
    if {[string match *::* $name]} {
sl@0
   467
        set exportCmd [list _%@namespace export [namespace tail $name]]
sl@0
   468
        $parser eval [list _%@namespace eval $ns $exportCmd]
sl@0
   469
 
sl@0
   470
	# The following proc definition does not work if you
sl@0
   471
	# want to tolerate space or something else diabolical
sl@0
   472
	# in the procedure name, (i.e., space in $alias)
sl@0
   473
	# The following does not work:
sl@0
   474
	#   "_%@eval {$alias} \$args"
sl@0
   475
	# because $alias gets concat'ed to $args.
sl@0
   476
	# The following does not work because $cmd is somehow undefined
sl@0
   477
	#   "set cmd {$alias} \; _%@eval {\$cmd} \$args"
sl@0
   478
	# A gold star to someone that can make test
sl@0
   479
	# autoMkindex-3.3 work properly
sl@0
   480
sl@0
   481
        set alias [namespace tail $fakeName]
sl@0
   482
        $parser invokehidden proc $name {args} "_%@eval {$alias} \$args"
sl@0
   483
        $parser alias $alias $fakeName
sl@0
   484
    } else {
sl@0
   485
        $parser alias $name $fakeName
sl@0
   486
    }
sl@0
   487
    return
sl@0
   488
}
sl@0
   489
sl@0
   490
# auto_mkindex_parser::fullname --
sl@0
   491
# Used by commands like "proc" within the auto_mkindex parser.
sl@0
   492
# Returns the qualified namespace name for the "name" argument.
sl@0
   493
# If the "name" does not start with "::", elements are added from
sl@0
   494
# the current namespace stack to produce a qualified name.  Then,
sl@0
   495
# the name is examined to see whether or not it should really be
sl@0
   496
# qualified.  If the name has more than the leading "::", it is
sl@0
   497
# returned as a fully qualified name.  Otherwise, it is returned
sl@0
   498
# as a simple name.  That way, the Tcl autoloader will recognize
sl@0
   499
# it properly.
sl@0
   500
#
sl@0
   501
# Arguments:
sl@0
   502
# name -		Name that is being added to index.
sl@0
   503
sl@0
   504
proc auto_mkindex_parser::fullname {name} {
sl@0
   505
    variable contextStack
sl@0
   506
sl@0
   507
    if {![string match ::* $name]} {
sl@0
   508
        foreach ns $contextStack {
sl@0
   509
            set name "${ns}::$name"
sl@0
   510
            if {[string match ::* $name]} {
sl@0
   511
                break
sl@0
   512
            }
sl@0
   513
        }
sl@0
   514
    }
sl@0
   515
sl@0
   516
    if {[namespace qualifiers $name] eq ""} {
sl@0
   517
        set name [namespace tail $name]
sl@0
   518
    } elseif {![string match ::* $name]} {
sl@0
   519
        set name "::$name"
sl@0
   520
    }
sl@0
   521
    
sl@0
   522
    # Earlier, mkindex replaced all $'s with \0.  Now, we have to reverse
sl@0
   523
    # that replacement.
sl@0
   524
    return [string map "\u0000 $" $name]
sl@0
   525
}
sl@0
   526
sl@0
   527
# Register all of the procedures for the auto_mkindex parser that
sl@0
   528
# will build the "tclIndex" file.
sl@0
   529
sl@0
   530
# AUTO MKINDEX:  proc name arglist body
sl@0
   531
# Adds an entry to the auto index list for the given procedure name.
sl@0
   532
sl@0
   533
auto_mkindex_parser::command proc {name args} {
sl@0
   534
    variable index
sl@0
   535
    variable scriptFile
sl@0
   536
    # Do some fancy reformatting on the "source" call to handle platform
sl@0
   537
    # differences with respect to pathnames.  Use format just so that the
sl@0
   538
    # command is a little easier to read (otherwise it'd be full of 
sl@0
   539
    # backslashed dollar signs, etc.
sl@0
   540
    append index [list set auto_index([fullname $name])] \
sl@0
   541
	    [format { [list source [file join $dir %s]]} \
sl@0
   542
	    [file split $scriptFile]] "\n"
sl@0
   543
}
sl@0
   544
sl@0
   545
# Conditionally add support for Tcl byte code files.  There are some
sl@0
   546
# tricky details here.  First, we need to get the tbcload library
sl@0
   547
# initialized in the current interpreter.  We cannot load tbcload into the
sl@0
   548
# slave until we have done so because it needs access to the tcl_patchLevel
sl@0
   549
# variable.  Second, because the package index file may defer loading the
sl@0
   550
# library until we invoke a command, we need to explicitly invoke auto_load
sl@0
   551
# to force it to be loaded.  This should be a noop if the package has
sl@0
   552
# already been loaded
sl@0
   553
sl@0
   554
auto_mkindex_parser::hook {
sl@0
   555
    if {![catch {package require tbcload}]} {
sl@0
   556
	if {[namespace which -command tbcload::bcproc] eq ""} {
sl@0
   557
	    auto_load tbcload::bcproc
sl@0
   558
	}
sl@0
   559
	load {} tbcload $auto_mkindex_parser::parser
sl@0
   560
sl@0
   561
	# AUTO MKINDEX:  tbcload::bcproc name arglist body
sl@0
   562
	# Adds an entry to the auto index list for the given pre-compiled
sl@0
   563
	# procedure name.  
sl@0
   564
sl@0
   565
	auto_mkindex_parser::commandInit tbcload::bcproc {name args} {
sl@0
   566
	    variable index
sl@0
   567
	    variable scriptFile
sl@0
   568
	    # Do some nice reformatting of the "source" call, to get around
sl@0
   569
	    # path differences on different platforms.  We use the format
sl@0
   570
	    # command just so that the code is a little easier to read.
sl@0
   571
	    append index [list set auto_index([fullname $name])] \
sl@0
   572
		    [format { [list source [file join $dir %s]]} \
sl@0
   573
		    [file split $scriptFile]] "\n"
sl@0
   574
	}
sl@0
   575
    }
sl@0
   576
}
sl@0
   577
sl@0
   578
# AUTO MKINDEX:  namespace eval name command ?arg arg...?
sl@0
   579
# Adds the namespace name onto the context stack and evaluates the
sl@0
   580
# associated body of commands.
sl@0
   581
#
sl@0
   582
# AUTO MKINDEX:  namespace import ?-force? pattern ?pattern...?
sl@0
   583
# Performs the "import" action in the parser interpreter.  This is
sl@0
   584
# important for any commands contained in a namespace that affect
sl@0
   585
# the index.  For example, a script may say "itcl::class ...",
sl@0
   586
# or it may import "itcl::*" and then say "class ...".  This
sl@0
   587
# procedure does the import operation, but keeps track of imported
sl@0
   588
# patterns so we can remove the imports later.
sl@0
   589
sl@0
   590
auto_mkindex_parser::command namespace {op args} {
sl@0
   591
    switch -- $op {
sl@0
   592
        eval {
sl@0
   593
            variable parser
sl@0
   594
            variable contextStack
sl@0
   595
sl@0
   596
            set name [lindex $args 0]
sl@0
   597
            set args [lrange $args 1 end]
sl@0
   598
sl@0
   599
            set contextStack [linsert $contextStack 0 $name]
sl@0
   600
	    $parser eval [list _%@namespace eval $name] $args
sl@0
   601
            set contextStack [lrange $contextStack 1 end]
sl@0
   602
        }
sl@0
   603
        import {
sl@0
   604
            variable parser
sl@0
   605
            variable imports
sl@0
   606
            foreach pattern $args {
sl@0
   607
                if {$pattern ne "-force"} {
sl@0
   608
                    lappend imports $pattern
sl@0
   609
                }
sl@0
   610
            }
sl@0
   611
            catch {$parser eval "_%@namespace import $args"}
sl@0
   612
        }
sl@0
   613
    }
sl@0
   614
}
sl@0
   615
sl@0
   616
return