Index: generic/xotcl.c =================================================================== diff -u -red8301802df5fc7427fc0e4dbd82c2cf880329de -r13c614867b8e7cc4c7821f5027a309cfbd3b4d9e --- generic/xotcl.c (.../xotcl.c) (revision ed8301802df5fc7427fc0e4dbd82c2cf880329de) +++ generic/xotcl.c (.../xotcl.c) (revision 13c614867b8e7cc4c7821f5027a309cfbd3b4d9e) @@ -161,7 +161,8 @@ } parseContext; #if defined(CANONICAL_ARGS) -int canonicalNonpositionalArgs(parseContext *pcPtr, Tcl_Interp *interp, XOTclObject *object, +int canonicalNonpositionalArgs(parseContext *pcPtr, Tcl_Interp *interp, + XOTclCallStackContent *csc, char *procName, int objc, Tcl_Obj *CONST objv[]); #endif void parseContextInit(parseContext *pc, int objc, Tcl_Obj *procName) { @@ -5500,7 +5501,7 @@ /* If the method to be invoked hasnonposArgs, we have to call the argument parser with the argument definitions. The argument - definitions are looked up in canonicalNonpositionalArgs via a + definitions are looked up in canonicalNonpositionalArgs() via a hash table, which causes a per-proc overhead. It would be certainly nicer and more efficient to store both the argument definitions in the Tcl Proc structure, which has unfortunately @@ -5514,7 +5515,7 @@ */ { parseContext pc; - int rc = canonicalNonpositionalArgs(&pc, interp, obj, objc, objv); + int rc = canonicalNonpositionalArgs(&pc, interp, csc, methodName, objc, objv); if (rc == TCL_CONTINUE) { result = PushProcCallFrame(cp, interp, objc, objv, /*isLambda*/ 0, csc); @@ -6764,8 +6765,13 @@ if (strncmp(body, "::eval ::xotcl::interpretNonpositionalArgs $args\n", 49) == 0) body += 49; #else +# if !defined(CANONICAL_ARGS) if (strncmp(body, "::xotcl::interpretNonpositionalArgs {*}$args\n", 45) == 0) body += 45; +# else + if (strncmp(body, "::xotcl::unsetUnknownArgs\n", 26) == 0) + body += 26; +# endif #endif return body; } @@ -12444,12 +12450,11 @@ #if defined(CANONICAL_ARGS) int -canonicalNonpositionalArgs(parseContext *pcPtr, Tcl_Interp *interp, XOTclObject *object, +canonicalNonpositionalArgs(parseContext *pcPtr, Tcl_Interp *interp, + XOTclCallStackContent *csc, char *methodName, int objc, Tcl_Obj *CONST objv[]) { - XOTclClass *class = XOTclObjectIsClass(object) ? (XOTclClass *)object : NULL; - Tcl_HashTable *nonposArgsTable = class ? class->nonposArgsTable : object->nonposArgsTable; - char *procName = (char *)GetSelfProc(interp); - XOTclNonposArgs *nonposArgs = NonposArgsGet(nonposArgsTable, procName); + Tcl_HashTable *nonposArgsTable = csc->cl ? csc->cl->nonposArgsTable : csc->self->nonposArgsTable; + XOTclNonposArgs *nonposArgs = NonposArgsGet(nonposArgsTable, methodName); argDefinition CONST *aPtr; int i, rc; @@ -12483,7 +12488,7 @@ /* TODO: default value is not jet checked; should be in arg parsing */ /*fprintf(stderr,"==> setting default value '%s' for var '%s'\n",ObjStr(aPtr->defaultValue),argName);*/ } else if (aPtr->required) { - return XOTclVarErrMsg(interp, "method ",procName, ": required argument '", + return XOTclVarErrMsg(interp, "method ",methodName, ": required argument '", argName, "' is missing", (char *) NULL); } else { /* Use as dummy default value an arbitrary symbol, normally Index: generic/xotcl.h =================================================================== diff -u -r721a118d34e93f4149da419436efa5b17bab9b35 -r13c614867b8e7cc4c7821f5027a309cfbd3b4d9e --- generic/xotcl.h (.../xotcl.h) (revision 721a118d34e93f4149da419436efa5b17bab9b35) +++ generic/xotcl.h (.../xotcl.h) (revision 13c614867b8e7cc4c7821f5027a309cfbd3b4d9e) @@ -83,10 +83,10 @@ */ /* -#define CANONICAL_ARGS 1 #define TCL85STACK_TRACE 1 #define TCL85STACK 1 */ +#define CANONICAL_ARGS 1 #define TCL85STACK 1 #if defined PARSE_TRACE_FULL Index: tests/testx.xotcl =================================================================== diff -u -ra19d77bc89cdb0882d2cad69305be4e0e483cae3 -r13c614867b8e7cc4c7821f5027a309cfbd3b4d9e --- tests/testx.xotcl (.../testx.xotcl) (revision a19d77bc89cdb0882d2cad69305be4e0e483cae3) +++ tests/testx.xotcl (.../testx.xotcl) (revision 13c614867b8e7cc4c7821f5027a309cfbd3b4d9e) @@ -3898,13 +3898,13 @@ Object o o proc foo {{-a apple} {b banana}} { - return [list [info locals] a: $a b: $b] + return [list [lsort [info locals]] a: $a b: $b] } o proc foo2 {{-a apple} {b banana} {c apple}} { - return [list [info locals] a: $a b: $b c: $c] + return [list [lsort [info locals]] a: $a b: $b c: $c] } o proc foo3 {{-a apple} x y {b banana} {c apple}} { - return [list [info locals] x: $x y: $y a: $a b: $b c: $c] + return [list [lsort [info locals]] x: $x y: $y a: $a b: $b c: $c] } errorCheck [o foo] [list {a b} a: apple b: banana] \ @@ -3917,7 +3917,7 @@ "non pos + default values 4" errorCheck [o foo2 -a ack] [list {a b c} a: ack b: banana c: apple] \ "non pos + default values 5" - errorCheck [ o foo3 -a ack 1 2] [list {x y a b c} x: 1 y: 2 \ + errorCheck [ o foo3 -a ack 1 2] [list {a b c x y} x: 1 y: 2 \ a: ack b: banana c: apple] \ "non pos + default values 6"