Line | Count | Source |
1 | | /* SPDX-License-Identifier: GPL-3.0-or-later |
2 | | * Copyright © 2016-2021 The TokTok team. |
3 | | */ |
4 | | |
5 | | /** |
6 | | * C language compatibility macros for varying compiler support. |
7 | | */ |
8 | | #ifndef C_TOXCORE_TOXCORE_CCOMPAT_H |
9 | | #define C_TOXCORE_TOXCORE_CCOMPAT_H |
10 | | |
11 | | #include <stddef.h> // NULL, size_t |
12 | | |
13 | | #include "attributes.h" |
14 | | |
15 | | //!TOKSTYLE- |
16 | | |
17 | | // Variable length arrays. |
18 | | // VLA(type, name, size) allocates a variable length array with automatic |
19 | | // storage duration. VLA_SIZE(name) evaluates to the runtime size of that array |
20 | | // in bytes. |
21 | | // |
22 | | // If C99 VLAs are not available, an emulation using alloca (stack allocation |
23 | | // "function") is used. Note the semantic difference: alloca'd memory does not |
24 | | // get freed at the end of the declaration's scope. Do not use VLA() in loops or |
25 | | // you may run out of stack space. |
26 | | #if !defined(DISABLE_VLA) && !defined(_MSC_VER) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L |
27 | | // C99 VLAs. |
28 | 2.21M | #define ALLOC_VLA(type, name, size) type name[size] |
29 | | #else |
30 | | |
31 | | // Emulation using alloca. |
32 | | #ifdef _WIN32 |
33 | | #include <malloc.h> |
34 | | #elif defined(__COMPCERT__) |
35 | | // TODO(iphydf): This leaks memory like crazy, so compcert is useless for now. |
36 | | // Once we're rid of VLAs, we can remove this and compcert becomes useful. |
37 | | #define alloca malloc |
38 | | #include <stdlib.h> |
39 | | #elif defined(__linux__) |
40 | | #include <alloca.h> |
41 | | #else |
42 | | #include <stdlib.h> |
43 | | #if !defined(alloca) && defined(__GNUC__) |
44 | | #define alloca __builtin_alloca |
45 | | #endif |
46 | | #endif |
47 | | |
48 | | #define ALLOC_VLA(type, name, size) \ |
49 | | type *const name = (type *)alloca((size) * sizeof(type)) |
50 | | |
51 | | #endif |
52 | | |
53 | | #ifdef MAX_VLA_SIZE |
54 | | #include <assert.h> |
55 | | #define VLA(type, name, size) \ |
56 | | ALLOC_VLA(type, name, size); \ |
57 | | assert((size_t)(size) * sizeof(type) <= MAX_VLA_SIZE) |
58 | | #else |
59 | 2.21M | #define VLA ALLOC_VLA |
60 | | #endif |
61 | | |
62 | | #if !defined(__cplusplus) || __cplusplus < 201103L |
63 | 212M | #define nullptr NULL |
64 | | #ifndef static_assert |
65 | | #ifdef __GNUC__ |
66 | | // We'll just assume gcc and clang support C11 _Static_assert. |
67 | | #define static_assert _Static_assert |
68 | | #else // !__GNUC__ |
69 | | #define STATIC_ASSERT_(cond, msg, line) typedef int static_assert_##line[(cond) ? 1 : -1] |
70 | | #define STATIC_ASSERT(cond, msg, line) STATIC_ASSERT_(cond, msg, line) |
71 | | #define static_assert(cond, msg) STATIC_ASSERT(cond, msg, __LINE__) |
72 | | #endif /* !__GNUC__ */ |
73 | | #endif /* !static_assert */ |
74 | | #endif /* !__cplusplus */ |
75 | | |
76 | | #ifdef __GNUC__ |
77 | | #define GNU_PRINTF(f, a) __attribute__((__format__(__printf__, f, a))) |
78 | | #else |
79 | | #define GNU_PRINTF(f, a) |
80 | | #endif |
81 | | |
82 | | //!TOKSTYLE+ |
83 | | |
84 | | #endif /* C_TOXCORE_TOXCORE_CCOMPAT_H */ |