C:\home\SVGCats_src\src\except3.c
1|/************************************************************************* 2|* 1. <<< ソフトウェア例外処理3 (Except3) >>> 3|**************************************************************************/ 4| 5|#include "mixer_precomp.h" /* Auto precompiled header, Look at mixer-... folder */ 6|// #pragma hdrstop ("mixer_precomp") 7| 8|#define STDLIBS_INCLUDE 9|#define STDLIBS_INCLUDE_SETJMP_H 10|#define STDLIBS_INCLUDE_STRING_H 11| 12|#if defined(USES_MXP_AUTOINC) 13| #include "except3.ah" /* Auto include header, Look at mixer-... folder */ 14|#endif 15| 16| 17|#ifdef USES_MULTASK 18| Except3 Except3_con[Except3_m]; 19|#else 20| Except3 Except3_con; 21|#endif 22| 23|#if !defined(NDEBUG) || defined(ERRORS_ERROR_REPORT) 24| static char* Except3_OutOfTry_Str = "キャッチできない例外が発生しました"; 25|#else 26| static char* Except3_OutOfTry_Str = ""; 27|#endif 28| 29|static char* Except3_DupTry_Str = "catch か finally ブロック内か、ロングジャンプしない領域で" 30| "例外を処理していないときに try があってはなりません。\n" 31| "以前のエラーメッセージが一部消える可能性があります。"; 32|static char* Except3_FinallyThrow_Str = "finally ブロック内で例外が発生しました。" 33| "一部の後始末処理は行われません。"; 34|static char* Except3_TryStackOver_Str = "try 用スタック領域がいっぱいになりました。"; 35| 36| 37|/*--------------------------------------------------------------------*/ 38|/* 2. <<<◆(Except3) 例外処理システム >>> */ 39|/*--------------------------------------------------------------------*/ 40| 41|/************************************************************************* 42|* 3. <<< [Except3_init_imp] Except3_init の実装 >>> 43|**************************************************************************/ 44|void Except3_init_imp( Except3* m, 45| Except3_Try* tryInfo, int tryInfo_size ) 46|{ 47| ERRORS_INITCHK( m, 0 ); 48| 49| m->bExcept = false; 50| m->bNoJumpArea = false; 51| m->tryInfo = tryInfo; 52| m->mTry = tryInfo_size / sizeof(Except3_Try); 53|} 54| 55| 56| 57|/************************************************************************* 58|* 4. <<< [Except3_try_imp] try の実装 >>> 59|**************************************************************************/ 60|void Except3_try_imp( Except3* m, char* file, int line ) 61|{ 62| EXCEPT3_INITCHK( m ); 63| 64| #ifndef NDEBUG 65| if ( m->bExcept ) 66| Except3_error( Except3_Err_DupTry, Except3_DupTry_Str ); 67| if ( m->nTry >= m->mTry - 1 ) /* -1 はマクロで既に使っているため */ 68| Except3_error( Except3_Err_TryStackOver, Except3_TryStackOver_Str ); 69| #endif 70| 71| /* try ネストの記録 */ 72| m->tryInfo[m->nTry].file = file; 73| m->tryInfo[m->nTry].line = line; 74| m->tryInfo[m->nTry].bNoJumpAreaTop = m->bNoJumpArea; 75| 76| /* try 処理 */ 77| m->nTry ++; 78| m->bExcept = false; 79| m->bAgain = false; 80| m->bCatch = false; 81| m->bNoJumpArea = false; 82|} 83| 84| 85| 86|/************************************************************************* 87|* 5. <<< [Except3_catch_imp] catch の実装 >>> 88|**************************************************************************/ 89|int Except3_catch_imp( Except3* m ) 90|{ 91| extern int Errors_errDupCount; 92| EXCEPT3_INITCHK( m ); 93| 94| if ( m->bAgain ) return 0; /* catch 内の再スロー */ 95| 96| Errors_errDupCount = 0; 97| m->bCatch = true; 98| return 1; 99|} 100| 101| 102| 103|/************************************************************************* 104|* 6. <<< [Except3_end_finally_imp] >>> 105|**************************************************************************/ 106|void Except3_end_finally_imp( Except3* m ) 107|{ 108| EXCEPT3_INITCHK( m ); 109| 110| if ( m->tryInfo[m->nTry - 1].bNoJumpAreaTop ) 111| m->bNoJumpArea = true; 112| 113| if ( m->bExcept ) { 114| if ( m->bAgain ) { 115| m->nTry --; 116| m->bAgain = false; 117| m->bCatch = false; 118| if ( m->nTry <= 0 ) { 119| if ( ! m->tryInfo[0].bNoJumpAreaTop ) 120| Except3_error( Except3_Err_OutOfTry, Except3_OutOfTry_Str ); 121| } 122| else { 123| if ( ! m->tryInfo[m->nTry].bNoJumpAreaTop ) 124| longjmp( m->tryInfo[m->nTry - 1].longjmp_buf, 1 ); 125| } 126| } 127| else if ( ! m->bCatch ) { 128| m->nTry --; 129| if ( m->nTry <= 0 ) { 130| if ( ! m->tryInfo[0].bNoJumpAreaTop ) 131| Except3_error( Except3_Err_OutOfTry, Except3_OutOfTry_Str ); 132| } 133| else { 134| if ( ! m->tryInfo[m->nTry].bNoJumpAreaTop ) 135| longjmp( m->tryInfo[m->nTry - 1].longjmp_buf, 1 ); 136| } 137| } 138| else { 139| m->nTry --; 140| m->bExcept = false; 141| m->bCatch = false; 142| Errors_clearError(); 143| } 144| } 145| else { 146| if ( m->nTry <= 0 ) 147| Except3_error( Except3_Err_OutOfTry, Except3_OutOfTry_Str ); 148| m->nTry --; 149| } 150|} 151| 152| 153| 154|/************************************************************************* 155|* 7. <<< [Except3_throw_imp] throw の実装 >>> 156|**************************************************************************/ 157|void Except3_throw_imp( Except3* m, void* msg ) 158|{ 159| #ifndef NDEBUG 160| static int throwing = 0; 161| 162| throwing ++; 163| ASSERT( throwing == 1 ); 164| 165| EXCEPT3_INITCHK( m ); 166| if ( m->bExcept && ! m->bCatch ) 167| Except3_error( Except3_Err_FinallyThrow, Except3_FinallyThrow_Str ); 168| #endif 169| 170| ERRORS_FUNCLOG_ONLONGJUMP(); 171| 172| /* 例外メッセージを登録する */ 173| m->msg = msg; 174| 175| /* ロングジャンプする */ 176| /* 通常のスローは、上位の catch へ、catch 内での再スロー は同位の finally へ */ 177| if ( m->bNoJumpArea ) { 178| m->bExcept = true; 179| #ifndef NDEBUG 180| throwing = 0; 181| #endif 182| } 183| else { 184| if ( m->nTry <= 0 ) 185| Except3_error( Except3_Err_OutOfTry, Except3_OutOfTry_Str ); 186| 187| if ( m->bCatch ) { 188| m->bAgain = true; 189| #ifndef NDEBUG 190| throwing = 0; 191| #endif 192| longjmp( m->tryInfo[m->nTry - 1].longjmp_buf, 1 ); 193| } 194| else { 195| m->bExcept = true; 196| #ifndef NDEBUG 197| throwing = 0; 198| #endif 199| longjmp( m->tryInfo[m->nTry - 1].longjmp_buf, 1 ); 200| } 201| } 202|} 203| 204| 205| 206|/************************************************************************* 207|* 8. <<< [Except3_startNoJumpArea_imp] Except3_startNoJumpArea の実装 >>> 208|**************************************************************************/ 209|void Except3_startNoJumpArea_imp( Except3* m ) 210|{ 211| m->bNoJumpArea = true; 212|} 213| 214|/************************************************************************* 215|* 9. <<< [Except3_endNoJumpArea_imp] Except3_endNoJumpArea の実装 >>> 216|**************************************************************************/ 217|void Except3_endNoJumpArea_imp( Except3* m ) 218|{ 219| m->bNoJumpArea = false; 220| 221| if ( m->bExcept ) { 222| if ( m->nTry <= 0 ) 223| Except3_error( Except3_Err_OutOfTry, Except3_OutOfTry_Str ); 224| 225| if ( m->bCatch ) { 226| m->bAgain = true; 227| longjmp( m->tryInfo[m->nTry - 1].longjmp_buf, 1 ); 228| } 229| else { 230| m->bExcept = true; 231| longjmp( m->tryInfo[m->nTry - 1].longjmp_buf, 1 ); 232| } 233| } 234|} 235| 236| 237|/************************************************************************* 238|* 10. <<< [Except3_isNoJumpArea_imp] Except3_isNoJumpArea の実装 >>> 239|**************************************************************************/ 240|bool Except3_isNoJumpArea_imp( Except3* m ) 241|{ 242| return ( m->bNoJumpArea == true || m->nTry == 0 ); 243|} 244| 245| 246|/************************************************************************* 247|* 11. <<< [Except3_isError_imp] Except3_isError の実装 >>> 248|**************************************************************************/ 249|bool Except3_isError_imp( Except3* m ) 250|{ 251| EXCEPT3_INITCHK( m ); 252| 253| /* 多重例外かどうかを記録する */ 254| if ( m->bExcept ) return true; 255| return false; 256|} 257| 258| 259| 260|/************************************************************************* 261|* 12. <<< [Except3_print_imp] 例外処理システムの状態をデバッグ表示する >>> 262|**************************************************************************/ 263|#ifndef ERRORS_CUT_DEBUG_TOOL 264|#ifdef USES_MULTASK 265| void Except3_print_imp( Except3* m, int id ) 266|#else 267| void Except3_print_imp( Except3* m ) 268|#endif 269|{ 270| int i; 271| 272| EXCEPT3_INITCHK( m ); 273| 274| #ifdef USES_MULTASK 275| Errors_printf( "Except3[%d]: adr = %p", id, m->msg ); 276| #else 277| Errors_printf( "Except3:" ); 278| #endif 279| Errors_printf( " msg adr = %p", m->msg ); 280| Errors_printf( " bExcept = %d", m->bExcept ); 281| Errors_printf( " bCatch = %d", m->bCatch ); 282| Errors_printf( " bAgain = %d", m->bAgain ); 283| Errors_printf( " nTry = %d", m->nTry ); 284| #ifdef EXCEPT3_NO_HINT 285| Errors_printf( " try is NO HINT" ); 286| #else 287| for ( i = 0; i < m->nTry; i++ ) { 288| Errors_printf( " try[%d] in %s:%d", 289| i, m->tryInfo[i].file, m->tryInfo[i].line ); 290| } 291| #endif 292|} 293|#endif 294| 295|/************************************************************************* 296|* 13. <<< [Except3_error_imp] 例外処理システムの異常終了 >>> 297|* 14. <<< [Except3_bNoExitChk] 異常終了時にチェックをしないフラグ >>> 298|**************************************************************************/ 299|void Except3_error_imp( int code, const char* msg, char* file, int line ) 300|{ 301| #ifdef USES_MULTASK 302| Except3* m = &Except3_con[MulTask_Sys_getCurIndex()]; 303| #else 304| Except3* m = &Except3_con; 305| #endif 306| 307| if ( Errors_MsgPool_isInit( Errors_MsgPool_getGlobl() ) && 308| Errors_Msg_getGlobl()->code != Errors_NoError ) { 309| Errors_MsgPool_add( Errors_MsgPool_getGlobl(), Errors_Msg_getGlobl() ); 310| /* この上でハングアップするときは、Errors_MsgPool のメモリ領域が */ 311| /* ローカル変数のスコープ外になるなどの無効になっている可能性があります。 */ 312| } 313| Errors_Msg_init( Errors_Msg_getGlobl(), -1, code, file, line, "%s", msg ); 314| 315| if ( Errors_hdl != NULL ) { 316| extern Errors_errDupCount; 317| Errors_errDupCount ++; 318| 319| m->bExcept = false; 320| (*Errors_hdl)( Errors_Msg_getGlobl()->id, code, Errors_Msg_getGlobl()->msg ); 321| } 322| else 323| Errors_printf_release( Errors_Msg_getGlobl()->msg ); 324| 325| Errors_exit( file, line ); 326|} 327| 328|/*--------------------------------------------------------------------*/ 329|/* 15. <<<◆(Except3_MsgMng) エラーメッセージの管理 >>> */ 330|/*--------------------------------------------------------------------*/ 331| 332|/************************************************************************* 333|* 16. <<< (Except3_MsgStack) メッセージ・スタック抽象型 >>> 334|**************************************************************************/ 335|#ifdef USES_INF 336|#ifndef NDEBUG 337|INF_FUNC_R1( Except3_MsgStack,push, void*, Except3_MsgStack_push, Except3_MsgStack,void*, t,a ) 338|INF_FUNC_R1( Except3_MsgStack,pop, void*, Except3_MsgStack_pop, Except3_MsgStack,void*, t,a ) 339|#endif 340|#endif 341| 342| 343|