Home | History | Annotate | Download | only in mac
      1 //
      2 // GTMDefines.h
      3 //
      4 //  Copyright 2008 Google Inc.
      5 //
      6 //  Licensed under the Apache License, Version 2.0 (the "License"); you may not
      7 //  use this file except in compliance with the License.  You may obtain a copy
      8 //  of the License at
      9 //
     10 //  http://www.apache.org/licenses/LICENSE-2.0
     11 //
     12 //  Unless required by applicable law or agreed to in writing, software
     13 //  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     14 //  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
     15 //  License for the specific language governing permissions and limitations under
     16 //  the License.
     17 //
     18 
     19 // ============================================================================
     20 
     21 #include <AvailabilityMacros.h>
     22 #include <TargetConditionals.h>
     23 
     24 #ifdef __OBJC__
     25 #include <Foundation/NSObjCRuntime.h>
     26 #endif  // __OBJC__
     27 
     28 #if TARGET_OS_IPHONE
     29 #include <Availability.h>
     30 #endif  // TARGET_OS_IPHONE
     31 
     32 // Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs
     33 #ifndef MAC_OS_X_VERSION_10_5
     34   #define MAC_OS_X_VERSION_10_5 1050
     35 #endif
     36 #ifndef MAC_OS_X_VERSION_10_6
     37   #define MAC_OS_X_VERSION_10_6 1060
     38 #endif
     39 #ifndef MAC_OS_X_VERSION_10_7
     40   #define MAC_OS_X_VERSION_10_7 1070
     41 #endif
     42 
     43 // Not all __IPHONE_X macros defined in past SDKs
     44 #ifndef __IPHONE_3_0
     45   #define __IPHONE_3_0 30000
     46 #endif
     47 #ifndef __IPHONE_3_1
     48   #define __IPHONE_3_1 30100
     49 #endif
     50 #ifndef __IPHONE_3_2
     51   #define __IPHONE_3_2 30200
     52 #endif
     53 #ifndef __IPHONE_4_0
     54   #define __IPHONE_4_0 40000
     55 #endif
     56 #ifndef __IPHONE_4_3
     57   #define __IPHONE_4_3 40300
     58 #endif
     59 #ifndef __IPHONE_5_0
     60   #define __IPHONE_5_0 50000
     61 #endif
     62 
     63 // ----------------------------------------------------------------------------
     64 // CPP symbols that can be overridden in a prefix to control how the toolbox
     65 // is compiled.
     66 // ----------------------------------------------------------------------------
     67 
     68 
     69 // By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and
     70 // GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens
     71 // when a validation fails. If you implement your own validators, you may want
     72 // to control their internals using the same macros for consistency.
     73 #ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT
     74   #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0
     75 #endif
     76 
     77 // Give ourselves a consistent way to do inlines.  Apple's macros even use
     78 // a few different actual definitions, so we're based off of the foundation
     79 // one.
     80 #if !defined(GTM_INLINE)
     81   #if (defined (__GNUC__) && (__GNUC__ == 4)) || defined (__clang__)
     82     #define GTM_INLINE static __inline__ __attribute__((always_inline))
     83   #else
     84     #define GTM_INLINE static __inline__
     85   #endif
     86 #endif
     87 
     88 // Give ourselves a consistent way of doing externs that links up nicely
     89 // when mixing objc and objc++
     90 #if !defined (GTM_EXTERN)
     91   #if defined __cplusplus
     92     #define GTM_EXTERN extern "C"
     93     #define GTM_EXTERN_C_BEGIN extern "C" {
     94     #define GTM_EXTERN_C_END }
     95   #else
     96     #define GTM_EXTERN extern
     97     #define GTM_EXTERN_C_BEGIN
     98     #define GTM_EXTERN_C_END
     99   #endif
    100 #endif
    101 
    102 // Give ourselves a consistent way of exporting things if we have visibility
    103 // set to hidden.
    104 #if !defined (GTM_EXPORT)
    105   #define GTM_EXPORT __attribute__((visibility("default")))
    106 #endif
    107 
    108 // Give ourselves a consistent way of declaring something as unused. This
    109 // doesn't use __unused because that is only supported in gcc 4.2 and greater.
    110 #if !defined (GTM_UNUSED)
    111 #define GTM_UNUSED(x) ((void)(x))
    112 #endif
    113 
    114 // _GTMDevLog & _GTMDevAssert
    115 //
    116 // _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for
    117 // developer level errors.  This implementation simply macros to NSLog/NSAssert.
    118 // It is not intended to be a general logging/reporting system.
    119 //
    120 // Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert
    121 // for a little more background on the usage of these macros.
    122 //
    123 //    _GTMDevLog           log some error/problem in debug builds
    124 //    _GTMDevAssert        assert if conditon isn't met w/in a method/function
    125 //                           in all builds.
    126 //
    127 // To replace this system, just provide different macro definitions in your
    128 // prefix header.  Remember, any implementation you provide *must* be thread
    129 // safe since this could be called by anything in what ever situtation it has
    130 // been placed in.
    131 //
    132 
    133 // We only define the simple macros if nothing else has defined this.
    134 #ifndef _GTMDevLog
    135 
    136 #ifdef DEBUG
    137   #define _GTMDevLog(...) NSLog(__VA_ARGS__)
    138 #else
    139   #define _GTMDevLog(...) do { } while (0)
    140 #endif
    141 
    142 #endif // _GTMDevLog
    143 
    144 #ifndef _GTMDevAssert
    145 // we directly invoke the NSAssert handler so we can pass on the varargs
    146 // (NSAssert doesn't have a macro we can use that takes varargs)
    147 #if !defined(NS_BLOCK_ASSERTIONS)
    148   #define _GTMDevAssert(condition, ...)                                       \
    149     do {                                                                      \
    150       if (!(condition)) {                                                     \
    151         [[NSAssertionHandler currentHandler]                                  \
    152             handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
    153                                file:[NSString stringWithUTF8String:__FILE__]  \
    154                          lineNumber:__LINE__                                  \
    155                         description:__VA_ARGS__];                             \
    156       }                                                                       \
    157     } while(0)
    158 #else // !defined(NS_BLOCK_ASSERTIONS)
    159   #define _GTMDevAssert(condition, ...) do { } while (0)
    160 #endif // !defined(NS_BLOCK_ASSERTIONS)
    161 
    162 #endif // _GTMDevAssert
    163 
    164 // _GTMCompileAssert
    165 // _GTMCompileAssert is an assert that is meant to fire at compile time if you
    166 // want to check things at compile instead of runtime. For example if you
    167 // want to check that a wchar is 4 bytes instead of 2 you would use
    168 // _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X)
    169 // Note that the second "arg" is not in quotes, and must be a valid processor
    170 // symbol in it's own right (no spaces, punctuation etc).
    171 
    172 // Wrapping this in an #ifndef allows external groups to define their own
    173 // compile time assert scheme.
    174 #ifndef _GTMCompileAssert
    175   // We got this technique from here:
    176   // http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html
    177 
    178   #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg
    179   #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)
    180   #define _GTMCompileAssert(test, msg) \
    181     typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
    182 #endif // _GTMCompileAssert
    183 
    184 // ----------------------------------------------------------------------------
    185 // CPP symbols defined based on the project settings so the GTM code has
    186 // simple things to test against w/o scattering the knowledge of project
    187 // setting through all the code.
    188 // ----------------------------------------------------------------------------
    189 
    190 // Provide a single constant CPP symbol that all of GTM uses for ifdefing
    191 // iPhone code.
    192 #if TARGET_OS_IPHONE // iPhone SDK
    193   // For iPhone specific stuff
    194   #define GTM_IPHONE_SDK 1
    195   #if TARGET_IPHONE_SIMULATOR
    196     #define GTM_IPHONE_DEVICE 0
    197     #define GTM_IPHONE_SIMULATOR 1
    198   #else
    199     #define GTM_IPHONE_DEVICE 1
    200     #define GTM_IPHONE_SIMULATOR 0
    201   #endif  // TARGET_IPHONE_SIMULATOR
    202   // By default, GTM has provided it's own unittesting support, define this
    203   // to use the support provided by Xcode, especially for the Xcode4 support
    204   // for unittesting.
    205   #ifndef GTM_IPHONE_USE_SENTEST
    206     #define GTM_IPHONE_USE_SENTEST 0
    207   #endif
    208   #define GTM_MACOS_SDK 0
    209 #else
    210   // For MacOS specific stuff
    211   #define GTM_MACOS_SDK 1
    212   #define GTM_IPHONE_SDK 0
    213   #define GTM_IPHONE_SIMULATOR 0
    214   #define GTM_IPHONE_DEVICE 0
    215   #define GTM_IPHONE_USE_SENTEST 0
    216 #endif
    217 
    218 // Some of our own availability macros
    219 #if GTM_MACOS_SDK
    220 #define GTM_AVAILABLE_ONLY_ON_IPHONE UNAVAILABLE_ATTRIBUTE
    221 #define GTM_AVAILABLE_ONLY_ON_MACOS
    222 #else
    223 #define GTM_AVAILABLE_ONLY_ON_IPHONE
    224 #define GTM_AVAILABLE_ONLY_ON_MACOS UNAVAILABLE_ATTRIBUTE
    225 #endif
    226 
    227 // GC was dropped by Apple, define the old constant incase anyone still keys
    228 // off of it.
    229 #ifndef GTM_SUPPORT_GC
    230   #define GTM_SUPPORT_GC 0
    231 #endif
    232 
    233 // To simplify support for 64bit (and Leopard in general), we provide the type
    234 // defines for non Leopard SDKs
    235 #if !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
    236  // NSInteger/NSUInteger and Max/Mins
    237   #ifndef NSINTEGER_DEFINED
    238     #if (defined(__LP64__) && __LP64__) || NS_BUILD_32_LIKE_64
    239       typedef long NSInteger;
    240       typedef unsigned long NSUInteger;
    241     #else
    242       typedef int NSInteger;
    243       typedef unsigned int NSUInteger;
    244     #endif
    245     #define NSIntegerMax    LONG_MAX
    246     #define NSIntegerMin    LONG_MIN
    247     #define NSUIntegerMax   ULONG_MAX
    248     #define NSINTEGER_DEFINED 1
    249   #endif  // NSINTEGER_DEFINED
    250   // CGFloat
    251   #ifndef CGFLOAT_DEFINED
    252     #if defined(__LP64__) && __LP64__
    253       // This really is an untested path (64bit on Tiger?)
    254       typedef double CGFloat;
    255       #define CGFLOAT_MIN DBL_MIN
    256       #define CGFLOAT_MAX DBL_MAX
    257       #define CGFLOAT_IS_DOUBLE 1
    258     #else /* !defined(__LP64__) || !__LP64__ */
    259       typedef float CGFloat;
    260       #define CGFLOAT_MIN FLT_MIN
    261       #define CGFLOAT_MAX FLT_MAX
    262       #define CGFLOAT_IS_DOUBLE 0
    263     #endif /* !defined(__LP64__) || !__LP64__ */
    264     #define CGFLOAT_DEFINED 1
    265   #endif // CGFLOAT_DEFINED
    266 #endif  // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
    267 
    268 // Some support for advanced clang static analysis functionality
    269 // See http://clang-analyzer.llvm.org/annotations.html
    270 #ifndef __has_feature      // Optional.
    271   #define __has_feature(x) 0 // Compatibility with non-clang compilers.
    272 #endif
    273 
    274 #ifndef NS_RETURNS_RETAINED
    275   #if __has_feature(attribute_ns_returns_retained)
    276     #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
    277   #else
    278     #define NS_RETURNS_RETAINED
    279   #endif
    280 #endif
    281 
    282 #ifndef NS_RETURNS_NOT_RETAINED
    283   #if __has_feature(attribute_ns_returns_not_retained)
    284     #define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
    285   #else
    286     #define NS_RETURNS_NOT_RETAINED
    287   #endif
    288 #endif
    289 
    290 #ifndef CF_RETURNS_RETAINED
    291   #if __has_feature(attribute_cf_returns_retained)
    292     #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
    293   #else
    294     #define CF_RETURNS_RETAINED
    295   #endif
    296 #endif
    297 
    298 #ifndef CF_RETURNS_NOT_RETAINED
    299   #if __has_feature(attribute_cf_returns_not_retained)
    300     #define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
    301   #else
    302     #define CF_RETURNS_NOT_RETAINED
    303   #endif
    304 #endif
    305 
    306 #ifndef NS_CONSUMED
    307   #if __has_feature(attribute_ns_consumed)
    308     #define NS_CONSUMED __attribute__((ns_consumed))
    309   #else
    310     #define NS_CONSUMED
    311   #endif
    312 #endif
    313 
    314 #ifndef CF_CONSUMED
    315   #if __has_feature(attribute_cf_consumed)
    316     #define CF_CONSUMED __attribute__((cf_consumed))
    317   #else
    318     #define CF_CONSUMED
    319   #endif
    320 #endif
    321 
    322 #ifndef NS_CONSUMES_SELF
    323   #if __has_feature(attribute_ns_consumes_self)
    324     #define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
    325   #else
    326     #define NS_CONSUMES_SELF
    327   #endif
    328 #endif
    329 
    330 // Defined on 10.6 and above.
    331 #ifndef NS_FORMAT_ARGUMENT
    332   #define NS_FORMAT_ARGUMENT(A)
    333 #endif
    334 
    335 // Defined on 10.6 and above.
    336 #ifndef NS_FORMAT_FUNCTION
    337   #define NS_FORMAT_FUNCTION(F,A)
    338 #endif
    339 
    340 // Defined on 10.6 and above.
    341 #ifndef CF_FORMAT_ARGUMENT
    342   #define CF_FORMAT_ARGUMENT(A)
    343 #endif
    344 
    345 // Defined on 10.6 and above.
    346 #ifndef CF_FORMAT_FUNCTION
    347   #define CF_FORMAT_FUNCTION(F,A)
    348 #endif
    349 
    350 #ifndef GTM_NONNULL
    351   #if defined(__has_attribute)
    352     #if __has_attribute(nonnull)
    353       #define GTM_NONNULL(x) __attribute__((nonnull x))
    354     #else
    355       #define GTM_NONNULL(x)
    356     #endif
    357   #else
    358     #define GTM_NONNULL(x)
    359   #endif
    360 #endif
    361 
    362 // Invalidates the initializer from which it's called.
    363 #ifndef GTMInvalidateInitializer
    364   #if __has_feature(objc_arc)
    365     #define GTMInvalidateInitializer() \
    366       do { \
    367         [self class]; /* Avoid warning of dead store to |self|. */ \
    368         _GTMDevAssert(NO, @"Invalid initializer."); \
    369         return nil; \
    370       } while (0)
    371   #else
    372     #define GTMInvalidateInitializer() \
    373       do { \
    374         [self release]; \
    375         _GTMDevAssert(NO, @"Invalid initializer."); \
    376         return nil; \
    377       } while (0)
    378   #endif
    379 #endif
    380 
    381 #ifndef GTMCFAutorelease
    382   #if __has_feature(objc_arc)
    383     #define GTMCFAutorelease(x) CFBridgingRelease(x)
    384   #else
    385     #define GTMCFAutorelease(x) ([(id)x autorelease])
    386   #endif
    387 #endif
    388 
    389 #ifdef __OBJC__
    390 
    391 // Declared here so that it can easily be used for logging tracking if
    392 // necessary. See GTMUnitTestDevLog.h for details.
    393 @class NSString;
    394 GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...) NS_FORMAT_FUNCTION(1, 2);
    395 
    396 // Macro to allow you to create NSStrings out of other macros.
    397 // #define FOO foo
    398 // NSString *fooString = GTM_NSSTRINGIFY(FOO);
    399 #if !defined (GTM_NSSTRINGIFY)
    400   #define GTM_NSSTRINGIFY_INNER(x) @#x
    401   #define GTM_NSSTRINGIFY(x) GTM_NSSTRINGIFY_INNER(x)
    402 #endif
    403 
    404 // Macro to allow fast enumeration when building for 10.5 or later, and
    405 // reliance on NSEnumerator for 10.4.  Remember, NSDictionary w/ FastEnumeration
    406 // does keys, so pick the right thing, nothing is done on the FastEnumeration
    407 // side to be sure you're getting what you wanted.
    408 #ifndef GTM_FOREACH_OBJECT
    409   #if TARGET_OS_IPHONE || !(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
    410     #define GTM_FOREACH_ENUMEREE(element, enumeration) \
    411       for (element in enumeration)
    412     #define GTM_FOREACH_OBJECT(element, collection) \
    413       for (element in collection)
    414     #define GTM_FOREACH_KEY(element, collection) \
    415       for (element in collection)
    416   #else
    417     #define GTM_FOREACH_ENUMEREE(element, enumeration) \
    418       for (NSEnumerator *_ ## element ## _enum = enumeration; \
    419            (element = [_ ## element ## _enum nextObject]) != nil; )
    420     #define GTM_FOREACH_OBJECT(element, collection) \
    421       GTM_FOREACH_ENUMEREE(element, [collection objectEnumerator])
    422     #define GTM_FOREACH_KEY(element, collection) \
    423       GTM_FOREACH_ENUMEREE(element, [collection keyEnumerator])
    424   #endif
    425 #endif
    426 
    427 // ============================================================================
    428 
    429 // To simplify support for both Leopard and Snow Leopard we declare
    430 // the Snow Leopard protocols that we need here.
    431 #if !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
    432 #define GTM_10_6_PROTOCOLS_DEFINED 1
    433 @protocol NSConnectionDelegate
    434 @end
    435 @protocol NSAnimationDelegate
    436 @end
    437 @protocol NSImageDelegate
    438 @end
    439 @protocol NSTabViewDelegate
    440 @end
    441 #endif  // !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
    442 
    443 // GTM_SEL_STRING is for specifying selector (usually property) names to KVC
    444 // or KVO methods.
    445 // In debug it will generate warnings for undeclared selectors if
    446 // -Wunknown-selector is turned on.
    447 // In release it will have no runtime overhead.
    448 #ifndef GTM_SEL_STRING
    449   #ifdef DEBUG
    450     #define GTM_SEL_STRING(selName) NSStringFromSelector(@selector(selName))
    451   #else
    452     #define GTM_SEL_STRING(selName) @#selName
    453   #endif  // DEBUG
    454 #endif  // GTM_SEL_STRING
    455 
    456 #endif  // __OBJC__
    457