Skip to content

Commit

Permalink
generate source info for error messages at top level
Browse files Browse the repository at this point in the history
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 <steveb@workware.net.au>
  • Loading branch information
msteveb committed Mar 13, 2024
1 parent ef54029 commit 263c281
Showing 1 changed file with 21 additions and 10 deletions.
31 changes: 21 additions & 10 deletions jim.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen);
static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len);
static int JimSetNewVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr, Jim_VarVal *vv);
static Jim_VarVal *JimFindVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr);
static void JimSetErrorStack(Jim_Interp *interp);
static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);

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

void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
{
Expand Down Expand Up @@ -6050,16 +6050,27 @@ static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj)
interp->errorFlag = 1;
}

static void JimSetErrorStack(Jim_Interp *interp)
static void JimSetErrorStack(Jim_Interp *interp, ScriptObj *script)
{
if (!interp->errorFlag) {
int i;
Jim_Obj *stackTrace = Jim_NewListObj(interp, NULL, 0);

for (i = 0; i <= interp->procLevel; i++) {
Jim_EvalFrame *frame = JimGetEvalFrameByProcLevel(interp, -i);
if (frame) {
JimAddStackFrame(interp, frame, stackTrace);
if (interp->procLevel == 0 && script) {
/* If this is at the top level and there is a script, use the script info
* rather than the proc info
*/
Jim_ListAppendElement(interp, stackTrace, interp->emptyObj);
Jim_ListAppendElement(interp, stackTrace, script->fileNameObj);
Jim_ListAppendElement(interp, stackTrace, Jim_NewIntObj(interp, script->linenr));
Jim_ListAppendElement(interp, stackTrace, interp->emptyObj);
}
else {
for (i = 0; i <= interp->procLevel; i++) {
Jim_EvalFrame *frame = JimGetEvalFrameByProcLevel(interp, -i);
if (frame) {
JimAddStackFrame(interp, frame, stackTrace);
}
}
}
JimSetStackTrace(interp, stackTrace);
Expand Down Expand Up @@ -10862,7 +10873,7 @@ static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
retcode = cmdPtr->u.native.cmdProc(interp, objc, objv);
}
if (retcode == JIM_ERR) {
JimSetErrorStack(interp);
JimSetErrorStack(interp, NULL);
}
}

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

if (retcode == JIM_ERR) {
JimSetErrorStack(interp);
JimSetErrorStack(interp, NULL);
}

if (interp->framePtr->tailcallObj) {
Expand Down Expand Up @@ -11157,7 +11168,7 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
Jim_IncrRefCount(scriptObjPtr); /* Make sure it's shared. */
script = JimGetScript(interp, scriptObjPtr);
if (JimParseCheckMissing(interp, script->missing) == JIM_ERR) {
JimSetErrorStack(interp);
JimSetErrorStack(interp, script);
Jim_DecrRefCount(interp, scriptObjPtr);
return JIM_ERR;
}
Expand Down Expand Up @@ -11360,7 +11371,7 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)

/* Possibly add to the error stack trace */
if (retcode == JIM_ERR) {
JimSetErrorStack(interp);
JimSetErrorStack(interp, NULL);
}

JimPopEvalFrame(interp);
Expand Down

0 comments on commit 263c281

Please sign in to comment.