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