Commit 326711448308c4197923d75f40ae02162f152ce8

Guillem Jover 2014-11-01T00:21:30

Add __offsetof, __rangeof and __containerof to sys/cdefs.h Import and adapt from FreeBSD.

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