FrameWorks/OmniBase.framework/Versions/A/Headers/OBUtilities.h

00001 // Copyright 1997-2005 Omni Development, Inc.  All rights reserved.
00002 //
00003 // This software may only be used and reproduced according to the
00004 // terms in the file OmniSourceLicense.html, which should be
00005 // distributed with this project and can also be found at
00006 // <http://www.omnigroup.com/developer/sourcecode/sourcelicense/>.
00007 //
00008 // $Header: svn+ssh://source.omnigroup.com/Source/svn/Omni/tags/SourceRelease_2005-11-18/OmniGroup/Frameworks/OmniBase/OBUtilities.h 68913 2005-10-03 19:36:19Z kc $
00009 
00010 #import <Foundation/NSString.h>
00011 
00012 #import <objc/objc.h>
00013 #import <objc/objc-class.h>
00014 #import <objc/objc-runtime.h>
00015 #import <OmniBase/FrameworkDefines.h>
00016 #import <OmniBase/assertions.h>
00017 
00018 #if defined(__GNUC__)
00019 #define NORETURN __attribute__ ((noreturn))
00020 #else
00021 #define NORETURN
00022 #endif
00023 
00024 OmniBase_EXTERN void OBRequestConcreteImplementation(id self, SEL _cmd) NORETURN;
00025 OmniBase_EXTERN void OBRejectUnusedImplementation(id self, SEL _cmd) NORETURN;
00026 OmniBase_EXTERN void OBRejectInvalidCall(id self, SEL _cmd, NSString *format, ...) NORETURN;
00027 OmniBase_EXTERN NSString *OBAbstractImplementation;
00028 OmniBase_EXTERN NSString *OBUnusedImplementation;
00029 
00030 #undef NORETURN
00031 
00032 OmniBase_EXTERN IMP OBRegisterInstanceMethodWithSelector(Class aClass, SEL oldSelector, SEL newSelector);
00033 /*.doc.
00034 Provides the same functionality as +[NSObject registerInstanceMethod:withMethodTypes:forSelector: but does it without provoking +initialize on the target class.  Returns the original implementation.
00035 */
00036 
00037 OmniBase_EXTERN IMP OBReplaceMethodImplementation(Class aClass, SEL oldSelector, IMP newImp);
00038 /*.doc.
00039 Replaces the given method implementation in place.  Returns the old implementation.
00040 */
00041 
00042 OmniBase_EXTERN IMP OBReplaceMethodImplementationWithSelector(Class aClass, SEL oldSelector, SEL newSelector);
00043 /*.doc.
00044 Calls the above, but determines newImp by looking up the instance method for newSelector.  Returns the old implementation.
00045 */
00046 
00047 OmniBase_EXTERN IMP OBReplaceMethodImplementationWithSelectorOnClass(Class destClass, SEL oldSelector, Class sourceClass, SEL newSelector);
00048 /*.doc.
00049 Calls OBReplaceMethodImplementation.  Derives newImp from newSelector on sourceClass and changes method implementation for oldSelector on destClass.
00050 */
00051 
00052 // This returns YES if the given pointer is a class object
00053 static inline BOOL OBPointerIsClass(id object)
00054 {
00055     if (object)
00056         return CLS_GETINFO((struct objc_class *)(object->isa), CLS_META);
00057     return NO;
00058 }
00059 
00060 // This returns the class object for the given pointer.  For an instance, that means getting the class.  But for a class object, that means returning the pointer itself 
00061 
00062 static inline Class OBClassForPointer(id object)
00063 {
00064     if (!object)
00065         return object;
00066 
00067     if (OBPointerIsClass(object))
00068         return object;
00069     else
00070         return object->isa;
00071 }
00072 
00073 static inline BOOL OBClassIsSubclassOfClass(Class subClass, Class superClass)
00074 {
00075     while (subClass) {
00076         if (subClass == superClass)
00077             return YES;
00078         else
00079             subClass = subClass->super_class;
00080     }
00081     return NO;
00082 }
00083 
00084 // This macro ensures that we call [super initialize] in our +initialize (since this behavior is necessary for some classes in Cocoa), but it keeps custom class initialization from executing more than once.
00085 #define OBINITIALIZE \
00086     do { \
00087         static BOOL hasBeenInitialized = NO; \
00088         [super initialize]; \
00089         if (hasBeenInitialized) \
00090             return; \
00091         hasBeenInitialized = YES;\
00092     } while (0);
00093 
00094     
00095 #ifdef USING_BUGGY_CPP_PRECOMP
00096 // Versions of cpp-precomp released before April 2002 have a bug that makes us have to do this
00097 #define NSSTRINGIFY(name) @ ## '"' ## name ## '"'
00098 #elif defined(__GNUC__)
00099     #if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
00100         // GCC before 3.3 requires this format
00101         #define NSSTRINGIFY(name) @ ## #name
00102     #else
00103         // GCC 3.3 requires this format
00104         #define NSSTRINGIFY(name) @#name
00105     #endif
00106 #endif
00107 
00108 // An easy way to define string constants.  For example, "NSSTRINGIFY(foo)" produces @"foo" and "DEFINE_NSSTRING(foo);" produces: NSString *foo = @"foo";
00109 
00110 #define DEFINE_NSSTRING(name) \
00111         NSString *name = NSSTRINGIFY(name)
00112 
00113 // Emits a warning indicating that an obsolete method has been called.
00114 
00115 #define OB_WARN_OBSOLETE_METHOD \
00116     do { \
00117         static BOOL warned = NO; \
00118             if (!warned) { \
00119                 warned = YES; \
00120                     NSLog(@"Warning: obsolete method %c[%@ %s] invoked", OBPointerIsClass(self)?'+':'-', OBClassForPointer(self), _cmd); \
00121             } \
00122             OBASSERT_NOT_REACHED("obsolete method called"); \
00123     } while(0)

Generated on Sat Aug 26 21:14:12 2006 for MacTrek by  doxygen 1.4.7