Index: TODO =================================================================== diff -u -rd168a26bce713de8daa5bbe79d740926e961c5bc -ra3b0e40438f4c944dac1c34387f4292e012f4bd0 --- TODO (.../TODO) (revision d168a26bce713de8daa5bbe79d740926e961c5bc) +++ TODO (.../TODO) (revision a3b0e40438f4c944dac1c34387f4292e012f4bd0) @@ -1340,8 +1340,12 @@ - extended regression test - changed "cls object method ..." and friends into - "cls class-object method ..." and friends into + "cls class-object method ..." +- added "info method subcommands ..." to return list of subcommands (of the ensemble) +- extended regression test +- use always NULL instead of 0 when assigning to a pointer variable + TODO: - check equivalence of the following two commands in respect to fully-qualified names Index: generic/gentclAPI.decls =================================================================== diff -u -r1e3a84fd851f93ae3116130a530fae5e8bd63336 -ra3b0e40438f4c944dac1c34387f4292e012f4bd0 --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision 1e3a84fd851f93ae3116130a530fae5e8bd63336) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision a3b0e40438f4c944dac1c34387f4292e012f4bd0) @@ -261,7 +261,7 @@ {-argName "-type" -required 0 -nrargs 1 -type class} } objectInfoMethod method NsfObjInfoMethodMethod { - {-argName "infomethodsubcmd" -type "args|body|definition|handle|parameter|parametersyntax|type|precondition|postcondition"} + {-argName "infomethodsubcmd" -type "args|body|definition|handle|parameter|parametersyntax|type|precondition|postcondition|subcommands"} {-argName "name" -type tclobj} } objectInfoMethod methods NsfObjInfoMethodsMethod { @@ -313,7 +313,7 @@ } classInfoMethod method NsfClassInfoMethodMethod { - {-argName "infomethodsubcmd" -type "args|body|definition|handle|parameter|parametersyntax|type|precondition|postcondition"} + {-argName "infomethodsubcmd" -type "args|body|definition|handle|parameter|parametersyntax|type|precondition|postcondition|subcommands"} {-argName "name" -type tclobj} } classInfoMethod methods NsfClassInfoMethodsMethod { Index: generic/nsf.c =================================================================== diff -u -rd168a26bce713de8daa5bbe79d740926e961c5bc -ra3b0e40438f4c944dac1c34387f4292e012f4bd0 --- generic/nsf.c (.../nsf.c) (revision d168a26bce713de8daa5bbe79d740926e961c5bc) +++ generic/nsf.c (.../nsf.c) (revision a3b0e40438f4c944dac1c34387f4292e012f4bd0) @@ -244,8 +244,10 @@ /* misc prototypes */ static int NsfDeprecatedCmd(Tcl_Interp *interp, CONST char *what, CONST char *oldCmd, CONST char *newCmd); static int SetInstVar(Tcl_Interp *interp, NsfObject *object, Tcl_Obj *nameObj, Tcl_Obj *valueObj); +static int ListDefinedMethods(Tcl_Interp *interp, NsfObject *object, CONST char *pattern, + int withPer_object, int methodType, int withCallproctection, + int noMixins, int inContext); - /* * argv parsing */ @@ -3301,7 +3303,7 @@ NsfClasses *clPtr; clPtr = ComputeOrder(object->cl, object->cl->order, Super); while (clPtr && result != TCL_ERROR) { - NsfAssertionStore *aStore = (clPtr->cl->opt) ? clPtr->cl->opt->assertions : 0; + NsfAssertionStore *aStore = (clPtr->cl->opt) ? clPtr->cl->opt->assertions : NULL; if (aStore) { result = AssertionCheckList(interp, object, aStore->invariants, methodName); } @@ -3319,9 +3321,9 @@ NsfAssertionStore *aStore; if (cl) - aStore = cl->opt ? cl->opt->assertions : 0; + aStore = cl->opt ? cl->opt->assertions : NULL; else - aStore = object->opt ? object->opt->assertions : 0; + aStore = object->opt ? object->opt->assertions : NULL; assert(object->opt); @@ -4694,7 +4696,7 @@ for ( ; clPtr; clPtr = clPtr->nextPtr) { Tcl_HashSearch hSrch; Tcl_HashEntry *hPtr = &clPtr->cl->instances ? - Tcl_FirstHashEntry(&clPtr->cl->instances, &hSrch) : 0; + Tcl_FirstHashEntry(&clPtr->cl->instances, &hSrch) : NULL; /* recalculate the commands of all class-filter registrations */ if (clPtr->cl->opt) { @@ -5312,7 +5314,7 @@ varName, varPtr, requireDefined, triggerTrace, - varPtr ? TclIsVarUndefined(varPtr) : 0); + varPtr ? TclIsVarUndefined(varPtr) : NULL); */ result = (varPtr && (!requireDefined || !TclIsVarUndefined(varPtr))); @@ -6545,7 +6547,7 @@ if (result == TCL_ERROR) { /*fprintf(stderr, "Call ErrInProc cl = %p, cmd %p, flags %.6x\n", - cl, cl ? cl->object.id : 0, cl ? cl->object.flags : 0);*/ + cl, cl ? cl->object.id : NULL, cl ? cl->object.flags : 0);*/ result = NsfErrInProc(interp, cmdName, cl && cl->object.teardown ? cl->object.cmdName : NULL, methodName); @@ -8557,7 +8559,7 @@ */ if ((cl->object.flags & NSF_IS_ROOT_CLASS) == 0) { - hPtr = &cl->instances ? Tcl_FirstHashEntry(&cl->instances, &hSrch) : 0; + hPtr = &cl->instances ? Tcl_FirstHashEntry(&cl->instances, &hSrch) : NULL; for (; hPtr; hPtr = Tcl_NextHashEntry(&hSrch)) { NsfObject *inst = (NsfObject*)Tcl_GetHashKey(&cl->instances, hPtr); /*fprintf(stderr, " inst %p %s flags %.6x id %p baseClass %p %s\n", @@ -9248,7 +9250,7 @@ extern ClientData NsfGetObjClientData(Nsf_Object *object1) { NsfObject *object = (NsfObject*) object1; - return (object && object->opt) ? object->opt->clientData : 0; + return (object && object->opt) ? object->opt->clientData : NULL; } extern void NsfSetClassClientData(Nsf_Class *cli, ClientData data) { @@ -9259,7 +9261,7 @@ extern ClientData NsfGetClassClientData(Nsf_Class *cli) { NsfClass *cl = (NsfClass*) cli; - return (cl && cl->opt) ? cl->opt->clientData : 0; + return (cl && cl->opt) ? cl->opt->clientData : NULL; } static int @@ -10384,7 +10386,7 @@ } else { Tcl_Obj *list = Tcl_NewListObj(0, NULL); Tcl_HashSearch hSrch; - hPtr = tablePtr ? Tcl_FirstHashEntry(tablePtr, &hSrch) : 0; + hPtr = tablePtr ? Tcl_FirstHashEntry(tablePtr, &hSrch) : NULL; for (; hPtr; hPtr = Tcl_NextHashEntry(&hSrch)) { Var *val = VarHashGetValue(hPtr); Tcl_Obj *key = VarHashGetKey(val); @@ -10642,7 +10644,19 @@ if (procs) Tcl_SetObjResult(interp, AssertionList(interp, procs->post)); return TCL_OK; } - + case InfomethodsubcmdSubcommandsIdx: + { + if (procPtr == NsfObjDispatch) { + NsfObject *subObject = NsfGetObjectFromCmdPtr(cmd); + if (subObject) { + return ListDefinedMethods(interp, subObject, NULL, 1 /* per-object */, + NSF_METHODTYPE_ALL, 0, 1, 0); + } + } + /* all other cases return emtpy */ + Tcl_SetObjResult(interp, NsfGlobalObjs[NSF_EMPTY]); + return TCL_OK; + } } /* @@ -10914,7 +10928,7 @@ return TCL_OK; } else { - hPtr = table ? Tcl_FirstHashEntry(table, &hSrch) : 0; + hPtr = table ? Tcl_FirstHashEntry(table, &hSrch) : NULL; for (; hPtr; hPtr = Tcl_NextHashEntry(&hSrch)) { key = Tcl_GetHashKey(table, hPtr); @@ -12227,7 +12241,7 @@ if (cl) { /* Next Scripting class-methods */ NsfProcAssertion *procs; - procs = cl->opt ? AssertionFindProcs(cl->opt->assertions, name) : 0; + procs = cl->opt ? AssertionFindProcs(cl->opt->assertions, name) : NULL; DSTRING_INIT(dsPtr); Tcl_DStringAppendElement(dsPtr, "::nsf::method"); @@ -12248,7 +12262,7 @@ NsfProcAssertion *procs; if (object) { - procs = object->opt ? AssertionFindProcs(object->opt->assertions, name) : 0; + procs = object->opt ? AssertionFindProcs(object->opt->assertions, name) : NULL; } else { DECR_REF_COUNT(newFullCmdName); DECR_REF_COUNT(oldFullCmdName); @@ -13861,7 +13875,7 @@ specifiedName, nameString, newObject, className(cl), IsMetaClass(interp, cl, 1), newObject ? ObjStr(newObject->cl->object.cmdName) : "NULL", - newObject ? IsMetaClass(interp, newObject->cl, 1) : 0 + newObject ? IsMetaClass(interp, newObject->cl, 1) : NULL );*/ /* don't allow to @@ -14193,7 +14207,7 @@ switch (methodType) { case MethodtypeNULL: /* default */ case MethodtypeAllIdx: - methodType = NSF_METHODTYPE_SCRIPTED|NSF_METHODTYPE_BUILTIN|NSF_METHODTYPE_OBJECT; + methodType = NSF_METHODTYPE_ALL; break; case MethodtypeScriptedIdx: /*methodType = NSF_METHODTYPE_SCRIPTED|NSF_METHODTYPE_ALIAS;*/ @@ -14506,7 +14520,7 @@ /* objectInfoMethod method NsfObjInfoMethodMethod { - {-argName "infomethodsubcmd" -type "args|body|definition|handle|parameter|parametersyntax|type|precondition|postcondition"} + {-argName "infomethodsubcmd" -type "args|body|definition|handle|parameter|parametersyntax|type|precondition|postcondition|subcommands"} {-argName "name"} } */ @@ -14752,7 +14766,7 @@ /* classInfoMethod method NsfClassInfoMethodMethod { - {-argName "infomethodsubcmd" -type "args|body|definition|handle|parameter|parametersyntax|type|precondition|postcondition"} + {-argName "infomethodsubcmd" -type "args|body|definition|handle|parameter|parametersyntax|type|precondition|postcondition|subcommands"} {-argName "name"} } */ Index: generic/nsfInt.h =================================================================== diff -u -r1e14e709ba184c6daf7a2f94605a2cff65d7706c -ra3b0e40438f4c944dac1c34387f4292e012f4bd0 --- generic/nsfInt.h (.../nsfInt.h) (revision 1e14e709ba184c6daf7a2f94605a2cff65d7706c) +++ generic/nsfInt.h (.../nsfInt.h) (revision a3b0e40438f4c944dac1c34387f4292e012f4bd0) @@ -387,8 +387,8 @@ #define NSF_METHODTYPE_OBJECT 0x0010 #define NSF_METHODTYPE_OTHER 0x0100 #define NSF_METHODTYPE_BUILTIN NSF_METHODTYPE_ALIAS|NSF_METHODTYPE_SETTER|NSF_METHODTYPE_FORWARDER|NSF_METHODTYPE_OTHER +#define NSF_METHODTYPE_ALL NSF_METHODTYPE_SCRIPTED|NSF_METHODTYPE_BUILTIN|NSF_METHODTYPE_OBJECT - /* flags for ParseContext */ #define NSF_PC_MUST_DECR 0x0001 Index: generic/tclAPI.h =================================================================== diff -u -r1e3a84fd851f93ae3116130a530fae5e8bd63336 -ra3b0e40438f4c944dac1c34387f4292e012f4bd0 --- generic/tclAPI.h (.../tclAPI.h) (revision 1e3a84fd851f93ae3116130a530fae5e8bd63336) +++ generic/tclAPI.h (.../tclAPI.h) (revision a3b0e40438f4c944dac1c34387f4292e012f4bd0) @@ -2,13 +2,13 @@ static int ConvertToInfomethodsubcmd(Tcl_Interp *interp, Tcl_Obj *objPtr, NsfParam CONST *pPtr, ClientData *clientData, Tcl_Obj **outObjPtr) { int index, result; - static CONST char *opts[] = {"args", "body", "definition", "handle", "parameter", "parametersyntax", "type", "precondition", "postcondition", NULL}; + static CONST char *opts[] = {"args", "body", "definition", "handle", "parameter", "parametersyntax", "type", "precondition", "postcondition", "subcommands", NULL}; result = Tcl_GetIndexFromObj(interp, objPtr, opts, "infomethodsubcmd", 0, &index); *clientData = (ClientData) INT2PTR(index + 1); *outObjPtr = objPtr; return result; } -enum InfomethodsubcmdIdx {InfomethodsubcmdNULL, InfomethodsubcmdArgsIdx, InfomethodsubcmdBodyIdx, InfomethodsubcmdDefinitionIdx, InfomethodsubcmdHandleIdx, InfomethodsubcmdParameterIdx, InfomethodsubcmdParametersyntaxIdx, InfomethodsubcmdTypeIdx, InfomethodsubcmdPreconditionIdx, InfomethodsubcmdPostconditionIdx}; +enum InfomethodsubcmdIdx {InfomethodsubcmdNULL, InfomethodsubcmdArgsIdx, InfomethodsubcmdBodyIdx, InfomethodsubcmdDefinitionIdx, InfomethodsubcmdHandleIdx, InfomethodsubcmdParameterIdx, InfomethodsubcmdParametersyntaxIdx, InfomethodsubcmdTypeIdx, InfomethodsubcmdPreconditionIdx, InfomethodsubcmdPostconditionIdx, InfomethodsubcmdSubcommandsIdx}; static int ConvertToMethodtype(Tcl_Interp *interp, Tcl_Obj *objPtr, NsfParam CONST *pPtr, ClientData *clientData, Tcl_Obj **outObjPtr) { Index: tests/info-method.tcl =================================================================== diff -u -rd168a26bce713de8daa5bbe79d740926e961c5bc -ra3b0e40438f4c944dac1c34387f4292e012f4bd0 --- tests/info-method.tcl (.../info-method.tcl) (revision d168a26bce713de8daa5bbe79d740926e961c5bc) +++ tests/info-method.tcl (.../info-method.tcl) (revision a3b0e40438f4c944dac1c34387f4292e012f4bd0) @@ -247,6 +247,18 @@ ? {o info method definition "::nx::Object::slot::__info::lookup::methods"} \ {::nx::Object::slot::__info::lookup alias methods ::nsf::cmd::ObjectInfo::lookupmethods} + ? {lsort [o info method subcommands dummy]} "" + ? {lsort [o info method subcommands foo]} "a b" + ? {lsort [o info method subcommands "foo a"]} "" + + ? {lsort [C info method subcommands "bar"]} "a b baz" + ? {lsort [C info method subcommands "bar a"]} "" + ? {lsort [C info method subcommands "bar baz"]} "x y" + ? {lsort [C info method subcommands "bar baz y"]} "" + + ? {lsort [C class-object info method subcommands "foo"]} "x y" + ? {lsort [C class-object info method subcommands "foo x"]} "" + ? {C info method handle "bar"} {::nsf::classes::C::bar} ? {C info method handle "bar a"} {::nsf::classes::C::bar a} ? {C info method handle "bar baz y"} {::nsf::classes::C::bar baz y}