Add __offsetof, __rangeof and __containerof to sys/cdefs.h Import and adapt from FreeBSD.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
diff --git a/include/bsd/sys/cdefs.h b/include/bsd/sys/cdefs.h
index c1567be..4b1063a 100644
--- a/include/bsd/sys/cdefs.h
+++ b/include/bsd/sys/cdefs.h
@@ -114,6 +114,47 @@
# define __bounded__(x, y, z)
#endif
+/*
+ * We define this here since <stddef.h>, <sys/queue.h>, and <sys/types.h>
+ * require it.
+ */
+#ifndef __offsetof
+# if LIBBSD_GCC_VERSION >= 0x0401
+# define __offsetof(type, field) __builtin_offsetof(type, field)
+# else
+# ifndef __cplusplus
+# define __offsetof(type, field) \
+ ((__size_t)(__uintptr_t)((const volatile void *)&((type *)0)->field))
+# else
+# define __offsetof(type, field) \
+ (__offsetof__ (reinterpret_cast <__size_t> \
+ (&reinterpret_cast <const volatile char &> \
+ (static_cast<type *> (0)->field))))
+# endif
+# endif
+#endif
+
+#define __rangeof(type, start, end) \
+ (__offsetof(type, end) - __offsetof(type, start))
+
+/*
+ * Given the pointer x to the member m of the struct s, return
+ * a pointer to the containing structure. When using GCC, we first
+ * assign pointer x to a local variable, to check that its type is
+ * compatible with member m.
+ */
+#ifndef __containerof
+# if LIBBSD_GCC_VERSION >= 0x0301
+# define __containerof(x, s, m) ({ \
+ const volatile __typeof(((s *)0)->m) *__x = (x); \
+ __DEQUALIFY(s *, (const volatile char *)__x - __offsetof(s, m)); \
+})
+# else
+# define __containerof(x, s, m) \
+ __DEQUALIFY(s *, (const volatile char *)(x) - __offsetof(s, m))
+# endif
+#endif
+
#ifndef __RCSID
# define __RCSID(x)
#endif