Merge branch 'mainstream'
[sliver-openvswitch.git] / lib / util.h
index 2159594..32a7c8c 100644 (file)
@@ -87,8 +87,23 @@ void ovs_assert_failure(const char *, const char *, const char *) NO_RETURN;
 
 extern const char *program_name;
 
+#define __ARRAY_SIZE_NOCHECK(ARRAY) (sizeof(ARRAY) / sizeof((ARRAY)[0]))
+#ifdef __GNUC__
+/* return 0 for array types, 1 otherwise */
+#define __ARRAY_CHECK(ARRAY)                                   \
+    !__builtin_types_compatible_p(typeof(ARRAY), typeof(&ARRAY[0]))
+
+/* compile-time fail if not array */
+#define __ARRAY_FAIL(ARRAY) (sizeof(char[-2*!__ARRAY_CHECK(ARRAY)]))
+#define __ARRAY_SIZE(ARRAY)                                    \
+    __builtin_choose_expr(__ARRAY_CHECK(ARRAY),                        \
+        __ARRAY_SIZE_NOCHECK(ARRAY), __ARRAY_FAIL(ARRAY))
+#else
+#define __ARRAY_SIZE(ARRAY) __ARRAY_SIZE_NOCHECK(ARRAY)
+#endif
+
 /* Returns the number of elements in ARRAY. */
-#define ARRAY_SIZE(ARRAY) (sizeof ARRAY / sizeof *ARRAY)
+#define ARRAY_SIZE(ARRAY) __ARRAY_SIZE(ARRAY)
 
 /* Returns X / Y, rounding up.  X must be nonnegative to round correctly. */
 #define DIV_ROUND_UP(X, Y) (((X) + ((Y) - 1)) / (Y))
@@ -189,9 +204,13 @@ is_pow2(uintmax_t x)
  * that that OBJECT points to, assigns the address of the outer object to
  * OBJECT, which must be an lvalue.
  *
- * Evaluates to 1. */
+ * Evaluates to (void) 0 as the result is not to be used. */
 #define ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER) \
-    ((OBJECT) = OBJECT_CONTAINING(POINTER, OBJECT, MEMBER), 1)
+    ((OBJECT) = OBJECT_CONTAINING(POINTER, OBJECT, MEMBER), (void) 0)
+
+/* Given ATTR, and TYPE, cast the ATTR to TYPE by first casting ATTR to
+ * (void *). This is to suppress the alignment warning issued by clang. */
+#define ALIGNED_CAST(TYPE, ATTR) ((TYPE) (void *) (ATTR))
 
 #ifdef  __cplusplus
 extern "C" {
@@ -203,7 +222,7 @@ void set_program_name__(const char *name, const char *version,
         set_program_name__(name, VERSION, __DATE__, __TIME__)
 
 const char *get_subprogram_name(void);
-void set_subprogram_name(const char *name);
+void set_subprogram_name(const char *format, ...) PRINTF_FORMAT(1, 2);
 
 const char *get_program_version(void);
 void ovs_print_version(uint8_t min_ofp, uint8_t max_ofp);