os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclBasic.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /* 
     2  * tclBasic.c --
     3  *
     4  *	Contains the basic facilities for TCL command interpretation,
     5  *	including interpreter creation and deletion, command creation
     6  *	and deletion, and command/script execution. 
     7  *
     8  * Copyright (c) 1987-1994 The Regents of the University of California.
     9  * Copyright (c) 1994-1997 Sun Microsystems, Inc.
    10  * Copyright (c) 1998-1999 by Scriptics Corporation.
    11  * Copyright (c) 2001, 2002 by Kevin B. Kenny.  All rights reserved.
    12  * Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved.  
    13  *
    14  * See the file "license.terms" for information on usage and redistribution
    15  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    16  *
    17  * RCS: @(#) $Id: tclBasic.c,v 1.75.2.26 2006/11/28 22:19:59 andreas_kupries Exp $
    18  */
    19 
    20 #include "tclInt.h"
    21 #include "tclCompile.h"
    22 #ifndef TCL_GENERIC_ONLY
    23 #   include "tclPort.h"
    24 #endif
    25 
    26 /*
    27  * Static procedures in this file:
    28  */
    29 
    30 static char *		CallCommandTraces _ANSI_ARGS_((Interp *iPtr, 
    31 			    Command *cmdPtr, CONST char *oldName, 
    32 			    CONST char* newName, int flags));
    33 static void		DeleteInterpProc _ANSI_ARGS_((Tcl_Interp *interp));
    34 static void		ProcessUnexpectedResult _ANSI_ARGS_((
    35 			    Tcl_Interp *interp, int returnCode));
    36 static int	        StringTraceProc _ANSI_ARGS_((ClientData clientData,
    37 						     Tcl_Interp* interp,
    38 						     int level,
    39 						     CONST char* command,
    40 						    Tcl_Command commandInfo,
    41 						    int objc,
    42 						    Tcl_Obj *CONST objv[]));
    43 static void           StringTraceDeleteProc _ANSI_ARGS_((ClientData clientData));
    44 
    45 #ifdef TCL_TIP280
    46 /* TIP #280 - Modified token based evulation, with line information */
    47 static int            EvalEx _ANSI_ARGS_((Tcl_Interp *interp, CONST char *script,
    48 					  int numBytes, int flags, int line));
    49 
    50 static int            EvalTokensStandard _ANSI_ARGS_((Tcl_Interp *interp,
    51 						      Tcl_Token *tokenPtr,
    52 						      int count, int line));
    53 
    54 #endif
    55 
    56 extern TclStubs tclStubs;
    57 
    58 /*
    59  * The following structure defines the commands in the Tcl core.
    60  */
    61 
    62 typedef struct {
    63     char *name;			/* Name of object-based command. */
    64     Tcl_CmdProc *proc;		/* String-based procedure for command. */
    65     Tcl_ObjCmdProc *objProc;	/* Object-based procedure for command. */
    66     CompileProc *compileProc;	/* Procedure called to compile command. */
    67     int isSafe;			/* If non-zero, command will be present
    68                                  * in safe interpreter. Otherwise it will
    69                                  * be hidden. */
    70 } CmdInfo;
    71 
    72 /*
    73  * The built-in commands, and the procedures that implement them:
    74  */
    75 
    76 static CmdInfo builtInCmds[] = {
    77     /*
    78      * Commands in the generic core. Note that at least one of the proc or
    79      * objProc members should be non-NULL. This avoids infinitely recursive
    80      * calls between TclInvokeObjectCommand and TclInvokeStringCommand if a
    81      * command name is computed at runtime and results in the name of a
    82      * compiled command.
    83      */
    84 
    85     {"append",		(Tcl_CmdProc *) NULL,	Tcl_AppendObjCmd,
    86 	TclCompileAppendCmd,		1},
    87     {"array",		(Tcl_CmdProc *) NULL,	Tcl_ArrayObjCmd,
    88         (CompileProc *) NULL,		1},
    89     {"binary",		(Tcl_CmdProc *) NULL,	Tcl_BinaryObjCmd,
    90         (CompileProc *) NULL,		1},
    91     {"break",		(Tcl_CmdProc *) NULL,	Tcl_BreakObjCmd,
    92         TclCompileBreakCmd,		1},
    93     {"case",		(Tcl_CmdProc *) NULL,	Tcl_CaseObjCmd,
    94         (CompileProc *) NULL,		1},
    95     {"catch",		(Tcl_CmdProc *) NULL,	Tcl_CatchObjCmd,	
    96         TclCompileCatchCmd,		1},
    97     {"clock",		(Tcl_CmdProc *) NULL,	Tcl_ClockObjCmd,
    98         (CompileProc *) NULL,		1},
    99     {"concat",		(Tcl_CmdProc *) NULL,	Tcl_ConcatObjCmd,
   100         (CompileProc *) NULL,		1},
   101     {"continue",	(Tcl_CmdProc *) NULL,	Tcl_ContinueObjCmd,
   102         TclCompileContinueCmd,		1},
   103     {"encoding",	(Tcl_CmdProc *) NULL,	Tcl_EncodingObjCmd,
   104         (CompileProc *) NULL,		0},
   105     {"error",		(Tcl_CmdProc *) NULL,	Tcl_ErrorObjCmd,
   106         (CompileProc *) NULL,		1},
   107     {"eval",		(Tcl_CmdProc *) NULL,	Tcl_EvalObjCmd,
   108         (CompileProc *) NULL,		1},
   109     {"exit",		(Tcl_CmdProc *) NULL,	Tcl_ExitObjCmd,
   110         (CompileProc *) NULL,		0},
   111     {"expr",		(Tcl_CmdProc *) NULL,	Tcl_ExprObjCmd,
   112         TclCompileExprCmd,		1},
   113     {"fcopy",		(Tcl_CmdProc *) NULL,	Tcl_FcopyObjCmd,
   114         (CompileProc *) NULL,		1},
   115     {"fileevent",	(Tcl_CmdProc *) NULL,	Tcl_FileEventObjCmd,
   116         (CompileProc *) NULL,		1},
   117     {"for",		(Tcl_CmdProc *) NULL,	Tcl_ForObjCmd,
   118         TclCompileForCmd,		1},
   119     {"foreach",		(Tcl_CmdProc *) NULL,	Tcl_ForeachObjCmd,
   120         TclCompileForeachCmd,		1},
   121     {"format",		(Tcl_CmdProc *) NULL,	Tcl_FormatObjCmd,
   122         (CompileProc *) NULL,		1},
   123     {"global",		(Tcl_CmdProc *) NULL,	Tcl_GlobalObjCmd,
   124         (CompileProc *) NULL,		1},
   125     {"if",		(Tcl_CmdProc *) NULL,	Tcl_IfObjCmd,
   126         TclCompileIfCmd,		1},
   127     {"incr",		(Tcl_CmdProc *) NULL,	Tcl_IncrObjCmd,
   128         TclCompileIncrCmd,		1},
   129     {"info",		(Tcl_CmdProc *) NULL,	Tcl_InfoObjCmd,
   130         (CompileProc *) NULL,		1},
   131     {"join",		(Tcl_CmdProc *) NULL,	Tcl_JoinObjCmd,
   132         (CompileProc *) NULL,		1},
   133     {"lappend",		(Tcl_CmdProc *) NULL,	Tcl_LappendObjCmd,
   134         TclCompileLappendCmd,		1},
   135     {"lindex",		(Tcl_CmdProc *) NULL,	Tcl_LindexObjCmd,
   136         TclCompileLindexCmd,		1},
   137     {"linsert",		(Tcl_CmdProc *) NULL,	Tcl_LinsertObjCmd,
   138         (CompileProc *) NULL,		1},
   139     {"list",		(Tcl_CmdProc *) NULL,	Tcl_ListObjCmd,
   140         TclCompileListCmd,		1},
   141     {"llength",		(Tcl_CmdProc *) NULL,	Tcl_LlengthObjCmd,
   142         TclCompileLlengthCmd,		1},
   143     {"load",		(Tcl_CmdProc *) NULL,	Tcl_LoadObjCmd,
   144         (CompileProc *) NULL,		0},
   145     {"lrange",		(Tcl_CmdProc *) NULL,	Tcl_LrangeObjCmd,
   146         (CompileProc *) NULL,		1},
   147     {"lreplace",	(Tcl_CmdProc *) NULL,	Tcl_LreplaceObjCmd,
   148         (CompileProc *) NULL,		1},
   149     {"lsearch",		(Tcl_CmdProc *) NULL,	Tcl_LsearchObjCmd,
   150         (CompileProc *) NULL,		1},
   151     {"lset",            (Tcl_CmdProc *) NULL,   Tcl_LsetObjCmd,
   152         TclCompileLsetCmd,           	1},
   153     {"lsort",		(Tcl_CmdProc *) NULL,	Tcl_LsortObjCmd,
   154         (CompileProc *) NULL,		1},
   155     {"namespace",	(Tcl_CmdProc *) NULL,	Tcl_NamespaceObjCmd,
   156         (CompileProc *) NULL,		1},
   157     {"package",		(Tcl_CmdProc *) NULL,	Tcl_PackageObjCmd,
   158         (CompileProc *) NULL,		1},
   159     {"proc",		(Tcl_CmdProc *) NULL,	Tcl_ProcObjCmd,	
   160         (CompileProc *) NULL,		1},
   161     {"regexp",		(Tcl_CmdProc *) NULL,	Tcl_RegexpObjCmd,
   162         TclCompileRegexpCmd,		1},
   163     {"regsub",		(Tcl_CmdProc *) NULL,	Tcl_RegsubObjCmd,
   164         (CompileProc *) NULL,		1},
   165     {"rename",		(Tcl_CmdProc *) NULL,	Tcl_RenameObjCmd,
   166         (CompileProc *) NULL,		1},
   167     {"return",		(Tcl_CmdProc *) NULL,	Tcl_ReturnObjCmd,	
   168         TclCompileReturnCmd,		1},
   169     {"scan",		(Tcl_CmdProc *) NULL,	Tcl_ScanObjCmd,
   170         (CompileProc *) NULL,		1},
   171     {"set",		(Tcl_CmdProc *) NULL,	Tcl_SetObjCmd,
   172         TclCompileSetCmd,		1},
   173     {"split",		(Tcl_CmdProc *) NULL,	Tcl_SplitObjCmd,
   174         (CompileProc *) NULL,		1},
   175     {"string",		(Tcl_CmdProc *) NULL,	Tcl_StringObjCmd,
   176         TclCompileStringCmd,		1},
   177     {"subst",		(Tcl_CmdProc *) NULL,	Tcl_SubstObjCmd,
   178         (CompileProc *) NULL,		1},
   179     {"switch",		(Tcl_CmdProc *) NULL,	Tcl_SwitchObjCmd,	
   180         (CompileProc *) NULL,		1},
   181     {"trace",		(Tcl_CmdProc *) NULL,	Tcl_TraceObjCmd,
   182         (CompileProc *) NULL,		1},
   183     {"unset",		(Tcl_CmdProc *) NULL,	Tcl_UnsetObjCmd,	
   184         (CompileProc *) NULL,		1},
   185     {"uplevel",		(Tcl_CmdProc *) NULL,	Tcl_UplevelObjCmd,	
   186         (CompileProc *) NULL,		1},
   187     {"upvar",		(Tcl_CmdProc *) NULL,	Tcl_UpvarObjCmd,	
   188         (CompileProc *) NULL,		1},
   189     {"variable",	(Tcl_CmdProc *) NULL,	Tcl_VariableObjCmd,
   190         (CompileProc *) NULL,		1},
   191     {"while",		(Tcl_CmdProc *) NULL,	Tcl_WhileObjCmd,
   192         TclCompileWhileCmd,		1},
   193 
   194     /*
   195      * Commands in the UNIX core:
   196      */
   197 
   198 #ifndef TCL_GENERIC_ONLY
   199     {"after",		(Tcl_CmdProc *) NULL,	Tcl_AfterObjCmd,
   200         (CompileProc *) NULL,		1},
   201     {"cd",		(Tcl_CmdProc *) NULL,	Tcl_CdObjCmd,
   202         (CompileProc *) NULL,		0},
   203     {"close",		(Tcl_CmdProc *) NULL,	Tcl_CloseObjCmd,
   204         (CompileProc *) NULL,		1},
   205     {"eof",		(Tcl_CmdProc *) NULL,	Tcl_EofObjCmd,
   206         (CompileProc *) NULL,		1},
   207     {"fblocked",	(Tcl_CmdProc *) NULL,	Tcl_FblockedObjCmd,
   208         (CompileProc *) NULL,		1},
   209     {"fconfigure",	(Tcl_CmdProc *) NULL,	Tcl_FconfigureObjCmd,
   210         (CompileProc *) NULL,		0},
   211     {"file",		(Tcl_CmdProc *) NULL,	Tcl_FileObjCmd,
   212         (CompileProc *) NULL,		0},
   213     {"flush",		(Tcl_CmdProc *) NULL,	Tcl_FlushObjCmd,
   214         (CompileProc *) NULL,		1},
   215     {"gets",		(Tcl_CmdProc *) NULL,	Tcl_GetsObjCmd,
   216         (CompileProc *) NULL,		1},
   217     {"glob",		(Tcl_CmdProc *) NULL,	Tcl_GlobObjCmd,
   218         (CompileProc *) NULL,		0},
   219     {"open",		(Tcl_CmdProc *) NULL,	Tcl_OpenObjCmd,
   220         (CompileProc *) NULL,		0},
   221     {"pid",		(Tcl_CmdProc *) NULL,	Tcl_PidObjCmd,
   222         (CompileProc *) NULL,		1},
   223     {"puts",		(Tcl_CmdProc *) NULL,	Tcl_PutsObjCmd,
   224         (CompileProc *) NULL,		1},
   225     {"pwd",		(Tcl_CmdProc *) NULL,	Tcl_PwdObjCmd,
   226         (CompileProc *) NULL,		0},
   227     {"read",		(Tcl_CmdProc *) NULL,	Tcl_ReadObjCmd,
   228         (CompileProc *) NULL,		1},
   229     {"seek",		(Tcl_CmdProc *) NULL,	Tcl_SeekObjCmd,
   230         (CompileProc *) NULL,		1},
   231     {"socket",		(Tcl_CmdProc *) NULL,	Tcl_SocketObjCmd,
   232         (CompileProc *) NULL,		0},
   233     {"tell",		(Tcl_CmdProc *) NULL,	Tcl_TellObjCmd,
   234         (CompileProc *) NULL,		1},
   235     {"time",		(Tcl_CmdProc *) NULL,	Tcl_TimeObjCmd,
   236         (CompileProc *) NULL,		1},
   237     {"update",		(Tcl_CmdProc *) NULL,	Tcl_UpdateObjCmd,
   238         (CompileProc *) NULL,		1},
   239     {"vwait",		(Tcl_CmdProc *) NULL,	Tcl_VwaitObjCmd,
   240         (CompileProc *) NULL,		1},
   241     
   242 #ifdef MAC_TCL
   243     {"beep",		(Tcl_CmdProc *) NULL,	Tcl_BeepObjCmd,
   244         (CompileProc *) NULL,		0},
   245     {"echo",		Tcl_EchoCmd,		(Tcl_ObjCmdProc *) NULL,
   246         (CompileProc *) NULL,		0},
   247     {"ls",		(Tcl_CmdProc *) NULL, 	Tcl_LsObjCmd,
   248         (CompileProc *) NULL,		0},
   249     {"resource",	(Tcl_CmdProc *) NULL,	Tcl_ResourceObjCmd,
   250         (CompileProc *) NULL,		1},
   251     {"source",		(Tcl_CmdProc *) NULL,	Tcl_MacSourceObjCmd,
   252         (CompileProc *) NULL,		0},
   253 #else
   254     {"exec",		(Tcl_CmdProc *) NULL,	Tcl_ExecObjCmd,
   255         (CompileProc *) NULL,		0},
   256     {"source",		(Tcl_CmdProc *) NULL,	Tcl_SourceObjCmd,
   257         (CompileProc *) NULL,		0},
   258 #endif /* MAC_TCL */
   259     
   260 #endif /* TCL_GENERIC_ONLY */
   261     {NULL,		(Tcl_CmdProc *) NULL,	(Tcl_ObjCmdProc *) NULL,
   262         (CompileProc *) NULL,		0}
   263 };
   264 
   265 /*
   266  * The following structure holds the client data for string-based
   267  * trace procs
   268  */
   269 
   270 typedef struct StringTraceData {
   271     ClientData clientData;	/* Client data from Tcl_CreateTrace */
   272     Tcl_CmdTraceProc* proc;	/* Trace procedure from Tcl_CreateTrace */
   273 } StringTraceData;
   274 
   275 /*
   276  *----------------------------------------------------------------------
   277  *
   278  * Tcl_CreateInterp --
   279  *
   280  *	Create a new TCL command interpreter.
   281  *
   282  * Results:
   283  *	The return value is a token for the interpreter, which may be
   284  *	used in calls to procedures like Tcl_CreateCmd, Tcl_Eval, or
   285  *	Tcl_DeleteInterp.
   286  *
   287  * Side effects:
   288  *	The command interpreter is initialized with the built-in commands
   289  *      and with the variables documented in tclvars(n).
   290  *
   291  *----------------------------------------------------------------------
   292  */
   293 
   294 EXPORT_C Tcl_Interp *
   295 Tcl_CreateInterp()
   296 {
   297     Interp *iPtr;
   298     Tcl_Interp *interp;
   299     Command *cmdPtr;
   300     BuiltinFunc *builtinFuncPtr;
   301     MathFunc *mathFuncPtr;
   302     Tcl_HashEntry *hPtr;
   303     CmdInfo *cmdInfoPtr;
   304     int i;
   305     union {
   306 	char c[sizeof(short)];
   307 	short s;
   308     } order;
   309 #ifdef TCL_COMPILE_STATS
   310     ByteCodeStats *statsPtr;
   311 #endif /* TCL_COMPILE_STATS */
   312 
   313     TclInitSubsystems(NULL);
   314 
   315     /*
   316      * Panic if someone updated the CallFrame structure without
   317      * also updating the Tcl_CallFrame structure (or vice versa).
   318      */  
   319 
   320     if (sizeof(Tcl_CallFrame) != sizeof(CallFrame)) {
   321 	/*NOTREACHED*/
   322         panic("Tcl_CallFrame and CallFrame are not the same size");
   323     }
   324 
   325     /*
   326      * Initialize support for namespaces and create the global namespace
   327      * (whose name is ""; an alias is "::"). This also initializes the
   328      * Tcl object type table and other object management code.
   329      */
   330 
   331     iPtr = (Interp *) ckalloc(sizeof(Interp));
   332     interp = (Tcl_Interp *) iPtr;
   333 
   334     iPtr->result		= iPtr->resultSpace;
   335     iPtr->freeProc		= NULL;
   336     iPtr->errorLine		= 0;
   337     iPtr->objResultPtr		= Tcl_NewObj();
   338     Tcl_IncrRefCount(iPtr->objResultPtr);
   339     iPtr->handle		= TclHandleCreate(iPtr);
   340     iPtr->globalNsPtr		= NULL;
   341     iPtr->hiddenCmdTablePtr	= NULL;
   342     iPtr->interpInfo		= NULL;
   343     Tcl_InitHashTable(&iPtr->mathFuncTable, TCL_STRING_KEYS);
   344 
   345     iPtr->numLevels = 0;
   346     iPtr->maxNestingDepth = MAX_NESTING_DEPTH;
   347     iPtr->framePtr = NULL;
   348     iPtr->varFramePtr = NULL;
   349 
   350 #ifdef TCL_TIP280
   351     /*
   352      * TIP #280 - Initialize the arrays used to extend the ByteCode and
   353      * Proc structures.
   354      */
   355     iPtr->cmdFramePtr  = NULL;
   356     iPtr->linePBodyPtr = (Tcl_HashTable*) ckalloc (sizeof (Tcl_HashTable));
   357     iPtr->lineBCPtr    = (Tcl_HashTable*) ckalloc (sizeof (Tcl_HashTable));
   358     Tcl_InitHashTable(iPtr->linePBodyPtr, TCL_ONE_WORD_KEYS);
   359     Tcl_InitHashTable(iPtr->lineBCPtr,    TCL_ONE_WORD_KEYS);
   360 #endif
   361 
   362     iPtr->activeVarTracePtr = NULL;
   363     iPtr->returnCode = TCL_OK;
   364     iPtr->errorInfo = NULL;
   365     iPtr->errorCode = NULL;
   366 
   367     iPtr->appendResult = NULL;
   368     iPtr->appendAvl = 0;
   369     iPtr->appendUsed = 0;
   370 
   371     Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS);
   372     iPtr->packageUnknown = NULL;
   373 #ifdef TCL_TIP268
   374     /* TIP #268 */
   375     iPtr->packagePrefer = (getenv ("TCL_PKG_PREFER_LATEST") == NULL ? 
   376 			   PKG_PREFER_STABLE   :
   377 			   PKG_PREFER_LATEST);
   378 #endif
   379     iPtr->cmdCount = 0;
   380     iPtr->termOffset = 0;
   381     TclInitLiteralTable(&(iPtr->literalTable));
   382     iPtr->compileEpoch = 0;
   383     iPtr->compiledProcPtr = NULL;
   384     iPtr->resolverPtr = NULL;
   385     iPtr->evalFlags = 0;
   386     iPtr->scriptFile = NULL;
   387     iPtr->flags = 0;
   388     iPtr->tracePtr = NULL;
   389     iPtr->tracesForbiddingInline = 0;
   390     iPtr->activeCmdTracePtr = NULL;
   391     iPtr->activeInterpTracePtr = NULL;
   392     iPtr->assocData = (Tcl_HashTable *) NULL;
   393     iPtr->execEnvPtr = NULL;	      /* set after namespaces initialized */
   394     iPtr->emptyObjPtr = Tcl_NewObj(); /* another empty object */
   395     Tcl_IncrRefCount(iPtr->emptyObjPtr);
   396     iPtr->resultSpace[0] = 0;
   397     iPtr->threadId = Tcl_GetCurrentThread();
   398 
   399     iPtr->globalNsPtr = NULL;	/* force creation of global ns below */
   400     iPtr->globalNsPtr = (Namespace *) Tcl_CreateNamespace(interp, "",
   401 	    (ClientData) NULL, (Tcl_NamespaceDeleteProc *) NULL);
   402     if (iPtr->globalNsPtr == NULL) {
   403         panic("Tcl_CreateInterp: can't create global namespace");
   404     }
   405 
   406     /*
   407      * Initialize support for code compilation and execution. We call
   408      * TclCreateExecEnv after initializing namespaces since it tries to
   409      * reference a Tcl variable (it links to the Tcl "tcl_traceExec"
   410      * variable).
   411      */
   412 
   413     iPtr->execEnvPtr = TclCreateExecEnv(interp);
   414 
   415     /*
   416      * Initialize the compilation and execution statistics kept for this
   417      * interpreter.
   418      */
   419 
   420 #ifdef TCL_COMPILE_STATS
   421     statsPtr = &(iPtr->stats);
   422     statsPtr->numExecutions = 0;
   423     statsPtr->numCompilations = 0;
   424     statsPtr->numByteCodesFreed = 0;
   425     (VOID *) memset(statsPtr->instructionCount, 0,
   426 	    sizeof(statsPtr->instructionCount));
   427 
   428     statsPtr->totalSrcBytes = 0.0;
   429     statsPtr->totalByteCodeBytes = 0.0;
   430     statsPtr->currentSrcBytes = 0.0;
   431     statsPtr->currentByteCodeBytes = 0.0;
   432     (VOID *) memset(statsPtr->srcCount, 0, sizeof(statsPtr->srcCount));
   433     (VOID *) memset(statsPtr->byteCodeCount, 0,
   434 	    sizeof(statsPtr->byteCodeCount));
   435     (VOID *) memset(statsPtr->lifetimeCount, 0,
   436 	    sizeof(statsPtr->lifetimeCount));
   437     
   438     statsPtr->currentInstBytes   = 0.0;
   439     statsPtr->currentLitBytes    = 0.0;
   440     statsPtr->currentExceptBytes = 0.0;
   441     statsPtr->currentAuxBytes    = 0.0;
   442     statsPtr->currentCmdMapBytes = 0.0;
   443     
   444     statsPtr->numLiteralsCreated    = 0;
   445     statsPtr->totalLitStringBytes   = 0.0;
   446     statsPtr->currentLitStringBytes = 0.0;
   447     (VOID *) memset(statsPtr->literalCount, 0,
   448             sizeof(statsPtr->literalCount));
   449 #endif /* TCL_COMPILE_STATS */    
   450 
   451     /*
   452      * Initialise the stub table pointer.
   453      */
   454 
   455     iPtr->stubTable = &tclStubs;
   456 
   457     
   458     /*
   459      * Create the core commands. Do it here, rather than calling
   460      * Tcl_CreateCommand, because it's faster (there's no need to check for
   461      * a pre-existing command by the same name). If a command has a
   462      * Tcl_CmdProc but no Tcl_ObjCmdProc, set the Tcl_ObjCmdProc to
   463      * TclInvokeStringCommand. This is an object-based wrapper procedure
   464      * that extracts strings, calls the string procedure, and creates an
   465      * object for the result. Similarly, if a command has a Tcl_ObjCmdProc
   466      * but no Tcl_CmdProc, set the Tcl_CmdProc to TclInvokeObjectCommand.
   467      */
   468 
   469     for (cmdInfoPtr = builtInCmds;  cmdInfoPtr->name != NULL;
   470 	    cmdInfoPtr++) {
   471 	int new;
   472 	Tcl_HashEntry *hPtr;
   473 
   474 	if ((cmdInfoPtr->proc == (Tcl_CmdProc *) NULL)
   475 	        && (cmdInfoPtr->objProc == (Tcl_ObjCmdProc *) NULL)
   476 	        && (cmdInfoPtr->compileProc == (CompileProc *) NULL)) {
   477 	    panic("Tcl_CreateInterp: builtin command with NULL string and object command procs and a NULL compile proc\n");
   478 	}
   479 	
   480 	hPtr = Tcl_CreateHashEntry(&iPtr->globalNsPtr->cmdTable,
   481 	        cmdInfoPtr->name, &new);
   482 	if (new) {
   483 	    cmdPtr = (Command *) ckalloc(sizeof(Command));
   484 	    cmdPtr->hPtr = hPtr;
   485 	    cmdPtr->nsPtr = iPtr->globalNsPtr;
   486 	    cmdPtr->refCount = 1;
   487 	    cmdPtr->cmdEpoch = 0;
   488 	    cmdPtr->compileProc = cmdInfoPtr->compileProc;
   489 	    if (cmdInfoPtr->proc == (Tcl_CmdProc *) NULL) {
   490 		cmdPtr->proc = TclInvokeObjectCommand;
   491 		cmdPtr->clientData = (ClientData) cmdPtr;
   492 	    } else {
   493 		cmdPtr->proc = cmdInfoPtr->proc;
   494 		cmdPtr->clientData = (ClientData) NULL;
   495 	    }
   496 	    if (cmdInfoPtr->objProc == (Tcl_ObjCmdProc *) NULL) {
   497 		cmdPtr->objProc = TclInvokeStringCommand;
   498 		cmdPtr->objClientData = (ClientData) cmdPtr;
   499 	    } else {
   500 		cmdPtr->objProc = cmdInfoPtr->objProc;
   501 		cmdPtr->objClientData = (ClientData) NULL;
   502 	    }
   503 	    cmdPtr->deleteProc = NULL;
   504 	    cmdPtr->deleteData = (ClientData) NULL;
   505 	    cmdPtr->flags = 0;
   506 	    cmdPtr->importRefPtr = NULL;
   507 	    cmdPtr->tracePtr = NULL;
   508 	    Tcl_SetHashValue(hPtr, cmdPtr);
   509 	}
   510     }
   511 
   512     /*
   513      * Register the builtin math functions.
   514      */
   515 
   516     i = 0;
   517     for (builtinFuncPtr = tclBuiltinFuncTable;  builtinFuncPtr->name != NULL;
   518 	    builtinFuncPtr++) {
   519 	Tcl_CreateMathFunc((Tcl_Interp *) iPtr, builtinFuncPtr->name,
   520 		builtinFuncPtr->numArgs, builtinFuncPtr->argTypes,
   521 		(Tcl_MathProc *) NULL, (ClientData) 0);
   522 	hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable,
   523 		builtinFuncPtr->name);
   524 	if (hPtr == NULL) {
   525 	    panic("Tcl_CreateInterp: Tcl_CreateMathFunc incorrectly registered '%s'", builtinFuncPtr->name);
   526 	    return NULL;
   527 	}
   528 	mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);
   529 	mathFuncPtr->builtinFuncIndex = i;
   530 	i++;
   531     }
   532     iPtr->flags |= EXPR_INITIALIZED;
   533 
   534     /*
   535      * Do Multiple/Safe Interps Tcl init stuff
   536      */
   537 
   538     TclInterpInit(interp);
   539 
   540     /*
   541      * We used to create the "errorInfo" and "errorCode" global vars at this
   542      * point because so much of the Tcl implementation assumes they already
   543      * exist. This is not quite enough, however, since they can be unset
   544      * at any time.
   545      *
   546      * There are 2 choices:
   547      *    + Check every place where a GetVar of those is used 
   548      *      and the NULL result is not checked (like in tclLoad.c)
   549      *    + Make SetVar,... NULL friendly
   550      * We choose the second option because :
   551      *    + It is easy and low cost to check for NULL pointer before
   552      *      calling strlen()
   553      *    + It can be helpfull to other people using those API
   554      *    + Passing a NULL value to those closest 'meaning' is empty string
   555      *      (specially with the new objects where 0 bytes strings are ok)
   556      * So the following init is commented out:              -- dl
   557      *
   558      * (void) Tcl_SetVar2((Tcl_Interp *)iPtr, "errorInfo", (char *) NULL,
   559      *       "", TCL_GLOBAL_ONLY);
   560      * (void) Tcl_SetVar2((Tcl_Interp *)iPtr, "errorCode", (char *) NULL,
   561      *       "NONE", TCL_GLOBAL_ONLY);
   562      */
   563 
   564 #ifndef TCL_GENERIC_ONLY
   565     TclSetupEnv(interp);
   566 #endif
   567 
   568     /*
   569      * Compute the byte order of this machine.
   570      */
   571 
   572     order.s = 1;
   573     Tcl_SetVar2(interp, "tcl_platform", "byteOrder",
   574 	    ((order.c[0] == 1) ? "littleEndian" : "bigEndian"),
   575 	    TCL_GLOBAL_ONLY);
   576 
   577     Tcl_SetVar2Ex(interp, "tcl_platform", "wordSize",
   578 	    Tcl_NewLongObj((long) sizeof(long)), TCL_GLOBAL_ONLY);
   579 
   580     /*
   581      * Set up other variables such as tcl_version and tcl_library
   582      */
   583 
   584     Tcl_SetVar(interp, "tcl_patchLevel", TCL_PATCH_LEVEL, TCL_GLOBAL_ONLY);
   585     Tcl_SetVar(interp, "tcl_version", TCL_VERSION, TCL_GLOBAL_ONLY);
   586     Tcl_TraceVar2(interp, "tcl_precision", (char *) NULL,
   587 	    TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
   588 	    TclPrecTraceProc, (ClientData) NULL);
   589     TclpSetVariables(interp);
   590 
   591 #ifdef TCL_THREADS
   592     /*
   593      * The existence of the "threaded" element of the tcl_platform array indicates
   594      * that this particular Tcl shell has been compiled with threads turned on.
   595      * Using "info exists tcl_platform(threaded)" a Tcl script can introspect on the 
   596      * interpreter level of thread safety.
   597      */
   598 
   599 
   600     Tcl_SetVar2(interp, "tcl_platform", "threaded", "1",
   601 	    TCL_GLOBAL_ONLY);
   602 #endif
   603 
   604     /*
   605      * Register Tcl's version number.
   606      * TIP#268: Expose information about its status,
   607      *          for runtime switches in the core library
   608      *          and tests.
   609      */
   610 
   611     Tcl_PkgProvideEx(interp, "Tcl", TCL_VERSION, (ClientData) &tclStubs);
   612 
   613 #ifdef TCL_TIP268
   614     Tcl_SetVar2(interp, "tcl_platform", "tip,268", "1",
   615 	    TCL_GLOBAL_ONLY);
   616 #endif
   617 #ifdef TCL_TIP280
   618     Tcl_SetVar2(interp, "tcl_platform", "tip,280", "1",
   619 	    TCL_GLOBAL_ONLY);
   620 #endif
   621 #ifdef Tcl_InitStubs
   622 #undef Tcl_InitStubs
   623 #endif
   624     Tcl_InitStubs(interp, TCL_VERSION, 1);
   625 
   626     return interp;
   627 }
   628 
   629 /*
   630  *----------------------------------------------------------------------
   631  *
   632  * TclHideUnsafeCommands --
   633  *
   634  *	Hides base commands that are not marked as safe from this
   635  *	interpreter.
   636  *
   637  * Results:
   638  *	TCL_OK if it succeeds, TCL_ERROR else.
   639  *
   640  * Side effects:
   641  *	Hides functionality in an interpreter.
   642  *
   643  *----------------------------------------------------------------------
   644  */
   645 
   646 int
   647 TclHideUnsafeCommands(interp)
   648     Tcl_Interp *interp;		/* Hide commands in this interpreter. */
   649 {
   650     register CmdInfo *cmdInfoPtr;
   651 
   652     if (interp == (Tcl_Interp *) NULL) {
   653         return TCL_ERROR;
   654     }
   655     for (cmdInfoPtr = builtInCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
   656         if (!cmdInfoPtr->isSafe) {
   657             Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name);
   658         }
   659     }
   660     return TCL_OK;
   661 }
   662 
   663 /*
   664  *--------------------------------------------------------------
   665  *
   666  * Tcl_CallWhenDeleted --
   667  *
   668  *	Arrange for a procedure to be called before a given
   669  *	interpreter is deleted. The procedure is called as soon
   670  *	as Tcl_DeleteInterp is called; if Tcl_CallWhenDeleted is
   671  *	called on an interpreter that has already been deleted,
   672  *	the procedure will be called when the last Tcl_Release is
   673  *	done on the interpreter.
   674  *
   675  * Results:
   676  *	None.
   677  *
   678  * Side effects:
   679  *	When Tcl_DeleteInterp is invoked to delete interp,
   680  *	proc will be invoked.  See the manual entry for
   681  *	details.
   682  *
   683  *--------------------------------------------------------------
   684  */
   685 
   686 EXPORT_C void
   687 Tcl_CallWhenDeleted(interp, proc, clientData)
   688     Tcl_Interp *interp;		/* Interpreter to watch. */
   689     Tcl_InterpDeleteProc *proc;	/* Procedure to call when interpreter
   690 				 * is about to be deleted. */
   691     ClientData clientData;	/* One-word value to pass to proc. */
   692 {
   693     Interp *iPtr = (Interp *) interp;
   694     static Tcl_ThreadDataKey assocDataCounterKey;
   695     int *assocDataCounterPtr =
   696 	    Tcl_GetThreadData(&assocDataCounterKey, (int)sizeof(int));
   697     int new;
   698     char buffer[32 + TCL_INTEGER_SPACE];
   699     AssocData *dPtr = (AssocData *) ckalloc(sizeof(AssocData));
   700     Tcl_HashEntry *hPtr;
   701 
   702     sprintf(buffer, "Assoc Data Key #%d", *assocDataCounterPtr);
   703     (*assocDataCounterPtr)++;
   704 
   705     if (iPtr->assocData == (Tcl_HashTable *) NULL) {
   706         iPtr->assocData = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
   707         Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
   708     }
   709     hPtr = Tcl_CreateHashEntry(iPtr->assocData, buffer, &new);
   710     dPtr->proc = proc;
   711     dPtr->clientData = clientData;
   712     Tcl_SetHashValue(hPtr, dPtr);
   713 }
   714 
   715 /*
   716  *--------------------------------------------------------------
   717  *
   718  * Tcl_DontCallWhenDeleted --
   719  *
   720  *	Cancel the arrangement for a procedure to be called when
   721  *	a given interpreter is deleted.
   722  *
   723  * Results:
   724  *	None.
   725  *
   726  * Side effects:
   727  *	If proc and clientData were previously registered as a
   728  *	callback via Tcl_CallWhenDeleted, they are unregistered.
   729  *	If they weren't previously registered then nothing
   730  *	happens.
   731  *
   732  *--------------------------------------------------------------
   733  */
   734 
   735 EXPORT_C void
   736 Tcl_DontCallWhenDeleted(interp, proc, clientData)
   737     Tcl_Interp *interp;		/* Interpreter to watch. */
   738     Tcl_InterpDeleteProc *proc;	/* Procedure to call when interpreter
   739 				 * is about to be deleted. */
   740     ClientData clientData;	/* One-word value to pass to proc. */
   741 {
   742     Interp *iPtr = (Interp *) interp;
   743     Tcl_HashTable *hTablePtr;
   744     Tcl_HashSearch hSearch;
   745     Tcl_HashEntry *hPtr;
   746     AssocData *dPtr;
   747 
   748     hTablePtr = iPtr->assocData;
   749     if (hTablePtr == (Tcl_HashTable *) NULL) {
   750         return;
   751     }
   752     for (hPtr = Tcl_FirstHashEntry(hTablePtr, &hSearch); hPtr != NULL;
   753 	    hPtr = Tcl_NextHashEntry(&hSearch)) {
   754         dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
   755         if ((dPtr->proc == proc) && (dPtr->clientData == clientData)) {
   756             ckfree((char *) dPtr);
   757             Tcl_DeleteHashEntry(hPtr);
   758             return;
   759         }
   760     }
   761 }
   762 
   763 /*
   764  *----------------------------------------------------------------------
   765  *
   766  * Tcl_SetAssocData --
   767  *
   768  *	Creates a named association between user-specified data, a delete
   769  *	function and this interpreter. If the association already exists
   770  *	the data is overwritten with the new data. The delete function will
   771  *	be invoked when the interpreter is deleted.
   772  *
   773  * Results:
   774  *	None.
   775  *
   776  * Side effects:
   777  *	Sets the associated data, creates the association if needed.
   778  *
   779  *----------------------------------------------------------------------
   780  */
   781 
   782 EXPORT_C void
   783 Tcl_SetAssocData(interp, name, proc, clientData)
   784     Tcl_Interp *interp;		/* Interpreter to associate with. */
   785     CONST char *name;		/* Name for association. */
   786     Tcl_InterpDeleteProc *proc;	/* Proc to call when interpreter is
   787                                  * about to be deleted. */
   788     ClientData clientData;	/* One-word value to pass to proc. */
   789 {
   790     Interp *iPtr = (Interp *) interp;
   791     AssocData *dPtr;
   792     Tcl_HashEntry *hPtr;
   793     int new;
   794 
   795     if (iPtr->assocData == (Tcl_HashTable *) NULL) {
   796         iPtr->assocData = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
   797         Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
   798     }
   799     hPtr = Tcl_CreateHashEntry(iPtr->assocData, name, &new);
   800     if (new == 0) {
   801         dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
   802     } else {
   803         dPtr = (AssocData *) ckalloc(sizeof(AssocData));
   804     }
   805     dPtr->proc = proc;
   806     dPtr->clientData = clientData;
   807 
   808     Tcl_SetHashValue(hPtr, dPtr);
   809 }
   810 
   811 /*
   812  *----------------------------------------------------------------------
   813  *
   814  * Tcl_DeleteAssocData --
   815  *
   816  *	Deletes a named association of user-specified data with
   817  *	the specified interpreter.
   818  *
   819  * Results:
   820  *	None.
   821  *
   822  * Side effects:
   823  *	Deletes the association.
   824  *
   825  *----------------------------------------------------------------------
   826  */
   827 
   828 EXPORT_C void
   829 Tcl_DeleteAssocData(interp, name)
   830     Tcl_Interp *interp;			/* Interpreter to associate with. */
   831     CONST char *name;			/* Name of association. */
   832 {
   833     Interp *iPtr = (Interp *) interp;
   834     AssocData *dPtr;
   835     Tcl_HashEntry *hPtr;
   836 
   837     if (iPtr->assocData == (Tcl_HashTable *) NULL) {
   838         return;
   839     }
   840     hPtr = Tcl_FindHashEntry(iPtr->assocData, name);
   841     if (hPtr == (Tcl_HashEntry *) NULL) {
   842         return;
   843     }
   844     dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
   845     if (dPtr->proc != NULL) {
   846         (dPtr->proc) (dPtr->clientData, interp);
   847     }
   848     ckfree((char *) dPtr);
   849     Tcl_DeleteHashEntry(hPtr);
   850 }
   851 
   852 /*
   853  *----------------------------------------------------------------------
   854  *
   855  * Tcl_GetAssocData --
   856  *
   857  *	Returns the client data associated with this name in the
   858  *	specified interpreter.
   859  *
   860  * Results:
   861  *	The client data in the AssocData record denoted by the named
   862  *	association, or NULL.
   863  *
   864  * Side effects:
   865  *	None.
   866  *
   867  *----------------------------------------------------------------------
   868  */
   869 
   870 EXPORT_C ClientData
   871 Tcl_GetAssocData(interp, name, procPtr)
   872     Tcl_Interp *interp;			/* Interpreter associated with. */
   873     CONST char *name;			/* Name of association. */
   874     Tcl_InterpDeleteProc **procPtr;	/* Pointer to place to store address
   875 					 * of current deletion callback. */
   876 {
   877     Interp *iPtr = (Interp *) interp;
   878     AssocData *dPtr;
   879     Tcl_HashEntry *hPtr;
   880 
   881     if (iPtr->assocData == (Tcl_HashTable *) NULL) {
   882         return (ClientData) NULL;
   883     }
   884     hPtr = Tcl_FindHashEntry(iPtr->assocData, name);
   885     if (hPtr == (Tcl_HashEntry *) NULL) {
   886         return (ClientData) NULL;
   887     }
   888     dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
   889     if (procPtr != (Tcl_InterpDeleteProc **) NULL) {
   890         *procPtr = dPtr->proc;
   891     }
   892     return dPtr->clientData;
   893 }
   894 
   895 /*
   896  *----------------------------------------------------------------------
   897  *
   898  * Tcl_InterpDeleted --
   899  *
   900  *	Returns nonzero if the interpreter has been deleted with a call
   901  *	to Tcl_DeleteInterp.
   902  *
   903  * Results:
   904  *	Nonzero if the interpreter is deleted, zero otherwise.
   905  *
   906  * Side effects:
   907  *	None.
   908  *
   909  *----------------------------------------------------------------------
   910  */
   911 
   912 EXPORT_C int
   913 Tcl_InterpDeleted(interp)
   914     Tcl_Interp *interp;
   915 {
   916     return (((Interp *) interp)->flags & DELETED) ? 1 : 0;
   917 }
   918 
   919 /*
   920  *----------------------------------------------------------------------
   921  *
   922  * Tcl_DeleteInterp --
   923  *
   924  *	Ensures that the interpreter will be deleted eventually. If there
   925  *	are no Tcl_Preserve calls in effect for this interpreter, it is
   926  *	deleted immediately, otherwise the interpreter is deleted when
   927  *	the last Tcl_Preserve is matched by a call to Tcl_Release. In either
   928  *	case, the procedure runs the currently registered deletion callbacks. 
   929  *
   930  * Results:
   931  *	None.
   932  *
   933  * Side effects:
   934  *	The interpreter is marked as deleted. The caller may still use it
   935  *	safely if there are calls to Tcl_Preserve in effect for the
   936  *	interpreter, but further calls to Tcl_Eval etc in this interpreter
   937  *	will fail.
   938  *
   939  *----------------------------------------------------------------------
   940  */
   941 
   942 EXPORT_C void
   943 Tcl_DeleteInterp(interp)
   944     Tcl_Interp *interp;		/* Token for command interpreter (returned
   945 				 * by a previous call to Tcl_CreateInterp). */
   946 {
   947     Interp *iPtr = (Interp *) interp;
   948 
   949     /*
   950      * If the interpreter has already been marked deleted, just punt.
   951      */
   952 
   953     if (iPtr->flags & DELETED) {
   954         return;
   955     }
   956     
   957     /*
   958      * Mark the interpreter as deleted. No further evals will be allowed.
   959      */
   960 
   961     iPtr->flags |= DELETED;
   962 
   963     /*
   964      * Ensure that the interpreter is eventually deleted.
   965      */
   966 
   967     Tcl_EventuallyFree((ClientData) interp,
   968             (Tcl_FreeProc *) DeleteInterpProc);
   969 }
   970 
   971 /*
   972  *----------------------------------------------------------------------
   973  *
   974  * DeleteInterpProc --
   975  *
   976  *	Helper procedure to delete an interpreter. This procedure is
   977  *	called when the last call to Tcl_Preserve on this interpreter
   978  *	is matched by a call to Tcl_Release. The procedure cleans up
   979  *	all resources used in the interpreter and calls all currently
   980  *	registered interpreter deletion callbacks.
   981  *
   982  * Results:
   983  *	None.
   984  *
   985  * Side effects:
   986  *	Whatever the interpreter deletion callbacks do. Frees resources
   987  *	used by the interpreter.
   988  *
   989  *----------------------------------------------------------------------
   990  */
   991 
   992 static void
   993 DeleteInterpProc(interp)
   994     Tcl_Interp *interp;			/* Interpreter to delete. */
   995 {
   996     Interp *iPtr = (Interp *) interp;
   997     Tcl_HashEntry *hPtr;
   998     Tcl_HashSearch search;
   999     Tcl_HashTable *hTablePtr;
  1000     ResolverScheme *resPtr, *nextResPtr;
  1001 
  1002     /*
  1003      * Punt if there is an error in the Tcl_Release/Tcl_Preserve matchup.
  1004      */
  1005     
  1006     if (iPtr->numLevels > 0) {
  1007         panic("DeleteInterpProc called with active evals");
  1008     }
  1009 
  1010     /*
  1011      * The interpreter should already be marked deleted; otherwise how
  1012      * did we get here?
  1013      */
  1014 
  1015     if (!(iPtr->flags & DELETED)) {
  1016         panic("DeleteInterpProc called on interpreter not marked deleted");
  1017     }
  1018 
  1019     TclHandleFree(iPtr->handle);
  1020 
  1021     /*
  1022      * Dismantle everything in the global namespace except for the
  1023      * "errorInfo" and "errorCode" variables. These remain until the
  1024      * namespace is actually destroyed, in case any errors occur.
  1025      *   
  1026      * Dismantle the namespace here, before we clear the assocData. If any
  1027      * background errors occur here, they will be deleted below.
  1028      */
  1029     
  1030     TclTeardownNamespace(iPtr->globalNsPtr);
  1031 
  1032     /*
  1033      * Delete all the hidden commands.
  1034      */
  1035      
  1036     hTablePtr = iPtr->hiddenCmdTablePtr;
  1037     if (hTablePtr != NULL) {
  1038 	/*
  1039 	 * Non-pernicious deletion.  The deletion callbacks will not be
  1040 	 * allowed to create any new hidden or non-hidden commands.
  1041 	 * Tcl_DeleteCommandFromToken() will remove the entry from the
  1042 	 * hiddenCmdTablePtr.
  1043 	 */
  1044 	 
  1045 	hPtr = Tcl_FirstHashEntry(hTablePtr, &search);
  1046 	for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
  1047 	    Tcl_DeleteCommandFromToken(interp,
  1048 		    (Tcl_Command) Tcl_GetHashValue(hPtr));
  1049 	}
  1050 	Tcl_DeleteHashTable(hTablePtr);
  1051 	ckfree((char *) hTablePtr);
  1052     }
  1053     /*
  1054      * Tear down the math function table.
  1055      */
  1056 
  1057     for (hPtr = Tcl_FirstHashEntry(&iPtr->mathFuncTable, &search);
  1058 	     hPtr != NULL;
  1059              hPtr = Tcl_NextHashEntry(&search)) {
  1060 	ckfree((char *) Tcl_GetHashValue(hPtr));
  1061     }
  1062     Tcl_DeleteHashTable(&iPtr->mathFuncTable);
  1063 
  1064     /*
  1065      * Invoke deletion callbacks; note that a callback can create new
  1066      * callbacks, so we iterate.
  1067      */
  1068 
  1069     while (iPtr->assocData != (Tcl_HashTable *) NULL) {
  1070 	AssocData *dPtr;
  1071 	
  1072         hTablePtr = iPtr->assocData;
  1073         iPtr->assocData = (Tcl_HashTable *) NULL;
  1074         for (hPtr = Tcl_FirstHashEntry(hTablePtr, &search);
  1075                  hPtr != NULL;
  1076                  hPtr = Tcl_FirstHashEntry(hTablePtr, &search)) {
  1077             dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
  1078             Tcl_DeleteHashEntry(hPtr);
  1079             if (dPtr->proc != NULL) {
  1080                 (*dPtr->proc)(dPtr->clientData, interp);
  1081             }
  1082             ckfree((char *) dPtr);
  1083         }
  1084         Tcl_DeleteHashTable(hTablePtr);
  1085         ckfree((char *) hTablePtr);
  1086     }
  1087 
  1088     /*
  1089      * Finish deleting the global namespace.
  1090      */
  1091     
  1092     Tcl_DeleteNamespace((Tcl_Namespace *) iPtr->globalNsPtr);
  1093 
  1094     /*
  1095      * Free up the result *after* deleting variables, since variable
  1096      * deletion could have transferred ownership of the result string
  1097      * to Tcl.
  1098      */
  1099 
  1100     Tcl_FreeResult(interp);
  1101     interp->result = NULL;
  1102     Tcl_DecrRefCount(iPtr->objResultPtr);
  1103     iPtr->objResultPtr = NULL;
  1104     if (iPtr->errorInfo != NULL) {
  1105 	ckfree(iPtr->errorInfo);
  1106         iPtr->errorInfo = NULL;
  1107     }
  1108     if (iPtr->errorCode != NULL) {
  1109 	ckfree(iPtr->errorCode);
  1110         iPtr->errorCode = NULL;
  1111     }
  1112     if (iPtr->appendResult != NULL) {
  1113 	ckfree(iPtr->appendResult);
  1114         iPtr->appendResult = NULL;
  1115     }
  1116     TclFreePackageInfo(iPtr);
  1117     while (iPtr->tracePtr != NULL) {
  1118 	Tcl_DeleteTrace((Tcl_Interp*) iPtr, (Tcl_Trace) iPtr->tracePtr);
  1119     }
  1120     if (iPtr->execEnvPtr != NULL) {
  1121 	TclDeleteExecEnv(iPtr->execEnvPtr);
  1122     }
  1123     Tcl_DecrRefCount(iPtr->emptyObjPtr);
  1124     iPtr->emptyObjPtr = NULL;
  1125 
  1126     resPtr = iPtr->resolverPtr;
  1127     while (resPtr) {
  1128 	nextResPtr = resPtr->nextPtr;
  1129 	ckfree(resPtr->name);
  1130 	ckfree((char *) resPtr);
  1131         resPtr = nextResPtr;
  1132     }
  1133     
  1134     /*
  1135      * Free up literal objects created for scripts compiled by the
  1136      * interpreter.
  1137      */
  1138 
  1139     TclDeleteLiteralTable(interp, &(iPtr->literalTable));
  1140 
  1141 #ifdef TCL_TIP280
  1142     /* TIP #280 - Release the arrays for ByteCode/Proc extension, and contents.
  1143      */
  1144     {
  1145         Tcl_HashEntry *hPtr;
  1146 	Tcl_HashSearch hSearch;
  1147 	CmdFrame*      cfPtr;
  1148 	ExtCmdLoc*     eclPtr;
  1149 	int            i;
  1150 
  1151 	for (hPtr = Tcl_FirstHashEntry(iPtr->linePBodyPtr, &hSearch);
  1152 	     hPtr != NULL;
  1153 	     hPtr = Tcl_NextHashEntry(&hSearch)) {
  1154 
  1155 	    cfPtr = (CmdFrame*) Tcl_GetHashValue (hPtr);
  1156 
  1157 	    if (cfPtr->type == TCL_LOCATION_SOURCE) {
  1158 	        Tcl_DecrRefCount (cfPtr->data.eval.path);
  1159 	    }
  1160 	    ckfree ((char*) cfPtr->line);
  1161 	    ckfree ((char*) cfPtr);
  1162 	    Tcl_DeleteHashEntry (hPtr);
  1163 
  1164 	}
  1165 	Tcl_DeleteHashTable (iPtr->linePBodyPtr);
  1166 	ckfree ((char*) iPtr->linePBodyPtr);
  1167 	iPtr->linePBodyPtr = NULL;
  1168 
  1169 	/* See also tclCompile.c, TclCleanupByteCode */
  1170 
  1171 	for (hPtr = Tcl_FirstHashEntry(iPtr->lineBCPtr, &hSearch);
  1172 	     hPtr != NULL;
  1173 	     hPtr = Tcl_NextHashEntry(&hSearch)) {
  1174 
  1175 	    eclPtr = (ExtCmdLoc*) Tcl_GetHashValue (hPtr);
  1176 
  1177 	    if (eclPtr->type == TCL_LOCATION_SOURCE) {
  1178 	        Tcl_DecrRefCount (eclPtr->path);
  1179 	    }
  1180 	    for (i=0; i< eclPtr->nuloc; i++) {
  1181 	        ckfree ((char*) eclPtr->loc[i].line);
  1182 	    }
  1183 
  1184             if (eclPtr->loc != NULL) {
  1185 		ckfree ((char*) eclPtr->loc);
  1186 	    }
  1187 
  1188 	    ckfree ((char*) eclPtr);
  1189 	    Tcl_DeleteHashEntry (hPtr);
  1190 	}
  1191 	Tcl_DeleteHashTable (iPtr->lineBCPtr);
  1192 	ckfree((char*) iPtr->lineBCPtr);
  1193 	iPtr->lineBCPtr = NULL;
  1194     }
  1195 #endif
  1196     ckfree((char *) iPtr);
  1197 }
  1198 
  1199 /*
  1200  *---------------------------------------------------------------------------
  1201  *
  1202  * Tcl_HideCommand --
  1203  *
  1204  *	Makes a command hidden so that it cannot be invoked from within
  1205  *	an interpreter, only from within an ancestor.
  1206  *
  1207  * Results:
  1208  *	A standard Tcl result; also leaves a message in the interp's result
  1209  *	if an error occurs.
  1210  *
  1211  * Side effects:
  1212  *	Removes a command from the command table and create an entry
  1213  *      into the hidden command table under the specified token name.
  1214  *
  1215  *---------------------------------------------------------------------------
  1216  */
  1217 
  1218 EXPORT_C int
  1219 Tcl_HideCommand(interp, cmdName, hiddenCmdToken)
  1220     Tcl_Interp *interp;		/* Interpreter in which to hide command. */
  1221     CONST char *cmdName;	/* Name of command to hide. */
  1222     CONST char *hiddenCmdToken;	/* Token name of the to-be-hidden command. */
  1223 {
  1224     Interp *iPtr = (Interp *) interp;
  1225     Tcl_Command cmd;
  1226     Command *cmdPtr;
  1227     Tcl_HashTable *hiddenCmdTablePtr;
  1228     Tcl_HashEntry *hPtr;
  1229     int new;
  1230 
  1231     if (iPtr->flags & DELETED) {
  1232 
  1233         /*
  1234          * The interpreter is being deleted. Do not create any new
  1235          * structures, because it is not safe to modify the interpreter.
  1236          */
  1237         
  1238         return TCL_ERROR;
  1239     }
  1240 
  1241     /*
  1242      * Disallow hiding of commands that are currently in a namespace or
  1243      * renaming (as part of hiding) into a namespace.
  1244      *
  1245      * (because the current implementation with a single global table
  1246      *  and the needed uniqueness of names cause problems with namespaces)
  1247      *
  1248      * we don't need to check for "::" in cmdName because the real check is
  1249      * on the nsPtr below.
  1250      *
  1251      * hiddenCmdToken is just a string which is not interpreted in any way.
  1252      * It may contain :: but the string is not interpreted as a namespace
  1253      * qualifier command name. Thus, hiding foo::bar to foo::bar and then
  1254      * trying to expose or invoke ::foo::bar will NOT work; but if the
  1255      * application always uses the same strings it will get consistent
  1256      * behaviour.
  1257      *
  1258      * But as we currently limit ourselves to the global namespace only
  1259      * for the source, in order to avoid potential confusion,
  1260      * lets prevent "::" in the token too.  --dl
  1261      */
  1262 
  1263     if (strstr(hiddenCmdToken, "::") != NULL) {
  1264         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1265                 "cannot use namespace qualifiers in hidden command",
  1266 		" token (rename)", (char *) NULL);
  1267         return TCL_ERROR;
  1268     }
  1269 
  1270     /*
  1271      * Find the command to hide. An error is returned if cmdName can't
  1272      * be found. Look up the command only from the global namespace.
  1273      * Full path of the command must be given if using namespaces.
  1274      */
  1275 
  1276     cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
  1277 	    /*flags*/ TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
  1278     if (cmd == (Tcl_Command) NULL) {
  1279 	return TCL_ERROR;
  1280     }
  1281     cmdPtr = (Command *) cmd;
  1282 
  1283     /*
  1284      * Check that the command is really in global namespace
  1285      */
  1286 
  1287     if ( cmdPtr->nsPtr != iPtr->globalNsPtr ) {
  1288         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1289                 "can only hide global namespace commands",
  1290 		" (use rename then hide)", (char *) NULL);
  1291         return TCL_ERROR;
  1292     }
  1293     
  1294     /*
  1295      * Initialize the hidden command table if necessary.
  1296      */
  1297 
  1298     hiddenCmdTablePtr = iPtr->hiddenCmdTablePtr;
  1299     if (hiddenCmdTablePtr == NULL) {
  1300         hiddenCmdTablePtr = (Tcl_HashTable *)
  1301 	        ckalloc((unsigned) sizeof(Tcl_HashTable));
  1302         Tcl_InitHashTable(hiddenCmdTablePtr, TCL_STRING_KEYS);
  1303 	iPtr->hiddenCmdTablePtr = hiddenCmdTablePtr;
  1304     }
  1305 
  1306     /*
  1307      * It is an error to move an exposed command to a hidden command with
  1308      * hiddenCmdToken if a hidden command with the name hiddenCmdToken already
  1309      * exists.
  1310      */
  1311     
  1312     hPtr = Tcl_CreateHashEntry(hiddenCmdTablePtr, hiddenCmdToken, &new);
  1313     if (!new) {
  1314         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1315                 "hidden command named \"", hiddenCmdToken, "\" already exists",
  1316                 (char *) NULL);
  1317         return TCL_ERROR;
  1318     }
  1319 
  1320     /*
  1321      * Nb : This code is currently 'like' a rename to a specialy set apart
  1322      * name table. Changes here and in TclRenameCommand must
  1323      * be kept in synch untill the common parts are actually
  1324      * factorized out.
  1325      */
  1326 
  1327     /*
  1328      * Remove the hash entry for the command from the interpreter command
  1329      * table. This is like deleting the command, so bump its command epoch;
  1330      * this invalidates any cached references that point to the command.
  1331      */
  1332 
  1333     if (cmdPtr->hPtr != NULL) {
  1334         Tcl_DeleteHashEntry(cmdPtr->hPtr);
  1335         cmdPtr->hPtr = (Tcl_HashEntry *) NULL;
  1336 	cmdPtr->cmdEpoch++;
  1337     }
  1338 
  1339     /*
  1340      * Now link the hash table entry with the command structure.
  1341      * We ensured above that the nsPtr was right.
  1342      */
  1343     
  1344     cmdPtr->hPtr = hPtr;
  1345     Tcl_SetHashValue(hPtr, (ClientData) cmdPtr);
  1346 
  1347     /*
  1348      * If the command being hidden has a compile procedure, increment the
  1349      * interpreter's compileEpoch to invalidate its compiled code. This
  1350      * makes sure that we don't later try to execute old code compiled with
  1351      * command-specific (i.e., inline) bytecodes for the now-hidden
  1352      * command. This field is checked in Tcl_EvalObj and ObjInterpProc,
  1353      * and code whose compilation epoch doesn't match is recompiled.
  1354      */
  1355 
  1356     if (cmdPtr->compileProc != NULL) {
  1357 	iPtr->compileEpoch++;
  1358     }
  1359     return TCL_OK;
  1360 }
  1361 
  1362 /*
  1363  *----------------------------------------------------------------------
  1364  *
  1365  * Tcl_ExposeCommand --
  1366  *
  1367  *	Makes a previously hidden command callable from inside the
  1368  *	interpreter instead of only by its ancestors.
  1369  *
  1370  * Results:
  1371  *	A standard Tcl result. If an error occurs, a message is left
  1372  *	in the interp's result.
  1373  *
  1374  * Side effects:
  1375  *	Moves commands from one hash table to another.
  1376  *
  1377  *----------------------------------------------------------------------
  1378  */
  1379 
  1380 EXPORT_C int
  1381 Tcl_ExposeCommand(interp, hiddenCmdToken, cmdName)
  1382     Tcl_Interp *interp;		/* Interpreter in which to make command
  1383                                  * callable. */
  1384     CONST char *hiddenCmdToken;	/* Name of hidden command. */
  1385     CONST char *cmdName;	/* Name of to-be-exposed command. */
  1386 {
  1387     Interp *iPtr = (Interp *) interp;
  1388     Command *cmdPtr;
  1389     Namespace *nsPtr;
  1390     Tcl_HashEntry *hPtr;
  1391     Tcl_HashTable *hiddenCmdTablePtr;
  1392     int new;
  1393 
  1394     if (iPtr->flags & DELETED) {
  1395         /*
  1396          * The interpreter is being deleted. Do not create any new
  1397          * structures, because it is not safe to modify the interpreter.
  1398          */
  1399         
  1400         return TCL_ERROR;
  1401     }
  1402 
  1403     /*
  1404      * Check that we have a regular name for the command
  1405      * (that the user is not trying to do an expose and a rename
  1406      *  (to another namespace) at the same time)
  1407      */
  1408 
  1409     if (strstr(cmdName, "::") != NULL) {
  1410         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1411                 "can not expose to a namespace ",
  1412 		"(use expose to toplevel, then rename)",
  1413                  (char *) NULL);
  1414         return TCL_ERROR;
  1415     }
  1416 
  1417     /*
  1418      * Get the command from the hidden command table:
  1419      */
  1420 
  1421     hPtr = NULL;
  1422     hiddenCmdTablePtr = iPtr->hiddenCmdTablePtr;
  1423     if (hiddenCmdTablePtr != NULL) {
  1424 	hPtr = Tcl_FindHashEntry(hiddenCmdTablePtr, hiddenCmdToken);
  1425     }
  1426     if (hPtr == (Tcl_HashEntry *) NULL) {
  1427         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1428                 "unknown hidden command \"", hiddenCmdToken,
  1429                 "\"", (char *) NULL);
  1430         return TCL_ERROR;
  1431     }
  1432     cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
  1433     
  1434 
  1435     /*
  1436      * Check that we have a true global namespace
  1437      * command (enforced by Tcl_HideCommand() but let's double
  1438      * check. (If it was not, we would not really know how to
  1439      * handle it).
  1440      */
  1441     if ( cmdPtr->nsPtr != iPtr->globalNsPtr ) {
  1442 	/* 
  1443 	 * This case is theoritically impossible,
  1444 	 * we might rather panic() than 'nicely' erroring out ?
  1445 	 */
  1446         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1447                 "trying to expose a non global command name space command",
  1448 		(char *) NULL);
  1449         return TCL_ERROR;
  1450     }
  1451     
  1452     /* This is the global table */
  1453     nsPtr = cmdPtr->nsPtr;
  1454 
  1455     /*
  1456      * It is an error to overwrite an existing exposed command as a result
  1457      * of exposing a previously hidden command.
  1458      */
  1459 
  1460     hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &new);
  1461     if (!new) {
  1462         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1463                 "exposed command \"", cmdName,
  1464                 "\" already exists", (char *) NULL);
  1465         return TCL_ERROR;
  1466     }
  1467 
  1468     /*
  1469      * Remove the hash entry for the command from the interpreter hidden
  1470      * command table.
  1471      */
  1472 
  1473     if (cmdPtr->hPtr != NULL) {
  1474         Tcl_DeleteHashEntry(cmdPtr->hPtr);
  1475         cmdPtr->hPtr = NULL;
  1476     }
  1477 
  1478     /*
  1479      * Now link the hash table entry with the command structure.
  1480      * This is like creating a new command, so deal with any shadowing
  1481      * of commands in the global namespace.
  1482      */
  1483     
  1484     cmdPtr->hPtr = hPtr;
  1485 
  1486     Tcl_SetHashValue(hPtr, (ClientData) cmdPtr);
  1487 
  1488     /*
  1489      * Not needed as we are only in the global namespace
  1490      * (but would be needed again if we supported namespace command hiding)
  1491      *
  1492      * TclResetShadowedCmdRefs(interp, cmdPtr);
  1493      */
  1494 
  1495 
  1496     /*
  1497      * If the command being exposed has a compile procedure, increment
  1498      * interpreter's compileEpoch to invalidate its compiled code. This
  1499      * makes sure that we don't later try to execute old code compiled
  1500      * assuming the command is hidden. This field is checked in Tcl_EvalObj
  1501      * and ObjInterpProc, and code whose compilation epoch doesn't match is
  1502      * recompiled.
  1503      */
  1504 
  1505     if (cmdPtr->compileProc != NULL) {
  1506 	iPtr->compileEpoch++;
  1507     }
  1508     return TCL_OK;
  1509 }
  1510 
  1511 /*
  1512  *----------------------------------------------------------------------
  1513  *
  1514  * Tcl_CreateCommand --
  1515  *
  1516  *	Define a new command in a command table.
  1517  *
  1518  * Results:
  1519  *	The return value is a token for the command, which can
  1520  *	be used in future calls to Tcl_GetCommandName.
  1521  *
  1522  * Side effects:
  1523  *	If a command named cmdName already exists for interp, it is deleted.
  1524  *	In the future, when cmdName is seen as the name of a command by
  1525  *	Tcl_Eval, proc will be called. To support the bytecode interpreter,
  1526  *	the command is created with a wrapper Tcl_ObjCmdProc
  1527  *	(TclInvokeStringCommand) that eventially calls proc. When the
  1528  *	command is deleted from the table, deleteProc will be called.
  1529  *	See the manual entry for details on the calling sequence.
  1530  *
  1531  *----------------------------------------------------------------------
  1532  */
  1533 
  1534 EXPORT_C Tcl_Command
  1535 Tcl_CreateCommand(interp, cmdName, proc, clientData, deleteProc)
  1536     Tcl_Interp *interp;		/* Token for command interpreter returned by
  1537 				 * a previous call to Tcl_CreateInterp. */
  1538     CONST char *cmdName;	/* Name of command. If it contains namespace
  1539 				 * qualifiers, the new command is put in the
  1540 				 * specified namespace; otherwise it is put
  1541 				 * in the global namespace. */
  1542     Tcl_CmdProc *proc;		/* Procedure to associate with cmdName. */
  1543     ClientData clientData;	/* Arbitrary value passed to string proc. */
  1544     Tcl_CmdDeleteProc *deleteProc;
  1545 				/* If not NULL, gives a procedure to call
  1546 				 * when this command is deleted. */
  1547 {
  1548     Interp *iPtr = (Interp *) interp;
  1549     ImportRef *oldRefPtr = NULL;
  1550     Namespace *nsPtr, *dummy1, *dummy2;
  1551     Command *cmdPtr, *refCmdPtr;
  1552     Tcl_HashEntry *hPtr;
  1553     CONST char *tail;
  1554     int new;
  1555     ImportedCmdData *dataPtr;
  1556 
  1557     if (iPtr->flags & DELETED) {
  1558 	/*
  1559 	 * The interpreter is being deleted.  Don't create any new
  1560 	 * commands; it's not safe to muck with the interpreter anymore.
  1561 	 */
  1562 
  1563 	return (Tcl_Command) NULL;
  1564     }
  1565 
  1566     /*
  1567      * Determine where the command should reside. If its name contains 
  1568      * namespace qualifiers, we put it in the specified namespace; 
  1569      * otherwise, we always put it in the global namespace.
  1570      */
  1571 
  1572     if (strstr(cmdName, "::") != NULL) {
  1573        TclGetNamespaceForQualName(interp, cmdName, (Namespace *) NULL,
  1574            CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
  1575        if ((nsPtr == NULL) || (tail == NULL)) {
  1576 	    return (Tcl_Command) NULL;
  1577 	}
  1578     } else {
  1579 	nsPtr = iPtr->globalNsPtr;
  1580 	tail = cmdName;
  1581     }
  1582     
  1583     hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
  1584     if (!new) {
  1585 	/*
  1586 	 * Command already exists. Delete the old one.
  1587 	 * Be careful to preserve any existing import links so we can
  1588 	 * restore them down below.  That way, you can redefine a
  1589 	 * command and its import status will remain intact.
  1590 	 */
  1591 
  1592 	cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
  1593 	oldRefPtr = cmdPtr->importRefPtr;
  1594 	cmdPtr->importRefPtr = NULL;
  1595 
  1596 	Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
  1597 	hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
  1598 	if (!new) {
  1599 	    /*
  1600 	     * If the deletion callback recreated the command, just throw
  1601              * away the new command (if we try to delete it again, we
  1602              * could get stuck in an infinite loop).
  1603 	     */
  1604 
  1605 	     ckfree((char*) Tcl_GetHashValue(hPtr));
  1606 	}
  1607     }
  1608     cmdPtr = (Command *) ckalloc(sizeof(Command));
  1609     Tcl_SetHashValue(hPtr, cmdPtr);
  1610     cmdPtr->hPtr = hPtr;
  1611     cmdPtr->nsPtr = nsPtr;
  1612     cmdPtr->refCount = 1;
  1613     cmdPtr->cmdEpoch = 0;
  1614     cmdPtr->compileProc = (CompileProc *) NULL;
  1615     cmdPtr->objProc = TclInvokeStringCommand;
  1616     cmdPtr->objClientData = (ClientData) cmdPtr;
  1617     cmdPtr->proc = proc;
  1618     cmdPtr->clientData = clientData;
  1619     cmdPtr->deleteProc = deleteProc;
  1620     cmdPtr->deleteData = clientData;
  1621     cmdPtr->flags = 0;
  1622     cmdPtr->importRefPtr = NULL;
  1623     cmdPtr->tracePtr = NULL;
  1624 
  1625     /*
  1626      * Plug in any existing import references found above.  Be sure
  1627      * to update all of these references to point to the new command.
  1628      */
  1629 
  1630     if (oldRefPtr != NULL) {
  1631 	cmdPtr->importRefPtr = oldRefPtr;
  1632 	while (oldRefPtr != NULL) {
  1633 	    refCmdPtr = oldRefPtr->importedCmdPtr;
  1634 	    dataPtr = (ImportedCmdData*)refCmdPtr->objClientData;
  1635 	    dataPtr->realCmdPtr = cmdPtr;
  1636 	    oldRefPtr = oldRefPtr->nextPtr;
  1637 	}
  1638     }
  1639 
  1640     /*
  1641      * We just created a command, so in its namespace and all of its parent
  1642      * namespaces, it may shadow global commands with the same name. If any
  1643      * shadowed commands are found, invalidate all cached command references
  1644      * in the affected namespaces.
  1645      */
  1646     
  1647     TclResetShadowedCmdRefs(interp, cmdPtr);
  1648     return (Tcl_Command) cmdPtr;
  1649 }
  1650 
  1651 /*
  1652  *----------------------------------------------------------------------
  1653  *
  1654  * Tcl_CreateObjCommand --
  1655  *
  1656  *	Define a new object-based command in a command table.
  1657  *
  1658  * Results:
  1659  *	The return value is a token for the command, which can
  1660  *	be used in future calls to Tcl_GetCommandName.
  1661  *
  1662  * Side effects:
  1663  *	If no command named "cmdName" already exists for interp, one is
  1664  *	created. Otherwise, if a command does exist, then if the
  1665  *	object-based Tcl_ObjCmdProc is TclInvokeStringCommand, we assume
  1666  *	Tcl_CreateCommand was called previously for the same command and
  1667  *	just set its Tcl_ObjCmdProc to the argument "proc"; otherwise, we
  1668  *	delete the old command.
  1669  *
  1670  *	In the future, during bytecode evaluation when "cmdName" is seen as
  1671  *	the name of a command by Tcl_EvalObj or Tcl_Eval, the object-based
  1672  *	Tcl_ObjCmdProc proc will be called. When the command is deleted from
  1673  *	the table, deleteProc will be called. See the manual entry for
  1674  *	details on the calling sequence.
  1675  *
  1676  *----------------------------------------------------------------------
  1677  */
  1678 
  1679 EXPORT_C Tcl_Command
  1680 Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc)
  1681     Tcl_Interp *interp;		/* Token for command interpreter (returned
  1682 				 * by previous call to Tcl_CreateInterp). */
  1683     CONST char *cmdName;	/* Name of command. If it contains namespace
  1684 				 * qualifiers, the new command is put in the
  1685 				 * specified namespace; otherwise it is put
  1686 				 * in the global namespace. */
  1687     Tcl_ObjCmdProc *proc;	/* Object-based procedure to associate with
  1688 				 * name. */
  1689     ClientData clientData;	/* Arbitrary value to pass to object
  1690     				 * procedure. */
  1691     Tcl_CmdDeleteProc *deleteProc;
  1692 				/* If not NULL, gives a procedure to call
  1693 				 * when this command is deleted. */
  1694 {
  1695     Interp *iPtr = (Interp *) interp;
  1696     ImportRef *oldRefPtr = NULL;
  1697     Namespace *nsPtr, *dummy1, *dummy2;
  1698     Command *cmdPtr, *refCmdPtr;
  1699     Tcl_HashEntry *hPtr;
  1700     CONST char *tail;
  1701     int new;
  1702     ImportedCmdData *dataPtr;
  1703 
  1704     if (iPtr->flags & DELETED) {
  1705 	/*
  1706 	 * The interpreter is being deleted.  Don't create any new
  1707 	 * commands;  it's not safe to muck with the interpreter anymore.
  1708 	 */
  1709 
  1710 	return (Tcl_Command) NULL;
  1711     }
  1712 
  1713     /*
  1714      * Determine where the command should reside. If its name contains 
  1715      * namespace qualifiers, we put it in the specified namespace; 
  1716      * otherwise, we always put it in the global namespace.
  1717      */
  1718 
  1719     if (strstr(cmdName, "::") != NULL) {
  1720        TclGetNamespaceForQualName(interp, cmdName, (Namespace *) NULL,
  1721            CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
  1722        if ((nsPtr == NULL) || (tail == NULL)) {
  1723 	    return (Tcl_Command) NULL;
  1724 	}
  1725     } else {
  1726 	nsPtr = iPtr->globalNsPtr;
  1727 	tail = cmdName;
  1728     }
  1729 
  1730     hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
  1731     if (!new) {
  1732 	cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
  1733 
  1734 	/*
  1735 	 * Command already exists. If its object-based Tcl_ObjCmdProc is
  1736 	 * TclInvokeStringCommand, we just set its Tcl_ObjCmdProc to the
  1737 	 * argument "proc". Otherwise, we delete the old command. 
  1738 	 */
  1739 
  1740 	if (cmdPtr->objProc == TclInvokeStringCommand) {
  1741 	    cmdPtr->objProc = proc;
  1742 	    cmdPtr->objClientData = clientData;
  1743             cmdPtr->deleteProc = deleteProc;
  1744             cmdPtr->deleteData = clientData;
  1745 	    return (Tcl_Command) cmdPtr;
  1746 	}
  1747 
  1748 	/*
  1749 	 * Otherwise, we delete the old command.  Be careful to preserve
  1750 	 * any existing import links so we can restore them down below.
  1751 	 * That way, you can redefine a command and its import status
  1752 	 * will remain intact.
  1753 	 */
  1754 
  1755 	oldRefPtr = cmdPtr->importRefPtr;
  1756 	cmdPtr->importRefPtr = NULL;
  1757 
  1758 	Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
  1759 	hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
  1760 	if (!new) {
  1761 	    /*
  1762 	     * If the deletion callback recreated the command, just throw
  1763 	     * away the new command (if we try to delete it again, we
  1764 	     * could get stuck in an infinite loop).
  1765 	     */
  1766 
  1767 	     ckfree((char *) Tcl_GetHashValue(hPtr));
  1768 	}
  1769     }
  1770     cmdPtr = (Command *) ckalloc(sizeof(Command));
  1771     Tcl_SetHashValue(hPtr, cmdPtr);
  1772     cmdPtr->hPtr = hPtr;
  1773     cmdPtr->nsPtr = nsPtr;
  1774     cmdPtr->refCount = 1;
  1775     cmdPtr->cmdEpoch = 0;
  1776     cmdPtr->compileProc = (CompileProc *) NULL;
  1777     cmdPtr->objProc = proc;
  1778     cmdPtr->objClientData = clientData;
  1779     cmdPtr->proc = TclInvokeObjectCommand;
  1780     cmdPtr->clientData = (ClientData) cmdPtr;
  1781     cmdPtr->deleteProc = deleteProc;
  1782     cmdPtr->deleteData = clientData;
  1783     cmdPtr->flags = 0;
  1784     cmdPtr->importRefPtr = NULL;
  1785     cmdPtr->tracePtr = NULL;
  1786 
  1787     /*
  1788      * Plug in any existing import references found above.  Be sure
  1789      * to update all of these references to point to the new command.
  1790      */
  1791 
  1792     if (oldRefPtr != NULL) {
  1793 	cmdPtr->importRefPtr = oldRefPtr;
  1794 	while (oldRefPtr != NULL) {
  1795 	    refCmdPtr = oldRefPtr->importedCmdPtr;
  1796 	    dataPtr = (ImportedCmdData*)refCmdPtr->objClientData;
  1797 	    dataPtr->realCmdPtr = cmdPtr;
  1798 	    oldRefPtr = oldRefPtr->nextPtr;
  1799 	}
  1800     }
  1801     
  1802     /*
  1803      * We just created a command, so in its namespace and all of its parent
  1804      * namespaces, it may shadow global commands with the same name. If any
  1805      * shadowed commands are found, invalidate all cached command references
  1806      * in the affected namespaces.
  1807      */
  1808     
  1809     TclResetShadowedCmdRefs(interp, cmdPtr);
  1810     return (Tcl_Command) cmdPtr;
  1811 }
  1812 
  1813 /*
  1814  *----------------------------------------------------------------------
  1815  *
  1816  * TclInvokeStringCommand --
  1817  *
  1818  *	"Wrapper" Tcl_ObjCmdProc used to call an existing string-based
  1819  *	Tcl_CmdProc if no object-based procedure exists for a command. A
  1820  *	pointer to this procedure is stored as the Tcl_ObjCmdProc in a
  1821  *	Command structure. It simply turns around and calls the string
  1822  *	Tcl_CmdProc in the Command structure.
  1823  *
  1824  * Results:
  1825  *	A standard Tcl object result value.
  1826  *
  1827  * Side effects:
  1828  *	Besides those side effects of the called Tcl_CmdProc,
  1829  *	TclInvokeStringCommand allocates and frees storage.
  1830  *
  1831  *----------------------------------------------------------------------
  1832  */
  1833 
  1834 int
  1835 TclInvokeStringCommand(clientData, interp, objc, objv)
  1836     ClientData clientData;	/* Points to command's Command structure. */
  1837     Tcl_Interp *interp;		/* Current interpreter. */
  1838     register int objc;		/* Number of arguments. */
  1839     Tcl_Obj *CONST objv[];	/* Argument objects. */
  1840 {
  1841     register Command *cmdPtr = (Command *) clientData;
  1842     register int i;
  1843     int result;
  1844 
  1845     /*
  1846      * This procedure generates an argv array for the string arguments. It
  1847      * starts out with stack-allocated space but uses dynamically-allocated
  1848      * storage if needed.
  1849      */
  1850 
  1851 #define NUM_ARGS 20
  1852     CONST char *(argStorage[NUM_ARGS]);
  1853     CONST char **argv = argStorage;
  1854 
  1855     /*
  1856      * Create the string argument array "argv". Make sure argv is large
  1857      * enough to hold the objc arguments plus 1 extra for the zero
  1858      * end-of-argv word.
  1859      */
  1860 
  1861     if ((objc + 1) > NUM_ARGS) {
  1862 	argv = (CONST char **) ckalloc((unsigned)(objc + 1) * sizeof(char *));
  1863     }
  1864 
  1865     for (i = 0;  i < objc;  i++) {
  1866 	argv[i] = Tcl_GetString(objv[i]);
  1867     }
  1868     argv[objc] = 0;
  1869 
  1870     /*
  1871      * Invoke the command's string-based Tcl_CmdProc.
  1872      */
  1873 
  1874     result = (*cmdPtr->proc)(cmdPtr->clientData, interp, objc, argv);
  1875 
  1876     /*
  1877      * Free the argv array if malloc'ed storage was used.
  1878      */
  1879 
  1880     if (argv != argStorage) {
  1881 	ckfree((char *) argv);
  1882     }
  1883     return result;
  1884 #undef NUM_ARGS
  1885 }
  1886 
  1887 /*
  1888  *----------------------------------------------------------------------
  1889  *
  1890  * TclInvokeObjectCommand --
  1891  *
  1892  *	"Wrapper" Tcl_CmdProc used to call an existing object-based
  1893  *	Tcl_ObjCmdProc if no string-based procedure exists for a command.
  1894  *	A pointer to this procedure is stored as the Tcl_CmdProc in a
  1895  *	Command structure. It simply turns around and calls the object
  1896  *	Tcl_ObjCmdProc in the Command structure.
  1897  *
  1898  * Results:
  1899  *	A standard Tcl string result value.
  1900  *
  1901  * Side effects:
  1902  *	Besides those side effects of the called Tcl_CmdProc,
  1903  *	TclInvokeStringCommand allocates and frees storage.
  1904  *
  1905  *----------------------------------------------------------------------
  1906  */
  1907 
  1908 int
  1909 TclInvokeObjectCommand(clientData, interp, argc, argv)
  1910     ClientData clientData;	/* Points to command's Command structure. */
  1911     Tcl_Interp *interp;		/* Current interpreter. */
  1912     int argc;			/* Number of arguments. */
  1913     register CONST char **argv;	/* Argument strings. */
  1914 {
  1915     Command *cmdPtr = (Command *) clientData;
  1916     register Tcl_Obj *objPtr;
  1917     register int i;
  1918     int length, result;
  1919 
  1920     /*
  1921      * This procedure generates an objv array for object arguments that hold
  1922      * the argv strings. It starts out with stack-allocated space but uses
  1923      * dynamically-allocated storage if needed.
  1924      */
  1925 
  1926 #define NUM_ARGS 20
  1927     Tcl_Obj *(argStorage[NUM_ARGS]);
  1928     register Tcl_Obj **objv = argStorage;
  1929 
  1930     /*
  1931      * Create the object argument array "objv". Make sure objv is large
  1932      * enough to hold the objc arguments plus 1 extra for the zero
  1933      * end-of-objv word.
  1934      */
  1935 
  1936     if (argc > NUM_ARGS) {
  1937 	objv = (Tcl_Obj **)
  1938 	    ckalloc((unsigned)(argc * sizeof(Tcl_Obj *)));
  1939     }
  1940 
  1941     for (i = 0;  i < argc;  i++) {
  1942 	length = strlen(argv[i]);
  1943 	TclNewObj(objPtr);
  1944 	TclInitStringRep(objPtr, argv[i], length);
  1945 	Tcl_IncrRefCount(objPtr);
  1946 	objv[i] = objPtr;
  1947     }
  1948 
  1949     /*
  1950      * Invoke the command's object-based Tcl_ObjCmdProc.
  1951      */
  1952 
  1953     result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, argc, objv);
  1954 
  1955     /*
  1956      * Move the interpreter's object result to the string result, 
  1957      * then reset the object result.
  1958      */
  1959 
  1960     Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
  1961 	    TCL_VOLATILE);
  1962     
  1963     /*
  1964      * Decrement the ref counts for the argument objects created above,
  1965      * then free the objv array if malloc'ed storage was used.
  1966      */
  1967 
  1968     for (i = 0;  i < argc;  i++) {
  1969 	objPtr = objv[i];
  1970 	Tcl_DecrRefCount(objPtr);
  1971     }
  1972     if (objv != argStorage) {
  1973 	ckfree((char *) objv);
  1974     }
  1975     return result;
  1976 #undef NUM_ARGS
  1977 }
  1978 
  1979 /*
  1980  *----------------------------------------------------------------------
  1981  *
  1982  * TclRenameCommand --
  1983  *
  1984  *      Called to give an existing Tcl command a different name. Both the
  1985  *      old command name and the new command name can have "::" namespace
  1986  *      qualifiers. If the new command has a different namespace context,
  1987  *      the command will be moved to that namespace and will execute in
  1988  *	the context of that new namespace.
  1989  *
  1990  *      If the new command name is NULL or the null string, the command is
  1991  *      deleted.
  1992  *
  1993  * Results:
  1994  *      Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
  1995  *
  1996  * Side effects:
  1997  *      If anything goes wrong, an error message is returned in the
  1998  *      interpreter's result object.
  1999  *
  2000  *----------------------------------------------------------------------
  2001  */
  2002 
  2003 int
  2004 TclRenameCommand(interp, oldName, newName)
  2005     Tcl_Interp *interp;                 /* Current interpreter. */
  2006     char *oldName;                      /* Existing command name. */
  2007     char *newName;                      /* New command name. */
  2008 {
  2009     Interp *iPtr = (Interp *) interp;
  2010     CONST char *newTail;
  2011     Namespace *cmdNsPtr, *newNsPtr, *dummy1, *dummy2;
  2012     Tcl_Command cmd;
  2013     Command *cmdPtr;
  2014     Tcl_HashEntry *hPtr, *oldHPtr;
  2015     int new, result;
  2016     Tcl_Obj* oldFullName;
  2017     Tcl_DString newFullName;
  2018 
  2019     /*
  2020      * Find the existing command. An error is returned if cmdName can't
  2021      * be found.
  2022      */
  2023 
  2024     cmd = Tcl_FindCommand(interp, oldName, (Tcl_Namespace *) NULL,
  2025 	/*flags*/ 0);
  2026     cmdPtr = (Command *) cmd;
  2027     if (cmdPtr == NULL) {
  2028 	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "can't ",
  2029                 ((newName == NULL)||(*newName == '\0'))? "delete":"rename",
  2030                 " \"", oldName, "\": command doesn't exist", (char *) NULL);
  2031 	return TCL_ERROR;
  2032     }
  2033     cmdNsPtr = cmdPtr->nsPtr;
  2034     oldFullName = Tcl_NewObj();
  2035     Tcl_IncrRefCount( oldFullName );
  2036     Tcl_GetCommandFullName( interp, cmd, oldFullName );
  2037 
  2038     /*
  2039      * If the new command name is NULL or empty, delete the command. Do this
  2040      * with Tcl_DeleteCommandFromToken, since we already have the command.
  2041      */
  2042     
  2043     if ((newName == NULL) || (*newName == '\0')) {
  2044 	Tcl_DeleteCommandFromToken(interp, cmd);
  2045 	result = TCL_OK;
  2046 	goto done;
  2047     }
  2048 
  2049     /*
  2050      * Make sure that the destination command does not already exist.
  2051      * The rename operation is like creating a command, so we should
  2052      * automatically create the containing namespaces just like
  2053      * Tcl_CreateCommand would.
  2054      */
  2055 
  2056     TclGetNamespaceForQualName(interp, newName, (Namespace *) NULL,
  2057        CREATE_NS_IF_UNKNOWN, &newNsPtr, &dummy1, &dummy2, &newTail);
  2058 
  2059     if ((newNsPtr == NULL) || (newTail == NULL)) {
  2060 	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  2061 		 "can't rename to \"", newName, "\": bad command name",
  2062     	    	 (char *) NULL);
  2063 	result = TCL_ERROR;
  2064 	goto done;
  2065     }
  2066     if (Tcl_FindHashEntry(&newNsPtr->cmdTable, newTail) != NULL) {
  2067 	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  2068 		 "can't rename to \"", newName,
  2069 		 "\": command already exists", (char *) NULL);
  2070 	result = TCL_ERROR;
  2071 	goto done;
  2072     }
  2073 
  2074     /*
  2075      * Warning: any changes done in the code here are likely
  2076      * to be needed in Tcl_HideCommand() code too.
  2077      * (until the common parts are extracted out)     --dl
  2078      */
  2079 
  2080     /*
  2081      * Put the command in the new namespace so we can check for an alias
  2082      * loop. Since we are adding a new command to a namespace, we must
  2083      * handle any shadowing of the global commands that this might create.
  2084      */
  2085     
  2086     oldHPtr = cmdPtr->hPtr;
  2087     hPtr = Tcl_CreateHashEntry(&newNsPtr->cmdTable, newTail, &new);
  2088     Tcl_SetHashValue(hPtr, (ClientData) cmdPtr);
  2089     cmdPtr->hPtr = hPtr;
  2090     cmdPtr->nsPtr = newNsPtr;
  2091     TclResetShadowedCmdRefs(interp, cmdPtr);
  2092 
  2093     /*
  2094      * Now check for an alias loop. If we detect one, put everything back
  2095      * the way it was and report the error.
  2096      */
  2097 
  2098     result = TclPreventAliasLoop(interp, interp, (Tcl_Command) cmdPtr);
  2099     if (result != TCL_OK) {
  2100         Tcl_DeleteHashEntry(cmdPtr->hPtr);
  2101         cmdPtr->hPtr = oldHPtr;
  2102         cmdPtr->nsPtr = cmdNsPtr;
  2103 	goto done;
  2104     }
  2105 
  2106     /*
  2107      * Script for rename traces can delete the command "oldName".
  2108      * Therefore increment the reference count for cmdPtr so that
  2109      * it's Command structure is freed only towards the end of this
  2110      * function by calling TclCleanupCommand.
  2111      *
  2112      * The trace procedure needs to get a fully qualified name for
  2113      * old and new commands [Tcl bug #651271], or else there's no way
  2114      * for the trace procedure to get the namespace from which the old
  2115      * command is being renamed!
  2116      */
  2117 
  2118     Tcl_DStringInit( &newFullName );
  2119     Tcl_DStringAppend( &newFullName, newNsPtr->fullName, -1 );
  2120     if ( newNsPtr != iPtr->globalNsPtr ) {
  2121 	Tcl_DStringAppend( &newFullName, "::", 2 );
  2122     }
  2123     Tcl_DStringAppend( &newFullName, newTail, -1 );
  2124     cmdPtr->refCount++;
  2125     CallCommandTraces( iPtr, cmdPtr,
  2126 		       Tcl_GetString( oldFullName ),
  2127 		       Tcl_DStringValue( &newFullName ),
  2128 		       TCL_TRACE_RENAME);
  2129     Tcl_DStringFree( &newFullName );
  2130 
  2131     /*
  2132      * The new command name is okay, so remove the command from its
  2133      * current namespace. This is like deleting the command, so bump
  2134      * the cmdEpoch to invalidate any cached references to the command.
  2135      */
  2136     
  2137     Tcl_DeleteHashEntry(oldHPtr);
  2138     cmdPtr->cmdEpoch++;
  2139 
  2140     /*
  2141      * If the command being renamed has a compile procedure, increment the
  2142      * interpreter's compileEpoch to invalidate its compiled code. This
  2143      * makes sure that we don't later try to execute old code compiled for
  2144      * the now-renamed command.
  2145      */
  2146 
  2147     if (cmdPtr->compileProc != NULL) {
  2148 	iPtr->compileEpoch++;
  2149     }
  2150 
  2151     /*
  2152      * Now free the Command structure, if the "oldName" command has
  2153      * been deleted by invocation of rename traces.
  2154      */
  2155     TclCleanupCommand(cmdPtr);
  2156     result = TCL_OK;
  2157 
  2158     done:
  2159     TclDecrRefCount( oldFullName );
  2160     return result;
  2161 }
  2162 
  2163 /*
  2164  *----------------------------------------------------------------------
  2165  *
  2166  * Tcl_SetCommandInfo --
  2167  *
  2168  *	Modifies various information about a Tcl command. Note that
  2169  *	this procedure will not change a command's namespace; use
  2170  *	Tcl_RenameCommand to do that. Also, the isNativeObjectProc
  2171  *	member of *infoPtr is ignored.
  2172  *
  2173  * Results:
  2174  *	If cmdName exists in interp, then the information at *infoPtr
  2175  *	is stored with the command in place of the current information
  2176  *	and 1 is returned. If the command doesn't exist then 0 is
  2177  *	returned. 
  2178  *
  2179  * Side effects:
  2180  *	None.
  2181  *
  2182  *----------------------------------------------------------------------
  2183  */
  2184 
  2185 EXPORT_C int
  2186 Tcl_SetCommandInfo(interp, cmdName, infoPtr)
  2187     Tcl_Interp *interp;			/* Interpreter in which to look
  2188 					 * for command. */
  2189     CONST char *cmdName;		/* Name of desired command. */
  2190     CONST Tcl_CmdInfo *infoPtr;		/* Where to find information
  2191 					 * to store in the command. */
  2192 {
  2193     Tcl_Command cmd;
  2194 
  2195     cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
  2196             /*flags*/ 0);
  2197 
  2198     return Tcl_SetCommandInfoFromToken( cmd, infoPtr );
  2199 
  2200 }
  2201 
  2202 /*
  2203  *----------------------------------------------------------------------
  2204  *
  2205  * Tcl_SetCommandInfoFromToken --
  2206  *
  2207  *	Modifies various information about a Tcl command. Note that
  2208  *	this procedure will not change a command's namespace; use
  2209  *	Tcl_RenameCommand to do that. Also, the isNativeObjectProc
  2210  *	member of *infoPtr is ignored.
  2211  *
  2212  * Results:
  2213  *	If cmdName exists in interp, then the information at *infoPtr
  2214  *	is stored with the command in place of the current information
  2215  *	and 1 is returned. If the command doesn't exist then 0 is
  2216  *	returned. 
  2217  *
  2218  * Side effects:
  2219  *	None.
  2220  *
  2221  *----------------------------------------------------------------------
  2222  */
  2223 
  2224 EXPORT_C int
  2225 Tcl_SetCommandInfoFromToken( cmd, infoPtr )
  2226     Tcl_Command cmd;
  2227     CONST Tcl_CmdInfo* infoPtr;
  2228 {
  2229     Command* cmdPtr;		/* Internal representation of the command */
  2230 
  2231     if (cmd == (Tcl_Command) NULL) {
  2232 	return 0;
  2233     }
  2234 
  2235     /*
  2236      * The isNativeObjectProc and nsPtr members of *infoPtr are ignored.
  2237      */
  2238     
  2239     cmdPtr = (Command *) cmd;
  2240     cmdPtr->proc = infoPtr->proc;
  2241     cmdPtr->clientData = infoPtr->clientData;
  2242     if (infoPtr->objProc == (Tcl_ObjCmdProc *) NULL) {
  2243 	cmdPtr->objProc = TclInvokeStringCommand;
  2244 	cmdPtr->objClientData = (ClientData) cmdPtr;
  2245     } else {
  2246 	cmdPtr->objProc = infoPtr->objProc;
  2247 	cmdPtr->objClientData = infoPtr->objClientData;
  2248     }
  2249     cmdPtr->deleteProc = infoPtr->deleteProc;
  2250     cmdPtr->deleteData = infoPtr->deleteData;
  2251     return 1;
  2252 }
  2253 
  2254 /*
  2255  *----------------------------------------------------------------------
  2256  *
  2257  * Tcl_GetCommandInfo --
  2258  *
  2259  *	Returns various information about a Tcl command.
  2260  *
  2261  * Results:
  2262  *	If cmdName exists in interp, then *infoPtr is modified to
  2263  *	hold information about cmdName and 1 is returned.  If the
  2264  *	command doesn't exist then 0 is returned and *infoPtr isn't
  2265  *	modified.
  2266  *
  2267  * Side effects:
  2268  *	None.
  2269  *
  2270  *----------------------------------------------------------------------
  2271  */
  2272 
  2273 EXPORT_C int
  2274 Tcl_GetCommandInfo(interp, cmdName, infoPtr)
  2275     Tcl_Interp *interp;			/* Interpreter in which to look
  2276 					 * for command. */
  2277     CONST char *cmdName;		/* Name of desired command. */
  2278     Tcl_CmdInfo *infoPtr;		/* Where to store information about
  2279 					 * command. */
  2280 {
  2281     Tcl_Command cmd;
  2282 
  2283     cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
  2284             /*flags*/ 0);
  2285 
  2286     return Tcl_GetCommandInfoFromToken( cmd, infoPtr );
  2287 
  2288 }
  2289 
  2290 /*
  2291  *----------------------------------------------------------------------
  2292  *
  2293  * Tcl_GetCommandInfoFromToken --
  2294  *
  2295  *	Returns various information about a Tcl command.
  2296  *
  2297  * Results:
  2298  *	Copies information from the command identified by 'cmd' into
  2299  *	a caller-supplied structure and returns 1.  If the 'cmd' is
  2300  *	NULL, leaves the structure untouched and returns 0.
  2301  *
  2302  * Side effects:
  2303  *	None.
  2304  *
  2305  *----------------------------------------------------------------------
  2306  */
  2307 
  2308 EXPORT_C int
  2309 Tcl_GetCommandInfoFromToken( cmd, infoPtr )
  2310     Tcl_Command cmd;
  2311     Tcl_CmdInfo* infoPtr;
  2312 {
  2313 
  2314     Command* cmdPtr;		/* Internal representation of the command */
  2315 
  2316     if ( cmd == (Tcl_Command) NULL ) {
  2317 	return 0;
  2318     }
  2319 
  2320     /*
  2321      * Set isNativeObjectProc 1 if objProc was registered by a call to
  2322      * Tcl_CreateObjCommand. Otherwise set it to 0.
  2323      */
  2324 
  2325     cmdPtr = (Command *) cmd;
  2326     infoPtr->isNativeObjectProc =
  2327 	    (cmdPtr->objProc != TclInvokeStringCommand);
  2328     infoPtr->objProc = cmdPtr->objProc;
  2329     infoPtr->objClientData = cmdPtr->objClientData;
  2330     infoPtr->proc = cmdPtr->proc;
  2331     infoPtr->clientData = cmdPtr->clientData;
  2332     infoPtr->deleteProc = cmdPtr->deleteProc;
  2333     infoPtr->deleteData = cmdPtr->deleteData;
  2334     infoPtr->namespacePtr = (Tcl_Namespace *) cmdPtr->nsPtr;
  2335 
  2336     return 1;
  2337 
  2338 }
  2339 
  2340 /*
  2341  *----------------------------------------------------------------------
  2342  *
  2343  * Tcl_GetCommandName --
  2344  *
  2345  *	Given a token returned by Tcl_CreateCommand, this procedure
  2346  *	returns the current name of the command (which may have changed
  2347  *	due to renaming).
  2348  *
  2349  * Results:
  2350  *	The return value is the name of the given command.
  2351  *
  2352  * Side effects:
  2353  *	None.
  2354  *
  2355  *----------------------------------------------------------------------
  2356  */
  2357 
  2358 EXPORT_C CONST char *
  2359 Tcl_GetCommandName(interp, command)
  2360     Tcl_Interp *interp;		/* Interpreter containing the command. */
  2361     Tcl_Command command;	/* Token for command returned by a previous
  2362 				 * call to Tcl_CreateCommand. The command
  2363 				 * must not have been deleted. */
  2364 {
  2365     Command *cmdPtr = (Command *) command;
  2366 
  2367     if ((cmdPtr == NULL) || (cmdPtr->hPtr == NULL)) {
  2368 
  2369 	/*
  2370 	 * This should only happen if command was "created" after the
  2371 	 * interpreter began to be deleted, so there isn't really any
  2372 	 * command. Just return an empty string.
  2373 	 */
  2374 
  2375 	return "";
  2376     }
  2377     return Tcl_GetHashKey(cmdPtr->hPtr->tablePtr, cmdPtr->hPtr);
  2378 }
  2379 
  2380 /*
  2381  *----------------------------------------------------------------------
  2382  *
  2383  * Tcl_GetCommandFullName --
  2384  *
  2385  *	Given a token returned by, e.g., Tcl_CreateCommand or
  2386  *	Tcl_FindCommand, this procedure appends to an object the command's
  2387  *	full name, qualified by a sequence of parent namespace names. The
  2388  *	command's fully-qualified name may have changed due to renaming.
  2389  *
  2390  * Results:
  2391  *	None.
  2392  *
  2393  * Side effects:
  2394  *	The command's fully-qualified name is appended to the string
  2395  *	representation of objPtr. 
  2396  *
  2397  *----------------------------------------------------------------------
  2398  */
  2399 
  2400 void
  2401 Tcl_GetCommandFullName(interp, command, objPtr)
  2402     Tcl_Interp *interp;		/* Interpreter containing the command. */
  2403     Tcl_Command command;	/* Token for command returned by a previous
  2404 				 * call to Tcl_CreateCommand. The command
  2405 				 * must not have been deleted. */
  2406     Tcl_Obj *objPtr;		/* Points to the object onto which the
  2407 				 * command's full name is appended. */
  2408 
  2409 {
  2410     Interp *iPtr = (Interp *) interp;
  2411     register Command *cmdPtr = (Command *) command;
  2412     char *name;
  2413 
  2414     /*
  2415      * Add the full name of the containing namespace, followed by the "::"
  2416      * separator, and the command name.
  2417      */
  2418 
  2419     if (cmdPtr != NULL) {
  2420 	if (cmdPtr->nsPtr != NULL) {
  2421 	    Tcl_AppendToObj(objPtr, cmdPtr->nsPtr->fullName, -1);
  2422 	    if (cmdPtr->nsPtr != iPtr->globalNsPtr) {
  2423 		Tcl_AppendToObj(objPtr, "::", 2);
  2424 	    }
  2425 	}
  2426 	if (cmdPtr->hPtr != NULL) {
  2427 	    name = Tcl_GetHashKey(cmdPtr->hPtr->tablePtr, cmdPtr->hPtr);
  2428 	    Tcl_AppendToObj(objPtr, name, -1);
  2429 	} 
  2430     }
  2431 }
  2432 
  2433 /*
  2434  *----------------------------------------------------------------------
  2435  *
  2436  * Tcl_DeleteCommand --
  2437  *
  2438  *	Remove the given command from the given interpreter.
  2439  *
  2440  * Results:
  2441  *	0 is returned if the command was deleted successfully.
  2442  *	-1 is returned if there didn't exist a command by that name.
  2443  *
  2444  * Side effects:
  2445  *	cmdName will no longer be recognized as a valid command for
  2446  *	interp.
  2447  *
  2448  *----------------------------------------------------------------------
  2449  */
  2450 
  2451 EXPORT_C int
  2452 Tcl_DeleteCommand(interp, cmdName)
  2453     Tcl_Interp *interp;		/* Token for command interpreter (returned
  2454 				 * by a previous Tcl_CreateInterp call). */
  2455     CONST char *cmdName;	/* Name of command to remove. */
  2456 {
  2457     Tcl_Command cmd;
  2458 
  2459     /*
  2460      *  Find the desired command and delete it.
  2461      */
  2462 
  2463     cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
  2464             /*flags*/ 0);
  2465     if (cmd == (Tcl_Command) NULL) {
  2466 	return -1;
  2467     }
  2468     return Tcl_DeleteCommandFromToken(interp, cmd);
  2469 }
  2470 
  2471 /*
  2472  *----------------------------------------------------------------------
  2473  *
  2474  * Tcl_DeleteCommandFromToken --
  2475  *
  2476  *	Removes the given command from the given interpreter. This procedure
  2477  *	resembles Tcl_DeleteCommand, but takes a Tcl_Command token instead
  2478  *	of a command name for efficiency.
  2479  *
  2480  * Results:
  2481  *	0 is returned if the command was deleted successfully.
  2482  *	-1 is returned if there didn't exist a command by that name.
  2483  *
  2484  * Side effects:
  2485  *	The command specified by "cmd" will no longer be recognized as a
  2486  *	valid command for "interp".
  2487  *
  2488  *----------------------------------------------------------------------
  2489  */
  2490 
  2491 EXPORT_C int
  2492 Tcl_DeleteCommandFromToken(interp, cmd)
  2493     Tcl_Interp *interp;		/* Token for command interpreter returned by
  2494 				 * a previous call to Tcl_CreateInterp. */
  2495     Tcl_Command cmd;            /* Token for command to delete. */
  2496 {
  2497     Interp *iPtr = (Interp *) interp;
  2498     Command *cmdPtr = (Command *) cmd;
  2499     ImportRef *refPtr, *nextRefPtr;
  2500     Tcl_Command importCmd;
  2501 
  2502     /*
  2503      * The code here is tricky.  We can't delete the hash table entry
  2504      * before invoking the deletion callback because there are cases
  2505      * where the deletion callback needs to invoke the command (e.g.
  2506      * object systems such as OTcl). However, this means that the
  2507      * callback could try to delete or rename the command. The deleted
  2508      * flag allows us to detect these cases and skip nested deletes.
  2509      */
  2510 
  2511     if (cmdPtr->flags & CMD_IS_DELETED) {
  2512 	/*
  2513 	 * Another deletion is already in progress.  Remove the hash
  2514 	 * table entry now, but don't invoke a callback or free the
  2515 	 * command structure.
  2516 	 */
  2517 
  2518         Tcl_DeleteHashEntry(cmdPtr->hPtr);
  2519 	cmdPtr->hPtr = NULL;
  2520 	return 0;
  2521     }
  2522 
  2523     /* 
  2524      * We must delete this command, even though both traces and
  2525      * delete procs may try to avoid this (renaming the command etc).
  2526      * Also traces and delete procs may try to delete the command
  2527      * themsevles.  This flag declares that a delete is in progress
  2528      * and that recursive deletes should be ignored.
  2529      */
  2530     cmdPtr->flags |= CMD_IS_DELETED;
  2531 
  2532     /*
  2533      * Bump the command epoch counter. This will invalidate all cached
  2534      * references that point to this command.
  2535      */
  2536     
  2537     cmdPtr->cmdEpoch++;
  2538 
  2539     /*
  2540      * Call trace procedures for the command being deleted. Then delete
  2541      * its traces. 
  2542      */
  2543 
  2544     if (cmdPtr->tracePtr != NULL) {
  2545 	CommandTrace *tracePtr;
  2546 	CallCommandTraces(iPtr,cmdPtr,NULL,NULL,TCL_TRACE_DELETE);
  2547 	/* Now delete these traces */
  2548 	tracePtr = cmdPtr->tracePtr;
  2549 	while (tracePtr != NULL) {
  2550 	    CommandTrace *nextPtr = tracePtr->nextPtr;
  2551 	    if ((--tracePtr->refCount) <= 0) {
  2552 		ckfree((char*)tracePtr);
  2553 	    }
  2554 	    tracePtr = nextPtr;
  2555 	}
  2556 	cmdPtr->tracePtr = NULL;
  2557     }
  2558     
  2559     /*
  2560      * If the command being deleted has a compile procedure, increment the
  2561      * interpreter's compileEpoch to invalidate its compiled code. This
  2562      * makes sure that we don't later try to execute old code compiled with
  2563      * command-specific (i.e., inline) bytecodes for the now-deleted
  2564      * command. This field is checked in Tcl_EvalObj and ObjInterpProc, and
  2565      * code whose compilation epoch doesn't match is recompiled.
  2566      */
  2567 
  2568     if (cmdPtr->compileProc != NULL) {
  2569         iPtr->compileEpoch++;
  2570     }
  2571 
  2572     if (cmdPtr->deleteProc != NULL) {
  2573 	/*
  2574 	 * Delete the command's client data. If this was an imported command
  2575 	 * created when a command was imported into a namespace, this client
  2576 	 * data will be a pointer to a ImportedCmdData structure describing
  2577 	 * the "real" command that this imported command refers to.
  2578 	 */
  2579 	
  2580 	/*
  2581 	 * If you are getting a crash during the call to deleteProc and
  2582 	 * cmdPtr->deleteProc is a pointer to the function free(), the
  2583 	 * most likely cause is that your extension allocated memory
  2584 	 * for the clientData argument to Tcl_CreateObjCommand() with
  2585 	 * the ckalloc() macro and you are now trying to deallocate
  2586 	 * this memory with free() instead of ckfree(). You should
  2587 	 * pass a pointer to your own method that calls ckfree().
  2588 	 */
  2589 
  2590 	(*cmdPtr->deleteProc)(cmdPtr->deleteData);
  2591     }
  2592 
  2593     /*
  2594      * If this command was imported into other namespaces, then imported
  2595      * commands were created that refer back to this command. Delete these
  2596      * imported commands now.
  2597      */
  2598 
  2599     for (refPtr = cmdPtr->importRefPtr;  refPtr != NULL;
  2600             refPtr = nextRefPtr) {
  2601 	nextRefPtr = refPtr->nextPtr;
  2602 	importCmd = (Tcl_Command) refPtr->importedCmdPtr;
  2603         Tcl_DeleteCommandFromToken(interp, importCmd);
  2604     }
  2605 
  2606     /*
  2607      * Don't use hPtr to delete the hash entry here, because it's
  2608      * possible that the deletion callback renamed the command.
  2609      * Instead, use cmdPtr->hptr, and make sure that no-one else
  2610      * has already deleted the hash entry.
  2611      */
  2612 
  2613     if (cmdPtr->hPtr != NULL) {
  2614 	Tcl_DeleteHashEntry(cmdPtr->hPtr);
  2615     }
  2616 
  2617     /*
  2618      * Mark the Command structure as no longer valid. This allows
  2619      * TclExecuteByteCode to recognize when a Command has logically been
  2620      * deleted and a pointer to this Command structure cached in a CmdName
  2621      * object is invalid. TclExecuteByteCode will look up the command again
  2622      * in the interpreter's command hashtable.
  2623      */
  2624 
  2625     cmdPtr->objProc = NULL;
  2626 
  2627     /*
  2628      * Now free the Command structure, unless there is another reference to
  2629      * it from a CmdName Tcl object in some ByteCode code sequence. In that
  2630      * case, delay the cleanup until all references are either discarded
  2631      * (when a ByteCode is freed) or replaced by a new reference (when a
  2632      * cached CmdName Command reference is found to be invalid and
  2633      * TclExecuteByteCode looks up the command in the command hashtable).
  2634      */
  2635     
  2636     TclCleanupCommand(cmdPtr);
  2637     return 0;
  2638 }
  2639 
  2640 static char *
  2641 CallCommandTraces(iPtr, cmdPtr, oldName, newName, flags)
  2642     Interp *iPtr;		/* Interpreter containing command. */
  2643     Command *cmdPtr;		/* Command whose traces are to be
  2644 				 * invoked. */
  2645     CONST char *oldName;        /* Command's old name, or NULL if we
  2646                                  * must get the name from cmdPtr */
  2647     CONST char *newName;        /* Command's new name, or NULL if
  2648                                  * the command is not being renamed */
  2649     int flags;			/* Flags indicating the type of traces
  2650 				 * to trigger, either TCL_TRACE_DELETE
  2651 				 * or TCL_TRACE_RENAME. */
  2652 {
  2653     register CommandTrace *tracePtr;
  2654     ActiveCommandTrace active;
  2655     char *result;
  2656     Tcl_Obj *oldNamePtr = NULL;
  2657     int mask = (TCL_TRACE_DELETE | TCL_TRACE_RENAME);	/* Safety */
  2658 
  2659     flags &= mask;
  2660 
  2661     if (cmdPtr->flags & CMD_TRACE_ACTIVE) {
  2662 	/* 
  2663 	 * While a rename trace is active, we will not process any more
  2664 	 * rename traces; while a delete trace is active we will never
  2665 	 * reach here -- because Tcl_DeleteCommandFromToken checks for the
  2666 	 * condition (cmdPtr->flags & CMD_IS_DELETED) and returns immediately
  2667 	 * when a command deletion is in progress.  For all other traces,
  2668 	 * delete traces will not be invoked but a call to TraceCommandProc
  2669 	 * will ensure that tracePtr->clientData is freed whenever the
  2670 	 * command "oldName" is deleted.
  2671 	 */
  2672 	if (cmdPtr->flags & TCL_TRACE_RENAME) {
  2673 	    flags &= ~TCL_TRACE_RENAME;
  2674 	}
  2675 	if (flags == 0) {
  2676 	    return NULL;
  2677 	}
  2678     }
  2679     cmdPtr->flags |= CMD_TRACE_ACTIVE;
  2680     cmdPtr->refCount++;
  2681     
  2682     result = NULL;
  2683     active.nextPtr = iPtr->activeCmdTracePtr;
  2684     active.reverseScan = 0;
  2685     iPtr->activeCmdTracePtr = &active;
  2686 
  2687     if (flags & TCL_TRACE_DELETE) {
  2688 	flags |= TCL_TRACE_DESTROYED;
  2689     }
  2690     active.cmdPtr = cmdPtr;
  2691     
  2692     Tcl_Preserve((ClientData) iPtr);
  2693     
  2694     for (tracePtr = cmdPtr->tracePtr; tracePtr != NULL;
  2695 	 tracePtr = active.nextTracePtr) {
  2696 	int traceFlags = (tracePtr->flags & mask);
  2697 
  2698 	active.nextTracePtr = tracePtr->nextPtr;
  2699 	if (!(traceFlags & flags)) {
  2700 	    continue;
  2701 	}
  2702 	cmdPtr->flags |= traceFlags;
  2703 	if (oldName == NULL) {
  2704 	    TclNewObj(oldNamePtr);
  2705 	    Tcl_IncrRefCount(oldNamePtr);
  2706 	    Tcl_GetCommandFullName((Tcl_Interp *) iPtr, 
  2707 	            (Tcl_Command) cmdPtr, oldNamePtr);
  2708 	    oldName = TclGetString(oldNamePtr);
  2709 	}
  2710 	tracePtr->refCount++;
  2711 	(*tracePtr->traceProc)(tracePtr->clientData,
  2712 		(Tcl_Interp *) iPtr, oldName, newName, flags);
  2713 	cmdPtr->flags &= ~traceFlags;
  2714 	if ((--tracePtr->refCount) <= 0) {
  2715 	    ckfree((char*)tracePtr);
  2716 	}
  2717     }
  2718 
  2719     /*
  2720      * If a new object was created to hold the full oldName,
  2721      * free it now.
  2722      */
  2723 
  2724     if (oldNamePtr != NULL) {
  2725 	TclDecrRefCount(oldNamePtr);
  2726     }
  2727 
  2728     /*
  2729      * Restore the variable's flags, remove the record of our active
  2730      * traces, and then return.
  2731      */
  2732 
  2733     cmdPtr->flags &= ~CMD_TRACE_ACTIVE;
  2734     cmdPtr->refCount--;
  2735     iPtr->activeCmdTracePtr = active.nextPtr;
  2736     Tcl_Release((ClientData) iPtr);
  2737     return result;
  2738 }
  2739 
  2740 /*
  2741  *----------------------------------------------------------------------
  2742  *
  2743  * TclCleanupCommand --
  2744  *
  2745  *	This procedure frees up a Command structure unless it is still
  2746  *	referenced from an interpreter's command hashtable or from a CmdName
  2747  *	Tcl object representing the name of a command in a ByteCode
  2748  *	instruction sequence. 
  2749  *
  2750  * Results:
  2751  *	None.
  2752  *
  2753  * Side effects:
  2754  *	Memory gets freed unless a reference to the Command structure still
  2755  *	exists. In that case the cleanup is delayed until the command is
  2756  *	deleted or when the last ByteCode referring to it is freed.
  2757  *
  2758  *----------------------------------------------------------------------
  2759  */
  2760 
  2761 void
  2762 TclCleanupCommand(cmdPtr)
  2763     register Command *cmdPtr;	/* Points to the Command structure to
  2764 				 * be freed. */
  2765 {
  2766     cmdPtr->refCount--;
  2767     if (cmdPtr->refCount <= 0) {
  2768 	ckfree((char *) cmdPtr);
  2769     }
  2770 }
  2771 
  2772 /*
  2773  *----------------------------------------------------------------------
  2774  *
  2775  * Tcl_CreateMathFunc --
  2776  *
  2777  *	Creates a new math function for expressions in a given
  2778  *	interpreter.
  2779  *
  2780  * Results:
  2781  *	None.
  2782  *
  2783  * Side effects:
  2784  *	The function defined by "name" is created or redefined. If the
  2785  *	function already exists then its definition is replaced; this
  2786  *	includes the builtin functions. Redefining a builtin function forces
  2787  *	all existing code to be invalidated since that code may be compiled
  2788  *	using an instruction specific to the replaced function. In addition,
  2789  *	redefioning a non-builtin function will force existing code to be
  2790  *	invalidated if the number of arguments has changed.
  2791  *
  2792  *----------------------------------------------------------------------
  2793  */
  2794 
  2795 EXPORT_C void
  2796 Tcl_CreateMathFunc(interp, name, numArgs, argTypes, proc, clientData)
  2797     Tcl_Interp *interp;			/* Interpreter in which function is
  2798 					 * to be available. */
  2799     CONST char *name;			/* Name of function (e.g. "sin"). */
  2800     int numArgs;			/* Nnumber of arguments required by
  2801 					 * function. */
  2802     Tcl_ValueType *argTypes;		/* Array of types acceptable for
  2803 					 * each argument. */
  2804     Tcl_MathProc *proc;			/* Procedure that implements the
  2805 					 * math function. */
  2806     ClientData clientData;		/* Additional value to pass to the
  2807 					 * function. */
  2808 {
  2809     Interp *iPtr = (Interp *) interp;
  2810     Tcl_HashEntry *hPtr;
  2811     MathFunc *mathFuncPtr;
  2812     int new, i;
  2813 
  2814     hPtr = Tcl_CreateHashEntry(&iPtr->mathFuncTable, name, &new);
  2815     if (new) {
  2816 	Tcl_SetHashValue(hPtr, ckalloc(sizeof(MathFunc)));
  2817     }
  2818     mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);
  2819 
  2820     if (!new) {	
  2821 	if (mathFuncPtr->builtinFuncIndex >= 0) {
  2822 	    /*
  2823 	     * We are redefining a builtin math function. Invalidate the
  2824              * interpreter's existing code by incrementing its
  2825              * compileEpoch member. This field is checked in Tcl_EvalObj
  2826              * and ObjInterpProc, and code whose compilation epoch doesn't
  2827              * match is recompiled. Newly compiled code will no longer
  2828              * treat the function as builtin.
  2829 	     */
  2830 
  2831 	    iPtr->compileEpoch++;
  2832 	} else {
  2833 	    /*
  2834 	     * A non-builtin function is being redefined. We must invalidate
  2835              * existing code if the number of arguments has changed. This
  2836 	     * is because existing code was compiled assuming that number.
  2837 	     */
  2838 
  2839 	    if (numArgs != mathFuncPtr->numArgs) {
  2840 		iPtr->compileEpoch++;
  2841 	    }
  2842 	}
  2843     }
  2844     
  2845     mathFuncPtr->builtinFuncIndex = -1;	/* can't be a builtin function */
  2846     if (numArgs > MAX_MATH_ARGS) {
  2847 	numArgs = MAX_MATH_ARGS;
  2848     }
  2849     mathFuncPtr->numArgs = numArgs;
  2850     for (i = 0;  i < numArgs;  i++) {
  2851 	mathFuncPtr->argTypes[i] = argTypes[i];
  2852     }
  2853     mathFuncPtr->proc = proc;
  2854     mathFuncPtr->clientData = clientData;
  2855 }
  2856 
  2857 /*
  2858  *----------------------------------------------------------------------
  2859  *
  2860  * Tcl_GetMathFuncInfo --
  2861  *
  2862  *	Discovers how a particular math function was created in a given
  2863  *	interpreter.
  2864  *
  2865  * Results:
  2866  *	TCL_OK if it succeeds, TCL_ERROR else (leaving an error message
  2867  *	in the interpreter result if that happens.)
  2868  *
  2869  * Side effects:
  2870  *	If this function succeeds, the variables pointed to by the
  2871  *	numArgsPtr and argTypePtr arguments will be updated to detail the
  2872  *	arguments allowed by the function.  The variable pointed to by the
  2873  *	procPtr argument will be set to NULL if the function is a builtin
  2874  *	function, and will be set to the address of the C function used to
  2875  *	implement the math function otherwise (in which case the variable
  2876  *	pointed to by the clientDataPtr argument will also be updated.)
  2877  *
  2878  *----------------------------------------------------------------------
  2879  */
  2880 
  2881 EXPORT_C int
  2882 Tcl_GetMathFuncInfo(interp, name, numArgsPtr, argTypesPtr, procPtr,
  2883 		    clientDataPtr)
  2884     Tcl_Interp *interp;
  2885     CONST char *name;
  2886     int *numArgsPtr;
  2887     Tcl_ValueType **argTypesPtr;
  2888     Tcl_MathProc **procPtr;
  2889     ClientData *clientDataPtr;
  2890 {
  2891     Interp *iPtr = (Interp *) interp;
  2892     Tcl_HashEntry *hPtr;
  2893     MathFunc *mathFuncPtr;
  2894     Tcl_ValueType *argTypes;
  2895     int i,numArgs;
  2896 
  2897     hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable, name);
  2898     if (hPtr == NULL) {
  2899         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  2900                 "math function \"", name, "\" not known in this interpreter",
  2901 		(char *) NULL);
  2902 	return TCL_ERROR;
  2903     }
  2904     mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);
  2905 
  2906     *numArgsPtr = numArgs = mathFuncPtr->numArgs;
  2907     if (numArgs == 0) {
  2908 	/* Avoid doing zero-sized allocs... */
  2909 	numArgs = 1;
  2910     }
  2911     *argTypesPtr = argTypes =
  2912 	(Tcl_ValueType *)ckalloc(numArgs * sizeof(Tcl_ValueType));
  2913     for (i = 0; i < mathFuncPtr->numArgs; i++) {
  2914 	argTypes[i] = mathFuncPtr->argTypes[i];
  2915     }
  2916 
  2917     if (mathFuncPtr->builtinFuncIndex == -1) {
  2918 	*procPtr = (Tcl_MathProc *) NULL;
  2919     } else {
  2920 	*procPtr = mathFuncPtr->proc;
  2921 	*clientDataPtr = mathFuncPtr->clientData;
  2922     }
  2923 
  2924     return TCL_OK;
  2925 }
  2926 
  2927 /*
  2928  *----------------------------------------------------------------------
  2929  *
  2930  * Tcl_ListMathFuncs --
  2931  *
  2932  *	Produces a list of all the math functions defined in a given
  2933  *	interpreter.
  2934  *
  2935  * Results:
  2936  *	A pointer to a Tcl_Obj structure with a reference count of zero,
  2937  *	or NULL in the case of an error (in which case a suitable error
  2938  *	message will be left in the interpreter result.)
  2939  *
  2940  * Side effects:
  2941  *	None.
  2942  *
  2943  *----------------------------------------------------------------------
  2944  */
  2945 
  2946 EXPORT_C Tcl_Obj *
  2947 Tcl_ListMathFuncs(interp, pattern)
  2948     Tcl_Interp *interp;
  2949     CONST char *pattern;
  2950 {
  2951     Interp *iPtr = (Interp *) interp;
  2952     Tcl_Obj *resultList = Tcl_NewObj();
  2953     register Tcl_HashEntry *hPtr;
  2954     Tcl_HashSearch hSearch;
  2955     CONST char *name;
  2956 
  2957     for (hPtr = Tcl_FirstHashEntry(&iPtr->mathFuncTable, &hSearch);
  2958 	 hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) {
  2959         name = Tcl_GetHashKey(&iPtr->mathFuncTable, hPtr);
  2960 	if ((pattern == NULL || Tcl_StringMatch(name, pattern)) &&
  2961 	    /* I don't expect this to fail, but... */
  2962 	    Tcl_ListObjAppendElement(interp, resultList,
  2963 				     Tcl_NewStringObj(name,-1)) != TCL_OK) {
  2964 	    Tcl_DecrRefCount(resultList);
  2965 	    return NULL;
  2966 	}
  2967     }
  2968     return resultList;
  2969 }
  2970 
  2971 /*
  2972  *----------------------------------------------------------------------
  2973  *
  2974  * TclInterpReady --
  2975  *
  2976  *	Check if an interpreter is ready to eval commands or scripts, 
  2977  *      i.e., if it was not deleted and if the nesting level is not 
  2978  *      too high.
  2979  *
  2980  * Results:
  2981  *	The return value is TCL_OK if it the interpreter is ready, 
  2982  *      TCL_ERROR otherwise.
  2983  *
  2984  * Side effects:
  2985  *	The interpreters object and string results are cleared.
  2986  *
  2987  *----------------------------------------------------------------------
  2988  */
  2989 
  2990 int 
  2991 TclInterpReady(interp)
  2992     Tcl_Interp *interp;
  2993 {
  2994     register Interp *iPtr = (Interp *) interp;
  2995 
  2996     /*
  2997      * Reset both the interpreter's string and object results and clear 
  2998      * out any previous error information. 
  2999      */
  3000 
  3001     Tcl_ResetResult(interp);
  3002 
  3003     /*
  3004      * If the interpreter has been deleted, return an error.
  3005      */
  3006     
  3007     if (iPtr->flags & DELETED) {
  3008 	Tcl_ResetResult(interp);
  3009 	Tcl_AppendToObj(Tcl_GetObjResult(interp),
  3010 	        "attempt to call eval in deleted interpreter", -1);
  3011 	Tcl_SetErrorCode(interp, "CORE", "IDELETE",
  3012 	        "attempt to call eval in deleted interpreter",
  3013 		(char *) NULL);
  3014 	return TCL_ERROR;
  3015     }
  3016 
  3017     /*
  3018      * Check depth of nested calls to Tcl_Eval:  if this gets too large,
  3019      * it's probably because of an infinite loop somewhere.
  3020      */
  3021 
  3022     if (((iPtr->numLevels) > iPtr->maxNestingDepth) 
  3023 	    || (TclpCheckStackSpace() == 0)) {
  3024 	Tcl_AppendToObj(Tcl_GetObjResult(interp),
  3025 		"too many nested evaluations (infinite loop?)", -1); 
  3026 	return TCL_ERROR;
  3027     }
  3028 
  3029     return TCL_OK;
  3030 }
  3031 
  3032 /*
  3033  *----------------------------------------------------------------------
  3034  *
  3035  * TclEvalObjvInternal --
  3036  *
  3037  *	This procedure evaluates a Tcl command that has already been
  3038  *	parsed into words, with one Tcl_Obj holding each word. The caller
  3039  *      is responsible for managing the iPtr->numLevels.
  3040  *
  3041  * Results:
  3042  *	The return value is a standard Tcl completion code such as
  3043  *	TCL_OK or TCL_ERROR.  A result or error message is left in
  3044  *	interp's result.  If an error occurs, this procedure does
  3045  *	NOT add any information to the errorInfo variable.
  3046  *
  3047  * Side effects:
  3048  *	Depends on the command.
  3049  *
  3050  *----------------------------------------------------------------------
  3051  */
  3052 
  3053 int
  3054 TclEvalObjvInternal(interp, objc, objv, command, length, flags)
  3055     Tcl_Interp *interp;		/* Interpreter in which to evaluate the
  3056 				 * command.  Also used for error
  3057 				 * reporting. */
  3058     int objc;			/* Number of words in command. */
  3059     Tcl_Obj *CONST objv[];	/* An array of pointers to objects that are
  3060 				 * the words that make up the command. */
  3061     CONST char *command;	/* Points to the beginning of the string
  3062 				 * representation of the command; this
  3063 				 * is used for traces.  If the string
  3064 				 * representation of the command is
  3065 				 * unknown, an empty string should be
  3066 				 * supplied. If it is NULL, no traces will
  3067 				 * be called. */
  3068     int length;			/* Number of bytes in command; if -1, all
  3069 				 * characters up to the first null byte are
  3070 				 * used. */
  3071     int flags;			/* Collection of OR-ed bits that control
  3072 				 * the evaluation of the script.  Only
  3073 				 * TCL_EVAL_GLOBAL and TCL_EVAL_INVOKE are
  3074 				 * currently supported. */
  3075 
  3076 {
  3077     Command *cmdPtr;
  3078     Interp *iPtr = (Interp *) interp;
  3079     Tcl_Obj **newObjv;
  3080     int i;
  3081     CallFrame *savedVarFramePtr;	/* Saves old copy of iPtr->varFramePtr
  3082 					 * in case TCL_EVAL_GLOBAL was set. */
  3083     int code = TCL_OK;
  3084     int traceCode = TCL_OK;
  3085     int checkTraces = 1;
  3086     Namespace *savedNsPtr = NULL;
  3087 
  3088     if (TclInterpReady(interp) == TCL_ERROR) {
  3089 	return TCL_ERROR;
  3090     }
  3091 
  3092     if (objc == 0) {
  3093 	return TCL_OK;
  3094     }
  3095 
  3096 
  3097     /*
  3098      * If any execution traces rename or delete the current command,
  3099      * we may need (at most) two passes here.
  3100      */
  3101 
  3102     savedVarFramePtr = iPtr->varFramePtr;
  3103     while (1) {
  3104     
  3105 	/* Configure evaluation context to match the requested flags */
  3106 	if (flags & TCL_EVAL_GLOBAL) {
  3107 	    iPtr->varFramePtr = NULL;
  3108 	} else if ((flags & TCL_EVAL_INVOKE) && iPtr->varFramePtr) {
  3109 	    savedNsPtr = iPtr->varFramePtr->nsPtr;
  3110 	    iPtr->varFramePtr->nsPtr = iPtr->globalNsPtr;
  3111 	}
  3112 	
  3113         /*
  3114          * Find the procedure to execute this command. If there isn't one,
  3115          * then see if there is a command "unknown".  If so, create a new
  3116          * word array with "unknown" as the first word and the original
  3117          * command words as arguments.  Then call ourselves recursively
  3118          * to execute it.
  3119          */
  3120         cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[0]);
  3121         if (cmdPtr == NULL) {
  3122 	    newObjv = (Tcl_Obj **) ckalloc((unsigned)
  3123 		((objc + 1) * sizeof (Tcl_Obj *)));
  3124 	    for (i = objc-1; i >= 0; i--) {
  3125 	        newObjv[i+1] = objv[i];
  3126 	    }
  3127 	    newObjv[0] = Tcl_NewStringObj("::unknown", -1);
  3128 	    Tcl_IncrRefCount(newObjv[0]);
  3129 	    cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, newObjv[0]);
  3130 	    if (cmdPtr == NULL) {
  3131 	        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  3132 		    "invalid command name \"", Tcl_GetString(objv[0]), "\"",
  3133 		    (char *) NULL);
  3134 	        code = TCL_ERROR;
  3135 	    } else {
  3136 	        iPtr->numLevels++;
  3137 	        code = TclEvalObjvInternal(interp, objc+1, newObjv,
  3138 			command, length, 0);
  3139 	        iPtr->numLevels--;
  3140 	    }
  3141 	    Tcl_DecrRefCount(newObjv[0]);
  3142 	    ckfree((char *) newObjv);
  3143 	    if (savedNsPtr) {
  3144 		iPtr->varFramePtr->nsPtr = savedNsPtr;
  3145 	    }
  3146 	    goto done;
  3147         }
  3148 	if (savedNsPtr) {
  3149 	    iPtr->varFramePtr->nsPtr = savedNsPtr;
  3150 	}
  3151     
  3152         /*
  3153          * Call trace procedures if needed.
  3154          */
  3155         if ((checkTraces) && (command != NULL)) {
  3156             int cmdEpoch = cmdPtr->cmdEpoch;
  3157 	    int newEpoch;
  3158 	    
  3159 	    cmdPtr->refCount++;
  3160             /* 
  3161              * If the first set of traces modifies/deletes the command or
  3162              * any existing traces, then the set checkTraces to 0 and
  3163              * go through this while loop one more time.
  3164              */
  3165             if (iPtr->tracePtr != NULL && traceCode == TCL_OK) {
  3166                 traceCode = TclCheckInterpTraces(interp, command, length,
  3167                                cmdPtr, code, TCL_TRACE_ENTER_EXEC, objc, objv);
  3168             }
  3169             if ((cmdPtr->flags & CMD_HAS_EXEC_TRACES) 
  3170 		    && (traceCode == TCL_OK)) {
  3171                 traceCode = TclCheckExecutionTraces(interp, command, length,
  3172                                cmdPtr, code, TCL_TRACE_ENTER_EXEC, objc, objv);
  3173             }
  3174 	    newEpoch = cmdPtr->cmdEpoch;
  3175 	    TclCleanupCommand(cmdPtr);
  3176             if (cmdEpoch != newEpoch) {
  3177                 /* The command has been modified in some way */
  3178                 checkTraces = 0;
  3179                 continue;
  3180             }
  3181         }
  3182         break;
  3183     }
  3184 
  3185     /*
  3186      * Finally, invoke the command's Tcl_ObjCmdProc.
  3187      */
  3188     cmdPtr->refCount++;
  3189     iPtr->cmdCount++;
  3190     if ( code == TCL_OK && traceCode == TCL_OK) {
  3191 	code = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, objc, objv);
  3192     }
  3193     if (Tcl_AsyncReady()) {
  3194 	code = Tcl_AsyncInvoke(interp, code);
  3195     }
  3196 
  3197     /*
  3198      * Call 'leave' command traces
  3199      */
  3200     if (!(cmdPtr->flags & CMD_IS_DELETED)) {
  3201 	int saveErrFlags = iPtr->flags 
  3202 		& (ERR_IN_PROGRESS | ERR_ALREADY_LOGGED | ERROR_CODE_SET);
  3203         if ((cmdPtr->flags & CMD_HAS_EXEC_TRACES) && (traceCode == TCL_OK)) {
  3204             traceCode = TclCheckExecutionTraces (interp, command, length,
  3205                    cmdPtr, code, TCL_TRACE_LEAVE_EXEC, objc, objv);
  3206         }
  3207         if (iPtr->tracePtr != NULL && traceCode == TCL_OK) {
  3208             traceCode = TclCheckInterpTraces(interp, command, length,
  3209                    cmdPtr, code, TCL_TRACE_LEAVE_EXEC, objc, objv);
  3210         }
  3211 	if (traceCode == TCL_OK) {
  3212 	    iPtr->flags |= saveErrFlags;
  3213 	}
  3214     }
  3215     TclCleanupCommand(cmdPtr);
  3216 
  3217     /*
  3218      * If one of the trace invocation resulted in error, then 
  3219      * change the result code accordingly. Note, that the
  3220      * interp->result should already be set correctly by the
  3221      * call to TraceExecutionProc.  
  3222      */
  3223 
  3224     if (traceCode != TCL_OK) {
  3225 	code = traceCode;
  3226     }
  3227     
  3228     /*
  3229      * If the interpreter has a non-empty string result, the result
  3230      * object is either empty or stale because some procedure set
  3231      * interp->result directly. If so, move the string result to the
  3232      * result object, then reset the string result.
  3233      */
  3234     
  3235     if (*(iPtr->result) != 0) {
  3236 	(void) Tcl_GetObjResult(interp);
  3237     }
  3238 
  3239     done:
  3240     iPtr->varFramePtr = savedVarFramePtr;
  3241     return code;
  3242 }
  3243 
  3244 /*
  3245  *----------------------------------------------------------------------
  3246  *
  3247  * Tcl_EvalObjv --
  3248  *
  3249  *	This procedure evaluates a Tcl command that has already been
  3250  *	parsed into words, with one Tcl_Obj holding each word.
  3251  *
  3252  * Results:
  3253  *	The return value is a standard Tcl completion code such as
  3254  *	TCL_OK or TCL_ERROR.  A result or error message is left in
  3255  *	interp's result.
  3256  *
  3257  * Side effects:
  3258  *	Depends on the command.
  3259  *
  3260  *----------------------------------------------------------------------
  3261  */
  3262 
  3263 EXPORT_C int
  3264 Tcl_EvalObjv(interp, objc, objv, flags)
  3265     Tcl_Interp *interp;		/* Interpreter in which to evaluate the
  3266 				 * command.  Also used for error
  3267 				 * reporting. */
  3268     int objc;			/* Number of words in command. */
  3269     Tcl_Obj *CONST objv[];	/* An array of pointers to objects that are
  3270 				 * the words that make up the command. */
  3271     int flags;			/* Collection of OR-ed bits that control
  3272 				 * the evaluation of the script.  Only
  3273 				 * TCL_EVAL_GLOBAL and TCL_EVAL_INVOKE
  3274 				 * are  currently supported. */
  3275 {
  3276     Interp *iPtr = (Interp *)interp;
  3277     Trace *tracePtr;
  3278     Tcl_DString cmdBuf;
  3279     char *cmdString = "";	/* A command string is only necessary for
  3280 				 * command traces or error logs; it will be
  3281 				 * generated to replace this default value if
  3282 				 * necessary. */
  3283     int cmdLen = 0;		/* a non-zero value indicates that a command
  3284 				 * string was generated. */
  3285     int code = TCL_OK;
  3286     int i;
  3287     int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS);
  3288 
  3289     for (tracePtr = iPtr->tracePtr; tracePtr; tracePtr = tracePtr->nextPtr) {
  3290 	if ((tracePtr->level == 0) || (iPtr->numLevels <= tracePtr->level)) {
  3291 	    /*
  3292 	     * The command may be needed for an execution trace.  Generate a
  3293 	     * command string.
  3294 	     */
  3295 	    
  3296 	    Tcl_DStringInit(&cmdBuf);
  3297 	    for (i = 0; i < objc; i++) {
  3298 		Tcl_DStringAppendElement(&cmdBuf, Tcl_GetString(objv[i]));
  3299 	    }
  3300 	    cmdString = Tcl_DStringValue(&cmdBuf);
  3301 	    cmdLen = Tcl_DStringLength(&cmdBuf);
  3302 	    break;
  3303 	}
  3304     }
  3305 
  3306     iPtr->numLevels++;
  3307     code = TclEvalObjvInternal(interp, objc, objv, cmdString, cmdLen, flags);
  3308     iPtr->numLevels--;
  3309 
  3310     /*
  3311      * If we are again at the top level, process any unusual 
  3312      * return code returned by the evaluated code. 
  3313      */
  3314 	
  3315     if (iPtr->numLevels == 0) {
  3316 	if (code == TCL_RETURN) {
  3317 	    code = TclUpdateReturnInfo(iPtr);
  3318 	}
  3319 	if ((code != TCL_OK) && (code != TCL_ERROR) 
  3320 	    && !allowExceptions) {
  3321 	    ProcessUnexpectedResult(interp, code);
  3322 	    code = TCL_ERROR;
  3323 	}
  3324     }
  3325 	    
  3326     if ((code == TCL_ERROR) && !(flags & TCL_EVAL_INVOKE)) {
  3327 
  3328 	/* 
  3329 	 * If there was an error, a command string will be needed for the 
  3330 	 * error log: generate it now if it was not done previously.
  3331 	 */
  3332 
  3333 	if (cmdLen == 0) {
  3334 	    Tcl_DStringInit(&cmdBuf);
  3335 	    for (i = 0; i < objc; i++) {
  3336 		Tcl_DStringAppendElement(&cmdBuf, Tcl_GetString(objv[i]));
  3337 	    }
  3338 	    cmdString = Tcl_DStringValue(&cmdBuf);
  3339 	    cmdLen = Tcl_DStringLength(&cmdBuf);
  3340 	}
  3341 	Tcl_LogCommandInfo(interp, cmdString, cmdString, cmdLen);
  3342     }
  3343 
  3344     if (cmdLen != 0) {
  3345 	Tcl_DStringFree(&cmdBuf);
  3346     }
  3347     return code;
  3348 }
  3349 
  3350 /*
  3351  *----------------------------------------------------------------------
  3352  *
  3353  * Tcl_LogCommandInfo --
  3354  *
  3355  *	This procedure is invoked after an error occurs in an interpreter.
  3356  *	It adds information to the "errorInfo" variable to describe the
  3357  *	command that was being executed when the error occurred.
  3358  *
  3359  * Results:
  3360  *	None.
  3361  *
  3362  * Side effects:
  3363  *	Information about the command is added to errorInfo and the
  3364  *	line number stored internally in the interpreter is set.  If this
  3365  *	is the first call to this procedure or Tcl_AddObjErrorInfo since
  3366  *	an error occurred, then old information in errorInfo is
  3367  *	deleted.
  3368  *
  3369  *----------------------------------------------------------------------
  3370  */
  3371 
  3372 EXPORT_C void
  3373 Tcl_LogCommandInfo(interp, script, command, length)
  3374     Tcl_Interp *interp;		/* Interpreter in which to log information. */
  3375     CONST char *script;		/* First character in script containing
  3376 				 * command (must be <= command). */
  3377     CONST char *command;	/* First character in command that
  3378 				 * generated the error. */
  3379     int length;			/* Number of bytes in command (-1 means
  3380 				 * use all bytes up to first null byte). */
  3381 {
  3382     char buffer[200];
  3383     register CONST char *p;
  3384     char *ellipsis = "";
  3385     Interp *iPtr = (Interp *) interp;
  3386 
  3387     if (iPtr->flags & ERR_ALREADY_LOGGED) {
  3388 	/*
  3389 	 * Someone else has already logged error information for this
  3390 	 * command; we shouldn't add anything more.
  3391 	 */
  3392 
  3393 	return;
  3394     }
  3395 
  3396     /*
  3397      * Compute the line number where the error occurred.
  3398      */
  3399 
  3400     iPtr->errorLine = 1;
  3401     for (p = script; p != command; p++) {
  3402 	if (*p == '\n') {
  3403 	    iPtr->errorLine++;
  3404 	}
  3405     }
  3406 
  3407     /*
  3408      * Create an error message to add to errorInfo, including up to a
  3409      * maximum number of characters of the command.
  3410      */
  3411 
  3412     if (length < 0) {
  3413 	length = strlen(command);
  3414     }
  3415     if (length > 150) {
  3416 	length = 150;
  3417 	ellipsis = "...";
  3418     }
  3419     while ( (command[length] & 0xC0) == 0x80 ) {
  3420 	/*
  3421 	 * Back up truncation point so that we don't truncate in the
  3422 	 * middle of a multi-byte character (in UTF-8)
  3423 	 */
  3424 	length--;
  3425 	ellipsis = "...";
  3426     }
  3427     if (!(iPtr->flags & ERR_IN_PROGRESS)) {
  3428 	sprintf(buffer, "\n    while executing\n\"%.*s%s\"",
  3429 		length, command, ellipsis);
  3430     } else {
  3431 	sprintf(buffer, "\n    invoked from within\n\"%.*s%s\"",
  3432 		length, command, ellipsis);
  3433     }
  3434     Tcl_AddObjErrorInfo(interp, buffer, -1);
  3435     iPtr->flags &= ~ERR_ALREADY_LOGGED;
  3436 }
  3437 
  3438 /*
  3439  *----------------------------------------------------------------------
  3440  *
  3441  * Tcl_EvalTokensStandard, EvalTokensStandard --
  3442  *
  3443  *	Given an array of tokens parsed from a Tcl command (e.g., the
  3444  *	tokens that make up a word or the index for an array variable)
  3445  *	this procedure evaluates the tokens and concatenates their
  3446  *	values to form a single result value.
  3447  * 
  3448  * Results:
  3449  *	The return value is a standard Tcl completion code such as
  3450  *	TCL_OK or TCL_ERROR.  A result or error message is left in
  3451  *	interp's result.
  3452  *
  3453  * Side effects:
  3454  *	Depends on the array of tokens being evaled.
  3455  *
  3456  * TIP #280 : Keep public API, internally extended API.
  3457  *----------------------------------------------------------------------
  3458  */
  3459 
  3460 EXPORT_C int
  3461 Tcl_EvalTokensStandard(interp, tokenPtr, count)
  3462     Tcl_Interp *interp;		/* Interpreter in which to lookup
  3463 				 * variables, execute nested commands,
  3464 				 * and report errors. */
  3465     Tcl_Token *tokenPtr;	/* Pointer to first in an array of tokens
  3466 				 * to evaluate and concatenate. */
  3467     int count;			/* Number of tokens to consider at tokenPtr.
  3468 				 * Must be at least 1. */
  3469 {
  3470 #ifdef TCL_TIP280
  3471   return EvalTokensStandard (interp, tokenPtr, count, 1);
  3472 }
  3473 
  3474 static int
  3475 EvalTokensStandard(interp, tokenPtr, count, line)
  3476     Tcl_Interp *interp;		/* Interpreter in which to lookup
  3477 				 * variables, execute nested commands,
  3478 				 * and report errors. */
  3479     Tcl_Token *tokenPtr;	/* Pointer to first in an array of tokens
  3480 				 * to evaluate and concatenate. */
  3481     int count;			/* Number of tokens to consider at tokenPtr.
  3482 				 * Must be at least 1. */
  3483     int line;                   /* The line the script starts on. */
  3484 {
  3485 #endif
  3486     Tcl_Obj *resultPtr, *indexPtr, *valuePtr;
  3487     char buffer[TCL_UTF_MAX];
  3488 #ifdef TCL_MEM_DEBUG
  3489 #   define  MAX_VAR_CHARS 5
  3490 #else
  3491 #   define  MAX_VAR_CHARS 30
  3492 #endif
  3493     char nameBuffer[MAX_VAR_CHARS+1];
  3494     char *varName, *index;
  3495     CONST char *p = NULL;	/* Initialized to avoid compiler warning. */
  3496     int length, code;
  3497 
  3498     /*
  3499      * The only tricky thing about this procedure is that it attempts to
  3500      * avoid object creation and string copying whenever possible.  For
  3501      * example, if the value is just a nested command, then use the
  3502      * command's result object directly.
  3503      */
  3504 
  3505     code = TCL_OK;
  3506     resultPtr = NULL;
  3507     Tcl_ResetResult(interp);
  3508     for ( ; count > 0; count--, tokenPtr++) {
  3509 	valuePtr = NULL;
  3510 
  3511 	/*
  3512 	 * The switch statement below computes the next value to be
  3513 	 * concat to the result, as either a range of text or an
  3514 	 * object.
  3515 	 */
  3516 
  3517 	switch (tokenPtr->type) {
  3518 	    case TCL_TOKEN_TEXT:
  3519 		p = tokenPtr->start;
  3520 		length = tokenPtr->size;
  3521 		break;
  3522 
  3523 	    case TCL_TOKEN_BS:
  3524 		length = Tcl_UtfBackslash(tokenPtr->start, (int *) NULL,
  3525 			buffer);
  3526 		p = buffer;
  3527 		break;
  3528 
  3529 	    case TCL_TOKEN_COMMAND: {
  3530 		Interp *iPtr = (Interp *) interp;
  3531 		iPtr->numLevels++;
  3532 		code = TclInterpReady(interp);
  3533 		if (code == TCL_OK) {
  3534 #ifndef TCL_TIP280
  3535 		    code = Tcl_EvalEx(interp,
  3536 			    tokenPtr->start+1, tokenPtr->size-2, 0);
  3537 #else
  3538 		    /* TIP #280: Transfer line information to nested command */
  3539 		    code = EvalEx(interp,
  3540 			    tokenPtr->start+1, tokenPtr->size-2, 0, line);
  3541 #endif
  3542 		}
  3543 		iPtr->numLevels--;
  3544 		if (code != TCL_OK) {
  3545 		    goto done;
  3546 		}
  3547 		valuePtr = Tcl_GetObjResult(interp);
  3548 		break;
  3549 	    }
  3550 
  3551 	    case TCL_TOKEN_VARIABLE:
  3552 		if (tokenPtr->numComponents == 1) {
  3553 		    indexPtr = NULL;
  3554 		    index = NULL;
  3555 		} else {
  3556 #ifndef TCL_TIP280
  3557 		    code = Tcl_EvalTokensStandard(interp, tokenPtr+2,
  3558 			    tokenPtr->numComponents - 1);
  3559 #else
  3560 		    /* TIP #280: Transfer line information to nested command */
  3561 		    code = EvalTokensStandard(interp, tokenPtr+2,
  3562 			    tokenPtr->numComponents - 1, line);
  3563 #endif
  3564 		    if (code != TCL_OK) {
  3565 			goto done;
  3566 		    }
  3567 		    indexPtr = Tcl_GetObjResult(interp);
  3568 		    Tcl_IncrRefCount(indexPtr);
  3569 		    index = Tcl_GetString(indexPtr);
  3570 		}
  3571 
  3572 		/*
  3573 		 * We have to make a copy of the variable name in order
  3574 		 * to have a null-terminated string.  We can't make a
  3575 		 * temporary modification to the script to null-terminate
  3576 		 * the name, because a trace callback might potentially
  3577 		 * reuse the script and be affected by the null character.
  3578 		 */
  3579 
  3580 		if (tokenPtr[1].size <= MAX_VAR_CHARS) {
  3581 		    varName = nameBuffer;
  3582 		} else {
  3583 		    varName = ckalloc((unsigned) (tokenPtr[1].size + 1));
  3584 		}
  3585 		strncpy(varName, tokenPtr[1].start, (size_t) tokenPtr[1].size);
  3586 		varName[tokenPtr[1].size] = 0;
  3587 		valuePtr = Tcl_GetVar2Ex(interp, varName, index,
  3588 			TCL_LEAVE_ERR_MSG);
  3589 		if (varName != nameBuffer) {
  3590 		    ckfree(varName);
  3591 		}
  3592 		if (indexPtr != NULL) {
  3593 		    Tcl_DecrRefCount(indexPtr);
  3594 		}
  3595 		if (valuePtr == NULL) {
  3596 		    code = TCL_ERROR;
  3597 		    goto done;
  3598 		}
  3599 		count -= tokenPtr->numComponents;
  3600 		tokenPtr += tokenPtr->numComponents;
  3601 		break;
  3602 
  3603 	    default:
  3604 		panic("unexpected token type in Tcl_EvalTokensStandard");
  3605 	}
  3606 
  3607 	/*
  3608 	 * If valuePtr isn't NULL, the next piece of text comes from that
  3609 	 * object; otherwise, take length bytes starting at p.
  3610 	 */
  3611 
  3612 	if (resultPtr == NULL) {
  3613 	    if (valuePtr != NULL) {
  3614 		resultPtr = valuePtr;
  3615 	    } else {
  3616 		resultPtr = Tcl_NewStringObj(p, length);
  3617 	    }
  3618 	    Tcl_IncrRefCount(resultPtr);
  3619 	} else {
  3620 	    if (Tcl_IsShared(resultPtr)) {
  3621 		Tcl_DecrRefCount(resultPtr);
  3622 		resultPtr = Tcl_DuplicateObj(resultPtr);
  3623 		Tcl_IncrRefCount(resultPtr);
  3624 	    }
  3625 	    if (valuePtr != NULL) {
  3626 		p = Tcl_GetStringFromObj(valuePtr, &length);
  3627 	    }
  3628 	    Tcl_AppendToObj(resultPtr, p, length);
  3629 	}
  3630     }
  3631     if (resultPtr != NULL) {
  3632 	Tcl_SetObjResult(interp, resultPtr);
  3633     } else {
  3634 	code = TCL_ERROR;
  3635     }
  3636 
  3637     done:
  3638     if (resultPtr != NULL) {
  3639 	Tcl_DecrRefCount(resultPtr);
  3640     }
  3641     return code;
  3642 }
  3643 
  3644 /*
  3645  *----------------------------------------------------------------------
  3646  *
  3647  * Tcl_EvalTokens --
  3648  *
  3649  *	Given an array of tokens parsed from a Tcl command (e.g., the
  3650  *	tokens that make up a word or the index for an array variable)
  3651  *	this procedure evaluates the tokens and concatenates their
  3652  *	values to form a single result value.
  3653  *
  3654  * Results:
  3655  *	The return value is a pointer to a newly allocated Tcl_Obj
  3656  *	containing the value of the array of tokens.  The reference
  3657  *	count of the returned object has been incremented.  If an error
  3658  *	occurs in evaluating the tokens then a NULL value is returned
  3659  *	and an error message is left in interp's result.
  3660  *
  3661  * Side effects:
  3662  *	A new object is allocated to hold the result.
  3663  *
  3664  *----------------------------------------------------------------------
  3665  *
  3666  * This uses a non-standard return convention; its use is now deprecated.
  3667  * It is a wrapper for the new function Tcl_EvalTokensStandard, and is not 
  3668  * used in the core any longer. It is only kept for backward compatibility.
  3669  */
  3670 
  3671 EXPORT_C Tcl_Obj *
  3672 Tcl_EvalTokens(interp, tokenPtr, count)
  3673     Tcl_Interp *interp;		/* Interpreter in which to lookup
  3674 				 * variables, execute nested commands,
  3675 				 * and report errors. */
  3676     Tcl_Token *tokenPtr;	/* Pointer to first in an array of tokens
  3677 				 * to evaluate and concatenate. */
  3678     int count;			/* Number of tokens to consider at tokenPtr.
  3679 				 * Must be at least 1. */
  3680 {
  3681     int code;
  3682     Tcl_Obj *resPtr;
  3683     
  3684     code = Tcl_EvalTokensStandard(interp, tokenPtr, count);
  3685     if (code == TCL_OK) {
  3686 	resPtr = Tcl_GetObjResult(interp);
  3687 	Tcl_IncrRefCount(resPtr);
  3688 	Tcl_ResetResult(interp);
  3689 	return resPtr;
  3690     } else {
  3691 	return NULL;
  3692     }
  3693 }
  3694 
  3695 
  3696 /*
  3697  *----------------------------------------------------------------------
  3698  *
  3699  * Tcl_EvalEx, EvalEx --
  3700  *
  3701  *	This procedure evaluates a Tcl script without using the compiler
  3702  *	or byte-code interpreter.  It just parses the script, creates
  3703  *	values for each word of each command, then calls EvalObjv
  3704  *	to execute each command.
  3705  *
  3706  * Results:
  3707  *	The return value is a standard Tcl completion code such as
  3708  *	TCL_OK or TCL_ERROR.  A result or error message is left in
  3709  *	interp's result.
  3710  *
  3711  * Side effects:
  3712  *	Depends on the script.
  3713  *
  3714  * TIP #280 : Keep public API, internally extended API.
  3715  *----------------------------------------------------------------------
  3716  */
  3717 
  3718 EXPORT_C int
  3719 Tcl_EvalEx(interp, script, numBytes, flags)
  3720     Tcl_Interp *interp;		/* Interpreter in which to evaluate the
  3721 				 * script.  Also used for error reporting. */
  3722     CONST char *script;		/* First character of script to evaluate. */
  3723     int numBytes;		/* Number of bytes in script.  If < 0, the
  3724 				 * script consists of all bytes up to the
  3725 				 * first null character. */
  3726     int flags;			/* Collection of OR-ed bits that control
  3727 				 * the evaluation of the script.  Only
  3728 				 * TCL_EVAL_GLOBAL is currently
  3729 				 * supported. */
  3730 {
  3731 #ifdef TCL_TIP280
  3732   return EvalEx (interp, script, numBytes, flags, 1);
  3733 }
  3734 
  3735 static int
  3736 EvalEx(interp, script, numBytes, flags, line)
  3737     Tcl_Interp *interp;		/* Interpreter in which to evaluate the
  3738 				 * script.  Also used for error reporting. */
  3739     CONST char *script;		/* First character of script to evaluate. */
  3740     int numBytes;		/* Number of bytes in script.  If < 0, the
  3741 				 * script consists of all bytes up to the
  3742 				 * first null character. */
  3743     int flags;			/* Collection of OR-ed bits that control
  3744 				 * the evaluation of the script.  Only
  3745 				 * TCL_EVAL_GLOBAL is currently
  3746 				 * supported. */
  3747     int line;                   /* The line the script starts on. */
  3748 {
  3749 #endif
  3750     Interp *iPtr = (Interp *) interp;
  3751     CONST char *p, *next;
  3752     Tcl_Parse parse;
  3753 #define NUM_STATIC_OBJS 20
  3754     Tcl_Obj *staticObjArray[NUM_STATIC_OBJS], **objv;
  3755     Tcl_Token *tokenPtr;
  3756     int code = TCL_OK;
  3757     int i, commandLength, bytesLeft, nested;
  3758     CallFrame *savedVarFramePtr;   /* Saves old copy of iPtr->varFramePtr
  3759 				    * in case TCL_EVAL_GLOBAL was set. */
  3760     int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS);
  3761     
  3762     /*
  3763      * The variables below keep track of how much state has been
  3764      * allocated while evaluating the script, so that it can be freed
  3765      * properly if an error occurs.
  3766      */
  3767 
  3768     int gotParse = 0, objectsUsed = 0;
  3769 
  3770 #ifdef TCL_TIP280
  3771     /* TIP #280 Structures for tracking of command locations. */
  3772     CmdFrame eeFrame;
  3773 #endif
  3774 
  3775     if (numBytes < 0) {
  3776 	numBytes = strlen(script);
  3777     }
  3778     Tcl_ResetResult(interp);
  3779 
  3780     savedVarFramePtr = iPtr->varFramePtr;
  3781     if (flags & TCL_EVAL_GLOBAL) {
  3782 	iPtr->varFramePtr = NULL;
  3783     }
  3784 
  3785     /*
  3786      * Each iteration through the following loop parses the next
  3787      * command from the script and then executes it.
  3788      */
  3789 
  3790     objv = staticObjArray;
  3791     p = script;
  3792     bytesLeft = numBytes;
  3793     if (iPtr->evalFlags & TCL_BRACKET_TERM) {
  3794 	nested = 1;
  3795     } else {
  3796 	nested = 0;
  3797     }
  3798 
  3799 #ifdef TCL_TIP280
  3800     /* TIP #280 Initialize tracking. Do not push on the frame stack yet. */
  3801     /*
  3802      * We may cont. counting based on a specific context (CTX), or open a new
  3803      * context, either for a sourced script, or 'eval'. For sourced files we
  3804      * always have a path object, even if nothing was specified in the interp
  3805      * itself. That makes code using it simpler as NULL checks can be left
  3806      * out. Sourced file without path in the 'scriptFile' is possible during
  3807      * Tcl initialization.
  3808      */
  3809 
  3810     if (iPtr->evalFlags & TCL_EVAL_CTX) {
  3811         /* Path information comes out of the context. */
  3812 
  3813         eeFrame.type           = TCL_LOCATION_SOURCE;
  3814 	eeFrame.data.eval.path = iPtr->invokeCmdFramePtr->data.eval.path;
  3815 	Tcl_IncrRefCount (eeFrame.data.eval.path);
  3816     } else if (iPtr->evalFlags & TCL_EVAL_FILE) {
  3817 	/* Set up for a sourced file */
  3818 
  3819         eeFrame.type = TCL_LOCATION_SOURCE;
  3820 
  3821 	if (iPtr->scriptFile) {
  3822 	    /* Normalization here, to have the correct pwd. Should have
  3823 	     * negligible impact on performance, as the norm should have been
  3824 	     * done already by the 'source' invoking us, and it caches the
  3825 	     * result
  3826 	     */
  3827 
  3828 	    Tcl_Obj* norm = Tcl_FSGetNormalizedPath (interp, iPtr->scriptFile);
  3829 	    if (!norm) {
  3830 		/* Error message in the interp result */
  3831 		return TCL_ERROR;
  3832 	    }
  3833 	    eeFrame.data.eval.path = norm;
  3834 	    Tcl_IncrRefCount (eeFrame.data.eval.path);
  3835 	} else {
  3836 	    eeFrame.data.eval.path = Tcl_NewStringObj ("",-1);
  3837 	}
  3838     } else {
  3839 	/* Set up for plain eval */
  3840 
  3841         eeFrame.type           = TCL_LOCATION_EVAL;
  3842 	eeFrame.data.eval.path = NULL;
  3843     }
  3844 
  3845     eeFrame.level     = (iPtr->cmdFramePtr == NULL
  3846 			 ? 1
  3847 			 : iPtr->cmdFramePtr->level + 1);
  3848     eeFrame.framePtr  = iPtr->framePtr;
  3849     eeFrame.nextPtr   = iPtr->cmdFramePtr;
  3850     eeFrame.nline     = 0;
  3851     eeFrame.line      = NULL;
  3852 #endif
  3853 
  3854     iPtr->evalFlags = 0;
  3855     do {
  3856 	if (Tcl_ParseCommand(interp, p, bytesLeft, nested, &parse)
  3857 	        != TCL_OK) {
  3858 	    code = TCL_ERROR;
  3859 	    goto error;
  3860 	}
  3861 	gotParse = 1; 
  3862 
  3863 	if (nested && parse.term == (script + numBytes)) {
  3864 	    /*
  3865 	     * A nested script can only terminate in ']'. If
  3866 	     * the parsing got terminated at the end of the script,
  3867 	     * there was no closing ']'.  Report the syntax error.
  3868 	     */
  3869 
  3870 	    code = TCL_ERROR;
  3871 	    goto error;
  3872 	}
  3873 
  3874 #ifdef TCL_TIP280
  3875 	/*
  3876 	 * TIP #280 Track lines. The parser may have skipped text till it
  3877 	 * found the command we are now at. We have count the lines in this
  3878 	 * block.
  3879 	 */
  3880 
  3881 	TclAdvanceLines (&line, p, parse.commandStart);
  3882 #endif
  3883 
  3884 	if (parse.numWords > 0) {
  3885 #ifdef TCL_TIP280
  3886 	    /*
  3887 	     * TIP #280. Track lines within the words of the current
  3888 	     * command.
  3889 	     */
  3890 
  3891 	    int         wordLine  = line;
  3892 	    CONST char* wordStart = parse.commandStart;
  3893 #endif
  3894 
  3895 	    /*
  3896 	     * Generate an array of objects for the words of the command.
  3897 	     */
  3898     
  3899 	    if (parse.numWords <= NUM_STATIC_OBJS) {
  3900 		objv = staticObjArray;
  3901 	    } else {
  3902 		objv = (Tcl_Obj **) ckalloc((unsigned)
  3903 		    (parse.numWords * sizeof (Tcl_Obj *)));
  3904 	    }
  3905 
  3906 #ifdef TCL_TIP280
  3907 	    eeFrame.nline = parse.numWords;
  3908 	    eeFrame.line  = (int*) ckalloc((unsigned)
  3909 		  (parse.numWords * sizeof (int)));
  3910 #endif
  3911 
  3912 	    for (objectsUsed = 0, tokenPtr = parse.tokenPtr;
  3913 		 objectsUsed < parse.numWords;
  3914 		 objectsUsed++, tokenPtr += (tokenPtr->numComponents + 1)) {
  3915 #ifndef TCL_TIP280
  3916 		code = Tcl_EvalTokensStandard(interp, tokenPtr+1, 
  3917 		            tokenPtr->numComponents);
  3918 #else
  3919 	        /*
  3920 		 * TIP #280. Track lines to current word. Save the
  3921 		 * information on a per-word basis, signaling dynamic words as
  3922 		 * needed. Make the information available to the recursively
  3923 		 * called evaluator as well, including the type of context
  3924 		 * (source vs. eval).
  3925 		 */
  3926 
  3927 		TclAdvanceLines (&wordLine, wordStart, tokenPtr->start);
  3928 		wordStart = tokenPtr->start;
  3929 
  3930                 eeFrame.line [objectsUsed] = (TclWordKnownAtCompileTime (tokenPtr)
  3931 					      ? wordLine
  3932 					      : -1);
  3933 
  3934 	        if (eeFrame.type == TCL_LOCATION_SOURCE) {
  3935 		    iPtr->evalFlags |= TCL_EVAL_FILE;
  3936 		}
  3937 
  3938 		code = EvalTokensStandard(interp, tokenPtr+1, 
  3939 		            tokenPtr->numComponents, wordLine);
  3940 
  3941 		iPtr->evalFlags = 0;
  3942 #endif
  3943 
  3944 		if (code == TCL_OK) {
  3945 		    objv[objectsUsed] = Tcl_GetObjResult(interp);
  3946 		    Tcl_IncrRefCount(objv[objectsUsed]);
  3947 		} else {
  3948 		    goto error;
  3949 		}
  3950 	    }
  3951     
  3952 	    /*
  3953 	     * Execute the command and free the objects for its words.
  3954 	     *
  3955 	     * TIP #280: Remember the command itself for 'info frame'. We
  3956 	     * shorten the visible command by one char to exclude the
  3957 	     * termination character, if necessary. Here is where we put our
  3958 	     * frame on the stack of frames too. _After_ the nested commands
  3959 	     * have been executed.
  3960 	     */
  3961 
  3962 #ifdef TCL_TIP280
  3963 	    eeFrame.cmd.str.cmd = parse.commandStart;
  3964 	    eeFrame.cmd.str.len = parse.commandSize;
  3965 
  3966 	    if (parse.term == parse.commandStart + parse.commandSize - 1) {
  3967 		eeFrame.cmd.str.len --;
  3968 	    }
  3969 
  3970 	    iPtr->cmdFramePtr = &eeFrame;
  3971 #endif
  3972 	    iPtr->numLevels++;    
  3973 	    code = TclEvalObjvInternal(interp, objectsUsed, objv, 
  3974 	            parse.commandStart, parse.commandSize, 0);
  3975 	    iPtr->numLevels--;
  3976 #ifdef TCL_TIP280
  3977 	    iPtr->cmdFramePtr = iPtr->cmdFramePtr->nextPtr;
  3978 
  3979 	    ckfree ((char*) eeFrame.line);
  3980 	    eeFrame.line  = NULL;
  3981 	    eeFrame.nline = 0;
  3982 #endif
  3983 
  3984 	    if (code != TCL_OK) {
  3985 		goto error;
  3986 	    }
  3987 	    for (i = 0; i < objectsUsed; i++) {
  3988 		Tcl_DecrRefCount(objv[i]);
  3989 	    }
  3990 	    objectsUsed = 0;
  3991 	    if (objv != staticObjArray) {
  3992 		ckfree((char *) objv);
  3993 		objv = staticObjArray;
  3994 	    }
  3995 	}
  3996 
  3997 	/*
  3998 	 * Advance to the next command in the script.
  3999 	 *
  4000 	 * TIP #280 Track Lines. Now we track how many lines were in the
  4001 	 * executed command.
  4002 	 */
  4003 
  4004 	next = parse.commandStart + parse.commandSize;
  4005 	bytesLeft -= next - p;
  4006 	p = next;
  4007 #ifdef TCL_TIP280
  4008 	TclAdvanceLines (&line, parse.commandStart, p);
  4009 #endif
  4010 	Tcl_FreeParse(&parse);
  4011 	gotParse = 0;
  4012 	if (nested && (*parse.term == ']')) {
  4013 	    /*
  4014 	     * We get here in the special case where the TCL_BRACKET_TERM
  4015 	     * flag was set in the interpreter and the latest parsed command
  4016 	     * was terminated by the matching close-bracket we seek.
  4017 	     * Return immediately.
  4018 	     */
  4019 
  4020 	    iPtr->termOffset = (p - 1) - script;
  4021 	    iPtr->varFramePtr = savedVarFramePtr;
  4022 #ifndef TCL_TIP280
  4023 	    return TCL_OK;
  4024 #else
  4025 	    code = TCL_OK;
  4026 	    goto cleanup_return;
  4027 #endif
  4028 	}
  4029     } while (bytesLeft > 0);
  4030 
  4031     if (nested) {
  4032 	/*
  4033 	 * This nested script did not terminate in ']', it is an error.
  4034 	 */
  4035 	
  4036 	code = TCL_ERROR;
  4037 	goto error;
  4038     }
  4039     
  4040     iPtr->termOffset = p - script;
  4041     iPtr->varFramePtr = savedVarFramePtr;
  4042 #ifndef TCL_TIP280
  4043     return TCL_OK;
  4044 #else
  4045     code = TCL_OK;
  4046     goto cleanup_return;
  4047 #endif
  4048 
  4049     error:
  4050     /*
  4051      * Generate various pieces of error information, such as the line
  4052      * number where the error occurred and information to add to the
  4053      * errorInfo variable.  Then free resources that had been allocated
  4054      * to the command.
  4055      */
  4056 
  4057     if (iPtr->numLevels == 0) {
  4058 	if (code == TCL_RETURN) {
  4059 	    code = TclUpdateReturnInfo(iPtr);
  4060 	}
  4061 	if ((code != TCL_OK) && (code != TCL_ERROR) 
  4062 		&& !allowExceptions) {
  4063 	    ProcessUnexpectedResult(interp, code);
  4064 	    code = TCL_ERROR;
  4065 	}
  4066     }
  4067     if ((code == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) { 
  4068 	commandLength = parse.commandSize;
  4069 	if (parse.term == parse.commandStart + commandLength - 1) {
  4070 	    /*
  4071 	     * The terminator character (such as ; or ]) of the command where
  4072 	     * the error occurred is the last character in the parsed command.
  4073 	     * Reduce the length by one so that the error message doesn't
  4074 	     * include the terminator character.
  4075 	     */
  4076 	    
  4077 	    commandLength -= 1;
  4078 	}
  4079 	Tcl_LogCommandInfo(interp, script, parse.commandStart, commandLength);
  4080     }
  4081     
  4082     for (i = 0; i < objectsUsed; i++) {
  4083 	Tcl_DecrRefCount(objv[i]);
  4084     }
  4085     if (gotParse) {
  4086 	Tcl_FreeParse(&parse);
  4087     }
  4088     if (objv != staticObjArray) {
  4089 	ckfree((char *) objv);
  4090     }
  4091     iPtr->varFramePtr = savedVarFramePtr;
  4092 
  4093     /*
  4094      * All that's left to do before returning is to set iPtr->termOffset
  4095      * to point past the end of the script we just evaluated.
  4096      */
  4097 
  4098     next = parse.commandStart + parse.commandSize;
  4099     bytesLeft -= next - p;
  4100     p = next;
  4101 
  4102     if (!nested) {
  4103 	iPtr->termOffset = p - script;
  4104 #ifndef TCL_TIP280
  4105 	return code;
  4106 #else
  4107 	goto cleanup_return;
  4108 #endif
  4109     }
  4110 
  4111     /*
  4112      * When we are nested (the TCL_BRACKET_TERM flag was set in the
  4113      * interpreter), we must find the matching close-bracket to
  4114      * end the script we are evaluating.
  4115      *
  4116      * When our return code is TCL_CONTINUE or TCL_RETURN, we want
  4117      * to correctly set iPtr->termOffset to point to that matching
  4118      * close-bracket so our caller can move to the part of the
  4119      * string beyond the script we were asked to evaluate.
  4120      * So we try to parse past the rest of the commands.
  4121      */
  4122 
  4123     next = NULL;
  4124     while (bytesLeft && (*parse.term != ']')) {
  4125 	if (TCL_OK != Tcl_ParseCommand(NULL, p, bytesLeft, 1, &parse)) {
  4126 	    /*
  4127 	     * Syntax error.  Set the termOffset to the beginning of
  4128 	     * the last command parsed.
  4129 	     */
  4130 
  4131 	    if (next == NULL) {
  4132 	        iPtr->termOffset = (parse.commandStart - 1) - script;
  4133 	    } else {
  4134 	        iPtr->termOffset = (next - 1) - script;
  4135 	    }
  4136 #ifndef TCL_TIP280
  4137 	    return code;
  4138 #else
  4139 	    goto cleanup_return;
  4140 #endif
  4141 	}
  4142 	next = parse.commandStart + parse.commandSize;
  4143 	bytesLeft -= next - p;
  4144 	p = next;
  4145 	next = parse.commandStart;
  4146 	Tcl_FreeParse(&parse);
  4147     }
  4148 
  4149     if (bytesLeft) {
  4150 	/* 
  4151 	 * parse.term points to the close-bracket.
  4152 	 */
  4153 
  4154 	iPtr->termOffset = parse.term - script;
  4155     } else if (parse.term == script + numBytes) {
  4156 	/*
  4157 	 * There was no close-bracket.  Syntax error.
  4158 	 */
  4159 
  4160 	iPtr->termOffset = parse.term - script;
  4161 	Tcl_SetObjResult(interp,
  4162 		Tcl_NewStringObj("missing close-bracket", -1));
  4163 #ifndef TCL_TIP280
  4164 	return TCL_ERROR;
  4165 #else
  4166 	code = TCL_ERROR;
  4167 	goto cleanup_return;
  4168 #endif
  4169     } else if (*parse.term != ']') {
  4170 	/*
  4171 	 * There was no close-bracket.  Syntax error.
  4172 	 */
  4173 
  4174 	iPtr->termOffset = (parse.term + 1) - script;
  4175 	Tcl_SetObjResult(interp,
  4176 		Tcl_NewStringObj("missing close-bracket", -1));
  4177 #ifndef TCL_TIP280
  4178 	return TCL_ERROR;
  4179 #else
  4180 	code = TCL_ERROR;
  4181 	goto cleanup_return;
  4182 #endif
  4183     } else {
  4184 	/* 
  4185 	 * parse.term points to the close-bracket.
  4186 	 */
  4187 	iPtr->termOffset = parse.term - script;
  4188     }
  4189 
  4190 #ifdef TCL_TIP280
  4191  cleanup_return:
  4192     /* TIP #280. Release the local CmdFrame, and its contents. */
  4193 
  4194     if (eeFrame.line != NULL) {
  4195         ckfree ((char*) eeFrame.line);
  4196     }
  4197     if (eeFrame.type == TCL_LOCATION_SOURCE) {
  4198         Tcl_DecrRefCount (eeFrame.data.eval.path);
  4199     }
  4200 #endif
  4201     return code;
  4202 }
  4203 
  4204 #ifdef TCL_TIP280
  4205 /*
  4206  *----------------------------------------------------------------------
  4207  *
  4208  * TclAdvanceLines --
  4209  *
  4210  *	This procedure is a helper which counts the number of lines
  4211  *	in a block of text and advances an external counter.
  4212  *
  4213  * Results:
  4214  *	None.
  4215  *
  4216  * Side effects:
  4217  *	The specified counter is advanced per the number of lines found.
  4218  *
  4219  * TIP #280
  4220  *----------------------------------------------------------------------
  4221  */
  4222 
  4223 void
  4224 TclAdvanceLines (line,start,end)
  4225      int*        line;
  4226      CONST char* start;
  4227      CONST char* end;
  4228 {
  4229     CONST char* p;
  4230     for (p = start; p < end; p++) {
  4231         if (*p == '\n') {
  4232 	  (*line) ++;
  4233 	}
  4234     }
  4235 }
  4236 #endif
  4237 
  4238 /*
  4239  *----------------------------------------------------------------------
  4240  *
  4241  * Tcl_Eval --
  4242  *
  4243  *	Execute a Tcl command in a string.  This procedure executes the
  4244  *	script directly, rather than compiling it to bytecodes.  Before
  4245  *	the arrival of the bytecode compiler in Tcl 8.0 Tcl_Eval was
  4246  *	the main procedure used for executing Tcl commands, but nowadays
  4247  *	it isn't used much.
  4248  *
  4249  * Results:
  4250  *	The return value is one of the return codes defined in tcl.h
  4251  *	(such as TCL_OK), and interp's result contains a value
  4252  *	to supplement the return code. The value of the result
  4253  *	will persist only until the next call to Tcl_Eval or Tcl_EvalObj:
  4254  *	you must copy it or lose it!
  4255  *
  4256  * Side effects:
  4257  *	Can be almost arbitrary, depending on the commands in the script.
  4258  *
  4259  *----------------------------------------------------------------------
  4260  */
  4261 
  4262 EXPORT_C int
  4263 Tcl_Eval(interp, string)
  4264     Tcl_Interp *interp;		/* Token for command interpreter (returned
  4265 				 * by previous call to Tcl_CreateInterp). */
  4266     CONST char *string;		/* Pointer to TCL command to execute. */
  4267 {
  4268     int code = Tcl_EvalEx(interp, string, -1, 0);
  4269 
  4270     /*
  4271      * For backwards compatibility with old C code that predates the
  4272      * object system in Tcl 8.0, we have to mirror the object result
  4273      * back into the string result (some callers may expect it there).
  4274      */
  4275 
  4276     Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
  4277 	    TCL_VOLATILE);
  4278     return code;
  4279 }
  4280 
  4281 /*
  4282  *----------------------------------------------------------------------
  4283  *
  4284  * Tcl_EvalObj, Tcl_GlobalEvalObj --
  4285  *
  4286  *	These functions are deprecated but we keep them around for backwards
  4287  *	compatibility reasons.
  4288  *
  4289  * Results:
  4290  *	See the functions they call.
  4291  *
  4292  * Side effects:
  4293  *	See the functions they call.
  4294  *
  4295  *----------------------------------------------------------------------
  4296  */
  4297 
  4298 #undef Tcl_EvalObj
  4299 EXPORT_C int
  4300 Tcl_EvalObj(interp, objPtr)
  4301     Tcl_Interp * interp;
  4302     Tcl_Obj * objPtr;
  4303 {
  4304     return Tcl_EvalObjEx(interp, objPtr, 0);
  4305 }
  4306 
  4307 #undef Tcl_GlobalEvalObj
  4308 EXPORT_C int
  4309 Tcl_GlobalEvalObj(interp, objPtr)
  4310     Tcl_Interp * interp;
  4311     Tcl_Obj * objPtr;
  4312 {
  4313     return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL);
  4314 }
  4315 
  4316 /*
  4317  *----------------------------------------------------------------------
  4318  *
  4319  * Tcl_EvalObjEx, TclEvalObjEx --
  4320  *
  4321  *	Execute Tcl commands stored in a Tcl object. These commands are
  4322  *	compiled into bytecodes if necessary, unless TCL_EVAL_DIRECT
  4323  *	is specified.
  4324  *
  4325  * Results:
  4326  *	The return value is one of the return codes defined in tcl.h
  4327  *	(such as TCL_OK), and the interpreter's result contains a value
  4328  *	to supplement the return code.
  4329  *
  4330  * Side effects:
  4331  *	The object is converted, if necessary, to a ByteCode object that
  4332  *	holds the bytecode instructions for the commands. Executing the
  4333  *	commands will almost certainly have side effects that depend
  4334  *	on those commands.
  4335  *
  4336  *	Just as in Tcl_Eval, interp->termOffset is set to the offset of the
  4337  *	last character executed in the objPtr's string.
  4338  *
  4339  * TIP #280 : Keep public API, internally extended API.
  4340  *----------------------------------------------------------------------
  4341  */
  4342 
  4343 EXPORT_C int
  4344 Tcl_EvalObjEx(interp, objPtr, flags)
  4345     Tcl_Interp *interp;			/* Token for command interpreter
  4346 					 * (returned by a previous call to
  4347 					 * Tcl_CreateInterp). */
  4348     register Tcl_Obj *objPtr;		/* Pointer to object containing
  4349 					 * commands to execute. */
  4350     int flags;				/* Collection of OR-ed bits that
  4351 					 * control the evaluation of the
  4352 					 * script.  Supported values are
  4353 					 * TCL_EVAL_GLOBAL and
  4354 					 * TCL_EVAL_DIRECT. */
  4355 {
  4356 #ifdef TCL_TIP280
  4357   return TclEvalObjEx (interp, objPtr, flags, NULL, 0);
  4358 }
  4359 
  4360 int
  4361 TclEvalObjEx(interp, objPtr, flags, invoker, word)
  4362     Tcl_Interp *interp;			/* Token for command interpreter
  4363 					 * (returned by a previous call to
  4364 					 * Tcl_CreateInterp). */
  4365     register Tcl_Obj *objPtr;		/* Pointer to object containing
  4366 					 * commands to execute. */
  4367     int flags;				/* Collection of OR-ed bits that
  4368 					 * control the evaluation of the
  4369 					 * script.  Supported values are
  4370 					 * TCL_EVAL_GLOBAL and
  4371 					 * TCL_EVAL_DIRECT. */
  4372     CONST CmdFrame* invoker; /* Frame of the command doing the eval  */
  4373     int             word;    /* Index of the word which is in objPtr */
  4374 {
  4375 #endif
  4376     register Interp *iPtr = (Interp *) interp;
  4377     char *script;
  4378     int numSrcBytes;
  4379     int result;
  4380     CallFrame *savedVarFramePtr;	/* Saves old copy of iPtr->varFramePtr
  4381 					 * in case TCL_EVAL_GLOBAL was set. */
  4382     int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS);
  4383 
  4384     Tcl_IncrRefCount(objPtr);
  4385 
  4386     if ((iPtr->flags & USE_EVAL_DIRECT) || (flags & TCL_EVAL_DIRECT)) {
  4387 	/*
  4388 	 * We're not supposed to use the compiler or byte-code interpreter.
  4389 	 * Let Tcl_EvalEx evaluate the command directly (and probably
  4390 	 * more slowly).
  4391 	 *
  4392 	 * Pure List Optimization (no string representation).  In this
  4393 	 * case, we can safely use Tcl_EvalObjv instead and get an
  4394 	 * appreciable improvement in execution speed.  This is because it
  4395 	 * allows us to avoid a setFromAny step that would just pack
  4396 	 * everything into a string and back out again.
  4397 	 *
  4398 	 * USE_EVAL_DIRECT is a special flag used for testing purpose only
  4399 	 * (ensure we go into the TCL_EVAL_DIRECT path, avoiding opt)
  4400 	 */
  4401 	if (!(iPtr->flags & USE_EVAL_DIRECT) &&
  4402 		(objPtr->typePtr == &tclListType) && /* is a list... */
  4403 		(objPtr->bytes == NULL) /* ...without a string rep */) {
  4404 	    register List *listRepPtr =
  4405 		(List *) objPtr->internalRep.twoPtrValue.ptr1;
  4406 	    int i, objc = listRepPtr->elemCount;
  4407 
  4408 #define TEOE_PREALLOC 10
  4409 	    Tcl_Obj *staticObjv[TEOE_PREALLOC], **objv = staticObjv;
  4410 
  4411 #ifdef TCL_TIP280
  4412 	    /* TIP #280 Structures for tracking lines.
  4413 	     * As we know that this is dynamic execution we ignore the
  4414 	     * invoker, even if known.
  4415 	     */
  4416 	    int      line;
  4417 	    CmdFrame eoFrame;
  4418 
  4419 	    eoFrame.type     = TCL_LOCATION_EVAL_LIST;
  4420 	    eoFrame.level    = (iPtr->cmdFramePtr == NULL ?
  4421 				1 :
  4422 				iPtr->cmdFramePtr->level + 1);
  4423 	    eoFrame.framePtr = iPtr->framePtr;
  4424 	    eoFrame.nextPtr  = iPtr->cmdFramePtr;
  4425 	    eoFrame.nline    = objc;
  4426 	    eoFrame.line     = (int*) ckalloc (objc * sizeof (int));
  4427 
  4428 	    /* NOTE: Getting the string rep of the list to eval to fill the
  4429 	     * command information required by 'info frame' implies that
  4430 	     * further calls for the same list would not be optimized, as it
  4431 	     * would not be 'pure' anymore. It would also be a waste of time
  4432 	     * as most of the time this information is not needed at all. What
  4433 	     * we do instead is to keep the list obj itself around and have
  4434 	     * 'info frame' sort it out.
  4435 	     */
  4436 
  4437 	    eoFrame.cmd.listPtr  = objPtr;
  4438 	    Tcl_IncrRefCount (eoFrame.cmd.listPtr);
  4439 	    eoFrame.data.eval.path = NULL;
  4440 #endif
  4441 	    if (objc > TEOE_PREALLOC) {
  4442 		objv = (Tcl_Obj **) ckalloc(objc*sizeof(Tcl_Obj *));
  4443 	    }
  4444 #undef TEOE_PREALLOC
  4445 	    /*
  4446 	     * Copy the list elements here, to avoid a segfault if
  4447 	     * objPtr loses its List internal rep [Bug 1119369].
  4448 	     *
  4449 	     * TIP #280 Computes all the line numbers for the
  4450 	     * words in the command.
  4451 	     */
  4452 
  4453 #ifdef TCL_TIP280
  4454 	    line = 1;
  4455 #endif
  4456 	    for (i=0; i < objc; i++) {
  4457 		objv[i] = listRepPtr->elements[i];
  4458 		Tcl_IncrRefCount(objv[i]);
  4459 #ifdef TCL_TIP280
  4460 		eoFrame.line [i] = line;
  4461 		{
  4462 		    char* w = Tcl_GetString (objv [i]);
  4463 		    TclAdvanceLines (&line, w, w+ strlen(w));
  4464 		}
  4465 #endif
  4466 	    }
  4467 
  4468 #ifdef TCL_TIP280
  4469 	    iPtr->cmdFramePtr = &eoFrame;
  4470 #endif
  4471 	    result = Tcl_EvalObjv(interp, objc, objv, flags);
  4472 #ifdef TCL_TIP280
  4473 	    iPtr->cmdFramePtr = iPtr->cmdFramePtr->nextPtr;
  4474 	    Tcl_DecrRefCount (eoFrame.cmd.listPtr);
  4475 #endif
  4476 
  4477 	    for (i=0; i < objc; i++) {
  4478 		TclDecrRefCount(objv[i]);
  4479 	    }
  4480 	    if (objv != staticObjv) {
  4481 		ckfree((char *) objv);
  4482 	    }
  4483 #ifdef TCL_TIP280
  4484 	    ckfree ((char*) eoFrame.line);
  4485 	    eoFrame.line  = NULL;
  4486 	    eoFrame.nline = 0;
  4487 #endif
  4488 	} else {
  4489 #ifndef TCL_TIP280
  4490 	    script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
  4491 	    result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
  4492 #else
  4493 	    /*
  4494 	     * TIP #280. Propagate context as much as we can. Especially if
  4495 	     * the script to evaluate is a single literal it makes sense to
  4496 	     * look if our context is one with absolute line numbers we can
  4497 	     * then track into the literal itself too.
  4498 	     *
  4499 	     * See also tclCompile.c, TclInitCompileEnv, for the equivalent
  4500 	     * code in the bytecode compiler.
  4501 	     */
  4502 
  4503 	    if (invoker == NULL) {
  4504 	        /* No context, force opening of our own */
  4505 	        script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
  4506 		result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
  4507 	    } else {
  4508 		/* We have an invoker, describing the command asking for the
  4509 		 * evaluation of a subordinate script. This script may
  4510 		 * originate in a literal word, or from a variable, etc. Using
  4511 		 * the line array we now check if we have good line
  4512 		 * information for the relevant word. The type of context is
  4513 		 * relevant as well. In a non-'source' context we don't have
  4514 		 * to try tracking lines.
  4515 		 *
  4516 		 * First see if the word exists and is a literal. If not we go
  4517 		 * through the easy dynamic branch. No need to perform more
  4518 		 * complex invokations.
  4519 		 */
  4520 
  4521 		if ((invoker->nline <= word) || (invoker->line[word] < 0)) {
  4522 		    /* Dynamic script, or dynamic context, force our own
  4523 		     * context */
  4524 
  4525 		    script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
  4526 		    result = Tcl_EvalEx(interp, script,    numSrcBytes, flags);
  4527 
  4528 		} else {
  4529 		    /*  Try to get an absolute context for the evaluation
  4530 		     */
  4531 
  4532 		    CmdFrame ctx = *invoker;
  4533 		    int pc       = 0;
  4534 
  4535 		    if (invoker->type == TCL_LOCATION_BC) {
  4536 			/* Note: Type BC => ctx.data.eval.path    is not used.
  4537 			 *                  ctx.data.tebc.codePtr is used instead.
  4538 			 */
  4539 			TclGetSrcInfoForPc (&ctx);
  4540 			pc = 1;
  4541 		    }
  4542 
  4543 		    if (ctx.type == TCL_LOCATION_SOURCE) {
  4544 			/* Absolute context to reuse. */
  4545 
  4546 			iPtr->invokeCmdFramePtr = &ctx;
  4547 			iPtr->evalFlags |= TCL_EVAL_CTX;
  4548 
  4549 			script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
  4550 			result = EvalEx(interp, script, numSrcBytes, flags, ctx.line [word]);
  4551 
  4552 			if (pc) {
  4553 			    /* Death of SrcInfo reference */
  4554 			    Tcl_DecrRefCount (ctx.data.eval.path);
  4555 			}
  4556 		    } else {
  4557 			/* Dynamic context or script, easier to make our own as
  4558 			 * well */
  4559 			script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
  4560 			result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
  4561 		    }
  4562 		}
  4563 	    }
  4564 #endif
  4565 	}
  4566     } else {
  4567 	/*
  4568 	 * Let the compiler/engine subsystem do the evaluation.
  4569 	 *
  4570 	 * TIP #280 The invoker provides us with the context for the
  4571 	 * script. We transfer this to the byte code compiler.
  4572 	 */
  4573 
  4574 	savedVarFramePtr = iPtr->varFramePtr;
  4575 	if (flags & TCL_EVAL_GLOBAL) {
  4576 	    iPtr->varFramePtr = NULL;
  4577 	}
  4578 
  4579 #ifndef TCL_TIP280
  4580 	result = TclCompEvalObj(interp, objPtr);
  4581 #else
  4582 	result = TclCompEvalObj(interp, objPtr, invoker, word);
  4583 #endif
  4584 
  4585 	/*
  4586 	 * If we are again at the top level, process any unusual 
  4587 	 * return code returned by the evaluated code. 
  4588 	 */
  4589 	
  4590 	if (iPtr->numLevels == 0) {
  4591 	    if (result == TCL_RETURN) {
  4592 		result = TclUpdateReturnInfo(iPtr);
  4593 	    }
  4594 	    if ((result != TCL_OK) && (result != TCL_ERROR) 
  4595 	        && !allowExceptions) {
  4596 		ProcessUnexpectedResult(interp, result);
  4597 		result = TCL_ERROR;
  4598 
  4599 		/*
  4600 		 * If an error was created here, record information about 
  4601 		 * what was being executed when the error occurred. Remove
  4602 		 * the extra \n added by tclMain.c in the command sent to
  4603 		 * Tcl_LogCommandInfo [Bug 833150].
  4604 		 */
  4605 
  4606 		if (!(iPtr->flags & ERR_ALREADY_LOGGED)) {
  4607 		    script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
  4608 		    Tcl_LogCommandInfo(interp, script, script, --numSrcBytes);
  4609 		    iPtr->flags &= ~ERR_ALREADY_LOGGED;
  4610 		}
  4611 	    }
  4612 	}
  4613 	iPtr->evalFlags = 0;
  4614 	iPtr->varFramePtr = savedVarFramePtr; 
  4615     }
  4616 
  4617     TclDecrRefCount(objPtr);
  4618     return result;
  4619 }
  4620 
  4621 /*
  4622  *----------------------------------------------------------------------
  4623  *
  4624  * ProcessUnexpectedResult --
  4625  *
  4626  *	Procedure called by Tcl_EvalObj to set the interpreter's result
  4627  *	value to an appropriate error message when the code it evaluates
  4628  *	returns an unexpected result code (not TCL_OK and not TCL_ERROR) to
  4629  *	the topmost evaluation level.
  4630  *
  4631  * Results:
  4632  *	None.
  4633  *
  4634  * Side effects:
  4635  *	The interpreter result is set to an error message appropriate to
  4636  *	the result code.
  4637  *
  4638  *----------------------------------------------------------------------
  4639  */
  4640 
  4641 static void
  4642 ProcessUnexpectedResult(interp, returnCode)
  4643     Tcl_Interp *interp;		/* The interpreter in which the unexpected
  4644 				 * result code was returned. */
  4645     int returnCode;		/* The unexpected result code. */
  4646 {
  4647     Tcl_ResetResult(interp);
  4648     if (returnCode == TCL_BREAK) {
  4649 	Tcl_AppendToObj(Tcl_GetObjResult(interp),
  4650 	        "invoked \"break\" outside of a loop", -1);
  4651     } else if (returnCode == TCL_CONTINUE) {
  4652 	Tcl_AppendToObj(Tcl_GetObjResult(interp),
  4653 		"invoked \"continue\" outside of a loop", -1);
  4654     } else {
  4655         char buf[30 + TCL_INTEGER_SPACE];
  4656 
  4657 	sprintf(buf, "command returned bad code: %d", returnCode);
  4658 	Tcl_SetResult(interp, buf, TCL_VOLATILE);
  4659     }
  4660 }
  4661 
  4662 /*
  4663  *---------------------------------------------------------------------------
  4664  *
  4665  * Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean --
  4666  *
  4667  *	Procedures to evaluate an expression and return its value in a
  4668  *	particular form.
  4669  *
  4670  * Results:
  4671  *	Each of the procedures below returns a standard Tcl result. If an
  4672  *	error occurs then an error message is left in the interp's result.
  4673  *	Otherwise the value of the expression, in the appropriate form,
  4674  *	is stored at *ptr. If the expression had a result that was
  4675  *	incompatible with the desired form then an error is returned.
  4676  *
  4677  * Side effects:
  4678  *	None.
  4679  *
  4680  *---------------------------------------------------------------------------
  4681  */
  4682 
  4683 EXPORT_C int
  4684 Tcl_ExprLong(interp, string, ptr)
  4685     Tcl_Interp *interp;		/* Context in which to evaluate the
  4686 				 * expression. */
  4687     CONST char *string;		/* Expression to evaluate. */
  4688     long *ptr;			/* Where to store result. */
  4689 {
  4690     register Tcl_Obj *exprPtr;
  4691     Tcl_Obj *resultPtr;
  4692     int length = strlen(string);
  4693     int result = TCL_OK;
  4694 
  4695     if (length > 0) {
  4696 	exprPtr = Tcl_NewStringObj(string, length);
  4697 	Tcl_IncrRefCount(exprPtr);
  4698 	result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
  4699 	if (result == TCL_OK) {
  4700 	    /*
  4701 	     * Store an integer based on the expression result.
  4702 	     */
  4703 
  4704 	    if (resultPtr->typePtr == &tclIntType) {
  4705 		*ptr = resultPtr->internalRep.longValue;
  4706 	    } else if (resultPtr->typePtr == &tclDoubleType) {
  4707 		*ptr = (long) resultPtr->internalRep.doubleValue;
  4708 	    } else if (resultPtr->typePtr == &tclWideIntType) {
  4709 #ifndef TCL_WIDE_INT_IS_LONG
  4710 		/*
  4711 		 * See Tcl_GetIntFromObj for conversion comments.
  4712 		 */
  4713 		Tcl_WideInt w = resultPtr->internalRep.wideValue;
  4714 		if ((w >= -(Tcl_WideInt)(ULONG_MAX))
  4715 			&& (w <= (Tcl_WideInt)(ULONG_MAX))) {
  4716 		    *ptr = Tcl_WideAsLong(w);
  4717 		} else {
  4718 		    Tcl_SetResult(interp,
  4719 			    "integer value too large to represent as non-long integer",
  4720 			    TCL_STATIC);
  4721 		    result = TCL_ERROR;
  4722 		}
  4723 #else
  4724 		*ptr = resultPtr->internalRep.longValue;
  4725 #endif
  4726 	    } else {
  4727 		Tcl_SetResult(interp,
  4728 		        "expression didn't have numeric value", TCL_STATIC);
  4729 		result = TCL_ERROR;
  4730 	    }
  4731 	    Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  4732 	} else {
  4733 	    /*
  4734 	     * Move the interpreter's object result to the string result, 
  4735 	     * then reset the object result.
  4736 	     */
  4737 
  4738 	    Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
  4739 	            TCL_VOLATILE);
  4740 	}
  4741 	Tcl_DecrRefCount(exprPtr);  /* discard the expression object */	
  4742     } else {
  4743 	/*
  4744 	 * An empty string. Just set the result integer to 0.
  4745 	 */
  4746 	
  4747 	*ptr = 0;
  4748     }
  4749     return result;
  4750 }
  4751 
  4752 EXPORT_C int
  4753 Tcl_ExprDouble(interp, string, ptr)
  4754     Tcl_Interp *interp;		/* Context in which to evaluate the
  4755 				 * expression. */
  4756     CONST char *string;		/* Expression to evaluate. */
  4757     double *ptr;		/* Where to store result. */
  4758 {
  4759     register Tcl_Obj *exprPtr;
  4760     Tcl_Obj *resultPtr;
  4761     int length = strlen(string);
  4762     int result = TCL_OK;
  4763 
  4764     if (length > 0) {
  4765 	exprPtr = Tcl_NewStringObj(string, length);
  4766 	Tcl_IncrRefCount(exprPtr);
  4767 	result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
  4768 	if (result == TCL_OK) {
  4769 	    /*
  4770 	     * Store a double  based on the expression result.
  4771 	     */
  4772 
  4773 	    if (resultPtr->typePtr == &tclIntType) {
  4774 		*ptr = (double) resultPtr->internalRep.longValue;
  4775 	    } else if (resultPtr->typePtr == &tclDoubleType) {
  4776 		*ptr = resultPtr->internalRep.doubleValue;
  4777 	    } else if (resultPtr->typePtr == &tclWideIntType) {
  4778 #ifndef TCL_WIDE_INT_IS_LONG
  4779 		/*
  4780 		 * See Tcl_GetIntFromObj for conversion comments.
  4781 		 */
  4782 		Tcl_WideInt w = resultPtr->internalRep.wideValue;
  4783 		if ((w >= -(Tcl_WideInt)(ULONG_MAX))
  4784 			&& (w <= (Tcl_WideInt)(ULONG_MAX))) {
  4785 		    *ptr = (double) Tcl_WideAsLong(w);
  4786 		} else {
  4787 		    Tcl_SetResult(interp,
  4788 			    "integer value too large to represent as non-long integer",
  4789 			    TCL_STATIC);
  4790 		    result = TCL_ERROR;
  4791 		}
  4792 #else
  4793 		*ptr = (double) resultPtr->internalRep.longValue;
  4794 #endif
  4795 	    } else {
  4796 		Tcl_SetResult(interp,
  4797 		        "expression didn't have numeric value", TCL_STATIC);
  4798 		result = TCL_ERROR;
  4799 	    }
  4800 	    Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  4801 	} else {
  4802 	    /*
  4803 	     * Move the interpreter's object result to the string result, 
  4804 	     * then reset the object result.
  4805 	     */
  4806 
  4807 	    Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
  4808 	            TCL_VOLATILE);
  4809 	}
  4810 	Tcl_DecrRefCount(exprPtr);  /* discard the expression object */
  4811     } else {
  4812 	/*
  4813 	 * An empty string. Just set the result double to 0.0.
  4814 	 */
  4815 	
  4816 	*ptr = 0.0;
  4817     }
  4818     return result;
  4819 }
  4820 
  4821 EXPORT_C int
  4822 Tcl_ExprBoolean(interp, string, ptr)
  4823     Tcl_Interp *interp;		/* Context in which to evaluate the
  4824 			         * expression. */
  4825     CONST char *string;		/* Expression to evaluate. */
  4826     int *ptr;			/* Where to store 0/1 result. */
  4827 {
  4828     register Tcl_Obj *exprPtr;
  4829     Tcl_Obj *resultPtr;
  4830     int length = strlen(string);
  4831     int result = TCL_OK;
  4832 
  4833     if (length > 0) {
  4834 	exprPtr = Tcl_NewStringObj(string, length);
  4835 	Tcl_IncrRefCount(exprPtr);
  4836 	result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
  4837 	if (result == TCL_OK) {
  4838 	    /*
  4839 	     * Store a boolean based on the expression result.
  4840 	     */
  4841 
  4842 	    if (resultPtr->typePtr == &tclIntType) {
  4843 		*ptr = (resultPtr->internalRep.longValue != 0);
  4844 	    } else if (resultPtr->typePtr == &tclDoubleType) {
  4845 		*ptr = (resultPtr->internalRep.doubleValue != 0.0);
  4846 	    } else if (resultPtr->typePtr == &tclWideIntType) {
  4847 #ifndef TCL_WIDE_INT_IS_LONG
  4848 		*ptr = (resultPtr->internalRep.wideValue != 0);
  4849 #else
  4850 		*ptr = (resultPtr->internalRep.longValue != 0);
  4851 #endif
  4852 	    } else {
  4853 		result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);
  4854 	    }
  4855 	    Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  4856 	}
  4857 	if (result != TCL_OK) {
  4858 	    /*
  4859 	     * Move the interpreter's object result to the string result, 
  4860 	     * then reset the object result.
  4861 	     */
  4862 
  4863 	    Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
  4864 	            TCL_VOLATILE);
  4865 	}
  4866 	Tcl_DecrRefCount(exprPtr); /* discard the expression object */
  4867     } else {
  4868 	/*
  4869 	 * An empty string. Just set the result boolean to 0 (false).
  4870 	 */
  4871 	
  4872 	*ptr = 0;
  4873     }
  4874     return result;
  4875 }
  4876 
  4877 /*
  4878  *--------------------------------------------------------------
  4879  *
  4880  * Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj --
  4881  *
  4882  *	Procedures to evaluate an expression in an object and return its
  4883  *	value in a particular form.
  4884  *
  4885  * Results:
  4886  *	Each of the procedures below returns a standard Tcl result
  4887  *	object. If an error occurs then an error message is left in the
  4888  *	interpreter's result. Otherwise the value of the expression, in the
  4889  *	appropriate form, is stored at *ptr. If the expression had a result
  4890  *	that was incompatible with the desired form then an error is
  4891  *	returned.
  4892  *
  4893  * Side effects:
  4894  *	None.
  4895  *
  4896  *--------------------------------------------------------------
  4897  */
  4898 
  4899 EXPORT_C int
  4900 Tcl_ExprLongObj(interp, objPtr, ptr)
  4901     Tcl_Interp *interp;			/* Context in which to evaluate the
  4902 					 * expression. */
  4903     register Tcl_Obj *objPtr;		/* Expression to evaluate. */
  4904     long *ptr;				/* Where to store long result. */
  4905 {
  4906     Tcl_Obj *resultPtr;
  4907     int result;
  4908 
  4909     result = Tcl_ExprObj(interp, objPtr, &resultPtr);
  4910     if (result == TCL_OK) {
  4911 	if (resultPtr->typePtr == &tclIntType) {
  4912 	    *ptr = resultPtr->internalRep.longValue;
  4913 	} else if (resultPtr->typePtr == &tclDoubleType) {
  4914 	    *ptr = (long) resultPtr->internalRep.doubleValue;
  4915 	} else {
  4916 	    result = Tcl_GetLongFromObj(interp, resultPtr, ptr);
  4917 	    if (result != TCL_OK) {
  4918 		return result;
  4919 	    }
  4920 	}
  4921 	Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  4922     }
  4923     return result;
  4924 }
  4925 
  4926 EXPORT_C int
  4927 Tcl_ExprDoubleObj(interp, objPtr, ptr)
  4928     Tcl_Interp *interp;			/* Context in which to evaluate the
  4929 					 * expression. */
  4930     register Tcl_Obj *objPtr;		/* Expression to evaluate. */
  4931     double *ptr;			/* Where to store double result. */
  4932 {
  4933     Tcl_Obj *resultPtr;
  4934     int result;
  4935 
  4936     result = Tcl_ExprObj(interp, objPtr, &resultPtr);
  4937     if (result == TCL_OK) {
  4938 	if (resultPtr->typePtr == &tclIntType) {
  4939 	    *ptr = (double) resultPtr->internalRep.longValue;
  4940 	} else if (resultPtr->typePtr == &tclDoubleType) {
  4941 	    *ptr = resultPtr->internalRep.doubleValue;
  4942 	} else {
  4943 	    result = Tcl_GetDoubleFromObj(interp, resultPtr, ptr);
  4944 	    if (result != TCL_OK) {
  4945 		return result;
  4946 	    }
  4947 	}
  4948 	Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  4949     }
  4950     return result;
  4951 }
  4952 
  4953 EXPORT_C int
  4954 Tcl_ExprBooleanObj(interp, objPtr, ptr)
  4955     Tcl_Interp *interp;			/* Context in which to evaluate the
  4956 					 * expression. */
  4957     register Tcl_Obj *objPtr;		/* Expression to evaluate. */
  4958     int *ptr;				/* Where to store 0/1 result. */
  4959 {
  4960     Tcl_Obj *resultPtr;
  4961     int result;
  4962 
  4963     result = Tcl_ExprObj(interp, objPtr, &resultPtr);
  4964     if (result == TCL_OK) {
  4965 	if (resultPtr->typePtr == &tclIntType) {
  4966 	    *ptr = (resultPtr->internalRep.longValue != 0);
  4967 	} else if (resultPtr->typePtr == &tclDoubleType) {
  4968 	    *ptr = (resultPtr->internalRep.doubleValue != 0.0);
  4969 	} else {
  4970 	    result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);
  4971 	}
  4972 	Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  4973     }
  4974     return result;
  4975 }
  4976 
  4977 /*
  4978  *----------------------------------------------------------------------
  4979  *
  4980  * TclInvoke --
  4981  *
  4982  *	Invokes a Tcl command, given an argv/argc, from either the
  4983  *	exposed or the hidden sets of commands in the given interpreter.
  4984  *	NOTE: The command is invoked in the current stack frame of
  4985  *	the interpreter, thus it can modify local variables.
  4986  *
  4987  * Results:
  4988  *	A standard Tcl result.
  4989  *
  4990  * Side effects:
  4991  *	Whatever the command does.
  4992  *
  4993  *----------------------------------------------------------------------
  4994  */
  4995 
  4996 int
  4997 TclInvoke(interp, argc, argv, flags)
  4998     Tcl_Interp *interp;		/* Where to invoke the command. */
  4999     int argc;			/* Count of args. */
  5000     register CONST char **argv;	/* The arg strings; argv[0] is the name of
  5001                                  * the command to invoke. */
  5002     int flags;			/* Combination of flags controlling the
  5003 				 * call: TCL_INVOKE_HIDDEN and
  5004 				 * TCL_INVOKE_NO_UNKNOWN. */
  5005 {
  5006     register Tcl_Obj *objPtr;
  5007     register int i;
  5008     int length, result;
  5009 
  5010     /*
  5011      * This procedure generates an objv array for object arguments that hold
  5012      * the argv strings. It starts out with stack-allocated space but uses
  5013      * dynamically-allocated storage if needed.
  5014      */
  5015 
  5016 #define NUM_ARGS 20
  5017     Tcl_Obj *(objStorage[NUM_ARGS]);
  5018     register Tcl_Obj **objv = objStorage;
  5019 
  5020     /*
  5021      * Create the object argument array "objv". Make sure objv is large
  5022      * enough to hold the objc arguments plus 1 extra for the zero
  5023      * end-of-objv word.
  5024      */
  5025 
  5026     if ((argc + 1) > NUM_ARGS) {
  5027 	objv = (Tcl_Obj **)
  5028 	    ckalloc((unsigned)(argc + 1) * sizeof(Tcl_Obj *));
  5029     }
  5030 
  5031     for (i = 0;  i < argc;  i++) {
  5032 	length = strlen(argv[i]);
  5033 	objv[i] = Tcl_NewStringObj(argv[i], length);
  5034 	Tcl_IncrRefCount(objv[i]);
  5035     }
  5036     objv[argc] = 0;
  5037 
  5038     /*
  5039      * Use TclObjInterpProc to actually invoke the command.
  5040      */
  5041 
  5042     result = TclObjInvoke(interp, argc, objv, flags);
  5043 
  5044     /*
  5045      * Move the interpreter's object result to the string result, 
  5046      * then reset the object result.
  5047      */
  5048     
  5049     Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
  5050 	    TCL_VOLATILE);
  5051 
  5052     /*
  5053      * Decrement the ref counts on the objv elements since we are done
  5054      * with them.
  5055      */
  5056 
  5057     for (i = 0;  i < argc;  i++) {
  5058 	objPtr = objv[i];
  5059 	Tcl_DecrRefCount(objPtr);
  5060     }
  5061     
  5062     /*
  5063      * Free the objv array if malloc'ed storage was used.
  5064      */
  5065 
  5066     if (objv != objStorage) {
  5067 	ckfree((char *) objv);
  5068     }
  5069     return result;
  5070 #undef NUM_ARGS
  5071 }
  5072 
  5073 /*
  5074  *----------------------------------------------------------------------
  5075  *
  5076  * TclGlobalInvoke --
  5077  *
  5078  *	Invokes a Tcl command, given an argv/argc, from either the
  5079  *	exposed or hidden sets of commands in the given interpreter.
  5080  *	NOTE: The command is invoked in the global stack frame of
  5081  *	the interpreter, thus it cannot see any current state on
  5082  *	the stack for that interpreter.
  5083  *
  5084  * Results:
  5085  *	A standard Tcl result.
  5086  *
  5087  * Side effects:
  5088  *	Whatever the command does.
  5089  *
  5090  *----------------------------------------------------------------------
  5091  */
  5092 
  5093 int
  5094 TclGlobalInvoke(interp, argc, argv, flags)
  5095     Tcl_Interp *interp;		/* Where to invoke the command. */
  5096     int argc;			/* Count of args. */
  5097     register CONST char **argv;	/* The arg strings; argv[0] is the name of
  5098                                  * the command to invoke. */
  5099     int flags;			/* Combination of flags controlling the
  5100 				 * call: TCL_INVOKE_HIDDEN and
  5101 				 * TCL_INVOKE_NO_UNKNOWN. */
  5102 {
  5103     register Interp *iPtr = (Interp *) interp;
  5104     int result;
  5105     CallFrame *savedVarFramePtr;
  5106 
  5107     savedVarFramePtr = iPtr->varFramePtr;
  5108     iPtr->varFramePtr = NULL;
  5109     result = TclInvoke(interp, argc, argv, flags);
  5110     iPtr->varFramePtr = savedVarFramePtr;
  5111     return result;
  5112 }
  5113 
  5114 /*
  5115  *----------------------------------------------------------------------
  5116  *
  5117  * TclObjInvokeGlobal --
  5118  *
  5119  *	Object version: Invokes a Tcl command, given an objv/objc, from
  5120  *	either the exposed or hidden set of commands in the given
  5121  *	interpreter.
  5122  *	NOTE: The command is invoked in the global stack frame of the
  5123  *	interpreter, thus it cannot see any current state on the
  5124  *	stack of that interpreter.
  5125  *
  5126  * Results:
  5127  *	A standard Tcl result.
  5128  *
  5129  * Side effects:
  5130  *	Whatever the command does.
  5131  *
  5132  *----------------------------------------------------------------------
  5133  */
  5134 
  5135 int
  5136 TclObjInvokeGlobal(interp, objc, objv, flags)
  5137     Tcl_Interp *interp;		/* Interpreter in which command is to be
  5138 				 * invoked. */
  5139     int objc;			/* Count of arguments. */
  5140     Tcl_Obj *CONST objv[];	/* Argument objects; objv[0] points to the
  5141 				 * name of the command to invoke. */
  5142     int flags;			/* Combination of flags controlling the
  5143 				 * call: TCL_INVOKE_HIDDEN,
  5144 				 * TCL_INVOKE_NO_UNKNOWN, or
  5145 				 * TCL_INVOKE_NO_TRACEBACK. */
  5146 {
  5147     register Interp *iPtr = (Interp *) interp;
  5148     int result;
  5149     CallFrame *savedVarFramePtr;
  5150 
  5151     savedVarFramePtr = iPtr->varFramePtr;
  5152     iPtr->varFramePtr = NULL;
  5153     result = TclObjInvoke(interp, objc, objv, flags);
  5154     iPtr->varFramePtr = savedVarFramePtr;
  5155     return result;
  5156 }
  5157 
  5158 /*
  5159  *----------------------------------------------------------------------
  5160  *
  5161  * TclObjInvoke --
  5162  *
  5163  *	Invokes a Tcl command, given an objv/objc, from either the
  5164  *	exposed or the hidden sets of commands in the given interpreter.
  5165  *
  5166  * Results:
  5167  *	A standard Tcl object result.
  5168  *
  5169  * Side effects:
  5170  *	Whatever the command does.
  5171  *
  5172  *----------------------------------------------------------------------
  5173  */
  5174 
  5175 int
  5176 TclObjInvoke(interp, objc, objv, flags)
  5177     Tcl_Interp *interp;		/* Interpreter in which command is to be
  5178 				 * invoked. */
  5179     int objc;			/* Count of arguments. */
  5180     Tcl_Obj *CONST objv[];	/* Argument objects; objv[0] points to the
  5181 				 * name of the command to invoke. */
  5182     int flags;			/* Combination of flags controlling the
  5183 				 * call: TCL_INVOKE_HIDDEN,
  5184 				 * TCL_INVOKE_NO_UNKNOWN, or
  5185 				 * TCL_INVOKE_NO_TRACEBACK. */
  5186 {
  5187     register Interp *iPtr = (Interp *) interp;
  5188     Tcl_HashTable *hTblPtr;	/* Table of hidden commands. */
  5189     char *cmdName;		/* Name of the command from objv[0]. */
  5190     register Tcl_HashEntry *hPtr;
  5191     Tcl_Command cmd;
  5192     Command *cmdPtr;
  5193     int localObjc;		/* Used to invoke "unknown" if the */
  5194     Tcl_Obj **localObjv = NULL;	/* command is not found. */
  5195     register int i;
  5196     int result;
  5197 
  5198     if (interp == (Tcl_Interp *) NULL) {
  5199         return TCL_ERROR;
  5200     }
  5201 
  5202     if ((objc < 1) || (objv == (Tcl_Obj **) NULL)) {
  5203         Tcl_AppendToObj(Tcl_GetObjResult(interp),
  5204 	        "illegal argument vector", -1);
  5205         return TCL_ERROR;
  5206     }
  5207 
  5208     cmdName = Tcl_GetString(objv[0]);
  5209     if (flags & TCL_INVOKE_HIDDEN) {
  5210         /*
  5211          * We never invoke "unknown" for hidden commands.
  5212          */
  5213         
  5214 	hPtr = NULL;
  5215         hTblPtr = ((Interp *) interp)->hiddenCmdTablePtr;
  5216         if (hTblPtr != NULL) {
  5217 	    hPtr = Tcl_FindHashEntry(hTblPtr, cmdName);
  5218 	}
  5219 	if (hPtr == NULL) {
  5220 	    Tcl_ResetResult(interp);
  5221 	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  5222 		     "invalid hidden command name \"", cmdName, "\"",
  5223 		     (char *) NULL);
  5224             return TCL_ERROR;
  5225         }
  5226 	cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
  5227     } else {
  5228 	cmdPtr = NULL;
  5229 	cmd = Tcl_FindCommand(interp, cmdName,
  5230 	        (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
  5231         if (cmd != (Tcl_Command) NULL) {
  5232 	    cmdPtr = (Command *) cmd;
  5233         }
  5234 	if (cmdPtr == NULL) {
  5235             if (!(flags & TCL_INVOKE_NO_UNKNOWN)) {
  5236 		cmd = Tcl_FindCommand(interp, "unknown",
  5237                         (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
  5238 		if (cmd != (Tcl_Command) NULL) {
  5239 	            cmdPtr = (Command *) cmd;
  5240                 }
  5241                 if (cmdPtr != NULL) {
  5242                     localObjc = (objc + 1);
  5243                     localObjv = (Tcl_Obj **)
  5244 			ckalloc((unsigned) (sizeof(Tcl_Obj *) * localObjc));
  5245 		    localObjv[0] = Tcl_NewStringObj("unknown", -1);
  5246 		    Tcl_IncrRefCount(localObjv[0]);
  5247                     for (i = 0;  i < objc;  i++) {
  5248                         localObjv[i+1] = objv[i];
  5249                     }
  5250                     objc = localObjc;
  5251                     objv = localObjv;
  5252                 }
  5253             }
  5254 
  5255             /*
  5256              * Check again if we found the command. If not, "unknown" is
  5257              * not present and we cannot help, or the caller said not to
  5258              * call "unknown" (they specified TCL_INVOKE_NO_UNKNOWN).
  5259              */
  5260 
  5261             if (cmdPtr == NULL) {
  5262 		Tcl_ResetResult(interp);
  5263 		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  5264 			"invalid command name \"",  cmdName, "\"", 
  5265 			 (char *) NULL);
  5266                 return TCL_ERROR;
  5267             }
  5268         }
  5269     }
  5270 
  5271     /*
  5272      * Invoke the command procedure. First reset the interpreter's string
  5273      * and object results to their default empty values since they could
  5274      * have gotten changed by earlier invocations.
  5275      */
  5276 
  5277     Tcl_ResetResult(interp);
  5278     iPtr->cmdCount++;
  5279     result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, objc, objv);
  5280 
  5281     /*
  5282      * If an error occurred, record information about what was being
  5283      * executed when the error occurred.
  5284      */
  5285 
  5286     if ((result == TCL_ERROR)
  5287 	    && ((flags & TCL_INVOKE_NO_TRACEBACK) == 0)
  5288 	    && ((iPtr->flags & ERR_ALREADY_LOGGED) == 0)) {
  5289 	Tcl_Obj *msg;
  5290         
  5291         if (!(iPtr->flags & ERR_IN_PROGRESS)) {
  5292             msg = Tcl_NewStringObj("\n    while invoking\n\"", -1);
  5293         } else {
  5294             msg = Tcl_NewStringObj("\n    invoked from within\n\"", -1);
  5295         }
  5296 	Tcl_IncrRefCount(msg);
  5297         for (i = 0;  i < objc;  i++) {
  5298 	    CONST char *bytes;
  5299 	    int length;
  5300 
  5301 	    Tcl_AppendObjToObj(msg, objv[i]);
  5302 	    bytes = Tcl_GetStringFromObj(msg, &length);
  5303 	    if (length > 100) {
  5304 		/*
  5305 		 * Back up truncation point so that we don't truncate
  5306 		 * in the middle of a multi-byte character.
  5307 		 */
  5308 		length = 100;
  5309 		while ( (bytes[length] & 0xC0) == 0x80 ) {
  5310 		    length--;
  5311 		}
  5312 		Tcl_SetObjLength(msg, length);
  5313 		Tcl_AppendToObj(msg, "...", -1);
  5314 		break;
  5315 	    }
  5316 	    if (i != (objc - 1)) {
  5317 		Tcl_AppendToObj(msg, " ", -1);
  5318 	    }
  5319         }
  5320 
  5321 	Tcl_AppendToObj(msg, "\"", -1);
  5322         Tcl_AddObjErrorInfo(interp, Tcl_GetString(msg), -1);
  5323 	Tcl_DecrRefCount(msg);
  5324 	iPtr->flags &= ~ERR_ALREADY_LOGGED;
  5325     }
  5326 
  5327     /*
  5328      * Free any locally allocated storage used to call "unknown".
  5329      */
  5330 
  5331     if (localObjv != (Tcl_Obj **) NULL) {
  5332 	Tcl_DecrRefCount(localObjv[0]);
  5333         ckfree((char *) localObjv);
  5334     }
  5335     return result;
  5336 }
  5337 
  5338 /*
  5339  *---------------------------------------------------------------------------
  5340  *
  5341  * Tcl_ExprString --
  5342  *
  5343  *	Evaluate an expression in a string and return its value in string
  5344  *	form.
  5345  *
  5346  * Results:
  5347  *	A standard Tcl result. If the result is TCL_OK, then the interp's
  5348  *	result is set to the string value of the expression. If the result
  5349  *	is TCL_ERROR, then the interp's result contains an error message.
  5350  *
  5351  * Side effects:
  5352  *	A Tcl object is allocated to hold a copy of the expression string.
  5353  *	This expression object is passed to Tcl_ExprObj and then
  5354  *	deallocated.
  5355  *
  5356  *---------------------------------------------------------------------------
  5357  */
  5358 
  5359 EXPORT_C int
  5360 Tcl_ExprString(interp, string)
  5361     Tcl_Interp *interp;		/* Context in which to evaluate the
  5362 				 * expression. */
  5363     CONST char *string;		/* Expression to evaluate. */
  5364 {
  5365     register Tcl_Obj *exprPtr;
  5366     Tcl_Obj *resultPtr;
  5367     int length = strlen(string);
  5368     char buf[TCL_DOUBLE_SPACE];
  5369     int result = TCL_OK;
  5370 
  5371     if (length > 0) {
  5372 	TclNewObj(exprPtr);
  5373 	TclInitStringRep(exprPtr, string, length);
  5374 	Tcl_IncrRefCount(exprPtr);
  5375 
  5376 	result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
  5377 	if (result == TCL_OK) {
  5378 	    /*
  5379 	     * Set the interpreter's string result from the result object.
  5380 	     */
  5381 	    
  5382 	    if (resultPtr->typePtr == &tclIntType) {
  5383 		sprintf(buf, "%ld", resultPtr->internalRep.longValue);
  5384 		Tcl_SetResult(interp, buf, TCL_VOLATILE);
  5385 	    } else if (resultPtr->typePtr == &tclDoubleType) {
  5386 		Tcl_PrintDouble((Tcl_Interp *) NULL,
  5387 		        resultPtr->internalRep.doubleValue, buf);
  5388 		Tcl_SetResult(interp, buf, TCL_VOLATILE);
  5389 	    } else {
  5390 		/*
  5391 		 * Set interpreter's string result from the result object.
  5392 		 */
  5393 	    
  5394 		Tcl_SetResult(interp, TclGetString(resultPtr),
  5395 		        TCL_VOLATILE);
  5396 	    }
  5397 	    Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  5398 	} else {
  5399 	    /*
  5400 	     * Move the interpreter's object result to the string result, 
  5401 	     * then reset the object result.
  5402 	     */
  5403 	    
  5404 	    Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
  5405 	            TCL_VOLATILE);
  5406 	}
  5407 	Tcl_DecrRefCount(exprPtr); /* discard the expression object */
  5408     } else {
  5409 	/*
  5410 	 * An empty string. Just set the interpreter's result to 0.
  5411 	 */
  5412 	
  5413 	Tcl_SetResult(interp, "0", TCL_VOLATILE);
  5414     }
  5415     return result;
  5416 }
  5417 
  5418 /*
  5419  *----------------------------------------------------------------------
  5420  *
  5421  * Tcl_CreateObjTrace --
  5422  *
  5423  *	Arrange for a procedure to be called to trace command execution.
  5424  *
  5425  * Results:
  5426  *	The return value is a token for the trace, which may be passed
  5427  *	to Tcl_DeleteTrace to eliminate the trace.
  5428  *
  5429  * Side effects:
  5430  *	From now on, proc will be called just before a command procedure
  5431  *	is called to execute a Tcl command.  Calls to proc will have the
  5432  *	following form:
  5433  *
  5434  *      void proc( ClientData     clientData,
  5435  *                 Tcl_Interp*    interp,
  5436  *                 int            level,
  5437  *                 CONST char*    command,
  5438  *                 Tcl_Command    commandInfo,
  5439  *                 int            objc,
  5440  *                 Tcl_Obj *CONST objv[] );
  5441  *
  5442  *      The 'clientData' and 'interp' arguments to 'proc' will be the
  5443  *      same as the arguments to Tcl_CreateObjTrace.  The 'level'
  5444  *	argument gives the nesting depth of command interpretation within
  5445  *	the interpreter.  The 'command' argument is the ASCII text of
  5446  *	the command being evaluated -- before any substitutions are
  5447  *	performed.  The 'commandInfo' argument gives a handle to the
  5448  *	command procedure that will be evaluated.  The 'objc' and 'objv'
  5449  *	parameters give the parameter vector that will be passed to the
  5450  *	command procedure.  proc does not return a value.
  5451  *
  5452  *      It is permissible for 'proc' to call Tcl_SetCommandTokenInfo
  5453  *      to change the command procedure or client data for the command
  5454  *      being evaluated, and these changes will take effect with the
  5455  *      current evaluation.
  5456  *
  5457  * The 'level' argument specifies the maximum nesting level of calls
  5458  * to be traced.  If the execution depth of the interpreter exceeds
  5459  * 'level', the trace callback is not executed.
  5460  *
  5461  * The 'flags' argument is either zero or the value,
  5462  * TCL_ALLOW_INLINE_COMPILATION.  If the TCL_ALLOW_INLINE_COMPILATION
  5463  * flag is not present, the bytecode compiler will not generate inline
  5464  * code for Tcl's built-in commands.  This behavior will have a significant
  5465  * impact on performance, but will ensure that all command evaluations are
  5466  * traced.  If the TCL_ALLOW_INLINE_COMPILATION flag is present, the
  5467  * bytecode compiler will have its normal behavior of compiling in-line
  5468  * code for some of Tcl's built-in commands.  In this case, the tracing
  5469  * will be imprecise -- in-line code will not be traced -- but run-time
  5470  * performance will be improved.  The latter behavior is desired for
  5471  * many applications such as profiling of run time.
  5472  *
  5473  * When the trace is deleted, the 'delProc' procedure will be invoked,
  5474  * passing it the original client data.  
  5475  *
  5476  *----------------------------------------------------------------------
  5477  */
  5478 
  5479 EXPORT_C Tcl_Trace
  5480 Tcl_CreateObjTrace( interp, level, flags, proc, clientData, delProc )
  5481     Tcl_Interp* interp;		/* Tcl interpreter */
  5482     int level;			/* Maximum nesting level */
  5483     int flags;			/* Flags, see above */
  5484     Tcl_CmdObjTraceProc* proc;	/* Trace callback */
  5485     ClientData clientData;	/* Client data for the callback */
  5486     Tcl_CmdObjTraceDeleteProc* delProc;
  5487 				/* Procedure to call when trace is deleted */
  5488 {
  5489     register Trace *tracePtr;
  5490     register Interp *iPtr = (Interp *) interp;
  5491 
  5492     /* Test if this trace allows inline compilation of commands */
  5493 
  5494     if (!(flags & TCL_ALLOW_INLINE_COMPILATION)) {
  5495 	if (iPtr->tracesForbiddingInline == 0) {
  5496 
  5497 	    /*
  5498 	     * When the first trace forbidding inline compilation is
  5499 	     * created, invalidate existing compiled code for this
  5500 	     * interpreter and arrange (by setting the
  5501 	     * DONT_COMPILE_CMDS_INLINE flag) that when compiling new
  5502 	     * code, no commands will be compiled inline (i.e., into
  5503 	     * an inline sequence of instructions). We do this because
  5504 	     * commands that were compiled inline will never result in
  5505 	     * a command trace being called.
  5506 	     */
  5507 
  5508 	    iPtr->compileEpoch++;
  5509 	    iPtr->flags |= DONT_COMPILE_CMDS_INLINE;
  5510 	}
  5511 	iPtr->tracesForbiddingInline++;
  5512     }
  5513     
  5514     tracePtr = (Trace *) ckalloc(sizeof(Trace));
  5515     tracePtr->level		= level;
  5516     tracePtr->proc		= proc;
  5517     tracePtr->clientData	= clientData;
  5518     tracePtr->delProc           = delProc;
  5519     tracePtr->nextPtr		= iPtr->tracePtr;
  5520     tracePtr->flags		= flags;
  5521     iPtr->tracePtr		= tracePtr;
  5522 
  5523     return (Tcl_Trace) tracePtr;
  5524 }
  5525 
  5526 /*
  5527  *----------------------------------------------------------------------
  5528  *
  5529  * Tcl_CreateTrace --
  5530  *
  5531  *	Arrange for a procedure to be called to trace command execution.
  5532  *
  5533  * Results:
  5534  *	The return value is a token for the trace, which may be passed
  5535  *	to Tcl_DeleteTrace to eliminate the trace.
  5536  *
  5537  * Side effects:
  5538  *	From now on, proc will be called just before a command procedure
  5539  *	is called to execute a Tcl command.  Calls to proc will have the
  5540  *	following form:
  5541  *
  5542  *	void
  5543  *	proc(clientData, interp, level, command, cmdProc, cmdClientData,
  5544  *		argc, argv)
  5545  *	    ClientData clientData;
  5546  *	    Tcl_Interp *interp;
  5547  *	    int level;
  5548  *	    char *command;
  5549  *	    int (*cmdProc)();
  5550  *	    ClientData cmdClientData;
  5551  *	    int argc;
  5552  *	    char **argv;
  5553  *	{
  5554  *	}
  5555  *
  5556  *	The clientData and interp arguments to proc will be the same
  5557  *	as the corresponding arguments to this procedure.  Level gives
  5558  *	the nesting level of command interpretation for this interpreter
  5559  *	(0 corresponds to top level).  Command gives the ASCII text of
  5560  *	the raw command, cmdProc and cmdClientData give the procedure that
  5561  *	will be called to process the command and the ClientData value it
  5562  *	will receive, and argc and argv give the arguments to the
  5563  *	command, after any argument parsing and substitution.  Proc
  5564  *	does not return a value.
  5565  *
  5566  *----------------------------------------------------------------------
  5567  */
  5568 
  5569 EXPORT_C Tcl_Trace
  5570 Tcl_CreateTrace(interp, level, proc, clientData)
  5571     Tcl_Interp *interp;		/* Interpreter in which to create trace. */
  5572     int level;			/* Only call proc for commands at nesting
  5573 				 * level<=argument level (1=>top level). */
  5574     Tcl_CmdTraceProc *proc;	/* Procedure to call before executing each
  5575 				 * command. */
  5576     ClientData clientData;	/* Arbitrary value word to pass to proc. */
  5577 {
  5578     StringTraceData* data;
  5579     data = (StringTraceData*) ckalloc( sizeof( *data ));
  5580     data->clientData = clientData;
  5581     data->proc = proc;
  5582     return Tcl_CreateObjTrace( interp, level, 0, StringTraceProc,
  5583 			       (ClientData) data, StringTraceDeleteProc );
  5584 }
  5585 
  5586 /*
  5587  *----------------------------------------------------------------------
  5588  *
  5589  * StringTraceProc --
  5590  *
  5591  *	Invoke a string-based trace procedure from an object-based
  5592  *	callback.
  5593  *
  5594  * Results:
  5595  *	None.
  5596  *
  5597  * Side effects:
  5598  *	Whatever the string-based trace procedure does.
  5599  *
  5600  *----------------------------------------------------------------------
  5601  */
  5602 
  5603 static int
  5604 StringTraceProc( clientData, interp, level, command, commandInfo, objc, objv )
  5605     ClientData clientData;
  5606     Tcl_Interp* interp;
  5607     int level;
  5608     CONST char* command;
  5609     Tcl_Command commandInfo;
  5610     int objc;
  5611     Tcl_Obj *CONST *objv;
  5612 {
  5613     StringTraceData* data = (StringTraceData*) clientData;
  5614     Command* cmdPtr = (Command*) commandInfo;
  5615 
  5616     CONST char** argv;		/* Args to pass to string trace proc */
  5617 
  5618     int i;
  5619 
  5620     /*
  5621      * This is a bit messy because we have to emulate the old trace
  5622      * interface, which uses strings for everything.
  5623      */
  5624 	    
  5625     argv = (CONST char **) ckalloc((unsigned) ( (objc + 1)
  5626 						* sizeof(CONST char *) ));
  5627     for (i = 0; i < objc; i++) {
  5628 	argv[i] = Tcl_GetString(objv[i]);
  5629     }
  5630     argv[objc] = 0;
  5631 
  5632     /*
  5633      * Invoke the command procedure.  Note that we cast away const-ness
  5634      * on two parameters for compatibility with legacy code; the code
  5635      * MUST NOT modify either command or argv.
  5636      */
  5637           
  5638     ( data->proc )( data->clientData, interp, level,
  5639 		    (char*) command, cmdPtr->proc, cmdPtr->clientData,
  5640 		    objc, argv );
  5641     ckfree( (char*) argv );
  5642 
  5643     return TCL_OK;
  5644 }
  5645 
  5646 /*
  5647  *----------------------------------------------------------------------
  5648  *
  5649  * StringTraceDeleteProc --
  5650  *
  5651  *	Clean up memory when a string-based trace is deleted.
  5652  *
  5653  * Results:
  5654  *	None.
  5655  *
  5656  * Side effects:
  5657  *	Allocated memory is returned to the system.
  5658  *
  5659  *----------------------------------------------------------------------
  5660  */
  5661 
  5662 static void
  5663 StringTraceDeleteProc( clientData )
  5664     ClientData clientData;
  5665 {
  5666     ckfree( (char*) clientData );
  5667 }
  5668 
  5669 /*
  5670  *----------------------------------------------------------------------
  5671  *
  5672  * Tcl_DeleteTrace --
  5673  *
  5674  *	Remove a trace.
  5675  *
  5676  * Results:
  5677  *	None.
  5678  *
  5679  * Side effects:
  5680  *	From now on there will be no more calls to the procedure given
  5681  *	in trace.
  5682  *
  5683  *----------------------------------------------------------------------
  5684  */
  5685 
  5686 EXPORT_C void
  5687 Tcl_DeleteTrace(interp, trace)
  5688     Tcl_Interp *interp;		/* Interpreter that contains trace. */
  5689     Tcl_Trace trace;		/* Token for trace (returned previously by
  5690 				 * Tcl_CreateTrace). */
  5691 {
  5692     Interp *iPtr = (Interp *) interp;
  5693     Trace *prevPtr, *tracePtr = (Trace *) trace;
  5694     register Trace **tracePtr2 = &(iPtr->tracePtr);
  5695     ActiveInterpTrace *activePtr;
  5696 
  5697     /*
  5698      * Locate the trace entry in the interpreter's trace list,
  5699      * and remove it from the list.
  5700      */
  5701 
  5702     prevPtr = NULL;
  5703     while ((*tracePtr2) != NULL && (*tracePtr2) != tracePtr) {
  5704 	prevPtr = *tracePtr2;
  5705 	tracePtr2 = &((*tracePtr2)->nextPtr);
  5706     }
  5707     if (*tracePtr2 == NULL) {
  5708 	return;
  5709     }
  5710     (*tracePtr2) = (*tracePtr2)->nextPtr;
  5711 
  5712     /*
  5713      * The code below makes it possible to delete traces while traces
  5714      * are active: it makes sure that the deleted trace won't be
  5715      * processed by TclCheckInterpTraces.
  5716      */
  5717 
  5718     for (activePtr = iPtr->activeInterpTracePtr;  activePtr != NULL;
  5719 	    activePtr = activePtr->nextPtr) {
  5720 	if (activePtr->nextTracePtr == tracePtr) {
  5721 	    if (activePtr->reverseScan) {
  5722 		activePtr->nextTracePtr = prevPtr;
  5723 	    } else {
  5724 		activePtr->nextTracePtr = tracePtr->nextPtr;
  5725 	    }
  5726 	}
  5727     }
  5728 
  5729     /*
  5730      * If the trace forbids bytecode compilation, change the interpreter's
  5731      * state.  If bytecode compilation is now permitted, flag the fact and
  5732      * advance the compilation epoch so that procs will be recompiled to
  5733      * take advantage of it.
  5734      */
  5735 
  5736     if (!(tracePtr->flags & TCL_ALLOW_INLINE_COMPILATION)) {
  5737 	iPtr->tracesForbiddingInline--;
  5738 	if (iPtr->tracesForbiddingInline == 0) {
  5739 	    iPtr->flags &= ~DONT_COMPILE_CMDS_INLINE;
  5740 	    iPtr->compileEpoch++;
  5741 	}
  5742     }
  5743 
  5744     /*
  5745      * Execute any delete callback.
  5746      */
  5747 
  5748     if (tracePtr->delProc != NULL) {
  5749 	(tracePtr->delProc)(tracePtr->clientData);
  5750     }
  5751 
  5752     /* Delete the trace object */
  5753 
  5754     Tcl_EventuallyFree((char*)tracePtr, TCL_DYNAMIC);
  5755 }
  5756 
  5757 /*
  5758  *----------------------------------------------------------------------
  5759  *
  5760  * Tcl_AddErrorInfo --
  5761  *
  5762  *	Add information to the "errorInfo" variable that describes the
  5763  *	current error.
  5764  *
  5765  * Results:
  5766  *	None.
  5767  *
  5768  * Side effects:
  5769  *	The contents of message are added to the "errorInfo" variable.
  5770  *	If Tcl_Eval has been called since the current value of errorInfo
  5771  *	was set, errorInfo is cleared before adding the new message.
  5772  *	If we are just starting to log an error, errorInfo is initialized
  5773  *	from the error message in the interpreter's result.
  5774  *
  5775  *----------------------------------------------------------------------
  5776  */
  5777 
  5778 EXPORT_C void
  5779 Tcl_AddErrorInfo(interp, message)
  5780     Tcl_Interp *interp;		/* Interpreter to which error information
  5781 				 * pertains. */
  5782     CONST char *message;	/* Message to record. */
  5783 {
  5784     Tcl_AddObjErrorInfo(interp, message, -1);
  5785 }
  5786 
  5787 /*
  5788  *----------------------------------------------------------------------
  5789  *
  5790  * Tcl_AddObjErrorInfo --
  5791  *
  5792  *	Add information to the "errorInfo" variable that describes the
  5793  *	current error. This routine differs from Tcl_AddErrorInfo by
  5794  *	taking a byte pointer and length.
  5795  *
  5796  * Results:
  5797  *	None.
  5798  *
  5799  * Side effects:
  5800  *	"length" bytes from "message" are added to the "errorInfo" variable.
  5801  *	If "length" is negative, use bytes up to the first NULL byte.
  5802  *	If Tcl_EvalObj has been called since the current value of errorInfo
  5803  *	was set, errorInfo is cleared before adding the new message.
  5804  *	If we are just starting to log an error, errorInfo is initialized
  5805  *	from the error message in the interpreter's result.
  5806  *
  5807  *----------------------------------------------------------------------
  5808  */
  5809 
  5810 EXPORT_C void
  5811 Tcl_AddObjErrorInfo(interp, message, length)
  5812     Tcl_Interp *interp;		/* Interpreter to which error information
  5813 				 * pertains. */
  5814     CONST char *message;	/* Points to the first byte of an array of
  5815 				 * bytes of the message. */
  5816     int length;			/* The number of bytes in the message.
  5817 				 * If < 0, then append all bytes up to a
  5818 				 * NULL byte. */
  5819 {
  5820     register Interp *iPtr = (Interp *) interp;
  5821     Tcl_Obj *objPtr;
  5822     
  5823     /*
  5824      * If we are just starting to log an error, errorInfo is initialized
  5825      * from the error message in the interpreter's result.
  5826      */
  5827 
  5828     if (!(iPtr->flags & ERR_IN_PROGRESS)) { /* just starting to log error */
  5829 	iPtr->flags |= ERR_IN_PROGRESS;
  5830 
  5831 	if (iPtr->result[0] == 0) {
  5832 	    Tcl_ObjSetVar2(interp, iPtr->execEnvPtr->errorInfo, NULL, 
  5833 	            iPtr->objResultPtr, TCL_GLOBAL_ONLY);
  5834 	} else {		/* use the string result */
  5835 	    objPtr = Tcl_NewStringObj(interp->result, -1);
  5836 	    Tcl_IncrRefCount(objPtr);
  5837 	    Tcl_ObjSetVar2(interp, iPtr->execEnvPtr->errorInfo, NULL, 
  5838 	            objPtr, TCL_GLOBAL_ONLY);
  5839 	    Tcl_DecrRefCount(objPtr);
  5840 	}
  5841 
  5842 	/*
  5843 	 * If the errorCode variable wasn't set by the code that generated
  5844 	 * the error, set it to "NONE".
  5845 	 */
  5846 
  5847 	if (!(iPtr->flags & ERROR_CODE_SET)) {
  5848 	    objPtr = Tcl_NewStringObj("NONE", -1);
  5849 	    Tcl_IncrRefCount(objPtr);
  5850 	    Tcl_ObjSetVar2(interp, iPtr->execEnvPtr->errorCode, NULL, 
  5851 	            objPtr, TCL_GLOBAL_ONLY);
  5852 	    Tcl_DecrRefCount(objPtr);
  5853 	}
  5854     }
  5855 
  5856     /*
  5857      * Now append "message" to the end of errorInfo.
  5858      */
  5859 
  5860     if (length != 0) {
  5861 	objPtr = Tcl_NewStringObj(message, length);
  5862 	Tcl_IncrRefCount(objPtr);
  5863 	Tcl_ObjSetVar2(interp, iPtr->execEnvPtr->errorInfo, NULL, 
  5864 	        objPtr, (TCL_GLOBAL_ONLY | TCL_APPEND_VALUE));
  5865 	Tcl_DecrRefCount(objPtr); /* free msg object appended above */
  5866     }
  5867 }
  5868 
  5869 /*
  5870  *---------------------------------------------------------------------------
  5871  *
  5872  * Tcl_VarEvalVA --
  5873  *
  5874  *	Given a variable number of string arguments, concatenate them
  5875  *	all together and execute the result as a Tcl command.
  5876  *
  5877  * Results:
  5878  *	A standard Tcl return result.  An error message or other result may
  5879  *	be left in the interp's result.
  5880  *
  5881  * Side effects:
  5882  *	Depends on what was done by the command.
  5883  *
  5884  *---------------------------------------------------------------------------
  5885  */
  5886 
  5887 EXPORT_C int
  5888 Tcl_VarEvalVA (interp, argList)
  5889     Tcl_Interp *interp;		/* Interpreter in which to evaluate command. */
  5890     va_list argList;		/* Variable argument list. */
  5891 {
  5892     Tcl_DString buf;
  5893     char *string;
  5894     int result;
  5895 
  5896     /*
  5897      * Copy the strings one after the other into a single larger
  5898      * string.  Use stack-allocated space for small commands, but if
  5899      * the command gets too large than call ckalloc to create the
  5900      * space.
  5901      */
  5902 
  5903     Tcl_DStringInit(&buf);
  5904     while (1) {
  5905 	string = va_arg(argList, char *);
  5906 	if (string == NULL) {
  5907 	    break;
  5908 	}
  5909 	Tcl_DStringAppend(&buf, string, -1);
  5910     }
  5911 
  5912     result = Tcl_Eval(interp, Tcl_DStringValue(&buf));
  5913     Tcl_DStringFree(&buf);
  5914     return result;
  5915 }
  5916 
  5917 /*
  5918  *----------------------------------------------------------------------
  5919  *
  5920  * Tcl_VarEval --
  5921  *
  5922  *	Given a variable number of string arguments, concatenate them
  5923  *	all together and execute the result as a Tcl command.
  5924  *
  5925  * Results:
  5926  *	A standard Tcl return result.  An error message or other
  5927  *	result may be left in interp->result.
  5928  *
  5929  * Side effects:
  5930  *	Depends on what was done by the command.
  5931  *
  5932  *----------------------------------------------------------------------
  5933  */
  5934 	/* VARARGS2 */ /* ARGSUSED */
  5935 EXPORT_C int
  5936 Tcl_VarEval TCL_VARARGS_DEF(Tcl_Interp *,arg1)
  5937 {
  5938     Tcl_Interp *interp;
  5939     va_list argList;
  5940     int result;
  5941 
  5942     interp = TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
  5943     result = Tcl_VarEvalVA(interp, argList);
  5944     va_end(argList);
  5945 
  5946     return result;
  5947 }
  5948 
  5949 /*
  5950  *---------------------------------------------------------------------------
  5951  *
  5952  * Tcl_GlobalEval --
  5953  *
  5954  *	Evaluate a command at global level in an interpreter.
  5955  *
  5956  * Results:
  5957  *	A standard Tcl result is returned, and the interp's result is
  5958  *	modified accordingly.
  5959  *
  5960  * Side effects:
  5961  *	The command string is executed in interp, and the execution
  5962  *	is carried out in the variable context of global level (no
  5963  *	procedures active), just as if an "uplevel #0" command were
  5964  *	being executed.
  5965  *
  5966  ---------------------------------------------------------------------------
  5967  */
  5968 
  5969 EXPORT_C int
  5970 Tcl_GlobalEval(interp, command)
  5971     Tcl_Interp *interp;		/* Interpreter in which to evaluate command. */
  5972     CONST char *command;	/* Command to evaluate. */
  5973 {
  5974     register Interp *iPtr = (Interp *) interp;
  5975     int result;
  5976     CallFrame *savedVarFramePtr;
  5977 
  5978     savedVarFramePtr = iPtr->varFramePtr;
  5979     iPtr->varFramePtr = NULL;
  5980     result = Tcl_Eval(interp, command);
  5981     iPtr->varFramePtr = savedVarFramePtr;
  5982     return result;
  5983 }
  5984 
  5985 /*
  5986  *----------------------------------------------------------------------
  5987  *
  5988  * Tcl_SetRecursionLimit --
  5989  *
  5990  *	Set the maximum number of recursive calls that may be active
  5991  *	for an interpreter at once.
  5992  *
  5993  * Results:
  5994  *	The return value is the old limit on nesting for interp.
  5995  *
  5996  * Side effects:
  5997  *	None.
  5998  *
  5999  *----------------------------------------------------------------------
  6000  */
  6001 
  6002 EXPORT_C int
  6003 Tcl_SetRecursionLimit(interp, depth)
  6004     Tcl_Interp *interp;			/* Interpreter whose nesting limit
  6005 					 * is to be set. */
  6006     int depth;				/* New value for maximimum depth. */
  6007 {
  6008     Interp *iPtr = (Interp *) interp;
  6009     int old;
  6010 
  6011     old = iPtr->maxNestingDepth;
  6012     if (depth > 0) {
  6013 	iPtr->maxNestingDepth = depth;
  6014     }
  6015     return old;
  6016 }
  6017 
  6018 /*
  6019  *----------------------------------------------------------------------
  6020  *
  6021  * Tcl_AllowExceptions --
  6022  *
  6023  *	Sets a flag in an interpreter so that exceptions can occur
  6024  *	in the next call to Tcl_Eval without them being turned into
  6025  *	errors.
  6026  *
  6027  * Results:
  6028  *	None.
  6029  *
  6030  * Side effects:
  6031  *	The TCL_ALLOW_EXCEPTIONS flag gets set in the interpreter's
  6032  *	evalFlags structure.  See the reference documentation for
  6033  *	more details.
  6034  *
  6035  *----------------------------------------------------------------------
  6036  */
  6037 
  6038 EXPORT_C void
  6039 Tcl_AllowExceptions(interp)
  6040     Tcl_Interp *interp;		/* Interpreter in which to set flag. */
  6041 {
  6042     Interp *iPtr = (Interp *) interp;
  6043 
  6044     iPtr->evalFlags |= TCL_ALLOW_EXCEPTIONS;
  6045 }
  6046 
  6047 
  6048 /*
  6049  *----------------------------------------------------------------------
  6050  *
  6051  * Tcl_GetVersion
  6052  *
  6053  *	Get the Tcl major, minor, and patchlevel version numbers and
  6054  *      the release type.  A patch is a release type TCL_FINAL_RELEASE
  6055  *      with a patchLevel > 0.
  6056  *
  6057  * Results:
  6058  *	None.
  6059  *
  6060  * Side effects:
  6061  *	None.
  6062  *
  6063  *----------------------------------------------------------------------
  6064  */
  6065 
  6066 EXPORT_C void
  6067 Tcl_GetVersion(majorV, minorV, patchLevelV, type)
  6068     int *majorV;
  6069     int *minorV;
  6070     int *patchLevelV;
  6071     int *type;
  6072 {
  6073     if (majorV != NULL) {
  6074         *majorV = TCL_MAJOR_VERSION;
  6075     }
  6076     if (minorV != NULL) {
  6077         *minorV = TCL_MINOR_VERSION;
  6078     }
  6079     if (patchLevelV != NULL) {
  6080         *patchLevelV = TCL_RELEASE_SERIAL;
  6081     }
  6082     if (type != NULL) {
  6083         *type = TCL_RELEASE_LEVEL;
  6084     }
  6085 }
  6086 
  6087 /*
  6088  * Local Variables:
  6089  * mode: c
  6090  * c-basic-offset: 4
  6091  * fill-column: 78
  6092  * End:
  6093  */
  6094