Index: TODO =================================================================== diff -u -r3016e6466668218392140bc884fa8bf489721eda -r61d81f3da45ce76f6bb9eafa4cc8a1b4c5b08953 --- TODO (.../TODO) (revision 3016e6466668218392140bc884fa8bf489721eda) +++ TODO (.../TODO) (revision 61d81f3da45ce76f6bb9eafa4cc8a1b4c5b08953) @@ -5494,6 +5494,10 @@ ::nsf::methods::class::info::mixinclasses -> ::nsf::methods::class::info::mixins ::nsf::methods::object::info::mixinclasses -> ::nsf::methods::object::info::mixins +nsf.c: +- provide error messages for ambiguous abbreviations +- extend regression test (now 5460 tests) + ======================================================================== TODO: Index: generic/nsf.c =================================================================== diff -u -r3016e6466668218392140bc884fa8bf489721eda -r61d81f3da45ce76f6bb9eafa4cc8a1b4c5b08953 --- generic/nsf.c (.../nsf.c) (revision 3016e6466668218392140bc884fa8bf489721eda) +++ generic/nsf.c (.../nsf.c) (revision 61d81f3da45ce76f6bb9eafa4cc8a1b4c5b08953) @@ -11091,17 +11091,22 @@ * *---------------------------------------------------------------------- */ -static Nsf_Param CONST *NsfParamDefsNonposLookup(CONST char *nameString, Nsf_Param CONST *paramsPtr) - nonnull(1) nonnull(2); +static int NsfParamDefsNonposLookup(Tcl_Interp *interp, CONST char *nameString, + Nsf_Param CONST *paramsPtr, Nsf_Param CONST **paramPtrPtr) + nonnull(1) nonnull(2) nonnull(3) nonnull(4); -static Nsf_Param CONST * -NsfParamDefsNonposLookup(CONST char *nameString, Nsf_Param CONST *paramsPtr) { +static int +NsfParamDefsNonposLookup(Tcl_Interp *interp, CONST char *nameString, + Nsf_Param CONST *paramsPtr, Nsf_Param CONST **paramPtrPtr) { Nsf_Param CONST *paramPtr; char ch1 = nameString[2]; int length; + assert(interp); assert(nameString); assert(paramsPtr); + assert(paramPtrPtr); + /* * The provided paramsPtr must point to a block starting with a nonpos arg. */ @@ -11116,7 +11121,8 @@ if (unlikely(paramPtr->flags & NSF_ARG_NOCONFIG)) continue; if (ch1 == paramPtr->name[2] && strcmp(nameString, paramPtr->name) == 0) { - return paramPtr; + *paramPtrPtr = paramPtr; + return TCL_OK; } } @@ -11129,12 +11135,34 @@ if (ch1 == paramPtr->name[2] && strncmp(nameString, paramPtr->name, length) == 0) { + Nsf_Param CONST *pPtr; + /* fprintf(stderr, "... <%s> is an abbrev of <%s>\n", nameString, paramPtr->name); */ - return paramPtr; + /* + * Check, if the abbreviation is unique + */ + for (pPtr = paramPtr + 1; likely(pPtr->name != NULL) && *pPtr->name == '-'; pPtr++) { + if (unlikely(pPtr->flags & NSF_ARG_NOCONFIG)) continue; + if (ch1 == pPtr->name[2] + && strncmp(nameString, pPtr->name, length) == 0) { + /* + * The abbreviation is not unique + */ + *paramPtrPtr = NULL; + return NsfPrintError(interp, "the provided argument %s is an abbreviation for %s and %s", + nameString, paramPtr->name, pPtr->name); + } + } + /* + * The abbreviation is unique + */ + *paramPtrPtr = paramPtr; + return TCL_OK; } } } - return NULL; + *paramPtrPtr = NULL; + return TCL_OK; } /* @@ -21264,10 +21292,13 @@ assert(pPtr == currentParamPtr); if (ch1 != '\0') { - pPtr = NsfParamDefsNonposLookup(argumentString, currentParamPtr); - if (pPtr != NULL) { - found = 1; - NsfFlagObjSet(interp, argumentObj, paramPtr, serial, pPtr, NULL, 0); + if (unlikely(NsfParamDefsNonposLookup(interp, argumentString, currentParamPtr, &pPtr) != TCL_OK)) { + return TCL_ERROR; + } else { + if (pPtr != NULL) { + found = 1; + NsfFlagObjSet(interp, argumentObj, paramPtr, serial, pPtr, NULL, 0); + } } } @@ -27506,8 +27537,12 @@ /* * Perform the lookup from the next group. */ - paramPtr = NsfParamDefsNonposLookup(nameString, paramPtr); - found = (paramPtr != NULL); + if (unlikely(NsfParamDefsNonposLookup(interp, nameString, paramPtr, ¶mPtr) != TCL_OK)) { + result = TCL_ERROR; + goto cget_exit; + } else { + found = (paramPtr != NULL); + } } if (!found) { Index: tests/method-parameter.test =================================================================== diff -u -r0f881e4bc45e927c8d84c1b1b468ef7537cb9b03 -r61d81f3da45ce76f6bb9eafa4cc8a1b4c5b08953 --- tests/method-parameter.test (.../method-parameter.test) (revision 0f881e4bc45e927c8d84c1b1b468ef7537cb9b03) +++ tests/method-parameter.test (.../method-parameter.test) (revision 61d81f3da45ce76f6bb9eafa4cc8a1b4c5b08953) @@ -355,8 +355,25 @@ ? {-b info superclasses -- -a} "::-a" } +nx::test case abbrevs { + nsf::proc x {-super -super11 -superclass -super12} { + return [info exists super]-[info exists super11]-[info exists superclass]-[info exists super12] + } + ? {x -super 1} "1-0-0-0" + ? {x -super1 1} "the provided argument -super1 is an abbreviation for -super11 and -super12" + ? {x -superc 1} "0-0-1-0" + ? {x -super12 1} "0-0-0-1" + nsf::proc y {-aaa1 -aa1 -a1 -a} { return [info exists aaa1]-[info exists aa1]-[info exists a1]-[info exists a] } + + ? {y -a 1} "0-0-0-1" + ? {y -aa 1} {invalid non-positional argument '-aa', valid are : -aaa1, -aa1, -a1, -a; + should be "y ?-aaa1 /value/? ?-aa1 /value/? ?-a1 /value/? ?-a /value/?"} + ? {y -aaa 1} "1-0-0-0" + ? {y -aa1 1} "0-1-0-0" +} + # # Local variables: # mode: tcl