• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
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 CHPP_MACROS_H_
18 #define CHPP_MACROS_H_
19 
20 #include <assert.h>
21 #include <inttypes.h>
22 #include <stddef.h>
23 #include <stdlib.h>
24 
25 #include "chpp/memory.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 #define MOST_SIGNIFICANT_NIBBLE 0xf0
32 #define LEAST_SIGNIFICANT_NIBBLE 0x0f
33 
34 #ifndef UNUSED_VAR
35 #define UNUSED_VAR(var) ((void)(var))
36 #endif
37 
38 #ifndef MIN
39 #define MIN(a, b) ((a) < (b) ? (a) : (b))
40 #endif
41 
42 #ifndef MAX
43 #define MAX(a, b) ((a) > (b) ? (a) : (b))
44 #endif
45 
46 #ifndef ARRAY_SIZE
47 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
48 #endif
49 
50 #ifndef CHPP_ASSERT
51 #define CHPP_ASSERT(var) assert(var)
52 #endif
53 
54 #ifndef CHPP_ASSERT_LOG
55 #define CHPP_ASSERT_LOG(var, fmt, ...) \
56   do {                                 \
57     if (!(var)) {                      \
58       CHPP_LOGE(fmt, ##__VA_ARGS__);   \
59       CHPP_ASSERT(false);              \
60     }                                  \
61   } while (0)
62 #endif
63 
64 #ifndef CHPP_NOT_NULL
65 #define CHPP_NOT_NULL(var) CHPP_ASSERT((var) != NULL)
66 #endif
67 
68 /**
69  * Debug assertions that are not intended to be enabled for production software.
70  */
71 #ifndef CHPP_DEBUG_ASSERT
72 #ifdef CHPP_DEBUG_ASSERT_ENABLED
73 #define CHPP_DEBUG_ASSERT(var) CHPP_ASSERT(var)
74 #else
75 #define CHPP_DEBUG_ASSERT(var) UNUSED_VAR(var)
76 #endif  // CHPP_DEBUG_ASSERT_ENABLED
77 #endif  // CHPP_DEBUG_ASSERT
78 
79 #ifndef CHPP_DEBUG_NOT_NULL
80 #define CHPP_DEBUG_NOT_NULL(var) CHPP_DEBUG_ASSERT((var) != NULL)
81 #endif
82 
83 #ifndef CHPP_DEBUG_ASSERT_LOG
84 #define CHPP_DEBUG_ASSERT_LOG(var, fmt, ...) \
85   do {                                       \
86     if (!(var)) {                            \
87       CHPP_LOGE(fmt, ##__VA_ARGS__);         \
88       CHPP_DEBUG_ASSERT(false);              \
89     }                                        \
90   } while (0)
91 #endif
92 
93 #ifndef PRIu64  // Pre-C99 lacks PRIu64 support. Note that the correct
94                 // definition on pre-C99 systems would be compiler-dependent.
95 #define PRIu64 "llu"
96 #endif
97 
98 #if (defined(__cpp_static_assert) && (__cpp_static_assert >= 200410)) || \
99     (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L))
100 #define CHPP_STATIC_ASSERT static_assert
101 
102 #else  // Use fallback implementation as static_assert is not available.
103 #define CHPP_STATIC_ASSERT4(cond, var) typedef char var[(!!(cond)) * 2 - 1]
104 #define CHPP_STATIC_ASSERT3(cond, line) \
105   CHPP_STATIC_ASSERT4(cond, static_assertion_at_line_##line)
106 #define CHPP_STATIC_ASSERT2(cond, line) CHPP_STATIC_ASSERT3(cond, line)
107 #define CHPP_STATIC_ASSERT(cond, msg) CHPP_STATIC_ASSERT2(cond, __LINE__)
108 
109 #endif  // Use C11 or C++11 static_assert
110 
111 // Time-related macros
112 #define CHPP_TIME_NONE 0
113 #define CHPP_TIME_MAX UINT64_MAX
114 #define CHPP_MSEC_PER_SEC UINT64_C(1000)
115 #define CHPP_USEC_PER_MSEC UINT64_C(1000)
116 #define CHPP_NSEC_PER_USEC UINT64_C(1000)
117 #define CHPP_USEC_PER_SEC (CHPP_USEC_PER_MSEC * CHPP_MSEC_PER_SEC)
118 #define CHPP_NSEC_PER_MSEC (CHPP_NSEC_PER_USEC * CHPP_USEC_PER_MSEC)
119 #define CHPP_NSEC_PER_SEC \
120   (CHPP_NSEC_PER_USEC * CHPP_USEC_PER_MSEC * CHPP_MSEC_PER_SEC)
121 #define CHPP_NSEC_PER_MINUTE (CHPP_NSEC_PER_SEC * 60)
122 #define CHPP_NSEC_PER_HOUR (CHPP_NSEC_PER_MINUTE * 60)
123 
124 #if defined(__GNUC__) || defined(__clang__)
125 #define check_types_match(t1, t2) ((__typeof__(t1) *)0 != (__typeof__(t2) *)0)
126 #else
127 #define check_types_match(t1, t2) 0
128 #endif
129 
130 #define container_of(ptr, type, member)                     \
131   ((type *)(void *)((char *)(ptr)-offsetof(type, member)) + \
132    check_types_match(*(ptr), ((type *)0)->member))
133 
134 #define sizeof_member(type, member) (sizeof(((type *)0)->member))
135 
136 /**
137  * Macros for defining (compiler dependent) packed structures
138  */
139 #if defined(__GNUC__) || defined(__clang__)
140 // For GCC and clang
141 #define CHPP_PACKED_START
142 #define CHPP_PACKED_END
143 #define CHPP_PACKED_ATTR __attribute__((packed))
144 
145 #elif defined(__ICCARM__) || defined(__CC_ARM)
146 // For IAR ARM and Keil MDK-ARM compilers
147 #define CHPP_PACKED_START _Pragma("pack(push, 1)")
148 #define CHPP_PACKED_END _Pragma("pack(pop)")
149 #define CHPP_PACKED_ATTR
150 
151 #elif defined(_MSC_VER)
152 // For Microsoft Visual Studio
153 #define CHPP_PACKED_START __pragma(pack(push, 1))
154 #define CHPP_PACKED_END __pragma(pack(pop))
155 #define CHPP_PACKED_ATTR
156 
157 #else
158 // Unknown compiler
159 #error Unrecognized compiler
160 #endif
161 
162 #define CHPP_FREE_AND_NULLIFY(p) \
163   do {                           \
164     chppFree(p);                 \
165     (p) = NULL;                  \
166   } while (0)
167 
168 //! Cast a const pointer to a non-const. This is necessary for removing const
169 //! with the -Wcast-qual compiler flag.
170 #define CHPP_CONST_CAST_POINTER(p) (void *)(intptr_t)(p)
171 
172 #ifdef __cplusplus
173 }
174 #endif
175 
176 #endif  // CHPP_MACROS_H_
177