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