1 #ifndef BASEDEFS_H 2 #define BASEDEFS_H 3 4 /************************************************************************************************** 5 * IOWOW library 6 * 7 * MIT License 8 * 9 * Copyright (c) 2012-2022 Softmotions Ltd <info@softmotions.com> 10 * 11 * Permission is hereby granted, free of charge, to any person obtaining a copy 12 * of this software and associated documentation files (the "Software"), to deal 13 * in the Software without restriction, including without limitation the rights 14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 * copies of the Software, and to permit persons to whom the Software is 16 * furnished to do so, subject to the following conditions: 17 * 18 * The above copyright notice and this permission notice shall be included in all 19 * copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 * SOFTWARE. 28 *************************************************************************************************/ 29 30 /** 31 * @file 32 * @brief Very basic definitions. 33 * @author Anton Adamansky (adamansky@softmotions.com) 34 */ 35 36 #ifdef __cplusplus 37 #define IW_EXTERN_C_START extern "C" { 38 #define IW_EXTERN_C_END } 39 #else 40 #define IW_EXTERN_C_START 41 #define IW_EXTERN_C_END 42 #endif 43 44 #define IW_XSTR(s) IW_STR(s) 45 #define IW_STR(s) #s 46 47 #define IW_MAX(x__, y__) ({ __typeof__(x__) x = (x__); __typeof__(y__) y = (y__); x < y ? y : x; }) 48 #define IW_MIN(x__, y__) ({ __typeof__(x__) x = (x__); __typeof__(y__) y = (y__); x < y ? x : y; }) 49 #define IW_LLEN(l__) (sizeof(l__) - 1) 50 51 #if (defined(_WIN32) || defined(_WIN64)) 52 #if (defined(IW_NODLL) || defined(IW_STATIC)) 53 #define IW_EXPORT 54 #else 55 #ifdef IW_API_EXPORTS 56 #define IW_EXPORT __declspec(dllexport) 57 #else 58 #define IW_EXPORT __declspec(dllimport) 59 #endif 60 #endif 61 #else 62 #if __GNUC__ >= 4 63 #define IW_EXPORT __attribute__((visibility("default"))) 64 #else 65 #define IW_EXPORT 66 #endif 67 #endif 68 69 #if defined(__GNUC__) 70 #define IW_INLINE static inline __attribute__((always_inline)) 71 #else 72 #define IW_INLINE static inline 73 #endif 74 75 #define IW_SOFT_INLINE static inline 76 77 #if __GNUC__ >= 4 78 #define WUR __attribute__((warn_unused_result)) 79 #define IW_ALLOC __attribute__((malloc)) __attribute__((warn_unused_result)) 80 #define IW_NORET __attribute__((noreturn)) 81 #else 82 #define WUR 83 #define IW_ALLOC 84 #define IW_NORET 85 #endif 86 87 #define IW_CONSTRUCTOR __attribute__((constructor)) 88 #define IW_DESTRUCTOR __attribute__((destructor)) 89 90 #define IW_CLEANUP(func__) __attribute__(cleanup(func__)) 91 92 #define IW_CLEANUP_FUNC(type__, func__) \ 93 static inline void func__ ## _cc(type__ * p) { \ 94 if (*p) { \ 95 *p = func__(*p); \ 96 } \ 97 } 98 99 #define IW_CLEANUP_DESTROY_FUNC(type__, func__) \ 100 static inline void func__ ## _cc(type__ * p) { \ 101 if (*p) { \ 102 func__(*p); \ 103 } \ 104 } 105 106 107 #define IW_SENTINEL __attribute__((sentinel)) 108 109 #define IW_ARR_STATIC static 110 #define IW_ARR_CONST const 111 112 #ifdef _WIN32 113 #include <windows.h> 114 #define INVALIDHANDLE(h__) \ 115 (((h__) == INVALID_HANDLE_VALUE) || (h__) == NULL) 116 #else 117 typedef int HANDLE; 118 #define INVALID_HANDLE_VALUE (-1) 119 #define INVALIDHANDLE(h__) ((h__) < 0 || (h__) == UINT16_MAX) 120 #endif 121 122 #define IW_ERROR_START 70000 123 124 #define IWNUMBUF_SIZE 32 125 126 #ifdef _WIN32 127 #define IW_PATH_CHR '\\' 128 #define IW_PATH_STR "\\" 129 #define IW_LINE_SEP "\r\n" 130 #else 131 #define IW_PATH_CHR '/' 132 #define IW_PATH_STR "/" 133 #define IW_LINE_SEP "\n" 134 #endif 135 136 #define ZGO(label__, val__) \ 137 ({ __typeof__(val__) v__ = (val__); \ 138 if (!v__) goto label__; \ 139 v__; }) 140 141 #define ZRET(ret__, val__) \ 142 ({ __typeof__(val__) v__ = (val__); \ 143 if (!v__) return ret__; \ 144 v__; }) 145 146 #ifdef __GNUC__ 147 #define RCGO(rc__, label__) if (__builtin_expect((!!(rc__)), 0)) goto label__ 148 #else 149 #define RCGO(rc__, label__) if (rc__) goto label__ 150 #endif 151 152 #define RCIF(res__, rc__, rcv__, label__) \ 153 if (res__) { \ 154 rc__ = (rcv__); \ 155 goto label__; \ 156 } 157 158 #define RCHECK(rc__, label__, expr__) \ 159 rc__ = expr__; \ 160 RCGO(rc__, label__) 161 162 #define RCC(rc__, label__, expr__) RCHECK(rc__, label__, expr__) 163 164 #ifndef RCGA 165 #define RCGA(v__, label__) \ 166 if (!(v__)) { \ 167 rc = iwrc_set_errno(IW_ERROR_ALLOC, errno); \ 168 goto label__; \ 169 } 170 #endif 171 172 #ifndef RCA 173 #define RCA(v__, label__) RCGA(v__, label__) 174 #endif 175 176 #ifndef RCB 177 #define RCB(label__, v__) RCGA(v__, label__) 178 #endif 179 180 #ifndef RCN 181 #define RCN(label__, v__) \ 182 if ((v__) < 0) { \ 183 rc = iwrc_set_errno(IW_ERROR_ERRNO, errno); \ 184 goto label__; \ 185 } 186 #endif 187 188 #ifndef RCT 189 #define RCT(label__, val__) \ 190 ({ __typeof__(val__) v__ = (val__); \ 191 if (v__) { \ 192 rc = iwrc_set_errno(IW_ERROR_THREADING_ERRNO, v__); \ 193 goto label__; \ 194 } \ 195 }) 196 #endif 197 198 #ifdef __GNUC__ 199 #define RCRET(rc__) if (__builtin_expect((!!(rc__)), 0)) return (rc__) 200 #else 201 #define RCRET(rc__) if (rc__) return (rc__) 202 #endif 203 204 #define RCR(expr__) \ 205 ({ iwrc rc__ = (expr__); RCRET(rc__); 0; }) 206 207 #ifdef __GNUC__ 208 #define RCBREAK(rc__) if (__builtin_expect((!!(rc__)), 0)) break 209 #else 210 #define RCBREAK(rc__) if (rc__) break 211 #endif 212 213 #ifdef __GNUC__ 214 #define RCONT(rc__) if (__builtin_expect((!!(rc__)), 0)) continue 215 #else 216 #define RCONT(rc__) if (rc__) continue 217 #endif 218 219 #ifndef MIN 220 #define MIN(a_, b_) ((a_) < (b_) ? (a_) : (b_)) 221 #endif 222 223 #ifndef MAX 224 #define MAX(a_, b_) ((a_) > (b_) ? (a_) : (b_)) 225 #endif 226 227 /* Align x_ with v_. v_ must be simple power for 2 value. */ 228 #define IW_ROUNDUP(x_, v_) (((x_) + (v_) - 1) & ~((v_) - 1)) 229 230 /* Round down align x_ with v_. v_ must be simple power for 2 value. */ 231 #define IW_ROUNDOWN(x_, v_) ((x_) - ((x_) & ((v_) - 1))) 232 233 #ifdef __GNUC__ 234 #define IW_LIKELY(x_) __builtin_expect(!!(x_), 1) 235 #define IW_UNLIKELY(x_) __builtin_expect(!!(x_), 0) 236 #else 237 #define IW_LIKELY(x_) 238 #define IW_UNLIKELY(x_) 239 #endif 240 241 #if defined(NDEBUG) 242 #define IW_DODEBUG(IW_expr_) 243 #else 244 #define IW_DODEBUG(IW_expr_) \ 245 { IW_expr_; } 246 #endif 247 248 #if __GNUC__ >= 5 249 #define IW_SWAB16(num_) __builtin_bswap16(num_) 250 #else 251 #define IW_SWAB16(num_) \ 252 ((((num_) & 0x00ffU) << 8) | (((num_) & 0xff00U) >> 8)) 253 #endif 254 255 #if __GNUC__ >= 4 256 #define IW_SWAB32(num_) __builtin_bswap32(num_) 257 #else 258 #define IW_SWAB32(num_) \ 259 ((((num_) & 0x000000ffUL) << 24) | (((num_) & 0x0000ff00UL) << 8) \ 260 | (((num_) & 0x00ff0000UL) >> 8) | (((num_) & 0xff000000UL) >> 24)) 261 #endif 262 263 #if __GNUC__ >= 4 264 #define IW_SWAB64(num_) __builtin_bswap64(num_) 265 #else 266 #define IW_SWAB64(num_) \ 267 ((((num_) & 0x00000000000000ffULL) << 56) \ 268 | (((num_) & 0x000000000000ff00ULL) << 40) \ 269 | (((num_) & 0x0000000000ff0000ULL) << 24) \ 270 | (((num_) & 0x00000000ff000000ULL) << 8) \ 271 | (((num_) & 0x000000ff00000000ULL) >> 8) \ 272 | (((num_) & 0x0000ff0000000000ULL) >> 24) \ 273 | (((num_) & 0x00ff000000000000ULL) >> 40) \ 274 | (((num_) & 0xff00000000000000ULL) >> 56)) 275 #endif 276 277 #ifdef IW_BIGENDIAN 278 #define IW_HTOIS(num_) IW_SWAB16(num_) 279 #define IW_HTOIL(num_) IW_SWAB32(num_) 280 #define IW_HTOILL(num_) IW_SWAB64(num_) 281 #define IW_ITOHS(num_) IW_SWAB16(num_) 282 #define IW_ITOHL(num_) IW_SWAB32(num_) 283 #define IW_ITOHLL(num_) IW_SWAB64(num_) 284 #else 285 #define IW_HTOIS(num_) (num_) 286 #define IW_HTOIL(num_) (num_) 287 #define IW_HTOILL(num_) (num_) 288 #define IW_ITOHS(num_) (num_) 289 #define IW_ITOHL(num_) (num_) 290 #define IW_ITOHLL(num_) (num_) 291 #endif 292 293 #define IW_WRITEBV(ptr_, v_, m_) \ 294 static_assert(sizeof(v_) == 1, "Mismatch v_ size"); \ 295 (v_) = (m_); \ 296 memcpy(ptr_, &(v_), 1); \ 297 (ptr_) += 1 298 299 #define IW_WRITESV(ptr_, v_, m_) \ 300 static_assert(sizeof(v_) == 2, "Mismatch v_ size"); \ 301 (v_) = (m_); \ 302 (v_) = IW_HTOIS(v_); \ 303 memcpy(ptr_, &(v_), 2); \ 304 (ptr_) += 2 305 306 #define IW_WRITELV(ptr_, v_, m_) \ 307 static_assert(sizeof(v_) == 4, "Mismatch v_ size"); \ 308 (v_) = (m_); \ 309 (v_) = IW_HTOIL(v_); \ 310 memcpy(ptr_, &(v_), 4); \ 311 (ptr_) += 4 312 313 #define IW_WRITELLV(ptr_, v_, m_) \ 314 static_assert(sizeof(v_) == 8, "Mismatch v_ size"); \ 315 (v_) = (m_); \ 316 (v_) = IW_HTOILL(v_); \ 317 memcpy((ptr_), &(v_), 8); \ 318 (ptr_) += 8 319 320 #define IW_READBV(ptr_, t_, m_) \ 321 static_assert(sizeof(t_) == 1, "Mismatch t_ size"); \ 322 (t_) = 0; \ 323 memcpy(&(t_), ptr_, 1); \ 324 (m_) = (t_); \ 325 (ptr_) += 1 326 327 #define IW_READSV(ptr_, t_, m_) \ 328 static_assert(sizeof(t_) == 2, "Mismatch t_ size"); \ 329 (t_) = 0; \ 330 memcpy(&(t_), ptr_, 2); \ 331 (m_) = IW_ITOHS(t_); \ 332 (ptr_) += 2 333 334 #define IW_READLV(ptr_, t_, m_) \ 335 static_assert(sizeof(t_) == 4, "Mismatch t_ size"); \ 336 (t_) = 0; \ 337 memcpy(&(t_), ptr_, 4); \ 338 (m_) = IW_ITOHL(t_); \ 339 (ptr_) += 4 340 341 #define IW_READLLV(ptr_, t_, m_) \ 342 static_assert(sizeof(t_) == 8, "Mismatch t_ size"); \ 343 (t_) = 0; \ 344 memcpy(&(t_), ptr_, 8); \ 345 (m_) = IW_ITOHLL(t_); \ 346 (ptr_) += 8 347 348 #ifndef SIZE_T_MAX 349 #define SIZE_T_MAX ((size_t) -1) 350 #endif 351 352 #ifndef OFF_T_MIN 353 #define OFF_T_MIN ((off_t) (((uint64_t) 1) << (8 * sizeof(off_t) - 1))) 354 #endif 355 #ifndef OFF_T_MAX 356 #define OFF_T_MAX ((off_t) ~(((uint64_t) 1) << (8 * sizeof(off_t) - 1))) 357 #endif 358 359 #include <stdint.h> 360 #include <stddef.h> 361 #include <stdbool.h> 362 #include <sys/types.h> 363 364 #ifdef _WIN32 365 typedef _locale_t locale_t; 366 #endif 367 368 #if defined(__GNUC__) || defined(__clang__) 369 #define IW_DEPRECATED __attribute__((deprecated)) 370 #elif defined(_MSC_VER) 371 #define IW_DEPRECATED __declspec(deprecated) 372 #else 373 #define IW_DEPRECATED 374 #endif 375 376 /** 377 * @brief The operation result status code. 378 * 379 * Zero status code `0` indicates <em>operation success</em> 380 * 381 * Status code can embed an `errno` code as operation result. 382 * In this case `uint32_t iwrc_strip_errno(iwrc *rc)` used 383 * to fetch embedded errno. 384 * 385 * @see iwlog.h 386 */ 387 typedef uint64_t iwrc; 388 389 /** 390 * @brief A rational number. 391 */ 392 typedef struct IW_RNUM { 393 int32_t n; /**< Numerator */ 394 int32_t dn; /**< Denometator */ 395 } IW_RNUM; 396 397 #endif 398