1 /* $Id: kDefs.h 105 2017-11-21 23:55:40Z bird $ */ 2 /** @file 3 * kTypes - Defines and Macros. 4 */ 5 6 /* 7 * Copyright (c) 2006-2017 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net> 8 * 9 * Permission is hereby granted, free of charge, to any person 10 * obtaining a copy of this software and associated documentation 11 * files (the "Software"), to deal in the Software without 12 * restriction, including without limitation the rights to use, 13 * copy, modify, merge, publish, distribute, sublicense, and/or sell 14 * copies of the Software, and to permit persons to whom the 15 * Software is furnished to do so, subject to the following 16 * conditions: 17 * 18 * The above copyright notice and this permission notice shall be 19 * included in all copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 * OTHER DEALINGS IN THE SOFTWARE. 29 */ 30 31 #ifndef ___k_kDefs_h___ 32 #define ___k_kDefs_h___ 33 34 /** @defgroup grp_kDefs kDefs - Defines and Macros 35 * @{ */ 36 37 /** @name Operative System Identifiers. 38 * These are the value that the K_OS \#define can take. 39 * @{ 40 */ 41 /** Unknown OS. */ 42 #define K_OS_UNKNOWN 0 43 /** Darwin - aka Mac OS X. */ 44 #define K_OS_DARWIN 1 45 /** DragonFly BSD. */ 46 #define K_OS_DRAGONFLY 2 47 /** FreeBSD. */ 48 #define K_OS_FREEBSD 3 49 /** GNU/Hurd. */ 50 #define K_OS_GNU_HURD 4 51 /** GNU/kFreeBSD. */ 52 #define K_OS_GNU_KFBSD 5 53 /** GNU/kNetBSD or GNU/NetBSD or whatever the decide to call it. */ 54 #define K_OS_GNU_KNBSD 6 55 /** Haiku. */ 56 #define K_OS_HAIKU 7 57 /** Linux. */ 58 #define K_OS_LINUX 8 59 /** NetBSD. */ 60 #define K_OS_NETBSD 9 61 /** NT (native). */ 62 #define K_OS_NT 10 63 /** OpenBSD*/ 64 #define K_OS_OPENBSD 11 65 /** OS/2 */ 66 #define K_OS_OS2 12 67 /** Solaris */ 68 #define K_OS_SOLARIS 13 69 /** Windows. */ 70 #define K_OS_WINDOWS 14 71 /** The max K_OS_* value (exclusive). */ 72 #define K_OS_MAX 15 73 /** @} */ 74 75 /** @def K_OS 76 * Indicates which OS we're targetting. It's a \#define with is 77 * assigned one of the K_OS_* defines above. 78 * 79 * So to test if we're on FreeBSD do the following: 80 * @code 81 * #if K_OS == K_OS_FREEBSD 82 * some_funky_freebsd_specific_stuff(); 83 * #endif 84 * @endcode 85 */ 86 #ifndef K_OS 87 # if defined(__APPLE__) 88 # define K_OS K_OS_DARWIN 89 # elif defined(__DragonFly__) 90 # define K_OS K_OS_DRAGONFLY 91 # elif defined(__FreeBSD__) 92 # define K_OS K_OS_FREEBSD 93 # elif defined(__FreeBSD_kernel__) 94 # define K_OS K_OS_GNU_KFBSD 95 # elif defined(__gnu_hurd__) 96 # define K_OS K_OS_GNU_HURD 97 # elif defined(__gnu_linux__) 98 # define K_OS K_OS_LINUX 99 # elif defined(__NetBSD__) /*??*/ 100 # define K_OS K_OS_NETBSD 101 # elif defined(__NetBSD_kernel__) 102 # define K_OS K_OS_GNU_KNBSD 103 # elif defined(__OpenBSD__) /*??*/ 104 # define K_OS K_OS_OPENBSD 105 # elif defined(__OS2__) 106 # define K_OS K_OS_OS2 107 # elif defined(__sun__) || defined(__SunOS__) || defined(__sun) || defined(__SunOS) 108 # define K_OS K_OS_SOLARIS 109 # elif defined(_WIN32) || defined(_WIN64) 110 # define K_OS K_OS_WINDOWS 111 # elif defined(__haiku__) || defined(__HAIKU__) 112 # define K_OS K_OS_HAIKU 113 # else 114 # error "Port Me" 115 # endif 116 #endif 117 #if K_OS < K_OS_UNKNOWN || K_OS >= K_OS_MAX 118 # error "Invalid K_OS value." 119 #endif 120 121 122 123 /** @name Architecture bit width. 124 * @{ */ 125 #define K_ARCH_BIT_8 0x0100 /**< 8-bit */ 126 #define K_ARCH_BIT_16 0x0200 /**< 16-bit */ 127 #define K_ARCH_BIT_32 0x0400 /**< 32-bit */ 128 #define K_ARCH_BIT_64 0x0800 /**< 64-bit */ 129 #define K_ARCH_BIT_128 0x1000 /**< 128-bit */ 130 #define K_ARCH_BIT_MASK 0x1f00 /**< The bit mask. */ 131 #define K_ARCH_BIT_SHIFT 5 /**< Shift count for producing the width in bits. */ 132 #define K_ARCH_BYTE_SHIFT 8 /**< Shift count for producing the width in bytes. */ 133 /** @} */ 134 135 /** @name Architecture Endianness. 136 * @{ */ 137 #define K_ARCH_END_LITTLE 0x2000 /**< Little-endian. */ 138 #define K_ARCH_END_BIG 0x4000 /**< Big-endian. */ 139 #define K_ARCH_END_BI 0x6000 /**< Bi-endian, can be switched. */ 140 #define K_ARCH_END_MASK 0x6000 /**< The endian mask. */ 141 #define K_ARCH_END_SHIFT 13 /**< Shift count for converting between this K_ENDIAN_*. */ 142 /** @} */ 143 144 /** @name Architecture Identifiers. 145 * These are the value that the K_ARCH \#define can take. 146 *@{ */ 147 /** Unknown CPU architecture. */ 148 #define K_ARCH_UNKNOWN ( 0 ) 149 /** Clone or Intel 16-bit x86. */ 150 #define K_ARCH_X86_16 ( 1 | K_ARCH_BIT_16 | K_ARCH_END_LITTLE) 151 /** Clone or Intel 32-bit x86. */ 152 #define K_ARCH_X86_32 ( 1 | K_ARCH_BIT_32 | K_ARCH_END_LITTLE) 153 /** AMD64 (including clones). */ 154 #define K_ARCH_AMD64 ( 2 | K_ARCH_BIT_64 | K_ARCH_END_LITTLE) 155 /** Itanic (64-bit). */ 156 #define K_ARCH_IA64 ( 3 | K_ARCH_BIT_64 | K_ARCH_END_BI) 157 /** ALPHA (64-bit). */ 158 #define K_ARCH_ALPHA ( 4 | K_ARCH_BIT_64 | K_ARCH_END_BI) 159 /** ALPHA limited to 32-bit. */ 160 #define K_ARCH_ALPHA_32 ( 4 | K_ARCH_BIT_32 | K_ARCH_END_BI) 161 /** 32-bit ARM. */ 162 #define K_ARCH_ARM_32 ( 5 | K_ARCH_BIT_32 | K_ARCH_END_BI) 163 /** 64-bit ARM. */ 164 #define K_ARCH_ARM_64 ( 5 | K_ARCH_BIT_64 | K_ARCH_END_BI) 165 /** Motorola 68000 (32-bit). */ 166 #define K_ARCH_M68K ( 6 | K_ARCH_BIT_32 | K_ARCH_END_BIG) 167 /** 32-bit MIPS. */ 168 #define K_ARCH_MIPS_32 ( 7 | K_ARCH_BIT_32 | K_ARCH_END_BI) 169 /** 64-bit MIPS. */ 170 #define K_ARCH_MIPS_64 ( 7 | K_ARCH_BIT_64 | K_ARCH_END_BI) 171 /** 32-bit PA-RISC. */ 172 #define K_ARCH_PARISC_32 ( 8 | K_ARCH_BIT_32 | K_ARCH_END_BI) 173 /** 64-bit PA-RISC. */ 174 #define K_ARCH_PARISC_64 ( 8 | K_ARCH_BIT_64 | K_ARCH_END_BI) 175 /** 32-bit PowerPC. */ 176 #define K_ARCH_POWERPC_32 ( 9 | K_ARCH_BIT_32 | K_ARCH_END_BI) 177 /** 64-bit PowerPC. */ 178 #define K_ARCH_POWERPC_64 ( 9 | K_ARCH_BIT_64 | K_ARCH_END_BI) 179 /** 32(31)-bit S390. */ 180 #define K_ARCH_S390_32 (10 | K_ARCH_BIT_32 | K_ARCH_END_BIG) 181 /** 64-bit S390. */ 182 #define K_ARCH_S390_64 (10 | K_ARCH_BIT_64 | K_ARCH_END_BIG) 183 /** 32-bit SuperH. */ 184 #define K_ARCH_SH_32 (11 | K_ARCH_BIT_32 | K_ARCH_END_BI) 185 /** 64-bit SuperH. */ 186 #define K_ARCH_SH_64 (11 | K_ARCH_BIT_64 | K_ARCH_END_BI) 187 /** 32-bit SPARC. */ 188 #define K_ARCH_SPARC_32 (12 | K_ARCH_BIT_32 | K_ARCH_END_BIG) 189 /** 64-bit SPARC. */ 190 #define K_ARCH_SPARC_64 (12 | K_ARCH_BIT_64 | K_ARCH_END_BI) 191 /** The end of the valid architecture values (exclusive). */ 192 #define K_ARCH_MAX (12+1) 193 /** @} */ 194 195 196 /** @def K_ARCH 197 * The value of this \#define indicates which architecture we're targetting. 198 */ 199 #ifndef K_ARCH 200 /* detection based on compiler defines. */ 201 # if defined(__amd64__) || defined(__x86_64__) || defined(__AMD64__) || defined(_M_X64) || defined(__amd64) 202 # define K_ARCH K_ARCH_AMD64 203 # elif defined(__i386__) || defined(__x86__) || defined(__X86__) || defined(_M_IX86) || defined(__i386) 204 # define K_ARCH K_ARCH_X86_32 205 # elif defined(__ia64__) || defined(__IA64__) || defined(_M_IA64) 206 # define K_ARCH K_ARCH_IA64 207 # elif defined(__alpha__) 208 # define K_ARCH K_ARCH_ALPHA 209 # elif defined(__arm__) || defined(__arm32__) 210 # define K_ARCH K_ARCH_ARM_32 211 # elif defined(__aarch64__) || defined(__arm64__) 212 # define K_ARCH K_ARCH_ARM_64 213 # elif defined(__hppa__) && defined(__LP64__) 214 # define K_ARCH K_ARCH_PARISC_64 215 # elif defined(__hppa__) 216 # define K_ARCH K_ARCH_PARISC_32 217 # elif defined(__m68k__) 218 # define K_ARCH K_ARCH_M68K 219 # elif defined(__mips64) 220 # define K_ARCH K_ARCH_MIPS_64 221 # elif defined(__mips__) 222 # define K_ARCH K_ARCH_MIPS_32 223 # elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) 224 # define K_ARCH K_ARCH_POWERPC_64 225 # elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) 226 # define K_ARCH K_ARCH_POWERPC_32 227 # elif defined(__sparcv9__) || defined(__sparcv9) 228 # define K_ARCH K_ARCH_SPARC_64 229 # elif defined(__sparc__) || defined(__sparc) 230 # define K_ARCH K_ARCH_SPARC_32 231 # elif defined(__s390x__) 232 # define K_ARCH K_ARCH_S390_64 233 # elif defined(__s390__) 234 # define K_ARCH K_ARCH_S390_32 235 # elif defined(__sh__) 236 # if !defined(__SH5__) 237 # define K_ARCH K_ARCH_SH_32 238 # else 239 # if __SH5__ == 64 240 # define K_ARCH K_ARCH_SH_64 241 # else 242 # define K_ARCH K_ARCH_SH_32 243 # endif 244 # endif 245 # else 246 # error "Port Me" 247 # endif 248 #else 249 /* validate the user specified value. */ 250 # if (K_ARCH & K_ARCH_BIT_MASK) != K_ARCH_BIT_8 \ 251 && (K_ARCH & K_ARCH_BIT_MASK) != K_ARCH_BIT_16 \ 252 && (K_ARCH & K_ARCH_BIT_MASK) != K_ARCH_BIT_32 \ 253 && (K_ARCH & K_ARCH_BIT_MASK) != K_ARCH_BIT_64 \ 254 && (K_ARCH & K_ARCH_BIT_MASK) != K_ARCH_BIT_128 255 # error "Invalid K_ARCH value (bit)" 256 # endif 257 # if (K_ARCH & K_ARCH_END_MASK) != K_ARCH_END_LITTLE \ 258 && (K_ARCH & K_ARCH_END_MASK) != K_ARCH_END_BIG \ 259 && (K_ARCH & K_ARCH_END_MASK) != K_ARCH_END_BI 260 # error "Invalid K_ARCH value (endian)" 261 # endif 262 # if (K_ARCH & ~(K_ARCH_BIT_MASK | K_ARCH_BIT_END_MASK)) < K_ARCH_UNKNOWN \ 263 || (K_ARCH & ~(K_ARCH_BIT_MASK | K_ARCH_BIT_END_MASK)) >= K_ARCH_MAX 264 # error "Invalid K_ARCH value" 265 # endif 266 #endif 267 268 /** @def K_ARCH_IS_VALID 269 * Check if the architecture identifier is valid. 270 * @param arch The K_ARCH_* define to examin. 271 */ 272 #define K_ARCH_IS_VALID(arch) ( ( ((arch) & K_ARCH_BIT_MASK) == K_ARCH_BIT_8 \ 273 || ((arch) & K_ARCH_BIT_MASK) == K_ARCH_BIT_16 \ 274 || ((arch) & K_ARCH_BIT_MASK) == K_ARCH_BIT_32 \ 275 || ((arch) & K_ARCH_BIT_MASK) == K_ARCH_BIT_64 \ 276 || ((arch) & K_ARCH_BIT_MASK) == K_ARCH_BIT_128) \ 277 && \ 278 ( ((arch) & K_ARCH_END_MASK) == K_ARCH_END_LITTLE \ 279 || ((arch) & K_ARCH_END_MASK) == K_ARCH_END_BIG \ 280 || ((arch) & K_ARCH_END_MASK) == K_ARCH_END_BI) \ 281 && \ 282 ( ((arch) & ~(K_ARCH_BIT_MASK | K_ARCH_END_MASK)) >= K_ARCH_UNKNOWN \ 283 && ((arch) & ~(K_ARCH_BIT_MASK | K_ARCH_END_MASK)) < K_ARCH_MAX) \ 284 ) 285 286 /** @def K_ARCH_BITS_EX 287 * Determin the architure byte width of the specified architecture. 288 * @param arch The K_ARCH_* define to examin. 289 */ 290 #define K_ARCH_BITS_EX(arch) ( ((arch) & K_ARCH_BIT_MASK) >> K_ARCH_BIT_SHIFT ) 291 292 /** @def K_ARCH_BYTES_EX 293 * Determin the architure byte width of the specified architecture. 294 * @param arch The K_ARCH_* define to examin. 295 */ 296 #define K_ARCH_BYTES_EX(arch) ( ((arch) & K_ARCH_BIT_MASK) >> K_ARCH_BYTE_SHIFT ) 297 298 /** @def K_ARCH_ENDIAN_EX 299 * Determin the K_ENDIAN value for the specified architecture. 300 * @param arch The K_ARCH_* define to examin. 301 */ 302 #define K_ARCH_ENDIAN_EX(arch) ( ((arch) & K_ARCH_END_MASK) >> K_ARCH_END_SHIFT ) 303 304 /** @def K_ARCH_BITS 305 * Determin the target architure bit width. 306 */ 307 #define K_ARCH_BITS K_ARCH_BITS_EX(K_ARCH) 308 309 /** @def K_ARCH_BYTES 310 * Determin the target architure byte width. 311 */ 312 #define K_ARCH_BYTES K_ARCH_BYTES_EX(K_ARCH) 313 314 /** @def K_ARCH_ENDIAN 315 * Determin the target K_ENDIAN value. 316 */ 317 #define K_ARCH_ENDIAN K_ARCH_ENDIAN_EX(K_ARCH) 318 319 320 321 /** @name Endianness Identifiers. 322 * These are the value that the K_ENDIAN \#define can take. 323 * @{ */ 324 #define K_ENDIAN_LITTLE 1 /**< Little-endian. */ 325 #define K_ENDIAN_BIG 2 /**< Big-endian. */ 326 #define K_ENDIAN_BI 3 /**< Bi-endian, can be switched. Only used with K_ARCH. */ 327 /** @} */ 328 329 /** @def K_ENDIAN 330 * The value of this \#define indicates the target endianness. 331 * 332 * @remark It's necessary to define this (or add the necessary deduction here) 333 * on bi-endian architectures. 334 */ 335 #ifndef K_ENDIAN 336 /* use K_ARCH if possible. */ 337 # if K_ARCH_ENDIAN != K_ENDIAN_BI 338 # define K_ENDIAN K_ARCH_ENDIAN 339 # elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) 340 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 341 # define K_ENDIAN K_ARCH_LITTLE 342 # elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 343 # define K_ENDIAN K_ARCH_BIG 344 # else 345 # error "Port Me or define K_ENDIAN." 346 # endif 347 # else 348 # error "Port Me or define K_ENDIAN." 349 # endif 350 #else 351 /* validate the user defined value. */ 352 # if K_ENDIAN != K_ENDIAN_LITTLE 353 && K_ENDIAN != K_ENDIAN_BIG 354 # error "K_ENDIAN must either be defined as K_ENDIAN_LITTLE or as K_ENDIAN_BIG." 355 # endif 356 #endif 357 358 /** @name Endian Conversion 359 * @{ */ 360 361 /** @def K_E2E_U16 362 * Convert the endian of an unsigned 16-bit value. */ 363 # define K_E2E_U16(u16) ( (KU16) (((u16) >> 8) | ((u16) << 8)) ) 364 /** @def K_E2E_U32 365 * Convert the endian of an unsigned 32-bit value. */ 366 # define K_E2E_U32(u32) ( ( ((u32) & KU32_C(0xff000000)) >> 24 ) \ 367 | ( ((u32) & KU32_C(0x00ff0000)) >> 8 ) \ 368 | ( ((u32) & KU32_C(0x0000ff00)) << 8 ) \ 369 | ( ((u32) & KU32_C(0x000000ff)) << 24 ) \ 370 ) 371 /** @def K_E2E_U64 372 * Convert the endian of an unsigned 64-bit value. */ 373 # define K_E2E_U64(u64) ( ( ((u64) & KU64_C(0xff00000000000000)) >> 56 ) \ 374 | ( ((u64) & KU64_C(0x00ff000000000000)) >> 40 ) \ 375 | ( ((u64) & KU64_C(0x0000ff0000000000)) >> 24 ) \ 376 | ( ((u64) & KU64_C(0x000000ff00000000)) >> 8 ) \ 377 | ( ((u64) & KU64_C(0x00000000ff000000)) << 8 ) \ 378 | ( ((u64) & KU64_C(0x0000000000ff0000)) << 24 ) \ 379 | ( ((u64) & KU64_C(0x000000000000ff00)) << 40 ) \ 380 | ( ((u64) & KU64_C(0x00000000000000ff)) << 56 ) \ 381 ) 382 383 /** @def K_LE2H_U16 384 * Unsigned 16-bit little-endian to host endian. */ 385 /** @def K_LE2H_U32 386 * Unsigned 32-bit little-endian to host endian. */ 387 /** @def K_LE2H_U64 388 * Unsigned 64-bit little-endian to host endian. */ 389 /** @def K_BE2H_U16 390 * Unsigned 16-bit big-endian to host endian. */ 391 /** @def K_BE2H_U32 392 * Unsigned 32-bit big-endian to host endian. */ 393 /** @def K_BE2H_U64 394 * Unsigned 64-bit big-endian to host endian. */ 395 #if K_ENDIAN == K_ENDIAN_LITTLE 396 # define K_LE2H_U16(u16) ((KU16)(u16)) 397 # define K_LE2H_U32(u32) ((KU32)(u32)) 398 # define K_LE2H_U64(u64) ((KU64)(u32)) 399 # define K_BE2H_U16(u16) K_E2E_U16(u16) 400 # define K_BE2H_U32(u32) K_E2E_U32(u32) 401 # define K_BE2H_U64(u64) K_E2E_U64(u64) 402 #else 403 # define K_LE2H_U16(u16) K_E2E_U16(u16) 404 # define K_LE2H_U32(u32) K_E2E_U32(u32) 405 # define K_LE2H_U64(u64) K_E2E_U64(u64) 406 # define K_BE2H_U16(u16) ((KU16)(u16)) 407 # define K_BE2H_U32(u32) ((KU32)(u32)) 408 # define K_BE2H_U64(u64) ((KU64)(u32)) 409 #endif 410 411 412 413 /** @def K_INLINE 414 * How to say 'inline' in both C and C++ dialects. 415 * @param type The return type. 416 */ 417 #ifdef __cplusplus 418 # if defined(__GNUC__) 419 # define K_INLINE static inline 420 # else 421 # define K_INLINE inline 422 # endif 423 #else 424 # if defined(__GNUC__) 425 # define K_INLINE static __inline__ 426 # elif defined(_MSC_VER) 427 # define K_INLINE static __inline 428 # else 429 # error "Port Me" 430 # endif 431 #endif 432 433 /** @def K_EXPORT 434 * What to put in front of an exported function. 435 */ 436 #if K_OS == K_OS_OS2 || K_OS == K_OS_WINDOWS 437 # define K_EXPORT __declspec(dllexport) 438 #else 439 # define K_EXPORT 440 #endif 441 442 /** @def K_IMPORT 443 * What to put in front of an imported function. 444 */ 445 #if K_OS == K_OS_OS2 || K_OS == K_OS_WINDOWS 446 # define K_IMPORT __declspec(dllimport) 447 #else 448 # define K_IMPORT extern 449 #endif 450 451 /** @def K_DECL_EXPORT 452 * Declare an exported function. 453 * @param type The return type. 454 */ 455 #define K_DECL_EXPORT(type) K_EXPORT type 456 457 /** @def K_DECL_IMPORT 458 * Declare an import function. 459 * @param type The return type. 460 */ 461 #define K_DECL_IMPORT(type) K_IMPORT type 462 463 /** @def K_DECL_INLINE 464 * Declare an inline function. 465 * @param type The return type. 466 * @remark Don't use on (class) methods. 467 */ 468 #define K_DECL_INLINE(type) K_INLINE type 469 470 471 /** Get the minimum of two values. */ 472 #define K_MIN(a, b) ( (a) <= (b) ? (a) : (b) ) 473 /** Get the maximum of two values. */ 474 #define K_MAX(a, b) ( (a) >= (b) ? (a) : (b) ) 475 /** Calculate the offset of a structure member. */ 476 #define K_OFFSETOF(strct, memb) ( (KSIZE)( &((strct *)0)->memb ) ) 477 /** Align a size_t value. */ 478 #define K_ALIGN_Z(val, align) ( ((val) + ((align) - 1)) & ~(KSIZE)((align) - 1) ) 479 /** Align a void * value. */ 480 #define K_ALIGN_P(pv, align) ( (void *)( ((KUPTR)(pv) + ((align) - 1)) & ~(KUPTR)((align) - 1) ) ) 481 /** Number of elements in an array. */ 482 #define K_ELEMENTS(a) ( sizeof(a) / sizeof((a)[0]) ) 483 /** Checks if the specified pointer is a valid address or not. */ 484 #define K_VALID_PTR(ptr) ( (KUPTR)(ptr) + 0x1000U >= 0x2000U ) 485 /** Makes a 32-bit bit mask. */ 486 #define K_BIT32(bit) ( KU32_C(1) << (bit)) 487 /** Makes a 64-bit bit mask. */ 488 #define K_BIT64(bit) ( KU64_C(1) << (bit)) 489 /** Shuts up unused parameter and unused variable warnings. */ 490 #define K_NOREF(var) ( (void)(var) ) 491 492 493 /** @name Parameter validation macros 494 * @{ */ 495 496 /** Return/Crash validation of a string argument. */ 497 #define K_VALIDATE_STRING(str) \ 498 do { \ 499 if (!K_VALID_PTR(str)) \ 500 return KERR_INVALID_POINTER; \ 501 kHlpStrLen(str); \ 502 } while (0) 503 504 /** Return/Crash validation of an optional string argument. */ 505 #define K_VALIDATE_OPTIONAL_STRING(str) \ 506 do { \ 507 if (str) \ 508 K_VALIDATE_STRING(str); \ 509 } while (0) 510 511 /** Return/Crash validation of an output buffer. */ 512 #define K_VALIDATE_BUFFER(buf, cb) \ 513 do { \ 514 if (!K_VALID_PTR(buf)) \ 515 return KERR_INVALID_POINTER; \ 516 if ((cb) != 0) \ 517 { \ 518 KU8 __b; \ 519 KU8 volatile *__pb = (KU8 volatile *)(buf); \ 520 KSIZE __cbPage1 = 0x1000 - ((KUPTR)(__pb) & 0xfff); /* ASSUMES page size! */ \ 521 __b = *__pb; *__pb = 0xff; *__pb = __b; \ 522 if ((cb) > __cbPage1) \ 523 { \ 524 KSIZE __cb = (cb) - __cbPage1; \ 525 __pb -= __cbPage1; \ 526 for (;;) \ 527 { \ 528 __b = *__pb; *__pb = 0xff; *__pb = __b; \ 529 if (__cb < 0x1000) \ 530 break; \ 531 __pb += 0x1000; \ 532 __cb -= 0x1000; \ 533 } \ 534 } \ 535 } \ 536 else \ 537 return KERR_INVALID_PARAMETER; \ 538 } while (0) 539 540 /** Return/Crash validation of an optional output buffer. */ 541 #define K_VALIDATE_OPTIONAL_BUFFER(buf, cb) \ 542 do { \ 543 if ((buf) && (cb) != 0) \ 544 K_VALIDATE_BUFFER(buf, cb); \ 545 } while (0) 546 547 /** Return validation of an enum argument. */ 548 #define K_VALIDATE_ENUM(arg, enumname) \ 549 do { \ 550 if ((arg) <= enumname##_INVALID || (arg) >= enumname##_END) \ 551 return KERR_INVALID_PARAMETER; \ 552 } while (0) 553 554 /** Return validation of a flags argument. */ 555 #define K_VALIDATE_FLAGS(arg, AllowedMask) \ 556 do { \ 557 if ((arg) & ~(AllowedMask)) \ 558 return KERR_INVALID_PARAMETER; \ 559 } while (0) 560 561 /** @} */ 562 563 /** @def NULL 564 * The nil pointer value. */ 565 #ifndef NULL 566 # ifdef __cplusplus 567 # define NULL 0 568 # else 569 # define NULL ((void *)0) 570 # endif 571 #endif 572 573 /** @} */ 574 575 #endif 576 577