ERRORS.H

[目次 | 型・クラス・構造体 | マクロ]

目次

型・クラス・構造体一覧

マクロ一覧


   1|/***************************************************************************
   2|  1. <<< テスト&デバッグツール (errors) >>> 
   3|****************************************************************************/
   4|
   5|#ifndef __ERRORS_H
   6|#define __ERRORS_H
   7|
   8|#ifdef  count
   9| #undef count
  10|#endif
  11| 
  12|/***********************************************************************
  13|  2. <<< モジュール設定・優先ヘッダ >>> 
  14|  3. <<< [ERRORS_INITCHK_VAR] Errors_InitChk 初期化チェックのマジックナンバー >>>
  15|  4. <<< [NDEBUG, リリース版, デバッグ版] >>>
  16|【補足】
  17|・NDEBUG が #define されているとリリース版、
  18|  #define されていないとデバッグ版となります。
  19|  これは、他のすべてのモジュールに対して有効です。
  20|************************************************************************/
  21|
  22|#ifndef USES_PRIORITY_HEADER
  23|/*[START_OF_PRIORITY_HEADER]*/
  24|
  25|#ifndef  USES_ERRORS
  26|#define  USES_ERRORS
  27|
  28|/*#define  NDEBUG */         /* リリースバージョンなら有効にしてください */
  29|
  30|/* デバッグ・ヒント用 printf の出力先の設定 */
  31|/* 複数選択できます。選択しない場合、環境に応じたデフォルトになります */
  32|/*#define  ERRORS_PRINTF_TO_WINDOW */ /* メッセージボックス(ウィンドウ)へ */
  33|/*#define  ERRORS_PRINTF_TO_STDOUT */ /* コンソールの標準出力へ*/
  34|/*#define  ERRORS_PRINTF_TO_STDERR */ /* コンソールの標準エラー出力へ*/
  35|/*#define  ERRORS_PRINTF_TO_MEMORY */ /* メモリ領域へ */
  36|/*#define  ERRORS_PRINTF_TO_FILE */   /* ファイルへ */
  37|/*#define  ERRORS_PRINTF_TO_PB */     /* PB のデバッグメッセージへ */
  38|
  39|/* リリース時のエラーメッセージ用 printf の出力先の設定 */
  40|/* 複数選択できます。選択しない場合、環境に応じたデフォルトになります */
  41|/*#define  ERRORS_ERR_PRINTF_TO_WINDOW */ /* メッセージボックス(ウィンドウ)へ */
  42|/*#define  ERRORS_ERR_PRINTF_TO_STDERR */ /* コンソールの標準エラー出力へ*/
  43|/*#define  ERRORS_ERR_PRINTF_TO_MEMORY */ /* メモリ領域へ */
  44|/*#define  ERRORS_ERR_PRINTF_TO_FILE*/  /* ファイルへ */
  45|/*#define  ERRORS_ERR_PRINTF_TO_PB */     /* PB のデバッグメッセージへ */
  46|
  47|/* リリース版でもエラーメッセージを詳細にする(文字列領域が増えます)*/
  48|  #define  ERRORS_ERROR_REPORT
  49|
  50|/* アサートメッセージを詳細にする(文字列領域が増えます)*/
  51|  #define  ERRORS_ASSERT_REPORT
  52|
  53|/* デバッグツールを取除く(あったら、コンパイラからメッセージを出す)*/
  54|/*#define  ERRORS_CUT_DEBUG_TOOL */
  55|
  56|/* テストツールを取除く(あったら、コンパイラからメッセージを出す)*/
  57|/*#define  ERRORS_CUT_TEST_TOOL */
  58|
  59|/* BACKMARK を有効にする */
  60|/*#define ERRORS_USE_BACKMARK */
  61|
  62|/* WX の最大表示行数 */
  63|#define  ERRORS_WX_NLINE  5
  64|
  65|/* 異常終了時に後始末チェックを行わない */
  66|/* #define ERRORS_NO_EXIT_CHK */
  67|
  68|/* 関数コール履歴を有効にする */
  69|/* #define  ERRORS_USE_FUNCLOG */
  70|/* #define  ERRORS_FUNCLOG_PRINT_EVERY */  /* 関数の出入口で、デバッグ表示する */
  71|/* #define  ERRORS_FUNCLOG_LEVEL  ERRORS_FUNC_CRITICAL_IMP */  /* 履歴を追跡するレベル */
  72|/* #define  ERRORS_FUNCLOG_LED   0  */  /* LED に履歴に入ったら 1を表示する、履歴は記録しないため高速、番号=LED7識別番号(0〜) */
  73|/* #define  ERRORS_FUNCLOG_SPECIFIC */  /* 明示的に指定したファイルのみ有効にする(errors.htm参照) */
  74|
  75|/* エラーログのメモリサイズ */
  76|/* #define  Errors_log_size  7777 */  /* 省略するとデフォルト値(→別記)になる */
  77|
  78|
  79|/* 以下は修正しないでください ---------------------------------------------*/
  80|
  81|#ifndef FOR_NOFILE
  82|  #define  STDLIBS_INCLUDE_STDIO_H
  83|#endif
  84|
  85|typedef  int  (*Errors_Handler)( int err_id, int code, char* msg );
  86|typedef struct _Errors_Msg      Errors_Msg;
  87|typedef struct _Errors_MsgPool  Errors_MsgPool;
  88|
  89|#ifdef  count
  90|  #undef  count
  91|#endif
  92|
  93|#ifndef ERRORS_INITCHK_VAR
  94|typedef struct {
  95|  int  order, key, count, var;
  96|} Errors_InitChk;
  97|#ifndef  NDEBUG
  98|#define  ERRORS_INITCHK_VAR  Errors_InitChk  __initchk;
  99|#else
 100|#define  ERRORS_INITCHK_VAR
 101|#endif
 102|#endif
 103|
 104|typedef  struct  _Errors_FuncLog  Errors_FuncLog;
 105|
 106|#endif
 107|
 108|/*[END_OF_PRIORITY_HEADER]*/
 109|#endif /* USES_PRIORITY_HEADER */
 110|
 111| 
 112|/* 以下は、内部用です。------------------------------*/ 
 113|#ifndef  ERRORS_SETTING
 114|#define  ERRORS_SETTING
 115|
 116|/*(デバッグ用 printf の出力先のデフォルト設定)*/
 117|#ifndef  ERRORS_PRINTF_TO_WINDOW
 118| #ifndef  ERRORS_PRINTF_TO_STDOUT
 119|  #ifndef  ERRORS_PRINTF_TO_STDERR
 120|   #ifndef  ERRORS_PRINTF_TO_MEMORY
 121|    #ifndef  ERRORS_PRINTF_TO_FILE
 122|
 123|  #ifdef  FOR_WIN32
 124|    #define  ERRORS_PRINTF_TO_WINDOW
 125|    #define  ERRORS_PRINTF_TO_MEMORY
 126|  #endif
 127|  #ifdef  FOR_DOS32
 128|    #define  ERRORS_PRINTF_TO_STDOUT
 129|    #define  ERRORS_PRINTF_TO_MEMORY
 130|  #endif
 131|  #ifndef  FOR_WIN32
 132|   #ifndef  FOR_DOS32
 133|    #define  ERRORS_PRINTF_TO_MEMORY
 134|   #endif
 135|  #endif
 136|
 137|    #endif
 138|   #endif
 139|  #endif
 140| #endif
 141|#endif
 142|
 143|
 144|/* エラーメッセージの出力先の設定 */
 145|/* Except2 とリンクしない場合のみ有効です */
 146|/* 複数選択できます。選択しない場合、環境に応じたデフォルトになります */
 147|/*#define  ERRORS_ERR_PRINTF_TO_WINDOW */ /* メッセージボックス(ウィンドウ)へ */
 148|/*#define  ERRORS_ERR_PRINTF_TO_STDERR */ /* コンソールの標準エラー出力へ*/
 149|/*#define  ERRORS_ERR_PRINTF_TO_MEMORY */ /* メモリ領域へ */
 150|
 151|
 152|#endif /* ERRORS_SETTING */
 153|
 154| 
 155|/***********************************************************************
 156|  5. <<< エラーコード >>> 
 157|************************************************************************/
 158|#define  Errors_NoError      0    /* [Compone_GID:Errors_Code] */
 159|#define  Errors_ErrorStart   101  /* [Compone_GID:Errors_Code] */
 160|#define  Errors_Unofficial   102  /* [Compone_GID:Errors_Code] エラーコードを割当てていない内部的なエラー */
 161|#define  Errors_InitMiss     103  /* [Compone_GID:Errors_Code] */
 162|#define  Errors_OrderMiss    104  /* [Compone_GID:Errors_Code] */
 163|#define  Errors_ErrorEnd     105  /* [Compone_GID:Errors_Code] */
 164|#define  Errors_FinishChker  106  /* [Compone_GID:Errors_Code] 初期化と後始末の関係が合っていない */
 165|#define  Errors_NotSupport   107  /* [Compone_GID:Errors_Code] 一般的な未サポート */
 166|#define  Errors_ChkRet       108  /* [Compone_GID:Errors_Code] エラー返り値 */
 167|#define  Errors_ASSERT       109  /* [Compone_GID:Errors_Code] */
 168|#define  Errors_BadCheckSum  110  /* [Compone_GID:Errors_Code] */
 169|#define  Errors_Err_FuncLogNotInit  111    /* [Compone_GID:Errors_Code] */
 170|#define  Errors_Err_Errno    112  /* [Compone_GID:Errors_Code] */
 171|#define  Errors_Err_DoubleCount 113 /* [Compone_GID:Errors_Code] */
 172|#define  Errors_Err_DoubleInit  114  /* [Compone_GID:Errors_Code] */
 173|#define  Errors_Err_NoInit      115  /* [Compone_GID:Errors_Code] */
 174| 
 175|/*-----------------------------------------------------------------*/
 176|/* 6. <<< Interface Area ----------------------------------------->>> */ 
 177|/*-----------------------------------------------------------------*/
 178|
 179|#ifdef __cplusplus
 180|extern "C" {
 181|#endif
 182|
 183|
 184| 
 185|/**************************************************************************
 186|  7. <<< ◆エラー処理ツール >>> 
 187|【役割】
 188|・発生したエラーをプログラムが対処するときに使用します。
 189|***************************************************************************/
 190|/* error(); */
 191|/* error2_0( code, msg ); */
 192|/* error2_1( code, msg,a ); */
 193|/* error2_2( code, msg,a,b ); */
 194|/* error2_3( code, msg,a,b,c ); */
 195|/* error2_4( code, msg,a,b,c,d ); */
 196|/* error2_5( code, msg,a,b,c,d,e ); */
 197|
 198|void  Errors_clearError(void);
 199|void  Errors_errorStdlib(void);
 200|
 201|/* void  ERRORS_WARNING_0( const char* fmt ); */
 202|/* void  ERRORS_WARNING_1( const char* fmt, a ); */
 203|/* void  ERRORS_WARNING_2( const char* fmt, a, b ); */
 204|/* void  ERRORS_WARNING_3( const char* fmt, a, b, c ); */
 205|/* void  ERRORS_WARNING_4( const char* fmt, a, b, c, d ); */
 206|/* void  ERRORS_WARNING_5( const char* fmt, a, b, c, d, e ); */
 207|void  Errors_warning_imp( const char* file, int line, const char* fmt, ... );
 208|
 209|void  Errors_setErrorHandler( Errors_Handler f );
 210|int   Errors_stdErrHandler( int id, int code, char* msg );
 211|
 212|
 213|/* Errors_catch( type, msg, cases ); */
 214|/* Errors_end_catch; */
 215|/* Errors_pool_catch( cases ); */
 216|/* Errors_ignore_catch( cases ); */
 217|
 218|bool  Errors_isUserError(void);
 219|extern  int  Errors_bStrongExit;  /* 強制終了モードかどうか */
 220|
 221| 
 222|/*************************************************************************
 223|  8. <<< [Errors_Msg] エラーメッセージ >>> 
 224|**************************************************************************/
 225|struct _Errors_Msg {
 226| #ifdef  USES_ARRX
 227|  ArrX_AbleElem  inherit_ArrX_AbleElem;  /* for Errors_MsgPool */
 228| #endif
 229|  int   id;               /* エラーID */
 230|  int   code;             /* エラーコード */
 231|  char  msg[512];         /* エラーメッセージ(表示用変換済み) */
 232|  char* orgMsg;           /* オリジナル・メッセージ(表示用変換前) */
 233|  char  file[256];        /* エラーが発生したソースファイル名 */
 234|  int   line;             /* エラーが発生したソース行番号 */
 235|};
 236|void  Errors_Msg_init( Errors_Msg*, int id, int code, const char* file,
 237|  int line, const char* msg_fmt, ... );
 238|void  Errors_Msg_print( Errors_Msg* );
 239|Errors_Msg*  Errors_Msg_getGlobl(void);
 240|#ifdef  USES_MULTASK
 241|  void  Errors_Msg_initGlobl( Errors_Msg* msgs, int size );
 242|#endif
 243|
 244| 
 245|/**************************************************************************
 246|  9. <<< [Errors_MsgPool] エラーメッセージ・プール >>> 
 247|【補足】
 248|・エラーを一時的に無視して処理を続け、あとでエラーメッセージを
 249|  使用するときのために、エラーメッセージをためておく場所です。
 250|・第一引数には、Errors_MsgPool_getGlobl 関数で取得できる
 251|  グローバル変数へのアドレスを指定します。
 252|・エラーが発生したところで、Errors_pool_catch マクロや ErrorsMsgPool_add 関数
 253|  を使ってエラーメッセージをためます。
 254|・エラー処理(通知)をするところで、Errors_MsgPool_getN 関数を使って
 255|  たまっているメッセージがあると判断したら、Errors_MsgPool_getFirst や
 256|  Errors_MsgPool_forEach を使ってエラーメッセージを取得します。
 257|***************************************************************************/
 258|#ifdef  USES_ARRX
 259|#ifdef  USES_OFFSET
 260|
 261|struct _Errors_MsgPool {
 262|  ArrX_Able  msgs;  /* Errors_Msg 型の要素 */
 263|};
 264|
 265|void  Errors_MsgPool_init( Errors_MsgPool*, Errors_Msg* msgs, int msgs_size );
 266|bool  Errors_MsgPool_isInit( Errors_MsgPool* );
 267|void  Errors_MsgPool_toEmpty( Errors_MsgPool* );
 268|void  Errors_MsgPool_add( Errors_MsgPool*, Errors_Msg* );
 269|void  Errors_MsgPool_remove( Errors_MsgPool*, Errors_Msg* );
 270|int   Errors_MsgPool_getN( Errors_MsgPool* );
 271|/*    Errors_MsgPool_forEach( Errors_MsgPool*, Errors_Msg** );*/
 272|Errors_Msg*  Errors_MsgPool_getFirst( Errors_MsgPool* );
 273|/* その他の操作は msgs メンバ変数を直接操作してください */
 274|
 275|Errors_MsgPool*  Errors_MsgPool_getGlobl(void);
 276|void  Errors_MsgPool_print( Errors_MsgPool* );
 277|void  ERRORS_MSGPOOL_PRINT( Errors_MsgPool* );
 278|void  Errors_MsgPool_printLowLevel( Errors_MsgPool* );
 279|#ifdef  USES_MULTASK
 280|  void  Errors_MsgPool_initGlobl( Errors_MsgPool* msgs, int size );
 281|#endif
 282|
 283|#endif
 284|#endif
 285|
 286| 
 287|/**************************************************************************
 288|  10. <<< ◆テストツール >>> 
 289|【役割】
 290|・プログラムを実行しながらエラーの存在を探し出します。
 291|【補足】
 292|・テストツールは以下のものがあります。
 293|  ・ASSERT              表明(事前条件チェック、事後条件チェック)
 294|  ・ERRORS_SINGLETON    シングレトン・パターン
 295|  ・ERRORS_INITCHK      初期化チェック
 296|  ・ERRORS_FINISHCHK    後始末チェック
 297|  ・ERRORS_NOT_SUPPORT  未サポート・エラー
 298|***************************************************************************/
 299|void  Errors_chkDefault(void);
 300|
 301|/* ASSERT( cond ); */
 302|
 303|#if ERRORS_USES_OLD_020419
 304|/* ASSERT2_0( cond, code, msg ); */
 305|/* ASSERT2_1( cond, code, msg,a ); */
 306|/* ASSERT2_2( cond, code, msg,a,b ); */
 307|/* ASSERT2_3( cond, code, msg,a,b,c ); */
 308|/* ASSERT2_4( cond, code, msg,a,b,c,d ); */
 309|/* ASSERT2_5( cond, code, msg,a,b,c,d,e ); */
 310|#endif
 311|
 312|/* ERRORS_SWITCH_DEFAULT_ASSERT; */
 313|
 314|/* ERRORS_CHKRET( cond, code ); */
 315|/* Errors_chkRet( cond, code ); */
 316|
 317|/* Errors_autoChk( format, _var, cond ); */
 318|/* Errors_autoChk2( format, _declaration, _let, cond ); */
 319|/* Errors_autoChkW( format, _var1, _op, _var2 ); */
 320|void  Errors_checkSum( void** ranges, int ranges_size );
 321|extern int   Errors_sum;
 322|
 323|/* ERRORS_SINGLETON_FOR_INIT( chker, this ); */
 324|/* ERRORS_SINGLETON_FOR_FINISH( chker, this ); */
 325|
 326|/* ERRORS_VERSION( module_name, number ); */
 327|
 328|void  ERRORS_NOT_SUPPORT(void);
 329|void  Errors_notSupport(void);
 330|
 331|void  Errors_setStart( int r6, int* r7 );
 332|void  Errors_setStart_imp( int r6, int* r7 );
 333|extern char*  Errors_okLabel;
 334|extern char*  Errors_errLabel;
 335|extern  int   Errors_errCount;
 336|
 337|
 338| 
 339|/**********************************************************************
 340|  11. <<< [初期化チェック] >>> 
 341|【役割】
 342|・初期化関数(*_init)が呼ばれたかチェックします。
 343|・関数を呼び出す順序もチェックできます。
 344|【補足】
 345|・チェックを通らなかった場合、error() になります。
 346|・NDEBUG 設定では、初期化チェックに関するコードを生成しません。
 347|・チェックはあくまで確率的なものなので、ERRORS_INITCHK を用いて
 348|  初期化したかどうかの判断をリリース用のコードに組み込まないで
 349|  ください。(管理モジュールが初期化フラグを用意するなどしてください)
 350|【例】
 351|・構造体の最後に、マジックナンバー ERRORS_INITCHK_VAR を書きます。
 352|  struct _Class {
 353|    int a,b,c;
 354|    ERRORS_INITCHK_VAR    // セミコロン(;)を付けないこと
 355|  };
 356|・関数内の変数宣言が終わった直後に ERRORS_INITCHK を書きます。
 357|  void  Class_init( Class* this )
 358|  {
 359|    int  i;
 360|    ERRORS_INITCHK( this, 0 );
 361|    sub();
 362|  }
 363|・関数の呼び出す順序が決まっている場合、手続きオーダーの値を次のように
 364| 設定します。(手続きオーダーは、関数呼び出しの順番を表したもので、
 365|  ERRORS_INITCHK マクロの第2引数に指定する値です。)
 366|  ・init, funcA, funcB の順番に呼び出す場合、0,1,2 を指定します。
 367|  ・init, funcA1, funcA2, funcB の順番に呼び出すか、
 368|    init, funcA2, funcA1, funcB の順番に呼び出す場合、0,1,1,3
 369|    を指定します。
 370|  ・init, funcA1, funcB の順番に呼び出すか、
 371|    init, funcA2, funcB の順番に呼び出す場合、0,1,2(funcA1 も funcA2
 372|    も 1)を指定します。
 373|・ユーザに公開しないで内部で使われる関数で、初期化チェックを行う場合、
 374|  ERRORS_INITCHK の代わりに ERRORS_INITCHK_FOR_SUB を使ってください。
 375|  これを使うと、同じ手続きオーダーでもカウントアップしません
 376|  内部で手続きオーダー 1 が2回呼ばれてもオーダー 3 は受け入れなくなります。
 377|・初期化済みのデータには、ERRORS_INITCHK_CANCELER を置きます。
 378|**********************************************************************/
 379|/* 構造体の定義は、優先ヘッダにあります */
 380|/* void  ERRORS_INITCHK( void* this, int order ); */
 381|/* void  ERRORS_INITCHK_FOR_SUB( void* this, int order ); */
 382|/* int   ERRORS_INITCHK_MAGIC( void* this, int order, int key, int count ); */
 383|/* int   ERRORS_INITCHK_CANCELER; */
 384|
 385|bool  Errors_InitChk_getOrder( void* );
 386|#if !defined(ERRORS_CUT_DEBUG_TOOL) && !defined(NDEBUG)
 387|void  Errors_InitChk_print( void* );
 388|#endif
 389|
 390|/* 内部用 */
 391|void  Errors_InitChk_imp( void*, Errors_InitChk*,
 392|  int order, const char* file, int line, bool bCountUp );
 393|void  Errors_InitChk_print_imp( Errors_InitChk*, int order );
 394|
 395|
 396| 
 397|/**********************************************************************
 398|  12. <<< [後始末チェック] >>> 
 399|【補足】
 400|・指定のクラスが後始末チェックに対応するには、以下の場所に
 401|  特定の文を書きます。
 402|  ・初期化関数(〜_init)の正常処理の最後に ERRORS_FINISHCHK_FOR_INIT
 403|  ・後始末関数(〜_finish)の最初に ERRORS_FINISHCHK_FOR_FINISH
 404|・後始末チェックERRORS_FINISHCHK)は、プログラムの最後で行います。
 405|・リリース版では、チェックをしません。
 406|・ArrX をリンクしないときは、チェックをしないようになります。
 407|・後始末し忘れているオブジェクトを調査するときは、
 408|  ERRORS_FINISHCHK_INSPECT_FOR_INIT, ERRORS_FINISHCHK_INSPECT_FOR_FINISH
 409|  を使います。
 410|**********************************************************************/
 411|#if  defined(USES_ARRX) && defined(USES_OFFSET)
 412|
 413|/* 後始末チェック用関数 */
 414|
 415|/* void  ERRORS_FINISHCHK_FOR_INIT( _finish ); (下記)*/
 416|/* void  ERRORS_FINISHCHK_FOR_FINISH( _finish ); (下記)*/
 417|/* void  ERRORS_FINISHCHK(void); (下記)*/
 418|void  Errors_FinishChk_printAll(void);
 419|/* void  Errors_FinishChk_print( _finish ); */
 420|
 421|#define  ERRORS_FINISHCHK_MCLASS   50   /* チェックできるクラスの最大数 */
 422|#define  ERRORS_FINISHCHK_MNAME    16   /* 1つの後始末関数名を記録する長さ+1 */
 423|
 424|
 425|/* 後始末を忘れたオブジェクトの調査用関数 */
 426|
 427|/* void  ERRORS_FINISHCHK_INSPECT_FOR_INIT( this, _finish ); */
 428|/* void  ERRORS_FINISHCHK_INSPECT_FOR_FINISH( this, _finish ); */
 429|
 430|#define  ERRORS_FINISHCHK_INSPECT_MOBJ  1000
 431|
 432|
 433|/* 内部用 */
 434|void  Errors_FinishChk_count( void (*_finish)(), char* name, int plus );
 435|void  Errors_FinishChk_imp(void);
 436|void  Errors_FinishChk_print_imp( const char* _finish, char* file, int line );
 437|void  Errors_FinishChk_Inspect_forInit_imp( void*, void (*_finish)(),
 438|  const char* name );
 439|void  Errors_FinishChk_Inspect_forFinish_imp( void*, void (*_finish)(),
 440|  const char* name );
 441|
 442|/*  13. <<< [Errors_FinElem] 後始末チェック 内部用データ >>> */
 443|typedef  struct {
 444|  char  name[ERRORS_FINISHCHK_MNAME];   /* 後始末関数名の先頭mバイト */
 445|  int   funcAdr;    /* 後始末関数のアドレス */
 446|  int   count;      /* 後始末カウンタ */
 447|} Errors_FinElem;
 448|
 449|#endif  /* USES_ARRX && USES_OFFSET */
 450|
 451| 
 452|/**************************************************************************
 453|  14. <<< ◆デバッグツール >>> 
 454|【役割】
 455|・エラーの原因を探し出します。
 456|【補足】
 457|・デバッグツールは以下のものがあります。
 458|  ・Errors_printf, WD, WS, WP   変数表示、デバッグ用
 459|  ・Errors_printf_release       変数表示、リリース用
 460|  ・Errors_errPrintf   変数表示、テストエラー表示用
 461|  ・Errors_break       ブレークポイント
 462|***************************************************************************/
 463|
 464|/* デバッグツール */
 465|void  MARK(void);
 466|void  BACKMARK(void);
 467|void  COUNT( int );
 468|void  COUNT2( int );
 469|/* BK */
 470|void  WD( int var );
 471|void  WD0( int var );
 472|void  WS( char* var );
 473|void  WS0( char* var );
 474|void  WSP( char* var );
 475|void  WSP0( char* var );
 476|void  WP( void* var );
 477|void  WP0( void* var );
 478|void  WPP( void* var );
 479|void  WF( double* var );
 480|void  WF0( double* var );
 481|void  WX( void* adr, int size );
 482|void  WX2( void* adr, int size );
 483|void  WATCH(void);
 484|void  setWATCH( void* adr, int sizek, bool lookAtCount );
 485|extern int  Errors_Line;
 486|
 487|/* 出力 */
 488|char* Errors_printf( const char* fmt, ... );
 489|void  Errors_setPrintfFlag( bool pf );
 490|char* Errors_printf_release( const char* fmt, ... );
 491|void  Errors_printf_back( const char* fmt, ... );
 492|char* Errors_errPrintf( const char* fmt, ... );
 493|char* Errors_testCasePrintf( const char* fmt, ... );
 494|void  Errors_printSize( const char* guide, int size );
 495|void  ERRORS_PRINTF_FLUSH(void);
 496|void  Errors_clearLog(void);
 497|int   Errors_counter( int stop_count );
 498|int   Errors_getDispCh( int c );
 499|void  Errors_printLowLevel( const char* msg );
 500|
 501|#ifdef  FOR_WIN32
 502| void  Errors_startPool_release(void);
 503| void  Errors_endPool_release(void);
 504| void  Errors_endAllPool_release(void);
 505| void  Errors_clearPool_release(void);
 506|
 507| void  Errors_startPool(void);
 508| void  Errors_endPool(void);
 509| void  Errors_endAllPool(void);
 510| void  Errors_clearPool(void);
 511|#endif
 512|
 513|/* 親ウィンドウ: MFC を使うときは、下記の両方を設定してください */
 514|#if !defined(NDEBUG) || defined(ERRORS_ERROR_REPORT)
 515| extern char*  Errors_appName;
 516| extern char*  Errors_appVersion;
 517| extern struct HWND__* Errors_parentWnd;  /* HWND 型 */
 518| extern void*  Errors_parentCWnd;   /* CWnd* 型にキャストして使う */
 519|#endif
 520|
 521|/* Errors_log_size */
 522|#ifndef  Errors_log_size
 523|  #if !defined(NDEBUG) || !defined(ERRORS_CUT_DEBUG_TOOL)
 524|    #define  Errors_log_size  0x7777  /* 30583(10進数) */
 525|  #else
 526|    #define  Errors_log_size  0x777   /* 1911(10進数) */
 527|  #endif
 528|#endif
 529|
 530|/* ブレークポイント */
 531|void  BP(void);
 532|void  Errors_break( int var );
 533|void  Errors_break_release( int var );
 534|void  Errors_break_asm( /*sym*/ );
 535|void  Errors_setBreakFlag( bool bf );
 536|void  Errors_setBreakID( int id );
 537|
 538|/* 一時グローバル変数 */
 539|#ifndef  ERRORS_CUT_DEBUG_TOOL
 540| extern int  Errors_X;  extern int  Errors_X2;  extern int  Errors_X3;
 541|#else
 542| #define  Errors_X   cut_errors_x_of_debug_tool  /* Syntax Error */
 543| #define  Errors_X2  cut_errors_x_of_debug_tool  /* Syntax Error */
 544| #define  Errors_X3  cut_errors_x_of_debug_tool  /* Syntax Error */
 545|#endif
 546|
 547| 
 548|/**************************************************************************
 549|  15. <<< [Errors_FuncLog, Errors_FuncLog_Elem] 関数コール履歴 >>> 
 550|***************************************************************************/
 551|void  ERRORS_FUNCLOG_INIT(void);
 552|void  Errors_FuncLog_print(void);
 553|void  ERRORS_FUNCLOG_PRINT(void);
 554|void  ERRORS_FUNCLOG_ONLONGJUMP(void);
 555|
 556|/* void  ERRORS_FUNC_START( _func ); */  /* _func は関数名 */
 557|/* void  ERRORS_FUNC_END( _func ); */
 558|/* void  ERRORS_FUNC_START2( level, _func ); */  /* class_func はクラス名+関数名 */
 559|/* void  ERRORS_FUNC_END2( level, _func ); */
 560|
 561|/* ERRORS_FUNC_CPP_VAR( class_func ); */  /* 変数宣言 */
 562|/* void  ERRORS_FUNC_START_CPP( class_func ); */  /* class_func はクラス名+関数名 */
 563|/* void  ERRORS_FUNC_END_CPP( class_func ); */
 564|/* void  ERRORS_FUNC_START2_CPP( level, class_func ); */
 565|/* void  ERRORS_FUNC_END2_CPP( level, class_func ); */
 566|
 567|
 568|/* 以下は内部用 */
 569|
 570|#define  Errors_FuncLog_size  256
 571|
 572|typedef struct {
 573|  void*  adr;
 574|  char*  name;
 575|}  Errors_FuncLog_Elem;
 576|
 577|struct  _Errors_FuncLog {
 578|  Errors_FuncLog_Elem  funcs[Errors_FuncLog_size];  /* 関数コールした関数(スタック)*/
 579|  int    funcs_n;  /* funcs の有効数 */
 580|  bool   bLongJumped;  /* ロングジャンプがあったかどうか */
 581|};
 582|
 583|
 584|void  Errors_FuncLog_init( Errors_FuncLog* );
 585|void  Errors_FuncLog_print_imp( Errors_FuncLog* );
 586|void  Errors_FuncLog_onLongJump( Errors_FuncLog* );
 587|void  Errors_FuncLog_setStart( Errors_FuncLog*, void* func, char* func_name );
 588|void  Errors_FuncLog_setEnd( Errors_FuncLog*, void* func, char* func_name );
 589|extern  Errors_FuncLog  Errors_FuncLog_globl;
 590| 
 591|/**************************************************************************
 592|  16. <<< 内部用 >>> 
 593|【補足】
 594|・内部用です
 595|・Error_Tri 型(関数ポインタ型)の mode 引数は次の通りです。
 596|  int mode;   arg のさしている実体の型、0=なし、1=int, 2=string, 3=long
 597|***************************************************************************/
 598|
 599|/* エラー処理 */
 600|void  Errors_error_imp( const char* file, int line, int code, char* codeStr,
 601|  char* fmt, ... );
 602|void  Errors_exit( const char* file, int line );
 603|extern  bool  Errors_exited;
 604|
 605|/* デバッグツール(変数) */
 606|extern char* Errors_ps;
 607|extern char* Errors_ns;
 608|extern char* Errors_eu;
 609|extern char* Errors_ea;
 610|extern char* Errors_null;
 611|
 612|extern  char  Errors_log[];
 613|extern  char* Errors_log_p;
 614|extern  char  Errors_log2[];
 615|extern  char* Errors_log2_p;
 616|extern  char* Errors_poolStart;
 617|
 618|extern int  Errors_count;
 619|
 620|#ifndef  ERRORS_CUT_DEBUG_TOOL
 621| extern  int    Errors_count0;
 622| extern  char*  Errors_count_prev_n_file;
 623| extern  int    Errors_count_prev_n_line;
 624| extern  int    Errors_count_prev_n;
 625|
 626| extern  int    Errors_count2;
 627| extern  int    Errors_count2_0;
 628| extern  char*  Errors_count2_prev_n_file;
 629| extern  int    Errors_count2_prev_n_line;
 630| extern  int    Errors_count2_prev_n;
 631|
 632| extern  int    Errors_count_b;
 633| extern  int    Errors_count_b2;
 634|#endif
 635|
 636|extern  bool  Errors_bWatchLookAtCount;
 637|
 638|
 639|/* デバッグツール(関数) */
 640|char* Errors_printf_imp( const char* fmt, ... );
 641|void  Errors_printf_back_imp( const char* fmt, ... );
 642|void  Errors_backmark_imp( const char* file, int line );
 643|int   Errors_counter_imp( int stop_count );
 644|#ifdef  ERRORS_BF_IS_1ARG
 645|  void  bf( int r6 );
 646|#else
 647|  int   bf( int r6, int r7, int r8, int r9 );
 648|#endif
 649|void  bf2( int r6, int r7, int r8, int r9 );
 650|void  Errors_WD_imp( char* name, void* p, int ver, char* file, int line );
 651|void  Errors_WSP_imp( char* name, const char** p, const char* ver, char* file, int line );
 652|void  Errors_WB_imp( char* name, const void* p, char* file, int line );
 653|void  Errors_WX_imp( char* adr_name, void* adr, int size, char* file, int line );
 654|void  Errors_WX2_imp( char* adr_name, void* adr, int size, char* file, int line );
 655|void  Errors_WATCH_imp( char* file, int line );
 656|void  Errors_setWATCH_imp( void* adr, char* name, int type, int size,
 657|  bool lookAtCount, char* file, int line );
 658|void  Errors_break_imp( int r6, int r7, int r8, int r9 );
 659|
 660|
 661|
 662| 
 663|/*-----------------------------------------------------------------*/
 664|/* 17. <<< Mapping Area ------------------------------------------->>> */ 
 665|/*-----------------------------------------------------------------*/
 666|
 667|
 668| 
 669|/*-------------------------------------------------------------------------*/
 670|/* 18. <<< ◆エラー処理ツール >>>  */ 
 671|/*-------------------------------------------------------------------------*/
 672| 
 673|/**************************************************************************
 674|*  19. <<< [error] エラーを発生させる >>> 
 675|*【機能】
 676|*・一般的なエラーを発生させます。
 677|*【補足】
 678|*・エラーの内容を報告する場合は、error2_0 マクロなどを使用します。
 679|*・error によって与えられるエラーコードは、Errors_Unofficial です。
 680|*・エラー処理を行ったら、Errors_clearError 関数を呼び出してください。
 681|*・プログラムを終了する直前に、Errors_setErrorHandler 関数で登録した
 682|*  関数を呼出します。登録した関数の中で、正常に終了するための処理を記述します。
 683|*  (詳細は、Errors_setErrorHandler 関数の解説を参照してください。)
 684|*・ERRORS_ERROR_REPORT を #define すると、条件文 cond がエラーメッセージに
 685|*  付くようになります。ただし、Except2 をリンクしている場合は、
 686|*  EXCEPT2_NOMSG を #define しないように設定をしてください。
 687|*・リリース時も有効です。
 688|*・本マクロは、Except2 モジュールとリンクするときと、しないときで、
 689|*  動作が異なります。
 690|*  リンクする場合、Except2_Std 型の例外を発生します。
 691|*  対応する catch ブロックが無ければ、Errors_exit 関数を呼出して
 692|*  プログラムを終了します。
 693|*  リンクしない場合、すぐに Errors_exit 関数を呼出してプログラムを終了します。
 694|*  プログラムの終了ができないアセンブラ・デバッガでは、第一引数に相当する
 695|*  レジスタに 0xEEEEEEEE を格納してから exit ラベルにジャンプします。
 696|*  よって、スタートアップ・ルーチンなどに exit ラベルを作成する必要があります。
 697|***************************************************************************/
 698|#ifdef  USES_EXCEPT2
 699|  #define error() \
 700|    throw( Except2_Std_newExcept2_c( \
 701|    Errors_Unofficial, Errors_eu, "error" ) )
 702|#else
 703|  #define  error()  Errors_error_imp(__FILE__,__LINE__,Errors_Unofficial, Errors_eu, "error")
 704|#endif
 705|
 706|
 707|
 708|
 709|
 710| 
 711|/**************************************************************************
 712|*  20. <<< [error2] エラーを発生させる(拡張版) >>> 
 713|*  21. <<< [error2_0, error2_1, error2_2, error2_3, error2_4, error2_5] >>>
 714|*【機能】
 715|*・エラーコード、エラーメッセージを備えた error です。
 716|*【引数】
 717|*  ・int    code;    エラーコード
 718|*  ・char*  msg;     エラーメッセージ(printf形式)
 719|*  ・var1,var2...;   msg の printf 引数
 720|*【補足】
 721|*・リリース時も有効です。
 722|*・error, ASSERT2 の解説を参照してください。
 723|***************************************************************************/
 724|#ifdef  USES_EXCEPT2
 725|  #if defined(ERRORS_ERROR_REPORT) || !defined(NDEBUG)
 726|    #define error2_0( code, msg ) \
 727|      throw( Except2_Std_newExcept2_c( code, #code, msg ) )
 728|    #define error2_1( code, msg, var1 ) \
 729|      throw( Except2_Std_newExcept2_cf( code, #code, msg, var1 ) )
 730|    #define error2_2( code, msg, var1, var2 ) \
 731|      throw( Except2_Std_newExcept2_cf( code, #code, msg, var1, var2 ) )
 732|    #define error2_3( code, msg, var1, var2, var3 ) \
 733|      throw( Except2_Std_newExcept2_cf( code, #code, msg, var1, var2, var3 ) )
 734|    #define error2_4( code, msg, var1, var2, var3, var4 ) \
 735|      throw( Except2_Std_newExcept2_cf( code, #code, msg, var1, var2, var3, var4 ) )
 736|    #define error2_5( code, msg, var1, var2, var3, var4, var5 ) \
 737|      throw( Except2_Std_newExcept2_cf( code, #code, msg, var1, var2, var3, var4, var5 ) )
 738|  #else
 739|    #define error2_0( code, msg ) \
 740|      throw( Except2_Std_newExcept2_c( code, Errors_null, Errors_null ) )
 741|    #define error2_1( code, msg, var1 ) \
 742|      throw( Except2_Std_newExcept2_c( code, Errors_null, Errors_null ) )
 743|    #define error2_2( code, msg, var1, var2 ) \
 744|      throw( Except2_Std_newExcept2_c( code, Errors_null, Errors_null ) )
 745|    #define error2_3( code, msg, var1, var2, var3 ) \
 746|      throw( Except2_Std_newExcept2_c( code, Errors_null, Errors_null ) )
 747|    #define error2_4( code, msg, var1, var2, var3, var4 ) \
 748|      throw( Except2_Std_newExcept2_c( code, Errors_null, Errors_null ) )
 749|    #define error2_5( code, msg, var1, var2, var3, var4, var5 ) \
 750|      throw( Except2_Std_newExcept2_c( code, Errors_null, Errors_null ) )
 751|  #endif
 752|#else
 753|  #if defined(ERRORS_ERROR_REPORT) || !defined(NDEBUG)
 754|    #define  error2_0( code, msg )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg)
 755|    #define  error2_1( code, msg, var1 )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1)
 756|    #define  error2_2( code, msg, var1, var2 )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1,var2)
 757|    #define  error2_3( code, msg, var1, var2, var3)  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1,var2,var3)
 758|    #define  error2_4( code, msg, var1, var2, var3, var4 )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1,var2,var3,var4)
 759|    #define  error2_5( code, msg, var1, var2, var3, var4, var5 )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1,var2,var3,var4,var5)
 760|  #else
 761|    #define  error2_0( code, msg )  Errors_error_imp(__FILE__,__LINE__,code,Errors_null,Errors_null)
 762|    #define  error2_1( code, msg, var1 )  Errors_error_imp(__FILE__,__LINE__,code,Errors_null,Errors_null)
 763|    #define  error2_2( code, msg, var1, var2 )  Errors_error_imp(__FILE__,__LINE__,code,Errors_null,Errors_null)
 764|    #define  error2_3( code, msg, var1, var2, var3)  Errors_error_imp(__FILE__,__LINE__,code,Errors_null,Errors_null)
 765|    #define  error2_4( code, msg, var1, var2, var3, var4 )  Errors_error_imp(__FILE__,__LINE__,code,Errors_null,Errors_null)
 766|    #define  error2_5( code, msg, var1, var2, var3, var4, var5 )  Errors_error_imp(__FILE__,__LINE__,code,Errors_null,Errors_null)
 767|  #endif
 768|#endif
 769|
 770|
 771| 
 772|/***************************************************************************
 773|*  22. <<< [ERRORS_WARNING_0] 警告を通知する >>> 
 774|*  23. <<< [ERRORS_WARNING_1, ERRORS_WARNING_2, ERRORS_WARNING_3] >>>
 775|*  24. <<< [ERRORS_WARNING_4, ERRORS_WARNING_5] >>>
 776|*【補足】
 777|*・設定が、場合によっては良くても、一般的に良くないときに警告を表示します。
 778|*  表示は Errors_printf を使用します。
 779|*・警告はデバッグ版でのみ行います。
 780|****************************************************************************/
 781|#if !defined(ERRORS_CUT_DEBUG_TOOL) && !defined(NDEBUG)
 782|  #define  ERRORS_WARNING_0( fmt ) \
 783|    Errors_warning_imp( __FILE__, __LINE__, fmt )
 784|  #define  ERRORS_WARNING_1( fmt, var1 ) \
 785|    Errors_warning_imp( __FILE__, __LINE__, fmt, var1 )
 786|  #define  ERRORS_WARNING_2( fmt, var1, var2 ) \
 787|    Errors_warning_imp( __FILE__, __LINE__, fmt, var1, var2 )
 788|  #define  ERRORS_WARNING_3( fmt, var1, var2, var3 ) \
 789|    Errors_warning_imp( __FILE__, __LINE__, fmt, var1, var2, var3 )
 790|  #define  ERRORS_WARNING_4( fmt, var1, var2, var3, var4 ) \
 791|    Errors_warning_imp( __FILE__, __LINE__, fmt, var1, var2, var3, var4 )
 792|  #define  ERRORS_WARNING_5( fmt, var1, var2, var3, var4, var5 ) \
 793|    Errors_warning_imp( __FILE__, __LINE__, fmt, var1, var2, var3, var4, var5 )
 794|#else
 795|  #define  ERRORS_WARNING_0( fmt )
 796|  #define  ERRORS_WARNING_1( fmt, var1 )
 797|  #define  ERRORS_WARNING_2( fmt, var1, var2 )
 798|  #define  ERRORS_WARNING_3( fmt, var1, var2, var3 )
 799|  #define  ERRORS_WARNING_4( fmt, var1, var2, var3, var4 )
 800|  #define  ERRORS_WARNING_5( fmt, var1, var2, var3, var4, var5 )
 801|#endif
 802| 
 803|/**************************************************************************
 804|*  25. <<< [Errors_catch] 指定エラーコードのみの例外キャッチ >>> 
 805|*【補足】
 806|*・指定したエラーコード以外の場合は、再スロー(c_throw_again) します。
 807|*【例】
 808|*  c_try {
 809|*  } Errors_catch ( Errors_Msg*, msg, case ErrorCode: ) {
 810|*  } Errors_end_catch;
 811|***************************************************************************/
 812|#ifdef  USES_EXCEPT3
 813|  #define  Errors_catch( type, msg, cases ) \
 814|    c_catch ( type, msg ) { \
 815|      switch ( msg->code ) { \
 816|        cases
 817|#endif
 818|
 819| 
 820|/**************************************************************************
 821|*  26. <<< [Errors_end_catch] Errors_catch のブロックの終了 >>> 
 822|***************************************************************************/
 823|#ifdef  USES_EXCEPT3
 824|  #define  Errors_end_catch \
 825|          break; \
 826|        default:  c_throw_again(); \
 827|      } \
 828|    } c_end_catch
 829|#endif
 830|
 831| 
 832|/**************************************************************************
 833|*  27. <<< [Errors_pool_catch] エラーメッセージをプールにためて例外を無視する >>> 
 834|*【補足】
 835|*・指定したエラーコードの場合は、エラーメッセージ・プール(Errros_MsgPool)
 836|*  に追加して例外処理を終了します。
 837|*・指定したエラーコード以外の場合は、再スロー(c_throw_again) します。
 838|*【例】
 839|*  c_try {
 840|*  } Errors_pool_catch ( case ErrorCode1: case ErrorCode2: );
 841|***************************************************************************/
 842|#define  Errors_pool_catch( cases ) \
 843|  Errors_catch ( Errors_Msg*, msg, cases ) { \
 844|    Errors_MsgPool_add( Errors_MsgPool_getGlobl(), Errors_Msg_getGlobl() ); \
 845|  } Errors_end_catch;
 846|
 847| 
 848|/**************************************************************************
 849|*  28. <<< [Errors_ignore_catch] 例外を無視する >>> 
 850|*【補足】
 851|*・指定したエラーコードの場合は、エラーを無視して次の文を実行します。
 852|*・指定したエラーコード以外の場合は、再スロー(c_throw_again) します。
 853|*【例】
 854|*  c_try {
 855|*  } Errors_ignore_catch ( case ErrorCode1: case ErrorCode2: );
 856|***************************************************************************/
 857|#define  Errors_ignore_catch( cases ) \
 858|  Errors_catch ( Errors_Msg*, msg, cases ) { \
 859|  } Errors_end_catch;
 860|
 861| 
 862|/*************************************************************************
 863|*  29. <<< ユーザ・エラーかどうか [Errors_isUserError] >>> 
 864|*【機能】
 865|*・ユーザの ASSERT または、try ブロックの外の ASSERT かどうか判定します。
 866|*【補足】
 867|*・エラー処理ハンドラの返り値として、ユーザ・エラーなら ERRORS_EXIT、
 868|*  ライブラリ内部のエラーなら ERRORS_IGNORE とするときに用います。
 869|**************************************************************************/
 870|#ifdef  USES_EXCEPT2
 871|  #define  Errors_isUserError   Except2_Sys_isUserError
 872|#else
 873|  #define  Errors_isUserError   _need_except2_module
 874|#endif
 875|
 876| 
 877|/*-------------------------------------------------------------------------*/
 878|/* 30. <<< ◆(Errors_MsgPool) エラーメッセージ・プール >>> */ 
 879|/*-------------------------------------------------------------------------*/
 880|
 881|
 882| 
 883|/**************************************************************************
 884|*  31. <<< [Errors_MsgPool_init] エラーメッセージ・プールを初期化する >>> 
 885|***************************************************************************/
 886|#define  Errors_MsgPool_init( pool, _msgs, _msgs_size ) \
 887|  ArrX_Able_init( &(pool)->msgs, _msgs, _msgs_size, Errors_Msg )
 888|
 889|
 890| 
 891|/**************************************************************************
 892|*  32. <<< [Errors_MsgPool_toEmpty] エラーメッセージ・プールを空にする >>> 
 893|***************************************************************************/
 894|#define  Errors_MsgPool_toEmpty( pool ) \
 895|  ArrX_Able_setAbleAll( &(pool)->msgs, false, Errors_Msg )
 896|
 897|
 898| 
 899|/**************************************************************************
 900|*  33. <<< [Errors_MsgPool_add] エラーメッセージ・プールを追加する >>> 
 901|*【引数】
 902|*  ・Errors_MsgPool*  pool;  エラーメッセージ・プール
 903|*  ・Errors_Msg*      msg;   エラーメッセージの入った領域のアドレス
 904|*【補足】
 905|*・msg のエラーメッセージは、エラーメッセージ・プールへコピーされます。
 906|*  よって、msg の内容を変更しても、追加されたエラーメッセージは
 907|*  変更されません。
 908|*【内部補足】
 909|*・構造体コピーを使用しているので、Errors_Msg 型のメンバにはポインタを
 910|*  使用しないでください。
 911|***************************************************************************/
 912|#define  Errors_MsgPool_add( pool, msg ) \
 913|  { \
 914|    Errors_Msg*  m; \
 915|    m = ArrX_Able_getFirstDisabled( &(pool)->msgs, Errors_Msg ); \
 916|    *m = *msg; \
 917|    ArrX_AbleElem_setAble( m, true ); \
 918|  }
 919|
 920|
 921| 
 922|/**************************************************************************
 923|*  34. <<< [Errors_MsgPool_remove] エラーメッセージ・プールから除外する >>> 
 924|*【引数】
 925|*  ・Errors_MsgPool*  pool;  エラーメッセージ・プール
 926|*  ・Errors_Msg*      msg;   除外するエラーメッセージ
 927|*【補足】
 928|*・msg には、Errors_MsgPool_forEach などで取得できる pool 内部の
 929|*  アドレスを指定してください。
 930|***************************************************************************/
 931|#define  Errors_MsgPool_remove( pool, msg ) \
 932|  ArrX_AbleElem_setAble( msg, false )
 933|
 934|
 935| 
 936|/**************************************************************************
 937|*  35. <<< [Errors_MsgPool_getN] エラーメッセージ・プールに入っている数を返す >>> 
 938|***************************************************************************/
 939|#define  Errors_MsgPool_getN( pool ) \
 940|  ArrX_Able_getN( &(pool)->msgs, Errors_Msg )
 941|
 942|
 943| 
 944|/**************************************************************************
 945|*  36. <<< [Errors_MsgPool_forEach] 登録されているエラーメッセージを列挙する >>> 
 946|*【引数】
 947|*  ・Errors_Msg**     pMsg;  参照するエラーメッセージ・ポインタのアドレス
 948|*  ・Errors_MsgPool*  pool;  エラーメッセージ・プール
 949|*【補足】
 950|*・次のように for 文の内部で使用します。
 951|*     for ( Errore_MsgPool_forEach( pool, &msg ) );
 952|***************************************************************************/
 953|#ifdef USES_ARRX
 954|#ifdef USES_OFFSET
 955|#define  Errors_MsgPool_forEach( pool, pMsg ) \
 956|  ArrX_Able_forEach( &(pool)->msgs, pMsg, Errors_Msg )
 957|#endif
 958|#endif
 959| 
 960|/**************************************************************************
 961|*  37. <<< [Errors_MsgPool_getFirst] 最初のエラーメッセージを返す >>> 
 962|***************************************************************************/
 963|#define  Errors_MsgPool_getFirst( pool ) \
 964|  ArrX_Able_getFirst( &(pool)->msgs, Errors_Msg )
 965| 
 966|/**************************************************************************
 967|*  38. <<< [ERRORS_MSGPOOL_PRINT] 登録されているエラーメッセージをすべて表示する >>> 
 968|***************************************************************************/
 969|#ifdef  NDEBUG
 970|  #define  ERRORS_MSGPOOL_PRINT( pool )
 971|#else
 972|  #define  ERRORS_MSGPOOL_PRINT( pool )    Errors_MsgPool_print( pool )
 973|#endif
 974|
 975| 
 976|/*-------------------------------------------------------------------------*/
 977|/* 39. <<< ◆テストツール >>> */ 
 978|/*-------------------------------------------------------------------------*/
 979|
 980|
 981| 
 982|/**************************************************************************
 983|*  40. <<< [ASSERT] 値をチェックする(条件表明)>>> 
 984|*【機能】
 985|*・引数 cond に書かれた条件が満たされていることを保証します。
 986|*  もし、条件が満たされていない場合、エラー通知します(errorマクロ)。
 987|*【引数】
 988|*  ・bool   cond;    正常条件(falseならエラー)
 989|*【例】
 990|*  int  func( int n )
 991|*  {
 992|*     ASSERT( n >= 0 );    // この関数の引数 n は0以上であること、の意味
 993|*     return  array[n];
 994|*  }
 995|*【補足】
 996|*・条件が満たされなかった場合については、error マクロを参照してください。
 997|*・リリース版では、条件文が実行されないことと、エラーが発生しないことに
 998|*  注意してください。正常なループの終了条件に ASSERT を使用しないでください。
 999|*・本ヘッダより前に FOR_TEST が #define してあった場合、リリース版でも
1000|*  ASSERT デバッグ版と同じ動きをします。
1001|*・ERRORS_ASSERT_REPORT を #define すると、条件文 cond がエラーメッセージに
1002|*  付くようになります。ただし、Except2 をリンクしている場合は、
1003|*  EXCEPT2_NOMSG を #define しないように設定をしてください。
1004|*・else 文を書くときは、直前の if 文に { } を必ず付けてください。エラーになります。
1005|***************************************************************************/
1006|#ifndef ASSERT
1007|  #ifdef  USES_EXCEPT2
1008|    #if  !defined(NDEBUG) || defined(FOR_TEST)
1009|      #ifdef  ERRORS_ASSERT_REPORT
1010|        #define ASSERT( cond ) \
1011|          if ( ! (cond) )  throw( Except2_Std_newExcept2_c( \
1012|              Errors_ASSERT, Errors_ea, #cond ) );
1013|      #else
1014|        #define ASSERT( cond ) \
1015|          if ( ! (cond) )  throw( Except2_Std_newExcept2_c( \
1016|              Errors_ASSERT, Errors_ea, Errors_null ) );
1017|      #endif
1018|    #else
1019|      #define ASSERT( cond )   0
1020|    #endif
1021|  #else
1022|    #if  !defined(NDEBUG) || defined(FOR_TEST)
1023|      #ifdef  ERRORS_ASSERT_REPORT
1024|        #define ASSERT( cond ) \
1025|          if ( ! (cond) )  Errors_error_imp( __FILE__, __LINE__, \
1026|              Errors_ASSERT, Errors_ea, Errors_ps, #cond );
1027|      #else
1028|        #define ASSERT( cond ) \
1029|          if ( ! (cond) )  Errors_error_imp( Errors_null, __LINE__, \
1030|              Errors_ASSERT, Errors_ea, Errors_ps, Errors_ns );
1031|      #endif
1032|    #else
1033|      #define ASSERT( cond )   0
1034|    #endif
1035|  #endif
1036|#endif
1037|
1038|
1039| 
1040|/***********************************************************************
1041|*  41. <<< [ASSERT2] 値をチェックする(条件表明、拡張版) >>> 
1042|*  42. <<< [ASSERT2_0, ASSERT2_1, ASSERT2_2, ASSERT2_3, ASSERT2_4, ASSERT2_5] >>>
1043|*【機能】
1044|*・エラーコード、エラーメッセージを備えた ASSERT です。
1045|*【引数】
1046|*  ・bool   cond;    正常条件(falseならエラー)
1047|*  ・int    code;    エラーコード
1048|*  ・char*  msg;     エラーメッセージ(printf形式)
1049|*  ・var1,var2...;   msg の printf 引数
1050|*【補足】
1051|*・ASSERT2 ASSERT の違いは、エラーコード、エラーメッセージを
1052|*  指定できることです。これらによってエラーの原因のヒントを与える
1053|*  ことができます。
1054|*・code と msg は、内部で呼出される Errors_errPrintf 関数と、
1055|*  エラー処理関数に伝わります。よって、code や msg に応じて
1056|*  エラー処理関数の動きを変えることができます。
1057|*・Except2 モジュールとリンクした場合は、Except2_Std 型の例外を
1058|*  発生します。code と msg は、その例外オブジェクトに格納されるので、
1059|*  code や msg に応じて catch ブロックの動きを変えることができます。
1060|************************************************************************/
1061|#if ERRORS_USES_OLD_020419
1062|
1063|#if defined(NDEBUG) && !defined(FOR_TEST)
1064| #define  ASSERT2_0( cond, code, msg )   0
1065| #define  ASSERT2_1( cond, code, msg, var1 )   0
1066| #define  ASSERT2_2( cond, code, msg, var1, var2 )   0
1067| #define  ASSERT2_3( cond, code, msg, var1, var2, var3 )   0
1068| #define  ASSERT2_4( cond, code, msg, var1, var2, var3, var4 )   0
1069| #define  ASSERT2_5( cond, code, msg, var1, var2, var3, var4, var5 )   0
1070|#else
1071| #ifdef  USES_EXCEPT2
1072|  #ifdef  ERRORS_ASSERT_REPORT
1073|   #define  ASSERT2_0( cond, code, msg ) \
1074|    if ( ! (cond) )  throw( Except2_Std_newExcept2_c( code, #code, msg ) );
1075|   #define  ASSERT2_1( cond, code, msg, var1 ) \
1076|    if ( ! (cond) )  throw( Except2_Std_newExcept2_cf( code, #code, msg, var1 ) );
1077|   #define  ASSERT2_2( cond, code, msg, var1, var2 ) \
1078|    if ( ! (cond) )  throw( Except2_Std_newExcept2_cf( code, #code, msg, var1, var2 ) );
1079|   #define  ASSERT2_3( cond, code, msg, var1, var2, var3 ) \
1080|    if ( ! (cond) )  throw( Except2_Std_newExcept2_cf \
1081|    ( code, #code, msg, var1, var2, var3 ) );
1082|   #define  ASSERT2_4( cond, code, msg, var1, var2, var3, var4 ) \
1083|    if ( ! (cond) )  throw( Except2_Std_newExcept2_cf \
1084|    ( code, #code, msg, var1, var2, var3, var4 ) );
1085|   #define  ASSERT2_5( cond, code, msg, var1, var2, var3, var4, var5 ) \
1086|    if ( ! (cond) )  throw( Except2_Std_newExcept2_cf \
1087|    ( code, #code, msg, var1, var2, var3, var4, var5 ) );
1088|  #else
1089|   #define  ASSERT2_0( cond, code, msg ) \
1090|    if ( ! (cond) )  throw( Except2_Std_newExcept2_c( code, Errors_null, msg ) );
1091|   #define  ASSERT2_1( cond, code, msg, var1 ) \
1092|    if ( ! (cond) )  throw( Except2_Std_newExcept2_cf( code, Errors_null, msg, var1 ) );
1093|   #define  ASSERT2_2( cond, code, msg, var1, var2 ) \
1094|    if ( ! (cond) )  throw( Except2_Std_newExcept2_cf( code, Errors_null, msg, var1, var2 ) );
1095|   #define  ASSERT2_3( cond, code, msg, var1, var2, var3 ) \
1096|    if ( ! (cond) )  throw( Except2_Std_newExcept2_cf \
1097|    ( code, Errors_null, msg, var1, var2, var3 ) );
1098|   #define  ASSERT2_4( cond, code, msg, var1, var2, var3, var4 ) \
1099|    if ( ! (cond) )  throw( Except2_Std_newExcept2_cf \
1100|    ( code, Errors_null, msg, var1, var2, var3, var4 ) );
1101|   #define  ASSERT2_5( cond, code, msg, var1, var2, var3, var4, var5 ) \
1102|    if ( ! (cond) )  throw( Except2_Std_newExcept2_cf \
1103|    ( code, Errors_null, msg, var1, var2, var3, var4, var5 ) );
1104|  #endif
1105| #else
1106|  #ifdef  ERRORS_ASSERT_REPORT
1107|   #define  ASSERT2_0( cond, code, msg ) \
1108|    if ( ! (cond) )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg);
1109|   #define  ASSERT2_1( cond, code, msg, var1 ) \
1110|    if ( ! (cond) )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1);
1111|   #define  ASSERT2_2( cond, code, msg, var1, var2 ) \
1112|    if ( ! (cond) )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1,var2);
1113|   #define  ASSERT2_3( cond, code, msg, var1, var2, var3 ) \
1114|    if ( ! (cond) )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1,var2,var3);
1115|   #define  ASSERT2_4( cond, code, msg, var1, var2, var3, var4 ) \
1116|    if ( ! (cond) )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1,var2,var3,var4);
1117|   #define  ASSERT2_5( cond, code, msg, var1, var2, var3, var4, var5 ) \
1118|    if ( ! (cond) )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1,var2,var3,var4,var5);
1119|  #else
1120|   #define  ASSERT2_0( cond, code, msg ) \
1121|    if ( ! (cond) )  Errors_error_imp(Errors_null,__LINE__,code,Errors_null,Errors_ns);
1122|   #define  ASSERT2_1( cond, code, msg, var1 ) \
1123|    if ( ! (cond) )  Errors_error_imp(Errors_null,__LINE__,code,Errors_null,Errors_ns);
1124|   #define  ASSERT2_2( cond, code, msg, var1, var2 ) \
1125|    if ( ! (cond) )  Errors_error_imp(Errors_null,__LINE__,code,Errors_null,Errors_ns);
1126|   #define  ASSERT2_3( cond, code, msg, var1, var2, var3 ) \
1127|    if ( ! (cond) )  Errors_error_imp(Errors_null,__LINE__,code,Errors_null,Errors_ns);
1128|   #define  ASSERT2_4( cond, code, msg, var1, var2, var3, var4 ) \
1129|    if ( ! (cond) )  Errors_error_imp(Errors_null,__LINE__,code,Errors_null,Errors_ns);
1130|   #define  ASSERT2_5( cond, code, msg, var1, var2, var3, var4, var5 ) \
1131|    if ( ! (cond) )  Errors_error_imp(Errors_null,__LINE__,code,Errors_null,Errors_ns);
1132|  #endif
1133| #endif
1134|#endif
1135|
1136|#endif
1137| 
1138|/**************************************************************************
1139|*  43. <<< [ERRORS_SWITCH_DEFAULT_ASSERT] switch 文の default ではアサートする >>> 
1140|*【例】
1141|*  swtich ( ) {
1142|*    case ... : ;
1143|*    ERRORS_SWITCH_DEFAULT_ASSERT;
1144|*  }
1145|***************************************************************************/
1146|#ifdef  NDEBUG
1147|  #define  ERRORS_SWITCH_DEFAULT_ASSERT
1148|#else
1149|  #define  ERRORS_SWITCH_DEFAULT_ASSERT   default: error(); break;
1150|#endif
1151| 
1152|/**************************************************************************
1153|*  44. <<< [ERRORS_NOT_SUPPORT, Errors_notSupport] 未サポートエラー >>> 
1154|*【引数】
1155|*  ・(なし)
1156|*【補足】
1157|*・ERRORS_NOT_SUPPORT は、デバッグ時のみ有効で、Errors_notSupport2 は
1158|*  りリース時も有効です。
1159|*・本関数の動きは、error2_0 と同じです。
1160|***************************************************************************/
1161|
1162|#ifdef  NDEBUG
1163|  #define  ERRORS_NOT_SUPPORT()
1164|#else
1165|  #define  ERRORS_NOT_SUPPORT()  Errors_notSupport()
1166|#endif
1167|
1168|#ifdef  FOR_QUICK_TEST
1169|  #define    Errors_notSupport() \
1170|    Errors_errPrintf( Errors_NorSupport_msgFmt, Errors_NorSupport_msg, __FILE__, __LINE__ )
1171|#else
1172|  #define    Errors_notSupport() \
1173|    error2_0( Errors_NotSupport, Errors_NorSupport_msg )
1174|#endif
1175|
1176|extern char*  Errors_NorSupport_msg;
1177|#ifdef  FOR_QUICK_TEST
1178|  extern char*  Errors_NorSupport_msgFmt;
1179|#endif
1180|
1181|
1182|
1183| 
1184|/**************************************************************************
1185|*  45. <<< [ERRORS_CHKRET, Errors_chkRet] エラー返り値チェック >>> 
1186|*【引数】
1187|*  ・int  cond;    正常条件
1188|*  ・int  code;    エラーコード
1189|*【補足】
1190|*・ERRORS_CHKRET は、デバッグ時のみ有効で、Errors_chkRet は
1191|*  りリース時も有効です。
1192|*・本関数の動きは、error2_0 と同じです。
1193|***************************************************************************/
1194|
1195|#ifdef  NDEBUG
1196|  #define  ERRORS_CHKRET( cond, code )
1197|#else
1198|  #define  ERRORS_CHKRET( cond, code ) \
1199|    ASSERT2_1( cond, Errors_ChkRet, Errors_ChkRet_msg, code )
1200|#endif
1201|
1202|#define    Errors_chkRet( cond, code ) \
1203|  if ( ! (cond) ) \
1204|    error2_1( Errors_ChkRet, Errors_ChkRet_msg, code );
1205|
1206|extern char*  Errors_ChkRet_msg;
1207|
1208|
1209| 
1210|/**************************************************************************
1211|*  46. <<< [Errors_autoChk] 自動チェック >>> 
1212|*  47. <<< [Errors_autoChk2, Errors_autoChkW] >>>
1213|*【機能】
1214|*・テストプログラムで自動チェックするとき、値の出力と自動チェックを
1215|*  同時に行うためのマクロです。
1216|*【引数】
1217|*  ・char*  format;  チェックする値を出力する printf 書式
1218|*  ・int    _var;    チェックする変数
1219|*  ・int    r_cond;  左辺の無い条件文(左辺は _var)
1220|*  ・int    _op;     両辺の無い条件文(左辺は _var1, 右辺は _var2)
1221|*  ・_declaration;   チェックする値の変数宣言
1222|*  ・int    _let;    チェックする値の代入文
1223|*  ・int    cond;    正常な条件文
1224|*【例】
1225|*・Errors_autoChk( "%d", ArrX_getN( arr ), == 1 );
1226|*  上の出力 ... "ArrX_getN( arr ) = 1"
1227|*・Errors_autoChk2( "%d", int x, x = ArrX_getN( arr ), x >= 1 && x <= 5 );
1228|*  上の出力 ... "x = ArrX_getN( arr ) : 1"
1229|*・Errors_autoChkW( "%d", x, ==, y );
1230|*  上の出力 ... "(x = 1) == (y = 1)"
1231|***************************************************************************/
1232|#define  Errors_autoChk( format, _var, r_cond ) \
1233|  { \
1234|    Errors_printf_release( "%s = " format, #_var, _var ); \
1235|    if ( !( (_var) r_cond ) )  error(); \
1236|  }
1237|
1238|#define  Errors_autoChk2( format, _declaration, _let, cond ) \
1239|  { \
1240|    _declaration; \
1241|    Errors_printf_release( "%s : " format, #_let, _let ); \
1242|    if ( !(cond) )  error(); \
1243|  }
1244|
1245|#define  Errors_autoChkW( format, _var1, _op, _var2 ) \
1246|  { \
1247|    Errors_printf_release( "(%s = " format ") %s (%s = " format ")", \
1248|      #_var1, _var1, #_op, #_var2, _var2 ); \
1249|    if ( !( (_var1) _op (_var2) ) )  error(); \
1250|  }
1251|
1252| 
1253|/**************************************************************************
1254|*  48. <<< [ERRORS_SINGLETON_FOR_INIT] singleton チェックコード >>> 
1255|*【引数】
1256|*  ・void**  chker;   チェック用ワーク領域(void*型)のアドレス(→補足)
1257|*  ・        this;    オブジェクトのアドレス
1258|*【補足】
1259|*・chker は、クラスに1つグローバル領域に  void* 型変数を用意してください。
1260|*  これらのマクロのより前(ファイルの上)の方でグローバル変数を宣言してください。
1261|***************************************************************************/
1262|#ifndef NDEBUG
1263|  #define  ERRORS_SINGLETON_FOR_INIT( chker, this ) \
1264|    { ASSERT( *(chker) == NULL );  *(chker) = this; }
1265|#else
1266|  #define  ERRORS_SINGLETON_FOR_INIT( chker, this )
1267|#endif
1268|
1269|
1270| 
1271|/**************************************************************************
1272|*  49. <<< [ERRORS_SINGLETON_FOR_FINISH] singleton チェックコード >>> 
1273|***************************************************************************/
1274|#define  ERRORS_SINGLETON_FOR_FINISH( chker, this ) \
1275|   { ASSERT( *(chker) == NULL || *(chker) == this );  *(chker) = NULL; }
1276|
1277|
1278| 
1279|/***********************************************************************
1280|*  50. <<< [ERRORS_VERSION] バージョン情報を埋め込む >>> 
1281|*【補足】
1282|*・ソースファイルのバージョン情報を文字列ポインタ型のグローバル変数として
1283|*  定義します。
1284|*・変数名は name_version になります。ただし、name は本マクロの引数で指定
1285|*  したものになります。
1286|*・ソースファイルのグローバル領域に記述してください。
1287|*【例】
1288|*  ERRORS_VERSION( errors, 3.2 );
1289|************************************************************************/
1290|#define  ERRORS_VERSION( module_name, number ) \
1291|  char*  module_name##_version = "ver" #number "(" __DATE__ " " __TIME__ ")"
1292| 
1293|/***********************************************************************
1294|*  51. <<< [Errors_setErrorHandler] エラー処理関数を登録する >>> 
1295|*  52. <<< [Errors_Handler] エラー処理関数型 >>>
1296|*【補足】
1297|*・通常の処理で十分であれば、Errors_stdErrHandler を登録します。
1298|************************************************************************/
1299|/* Errors_Handler の実装は、優先ヘッダに入っています */
1300|
1301|#ifdef  USES_EXCEPT2
1302|  #define  Errors_setErrorHandler( hdl ) \
1303|    Except2_Sys_setErrorHandler(hdl)
1304|#else
1305|  #define  Errors_setErrorHandler( hdl ) \
1306|    Errors_hdl = (hdl)
1307|#endif
1308|
1309|enum { ERRORS_IGNORE, ERRORS_EXIT };
1310|
1311|
1312|/* 内部用 */
1313|#ifndef  USES_EXCEPT2
1314|  extern  Errors_Handler   Errors_hdl;  /* エラーハンドラのアドレス */
1315|#endif
1316|
1317| 
1318|/**********************************************************************
1319|  53. <<< [ERRORS_FINISHCHK_FOR_INIT] 後始末チェック・初期化関数内記述用 >>> 
1320|  54. <<< [ERRORS_FINISHCHK_FOR_FINISH] 後始末チェック・後始末関数内記述用 >>>
1321|  55. <<< [ERRORS_FINISHCHK] 後始末チェックを開始する >>>
1322|  56. <<< [Errors_FinishChk_print] 後始末状態を表示する >>>
1323|【引数】
1324|  ・_finish   後始末関数
1325|【補足】
1326|・クラスの初期化関数に次のように記述します。
1327|  ERRORS_FINISHCHK_FOR_INIT( _finish );
1328|・クラスの後始末関数に次のように記述します。
1329|  ERRORS_FINISHCHK_FOR_FINISH( _finish );
1330|・プログラムが終了する直前に次のように記述します。
1331|  ERRORS_FINISHCHK();
1332|***********************************************************************/
1333|#if  defined(USES_ARRX) && defined(USES_OFFSET)
1334|
1335| #ifdef  NDEBUG
1336|  #define  ERRORS_FINISHCHK_FOR_INIT( _finish )
1337|  #define  ERRORS_FINISHCHK_FOR_FINISH( _finish )
1338|  #define  ERRORS_FINISHCHK()
1339|  #define  Errors_FinishChk_printAll  __cut_debug_tool
1340|  #define  Errors_FinishChk_print  __cut_debug_tool
1341| #else
1342|  #define  ERRORS_FINISHCHK_FOR_INIT( _finish ) \
1343|    Errors_FinishChk_count( (void (*)())(_finish), #_finish, +1 )
1344|  #define  ERRORS_FINISHCHK_FOR_FINISH( _finish ) \
1345|    Errors_FinishChk_count( (void (*)())(_finish), #_finish, -1 )
1346|  #define  ERRORS_FINISHCHK() \
1347|    Errors_FinishChk_imp()
1348|  #define  Errors_FinishChk_print( _finish ) \
1349|    Errors_FinishChk_print_imp( #_finish, __FILE__, __LINE__ )
1350| #endif
1351|
1352|#else  /* USES_ARRX && USES_OFFSET */
1353|
1354| #define  ERRORS_FINISHCHK_FOR_INIT( _finish )
1355| #define  ERRORS_FINISHCHK_FOR_FINISH( _finish )
1356| #define  ERRORS_FINISHCHK_PRINT()
1357| #define  ERRORS_FINISHCHK()
1358|
1359|#endif  /* USES_ARRX && USES_OFFSET */
1360|
1361|
1362| 
1363|/***************************************************************************
1364|  57. <<< [ERRORS_FINISHCHK_INSPECT_FOR_INIT] 後始末を忘れたオブジェクトを調査する >>> 
1365|  58. <<< [ERRORS_FINISHCHK_INSPECT_FOR_FINISH] 後始末を忘れたオブジェクトを調査する >>>
1366|【補足】
1367|・後始末を忘れたオブジェクトのクラスの初期化関数に次のように記述します。
1368|  ERRORS_FINISHCHK_INSPECT_FOR_INIT( this, _finish );
1369|    this はオブジェクトのアドレス, _finish は、後始末関数
1370|・後始末を忘れたオブジェクトのクラスの後始末関数に次のように記述します。
1371|  ERRORS_FINISHCHK_INSPECT_FOR_FINISH( this, _finish );
1372|****************************************************************************/
1373|#if  defined(USES_ARRX) && defined(USES_OFFSET)
1374|
1375|#ifdef  ERRORS_CUT_DEBUG_TOOL
1376|  #define  ERRORS_FINISHCHK_INSPECT_FOR_INIT    __cut_debug_tool
1377|  #define  ERRORS_FINISHCHK_INSPECT_FOR_FINISH  __cut_debug_tool
1378|#else
1379|  #define  ERRORS_FINISHCHK_INSPECT_FOR_INIT( this, _finish ) \
1380|    ( Errors_FinishChk_count( (void (*)())(_finish), #_finish, +1 ), \
1381|      Errors_FinishChk_Inspect_forInit_imp( this, _finish, #_finish ) )
1382|  #define  ERRORS_FINISHCHK_INSPECT_FOR_FINISH( this, _finish ) \
1383|    ( Errors_FinishChk_count( (void (*)())(_finish), #_finish, -1 ), \
1384|      Errors_FinishChk_Inspect_forFinish_imp( this, _finish, #_finish ) )
1385|#endif
1386|
1387|#endif
1388| 
1389|/***********************************************************************
1390|*  59. <<< [Errors_setStart] テストを開始するテスト番号を設定する >>> 
1391|*【補足】
1392|*・FOR_QUICK_TEST が #define されていると、r6 への指定に関わらず、
1393|*  テスト番号1を設定しようとします。
1394|************************************************************************/
1395|#ifdef  FOR_QUICK_TEST
1396|  #define  Errors_setStart( r6, r7 ) \
1397|    Errors_setStart_imp( 1, r7 )
1398|#else
1399|  #define  Errors_setStart( r6, r7 ) \
1400|    Errors_setStart_imp( r6, r7 )
1401|#endif
1402| 
1403|/*-------------------------------------------------------------------------*/
1404|/* 60. <<< ◆初期化チェッカ (ERRORS_INITCHK) >>> */ 
1405|/*-------------------------------------------------------------------------*/
1406|
1407|
1408| 
1409|/**********************************************************************
1410|*  61. <<< [ERRORS_INITCHK, ERRORS_INITCHK_FOR_SUB] 初期化チェック >>> 
1411|*【引数】
1412|*  ・void*  this;   構造体のアドレス
1413|*  ・int    order;  手続きオーダー
1414|*【補足】
1415|*・参照:Errors_InitChk 初期化チェック概要
1416|**********************************************************************/
1417|#ifndef NDEBUG
1418|  #define  ERRORS_INITCHK( this, order ) \
1419|    Errors_InitChk_imp( (this), &(this)->__initchk, order, __FILE__, __LINE__, 1 )
1420|#else
1421|  #define  ERRORS_INITCHK( this, order )
1422|#endif
1423|
1424|#ifndef NDEBUG
1425|  #define  ERRORS_INITCHK_FOR_SUB( this, order ) \
1426|    Errors_InitChk_imp( (this), &(this)->__initchk, order, __FILE__, __LINE__, 0 )
1427|#else
1428|  #define  ERRORS_INITCHK_FOR_SUB( this, order )
1429|#endif
1430|
1431|
1432| 
1433|/**********************************************************************
1434|*  62. <<< [Errors_InitChk_print] 初期化チェックのデバッグ表示 >>> 
1435|*【引数】
1436|*  ・void*  this;   構造体のアドレス
1437|*  ・int    order;  手続きオーダー
1438|*【補足】
1439|*・参照:Errors_InitChk 初期化チェック概要
1440|**********************************************************************/
1441|#if defined(ERRORS_CUT_DEBUG_TOOL) || defined(NDEBUG)
1442|  #define  Errors_InitChk_print( this, order ) \
1443|    _cut_InitChk_print  /* Syntax Error */
1444|#else
1445|  #define  Errors_InitChk_print( this, order ) \
1446|    Errors_InitChk_print_imp( &(this)->__initchk, (order) )
1447|#endif
1448|
1449|
1450| 
1451|/**********************************************************************
1452|*  63. <<< [ERRORS_INITCHK_MAGIC] 初期化チェック用の暗号化 >>> 
1453|*【補足】
1454|*・ERRORS_INITCHK_VAR を含む構造体を a とすると、
1455|*  a.__initchk.var = ERRORS_INITCHK_MAGIC( &a.__initchk,
1456|*         a.__initchk.order, a.__initchk.key, a.__initchk.count );
1457|*【内部補足】
1458|*・this ポインタを int 型にキャストして乗算すると、
1459|*  初期化指定でエラーになるので、改良する際、注意してください。
1460|**********************************************************************/
1461|#define  ERRORS_INITCHK_MAGIC( this, order, key, count ) \
1462|  ( (int)(this) + ((order)+1) + (key) * (count) )
1463|
1464|
1465| 
1466|/**********************************************************************
1467|*  64. <<< [ERRORS_INITCHK_CANCELER] 初期化済みデータ用・暗号値 >>> 
1468|*【補足】
1469|*・初期化済みのデータの ERRORS_INITCHK_VAR に相当する場所に
1470|*  置きます。
1471|**********************************************************************/
1472|#ifndef  NDEBUG
1473|  #define  ERRORS_INITCHK_CANCELER \
1474|    0, 0, 0, ERRORS_INITCHK_CANCELER_NUM
1475|#else
1476|  #define  ERRORS_INITCHK_CANCELER
1477|#endif
1478|
1479|
1480| 
1481|/**********************************************************************
1482|*  65. <<< [ERRORS_INITCHK_CANCELER_NUM] 初期化済みデータ用・暗号値(2) >>> 
1483|*【補足】
1484|*・内部用です
1485|*【内部補足】
1486|*・ERRORS_INITCHK_CANCELER を参照
1487|**********************************************************************/
1488|#define  ERRORS_INITCHK_CANCELER_NUM    0x19743509
1489|
1490|
1491| 
1492|/**********************************************************************
1493|*  66. <<< [Errors_InitChk_getOrder] 初期化したかどうか(手続きオーダー)を返す >>> 
1494|*【引数】
1495|*  ・void*  this;   構造体のアドレス
1496|*  ・int  返り値;   初期化したかどうか(手続きオーダー) -1=未初期化
1497|*【補足】
1498|*・ERRORS_INITCHK( this, 0 ) で初期化した直後では、本マクロは 0 を
1499|*  返します。初期化していないときは -1 を返します。
1500|*・リリースバージョンでは 99 を返します。
1501|**********************************************************************/
1502|#ifdef  NDEBUG
1503|  #define  Errors_InitChk_getOrder( this )   99
1504|#else
1505|#define  Errors_InitChk_getOrder( this ) \
1506| ( ( (this)->__initchk.var == ERRORS_INITCHK_MAGIC( &(this)->__initchk, \
1507|     (this)->__initchk.order, (this)->__initchk.key, (this)->__initchk.count ) ) \
1508|  ? ( (this)->__initchk.order ) : -1 )
1509|#endif
1510|
1511| 
1512|/*-------------------------------------------------------------------------*/
1513|/* 67. <<< ◆デバッグツール >>> */ 
1514|/*-------------------------------------------------------------------------*/
1515|
1516|
1517| 
1518|/**************************************************************************
1519|  68. <<< デバッグツール MARK, COUNT, BK, WD, WS, WP, WF >>> 
1520|【補足】
1521|・標準的なデバッグの方法を示します。
1522|・1.エラーが発生する入力条件やモジュール構成を簡単にする。
1523|・2.エラー値を確認して、それが ASSERT されるかエラーになるようにする。
1524|・3.関数コールスタックを見ることができない環境では、MARK マクロを使って、
1525|  エラーが発生するソースの位置をトップダウンに特定していく。
1526|・4.CONUT マクロを使って、エラーが発生するタイミングを特定する。
1527|・5.WD,WS,WP,WF マクロや Errors_printf などを使って変数値を確認する。
1528|・6.異常な変数値にする入力値を追跡する。
1529|***************************************************************************/
1530|
1531| 
1532|/**************************************************************************
1533|  69. <<< [MARK, MARK2, MARK3, BACKMARK] プロセッサが通過したら表示する >>> 
1534|【補足】
1535|・デバッグ時にエラーが発生したソースの位置を特定するときに使用します。
1536|・MARK2 は、Windows 専用で、ダイアログボックスを表示します。
1537|・MARK3 は、高速リアルタイム用で、Errors_Line に行番号を入れます。
1538|  Visual Studio の場合、プロジェクトの設定で MAP ファイルを生成する
1539|  ようにしてから、MARK3 を記述し、実行ファイルを作成します。
1540|  例外が発生したら、メモリウィンドウを表示して、
1541|  _Errors_Line シンボルのメモリアドレスにジャンプして、
1542|  変数の値を確認します。
1543|  _Errors_Line シンボルのメモリアドレスは、
1544|  MAP ファイルの中を検索して調べることができます。
1545|・MARK4 は、引数を持ち、LED に表示します。
1546|・BACKMARK は、リリースビルドしたものに埋め込むものです。
1547|  使用するときは、ERRORS_USE_BACKMARK を #define します。
1548|  実行ファイルと同じフォルダにできる errlog.txt ファイルにのみ出力できます。
1549|  printf したいときは、Errors_printf_back を使用します。
1550|***************************************************************************/
1551|#ifdef  ERRORS_CUT_DEBUG_TOOL
1552|  #define  MARK()   __cut_debug_tool
1553|  #define  MARK2()  __cut_debug_tool
1554|  #define  MARK3()  __cut_debug_tool
1555|  #define  MARK4()  __cut_debug_tool
1556|#else
1557|  #define  MARK()   ( Errors_Line = __LINE__, Errors_printf( "MARK : (%d) %s", __LINE__, __FILE__ ) )
1558|  #define  MARK2()  ( Errors_Line = __LINE__, Errors_printf_release( "MARK : (%d) %s", __LINE__, __FILE__ ) )
1559|  #define  MARK3()  ( Errors_Line = __LINE__ )
1560|  /* MARK4 のインプリメントは、各種プラットフォームを参照 */
1561|#endif
1562|
1563|#ifdef  ERRORS_USE_BACKMARK
1564|  #define  BACKMARK()  Errors_backmark_imp( __FILE__, __LINE__ )
1565|#elif  defined(ERRORS_CUT_BACKMARK)
1566|  #define  BACKMARK()  __cut_debug_tool
1567|#else
1568|  #define  BACKMARK()
1569|#endif
1570| 
1571|/**************************************************************************
1572|  70. <<< [COUNT] プロセッサが通過した回数を数える、通過回数で分岐する >>> 
1573|  71. <<< [COUNT2] COUNT に達した後で更に内部のループで回数を数える >>>
1574|  72. <<< [COUNT_LOCAL] 通った回数をデバッグ表示する(COUNT, COUNT2 と競合しない) >>>
1575|  73. <<< [IFCOUNT] COUNT, COUNT2 で指定のカウント値になり、IFC が真かどうかの分岐 >>>
1576|  74. <<< [IFCOUNT1] COUNT のみで指定のカウント値になったかどうかの分岐 >>>
1577|  75. <<< [IFCOUNT2] COUNT COUNT2 で指定のカウント値になったかどうかの分岐 >>>
1578|  76. <<< [BK] ソースデバッガ用ブレークポイント設定可能位置 >>>
1579|  77. <<< [BKK] ブレークポイント(パラメータ付き) >>>
1580|【補足】
1581|・エラーが発生するタイミングを特定するときに使用します。
1582|・本マクロをとおるたびに Errors_count グローバル変数がプラス1されます。
1583|  WD BP マクロは、COUNT で指定した値以上になったときのみ機能します。
1584|・1.引数 n を 0 にしてプロセッサが通過する回数を調べます。
1585|    COUNT(0);
1586|  通過するたびにカウント値を出力します(Errors_printfによる)。
1587|  出力したくないときは、COUNT(-1); と指定します。
1588|  通過回数はエラーメッセージに表示されます。
1589|  (または、Errors_count グローバル変数を参照します)
1590|・2.次のように記述して変数値を確認します。
1591|    COUNT(120) { WD(x); WF(f); }
1592|  COUNT マクロの後の中括弧は、プロセッサの通過回数が引数に指定した値に
1593|  なったときに実行します。
1594|  COUNT より前の WD BP で出力したくないときは、main 関数の最初で
1595|  Errors_count0 = -1 と記述します。
1596|・IFCOUNT は、次のように記述します。
1597|    IFCOUNT {  カウントが COUNT の引数値に達したときの処理  }
1598|・BKK に指定した値は、bf 関数の第2引数に渡ってきます。
1599|***************************************************************************/
1600|#ifdef  ERRORS_CUT_DEBUG_TOOL
1601|  #define  COUNT(n)  __cut_debug_tool
1602|  #define  COUNT2(n)  __cut_debug_tool
1603|  #define  COUNT_LOCAL(n)  __cut_debug_tool
1604|  #define  IFCOUNT   __cut_debug_tool
1605|  #define  BK        __cut_debug_tool
1606|  #define  BKK       __cut_debug_tool
1607|#else
1608|  #define  COUNT(n) \
1609|    if ( Errors_count_prev_n == 0 ) { \
1610|      Errors_count_prev_n_file = __FILE__; \
1611|      Errors_count_prev_n_line = __LINE__; \
1612|      Errors_count_prev_n = (n); \
1613|    } \
1614|    if ( Errors_count_prev_n != (n) ) \
1615|      error2_2( Errors_Err_DoubleCount, "COUNT が2ヶ所で定義されています %s(%d)", \
1616|        Errors_count_prev_n_file, Errors_count_prev_n_line ); \
1617|    Errors_count0 = (n); \
1618|    Errors_count ++; \
1619|    IFCOUNT1 \
1620|      Errors_printf( "COUNT = %d in %s(%d)", Errors_count, __FILE__, __LINE__ ); \
1621|    IFCOUNT1
1622|
1623|  #define  COUNT2(n) \
1624|    IFCOUNT1 \
1625|      if ( Errors_count2_prev_n == 0 ) { \
1626|        Errors_count2_prev_n_file = __FILE__; \
1627|        Errors_count2_prev_n_line = __LINE__; \
1628|        Errors_count2_prev_n = (n); \
1629|      } \
1630|      if ( Errors_count2_prev_n != (n) ) \
1631|        error2_2( Errors_Err_DoubleCount, "COUNT2 が2ヶ所で定義されています %s(%d)", \
1632|          Errors_count2_prev_n_file, Errors_count2_prev_n_line ); \
1633|      Errors_count2_0 = (n); \
1634|      Errors_count2 ++; \
1635|      IFCOUNT \
1636|        Errors_printf( "COUNT2 = %d in %s(%d)", Errors_count2, __FILE__, __LINE__ ); \
1637|      IFCOUNT
1638|
1639|  #define  COUNT_LOCAL( n ) \
1640|  { static int c = 0;  c++; \
1641|    if ( c >= n )  Errors_printf( "COUNT_LOCAL = %d in %s(%d)", c, __FILE__, __LINE__ ); \
1642|  }
1643|
1644|  #define  IFCOUNT \
1645|    if ( Errors_count >= Errors_count0 && Errors_count0 != -1 && \
1646|         Errors_count2 >= Errors_count2_0 && Errors_count2_0 != -1 && \
1647|         Errors_count_b && Errors_count_b2 )
1648|
1649|  #define  IFCOUNT1 \
1650|    if ( Errors_count >= Errors_count0 && Errors_count0 != -1 )
1651|
1652|  #define  IFCOUNT2 \
1653|    if ( Errors_count >= Errors_count0 && Errors_count0 != -1 && \
1654|         Errors_count2 >= Errors_count2_0 && Errors_count2_0 != -1 )
1655|
1656|  #if defined(FOR_DOS32)
1657|    #define  BK  {int i=0;}
1658|  #else
1659|    #define  BK  {bf(0xBBBBBBBB, 0, (int)__FILE__, __LINE__);}
1660|  #endif
1661|  #define  BKK  Errors_break
1662|
1663|#endif
1664|
1665|
1666| 
1667|/**************************************************************************
1668|  78. <<< [WD,WD0,WS,WSP,WSP0,WP,WP0,WF] 変数値を表示する >>> 
1669|【補足】
1670|・すべて Errors_count が Errors_count0 以上のときにのみ表示します。
1671|・WD は整数用、WS は文字列用、WSP は文字列ポインタ用、WP は16進数整数
1672|  (メモリアドレス)用、WF は浮動小数用、WX, WX2 はメモリダンプ用です。
1673|・WD0 など 0 の付くものは、引数に変数でないもの(例:式)を指定できます。
1674|・WX WX2 では表示方法が異なります。WX では常に行頭からデータを表示し、
1675|  WX2 では常にアドレスの1の位が0のデータから行を表示します。
1676|・内部で Errors_printf を用いています。
1677|***************************************************************************/
1678|#ifdef  ERRORS_CUT_DEBUG_TOOL
1679|  #define  WD(x)    __cut_debug_tool
1680|  #define  WD0(x)   __cut_debug_tool
1681|  #define  WS(x)    __cut_debug_tool
1682|  #define  WS0(x)   __cut_debug_tool
1683|  #define  WSP(x)   __cut_debug_tool
1684|  #define  WSP0(x)  __cut_debug_tool
1685|  #define  WP(x)    __cut_debug_tool
1686|  #define  WP0(x)   __cut_debug_tool
1687|  #define  WPP(x)   __cut_debug_tool
1688|  #define  WF(x)    __cut_debug_tool
1689|  #define  WF0(x)   __cut_debug_tool
1690|  #define  WX( adr, size )   __cut_debug_tool
1691|  #define  WX0( adr, size )  __cut_debug_tool
1692|  #define  WX2( adr, size )  __cut_debug_tool
1693|#else
1694|  #define  WD(x)    IFCOUNT  Errors_WD_imp( #x, &(x), (int)(x), __FILE__, __LINE__ )
1695|  #define  WD0(x)   IFCOUNT  Errors_WD_imp( #x, NULL, (int)(x), __FILE__, __LINE__ )
1696|  #define  WS(x)    IFCOUNT  Errors_printf( "%s (%p) = \"%s\" : %s(%d)", #x, &(x), (char*)(x), __FILE__, __LINE__ )
1697|  #define  WS0      WS
1698|  #define  WSP(x)   IFCOUNT  Errors_WSP_imp( #x, &(x), x, __FILE__, __LINE__ )
1699|  #define  WSP0(x)  IFCOUNT  Errors_WSP_imp( #x, NULL, x, __FILE__, __LINE__ )
1700|  #define  WP(x)    IFCOUNT  Errors_printf( "%s (%p) = %p : %s(%d)", #x, &(x), (void*)(x), __FILE__, __LINE__ )
1701|  #define  WP0(x)   IFCOUNT  Errors_printf( "%s = %p : %s(%d)", #x, (void*)(x), __FILE__, __LINE__ )
1702|  #define  WPP(x)   IFCOUNT  Errors_printf( "%s = %p *(%08X) : %s(%d)", #x, x, *(int*)x, __FILE__, __LINE__ )
1703|  #define  WF(x)    IFCOUNT  Errors_printf( "%s (%p) = %f : %s(%d)", #x, &(x), x, __FILE__, __LINE__ )
1704|  #define  WF0(x)   IFCOUNT  Errors_printf( "%s (%p) = %f : %s(%d)", #x, NULL, x, __FILE__, __LINE__ )
1705|  #define  WX( adr, size )   IFCOUNT  Errors_WX_imp( #adr, (void*)(adr), size, __FILE__, __LINE__ );
1706|  #define  WX0  WX
1707|  #define  WX2( adr, size )  IFCOUNT  Errors_WX2_imp( #adr, (void*)(adr), size, __FILE__, __LINE__ );
1708|#endif
1709|
1710|
1711| 
1712|/**************************************************************************
1713|  79. <<< [WATCH, setWATCH, setWD, setWS] 値の変化する位置を特定するデバッグツール >>> 
1714|【引数】
1715|  ・x;           ウォッチしつづける変数
1716|  ・void*  adr;  ウォッチしつづけるアドレス
1717|  ・int   size;         ウォッチしつづけるメモリサイズ(バイト)
1718|  ・bool  lookAtCount;  Errors_count が Errors_count0 以上のときにのみチェックするか
1719|【補足】
1720|・WATCH を呼び出す前に setWATCH, setWD などでウォッチしつづける
1721|  変数(アドレス)を設定します。
1722|・値が変化するであろう位置に WATCH の呼び出しを散りばめます。
1723|・WATCH は、内容が変化したときに "WATCH!★" を出力します。
1724|・WATCH は、Errors_count が Errors_count0 以上のときにのみ表示します。
1725|・内部で Errors_printf を用いています。
1726|・変数が有効であればスコープ外であっても参照することができます。
1727|・プログラムを変更するとアドレスが変化してしまうときは、次の手順で実行します。
1728|   1. setWATCH の adr に NULL を指定
1729|   2. WATCH を記述
1730|   3. プログラムを実行してウォッチするアドレスを確認
1731|   4. Errors_setWATCH_imp にブレークをつけて最初から再実行し、
1732|      ブレーク中に adr 引数(第一引数)の値を変更する
1733|***************************************************************************/
1734|#ifdef  ERRORS_CUT_DEBUG_TOOL
1735|  #define  WATCH()                             __cut_debug_tool
1736|  #define  setWATCH( adr, size, lookAtCount )  __cut_debug_tool
1737|#else
1738|  #define  WATCH() \
1739|     IFCOUNT  Errors_WATCH_imp( __FILE__, __LINE__ ); \
1740|     else if ( ! Errors_bWatchLookAtCount )  Errors_WATCH_imp( __FILE__, __LINE__ )
1741|  #define  setWATCH( adr, size, lookAtCount ) \
1742|    Errors_setWATCH_imp( adr, #adr, Errors_WATCH_Bin, size, lookAtCount, __FILE__, __LINE__ )
1743|  #define  setWD(x) \
1744|    __not_implemented
1745|  #define  setWS(x) \
1746|    __not_implemented
1747|#endif
1748|
1749|#define  Errors_WATCH_Bin    0
1750|#define  Errors_WATCH_Int    1   /* future */
1751|#define  Errors_WATCH_CharP  2   /* future */
1752|
1753| 
1754|/**************************************************************************
1755|  80. <<< [IFC, IFC2, IFS, IFS2] 条件が一致したら各デバッグ機能を有効にする >>> 
1756|【引数】
1757|  ・bool   cond;    条件式
1758|  ・char*  s;       比較対象となる文字列
1759|  ・char*  kword;   s に含まれると一致したとみなす文字列
1760|【補足】
1761|・条件が一致したら、Errors_count0 を Errors_count に設定して各デバッグ機能を
1762|  有効にします。
1763|・s に kword が含まれていたら一致したとします。(strstr 使用)
1764|・COUNT マクロと同様に、IFC, IFS に続けて一致したときの処理を記述できます。
1765|・IFS2 は、IFS, IFC が真だったときのみ機能します。
1766|・IFC, IFS, IFS2 のいずれかが偽であったら、IFCOUNT は偽になり、
1767|  WD などのデバッグツールは動きません。
1768|・はじめに IFC(false) として、IFCOUNT が偽になるようにしてから始めてください。
1769|【例】
1770|  IFS( s, "key" ) {
1771|    Errors_print( "aaa" );   // 一致したときに実行する
1772|  }
1773|***************************************************************************/
1774|#ifdef  ERRORS_CUT_DEBUG_TOOL
1775| #define  IFC( cond )        __cut_debug_tool
1776| #define  IFC2( cond )       __cut_debug_tool
1777| #define  IFS( s, kword )    __cut_debug_tool
1778| #define  IFS2( s, kword )   __cut_debug_tool
1779|#else
1780| #define  IFC( cond ) \
1781|   Errors_count_b = ( cond ); \
1782|   if ( Errors_count_b )
1783|
1784| #define  IFC2( cond ) \
1785|   if ( Errors_count_b ) \
1786|     Errors_count_b2 = ( cond ); \
1787|   if ( Errors_count_b && Errors_count_b2 )
1788|
1789| #define  IFS( s, kword ) \
1790|   IFC ( strstr( s, kword ) != NULL )
1791|
1792| #define  IFS2( s, kword ) \
1793|   IFC2 ( strstr( s, kword ) != NULL )
1794|
1795|#endif
1796| 
1797|/**************************************************************************
1798|  81. <<< [Errors_printf, Errors_printf_back] デバッグ情報を表示する >>> 
1799|【補足】
1800|・関数 bf にブレークポイントをつけると、エラーログがあふれたときに
1801|  ブレークします。
1802|・メイン関数の始めで、char*  Errors_appName と char* Errors_appVersion に
1803|  アプリケーション名とバージョン(文字列)を設定してください。
1804|・Windows では、HWND  Errors_parentWnd; グローバル変数に設定したウィンドウ
1805|  を親ウィンドウとしてメッセージボックスを表示します。
1806|・MFC では、Errors_parentWnd のほかに Errors_parentCWnd を CWnd* 型に
1807|  キャストして設定してください。
1808|・Errors_printf_back は、BACKMARK と同じ動作をする Errors_printf です。
1809|***************************************************************************/
1810|#ifdef  ERRORS_CUT_DEBUG_TOOL
1811|  #define  Errors_printf   __cut_debug_tool  /* Syntax Error */
1812|#else
1813|  #define  Errors_printf   Errors_printf_imp
1814|#endif
1815|
1816|#ifdef  ERRORS_USE_BACKMARK
1817|  #define  Errors_printf_back  Errors_printf_back_imp
1818|#elif  defined(ERRORS_CUT_BACKMARK)
1819|  #define  Errors_printf_back  __cut_debug_tool
1820|#else
1821|  #define  Errors_printf_back
1822|#endif
1823| 
1824|/***************************************************************************
1825|  82. <<< [Errors_setPrintfFlag] 表示フラグを設定する >>> 
1826|【機能】
1827|・すべての Errors_printf を有効にしたり無効にしたりします。
1828|【引数】
1829|  ・bool  pf;   有効かどうか
1830|****************************************************************************/
1831|#ifdef  ERRORS_CUT_DEBUG_TOOL
1832|  #define  Errors_setPrintfFlag(pf)   cut_setprintf_of_debug_tool  /* Syntax Error */
1833|#else
1834|  #ifdef  FOR_WINCE
1835|    #define  Errors_setPrintfFlag(pf)  Errors_setPrintfFlag_imp(pf)
1836|  #else
1837|    #define  Errors_setPrintfFlag(pf)  (Errors_printfFlag = (pf))
1838|  #endif
1839|#endif
1840|
1841|extern  bool  Errors_printfFlag;
1842|
1843|#if  !defined(ERRORS_CUT_DEBUG_TOOL) && defined(__cplusplus) && defined(FOR_WINCE)
1844|  void  Errors_setPrintfFlag( int );
1845|#endif
1846| 
1847|/**************************************************************************
1848|  83. <<< [_ERRORS_PRINTF_FLUSH] エラーメッセージのログを出力する >>> 
1849|【補足】
1850|・リリースバージョンでは、この関数を無効にします。
1851|***************************************************************************/
1852|/*#ifdef ERRORS_CUT_DEBUG_TOOL*/
1853|  #define  ERRORS_PRINTF_FLUSH()   /* do nothing */
1854|/*#endif*/
1855|
1856|
1857| 
1858|/**************************************************************************
1859|  84. <<< [Errors_counter] カウンタ >>> 
1860|***************************************************************************/
1861|#ifdef  ERRORS_CUT_DEBUG_TOOL
1862|  #define  Errors_counter   cut_counter_of_debug_tool   /* Syntax Error */
1863|#else
1864|  #define  Errors_counter   Errors_counter_imp
1865|#endif
1866|
1867|
1868|
1869| 
1870|/**************************************************************************
1871|  85. <<< [Errors_startPool, Errors_endPool, Errors_endAllPool, Errors_clearPool] >>> 
1872|【補足】
1873|・Errors_startPool_release のように 末尾に _release が付いたものと異なり、
1874|  Errors_startPool などは、デバッグ用です。
1875|***************************************************************************/
1876|#if  defined(ERRORS_CUT_DEBUG_TOOL)
1877| #define  Errors_startPool   __cut_debug_tool
1878| #define  Errors_endPool     __cut_debug_tool
1879| #define  Errors_endAllPool  __cut_debug_tool
1880| #define  Errors_clearPool   __cut_debug_tool
1881|#else
1882| #define  Errors_startPool   Errors_startPool_release
1883| #define  Errors_endPool     Errors_endPool_release
1884| #define  Errors_endAllPool  Errors_endAllPool_release
1885| #define  Errors_clearPool   Errors_clearPool_release
1886|#endif
1887|
1888| 
1889|/**************************************************************************
1890|  86. <<< [BP, Errors_break, Errors_break_release] ブレークポイント >>> 
1891|【引数】
1892|  ・int  var;  デバッグ用に表示する値
1893|【補足】
1894|・BP は Errors_count が Errors_count0 以上のときに止まります。
1895|・var は、簡易的に値を確認するのに用います。通常は、Errors_printf を
1896|  用います。
1897|・デバッガでは、bf 関数にブレークポイントを付けてください。
1898|  MS-DevStudio 環境では、この関数を使わないでブレークポイント機能で
1899|  かまいません。
1900|・Errors_break_release は、テストプログラムで手動テストを行うときに
1901|  ブレークを書けるときに使用します。
1902|***************************************************************************/
1903|#ifdef  ERRORS_CUT_DEBUG_TOOL
1904|  #define  BP()               cut_breakpoint_of_debug_tool  /* Syntax Error */
1905|  #define  Errors_break(var)  cut_breakpoint_of_debug_tool  /* Syntax Error */
1906|#else
1907|  #define  BP()  IFCOUNT  Errors_break(0)
1908|  #define  Errors_break(var)  \
1909|    Errors_break_imp( 0xBBBBBBBB, var, (int)__FILE__,__LINE__);
1910|#endif
1911|
1912|#define  Errors_break_release(var)  \
1913|  Errors_break_imp( 0xBBBBBBBB, var, (int)__FILE__,__LINE__);
1914|
1915|
1916|extern  int  Errors_nextBreakCount;
1917|extern  int  Errors_breakCount;
1918| 
1919|/**************************************************************************
1920|  87. <<< [Errors_break_asm] アセンブラ・ブレークポイント >>> 
1921|【引数】
1922|  ・symbol    シンボル(アセンブラのブレークポイントに指定するシンボル)
1923|【補足】
1924|・Errors_break では関数呼び出しをしているので、アセンブラ・デバッガでは
1925|  見にくくなりますが、本マクロはシンボルをそのまま埋めこむので見やすくなります。
1926|***************************************************************************/
1927|#define  Errors_break_asm( symbol ) \
1928|    __asm( ".globl  " #symbol ); \
1929|    __asm( #symbol ":" ); \
1930|    __asm( "nop" )
1931| 
1932|/***************************************************************************
1933|  88. <<< [Errors_setBreakFlag] ブレークフラグを設定する >>> 
1934|【引数】
1935|  ・bool  bf;   有効かどうか
1936|【補足】
1937|・すべての Errors_break を有効にしたり無効にしたりします。
1938|****************************************************************************/
1939|#ifdef  ERRORS_CUT_DEBUG_TOOL
1940|  #define  Errors_setBreakFlag(bf)   __cut_debug_tool  /* Syntax Error */
1941|#else
1942|  #define  Errors_setBreakFlag(bf)  (Errors_breakFlag = (bf))
1943|#endif
1944|
1945|extern  bool  Errors_breakFlag;
1946|
1947| 
1948|/***************************************************************************
1949|  89. <<< [Errors_setBreakID] ブレーク番号を設定する >>> 
1950|【引数】
1951|  ・int  id;   ブレーク番号(0=すべてブレークする)
1952|【補足】
1953|・ブレークさせる Errors_break または Errors_break_release の、
1954|  第1引数に指定されている番号を指定します。
1955|・0を指定すると、すべての Errors_break または Errors_break_release で
1956|  ブレークします。
1957|****************************************************************************/
1958|#ifdef  ERRORS_CUT_DEBUG_TOOL
1959|  #define  Errors_setBreakID(id)   __cut_debug_tool  /* Syntax Error */
1960|#else
1961|  #define  Errors_setBreakID(id)  (Errors_breakID = (id))
1962|#endif
1963|
1964|extern  int  Errors_breakID;
1965|
1966| 
1967|/**************************************************************************
1968|  90. <<< [ERRORS_FUNCLOG_INIT, Errors_FuncLog_print] 関数コール履歴の表示 >>> 
1969|  91. <<< [ERRORS_FUNC_VAR] C++ 言語用ダミー変数定義 >>>
1970|  92. <<< [ERRORS_FUNC_START, ERRORS_FUNC_END] 関数コール履歴に対応するためのマクロ >>>
1971|  93. <<< [ERRORS_FUNC_START_CPP, ERRORS_FUNC_END_CPP] 同、C++ 用 >>>
1972|  94. <<< [ERRORS_FUNC_START2, ERRORS_FUNC_END2] 同、レベル指定 >>>
1973|  95. <<< [ERRORS_FUNC_START2_CPP, ERRORS_FUNC_END2_CPP] 同、C++ 用レベル指定 >>>
1974|【補足】
1975|・→「関数コール履歴」
1976|***************************************************************************/
1977|#if  defined(ERRORS_CUT_DEBUG_TOOL) || ! defined(ERRORS_USE_FUNCLOG)
1978|  #define  ERRORS_FUNCLOG_INIT()
1979|  #define  Errors_FuncLog_print()   __cut_debug_tool_or_nouse_funcLog
1980|  #define  ERRORS_FUNCLOG_PRINT()
1981|  #define  ERRORS_FUNCLOG_ONLONGJUMP()
1982|  #define  ERRORS_FUNC_CPP_VAR( _func )
1983|  #define  ERRORS_FUNC_START( _func )                   /* C   言語用デフォルト */
1984|  #define  ERRORS_FUNC_START_CPP( _class_func )         /* C++ 言語用デフォルト */
1985|  #define  ERRORS_FUNC_START2( level, _func )           /* C   言語用・レベル指定 */
1986|  #define  ERRORS_FUNC_START2_CPP( level, _class_func ) /* C++ 言語用・レベル指定 */
1987|  #define  ERRORS_FUNC_END( _func )                     /* C   言語用デフォルト */
1988|  #define  ERRORS_FUNC_END_CPP( _class_func )           /* C++ 言語用デフォルト */
1989|  #define  ERRORS_FUNC_END2( level, _func )             /* C   言語用・レベル指定 */
1990|  #define  ERRORS_FUNC_END2_CPP( level, _class_func )   /* C++ 言語用・レベル指定 */
1991|
1992|#elif defined(ERRORS_FUNCLOG_SPECIFIC)
1993|  #define  ERRORS_FUNCLOG_INIT() \
1994|    Errors_FuncLog_init( Errors_FuncLog_getGlobl() )
1995|  #define  Errors_FuncLog_print() \
1996|    Errors_FuncLog_print_imp( Errors_FuncLog_getGlobl() )
1997|  #define  ERRORS_FUNCLOG_PRINT() \
1998|    Errors_FuncLog_print_imp( Errors_FuncLog_getGlobl() )
1999|  #define  ERRORS_FUNCLOG_ONLONGJUMP()
2000|  #define  ERRORS_FUNC_CPP_VAR( _func )
2001|  #define  ERRORS_FUNC_START( _func )                   /* C   言語用デフォルト */
2002|  #define  ERRORS_FUNC_START_CPP( _class_func )         /* C++ 言語用デフォルト */
2003|  #define  ERRORS_FUNC_START2( level, _func )           /* C   言語用・レベル指定 */
2004|  #define  ERRORS_FUNC_START2_CPP( level, _class_func ) /* C++ 言語用・レベル指定 */
2005|  #define  ERRORS_FUNC_END( _func )                     /* C   言語用デフォルト */
2006|  #define  ERRORS_FUNC_END_CPP( _class_func )           /* C++ 言語用デフォルト */
2007|  #define  ERRORS_FUNC_END2( level, _func )             /* C   言語用・レベル指定 */
2008|  #define  ERRORS_FUNC_END2_CPP( level, _class_func )   /* C++ 言語用・レベル指定 */
2009|
2010|#else  /* ERRORS_FUNCLOG_SPECIFIC を定義したときに #undef(→補足)と以下をすべてコピー&ペーストする */
2011|  #define  ERRORS_FUNCLOG_INIT() \
2012|    Errors_FuncLog_init( Errors_FuncLog_getGlobl() )
2013|  #define  Errors_FuncLog_print() \
2014|    Errors_FuncLog_print_imp( Errors_FuncLog_getGlobl() )
2015|  #define  ERRORS_FUNCLOG_PRINT() \
2016|    Errors_FuncLog_print_imp( Errors_FuncLog_getGlobl() )
2017|  #define  ERRORS_FUNCLOG_ONLONGJUMP() \
2018|    Errors_FuncLog_onLongJump( Errors_FuncLog_getGlobl() )
2019|  #define  ERRORS_FUNC_CPP_VAR( _func ) \
2020|    int  _func
2021|  #define  ERRORS_FUNC_START( _func ) \
2022|    Errors_FuncLog_setStart( Errors_FuncLog_getGlobl(), (void*)_func, #_func )
2023|  #define  ERRORS_FUNC_START_CPP( _func ) \
2024|    Errors_FuncLog_setStart( Errors_FuncLog_getGlobl(), (void*)&_func, #_func )
2025| #ifdef __cplusplus
2026|  #define  ERRORS_FUNC_START2( level, _func ) \
2027|    Errors_FuncLog_setStart( Errors_FuncLog_getGlobl(), reinterpret_cast<void*>(_func), #_func )
2028| #else
2029|  #define  ERRORS_FUNC_START2( level, _func ) \
2030|    Errors_FuncLog_setStart( Errors_FuncLog_getGlobl(), (void*)_func, #_func )
2031| #endif
2032|  #define  ERRORS_FUNC_START2_CPP( level, _func ) \
2033|    Errors_FuncLog_setStart( Errors_FuncLog_getGlobl(), (void*)&_func, #_func )
2034|  #define  ERRORS_FUNC_END( _func ) \
2035|    Errors_FuncLog_setEnd( Errors_FuncLog_getGlobl(), (void*)_func, #_func )
2036|  #define  ERRORS_FUNC_END_CPP( _func ) \
2037|    Errors_FuncLog_setEnd( Errors_FuncLog_getGlobl(), (void*)&_func, #_func )
2038|  #define  ERRORS_FUNC_END2( level, _func ) \
2039|    Errors_FuncLog_setEnd( Errors_FuncLog_getGlobl(), (void*)_func, #_func )
2040|  #define  ERRORS_FUNC_END2_CPP( level, _func ) \
2041|    Errors_FuncLog_setEnd( Errors_FuncLog_getGlobl(), (void*)&_func, #_func )
2042|#endif
2043|
2044|#define  Errors_FuncLog_getGlobl() \
2045|  (&Errors_FuncLog_globl)
2046| 
2047|/***************************************************************************
2048|  96. <<< [ERRORS_DEBUG_TRUE, ERRORS_DEBUG_FALSE] 埋めこみデバッグツールの有効無効 >>> 
2049|【補足】
2050|・コード中に printf などのデバッグツールを埋めこむとき、
2051|  以下のように #if 〜 #endif で囲みます。
2052|  (デバッグツールを有効にするとき)
2053|    #if  ERRORS_DEBUG_TRUE
2054|       printf(...);
2055|    #endif
2056|  (デバッグツールを無効にするとき)
2057|    #if  ERRORS_DEBUG_FALSE
2058|       printf(...);
2059|    #endif
2060|・ERRORS_CUT_DEBUG_TOOL を #define すると ERRORS_DEBUG_TRUE がコンパイル
2061|  エラーになるので、デバッグツールを容易に削除することができます。
2062|****************************************************************************/
2063|#ifdef  ERRORS_CUT_DEBUG_TOOL
2064|  #define  ERRORS_DEBUG_TRUE   __cut_debug_tool()  /* () が無いと通ってしまう */
2065|  #define  ERRORS_DEBUG_FALSE  0
2066|#else
2067|  #define  ERRORS_DEBUG_TRUE   1
2068|  #define  ERRORS_DEBUG_FALSE  0
2069|#endif
2070| 
2071|#ifdef __cplusplus 
2072|}
2073|#endif
2074|
2075|#endif
2076| 
2077|