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