Index: TODO =================================================================== diff -u -rbcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e -ra5e4ab3a3f85b51e855adb3fe981833c2534ee8b --- TODO (.../TODO) (revision bcf94f0b3bac771ebd9a65a8eb9dd6030651bb7e) +++ TODO (.../TODO) (revision a5e4ab3a3f85b51e855adb3fe981833c2534ee8b) @@ -2642,9 +2642,35 @@ * support connection to replica sets * support attribute selection lists for ::mongo::query (positive and negative selection) +- nx-mango.tcl: + * support for unique indices + * support for query operators "in" and "all" +- extended migration guide (introduction, feature lists, etc.) + +- serializer: + * prefix warnings to ease tracking of warnings + * some cleanup for handling aliased methods + +- nsf.c: + * moved implementation of ::nsf::method::delete to C + * produce same error messages when methods are delete + via nsf::method::delete and nsf::method::create {} {} + * Prohibit deletion of methods during shutdown. Otherwise + when destructors delete methods, some other destructors + depending on these methods will fail. Cleanup deletes + all methods anyway. + * Provided alternative (faster) way of dispatching + nsf::procs (can be tured off with NSF_INVOKE_SHADOWED_TRADITIONAL) + * renamed NsfMethodCmd() into NsfMethodCreateCmd() for consistency + * nsf works with OpenACS again (requires new nstrace.tcl, + aolserver-openacs.tcl, and 01-debug-procs.tcl). + TODO: +- ::nsf::method::exists /handle/ -> check, if handle is a handle of a registered method + (to be be used in serializer alias-dependency) + - maybe change nx::Test to nx::test (user never has to know that nx::Test is a class). - maybe move -count to the test case (but then a test-case less test needs a change of method) @@ -2662,7 +2688,6 @@ * It is not nice to have the full ParseContext structure in nsfmongo (required for the allocation of the parse context in the stubs) Adding fields to these structures would kill alder binaries -- not all converters have already external symbols - when alloc|dealloc are loaded via require, we have no redefined-protection on those. Since the script does not know, Index: generic/gentclAPI.decls =================================================================== diff -u -rda6586782390b02ed7660b56417c3db00d63d1c3 -ra5e4ab3a3f85b51e855adb3fe981833c2534ee8b --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision da6586782390b02ed7660b56417c3db00d63d1c3) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision a5e4ab3a3f85b51e855adb3fe981833c2534ee8b) @@ -66,8 +66,13 @@ {-argName "assertionsubcmd" -required 1 -nrargs 1 -type "check|object-invar|class-invar"} {-argName "arg" -required 0 -type tclobj} } -cmd "method::create" NsfMethodCmd { +cmd "method::delete" NsfMethodDeleteCmd { {-argName "object" -required 1 -type object} + {-argName "-per-object"} + {-argName "methodName" -required 1 -type tclobj} +} +cmd "method::create" NsfMethodCreateCmd { + {-argName "object" -required 1 -type object} {-argName "-inner-namespace"} {-argName "-per-object"} {-argName "methodName" -required 1 -type tclobj} Index: generic/nsf.c =================================================================== diff -u -r211c77c1a94a47be185a8bfb12c89512937b1901 -ra5e4ab3a3f85b51e855adb3fe981833c2534ee8b --- generic/nsf.c (.../nsf.c) (revision 211c77c1a94a47be185a8bfb12c89512937b1901) +++ generic/nsf.c (.../nsf.c) (revision a5e4ab3a3f85b51e855adb3fe981833c2534ee8b) @@ -820,8 +820,8 @@ if (object->nsPtr) { int rc = NSDeleteCmd(interp, object->nsPtr, methodName); if (rc < 0) { - return NsfPrintError(interp, "%s cannot delete method '%s' of object %s", - ObjectName(object), methodName, ObjectName(object)); + return NsfPrintError(interp, "%s: cannot delete object specific method '%s'", + ObjectName(object), methodName); } } return TCL_OK; @@ -7034,10 +7034,9 @@ *---------------------------------------------------------------------- */ static int -PushProcCallFrame(ClientData clientData, Tcl_Interp *interp, +PushProcCallFrame(Proc *procPtr, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], NsfCallStackContent *cscPtr) { - Proc *procPtr = (Proc *) clientData; CallFrame *framePtr; int result; @@ -7550,6 +7549,29 @@ /* *---------------------------------------------------------------------- + * ProcDispatchFinalize -- + * + * Finalization function for nsf::proc. Simplified version of + * ProcMethodDispatchFinalize(). + * + * Results: + * Tcl result code. + * + * Side effects: + * indirect effects by calling Tcl code + * + *---------------------------------------------------------------------- + */ +static int +ProcDispatchFinalize(ClientData data[], Tcl_Interp *interp, int result) { + /*CONST char *methodName = data[0]; + fprintf(stderr, "ProcDispatchFinalize of method %s\n", methodName);*/ + return result; +} + + +/* + *---------------------------------------------------------------------- * ProcMethodDispatch -- * * Invoke a scripted method (with assertion checking and filters). @@ -9570,11 +9592,24 @@ ClassName(cl), nameStr, ObjStr(precondition)); } - /* if both, args and body are empty strings, we delete the method */ if (*argsStr == 0 && *bodyStr == 0) { - result = cl ? - NsfRemoveClassMethod(interp, (Nsf_Class *)cl, nameStr) : - NsfRemoveObjectMethod(interp, (Nsf_Object *)object, nameStr); + /* + * Both, args and body are empty strings. This means we should delete the + * method. + */ + + if (RUNTIME_STATE(interp)->exitHandlerDestroyRound == NSF_EXITHANDLER_OFF) { + /* + * Don't delete methods via scripting during shutdown + */ + result = cl ? + NsfRemoveClassMethod(interp, (Nsf_Class *)cl, nameStr) : + NsfRemoveObjectMethod(interp, (Nsf_Object *)object, nameStr); + } else { + /* fprintf(stderr, "don't delete method %s during shutdown\n", nameStr); */ + result = TCL_OK; + } + } else { #if defined(NSF_WITH_ASSERTIONS) NsfAssertionStore *aStore = NULL; @@ -9640,6 +9675,9 @@ fprintf(stderr, "... procName %s paramDefs %p\n", ObjStr(tcd->procName), tcd->paramDefs);*/ DECR_REF_COUNT(tcd->procName); + if (tcd->cmd) { + NsfCommandRelease(tcd->cmd); + } /* tcd->paramDefs is freed by NsfProcDeleteProc() */ FREE(NsfProcClientData, tcd); } @@ -9659,10 +9697,12 @@ * *---------------------------------------------------------------------- */ +// #define NSF_INVOKE_SHADOWED_TRADITIONAL 1 static int -InvokeShadowedProc(Tcl_Interp *interp, Tcl_Obj *procNameObj, int objc, Tcl_Obj *CONST objv[]) { +InvokeShadowedProc(Tcl_Interp *interp, Tcl_Obj *procNameObj, Tcl_Command cmd, int objc, Tcl_Obj *CONST objv[]) { int result; -#if 1 + // xxxxx +#if defined(NSF_INVOKE_SHADOWED_TRADITIONAL) /* * For the time being, we call the shadowed proc defined with a * mutated name. It should be possible to compile and call the @@ -9695,33 +9735,73 @@ * PushProcCallFrame()). So, the benefit is not sure, when we go * low-level here. */ + CallFrame *framePtr; Proc *procPtr; - Tcl_Command cmd = Tcl_GetCommandFromObj(interp, objv[0]); + unsigned short dummy; + CONST char *fullMethodName = ObjStr(procNameObj); + + /* TODO check epoch */ + /*fprintf(stderr, "fullMethodName %s, shortMethodName %s\n", fullMethodName, shortMethodName);*/ - if (!cmd) { - return NsfPrintError(interp, "cannot lookup command '%s'", ObjStr(procNameObj)); + if (Tcl_Command_cmdEpoch(cmd)) { +#if 1 + /* + * It seems, as someone messed around with the shadowed proc. For now, we + * give up. + */ + return NsfPrintError(interp, "command '%s' is epoched", fullMethodName); +#else + /* + * We could refetch the command ... + */ + + cmd = Tcl_GetCommandFromObj(interp, procNameObj); + if (!cmd) { + return NsfPrintError(interp, "cannot lookup command '%s'", fullMethodName); + } + if (!CmdIsProc(cmd)) { + return NsfPrintError(interp, "command '%s' is not a proc", fullMethodName); + } + /* + * ... and update the refcounts + */ + NsfCommandRelease(tcd->cmd); + tcd->cmd = cmd; + NsfCommandPreserve(tcd->cmd); +#endif } - if (!CmdIsProc(cmd)) { - return NsfPrintError(interp, "command '%s' is not a proc", ObjStr(procNameObj)); + + procPtr = (Proc *)Tcl_Command_objClientData(cmd); + result = TclPushStackFrame(interp, (Tcl_CallFrame **)&framePtr, + (Tcl_Namespace *) procPtr->cmdPtr->nsPtr, + (FRAME_IS_PROC)); + + if (result == TCL_OK) { + result = ByteCompiled(interp, &dummy, procPtr, fullMethodName); } - procPtr = (Proc*) Tcl_Command_objClientData(cmd); - /* todo: refactor PushProcCallFrame or duplicate to avoid cscPtr */ - result = PushProcCallFrame(procPtr, interp, objc, objv, cscPtr); + if (result != TCL_OK) { + /* todo: really? error msg */ + return result; + } + + framePtr->objc = objc; + framePtr->objv = objv; + framePtr->procPtr = procPtr; + # if defined(NRE) /*fprintf(stderr, "CALL TclNRInterpProcCore %s method '%s'\n", ObjectName(object), ObjStr(objv[0]));*/ - Tcl_NRAddCallback(interp, ProcMethodDispatchFinalize, - releasePc ? pcPtr : NULL, cscPtr, (ClientData)methodName, NULL); - cscPtr->flags |= NSF_CSC_CALL_IS_NRE; - result = TclNRInterpProcCore(interp, objv[0], 1, &MakeProcError); + Tcl_NRAddCallback(interp, ProcDispatchFinalize, + (ClientData)fullMethodName, NULL, NULL, NULL); + result = TclNRInterpProcCore(interp, procNameObj /*objv[0]*/, 1, &MakeProcError); # else ClientData data[3] = { - releasePc ? pcPtr : NULL, - cscPtr, - (ClientData)methodName + (ClientData)fullMethodName, + NULL, + NULL }; - result = TclObjInterpProcCore(interp, objv[0], 1, &MakeProcError); - result = ProcMethodDispatchFinalize(data, interp, result); + result = TclObjInterpProcCore(interp, procNameObj /*objv[0]*/, 1, &MakeProcError); + result = ProcDispatchFinalize(data, interp, result); # endif #endif return result; @@ -9770,7 +9850,7 @@ objc, tov); if (result == TCL_OK) { - result = InvokeShadowedProc(interp, tcd->procName, pcPtr->objc, pcPtr->full_objv); + result = InvokeShadowedProc(interp, tcd->procName, tcd->cmd, pcPtr->objc, pcPtr->full_objv); } else { Tcl_Obj *resultObj = Tcl_GetObjResult(interp); fprintf(stderr, "NsfProcStub: incorrect arguments (%s)\n", ObjStr(resultObj)); @@ -9848,7 +9928,7 @@ * we have a useful error message. */ Tcl_DStringFree(dsPtr); - FREE(NsfProcClientData,tcd); + FREE(NsfProcClientData, tcd); return TCL_ERROR; } @@ -9889,6 +9969,7 @@ tcd->procName = procNameObj; tcd->paramDefs = paramDefs; tcd->with_ad = with_ad; + tcd->cmd = NULL; /*fprintf(stderr, "NsfAddParameterProc %s tcd %p paramdefs %p\n", ObjStr(procNameObj), tcd, tcd->paramDefs);*/ @@ -9945,7 +10026,9 @@ Tcl_Command procCmd = Tcl_GetCommandFromObj(interp, procNameObj); assert(procCmd); ((Command *)procCmd)->nsPtr = (Namespace *)cmdNsPtr; - + tcd->cmd = procCmd; + NsfCommandPreserve(tcd->cmd); + } else { /* * We could not define the shadowed proc. In this case, cleanup by @@ -15574,7 +15657,7 @@ /* -nsfCmd method::create NsfMethodCmd { +nsfCmd method::create NsfMethodCreateCmd { {-argName "object" -required 1 -type object} {-argName "-inner-namespace"} {-argName "-per-object"} @@ -15586,7 +15669,7 @@ } */ static int -NsfMethodCmd(Tcl_Interp *interp, NsfObject *object, +NsfMethodCreateCmd(Tcl_Interp *interp, NsfObject *object, int withInner_namespace, int withPer_object, Tcl_Obj *nameObj, Tcl_Obj *arguments, Tcl_Obj *body, Tcl_Obj *withPrecondition, Tcl_Obj *withPostcondition) { @@ -15603,6 +15686,21 @@ } /* +cmd "method::delete" NsfMethodDeleteCmd { + {-argName "object" -required 1 -type object} + {-argName "-per-object"} + {-argName "methodName" -required 1 -type tclobj} +} +*/ +static int +NsfMethodDeleteCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, + Tcl_Obj *methodNameObj) { + return NsfMethodCreateCmd(interp, object, 0, withPer_object, methodNameObj, + NsfGlobalObjs[NSF_EMPTY], NsfGlobalObjs[NSF_EMPTY], + NULL, NULL); +} + +/* nsfCmd ::method::property NsfMethodPropertyCmd { {-argName "object" -required 1 -type object} {-argName "-per-object"} @@ -15617,7 +15715,7 @@ CONST char *methodName = ObjStr(methodObj), *methodName1 = NULL; NsfObject *regObject, *defObject; Tcl_DString ds, *dsPtr = &ds; - Tcl_Command cmd = NULL; + Tcl_Command cmd; NsfClass *cl = withPer_object == 0 && NsfObjectIsClass(object) ? (NsfClass *)object : NULL; int flag, fromClassNS = cl != NULL; @@ -15630,7 +15728,8 @@ if (!cmd) { Tcl_DStringFree(dsPtr); - return NsfPrintError(interp, "Cannot lookup object method '%s' for object %s", + return NsfPrintError(interp, "Cannot lookup %smethod '%s' for %s", + cl == 0 ? "object " : "", methodName, ObjectName(object)); } Tcl_DStringFree(dsPtr); @@ -19283,7 +19382,7 @@ deleted++; } } - /* fprintf(stderr, "deleted %d Objects without dependencies\n", deleted);*/ + /*fprintf(stderr, "deleted %d Objects without dependencies\n", deleted);*/ if (deleted > 0) { continue; } Index: generic/nsf.tcl =================================================================== diff -u -r4536c2540977c43aaf422800dab048e5d9063b3f -ra5e4ab3a3f85b51e855adb3fe981833c2534ee8b --- generic/nsf.tcl (.../nsf.tcl) (revision 4536c2540977c43aaf422800dab048e5d9063b3f) +++ generic/nsf.tcl (.../nsf.tcl) (revision a5e4ab3a3f85b51e855adb3fe981833c2534ee8b) @@ -40,18 +40,6 @@ } # - # proc for deleting methods - # - nsf::proc ::nsf::method::delete {object:object -per-object:switch methodName} { - set scope [expr {${per-object} ? "object" : "class"}] - if {[$object ::nsf::methods::${scope}::info::method exists $methodName]} { - ::nsf::method::create $object {*}[expr {${per-object} ? "-per-object" : ""}] $methodName "" "" - } else { - error "Object $object: method $methodName is not defined" - } - } - - # # The following helper proc is used e.g. in OpenACS to pair # introspection with nsf::procs. # Index: generic/nsfInt.h =================================================================== diff -u -rbf592f968ae84740d9ef7c40cddbcbf9f5a68283 -ra5e4ab3a3f85b51e855adb3fe981833c2534ee8b --- generic/nsfInt.h (.../nsfInt.h) (revision bf592f968ae84740d9ef7c40cddbcbf9f5a68283) +++ generic/nsfInt.h (.../nsfInt.h) (revision a5e4ab3a3f85b51e855adb3fe981833c2534ee8b) @@ -524,6 +524,7 @@ */ typedef struct NsfProcClientData { Tcl_Obj *procName; + Tcl_Command cmd; NsfParamDefs *paramDefs; int with_ad; } NsfProcClientData; Index: generic/predefined.h =================================================================== diff -u -r4536c2540977c43aaf422800dab048e5d9063b3f -ra5e4ab3a3f85b51e855adb3fe981833c2534ee8b --- generic/predefined.h (.../predefined.h) (revision 4536c2540977c43aaf422800dab048e5d9063b3f) +++ generic/predefined.h (.../predefined.h) (revision a5e4ab3a3f85b51e855adb3fe981833c2534ee8b) @@ -17,11 +17,6 @@ "return [eval [linsert $cmd 1 $object]]} else {\n" "return [eval [linsert $(definition) 1 $object]]}} else {\n" "error \"cannot require method $name for $object, method unknown\"}}\n" -"nsf::proc ::nsf::method::delete {object:object -per-object:switch methodName} {\n" -"set scope [expr {${per-object} ? \"object\" : \"class\"}]\n" -"if {[$object ::nsf::methods::${scope}::info::method exists $methodName]} {\n" -"::nsf::method::create $object {*}[expr {${per-object} ? \"-per-object\" : \"\"}] $methodName \"\" \"\"} else {\n" -"error \"Object $object: method $methodName is not defined\"}}\n" "::proc strip_proc_name {name} {\n" "if {[string match ::nsf::procs::* $name]} {\n" "return [string range $name 12 end]} elseif {[string match nsf::procs::* $name]} {\n" Index: generic/tclAPI.h =================================================================== diff -u -rda6586782390b02ed7660b56417c3db00d63d1c3 -ra5e4ab3a3f85b51e855adb3fe981833c2534ee8b --- generic/tclAPI.h (.../tclAPI.h) (revision da6586782390b02ed7660b56417c3db00d63d1c3) +++ generic/tclAPI.h (.../tclAPI.h) (revision a5e4ab3a3f85b51e855adb3fe981833c2534ee8b) @@ -218,7 +218,8 @@ static int NsfInvalidateObjectParameterCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfIsCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfIsObjectCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); -static int NsfMethodCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); +static int NsfMethodCreateCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); +static int NsfMethodDeleteCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfMethodPropertyCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfMyCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfNSCopyCmdsCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); @@ -306,7 +307,8 @@ static int NsfInvalidateObjectParameterCmd(Tcl_Interp *interp, NsfClass *class); static int NsfIsCmd(Tcl_Interp *interp, int withComplain, Tcl_Obj *constraint, Tcl_Obj *value); static int NsfIsObjectCmd(Tcl_Interp *interp, Tcl_Obj *value); -static int NsfMethodCmd(Tcl_Interp *interp, NsfObject *object, int withInner_namespace, int withPer_object, Tcl_Obj *methodName, Tcl_Obj *arguments, Tcl_Obj *body, Tcl_Obj *withPrecondition, Tcl_Obj *withPostcondition); +static int NsfMethodCreateCmd(Tcl_Interp *interp, NsfObject *object, int withInner_namespace, int withPer_object, Tcl_Obj *methodName, Tcl_Obj *arguments, Tcl_Obj *body, Tcl_Obj *withPrecondition, Tcl_Obj *withPostcondition); +static int NsfMethodDeleteCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, Tcl_Obj *methodName); static int NsfMethodPropertyCmd(Tcl_Interp *interp, NsfObject *object, int withPer_object, Tcl_Obj *methodName, int methodproperty, Tcl_Obj *value); static int NsfMyCmd(Tcl_Interp *interp, int withLocal, Tcl_Obj *methodName, int nobjc, Tcl_Obj *CONST nobjv[]); static int NsfNSCopyCmdsCmd(Tcl_Interp *interp, Tcl_Obj *fromNs, Tcl_Obj *toNs); @@ -395,7 +397,8 @@ NsfInvalidateObjectParameterCmdIdx, NsfIsCmdIdx, NsfIsObjectCmdIdx, - NsfMethodCmdIdx, + NsfMethodCreateCmdIdx, + NsfMethodDeleteCmdIdx, NsfMethodPropertyCmdIdx, NsfMyCmdIdx, NsfNSCopyCmdsCmdIdx, @@ -1203,13 +1206,13 @@ } static int -NsfMethodCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { +NsfMethodCreateCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { ParseContext pc; (void)clientData; if (ArgumentParse(interp, objc, objv, NULL, objv[0], - method_definitions[NsfMethodCmdIdx].paramDefs, - method_definitions[NsfMethodCmdIdx].nrParameters, 1, + method_definitions[NsfMethodCreateCmdIdx].paramDefs, + method_definitions[NsfMethodCreateCmdIdx].nrParameters, 1, &pc) != TCL_OK) { return TCL_ERROR; } else { @@ -1223,12 +1226,33 @@ Tcl_Obj *withPostcondition = (Tcl_Obj *)pc.clientData[7]; assert(pc.status == 0); - return NsfMethodCmd(interp, object, withInner_namespace, withPer_object, methodName, arguments, body, withPrecondition, withPostcondition); + return NsfMethodCreateCmd(interp, object, withInner_namespace, withPer_object, methodName, arguments, body, withPrecondition, withPostcondition); } } static int +NsfMethodDeleteCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + ParseContext pc; + (void)clientData; + + if (ArgumentParse(interp, objc, objv, NULL, objv[0], + method_definitions[NsfMethodDeleteCmdIdx].paramDefs, + method_definitions[NsfMethodDeleteCmdIdx].nrParameters, 1, + &pc) != TCL_OK) { + return TCL_ERROR; + } else { + NsfObject *object = (NsfObject *)pc.clientData[0]; + int withPer_object = (int )PTR2INT(pc.clientData[1]); + Tcl_Obj *methodName = (Tcl_Obj *)pc.clientData[2]; + + assert(pc.status == 0); + return NsfMethodDeleteCmd(interp, object, withPer_object, methodName); + + } +} + +static int NsfMethodPropertyCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { ParseContext pc; (void)clientData; @@ -2295,7 +2319,7 @@ {"::nsf::object::exists", NsfIsObjectCmdStub, 1, { {"value", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, -{"::nsf::method::create", NsfMethodCmdStub, 8, { +{"::nsf::method::create", NsfMethodCreateCmdStub, 8, { {"object", NSF_ARG_REQUIRED, 0, Nsf_ConvertToObject, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"-inner-namespace", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"-per-object", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, @@ -2305,6 +2329,11 @@ {"-precondition", 0, 1, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"-postcondition", 0, 1, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, +{"::nsf::method::delete", NsfMethodDeleteCmdStub, 3, { + {"object", NSF_ARG_REQUIRED, 0, Nsf_ConvertToObject, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"-per-object", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, + {"methodName", NSF_ARG_REQUIRED, 0, Nsf_ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} +}, {"::nsf::method::property", NsfMethodPropertyCmdStub, 5, { {"object", NSF_ARG_REQUIRED, 0, Nsf_ConvertToObject, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"-per-object", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, Index: tests/methods.test =================================================================== diff -u -re02cb00ae815bd6f8561a6a03fceacc13fd91903 -ra5e4ab3a3f85b51e855adb3fe981833c2534ee8b --- tests/methods.test (.../methods.test) (revision e02cb00ae815bd6f8561a6a03fceacc13fd91903) +++ tests/methods.test (.../methods.test) (revision a5e4ab3a3f85b51e855adb3fe981833c2534ee8b) @@ -374,13 +374,13 @@ :create c1 } - ? {::nsf::method::delete C x} "Object C: method x is not defined" - ? {::nsf::method::delete C -per-object x} "Object C: method x is not defined" + ? {::nsf::method::delete C x} "::C: cannot delete method 'x'" + ? {::nsf::method::delete C -per-object x} "::C: cannot delete object specific method 'x'" ? {::nsf::method::delete C foo} "" - ? {::nsf::method::delete C foo} "Object C: method foo is not defined" - ? {::nsf::method::delete C bar} "Object C: method bar is not defined" + ? {::nsf::method::delete C foo} "::C: cannot delete method 'foo'" + ? {::nsf::method::delete C bar} "::C: cannot delete method 'bar'" ? {::nsf::method::delete C -per-object bar} "" - ? {::nsf::method::delete C -per-object bar} "Object C: method bar is not defined" + ? {::nsf::method::delete C -per-object bar} "::C: cannot delete object specific method 'bar'" } #