Index: TODO =================================================================== diff -u -r9beee9e5c366bb49ecb22c5a399b58f73fbde040 -r236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e --- TODO (.../TODO) (revision 9beee9e5c366bb49ecb22c5a399b58f73fbde040) +++ TODO (.../TODO) (revision 236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e) @@ -5391,6 +5391,7 @@ nsf.c: - move NsfMethodNamePath() out of NsfObjWrongArgs() - move NsfMethodNamePath() out of NsfUnexpectedArgumentError() and NsfUnexpectedNonposArgumentError() +- fix name paths in error messages triggered from ArgumentParse() ======================================================================== TODO: Index: generic/nsf.c =================================================================== diff -u -r3ffcbc1b5cf21f850b3dd486f9aa48c93f08e7a8 -r236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e --- generic/nsf.c (.../nsf.c) (revision 3ffcbc1b5cf21f850b3dd486f9aa48c93f08e7a8) +++ generic/nsf.c (.../nsf.c) (revision 236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e) @@ -4408,6 +4408,7 @@ Tcl_Obj * NsfMethodNamePath(Tcl_Interp *interp, Tcl_CallFrame *framePtr, + int skip, CONST char *methodName) { Tcl_Obj *resultObj = Tcl_NewListObj(0, NULL); @@ -4422,7 +4423,7 @@ if (framePtr) { Tcl_ListObjAppendList(interp, resultObj, - CallStackMethodPath(interp, framePtr)); + CallStackMethodPath(interp, skip, framePtr)); } Tcl_ListObjAppendElement(interp, resultObj, @@ -12446,7 +12447,7 @@ */ Tcl_Obj *callInfoObj = Tcl_NewListObj(1, &callerSelf->cmdName); Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, - (Tcl_CallFrame *)framePtr, + (Tcl_CallFrame *)framePtr, 1, MethodName(objv[0])); INCR_REF_COUNT(callInfoObj); Tcl_ListObjAppendList(interp, callInfoObj, methodPathObj); @@ -19518,8 +19519,8 @@ assert(objv); if (objc > 2) { - return NsfObjWrongArgs(interp, "wrong # args", object->cmdName, - NsfMethodNamePath(interp, NULL /* use topmost frame */, NsfMethodName(objv[0])), "?value?"); + return NsfObjWrongArgs(interp, "wrong # args", object->cmdName, + NsfMethodNamePath(interp, NULL, 1, NsfMethodName(objv[0])), "?value?"); } if (object == NULL) return NsfDispatchClientDataError(interp, clientData, "object", ObjStr(objv[0])); @@ -19598,7 +19599,7 @@ if (tcd->object) { cmd = Tcl_DuplicateObj(tcd->object->cmdName); if (objc > 0) { - Tcl_ListObjAppendList(interp, cmd, NsfMethodNamePath(interp, NULL, MethodName(objv[0]))); + Tcl_ListObjAppendList(interp, cmd, NsfMethodNamePath(interp, NULL, 1, MethodName(objv[0]))); if (objc > 1) { Tcl_ListObjAppendElement(interp, cmd, Tcl_NewListObj(objc-1,objv+1)); } @@ -20852,7 +20853,7 @@ && (processFlags & NSF_ARGPARSE_FORCE_REQUIRED)) { Tcl_Obj *paramDefsObj = NsfParamDefsSyntax(interp, ifd, pcPtr->object, NULL); Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, - NULL /* use topmost frame */, + NULL, 1, MethodName(pcPtr->full_objv[0])); INCR_REF_COUNT2("methodPathObj", methodPathObj); @@ -21006,9 +21007,9 @@ #endif if (unlikely(currentParamPtr > lastParamPtr)) { - return NsfUnexpectedArgumentError(interp, ObjStr(argumentObj), - (Nsf_Object*)object, paramPtr, - NsfMethodNamePath(interp, NULL /* use topmost frame */, NsfMethodName(procNameObj))); + Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, NULL, 0, NsfMethodName(procNameObj)); + return NsfUnexpectedArgumentError(interp, ObjStr(argumentObj), (Nsf_Object*)object, + paramPtr, methodPathObj); } if (*currentParamPtr->name == '-') { @@ -21115,10 +21116,11 @@ Nsf_Param CONST *nextParamPtr = NextParam(currentParamPtr, lastParamPtr); if (nextParamPtr > lastParamPtr || (nextParamPtr->flags & NSF_ARG_NOLEADINGDASH)) { + Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, NULL, 0, NsfMethodName(procNameObj)); return NsfUnexpectedNonposArgumentError(interp, argumentString, (Nsf_Object *)object, currentParamPtr, paramPtr, - NsfMethodNamePath(interp, NULL /* use topmost frame */, NsfMethodName(procNameObj))); + methodPathObj); } pPtr = currentParamPtr = nextParamPtr; } @@ -21170,10 +21172,11 @@ ObjStr(argumentObj)); } #endif + Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, NULL, 0, NsfMethodName(procNameObj)); return NsfUnexpectedNonposArgumentError(interp, argumentString, (Nsf_Object *)object, currentParamPtr, paramPtr, - NsfMethodNamePath(interp, NULL /* use topmost frame */, NsfMethodName(procNameObj))); + methodPathObj); } pPtr = currentParamPtr = nextParamPtr; } @@ -21191,9 +21194,11 @@ * parameter, valueObj might be already provided for valueInArgument. */ if (unlikely(pPtr > lastParamPtr)) { + Tcl_Obj *methodPathObj = NsfMethodNamePath(interp, NULL, 0, NsfMethodName(procNameObj)); + return NsfUnexpectedArgumentError(interp, ObjStr(argumentObj), - (Nsf_Object *)object, paramPtr, - NsfMethodNamePath(interp, NULL /* use topmost frame */, NsfMethodName(procNameObj))); + (Nsf_Object *)object, paramPtr, + methodPathObj); } @@ -26163,7 +26168,7 @@ case CurrentoptionMethodpathIdx: cscPtr = CallStackGetTopFrame0(interp); Tcl_SetObjResult(interp, NsfMethodNamePath(interp, - NULL /* use topmost frame */, + NULL, 1, Tcl_GetCommandName(interp, cscPtr->cmdPtr))); break; @@ -26231,6 +26236,7 @@ if (cscPtr && cscPtr->cmdPtr) { resultObj = NsfMethodNamePath(interp, framePtr, + 1, Tcl_GetCommandName(interp, cscPtr->cmdPtr)); } else { resultObj = NsfGlobalObjs[NSF_EMPTY]; @@ -29696,7 +29702,7 @@ } */ static int -NsfClassInfoSubclassMethod(Tcl_Interp *interp, NsfClass *class, +NsfClassInfoSubclassMethod(Tcl_Interp *interp, NsfClass *class, int withClosure, int withDependent, CONST char *patternString, NsfObject *patternObj) { int rc = 0; Index: generic/nsfError.c =================================================================== diff -u -r3ffcbc1b5cf21f850b3dd486f9aa48c93f08e7a8 -r236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e --- generic/nsfError.c (.../nsfError.c) (revision 3ffcbc1b5cf21f850b3dd486f9aa48c93f08e7a8) +++ generic/nsfError.c (.../nsfError.c) (revision 236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e) @@ -315,21 +315,21 @@ int NsfUnexpectedArgumentError(Tcl_Interp *interp, CONST char *argumentString, Nsf_Object *object, Nsf_Param CONST *paramPtr, - Tcl_Obj *methodNamePathObj) { + Tcl_Obj *methodPathObj) { Tcl_DString ds, *dsPtr = &ds; assert(interp); assert(argumentString); assert(paramPtr); - assert(methodNamePathObj); + assert(methodPathObj); DSTRING_INIT(dsPtr); Tcl_DStringAppend(dsPtr, "invalid argument '", -1); Tcl_DStringAppend(dsPtr, argumentString, -1); Tcl_DStringAppend(dsPtr, "', maybe too many arguments;", -1); NsfArgumentError(interp, Tcl_DStringValue(dsPtr), paramPtr, object ? object->cmdName : NULL, - methodNamePathObj); + methodPathObj); DSTRING_FREE(dsPtr); return TCL_ERROR; } @@ -355,15 +355,15 @@ Nsf_Object *object, Nsf_Param CONST *currentParamPtr, Nsf_Param CONST *paramPtr, - Tcl_Obj *methodNamePathObj) { + Tcl_Obj *methodPathObj) { Tcl_DString ds, *dsPtr = &ds; Nsf_Param CONST *pPtr; assert(interp); assert(argumentString); assert(currentParamPtr); assert(paramPtr); - assert(methodNamePathObj); + assert(methodPathObj); DSTRING_INIT(dsPtr); Tcl_DStringAppend(dsPtr, "invalid non-positional argument '", -1); @@ -381,7 +381,7 @@ NsfArgumentError(interp, Tcl_DStringValue(dsPtr), paramPtr, object ? object->cmdName : NULL, - methodNamePathObj); + methodPathObj); DSTRING_FREE(dsPtr); return TCL_ERROR; } Index: generic/nsfInt.h =================================================================== diff -u -r76bdfab614f658464ee9e020d0275868cdd61026 -r236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e --- generic/nsfInt.h (.../nsfInt.h) (revision 76bdfab614f658464ee9e020d0275868cdd61026) +++ generic/nsfInt.h (.../nsfInt.h) (revision 236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e) @@ -1019,8 +1019,9 @@ EXTERN Tcl_Obj *NsfMethodNamePath(Tcl_Interp *interp, Tcl_CallFrame *framePtr, + int skip, CONST char *methodName) - nonnull(1) nonnull(3) returns_nonnull; + nonnull(1) nonnull(4) returns_nonnull; /* * Definition of methodEpoch macros Index: generic/nsfStack.c =================================================================== diff -u -r92ab630ebd3c1b907e3d0fdf97cc07914245c028 -r236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e --- generic/nsfStack.c (.../nsfStack.c) (revision 92ab630ebd3c1b907e3d0fdf97cc07914245c028) +++ generic/nsfStack.c (.../nsfStack.c) (revision 236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e) @@ -734,10 +734,10 @@ * *---------------------------------------------------------------------- */ -static Tcl_Obj* CallStackMethodPath(Tcl_Interp *interp, Tcl_CallFrame *framePtr) nonnull(1) nonnull(2); +static Tcl_Obj* CallStackMethodPath(Tcl_Interp *interp, int skip, Tcl_CallFrame *framePtr) nonnull(1) nonnull(3); static Tcl_Obj* -CallStackMethodPath(Tcl_Interp *interp, Tcl_CallFrame *framePtr) { +CallStackMethodPath(Tcl_Interp *interp, int skip, Tcl_CallFrame *framePtr) { int elements; Tcl_Obj *resultObj; Tcl_Obj *methodPathObj = Tcl_NewListObj(0, NULL); @@ -749,8 +749,10 @@ * Append all ensemble names to the specified list obj */ + while(skip--) {framePtr = Tcl_CallFrame_callerPtr(framePtr);} + for (/* Skipping the starting frame, assuming a "leaf" frame in an ensemble dispatch */ - framePtr = Tcl_CallFrame_callerPtr(framePtr), elements = 0; + elements = 0; Tcl_CallFrame_isProcCallFrame(framePtr) & (FRAME_IS_NSF_CMETHOD|FRAME_IS_NSF_METHOD); framePtr = Tcl_CallFrame_callerPtr(framePtr)) { Index: tests/submethods.test =================================================================== diff -u -r23b10a2c736cf33731b0d7b0381314ddec44f2d6 -r236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e --- tests/submethods.test (.../submethods.test) (revision 23b10a2c736cf33731b0d7b0381314ddec44f2d6) +++ tests/submethods.test (.../submethods.test) (revision 236b6dfeb5bc9a7fa81e596f9f5d0bb7dfa6ea9e) @@ -4,7 +4,17 @@ ::nx::configure defaultMethodCallProtection false -nx::test configure -count 100 +# +# test, whether error message from a submethod contains method path +# +nx::test case info-errors { + ? {::nx::Object info subclass a b c} \ + {invalid argument 'b', maybe too many arguments; should be "::nx::Object info subclass ?-closure? ?-dependent? ?/pattern/?"} + ? {::nx::Object info object mixin classes a b c} \ + {invalid argument 'b', maybe too many arguments; should be "::nx::Object info object mixin classes ?-guards? ?/pattern/?"} +} + +nx::test configure -count 10 nx::test case submethods { #Object method unknown {} {} Object create o1