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 * Deprecated ... pointless on modern processors. 107 * Simply call the -retain method. 108 */ 109 #define RETAIN(object) [(object) retain] 110 #endif 111 112 #ifndef RELEASE 113 /** 114 * Basic release operation ... calls [NSObject-release]<br /> 115 * Deprecated ... pointless on modern processors. 116 * Simply call the -release method. 117 */ 118 #define RELEASE(object) [(object) release] 119 #endif 120 121 #ifndef AUTORELEASE 122 /** 123 * Basic autorelease operation ... calls [NSObject-autorelease]<br /> 124 * Deprecated ... pointless on modern processors. 125 * Simply call the -autorelease method. 126 */ 127 #define AUTORELEASE(object) [(object) autorelease] 128 #endif 129 130 #ifndef TEST_RETAIN 131 /** 132 * Tested retain - only invoke the 133 * objective-c method if the receiver is not nil.<br /> 134 * Deprecated ... pointless on modern processors. 135 * Simply call the -retain method. 136 */ 137 #define TEST_RETAIN(object) ({\ 138 id __object = (object); (__object != nil) ? [__object retain] : nil; }) 139 #endif 140 141 #ifndef TEST_RELEASE 142 /** 143 * Tested release - only invoke the 144 * objective-c method if the receiver is not nil.<br /> 145 * Deprecated ... pointless on modern processors. 146 * Simply call the -release method. 147 */ 148 #define TEST_RELEASE(object) ({\ 149 id __object = (object); if (__object != nil) [__object release]; }) 150 #endif 151 152 #ifndef TEST_AUTORELEASE 153 /** 154 * Tested autorelease - only invoke the 155 * objective-c method if the receiver is not nil.<br /> 156 * Deprecated ... pointless on modern processors. 157 * Simply call the -autorelease method. 158 */ 159 #define TEST_AUTORELEASE(object) ({\ 160 id __object = (object); (__object != nil) ? [__object autorelease] : nil; }) 161 #endif 162 163 #ifndef ASSIGN 164 /** 165 * ASSIGN(object,value) assigns the value to the object with 166 * appropriate retain and release operations.<br /> 167 * Use this to avoid retain/release errors. 168 */ 169 #define ASSIGN(object,value) ({\ 170 id __object = object; \ 171 object = [(value) retain]; \ 172 [__object release]; \ 173 }) 174 #endif 175 176 #ifndef ASSIGNCOPY 177 /** 178 * ASSIGNCOPY(object,value) assigns a copy of the value to the object 179 * with release of the original.<br /> 180 * Use this to avoid retain/release errors. 181 */ 182 #define ASSIGNCOPY(object,value) ({\ 183 id __object = object; \ 184 object = [(value) copy];\ 185 [__object release]; \ 186 }) 187 #endif 188 189 #ifndef DESTROY 190 /** 191 * DESTROY() is a release operation which also sets the variable to be 192 * a nil pointer for tidiness - we can't accidentally use a DESTROYED 193 * object later. It also makes sure to set the variable to nil before 194 * releasing the object - to avoid side-effects of the release trying 195 * to reference the object being released through the variable. 196 */ 197 #define DESTROY(object) ({ \ 198 id __o = object; \ 199 object = nil; \ 200 [__o release]; \ 201 }) 202 #endif 203 204 #define IF_NO_GC(X) X 205 206 #ifndef ENTER_POOL 207 /** 208 * ENTER_POOL creates an autorelease pool and places subsequent code 209 * in a do/while loop (executed only once) which can be broken out of 210 * to reach the point when the pool is drained.<br /> 211 * The block must be terminated with a corresponding LEAVE_POOL.<br /> 212 * You should not return from such a block of code (to do so could 213 * leak an autorelease pool and give objects a longer lifetime than 214 * they ought to have. If you wish to leave the block of code early, 215 * you may do so using a 'break' statement. 216 */ 217 #define ENTER_POOL {NSAutoreleasePool *_lARP=[NSAutoreleasePool new];do{ 218 #endif 219 220 #ifndef LEAVE_POOL 221 /** 222 * LEAVE_POOL terminates a block of code started with ENTER_POOL. 223 */ 224 #define LEAVE_POOL }while(0);[_lARP drain];} 225 #endif 226 227 #ifndef DEALLOC 228 /** 229 * DEALLOC calls the superclass implementation of dealloc, unless 230 * ARC is in use (in which case it does nothing). 231 */ 232 #define DEALLOC [super dealloc]; 233 #endif 234 #endif 235 236 #ifndef CREATE_AUTORELEASE_POOL 237 /** DEPRECATED ... use ENTER_POOL and LEAVE_POOL 238 */ 239 #define CREATE_AUTORELEASE_POOL(X) \ 240 NSAutoreleasePool *X = [NSAutoreleasePool new] 241 #endif 242 243 #ifndef RECREATE_AUTORELEASE_POOL 244 /** DEPRECATED ... use ENTER_POOL and LEAVE_POOL 245 */ 246 #define RECREATE_AUTORELEASE_POOL(X) \ 247 DESTROY(X);\ 248 X = [NSAutoreleasePool new] 249 #endif 250 251 252 /** 253 * <p> 254 * This function (macro) is a GNUstep extension. 255 * </p> 256 * <p> 257 * <code>_(@"My string to translate")</code> 258 * </p> 259 * <p> 260 * is basically equivalent to 261 * </p> 262 * <p> 263 * <code>NSLocalizedString(@"My string to translate", @"")</code> 264 * </p> 265 * <p> 266 * It is useful when you need to translate an application 267 * very quickly, as you just need to enclose all strings 268 * inside <code>_()</code>. But please note that when you 269 * use this macro, you are not taking advantage of comments 270 * for the translator, so consider using 271 * <code>NSLocalizedString</code> instead when you need a 272 * comment. 273 * </p> 274 * <p>You may define GS_LOCALISATION_BUNDLE_ID to the bundle identifier 275 * of the bundle which is to provide the localisation information.<br /> 276 * This can be used when compiling a single file by specifying something like 277 * '-D GS_LOCALISATION_BUNDLE_ID=$(FRAMEWORK_NAME)' in your make file.<br /> 278 * If this is not defined, the localisation is provided by your application's 279 * main bundle exactly like the NSLocalizedString function. 280 * </p> 281 * <p>Alternatively you may define GS_LOCALISATION_BUNDLE to be the bundle 282 * to be used to prvide the localisation information. 283 * </p> 284 */ 285 # define _(X) \ 286 [GS_LOCALISATION_BUNDLE localizedStringForKey: (X) value: @"" table: nil] 287 288 #if !defined(GS_LOCALISATION_BUNDLE) 289 # if defined(GS_LOCALISATION_BUNDLE_ID) 290 # define GS_LOCALISATION_BUNDLE [NSBundle bundleWithIdentifier: \ 291 GS_LOCALISATION_BUNDLE_ID] 292 # else 293 # define GS_LOCALISATION_BUNDLE [NSBundle mainBundle] 294 # endif 295 #endif 296 297 298 299 /** 300 * <p> 301 * This function (macro) is a GNUstep extension. 302 * </p> 303 * <p> 304 * <code>__(@"My string to translate")</code> 305 * </p> 306 * <p> 307 * is exactly the same as 308 * </p> 309 * <p> 310 * <code>GSLocalizedStaticString(@"My string to translate", @"")</code> 311 * </p> 312 * <p> 313 * It is useful when you need to translate an application very 314 * quickly. You would use it as follows for static strings: 315 * </p> 316 * <p> 317 * <code> 318 * NSString *message = __(@"Hello there"); 319 * ... more code ... 320 * NSLog (_(messages)); 321 * </code> 322 * </p> 323 * <p> 324 * But please note that when you use this macro, you are not 325 * taking advantage of comments for the translator, so 326 * consider using <code>GSLocalizedStaticString</code> 327 * instead when you need a comment. 328 * </p> 329 */ 330 #define __(X) X 331 332 /* The better way for a static string, with a comment - use as follows - 333 * 334 * static NSString *string = GSLocalizedStaticString (@"New Game", 335 * @"Menu Option"); 336 * 337 * NSLog (_(string)); 338 * 339 * If you need anything more complicated than this, please initialize 340 * the static strings manually. 341 */ 342 343 /** 344 * <p> 345 * This function (macro) is a GNUstep extensions, and it is used 346 * to localize static strings. Here is an example of a static 347 * string: 348 * </p> 349 * <p> 350 * <code> 351 * NSString *message = @"Hi there"; 352 * ... some code ... 353 * NSLog (message); 354 * </code> 355 * </p> 356 * <p> 357 * This string can not be localized using the standard 358 * openstep functions/macros. By using this gnustep extension, 359 * you can localize it as follows: 360 * </p> 361 * <p> 362 * <code> 363 * NSString *message = GSLocalizedStaticString (@"Hi there", 364 * @"Greeting"); 365 * 366 * ... some code ... 367 * 368 * NSLog (NSLocalizedString (message, @"")); 369 * </code> 370 * </p> 371 * <p> 372 * When the tools generate the 373 * <code>Localizable.strings</code> file from the source 374 * code, they will ignore the <code>NSLocalizedString</code> 375 * call while they will extract the string (and the comment) 376 * to localize from the <code>GSLocalizedStaticString</code> 377 * call. 378 * </p> 379 * <p> 380 * When the code is compiled, instead, the 381 * <code>GSLocalizedStaticString</code> call is ignored (discarded, 382 * it is a macro which simply expands to <code>key</code>), while 383 * the <code>NSLocalizedString</code> will actually look up the 384 * string for translation in the <code>Localizable.strings</code> 385 * file. 386 * </p> 387 * <p> 388 * Please note that there is currently no macro/function to 389 * localize static strings using different tables. If you 390 * need that functionality, you have either to prepare the 391 * localization tables by hand, or to rewrite your code in 392 * such a way as not to use static strings. 393 * </p> 394 */ 395 #define GSLocalizedStaticString(key, comment) key 396 397 /** 398 * To be used inside a method for making sure that a range does not specify 399 * anything outside the size of an array/string. Raises exception if range 400 * extends beyond [0,size]. Size must be an unsigned integer (NSUInteger). 401 */ 402 #define GS_RANGE_CHECK(RANGE, SIZE) \ 403 if (RANGE.location > (NSUInteger)SIZE \ 404 || RANGE.length > ((NSUInteger)SIZE - RANGE.location)) \ 405 [NSException raise: NSRangeException format: @"in %s, range { %"\ 406 PRIuPTR ", %" PRIuPTR " } extends beyond size (%" PRIuPTR ")", \ 407 GSNameFromSelector(_cmd), RANGE.location, RANGE.length, (NSUInteger)SIZE] 408 409 /** Checks whether INDEX is strictly less than OVER (within C array space). 410 * INDEX and OVER must be unsigned integers (NSUInteger). 411 */ 412 #define CHECK_INDEX_RANGE_ERROR(INDEX, OVER) \ 413 if ((NSUInteger)INDEX >= (NSUInteger)OVER) \ 414 [NSException raise: NSRangeException \ 415 format: @"in %s, index %" PRIuPTR " is out of range", \ 416 GSNameFromSelector(_cmd), (NSUInteger)INDEX] 417 418 #endif /* __GNUSTEP_GNUSTEP_H_INCLUDED_ */ 419