/*---------------------------------------------------------------------------* Project: NintendoWare File: assert.h Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. The content herein is highly confidential and should be handled accordingly. $Revision: 31311 $ *---------------------------------------------------------------------------*/ #ifndef NW_ASSERT_H_ #define NW_ASSERT_H_ #include #include //#ifndef NW_FROM_TOOL // #include //#endif #include #if !defined(NW_RELEASE) #define NW_ASSERTION_ENABLE #if !defined(NW_WARNING_DISABLE) #define NW_WARNING_ENABLE #endif #endif //-------------------------------------------------------------------------------- // コンパイル時チェック // #define NW_COMPILER_ASSERT(expr) \ extern void nw4r_compiler_assert ## __LINE__ ( char is[(expr) ? +1 : -1] ) namespace nw { namespace internal { template struct static_assert; template<> struct static_assert {}; template struct static_check {}; } // namespace internal } // namespace nw //! クラス内にも配置できるコンパイル時アサーションです。 #define NW_STATIC_ASSERT(expr) \ typedef nw::internal::static_check)> STATIC_ASSERT_FAILED //-------------------------------------------------------------------------------- // Assert message // //#ifndef NW_ASSERTMSG //#ifdef NW_FROM_TOOL // #define NW_ASSERTMSG(exp, ... ) ((void)0) //#else //#define NW_ASSERTMSG NW_DB_ASSERTMSG //#endif //#endif #if !defined( NW_ASSERTION_ENABLE ) #define NW_ASSERTMSG(exp, ... ) ((void)0) #else #define NW_ASSERTMSG(exp, ... ) (void) ((exp) || (nwosPanic(__VA_ARGS__), 0)) #endif //-------------------------------------------------------------------------------- // Assert // #ifndef NW_ASSERT #define NW_ASSERT(exp) \ NW_ASSERTMSG( (exp), "NW:Failed assertion " #exp ) #endif //-------------------------------------------------------------------------------- // NULL Assert // #ifndef NW_NULL_ASSERT #define NW_NULL_ASSERT(exp) \ NW_ASSERTMSG( (exp) != NULL, "NW:Pointer must not be NULL ("#exp")" ) #endif //-------------------------------------------------------------------------------- // Min Assert // #ifndef NW_MIN_ASSERT #define NW_MIN_ASSERT(exp, min) \ NW_ASSERTMSG( (exp) >= (min), #exp " is out of bounds(%d)\n%d <= "#exp" not satisfied.", static_cast(exp), static_cast(min) ) #endif //-------------------------------------------------------------------------------- // Max Assert // #ifndef NW_MAX_ASSERT #define NW_MAX_ASSERT(exp, max) \ NW_ASSERTMSG( (exp) <= (max), #exp " is out of bounds(%d)\n"#exp" <= %d not satisfied.", static_cast(exp), static_cast(max) ) #endif //-------------------------------------------------------------------------------- // Min Max Assert // #ifndef NW_MINMAX_ASSERT #define NW_MINMAX_ASSERT(exp, min, max) \ NW_ASSERTMSG( (exp) >= (min) && (exp) <= (max), #exp " is out of bounds(%d)\n%d <= "#exp" <= %d not satisfied.", static_cast(exp), static_cast(min), static_cast(max)) #endif //-------------------------------------------------------------------------------- // Min Max Less Than Assert // #ifndef NW_MINMAXLT_ASSERT #define NW_MINMAXLT_ASSERT(exp, min, max) \ NW_ASSERTMSG( (exp) >= (min) && (exp) < (max), #exp " is out of bounds(%d)\n%d <= "#exp" < %d not satisfied.", static_cast(exp), static_cast(min), static_cast(max)) #endif //-------------------------------------------------------------------------------- // Min Assert for floating point value // #ifndef NW_FMIN_ASSERT #define NW_FMIN_ASSERT(exp, min) \ NW_ASSERTMSG( (exp) >= (min), #exp " is out of bounds(%f)\n%f <= "#exp" not satisfied.", static_cast(exp), static_cast(min) ) #endif //-------------------------------------------------------------------------------- // Max Assert for floating point value // #ifndef NW_FMAX_ASSERT #define NW_FMAX_ASSERT(exp, max) \ NW_ASSERTMSG( (exp) <= (max), #exp " is out of bounds(%f)\n"#exp" <= %f not satisfied.", static_cast(exp), static_cast(max) ) #endif //-------------------------------------------------------------------------------- // Min Max Assert for floating point value // #ifndef NW_FMINMAX_ASSERT #define NW_FMINMAX_ASSERT(exp, min, max) \ NW_ASSERTMSG( (exp) >= (min) && (exp) <= (max), #exp " is out of bounds(%f)\n%f <= "#exp" <= %f not satisfied.", static_cast(exp), static_cast(min), static_cast(max)) #endif //-------------------------------------------------------------------------------- // Fatal error // #ifndef NW_FATAL_ERROR #ifdef NW_FROM_TOOL #define NW_FATAL_ERROR true ? 0: #else #define NW_FATAL_ERROR(...) \ NW_ASSERTMSG( false, "NW:Fatal Error\n"__VA_ARGS__ ) #endif #endif //-------------------------------------------------------------------------------- // Internal error // #ifndef NW_INTERNAL_ERROR #ifdef NW_FROM_TOOL #define NW_INTERNAL_ERROR true ? 0: #else #define NW_INTERNAL_ERROR(...) \ NW_ASSERTMSG( false, "NW Internal error\n" __VA_ARGS__ ) #endif #endif //-------------------------------------------------------------------------------- // Cache Alignment error // #ifndef NW_CACHE_ALIGN_ASSERT #if defined( NW_PLATFORM_GC ) #define NW_CACHE_ALIGN_ASSERT NW_ALIGN32_ASSERT #else #define NW_CACHE_ALIGN_ASSERT NW_ALIGN32_ASSERT #endif #endif //-------------------------------------------------------------------------------- // Alignment error // #ifndef NW_ALIGN_ASSERT #define NW_ALIGN_ASSERT(exp,align) \ 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 ) #endif //-------------------------------------------------------------------------------- // Alignment error(128 bytes) // #ifndef NW_ALIGN128_ASSERT #define NW_ALIGN128_ASSERT(exp) \ NW_ALIGN_ASSERT( (exp), 128 ) #endif //-------------------------------------------------------------------------------- // Alignment error(32 bytes) // #ifndef NW_ALIGN32_ASSERT #define NW_ALIGN32_ASSERT(exp) \ NW_ALIGN_ASSERT( (exp), 32 ) #endif //-------------------------------------------------------------------------------- // Alignment error(4 bytes) // #ifndef NW_ALIGN4_ASSERT #define NW_ALIGN4_ASSERT(exp) \ NW_ALIGN_ASSERT( (exp), 4 ) #endif //-------------------------------------------------------------------------------- // Alignment error(2 bytes) // #ifndef NW_ALIGN2_ASSERT #define NW_ALIGN2_ASSERT(exp) \ NW_ALIGN_ASSERT( (exp), 2 ) #endif //-------------------------------------------------------------------------------- // buffer size error // #ifndef NW_BUFFERSIZE_ASSERT #ifdef NW_PLATFORM_RVL #define NW_BUFFERSIZE_ASSERT(exp) \ NW_ASSERTMSG( (exp) <= 64 * 1024 * 1024, "NW:Buffer Size Error\n" #exp "(=%d) over maximum physical memory size.", (exp)) #else #define NW_BUFFERSIZE_ASSERT(exp) \ NW_ASSERTMSG( (exp) <= 24 * 1024 * 1024, "NW:Buffer Size Error\n" #exp "(=%d) over maximum physical memory size.", (exp)) #endif #endif //-------------------------------------------------------------------------------- // Invalid pointer error // #ifndef NW_POINTER_ASSERT #if defined(NW_PLATFORM_CTRWIN) || defined(NW_PLATFORM_CTR) #define NW_POINTER_ASSERT(exp) \ NW_ASSERTMSG( \ NW_ANY_TO_PTR_VALUE(exp) != 0, \ "NW:Pointer Error\n"#exp"(=%p) is not valid pointer.", (exp) ) #elif defined(NW_PLATFORM_RVL) #define NW_POINTER_ASSERT(exp) \ NW_ASSERTMSG( \ ((NW_ANY_TO_PTR_VALUE(exp) & 0xFF000000) == 0x80000000) /* 8000_0000~80FF_FFFF MEM1 Cached */ \ || ((NW_ANY_TO_PTR_VALUE(exp) & 0xFF800000) == 0x81000000) /* 8100_0000~817F_FFFF MEM1 Cached */ \ || ((NW_ANY_TO_PTR_VALUE(exp) & 0xF8000000) == 0x90000000) /* 9000_0000~97FF_FFFF MEM2 Cached */ \ || ((NW_ANY_TO_PTR_VALUE(exp) & 0xFF000000) == 0xC0000000) /* C000_0000~C0FF_FFFF MEM1 Uncached */ \ || ((NW_ANY_TO_PTR_VALUE(exp) & 0xFF800000) == 0xC1000000) /* C100_0000~C17F_FFFF MEM1 Uncached */ \ || ((NW_ANY_TO_PTR_VALUE(exp) & 0xF8000000) == 0xD0000000) /* D000_0000~D7FF_FFFF MEM2 Uncached */ \ || ((NW_ANY_TO_PTR_VALUE(exp) & 0xFFFFC000) == 0xE0000000), /* E000_0000~E000_3FFF Locked Cache */ \ "NW:Pointer Error\n"#exp"(=%p) is not valid pointer.", (exp) ) #else #define NW_POINTER_ASSERT(exp) \ NW_ASSERTMSG( \ ((NW_ANY_TO_PTR_VALUE(exp) & 0xF0000000) == 0x80000000) /* Cached */ \ || ((NW_ANY_TO_PTR_VALUE(exp) & 0xF0000000) == 0xC0000000), /* Uncached */ \ "NW:Pointer Error\n"#exp"(=%p) is not valid pointer.", (exp) ) #endif #endif #ifndef NW_REFERENCE_ASSERT #define NW_REFERENCE_ASSERT(ref) NW_POINTER_ASSERT(&ref) #endif //-------------------------------------------------------------------------------- // Range error // #ifndef NW_U8_RANGE_ASSERT #define NW_U8_RANGE_ASSERT(exp) \ NW_MINMAX_ASSERT(exp, 0, UCHAR_MAX) #endif #ifndef NW_S8_RANGE_ASSERT #define NW_S8_RANGE_ASSERT(exp) \ NW_MINMAX_ASSERT(exp, SCHAR_MIN, SCHAR_MAX) #endif #ifndef NW_U16_RANGE_ASSERT #define NW_U16_RANGE_ASSERT(exp) \ NW_MINMAX_ASSERT(exp, 0, USHRT_MAX) #endif #ifndef NW_S16_RANGE_ASSERT #define NW_S16_RANGE_ASSERT(exp) \ NW_MINMAX_ASSERT(exp, SHRT_MIN, SHRT_MAX) #endif #ifndef NW_U32_RANGE_ASSERT #define NW_U32_RANGE_ASSERT(exp) \ NW_MINMAX_ASSERT(exp, 0, UINT_MAX) #endif #ifndef NW_S32_RANGE_ASSERT #define NW_S32_RANGE_ASSERT(exp) \ NW_MINMAX_ASSERT(exp, INT_MIN, INT_MAX) #endif //-------------------------------------------------------------------------------- // Floating point value error // #ifndef NW_FLOAT_ASSERT #ifdef NW_FROM_TOOL #define NW_FLOAT_ASSERT true ? 0: #else #define NW_FLOAT_ASSERT(exp) \ NW_ASSERTMSG((isfinite(exp) && !isnan(exp)), "NW:Floating Point Value Error(%f)\n"#exp" is infinite or nan.", exp) #endif #endif #if !defined( NW_ASSERTION_ENABLE ) #define NW_GL_ASSERT() ((void)0) #else inline const char* nwGlErrorString( u32 err ) { typedef struct { u32 value; const char* name; } EnumString; static const EnumString ENUM_STRINGS[] = { { 0, "GL_NO_ERROR" }, { 0x0500, "GL_INVALID_ENUM" }, { 0x0501, "GL_INVALID_VALUE" }, { 0x0502, "GL_INVALID_OPERATION" }, { 0x0505, "GL_OUT_OF_MEMORY" }, { 0x0506, "GL_INVALID_FRAMEBUFFER_OPERATION" }, { 0x8000, "in nngxGemCmdlists"}, { 0x8001, "in nngxGemCmdlists"}, { 0x8002, "in nngxDeleteCmdlists"}, { 0x8003, "in nngxDeleteCmdlists"}, { 0x8004, "in nngxBindCmdlist"}, { 0x8005, "in nngxBindCmdlist"}, { 0x8006, "in nngxCmdlistStorage"}, { 0x8007, "in nngxCmdlistStorage"}, { 0x8008, "in nngxCmdlistStorage"}, { 0x8009, "in nngxRunCmdlist"}, { 0x800A, "in nngxReserveStopCmdlist"}, { 0x800B, "in nngxReserveStopCmdlist"}, { 0x800C, "in nngxSplitDrawCmdlist"}, { 0x800D, "in nngxSplitDrawCmdlist"}, { 0x800E, "in nngxSplitDrawCmdlist"}, { 0x800F, "in nngxClearCmdlist"}, { 0x8010, "in nngxSetCmdlistCallback"}, { 0x8012, "in nngxEnableCmdlistCallback"}, { 0x8014, "in nngxDisableCmdlistCallback"}, { 0x8015, "in nngxSetCmdlistParameteri"}, { 0x8016, "in nngxSetCmdlistParameteri"}, { 0x8017, "in nngxGetCmdlistParameteri"}, { 0x8018, "in nngxGetCmdlistParameteri"}, { 0x8019, "in nngxCheckVSync"}, { 0x801A, "in nngxWaitVSync"}, { 0x801B, "in nngxSetVSyncCallback"}, { 0x801C, "in nngxGenDisplaybuffers"}, { 0x801D, "in nngxGetDisplaybuffers"}, { 0x801E, "in nngxDeleteDisplayBuffers"}, { 0x801F, "in nngxActiveDisplay"}, { 0x8020, "in nngxBindDisplaybuffer"}, { 0x8021, "in nngxDisplaybufferStorage"}, { 0x8022, "in nngxDisplaybufferStorage"}, { 0x8023, "in nngxDisplaybufferStorage"}, { 0x8024, "in nngxDisplaybufferStorage"}, { 0x8025, "in nngxDisplaybufferStorage"}, { 0x8026, "in nngxDisplayEnv"}, { 0x8027, "in nngxTransferRenderImage"}, { 0x8028, "in nngxTransferRenderImage"}, { 0x8029, "in nngxTransferRenderImage"}, { 0x802A, "in nngxTransferRenderImage"}, { 0x802B, "in nngxTransferRenderImage"}, { 0x802C, "in nngxTransferRenderImage"}, { 0x802D, "in nngxTransferRenderImage"}, { 0x802E, "in nngxTransferRenderImage"}, { 0x802F, "in nngxTransferRenderImage"}, { 0x8030, "in nnwxSwapBuffers"}, { 0x8031, "in nngxSwapBuffers"}, { 0x8032, "in nngxSwapBuffers"}, { 0x8033, "in nngxGetDisplaybufferParameteri"}, { 0x8034, "in nngxStartCmdlistSave"}, { 0x8035, "in nngxStartCmdlistSave"}, { 0x8036, "in nngxStopCmdlistSave"}, { 0x8037, "in nngxUseSavedCmdlist"}, { 0x8038, "in nngxUseSavedCmdlist"}, { 0x8039, "in nngxUseSavedCmdlist"}, { 0x803A, "in nngxUseSavedCmdlist"}, { 0x803B, "in nngxExportCmdlist"}, { 0x803C, "in nngxExportCmdlist"}, { 0x803D, "in nngxExportCmdlist"}, { 0x803E, "in nngxExportCmdlist"}, { 0x803F, "in nngxExportCmdlist"}, { 0x8040, "in nngxExportCmdlist"}, { 0x8041, "in nngxImportCmdlist"}, { 0x8042, "in nngxImportCmdlist"}, { 0x8043, "in nngxImportCmdlist"}, { 0x8044, "in nngxImportCmdlist"}, { 0x8045, "in nngxImportCmdlist"}, { 0x8046, "in nngxGetExportedCmdlistInfo"}, { 0x8047, "in nngxCopyCmdlist"}, { 0x8048, "in nngxCopyCmdlist"}, { 0x8049, "in nngxCopyCmdlist"}, { 0x804A, "in nngxCopyCmdlist"}, { 0x804B, "in nngxCopyCmdlist"}, { 0x804C, "in nngxCopyCmdlist"}, { 0x804D, "in nngxSetCommandGenerationMode"}, { 0x804E, "in nngxAdd3DCommand"}, { 0x804F, "in nngxAdd3DCommand"}, { 0x8050, "in nngxAdd3DCommand"}, { 0x8051, "in nngxAdd3DCommand"}, { 0x8052, "in nngxAdd3DCommand"}, { 0x8053, "in nngxSwapBuffers"}, { 0x8054, "in nngxAddCmdlist"}, { 0x8055, "in nngxAddCmdlist"}, { 0x8056, "in nngxAddCmdlist"}, { 0x8057, "in nngxAddCmdlist"}, { 0x8058, "in nngxAddCmdlist"}, { 0x8059, "in nngxTransferRenderImage"}, { 0x805A, "in nngxTransferRenderImage"}, { 0x805B, "in nngxTransferLinearImage"}, { 0x805C, "in nngxTransferLinearImage"}, { 0x805D, "in nngxTransferLinearImage"}, { 0x805E, "in nngxTransferLinearImage"}, { 0x805F, "in nngxTransferLinearImage"}, { 0x8060, "in nngxTransferLinearImage"}, { 0x8062, "in nngxAddVramDmaCommand"}, { 0x8063, "srcAddr alignment error in nngxAddVramDmaCommand"}, { 0x8064, "in nngxAddVramDmaCommand"}, { 0x8065, "in nngxClearFillCmdlist"}, { 0x8066, "in nngxValidateState"}, { 0x8067, "in nngxTransferLinearImage"}, { 0x8068, "in nngxFilterBlockImage"}, { 0x8069, "in nngxFilterBlockImage"}, { 0x806A, "in nngxFilterBlockImage"}, { 0x806B, "in nngxFilterBlockImage"}, { 0x806C, "in nngxValidateState"}, { 0x9000, "in nngxSwapBuffers"}, { 0x9001, "in nngxSwapBuffers"}, { 0x9002, "in nngxSwapBuffers"}, { 0x9003, "in nngxSetDisplayMode"}, }; const int NUM_ENUM_STRING = sizeof(ENUM_STRINGS) / sizeof(ENUM_STRINGS[0]); for (int idx = 0; idx < NUM_ENUM_STRING; ++idx) { if ( ENUM_STRINGS[ idx ].value == err ) { return ENUM_STRINGS[ idx ].name; } } return "Unknown"; } #define NW_GL_ASSERT() \ do { \ GLuint err = glGetError(); \ NW_ASSERTMSG( err == GL_NO_ERROR, "GL_ERROR : %s (0x%x)", nwGlErrorString( err ), err ); \ } while (0) #endif //-------------------------------------------------------------------------------- // Warning // #ifndef NW_WARNING //#ifdef NW_FROM_TOOL #if !defined(NW_WARNING_ENABLE) #define NW_WARNING(exp, ...) ((void)0) #else #define NW_WARNING(exp, ...) (void) ((exp) || (nwosWarning(__VA_ARGS__), 0)) #endif //#else //#define NW_WARNING NW_DB_EXP_WARNING //#endif #endif //-------------------------------------------------------------------------------- // Fail safe // #if !defined( NW_ASSERTION_ENABLE ) #define NW_FAILSAFE_IF(exp) if (exp) #else #define NW_FAILSAFE_IF(exp) if (exp) { NW_FATAL_ERROR(#exp); } if (false) #endif //-------------------------------------------------------------------------------- // Log // //#ifndef NW_LOG //#ifdef NW_FROM_TOOL #define NW_LOG nwosPrintf //#else //#define NW_LOG NW_DB_LOG //#endif //#endif //-------------------------------------------------------------------------------- // デバッグ時のみ有効で Development ではチェックしない ASSERT // #if defined( NW_DEBUG ) #define NW_DEBUG_ASSERTMSG NW_ASSERTMSG #define NW_DEBUG_ASSERT NW_ASSERT #define NW_DEBUG_NULL_ASSERT NW_NULL_ASSERT #else #define NW_DEBUG_ASSERTMSG(exp, ...) ((void)0) #define NW_DEBUG_ASSERT(exp) ((void)0) #define NW_DEBUG_NULL_ASSERT(exp) ((void)0) #endif /* NW_ASSERT_H_ */ #endif