Index: TODO =================================================================== diff -u -rd8dcbc3ba475a4617d540b4499a9c41e8bf81b07 -r2ba521e3dfbb1294908b51ed8e13dab5adc3ca03 --- TODO (.../TODO) (revision d8dcbc3ba475a4617d540b4499a9c41e8bf81b07) +++ TODO (.../TODO) (revision 2ba521e3dfbb1294908b51ed8e13dab5adc3ca03) @@ -3549,8 +3549,16 @@ (i.e. support -local, -system and -intrinsic) - extend regression test +nsf.c: + - reform of argument parse. new parser uses NsfFlagObjType + to reuse earlier parse resuslts. Improved speed for + for methods with primitive bodies: 5%-25%. + - added regression tests for argument parsing + TODO: + - check flag reuses in ~/scripts/nonposargs-speed.xotcl - NSF_WITH_OS_RESOLVER + - ParseContextExtendObjv - private: * document private in tutorial - add "property" and "attribute" and "info property" and "info slot ..." to migration guide Index: generic/gentclAPI.tcl =================================================================== diff -u -r95c4d29515cfda9283b406ba7a7ac1dd029de8c9 -r2ba521e3dfbb1294908b51ed8e13dab5adc3ca03 --- generic/gentclAPI.tcl (.../gentclAPI.tcl) (revision 95c4d29515cfda9283b406ba7a7ac1dd029de8c9) +++ generic/gentclAPI.tcl (.../gentclAPI.tcl) (revision 2ba521e3dfbb1294908b51ed8e13dab5adc3ca03) @@ -250,7 +250,7 @@ $intro if (ArgumentParse(interp, objc, objv, $obj, objv[0], method_definitions[$idx].paramDefs, - method_definitions[$idx].nrParameters, 1, + method_definitions[$idx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { Index: generic/nsf.c =================================================================== diff -u -rd8dcbc3ba475a4617d540b4499a9c41e8bf81b07 -r2ba521e3dfbb1294908b51ed8e13dab5adc3ca03 --- generic/nsf.c (.../nsf.c) (revision d8dcbc3ba475a4617d540b4499a9c41e8bf81b07) +++ generic/nsf.c (.../nsf.c) (revision 2ba521e3dfbb1294908b51ed8e13dab5adc3ca03) @@ -269,8 +269,8 @@ static int ParamSetFromAny(Tcl_Interp *interp, register Tcl_Obj *objPtr); static int ArgumentParse(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], NsfObject *obj, Tcl_Obj *procName, - Nsf_Param CONST *paramPtr, int nrParameters, int doCheck, - ParseContext *pc); + Nsf_Param CONST *paramPtr, int nrParameters, int serial, + int doCheck, ParseContext *pc); static int ArgumentCheck(Tcl_Interp *interp, Tcl_Obj *objPtr, struct Nsf_Param CONST *pPtr, int doCheck, int *flags, ClientData *clientData, Tcl_Obj **outObjPtr); @@ -8233,9 +8233,11 @@ static NsfParamDefs * ParamDefsNew() { NsfParamDefs *paramDefs; + static int serial = 0; paramDefs = NEW(NsfParamDefs); memset(paramDefs, 0, sizeof(NsfParamDefs)); + paramDefs->serial = serial++; /*fprintf(stderr, "ParamDefsNew %p\n", paramDefs);*/ return paramDefs; @@ -9486,7 +9488,6 @@ assert(objc > 1); shift = 1; cmdObj = objv[0]; - methodName = ObjStr(objv[1]); methodObj = objv[1]; methodName = ObjStr(methodObj); if (FOR_COLON_RESOLVER(methodName)) { @@ -11379,8 +11380,9 @@ paramDefs = ParamDefsNew(); paramDefs->paramsPtr = paramsPtr; paramDefs->nrParams = paramPtr-paramsPtr; - /*fprintf(stderr, "method %s paramDefs %p ifsize %ld, possible unknowns = %d,\n", - ObjStr(procNameObj), paramDefs, paramPtr-paramsPtr, possibleUnknowns);*/ + /*fprintf(stderr, "method %s serial %d paramDefs %p ifsize %ld, possible unknowns = %d,\n", + ObjStr(procNameObj), paramDefs->serial, + paramDefs, paramPtr-paramsPtr, possibleUnknowns);*/ parsedParamPtr->paramDefs = paramDefs; parsedParamPtr->possibleUnknowns = possibleUnknowns; } @@ -11981,15 +11983,15 @@ } result = ArgumentParse(interp, objc, objv, object, methodNameObj, - paramDefs->paramsPtr, paramDefs->nrParams, + paramDefs->paramsPtr, paramDefs->nrParams, paramDefs->serial, RUNTIME_STATE(interp)->doCheckArguments, pcPtr); #if 0 { int i; - fprintf(stderr, "after ArgumentParse\n"); + fprintf(stderr, "after ArgumentParse %s\n", ObjStr(methodNameObj)); for (i = 0; i < pcPtr->objc-1; i++) { - fprintf(stderr, "... pcPtr %p check [%d] obj %p refCount %d (%s) flags %.6x & %p\n", + fprintf(stderr, "... pcPtr %p [%d] obj %p refCount %d (%s) flags %.6x & %p\n", pcPtr, i, pcPtr->objv[i], pcPtr->objv[i]->refCount, ObjStr(pcPtr->objv[i]), pcPtr->flags[i], &(pcPtr->flags[i])); } @@ -15531,10 +15533,10 @@ if (pcPtr->objv[i]) { /* * We got an actual value, which was already checked by ArgumentParse() - * In case the value is a boolean, NSF_PC_MUST_INVERT is set. We invert - * the value in place. + * In case the value is a switch and NSF_PC_INVERT_DEFAULT is set, we + * take the default and invert the value in place. */ - if ((pcPtr->flags[i] & NSF_PC_MUST_INVERT)) { + if ((pcPtr->flags[i] & NSF_PC_INVERT_DEFAULT)) { int bool; Tcl_GetBooleanFromObj(interp, pPtr->defaultValue, &bool); pcPtr->objv[i] = Tcl_NewBooleanObj(!bool); @@ -15674,321 +15676,372 @@ extern int Nsf_ArgumentParse(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Nsf_Object *object, Tcl_Obj *procNameObj, - Nsf_Param CONST *paramPtr, int nrParams, int doCheck, + Nsf_Param CONST *paramPtr, int nrParams, int serial, + int doCheck, Nsf_ParseContext *pcPtr) { return ArgumentParse(interp, objc, objv, (NsfObject *)object, procNameObj, - paramPtr, nrParams, doCheck, + paramPtr, nrParams, serial, doCheck, (ParseContext *)pcPtr); } +#define SkipNonposParamDefs(cPtr) \ + for (; ++cPtr <= lastParamPtr && *cPtr->name == '-';) + static int ArgumentParse(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], NsfObject *object, Tcl_Obj *procNameObj, - Nsf_Param CONST *paramPtr, int nrParams, int doCheck, - ParseContext *pcPtr) { - int i, o, flagCount, dashdash = 0, nrDashdash = 0; - Nsf_Param CONST *pPtr; - + Nsf_Param CONST *paramPtr, int nrParams, int serial, + int doCheck, ParseContext *pcPtr) { + int o, dashdash = 0, j; + Nsf_Param CONST *currentParamPtr = paramPtr; + Nsf_Param CONST *lastParamPtr = paramPtr + nrParams - 1; + ParseContextInit(pcPtr, nrParams, object, objv[0]); #if defined(PARSE_TRACE) - fprintf(stderr, "PARAMETER "); - for (o = 0, pPtr = paramPtr; pPtr->name; o++, pPtr++) { - fprintf(stderr, "[%d]%s (nrargs %d %s) ", o, - pPtr->name, pPtr->nrArgs, - pPtr->flags & NSF_ARG_REQUIRED ? "req":"not req"); + { Nsf_Param CONST *pPtr; + fprintf(stderr, "PARAMETER "); + for (o = 0, pPtr = paramPtr; pPtr->name; o++, pPtr++) { + fprintf(stderr, "[%d]%s (nrargs %d %s) ", o, + pPtr->name, pPtr->nrArgs, + pPtr->flags & NSF_ARG_REQUIRED ? "req" : "opt"); + } + fprintf(stderr, "\n"); + fprintf(stderr, "BEGIN (%d) [0]%s ", objc, ObjStr(procNameObj)); + for (o = 1; o < objc; o++) {fprintf(stderr, "[%d]%s ", o, ObjStr(objv[o]));} + fprintf(stderr, "\n"); } - fprintf(stderr, "\n"); - fprintf(stderr, "BEGIN (%d) [0]%s ", objc, ObjStr(procNameObj)); - for (o = 1; o < objc; o++) {fprintf(stderr, "[%d]%s ", o, ObjStr(objv[o]));} - fprintf(stderr, "\n"); #endif + - /* - * Process the argument vector according to the parameter - * definitions. - */ - for (i = 0, o = 1, pPtr = paramPtr; pPtr->name && o < objc;) { + for (o = 1; o < objc; o++) { + Nsf_Param CONST *pPtr = currentParamPtr; + Tcl_Obj *argumentObj = objv[o]; + Tcl_Obj *valueObj = NULL; // TODO set selectively? + char *valueInArgument = NULL; // TODO set selectively? #if defined(PARSE_TRACE_FULL) - fprintf(stderr, "... (%d) processing [%d]: '%s' %s\n", i, o, - pPtr->name, pPtr->flags & NSF_ARG_REQUIRED ? "req":"not req"); + fprintf(stderr, "arg [%d]: %s\n", o, ObjStr(argumentObj)); #endif - flagCount = 0; - if (*pPtr->name == '-') { - int p, found; - CONST char *argument; - /* - * We expect now a non-positional (named) parameter, starting - * with a "-"; such arguments can be given in an arbitrary - * order. Therefore we iterate over the actual argument list - * until we find a matching flag. + + if (unlikely(currentParamPtr > lastParamPtr)) { + return NsfUnexpectedArgumentError(interp, ObjStr(argumentObj), + (Nsf_Object*)object, paramPtr, procNameObj); + } + + if (*currentParamPtr->name == '-') { + /* + * We expect a nonpos arg. Check, if we a Tcl_Obj already converted to + * NsfFlagObjType. */ - for (p = o; p < objc; p++) { - argument = ObjStr(objv[p]); - found = 0; + NsfFlag *flagPtr = argumentObj->internalRep.twoPtrValue.ptr1; - /*fprintf(stderr, "....checking objv[%d]=%s\n", p, argument);*/ +#if defined(PARSE_TRACE_FULL) + fprintf(stderr, "... arg %p %s expect nonpos arg in block %s isFlag %d sig %d serial %d (%d/%d)\n", + argumentObj, ObjStr(argumentObj), currentParamPtr->name, + argumentObj->typePtr == &NsfFlagObjType, + argumentObj->typePtr == &NsfFlagObjType ? flagPtr->signature == paramPtr : 0, + argumentObj->typePtr == &NsfFlagObjType ? flagPtr->serial == serial : 0, + argumentObj->typePtr == &NsfFlagObjType ? flagPtr->serial : 0, + serial ); +#endif - if (argument[0] != '-') { - /* there is no positional arg in the given argument vector */ - break; + if (argumentObj->typePtr == &NsfFlagObjType + && flagPtr->signature == paramPtr + && flagPtr->serial == serial + ) { + /* + * The argument was processed before, the Tcl_Obj is still valid. + */ + + if (flagPtr->flags & NSF_FLAG_DASHDAH) { + /* + * We got a dashDash, skip nonpos param defs and continue with next + * element from objv + */ + SkipNonposParamDefs(currentParamPtr); + assert(dashdash == 0); + //fprintf(stderr, "... NsfFlag: returned dashdash\n"); + continue; + } else if (flagPtr->flags & NSF_FLAG_CONTAINS_VALUE) { + valueInArgument = "flag"; + //fprintf(stderr, "... NsfFlag: '%s' contains value %s\n", ObjStr(argumentObj), ObjStr(flagPtr->payload)); } else { - /* - * We have an argument starting with a "-"; is it really one - * of the specified flags? + //fprintf(stderr, "... NsfFlag: '%s' plain flag, paramPtr %p %s\n", + // ObjStr(argumentObj), flagPtr->paramPtr, flagPtr->paramPtr->name); + } + pPtr = flagPtr->paramPtr; + valueObj = flagPtr->payload; + + } else { + CONST char *argumentString = ObjStr(argumentObj); + /* + * We are in a state, where we expect a non-positional argument, but + * if this non-pos args are optional, the provided arguments might + * contain also a value for a positional argument maybe the argument + * is for a posarg later). First check, if the argument looks like a + * flag. + */ + if (argumentString[0] != '-') { + /* + * The actual argument is not a flag, so proceed in the parameter + * vector to the next block (positional parameter) */ - Nsf_Param CONST *nppPtr; - CONST char *valueInArgument = strchr(argument, '='); - char ch1 = *(argument+1); + SkipNonposParamDefs(currentParamPtr); + pPtr = currentParamPtr; + /* currentParamPtr is either NULL or points to a positional parameter */ + } else { + /* + * The actual argument starts with a dash, so search for the flag in + * the current block of nonpos parameter definitions + */ + char ch1 = *(argumentString+1); + int found = 0; /* Is there a "--" ? */ - if (ch1 == '-' && *(argument+2) == '\0' && dashdash == 0) { -#if defined(PARSE_TRACE_FULL) - fprintf(stderr, "... skip double dash once\n"); -#endif - dashdash++; - nrDashdash++; - o++; - break; + if (ch1 == '-' && *(argumentString+2) == '\0' && dashdash == 0) { + dashdash = 1; + NsfFlagObjSet(interp, argumentObj, paramPtr, serial, + NULL, NULL, NSF_FLAG_DASHDAH); + SkipNonposParamDefs(currentParamPtr); + continue; } + valueInArgument = strchr(argumentString, '='); if (valueInArgument) { - int equalOffset = valueInArgument - argument; + int equalOffset = valueInArgument - argumentString; /* * Handle parameter like -flag=1 - * - * Just iterate over flags without arguments here. */ - for (nppPtr = pPtr; nppPtr->name && *nppPtr->name == '-'; nppPtr ++) { - if (nppPtr->nrArgs > 0) continue; - if ((nppPtr->flags & NSF_ARG_NOCONFIG) == 0 - && ch1 == nppPtr->name[1] - && strncmp(argument, nppPtr->name, equalOffset) == 0 - && *(nppPtr->name+equalOffset) == '\0') { + for (; pPtr <= lastParamPtr && *pPtr->name == '-'; pPtr ++) { + if (pPtr->nrArgs > 0) { + /* parameter expects no arg, can't be this */ + continue; + } + if ((pPtr->flags & NSF_ARG_NOCONFIG) == 0 + && ch1 == pPtr->name[1] + && strncmp(argumentString, pPtr->name, equalOffset) == 0 + && *(pPtr->name+equalOffset) == '\0') { + + valueObj = Tcl_NewStringObj(valueInArgument+1,-1); + /*fprintf(stderr, "... value from argument = %s\n", ObjStr(valueObj));*/ + NsfFlagObjSet(interp, argumentObj, paramPtr, serial, + pPtr, valueObj, NSF_FLAG_CONTAINS_VALUE); found = 1; break; } } + if (!found) { + SkipNonposParamDefs(currentParamPtr); + pPtr = currentParamPtr; + } } else { /* * Must be a classical nonpos arg; check for the string in * the parameter definitions. */ - for (nppPtr = pPtr; nppPtr->name && *nppPtr->name == '-'; nppPtr ++) { - if ((nppPtr->flags & NSF_ARG_NOCONFIG) == 0 - && ch1 == nppPtr->name[1] - && strcmp(argument, nppPtr->name) == 0) { + int found = 0; + + for (; pPtr <= lastParamPtr && *pPtr->name == '-'; pPtr ++) { + if ((pPtr->flags & NSF_ARG_NOCONFIG) == 0 + && ch1 == pPtr->name[1] + && strcmp(argumentString, pPtr->name) == 0) { found = 1; + NsfFlagObjSet(interp, argumentObj, paramPtr, serial, + pPtr, NULL, 0); break; } } + if (!found) { + SkipNonposParamDefs(currentParamPtr); + pPtr = currentParamPtr; + } } + } + /* end of lookup loop */ + } + } - /*fprintf(stderr, "... nonpos arg '%s' found %d\n", argument, found);*/ - - if (found) { - Tcl_Obj *valueObj; - int j = nppPtr-paramPtr; + assert(pPtr); + /* + * pPtr points to the actual parameter (part of the currentParamPtr block) + * or might point to a place past the last parameter, in which case an + * unexpected argument was provided. o is the index of the actual + * parameter, valueObj might be already provided for valueInArgument + */ + if (unlikely(pPtr > lastParamPtr)) { + return NsfUnexpectedArgumentError(interp, ObjStr(argumentObj), + (Nsf_Object *)object, paramPtr, procNameObj); + } - /* - * A matching non-positional argument was found. - */ - /*fprintf(stderr, "... flag '%s' nth param %d o=%d p=%d, objc=%d nrArgs %d\n", - argument, j, o, p, objc, nppPtr->nrArgs);*/ + /* + * set the position in the downstream argv (normalized order) + */ + j = pPtr - paramPtr; - if (nppPtr->nrArgs == 0) { - /* - * No argument expected. Take value either from flag or - * use constant ONE. - */ +#if defined(PARSE_TRACE_FULL) + fprintf(stderr, "... pPtr->name %s/%d o %d objc %d\n", pPtr->name, pPtr->nrArgs, o, objc); +#endif + if (*pPtr->name == '-') { + /* process the nonpos arg */ + if (pPtr->nrArgs == 1) { + /* The nonpos arg expects an argument */ + o++; + if (unlikely(o >= objc)) { + /* we expect an argument, but we are already at the end of the argument list */ + return NsfPrintError(interp, "Argument for parameter '%s' expected", pPtr->name); + } + assert(valueObj == NULL); + valueObj = objv[o]; + } else { + /* The nonpos arg expects no argument */ + if (valueObj == NULL) { + valueObj = NsfGlobalObjs[NSF_ONE]; + } + } - if (valueInArgument) { - valueObj = Tcl_NewStringObj(valueInArgument+1,-1); - INCR_REF_COUNT2("valueObj", valueObj); - pcPtr->flags[j] |= NSF_PC_MUST_DECR; - pcPtr->status |= NSF_PC_STATUS_MUST_DECR; - /*fprintf(stderr, "setting flag MUST_DECR for valueObj %p refCount %d " - "pcPtr %p flags[%d] %.6x &flags %p\n", - valueObj, valueObj->refCount, pcPtr, j, - pcPtr->flags[j], &(pcPtr->flags[j]));*/ - } else { - if (nppPtr->converter == Nsf_ConvertToSwitch) { - /*fprintf(stderr,"set MUST_INVERT for '%s' flags %.6x\n", - nppPtr->name, nppPtr->flags);*/ - pcPtr->flags[j] |= NSF_PC_MUST_INVERT; - } - valueObj = NsfGlobalObjs[NSF_ONE]; - } - } else { - /* - * nrArgs is 0 or 1; therfore we expect one argument (currently, - * it has to be exactly one argument). Increment the counters - * and get the argument from the provided argument vector. - */ - assert(nppPtr->nrArgs == 1); - o++; p++; + } else if (unlikely(pPtr == lastParamPtr && + pPtr->converter == ConvertToNothing)) { + /* + * "args" was given, use the varargs interface. Store the actual + * argument into pcPtr->objv. No checking is performed on "args". + */ + pcPtr->varArgs = 1; + pcPtr->objv[j] = argumentObj; - if (likely(p < objc)) { #if defined(PARSE_TRACE_FULL) - fprintf(stderr, "... setting cd[%d] '%s' = %s (%d) %s converter %p\n", - i, nppPtr->name, ObjStr(objv[p]), nppPtr->nrArgs, - nppPtr->flags & NSF_ARG_REQUIRED ? "req" : "not req", nppPtr->converter); + fprintf(stderr, "... args found o %d objc %d\n", o, objc); #endif - valueObj = objv[p]; - } else { - return NsfPrintError(interp, "Argument for parameter '%s' expected", nppPtr->name); - } - } - /* - * The value for the flag is now in the valueObj. We - * check, whether it is value is permissible. - */ - if (unlikely(ArgumentCheck(interp, valueObj, nppPtr, doCheck, - &pcPtr->flags[j], - &pcPtr->clientData[j], - &pcPtr->objv[j]) != TCL_OK)) { - if (pcPtr->flags[j] & NSF_PC_MUST_DECR) {pcPtr->status |= NSF_PC_STATUS_MUST_DECR;} - return TCL_ERROR; - } - /*fprintf(stderr, "... nonpositional pcPtr %p check [%d] obj %p flags %.6x & %p\n", - pcPtr, j, pcPtr->objv[j], pcPtr->flags[j], &(pcPtr->flags[j])); */ + break; - /* - * Provide warnings for double-settings. - */ - if (pcPtr->flags[j] & NSF_ARG_SET) { - Tcl_Obj *cmdLineObj = Tcl_NewListObj(objc-1, objv+1); - INCR_REF_COUNT(cmdLineObj); - NsfLog(interp, NSF_LOG_WARN, "Non-positional parameter %s was passed more than once (%s%s%s %s)", - nppPtr->name, - object ? ObjectName(object) : "", object ? " method " : "", - ObjStr(procNameObj), ObjStr(cmdLineObj)); - DECR_REF_COUNT(cmdLineObj); - } - pcPtr->flags[j] |= NSF_ARG_SET; + } else { + /* + * Process an ordinary positional argument + */ + currentParamPtr ++; - /* - * Provide context for warning messages - */ - if (pcPtr->flags[j] & NSF_ARG_WARN) { - Tcl_Obj *resultObj = Tcl_GetObjResult(interp); - Tcl_DString ds, *dsPtr = &ds; - - Tcl_DStringInit(dsPtr); - INCR_REF_COUNT(resultObj); - NsfDStringArgv(dsPtr, objc, objv); - NsfLog(interp, NSF_LOG_WARN, "%s during:\n%s %s", - ObjStr(resultObj), ObjectName(object), Tcl_DStringValue(dsPtr)); - DECR_REF_COUNT(resultObj); - Tcl_DStringFree(dsPtr); - } - - if (pcPtr->flags[j] & NSF_PC_MUST_DECR) { - //fprintf(stderr, "pcPtr %p setting NSF_PC_STATUS_MUST_DECR\n", pcPtr); - pcPtr->status |= NSF_PC_STATUS_MUST_DECR; - } - - flagCount++; - } else { - /* - * We did not find the specified flag, the thing starting - * with a '-' must be an argument - */ - assert(found == 0); - break; - } - } +#if defined(PARSE_TRACE_FULL) + fprintf(stderr, "... positional arg o %d objc %d, nrArgs %d next paramPtr %s\n", + o, objc, pPtr->nrArgs, currentParamPtr->name); +#endif + if (pPtr->nrArgs == 0) { + /* + * Allow positional arguments with 0 args for object parameter + * aliases, which are always fired. Such parameter are non-consuming, + * therfore the processing of the current argument is not finished, we + * have to decrement o. We have to check here if we are already at the + * end if the parameter vector. + */ + o--; + continue; } - /*fprintf(stderr, "... we found %d flags\n", flagCount);*/ - /* skip in parameter definition until the end of the switches */ - while (pPtr->name && *pPtr->name == '-') {pPtr++, i++;}; - /* under the assumption, flags have no arguments */ - o += flagCount; + if (dashdash) {dashdash = 0;} - } else { + valueObj = argumentObj; + } - /* Handle positional (unnamed) parameters, starting without a - * "-"; arguments must be always in same order - */ +#if defined(PARSE_TRACE_FULL) + fprintf(stderr, "... setting parameter %s pos %d valueObj '%s'\n", + pPtr->name, j, + valueObj == argumentObj ? "=" : ObjStr(valueObj)); +#endif - /* reset dashdash, if needed */ - if (dashdash) {dashdash = 0;} + /* + * The value for the flag is now in the valueObj. We + * check, whether it is value is permissible. + */ + assert(valueObj); - /*fprintf(stderr, "positional arg %s nrargs %d required %d\n", - pPtr->name, pPtr->nrArgs, pPtr->flags & NSF_ARG_REQUIRED);*/ + if (unlikely(ArgumentCheck(interp, valueObj, pPtr, doCheck, + &pcPtr->flags[j], + &pcPtr->clientData[j], + &pcPtr->objv[j]) != TCL_OK)) { + if (pcPtr->flags[j] & NSF_PC_MUST_DECR) {pcPtr->status |= NSF_PC_STATUS_MUST_DECR;} + return TCL_ERROR; + } - if (pPtr->nrArgs > 0) { + /* + * Switches are more tricky: if the flag is provided without + * valueInArgument, we take the default and invert it. If valueInArgument + * was used, the default inversion must not happen. + */ + if (valueInArgument == NULL && pPtr->converter == Nsf_ConvertToSwitch) { + /*fprintf(stderr,"... set INVERT_DEFAULT for '%s' flags %.6x\n", + pPtr->name, pPtr->flags);*/ + pcPtr->flags[j] |= NSF_PC_INVERT_DEFAULT; + } - /*fprintf(stderr, "... arg %s req %d converter %p try to set on %d: '%s' ConvertViaCmd %p\n", - pPtr->name, pPtr->flags & NSF_ARG_REQUIRED, pPtr->converter, i, ObjStr(objv[o]), - ConvertViaCmd);*/ - - if (unlikely(ArgumentCheck(interp, objv[o], pPtr, doCheck, - &pcPtr->flags[i], - &pcPtr->clientData[i], - &pcPtr->objv[i]) != TCL_OK)) { - if (pcPtr->flags[i] & NSF_PC_MUST_DECR) {pcPtr->status |= NSF_PC_STATUS_MUST_DECR;} - return TCL_ERROR; - } + /*fprintf(stderr, "... nonpositional pcPtr %p check [%d] obj %p flags %.6x & %p\n", + pcPtr, j, pcPtr->objv[j], pcPtr->flags[j], &(pcPtr->flags[j])); */ + + /* + * Provide warnings for double-settings. + */ + if (pcPtr->flags[j] & NSF_ARG_SET) { + Tcl_Obj *cmdLineObj = Tcl_NewListObj(objc-1, objv+1); + INCR_REF_COUNT(cmdLineObj); + NsfLog(interp, NSF_LOG_WARN, "Non-positional parameter %s was passed more than once (%s%s%s %s)", + pPtr->name, + object ? ObjectName(object) : "", object ? " method " : "", + ObjStr(procNameObj), ObjStr(cmdLineObj)); + DECR_REF_COUNT(cmdLineObj); + } + pcPtr->flags[j] |= NSF_ARG_SET; + + /* + * Embed error message of converter in current context + */ + if (pcPtr->flags[j] & NSF_ARG_WARN) { + Tcl_Obj *resultObj = Tcl_GetObjResult(interp); + Tcl_DString ds, *dsPtr = &ds; + + Tcl_DStringInit(dsPtr); + INCR_REF_COUNT(resultObj); + NsfDStringArgv(dsPtr, objc, objv); + NsfLog(interp, NSF_LOG_WARN, "%s during:\n%s %s", + ObjStr(resultObj), object ? ObjectName(object) : "nsf::proc", Tcl_DStringValue(dsPtr)); + DECR_REF_COUNT(resultObj); + Tcl_DStringFree(dsPtr); + } + + if (pcPtr->flags[j] & NSF_PC_MUST_DECR) { + //fprintf(stderr, "pcPtr %p setting NSF_PC_STATUS_MUST_DECR\n", pcPtr); + pcPtr->status |= NSF_PC_STATUS_MUST_DECR; + } - /*fprintf(stderr, "... positional pcPtr %p check [%d] obj %p flags %.6x & %p\n", - pcPtr, i, pcPtr->objv[i], pcPtr->flags[i], &(pcPtr->flags[i]));*/ + if (pcPtr->varArgs) { + break; + } - if (pcPtr->flags[i] & NSF_PC_MUST_DECR) { - //fprintf(stderr, "pcPtr %p setting NSF_PC_STATUS_MUST_DECR 2\n", pcPtr); - pcPtr->status |= NSF_PC_STATUS_MUST_DECR; - } - /* - * objv is always passed via pcPtr->objv - */ #if defined(PARSE_TRACE_FULL) - fprintf(stderr, "... setting %s pPtr->objv[%d] to [%d]'%s' converter %p\n", - pPtr->name, i, o, ObjStr(objv[o]), pPtr->converter); + fprintf(stderr, "... iterate on o %d objc %d, currentParamPtr %s\n", + o, objc, currentParamPtr->name); #endif - o++; - } - i++; pPtr++; - } } - pcPtr->lastObjc = pPtr->name ? o : o-1; - pcPtr->objc = i + 1; - /* - * Process remaining parameters to the end of parameter definitions - */ - for (; pPtr->name; pPtr++) {} - - /* - * Is the last argument a vararg? - */ - pPtr--; - if (unlikely(pPtr->converter == ConvertToNothing)) { - pcPtr->varArgs = 1; - /*fprintf(stderr, "last arg of proc '%s' is varargs\n", ObjStr(procNameObj));*/ + if (currentParamPtr <= lastParamPtr && pcPtr->varArgs == 0) { + /* not all parameter processed, make sure varags is set */ + + /*fprintf(stderr, ".... not all parms processed, pPtr '%s' j %ld nrParams %d last '%s' varArgs %d\n", + currentParamPtr->name, currentParamPtr - paramPtr, nrParams, lastParamPtr->name, + pcPtr->varArgs);*/ + if (lastParamPtr->converter == ConvertToNothing) { + pcPtr->varArgs = 1; + } } - /* - * Handle unexpected arguments for methods and cmds - */ - if (unlikely(!pcPtr->varArgs && o < objc)) { - Tcl_DString ds, *dsPtr = &ds; - DSTRING_INIT(dsPtr); - Tcl_DStringAppend(dsPtr, "Invalid argument '", -1); - Tcl_DStringAppend(dsPtr, ObjStr(objv[pcPtr->lastObjc+1]), -1); - Tcl_DStringAppend(dsPtr, "', maybe too many arguments;", -1); - NsfArgumentError(interp, Tcl_DStringValue(dsPtr), paramPtr, - object ? object->cmdName : NULL, - procNameObj); // aaaa - DSTRING_FREE(dsPtr); - return TCL_ERROR; - } + pcPtr->lastObjc = o; + pcPtr->objc = nrParams; +#if defined(PARSE_TRACE_FULL) + fprintf(stderr, "..... argv processed o %d lastObjc %d nrParams %d olastObjc, nrParams, ovarArgs); +#endif + return ArgumentDefaults(pcPtr, interp, paramPtr, nrParams); } - /*********************************** * Begin result setting commands * (essentially List*() and support @@ -16164,7 +16217,7 @@ mdPtr->methodName);*/ if (((Command *)cmd)->objProc == mdPtr->proc) { - NsfParamDefs paramDefs = {mdPtr->paramDefs, mdPtr->nrParameters, 1, NULL, NULL}; + NsfParamDefs paramDefs = {mdPtr->paramDefs, mdPtr->nrParameters, 1, 0, NULL, NULL}; Tcl_Obj *list = ListParamDefs(interp, paramDefs.paramsPtr, printStyle); Tcl_SetObjResult(interp, list); @@ -17543,7 +17596,7 @@ if (ArgumentParse(interp, nobjc, nobjv, NULL, nobjv[0], method_definitions[NsfMyCmdIdx].paramDefs, - method_definitions[NsfMyCmdIdx].nrParameters, 1, + method_definitions[NsfMyCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } @@ -18324,7 +18377,7 @@ int flags = 0; int useCmdDispatch = 1; - /*fprintf(stderr, "MethodDispatch obj=%s, cmd m='%s'\n", ObjectName(object), methodName);*/ + /*fprintf(stderr, "NsfDirectDispatchCmd obj=%s, cmd m='%s'\n", ObjectName(object), methodName);*/ if (unlikely(*methodName != ':')) { return NsfPrintError(interp, "method name '%s' must be fully qualified", methodName); @@ -18425,11 +18478,12 @@ */ static int NsfDispatchCmd(Tcl_Interp *interp, NsfObject *object, - int withIntrinsic, int withSystem, - Tcl_Obj *commandObj, int nobjc, Tcl_Obj *CONST nobjv[]) { + int withIntrinsic, int withSystem, + Tcl_Obj *commandObj, int nobjc, Tcl_Obj *CONST nobjv[]) { int flags = NSF_CM_NO_UNKNOWN|NSF_CSC_IMMEDIATE|NSF_CM_IGNORE_PERMISSIONS|NSF_CM_NO_SHIFT; - /*fprintf(stderr, "Dispatch obj=%s, cmd m='%s'\n", ObjectName(object), methodName);*/ + /*fprintf(stderr, "NsfDispatchCmd obj=%s, cmd m='%s' nobjc %d\n", + ObjectName(object), ObjStr(commandObj), nobjc);*/ if (withIntrinsic && withSystem) { return NsfPrintError(interp, "flags '-intrinsic' and '-system' are mutual exclusive"); @@ -21149,6 +21203,8 @@ Tcl_DString dFullname, *dsPtr = &dFullname; NsfStringIncrStruct *iss = &RUNTIME_STATE(interp)->iss; + /*fprintf(stderr, "NsfCNewMethod objc %d\n", objc);*/ + Tcl_DStringInit(dsPtr); if (withChildof) { Tcl_DStringAppend(dsPtr, ObjectName(withChildof), -1); @@ -23010,7 +23066,7 @@ #endif NsfReportVars(interp); - Tcl_AddInterpResolvers(interp,"nxt", + Tcl_AddInterpResolvers(interp,"nsf", (Tcl_ResolveCmdProc *)InterpColonCmdResolver, InterpColonVarResolver, (Tcl_ResolveCompiledVarProc *)InterpCompiledColonVarResolver); Index: generic/nsf.h =================================================================== diff -u -rb37bf2deab94b6294509fa79bb7b922d6e8a5635 -r2ba521e3dfbb1294908b51ed8e13dab5adc3ca03 --- generic/nsf.h (.../nsf.h) (revision b37bf2deab94b6294509fa79bb7b922d6e8a5635) +++ generic/nsf.h (.../nsf.h) (revision 2ba521e3dfbb1294908b51ed8e13dab5adc3ca03) @@ -96,14 +96,14 @@ #define NSF_MEM_COUNT 1 */ //#define PARSE_TRACE 1 +//#define PARSE_TRACE_FULL 1 /* turn tracing output on/off #define NSFOBJ_TRACE 1 #define NAMESPACE_TRACE 1 #define OBJDELETION_TRACE 1 #define STACK_TRACE 1 #define PARSE_TRACE 1 -#define PARSE_TRACE_FULL 1 #define CONFIGURE_ARGS_TRACE 1 #define TCL_STACK_ALLOC_TRACE 1 #define VAR_RESOLVER_TRACE 1 @@ -263,8 +263,8 @@ extern int Nsf_ArgumentParse(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Nsf_Object *object, Tcl_Obj *procNameObj, - Nsf_Param CONST *paramPtr, int nrParams, int doCheck, - Nsf_ParseContext *pcPtr); + Nsf_Param CONST *paramPtr, int nrParams, int serial, + int doCheck, Nsf_ParseContext *pcPtr); extern int NsfArgumentError(Tcl_Interp *interp, CONST char *errorMsg, Nsf_Param CONST *paramPtr, Tcl_Obj *cmdNameObj, Tcl_Obj *methodObj); @@ -275,6 +275,10 @@ extern int NsfNoCurrentObjectError(Tcl_Interp *interp, CONST char *what); +extern int +NsfUnexpectedArgumentError(Tcl_Interp *interp, CONST char *argumentString, + Nsf_Object *object, Nsf_Param CONST *paramPtr, Tcl_Obj *procNameObj); + /* * logging */ Index: generic/nsfAPI.h =================================================================== diff -u -rac96e6ce975fe5864b64dee9d66bc701a31e113b -r2ba521e3dfbb1294908b51ed8e13dab5adc3ca03 --- generic/nsfAPI.h (.../nsfAPI.h) (revision ac96e6ce975fe5864b64dee9d66bc701a31e113b) +++ generic/nsfAPI.h (.../nsfAPI.h) (revision 2ba521e3dfbb1294908b51ed8e13dab5adc3ca03) @@ -527,7 +527,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "create"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfCCreateMethodIdx].paramDefs, - method_definitions[NsfCCreateMethodIdx].nrParameters, 1, + method_definitions[NsfCCreateMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -562,7 +562,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "filterguard"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfCFilterGuardMethodIdx].paramDefs, - method_definitions[NsfCFilterGuardMethodIdx].nrParameters, 1, + method_definitions[NsfCFilterGuardMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -582,7 +582,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "mixinguard"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfCMixinGuardMethodIdx].paramDefs, - method_definitions[NsfCMixinGuardMethodIdx].nrParameters, 1, + method_definitions[NsfCMixinGuardMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -602,7 +602,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "new"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfCNewMethodIdx].paramDefs, - method_definitions[NsfCNewMethodIdx].nrParameters, 1, + method_definitions[NsfCNewMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -621,7 +621,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "recreate"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfCRecreateMethodIdx].paramDefs, - method_definitions[NsfCRecreateMethodIdx].nrParameters, 1, + method_definitions[NsfCRecreateMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -656,7 +656,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "filterguard"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoFilterguardMethodIdx].paramDefs, - method_definitions[NsfClassInfoFilterguardMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoFilterguardMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -675,7 +675,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "filtermethods"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoFiltermethodsMethodIdx].paramDefs, - method_definitions[NsfClassInfoFiltermethodsMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoFiltermethodsMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -695,7 +695,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "forward"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoForwardMethodIdx].paramDefs, - method_definitions[NsfClassInfoForwardMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoForwardMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -715,7 +715,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "heritage"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoHeritageMethodIdx].paramDefs, - method_definitions[NsfClassInfoHeritageMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoHeritageMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -734,7 +734,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "instances"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoInstancesMethodIdx].paramDefs, - method_definitions[NsfClassInfoInstancesMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoInstancesMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -768,7 +768,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "method"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoMethodMethodIdx].paramDefs, - method_definitions[NsfClassInfoMethodMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoMethodMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -788,7 +788,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "methods"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoMethodsMethodIdx].paramDefs, - method_definitions[NsfClassInfoMethodsMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoMethodsMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -810,7 +810,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "mixinof"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoMixinOfMethodIdx].paramDefs, - method_definitions[NsfClassInfoMixinOfMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoMixinOfMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -845,7 +845,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "mixinclasses"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoMixinclassesMethodIdx].paramDefs, - method_definitions[NsfClassInfoMixinclassesMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoMixinclassesMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -881,7 +881,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "mixinguard"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoMixinguardMethodIdx].paramDefs, - method_definitions[NsfClassInfoMixinguardMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoMixinguardMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -900,7 +900,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "objectparameter"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoObjectparameterMethodIdx].paramDefs, - method_definitions[NsfClassInfoObjectparameterMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoObjectparameterMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -920,7 +920,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "slotobjects"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoSlotobjectsMethodIdx].paramDefs, - method_definitions[NsfClassInfoSlotobjectsMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoSlotobjectsMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -942,7 +942,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "subclass"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoSubclassMethodIdx].paramDefs, - method_definitions[NsfClassInfoSubclassMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoSubclassMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -976,7 +976,7 @@ if (!cl) return NsfDispatchClientDataError(interp, clientData, "class", "superclass"); if (ArgumentParse(interp, objc, objv, (NsfObject *) cl, objv[0], method_definitions[NsfClassInfoSuperclassMethodIdx].paramDefs, - method_definitions[NsfClassInfoSuperclassMethodIdx].nrParameters, 1, + method_definitions[NsfClassInfoSuperclassMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1006,7 +1006,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfConfigureCmdIdx].paramDefs, - method_definitions[NsfConfigureCmdIdx].nrParameters, 1, + method_definitions[NsfConfigureCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1026,7 +1026,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfCurrentCmdIdx].paramDefs, - method_definitions[NsfCurrentCmdIdx].nrParameters, 1, + method_definitions[NsfCurrentCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1077,7 +1077,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfDirectDispatchCmdIdx].paramDefs, - method_definitions[NsfDirectDispatchCmdIdx].nrParameters, 1, + method_definitions[NsfDirectDispatchCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1098,7 +1098,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfDispatchCmdIdx].paramDefs, - method_definitions[NsfDispatchCmdIdx].nrParameters, 1, + method_definitions[NsfDispatchCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1120,7 +1120,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfFinalizeCmdIdx].paramDefs, - method_definitions[NsfFinalizeCmdIdx].nrParameters, 1, + method_definitions[NsfFinalizeCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1139,7 +1139,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfInterpObjCmdIdx].paramDefs, - method_definitions[NsfInterpObjCmdIdx].nrParameters, 1, + method_definitions[NsfInterpObjCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1158,7 +1158,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfInvalidateObjectParameterCmdIdx].paramDefs, - method_definitions[NsfInvalidateObjectParameterCmdIdx].nrParameters, 1, + method_definitions[NsfInvalidateObjectParameterCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1177,7 +1177,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfIsCmdIdx].paramDefs, - method_definitions[NsfIsCmdIdx].nrParameters, 1, + method_definitions[NsfIsCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1198,7 +1198,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMethodAliasCmdIdx].paramDefs, - method_definitions[NsfMethodAliasCmdIdx].nrParameters, 1, + method_definitions[NsfMethodAliasCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1221,7 +1221,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMethodAssertionCmdIdx].paramDefs, - method_definitions[NsfMethodAssertionCmdIdx].nrParameters, 1, + method_definitions[NsfMethodAssertionCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1242,7 +1242,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMethodCreateCmdIdx].paramDefs, - method_definitions[NsfMethodCreateCmdIdx].nrParameters, 1, + method_definitions[NsfMethodCreateCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1269,7 +1269,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMethodDeleteCmdIdx].paramDefs, - method_definitions[NsfMethodDeleteCmdIdx].nrParameters, 1, + method_definitions[NsfMethodDeleteCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1290,7 +1290,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMethodForwardCmdIdx].paramDefs, - method_definitions[NsfMethodForwardCmdIdx].nrParameters, 1, + method_definitions[NsfMethodForwardCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1318,7 +1318,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMethodPropertyCmdIdx].paramDefs, - method_definitions[NsfMethodPropertyCmdIdx].nrParameters, 1, + method_definitions[NsfMethodPropertyCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1357,7 +1357,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMethodSetterCmdIdx].paramDefs, - method_definitions[NsfMethodSetterCmdIdx].nrParameters, 1, + method_definitions[NsfMethodSetterCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1378,7 +1378,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfMyCmdIdx].paramDefs, - method_definitions[NsfMyCmdIdx].nrParameters, 1, + method_definitions[NsfMyCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1400,7 +1400,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfNSCopyCmdsCmdIdx].paramDefs, - method_definitions[NsfNSCopyCmdsCmdIdx].nrParameters, 1, + method_definitions[NsfNSCopyCmdsCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1420,7 +1420,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfNSCopyVarsCmdIdx].paramDefs, - method_definitions[NsfNSCopyVarsCmdIdx].nrParameters, 1, + method_definitions[NsfNSCopyVarsCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1472,7 +1472,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfObjectPropertyCmdIdx].paramDefs, - method_definitions[NsfObjectPropertyCmdIdx].nrParameters, 1, + method_definitions[NsfObjectPropertyCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1508,7 +1508,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfObjectSystemCreateCmdIdx].paramDefs, - method_definitions[NsfObjectSystemCreateCmdIdx].nrParameters, 1, + method_definitions[NsfObjectSystemCreateCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1529,7 +1529,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfProcCmdIdx].paramDefs, - method_definitions[NsfProcCmdIdx].nrParameters, 1, + method_definitions[NsfProcCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1583,7 +1583,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfRelationCmdIdx].paramDefs, - method_definitions[NsfRelationCmdIdx].nrParameters, 1, + method_definitions[NsfRelationCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1652,7 +1652,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfVarExistsCmdIdx].paramDefs, - method_definitions[NsfVarExistsCmdIdx].nrParameters, 1, + method_definitions[NsfVarExistsCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1673,7 +1673,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfVarImportCmdIdx].paramDefs, - method_definitions[NsfVarImportCmdIdx].nrParameters, 1, + method_definitions[NsfVarImportCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1692,7 +1692,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfVarSetCmdIdx].paramDefs, - method_definitions[NsfVarSetCmdIdx].nrParameters, 1, + method_definitions[NsfVarSetCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1714,7 +1714,7 @@ if (ArgumentParse(interp, objc, objv, NULL, objv[0], method_definitions[NsfVarUnsetCmdIdx].paramDefs, - method_definitions[NsfVarUnsetCmdIdx].nrParameters, 1, + method_definitions[NsfVarUnsetCmdIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1735,7 +1735,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "autoname"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfOAutonameMethodIdx].paramDefs, - method_definitions[NsfOAutonameMethodIdx].nrParameters, 1, + method_definitions[NsfOAutonameMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1814,7 +1814,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "exists"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfOExistsMethodIdx].paramDefs, - method_definitions[NsfOExistsMethodIdx].nrParameters, 1, + method_definitions[NsfOExistsMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1833,7 +1833,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "filterguard"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfOFilterGuardMethodIdx].paramDefs, - method_definitions[NsfOFilterGuardMethodIdx].nrParameters, 1, + method_definitions[NsfOFilterGuardMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1863,7 +1863,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "mixinguard"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfOMixinGuardMethodIdx].paramDefs, - method_definitions[NsfOMixinGuardMethodIdx].nrParameters, 1, + method_definitions[NsfOMixinGuardMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1961,7 +1961,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "children"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoChildrenMethodIdx].paramDefs, - method_definitions[NsfObjInfoChildrenMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoChildrenMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1997,7 +1997,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "filterguard"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoFilterguardMethodIdx].paramDefs, - method_definitions[NsfObjInfoFilterguardMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoFilterguardMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2016,7 +2016,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "filtermethods"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoFiltermethodsMethodIdx].paramDefs, - method_definitions[NsfObjInfoFiltermethodsMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoFiltermethodsMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2037,7 +2037,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "forward"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoForwardMethodIdx].paramDefs, - method_definitions[NsfObjInfoForwardMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoForwardMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2057,7 +2057,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "hasmixin"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoHasMixinMethodIdx].paramDefs, - method_definitions[NsfObjInfoHasMixinMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoHasMixinMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2076,7 +2076,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "hastype"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoHasTypeMethodIdx].paramDefs, - method_definitions[NsfObjInfoHasTypeMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoHasTypeMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2111,7 +2111,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "is"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoIsMethodIdx].paramDefs, - method_definitions[NsfObjInfoIsMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoIsMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2130,7 +2130,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "lookupfilter"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoLookupFilterMethodIdx].paramDefs, - method_definitions[NsfObjInfoLookupFilterMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoLookupFilterMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2165,7 +2165,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "lookupmethods"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoLookupMethodsMethodIdx].paramDefs, - method_definitions[NsfObjInfoLookupMethodsMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoLookupMethodsMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2190,7 +2190,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "lookupslots"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoLookupSlotsMethodIdx].paramDefs, - method_definitions[NsfObjInfoLookupSlotsMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoLookupSlotsMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2211,7 +2211,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "method"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoMethodMethodIdx].paramDefs, - method_definitions[NsfObjInfoMethodMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoMethodMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2231,7 +2231,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "methods"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoMethodsMethodIdx].paramDefs, - method_definitions[NsfObjInfoMethodsMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoMethodsMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2253,7 +2253,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "mixinclasses"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoMixinclassesMethodIdx].paramDefs, - method_definitions[NsfObjInfoMixinclassesMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoMixinclassesMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2288,7 +2288,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "mixinguard"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoMixinguardMethodIdx].paramDefs, - method_definitions[NsfObjInfoMixinguardMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoMixinguardMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2323,7 +2323,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "precedence"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoPrecedenceMethodIdx].paramDefs, - method_definitions[NsfObjInfoPrecedenceMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoPrecedenceMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2343,7 +2343,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "slotobjects"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoSlotobjectsMethodIdx].paramDefs, - method_definitions[NsfObjInfoSlotobjectsMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoSlotobjectsMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -2363,7 +2363,7 @@ if (!obj) return NsfDispatchClientDataError(interp, clientData, "object", "vars"); if (ArgumentParse(interp, objc, objv, obj, objv[0], method_definitions[NsfObjInfoVarsMethodIdx].paramDefs, - method_definitions[NsfObjInfoVarsMethodIdx].nrParameters, 1, + method_definitions[NsfObjInfoVarsMethodIdx].nrParameters, 0, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { Index: generic/nsfError.c =================================================================== diff -u -rf177b4dbbb589f91704b1acb8dfbd91fc076335a -r2ba521e3dfbb1294908b51ed8e13dab5adc3ca03 --- generic/nsfError.c (.../nsfError.c) (revision f177b4dbbb589f91704b1acb8dfbd91fc076335a) +++ generic/nsfError.c (.../nsfError.c) (revision 2ba521e3dfbb1294908b51ed8e13dab5adc3ca03) @@ -220,8 +220,38 @@ /* *---------------------------------------------------------------------- * - * NsfNoDispatchObjectError -- + * NsfUnexpectedArgumentError -- * + * Produce a unexpecte argument number (most likely, too many arguments) + * + * Results: + * TCL_ERROR + * + * Side effects: + * Sets the result message. + * + *---------------------------------------------------------------------- + */ +extern int +NsfUnexpectedArgumentError(Tcl_Interp *interp, CONST char *argumentString, + Nsf_Object *object, Nsf_Param CONST *paramPtr, Tcl_Obj *procNameObj) { + Tcl_DString ds, *dsPtr = &ds; + 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, + procNameObj); + DSTRING_FREE(dsPtr); + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * NsfDispatchClientDataError -- + * * Produce a error message when method was not dispatched on an object * * Results: @@ -246,9 +276,10 @@ /* *---------------------------------------------------------------------- * - * NsfNoDispatchObjectError -- + * NsfNoCurrentObjectError -- * - * Produce a error message when method was not dispatched on an object + * Produce a error message when method was called outside the context of + * a method * * Results: * TCL_ERROR Index: generic/nsfInt.h =================================================================== diff -u -rba609b1194e7aaa37ae0756717abb19215376af9 -r2ba521e3dfbb1294908b51ed8e13dab5adc3ca03 --- generic/nsfInt.h (.../nsfInt.h) (revision ba609b1194e7aaa37ae0756717abb19215376af9) +++ generic/nsfInt.h (.../nsfInt.h) (revision 2ba521e3dfbb1294908b51ed8e13dab5adc3ca03) @@ -407,7 +407,6 @@ #define NSF_ARG_UNNAMED 0x080000 #define NSF_ARG_IS_RETURNVALUE 0x100000 - /* method invocations */ #define NSF_ARG_METHOD_INVOCATION (NSF_ARG_ALIAS|NSF_ARG_FORWARD|NSF_ARG_INITCMD) @@ -422,7 +421,7 @@ /* flags for ParseContext */ #define NSF_PC_MUST_DECR 0x0001 #define NSF_PC_IS_DEFAULT 0x0002 -#define NSF_PC_MUST_INVERT 0x0010 +#define NSF_PC_INVERT_DEFAULT 0x0010 #define NSF_PC_STATUS_MUST_DECR 0x0001 #define NSF_PC_STATUS_FREE_OBJV 0x0002 @@ -459,6 +458,7 @@ Nsf_Param *paramsPtr; int nrParams; int refCount; + int serial; Tcl_Obj *slotObj; Tcl_Obj *returns; } NsfParamDefs; @@ -915,6 +915,26 @@ extern CONST char *MethodName(Tcl_Obj *methodObj); extern void NsfReportVars(Tcl_Interp *interp); + +/* + * NsfFlag type + */ +extern Tcl_ObjType NsfFlagObjType; +extern int NsfFlagObjSet(Tcl_Interp *interp, Tcl_Obj *objPtr, + Nsf_Param CONST *baseParamPtr, int serial, + Nsf_Param CONST *paramPtr, Tcl_Obj *payload, int flags); +typedef struct { + CONST Nsf_Param *signature; + int serial; + Nsf_Param *paramPtr; + Tcl_Obj *payload; + int flags; +} NsfFlag; + +#define NSF_FLAG_DASHDAH 0x01 +#define NSF_FLAG_CONTAINS_VALUE 0x02 + + /* functions from nsfUtil.c */ char *Nsf_ltoa(char *buf, long i, int *len); char *NsfStringIncr(NsfStringIncrStruct *iss); Index: generic/nsfObj.c =================================================================== diff -u -rf177b4dbbb589f91704b1acb8dfbd91fc076335a -r2ba521e3dfbb1294908b51ed8e13dab5adc3ca03 --- generic/nsfObj.c (.../nsfObj.c) (revision f177b4dbbb589f91704b1acb8dfbd91fc076335a) +++ generic/nsfObj.c (.../nsfObj.c) (revision 2ba521e3dfbb1294908b51ed8e13dab5adc3ca03) @@ -26,6 +26,116 @@ *---------------------------------------------------------------------- */ +static Tcl_FreeInternalRepProc FlagFreeInternalRep; + +Tcl_ObjType NsfFlagObjType = { + "nsfFlag", /* name */ + FlagFreeInternalRep, /* freeIntRepProc */ + NULL, /* dupIntRepProc */ + NULL, /* updateStringProc */ + NULL /* setFromAnyProc */ +}; + +/* + * freeIntRepProc + */ +static void +FlagFreeInternalRep( + register Tcl_Obj *objPtr) /* Tcl_Obj structure object with internal + * representation to free. */ +{ + NsfFlag *flagPtr = (NsfFlag *)objPtr->internalRep.twoPtrValue.ptr1; + + if (flagPtr != NULL) { + + /*fprintf(stderr, "FlagFreeInternalRep %p flagPtr %p serial (%d) payload %p\n", + objPtr, flagPtr, flagPtr->serial, flagPtr->payload);*/ + + /* + * Decrement refCounts; same as in NsfFlagSet() in the reuse branch + */ + if (flagPtr->payload) {DECR_REF_COUNT2("flagPtr->payload", flagPtr->payload);} + + /* + * ... and free structure + */ + FREE(NsfFlag, flagPtr); + objPtr->internalRep.twoPtrValue.ptr1 = NULL; // TODO: needed? + } +} + +/* + *---------------------------------------------------------------------- + * + * NsfFlagObjSet -- + * + * Convert the provided Tcl_Obj into the type of an nsf flag. + * + *---------------------------------------------------------------------- + */ +int +NsfFlagObjSet( + Tcl_Interp *interp, /* Used for error reporting if not NULL. */ + register Tcl_Obj *objPtr, /* The object to convert. */ + Nsf_Param CONST *baseParamPtr, /* the full parameter block */ + int serial, /* interface serial */ + Nsf_Param CONST *paramPtr, /* a single parameter */ + Tcl_Obj *payload, /* payload */ + int flags /* detail infos */ + ) +{ + NsfFlag *flagPtr; + + /*fprintf(stderr, "NsfFlagObjSet %p %s signature %p (%d) param %p payload %p flags %.4x\n", + objPtr, ObjStr(objPtr), baseParamPtr, serial, paramPtr, payload, flags);*/ + + /* + * Free or reuse the old interal representation and store own + * structure as internal representation. + */ + if (objPtr->typePtr != &NsfFlagObjType) { + TclFreeIntRep(objPtr); + flagPtr = NEW(NsfFlag); + objPtr->internalRep.twoPtrValue.ptr1 = (void *)flagPtr; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; + objPtr->typePtr = &NsfFlagObjType; + } else { + flagPtr = (NsfFlag *)objPtr->internalRep.twoPtrValue.ptr1; + + //fprintf(stderr, "NsfFlagObjSet %p reuses interal rep, serial (%d/%d)\n", + // objPtr, flagPtr->serial, serial); + + if (flagPtr->payload) {DECR_REF_COUNT2("flagPtr->payload", flagPtr->payload);} + } + + assert(flagPtr); + + /* + * add values to the structure + */ + flagPtr->signature = baseParamPtr; + flagPtr->serial = serial; + flagPtr->paramPtr = paramPtr; + flagPtr->payload = payload; + if (payload) {INCR_REF_COUNT2("flagPtr->payload", flagPtr->payload);} + flagPtr->flags = flags; + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * Mixinreg Tcl_Obj type -- + * + * The mixin registration type is an Tcl_Obj type carrying a + * class and a guard object. The string representation might have + * the form "/cls/" or "/cls/ -guard /expr/". When no guard + * expression is provided (first form), the guard entry is NULL. + * + *---------------------------------------------------------------------- + */ + typedef struct { NsfClass *mixin; Tcl_Obj *guardObj; @@ -131,6 +241,7 @@ return TCL_OK; } + /* *---------------------------------------------------------------------- *