]> pd.if.org Git - pdclib/blob - internals/_PDCLIB_aux.h
Patch suggested by darkinsanity, http://forum.osdev.org/viewtopic.php?p=256346#p256346
[pdclib] / internals / _PDCLIB_aux.h
1 #ifndef __PDCLIB_AUX_H
2 #define __PDCLIB_AUX_H __PDCLIB_AUX_H
3
4 /* Auxiliary PDCLib code <_PDCLIB_aux.h>
5
6    This file is part of the Public Domain C Library (PDCLib).
7    Permission is granted to use, modify, and / or redistribute at will.
8 */
9
10 /* -------------------------------------------------------------------------- */
11 /* You should not have to edit anything in this file; if you DO have to, it   */
12 /* would be considered a bug / missing feature: notify the author(s).         */
13 /* -------------------------------------------------------------------------- */
14
15 /* -------------------------------------------------------------------------- */
16 /* Standard Version                                                           */
17 /* -------------------------------------------------------------------------- */
18
19 /* Many a compiler gets this wrong, so you might have to hardcode it instead. */
20
21 #if __STDC__ != 1
22 #error Compiler does not define _ _STDC_ _ to 1 (not standard-compliant)!
23 #endif
24
25 #if defined(_PDCLIB_C_VERSION)
26     /* Pass - conditional simplification case */
27 #elif !defined(__STDC_VERSION__)
28     #define _PDCLIB_C_VERSION 1990
29 #elif __STDC_VERSION__ == 199409L
30     #define _PDCLIB_C_VERSION 1995
31 #elif __STDC_VERSION__ == 199901L
32     #define _PDCLIB_C_VERSION 1999
33 #elif __STDC_VERSION__ == 201112L
34     #define _PDCLIB_C_VERSION 2011
35 #else
36     #error Unsupported _ _STDC_VERSION_ _ (__STDC_VERSION__) (supported: ISO/IEC 9899:1990, 9899/AMD1:1995, 9899:1999, 9899:2011).
37 #endif
38
39 #if !defined(__cplusplus) || defined(_PDCLIB_CXX_VERSION)
40    #define _PDCLIB_CXX_VERSION 0
41 #elif __cplusplus == 201103L
42     #define _PDCLIB_CXX_VERSION 2011
43     /* TODO: Do we want this? */
44     #if _PDCLIB_C_VERSION < 2011
45         #undef _PDCLIB_C_VERSION
46         #define _PDCLIB_C_VERSION 2011
47     #endif
48 #elif __cplusplus == 199711L
49    #define _PDCLIB_CXX_VERSION 1997
50 #else
51    #error Unsupported _ _cplusplus (__cplusplus) (supported: ISO/IEC 14882:1997, ISO/IEC 14882:2011).
52 #endif
53
54 #ifndef __STDC_HOSTED__
55     #error Compiler does not define _ _STDC_HOSTED_ _ (not standard-compliant)!
56 #elif __STDC_HOSTED__ == 0
57     #define _PDCLIB_HOSTED 0
58 #elif __STDC_HOSTED__ == 1
59     #define _PDCLIB_HOSTED 1
60 #else
61     #error Compiler does not define _ _STDC_HOSTED_ _ to 0 or 1 (not standard-compliant)!
62 #endif
63
64 #ifdef __cplusplus
65     #define _PDCLIB_BEGIN_EXTERN_C extern "C" {
66     #define _PDCLIB_END_EXTERN_C }
67     typedef bool _PDCLIB_bool;
68 #else
69     #define _PDCLIB_BEGIN_EXTERN_C
70     #define _PDCLIB_END_EXTERN_C
71     typedef _Bool _PDCLIB_bool;
72 #endif
73
74 /* Clang style feature detection macros
75  * Note: It is common to #define __has_feature(0) if undefined so the presence
76  * of this macro does not guarantee it to be working
77  */
78
79 #ifdef __has_feature
80    #define _PDCLIB_HAS_FEATURE(x) __has_feature(x)
81 #else
82    #define _PDCLIB_HAS_FEATURE(x) (0)
83 #endif
84
85 #ifdef __has_extension
86    #define _PDCLIB_HAS_EXTENSION(x) __has_extension(x)
87 #else
88    // Older versions of Clang use __has_feature instead
89    #define _PDCLIB_HAS_EXTENSION(x) _PDCLIB_HAS_FEATURE(x)
90 #endif
91
92 #ifdef __has_builtin
93    #define _PDCLIB_HAS_BUILTIN(x) __has_builtin(x)
94 #else
95    #define _PDCLIB_HAS_BUILTIN(x) (0)
96 #endif
97
98 #ifdef __has_attribute
99    #define _PDCLIB_HAS_ATTRIBUTE(x) __has_attribute(x)
100 #else
101    #define _PDCLIB_HAS_ATTRIBUTE(x) (0)
102 #endif
103
104 /* GCC feature detection macros */
105
106 #if defined(__GNUC__)
107     #define _PDCLIB_GCC_MIN(maj, min) \
108         ((__GNUC__ > maj) || (__GNUC__ == maj && __GNUC_MINOR__ >= min))
109 #else
110     #define _PDCLIB_GCC_MIN(maj, min) (0)
111 #endif
112
113 /* Hybrid GCC/Clang feature detection macros */
114 #define _PDCLIB_GCC_FEATURE(x, gccmaj, gccmin) \
115         (_PDCLIB_HAS_FEATURE(x) || _PDCLIB_GCC_MIN(gccmin, gccmaj))
116
117 #define _PDCLIB_GCC_EXTENSION(x, gccmaj, gccmin) \
118         (_PDCLIB_HAS_EXTENSION(x) || _PDCLIB_GCC_MIN(gccmin, gccmaj))
119
120 #define _PDCLIB_GCC_BUILTIN(x, gccmaj, gccmin) \
121         (_PDCLIB_HAS_BUILTIN(x) || _PDCLIB_GCC_MIN(gccmin, gccmaj))
122
123 #define _PDCLIB_GCC_ATTRIBUTE(x, gccmaj, gccmin) \
124         (_PDCLIB_HAS_ATTRIBUTE(x) || _PDCLIB_GCC_MIN(gccmin, gccmaj))
125
126 /* Extension & Language feature detection */
127
128 #if _PDCLIB_C_VERSION >= 1999 || defined(__cplusplus)
129     #ifndef __cplusplus
130         #define _PDCLIB_restrict restrict
131     #endif
132     #define _PDCLIB_inline   inline
133 #endif
134
135 #if _PDCLIB_CXX_VERSION >= 2011
136   #define _PDCLIB_nothrow     noexcept
137   #define _PDCLIB_noexcept(x) noexcept(x)
138 #elif _PDCLIB_CXX_VERSION
139   #define _PDCLIB_nothrow     throw()
140   #define _PDCLIB_noexcept
141 #endif
142
143 #if _PDCLIB_CXX_VERSION >= 2011 && _PDCLIB_GCC_FEATURE(cxx_attributes, 4, 8)
144     #define _PDCLIB_noreturn [[noreturn]]
145 #elif _PDCLIB_C_VERSION >= 2011 && _PDCLIB_GCC_FEATURE(c_noreturn, 4, 7)
146     #define _PDCLIB_noreturn _Noreturn
147 #endif
148
149 #ifdef _WIN32
150    #define _PDCLIB_EXPORT __declspec(dllexport)
151    #define _PDCLIB_IMPORT __declspec(dllimport)
152 #endif
153
154 #if !defined(_PDCLIB_EXPORT) && _PDCLIB_GCC_ATTRIBUTE(__visibility__, 4, 0)
155     #define _PDCLIB_EXPORT __attribute__((__visibility__("protected")))
156 #endif
157
158 #if !defined(_PDCLIB_HIDDEN) && _PDCLIB_GCC_ATTRIBUTE(__visibility__, 4, 0)
159     #define _PDCLIB_HIDDEN __attribute__((__visibility__("hidden")))
160 #endif
161
162 #if !defined(_PDCLIB_nothrow) && _PDCLIB_GCC_ATTRIBUTE(__nothrow__, 4, 0)
163     #define _PDCLIB_nothrow __attribute__((__nothrow__))
164     #define _PDCLIB_noexcept
165 #endif
166
167 #if !defined(_PDCLIB_restrict) && _PDCLIB_GCC_MIN(3, 0)
168     #define _PDCLIB_restrict __restrict
169 #endif
170
171 #if !defined(_PDCLIB_inline) && _PDCLIB_GCC_MIN(3, 0)
172     #define _PDCLIB_inline __inline
173 #endif
174
175 #if !defined(_PDCLIB_noreturn) && _PDCLIB_GCC_ATTRIBUTE(__noreturn__, 3, 0)
176     /* If you don't use __noreturn__, then stdnoreturn.h will break things! */
177     #define _PDCLIB_noreturn __attribute__((__noreturn__))
178 #endif
179
180 #if !defined(_PDCLIB_DEPRECATED) && _PDCLIB_GCC_ATTRIBUTE(__deprecated__, 3, 0)
181     #define _PDCLIB_DEPRECATED __attribute__ ((__deprecated__))
182 #endif
183
184 #if !defined(_PDCLIB_UNREACHABLE) && _PDCLIB_GCC_BUILTIN(__builtin_unreachable, 4, 0)
185     #define _PDCLIB_UNREACHABLE __builtin_unreachable()
186 #endif
187
188 #if !defined(_PDCLIB_UNDEFINED) && defined(__GNUC__)
189     #define _PDCLIB_UNDEFINED(_var) \
190         do { __asm__("" : "=X"(_var)); } while(0)
191 #endif
192
193 /* No-op fallbacks */
194
195 #ifndef _PDCLIB_nothrow
196   #define _PDCLIB_nothrow
197   #define _PDCLIB_noexcept
198 #endif
199
200 #ifndef _PDCLIB_EXPORT
201     #define _PDCLIB_EXPORT
202 #endif
203 #ifndef _PDCLIB_IMPORT
204     #define _PDCLIB_IMPORT
205 #endif
206 #ifndef _PDCLIB_HIDDEN
207     #define _PDCLIB_HIDDEN
208 #endif
209
210 #if defined(_PDCLIB_SHARED) 
211     #if defined(_PDCLIB_BUILD)
212         #define _PDCLIB_API _PDCLIB_EXPORT
213     #else
214         #define _PDCLIB_API _PDCLIB_IMPORT
215     #endif
216 #else
217     #define _PDCLIB_API
218 #endif
219
220 #ifndef _PDCLIB_restrict
221       #define _PDCLIB_restrict
222 #endif
223
224 #ifndef _PDCLIB_inline
225       #define _PDCLIB_inline
226 #endif
227
228 #ifndef _PDCLIB_noreturn
229       #define _PDCLIB_noreturn
230 #endif
231
232 #ifndef _PDCLIB_DEPRECATED
233     #define _PDCLIB_DEPRECATED
234 #endif
235
236 #ifndef _PDCLIB_UNREACHABLE
237     #define _PDCLIB_UNREACHABLE do {} while(0)
238 #endif
239
240 #ifndef _PDCLIB_UNDEFINED
241     #define _PDCLIB_UNDEFINED(_var) do {} while(0)
242 #endif
243
244 /*#if _PDCLIB_C_VERSION != 1999
245 #error PDCLib might not be fully conforming to either C89 or C95 prior to v2.x.
246 #endif*/
247
248 /* -------------------------------------------------------------------------- */
249 /* Helper macros:                                                             */
250 /* _PDCLIB_cc( x, y ) concatenates two preprocessor tokens without extending  */
251 /* _PDCLIB_concat( x, y ) concatenates two preprocessor tokens with extending */
252 /* -------------------------------------------------------------------------- */
253
254 #define _PDCLIB_cc( x, y )     x ## y
255 #define _PDCLIB_concat( x, y ) _PDCLIB_cc( x, y )
256 #define _PDCLIB_concat3( x, y, z ) _PDCLIB_concat( _PDCLIB_concat( x, y ), z )
257
258 #define _PDCLIB_symbol2value( x ) #x
259 #define _PDCLIB_symbol2string( x ) _PDCLIB_symbol2value( x )
260
261 /* Feature test macros
262  *
263  * All of the feature test macros come in the following forms
264  *   _PDCLIB_*_MIN(min):            Available in versions >= min
265  *   _PDCLIB_*_MINMAX(min, max):    Available in versions >= min <= max
266  *   _PDCLIB_*_MAX(max):            Availabel in versions <= max
267  *
268  * The defined tests are:
269  *   C:     C standard versions 
270  *              1990, 1995, 1999, 2011
271  *   CXX:   C++ standard versions 
272  *              1997, 2011
273  *   POSIX: POSIX extension versions.
274  *              1 (POSIX.2), 2 (POSIX.2), 199309L (POSIX.1b), 
275  *              199506L (POSIX.1c), 200112L (2001), 200809L (2008)
276  *   XOPEN: X/Open System Interface (XSI)/Single Unix Specification
277  *              0 (XPG4), 500 (SUSv2/UNIX98), 600 (SUSv3/UNIX03), 700 (SUSv4)
278  *
279  *   Additionally, the macros
280  *     _BSD_SOURCE, _SVID_SOURCE and _GNU_SOURCE
281  *   are adhered to. If _GNU_SOURCE is defined, _XOPEN_SOURCE and 
282  *   _POSIX_C_SOURCE are defined to their most recent values to match glibc 
283  *   behaviour
284  *
285  *   The intention of supporting these feature test macros is to ease 
286  *   application portability from these systems to PDCLib systems; in addition,
287  *   it eases support for these standards by systems supporting them which are 
288  *   using PDCLib as their default C library.
289  *
290  *   Applications targetting purely PDClib/PDCLib based platforms may define 
291  *   just _PDCLIB_EXTENSIONS, which will enable all supported extensions, plus
292  *   all features from all supported versions of C and C++.
293  *
294  */
295 #define _PDCLIB_C_MIN(min)         _PDCLIB_C_MINMAX(min, 3000)
296 #define _PDCLIB_CXX_MIN(min)     _PDCLIB_CXX_MINMAX(min, 3000)
297 #define _PDCLIB_XOPEN_MIN(min) _PDCLIB_XOPEN_MINMAX(min, 30000000)
298 #define _PDCLIB_POSIX_MIN(min) _PDCLIB_POSIX_MINMAX(min, 30000000)
299 #define _PDCLIB_C_MAX(max)         _PDCLIB_C_MINMAX(0, max)
300 #define _PDCLIB_CXX_MAX(max)     _PDCLIB_CXX_MINMAX(0, max)
301 #define _PDCLIB_XOPEN_MAX(max) _PDCLIB_XOPEN_MINMAX(0, max)
302 #define _PDCLIB_POSIX_MAX(max) _PDCLIB_POSIX_MINMAX(0, max)
303 #if defined(_PDCLIB_EXTENSIONS) || defined(_PDCLIB_BUILD)
304     #define _PDCLIB_C_MINMAX(min, max) 1
305     #define _PDCLIB_CXX_MINMAX(min, max) 1
306     #define _PDCLIB_POSIX_MINMAX(min, max) 1
307     #define _PDCLIB_XOPEN_MINMAX(min, max) 1
308
309     #undef _PDCLIB_EXTENSIONS
310     #undef _PDCLIB_BSD_SOURCE 
311     #undef _PDCLIB_SVID_SOURCE
312     #undef _PDCLIB_GNU_SOURCE
313
314     #define _PDCLIB_EXTENSIONS 1
315     #define _PDCLIB_BSD_SOURCE 1
316     #define _PDCLIB_SVID_SOURCE 1
317     #define _PDCLIB_GNU_SOURCE 1
318 #else
319     #define _PDCLIB_C_MINMAX(min, max) \
320         (_PDCLIB_C_VERSION >= (min) && _PDCLIB_C_VERSION <= (max))
321     #define _PDCLIB_CXX_MINMAX(min, max) \
322         (_PDCLIB_CXX_VERSION >= (min) && _PDCLIB_CXX_VERSION <= (max))
323     #define _PDCLIB_XOPEN_MINMAX(min, max) \
324         (defined(_XOPEN_SOURCE) \
325             && _XOPEN_SOURCE >= (min) && _XOPEN_SOURCE <= (max))
326     #define _PDCLIB_POSIX_MINMAX(min, max) \
327         (defined(_POSIX_C_SOURCE) \
328             && _POSIX_C_SOURCE >= (min) && _POSIX_C_SOURCE <= (max))
329
330     #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE-1 == -1)
331         /* If _XOPEN_SOURCE is defined as empty, redefine here as zero */
332         #undef _XOPEN_SOURCE
333         #define _XOPEN_SOURCE 0
334     #endif
335
336     #if defined(_GNU_SOURCE)
337         #define _PDCLIB_GNU_SOURCE 1
338         #define _PDCLIB_SVID_SOURCE 1
339         #define _PDCLIB_BSD_SOURCE 1
340         #undef _XOPEN_SOURCE
341         #define _XOPEN_SOURCE 700
342     #else
343         #define _PDCLIB_GNU_SOURCE 0
344     #endif
345
346     #if defined(_PDCLIB_BSD_SOURCE)
347         // pass
348     #elif defined(_BSD_SOURCE)
349         #define _PDCLIB_BSD_SOURCE 1
350     #else
351         #define _PDCLIB_BSD_SOURCE 0
352     #endif
353
354     #if defined(_PDCLIB_SVID_SOURCE)
355         // pass
356     #elif defined(_SVID_SOURCE)
357         #define _PDCLIB_SVID_SOURCE 1
358     #else
359         #define _PDCLIB_SVID_SOURCE 0
360     #endif
361
362     #if _PDCLIB_XOPEN_MIN(700) && !_PDCLIB_POSIX_MIN(200809L)
363         #undef _POSIX_C_SOURCE
364         #define _POSIX_C_SOURCE 2008098L    
365     #elif _PDCLIB_XOPEN_MIN(600) && !_PDCLIB_POSIX_MIN(200112L)
366         #undef _POSIX_C_SOURCE
367         #define _POSIX_C_SOURCE 200112L
368     #elif _PDCLIB_XOPEN_MIN(0) && !_PDCLIB_POSIX_MIN(2)
369         #undef _POSIX_C_SOURCE
370         #define _POSIX_C_SOURCE 2
371     #endif
372
373     #if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
374         #define _POSIX_C_SOURCE 1
375     #endif
376 #endif
377
378 #endif