Index: generic/nsf.c =================================================================== diff -u -red5cc784dfa9e971fd124701a7bdfb9d609512a5 -r2a2f104357f92c52f53b72025ae2183152644140 --- generic/nsf.c (.../nsf.c) (revision ed5cc784dfa9e971fd124701a7bdfb9d609512a5) +++ generic/nsf.c (.../nsf.c) (revision 2a2f104357f92c52f53b72025ae2183152644140) @@ -18637,12 +18637,13 @@ NsfProcStubDeleteProc(ClientData clientData) { NsfProcClientData *tcd = clientData; - /*fprintf(stderr, "NsfProcStubDeleteProc received %p\n", clientData); - fprintf(stderr, "... procName %s paramDefs %p\n", ObjStr(tcd->procName), tcd->paramDefs);*/ - + fprintf(stderr, "NsfProcStubDeleteProc received %p\n", clientData); + /*fprintf(stderr, "... procName %s paramDefs %p\n", ObjStr(tcd->procName), tcd->paramDefs);*/ + DECR_REF_COUNT2("procNameObj", tcd->procName); if (tcd->cmd != NULL) { - NsfCommandRelease(tcd->cmd); + /* NsfCommandRelease(tcd->cmd); */ + Tcl_DeleteCommandFromToken(tcd->interp, tcd->cmd); } /* tcd->paramDefs is freed by NsfProcDeleteProc() */ FREE(NsfProcClientData, tcd); @@ -18991,7 +18992,8 @@ Tcl_DStringSetLength(dsPtr, 0); Tcl_DStringAppend(dsPtr, "::nsf::procs", -1); DStringAppendQualName(dsPtr, cmdNsPtr, Tcl_GetCommandName(interp, cmd)); - procNameObj = Tcl_NewStringObj(Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr)); + procNameObj = Tcl_NewStringObj(Tcl_DStringValue(dsPtr), + Tcl_DStringLength(dsPtr)); INCR_REF_COUNT2("procNameObj", procNameObj); /* will be freed, when NsfProcStub is deleted */ @@ -19019,6 +19021,7 @@ tcd->flags = (checkAlwaysFlag != 0u ? NSF_PROC_FLAG_CHECK_ALWAYS : 0u) | (with_ad != 0 ? NSF_PROC_FLAG_AD : 0u); tcd->cmd = NULL; tcd->wrapperCmd = cmd; /* TODO should we preserve? */ + tcd->interp = interp; /* for deleting the shadowed proc */ /*fprintf(stderr, "NsfProcAdd %s tcd %p paramdefs %p\n", ObjStr(procNameObj), tcd, tcd->paramDefs);*/ Index: generic/nsfInt.h =================================================================== diff -u -r47f388cda74f1b4656389d4129b96435034ac4a4 -r2a2f104357f92c52f53b72025ae2183152644140 --- generic/nsfInt.h (.../nsfInt.h) (revision 47f388cda74f1b4656389d4129b96435034ac4a4) +++ generic/nsfInt.h (.../nsfInt.h) (revision 2a2f104357f92c52f53b72025ae2183152644140) @@ -689,6 +689,7 @@ Tcl_Command wrapperCmd; NsfParamDefs *paramDefs; unsigned int flags; + Tcl_Interp *interp; } NsfProcClientData; typedef enum SystemMethodsIdx { Index: generic/nsfShadow.c =================================================================== diff -u -rae081c0f1926da915e0584d8561abaa8a2a022a4 -r2a2f104357f92c52f53b72025ae2183152644140 --- generic/nsfShadow.c (.../nsfShadow.c) (revision ae081c0f1926da915e0584d8561abaa8a2a022a4) +++ generic/nsfShadow.c (.../nsfShadow.c) (revision 2a2f104357f92c52f53b72025ae2183152644140) @@ -260,17 +260,51 @@ /* if an obj/cl should be renamed => call the Nsf move method */ cmd = Tcl_FindCommand(interp, ObjStr(objv[1]), (Tcl_Namespace *)NULL, 0); if (cmd != NULL) { + Tcl_ObjCmdProc *proc = Tcl_Command_objProc(cmd); + ClientData clientData = Tcl_Command_objClientData(cmd); NsfObject *object = NsfGetObjectFromCmdPtr(cmd); - Tcl_Obj *methodObj = (object != NULL) ? NsfMethodObj(object, NSF_o_move_idx) : NULL; Tcl_Command parentCmd; + char *newName = ObjStr(objv[2]); + + + if (proc == NsfProcStub && clientData != NULL && + *newName != '\0') { + Tcl_DString fqNewName; + int result; + NsfProcClientData *tcd = clientData; - if (object && methodObj) { - return NsfCallMethodWithArgs(interp, (Nsf_Object *)object, - methodObj, objv[2], 1, 0, NSF_CSC_IMMEDIATE); + Tcl_DStringInit(&fqNewName); + Tcl_DStringAppend(&fqNewName, "::nsf::procs::", 14); + Tcl_DStringAppend(&fqNewName, newName, -1); + + /* fprintf(stderr, "oldName %s newName %s\n", ObjStr(tcd->procName), Tcl_DStringValue(&fqNewName));*/ + result = TclRenameCommand(interp, ObjStr(tcd->procName), Tcl_DStringValue(&fqNewName)); + + if (result == TCL_OK) { + DECR_REF_COUNT2("procNameObj", tcd->procName); + tcd->procName = Tcl_NewStringObj(Tcl_DStringValue(&fqNewName), + Tcl_DStringLength(&fqNewName)); + INCR_REF_COUNT2("procNameObj", tcd->procName); + } + + Tcl_DStringFree(&fqNewName); + + if (result != TCL_OK) { + return TCL_ERROR; + } + + } else if (object != NULL) { + Tcl_Obj *methodObj = NsfMethodObj(object, NSF_o_move_idx); + + if (methodObj) { + return NsfCallMethodWithArgs(interp, (Nsf_Object *)object, + methodObj, objv[2], 1, 0, + NSF_CSC_IMMEDIATE); + } } parentCmd = Tcl_FindCommand(interp, Tcl_Command_nsPtr(cmd)->fullName, - (Tcl_Namespace *)NULL, 0); + (Tcl_Namespace *)NULL, 0); if (parentCmd != NULL) { NsfObjectMethodEpochIncr("::rename"); } Index: tests/nsf-cmd.test =================================================================== diff -u -red5cc784dfa9e971fd124701a7bdfb9d609512a5 -r2a2f104357f92c52f53b72025ae2183152644140 --- tests/nsf-cmd.test (.../nsf-cmd.test) (revision ed5cc784dfa9e971fd124701a7bdfb9d609512a5) +++ tests/nsf-cmd.test (.../nsf-cmd.test) (revision 2a2f104357f92c52f53b72025ae2183152644140) @@ -513,9 +513,68 @@ # to-dos: # - basic rename-delete -# - rename chain -# - interp hide/expose +nx::test case nsf-proc-rename-delete { + namespace eval ::ns1 {} + ? {info commands ::ns1::foo} "" + ? {info commands ::nsf::procs::ns1::foo} "" + ? {info procs ::ns1::foo} "" + ? {info procs ::nsf::procs::ns1::foo} "" + + ? {::ns1::foo -x ok} {invalid command name "::ns1::foo"} + + nsf::proc ::ns1::foo { + {-x:required} + } { return 1-$x } + ? {info commands ::ns1::foo} "::ns1::foo" + ? {info commands ::nsf::procs::ns1::foo} "::nsf::procs::ns1::foo" + ? {info procs ::ns1::foo} "" + ? {info procs ::nsf::procs::ns1::foo} "::nsf::procs::ns1::foo" + + ? {::ns1::foo -x ok} "1-ok" + + rename ::ns1::foo "" + + ? {info commands ::ns1::foo} "" + ? {info commands ::nsf::procs::ns1::foo} "" + ? {info procs ::ns1::foo} "" + ? {info procs ::nsf::procs::ns1::foo} "" + + ? {::ns1::foo -x ok} {invalid command name "::ns1::foo"} + + namespace eval ::ns1 {} +} + +nx::test case nsf-proc-ns-delete { + namespace eval ::ns1 {} + ? {info commands ::ns1::foo} "" + ? {info commands ::nsf::procs::ns1::foo} "" + ? {info procs ::ns1::foo} "" + ? {info procs ::nsf::procs::ns1::foo} "" + + ? {::ns1::foo -x ok} {invalid command name "::ns1::foo"} + + nsf::proc ::ns1::foo { + {-x:required} + } { return 1-$x } + ? {info commands ::ns1::foo} "::ns1::foo" + ? {info commands ::nsf::procs::ns1::foo} "::nsf::procs::ns1::foo" + ? {info procs ::ns1::foo} "" + ? {info procs ::nsf::procs::ns1::foo} "::nsf::procs::ns1::foo" + + ? {::ns1::foo -x ok} "1-ok" + + namespace delete ::ns1 + + ? {info commands ::ns1::foo} "" + ? {info commands ::nsf::procs::ns1::foo} "" + ? {info procs ::ns1::foo} "" + ? {info procs ::nsf::procs::ns1::foo} "" + + ? {::ns1::foo -x ok} {invalid command name "::ns1::foo"} + +} + nx::test case nsf-proc-rename-redefine { namespace eval ::ns1 {} @@ -553,13 +612,46 @@ ? {ns1::foo -x ok} 2-ok - ? {ns1::foo.orig -x ok} 2-ok; # should be 1-ok! + ? {ns1::foo.orig -x ok} 1-ok; namespace delete ::ns1 } +nx::test case nsf-proc-rename-delete { + namespace eval ::ns1 {} + ? {info commands ::ns1::foo} "" + ? {info commands ::nsf::procs::ns1::foo} "" + ? {info procs ::ns1::foo} "" + ? {info procs ::nsf::procs::ns1::foo} "" + ? {::ns1::foo -x ok} {invalid command name "::ns1::foo"} + + nsf::proc ::ns1::foo { + {-x:required} + } { return 1-$x } + ? {info commands ::ns1::foo} "::ns1::foo" + ? {info commands ::nsf::procs::ns1::foo} "::nsf::procs::ns1::foo" + ? {info procs ::ns1::foo} "" + ? {info procs ::nsf::procs::ns1::foo} "::nsf::procs::ns1::foo" + ? {::ns1::foo -x ok} "1-ok" + + rename [set x ::nsf::procs::ns1::foo] "" + + ? {info commands ::ns1::foo} "::ns1::foo" + ? {info commands ::nsf::procs::ns1::foo} "" + ? {info procs ::ns1::foo} "" + ? {info procs ::nsf::procs::ns1::foo} "" + + ? {::ns1::foo -x ok} {invalid command name "::ns1::foo"} + + namespace eval ::ns1 {} +} + + +# - to-do interp hide/expose + + # # Local variables: # mode: tcl