1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     assert.h
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef NW_ASSERT_H_
19 #define NW_ASSERT_H_
20 
21 #include <nw/config.h>
22 #include <nw/os/os_Utility.h>
23 
24 //#ifndef NW_FROM_TOOL
25 //    #include <nw/db/assert.h>
26 //#endif
27 
28 #include <limits.h>
29 
30 #if !defined(NW_RELEASE)
31   #define NW_ASSERTION_ENABLE
32 
33   #if !defined(NW_WARNING_DISABLE)
34     #define NW_WARNING_ENABLE
35   #endif
36 #endif
37 
38 //--------------------------------------------------------------------------------
39 //  コンパイル時チェック
40 //
41 #define NW_COMPILER_ASSERT(expr) \
42     extern void nw4r_compiler_assert ## __LINE__ ( char is[(expr) ? +1 : -1] )
43 
44 namespace nw
45 {
46 namespace internal
47 {
48 template<bool> struct static_assert;
49 template<> struct static_assert<true> {};
50 template<int> struct static_check {};
51 } // namespace internal
52 } // namespace nw
53 
54 //! クラス内にも配置できるコンパイル時アサーションです。
55 #define NW_STATIC_ASSERT(expr) \
56     typedef nw::internal::static_check<sizeof(nw::internal::static_assert<expr>)> STATIC_ASSERT_FAILED
57 
58 
59 //--------------------------------------------------------------------------------
60 //  Assert message
61 //
62 //#ifndef NW_ASSERTMSG
63 //#ifdef  NW_FROM_TOOL
64 // #define NW_ASSERTMSG(exp, ... )  ((void)0)
65 //#else
66 //#define NW_ASSERTMSG  NW_DB_ASSERTMSG
67 //#endif
68 //#endif
69 
70 #if !defined( NW_ASSERTION_ENABLE )
71 #define NW_ASSERTMSG(exp, ... ) ((void)0)
72 #else
73 #define NW_ASSERTMSG(exp, ... ) (void) ((exp) || (nwosPanic(__VA_ARGS__), 0))
74 #endif
75 
76 
77 
78 //--------------------------------------------------------------------------------
79 //  Assert
80 //
81 #ifndef NW_ASSERT
82 #define NW_ASSERT(exp) \
83             NW_ASSERTMSG( (exp), "NW:Failed assertion " #exp )
84 #endif
85 
86 //--------------------------------------------------------------------------------
87 //  NULL Assert
88 //
89 #ifndef NW_NULL_ASSERT
90 #define NW_NULL_ASSERT(exp) \
91             NW_ASSERTMSG( (exp) != NULL, "NW:Pointer must not be NULL ("#exp")" )
92 #endif
93 
94 //--------------------------------------------------------------------------------
95 //  Min Assert
96 //
97 #ifndef NW_MIN_ASSERT
98 #define NW_MIN_ASSERT(exp, min) \
99             NW_ASSERTMSG( (exp) >= (min), #exp " is out of bounds(%d)\n%d <= "#exp" not satisfied.", static_cast<int>(exp), static_cast<int>(min) )
100 #endif
101 
102 //--------------------------------------------------------------------------------
103 //  Max Assert
104 //
105 #ifndef NW_MAX_ASSERT
106 #define NW_MAX_ASSERT(exp, max) \
107             NW_ASSERTMSG( (exp) <= (max), #exp " is out of bounds(%d)\n"#exp" <= %d not satisfied.", static_cast<int>(exp), static_cast<int>(max) )
108 #endif
109 
110 //--------------------------------------------------------------------------------
111 //  Min Max Assert
112 //
113 #ifndef NW_MINMAX_ASSERT
114 #define NW_MINMAX_ASSERT(exp, min, max) \
115             NW_ASSERTMSG( (exp) >= (min) && (exp) <= (max), #exp " is out of bounds(%d)\n%d <= "#exp" <= %d not satisfied.", static_cast<int>(exp), static_cast<int>(min), static_cast<int>(max))
116 #endif
117 
118 //--------------------------------------------------------------------------------
119 //  Min Max Less Than Assert
120 //
121 #ifndef NW_MINMAXLT_ASSERT
122 #define NW_MINMAXLT_ASSERT(exp, min, max) \
123             NW_ASSERTMSG( (exp) >= (min) && (exp) < (max), #exp " is out of bounds(%d)\n%d <= "#exp" < %d not satisfied.", static_cast<int>(exp), static_cast<int>(min), static_cast<int>(max))
124 #endif
125 
126 //--------------------------------------------------------------------------------
127 //  Min Assert for floating point value
128 //
129 #ifndef NW_FMIN_ASSERT
130 #define NW_FMIN_ASSERT(exp, min) \
131             NW_ASSERTMSG( (exp) >= (min), #exp " is out of bounds(%f)\n%f <= "#exp" not satisfied.", static_cast<double>(exp), static_cast<double>(min) )
132 #endif
133 
134 //--------------------------------------------------------------------------------
135 //  Max Assert for floating point value
136 //
137 #ifndef NW_FMAX_ASSERT
138 #define NW_FMAX_ASSERT(exp, max) \
139             NW_ASSERTMSG( (exp) <= (max), #exp " is out of bounds(%f)\n"#exp" <= %f not satisfied.", static_cast<double>(exp), static_cast<double>(max) )
140 #endif
141 
142 //--------------------------------------------------------------------------------
143 //  Min Max Assert for floating point value
144 //
145 #ifndef NW_FMINMAX_ASSERT
146 #define NW_FMINMAX_ASSERT(exp, min, max) \
147             NW_ASSERTMSG( (exp) >= (min) && (exp) <= (max), #exp " is out of bounds(%f)\n%f <= "#exp" <= %f not satisfied.", static_cast<double>(exp), static_cast<double>(min), static_cast<double>(max))
148 #endif
149 
150 //--------------------------------------------------------------------------------
151 //  Fatal error
152 //
153 #ifndef NW_FATAL_ERROR
154 #ifdef  NW_FROM_TOOL
155 #define NW_FATAL_ERROR    true ? 0:
156 #else
157 #define NW_FATAL_ERROR(...) \
158             NW_ASSERTMSG( false, "NW:Fatal Error\n"__VA_ARGS__ )
159 #endif
160 #endif
161 
162 //--------------------------------------------------------------------------------
163 //  Internal error
164 //
165 #ifndef NW_INTERNAL_ERROR
166 #ifdef  NW_FROM_TOOL
167 #define NW_INTERNAL_ERROR true ? 0:
168 #else
169 #define NW_INTERNAL_ERROR(...) \
170             NW_ASSERTMSG( false, "NW Internal error\n" __VA_ARGS__ )
171 #endif
172 #endif
173 
174 
175 //--------------------------------------------------------------------------------
176 //  Cache Alignment error
177 //
178 #ifndef NW_CACHE_ALIGN_ASSERT
179 #if defined( NW_PLATFORM_GC )
180 #define NW_CACHE_ALIGN_ASSERT     NW_ALIGN32_ASSERT
181 #else
182 #define NW_CACHE_ALIGN_ASSERT     NW_ALIGN32_ASSERT
183 #endif
184 #endif
185 
186 
187 //--------------------------------------------------------------------------------
188 //  Alignment error
189 //
190 #ifndef NW_ALIGN_ASSERT
191 #define NW_ALIGN_ASSERT(exp,align) \
192     NW_ASSERTMSG( (NW_ANY_TO_PTR_VALUE(exp) & ((align) - 1)) == 0, "NW:Alignment Error(0x%x)\n"#exp" must be aligned to %d bytes boundary.", exp, align )
193 #endif
194 
195 //--------------------------------------------------------------------------------
196 //  Alignment error(128 bytes)
197 //
198 #ifndef NW_ALIGN128_ASSERT
199 #define NW_ALIGN128_ASSERT(exp) \
200              NW_ALIGN_ASSERT( (exp), 128 )
201 #endif
202 
203 //--------------------------------------------------------------------------------
204 //  Alignment error(32 bytes)
205 //
206 #ifndef NW_ALIGN32_ASSERT
207 #define NW_ALIGN32_ASSERT(exp) \
208              NW_ALIGN_ASSERT( (exp), 32 )
209 #endif
210 
211 //--------------------------------------------------------------------------------
212 //  Alignment error(4 bytes)
213 //
214 #ifndef NW_ALIGN4_ASSERT
215 #define NW_ALIGN4_ASSERT(exp) \
216              NW_ALIGN_ASSERT( (exp), 4 )
217 #endif
218 
219 //--------------------------------------------------------------------------------
220 //  Alignment error(2 bytes)
221 //
222 #ifndef NW_ALIGN2_ASSERT
223 #define NW_ALIGN2_ASSERT(exp) \
224              NW_ALIGN_ASSERT( (exp), 2 )
225 #endif
226 
227 //--------------------------------------------------------------------------------
228 //  buffer size error
229 //
230 #ifndef NW_BUFFERSIZE_ASSERT
231 #ifdef  NW_PLATFORM_RVL
232 #define NW_BUFFERSIZE_ASSERT(exp) \
233             NW_ASSERTMSG( (exp) <= 64 * 1024 * 1024, "NW:Buffer Size Error\n" #exp "(=%d) over maximum physical memory size.", (exp))
234 #else
235 #define NW_BUFFERSIZE_ASSERT(exp) \
236             NW_ASSERTMSG( (exp) <= 24 * 1024 * 1024, "NW:Buffer Size Error\n" #exp "(=%d) over maximum physical memory size.", (exp))
237 #endif
238 #endif
239 
240 //--------------------------------------------------------------------------------
241 //  Invalid pointer error
242 //
243 #ifndef NW_POINTER_ASSERT
244 #if defined(NW_PLATFORM_CTRWIN) || defined(NW_PLATFORM_CTR)
245 #define NW_POINTER_ASSERT(exp)                                                                                            \
246             NW_ASSERTMSG(                                                                                                 \
247                 NW_ANY_TO_PTR_VALUE(exp) != 0,                                                                            \
248                 "NW:Pointer Error\n"#exp"(=%p) is not valid pointer.", (exp) )
249 #elif   defined(NW_PLATFORM_RVL)
250 #define NW_POINTER_ASSERT(exp)                                                                                            \
251             NW_ASSERTMSG(                                                                                                 \
252                    ((NW_ANY_TO_PTR_VALUE(exp) & 0xFF000000) == 0x80000000)    /* 8000_0000~80FF_FFFF MEM1 Cached   */    \
253                 || ((NW_ANY_TO_PTR_VALUE(exp) & 0xFF800000) == 0x81000000)    /* 8100_0000~817F_FFFF MEM1 Cached   */    \
254                 || ((NW_ANY_TO_PTR_VALUE(exp) & 0xF8000000) == 0x90000000)    /* 9000_0000~97FF_FFFF MEM2 Cached   */    \
255                 || ((NW_ANY_TO_PTR_VALUE(exp) & 0xFF000000) == 0xC0000000)    /* C000_0000~C0FF_FFFF MEM1 Uncached */    \
256                 || ((NW_ANY_TO_PTR_VALUE(exp) & 0xFF800000) == 0xC1000000)    /* C100_0000~C17F_FFFF MEM1 Uncached */    \
257                 || ((NW_ANY_TO_PTR_VALUE(exp) & 0xF8000000) == 0xD0000000)    /* D000_0000~D7FF_FFFF MEM2 Uncached */    \
258                 || ((NW_ANY_TO_PTR_VALUE(exp) & 0xFFFFC000) == 0xE0000000),   /* E000_0000~E000_3FFF Locked Cache  */    \
259                 "NW:Pointer Error\n"#exp"(=%p) is not valid pointer.", (exp) )
260 #else
261 #define NW_POINTER_ASSERT(exp)                                                                \
262             NW_ASSERTMSG(                                                                     \
263                    ((NW_ANY_TO_PTR_VALUE(exp) & 0xF0000000) == 0x80000000)    /* Cached   */  \
264                 || ((NW_ANY_TO_PTR_VALUE(exp) & 0xF0000000) == 0xC0000000),   /* Uncached */  \
265                 "NW:Pointer Error\n"#exp"(=%p) is not valid pointer.", (exp) )
266 #endif
267 #endif
268 
269 #ifndef NW_REFERENCE_ASSERT
270 #define NW_REFERENCE_ASSERT(ref) NW_POINTER_ASSERT(&ref)
271 #endif
272 
273 //--------------------------------------------------------------------------------
274 //  Range error
275 //
276 
277 #ifndef NW_U8_RANGE_ASSERT
278 #define NW_U8_RANGE_ASSERT(exp) \
279             NW_MINMAX_ASSERT(exp, 0, UCHAR_MAX)
280 #endif
281 
282 #ifndef NW_S8_RANGE_ASSERT
283 #define NW_S8_RANGE_ASSERT(exp) \
284             NW_MINMAX_ASSERT(exp, SCHAR_MIN, SCHAR_MAX)
285 #endif
286 
287 #ifndef NW_U16_RANGE_ASSERT
288 #define NW_U16_RANGE_ASSERT(exp) \
289             NW_MINMAX_ASSERT(exp, 0, USHRT_MAX)
290 #endif
291 
292 #ifndef NW_S16_RANGE_ASSERT
293 #define NW_S16_RANGE_ASSERT(exp) \
294             NW_MINMAX_ASSERT(exp, SHRT_MIN, SHRT_MAX)
295 #endif
296 
297 #ifndef NW_U32_RANGE_ASSERT
298 #define NW_U32_RANGE_ASSERT(exp) \
299             NW_MINMAX_ASSERT(exp, 0, UINT_MAX)
300 #endif
301 
302 #ifndef NW_S32_RANGE_ASSERT
303 #define NW_S32_RANGE_ASSERT(exp) \
304             NW_MINMAX_ASSERT(exp, INT_MIN, INT_MAX)
305 #endif
306 
307 //--------------------------------------------------------------------------------
308 //  Floating point value error
309 //
310 
311 #ifndef NW_FLOAT_ASSERT
312 #ifdef  NW_FROM_TOOL
313 #define NW_FLOAT_ASSERT   true ? 0:
314 #else
315 #define NW_FLOAT_ASSERT(exp) \
316             NW_ASSERTMSG((isfinite(exp) && !isnan(exp)), "NW:Floating Point Value Error(%f)\n"#exp" is infinite or nan.", exp)
317 #endif
318 #endif
319 
320 
321 #if !defined( NW_ASSERTION_ENABLE )
322 #define NW_GL_ASSERT() ((void)0)
323 #else
324 
325 inline const char*
326 nwGlErrorString( u32 err )
327 {
328     typedef struct
329     {
330         u32 value;
331         const char* name;
332     } EnumString;
333 
334     static const EnumString ENUM_STRINGS[] =
335     {
336         { 0,      "GL_NO_ERROR"      },
337         { 0x0500, "GL_INVALID_ENUM"  },
338         { 0x0501, "GL_INVALID_VALUE" },
339         { 0x0502, "GL_INVALID_OPERATION" },
340         { 0x0505, "GL_OUT_OF_MEMORY" },
341         { 0x0506, "GL_INVALID_FRAMEBUFFER_OPERATION" },
342         { 0x8000, "in nngxGemCmdlists"},
343         { 0x8001, "in nngxGemCmdlists"},
344         { 0x8002, "in nngxDeleteCmdlists"},
345         { 0x8003, "in nngxDeleteCmdlists"},
346         { 0x8004, "in nngxBindCmdlist"},
347         { 0x8005, "in nngxBindCmdlist"},
348         { 0x8006, "in nngxCmdlistStorage"},
349         { 0x8007, "in nngxCmdlistStorage"},
350         { 0x8008, "in nngxCmdlistStorage"},
351         { 0x8009, "in nngxRunCmdlist"},
352         { 0x800A, "in nngxReserveStopCmdlist"},
353         { 0x800B, "in nngxReserveStopCmdlist"},
354         { 0x800C, "in nngxSplitDrawCmdlist"},
355         { 0x800D, "in nngxSplitDrawCmdlist"},
356         { 0x800E, "in nngxSplitDrawCmdlist"},
357         { 0x800F, "in nngxClearCmdlist"},
358         { 0x8010, "in nngxSetCmdlistCallback"},
359         { 0x8012, "in nngxEnableCmdlistCallback"},
360         { 0x8014, "in nngxDisableCmdlistCallback"},
361         { 0x8015, "in nngxSetCmdlistParameteri"},
362         { 0x8016, "in nngxSetCmdlistParameteri"},
363         { 0x8017, "in nngxGetCmdlistParameteri"},
364         { 0x8018, "in nngxGetCmdlistParameteri"},
365         { 0x8019, "in nngxCheckVSync"},
366         { 0x801A, "in nngxWaitVSync"},
367         { 0x801B, "in nngxSetVSyncCallback"},
368         { 0x801C, "in nngxGenDisplaybuffers"},
369         { 0x801D, "in nngxGetDisplaybuffers"},
370         { 0x801E, "in nngxDeleteDisplayBuffers"},
371         { 0x801F, "in nngxActiveDisplay"},
372         { 0x8020, "in nngxBindDisplaybuffer"},
373         { 0x8021, "in nngxDisplaybufferStorage"},
374         { 0x8022, "in nngxDisplaybufferStorage"},
375         { 0x8023, "in nngxDisplaybufferStorage"},
376         { 0x8024, "in nngxDisplaybufferStorage"},
377         { 0x8025, "in nngxDisplaybufferStorage"},
378         { 0x8026, "in nngxDisplayEnv"},
379         { 0x8027, "in nngxTransferRenderImage"},
380         { 0x8028, "in nngxTransferRenderImage"},
381         { 0x8029, "in nngxTransferRenderImage"},
382         { 0x802A, "in nngxTransferRenderImage"},
383         { 0x802B, "in nngxTransferRenderImage"},
384         { 0x802C, "in nngxTransferRenderImage"},
385         { 0x802D, "in nngxTransferRenderImage"},
386         { 0x802E, "in nngxTransferRenderImage"},
387         { 0x802F, "in nngxTransferRenderImage"},
388         { 0x8030, "in nnwxSwapBuffers"},
389         { 0x8031, "in nngxSwapBuffers"},
390         { 0x8032, "in nngxSwapBuffers"},
391         { 0x8033, "in nngxGetDisplaybufferParameteri"},
392         { 0x8034, "in nngxStartCmdlistSave"},
393         { 0x8035, "in nngxStartCmdlistSave"},
394         { 0x8036, "in nngxStopCmdlistSave"},
395         { 0x8037, "in nngxUseSavedCmdlist"},
396         { 0x8038, "in nngxUseSavedCmdlist"},
397         { 0x8039, "in nngxUseSavedCmdlist"},
398         { 0x803A, "in nngxUseSavedCmdlist"},
399         { 0x803B, "in nngxExportCmdlist"},
400         { 0x803C, "in nngxExportCmdlist"},
401         { 0x803D, "in nngxExportCmdlist"},
402         { 0x803E, "in nngxExportCmdlist"},
403         { 0x803F, "in nngxExportCmdlist"},
404         { 0x8040, "in nngxExportCmdlist"},
405         { 0x8041, "in nngxImportCmdlist"},
406         { 0x8042, "in nngxImportCmdlist"},
407         { 0x8043, "in nngxImportCmdlist"},
408         { 0x8044, "in nngxImportCmdlist"},
409         { 0x8045, "in nngxImportCmdlist"},
410         { 0x8046, "in nngxGetExportedCmdlistInfo"},
411         { 0x8047, "in nngxCopyCmdlist"},
412         { 0x8048, "in nngxCopyCmdlist"},
413         { 0x8049, "in nngxCopyCmdlist"},
414         { 0x804A, "in nngxCopyCmdlist"},
415         { 0x804B, "in nngxCopyCmdlist"},
416         { 0x804C, "in nngxCopyCmdlist"},
417         { 0x804D, "in nngxSetCommandGenerationMode"},
418         { 0x804E, "in nngxAdd3DCommand"},
419         { 0x804F, "in nngxAdd3DCommand"},
420         { 0x8050, "in nngxAdd3DCommand"},
421         { 0x8051, "in nngxAdd3DCommand"},
422         { 0x8052, "in nngxAdd3DCommand"},
423         { 0x8053, "in nngxSwapBuffers"},
424         { 0x8054, "in nngxAddCmdlist"},
425         { 0x8055, "in nngxAddCmdlist"},
426         { 0x8056, "in nngxAddCmdlist"},
427         { 0x8057, "in nngxAddCmdlist"},
428         { 0x8058, "in nngxAddCmdlist"},
429         { 0x8059, "in nngxTransferRenderImage"},
430         { 0x805A, "in nngxTransferRenderImage"},
431         { 0x805B, "in nngxTransferLinearImage"},
432         { 0x805C, "in nngxTransferLinearImage"},
433         { 0x805D, "in nngxTransferLinearImage"},
434         { 0x805E, "in nngxTransferLinearImage"},
435         { 0x805F, "in nngxTransferLinearImage"},
436         { 0x8060, "in nngxTransferLinearImage"},
437         { 0x8062, "in nngxAddVramDmaCommand"},
438         { 0x8063, "srcAddr alignment error in nngxAddVramDmaCommand"},
439         { 0x8064, "in nngxAddVramDmaCommand"},
440         { 0x8065, "in nngxClearFillCmdlist"},
441         { 0x8066, "in nngxValidateState"},
442         { 0x8067, "in nngxTransferLinearImage"},
443         { 0x8068, "in nngxFilterBlockImage"},
444         { 0x8069, "in nngxFilterBlockImage"},
445         { 0x806A, "in nngxFilterBlockImage"},
446         { 0x806B, "in nngxFilterBlockImage"},
447         { 0x806C, "in nngxValidateState"},
448         { 0x9000, "in nngxSwapBuffers"},
449         { 0x9001, "in nngxSwapBuffers"},
450         { 0x9002, "in nngxSwapBuffers"},
451         { 0x9003, "in nngxSetDisplayMode"},
452     };
453 
454     const int NUM_ENUM_STRING = sizeof(ENUM_STRINGS) / sizeof(ENUM_STRINGS[0]);
455 
456     for (int idx = 0; idx < NUM_ENUM_STRING; ++idx)
457     {
458         if ( ENUM_STRINGS[ idx ].value == err )
459         {
460             return ENUM_STRINGS[ idx ].name;
461         }
462     }
463 
464     return "Unknown";
465 }
466 
467 #define NW_GL_ASSERT()                                              \
468     do {                                                            \
469         GLuint err = glGetError();                                  \
470         NW_ASSERTMSG( err == GL_NO_ERROR, "GL_ERROR : %s (0x%x)", nwGlErrorString( err ), err ); \
471     } while (0)
472 #endif
473 
474 //--------------------------------------------------------------------------------
475 //  Warning
476 //
477 
478 #ifndef NW_WARNING
479 //#ifdef  NW_FROM_TOOL
480 #if !defined(NW_WARNING_ENABLE)
481   #define NW_WARNING(exp, ...) ((void)0)
482 #else
483   #define NW_WARNING(exp, ...) (void) ((exp) || (nwosWarning(__VA_ARGS__), 0))
484 #endif
485 //#else
486 //#define NW_WARNING    NW_DB_EXP_WARNING
487 //#endif
488 #endif
489 
490 //--------------------------------------------------------------------------------
491 //  Fail safe
492 //
493 
494 #if !defined( NW_ASSERTION_ENABLE )
495 #define NW_FAILSAFE_IF(exp) if (exp)
496 #else
497 #define NW_FAILSAFE_IF(exp) if (exp) { NW_FATAL_ERROR(#exp); } if (false)
498 #endif
499 
500 //--------------------------------------------------------------------------------
501 //  Log
502 //
503 //#ifndef NW_LOG
504 //#ifdef  NW_FROM_TOOL
505 #define NW_LOG    nwosPrintf
506 //#else
507 //#define NW_LOG    NW_DB_LOG
508 //#endif
509 //#endif
510 
511 
512 //--------------------------------------------------------------------------------
513 //  デバッグ時のみ有効で Development ではチェックしない ASSERT
514 //
515 
516 #if defined( NW_DEBUG )
517 #define NW_DEBUG_ASSERTMSG      NW_ASSERTMSG
518 #define NW_DEBUG_ASSERT         NW_ASSERT
519 #define NW_DEBUG_NULL_ASSERT    NW_NULL_ASSERT
520 #else
521 #define NW_DEBUG_ASSERTMSG(exp, ...) ((void)0)
522 #define NW_DEBUG_ASSERT(exp)         ((void)0)
523 #define NW_DEBUG_NULL_ASSERT(exp)    ((void)0)
524 #endif
525 
526 /* NW_ASSERT_H_ */
527 #endif
528