The FreeRADIUS server
$Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
src
include
build.h
Go to the documentation of this file.
1
#pragma once
2
/*
3
* This program is free software; you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation; either version 2 of the License, or
6
* (at your option) any later version.
7
*
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
12
*
13
* You should have received a copy of the GNU General Public License
14
* along with this program; if not, write to the Free Software
15
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16
*/
17
18
/**
19
* $Id: 67158d193ad86db7f178065f0abf26a7339a646f $
20
*
21
* @file include/build.h
22
* @brief Source control functions
23
*
24
* @copyright 2013 The FreeRADIUS server project
25
*/
26
27
#ifdef __cplusplus
28
extern
"C"
{
29
#endif
30
31
/** For systems with an old version libc, define static_assert.
32
*
33
*/
34
#ifndef static_assert
35
# if __STDC_VERSION__ < 202000
36
# define static_assert _Static_assert
37
# endif
38
# else
39
# include <assert.h>
40
#endif
41
42
/*
43
* Static analyzers don't notice or can't infer some properties
44
* of the code, and hence may give false positives. To deal with
45
* them, there is some conditionally compiled code in various
46
* places. The following lets the code change minimally if and
47
* when new static analyzers are added.
48
*/
49
#ifdef __clang_analyzer__
50
#define STATIC_ANALYZER 1
51
#endif
52
#ifdef __COVERITY__
53
#define STATIC_ANALYZER 1
54
#endif
55
56
/*
57
* Reduce spurious errors from static analyzers by having
58
* all paths that find the da to be NULL, result
59
* in program exit.
60
*/
61
#ifdef STATIC_ANALYZER
62
# define WITH_VERIFY_PTR 1
63
#endif
64
65
/*
66
* GCC uses __SANITIZE_ADDRESS__, clang uses __has_feature, which
67
* GCC complains about.
68
*/
69
#ifndef __SANITIZE_ADDRESS__
70
#ifdef __has_feature
71
#if __has_feature(address_sanitizer)
72
#define __SANITIZE_ADDRESS__ (1)
73
#endif
74
#endif
75
#endif
76
77
/*
78
* Basic headers we want everywhere
79
*/
80
#include <stdint.h>
81
#include <stddef.h>
82
#include <string.h>
83
84
/*
85
* These are compile time options to toggle whether
86
* we're building with thread support.
87
*
88
* With EMSCRIPTEN threading support isn't guaranteed
89
* as many browsers have explicitly disabled support
90
* due to spectre attacks.
91
*/
92
#if (defined(__EMSCRIPTEN__) && defined(__EMSCRIPTEN_PTHREADS__)) || !defined(__EMSCRIPTEN__) && defined(HAVE_PTHREAD_H)
93
# define HAVE_PTHREADS 1
94
#endif
95
96
/*
97
* GCC will sometimes define "unix" as well as "__unix",
98
* which gets confusing and is unnecessary.
99
*/
100
#undef unix
101
102
/** Evaluates to +1 for a > b, and -1 for a < b
103
*/
104
#define CMP_PREFER_SMALLER(_a,_b) (((_a) > (_b)) - ((_a) < (_b)))
105
106
/** Evaluates to -1 for a > b, and +1 for a < b
107
*/
108
#define CMP_PREFER_LARGER(_a,_b) (((_a) < (_b)) - ((_a) > (_b)))
109
110
/** Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want _an_ ordering.
111
*/
112
#define CMP(_a, _b) CMP_PREFER_SMALLER(_a, _b)
113
114
/** Return if the comparison is not 0 (is unequal)
115
*
116
* @param[in] _a pointer to first structure.
117
* @param[in] _b pointer to second structure.
118
* @param[in] _field within the structs to compare.
119
* @return The result of the comparison.
120
*/
121
#define CMP_RETURN(_a, _b, _field) \
122
do { \
123
int8_t _ret = CMP((_a)->_field, (_b)->_field); \
124
if (_ret != 0) return _ret; \
125
} while (0)
126
127
/** memcmp function which has similar behaviour as strncmp
128
*
129
* @param[in] a First thing to compare.
130
* @param[in] b Second thing to compare.
131
* @param[in] a_len Length of first thing.
132
* @param[in] b_len Length of second thing.
133
* @return
134
* - +1 if a > b
135
* - 0 if a == b
136
* - -1 if a < b
137
*/
138
static
inline
int8_t
memcmp_return
(
void
const
*a,
void
const
*b,
size_t
a_len,
size_t
b_len)
139
{
140
size_t
cmp_len = (a_len < b_len) ? a_len : b_len;
141
int8_t l_ret =
CMP
(a_len, b_len);
142
int8_t ret;
143
ret =
CMP
(memcmp(a, b, cmp_len), 0);
144
if
(ret != 0)
return
ret;
145
return
l_ret;
146
}
147
148
/** Return if the contents of the specified field is not identical between the specified structures
149
*
150
* @param[in] _a pointer to first structure.
151
* @param[in] _b pointer to second structure.
152
* @param[in] _field within the structs to compare.
153
* @param[in] _len_field within the structs, specifying the length of the data.
154
* @return The result of the comparison.
155
*/
156
#define MEMCMP_RETURN(_a, _b, _field, _len_field) \
157
do { \
158
int8_t _ret = memcmp_return((_a)->_field, (_b)->_field, (_a)->_len_field, (_b)->_len_field); \
159
if (_ret != 0) return _ret; \
160
} while (0)
161
162
/** Remove const qualification from a pointer
163
*
164
* @param[in] _type The non-const version of the type.
165
* @param[in] _ptr to de-const.
166
*/
167
#define UNCONST(_type, _ptr) ((_type)((uintptr_t)(_ptr)))
168
169
/** Typeof field
170
*
171
* @param[in] _type struct type containing the field.
172
* @param[in] _field to return the type of.
173
*/
174
#define typeof_field(_type, _field) __typeof__(((_type *)NULL)->_field)
175
176
/** HEX concatenation macros
177
*
178
*/
179
#ifndef HEXIFY
180
# define XHEXIFY4(b1,b2,b3,b4) (0x ## b1 ## b2 ## b3 ## b4)
181
# define HEXIFY4(b1,b2,b3,b4) XHEXIFY4(b1, b2, b3, b4)
182
183
# define XHEXIFY3(b1,b2,b3) (0x ## b1 ## b2 ## b3)
184
# define HEXIFY3(b1,b2,b3) XHEXIFY3(b1, b2, b3)
185
186
# define XHEXIFY2(b1,b2) (0x ## b1 ## b2)
187
# define HEXIFY2(b1,b2) XHEXIFY2(b1, b2)
188
189
# define XHEXIFY(b1) (0x ## b1)
190
# define HEXIFY(b1) XHEXIFY(b1)
191
#endif
192
193
/** The ubiquitous stringify macros
194
*
195
*/
196
#define XSTRINGIFY(x) #x
197
#define STRINGIFY(x) XSTRINGIFY(x)
198
#define JOINSTR(x,y) XSTRINGIFY(x ## y)
199
200
/** Join two values without stringifying
201
*
202
* Useful for calling different macros based on the output of
203
*/
204
#define _JOIN(x,y) x ## y
205
#define JOIN(x,y) _JOIN(x,y)
206
207
/** Helper for initialising arrays of string literals
208
*/
209
#define L(_str) { _str, sizeof(_str) - 1 }
210
211
/** Fill macros for array initialisation
212
*/
213
#define F1(_idx, _val) [_idx] = _val
214
#define F2(_idx, _val) F1(_idx, _val), F1(_idx + 1, _val)
215
#define F4(_idx, _val) F2(_idx, _val), F2(_idx + 2, _val)
216
#define F8(_idx, _val) F4(_idx, _val), F4(_idx + 4, _val)
217
#define F16(_idx, _val) F8(_idx, _val), F8(_idx + 8, _val)
218
#define F32(_idx, _val) F16(_idx, _val), F16(_idx + 16, _val)
219
#define F64(_idx, _val) F32(_idx, _val), F32(_idx + 32, _val)
220
#define F128(_idx, _val) F64(_idx, _val), F64(_idx + 64, _val)
221
#define F256(_idx, _val) F128(_idx, _val), F128(_idx + 128, _val)
222
223
/** Variadic macro framework
224
*/
225
226
/**
227
* The VA_NARG macro evaluates to the number of arguments that have been
228
* passed to it.
229
*
230
* Laurent Deniau, "__VA_NARG__," 17 January 2006, <comp.std.c> (29 November 2007).
231
*/
232
#define VA_ARG_N( \
233
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
234
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
235
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
236
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
237
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
238
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
239
_61,_62,_63,N,...) N
240
241
#define VA_RSEQ_N() \
242
63,62,61,60, \
243
59,58,57,56,55,54,53,52,51,50, \
244
49,48,47,46,45,44,43,42,41,40, \
245
39,38,37,36,35,34,33,32,31,30, \
246
29,28,27,26,25,24,23,22,21,20, \
247
19,18,17,16,15,14,13,12,11,10, \
248
9,8,7,6,5,4,3,2,1,0
249
250
#define _VA_NARG(...) VA_ARG_N(__VA_ARGS__)
251
252
/** Return the number of variadic arguments up to 64
253
*
254
* @param[in] ... Variadic arguments to count.
255
*/
256
#define VA_NARG(...) _VA_NARG(__VA_ARGS__, VA_RSEQ_N())
257
258
259
/** Pass caller information to the function
260
*
261
*/
262
#ifndef NDEBUG
263
# define NDEBUG_LOCATION_ARGS char const *file, int line,
264
# define NDEBUG_LOCATION_VALS file, line,
265
# define NDEBUG_LOCATION_FMT "%s[%d]: "
266
# define NDEBUG_LOCATION_EXP __FILE__, __LINE__,
267
# define NDEBUG_LOCATION_NONNULL(_num) ((_num) + 2)
268
#else
269
# define NDEBUG_LOCATION_ARGS
270
# define NDEBUG_LOCATION_VALS
271
# define NDEBUG_LOCATION_FMT ""
272
# define NDEBUG_LOCATION_EXP
273
# define NDEBUG_LOCATION_NONNULL(_num) (_num)
274
#endif
275
276
/** Check if a given variable is the _const or not
277
*
278
* @param[in] _type The base type of the variable (should not be marked const)
279
* @param[in] _var to check.
280
*/
281
#define IS_CONST(_type, _var) \
282
_Generic((_var), \
283
_type: false, \
284
const _type: true \
285
)
286
287
/** Check if a given variable is the const or unconst version of a type
288
*
289
* Expands to _var if _var matches type, otherwise throws a compiler error.
290
*
291
* Useful for creating typesafe wrapper macros around functions which take
292
* void *s.
293
*
294
* @param[in] _type The base type of the variable (should not be marked const)
295
* @param[in] _var to check.
296
*/
297
#define IS_TYPE(_type, _var) \
298
_Generic((_var), \
299
_type: _var, \
300
const _type: _var \
301
)
302
/*
303
* Mark variables as unused
304
*/
305
#define UNUSED_VAR(_x) ((void)_x)
306
307
/** Pad _x to the next multiple of _y
308
*
309
*/
310
#define PAD(_x, _y) (_y - ((_x) % _y))
311
312
/** Should be placed before the function return type
313
*
314
*/
315
#define NEVER_RETURNS _Noreturn
316
#define HIDDEN CC_HINT(visibility("hidden"))
317
#define UNUSED CC_HINT(unused)
318
319
/** clang 10 doesn't recognised the FALL-THROUGH comment anymore
320
*/
321
#if (defined(__clang__) && (__clang_major__ >= 10)) || (defined(__GNUC__) && __GNUC__ >= 7)
322
# define FALL_THROUGH CC_HINT(fallthrough)
323
#else
324
# define FALL_THROUGH ((void)0)
325
#endif
326
327
#ifndef NDEBUG
328
# define NDEBUG_UNUSED
329
#else
330
# define NDEBUG_UNUSED UNUSED
331
#endif
332
333
#define BLANK_FORMAT " "
/* GCC_LINT whines about empty formats */
334
335
/*
336
* struct field size
337
*/
338
#define SIZEOF_MEMBER(_t, _m) sizeof(((_t *)0)->_m)
339
#define NUM_ELEMENTS(_t) (sizeof((_t)) / sizeof((_t)[0]))
340
341
/*
342
* For use with multidimensional arrays where
343
* the deeper array element has a size smaller than
344
* a pointer i.e. char foo[n][m]
345
*/
346
#define NUM_PTR_ELEMENTS(_t) (sizeof((_t)) / sizeof(void *))
347
348
/*
349
* Type checking
350
*/
351
352
/** Check if two types are compatible (the C11 way)
353
*
354
* Expands to 1 if types are compatible, else 0.
355
*
356
* @param[in] _x pointer to check.
357
* @param[in] _t type to check compatibility with.
358
*/
359
#define IS_COMPATIBLE(_x, _t) _Generic(_x, _t:1, default: 0)
360
361
/** Check if a field in a struct is compatible (the C11 way)
362
*
363
* Expands to 1 if types are compatible, else 0.
364
*
365
* @param[in] _s struct to check.
366
* @param[in] _f field in struct.
367
* @param[in] _t type to check compatibility with.
368
*/
369
#define IS_FIELD_COMPATIBLE(_s, _f, _t) _Generic(((_s *)0)->_f, _t:1, default: 0)
370
371
/*
372
* Only use GCC __attribute__ if were building with a GCClike
373
* compiler.
374
*/
375
#ifdef __GNUC__
376
# define CC_HINT(...) __attribute__((__VA_ARGS__))
377
# define likely(_x) __builtin_expect((_x), 1)
378
# define unlikely(_x) __builtin_expect((_x), 0)
379
# define unpredictable(_x) __builtin_unpredictable((_x))
380
#else
381
# define CC_HINT(...)
382
# define likely(_x) _x
383
# define unlikely(_x) _x
384
# define unpredictable(_x) _x
385
#endif
386
387
/*
388
* GNU version check
389
*/
390
#ifdef __GNUC__
391
#define __GNUC_PREREQ__(x, y) \
392
((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
393
(__GNUC__ > (x)))
394
#else
395
#define __GNUC_PREREQ__(x, y) 0
396
#endif
397
398
399
/*
400
* Macros to add pragmas
401
*/
402
#define PRAGMA(_x) _Pragma(#_x)
403
404
/*
405
* Handle acquire/release macros
406
*/
407
#if defined(__clang__) && (__clang_major__ >= 13)
408
# define CC_ACQUIRE_HANDLE(_tag) CC_HINT(acquire_handle(_tag))
409
# define CC_USE_HANDLE(_tag) CC_HINT(use_handle(_tag))
410
# define CC_RELEASE_HANDLE(_tag) CC_HINT(release_handle(_tag))
411
#else
412
# define CC_ACQUIRE_HANDLE(_tag)
413
# define CC_USE_HANDLE(_tag)
414
# define CC_RELEASE_HANDLE(_tag)
415
#endif
416
417
/*
418
* Disable various forms of ubsan
419
*/
420
#ifndef __has_feature
421
# define __has_feature(_x) 0
422
#endif
423
#if defined(__clang__) && __has_feature(undefined_behavior_sanitizer)
424
# define CC_NO_UBSAN(_sanitize) __attribute__((no_sanitize(STRINGIFY(_sanitize))))
425
#elif __GNUC_PREREQ__(4, 9) && defined(__SANITIZE_UNDEFINED__)
426
# define CC_NO_UBSAN(_sanitize) __attribute__((no_sanitize_undefined))
427
#else
428
# define CC_NO_UBSAN(_sanitize)
429
#endif
430
431
/*
432
* Disable sanitizers for undefined behaviour
433
*/
434
#if defined(__clang__)
435
# define CC_NO_SANITIZE_UNDEFINED(_what) CC_HINT(no_sanitize(_what))
436
#else
437
# define CC_NO_SANITIZE_UNDEFINED(_what)
438
#endif
439
440
/*
441
* Macros for controlling warnings in GCC >= 4.2 and clang >= 2.8
442
*/
443
#if defined(__clang__) && ((__clang_major__ * 100) + __clang_minor__ >= 208)
444
# define DIAG_UNKNOWN_PRAGMAS unknown-pragmas
445
# define DIAG_PRAGMA(_x) PRAGMA(clang diagnostic _x)
446
# define DIAG_OFF(_x) DIAG_PRAGMA(ignored JOINSTR(-W,_x))
447
# define DIAG_ON(_x) DIAG_PRAGMA(warning JOINSTR(-W,_x))
448
# define DIAG_PUSH() DIAG_PRAGMA(push)
449
# define DIAG_POP() DIAG_PRAGMA(pop)
450
#elif !defined(__clang__) && defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402
451
# define DIAG_UNKNOWN_PRAGMAS pragmas
452
# define DIAG_PRAGMA(_x) PRAGMA(GCC diagnostic _x)
453
# define DIAG_OFF(_x) DIAG_PRAGMA(ignored JOINSTR(-W,_x))
454
# define DIAG_ON(_x) DIAG_PRAGMA(warning JOINSTR(-W,_x))
455
# define DIAG_PUSH() DIAG_PRAGMA(push)
456
# define DIAG_POP() DIAG_PRAGMA(pop)
457
#else
458
# define DIAG_UNKNOWN_PRAGMAS
459
# define DIAG_OFF(_x)
460
# define DIAG_ON(_x)
461
# define DIAG_PUSH()
462
# define DIAG_POP()
463
#endif
464
465
/*
466
* For dealing with APIs which are only deprecated in OSX (like the OpenSSL API)
467
*/
468
#ifdef __APPLE__
469
# define USES_APPLE_DEPRECATED_API DIAG_OFF(deprecated-declarations)
470
# define USES_APPLE_RST DIAG_ON(deprecated-declarations)
471
#else
472
# define USES_APPLE_DEPRECATED_API
473
# define USES_APPLE_RST
474
#endif
475
476
#if defined(__GNUC__)
477
/* force inclusion of ident keywords in the face of optimization */
478
# define RCSID(id) static char const rcsid[] __attribute__ ((used)) = id;
479
# define RCSIDH(h, id) static char const rcsid_ ## h [] __attribute__ ((used)) = id;
480
#elif defined(__SUNPRO_C)
481
/* put ident keyword into comment section (nicer than gcc way) */
482
# define RCSID(id) PRAGMA(sun ident id)
483
# define RCSIDH(h, id) PRAGMA(sun ident id)
484
#else
485
# define RCSID(id)
486
# define RCSIDH(h, id)
487
#endif
488
#ifdef __cplusplus
489
}
490
#endif
491
492
/*
493
* For closing macros which open a code block e.g. fr_rb_inorder_foreach
494
*/
495
#define endforeach }
496
497
/* Explicitly evaluate and ignore an expression
498
*
499
* Why this macro?
500
* 1. gcc will warn about unused return values, even with the traditional cast to void.
501
* 2. There are cases in which an error case wants to clean up, but the function to
502
* clean up itself returns a status. In this context you don't care, but then you
503
* have the Scylla of unused return value and the Charybdis of Coverity complaining
504
* about an if that doesn't affect control flow. The following evaluates _expr and
505
* stores it in a variable marked as unused
506
* @param _expr The expression to be evaluated and ignored
507
* @param _type The type of the expression
508
*/
509
#define IGNORE(_expr, _type) \
510
do { \
511
_type ignored UNUSED = (_expr); \
512
} while (0)
memcmp_return
static int8_t memcmp_return(void const *a, void const *b, size_t a_len, size_t b_len)
memcmp function which has similar behaviour as strncmp
Definition
build.h:138
CMP
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
Definition
build.h:112
Generated by
1.9.8