1 | #include "defs.h"
|
---|
2 | #include "exceptions.h"
|
---|
3 | #include <iostream.h>
|
---|
4 | #include <new.h>
|
---|
5 | #ifndef __mac__
|
---|
6 | #include <unistd.h>
|
---|
7 | #endif
|
---|
8 | #include <stdlib.h>
|
---|
9 | #include "perrors.h"
|
---|
10 |
|
---|
11 | #ifdef __mac__
|
---|
12 | #include "unixmac.h"
|
---|
13 | #include <SIOUX.h>
|
---|
14 | #endif
|
---|
15 |
|
---|
16 | //#define LAL
|
---|
17 |
|
---|
18 | #ifndef EXC_MSG
|
---|
19 | #define EXC_MSG(i) "Exception " << i
|
---|
20 | #endif
|
---|
21 |
|
---|
22 | #define kDynAllocBlock 10
|
---|
23 |
|
---|
24 | void EAFailHandler(void);
|
---|
25 |
|
---|
26 | #ifndef COMPILER_EXCEPTIONS
|
---|
27 |
|
---|
28 | #ifndef NO_EXCEPTIONS
|
---|
29 |
|
---|
30 | ExcHndl::ExcHndl(ExcHndl* up)
|
---|
31 | : nextHandler(up),
|
---|
32 | theExc(0), hadExc(0),
|
---|
33 | nObj(0), nObjAlloc(kDynAllocBlock), objects((ExcAwareObject**)malloc(kDynAllocBlock*sizeof(void*))),
|
---|
34 | nDyn(0), nDynAlloc(kDynAllocBlock), dynObjs((ExcAwareObject**)malloc(kDynAllocBlock*sizeof(void*))),
|
---|
35 | nDynTab(0), nDynTabAlloc(kDynAllocBlock),
|
---|
36 | dynTabObjs((ExcAwareObject**)malloc(kDynAllocBlock*sizeof(void*))),
|
---|
37 | dynTabSz((size_t*)malloc(kDynAllocBlock*sizeof(size_t)))
|
---|
38 | {
|
---|
39 | // cerr << "TRY : " << hex << this << " <- " << nextHandler << dec << endl;
|
---|
40 | }
|
---|
41 |
|
---|
42 | ExcHndl::~ExcHndl()
|
---|
43 | {
|
---|
44 | free(objects);
|
---|
45 | free(dynObjs);
|
---|
46 | free(dynTabObjs);
|
---|
47 | free(dynTabSz);
|
---|
48 | // cerr << "~TRY: " << hex << this << " <- " << nextHandler << dec << endl;
|
---|
49 | }
|
---|
50 |
|
---|
51 | void ExcHndl::Add(ExcAwareObject* obj)
|
---|
52 | {
|
---|
53 | // on verifie s'il est dans la liste a ignorer
|
---|
54 | int trouve=0;
|
---|
55 | int i;
|
---|
56 | for (i=0; i<nDyn; i++)
|
---|
57 | if (dynObjs[i] == obj) {
|
---|
58 | trouve = true;
|
---|
59 | break;
|
---|
60 | }
|
---|
61 | if (trouve) { // On le vire de la table des news.
|
---|
62 | nDyn--;
|
---|
63 | for (int j=i; j<nDyn; j++)
|
---|
64 | dynObjs[j] = dynObjs[j+1];
|
---|
65 | return;
|
---|
66 | }
|
---|
67 |
|
---|
68 | // Dans les tableaux ?
|
---|
69 | for (i=0; i<nDynTab; i++)
|
---|
70 | if ((dynTabObjs[i] <= obj) && ((char*)(dynTabObjs[i]) + dynTabSz[i] >= (char*)obj)) {
|
---|
71 | return;
|
---|
72 | }
|
---|
73 |
|
---|
74 | // on l'ajoute a la liste des objets
|
---|
75 | nObj++;
|
---|
76 | if (nObj>nObjAlloc) {
|
---|
77 | nObjAlloc += kDynAllocBlock;
|
---|
78 | objects = (ExcAwareObject**) realloc(objects, nObjAlloc*sizeof(void*));
|
---|
79 | }
|
---|
80 |
|
---|
81 | objects[nObj-1] = obj;
|
---|
82 | }
|
---|
83 |
|
---|
84 | void ExcHndl::Forget(ExcAwareObject* obj)
|
---|
85 | {
|
---|
86 | // on verifie s'il est dans la liste
|
---|
87 | int trouve=0;
|
---|
88 | int i=0;
|
---|
89 | for (i=0; i<nObj; i++)
|
---|
90 | if (objects[i] == obj) {
|
---|
91 | trouve = true;
|
---|
92 | break;
|
---|
93 | }
|
---|
94 | if (trouve) {
|
---|
95 | nObj--;
|
---|
96 | for (int j=i; j<nObj; j++)
|
---|
97 | objects[j] = objects[j+1];
|
---|
98 | }
|
---|
99 | }
|
---|
100 |
|
---|
101 | void ExcHndl::Ignore(ExcAwareObject* obj)
|
---|
102 | {
|
---|
103 | // on l'ajoute a la liste des objets
|
---|
104 | nDyn++;
|
---|
105 | if (nDyn>nDynAlloc) {
|
---|
106 | nDynAlloc += kDynAllocBlock;
|
---|
107 | dynObjs = (ExcAwareObject**) realloc(dynObjs, nDynAlloc*sizeof(void*));
|
---|
108 | }
|
---|
109 |
|
---|
110 | dynObjs[nDyn-1] = obj;
|
---|
111 | }
|
---|
112 |
|
---|
113 | void ExcHndl::IgnoreTab(ExcAwareObject* obj, size_t sz)
|
---|
114 | {
|
---|
115 | // on l'ajoute a la liste des objets
|
---|
116 | nDynTab++;
|
---|
117 | if (nDynTab>nDynTabAlloc) {
|
---|
118 | nDynTabAlloc += kDynAllocBlock;
|
---|
119 | dynTabObjs =(ExcAwareObject**) realloc(dynTabObjs, nDynTabAlloc*sizeof(void*));
|
---|
120 | dynTabSz = (size_t*) realloc(dynTabSz, nDynTabAlloc*sizeof(size_t));
|
---|
121 | }
|
---|
122 |
|
---|
123 | dynTabObjs[nDynTab-1] = obj;
|
---|
124 | dynTabSz [nDynTab-1] = sz;
|
---|
125 | }
|
---|
126 |
|
---|
127 | void ExcHndl::DelTab(ExcAwareObject* obj)
|
---|
128 | {
|
---|
129 | // on le supprime
|
---|
130 |
|
---|
131 | int trouve=0;
|
---|
132 | int i=0;
|
---|
133 | for (i=0; i<nDynTab; i++)
|
---|
134 | if (dynTabObjs[i] == obj) {
|
---|
135 | trouve = true;
|
---|
136 | break;
|
---|
137 | }
|
---|
138 | if (trouve) {
|
---|
139 | nDynTab--;
|
---|
140 | for (int j=i; j<nDynTab; j++) {
|
---|
141 | dynTabObjs[j] = dynTabObjs[j+1];
|
---|
142 | dynTabSz [j] = dynTabSz [j+1];
|
---|
143 | }
|
---|
144 | }
|
---|
145 | }
|
---|
146 |
|
---|
147 |
|
---|
148 |
|
---|
149 | // End Constructor : ne pas se preoccuper des objets qui sont
|
---|
150 | // a l'interieur de cet objet.
|
---|
151 | void ExcHndl::EndConstructor(void* obj, size_t s)
|
---|
152 | {
|
---|
153 | for (int i=0; i<nObj; i++)
|
---|
154 | if ((char*)objects[i] > (char*)obj && (char*)objects[i] < (char*)obj + s) {
|
---|
155 | nObj--;
|
---|
156 | for (int j=i; j<nObj; j++)
|
---|
157 | objects[j] = objects[j+1];
|
---|
158 | i--;
|
---|
159 | }
|
---|
160 | }
|
---|
161 |
|
---|
162 | #undef DEBUG
|
---|
163 |
|
---|
164 | void ExcHndl::Throw(int i, char* file, int line)
|
---|
165 | {
|
---|
166 | if (_ExcAbortAll || (i<0 && _ExcAbortNeg)) {
|
---|
167 | cerr << EXC_MSG(i);
|
---|
168 | if (file) cerr << " file " << file << " line " << line;
|
---|
169 | cerr << endl;
|
---|
170 | abort();
|
---|
171 | } else {
|
---|
172 | #ifdef DEBUG
|
---|
173 | cerr << "caught " << EXC_MSG(i);
|
---|
174 | if (file) cerr << " file " << file << " line " << line;
|
---|
175 | cerr << endl;
|
---|
176 | #endif
|
---|
177 | theExc = i;
|
---|
178 | hadExc = 1;
|
---|
179 |
|
---|
180 | // On detruit tous les objets crees depuis le TRY
|
---|
181 | // ExcAwareObject a un destructeur virtuel...
|
---|
182 | // Le tableau est dans l'ordre de creation. donc i--
|
---|
183 |
|
---|
184 | for (int i=nObj-1; i>=0; i--)
|
---|
185 | objects[i]->~ExcAwareObject();
|
---|
186 |
|
---|
187 | // et maintenant on saute...
|
---|
188 |
|
---|
189 | longjmp(env, 1);
|
---|
190 | }
|
---|
191 | }
|
---|
192 |
|
---|
193 |
|
---|
194 | void ExcHndl::NoHandler(int i, char* file, int line)
|
---|
195 | {
|
---|
196 | cerr << "No handler : ";
|
---|
197 | cerr << EXC_MSG(i);
|
---|
198 | if (file) cerr << " file " << file << " line " << line;
|
---|
199 | cerr << endl;
|
---|
200 | terminate();
|
---|
201 | }
|
---|
202 |
|
---|
203 | ExcHndl* topExcHndl = 0;
|
---|
204 | int _ExcAbortNeg = 1;
|
---|
205 | int _ExcAbortAll = 0;
|
---|
206 |
|
---|
207 | #endif
|
---|
208 | #endif
|
---|
209 |
|
---|
210 |
|
---|
211 | void EAFailHandler(void)
|
---|
212 | {
|
---|
213 | set_new_handler(NULL);
|
---|
214 | cerr << "Allocation exception -- out of memory" << endl;
|
---|
215 | THROW(allocationErr);
|
---|
216 | }
|
---|
217 |
|
---|
218 | void InitFailNewHandler()
|
---|
219 | {
|
---|
220 | set_new_handler(EAFailHandler);
|
---|
221 | }
|
---|
222 |
|
---|
223 |
|
---|
224 | #ifdef THINK_CPLUS
|
---|
225 | void terminate()
|
---|
226 | {
|
---|
227 | DebugStr("\pTerminate...");
|
---|
228 | abort();
|
---|
229 | }
|
---|
230 | #endif
|
---|
231 |
|
---|
232 | #ifdef x__GNUG__
|
---|
233 | void terminate()
|
---|
234 | { abort(); }
|
---|
235 | #endif
|
---|