Index: TODO =================================================================== diff -u -rf9bd043ef944ad48d9d626408d25d8df241d834d -r2767762e5ef68bee6e82cbff0d69f54b01c37a13 --- TODO (.../TODO) (revision f9bd043ef944ad48d9d626408d25d8df241d834d) +++ TODO (.../TODO) (revision 2767762e5ef68bee6e82cbff0d69f54b01c37a13) @@ -1991,12 +1991,25 @@ - NSDeleteChildren: delete here aliases as well - fix potential crash when "next" is called from a non-proc frame. +- nx.tcl: cleanup of forward implementation +- xotcl2.tcl: cleanup of forward implementation +- xotcl2.tcl: provide debug version of default init method + +- nsf.c: aquire parameter structure for returns more lazyly + (otherwise, a serializer handling returns would aquire the + structure for every argument) +- extend regression test + +- xotcl2.tcl: fix the default init handler +- nsf.c: provide warnings when unchecked parameter values might conflict with nonpos args + TODO: - "-returns" * handle "-returns" in serializer - change allowempty to "empty" +- check performance implications of value conflict checker - extend coro regression test Index: generic/nsf.c =================================================================== diff -u -r6b039871ad08a490bb975e3ddd713177f6dd9ea9 -r2767762e5ef68bee6e82cbff0d69f54b01c37a13 --- generic/nsf.c (.../nsf.c) (revision 6b039871ad08a490bb975e3ddd713177f6dd9ea9) +++ generic/nsf.c (.../nsf.c) (revision 2767762e5ef68bee6e82cbff0d69f54b01c37a13) @@ -7922,7 +7922,7 @@ int result; if (pPtr->converterArg) { - /*fprintf(stderr, "ConvertToStringType %s (must be %s)\n", ObjStr(objPtr), ObjStr(pPtr->converterArg));*/ + /*fprintf(stderr, "ConvertToTclobj %s (must be %s)\n", ObjStr(objPtr), ObjStr(pPtr->converterArg));*/ objv[1] = pPtr->converterArg; objv[2] = objPtr; @@ -7940,6 +7940,18 @@ } } } else { + + if (RUNTIME_STATE(interp)->debugLevel > 0) { + char *value = ObjStr(objPtr); + if (*value == '-' + && (pPtr->flags & NSF_ARG_CHECK_NONPOS) + && isalpha(*(value+1)) + && strchr(value+1, ' ') == 0) { + fprintf(stderr, "Warning: value '%s' of parameter %s could be a non-positional argument\n", + value, pPtr->name); + } + } + *clientData = (ClientData)objPtr; result = TCL_OK; } @@ -8302,7 +8314,7 @@ static int ParamParse(Tcl_Interp *interp, Tcl_Obj *procNameObj, Tcl_Obj *arg, int disallowedFlags, - NsfParam *paramPtr, int *possibleUnknowns, int *plainParams) { + NsfParam *paramPtr, int *possibleUnknowns, int *plainParams, int *nrNonposArgs) { int result, npac, isNonposArgument; size_t nameLength, length, j; CONST char *argString, *argName; @@ -8327,6 +8339,7 @@ argName = argString+1; nameLength = length-1; paramPtr->nrArgs = 1; /* per default 1 argument, switches set their arg numbers */ + (*nrNonposArgs) ++; } else { argName = argString; nameLength = length; @@ -8511,20 +8524,26 @@ if (argsc > 0) { NsfParam *paramsPtr, *paramPtr, *lastParamPtr; - int i, possibleUnknowns = 0, plainParams = 0; + int i, possibleUnknowns = 0, plainParams = 0, nrNonposArgs = 0; NsfParamDefs *paramDefs; paramPtr = paramsPtr = ParamsNew(argsc); for (i=0; i < argsc; i++, paramPtr++) { result = ParamParse(interp, procNameObj, argsv[i], allowedOptinons, - paramPtr, &possibleUnknowns, &plainParams); + paramPtr, &possibleUnknowns, &plainParams, &nrNonposArgs); if (result != TCL_OK) { ParamsFree(paramsPtr); return result; } } + if (nrNonposArgs > 0) { + for (i=0; i < argsc; i++) { + (paramsPtr + i)->flags |= NSF_ARG_CHECK_NONPOS; + } + } + /* * If all arguments are good old Tcl arguments, there is no need * to use the parameter definition structure. @@ -11984,7 +12003,6 @@ Tcl_DStringAppend(dsPtr, "Invalid argument '", -1); Tcl_DStringAppend(dsPtr, ObjStr(objv[pcPtr->lastobjc]), -1); Tcl_DStringAppend(dsPtr, "', maybe too many arguments;", -1); - fprintf(stderr, "processing %s\n",ObjStr(objv[pcPtr->lastobjc])); return ArgumentError(interp, Tcl_DStringValue(dsPtr), paramPtr, object ? object->cmdName : NULL, procNameObj); @@ -14808,12 +14826,13 @@ if (j < length) { /* looks as if we have a parameter specification */ - int result, possibleUnknowns = 0, plainParams = 0; + int result, possibleUnknowns = 0, plainParams = 0, nrNonposArgs = 0; setterClientData->paramsPtr = ParamsNew(1); result = ParamParse(interp, NsfGlobalObjs[NSF_SETTER], parameter, NSF_DISALLOWED_ARG_SETTER|NSF_ARG_HAS_DEFAULT, - setterClientData->paramsPtr, &possibleUnknowns, &plainParams); + setterClientData->paramsPtr, &possibleUnknowns, + &plainParams, &nrNonposArgs); if (result != TCL_OK) { SetterCmdDeleteProc((ClientData)setterClientData); @@ -14900,7 +14919,7 @@ { NsfParamWrapper *paramWrapperPtr = NEW(NsfParamWrapper); Tcl_Obj *fullParamObj = Tcl_NewStringObj(varNamePrefix, -1); - int result, possibleUnknowns = 0, plainParams = 0; + int result, possibleUnknowns = 0, plainParams = 0, nrNonposArgs = 0; paramWrapperPtr->paramPtr = ParamsNew(1); paramWrapperPtr->refCount = 1; @@ -14911,7 +14930,8 @@ INCR_REF_COUNT(fullParamObj); result = ParamParse(interp, NsfGlobalObjs[NSF_VALUECHECK], fullParamObj, NSF_DISALLOWED_ARG_VALUECHECK /* disallowed options */, - paramWrapperPtr->paramPtr, &possibleUnknowns, &plainParams); + paramWrapperPtr->paramPtr, &possibleUnknowns, + &plainParams, &nrNonposArgs); /* Here, we want to treat currently unknown user level converters as error. */ Index: generic/nsfInt.h =================================================================== diff -u -rd49e60e74c36c563db5ba7095c2f898f1029169b -r2767762e5ef68bee6e82cbff0d69f54b01c37a13 --- generic/nsfInt.h (.../nsfInt.h) (revision d49e60e74c36c563db5ba7095c2f898f1029169b) +++ generic/nsfInt.h (.../nsfInt.h) (revision 2767762e5ef68bee6e82cbff0d69f54b01c37a13) @@ -370,6 +370,7 @@ #define NSF_ARG_HAS_DEFAULT 0x1000 #define NSF_ARG_IS_CONVERTER 0x2000 #define NSF_ARG_IS_ENUMERATION 0x4000 +#define NSF_ARG_CHECK_NONPOS 0x8000 /* Disallowed parameter options */ #define NSF_DISALLOWED_ARG_METHOD_PARAMETER (NSF_ARG_METHOD|NSF_ARG_INITCMD|NSF_ARG_RELATION) Index: library/xotcl/library/xotcl2.tcl =================================================================== diff -u -reee4785ee9a2e4bad0c615d56d9e1477578e20e5 -r2767762e5ef68bee6e82cbff0d69f54b01c37a13 --- library/xotcl/library/xotcl2.tcl (.../xotcl2.tcl) (revision eee4785ee9a2e4bad0c615d56d9e1477578e20e5) +++ library/xotcl/library/xotcl2.tcl (.../xotcl2.tcl) (revision 2767762e5ef68bee6e82cbff0d69f54b01c37a13) @@ -330,7 +330,7 @@ # "init" must exist on Object. per default it is empty. Object instproc init args { - if {[::nsf::current isnextcall] && [llength $args] > 0 && [::nsf::configure debug] > 0} { + if {![::nsf::current isnextcall] && [llength $args] > 0 && [::nsf::configure debug] > 0} { puts stderr "Warning: arguments '$args' to constructor of object [self] are most likely not processed" } }