Index: TODO =================================================================== diff -u -rcacb1074477ab383bffc999a68e741ef11211de3 -rf7bd273b3e8b6929dcb662c66a8e870d467190da --- TODO (.../TODO) (revision cacb1074477ab383bffc999a68e741ef11211de3) +++ TODO (.../TODO) (revision f7bd273b3e8b6929dcb662c66a8e870d467190da) @@ -2113,9 +2113,16 @@ - remove colon from method name in error message "unable to dispatch method ...." - extended regression test +- nsf.c: code cleanup and documentation improvements +- made assertion code optional +- added and renamed additions compile flags + NSF_WITH_INHERIT_NAMESPACES + NSF_WITH_OS_RESOLVER + NSF_WITH_ASSERTIONS + TODO: -- info method definition for attributes? +- "info method definition" for attributes? - check performance implications of value conflict checker Index: generic/nsf.c =================================================================== diff -u -r25595287e7df9f5c3715beb72a14a698e46842a4 -rf7bd273b3e8b6929dcb662c66a8e870d467190da --- generic/nsf.c (.../nsf.c) (revision 25595287e7df9f5c3715beb72a14a698e46842a4) +++ generic/nsf.c (.../nsf.c) (revision f7bd273b3e8b6929dcb662c66a8e870d467190da) @@ -2750,8 +2750,8 @@ *cmdPtr = RUNTIME_STATE(interp)->colonCmd; return TCL_OK; } else { - //xxxxx -#if 1 + +#if defined(NSF_WITH_OS_RESOLVER) /* * Experimental Object-System specific resolver: If an * unprefixed method name is found in a body of a method, we try @@ -2776,7 +2776,6 @@ object = NULL; } if (object) { - //xxx osPtr = GetObjectSystem(object); cmd = osPtr->rootClass->object.id; cmdTablePtr = Tcl_Namespace_cmdTablePtr(((Command *)cmd)->nsPtr); @@ -2834,7 +2833,7 @@ Tcl_SetNamespaceResolvers(nsPtr, /*(Tcl_ResolveCmdProc*)NsColonCmdResolver*/ NULL, NsColonVarResolver, /*(Tcl_ResolveCompiledVarProc*)NsCompiledColonVarResolver*/NULL); -#if defined(INHERIT_NAMESPACES_TO_CHILD_OBJECTS) +#if defined(NSF_WITH_INHERIT_NAMESPACES) /* * In case there is a namespace path set for the parent namespace, * apply this as well to the object namespace to avoid surprises @@ -4010,6 +4009,40 @@ return NULL; } +/* + *---------------------------------------------------------------------- + * CheckConditionInScope -- + * + * Check a given condition in the current callframe's scope. It is + * the responsiblity of the caller to push the intended callframe. + * + * Results: + * Tcl result code. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ +static int +CheckConditionInScope(Tcl_Interp *interp, Tcl_Obj *condition) { + int result, success; + Tcl_Obj *ov[2] = {NULL, condition}; + + INCR_REF_COUNT(condition); + result = Nsf_ExprObjCmd(NULL, interp, 2, ov); + DECR_REF_COUNT(condition); + + if (result == TCL_OK) { + result = Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp), &success); + + if (result == TCL_OK && success == 0) + result = NSF_CHECK_FAILED; + } + return result; +} + +#if defined(NSF_WITH_ASSERTIONS) /********************************************************************* * Assertions **********************************************************************/ @@ -4063,8 +4096,6 @@ return listObj; } - - /* append a string of pre and post assertions to a method body */ static void AssertionAppendPrePost(Tcl_Interp *interp, Tcl_DString *dsPtr, NsfProcAssertion *procs) { @@ -4165,29 +4196,7 @@ } } -/* - * check a given condition in the current callframe's scope - * it's the responsiblity of the caller to push the intended callframe - */ static int -CheckConditionInScope(Tcl_Interp *interp, Tcl_Obj *condition) { - int result, success; - Tcl_Obj *ov[2] = {NULL, condition}; - - INCR_REF_COUNT(condition); - result = Nsf_ExprObjCmd(NULL, interp, 2, ov); - DECR_REF_COUNT(condition); - - if (result == TCL_OK) { - result = Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp), &success); - - if (result == TCL_OK && success == 0) - result = NSF_CHECK_FAILED; - } - return result; -} - -static int AssertionCheckList(Tcl_Interp *interp, NsfObject *object, NsfTclObjList *alist, CONST char *methodName) { NsfTclObjList *checkFailed = NULL; @@ -4390,11 +4399,11 @@ (*assertions)->invariants = AssertionNewList(interp, arg); } +#endif /* NSF_WITH_ASSERTIONS */ - /* * Per-Object-Mixins */ @@ -6924,15 +6933,17 @@ ParseContext *pcPtr = data[0]; NsfCallStackContent *cscPtr = data[1]; /*CONST char *methodName = data[2];*/ +#if defined(NSF_WITH_ASSERTIONS) NsfObject *object = cscPtr->self; NsfObjectOpt *opt = object->opt; - int rc; - +#endif /*fprintf(stderr, "ProcMethodDispatchFinalize %s.%s flags %.6x isNRE %d\n", ObjectName(object), methodName cscPtr->flags, (cscPtr->flags & NSF_CSC_CALL_IS_NRE));*/ +#if defined(NSF_WITH_ASSERTIONS) if (opt && object->teardown && (opt->checkoptions & CHECK_POST)) { + int rc; /* * Even, when the returned result != TCL_OK, run assertion to report * the highest possible method from the callstack (e.g. "set" would not @@ -6943,6 +6954,7 @@ result = rc; } } +#endif if ((cscPtr->flags & NSF_CSC_CALL_IS_NRE)) { if (pcPtr) { @@ -6978,7 +6990,9 @@ CONST char *methodName, NsfObject *object, NsfClass *cl, Tcl_Command cmdPtr, NsfCallStackContent *cscPtr) { int result, releasePc = 0; +#if defined(NSF_WITH_ASSERTIONS) NsfObjectOpt *opt = object->opt; +#endif NsfParamDefs *paramDefs; #if defined(NRE) ParseContext *pcPtr = NULL; @@ -7046,10 +7060,12 @@ } } +#if defined(NSF_WITH_ASSERTIONS) if (opt && (opt->checkoptions & CHECK_PRE) && (result = AssertionCheck(interp, object, cl, methodName, CHECK_PRE)) == TCL_ERROR) { goto prep_done; } +#endif /* * If the method to be invoked has paramDefs, we have to call the @@ -7093,7 +7109,9 @@ } */ +#if defined(NSF_WITH_ASSERTIONS) prep_done: +#endif if (result == TCL_OK) { #if defined(NRE) @@ -7142,7 +7160,9 @@ CONST char *methodName, NsfObject *object, Tcl_Command cmdPtr, NsfCallStackContent *cscPtr) { CallFrame frame, *framePtr = &frame; +#if defined(NSF_WITH_ASSERTIONS) CheckOptions co; +#endif int result; assert(object); @@ -7168,17 +7188,19 @@ Nsf_PopFrameCsc(interp, framePtr); } - /* - * Reference counting in the calling ObjectDispatch() makes sure - * that obj->opt is still accessible even after "dealloc" - */ +#if defined(NSF_WITH_ASSERTIONS) if (object->opt) { co = object->opt->checkoptions; if ((co & CHECK_INVAR)) { result = AssertionCheckInvars(interp, object, methodName, co); } } +#endif + /* + * Reference counting in the calling ObjectDispatch() makes sure + * that obj->opt is still accessible even after "dealloc" + */ return result; } @@ -8887,9 +8909,11 @@ } Tcl_PopCallFrame(interp); +#if defined(NSF_WITH_ASSERTIONS) if (result == TCL_OK && (precondition || postcondition)) { AssertionAddProc(interp, methodName, aStore, precondition, postcondition); } +#endif if (parsedParam.paramDefs) { DECR_REF_COUNT(ov[2]); @@ -8919,6 +8943,7 @@ NsfRemoveClassMethod(interp, (Nsf_Class *)cl, nameStr) : NsfRemoveObjectMethod(interp, (Nsf_Object *)object, nameStr); } else { +#if defined(NSF_WITH_ASSERTIONS) NsfAssertionStore *aStore = NULL; if (precondition || postcondition) { if (cl) { @@ -8936,6 +8961,11 @@ result = MakeProc(cl ? cl->nsPtr : object->nsPtr, aStore, interp, nameObj, args, body, precondition, postcondition, object, withPublic, cl == NULL, clsns); +#else + result = MakeProc(cl ? cl->nsPtr : object->nsPtr, NULL, + interp, nameObj, args, body, NULL, NULL, + object, withPublic, cl == NULL, clsns); +#endif } if (cl) { @@ -9943,8 +9973,10 @@ if (object->opt) { NsfObjectOpt *opt = object->opt; +#if defined(NSF_WITH_ASSERTIONS) AssertionRemoveStore(opt->assertions); opt->assertions = NULL; +#endif if (!softrecreate) { /* @@ -10365,8 +10397,12 @@ * Remove dependent filters of this class from all subclasses */ FilterRemoveDependentFilterCmds(cl, cl); + +#if defined(NSF_WITH_ASSERTIONS) AssertionRemoveStore(clopt->assertions); clopt->assertions = NULL; +#endif + #ifdef NSF_OBJECTDATA NsfFreeObjectData(cl); #endif @@ -11043,8 +11079,11 @@ AliasDelete(interp, object->cmdName, methodName, 1); - if (object->opt) +#if defined(NSF_WITH_ASSERTIONS) + if (object->opt) { AssertionRemoveProc(object->opt->assertions, methodName); + } +#endif if (object->nsPtr) { int rc = NSDeleteCmd(interp, object->nsPtr, methodName); @@ -11058,13 +11097,18 @@ extern int NsfRemoveClassMethod(Tcl_Interp *interp, Nsf_Class *class, CONST char *methodName) { NsfClass *cl = (NsfClass*) class; - NsfClassOpt *opt = cl->opt; int rc; +#if defined(NSF_WITH_ASSERTIONS) + NsfClassOpt *opt = cl->opt; +#endif AliasDelete(interp, class->object.cmdName, methodName, 0); - if (opt && opt->assertions) +#if defined(NSF_WITH_ASSERTIONS) + if (opt && opt->assertions) { AssertionRemoveProc(opt->assertions, methodName); + } +#endif rc = NSDeleteCmd(interp, cl->nsPtr, methodName); if (rc < 0) { @@ -12575,6 +12619,7 @@ } case InfomethodsubcmdPreconditionIdx: { +#if defined(NSF_WITH_ASSERTIONS) NsfProcAssertion *procs; if (withPer_object) { procs = regObject->opt ? AssertionFindProcs(regObject->opt->assertions, methodName) : NULL; @@ -12583,10 +12628,12 @@ procs = class->opt ? AssertionFindProcs(class->opt->assertions, methodName) : NULL; } if (procs) Tcl_SetObjResult(interp, AssertionList(interp, procs->pre)); +#endif return TCL_OK; } case InfomethodsubcmdPostconditionIdx: { +#if defined(NSF_WITH_ASSERTIONS) NsfProcAssertion *procs; if (withPer_object) { procs = regObject->opt ? AssertionFindProcs(regObject->opt->assertions, methodName) : NULL; @@ -12595,6 +12642,7 @@ procs = class->opt ? AssertionFindProcs(class->opt->assertions, methodName) : NULL; } if (procs) Tcl_SetObjResult(interp, AssertionList(interp, procs->post)); +#endif return TCL_OK; } case InfomethodsubcmdSubmethodsIdx: @@ -12649,6 +12697,7 @@ NsfClass *class = (NsfClass *)regObject; assertions = class->opt ? class->opt->assertions : NULL; } +#if defined(NSF_WITH_ASSERTIONS) if (assertions) { NsfProcAssertion *procs = AssertionFindProcs(assertions, methodName); if (procs) { @@ -12658,6 +12707,7 @@ Tcl_ListObjAppendElement(interp, resultObj, AssertionList(interp, procs->post)); } } +#endif Tcl_SetObjResult(interp, resultObj); break; } @@ -13451,6 +13501,7 @@ static int NsfAssertionCmd(Tcl_Interp *interp, NsfObject *object, int subcmd, Tcl_Obj *arg) { +#if defined(NSF_WITH_ASSERTIONS) NsfClass *class; switch (subcmd) { @@ -13484,6 +13535,7 @@ } } } +#endif return TCL_OK; } @@ -14425,29 +14477,37 @@ if (cl) { /* Next Scripting class-methods */ +#if defined(NSF_WITH_ASSERTIONS) NsfProcAssertion *procs; procs = cl->opt ? AssertionFindProcs(cl->opt->assertions, name) : NULL; +#endif DSTRING_INIT(dsPtr); Tcl_DStringAppendElement(dsPtr, "::nsf::method"); Tcl_DStringAppendElement(dsPtr, NSCutNsfClasses(toNsPtr->fullName)); Tcl_DStringAppendElement(dsPtr, name); Tcl_DStringAppendElement(dsPtr, ObjStr(arglistObj)); Tcl_DStringAppendElement(dsPtr, StripBodyPrefix(ObjStr(procPtr->bodyPtr))); +#if defined(NSF_WITH_ASSERTIONS) if (procs) { NsfRequireClassOpt(cl); AssertionAppendPrePost(interp, dsPtr, procs); } +#endif Tcl_EvalEx(interp, Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr), 0); DSTRING_FREE(dsPtr); } else { /* Next Scripting object-methods */ NsfObject *object = GetObjectFromString(interp, fromNsPtr->fullName); +#if defined(NSF_WITH_ASSERTIONS) NsfProcAssertion *procs; +#endif if (object) { +#if defined(NSF_WITH_ASSERTIONS) procs = object->opt ? AssertionFindProcs(object->opt->assertions, name) : NULL; +#endif } else { DECR_REF_COUNT(newFullCmdName); DECR_REF_COUNT(oldFullCmdName); @@ -14462,10 +14522,12 @@ Tcl_DStringAppendElement(dsPtr, name); Tcl_DStringAppendElement(dsPtr, ObjStr(arglistObj)); Tcl_DStringAppendElement(dsPtr, StripBodyPrefix(ObjStr(procPtr->bodyPtr))); +#if defined(NSF_WITH_ASSERTIONS) if (procs) { NsfRequireObjectOpt(object); AssertionAppendPrePost(interp, dsPtr, procs); } +#endif Tcl_EvalEx(interp, Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr), 0); DSTRING_FREE(dsPtr); } Index: generic/nsf.h =================================================================== diff -u -r89a3543bad5e98ba6af74f38567d831ddbc11f6f -rf7bd273b3e8b6929dcb662c66a8e870d467190da --- generic/nsf.h (.../nsf.h) (revision 89a3543bad5e98ba6af74f38567d831ddbc11f6f) +++ generic/nsf.h (.../nsf.h) (revision f7bd273b3e8b6929dcb662c66a8e870d467190da) @@ -77,16 +77,19 @@ /* are we developing? #define NSF_DEVELOPMENT 1 */ -#define NSF_DEVELOPMENT 1 /* activate/deacticate assert #define NDEBUG 1 */ -/* additional features -#define INHERIT_NAMESPACES_TO_CHILD_OBJECTS 1 +/* additional language features +#define NSF_WITH_INHERIT_NAMESPACES 1 */ +#define NSF_WITH_OS_RESOLVER 1 +#define NSF_WITH_ASSERTIONS 1 + + /* activate/deacticate memory tracing #define NSF_MEM_TRACE 1 #define NSF_MEM_COUNT 1 Index: generic/nsfInt.h =================================================================== diff -u -r3d4cb79342d1f74cdcc39d6d8b87e9c475f2706a -rf7bd273b3e8b6929dcb662c66a8e870d467190da --- generic/nsfInt.h (.../nsfInt.h) (revision 3d4cb79342d1f74cdcc39d6d8b87e9c475f2706a) +++ generic/nsfInt.h (.../nsfInt.h) (revision f7bd273b3e8b6929dcb662c66a8e870d467190da) @@ -260,15 +260,16 @@ struct NsfFilterStack *nextPtr; } NsfFilterStack; -typedef struct NsfTclObjList { - Tcl_Obj *content; - struct NsfTclObjList *nextPtr; -} NsfTclObjList; /* * Assertion structures */ +typedef struct NsfTclObjList { + Tcl_Obj *content; + struct NsfTclObjList *nextPtr; +} NsfTclObjList; + typedef struct NsfProcAssertion { NsfTclObjList *pre; NsfTclObjList *post;