errors.h

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