Attachment "dif" to
ticket [1119369fff]
added by
pcmacdon
2005-02-10 05:34:03.
*** tclBasic.c.orig Wed Feb 9 13:19:37 2005
--- tclBasic.c Wed Feb 9 13:44:00 2005
***************
*** 17,26 ****
--- 17,32 ----
*/
#include "tclInt.h"
#include "tclCompile.h"
+ /* Guard-check to ensure access to objv of a list has not changed. */
+ #define LIST_OBJV_VALID(listObj, objv, objc) \
+ ((listPtr == (Tcl_Obj*)NULL) ||\
+ ((listPtr->typePtr == &tclListType) && \
+ (((List *) listPtr->internalRep.twoPtrValue.ptr1)->elements == objv) && \
+ (((List *) listPtr->internalRep.twoPtrValue.ptr1)->elemCount == objc)))
/*
* Static procedures in this file:
*/
static char * CallCommandTraces _ANSI_ARGS_((Interp *iPtr,
***************
*** 2914,2924 ****
*
*----------------------------------------------------------------------
*/
int
! TclEvalObjvInternal(interp, objc, objv, command, length, flags)
Tcl_Interp *interp; /* Interpreter in which to evaluate the
* command. Also used for error
* reporting. */
int objc; /* Number of words in command. */
Tcl_Obj *CONST objv[]; /* An array of pointers to objects that are
--- 2920,2930 ----
*
*----------------------------------------------------------------------
*/
int
! TclEvalObjvInternal(interp, objc, objv, command, length, flags, listPtr)
Tcl_Interp *interp; /* Interpreter in which to evaluate the
* command. Also used for error
* reporting. */
int objc; /* Number of words in command. */
Tcl_Obj *CONST objv[]; /* An array of pointers to objects that are
***************
*** 2935,2944 ****
--- 2941,2951 ----
* used. */
int flags; /* Collection of OR-ed bits that control
* the evaluation of the script. Only
* TCL_EVAL_GLOBAL and TCL_EVAL_INVOKE are
* currently supported. */
+ Tcl_Obj *CONST listPtr; /* List object for objv, if any. */
{
Command *cmdPtr;
Interp *iPtr = (Interp *) interp;
Tcl_Obj **newObjv;
***************
*** 2995,3005 ****
Tcl_AppendResult(interp, "invalid command name \"",
Tcl_GetString(objv[0]), "\"", (char *) NULL);
code = TCL_ERROR;
} else {
iPtr->numLevels++;
! code = TclEvalObjvInternal(interp, objc+1, newObjv, command, length, 0);
iPtr->numLevels--;
}
Tcl_DecrRefCount(newObjv[0]);
ckfree((char *) newObjv);
goto done;
--- 3002,3012 ----
Tcl_AppendResult(interp, "invalid command name \"",
Tcl_GetString(objv[0]), "\"", (char *) NULL);
code = TCL_ERROR;
} else {
iPtr->numLevels++;
! code = TclEvalObjvInternal(interp, objc+1, newObjv, command, length, 0, NULL);
iPtr->numLevels--;
}
Tcl_DecrRefCount(newObjv[0]);
ckfree((char *) newObjv);
goto done;
***************
*** 3038,3048 ****
/*
* Finally, invoke the command's Tcl_ObjCmdProc.
*/
cmdPtr->refCount++;
iPtr->cmdCount++;
! if (code == TCL_OK && traceCode == TCL_OK && !Tcl_LimitExceeded(interp)) {
savedVarFramePtr = iPtr->varFramePtr;
if (flags & TCL_EVAL_GLOBAL) {
iPtr->varFramePtr = NULL;
}
if (!(flags & TCL_EVAL_INVOKE) &&
--- 3045,3056 ----
/*
* Finally, invoke the command's Tcl_ObjCmdProc.
*/
cmdPtr->refCount++;
iPtr->cmdCount++;
! if (code == TCL_OK && traceCode == TCL_OK && !Tcl_LimitExceeded(interp) &&
! LIST_OBJV_VALID(listObj, objv, objc)) {
savedVarFramePtr = iPtr->varFramePtr;
if (flags & TCL_EVAL_GLOBAL) {
iPtr->varFramePtr = NULL;
}
if (!(flags & TCL_EVAL_INVOKE) &&
***************
*** 3102,3115 ****
}
/*
*----------------------------------------------------------------------
*
! * Tcl_EvalObjv --
*
* This procedure evaluates a Tcl command that has already been
* parsed into words, with one Tcl_Obj holding each word.
*
* Results:
* The return value is a standard Tcl completion code such as
* TCL_OK or TCL_ERROR. A result or error message is left in
* interp's result.
--- 3110,3124 ----
}
/*
*----------------------------------------------------------------------
*
! * TclEvalObjvList --
*
* This procedure evaluates a Tcl command that has already been
* parsed into words, with one Tcl_Obj holding each word.
+ * The listObj argument ensures objv isn't invalidated.
*
* Results:
* The return value is a standard Tcl completion code such as
* TCL_OK or TCL_ERROR. A result or error message is left in
* interp's result.
***************
*** 3118,3139 ****
* Depends on the command.
*
*----------------------------------------------------------------------
*/
! int
! Tcl_EvalObjv(interp, objc, objv, flags)
Tcl_Interp *interp; /* Interpreter in which to evaluate the
* command. Also used for error
* reporting. */
int objc; /* Number of words in command. */
Tcl_Obj *CONST objv[]; /* An array of pointers to objects that are
* the words that make up the command. */
int flags; /* Collection of OR-ed bits that control
* the evaluation of the script. Only
* TCL_EVAL_GLOBAL and TCL_EVAL_INVOKE
* are currently supported. */
{
Interp *iPtr = (Interp *)interp;
Trace *tracePtr;
Tcl_DString cmdBuf;
char *cmdString = ""; /* A command string is only necessary for
--- 3127,3149 ----
* Depends on the command.
*
*----------------------------------------------------------------------
*/
! static int
! TclEvalObjvList(interp, objc, objv, flags, objPtr, listPtr)
Tcl_Interp *interp; /* Interpreter in which to evaluate the
* command. Also used for error
* reporting. */
int objc; /* Number of words in command. */
Tcl_Obj *CONST objv[]; /* An array of pointers to objects that are
* the words that make up the command. */
int flags; /* Collection of OR-ed bits that control
* the evaluation of the script. Only
* TCL_EVAL_GLOBAL and TCL_EVAL_INVOKE
* are currently supported. */
+ Tcl_Obj *CONST listPtr; /* List object for objv, if any. */
{
Interp *iPtr = (Interp *)interp;
Trace *tracePtr;
Tcl_DString cmdBuf;
char *cmdString = ""; /* A command string is only necessary for
***************
*** 3162,3172 ****
break;
}
}
iPtr->numLevels++;
! code = TclEvalObjvInternal(interp, objc, objv, cmdString, cmdLen, flags);
iPtr->numLevels--;
/*
* If we are again at the top level, process any unusual
* return code returned by the evaluated code.
--- 3172,3183 ----
break;
}
}
iPtr->numLevels++;
! code = TclEvalObjvInternal(interp, objc, objv, cmdString, cmdLen, flags,
! listPtr);
iPtr->numLevels--;
/*
* If we are again at the top level, process any unusual
* return code returned by the evaluated code.
***************
*** 3188,3198 ****
/*
* If there was an error, a command string will be needed for the
* error log: generate it now if it was not done previously.
*/
! if (cmdLen == 0) {
Tcl_DStringInit(&cmdBuf);
for (i = 0; i < objc; i++) {
Tcl_DStringAppendElement(&cmdBuf, Tcl_GetString(objv[i]));
}
cmdString = Tcl_DStringValue(&cmdBuf);
--- 3199,3209 ----
/*
* If there was an error, a command string will be needed for the
* error log: generate it now if it was not done previously.
*/
! if (cmdLen == 0 && LIST_OBJV_VALID(listObj, objv, objc)) {
Tcl_DStringInit(&cmdBuf);
for (i = 0; i < objc; i++) {
Tcl_DStringAppendElement(&cmdBuf, Tcl_GetString(objv[i]));
}
cmdString = Tcl_DStringValue(&cmdBuf);
***************
*** 3208,3217 ****
--- 3219,3263 ----
}
/*
*----------------------------------------------------------------------
*
+ * Tcl_EvalObjv --
+ *
+ * This procedure evaluates a Tcl command that has already been
+ * parsed into words, with one Tcl_Obj holding each word.
+ *
+ * Results:
+ * The return value is a standard Tcl completion code such as
+ * TCL_OK or TCL_ERROR. A result or error message is left in
+ * interp's result.
+ *
+ * Side effects:
+ * Depends on the command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ int
+ Tcl_EvalObjv(interp, objc, objv, flags)
+ Tcl_Interp *interp; /* Interpreter in which to evaluate the
+ * command. Also used for error
+ * reporting. */
+ int objc; /* Number of words in command. */
+ Tcl_Obj *CONST objv[]; /* An array of pointers to objects that are
+ * the words that make up the command. */
+ int flags; /* Collection of OR-ed bits that control
+ * the evaluation of the script. Only
+ * TCL_EVAL_GLOBAL and TCL_EVAL_INVOKE
+ * are currently supported. */
+ {
+ return TclEvalObjvList( interp, objc, objv, flags, NULL);
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ *
* Tcl_LogCommandInfo --
*
* This procedure is invoked after an error occurs in an interpreter.
* It adds information to iPtr->errorInfo field to describe the
* command that was being executed when the error occurred.
***************
*** 3533,3543 ****
* Execute the command and free the objects for its words.
*/
iPtr->numLevels++;
code = TclEvalObjvInternal(interp, objectsUsed, objv,
! parse.commandStart, parse.commandSize, 0);
iPtr->numLevels--;
if (code != TCL_OK) {
if (iPtr->numLevels == 0) {
if (code == TCL_RETURN) {
code = TclUpdateReturnInfo(iPtr);
--- 3579,3589 ----
* Execute the command and free the objects for its words.
*/
iPtr->numLevels++;
code = TclEvalObjvInternal(interp, objectsUsed, objv,
! parse.commandStart, parse.commandSize, 0, NULL);
iPtr->numLevels--;
if (code != TCL_OK) {
if (iPtr->numLevels == 0) {
if (code == TCL_RETURN) {
code = TclUpdateReturnInfo(iPtr);
*** tclCompile.h.orig Wed Feb 9 13:31:08 2005
--- tclCompile.h Wed Feb 9 13:24:54 2005
***************
*** 737,747 ****
*----------------------------------------------------------------
*/
MODULE_SCOPE int TclEvalObjvInternal _ANSI_ARGS_((Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[],
! CONST char *command, int length, int flags));
MODULE_SCOPE int TclInterpReady _ANSI_ARGS_((Tcl_Interp *interp));
/*
*----------------------------------------------------------------
--- 737,748 ----
*----------------------------------------------------------------
*/
MODULE_SCOPE int TclEvalObjvInternal _ANSI_ARGS_((Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[],
! CONST char *command, int length, int flags,
! Tcl_Obj *CONST listPtr));
MODULE_SCOPE int TclInterpReady _ANSI_ARGS_((Tcl_Interp *interp));
/*
*----------------------------------------------------------------
*** tclExecute.c.orig Wed Feb 9 13:31:40 2005
--- tclExecute.c Wed Feb 9 13:32:10 2005
***************
*** 1624,1634 ****
* Finally, let TclEvalObjvInternal handle the command.
*/
DECACHE_STACK_INFO();
Tcl_ResetResult(interp);
! result = TclEvalObjvInternal(interp, objc, objv, bytes, length, 0);
CACHE_STACK_INFO();
/*
* If the old stack is going to be released, it is
* safe to do so now, since no references to objv are
--- 1624,1634 ----
* Finally, let TclEvalObjvInternal handle the command.
*/
DECACHE_STACK_INFO();
Tcl_ResetResult(interp);
! result = TclEvalObjvInternal(interp, objc, objv, bytes, length, 0, NULL);
CACHE_STACK_INFO();
/*
* If the old stack is going to be released, it is
* safe to do so now, since no references to objv are
*** tclIOUtil.c.orig Wed Feb 9 13:16:47 2005
--- tclIOUtil.c Wed Feb 9 13:19:14 2005
***************
*** 1683,1701 ****
oldScriptFile = iPtr->scriptFile;
iPtr->scriptFile = pathPtr;
Tcl_IncrRefCount(iPtr->scriptFile);
string = Tcl_GetStringFromObj(objPtr, &length);
result = Tcl_EvalEx(interp, string, length, 0);
- /*
- * Now we have to be careful; the script may have changed the
- * iPtr->scriptFile value, so we must reset it without
- * assuming it still points to 'pathPtr'.
- */
- if (iPtr->scriptFile != NULL) {
- Tcl_DecrRefCount(iPtr->scriptFile);
- }
- iPtr->scriptFile = oldScriptFile;
if (result == TCL_RETURN) {
result = TclUpdateReturnInfo(iPtr);
} else if (result == TCL_ERROR) {
--- 1683,1692 ----
***************
*** 1714,1723 ****
--- 1705,1723 ----
Tcl_DecrRefCount(errorLine);
Tcl_AppendToObj(msg, ")", -1);
TclAppendObjToErrorInfo(interp, msg);
Tcl_DecrRefCount(msg);
}
+ /*
+ * Now we have to be careful; the script may have changed the
+ * iPtr->scriptFile value, so we must reset it without
+ * assuming it still points to 'pathPtr'.
+ */
+ if (iPtr->scriptFile != NULL) {
+ Tcl_DecrRefCount(iPtr->scriptFile);
+ }
+ iPtr->scriptFile = oldScriptFile;
end:
Tcl_DecrRefCount(objPtr);
return result;
}