Skip to content

Commit 263c281

Browse files
committed
generate source info for error messages at top level
Now that we rely on eval frames to unwind the stack on error, if an error occurs at the top level it would previously not provide a stack trace. e.g. $ jimsh t.tcl unmatched "[" After this change, the error location is now correctly reported: $ ./jimsh t.tcl t.tcl:8: Error: unmatched "[" Traceback (most recent call last): File "t.tcl", line 8 Signed-off-by: Steve Bennett <[email protected]>
1 parent ef54029 commit 263c281

File tree

1 file changed

+21
-10
lines changed

1 file changed

+21
-10
lines changed

jim.c

+21-10
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen);
155155
static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len);
156156
static int JimSetNewVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr, Jim_VarVal *vv);
157157
static Jim_VarVal *JimFindVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr);
158-
static void JimSetErrorStack(Jim_Interp *interp);
159158
static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
160159

161160
#define JIM_DICT_SUGAR 100 /* Only returned by SetVariableFromAny() */
@@ -3357,6 +3356,7 @@ typedef struct ScriptObj
33573356
static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
33583357
static int JimParseCheckMissing(Jim_Interp *interp, int ch);
33593358
static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr);
3359+
static void JimSetErrorStack(Jim_Interp *interp, ScriptObj *script);
33603360

33613361
void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
33623362
{
@@ -6050,16 +6050,27 @@ static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj)
60506050
interp->errorFlag = 1;
60516051
}
60526052

6053-
static void JimSetErrorStack(Jim_Interp *interp)
6053+
static void JimSetErrorStack(Jim_Interp *interp, ScriptObj *script)
60546054
{
60556055
if (!interp->errorFlag) {
60566056
int i;
60576057
Jim_Obj *stackTrace = Jim_NewListObj(interp, NULL, 0);
60586058

6059-
for (i = 0; i <= interp->procLevel; i++) {
6060-
Jim_EvalFrame *frame = JimGetEvalFrameByProcLevel(interp, -i);
6061-
if (frame) {
6062-
JimAddStackFrame(interp, frame, stackTrace);
6059+
if (interp->procLevel == 0 && script) {
6060+
/* If this is at the top level and there is a script, use the script info
6061+
* rather than the proc info
6062+
*/
6063+
Jim_ListAppendElement(interp, stackTrace, interp->emptyObj);
6064+
Jim_ListAppendElement(interp, stackTrace, script->fileNameObj);
6065+
Jim_ListAppendElement(interp, stackTrace, Jim_NewIntObj(interp, script->linenr));
6066+
Jim_ListAppendElement(interp, stackTrace, interp->emptyObj);
6067+
}
6068+
else {
6069+
for (i = 0; i <= interp->procLevel; i++) {
6070+
Jim_EvalFrame *frame = JimGetEvalFrameByProcLevel(interp, -i);
6071+
if (frame) {
6072+
JimAddStackFrame(interp, frame, stackTrace);
6073+
}
60636074
}
60646075
}
60656076
JimSetStackTrace(interp, stackTrace);
@@ -10862,7 +10873,7 @@ static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
1086210873
retcode = cmdPtr->u.native.cmdProc(interp, objc, objv);
1086310874
}
1086410875
if (retcode == JIM_ERR) {
10865-
JimSetErrorStack(interp);
10876+
JimSetErrorStack(interp, NULL);
1086610877
}
1086710878
}
1086810879

@@ -10900,7 +10911,7 @@ static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
1090010911
JimDecrCmdRefCount(interp, cmdPtr);
1090110912

1090210913
if (retcode == JIM_ERR) {
10903-
JimSetErrorStack(interp);
10914+
JimSetErrorStack(interp, NULL);
1090410915
}
1090510916

1090610917
if (interp->framePtr->tailcallObj) {
@@ -11157,7 +11168,7 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
1115711168
Jim_IncrRefCount(scriptObjPtr); /* Make sure it's shared. */
1115811169
script = JimGetScript(interp, scriptObjPtr);
1115911170
if (JimParseCheckMissing(interp, script->missing) == JIM_ERR) {
11160-
JimSetErrorStack(interp);
11171+
JimSetErrorStack(interp, script);
1116111172
Jim_DecrRefCount(interp, scriptObjPtr);
1116211173
return JIM_ERR;
1116311174
}
@@ -11360,7 +11371,7 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
1136011371

1136111372
/* Possibly add to the error stack trace */
1136211373
if (retcode == JIM_ERR) {
11363-
JimSetErrorStack(interp);
11374+
JimSetErrorStack(interp, NULL);
1136411375
}
1136511376

1136611377
JimPopEvalFrame(interp);

0 commit comments

Comments
 (0)