Errors16.H

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

目次

型・クラス・構造体一覧

マクロ一覧


   1|/***************************************************************************
   2|*  1. <<< テスト&デバッグツール 16bit コンパイラ版 (errors) >>> 
   3|****************************************************************************/
   4|
   5|#ifndef __ERRORS_H
   6|#define __ERRORS_H
   7|
   8| 
   9|/***********************************************************************
  10|* 2. <<< モジュール設定・優先ヘッダ >>> 
  11|* 3. <<< [NDEBUG, リリース版, デバッグ版] >>>
  12|*【補足】
  13|*・NDEBUG が #define されているとリリース版、
  14|*  #define されていないとデバッグ版となります。
  15|*  これは、他のすべてのモジュールに対して有効です。
  16|************************************************************************/
  17|
  18|#ifndef USES_PRIORITY_HEADER
  19|/*[START_OF_PRIORITY_HEADER]*/
  20|
  21|#ifndef  USES_ERRORS
  22|#define  USES_ERRORS
  23|
  24|/*#define  NDEBUG */         /* リリースバージョンなら有効にしてください */
  25|
  26|/* デバッグツールを取除く(あったら、コンパイラからメッセージを出す)*/
  27|#if  defined(NDEBUG) && !defined(ERRORS_CUT_DEBUG_TOOL_NOT)
  28|  #define  ERRORS_CUT_DEBUG_TOOL
  29|#endif
  30|
  31|#endif
  32|
  33|/*[END_OF_PRIORITY_HEADER]*/
  34|#endif /* USES_PRIORITY_HEADER */
  35|
  36| 
  37|/***********************************************************************
  38|* 4. <<< エラーコード >>> 
  39|************************************************************************/
  40|#define  Errors_NoError      0    /* [Compone_GID:Errors_Code] */
  41|#define  Errors_Unofficial   102  /* [Compone_GID:Errors_Code] エラーコードを割当てていない内部的なエラー */
  42|#define  Errors_ASSERT       109  /* [Compone_GID:Errors_Code] */
  43| 
  44|/*-----------------------------------------------------------------*/
  45|/* 5. <<< Interface Area ----------------------------------------->>> */ 
  46|/*-----------------------------------------------------------------*/
  47|
  48|#ifdef __cplusplus
  49|extern "C" {
  50|#endif
  51|
  52|
  53| 
  54|/**************************************************************************
  55|  6. <<< ◆エラー処理ツール >>> 
  56|【役割】
  57|・発生したエラーをプログラムが対処するときに使用します。
  58|***************************************************************************/
  59|typedef  int  (*Errors_Handler)( int err_id, int code, char* msg );
  60|
  61|/* error(); */
  62|/* error2_0( code, msg ); */
  63|/* error2_1( code, msg,a ); */
  64|/* error2_2( code, msg,a,b ); */
  65|/* error2_3( code, msg,a,b,c ); */
  66|/* error2_4( code, msg,a,b,c,d ); */
  67|/* error2_5( code, msg,a,b,c,d,e ); */
  68|
  69|void  Errors_setErrorHandler( Errors_Handler f );
  70| 
  71|/**************************************************************************
  72|  7. <<< ◆テストツール >>> 
  73|【役割】
  74|・プログラムを実行しながらエラーの存在を探し出します。
  75|【補足】
  76|・テストツールは以下のものがあります。
  77|  ・ASSERT              表明(事前条件チェック、事後条件チェック)
  78|***************************************************************************/
  79|
  80|/* ASSERT( cond ); */
  81| 
  82|/**************************************************************************
  83|  8. <<< ◆デバッグツール >>> 
  84|【役割】
  85|・エラーの原因を探し出します。
  86|【補足】
  87|・デバッグツールは以下のものがあります。
  88|  ・Errors_printf   表示、デバッグ用
  89|***************************************************************************/
  90|
  91|/* デバッグツール */
  92|void  MARK(void);
  93|void  COUNT( int );
  94|void  COUNT2( int );
  95|
  96|void  WX( void* adr, int size );
  97|
  98|char* Errors_printf_release( const char* fmt, ... );
  99|#ifndef  NDEBUG
 100| char* Errors_printf( const char* fmt, ... );
 101|#endif
 102|extern int  Errors_Line;
 103|
 104|int  Errors_getDispCh( int c );
 105| 
 106|/**************************************************************************
 107|  9. <<< 内部用 >>> 
 108|【補足】
 109|・内部用です
 110|***************************************************************************/
 111|void  Errors_error_imp( const char* file, int line, int code, char* codeStr,
 112|  char* fmt, ... );
 113|char*  Errors_printf_imp( const char* fmt, ... );
 114|
 115|/* デバッグツール(変数) */
 116|extern char* Errors_ps;
 117|extern char* Errors_ns;
 118|extern char* Errors_eu;
 119|extern char* Errors_ea;
 120|extern char* Errors_null;
 121|
 122|extern  char  Errors_log[];
 123|extern  char* Errors_log_p;
 124|extern  char  Errors_log2[];
 125|extern  char* Errors_log2_p;
 126|extern  char* Errors_poolStart;
 127|
 128|extern int  Errors_count;
 129|
 130|#ifndef  ERRORS_CUT_DEBUG_TOOL
 131| extern  int    Errors_count0;
 132| extern  char*  Errors_count_prev_n_file;
 133| extern  int    Errors_count_prev_n_line;
 134| extern  int    Errors_count_prev_n;
 135|
 136| extern  int    Errors_count2;
 137| extern  int    Errors_count2_0;
 138| extern  char*  Errors_count2_prev_n_file;
 139| extern  int    Errors_count2_prev_n_line;
 140| extern  int    Errors_count2_prev_n;
 141|
 142| extern  int    Errors_count_b;
 143| extern  int    Errors_count_b2;
 144|#endif
 145|
 146|
 147|/* デバッグツール(関数) */
 148|void  Errors_WD_imp( char* name, void* p, int ver, char* file, int line );
 149|void  Errors_WSP_imp( char* name, const char** p, const char* ver, char* file, int line );
 150|void  Errors_WB_imp( char* name, const void* p, char* file, int line );
 151|void  Errors_WX_imp( char* adr_name, void* adr, int size, char* file, int line );
 152|void  Errors_WX2_imp( char* adr_name, void* adr, int size, char* file, int line );
 153| 
 154|/*-----------------------------------------------------------------*/
 155|/* 10. <<< Mapping Area ------------------------------------------->>> */ 
 156|/*-----------------------------------------------------------------*/
 157|
 158|
 159| 
 160|/*-------------------------------------------------------------------------*/
 161|/* 11. <<< ◆エラー処理ツール >>>  */ 
 162|/*-------------------------------------------------------------------------*/
 163| 
 164|/**************************************************************************
 165|  12. <<< [error] エラーを発生させる >>> 
 166|【機能】
 167|・一般的なエラーを発生させます。
 168|【補足】
 169|・エラーの内容を報告する場合は、error2_0 マクロなどを使用します。
 170|・error によって与えられるエラーコードは、Errors_Unofficial です。
 171|・エラー処理を行ったら、Errors_clearError 関数を呼び出してください。
 172|・プログラムを終了する直前に、Errors_setErrorHandler 関数で登録した
 173|  関数を呼出します。登録した関数の中で、正常に終了するための処理を記述します。
 174|  (詳細は、Errors_setErrorHandler 関数の解説を参照してください。)
 175|・ERRORS_ERROR_REPORT を #define すると、条件文 cond がエラーメッセージに
 176|  付くようになります。ただし、Except2 をリンクしている場合は、
 177|  EXCEPT2_NOMSG を #define しないように設定をしてください。
 178|・リリース時も有効です。
 179|・本マクロは、Except2 モジュールとリンクするときと、しないときで、
 180|  動作が異なります。
 181|  リンクする場合、Except2_Std 型の例外を発生します。
 182|  対応する catch ブロックが無ければ、Errors_exit 関数を呼出して
 183|  プログラムを終了します。
 184|  リンクしない場合、すぐに Errors_exit 関数を呼出してプログラムを終了します。
 185|  プログラムの終了ができないアセンブラ・デバッガでは、第一引数に相当する
 186|  レジスタに 0xEEEEEEEE を格納してから exit ラベルにジャンプします。
 187|  よって、スタートアップ・ルーチンなどに exit ラベルを作成する必要があります。
 188|***************************************************************************/
 189|#ifdef  USES_EXCEPT2
 190|  #define error() \
 191|    throw( Except2_Std_newExcept2_c( \
 192|    Errors_Unofficial, Errors_eu, "error" ) )
 193|#else
 194|  #define  error()  Errors_error_imp(__FILE__,__LINE__,Errors_Unofficial, Errors_eu, "error")
 195|#endif
 196|
 197|void  Errors_clearError(void);
 198|
 199|
 200| 
 201|/**************************************************************************
 202|  13. <<< [error2] エラーを発生させる(拡張版) >>> 
 203|  14. <<< [error2_0, error2_1, error2_2, error2_3, error2_4, error2_5] >>>
 204|【機能】
 205|・エラーコード、エラーメッセージを備えた error です。
 206|【引数】
 207|  ・int    code;    エラーコード
 208|  ・char*  msg;     エラーメッセージ(printf形式)
 209|  ・var1,var2...;   msg の printf 引数
 210|【補足】
 211|・リリース時も有効です。
 212|・error, ASSERT2 の解説を参照してください。
 213|***************************************************************************/
 214|#ifdef  USES_EXCEPT2
 215|  #ifdef  ERRORS_ERROR_REPORT
 216|    #define error2_0( code, msg ) \
 217|      throw( Except2_Std_newExcept2_c( code, #code, msg ) )
 218|    #define error2_1( code, msg, var1 ) \
 219|      throw( Except2_Std_newExcept2_cf( code, #code, msg, var1 ) )
 220|    #define error2_2( code, msg, var1, var2 ) \
 221|      throw( Except2_Std_newExcept2_cf( code, #code, msg, var1, var2 ) )
 222|    #define error2_3( code, msg, var1, var2, var3 ) \
 223|      throw( Except2_Std_newExcept2_cf( code, #code, msg, var1, var2, var3 ) )
 224|    #define error2_4( code, msg, var1, var2, var3, var4 ) \
 225|      throw( Except2_Std_newExcept2_cf( code, #code, msg, var1, var2, var3, var4 ) )
 226|    #define error2_5( code, msg, var1, var2, var3, var4, var5 ) \
 227|      throw( Except2_Std_newExcept2_cf( code, #code, msg, var1, var2, var3, var4, var5 ) )
 228|  #else
 229|    #define error2_0( code, msg ) \
 230|      throw( Except2_Std_newExcept2_c( code, Errors_null, Errors_null ) )
 231|    #define error2_1( code, msg, var1 ) \
 232|      throw( Except2_Std_newExcept2_c( code, Errors_null, Errors_null ) )
 233|    #define error2_2( code, msg, var1, var2 ) \
 234|      throw( Except2_Std_newExcept2_c( code, Errors_null, Errors_null ) )
 235|    #define error2_3( code, msg, var1, var2, var3 ) \
 236|      throw( Except2_Std_newExcept2_c( code, Errors_null, Errors_null ) )
 237|    #define error2_4( code, msg, var1, var2, var3, var4 ) \
 238|      throw( Except2_Std_newExcept2_c( code, Errors_null, Errors_null ) )
 239|    #define error2_5( code, msg, var1, var2, var3, var4, var5 ) \
 240|      throw( Except2_Std_newExcept2_c( code, Errors_null, Errors_null ) )
 241|  #endif
 242|#else
 243|  #ifdef  ERRORS_ERROR_REPORT
 244|    #define  error2_0( code, msg )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg)
 245|    #define  error2_1( code, msg, var1 )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1)
 246|    #define  error2_2( code, msg, var1, var2 )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1,var2)
 247|    #define  error2_3( code, msg, var1, var2, var3)  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1,var2,var3)
 248|    #define  error2_4( code, msg, var1, var2, var3, var4 )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1,var2,var3,var4)
 249|    #define  error2_5( code, msg, var1, var2, var3, var4, var5 )  Errors_error_imp(__FILE__,__LINE__,code,#code,msg,var1,var2,var3,var4,var5)
 250|  #else
 251|    #define  error2_0( code, msg )  Errors_error_imp(__FILE__,__LINE__,code,Errors_null,Errors_null)
 252|    #define  error2_1( code, msg, var1 )  Errors_error_imp(__FILE__,__LINE__,code,Errors_null,Errors_null)
 253|    #define  error2_2( code, msg, var1, var2 )  Errors_error_imp(__FILE__,__LINE__,code,Errors_null,Errors_null)
 254|    #define  error2_3( code, msg, var1, var2, var3)  Errors_error_imp(__FILE__,__LINE__,code,Errors_null,Errors_null)
 255|    #define  error2_4( code, msg, var1, var2, var3, var4 )  Errors_error_imp(__FILE__,__LINE__,code,Errors_null,Errors_null)
 256|    #define  error2_5( code, msg, var1, var2, var3, var4, var5 )  Errors_error_imp(__FILE__,__LINE__,code,Errors_null,Errors_null)
 257|  #endif
 258|#endif
 259|
 260|
 261| 
 262|/*-------------------------------------------------------------------------*/
 263|/* 15. <<< ◆テストツール >>> */ 
 264|/*-------------------------------------------------------------------------*/
 265|
 266|
 267| 
 268|/**************************************************************************
 269|  16. <<< [ASSERT] 値をチェックする(条件表明)>>> 
 270|【機能】
 271|・引数 cond に書かれた条件が満たされていることを保証します。
 272|  もし、条件が満たされていない場合、エラー通知します(errorマクロ)。
 273|【引数】
 274|  ・bool   cond;    正常条件(falseならエラー)
 275|【例】
 276|  int  func( int n )
 277|  {
 278|     ASSERT( n >= 0 );    // この関数の引数 n は0以上であること、の意味
 279|     return  array[n];
 280|  }
 281|【補足】
 282|・条件が満たされなかった場合については、error マクロを参照してください。
 283|・リリース版では、条件文が実行されないことと、エラーが発生しないことに
 284|  注意してください。正常なループの終了条件に ASSERT を使用しないでください。
 285|・else 文を書くときは、直前の if 文に { } を必ず付けてください。エラーになります。
 286|***************************************************************************/
 287|#ifndef ASSERT
 288|  #if  !defined(NDEBUG) || defined(FOR_TEST)
 289|    #ifdef  ERRORS_ASSERT_REPORT
 290|      #define ASSERT( cond ) \
 291|        if ( ! (cond) )  Errors_error_imp( __FILE__, __LINE__, \
 292|            Errors_ASSERT, Errors_ea, Errors_ps, #cond );
 293|    #else
 294|      #define ASSERT( cond ) \
 295|        if ( ! (cond) )  Errors_error_imp( Errors_null, __LINE__, \
 296|            Errors_ASSERT, Errors_ea, Errors_ps, Errors_ns );
 297|    #endif
 298|  #else
 299|    #define ASSERT( cond )   0
 300|  #endif
 301|#endif
 302|
 303|
 304| 
 305|/*-------------------------------------------------------------------------*/
 306|/* 17. <<< ◆デバッグツール >>> */ 
 307|/*-------------------------------------------------------------------------*/
 308|
 309| 
 310|/**************************************************************************
 311|  18. <<< [MARK, MARK2, MARK3] プロセッサが通過したら表示する >>> 
 312|【補足】
 313|・デバッグ時にエラーが発生したソースの位置を特定するときに使用します。
 314|・MARK2 は、Windows 専用で、ダイアログボックスを表示します。
 315|・MARK3 は、高速リアルタイム用で、Errors_Line に行番号を入れます。
 316|  Visual Studio の場合、プロジェクトの設定で MAP ファイルを生成する
 317|  ようにしてから、MARK3 を記述し、実行ファイルを作成します。
 318|  例外が発生したら、メモリウィンドウを表示して、
 319|  _Errors_Line シンボルのメモリアドレスにジャンプして、
 320|  変数の値を確認します。
 321|  _Errors_Line シンボルのメモリアドレスは、
 322|  MAP ファイルの中を検索して調べることができます。
 323|***************************************************************************/
 324|#ifdef  ERRORS_CUT_DEBUG_TOOL
 325|  #define  MARK()   __cut_debug_tool
 326|  #define  MARK2()  __cut_debug_tool
 327|  #define  MARK3()  __cut_debug_tool
 328|#else
 329|  #define  MARK()   ( Errors_Line = __LINE__, Errors_printf( "MARK : %s(%d)", __FILE__, __LINE__ ) )
 330|  #define  MARK2()  ( Errors_Line = __LINE__, Errors_printf_release( "MARK : %s(%d)", __FILE__, __LINE__ ) )
 331|  #define  MARK3()  ( Errors_Line = __LINE__ )
 332|#endif
 333|
 334| 
 335|/**************************************************************************
 336|  19. <<< [COUNT] プロセッサが通過した回数を数える、通過回数で分岐する >>> 
 337|  20. <<< [COUNT2] COUNT に達した後で更に内部のループで回数を数える >>>
 338|  21. <<< [IFCOUNT] COUNT, COUNT2 で指定のカウント値になり、IFC が真かどうかの分岐 >>>
 339|  22. <<< [IFCOUNT1] COUNT のみで指定のカウント値になったかどうかの分岐 >>>
 340|  23. <<< [IFCOUNT2] COUNT COUNT2 で指定のカウント値になったかどうかの分岐 >>>
 341|  24. <<< [BK] ソースデバッガ用ブレークポイント設定可能位置 >>>
 342|【補足】
 343|・エラーが発生するタイミングを特定するときに使用します。
 344|・本マクロをとおるたびに Errors_count グローバル変数がプラス1されます。
 345|  WD BP マクロは、COUNT で指定した値以上になったときのみ機能します。
 346|・1.引数 n を 0 にしてプロセッサが通過する回数を調べます。
 347|    COUNT(0);
 348|  通過するたびにカウント値を出力します(Errors_printfによる)。
 349|  出力したくないときは、COUNT(-1); と指定します。
 350|  通過回数はエラーメッセージに表示されます。
 351|  (または、Errors_count グローバル変数を参照します)
 352|・2.次のように記述して変数値を確認します。
 353|    COUNT(120) { WD(x); WF(f); }
 354|  COUNT マクロの後の中括弧は、プロセッサの通過回数が引数に指定した値に
 355|  なったときに実行します。
 356|  COUNT より前の WD BP で出力したくないときは、main 関数の最初で
 357|  Errors_count0 = -1 と記述します。
 358|・IFCOUNT は、次のように記述します。
 359|    IFCOUNT {  カウントが COUNT の引数値に達したときの処理  }
 360|***************************************************************************/
 361|#ifdef  ERRORS_CUT_DEBUG_TOOL
 362|  #define  COUNT(n)  __cut_debug_tool
 363|  #define  COUNT2(n)  __cut_debug_tool
 364|  #define  IFCOUNT   __cut_debug_tool
 365|  #define  BK        __cut_debug_tool
 366|#else
 367|  #define  COUNT(n) \
 368|    if ( Errors_count_prev_n == 0 ) { \
 369|      Errors_count_prev_n_file = __FILE__; \
 370|      Errors_count_prev_n_line = __LINE__; \
 371|      Errors_count_prev_n = (n); \
 372|    } \
 373|    if ( Errors_count_prev_n != (n) ) \
 374|      error2_2( Errors_Err_DoubleCount, "COUNT が2ヶ所で定義されています %s(%d)", \
 375|        Errors_count_prev_n_file, Errors_count_prev_n_line ); \
 376|    Errors_count0 = (n); \
 377|    Errors_count ++; \
 378|    IFCOUNT1 \
 379|      Errors_printf( "COUNT = %d in %s(%d)", Errors_count, __FILE__, __LINE__ ); \
 380|    IFCOUNT1
 381|
 382|  #define  COUNT2(n) \
 383|    IFCOUNT1 \
 384|      if ( Errors_count2_prev_n == 0 ) { \
 385|        Errors_count2_prev_n_file = __FILE__; \
 386|        Errors_count2_prev_n_line = __LINE__; \
 387|        Errors_count2_prev_n = (n); \
 388|      } \
 389|      if ( Errors_count2_prev_n != (n) ) \
 390|        error2_2( Errors_Err_DoubleCount, "COUNT2 が2ヶ所で定義されています %s(%d)", \
 391|          Errors_count2_prev_n_file, Errors_count2_prev_n_line ); \
 392|      Errors_count2_0 = (n); \
 393|      Errors_count2 ++; \
 394|      IFCOUNT \
 395|        Errors_printf( "COUNT2 = %d in %s(%d)", Errors_count2, __FILE__, __LINE__ ); \
 396|      IFCOUNT
 397|
 398|  #define  IFCOUNT \
 399|    if ( Errors_count >= Errors_count0 && Errors_count0 != -1 && \
 400|         Errors_count2 >= Errors_count2_0 && Errors_count2_0 != -1 && \
 401|         Errors_count_b && Errors_count_b2 )
 402|
 403|  #define  IFCOUNT1 \
 404|    if ( Errors_count >= Errors_count0 && Errors_count0 != -1 )
 405|
 406|  #define  IFCOUNT2 \
 407|    if ( Errors_count >= Errors_count0 && Errors_count0 != -1 && \
 408|         Errors_count2 >= Errors_count2_0 && Errors_count2_0 != -1 )
 409|
 410|  #define  BK  {int i=0;}
 411|
 412|#endif
 413|
 414|
 415| 
 416|/**************************************************************************
 417|  25. <<< [WD,WD0,WS,WSP,WSP0,WP,WP0,WF] 変数値を表示する >>> 
 418|【補足】
 419|・すべて Errors_count が Errors_count0 以上のときにのみ表示します。
 420|・WD は整数用、WS は文字列用、WSP は文字列ポインタ用、WP は16進数整数
 421|  (メモリアドレス)用、WF は浮動小数用、WX, WX2 はメモリダンプ用です。
 422|・WD0 など 0 の付くものは、引数に変数でないもの(例:式)を指定できます。
 423|・WX WX2 では表示方法が異なります。WX では常に行頭からデータを表示し、
 424|  WX2 では常にアドレスの1の位が0のデータから行を表示します。
 425|・内部で Errors_printf を用いています。
 426|***************************************************************************/
 427|#ifdef  ERRORS_CUT_DEBUG_TOOL
 428|  #define  WD(x)    __cut_debug_tool
 429|  #define  WD0(x)   __cut_debug_tool
 430|  #define  WS(x)    __cut_debug_tool
 431|  #define  WS0(x)   __cut_debug_tool
 432|  #define  WSP(x)   __cut_debug_tool
 433|  #define  WSP0(x)  __cut_debug_tool
 434|  #define  WP(x)    __cut_debug_tool
 435|  #define  WP0(x)   __cut_debug_tool
 436|  #define  WPP(x)   __cut_debug_tool
 437|  #define  WF(x)    __cut_debug_tool
 438|  #define  WF0(x)   __cut_debug_tool
 439|  #define  WX( adr, size )   __cut_debug_tool
 440|  #define  WX2( adr, size )  __cut_debug_tool
 441|#else
 442|  #define  WD(x)    IFCOUNT  Errors_WD_imp( #x, &(x), x, __FILE__, __LINE__ )
 443|  #define  WD0(x)   IFCOUNT  Errors_WD_imp( #x, NULL, x, __FILE__, __LINE__ )
 444|  #define  WS(x)    IFCOUNT  Errors_printf( "%s (%p) = \"%s\" : %s(%d)", #x, &(x), x, __FILE__, __LINE__ )
 445|  #define  WS0      WS
 446|  #define  WSP(x)   IFCOUNT  Errors_WSP_imp( #x, &(x), x, __FILE__, __LINE__ )
 447|  #define  WSP0(x)  IFCOUNT  Errors_WSP_imp( #x, NULL, x, __FILE__, __LINE__ )
 448|  #define  WP(x)    IFCOUNT  Errors_printf( "%s (%p) = %p : %s(%d)", #x, &(x), x, __FILE__, __LINE__ )
 449|  #define  WP0(x)   IFCOUNT  Errors_printf( "%s = %p : %s(%d)", #x, x, __FILE__, __LINE__ )
 450|  #define  WPP(x)   IFCOUNT  Errors_printf( "%s = %p *(%08X) : %s(%d)", #x, x, *(int*)x, __FILE__, __LINE__ )
 451|  #define  WF(x)    IFCOUNT  Errors_printf( "%s (%p) = %f : %s(%d)", #x, &(x), x, __FILE__, __LINE__ )
 452|  #define  WF0(x)   IFCOUNT  Errors_printf( "%s (%p) = %f : %s(%d)", #x, NULL, x, __FILE__, __LINE__ )
 453|  #define  WX( adr, size )   IFCOUNT  Errors_WX_imp( #adr, adr, size, __FILE__, __LINE__ );
 454|  #define  WX2( adr, size )  IFCOUNT  Errors_WX2_imp( #adr, adr, size, __FILE__, __LINE__ );
 455|#endif
 456|
 457|
 458| 
 459|/**************************************************************************
 460|  26. <<< [Errors_printf] デバッグ情報を表示する >>> 
 461|【補足】
 462|・関数 bp にブレークポイントをつけると、エラーログがあふれたときに
 463|  ブレークします。
 464|・Windows では、HWND  Errors_parentWnd; グローバル変数に設定したウィンドウ
 465|  を親ウィンドウとしてメッセージボックスを表示します。
 466|***************************************************************************/
 467|#ifdef  ERRORS_CUT_DEBUG_TOOL
 468|  #define  Errors_printf   __cut_debug_tool  /* Syntax Error */
 469|#else
 470|  #define  Errors_printf   Errors_printf_imp
 471|#endif
 472|
 473|#define  Errors_printf_release   Errors_printf_imp
 474| 
 475|/***************************************************************************
 476|  27. <<< [ERRORS_DEBUG_TRUE, ERRORS_DEBUG_FALSE] 埋めこみデバッグツールの有効無効 >>> 
 477|【補足】
 478|・コード中に printf などのデバッグツールを埋めこむとき、
 479|  以下のように #if 〜 #endif で囲みます。
 480|  (デバッグツールを有効にするとき)
 481|    #if  ERRORS_DEBUG_TRUE
 482|       printf(...);
 483|    #endif
 484|  (デバッグツールを無効にするとき)
 485|    #if  ERRORS_DEBUG_FALSE
 486|       printf(...);
 487|    #endif
 488|・ERRORS_CUT_DEBUG_TOOL を #define すると ERRORS_DEBUG_TRUE がコンパイル
 489|  エラーになるので、デバッグツールを容易に削除することができます。
 490|****************************************************************************/
 491|#ifdef  ERRORS_CUT_DEBUG_TOOL
 492|  #define  ERRORS_DEBUG_TRUE   __cut_debug_tool()  /* () が無いと通ってしまう */
 493|  #define  ERRORS_DEBUG_FALSE  0
 494|#else
 495|  #define  ERRORS_DEBUG_TRUE   1
 496|  #define  ERRORS_DEBUG_FALSE  0
 497|#endif
 498| 
 499|#ifdef __cplusplus 
 500|}
 501|#endif
 502|
 503|#endif
 504| 
 505|