From 424814815e77f08b432a06e6ed8cb3d55d0c80e6 Mon Sep 17 00:00:00 2001 From: rfm Date: Mon, 8 Mar 2010 09:27:48 +0000 Subject: [PATCH] Improve debug git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29874 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 10 ++++ Documentation/Base.gsdoc | 7 +++ Headers/Additions/GNUstepBase/GSObjCRuntime.h | 4 ++ Source/Additions/GSObjCRuntime.m | 51 ++++++++++++++----- Source/NSObject.m | 5 +- 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a3f03f88..ef650cb37 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-03-08 Richard Frith-Macdonald + + * Source/NSObject.m: + * Source/Additions/GSObjCRuntime.m: + * Documentation/Base.gsdoc: + * Headers/Additions/GNUstepBase/GSObjCRuntime.h: + Add GNUSTEP_BEHAVIOR_DEBUG enovironment variable to turn on logging + of the use of behaviors/overrides of class methds by a list of + methods from another class. + 2010-03-08 Richard Frith-Macdonald * Source/GSArray.m: Re-remove [GSMutableArray count] (GSMutableArray diff --git a/Documentation/Base.gsdoc b/Documentation/Base.gsdoc index f180ad2ec..fabc89148 100644 --- a/Documentation/Base.gsdoc +++ b/Documentation/Base.gsdoc @@ -388,6 +388,13 @@ notice and this notice are preserved. or you want to use an alternative config file for some reason.

+ GNUSTEP_BEHAVIOR_DEBUG + + A boolean (YES or NO) which can be used to turn on debug + logging (to stderr) of the GSObjCRuntime functions to + add/override methods in a class using a list of methods + from another class. + HOMEDRIVE

diff --git a/Headers/Additions/GNUstepBase/GSObjCRuntime.h b/Headers/Additions/GNUstepBase/GSObjCRuntime.h index 7401b28e3..d76e404d8 100644 --- a/Headers/Additions/GNUstepBase/GSObjCRuntime.h +++ b/Headers/Additions/GNUstepBase/GSObjCRuntime.h @@ -176,6 +176,10 @@ GSObjCAddClassBehavior(Class receiver, Class behavior); GS_EXPORT void GSObjCAddClassOverride(Class receiver, Class override); +/** Turn on (YES), off (NO) or test (-1) behavior debugging. + */ +GS_EXPORT BOOL GSObjCBehaviorDebug(int setget); + GS_EXPORT NSValue * GSObjCMakeClass(NSString *name, NSString *superName, NSDictionary *iVars); diff --git a/Source/Additions/GSObjCRuntime.m b/Source/Additions/GSObjCRuntime.m index a33a99d0c..2f218a4dd 100644 --- a/Source/Additions/GSObjCRuntime.m +++ b/Source/Additions/GSObjCRuntime.m @@ -477,24 +477,36 @@ GSObjCAddClasses(NSArray *classes) -static int behavior_debug = 0; +static BOOL behavior_debug = NO; -void +BOOL GSObjCBehaviorDebug(int i) { - behavior_debug = i; + BOOL old = behavior_debug; + + if (i == YES) + { + behavior_debug = YES; + } + else if (i == NO) + { + behavior_debug = NO; + } + return old; } void GSObjCAddMethods(Class cls, Method *list, BOOL replace) { unsigned int index = 0; + char c; Method m; if (cls == 0 || list == 0) { return; } + c = class_isMetaClass(cls) ? '+' : '-'; while ((m = list[index++]) != NULL) { @@ -507,15 +519,19 @@ GSObjCAddMethods(Class cls, Method *list, BOOL replace) */ if (YES == class_addMethod(cls, n, i, t)) { - BDBGPrintf(" added %s\n", sel_getName(n)); + BDBGPrintf(" added %c%s\n", c, sel_getName(n)); } else if (YES == replace) { /* If we want to replace an existing implemetation ... */ method_setImplementation(class_getInstanceMethod(cls, n), i); - BDBGPrintf(" replaced %s\n", sel_getName(n)); + BDBGPrintf(" replaced %c%s\n", c, sel_getName(n)); } + else + { + BDBGPrintf(" skipped %c%s\n", c, sel_getName(n)); + } } } @@ -806,13 +822,13 @@ GSObjCAddClassBehavior(Class receiver, Class behavior) } BDBGPrintf("Adding behavior to class %s\n", class_getName(receiver)); - BDBGPrintf(" instance methods from %s\n", class_getName(behavior)); /* Add instance methods */ methods = class_copyMethodList(behavior, &count); + BDBGPrintf(" instance methods from %s %u\n", class_getName(behavior), count); if (methods == NULL) { - BDBGPrintf(" none.\n"); + BDBGPrintf(" none.\n"); } else { @@ -821,11 +837,11 @@ GSObjCAddClassBehavior(Class receiver, Class behavior) } /* Add class methods */ - BDBGPrintf(" class methods from %s\n", class_getName(behavior)); methods = class_copyMethodList(object_getClass(behavior), &count); + BDBGPrintf(" class methods from %s %u\n", class_getName(behavior), count); if (methods == NULL) { - BDBGPrintf(" none.\n"); + BDBGPrintf(" none.\n"); } else { @@ -868,21 +884,28 @@ GSObjCAddClassOverride(Class receiver, Class override) } BDBGPrintf("Adding override to class %s\n", class_getName(receiver)); - BDBGPrintf(" instance methods from %s\n", class_getName(override)); /* Add instance methods */ methods = class_copyMethodList(override, &count); - if (methods != NULL) + BDBGPrintf(" instance methods from %s %u\n", class_getName(override), count); + if (methods == NULL) + { + BDBGPrintf(" none.\n"); + } + else { GSObjCAddMethods (receiver, methods, YES); free(methods); } /* Add class methods */ - BDBGPrintf("Adding class methods from %s\n", - class_getName(object_getClass(override))); methods = class_copyMethodList(object_getClass(override), &count); - if (methods != NULL) + BDBGPrintf(" class methods from %s %u\n", class_getName(override), count); + if (methods == NULL) + { + BDBGPrintf(" none.\n"); + } + else { GSObjCAddMethods (object_getClass(receiver), methods, YES); free(methods); diff --git a/Source/NSObject.m b/Source/NSObject.m index e5118668a..0f906e471 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -995,7 +995,6 @@ objc_create_block_classes_as_subclasses_of(Class super) __attribute__((weak)); fedisableexcept(FE_INVALID); #endif - #ifdef HAVE_LOCALE_H GSSetLocaleC(LC_ALL, ""); // Set up locale from environment. #endif @@ -1003,6 +1002,10 @@ objc_create_block_classes_as_subclasses_of(Class super) __attribute__((weak)); // Create the global lock gnustep_global_lock = [NSRecursiveLock new]; + // Behavior debugging + GSObjCBehaviorDebug(GSPrivateEnvironmentFlag("GNUSTEP_BEHAVIOR_DEBUG", + GSObjCBehaviorDebug(-1))); + // Zombie management stuff. zombieMap = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, NSNonOwnedPointerMapValueCallBacks, 0);