1 /* GNUstep.h - macros to make easier to port gnustep apps to macos-x 2 Copyright (C) 2001 Free Software Foundation, Inc. 3 4 Written by: Nicola Pero <n.pero@mi.flashnet.it> 5 Date: March, October 2001 6 7 This file is part of GNUstep. 8 9 This library is free software; you can redistribute it and/or 10 modify it under the terms of the GNU Lesser General Public 11 License as published by the Free Software Foundation; either 12 version 2 of the License, or (at your option) any later version. 13 14 This library is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 Library General Public License for more details. 18 19 You should have received a copy of the GNU Lesser General Public 20 License along with this library; if not, write to the Free 21 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 Boston, MA 02110-1301, USA. 23 */ 24 25 #ifndef __GNUSTEP_GNUSTEP_H_INCLUDED_ 26 #define __GNUSTEP_GNUSTEP_H_INCLUDED_ 27 28 /* The contents of this file are designed to be usable with either 29 * GNUstep-base or MacOS-X Foundation. 30 */ 31 32 #ifndef __has_feature 33 # define __has_feature(x) 0 34 #endif 35 36 /* 37 * __has_extension has slightly different semantics from __has_feature. 38 * It evaluates to true if the feature is supported by by clang for the 39 * current compilation unit (language and -f switches), regardless of 40 * whether it is part of the language standard or just a (non-standard) 41 * extension. 42 */ 43 #ifndef __has_extension 44 # define __has_extension(x) __has_feature(x) 45 #endif 46 47 /* 48 * __has_attribute is the equivalent to __has_feature and __has_extension 49 * for GNU-style attributes. 50 */ 51 #ifndef __has_attribute 52 # define __has_attribute(x) 0 53 #endif 54 55 #if __has_feature(objc_arc) 56 57 #ifndef RETAIN 58 #define RETAIN(object) (object) 59 #endif 60 #ifndef RELEASE 61 #define RELEASE(object) 62 #endif 63 #ifndef AUTORELEASE 64 #define AUTORELEASE(object) (object) 65 #endif 66 67 #ifndef TEST_RETAIN 68 #define TEST_RETAIN(object) (object) 69 #endif 70 #ifndef TEST_RELEASE 71 #define TEST_RELEASE(object) 72 #endif 73 #ifndef TEST_AUTORELEASE 74 #define TEST_AUTORELEASE(object) (object) 75 #endif 76 77 #ifndef ASSIGN 78 #define ASSIGN(object,value) object = (value) 79 #endif 80 #ifndef ASSIGNCOPY 81 #define ASSIGNCOPY(object,value) object = [(value) copy] 82 #endif 83 #ifndef DESTROY 84 #define DESTROY(object) object = nil 85 #endif 86 87 #define IF_NO_GC(X) 88 89 #ifndef ENTER_POOL 90 #define ENTER_POOL @autoreleasepool{do{ 91 #endif 92 93 #ifndef LEAVE_POOL 94 #define LEAVE_POOL }while(0);} 95 #endif 96 97 #ifndef DEALLOC 98 #define DEALLOC 99 #endif 100 101 #else 102 103 #ifndef RETAIN 104 /** 105 * Basic retain operation ... calls [NSObject-retain]<br /> 106 * Does nothing when ARC is in use. 107 */ 108 #define RETAIN(object) [(object) retain] 109 #endif 110 111 #ifndef RELEASE 112 /** 113 * Basic release operation ... calls [NSObject-release]<br /> 114 * Does nothing when ARC is in use. 115 */ 116 #define RELEASE(object) [(object) release] 117 #endif 118 119 #ifndef AUTORELEASE 120 /** 121 * Basic autorelease operation ... calls [NSObject-autorelease]<br /> 122 * Does nothing when ARC is in use. 123 */ 124 #define AUTORELEASE(object) [(object) autorelease] 125 #endif 126 127 #ifndef TEST_RETAIN 128 /** 129 * Tested retain - only invoke the 130 * objective-c method if the receiver is not nil.<br /> 131 * Does nothing when ARC is in use. 132 */ 133 #define TEST_RETAIN(object) ({\ 134 id __object = (object); (__object != nil) ? [__object retain] : nil; }) 135 #endif 136 137 #ifndef TEST_RELEASE 138 /** 139 * Tested release - only invoke the 140 * objective-c method if the receiver is not nil.<br /> 141 * Does nothing when ARC is in use. 142 */ 143 #define TEST_RELEASE(object) ({\ 144 id __object = (object); if (__object != nil) [__object release]; }) 145 #endif 146 147 #ifndef TEST_AUTORELEASE 148 /** 149 * Tested autorelease - only invoke the 150 * objective-c method if the receiver is not nil.<br /> 151 * Does nothing when ARC is in use. 152 */ 153 #define TEST_AUTORELEASE(object) ({\ 154 id __object = (object); (__object != nil) ? [__object autorelease] : nil; }) 155 #endif 156 157 #ifndef ASSIGN 158 /** 159 * ASSIGN(object,value) assigns the value to the object with 160 * appropriate retain and release operations.<br /> 161 * Use this to avoid retain/release errors. 162 */ 163 #define ASSIGN(object,value) ({\ 164 id __object = object; \ 165 object = [(value) retain]; \ 166 [__object release]; \ 167 }) 168 #endif 169 170 #ifndef ASSIGNCOPY 171 /** 172 * ASSIGNCOPY(object,value) assigns a copy of the value to the object 173 * with release of the original.<br /> 174 * Use this to avoid retain/release errors. 175 */ 176 #define ASSIGNCOPY(object,value) ({\ 177 id __object = object; \ 178 object = [(value) copy];\ 179 [__object release]; \ 180 }) 181 #endif 182 183 #ifndef DESTROY 184 /** 185 * DESTROY() is a release operation which also sets the variable to be 186 * a nil pointer for tidiness - we can't accidentally use a DESTROYED 187 * object later. It also makes sure to set the variable to nil before 188 * releasing the object - to avoid side-effects of the release trying 189 * to reference the object being released through the variable. 190 */ 191 #define DESTROY(object) ({ \ 192 id __o = object; \ 193 object = nil; \ 194 [__o release]; \ 195 }) 196 #endif 197 198 #define IF_NO_GC(X) X 199 200 #ifndef ENTER_POOL 201 /** 202 * ENTER_POOL creates an autorelease pool and places subsequent code 203 * in a do/while loop (executed only once) which can be broken out of 204 * to reach the point when the pool is drained.<br /> 205 * The block must be terminated with a corresponding LEAVE_POOL.<br /> 206 * You should not return from such a block of code (to do so could 207 * leak an autorelease pool and give objects a longer lifetime than 208 * they ought to have. If you wish to leave the block of code early, 209 * you may do so using a 'break' statement. 210 */ 211 #define ENTER_POOL {NSAutoreleasePool *_lARP=[NSAutoreleasePool new];do{ 212 #endif 213 214 #ifndef LEAVE_POOL 215 /** 216 * LEAVE_POOL terminates a block of code started with ENTER_POOL. 217 */ 218 #define LEAVE_POOL }while(0);[_lARP drain];} 219 #endif 220 221 #ifndef DEALLOC 222 /** 223 * DEALLOC calls the superclass implementation of dealloc, unless 224 * ARC is in use (in which case it does nothing). 225 */ 226 #define DEALLOC [super dealloc]; 227 #endif 228 #endif 229 230 #ifndef CREATE_AUTORELEASE_POOL 231 /** DEPRECATED ... use ENTER_POOL and LEAVE_POOL 232 */ 233 #define CREATE_AUTORELEASE_POOL(X) \ 234 NSAutoreleasePool *X = [NSAutoreleasePool new] 235 #endif 236 237 #ifndef RECREATE_AUTORELEASE_POOL 238 /** DEPRECATED ... use ENTER_POOL and LEAVE_POOL 239 */ 240 #define RECREATE_AUTORELEASE_POOL(X) \ 241 DESTROY(X);\ 242 X = [NSAutoreleasePool new] 243 #endif 244 245 246 /** 247 * <p> 248 * This function (macro) is a GNUstep extension. 249 * </p> 250 * <p> 251 * <code>_(@"My string to translate")</code> 252 * </p> 253 * <p> 254 * is basically equivalent to 255 * </p> 256 * <p> 257 * <code>NSLocalizedString(@"My string to translate", @"")</code> 258 * </p> 259 * <p> 260 * It is useful when you need to translate an application 261 * very quickly, as you just need to enclose all strings 262 * inside <code>_()</code>. But please note that when you 263 * use this macro, you are not taking advantage of comments 264 * for the translator, so consider using 265 * <code>NSLocalizedString</code> instead when you need a 266 * comment. 267 * </p> 268 * <p>You may define GS_LOCALISATION_BUNDLE_ID to the bundle identifier 269 * of the bundle which is to provide the localisation information.<br /> 270 * This can be used when compiling a single file by specifying something like 271 * '-D GS_LOCALISATION_BUNDLE_ID=$(FRAMEWORK_NAME)' in your make file.<br /> 272 * If this is not defined, the localisation is provided by your application's 273 * main bundle exactly like the NSLocalizedString function. 274 * </p> 275 * <p>Alternatively you may define GS_LOCALISATION_BUNDLE to be the bundle 276 * to be used to prvide the localisation information. 277 * </p> 278 */ 279 # define _(X) \ 280 [GS_LOCALISATION_BUNDLE localizedStringForKey: (X) value: @"" table: nil] 281 282 #if !defined(GS_LOCALISATION_BUNDLE) 283 # if defined(GS_LOCALISATION_BUNDLE_ID) 284 # define GS_LOCALISATION_BUNDLE [NSBundle bundleWithIdentifier: \ 285 GS_LOCALISATION_BUNDLE_ID] 286 # else 287 # define GS_LOCALISATION_BUNDLE [NSBundle mainBundle] 288 # endif 289 #endif 290 291 292 293 /** 294 * <p> 295 * This function (macro) is a GNUstep extension. 296 * </p> 297 * <p> 298 * <code>__(@"My string to translate")</code> 299 * </p> 300 * <p> 301 * is exactly the same as 302 * </p> 303 * <p> 304 * <code>GSLocalizedStaticString(@"My string to translate", @"")</code> 305 * </p> 306 * <p> 307 * It is useful when you need to translate an application very 308 * quickly. You would use it as follows for static strings: 309 * </p> 310 * <p> 311 * <code> 312 * NSString *message = __(@"Hello there"); 313 * ... more code ... 314 * NSLog (_(messages)); 315 * </code> 316 * </p> 317 * <p> 318 * But please note that when you use this macro, you are not 319 * taking advantage of comments for the translator, so 320 * consider using <code>GSLocalizedStaticString</code> 321 * instead when you need a comment. 322 * </p> 323 */ 324 #define __(X) X 325 326 /* The better way for a static string, with a comment - use as follows - 327 * 328 * static NSString *string = GSLocalizedStaticString (@"New Game", 329 * @"Menu Option"); 330 * 331 * NSLog (_(string)); 332 * 333 * If you need anything more complicated than this, please initialize 334 * the static strings manually. 335 */ 336 337 /** 338 * <p> 339 * This function (macro) is a GNUstep extensions, and it is used 340 * to localize static strings. Here is an example of a static 341 * string: 342 * </p> 343 * <p> 344 * <code> 345 * NSString *message = @"Hi there"; 346 * ... some code ... 347 * NSLog (message); 348 * </code> 349 * </p> 350 * <p> 351 * This string can not be localized using the standard 352 * openstep functions/macros. By using this gnustep extension, 353 * you can localize it as follows: 354 * </p> 355 * <p> 356 * <code> 357 * NSString *message = GSLocalizedStaticString (@"Hi there", 358 * @"Greeting"); 359 * 360 * ... some code ... 361 * 362 * NSLog (NSLocalizedString (message, @"")); 363 * </code> 364 * </p> 365 * <p> 366 * When the tools generate the 367 * <code>Localizable.strings</code> file from the source 368 * code, they will ignore the <code>NSLocalizedString</code> 369 * call while they will extract the string (and the comment) 370 * to localize from the <code>GSLocalizedStaticString</code> 371 * call. 372 * </p> 373 * <p> 374 * When the code is compiled, instead, the 375 * <code>GSLocalizedStaticString</code> call is ignored (discarded, 376 * it is a macro which simply expands to <code>key</code>), while 377 * the <code>NSLocalizedString</code> will actually look up the 378 * string for translation in the <code>Localizable.strings</code> 379 * file. 380 * </p> 381 * <p> 382 * Please note that there is currently no macro/function to 383 * localize static strings using different tables. If you 384 * need that functionality, you have either to prepare the 385 * localization tables by hand, or to rewrite your code in 386 * such a way as not to use static strings. 387 * </p> 388 */ 389 #define GSLocalizedStaticString(key, comment) key 390 391 /** 392 * To be used inside a method for making sure that a range does not specify 393 * anything outside the size of an array/string. Raises exception if range 394 * extends beyond [0,size]. Size must be an unsigned integer (NSUInteger). 395 */ 396 #define GS_RANGE_CHECK(RANGE, SIZE) \ 397 if (RANGE.location > (NSUInteger)SIZE \ 398 || RANGE.length > ((NSUInteger)SIZE - RANGE.location)) \ 399 [NSException raise: NSRangeException format: @"in %s, range { %"\ 400 PRIuPTR ", %" PRIuPTR " } extends beyond size (%" PRIuPTR ")", \ 401 GSNameFromSelector(_cmd), RANGE.location, RANGE.length, (NSUInteger)SIZE] 402 403 /** Checks whether INDEX is strictly less than OVER (within C array space). 404 * INDEX and OVER must be unsigned integers (NSUInteger). 405 */ 406 #define CHECK_INDEX_RANGE_ERROR(INDEX, OVER) \ 407 if ((NSUInteger)INDEX >= (NSUInteger)OVER) \ 408 [NSException raise: NSRangeException \ 409 format: @"in %s, index %" PRIuPTR " is out of range", \ 410 GSNameFromSelector(_cmd), (NSUInteger)INDEX] 411 412 #endif /* __GNUSTEP_GNUSTEP_H_INCLUDED_ */ 413