reldb 0.1.0
Recreational SQLite
Loading...
Searching...
No Matches
macros.h
Go to the documentation of this file.
1
9
10#ifndef CTXMCS_H
11#define CTXMCS_H
12
13//
14// OS-specific headers macro
15//
16#if defined(_WIN32)
17# ifndef WIN32_LEAN_AND_MEAN
18# define WIN32_LEAN_AND_MEAN
19# endif
20// Avoid including windows.h in a header if possible to prevent namespace pollution.
21// Ideally, only include it in implementation files.
22# define OS_HEADERS
23#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
24# define OS_HEADERS #include<unistd.h>
25#else
26# define OS_HEADERS
27#endif
28
29//
30// Compiler Detection
31//
32#if defined(__clang__)
33# define COMPILER_CLANG 1
34# define COMPILER_NAME "Clang"
35#elif defined(__GNUC__)
36# define COMPILER_GCC 1
37# define COMPILER_NAME "GCC"
38#elif defined(_MSC_VER)
39# define COMPILER_MSVC 1
40# define COMPILER_NAME "MSVC"
41#else
42# error "Compiler not supported"
43#endif
44
45//
46// Operating System Detection
47//
48#if defined(_WIN32)
49# define OS_WINDOWS 1
50# define OS_NAME "Windows"
51#elif defined(__linux__)
52# define OS_LINUX 1
53# define OS_NAME "Linux"
54#elif defined(__APPLE__) && defined(__MACH__)
55# define OS_MAC 1
56# define OS_NAME "macOS"
57#else
58# error "Operating system not supported"
59#endif
60
61//
62// Architecture Detection
63//
64#if defined(_M_X64) || defined(__x86_64__)
65# define ARCH_X64 1
66# define ARCH_NAME "x86_64"
67#elif defined(_M_IX86) || defined(__i386__)
68# define ARCH_X86 1
69# define ARCH_NAME "x86"
70#elif defined(_M_ARM64) || defined(__aarch64__)
71# define ARCH_ARM64 1
72# define ARCH_NAME "ARM64"
73#elif defined(_M_ARM) || defined(__arm__)
74# define ARCH_ARM 1
75# define ARCH_NAME "ARM"
76#else
77# error "Architecture not supported"
78#endif
79
80//
81// Build Configuration
82//
83#if defined(NDEBUG)
84# define BUILD_RELEASE 1
85# define BUILD_NAME "Release"
86#else
87# define BUILD_DEBUG 1
88# define BUILD_NAME "Debug"
89#endif
90
91//
92// Endianness Detection
93//
94// Modern GCC/Clang provide __BYTE_ORDER__. MSVC does not, but is almost exclusively Little Endian
95// on x86/ARM.
96#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || defined(_M_IX86) || \
97 defined(_M_X64) || defined(__i386__) || defined(__x86_64__) || defined(_M_ARM) || \
98 defined(_M_ARM64)
99# define ENDIAN_LITTLE 1
100# define ENDIAN_NAME "Little Endian"
101#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || defined(__BIG_ENDIAN__)
102# define ENDIAN_BIG 1
103# define ENDIAN_NAME "Big Endian"
104#else
105# error "Could not determine endianness"
106#endif
107
108//
109// C Standard Version
110//
111#if defined(__STDC_VERSION__)
112# if __STDC_VERSION__ >= 202311L
113# define C_STANDARD 23
114# define C_STANDARD_NAME "C23"
115# elif __STDC_VERSION__ >= 201710L
116# define C_STANDARD 17
117# define C_STANDARD_NAME "C17"
118# elif __STDC_VERSION__ >= 201112L
119# define C_STANDARD 11
120# define C_STANDARD_NAME "C11"
121# elif __STDC_VERSION__ >= 199901L
122# define C_STANDARD 99
123# define C_STANDARD_NAME "C99"
124# else
125# define C_STANDARD 89
126# define C_STANDARD_NAME "C89"
127# endif
128#else
129// MSVC defaults to C89 mode unless /std:c11 or /std:c17 is used
130# define C_STANDARD 89
131# define C_STANDARD_NAME "C89/Default"
132#endif
133
134#include <stddef.h>
135#include <stdint.h>
136#include <stdio.h>
137
143#define INTERNAL static
144#define EXTERNAL extern
145
146#if defined(__GNUC__) || defined(__clang__)
147# define API_EXPORT \
148 __attribute__((visibility("default")))
149# define API_LOCAL \
150 __attribute__((visibility("hidden")))
151#elif defined(_MSC_VER)
152# define API_EXPORT __declspec(dllexport)
153# define API_LOCAL
154#else
155# define API_EXPORT
156# define API_LOCAL
157#endif
158
159#ifdef __cplusplus
160# define C_LINKAGE_BEGIN extern "C" {
161# define C_LINKAGE_END }
162#else
163# define C_LINKAGE_BEGIN
164# define C_LINKAGE_END
165#endif
167
173
175#define INT_FROM_PTR(ptr) ((uintptr_t)(ptr))
177#define PTR_FROM_INT(type, val) ((type *)(uintptr_t)(val))
178
180#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
181
182#if defined(__GNUC__) || defined(__clang__) || \
183 (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L)
184
185# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
186# define _TYPEOF(x) typeof(x)
187# else
188# define _TYPEOF(x) __typeof__(x)
189# endif
190
192# define MIN(a, b) \
193 ({ \
194 _TYPEOF(a) _a = (a); \
195 _TYPEOF(b) _b = (b); \
196 _a < _b ? _a : _b; \
197 })
198
200# define MAX(a, b) \
201 ({ \
202 _TYPEOF(a) _a = (a); \
203 _TYPEOF(b) _b = (b); \
204 _a > _b ? _a : _b; \
205 })
206
208# define CLAMP(val, min, max) \
209 ({ \
210 _TYPEOF(val) _val = (val); \
211 _TYPEOF(min) _min = (min); \
212 _TYPEOF(max) _max = (max); \
213 (_val < _min) ? _min : ((_val > _max) ? _max : _val); \
214 })
215
217# define SWAP(a, b) \
218 do { \
219 _TYPEOF(a) _tmp = (a); \
220 (a) = (b); \
221 (b) = _tmp; \
222 } while (0)
223
224#else
225// Fallbacks for standard C99/C11 (MSVC)
226# define MIN(a, b) (((a) < (b)) ? (a) : (b))
227# define MAX(a, b) (((a) > (b)) ? (a) : (b))
228# define CLAMP(val, min, max) (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val))
229# define SWAP(type, a, b) \
230 do { \
231 type _tmp = (a); \
232 (a) = (b); \
233 (b) = _tmp; \
234 } while (0)
235#endif
237
243
245INTERNAL inline void
247{
248 printf("Compilation Context:\n");
249 printf(" - Compiler: " COMPILER_NAME "\n");
250 printf(" - OS: " OS_NAME "\n");
251 printf(" - Architecture: " ARCH_NAME "\n");
252 printf(" - Endianness: " ENDIAN_NAME "\n");
253 printf(" - Build: " BUILD_NAME "\n");
254 printf(" - C Standard: " C_STANDARD_NAME "\n");
255}
256
257#if COMPILER_MSVC
258# define debug_break() __debugbreak()
259#elif COMPILER_GCC || COMPILER_CLANG
260# define debug_break() __builtin_trap()
261#else
262# define debug_break() (*(volatile int *)0 = 0)
263#endif
264
265#if BUILD_DEBUG
270# define ASSERT(expr) \
271 do { \
272 if (!(expr)) { \
273 fputs("Assertion failed: " #expr "\n", stderr); \
274 fputs("File: " __FILE__ "\n", stderr); \
275 fputs("Line: " STRINGIFY(__LINE__) "\n", stderr); \
276 debug_break(); \
277 } \
278 } while (0)
279
284# define ASSERT_NOT_NULL(ptr) \
285 do { \
286 if ((ptr) == NULL) { \
287 fputs("Assertion failed: " #ptr " is NULL\n", stderr); \
288 fputs("File: " __FILE__ "\n", stderr); \
289 fputs("Line: " STRINGIFY(__LINE__) "\n", stderr); \
290 debug_break(); \
291 } \
292 } while (0)
293#else
294# define ASSERT(expr) ((void)0)
295# define ASSERT_NOT_NULL(ptr) ((void)0)
296#endif
298
299#endif // CTXMCS_H
static void print_context_info(void)
Prints the OS, Architecture, and Compiler to stdout.
Definition macros.h:246
#define INTERNAL
Definition macros.h:143