From 0fff2bdf2fa5004c0b6a782ab5dbcd4831fb642d Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Mon, 3 Jun 2002 16:31:21 +0000 Subject: clarify the empty variable name issue ([Bug 549285]) --- ChangeLog | 5 +++++ doc/Tcl.n | 9 ++++---- generic/tclExecute.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2a09525..7b90e33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2002-06-03 Miguel Sofer + + * doc/Tcl.n: clarify the empty variable name issue ([Bug 549285] + reported by Tom Krehbiel, patch by Don Porter). + 2002-05-31 Don Porter * library/package.tcl: Fixed leak of slave interp in [pkg_mkIndex]. diff --git a/doc/Tcl.n b/doc/Tcl.n index 6bd8511..4ad1b63 100644 --- a/doc/Tcl.n +++ b/doc/Tcl.n @@ -5,7 +5,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: Tcl.n,v 1.3 1999/04/16 00:46:33 stanton Exp $ +'\" RCS: @(#) $Id: Tcl.n,v 1.4 2002/06/03 16:31:24 msofer Exp $ '\" .so man.macros .TH Tcl n "8.1" Tcl "Tcl Built-In Commands" @@ -82,13 +82,14 @@ Variable substitution may take any of the following forms: .RS .TP 15 \fB$\fIname\fR -\fIName\fR is the name of a scalar variable; the name is terminated -by any character that isn't a letter, digit, or underscore. +\fIName\fR is the name of a scalar variable; the name is a sequence +of one or more characters that are a letter, digit, or underscore. .TP 15 \fB$\fIname\fB(\fIindex\fB)\fR \fIName\fR gives the name of an array variable and \fIindex\fR gives the name of an element within that array. -\fIName\fR must contain only letters, digits, and underscores. +\fIName\fR must contain only letters, digits, and underscores, +but may be an empty string. Command substitutions, variable substitutions, and backslash substitutions are performed on the characters of \fIindex\fR. .TP 15 diff --git a/generic/tclExecute.c b/generic/tclExecute.c index e9ebbd4..2374cd3 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclExecute.c,v 1.57 2002/05/31 22:20:19 dgp Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.58 2002/06/03 16:31:25 msofer Exp $ */ #include "tclInt.h" @@ -66,6 +66,33 @@ TCL_DECLARE_MUTEX(execMutex) int tclTraceExec = 0; #endif +typedef struct ThreadSpecificData { + /* + * The following global variable is use to signal matherr that Tcl + * is responsible for the arithmetic, so errors can be handled in a + * fashion appropriate for Tcl. Zero means no Tcl math is in + * progress; non-zero means Tcl is doing math. + */ + + int mathInProgress; + +} ThreadSpecificData; + +static Tcl_ThreadDataKey dataKey; + +/* + * The variable below serves no useful purpose except to generate + * a reference to matherr, so that the Tcl version of matherr is + * linked in rather than the system version. Without this reference + * the need for matherr won't be discovered during linking until after + * libtcl.a has been processed, so Tcl's version won't be used. + */ + +#ifdef NEED_MATHERR +extern int matherr(); +int (*tclMatherrPtr)() = matherr; +#endif + /* * Mapping from expression instruction opcodes to strings; used for error * messages. Note that these entries must match the order and number of the @@ -3912,6 +3939,7 @@ TclExecuteByteCode(interp, codePtr) */ BuiltinFunc *mathFuncPtr; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if ((opnd < 0) || (opnd > LAST_BUILTIN_FUNC)) { TRACE(("UNRECOGNIZED BUILTIN FUNC CODE %d\n", opnd)); @@ -3919,8 +3947,10 @@ TclExecuteByteCode(interp, codePtr) } mathFuncPtr = &(builtinFuncTable[opnd]); DECACHE_STACK_INFO(); + tsdPtr->mathInProgress++; result = (*mathFuncPtr->proc)(interp, eePtr, mathFuncPtr->clientData); + tsdPtr->mathInProgress--; CACHE_STACK_INFO(); if (result != TCL_OK) { goto checkForCatch; @@ -3941,10 +3971,13 @@ TclExecuteByteCode(interp, codePtr) * is the 0-th argument. */ Tcl_Obj **objv; /* The array of arguments. The function * name is objv[0]. */ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); objv = &(stackPtr[stackTop - (objc-1)]); /* "objv[0]" */ DECACHE_STACK_INFO(); + tsdPtr->mathInProgress++; result = ExprCallMathFunc(interp, eePtr, objc, objv); + tsdPtr->mathInProgress--; CACHE_STACK_INFO(); if (result != TCL_OK) { goto checkForCatch; @@ -5645,6 +5678,7 @@ ExprCallMathFunc(interp, eePtr, objc, objv) long i; double d; int j, k, result; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Tcl_ResetResult(interp); @@ -5742,8 +5776,10 @@ ExprCallMathFunc(interp, eePtr, objc, objv) * Invoke the function and copy its result back into valuePtr. */ + tsdPtr->mathInProgress++; result = (*mathFuncPtr->proc)(mathFuncPtr->clientData, interp, args, &funcResult); + tsdPtr->mathInProgress--; if (result != TCL_OK) { goto done; } @@ -5833,6 +5869,30 @@ TclExprFloatError(interp, value) } } +/* + *---------------------------------------------------------------------- + * + * TclMathInProgress -- + * + * This procedure is called to find out if Tcl is doing math + * in this thread. + * + * Results: + * 0 or 1. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclMathInProgress() +{ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + return tsdPtr->mathInProgress; +} + #ifdef TCL_COMPILE_STATS /* *---------------------------------------------------------------------- -- cgit v0.12