Index: TODO =================================================================== diff -u -r542e84bd66ce4c3cd28e4ba1fd41f2151d8cb043 -r4f25a7683bc3261be5c5d2e7ab07a3cb0d6d6e96 --- TODO (.../TODO) (revision 542e84bd66ce4c3cd28e4ba1fd41f2151d8cb043) +++ TODO (.../TODO) (revision 4f25a7683bc3261be5c5d2e7ab07a3cb0d6d6e96) @@ -2908,6 +2908,10 @@ - added documentation for unknown handlers in tutorial - cleanup of __unknown +- added handling for provided arguments to positional object parameters with + disposition alias and forward +- provided better error messages for unknown parameter options +- provided error messages for multiple disposition parameters TODO: Index: generic/nsf.c =================================================================== diff -u -r802ecff8cf163e6c1e8e6cf8eb590fddc5097e06 -r4f25a7683bc3261be5c5d2e7ab07a3cb0d6d6e96 --- generic/nsf.c (.../nsf.c) (revision 802ecff8cf163e6c1e8e6cf8eb590fddc5097e06) +++ generic/nsf.c (.../nsf.c) (revision 4f25a7683bc3261be5c5d2e7ab07a3cb0d6d6e96) @@ -7907,7 +7907,7 @@ } else { Tcl_AppendLimitedToObj(argStringObj, "?", 1, INT_MAX, NULL); Tcl_AppendLimitedToObj(argStringObj, pPtr->name, -1, INT_MAX, NULL); - if (pPtr->nrArgs >0) { + if (pPtr->nrArgs > 0 && *pPtr->name == '-') { Tcl_AppendLimitedToObj(argStringObj, " ", 1, INT_MAX, NULL); Tcl_AppendLimitedToObj(argStringObj, ParamGetDomain(pPtr), -1, INT_MAX, NULL); if (pPtr->flags & NSF_ARG_MULTIVALUED) { @@ -9996,6 +9996,19 @@ } else { int i, found = -1; + if (paramPtr->converter || + (paramPtr->flags & (NSF_ARG_ALIAS|NSF_ARG_FORWARD|NSF_ARG_INITCMD))) { + Tcl_Obj *obj = Tcl_NewStringObj(option, optionLength); + NsfPrintError(interp, "Parameter option '%s' unknown for parameter type %s", + ObjStr(obj), + paramPtr->converter ? paramPtr->type : + paramPtr->flags & NSF_ARG_ALIAS ? "alias" : + paramPtr->flags & NSF_ARG_FORWARD ? "forward" : + "initcmd"); + DECR_REF_COUNT(obj); + return TCL_ERROR; + } + for (i=0; stringTypeOpts[i]; i++) { /* Do not allow abbreviations, so the additional strlen checks for a full match */ @@ -10022,6 +10035,14 @@ return NsfPrintError(interp, "Parameter option '%s' not allowed", option); } + if ((paramPtr->flags & (NSF_ARG_ALIAS|NSF_ARG_FORWARD)) == (NSF_ARG_ALIAS|NSF_ARG_FORWARD)) { + return NsfPrintError(interp, "Parameter options alias and forward can be not used together"); + } else if ((paramPtr->flags & (NSF_ARG_ALIAS|NSF_ARG_INITCMD)) == (NSF_ARG_ALIAS|NSF_ARG_INITCMD)) { + return NsfPrintError(interp, "Parameter options alias and initcmd can be not used together"); + } else if ((paramPtr->flags & (NSF_ARG_FORWARD|NSF_ARG_INITCMD)) == (NSF_ARG_FORWARD|NSF_ARG_INITCMD)) { + return NsfPrintError(interp, "Parameter options forward and initcmd can be not used together"); + } + return result; } @@ -10046,11 +10067,15 @@ argString = ObjStr(npav[0]); length = strlen(argString); - isNonposArgument = *argString == '-'; + /* + * Per default parameter have exactly one argument; types without arguments + * (like "switch") have to set their nrArgs explicitly. + */ + paramPtr->nrArgs = 1; + isNonposArgument = *argString == '-'; if (isNonposArgument) { argName = argString+1; - paramPtr->nrArgs = 1; /* per default 1 argument, switches set their arg numbers */ (*nrNonposArgs) ++; } else { argName = argString; @@ -18484,12 +18509,12 @@ * avoid overwriting with default values when e.g. "o configure" * is called lated without arguments. */ - /* - fprintf(stderr, "param %s, INIT CALLED %d is default %d value = %s\n", + + /*fprintf(stderr, "param %s, INIT CALLED %d is default %d value = %s\n", paramPtr->name, (object->flags & NSF_INIT_CALLED), (pc.flags[i-1] & NSF_PC_IS_DEFAULT), - ObjStr(pc.full_objv[i])); - */ + ObjStr(pc.full_objv[i]));*/ + if ((object->flags & NSF_INIT_CALLED) && (pc.flags[i-1] & NSF_PC_IS_DEFAULT)) { Tcl_Obj *varObj; @@ -18518,7 +18543,10 @@ continue; } - /* special setter for init commands */ + /* + * Special setter methods, calling method; handle types "initcmd", "alias" + * and "forward". + */ if (paramPtr->flags & (NSF_ARG_INITCMD|NSF_ARG_ALIAS|NSF_ARG_FORWARD)) { CallFrame *varFramePtr = Tcl_Interp_varFramePtr(interp); NsfCallStackContent csc, *cscPtr = &csc; @@ -18559,16 +18587,18 @@ cscPtr->frameType = NSF_CSC_TYPE_INACTIVE; /* - * If method= was given, use it as method name + * If "method=" was given, use it as method name */ methodObj = paramPtr->method ? paramPtr->method : paramPtr->nameObj; if (paramPtr->nrArgs == 1) { ov[oc] = newValue; oc ++; } - /*fprintf(stderr, "call **alias with methodObj %s.%s oc %d\n", - ObjectName(object), ObjStr(methodObj), oc);*/ + + /*fprintf(stderr, "call alias with methodObj %s.%s oc %d, nrArgs %d %s\n", + ObjectName(object), ObjStr(methodObj), oc, paramPtr->nrArgs, ObjStr(newValue));*/ + result = NsfCallMethodWithArgs(object, interp, methodObj, ov[0], oc, &ov[1], NSF_CSC_IMMEDIATE); Index: tests/parameters.test =================================================================== diff -u -r802ecff8cf163e6c1e8e6cf8eb590fddc5097e06 -r4f25a7683bc3261be5c5d2e7ab07a3cb0d6d6e96 --- tests/parameters.test (.../parameters.test) (revision 802ecff8cf163e6c1e8e6cf8eb590fddc5097e06) +++ tests/parameters.test (.../parameters.test) (revision 4f25a7683bc3261be5c5d2e7ab07a3cb0d6d6e96) @@ -661,7 +661,7 @@ # define type twice ? {D public method foo {a:int,range,arg=1-3} {return a=$a}} \ - "Refuse to redefine parameter converter to use type=range" \ + "Parameter option 'range' unknown for parameter type integer" \ "invalid value" # # handling of arg with spaces/arg as list