63c8a4532e459fa816cb5b973e48c5c46b65b53d
[cascardo/ovs.git] / include / openvswitch / util.h
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef OPENVSWITCH_UTIL_H
18 #define OPENVSWITCH_UTIL_H 1
19
20 #include <openvswitch/version.h>
21 #include <openvswitch/compiler.h>
22
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26
27 void ovs_set_program_name__(const char *name, const char *version,
28                             const char *date, const char *time);
29
30 #define ovs_set_program_name(name, version) \
31         ovs_set_program_name__(name, version, __DATE__, __TIME__)
32
33 const char *ovs_get_program_name(void);
34 const char *ovs_get_program_version(void);
35
36 /* Expands to a string that looks like "<file>:<line>", e.g. "tmp.c:10".
37  *
38  * See http://c-faq.com/ansi/stringize.html for an explanation of OVS_STRINGIZE
39  * and OVS_STRINGIZE2. */
40 #define OVS_SOURCE_LOCATOR __FILE__ ":" OVS_STRINGIZE(__LINE__)
41 #define OVS_STRINGIZE(ARG) OVS_STRINGIZE2(ARG)
42 #define OVS_STRINGIZE2(ARG) #ARG
43
44 /* Saturating multiplication of "unsigned int"s: overflow yields UINT_MAX. */
45 #define OVS_SAT_MUL(X, Y)                                               \
46     ((Y) == 0 ? 0                                                       \
47      : (X) <= UINT_MAX / (Y) ? (unsigned int) (X) * (unsigned int) (Y)  \
48      : UINT_MAX)
49
50 /* Like the standard assert macro, except writes the failure message to the
51  * log. */
52 #ifndef NDEBUG
53 #define ovs_assert(CONDITION)                                           \
54     if (!OVS_LIKELY(CONDITION)) {                                       \
55         ovs_assert_failure(OVS_SOURCE_LOCATOR, __func__, #CONDITION);       \
56     }
57 #else
58 #define ovs_assert(CONDITION) ((void) (CONDITION))
59 #endif
60 OVS_NO_RETURN void ovs_assert_failure(const char *, const char *, const char *);
61
62 /* This is a void expression that issues a compiler error if POINTER cannot be
63  * compared for equality with the given pointer TYPE.  This generally means
64  * that POINTER is a qualified or unqualified TYPE.  However,
65  * BUILD_ASSERT_TYPE(POINTER, void *) will accept any pointer to object type,
66  * because any pointer to object can be compared for equality with "void *".
67  *
68  * POINTER can be any expression.  The use of "sizeof" ensures that the
69  * expression is not actually evaluated, so that any side effects of the
70  * expression do not occur.
71  *
72  * The cast to int is present only to suppress an "expression using sizeof
73  * bool" warning from "sparse" (see
74  * http://permalink.gmane.org/gmane.comp.parsers.sparse/2967). */
75 #define BUILD_ASSERT_TYPE(POINTER, TYPE) \
76     ((void) sizeof ((int) ((POINTER) == (TYPE) (POINTER))))
77
78 /* Casts 'pointer' to 'type' and issues a compiler warning if the cast changes
79  * anything other than an outermost "const" or "volatile" qualifier.
80  *
81  * The cast to int is present only to suppress an "expression using sizeof
82  * bool" warning from "sparse" (see
83  * http://permalink.gmane.org/gmane.comp.parsers.sparse/2967). */
84 #define CONST_CAST(TYPE, POINTER)                               \
85     (BUILD_ASSERT_TYPE(POINTER, TYPE),                          \
86      (TYPE) (POINTER))
87
88 /* Given a pointer-typed lvalue OBJECT, expands to a pointer type that may be
89  * assigned to OBJECT. */
90 #ifdef __GNUC__
91 #define OVS_TYPEOF(OBJECT) typeof(OBJECT)
92 #else
93 #define OVS_TYPEOF(OBJECT) void *
94 #endif
95
96 /* Given OBJECT of type pointer-to-structure, expands to the offset of MEMBER
97  * within an instance of the structure.
98  *
99  * The GCC-specific version avoids the technicality of undefined behavior if
100  * OBJECT is null, invalid, or not yet initialized.  This makes some static
101  * checkers (like Coverity) happier.  But the non-GCC version does not actually
102  * dereference any pointer, so it would be surprising for it to cause any
103  * problems in practice.
104  */
105 #ifdef __GNUC__
106 #define OBJECT_OFFSETOF(OBJECT, MEMBER) offsetof(typeof(*(OBJECT)), MEMBER)
107 #else
108 #define OBJECT_OFFSETOF(OBJECT, MEMBER) \
109     ((char *) &(OBJECT)->MEMBER - (char *) (OBJECT))
110 #endif
111
112 /* Yields the size of MEMBER within STRUCT. */
113 #define MEMBER_SIZEOF(STRUCT, MEMBER) (sizeof(((STRUCT *) NULL)->MEMBER))
114
115 /* Yields the offset of the end of MEMBER within STRUCT. */
116 #define OFFSETOFEND(STRUCT, MEMBER) \
117         (offsetof(STRUCT, MEMBER) + MEMBER_SIZEOF(STRUCT, MEMBER))
118
119 /* Given POINTER, the address of the given MEMBER in a STRUCT object, returns
120    the STRUCT object. */
121 #define CONTAINER_OF(POINTER, STRUCT, MEMBER)                           \
122         ((STRUCT *) (void *) ((char *) (POINTER) - offsetof (STRUCT, MEMBER)))
123
124 /* Given POINTER, the address of the given MEMBER within an object of the type
125  * that that OBJECT points to, returns OBJECT as an assignment-compatible
126  * pointer type (either the correct pointer type or "void *").  OBJECT must be
127  * an lvalue.
128  *
129  * This is the same as CONTAINER_OF except that it infers the structure type
130  * from the type of '*OBJECT'. */
131 #define OBJECT_CONTAINING(POINTER, OBJECT, MEMBER)                      \
132     ((OVS_TYPEOF(OBJECT)) (void *)                                      \
133      ((char *) (POINTER) - OBJECT_OFFSETOF(OBJECT, MEMBER)))
134
135 /* Given POINTER, the address of the given MEMBER within an object of the type
136  * that that OBJECT points to, assigns the address of the outer object to
137  * OBJECT, which must be an lvalue.
138  *
139  * Evaluates to (void) 0 as the result is not to be used. */
140 #define ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER) \
141     ((OBJECT) = OBJECT_CONTAINING(POINTER, OBJECT, MEMBER), (void) 0)
142
143 /* As explained in the comment above OBJECT_OFFSETOF(), non-GNUC compilers
144  * like MSVC will complain about un-initialized variables if OBJECT
145  * hasn't already been initialized. To prevent such warnings, INIT_CONTAINER()
146  * can be used as a wrapper around ASSIGN_CONTAINER. */
147 #define INIT_CONTAINER(OBJECT, POINTER, MEMBER) \
148     ((OBJECT) = NULL, ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER))
149
150 #ifdef __cplusplus
151 }
152 #endif
153
154 #endif