except3.c

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|