1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
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 // -------------------------------------------------------------------------*/
11 * Basic configuration header.
16 #ifndef SQUIRRELJME_CONFIG_H
17 #define SQUIRRELJME_CONFIG_H
23 #ifndef SJME_CXX_IS_EXTERNED
24 #define SJME_CXX_IS_EXTERNED
25 #define SJME_CXX_SQUIRRELJME_CONFIG_H
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))
36 #define SJME_CONFIG_DEBUG
39 #define SJME_CONFIG_RELEASE
41 #elif defined(SJME_CONFIG_RELEASE) && defined(SJME_CONFIG_DEBUG)
42 #undef SJME_CONFIG_RELEASE
45 /* The current operating system. */
46 #if defined(__EMSCRIPTEN__) || defined(EMSCRIPTEN)
47 /** Emscripten (WASM). */
48 #define SJME_CONFIG_HAS_EMSCRIPTEN
49 #elif defined(__3DS__) || defined(_3DS)
50 /** Nintendo 3DS is available. */
51 #define SJME_CONFIG_HAS_NINTENDO_3DS
52 #elif defined(__linux__) || defined(linux) || defined(__linux)
53 /** Linux is available. */
54 #define SJME_CONFIG_HAS_LINUX
55 #elif defined(__CYGWIN__)
56 /** Cygwin is available. */
57 #define SJME_CONFIG_HAS_CYGWIN
58 #elif defined(_WIN16) || defined(__WIN16__) || defined(__WIN16)
59 /** Using Windows 16-bit. */
60 #define SJME_CONFIG_HAS_WINDOWS_16
62 /** Windows is available however. */
63 #define SJME_CONFIG_HAS_WINDOWS 16
64 #elif defined(_WIN32) || defined(__WIN32__) || \
65 defined(__WIN32) || defined(_WINDOWS)
66 /** Using Windows 32-bit. */
67 #define SJME_CONFIG_HAS_WINDOWS_32
69 /** Windows is available. */
70 #define SJME_CONFIG_HAS_WINDOWS 32
71 #elif defined(__APPLE__) && defined(__MACH__)
72 /** macOS 10+ is available. */
73 #define SJME_CONFIG_HAS_MACOS
74 #elif defined(macintosh)
75 /** macOS Classic is available. */
76 #define SJME_CONFIG_HAS_MACOS_CLASSIC
77 #elif defined(__palmos__)
78 /** PalmOS is available. */
79 #define SJME_CONFIG_HAS_PALMOS
80 #elif defined(__FreeBSD__) || defined(__NetBSD__) || \
81 defined(__OpenBSD__) || defined(__bsdi__) || \
82 defined(__DragonFly__) || defined(__MidnightBSD__)
83 /** BSD is available. */
84 #define SJME_CONFIG_HAS_BSD
85 #elif defined(__BEOS__) || defined(__HAIKU__)
86 /** BeOS/Haiku is available. */
87 #define SJME_CONFIG_HAS_BEOS
90 /** Possibly detect endianess. */
91 #if !defined(SJME_CONFIG_HAS_BIG_ENDIAN) && \
92 !defined(SJME_CONFIG_HAS_LITTLE_ENDIAN)
93 /** Defined by the system? */
94 #if !defined(SJME_CONFIG_HAS_BIG_ENDIAN)
95 #if defined(__BYTE_ORDER__) && \
96 (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
97 #define SJME_CONFIG_HAS_BIG_ENDIAN
101 /** Just set little endian if no endianess was defined */
102 #if !defined(SJME_CONFIG_HAS_BIG_ENDIAN) && \
103 !defined(SJME_CONFIG_HAS_LITTLE_ENDIAN)
104 #define SJME_CONFIG_HAS_LITTLE_ENDIAN
107 /** If both are defined, just set big endian. */
108 #if defined(SJME_CONFIG_HAS_BIG_ENDIAN) && \
109 defined(SJME_CONFIG_HAS_LITTLE_ENDIAN)
110 #undef SJME_CONFIG_HAS_LITTLE_ENDIAN
114 #if defined(__amd64__) || defined(__amd64__) || defined(__x86_64__) || \
115 defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
117 #define SJME_CONFIG_HAS_ARCH_AMD64
118 #elif defined(_M_ARM64) || defined(_M_ARM64EC) || defined(__aarch64__)
120 #define SJME_CONFIG_HAS_ARCH_ARM64
121 #elif defined(__ia64__) || defined(_IA64) || \
122 defined(__IA64__) || defined(__ia64) || defined(_M_IA64) || \
125 #define SJME_CONFIG_HAS_ARCH_IA64
126 #elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \
129 #define SJME_CONFIG_HAS_ARCH_POWERPC 32
131 /** Has PowerPC 64-bit. */
132 #define SJME_CONFIG_HAS_ARCH_POWERPC_64
133 #elif defined(_M_PPC) || defined(__powerpc) || defined(__powerpc__) || \
134 defined(__POWERPC__) || defined(__ppc__) || \
135 defined(__PPC__) || defined(_ARCH_PPC)
137 #define SJME_CONFIG_HAS_ARCH_POWERPC 32
139 /** Has PowerPC 32-bit. */
140 #define SJME_CONFIG_HAS_ARCH_POWERPC_32
141 #elif defined(_M_I86) || defined(_M_IX86) || defined(__X86__) || \
142 defined(_X86_) || defined(__I86__) || defined(__i386) || \
143 defined(__i386__) || defined(__i486__) || defined(__i586__) || \
145 /** Has Intel 32-bit (x86). */
146 #define SJME_CONFIG_HAS_ARCH_IA32
149 /* Attempt detection of pointer sizes based on architecture? */
150 #if (defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 4) || \
151 defined(_ILP32) || defined(__ILP32__)
153 #define SJME_CONFIG_HAS_POINTER 32
154 #elif (defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8) || \
155 defined(_LP64) || defined(_LP64)
157 #define SJME_CONFIG_HAS_POINTER 64
159 /* 64-bit seeming architecture, common 64-bit ones? */
160 #if defined(SJME_CONFIG_HAS_ARCH_AMD64) || \
161 defined(SJME_CONFIG_HAS_ARCH_ARM64) || \
162 defined(SJME_CONFIG_HAS_ARCH_IA64) || \
163 defined(SJME_CONFIG_HAS_ARCH_POWERPC_64) || \
166 #define SJME_CONFIG_HAS_POINTER 64
169 #define SJME_CONFIG_HAS_POINTER 32
173 #if SJME_CONFIG_HAS_POINTER == 32
174 /** Has 32-bit pointer. */
175 #define SJME_CONFIG_HAS_POINTER32
178 #if SJME_CONFIG_HAS_POINTER == 64
179 /** Has 64-bit pointer. */
180 #define SJME_CONFIG_HAS_POINTER64
183 #if defined(SJME_CONFIG_ROM0)
184 /** ROM 0 Address. */
185 #define SJME_CONFIG_ROM0_ADDR &SJME_CONFIG_ROM0
186 #elif !defined(SJME_CONFIG_ROM0_ADDR)
187 /** ROM 0 Address. */
188 #define SJME_CONFIG_ROM0_ADDR NULL
191 #if defined(SJME_CONFIG_ROM1)
192 /** ROM 1 Address. */
193 #define SJME_CONFIG_ROM1_ADDR &SJME_CONFIG_ROM1
194 #elif !defined(SJME_CONFIG_ROM1_ADDR)
195 /** ROM 1 Address. */
196 #define SJME_CONFIG_ROM1_ADDR NULL
199 #if defined(SJME_CONFIG_ROM2)
200 /** ROM 2 Address. */
201 #define SJME_CONFIG_ROM2_ADDR &SJME_CONFIG_ROM2
202 #elif !defined(SJME_CONFIG_ROM2_ADDR)
203 /** ROM 2 Address. */
204 #define SJME_CONFIG_ROM2_ADDR NULL
207 #if defined(SJME_CONFIG_ROM3)
208 /** ROM 3 Address. */
209 #define SJME_CONFIG_ROM3_ADDR &SJME_CONFIG_ROM3
210 #elif !defined(SJME_CONFIG_ROM3_ADDR)
211 /** ROM 3 Address. */
212 #define SJME_CONFIG_ROM3_ADDR NULL
215 #if defined(SJME_CONFIG_ROM4)
216 /** ROM 4 Address. */
217 #define SJME_CONFIG_ROM4_ADDR &SJME_CONFIG_ROM4
218 #elif !defined(SJME_CONFIG_ROM4_ADDR)
219 /** ROM 4 Address. */
220 #define SJME_CONFIG_ROM4_ADDR NULL
223 #if defined(SJME_CONFIG_ROM5)
224 /** ROM 5 Address. */
225 #define SJME_CONFIG_ROM5_ADDR &SJME_CONFIG_ROM5
226 #elif !defined(SJME_CONFIG_ROM5_ADDR)
227 /** ROM 5 Address. */
228 #define SJME_CONFIG_ROM5_ADDR NULL
231 #if defined(SJME_CONFIG_ROM6)
232 /** ROM 6 Address. */
233 #define SJME_CONFIG_ROM6_ADDR &SJME_CONFIG_ROM6
234 #elif !defined(SJME_CONFIG_ROM6_ADDR)
235 /** ROM 6 Address. */
236 #define SJME_CONFIG_ROM6_ADDR NULL
239 #if defined(SJME_CONFIG_ROM7)
240 /** ROM 7 Address. */
241 #define SJME_CONFIG_ROM7_ADDR &SJME_CONFIG_ROM7
242 #elif !defined(SJME_CONFIG_ROM7_ADDR)
243 /** ROM 7 Address. */
244 #define SJME_CONFIG_ROM7_ADDR NULL
247 #if defined(SJME_CONFIG_ROM8)
248 /** ROM 8 Address. */
249 #define SJME_CONFIG_ROM8_ADDR &SJME_CONFIG_ROM8
250 #elif !defined(SJME_CONFIG_ROM8_ADDR)
251 /** ROM 8 Address. */
252 #define SJME_CONFIG_ROM8_ADDR NULL
255 #if defined(SJME_CONFIG_ROM9)
256 /** ROM 9 Address. */
257 #define SJME_CONFIG_ROM9_ADDR &SJME_CONFIG_ROM9
258 #elif !defined(SJME_CONFIG_ROM9_ADDR)
259 /** ROM 9 Address. */
260 #define SJME_CONFIG_ROM9_ADDR NULL
263 /* C99 supports flexible array members. */
264 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
265 /** Flexible array members. */
266 #define sjme_flexibleArrayCount
270 #if defined(_MSC_VER)
273 /** Return value must be checked. */
274 #define sjme_attrCheckReturn _Must_inspect_result_
277 #define sjme_attrDeprecated __declspec(deprecated)
279 /** Formatted string argument. */
280 #define sjme_attrFormatArg _Printf_format_string_
282 /** Input cannot be null. */
283 #define sjme_attrInNotNull _In_
285 /** Input can be null. */
286 #define sjme_attrInNullable _In_opt_
288 /** Takes input and produces output. */
289 #define sjme_attrInOutNotNull _In_opt_ _Out_opt_
291 /** Input value range. */
292 #define sjme_attrInRange(lo, hi) _In_range_((lo), (hi))
294 /** Method takes input. */
295 #define sjme_attrInValue _In_
297 /** Does not return. */
298 #define sjme_attrReturnNever _Always_(_Raises_SEH_exception_)
300 /** Returns nullable value. */
301 #define sjme_attrReturnNullable _Outptr_result_maybenull_z_
303 /** Method gives output. */
304 #define sjme_attrOutNotNull _Out_
306 /** Method output can be null. */
307 #define sjme_attrOutNullable _Out_opt_
309 /** Output to buffer. */
310 #define sjme_attrOutNotNullBuf(lenArg) _Out_writes_(lenArg)
312 /** Output value range. */
313 #define sjme_attrOutRange(lo, hi) _Out_range_((lo), (hi))
315 #if !defined(sjme_flexibleArrayCount)
316 /** Flexible array count, MSVC requires 1 because C2233. */
317 #define sjme_flexibleArrayCount 1
320 #if !defined(sjme_flexibleArrayCountUnion)
321 /** Flexible array count for union, MSVC requires 1 because C2233. */
322 #define sjme_flexibleArrayCountUnion 1
325 /** Allocate on the stack. */
326 #define sjme_alloca(size) _alloca((size))
327 #elif defined(__clang__) || defined(__GNUC__)
328 /* Clang has special analyzer stuff, but also same as GCC otherwise. */
329 #if defined(__clang__)
330 #if __has_feature(attribute_analyzer_noreturn)
331 /** Method does not return. */
332 #define sjme_attrReturnNever __attribute__((analyzer_noreturn))
335 /** Returns nullable value. */
336 #define sjme_attrReturnNullable _Nullable_result
339 #if !defined(sjme_attrReturnNever)
340 #if defined(__builtin_unreachable)
341 /** Function never returns. */
342 #define sjme_attrReturnNever (__builtin_unreachable())
346 /** Artificial function. */
347 #define sjme_attrArtificial __attribute__((artificial))
349 /** Check return value. */
350 #define sjme_attrCheckReturn __attribute__((warn_unused_result))
353 #define sjme_attrDeprecated __attribute__((deprecated))
355 /** Disable optimization. */
356 #define sjme_noOptimize __attribute__((optimize("O0")))
361 * @param formatIndex The formatted string index.
362 * @param vaIndex The index of @c ... or @c va_list .
365 #define sjme_attrFormatOuter(formatIndex, vaIndex) \
366 __attribute__((format(__printf__, formatIndex + 1, vaIndex + 1)))
368 /** Indicates a callback. */
369 #define sjme_attrCallback __attribute__((callback))
372 #define sjme_attrUnused __attribute__((unused))
374 /** Not used enum constant. */
375 #define sjme_attrUnusedEnum(x) x sjme_attrUnused
377 #if !defined(sjme_attrReturnNever)
378 /** Method does not return. */
379 #define sjme_attrReturnNever __attribute__((noreturn))
382 #if !defined(sjme_flexibleArrayCount)
383 /** Flexible array size count, GCC is fine with blank. */
384 #define sjme_flexibleArrayCount
386 #elif defined(__WATCOMC__)
387 /** Flexible array size count. */
388 #define sjme_flexibleArrayCount
390 /** Flexible array count but for unions. */
391 #define sjme_flexibleArrayCountUnion 1
394 #if !defined(sjme_attrCallback)
395 /** Indicates a callback. */
396 #define sjme_attrCallback
399 #if !defined(sjme_attrCheckReturn)
400 /** Return value must be checked. */
401 #define sjme_attrCheckReturn
404 #if !defined(sjme_attrDeprecated)
406 #define sjme_attrDeprecated
409 #if !defined(sjme_attrFormatArg)
410 /** Formatted string argument. */
411 #define sjme_attrFormatArg
414 #if !defined(sjme_attrFormatOuter)
418 * @param formatIndex The formatted string index.
419 * The index of @c ... or @c va_list .
422 #define sjme_attrFormatOuter(formatIndex, vaIndex)
425 #if !defined(sjme_attrInValue)
426 /** Method takes input. */
427 #define sjme_attrInValue
430 #if !defined(sjme_attrInRange)
431 /** Input value range. */
432 #define sjme_attrInRange(lo, hi)
435 #if !defined(sjme_attrReturnNever)
436 /** Method does not return. */
437 #define sjme_attrReturnNever
440 #if !defined(sjme_attrReturnNullable)
441 /** Returns a nullable value. */
442 #define sjme_attrReturnNullable
445 #if !defined(sjme_attrInValue)
446 /** Takes input value. */
447 #define sjme_attrInValue
450 #if !defined(sjme_attrInNotNull)
451 /** Cannot be null. */
452 #define sjme_attrInNotNull sjme_attrInValue
455 #if !defined(sjme_attrInNullable)
457 #define sjme_attrInNullable sjme_attrInValue
460 #if !defined(sjme_attrOutNotNull)
461 /** Method gives output. */
462 #define sjme_attrOutNotNull sjme_attrInNotNull
465 #if !defined(sjme_attrOutNullable)
466 /** Method output can be null. */
467 #define sjme_attrOutNullable sjme_attrInNullable
470 #if !defined(sjme_attrInOutNotNull)
471 /** Takes input and produces output. */
472 #define sjme_attrInOutNotNull sjme_attrInNotNull sjme_attrOutNotNull
475 #if !defined(sjme_attrInNotNullBuf)
476 /** Input to buffer. */
477 #define sjme_attrInNotNullBuf(lenArg) sjme_attrInNotNull
480 #if !defined(sjme_attrOutNotNullBuf)
481 /** Output to buffer. */
482 #define sjme_attrOutNotNullBuf(lenArg) sjme_attrOutNotNull
485 #if !defined(sjme_attrOutRange)
486 /** Output value range. */
487 #define sjme_attrOutRange(lo, hi)
490 /** Positive value. */
491 #define sjme_attrInPositive sjme_attrInRange(0, INT32_MAX)
493 /** Non-zero positive value. */
494 #define sjme_attrInPositiveNonZero sjme_attrInRange(1, INT32_MAX)
496 /** Negative one to positive. */
497 #define sjme_attrInNegativeOnePositive sjme_attrInRange(-1, INT32_MAX)
499 /** Positive value. */
500 #define sjme_attrOutPositive sjme_attrOutRange(0, INT32_MAX)
502 /** Non-zero positive value. */
503 #define sjme_attrOutPositiveNonZero sjme_attrOutRange(1, INT32_MAX)
505 /** Negative one to positive. */
506 #define sjme_attrOutNegativeOnePositive sjme_attrOutRange(-1, INT32_MAX)
508 #if !defined(sjme_flexibleArrayCount)
509 /** Flexible array count, zero by default. */
510 #define sjme_flexibleArrayCount 0
513 #if !defined(sjme_flexibleArrayCountUnion)
514 /** Flexible array count but for unions. */
515 #define sjme_flexibleArrayCountUnion 0
518 #if !defined(sjme_attrUnused)
520 #define sjme_attrUnused
523 #if !defined(sjme_attrUnusedEnum)
524 /** Unused enumeration element. */
525 #define sjme_attrUnusedEnum(x) x
528 #if !defined(sjme_attrArtificial)
529 /** Artificial function. */
530 #define sjme_attrArtificial
533 #if !defined(sjme_alloca)
534 /** Allocate on the stack. */
535 #define sjme_alloca(size) alloca((size))
538 #if !defined(sjme_inline)
539 /** Inline function. */
540 #define sjme_inline inline
543 #if !defined(sjme_noOptimize)
544 /** Disable optimization. */
545 #define sjme_noOptimize
548 #if defined(__GNUC__)
549 /** GNU C Compiler. */
550 #define SJME_CONFIG_HAS_GCC
553 #if defined(_MSC_VER)
554 /** Microsoft Visual C++ Compiler. */
555 #define SJME_CONFIG_HAS_MSVC
558 #if defined(SJME_CONFIG_HAS_WINDOWS)
559 /** Supports Windows Atomic Access. */
560 #define SJME_CONFIG_HAS_ATOMIC_WIN32
561 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && \
562 !defined(__STDC_NO_ATOMICS__)
563 /** Supports C11 atomics. */
564 #define SJME_CONFIG_HAS_ATOMIC_C11
565 #elif defined(SJME_CONFIG_HAS_GCC)
567 #define SJME_CONFIG_HAS_ATOMIC_GCC
570 #if !defined(SJME_CONFIG_HAS_ATOMIC)
571 #if defined(SJME_CONFIG_HAS_ATOMIC_WIN32) || \
572 defined(SJME_CONFIG_HAS_ATOMIC_C11) || \
573 defined(SJME_CONFIG_HAS_ATOMIC_GCC)
574 /** Atomics are supported. */
575 #define SJME_CONFIG_HAS_ATOMIC
577 /** Use old atomic handling. */
578 #define SJME_CONFIG_HAS_ATOMIC_OLD
580 /** Atomics are supported. */
581 #define SJME_CONFIG_HAS_ATOMIC
585 #if defined(SJME_CONFIG_HAS_LINUX) || \
586 defined(SJME_CONFIG_HAS_BSD) || \
587 defined(SJME_CONFIG_HAS_BEOS)
588 /** Dynamic library path name as static define. */
589 #define SJME_CONFIG_DYLIB_PATHNAME(x) \
591 #elif defined(SJME_CONFIG_HAS_CYGWIN)
592 /** Dynamic library path name as static define. */
593 #define SJME_CONFIG_DYLIB_PATHNAME(x) \
595 #elif defined(SJME_CONFIG_HAS_WINDOWS)
596 /** Dynamic library path name as static define. */
597 #define SJME_CONFIG_DYLIB_PATHNAME(x) \
599 #elif defined(SJME_CONFIG_HAS_MACOS)
600 /** Dynamic library path name as static define. */
601 #define SJME_CONFIG_DYLIB_PATHNAME(x) \
604 /** Dynamic library path name as static define. */
605 #define SJME_CONFIG_DYLIB_PATHNAME(x) NULL
608 /* Nintendo 3DS: devkitPro has broken/unimplemented pthreads. */
609 #if defined(SJME_CONFIG_HAS_NINTENDO_3DS)
610 /** Use fallback threading regardless of the system. */
611 #define SJME_CONFIG_HAS_THREADS_FALLBACK
614 #if defined(SJME_CONFIG_HAS_WINDOWS_16)
615 #define SJME_CALL FAR PASCAL
616 #elif defined(SJME_CONFIG_HAS_WINDOWS)
617 #define SJME_CALL __stdcall
619 /** SquirrelJME calling convention. */
623 #if defined(SJME_CONFIG_HAS_MSVC)
624 /** Align to 64-bit. */
625 #define sjme_align64 __declspec(align(8))
626 #elif defined(SJME_CONFIG_HAS_GCC)
627 /** Align to 64-bit. */
628 #define sjme_align64 __attribute__((aligned(8)))
630 /** Align to 64-bit. */
634 /* Missing standard C functions. */
635 #if defined(SJME_CONFIG_HAS_NO_SNPRINTF)
636 #include "sjme/stdgone.h"
639 /*--------------------------------------------------------------------------*/
643 #ifdef SJME_CXX_SQUIRRELJME_CONFIG_H
645 #undef SJME_CXX_SQUIRRELJME_CONFIG_H
646 #undef SJME_CXX_IS_EXTERNED
647 #endif /* #ifdef SJME_CXX_SQUIRRELJME_CONFIG_H */
648 #endif /* #ifdef __cplusplus */
650 #endif /* SQUIRRELJME_CONFIG_H */