]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/compiler.h
zebra: Switch to using monotime(NULL) for re->uptime
[mirror_frr.git] / lib / compiler.h
index b19c33f65e6b3de860ae46f58e791429c67b4c65..474adc7c8bb08a1f1c7da14e7674442080b28ff4 100644 (file)
 #ifndef _FRR_COMPILER_H
 #define _FRR_COMPILER_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* function attributes, use like
  *   void prototype(void) __attribute__((_CONSTRUCTOR(100)));
  */
 #if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 5)
 #  define _RET_NONNULL    , returns_nonnull
 #endif
+#if __has_attribute(fallthrough)
+#  define _FALLTHROUGH __attribute__((fallthrough));
+#endif
 # define _CONSTRUCTOR(x)  constructor(x)
+# define _DEPRECATED(x) deprecated(x)
 #elif defined(__GNUC__)
 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
 #  define _RET_NONNULL    , returns_nonnull
 #  define _DESTRUCTOR(x)  destructor(x)
 #  define _ALLOC_SIZE(x)  alloc_size(x)
 #endif
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#  define _DEPRECATED(x) deprecated(x)
+#endif
+#if __GNUC__ >= 7
+#  define _FALLTHROUGH __attribute__((fallthrough));
+#endif
 #endif
 
 #ifdef __sun
 #ifndef _ALLOC_SIZE
 # define _ALLOC_SIZE(x)
 #endif
+#ifndef _FALLTHROUGH
+#define _FALLTHROUGH
+#endif
+#ifndef _DEPRECATED
+#define _DEPRECATED(x) deprecated
+#endif
+
+/* for helper functions defined inside macros */
+#define macro_inline   static inline __attribute__((unused))
+#define macro_pure     static inline __attribute__((unused, pure))
 
 /*
  * for warnings on macros, put in the macro content like this:
 #define CPP_NOTICE(text)
 #endif
 
+/* MAX / MIN are not commonly defined, but useful */
+/* note: glibc sys/param.h has #define MIN(a,b) (((a)<(b))?(a):(b)) */
+#ifdef MAX
+#undef MAX
+#endif
+#define MAX(a, b)                                                              \
+       ({                                                                     \
+               typeof(a) _max_a = (a);                                        \
+               typeof(b) _max_b = (b);                                        \
+               _max_a > _max_b ? _max_a : _max_b;                             \
+       })
+#ifdef MIN
+#undef MIN
+#endif
+#define MIN(a, b)                                                              \
+       ({                                                                     \
+               typeof(a) _min_a = (a);                                        \
+               typeof(b) _min_b = (b);                                        \
+               _min_a < _min_b ? _min_a : _min_b;                             \
+       })
+
+#ifndef offsetof
+#ifdef __compiler_offsetof
+#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE,MEMBER)
+#else
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+#endif
+
+/* this variant of container_of() retains 'const' on pointers without needing
+ * to be told to do so.  The following will all work without warning:
+ *
+ * struct member *p;
+ * const struct member *cp;
+ *
+ * const struct cont *x = container_of(cp, struct cont, member);
+ * const struct cont *x = container_of(cp, const struct cont, member);
+ * const struct cont *x = container_of(p,  struct cont, member);
+ * const struct cont *x = container_of(p,  const struct cont, member);
+ * struct cont *x       = container_of(p,  struct cont, member);
+ *
+ * but the following will generate warnings about stripping const:
+ *
+ * struct cont *x       = container_of(cp, struct cont, member);
+ * struct cont *x       = container_of(cp, const struct cont, member);
+ * struct cont *x       = container_of(p,  const struct cont, member);
+ */
+#ifdef container_of
+#undef container_of
+#endif
+#define container_of(ptr, type, member)                                        \
+       (__builtin_choose_expr(                                                \
+               __builtin_types_compatible_p(typeof(&((type *)0)->member),     \
+                       typeof(ptr))                                           \
+                   ||  __builtin_types_compatible_p(void *, typeof(ptr)),     \
+               ({                                                             \
+                       typeof(((type *)0)->member) *__mptr = (void *)(ptr);   \
+                       (type *)((char *)__mptr - offsetof(type, member));     \
+               }),                                                            \
+               ({                                                             \
+                       typeof(((const type *)0)->member) *__mptr = (ptr);     \
+                       (const type *)((const char *)__mptr -                  \
+                                       offsetof(type, member));               \
+               })                                                             \
+       ))
+
+#define container_of_null(ptr, type, member)                                   \
+       ({                                                                     \
+               typeof(ptr) _tmp = (ptr);                                      \
+               _tmp ? container_of(_tmp, type, member) : NULL;                \
+       })
+
+#define array_size(ar) (sizeof(ar) / sizeof(ar[0]))
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _FRR_COMPILER_H */