Index: generic/xotcl.c =================================================================== diff -u -r536cacc0e51390f46b6bde5874c823ea03e732e2 -r2cd9b650a6c6bb8a50473195278c7005e75188b0 --- generic/xotcl.c (.../xotcl.c) (revision 536cacc0e51390f46b6bde5874c823ea03e732e2) +++ generic/xotcl.c (.../xotcl.c) (revision 2cd9b650a6c6bb8a50473195278c7005e75188b0) @@ -6334,21 +6334,27 @@ ov[2] = pPtr->nameObj; ov[3] = objPtr; + /*fprintf(stderr, "call converter %s on %s \n", ObjStr(pPtr->converterName), ObjStr(ov[0]));*/ oc = 4; if (pPtr->converterArg) { ov[4] = pPtr->converterArg; oc++; } result = Tcl_EvalObjv(interp, oc, ov, 0); - + if (result == TCL_OK) { /*fprintf(stderr, "convertViaCmd converts %s to '%s'\n", ObjStr(objPtr), ObjStr(Tcl_GetObjResult(interp)));*/ *outObjPtr = Tcl_GetObjResult(interp); *clientData = (ClientData) *outObjPtr; + + /* incr refCount is necessary e.g. for + return [expr {$value + 1}] + */ + INCR_REF_COUNT(*outObjPtr); } else { - *outObjPtr = objPtr; /* xxx */ + *outObjPtr = objPtr; } return result; } @@ -6615,7 +6621,11 @@ if (paramPtr->converter == NULL) { /* convertToTclobj() is the default converter */ paramPtr->converter = convertToTclobj; - } else if (paramPtr->converter == convertViaCmd) { + } /*else if (paramPtr->converter == convertViaCmd) {*/ + + if ((paramPtr->slotObj || paramPtr->converter == convertViaCmd) && paramPtr->type) { + Tcl_Obj *converterNameObj; + char *converterNameString; XOTclObject *paramObj; XOTclClass *pcl; Tcl_Command cmd; @@ -6626,13 +6636,37 @@ if (result != TCL_OK) return result; - cmd = ObjectFindMethod(interp, paramObj, ObjStr(paramPtr->converterName), &pcl); + if (paramPtr->converterName == NULL) { + converterNameObj = ParamCheckObj(interp, paramPtr->type, strlen(paramPtr->type)); + INCR_REF_COUNT(converterNameObj); + } else { + converterNameObj = paramPtr->converterName; + } + converterNameString = ObjStr(converterNameObj); + + cmd = ObjectFindMethod(interp, paramObj, converterNameString, &pcl); if (cmd == NULL) { - fprintf(stderr, "**** could not find checker method %s defined on %s\n", - ObjStr(paramPtr->converterName), objectName(paramObj)); - paramPtr->flags |= XOTCL_ARG_CURRENTLY_UNKNOWN; - /* TODO: for the time being, we do not return an error here */ + if (paramPtr->converter == convertViaCmd) { + fprintf(stderr, "**** could not find checker method %s defined on %s\n", + converterNameString, objectName(paramObj)); + paramPtr->flags |= XOTCL_ARG_CURRENTLY_UNKNOWN; + /* TODO: for the time being, we do not return an error here */ + } + } else if (paramPtr->converter != convertViaCmd && + strcmp(ObjStr(paramPtr->slotObj),XOTclGlobalStrings[XOTE_METHOD_PARAMETER_SLOT_OBJ]) != 0) { + /* todo remove me */ + fprintf(stderr, "**** checker method %s defined on %s shadows built-in converter\n", + converterNameString, objectName(paramObj)); + if (paramPtr->converterName == NULL) { + paramPtr->converterName = converterNameObj; + paramPtr->converter = NULL; + result = ParamOptionSetConverter(interp, paramPtr, converterNameString, convertViaCmd); + } } + if (converterNameObj != paramPtr->converterName) { + DECR_REF_COUNT(converterNameObj); + } + } /* Index: tests/parameters.xotcl =================================================================== diff -u -r536cacc0e51390f46b6bde5874c823ea03e732e2 -r2cd9b650a6c6bb8a50473195278c7005e75188b0 --- tests/parameters.xotcl (.../parameters.xotcl) (revision 536cacc0e51390f46b6bde5874c823ea03e732e2) +++ tests/parameters.xotcl (.../parameters.xotcl) (revision 2cd9b650a6c6bb8a50473195278c7005e75188b0) @@ -790,6 +790,29 @@ "fail o last value" ####################################################### +# application specific multivalued converter +####################################################### +Test case shadowing-app-converter + +Object create mySlot { + :method type=integer {name value arg:optional} { + return [expr {$value + 1}] + } +} +Object create o { + :method foo {x:integer,slot=::mySlot} { + return $x + } +} + +? {::xotcl::valuecheck integer,slot=::mySlot 1} 1 +? {o foo 3} 4 + +o destroy +mySlot destroy + + +####################################################### # slot specific converter ####################################################### Test case slot-specfic-converter