source: Sophya/trunk/SophyaLib/BaseTools/exceptions.h@ 219

Last change on this file since 219 was 219, checked in by ansari, 26 years ago

Creation module DPC/SysTools Reza 09/04/99

File size: 6.1 KB
Line 
1// This may look like C code, but it is really -*- C++ -*-
2#ifndef EXCEPTIONS_SEEN
3#define EXCEPTIONS_SEEN
4
5// Gestion des exceptions, conformemnt au manuel de reference C++
6// en attendant que les compilateurs le fassent tous seuls
7//
8// Eric Aubourg, la Silla fevrier 95
9// Pour le moment, on ne sait gerer qu'un seul type d'exception, int.
10//
11// La syntaxe est
12// TRY {
13// ....
14// }
15// CATCH(i) {
16// ...
17// }
18// ENDTRY
19
20// ou bien CATCHALL a la place de CATCH.
21//
22
23// On peut faire THROW_ tout court, qui est pareil que THROW(0)
24// ou bien THROW(n)
25// ou bien THROW_SAME dans un bloc CATCH
26
27// IMPORTANT
28// Tout objet susceptible d'etre cree automatiquement au cours d'un bloc
29// try doit etre declare EXC_AWARE (class x EXC_AWARE {...};) ou bien
30// deriver d'une telle classe.
31
32// Tout constructeur d'une classe qui contient d'autres objets parmi ses
33// champs doit se terminer par END_CONSTRUCTOR.
34
35#include "defs.h"
36
37#include <iostream.h>
38#include "peidainit.h"
39
40//#define NO_EXCEPTIONS
41#ifdef NO_EXCEPTIONS
42
43#define EXC_ABORT_NEG(_x)
44#define EXC_ABORT_ALL(_x)
45
46#define EXC_AWARE
47
48#define END_CONSTRUCTOR
49
50#define TRY if (1) {
51#define CATCH(_var) } else { long _var;
52#define CATCHALL } else {
53#define ENDTRY }
54
55#define THROW(_i) \
56 {cerr << "Throw " << _i << " file " << __FILE__ << " line " << __LINE__; \
57 cerr << endl; \
58 abort();}
59
60#define THROW_ THROW(0)
61
62#define THROW_SAME THROW(0)
63
64#define ASSERT(_a_) if (!(_a_)) { \
65 cerr << "Assertion failed " #_a_ " file " __FILE__ " line " << __LINE__ \
66 << endl; \
67 THROW_ }
68
69#define RETURN(x) return(x)
70#define RETURN_ return
71
72#else
73#ifdef COMPILER_EXCEPTIONS
74
75#define EXC_ABORT_NEG(_x)
76#define EXC_ABORT_ALL(_x)
77
78#define EXC_AWARE
79
80#define END_CONSTRUCTOR
81
82#define TRY try
83#define CATCH(_var) catch(long _var)
84#define CATCHALL catch(...)
85#define ENDTRY
86
87#define THROW(_i) throw((long) _i);
88
89#define THROW_ THROW(0)
90
91#define THROW_SAME throw;
92
93#define ASSERT(_a_) if (!(_a_)) { \
94 cerr << "Assertion failed " #_a_ " file " __FILE__ " line " << __LINE__ \
95 << endl; \
96 THROW_ }
97
98#define RETURN(x) return(x)
99#define RETURN_ return
100
101void InitFailNewHandler();
102#else
103
104#include <setjmp.h>
105#include <stdlib.h>
106
107class ExcAwareObject;
108
109class ExcHndl {
110public:
111 ExcHndl(ExcHndl* up);
112 ~ExcHndl();
113
114 void SetEnv(jmp_buf& theEnv)
115#ifndef __GNUG__
116 {memcpy(env, theEnv, sizeof(jmp_buf));}
117#else
118 {env = theEnv;}
119#endif
120 void Throw(int exc=0, char* file=0, int line=0);
121 void Add(ExcAwareObject*);
122 void Forget(ExcAwareObject*);
123 void Ignore(ExcAwareObject*);
124 void IgnoreTab(ExcAwareObject*, size_t);
125 void DelTab(ExcAwareObject*);
126 void EndConstructor(void*, size_t);
127 static void NoHandler(int exc=0, char* file=0, int line=0);
128
129 ExcHndl* nextHandler;
130
131 int theExc;
132 int hadExc;
133
134private:
135 jmp_buf env;
136 int nObj, nObjAlloc;
137 ExcAwareObject** objects;
138 int nDyn, nDynAlloc;
139 ExcAwareObject** dynObjs;
140 int nDynTab, nDynTabAlloc;
141 ExcAwareObject** dynTabObjs;
142 size_t* dynTabSz;
143};
144
145extern ExcHndl* topExcHndl;
146extern int _ExcAbortNeg;
147extern int _ExcAbortAll;
148
149class ExcAwareObject {
150friend class ExcHndl;
151public:
152 ExcAwareObject() {
153 if (topExcHndl) topExcHndl->Add(this);
154 }
155
156 virtual ~ExcAwareObject() {
157 if (topExcHndl) topExcHndl->Forget(this);
158 }
159
160#ifdef HAS_VEC_NEW
161 void* operator new(size_t s) {
162 void* p = ::operator new(s);
163 if (topExcHndl) topExcHndl->Ignore((ExcAwareObject*)p);
164 return p;
165 }
166
167 void* operator new(size_t /*s*/, void* p) {
168 if (topExcHndl) topExcHndl->Ignore((ExcAwareObject*)p);
169 return p;
170 }
171
172 void* operator new[](size_t s) {
173 void* p = ::operator new[](s);
174 if (topExcHndl) topExcHndl->IgnoreTab((ExcAwareObject*)p,s);
175 return p;
176 }
177
178 void operator delete[](void* p) {
179 if (topExcHndl) topExcHndl->DelTab((ExcAwareObject*)p);
180 ::operator delete[](p);
181 }
182#else
183 void* operator new(size_t s) {
184 void* p = ::operator new(s);
185 if (topExcHndl) topExcHndl->IgnoreTab((ExcAwareObject*)p,s);
186 return p;
187 }
188
189 void* operator new(size_t s, void* p) {
190 if (topExcHndl) topExcHndl->IgnoreTab((ExcAwareObject*)p,s);
191 return p;
192 }
193
194 void operator delete(void* p) {
195 if (topExcHndl) topExcHndl->DelTab((ExcAwareObject*)p);
196 ::operator delete(p);
197 }
198#endif
199};
200
201//extern "C" void terminate();
202
203void InitFailNewHandler();
204
205// Et maintenant les macros!
206
207// TRY cree un nouveau handler, et fait le setjmp
208
209#define _UPHANDLER \
210 { ExcHndl* tmp = topExcHndl->nextHandler; \
211 delete topExcHndl; \
212 topExcHndl = tmp; }
213
214#define EXC_ABORT_NEG(_x) _ExcAbortNeg = _x;
215#define EXC_ABORT_ALL(_x) _ExcAbortAll = _x;
216
217#define EXC_AWARE : public virtual ExcAwareObject
218
219#define END_CONSTRUCTOR \
220if (topExcHndl) topExcHndl->EndConstructor(this, sizeof(*this));
221
222#define TRY \
223 { topExcHndl = new ExcHndl(topExcHndl); \
224 jmp_buf _jmpBuffer; \
225 volatile int _excCaught = 0; \
226 if (!setjmp(_jmpBuffer)) { \
227 topExcHndl->SetEnv(_jmpBuffer);
228
229#define CATCH(_var) \
230 _UPHANDLER \
231 } else if (topExcHndl->hadExc) { \
232 int _caughtException = topExcHndl->theExc; \
233 int _var = _caughtException; \
234 _excCaught = 1; \
235 _UPHANDLER
236
237#define CATCHALL \
238 _UPHANDLER \
239 } else if (topExcHndl->hadExc) { \
240 int _caughtException = topExcHndl->theExc;\
241 _excCaught = _caughtException; \
242 _excCaught = 1; \
243 _UPHANDLER
244
245#define ENDTRY \
246 } else _UPHANDLER\
247 }
248
249#define THROW(_i) \
250 {if (!topExcHndl) ExcHndl::NoHandler(_i,__FILE__,__LINE__); \
251 topExcHndl->Throw(_i,__FILE__,__LINE__);}
252
253#define THROW_ THROW(0)
254
255#define THROW_SAME THROW(_caughtException)
256
257#define ASSERT(_a_) if (!(_a_)) { \
258 cerr << "Assertion failed " #_a_ " file " __FILE__ " line " << __LINE__ \
259 << endl; \
260 THROW_ }
261
262#define RETURN(x) { _UPHANDLER; return(x); }
263#define RETURN_ { _UPHANDLER; return; }
264
265#endif
266#endif
267#endif
Note: See TracBrowser for help on using the repository browser.