Do not use pthreads on 3DS.
[SquirrelJME.git] / nanocoat / include / sjme / config.h
blob1db8f5f2926cad2b90a2b08fa4f3d6d2047e8d84
1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // SquirrelJME
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
10 /**
11 * Basic configuration header.
13 * @since 2023/07/27
16 #ifndef SQUIRRELJME_CONFIG_H
17 #define SQUIRRELJME_CONFIG_H
19 #include <stddef.h>
21 /* Anti-C++. */
22 #ifdef __cplusplus
23 #ifndef SJME_CXX_IS_EXTERNED
24 #define SJME_CXX_IS_EXTERNED
25 #define SJME_CXX_SQUIRRELJME_CONFIG_H
26 extern "C" {
27 #endif /* #ifdef SJME_CXX_IS_EXTERNED */
28 #endif /* #ifdef __cplusplus */
30 /*--------------------------------------------------------------------------*/
32 #if !defined(SJME_CONFIG_RELEASE) && !defined(SJME_CONFIG_DEBUG)
33 #if (defined(DEBUG) || defined(_DEBUG)) || \
34 (!defined(NDEBUG) && !defined(_NDEBUG))
35 /** Debug build. */
36 #define SJME_CONFIG_DEBUG
37 #else
38 /** Release build. */
39 #define SJME_CONFIG_RELEASE
40 #endif
41 #elif defined(SJME_CONFIG_RELEASE) && defined(SJME_CONFIG_DEBUG)
42 #undef SJME_CONFIG_RELEASE
43 #endif
45 /* The current operating system. */
46 #if defined(__3DS__)
47 /** Nintendo 3DS is available. */
48 #define SJME_CONFIG_HAS_NINTENDO_3DS
49 #elif defined(__linux__) || defined(linux) || defined(__linux)
50 /** Linux is available. */
51 #define SJME_CONFIG_HAS_LINUX
52 #elif defined(__CYGWIN__)
53 /** Cygwin is available. */
54 #define SJME_CONFIG_HAS_CYGWIN
55 #elif defined(_WIN32) || defined(__WIN32__) || \
56 defined(__WIN32) || defined(_WINDOWS)
57 /** Windows is available. */
58 #define SJME_CONFIG_HAS_WINDOWS
59 #elif defined(__APPLE__) && defined(__MACH__)
60 /** macOS 10+ is available. */
61 #define SJME_CONFIG_HAS_MACOS
62 #elif defined(macintosh)
63 /** macOS Classic is available. */
64 #define SJME_CONFIG_HAS_MACOS_CLASSIC
65 #elif defined(__palmos__)
66 /** PalmOS is available. */
67 #define SJME_CONFIG_HAS_PALMOS
68 #elif defined(__FreeBSD__) || defined(__NetBSD__) || \
69 defined(__OpenBSD__) || defined(__bsdi__) || \
70 defined(__DragonFly__) || defined(__MidnightBSD__)
71 /** BSD is available. */
72 #define SJME_CONFIG_HAS_BSD
73 #elif defined(__BEOS__) || defined(__HAIKU__)
74 /** BeOS/Haiku is available. */
75 #define SJME_CONFIG_HAS_BEOS
76 #endif
78 /** Possibly detect endianess. */
79 #if !defined(SJME_CONFIG_HAS_BIG_ENDIAN) && \
80 !defined(SJME_CONFIG_HAS_LITTLE_ENDIAN)
81 /** Defined by the system? */
82 #if !defined(SJME_CONFIG_HAS_BIG_ENDIAN)
83 #if defined(__BYTE_ORDER__) && \
84 (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
85 #define SJME_CONFIG_HAS_BIG_ENDIAN
86 #endif
87 #endif
89 /** Just set little endian if no endianess was defined */
90 #if !defined(SJME_CONFIG_HAS_BIG_ENDIAN) && \
91 !defined(SJME_CONFIG_HAS_LITTLE_ENDIAN)
92 #define SJME_CONFIG_HAS_LITTLE_ENDIAN
93 #endif
95 /** If both are defined, just set big endian. */
96 #if defined(SJME_CONFIG_HAS_BIG_ENDIAN) && \
97 defined(SJME_CONFIG_HAS_LITTLE_ENDIAN)
98 #undef SJME_CONFIG_HAS_LITTLE_ENDIAN
99 #endif
100 #endif
102 /* Attempt detection of pointer sizes based on architecture? */
103 #if (defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 4) || \
104 defined(_ILP32) || defined(__ILP32__)
105 /** Pointer size. */
106 #define SJME_CONFIG_HAS_POINTER 32
107 #elif (defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8) || \
108 defined(_LP64) || defined(_LP64)
109 /** Pointer size. */
110 #define SJME_CONFIG_HAS_POINTER 64
111 #else
112 /* 64-bit seeming architecture, common 64-bit ones? */
113 #if defined(__amd64__) || defined(__amd64__) || defined(__x86_64__) || \
114 defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) || \
115 defined(_M_ARM64) || defined(_M_ARM64EC) || \
116 defined(__aarch64__) || defined(__ia64__) || defined(_IA64) || \
117 defined(__IA64__) || defined(__ia64) || defined(_M_IA64) || \
118 defined(__itanium__) || defined(__powerpc64__) || \
119 defined(__ppc64__) || defined(__PPC64__) || defined(_ARCH_PPC64) || \
120 defined(_WIN64)
121 /** Pointer size. */
122 #define SJME_CONFIG_HAS_POINTER 64
123 #else
124 /** Pointer size. */
125 #define SJME_CONFIG_HAS_POINTER 32
126 #endif
127 #endif
129 #if SJME_CONFIG_HAS_POINTER == 32
130 /** Has 32-bit pointer. */
131 #define SJME_CONFIG_HAS_POINTER32
132 #endif
134 #if SJME_CONFIG_HAS_POINTER == 64
135 /** Has 64-bit pointer. */
136 #define SJME_CONFIG_HAS_POINTER64
137 #endif
139 #if defined(SJME_CONFIG_ROM0)
140 /** ROM 0 Address. */
141 #define SJME_CONFIG_ROM0_ADDR &SJME_CONFIG_ROM0
142 #elif !defined(SJME_CONFIG_ROM0_ADDR)
143 /** ROM 0 Address. */
144 #define SJME_CONFIG_ROM0_ADDR NULL
145 #endif
147 #if defined(SJME_CONFIG_ROM1)
148 /** ROM 1 Address. */
149 #define SJME_CONFIG_ROM1_ADDR &SJME_CONFIG_ROM1
150 #elif !defined(SJME_CONFIG_ROM1_ADDR)
151 /** ROM 1 Address. */
152 #define SJME_CONFIG_ROM1_ADDR NULL
153 #endif
155 #if defined(SJME_CONFIG_ROM2)
156 /** ROM 2 Address. */
157 #define SJME_CONFIG_ROM2_ADDR &SJME_CONFIG_ROM2
158 #elif !defined(SJME_CONFIG_ROM2_ADDR)
159 /** ROM 2 Address. */
160 #define SJME_CONFIG_ROM2_ADDR NULL
161 #endif
163 #if defined(SJME_CONFIG_ROM3)
164 /** ROM 3 Address. */
165 #define SJME_CONFIG_ROM3_ADDR &SJME_CONFIG_ROM3
166 #elif !defined(SJME_CONFIG_ROM3_ADDR)
167 /** ROM 3 Address. */
168 #define SJME_CONFIG_ROM3_ADDR NULL
169 #endif
171 #if defined(SJME_CONFIG_ROM4)
172 /** ROM 4 Address. */
173 #define SJME_CONFIG_ROM4_ADDR &SJME_CONFIG_ROM4
174 #elif !defined(SJME_CONFIG_ROM4_ADDR)
175 /** ROM 4 Address. */
176 #define SJME_CONFIG_ROM4_ADDR NULL
177 #endif
179 #if defined(SJME_CONFIG_ROM5)
180 /** ROM 5 Address. */
181 #define SJME_CONFIG_ROM5_ADDR &SJME_CONFIG_ROM5
182 #elif !defined(SJME_CONFIG_ROM5_ADDR)
183 /** ROM 5 Address. */
184 #define SJME_CONFIG_ROM5_ADDR NULL
185 #endif
187 #if defined(SJME_CONFIG_ROM6)
188 /** ROM 6 Address. */
189 #define SJME_CONFIG_ROM6_ADDR &SJME_CONFIG_ROM6
190 #elif !defined(SJME_CONFIG_ROM6_ADDR)
191 /** ROM 6 Address. */
192 #define SJME_CONFIG_ROM6_ADDR NULL
193 #endif
195 #if defined(SJME_CONFIG_ROM7)
196 /** ROM 7 Address. */
197 #define SJME_CONFIG_ROM7_ADDR &SJME_CONFIG_ROM7
198 #elif !defined(SJME_CONFIG_ROM7_ADDR)
199 /** ROM 7 Address. */
200 #define SJME_CONFIG_ROM7_ADDR NULL
201 #endif
203 #if defined(SJME_CONFIG_ROM8)
204 /** ROM 8 Address. */
205 #define SJME_CONFIG_ROM8_ADDR &SJME_CONFIG_ROM8
206 #elif !defined(SJME_CONFIG_ROM8_ADDR)
207 /** ROM 8 Address. */
208 #define SJME_CONFIG_ROM8_ADDR NULL
209 #endif
211 #if defined(SJME_CONFIG_ROM9)
212 /** ROM 9 Address. */
213 #define SJME_CONFIG_ROM9_ADDR &SJME_CONFIG_ROM9
214 #elif !defined(SJME_CONFIG_ROM9_ADDR)
215 /** ROM 9 Address. */
216 #define SJME_CONFIG_ROM9_ADDR NULL
217 #endif
219 /* C99 supports flexible array members. */
220 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
221 /** Flexible array members. */
222 #define sjme_flexibleArrayCount
223 #endif
225 /* Visual C++. */
226 #if defined(_MSC_VER)
227 #include <sal.h>
229 /** Return value must be checked. */
230 #define sjme_attrCheckReturn _Must_inspect_result_
232 /** Deprecated. */
233 #define sjme_attrDeprecated __declspec(deprecated)
235 /** Formatted string argument. */
236 #define sjme_attrFormatArg _Printf_format_string_
238 /** Input cannot be null. */
239 #define sjme_attrInNotNull _In_
241 /** Input can be null. */
242 #define sjme_attrInNullable _In_opt_
244 /** Takes input and produces output. */
245 #define sjme_attrInOutNotNull _In_opt_ _Out_opt_
247 /** Input value range. */
248 #define sjme_attrInRange(lo, hi) _In_range_((lo), (hi))
250 /** Method takes input. */
251 #define sjme_attrInValue _In_
253 /** Does not return. */
254 #define sjme_attrReturnNever _Always_(_Raises_SEH_exception_)
256 /** Returns nullable value. */
257 #define sjme_attrReturnNullable _Outptr_result_maybenull_z_
259 /** Method gives output. */
260 #define sjme_attrOutNotNull _Out_
262 /** Method output can be null. */
263 #define sjme_attrOutNullable _Out_opt_
265 /** Output to buffer. */
266 #define sjme_attrOutNotNullBuf(lenArg) _Out_writes_(lenArg)
268 /** Output value range. */
269 #define sjme_attrOutRange(lo, hi) _Out_range_((lo), (hi))
271 #if !defined(sjme_flexibleArrayCount)
272 /** Flexible array count, MSVC requires 1 because C2233. */
273 #define sjme_flexibleArrayCount 1
274 #endif
276 #if !defined(sjme_flexibleArrayCountUnion)
277 /** Flexible array count for union, MSVC requires 1 because C2233. */
278 #define sjme_flexibleArrayCountUnion 1
279 #endif
281 /** Allocate on the stack. */
282 #define sjme_alloca(size) _alloca((size))
283 #elif defined(__clang__) || defined(__GNUC__)
284 /* Clang has special analyzer stuff, but also same as GCC otherwise. */
285 #if defined(__clang__)
286 #if __has_feature(attribute_analyzer_noreturn)
287 /** Method does not return. */
288 #define sjme_attrReturnNever __attribute__((analyzer_noreturn))
289 #endif
291 /** Returns nullable value. */
292 #define sjme_attrReturnNullable _Nullable_result
293 #endif
295 #if !defined(sjme_attrReturnNever)
296 #if defined(__builtin_unreachable)
297 /** Function never returns. */
298 #define sjme_attrReturnNever (__builtin_unreachable())
299 #endif
300 #endif
302 /** Artificial function. */
303 #define sjme_attrArtificial __attribute__((artificial))
305 /** Check return value. */
306 #define sjme_attrCheckReturn __attribute__((warn_unused_result))
308 /** Deprecated. */
309 #define sjme_attrDeprecated __attribute__((deprecated))
312 * Formatted string.
314 * @param formatIndex The formatted string index.
315 * @param vaIndex The index of @c ... or @c va_list .
316 * @since 2023/08/05
318 #define sjme_attrFormatOuter(formatIndex, vaIndex) \
319 __attribute__((format(__printf__, formatIndex + 1, vaIndex + 1)))
321 /** Indicates a callback. */
322 #define sjme_attrCallback __attribute__((callback))
324 /** Not used. */
325 #define sjme_attrUnused __attribute__((unused))
327 /** Not used enum constant. */
328 #define sjme_attrUnusedEnum(x) x sjme_attrUnused
330 #if !defined(sjme_attrReturnNever)
331 /** Method does not return. */
332 #define sjme_attrReturnNever __attribute__((noreturn))
333 #endif
335 #if !defined(sjme_flexibleArrayCount)
336 /** Flexible array size count, GCC is fine with blank. */
337 #define sjme_flexibleArrayCount
338 #endif
339 #endif
341 #if !defined(sjme_attrCallback)
342 /** Indicates a callback. */
343 #define sjme_attrCallback
344 #endif
346 #if !defined(sjme_attrCheckReturn)
347 /** Return value must be checked. */
348 #define sjme_attrCheckReturn
349 #endif
351 #if !defined(sjme_attrDeprecated)
352 /** Deprecated. */
353 #define sjme_attrDeprecated
354 #endif
356 #if !defined(sjme_attrFormatArg)
357 /** Formatted string argument. */
358 #define sjme_attrFormatArg
359 #endif
361 #if !defined(sjme_attrFormatOuter)
363 * Formatted string.
365 * @param formatIndex The formatted string index.
366 * The index of @c ... or @c va_list .
367 * @since 2023/08/05
369 #define sjme_attrFormatOuter(formatIndex, vaIndex)
370 #endif
372 #if !defined(sjme_attrInValue)
373 /** Method takes input. */
374 #define sjme_attrInValue
375 #endif
377 #if !defined(sjme_attrInRange)
378 /** Input value range. */
379 #define sjme_attrInRange(lo, hi)
380 #endif
382 #if !defined(sjme_attrReturnNever)
383 /** Method does not return. */
384 #define sjme_attrReturnNever
385 #endif
387 #if !defined(sjme_attrReturnNullable)
388 /** Returns a nullable value. */
389 #define sjme_attrReturnNullable
390 #endif
392 #if !defined(sjme_attrInValue)
393 /** Takes input value. */
394 #define sjme_attrInValue
395 #endif
397 #if !defined(sjme_attrInNotNull)
398 /** Cannot be null. */
399 #define sjme_attrInNotNull sjme_attrInValue
400 #endif
402 #if !defined(sjme_attrInNullable)
403 /** Nullable. */
404 #define sjme_attrInNullable sjme_attrInValue
405 #endif
407 #if !defined(sjme_attrOutNotNull)
408 /** Method gives output. */
409 #define sjme_attrOutNotNull sjme_attrInNotNull
410 #endif
412 #if !defined(sjme_attrOutNullable)
413 /** Method output can be null. */
414 #define sjme_attrOutNullable sjme_attrInNullable
415 #endif
417 #if !defined(sjme_attrInOutNotNull)
418 /** Takes input and produces output. */
419 #define sjme_attrInOutNotNull sjme_attrInNotNull sjme_attrOutNotNull
420 #endif
422 #if !defined(sjme_attrOutNotNullBuf)
423 /** Output to buffer. */
424 #define sjme_attrOutNotNullBuf(lenArg) sjme_attrOutNotNull
425 #endif
427 #if !defined(sjme_attrOutRange)
428 /** Output value range. */
429 #define sjme_attrOutRange(lo, hi)
430 #endif
432 /** Positive value. */
433 #define sjme_attrInPositive sjme_attrInRange(0, INT32_MAX)
435 /** Non-zero positive value. */
436 #define sjme_attrInPositiveNonZero sjme_attrInRange(1, INT32_MAX)
438 /** Negative one to positive. */
439 #define sjme_attrInNegativeOnePositive sjme_attrInRange(-1, INT32_MAX)
441 /** Positive value. */
442 #define sjme_attrOutPositive sjme_attrOutRange(0, INT32_MAX)
444 /** Non-zero positive value. */
445 #define sjme_attrOutPositiveNonZero sjme_attrOutRange(1, INT32_MAX)
447 /** Negative one to positive. */
448 #define sjme_attrOutNegativeOnePositive sjme_attrOutRange(-1, INT32_MAX)
450 #if !defined(sjme_flexibleArrayCount)
451 /** Flexible array count, zero by default. */
452 #define sjme_flexibleArrayCount 0
453 #endif
455 #if !defined(sjme_flexibleArrayCountUnion)
456 /** Flexible array count but for unions. */
457 #define sjme_flexibleArrayCountUnion 0
458 #endif
460 #if !defined(sjme_attrUnused)
461 /** Unused value. */
462 #define sjme_attrUnused
463 #endif
465 #if !defined(sjme_attrUnusedEnum)
466 /** Unused enumeration element. */
467 #define sjme_attrUnusedEnum(x) x
468 #endif
470 #if !defined(sjme_attrArtificial)
471 /** Artificial function. */
472 #define sjme_attrArtificial
473 #endif
475 #if !defined(sjme_alloca)
476 /** Allocate on the stack. */
477 #define sjme_alloca(size) alloca((size))
478 #endif
480 #if !defined(sjme_inline)
481 /** Inline function. */
482 #define sjme_inline inline
483 #endif
485 #if defined(__GNUC__)
486 /** GNU C Compiler. */
487 #define SJME_CONFIG_HAS_GCC
488 #endif
490 #if defined(SJME_CONFIG_HAS_WINDOWS)
491 /** Supports Windows Atomic Access. */
492 #define SJME_CONFIG_HAS_ATOMIC_WIN32
493 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && \
494 !defined(__STDC_NO_ATOMICS__)
495 /** Supports C11 atomics. */
496 #define SJME_CONFIG_HAS_ATOMIC_C11
497 #elif defined(SJME_CONFIG_HAS_GCC)
498 /** GCC Atomics. */
499 #define SJME_CONFIG_HAS_ATOMIC_GCC
500 #endif
502 #if !defined(SJME_CONFIG_HAS_ATOMIC)
503 #if defined(SJME_CONFIG_HAS_ATOMIC_WIN32) || \
504 defined(SJME_CONFIG_HAS_ATOMIC_C11) || \
505 defined(SJME_CONFIG_HAS_ATOMIC_GCC)
506 /** Atomics are supported. */
507 #define SJME_CONFIG_HAS_ATOMIC
508 #else
509 /** Use old atomic handling. */
510 #define SJME_CONFIG_HAS_ATOMIC_OLD
512 /** Atomics are supported. */
513 #define SJME_CONFIG_HAS_ATOMIC
514 #endif
515 #endif
517 #if defined(SJME_CONFIG_HAS_LINUX) || \
518 defined(SJME_CONFIG_HAS_BSD) || \
519 defined(SJME_CONFIG_HAS_BEOS)
520 /** Dynamic library path name as static define. */
521 #define SJME_CONFIG_DYLIB_PATHNAME(x) \
522 "lib" x ".so"
523 #elif defined(SJME_CONFIG_HAS_CYGWIN)
524 /** Dynamic library path name as static define. */
525 #define SJME_CONFIG_DYLIB_PATHNAME(x) \
526 "lib" x ".dll"
527 #elif defined(SJME_CONFIG_HAS_WINDOWS)
528 /** Dynamic library path name as static define. */
529 #define SJME_CONFIG_DYLIB_PATHNAME(x) \
530 "" x ".dll"
531 #elif defined(SJME_CONFIG_HAS_MACOS)
532 /** Dynamic library path name as static define. */
533 #define SJME_CONFIG_DYLIB_PATHNAME(x) \
534 "lib" x ".dylib"
535 #else
536 /** Dynamic library path name as static define. */
537 #define SJME_CONFIG_DYLIB_PATHNAME(x) NULL
538 #endif
540 /* Nintendo 3DS: devkitPro has broken/unimplemented pthreads. */
541 #if defined(SJME_CONFIG_HAS_NINTENDO_3DS)
542 /** Use fallback threading regardless of the system. */
543 #define SJME_CONFIG_HAS_THREADS_FALLBACK
544 #endif
546 /*--------------------------------------------------------------------------*/
548 /* Anti-C++. */
549 #ifdef __cplusplus
550 #ifdef SJME_CXX_SQUIRRELJME_CONFIG_H
552 #undef SJME_CXX_SQUIRRELJME_CONFIG_H
553 #undef SJME_CXX_IS_EXTERNED
554 #endif /* #ifdef SJME_CXX_SQUIRRELJME_CONFIG_H */
555 #endif /* #ifdef __cplusplus */
557 #endif /* SQUIRRELJME_CONFIG_H */