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_ASSERT_LOG 80 #define CHPP_DEBUG_ASSERT_LOG(var, fmt, ...) \ 81 do { \ 82 if (!(var)) { \ 83 CHPP_LOGE(fmt, ##__VA_ARGS__); \ 84 CHPP_DEBUG_ASSERT(false); \ 85 } \ 86 } while (0) 87 #endif 88 89 #ifndef PRIu64 // Pre-C99 lacks PRIu64 support. Note that the correct 90 // definition on pre-C99 systems would be compiler-dependent. 91 #define PRIu64 "llu" 92 #endif 93 94 #if defined(__GNUC__) && (__STDC_VERSION__ >= 201112L) 95 #define CHPP_C11_OR_NEWER 96 #endif 97 98 #ifdef CHPP_C11_OR_NEWER 99 #define CHPP_STATIC_ASSERT _Static_assert 100 101 #else 102 #define CHPP_STATIC_ASSERT4(cond, var) typedef char var[(!!(cond)) * 2 - 1] 103 #define CHPP_STATIC_ASSERT3(cond, line) \ 104 CHPP_STATIC_ASSERT4(cond, static_assertion_at_line_##line) 105 #define CHPP_STATIC_ASSERT2(cond, line) CHPP_STATIC_ASSERT3(cond, line) 106 #define CHPP_STATIC_ASSERT(cond, msg) CHPP_STATIC_ASSERT2(cond, __LINE__) 107 108 #endif // CHPP_C11_OR_NEWER 109 110 // Time-related macros 111 #define CHPP_TIME_NONE 0 112 #define CHPP_TIME_MAX UINT64_MAX 113 #define CHPP_MSEC_PER_SEC UINT64_C(1000) 114 #define CHPP_USEC_PER_MSEC UINT64_C(1000) 115 #define CHPP_NSEC_PER_USEC UINT64_C(1000) 116 #define CHPP_USEC_PER_SEC (CHPP_USEC_PER_MSEC * CHPP_MSEC_PER_SEC) 117 #define CHPP_NSEC_PER_MSEC (CHPP_NSEC_PER_USEC * CHPP_USEC_PER_MSEC) 118 #define CHPP_NSEC_PER_SEC \ 119 (CHPP_NSEC_PER_USEC * CHPP_USEC_PER_MSEC * CHPP_MSEC_PER_SEC) 120 #define CHPP_NSEC_PER_MINUTE (CHPP_NSEC_PER_SEC * 60) 121 #define CHPP_NSEC_PER_HOUR (CHPP_NSEC_PER_MINUTE * 60) 122 123 #if defined(__GNUC__) || defined(__clang__) 124 #define check_types_match(t1, t2) ((__typeof__(t1) *)0 != (__typeof__(t2) *)0) 125 #else 126 #define check_types_match(t1, t2) 0 127 #endif 128 129 #define container_of(ptr, type, member) \ 130 ((type *)(void *)((char *)(ptr)-offsetof(type, member)) + \ 131 check_types_match(*(ptr), ((type *)0)->member)) 132 133 #define sizeof_member(type, member) (sizeof(((type *)0)->member)) 134 135 /** 136 * Macros for defining (compiler dependent) packed structures 137 */ 138 #if defined(__GNUC__) || defined(__clang__) 139 // For GCC and clang 140 #define CHPP_PACKED_START 141 #define CHPP_PACKED_END 142 #define CHPP_PACKED_ATTR __attribute__((packed)) 143 144 #elif defined(__ICCARM__) || defined(__CC_ARM) 145 // For IAR ARM and Keil MDK-ARM compilers 146 #define CHPP_PACKED_START _Pragma("pack(push, 1)") 147 #define CHPP_PACKED_END _Pragma("pack(pop)") 148 #define CHPP_PACKED_ATTR 149 150 #elif defined(_MSC_VER) 151 // For Microsoft Visual Studio 152 #define CHPP_PACKED_START __pragma(pack(push, 1)) 153 #define CHPP_PACKED_END __pragma(pack(pop)) 154 #define CHPP_PACKED_ATTR 155 156 #else 157 // Unknown compiler 158 #error Unrecognized compiler 159 #endif 160 161 #define CHPP_FREE_AND_NULLIFY(p) \ 162 do { \ 163 chppFree(p); \ 164 (p) = NULL; \ 165 } while (0) 166 167 //! Cast a const pointer to a non-const. This is necessary for removing const 168 //! with the -Wcast-qual compiler flag. 169 #define CHPP_CONST_CAST_POINTER(p) (void *)(intptr_t)(p) 170 171 #ifdef __cplusplus 172 } 173 #endif 174 175 #endif // CHPP_MACROS_H_ 176