libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
acfutils
sysmacros.h
Go to the documentation of this file.
1
/*
2
* CDDL HEADER START
3
*
4
* The contents of this file are subject to the terms of the
5
* Common Development and Distribution License, Version 1.0 only
6
* (the "License"). You may not use this file except in compliance
7
* with the License.
8
*
9
* You can obtain a copy of the license in the file COPYING
10
* or http://www.opensource.org/licenses/CDDL-1.0.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file COPYING.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
/*
23
* Copyright 2018 Saso Kiselkov. All rights reserved.
24
*/
29
#ifndef _ACF_UTILS_SYSMACROS_H_
30
#define _ACF_UTILS_SYSMACROS_H_
31
32
#if IBM
33
#include <windows.h>
34
#endif
/* IBM */
35
36
#include "types.h"
37
38
#ifdef __cplusplus
39
extern
"C"
{
40
#endif
41
42
#define NO_ACF_TYPE 0
43
#define FF_A320_ACF_TYPE 1
44
45
#if IBM
46
#define DIRSEP '\\'
47
#define DIRSEP_S "\\"
/* DIRSEP as a string */
48
#else
/* !IBM */
49
#define DIRSEP '/'
50
#define DIRSEP_S "/"
/* DIRSEP as a string */
51
#ifndef MAX_PATH
52
#define MAX_PATH 512
53
#endif
54
#endif
/* !IBM */
55
56
#if defined(__GNUC__) || defined(__clang__)
57
#define DEPRECATED_FUNC(f) f __attribute__((deprecated))
58
#define DEPRECATED_ATTR __attribute__((deprecated))
59
#define PRINTF_ATTR(x) __attribute__((format(printf, x, x + 1)))
60
#define PRINTF_ATTR2(x,y) __attribute__((format(printf, x, y)))
61
#define PRINTF_FORMAT(f) f
62
#define SENTINEL_ATTR __attribute__((sentinel))
63
#define HOT_ATTR __attribute__((hot))
64
#define PURE_ATTR __attribute__((pure))
65
#define ALWAYS_INLINE_ATTR __attribute__((always_inline))
66
#define ALIGN_ATTR(x) __attribute__((aligned(x)))
67
68
#ifndef BSWAP32
69
#define BSWAP16(x) __builtin_bswap16((x))
70
#define BSWAP32(x) __builtin_bswap32((x))
71
#define BSWAP64(x) __builtin_bswap64((x))
72
#endif
/* BSWAP32 */
73
74
#define COND_LIKELY(x) __builtin_expect(x, 1)
75
#define COND_UNLIKELY(x) __builtin_expect(x, 0)
76
77
#else
/* !__GNUC__ && !__clang__ */
78
79
#define DEPRECATED_ATTR
80
#define PRINTF_ATTR(x)
81
#define PRINTF_ATTR2(x,y)
82
#define SENTINEL_ATTR
83
#define HOT_ATTR
84
#define PURE_ATTR
85
#define ALWAYS_INLINE_ATTR
86
87
#define COND_LIKELY(x) x
88
#define COND_UNLIKELY(x) x
89
90
#if defined(_MSC_VER)
91
#define ALIGN_ATTR(x) __declspec(align(x))
92
#else
93
#define ALIGN_ATTR(x)
94
#endif
95
96
#if _MSC_VER >= 1400
97
# define DEPRECATED_FUNC(f) __declspec(deprecated) f
98
# include <sal.h>
99
# if _MSC_VER > 1400
100
# define PRINTF_FORMAT(f) _Printf_format_string_ f
101
# else
/* _MSC_VER == 1400 */
102
# define PRINTF_FORMAT(f) __format_string f
103
# endif
/* FORMAT_STRING */
104
#else
/* _MSC_VER < 1400 */
105
# define PRINTF_FORMAT(f) f
106
#endif
/* _MSC_VER */
107
108
#ifndef BSWAP32
109
#define BSWAP16(x) \
110
((((x) & 0xff00u) >> 8) | \
111
(((x) & 0x00ffu) << 8))
112
#define BSWAP32(x) \
113
((((x) & 0xff000000u) >> 24) | \
114
(((x) & 0x00ff0000u) >> 8) | \
115
(((x) & 0x0000ff00u) << 8) | \
116
(((x) & 0x000000ffu) << 24))
117
#define BSWAP64(x) \
118
((((x) & 0x00000000000000ffllu) >> 56) | \
119
(((x) & 0x000000000000ff00llu) << 40) | \
120
(((x) & 0x0000000000ff0000llu) << 24) | \
121
(((x) & 0x00000000ff000000llu) << 8) | \
122
(((x) & 0x000000ff00000000llu) >> 8) | \
123
(((x) & 0x0000ff0000000000llu) >> 24) | \
124
(((x) & 0x00ff000000000000llu) >> 40) | \
125
(((x) & 0xff00000000000000llu) << 56))
126
#endif
/* BSWAP32 */
127
#endif
/* !__GNUC__ && !__clang__ */
128
129
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
130
#define BE64(x) (x)
131
#define BE32(x) (x)
132
#define BE16(x) (x)
133
#else
/* __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ */
134
#define BE64(x) BSWAP64(x)
135
#define BE32(x) BSWAP32(x)
136
#define BE16(x) BSWAP16(x)
137
#endif
/* __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ */
138
139
#define DESTROY(x) do { free(x); (x) = NULL; } while (0)
140
#define DESTROY_OP(var, zero_val, destroy_op) \
141
do { \
142
if ((var) != (zero_val)) { \
143
destroy_op; \
144
(var) = (zero_val); \
145
} \
146
} while (0)
147
148
#ifdef WINDOWS
149
#define PATHSEP "\\"
150
#else
151
#define PATHSEP "/"
152
#endif
153
154
/* Minimum/Maximum allowable elevation AMSL of anything */
155
#define MIN_ELEV -2000.0
156
#define MAX_ELEV 30000.0
157
158
/* Minimum/Maximum allowable altitude AMSL of anything */
159
#define MIN_ALT -2000.0
160
#define MAX_ALT 100000.0
161
162
/* Maximum valid speed of anything */
163
#define MAX_SPD 1000.0
164
165
/* Minimum/Maximum allowable arc radius on any procedure */
166
#define MIN_ARC_RADIUS 0.1
167
#define MAX_ARC_RADIUS 100.0
168
169
/*
170
* Compile-time assertion. The condition 'x' must be constant.
171
* TYPE_ASSERT is a compile-time assertion, but which checks that
172
* the type of `x' is `type'.
173
*/
174
#if __STDC_VERSION__ >= 201112L && \
175
(!defined(__GNUC__) || __GNUC__ > 7 || defined(__clang__))
176
#define CTASSERT(x) _Static_assert((x), #x)
177
#define TYPE_ASSERT(x, type) \
178
CTASSERT(_Generic((x), type: 1, default: 0) != 0)
179
#define NOT_TYPE_ASSERT(x, type) \
180
CTASSERT(_Generic((x), type: 0, default: 1) != 0)
181
#else
/* __STDC_VERSION__ < 201112L */
182
#define TYPE_ASSERT(x, type)
183
#define NOT_TYPE_ASSERT(x, type)
184
#if defined(__GNUC__) || defined(__clang__)
185
#define CTASSERT(x) _CTASSERT(x, __LINE__)
186
#define _CTASSERT(x, y) __CTASSERT(x, y)
187
#define __CTASSERT(x, y) \
188
typedef char __compile_time_assertion__ ## y [(x) ? 1 : -1] \
189
__attribute__((unused))
190
#else
/* !defined(__GNUC__) && !defined(__clang__) */
191
#define CTASSERT(x)
192
#endif
/* !defined(__GNUC__) && !defined(__clang__) */
193
#endif
/* __STDC_VERSION__ < 201112L */
194
195
#if defined(__GNUC__) || defined(__clang__)
196
197
#define highbit64(x) (64 - __builtin_clzll(x) - 1)
198
#define highbit32(x) (32 - __builtin_clzll(x) - 1)
199
200
#elif defined(_MSC_VER)
201
202
static
inline
unsigned
203
highbit32(
unsigned
int
x)
204
{
205
unsigned
long
idx;
206
_BitScanReverse(&idx, x);
207
return
(idx);
208
}
209
210
static
inline
unsigned
211
highbit64(
unsigned
long
long
x)
212
{
213
unsigned
long
idx;
214
_BitScanReverse64(&idx, x);
215
return
(idx);
216
}
217
#else
218
#error "Compiler platform unsupported, please add highbit definition"
219
#endif
220
221
#ifndef MIN
222
#define MIN(x, y) ((x) < (y) ? (x) : (y))
223
#endif
224
#ifndef MAX
225
#define MAX(x, y) ((x) > (y) ? (x) : (y))
226
#endif
227
#ifndef AVG
228
#define AVG(x, y) (((x) + (y)) / 2.0)
229
#endif
230
#if defined(_MSC_VER)
231
#define FILTER_IN_TYPE(x) double
232
#else
233
#define FILTER_IN_TYPE(x) __typeof__(x)
234
#endif
235
/*
236
* Provides a gradual method of integrating an old value until it approaches
237
* a new target value. This is used in iterative processes by calling the
238
* FILTER_IN macro repeatedly a certain time intervals (d_t = delta-time).
239
* As time progresses, old_val will gradually be made to approach new_val.
240
* The lag serves to make the approach slower or faster (e.g. a value of
241
* '2' and d_t in seconds makes old_val approach new_val with a ramp that
242
* is approximately 2 seconds long).
243
*/
244
#define FILTER_IN(old_val, new_val, d_t, lag) \
245
do { \
246
FILTER_IN_TYPE(old_val) o = (old_val); \
247
FILTER_IN_TYPE(new_val) n = (new_val); \
248
ASSERT(!isnan(o)); \
249
(old_val) += (n - o) * ((d_t) / (lag)); \
250
/* Prevent an overshoot */
\
251
if ((o < n && (old_val) > n) || \
252
(o > n && (old_val) < n)) \
253
(old_val) = n; \
254
} while (0)
255
/*
256
* Same as FILTER_IN, but handles NAN values for old_val and new_val properly.
257
* If new_val is NAN, old_val is set to NAN. Otherwise if old_val is NAN,
258
* it is set to new_val directly (without gradual filtering). Otherwise this
259
* simply calls the FILTER_IN macro as normal.
260
*/
261
#define FILTER_IN_NAN(old_val, new_val, d_t, lag) \
262
do { \
263
FILTER_IN_TYPE(old_val) o = (old_val); \
264
FILTER_IN_TYPE(new_val) n = (new_val); \
265
if (isnan(n)) \
266
(old_val) = NAN; \
267
else if (isnan(o)) \
268
(old_val) = (new_val); \
269
else \
270
FILTER_IN(old_val, new_val, d_t, lag); \
271
} while (0)
272
273
/*
274
* Linearly interpolates old_val until it is equal to tgt. The current
275
* time delta is d_t (in seconds). The interpolation speed is step/second.
276
*/
277
#define FILTER_IN_LIN(old_val, tgt, d_t, step) \
278
do { \
279
double o = (old_val); \
280
double t = (tgt); \
281
double s; \
282
if (isnan(o)) \
283
o = t; \
284
if (o < t) \
285
s = (d_t) * (step); \
286
else \
287
s = (d_t) * (-(step)); \
288
if ((o <= t && o + s > t) || (o >= t && o + s < t)) \
289
(old_val) = t; \
290
else \
291
(old_val) += s; \
292
} while (0)
293
294
#define SCANF_STR_AUTOLEN_IMPL(_str_) #_str_
295
#define SCANF_STR_AUTOLEN(_str_) SCANF_STR_AUTOLEN_IMPL(_str_)
296
330
#ifndef REQ_PTR
331
#if __STDC_VERSION__ >= 201112L
332
#define REQ_PTR(x) x[static 1]
333
#else
334
#define REQ_PTR(x) *x
335
#endif
336
#endif
// !defined(REQ_PTR)
337
371
#ifndef REQ_ARR
372
#if __STDC_VERSION__ >= 201112L
373
#define REQ_ARR(x, n) x[static (n)]
374
#else
375
#define REQ_ARR(x) x[n]
376
#endif
377
#endif
// !defined(REQ_ARR)
378
414
#ifndef ENUM_BIT_WIDTH_CHECK
415
#define ENUM_BIT_WIDTH_CHECK(enum_type, num_bits, ...) \
416
do { \
417
enum_type __enum_check_value__ = 0; \
418
CTASSERT(num_bits > 0); \
419
enum { __enum_check_max_value__ = (1 << (num_bits)) - 1 }; \
420
switch (__enum_check_value__) { \
421
__VA_ARGS__ \
422
} \
423
} while (0)
424
#define ENUM_BIT_WIDTH_CHECK_VARIANT(variant_name) \
425
case variant_name: { \
426
CTASSERT((int)variant_name >= 0); \
427
CTASSERT((unsigned long long)variant_name <= \
428
(unsigned long long)__enum_check_max_value__); \
429
} \
430
break
431
#endif
// !defined(ENUM_BIT_WIDTH_CHECK)
432
433
#ifdef __cplusplus
434
}
435
#endif
436
437
#endif
/* _ACF_UTILS_SYSMACROS_H_ */
Generated by
1.9.8