aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2024-03-13 15:32:15 +1000
committerSteve Bennett <steveb@workware.net.au>2024-03-13 15:33:43 +1000
commit263c28170a916b24a1442687580299e332b732af (patch)
tree720fe12003308e69fda0c0e378ce42a6d2290576
parentef5402943619c843981fb5f36abfb828fd3fe981 (diff)
downloadjimtcl-263c28170a916b24a1442687580299e332b732af.zip
jimtcl-263c28170a916b24a1442687580299e332b732af.tar.gz
jimtcl-263c28170a916b24a1442687580299e332b732af.tar.bz2
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 <steveb@workware.net.au>
-rw-r--r--jim.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/jim.c b/jim.c
index 6520670..8588b7f 100644
--- a/jim.c
+++ b/jim.c
@@ -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() */
@@ -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)
{
@@ -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);
@@ -10862,7 +10873,7 @@ tailcall:
retcode = cmdPtr->u.native.cmdProc(interp, objc, objv);
}
if (retcode == JIM_ERR) {
- JimSetErrorStack(interp);
+ JimSetErrorStack(interp, NULL);
}
}
@@ -10900,7 +10911,7 @@ out:
JimDecrCmdRefCount(interp, cmdPtr);
if (retcode == JIM_ERR) {
- JimSetErrorStack(interp);
+ JimSetErrorStack(interp, NULL);
}
if (interp->framePtr->tailcallObj) {
@@ -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;
}
@@ -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);