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|