Index: generic/xotclStack.c =================================================================== diff -u -red8301802df5fc7427fc0e4dbd82c2cf880329de -r26a70d9d268d8d827ec0ed631549fa6c5217d832 --- generic/xotclStack.c (.../xotclStack.c) (revision ed8301802df5fc7427fc0e4dbd82c2cf880329de) +++ generic/xotclStack.c (.../xotclStack.c) (revision 26a70d9d268d8d827ec0ed631549fa6c5217d832) @@ -34,6 +34,37 @@ return cs->top; } +XOTclCallStackContent * +XOTclCallStackFindLastInvocation(Tcl_Interp *interp, int offset) { + XOTclCallStack *cs = &RUNTIME_STATE(interp)->cs; + register XOTclCallStackContent *csc = cs->top; + int topLevel = csc->currentFramePtr ? Tcl_CallFrame_level(csc->currentFramePtr) : 0; + int deeper = offset; + + /* skip through toplevel inactive filters, do this offset times */ + for (csc=cs->top; csc > cs->content; csc--) { + /* fprintf(stderr, "csc %p callType = %x, frameType = %x, offset=%d\n", + csc,csc->callType,csc->frameType,offset); */ + if ((csc->callType & XOTCL_CSC_CALL_IS_NEXT) || + (csc->frameType & XOTCL_CSC_TYPE_INACTIVE)) + continue; + if (offset) + offset--; + else { + /* fprintf(stderr, "csc %p offset ok, deeper=%d\n",csc,deeper); */ + if (!deeper || cs->top->callType & XOTCL_CSC_CALL_IS_GUARD) { + return csc; + } + if (csc->currentFramePtr && Tcl_CallFrame_level(csc->currentFramePtr) < topLevel) { + return csc; + } + } + } + /* for some reasons, we could not find invocation (topLevel, destroy) */ + /* fprintf(stderr, "csc %p could not find invocation\n",csc);*/ + return NULL; +} + static void CallStackClearCmdReferences(Tcl_Interp *interp, Tcl_Command cmd) { XOTclCallStack *cs = &RUNTIME_STATE(interp)->cs;