Except3.c
[目次 | 関数 | マクロ]
1|/*************************************************************************
2|* 1. <<< ソフトウェア例外処理3 (Except3) >>>
3|**************************************************************************/
4|
5|#include "mixer_precomp.h" /* Auto precompiled header, Look at mixer-... folder */
6|// #pragma hdrstop ("mixer_precomp")
7|
8|#define STDLIBS_INCLUDE
9|#define STDLIBS_INCLUDE_SETJMP_H
10|#define STDLIBS_INCLUDE_STRING_H
11|
12|#if defined(USES_MXP_AUTOINC)
13| #include "except3.ah" /* Auto include header, Look at mixer-... folder */
14|#endif
15|
16|
17|#ifdef USES_MULTASK
18| Except3 Except3_con[Except3_m];
19|#else
20| Except3 Except3_con;
21|#endif
22|
23|#if !defined(NDEBUG) || defined(ERRORS_ERROR_REPORT)
24| static char* Except3_OutOfTry_Str = "キャッチできない例外が発生しました";
25|#else
26| static char* Except3_OutOfTry_Str = "";
27|#endif
28|
29|static char* Except3_DupTry_Str = "catch か finally ブロック内か、ロングジャンプしない領域で"
30| "例外を処理していないときに try があってはなりません。\n"
31| "以前のエラーメッセージが一部消える可能性があります。";
32|static char* Except3_FinallyThrow_Str = "finally ブロック内で例外が発生しました。"
33| "一部の後始末処理は行われません。";
34|static char* Except3_TryStackOver_Str = "try 用スタック領域がいっぱいになりました。";
35|
36|
37|/*--------------------------------------------------------------------*/
38|/* 2. <<<◆(Except3) 例外処理システム >>> */
39|/*--------------------------------------------------------------------*/
40|
41|/*************************************************************************
42|* 3. <<< [Except3_init_imp] Except3_init の実装 >>>
43|**************************************************************************/
44|void Except3_init_imp( Except3* m,
45| Except3_Try* tryInfo, int tryInfo_size )
46|{
47| ERRORS_INITCHK( m, 0 );
48|
49| m->bExcept = false;
50| m->bNoJumpArea = false;
51| m->tryInfo = tryInfo;
52| m->mTry = tryInfo_size / sizeof(Except3_Try);
53|}
54|
55|
56|
57|/*************************************************************************
58|* 4. <<< [Except3_try_imp] try の実装 >>>
59|**************************************************************************/
60|void Except3_try_imp( Except3* m, char* file, int line )
61|{
62| EXCEPT3_INITCHK( m );
63|
64| #ifndef NDEBUG
65| if ( m->bExcept )
66| Except3_error( Except3_Err_DupTry, Except3_DupTry_Str );
67| if ( m->nTry >= m->mTry - 1 ) /* -1 はマクロで既に使っているため */
68| Except3_error( Except3_Err_TryStackOver, Except3_TryStackOver_Str );
69| #endif
70|
71| /* try ネストの記録 */
72| m->tryInfo[m->nTry].file = file;
73| m->tryInfo[m->nTry].line = line;
74| m->tryInfo[m->nTry].bNoJumpAreaTop = m->bNoJumpArea;
75|
76| /* try 処理 */
77| m->nTry ++;
78| m->bExcept = false;
79| m->bAgain = false;
80| m->bCatch = false;
81| m->bNoJumpArea = false;
82|}
83|
84|
85|
86|/*************************************************************************
87|* 5. <<< [Except3_catch_imp] catch の実装 >>>
88|**************************************************************************/
89|int Except3_catch_imp( Except3* m )
90|{
91| extern int Errors_errDupCount;
92| EXCEPT3_INITCHK( m );
93|
94| if ( m->bAgain ) return 0; /* catch 内の再スロー */
95|
96| Errors_errDupCount = 0;
97| m->bCatch = true;
98| return 1;
99|}
100|
101|
102|
103|/*************************************************************************
104|* 6. <<< [Except3_end_finally_imp] >>>
105|**************************************************************************/
106|void Except3_end_finally_imp( Except3* m )
107|{
108| EXCEPT3_INITCHK( m );
109|
110| if ( m->tryInfo[m->nTry - 1].bNoJumpAreaTop )
111| m->bNoJumpArea = true;
112|
113| if ( m->bExcept ) {
114| if ( m->bAgain ) {
115| m->nTry --;
116| m->bAgain = false;
117| m->bCatch = false;
118| if ( m->nTry <= 0 ) {
119| if ( ! m->tryInfo[0].bNoJumpAreaTop )
120| Except3_error( Except3_Err_OutOfTry, Except3_OutOfTry_Str );
121| }
122| else {
123| if ( ! m->tryInfo[m->nTry].bNoJumpAreaTop )
124| longjmp( m->tryInfo[m->nTry - 1].longjmp_buf, 1 );
125| }
126| }
127| else if ( ! m->bCatch ) {
128| m->nTry --;
129| if ( m->nTry <= 0 ) {
130| if ( ! m->tryInfo[0].bNoJumpAreaTop )
131| Except3_error( Except3_Err_OutOfTry, Except3_OutOfTry_Str );
132| }
133| else {
134| if ( ! m->tryInfo[m->nTry].bNoJumpAreaTop )
135| longjmp( m->tryInfo[m->nTry - 1].longjmp_buf, 1 );
136| }
137| }
138| else {
139| m->nTry --;
140| m->bExcept = false;
141| m->bCatch = false;
142| Errors_clearError();
143| }
144| }
145| else {
146| if ( m->nTry <= 0 )
147| Except3_error( Except3_Err_OutOfTry, Except3_OutOfTry_Str );
148| m->nTry --;
149| }
150|}
151|
152|
153|
154|/*************************************************************************
155|* 7. <<< [Except3_throw_imp] throw の実装 >>>
156|**************************************************************************/
157|void Except3_throw_imp( Except3* m, void* msg )
158|{
159| #ifndef NDEBUG
160| static int throwing = 0;
161|
162| throwing ++;
163| ASSERT( throwing == 1 );
164|
165| EXCEPT3_INITCHK( m );
166| if ( m->bExcept && ! m->bCatch )
167| Except3_error( Except3_Err_FinallyThrow, Except3_FinallyThrow_Str );
168| #endif
169|
170| ERRORS_FUNCLOG_ONLONGJUMP();
171|
172| /* 例外メッセージを登録する */
173| m->msg = msg;
174|
175| /* ロングジャンプする */
176| /* 通常のスローは、上位の catch へ、catch 内での再スロー は同位の finally へ */
177| if ( m->bNoJumpArea ) {
178| m->bExcept = true;
179| #ifndef NDEBUG
180| throwing = 0;
181| #endif
182| }
183| else {
184| if ( m->nTry <= 0 )
185| Except3_error( Except3_Err_OutOfTry, Except3_OutOfTry_Str );
186|
187| if ( m->bCatch ) {
188| m->bAgain = true;
189| #ifndef NDEBUG
190| throwing = 0;
191| #endif
192| longjmp( m->tryInfo[m->nTry - 1].longjmp_buf, 1 );
193| }
194| else {
195| m->bExcept = true;
196| #ifndef NDEBUG
197| throwing = 0;
198| #endif
199| longjmp( m->tryInfo[m->nTry - 1].longjmp_buf, 1 );
200| }
201| }
202|}
203|
204|
205|
206|/*************************************************************************
207|* 8. <<< [Except3_startNoJumpArea_imp] Except3_startNoJumpArea の実装 >>>
208|**************************************************************************/
209|void Except3_startNoJumpArea_imp( Except3* m )
210|{
211| m->bNoJumpArea = true;
212|}
213|
214|/*************************************************************************
215|* 9. <<< [Except3_endNoJumpArea_imp] Except3_endNoJumpArea の実装 >>>
216|**************************************************************************/
217|void Except3_endNoJumpArea_imp( Except3* m )
218|{
219| m->bNoJumpArea = false;
220|
221| if ( m->bExcept ) {
222| if ( m->nTry <= 0 )
223| Except3_error( Except3_Err_OutOfTry, Except3_OutOfTry_Str );
224|
225| if ( m->bCatch ) {
226| m->bAgain = true;
227| longjmp( m->tryInfo[m->nTry - 1].longjmp_buf, 1 );
228| }
229| else {
230| m->bExcept = true;
231| longjmp( m->tryInfo[m->nTry - 1].longjmp_buf, 1 );
232| }
233| }
234|}
235|
236|
237|/*************************************************************************
238|* 10. <<< [Except3_isNoJumpArea_imp] Except3_isNoJumpArea の実装 >>>
239|**************************************************************************/
240|bool Except3_isNoJumpArea_imp( Except3* m )
241|{
242| return ( m->bNoJumpArea == true || m->nTry == 0 );
243|}
244|
245|
246|/*************************************************************************
247|* 11. <<< [Except3_isError_imp] Except3_isError の実装 >>>
248|**************************************************************************/
249|bool Except3_isError_imp( Except3* m )
250|{
251| EXCEPT3_INITCHK( m );
252|
253| /* 多重例外かどうかを記録する */
254| if ( m->bExcept ) return true;
255| return false;
256|}
257|
258|
259|
260|/*************************************************************************
261|* 12. <<< [Except3_print_imp] 例外処理システムの状態をデバッグ表示する >>>
262|**************************************************************************/
263|#ifndef ERRORS_CUT_DEBUG_TOOL
264|#ifdef USES_MULTASK
265| void Except3_print_imp( Except3* m, int id )
266|#else
267| void Except3_print_imp( Except3* m )
268|#endif
269|{
270| int i;
271|
272| EXCEPT3_INITCHK( m );
273|
274| #ifdef USES_MULTASK
275| Errors_printf( "Except3[%d]: adr = %p", id, m->msg );
276| #else
277| Errors_printf( "Except3:" );
278| #endif
279| Errors_printf( " msg adr = %p", m->msg );
280| Errors_printf( " bExcept = %d", m->bExcept );
281| Errors_printf( " bCatch = %d", m->bCatch );
282| Errors_printf( " bAgain = %d", m->bAgain );
283| Errors_printf( " nTry = %d", m->nTry );
284| #ifdef EXCEPT3_NO_HINT
285| Errors_printf( " try is NO HINT" );
286| #else
287| for ( i = 0; i < m->nTry; i++ ) {
288| Errors_printf( " try[%d] in %s:%d",
289| i, m->tryInfo[i].file, m->tryInfo[i].line );
290| }
291| #endif
292|}
293|#endif
294|
295|/*************************************************************************
296|* 13. <<< [Except3_error_imp] 例外処理システムの異常終了 >>>
297|* 14. <<< [Except3_bNoExitChk] 異常終了時にチェックをしないフラグ >>>
298|**************************************************************************/
299|void Except3_error_imp( int code, const char* msg, char* file, int line )
300|{
301| #ifdef USES_MULTASK
302| Except3* m = &Except3_con[MulTask_Sys_getCurIndex()];
303| #else
304| Except3* m = &Except3_con;
305| #endif
306|
307| if ( Errors_MsgPool_isInit( Errors_MsgPool_getGlobl() ) &&
308| Errors_Msg_getGlobl()->code != Errors_NoError ) {
309| Errors_MsgPool_add( Errors_MsgPool_getGlobl(), Errors_Msg_getGlobl() );
310| /* この上でハングアップするときは、Errors_MsgPool のメモリ領域が */
311| /* ローカル変数のスコープ外になるなどの無効になっている可能性があります。 */
312| }
313| Errors_Msg_init( Errors_Msg_getGlobl(), -1, code, file, line, "%s", msg );
314|
315| if ( Errors_hdl != NULL ) {
316| extern Errors_errDupCount;
317| Errors_errDupCount ++;
318|
319| m->bExcept = false;
320| (*Errors_hdl)( Errors_Msg_getGlobl()->id, code, Errors_Msg_getGlobl()->msg );
321| }
322| else
323| Errors_printf_release( Errors_Msg_getGlobl()->msg );
324|
325| Errors_exit( file, line );
326|}
327|
328|/*--------------------------------------------------------------------*/
329|/* 15. <<<◆(Except3_MsgMng) エラーメッセージの管理 >>> */
330|/*--------------------------------------------------------------------*/
331|
332|/*************************************************************************
333|* 16. <<< (Except3_MsgStack) メッセージ・スタック抽象型 >>>
334|**************************************************************************/
335|#ifdef USES_INF
336|#ifndef NDEBUG
337|INF_FUNC_R1( Except3_MsgStack,push, void*, Except3_MsgStack_push, Except3_MsgStack,void*, t,a )
338|INF_FUNC_R1( Except3_MsgStack,pop, void*, Except3_MsgStack_pop, Except3_MsgStack,void*, t,a )
339|#endif
340|#endif
341|
342|
343|