summaryrefslogtreecommitdiff
path: root/lib/compiler.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler.h')
-rw-r--r--lib/compiler.h64
1 files changed, 52 insertions, 12 deletions
diff --git a/lib/compiler.h b/lib/compiler.h
index 70ef8e9bc8..bf443906eb 100644
--- a/lib/compiler.h
+++ b/lib/compiler.h
@@ -21,6 +21,21 @@
extern "C" {
#endif
+#ifdef __cplusplus
+# if __cplusplus < 201103L
+# error FRRouting headers must be compiled in C++11 mode or newer
+# endif
+/* C++ defines static_assert(), but not _Static_assert(). C defines
+ * _Static_assert() and has static_assert() in <assert.h>. However, we mess
+ * with assert() in zassert.h so let's not include <assert.h> here.
+ */
+# define _Static_assert static_assert
+#else
+# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L
+# error FRRouting must be compiled with min. -std=gnu11 (GNU ISO C11 dialect)
+# endif
+#endif
+
/* function attributes, use like
* void prototype(void) __attribute__((_CONSTRUCTOR(100)));
*/
@@ -108,19 +123,13 @@ extern "C" {
#define assume(x)
#endif
-/* pure = function does not modify memory & return value is the same if
- * memory hasn't changed (=> allows compiler to optimize)
- *
- * Mostly autodetected by the compiler if function body is available (i.e.
- * static inline functions in headers). Since that implies it should only be
- * used in headers for non-inline functions, the "extern" is included here.
- */
-#define ext_pure extern __attribute__((pure))
-
/* for helper functions defined inside macros */
#define macro_inline static inline __attribute__((unused))
#define macro_pure static inline __attribute__((unused, pure))
+/* if the macro ends with a function definition */
+#define MACRO_REQUIRE_SEMICOLON() \
+ _Static_assert(1, "please add a semicolon after this macro")
/* variadic macros, use like:
* #define V_0() ...
@@ -164,6 +173,29 @@ extern "C" {
#define MACRO_REPEAT(NAME, ...) \
MACRO_VARIANT(_MACRO_REPEAT, ##__VA_ARGS__)(NAME, ##__VA_ARGS__)
+/* per-arglist repeat macro, use like this:
+ * #define foo(...) MAP_LISTS(F, ##__VA_ARGS__)
+ * where F is a n-ary function where n is the number of args in each arglist.
+ * e.g.: MAP_LISTS(f, (a, b), (c, d))
+ * expands to: f(a, b); f(c, d)
+ */
+
+#define ESC(...) __VA_ARGS__
+#define MAP_LISTS(M, ...) \
+ _CONCAT(_MAP_LISTS_, PP_NARG(__VA_ARGS__))(M, ##__VA_ARGS__)
+#define _MAP_LISTS_0(M)
+#define _MAP_LISTS_1(M, _1) ESC(M _1)
+#define _MAP_LISTS_2(M, _1, _2) ESC(M _1; M _2)
+#define _MAP_LISTS_3(M, _1, _2, _3) ESC(M _1; M _2; M _3)
+#define _MAP_LISTS_4(M, _1, _2, _3, _4) ESC(M _1; M _2; M _3; M _4)
+#define _MAP_LISTS_5(M, _1, _2, _3, _4, _5) ESC(M _1; M _2; M _3; M _4; M _5)
+#define _MAP_LISTS_6(M, _1, _2, _3, _4, _5, _6) \
+ ESC(M _1; M _2; M _3; M _4; M _5; M _6)
+#define _MAP_LISTS_7(M, _1, _2, _3, _4, _5, _6, _7) \
+ ESC(M _1; M _2; M _3; M _4; M _5; M _6; M _7)
+#define _MAP_LISTS_8(M, _1, _2, _3, _4, _5, _6, _7, _8) \
+ ESC(M _1; M _2; M _3; M _4; M _5; M _6; M _7; M _8)
+
/*
* for warnings on macros, put in the macro content like this:
* #define MACRO BLA CPP_WARN("MACRO has been deprecated")
@@ -298,7 +330,7 @@ extern "C" {
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
9, 8, 7, 6, 5, 4, 3, 2, 1, 0
-#define PP_NARG_(...) PP_ARG_N(__VA_ARGS__)
+#define PP_NARG_(...) PP_ARG_N(__VA_ARGS__)
#define PP_NARG(...) PP_NARG_(_, ##__VA_ARGS__, PP_RSEQ_N())
@@ -338,8 +370,16 @@ extern "C" {
#define PRIx64 "Lx"
#else /* !_FRR_ATTRIBUTE_PRINTFRR */
+#ifdef __NetBSD__
+#define PRINTFRR(a, b) __attribute__((format(gnu_syslog, a, b)))
+#else
#define PRINTFRR(a, b) __attribute__((format(printf, a, b)))
+#endif
+/* frr-format plugin is C-only for now, so no point in doing these shenanigans
+ * for C++... (also they can break some C++ stuff...)
+ */
+#ifndef __cplusplus
/* these should be typedefs, but might also be #define */
#ifdef uint64_t
#undef uint64_t
@@ -357,10 +397,8 @@ typedef signed long long _int64_t;
/* if this breaks, 128-bit machines may have entered reality (or <long long>
* is something weird)
*/
-#if __STDC_VERSION__ >= 201112L
_Static_assert(sizeof(_uint64_t) == 8 && sizeof(_int64_t) == 8,
"nobody expects the spanish intquisition");
-#endif
/* since we redefined int64_t, we also need to redefine PRI*64 */
#undef PRIu64
@@ -369,6 +407,8 @@ _Static_assert(sizeof(_uint64_t) == 8 && sizeof(_int64_t) == 8,
#define PRIu64 "llu"
#define PRId64 "lld"
#define PRIx64 "llx"
+
+#endif /* !__cplusplus */
#endif /* !_FRR_ATTRIBUTE_PRINTFRR */
#ifdef __cplusplus