Index: TODO =================================================================== diff -u -r2161e45d79dd066d33b750bf462f0024331ae02c -r9318621f9cf5544818fbb03209814fdfc8d2156c --- TODO (.../TODO) (revision 2161e45d79dd066d33b750bf462f0024331ae02c) +++ TODO (.../TODO) (revision 9318621f9cf5544818fbb03209814fdfc8d2156c) @@ -3353,7 +3353,10 @@ * deacivated a few tests in interp.test for the time being (runs commands after finalize) * re-established assertion checking for deleted cmds in cmd lists + * added flag "-keepvars" to nsf::finalize for handling cases in interp.test + * reactivated tests and simplified in interp.test + TODO: - private: * make it mutual exclusive with protected. Index: generic/nsf.c =================================================================== diff -u -r2161e45d79dd066d33b750bf462f0024331ae02c -r9318621f9cf5544818fbb03209814fdfc8d2156c --- generic/nsf.c (.../nsf.c) (revision 2161e45d79dd066d33b750bf462f0024331ae02c) +++ generic/nsf.c (.../nsf.c) (revision 9318621f9cf5544818fbb03209814fdfc8d2156c) @@ -307,7 +307,7 @@ static void DeleteNsfProcs(Tcl_Interp *interp, Tcl_Namespace *nsPtr); #ifdef DO_FULL_CLEANUP -static void DeleteProcsAndVars(Tcl_Interp *interp, Tcl_Namespace *nsPtr); +static void DeleteProcsAndVars(Tcl_Interp *interp, Tcl_Namespace *nsPtr, int withKeepvars); #endif /* @@ -2544,7 +2544,7 @@ *---------------------------------------------------------------------- */ static int -ObjectSystemsCleanup(Tcl_Interp *interp) { +ObjectSystemsCleanup(Tcl_Interp *interp, int withKeepvars) { Tcl_HashTable objTable, *commandNameTable = &objTable; Tcl_HashSearch hSrch; Tcl_HashEntry *hPtr; @@ -2634,7 +2634,7 @@ FreeAllNsfObjectsAndClasses(interp, commandNameTable); # ifdef DO_FULL_CLEANUP - DeleteProcsAndVars(interp, Tcl_GetGlobalNamespace(interp)); + DeleteProcsAndVars(interp, Tcl_GetGlobalNamespace(interp), withKeepvars); # endif #endif @@ -10523,7 +10523,7 @@ */ *outObjPtr = Tcl_GetObjResult(interp); INCR_REF_COUNT2("valueObj", *outObjPtr); - //fprintf(stderr, "**** NSF_ARG_IS_CONVERTER\n"); ///yyyy; + /*fprintf(stderr, "**** NSF_ARG_IS_CONVERTER\n");*/ } *clientData = (ClientData) *outObjPtr; @@ -15234,7 +15234,6 @@ if (doCheck == 0 && (pPtr->flags & (NSF_ARG_IS_CONVERTER|NSF_ARG_INITCMD)) == 0) { /*fprintf(stderr, "*** omit argument check for arg %s flags %.6x\n", pPtr->name, pPtr->flags);*/ *clientData = ObjStr(objPtr); - //*flags = 0; //yyyy; return TCL_OK; } @@ -15302,7 +15301,7 @@ pPtr->name, pPtr->type, pPtr->flags & NSF_ARG_IS_CONVERTER, pPtr->flags, objPtr != *outObjPtr, objPtr, *outObjPtr, result == TCL_OK);*/ if ((pPtr->flags & NSF_ARG_IS_CONVERTER) && objPtr != *outObjPtr) { - *flags |= NSF_PC_MUST_DECR;//yyyy + *flags |= NSF_PC_MUST_DECR; } else { /* * If the output obj differs from the input obj, ensure we have @@ -17306,11 +17305,12 @@ } /* -cmd finalize NsfFinalizeObjCmd { +cmd finalize NsfFinalizeCmd { + {-argName "-keepvars" -required 0 -nrargs 0} } */ static int -NsfFinalizeObjCmd(Tcl_Interp *interp) { +NsfFinalizeCmd(Tcl_Interp *interp, int withKeepvars) { int result; /*fprintf(stderr, "+++ call tcl-defined exit handler\n"); */ @@ -17326,7 +17326,7 @@ Tcl_GetErrorLine(interp), ObjStr(Tcl_GetObjResult(interp))); } - ObjectSystemsCleanup(interp); + ObjectSystemsCleanup(interp, withKeepvars); #ifdef DO_CLEANUP # if defined(CHECK_ACTIVATION_COUNTS) @@ -21981,7 +21981,7 @@ #ifdef DO_FULL_CLEANUP /* delete global variables and procs */ static void -DeleteProcsAndVars(Tcl_Interp *interp, Tcl_Namespace *nsPtr) { +DeleteProcsAndVars(Tcl_Interp *interp, Tcl_Namespace *nsPtr, int withKeepvars) { Tcl_HashTable *varTablePtr, *cmdTablePtr, *childTablePtr; Tcl_HashSearch search; Tcl_Command cmd; @@ -22003,18 +22003,21 @@ for (entryPtr = Tcl_FirstHashEntry(childTablePtr, &search); entryPtr; entryPtr = Tcl_NextHashEntry(&search)) { Tcl_Namespace *childNsPtr = (Tcl_Namespace *) Tcl_GetHashValue(entryPtr); - DeleteProcsAndVars(interp, childNsPtr); + DeleteProcsAndVars(interp, childNsPtr, withKeepvars); } - for (entryPtr = Tcl_FirstHashEntry(varTablePtr, &search); entryPtr; - entryPtr = Tcl_NextHashEntry(&search)) { - Tcl_Obj *nameObj; - GetVarAndNameFromHash(entryPtr, &varPtr, &nameObj); - if (!TclIsVarUndefined(varPtr) || TclIsVarNamespaceVar(varPtr)) { - /* fprintf(stderr, "unsetting var %s\n", ObjStr(nameObj));*/ - Tcl_UnsetVar2(interp, ObjStr(nameObj), (char *)NULL, TCL_GLOBAL_ONLY); + if (!withKeepvars) { + for (entryPtr = Tcl_FirstHashEntry(varTablePtr, &search); entryPtr; + entryPtr = Tcl_NextHashEntry(&search)) { + Tcl_Obj *nameObj; + GetVarAndNameFromHash(entryPtr, &varPtr, &nameObj); + if (!TclIsVarUndefined(varPtr) || TclIsVarNamespaceVar(varPtr)) { + /* fprintf(stderr, "unsetting var %s\n", ObjStr(nameObj));*/ + Tcl_UnsetVar2(interp, ObjStr(nameObj), (char *)NULL, TCL_GLOBAL_ONLY); + } } } + for (entryPtr = Tcl_FirstHashEntry(cmdTablePtr, &search); entryPtr; entryPtr = Tcl_NextHashEntry(&search)) { cmd = (Tcl_Command)Tcl_GetHashValue(entryPtr); @@ -22209,7 +22212,7 @@ NsfObject *object; int deleted = 0; - fprintf(stderr, "FreeAllNsfObjectsAndClasses in %p\n", interp); + /*fprintf(stderr, "FreeAllNsfObjectsAndClasses in %p\n", interp);*/ RUNTIME_STATE(interp)->exitHandlerDestroyRound = NSF_EXITHANDLER_ON_PHYSICAL_DESTROY; @@ -22405,7 +22408,7 @@ CallStackPopAll(interp); if (RUNTIME_STATE(interp)->exitHandlerDestroyRound == NSF_EXITHANDLER_OFF) { - NsfFinalizeObjCmd(interp); + NsfFinalizeCmd(interp, 0); } /* must be before freeing of NsfGlobalObjs */ Index: generic/nsfAPI.decls =================================================================== diff -u -r29ed0c8902296dbea451c12d031cc06b6126dd5b -r9318621f9cf5544818fbb03209814fdfc8d2156c --- generic/nsfAPI.decls (.../nsfAPI.decls) (revision 29ed0c8902296dbea451c12d031cc06b6126dd5b) +++ generic/nsfAPI.decls (.../nsfAPI.decls) (revision 9318621f9cf5544818fbb03209814fdfc8d2156c) @@ -30,7 +30,8 @@ cmd colon NsfColonCmd { {-argName "args" -type allargs} } -cmd finalize NsfFinalizeObjCmd { +cmd finalize NsfFinalizeCmd { + {-argName "-keepvars" -required 0 -nrargs 0} } cmd interp NsfInterpObjCmd { {-argName "name" -required 1} Index: generic/nsfAPI.h =================================================================== diff -u -r29ed0c8902296dbea451c12d031cc06b6126dd5b -r9318621f9cf5544818fbb03209814fdfc8d2156c --- generic/nsfAPI.h (.../nsfAPI.h) (revision 29ed0c8902296dbea451c12d031cc06b6126dd5b) +++ generic/nsfAPI.h (.../nsfAPI.h) (revision 9318621f9cf5544818fbb03209814fdfc8d2156c) @@ -237,7 +237,7 @@ static int NsfCurrentCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfDebugCompileEpochStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfDebugRunAssertionsCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); -static int NsfFinalizeObjCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); +static int NsfFinalizeCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfInterpObjCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); 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 []); @@ -333,7 +333,7 @@ static int NsfCurrentCmd(Tcl_Interp *interp, int currentoption); static int NsfDebugCompileEpoch(Tcl_Interp *interp); static int NsfDebugRunAssertionsCmd(Tcl_Interp *interp); -static int NsfFinalizeObjCmd(Tcl_Interp *interp); +static int NsfFinalizeCmd(Tcl_Interp *interp, int withKeepvars); static int NsfInterpObjCmd(Tcl_Interp *interp, CONST char *name, int objc, Tcl_Obj *CONST objv[]); static int NsfInvalidateObjectParameterCmd(Tcl_Interp *interp, NsfClass *class); static int NsfIsCmd(Tcl_Interp *interp, int withComplain, Tcl_Obj *constraint, Tcl_Obj *value); @@ -430,7 +430,7 @@ NsfCurrentCmdIdx, NsfDebugCompileEpochIdx, NsfDebugRunAssertionsCmdIdx, - NsfFinalizeObjCmdIdx, + NsfFinalizeCmdIdx, NsfInterpObjCmdIdx, NsfInvalidateObjectParameterCmdIdx, NsfIsCmdIdx, @@ -1068,19 +1068,22 @@ } static int -NsfFinalizeObjCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { +NsfFinalizeCmdStub(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[NsfFinalizeCmdIdx].paramDefs, + method_definitions[NsfFinalizeCmdIdx].nrParameters, 1, + &pc) != TCL_OK) { + return TCL_ERROR; + } else { + int withKeepvars = (int )PTR2INT(pc.clientData[0]); - if (objc != 1) { - return NsfArgumentError(interp, "too many arguments:", - method_definitions[NsfFinalizeObjCmdIdx].paramDefs, - NULL, objv[0]); - } - - return NsfFinalizeObjCmd(interp); + assert(pc.status == 0); + return NsfFinalizeCmd(interp, withKeepvars); + } } static int @@ -2453,8 +2456,8 @@ {"::nsf::__db_run_assertions", NsfDebugRunAssertionsCmdStub, 0, { {NULL, 0, 0, NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, -{"::nsf::finalize", NsfFinalizeObjCmdStub, 0, { - {NULL, 0, 0, NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} +{"::nsf::finalize", NsfFinalizeCmdStub, 1, { + {"-keepvars", 0, 0, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, {"::nsf::interp", NsfInterpObjCmdStub, 2, { {"name", NSF_ARG_REQUIRED, 1, Nsf_ConvertToString, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, Index: tests/interp.test =================================================================== diff -u -rcae9407ff24389d6f950a07279adb31750793e02 -r9318621f9cf5544818fbb03209814fdfc8d2156c --- tests/interp.test (.../interp.test) (revision cae9407ff24389d6f950a07279adb31750793e02) +++ tests/interp.test (.../interp.test) (revision 9318621f9cf5544818fbb03209814fdfc8d2156c) @@ -6,11 +6,11 @@ } nx::Test case hidden-cmds { + global i # # Create a slave interp for testing # - global i set i [interp create] # @@ -37,7 +37,7 @@ # sets a global variable for tracing the processing of the # app-level destructor! # - set ::[namespace tail [::nsf::current object]] [::nsf::current class] + set ::[namespace tail [current object]] [current class] next } }} @@ -47,7 +47,7 @@ # sets a global variable for tracing the processing of the # app-level destructor! # - set ::[namespace tail [::nsf::current object]] [::nsf::current class] + set ::[namespace tail [current object]] [current class] next } @@ -57,7 +57,7 @@ }} $i eval {nx::Class create ::M { :public method foo {} { - return [::nsf::current object]-[:info class]-[::nsf::current class] + return [current object]-[:info class]-[current class] } }} ? {$i eval {info commands ::o}} ::o @@ -129,49 +129,40 @@ # shutdown *after* the exit handler returned! # # For testing, we shutdown the NSF object systems in our slave - # interp by using ::nsf::finalize; to do some smoke testing of the + # interp by using nsf::finalize; to do some smoke testing of the # cleanup results. As for the cleanup procedre, this is equivalent # to: interp delete $i - $i eval {::nsf::finalize} + $i eval {nsf::finalize -keepvars} # The destructor of e.g. object o sets a global variable with the # object name. The following test checks therfore, whether the # destructor was executed. # - # However, as documented ::nsf::finalize has to be the final nsf cmd - # in an interp. The behavior after finalize is undefined and depends - # in the detail on several compiler flags. For example, when - # MEM_COUNT is activated, a full cleanup us performed by nsf, - # causing the deletion of all variables and cmds. This is necessary - # to ensure a defined situation of the refcounts when for debugging. - # Therefore the following cmds will fail - for the time being - # deactivated. - # - if {0} { - ? {$i eval { info exists ::o }} 1 + + ? {$i eval { info exists ::o }} 1 + ? {$i eval {interp hidden}} foo + ? {$i eval {info commands ::o}} "" + ? {$i eval {info commands ::C}} "" - ? {$i eval {interp hidden}} foo - ? {$i eval {info commands ::o}} "" - ? {$i eval {info commands ::C}} "" - - # - # Were the app-level destructors called effectively? - # - ? {$i eval { info exists ::o }} 1 - ? {$i eval { set ::o }} "" - ? {$i eval { info exists ::c }} 1 - ? {$i eval { set ::c }} ::C - } + # + # Were the app-level destructors called effectively? + # + ? {$i eval { info exists ::o }} 1 + ? {$i eval { set ::o }} "" + ? {$i eval { info exists ::c }} 1 + ? {$i eval { set ::c }} ::C + interp delete $i } +# +# Explicit destruction +# nx::Test case hidden-cmds+explicit-delete { + global i - # - # 2) Explicit destruction - # set i [interp create] $i eval { package req nx @@ -181,38 +172,34 @@ return ok } }} + + + ? {$i eval {interp hidden}} "" + ? {$i eval {info commands ::o2}} ::o2 + ? {$i eval {nx::Object info instances ::o2}} ::o2 + ? {$i eval {nsf::object::exists ::o2}} 1 - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o2] \ - [nx::Object info instances ::o2] \ - [::nsf::object::exists ::o2] - }] {{} ::o2 ::o2 1} - $i hide o2 - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o2] \ - [nx::Object info instances ::o2] \ - [::nsf::object::exists ::o2] - }] {o2 {} ::o2 0} + ? {$i eval {interp hidden}} o2 + ? {$i eval {info commands ::o2}} "" + ? {$i eval {nx::Object info instances ::o2}} ::o2 + ? {$i eval {nsf::object::exists ::o2}} 0 - ? [list interp invokehidden $i o2 destroy] "ok" - - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o2] \ - [nx::Object info instances ::o2] \ - [::nsf::object::exists ::o2] - }] {{} {} {} 0} + ? {interp invokehidden $i o2 destroy} "ok" + ? {$i eval {interp hidden}} "" + ? {$i eval {info commands ::o2}} "" + ? {$i eval {nx::Object info instances ::o2}} "" + ? {$i eval {nsf::object::exists ::o2}} 0 } + +# +# hide and re-expose +# nx::Test case hide-and-re-expose { - # - # 3) hide and re-expose - # + global i set i [interp create] $i eval { @@ -229,46 +216,44 @@ interp hide {} o } - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o] \ - [nx::Object info instances ::o] \ - [::nsf::object::exists ::o] - }] {o {} ::o 0} "Check hidden state" + # Check hidden state + ? {interp eval $i {interp hidden}} "o" + ? {interp eval $i {info commands ::o}} "" + ? {interp eval $i {nx::Object info instances ::o}} ::o + ? {interp eval $i {nsf::object::exists ::o}} 0 interp expose $i o - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o] \ - [nx::Object info instances ::o] \ - [::nsf::object::exists ::o] - }] {{} ::o ::o 1} "Check re-exposed state" - + + # Check re-exposed state + ? {interp eval $i {interp hidden}} "" + ? {interp eval $i {info commands ::o}} "::o" + ? {interp eval $i {nx::Object info instances ::o}} ::o + ? {interp eval $i {nsf::object::exists ::o}} 1 + # # Is the object "alive"? # - ? [list $i eval {::o foo}] {::o {} ::nx::Object ::nx::Object} + ? {$i eval {::o foo}} {::o {} ::nx::Object ::nx::Object} - $i eval {::nsf::finalize} + $i eval {nsf::finalize -keepvars} - # deactivated, SEE above - if {0} { - # Was the destructor called? - ? [list interp eval $i {info exists ::o}] 1 - ? [list interp eval $i {set ::o}] 1 - - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o] - }] {{} {}} "Check cleaned-up state" - } + # Was the destructor called? + ? {interp eval $i {info exists ::o}} 1 + ? {interp eval $i {set ::o}} 1 + + # Check cleaned-up state + ? {interp eval $i {interp hidden}} "" + ? {interp eval $i {info commands ::o}} "" + interp delete $i } +# +# hide/re-expose with "command renaming" +# nx::Test case command-renaming { + global i - # 4) hide/re-expose with "command renaming" - set i [interp create] $i eval { package req nx @@ -285,50 +270,48 @@ interp hide {} o O } - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o] \ - [nx::Object info instances ::o] \ - [::nsf::object::exists ::o] - }] {O {} ::o 0} "Check hidden state -> object command renamed" + # Check hidden state -> object command renamed - ? [list interp invokehidden $i O foo] {::o {} ::nx::Object {invalid command name "::o"}} + ? {interp eval $i {interp hidden}} "O" + ? {interp eval $i {info commands ::o}} "" + ? {interp eval $i {nx::Object info instances ::o}} ::o + ? {interp eval $i {nsf::object::exists ::o}} 0 + ? {interp invokehidden $i O foo} \ + {::o {} ::nx::Object {invalid command name "::o"}} + interp expose $i O OO - ? [list interp eval $i {OO foo}] {::o {} ::nx::Object {invalid command name "::o"}} + ? {interp eval $i {OO foo}} \ + {::o {} ::nx::Object {invalid command name "::o"}} - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o] \ - [info commands ::OO] \ - [nx::Object info instances ::o] \ - [nx::Object info instances ::OO] \ - [::nsf::object::exists ::o] \ - [::nsf::object::exists ::OO] - }] {{} {} ::OO ::o ::o 0 1} "Check re-exposed state -> object command renamed again"; # should be {} {} ::OO ::o {} 0 1 + ? {interp eval $i {interp hidden}} "" + ? {interp eval $i {info commands ::o}} "" + ? {interp eval $i {info commands ::OO}} ::OO + ? {interp eval $i {nx::Object info instances ::o}} ::o + ? {interp eval $i {nx::Object info instances ::OO}} ::o ;# should be ""? + ? {interp eval $i {nsf::object::exists ::o}} 0 + ? {interp eval $i {nsf::object::exists ::OO}} 1 + + $i eval {nsf::finalize -keepvars} - $i eval {::nsf::finalize} - - # deactivated, SEE above - if {0} { - # Was the destructor called? - ? [list interp eval $i {info exists ::o}] 1 - ? [list interp eval $i {set ::o}] 1 + # Was the destructor called? + ? {interp eval $i {info exists ::o}} 1 + ? {interp eval $i {set ::o}} 1 - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o] - }] {{} {}} "Check cleaned-up state" - } - interp delete $i + ? {interp eval $i {interp hidden}} {} + ? {interp eval $i {info commands ::o}} {} + interp delete $i } + +# +# Rename namespaced object to global one and hide ... +# nx::Test case namespaced-object { + global i - # 5) Rename namespaced object to global one and hide ... - set i [interp create] $i eval { package req nx @@ -342,36 +325,38 @@ } } - ? [list $i hide ::ns1::o] {cannot use namespace qualifiers in hidden command token (rename)} + ? {$i hide ::ns1::o} \ + {cannot use namespace qualifiers in hidden command token (rename)} + $i eval {::rename ::ns1::o ::X} - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::X] \ - [nx::Object info instances ::X] \ - [::nsf::object::exists ::X] - }] {{} ::X ::X 1} + + ? {interp eval $i {interp hidden}} {} + ? {interp eval $i {info commands ::X}} {::X} + ? {interp eval $i {nx::Object info instances ::X}} {::X} + ? {interp eval $i {nsf::object::exists ::X}} 1 + $i eval {interp hide {} X} - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::X] \ - [nx::Object info instances ::X] \ - [::nsf::object::exists ::X] - }] {X {} ::X 0} - $i eval {::nsf::finalize} - # deactivated, SEE above - if {0} { - ? [list interp eval $i {info exists ::X}] 1 - ? [list interp eval $i {set ::X}] 1 - } + + ? {interp eval $i {interp hidden}} "X" + ? {interp eval $i {info commands ::X}} {} + ? {interp eval $i {nx::Object info instances ::X}} {::X} + ? {interp eval $i {nsf::object::exists ::X}} 0 + + $i eval {nsf::finalize -keepvars} + + ? {interp eval $i {info exists ::X}} 1 + ? {interp eval $i {set ::X}} 1 + interp delete $i } +# +# Deletion order +# + nx::Test case deletion-order { + global i - # - # 6) Deletion order - # - set i [interp create] $i eval { package req nx @@ -393,19 +378,22 @@ } $i hide o $i hide C - $i eval {::nsf::finalize} - # deactivated, SEE above - if {0} { - ? [list interp eval $i {info exists ::C}] 1 - ? [list interp eval $i {set ::C}] 1 - ? [list interp eval $i {info exists ::o}] 1 - ? [list interp eval $i {set ::o}] 1 - } + $i eval {nsf::finalize -keepvars} + + ? {interp eval $i {info exists ::C}} 1 + ? {interp eval $i {set ::C}} 1 + ? {interp eval $i {info exists ::o}} 1 + ? {interp eval $i {set ::o}} 1 + interp delete $i } -nx::Test case error-in-destroy { - # 8a) Some stumbling blocks in destructors: [error] in app-level destroy +# +# Some stumbling blocks in destructors: [error] in app-level destroy +# +nx::Test case error-in-destroy-1 { + global i + set i [interp create] $i eval { package req nx @@ -417,23 +405,31 @@ interp hide {} o } - ? [list interp eval $i {::rename ::o ""}] {can't delete "::o": command doesn't exist} + ? {interp eval $i {::rename ::o ""}} \ + {can't delete "::o": command doesn't exist} - ? [list interp invokehidden $i o destroy] "BAFF!" - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o] \ - [nx::Object info instances ::o] \ - [::nsf::object::exists ::o] - }] {o {} ::o 0} - $i eval {::nsf::finalize} - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o] - }] {{} {}} + ? {interp invokehidden $i o destroy} "BAFF!" + + ? {interp eval $i {interp hidden}} "o" + ? {interp eval $i {info commands ::o}} "" + ? {interp eval $i {nx::Object info instances ::o}} "::o" + ? {interp eval $i {nsf::object::exists ::o}} 0 + + $i eval {nsf::finalize} + + ? {interp eval $i {interp hidden}} "" + ? {interp eval $i {info commands ::o}} "" + interp delete $i +} - # 3b) Some stumbling blocks in destructors: [interp hide] in app-level destroy +# +# Some stumbling blocks in destructors: [interp hide] in app-level +# destroy +# +nx::Test case error-in-destroy-2 { + global i + set i [interp create] $i eval { package req nx @@ -461,17 +457,23 @@ } } - ? [list interp eval $i {::bar}] 1 - ? [list interp eval $i {::o destroy}] OK - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o] \ - [nx::Object info instances ::o] \ - [::nsf::object::exists ::o] - }] {bar {} {} 0} + ? {interp eval $i {::bar}} 1 + ? {interp eval $i {::o destroy}} OK + + ? {interp eval $i {interp hidden}} "bar" + ? {interp eval $i {info commands ::o}} "" + ? {interp eval $i {nx::Object info instances ::o}} "" + ? {interp eval $i {nsf::object::exists ::o}} 0 + interp delete $i +} - # 3b) Some stumbling blocks in destructors: [interp hide] in app-level destroy +# +# Some stumbling blocks in destructors: [interp hide] in app-level destroy +# +nx::Test case error-in-destroy-3 { + global i + set i [interp create] $i eval { package req nx @@ -484,27 +486,29 @@ } interp hide {} o } - - # ? [list interp eval $i {::o destroy}] OK; weird error message when channeling back the error info! - ? [list interp invokehidden $i o destroy] {can't delete "::o": command doesn't exist}; - ? [list interp eval $i { - list [interp hidden] \ - [info commands ::o] \ - [nx::Object info instances ::o] \ - [::nsf::object::exists ::o] - }] {{} {} {} 0} + + ? {interp eval $i {::o destroy}} {invalid command name "::o"} + + ? {interp invokehidden $i o destroy} \ + {can't delete "::o": command doesn't exist} + + ? {interp eval $i {interp hidden}} "" + ? {interp eval $i {info commands ::o}} "" + ? {interp eval $i {nx::Object info instances ::o}} "" + ? {interp eval $i {nsf::object::exists ::o}} 0 + interp delete $i } # # TODO: -# - [::nsf::current calledclass] seems broken -> returns NULL as string value?! +# - [current calledclass] seems broken -> returns NULL as string value?! # - renames to "" in destroy run into an endless loop: # nx::Object create ::o { -# :public method destroy {} { -# ::rename [current] "" -# next -# } -# :destroy -# } +# :public method destroy {} { +# ::rename [current] "" +# next +# } +# :destroy +# } # # \ No newline at end of file