Attachment "1032805.patch" to
ticket [1032805fff]
added by
dgp
2004-09-23 05:18:59.
Index: generic/tclCmdMZ.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCmdMZ.c,v
retrieving revision 1.106
diff -u -r1.106 tclCmdMZ.c
--- generic/tclCmdMZ.c 17 Sep 2004 22:59:14 -0000 1.106
+++ generic/tclCmdMZ.c 22 Sep 2004 22:15:48 -0000
@@ -921,6 +921,13 @@
if (valuePtr != NULL) {
Tcl_SetObjErrorCode(interp, valuePtr);
}
+
+ valuePtr = NULL;
+ Tcl_DictObjGet(NULL, iPtr->returnOpts,
+ iPtr->returnErrorlineKey, &valuePtr);
+ if (valuePtr != NULL) {
+ Tcl_GetIntFromObj(NULL, valuePtr, &iPtr->errorLine);
+ }
}
} else {
code = TCL_RETURN;
Index: generic/tclCompile.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCompile.c,v
retrieving revision 1.72
diff -u -r1.72 tclCompile.c
--- generic/tclCompile.c 21 Sep 2004 22:45:41 -0000 1.72
+++ generic/tclCompile.c 22 Sep 2004 22:15:48 -0000
@@ -948,8 +948,46 @@
gotParse = 0;
do {
if (Tcl_ParseCommand(interp, p, bytesLeft, 0, &parse) != TCL_OK) {
- code = TCL_ERROR;
- goto error;
+ /* Compile bytecodes to report the parse error at runtime */
+ Tcl_Obj *returnCmd = Tcl_NewStringObj(
+ "return -code 1 -level 0 -errorinfo", -1);
+ Tcl_Obj *errMsg = Tcl_GetObjResult(interp);
+ Tcl_Obj *errInfo = Tcl_DuplicateObj(errMsg);
+ char *cmdString;
+ int cmdLength;
+ Tcl_Parse subParse;
+ int errorLine = 1;
+
+ Tcl_IncrRefCount(returnCmd);
+ Tcl_IncrRefCount(errInfo);
+ Tcl_AppendToObj(errInfo, "\n while executing\n\"", -1);
+ TclAppendLimitedToObj(errInfo, parse.commandStart,
+ /* Drop the command terminator (";" or "]") if appropriate */
+ (parse.term == parse.commandStart + parse.commandSize - 1) ?
+ parse.commandSize - 1 : parse.commandSize, 153, NULL);
+ Tcl_AppendToObj(errInfo, "\"", -1);
+
+ Tcl_ListObjAppendElement(NULL, returnCmd, errInfo);
+
+ for (p = script; p != parse.commandStart; p++) {
+ if (*p == '\n') {
+ errorLine++;
+ }
+ }
+ Tcl_ListObjAppendElement(NULL, returnCmd,
+ Tcl_NewStringObj("-errorline", -1));
+ Tcl_ListObjAppendElement(NULL, returnCmd,
+ Tcl_NewIntObj(errorLine));
+
+ Tcl_ListObjAppendElement(NULL, returnCmd, errMsg);
+ Tcl_DecrRefCount(errInfo);
+
+ cmdString = Tcl_GetStringFromObj(returnCmd, &cmdLength);
+ Tcl_ParseCommand(interp, cmdString, cmdLength, 0, &subParse);
+ TclCompileReturnCmd(interp, &subParse, envPtr);
+ Tcl_DecrRefCount(returnCmd);
+ Tcl_FreeParse(&subParse);
+ return TCL_OK;
}
gotParse = 1;
if (parse.numWords > 0) {
@@ -1224,26 +1262,6 @@
Tcl_DStringFree(&ds);
return TCL_OK;
- error:
- /*
- * Generate various pieces of error information, such as the line
- * number where the error occurred and information to add to the
- * errorInfo variable. Then free resources that had been allocated
- * to the command.
- */
-
- commandLength = parse.commandSize;
- if (parse.term == parse.commandStart + commandLength - 1) {
- /*
- * The terminator character (such as ; or ]) of the command where
- * the error occurred is the last character in the parsed command.
- * Reduce the length by one so that the error message doesn't
- * include the terminator character.
- */
-
- commandLength -= 1;
- }
-
log:
LogCompilationInfo(interp, script, parse.commandStart, commandLength);
if (gotParse) {
@@ -3339,7 +3357,7 @@
|| (opCode == INST_JUMP_FALSE1))) {
fprintf(stdout, "%d # pc %u", opnd, (pcOffset + opnd));
} else {
- fprintf(stdout, "%d", opnd);
+ fprintf(stdout, "%d ", opnd);
}
break;
case OPERAND_INT4:
@@ -3349,7 +3367,7 @@
|| (opCode == INST_JUMP_FALSE4))) {
fprintf(stdout, "%d # pc %u", opnd, (pcOffset + opnd));
} else {
- fprintf(stdout, "%d", opnd);
+ fprintf(stdout, "%d ", opnd);
}
break;
case OPERAND_UINT1:
Index: tests/compile.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/compile.test,v
retrieving revision 1.31
diff -u -r1.31 compile.test
--- tests/compile.test 2 Aug 2004 15:33:36 -0000 1.31
+++ tests/compile.test 22 Sep 2004 22:15:49 -0000
@@ -570,6 +570,19 @@
rename ReturnResults {}
} -returnCodes ok -result [string trim [string repeat {x } 260]]
+test compile-16.23.$noComp {
+ Bug 1032805: defer parse error until run time
+} -body {
+ namespace eval x {
+ run {
+ proc if {a b} {uplevel 1 [list set $a $b]}
+ if 1 {syntax {}{}}
+ }
+ }
+} -cleanup {
+ namespace delete x
+} -returnCodes ok -result {syntax {}{}}
+
} ;# End of noComp loop
# cleanup
Index: tests/misc.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/misc.test,v
retrieving revision 1.9
diff -u -r1.9 misc.test
--- tests/misc.test 4 Jul 2004 18:02:42 -0000 1.9
+++ tests/misc.test 22 Sep 2004 22:15:49 -0000
@@ -57,14 +57,14 @@
} [subst -novariables -nocommands {1
missing close-brace for variable name
missing close-brace for variable name
- while compiling
+ while executing
"set tst $a([winfo name $\{zz)
# this is a bogus comment
# this is a bogus comment
# this is a bogus comment
# this is a bogus comment
# this is a ..."
- (compiling body of proc "tstProc", line 4)
+ (procedure "tstProc" line 4)
invoked from within
"tstProc"}]