Index: generic/gentclAPI.decls =================================================================== diff -u -rcd12f5a50d870605292d8c957cb2a079f1a17c10 -r496ffe8fb5e5bdaba56fe3a939d32634bdbcb088 --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision cd12f5a50d870605292d8c957cb2a079f1a17c10) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision 496ffe8fb5e5bdaba56fe3a939d32634bdbcb088) @@ -140,6 +140,7 @@ } xotclCmd valuecheck XOTclValuecheckCmd { {-argName "param" -type tclobj} + {-argName "-nocomplain"} {-argName "value" -required 0 -type tclobj} } # Index: generic/tclAPI.h =================================================================== diff -u -rcd12f5a50d870605292d8c957cb2a079f1a17c10 -r496ffe8fb5e5bdaba56fe3a939d32634bdbcb088 --- generic/tclAPI.h (.../tclAPI.h) (revision cd12f5a50d870605292d8c957cb2a079f1a17c10) +++ generic/tclAPI.h (.../tclAPI.h) (revision 496ffe8fb5e5bdaba56fe3a939d32634bdbcb088) @@ -283,7 +283,7 @@ static int XOTclRelationCmd(Tcl_Interp *interp, XOTclObject *object, int relationtype, Tcl_Obj *value); static int XOTclSetInstvarCmd(Tcl_Interp *interp, XOTclObject *object, Tcl_Obj *variable, Tcl_Obj *value); static int XOTclSetterCmd(Tcl_Interp *interp, XOTclObject *object, int withPer_object, Tcl_Obj *parameter); -static int XOTclValuecheckCmd(Tcl_Interp *interp, Tcl_Obj *param, Tcl_Obj *value); +static int XOTclValuecheckCmd(Tcl_Interp *interp, Tcl_Obj *param, int withNocomplain, Tcl_Obj *value); enum { XOTclCAllocMethodIdx, @@ -1947,10 +1947,11 @@ return TCL_ERROR; } else { Tcl_Obj *param = (Tcl_Obj *)pc.clientData[0]; - Tcl_Obj *value = (Tcl_Obj *)pc.clientData[1]; + int withNocomplain = (int )PTR2INT(pc.clientData[1]); + Tcl_Obj *value = (Tcl_Obj *)pc.clientData[2]; parseContextRelease(&pc); - return XOTclValuecheckCmd(interp, param, value); + return XOTclValuecheckCmd(interp, param, withNocomplain, value); } } @@ -2309,8 +2310,9 @@ {"-per-object", 0, 0, convertToString}, {"parameter", 0, 0, convertToTclobj}} }, -{"::xotcl::valuecheck", XOTclValuecheckCmdStub, 2, { +{"::xotcl::valuecheck", XOTclValuecheckCmdStub, 3, { {"param", 0, 0, convertToTclobj}, + {"-nocomplain", 0, 0, convertToString}, {"value", 0, 0, convertToTclobj}} },{NULL} }; Index: generic/xotcl.c =================================================================== diff -u -r782f6b060b16282799fe936bc528f512e562362a -r496ffe8fb5e5bdaba56fe3a939d32634bdbcb088 --- generic/xotcl.c (.../xotcl.c) (revision 782f6b060b16282799fe936bc528f512e562362a) +++ generic/xotcl.c (.../xotcl.c) (revision 496ffe8fb5e5bdaba56fe3a939d32634bdbcb088) @@ -6219,7 +6219,6 @@ Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &success); if (success == 1) { *clientData = (ClientData)objPtr; - *outObjPtr = objPtr; } else { result = XOTclVarErrMsg(interp, "expected ", ObjStr(pPtr->converterArg), " but got \"", ObjStr(objPtr), @@ -6228,9 +6227,9 @@ } } else { *clientData = (ClientData)objPtr; - *outObjPtr = objPtr; result = TCL_OK; } + *outObjPtr = objPtr; return result; } @@ -6347,6 +6346,8 @@ ObjStr(objPtr), ObjStr(Tcl_GetObjResult(interp)));*/ *outObjPtr = Tcl_GetObjResult(interp); *clientData = (ClientData) *outObjPtr; + } else { + *outObjPtr = objPtr; /* xxx */ } return result; } @@ -9679,6 +9680,7 @@ DECR_REF_COUNT(resultObj); DECR_REF_COUNT(*outObjPtr); *flags &= ~XOTCL_PC_MUST_DECR; + *outObjPtr = objPtr; break; } } @@ -12450,9 +12452,11 @@ /* xotclCmd valuecheck XOTclValuecheckCmd { {-argName "param" -type tclobj} + {-argName "-nocomplain"} {-argName "value" -required 0 -type tclobj} - } */ -static int XOTclValuecheckCmd(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj *value) { + } +*/ +static int XOTclValuecheckCmd(Tcl_Interp *interp, Tcl_Obj *objPtr, int withNocomplain, Tcl_Obj *value) { ClientData checkedData; XOTclParam *paramPtr; Tcl_Obj *outObjPtr; @@ -12474,16 +12478,22 @@ result = ArgumentCheck(interp, value, paramPtr, &flags, &checkedData, &outObjPtr); if (value != outObjPtr) { + fprintf(stderr, "reset result %p %p\n", value, outObjPtr); Tcl_ResetResult(interp); } if (flags & XOTCL_PC_MUST_DECR) { DECR_REF_COUNT(outObjPtr); } - Tcl_SetIntObj(Tcl_GetObjResult(interp), (result == TCL_OK)); + if (withNocomplain) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), (result == TCL_OK)); + result = TCL_OK; + } else if (result == TCL_OK) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), 1); + } - return TCL_OK; + return result; } /*************************** Index: tests/parameters.xotcl =================================================================== diff -u -rca751243a48ebff49bf1a105830e4c0d6d3961ba -r496ffe8fb5e5bdaba56fe3a939d32634bdbcb088 --- tests/parameters.xotcl (.../parameters.xotcl) (revision ca751243a48ebff49bf1a105830e4c0d6d3961ba) +++ tests/parameters.xotcl (.../parameters.xotcl) (revision 496ffe8fb5e5bdaba56fe3a939d32634bdbcb088) @@ -19,23 +19,29 @@ ? {::xotcl::valuecheck object o1} 1 ? {::xotcl::is o1 object} 1 -? {::xotcl::valuecheck class o1} 0 +? {::xotcl::valuecheck class o1} {expected class but got "o1" for parameter value} +? {::xotcl::valuecheck class -nocomplain o1} 0 ? {::xotcl::valuecheck class Test} 1 ? {::xotcl::valuecheck object,multivalued [list o1 Test]} 1 ? {::xotcl::valuecheck integer 1} 1 ? {::xotcl::valuecheck integer,multivalued [list 1 2 3]} 1 -? {::xotcl::valuecheck integer,multivalued [list 1 2 3 a]} 0 +? {::xotcl::valuecheck integer,multivalued [list 1 2 3 a]} \ + {invalid value in "1 2 3 a": expected integer but got "a" for parameter value} ? {::xotcl::valuecheck object,type=::C c1} 1 -? {::xotcl::valuecheck object,type=::C o} 0 "object, but different type" -? {::xotcl::valuecheck object,type=::C c} 0 "no object" +? {::xotcl::valuecheck object,type=::C o} \ + {expected object but got "o" for parameter value} \ + "object, but different type" +? {::xotcl::valuecheck object,type=::C c} \ + {expected object but got "c" for parameter value} \ + "no object" ? {::xotcl::valuecheck object,type=::xotcl2::Object c1} 1 "general type" # do not allow "currently unknown" user defined types in valuecheck ? {::xotcl::valuecheck in1 aaa} {invalid value constraints "in1"} ? {::xotcl::valuecheck lower c} 1 "lower case char" ? {::xotcl::valuecheck lower abc} 1 "lower case chars" -? {::xotcl::valuecheck lower Abc} 0 "no lower case chars" +? {::xotcl::valuecheck lower Abc} {expected lower but got "Abc" for parameter value} "no lower case chars" ? {string is lower abc} 1 "tcl command 'string is lower'" ? {::xotcl::valuecheck {i:integer 1} 2} {invalid value constraints "i:integer 1"} @@ -760,15 +766,19 @@ Object create tmpObj tmpObj method type=mType {name value arg:optional} { if {$value} { - error invalid + error "expected false but got $value" } # Note that this converter does NOT return a value; it converts all # values into emtpy strings. } -? {::xotcl::valuecheck mType,slot=::tmpObj,multivalued {1 0}} 0 "fail on first value" +? {::xotcl::valuecheck mType,slot=::tmpObj,multivalued {1 0}} \ + {invalid value in "1 0": expected false but got 1} \ + "fail on first value" ? {::xotcl::valuecheck mType,slot=::tmpObj,multivalued {0 0 0}} 1 "all pass" -? {::xotcl::valuecheck mType,slot=::tmpObj,multivalued {0 1}} 0 "fail o last value" +? {::xotcl::valuecheck mType,slot=::tmpObj,multivalued {0 1}} \ + {invalid value in "0 1": expected false but got 1} \ + "fail o last value" ####################################################### # slot specific converter