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