Index: generic/nsf.c =================================================================== diff -u -r236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e -r1d47bd9661fd8d641c0c8441f6def1081902c9db --- generic/nsf.c (.../nsf.c) (revision 236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e) +++ generic/nsf.c (.../nsf.c) (revision 1d47bd9661fd8d641c0c8441f6def1081902c9db) @@ -4431,6 +4431,33 @@ return resultObj; } +EXTERN Tcl_Obj *NsfMethodNamePath3(Tcl_Interp *interp, + Tcl_CallFrame *framePtr, + CONST char *methodName) + nonnull(1) returns_nonnull; + + +Tcl_Obj * +NsfMethodNamePath3(Tcl_Interp *interp, + Tcl_CallFrame *framePtr, + CONST char *methodName) { + + Tcl_Obj *resultObj = Tcl_NewListObj(0, NULL); + + assert(interp); + assert(methodName); + + if (framePtr) { + Tcl_ListObjAppendList(interp, resultObj, + CallStackMethodPath(interp, 0 /* fixme */, framePtr)); + } + + Tcl_ListObjAppendElement(interp, resultObj, + Tcl_NewStringObj(methodName,-1)); + return resultObj; +} + + /* *---------------------------------------------------------------------- * NsColonVarResolver -- @@ -12446,14 +12473,14 @@ * method path, and the unknown final method. */ Tcl_Obj *callInfoObj = Tcl_NewListObj(1, &callerSelf->cmdName); - Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, - (Tcl_CallFrame *)framePtr, 1, + Tcl_Obj *methodPathObj = NsfMethodNamePath3(interp, + CallStackGetFrame(interp,(Tcl_CallFrame *)framePtr, 1), MethodName(objv[0])); INCR_REF_COUNT(callInfoObj); Tcl_ListObjAppendList(interp, callInfoObj, methodPathObj); Tcl_ListObjAppendElement(interp, callInfoObj, objv[1]); - /*fprintf(stderr, "DispatchUnknownMethod is called with callinfo <%s> \n", ObjStr(callInfoObj));*/ + /* fprintf(stderr, "DispatchUnknownMethod is called with callinfo <%s> \n", ObjStr(callInfoObj)); */ result = DispatchUnknownMethod(interp, invokedObject, objc-1, objv+1, callInfoObj, objv[1], NSF_CM_NO_OBJECT_METHOD|NSF_CSC_IMMEDIATE); DECR_REF_COUNT(callInfoObj); @@ -19520,7 +19547,7 @@ if (objc > 2) { return NsfObjWrongArgs(interp, "wrong # args", object->cmdName, - NsfMethodNamePath(interp, NULL, 1, NsfMethodName(objv[0])), "?value?"); + NsfMethodNamePath3(interp, CallStackGetFrame(interp, NULL, 1), NsfMethodName(objv[0])), "?value?"); } if (object == NULL) return NsfDispatchClientDataError(interp, clientData, "object", ObjStr(objv[0])); @@ -19599,7 +19626,8 @@ if (tcd->object) { cmd = Tcl_DuplicateObj(tcd->object->cmdName); if (objc > 0) { - Tcl_ListObjAppendList(interp, cmd, NsfMethodNamePath(interp, NULL, 1, MethodName(objv[0]))); + Tcl_ListObjAppendList(interp, cmd, + NsfMethodNamePath3(interp, CallStackGetFrame(interp, NULL, 1), MethodName(objv[0]))); if (objc > 1) { Tcl_ListObjAppendElement(interp, cmd, Tcl_NewListObj(objc-1,objv+1)); } @@ -20852,9 +20880,9 @@ } else if (unlikely(pPtr->flags & NSF_ARG_REQUIRED) && (processFlags & NSF_ARGPARSE_FORCE_REQUIRED)) { Tcl_Obj *paramDefsObj = NsfParamDefsSyntax(interp, ifd, pcPtr->object, NULL); - Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, - NULL, 1, - MethodName(pcPtr->full_objv[0])); + Tcl_Obj *methodPathObj = NsfMethodNamePath3(interp, + CallStackGetFrame(interp, NULL, 1), + MethodName(pcPtr->full_objv[0])); INCR_REF_COUNT2("methodPathObj", methodPathObj); @@ -21007,7 +21035,7 @@ #endif if (unlikely(currentParamPtr > lastParamPtr)) { - Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, NULL, 0, NsfMethodName(procNameObj)); + Tcl_Obj *methodPathObj = NsfMethodNamePath3(interp, CallStackGetFrame(interp, NULL, 0), NsfMethodName(procNameObj)); return NsfUnexpectedArgumentError(interp, ObjStr(argumentObj), (Nsf_Object*)object, paramPtr, methodPathObj); } @@ -21116,7 +21144,8 @@ Nsf_Param CONST *nextParamPtr = NextParam(currentParamPtr, lastParamPtr); if (nextParamPtr > lastParamPtr || (nextParamPtr->flags & NSF_ARG_NOLEADINGDASH)) { - Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, NULL, 0, NsfMethodName(procNameObj)); + Tcl_Obj *methodPathObj = NsfMethodNamePath3(interp, CallStackGetFrame(interp, NULL, 0), + NsfMethodName(procNameObj)); return NsfUnexpectedNonposArgumentError(interp, argumentString, (Nsf_Object *)object, currentParamPtr, paramPtr, @@ -21172,7 +21201,8 @@ ObjStr(argumentObj)); } #endif - Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, NULL, 0, NsfMethodName(procNameObj)); + Tcl_Obj *methodPathObj = NsfMethodNamePath3(interp, CallStackGetFrame(interp, NULL, 0), + NsfMethodName(procNameObj)); return NsfUnexpectedNonposArgumentError(interp, argumentString, (Nsf_Object *)object, currentParamPtr, paramPtr, @@ -21194,7 +21224,8 @@ * parameter, valueObj might be already provided for valueInArgument. */ if (unlikely(pPtr > lastParamPtr)) { - Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, NULL, 0, NsfMethodName(procNameObj)); + Tcl_Obj *methodPathObj = NsfMethodNamePath3(interp, CallStackGetFrame(interp, NULL, 0), + NsfMethodName(procNameObj)); return NsfUnexpectedArgumentError(interp, ObjStr(argumentObj), (Nsf_Object *)object, paramPtr, @@ -26167,9 +26198,9 @@ case CurrentoptionMethodpathIdx: cscPtr = CallStackGetTopFrame0(interp); - Tcl_SetObjResult(interp, NsfMethodNamePath(interp, - NULL, 1, - Tcl_GetCommandName(interp, cscPtr->cmdPtr))); + Tcl_SetObjResult(interp, NsfMethodNamePath3(interp, + CallStackGetFrame(interp, NULL, 1), + Tcl_GetCommandName(interp, cscPtr->cmdPtr))); break; case CurrentoptionClassIdx: /* class subcommand */ @@ -26234,10 +26265,9 @@ cscPtr = NsfCallStackFindLastInvocation(interp, 1, &framePtr); if (cscPtr && cscPtr->cmdPtr) { - resultObj = NsfMethodNamePath(interp, - framePtr, - 1, - Tcl_GetCommandName(interp, cscPtr->cmdPtr)); + resultObj = NsfMethodNamePath3(interp, + CallStackGetFrame(interp, framePtr, 1), + Tcl_GetCommandName(interp, cscPtr->cmdPtr)); } else { resultObj = NsfGlobalObjs[NSF_EMPTY]; } Index: generic/nsfStack.c =================================================================== diff -u -r236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e -r1d47bd9661fd8d641c0c8441f6def1081902c9db --- generic/nsfStack.c (.../nsfStack.c) (revision 236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e) +++ generic/nsfStack.c (.../nsfStack.c) (revision 1d47bd9661fd8d641c0c8441f6def1081902c9db) @@ -388,6 +388,38 @@ return NULL; } +static Tcl_CallFrame* CallStackGetFrame(Tcl_Interp *interp, + Tcl_CallFrame *startFrame, + int skip) nonnull(1); + +static Tcl_CallFrame* CallStackGetFrame(Tcl_Interp *interp, + Tcl_CallFrame *startFrame, + int skip) { + register Tcl_CallFrame *varFramePtr; + + assert(interp); + + /* NsfShowStack(interp); */ + + if (startFrame == NULL) { + varFramePtr = (Tcl_CallFrame *)Tcl_Interp_varFramePtr(interp); + } else { + varFramePtr = startFrame; + } + + while(skip-- && varFramePtr != NULL) { + varFramePtr = Tcl_CallFrame_callerPtr(varFramePtr); + } + + for (; varFramePtr; varFramePtr = Tcl_CallFrame_callerPtr(varFramePtr)) { + if (Tcl_CallFrame_isProcCallFrame(varFramePtr) & (FRAME_IS_NSF_METHOD|FRAME_IS_NSF_CMETHOD)) { + return varFramePtr; + } + } + + return NULL; +} + /* *---------------------------------------------------------------------- * CallStackGetTopFrame, CallStackGetTopFrame0, NsfCallStackGetTopFrame --