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