~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSException.cc

  • Committer: Monty Taylor
  • Date: 2010-07-06 00:44:32 UTC
  • mfrom: (1643.1.13 build)
  • Revision ID: mordred@inaugust.com-20100706004432-843uftc92rc2497l
Merged in PBMS, translation updates, a few build fixes and a few bug fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2008 PrimeBase Technologies GmbH, Germany
 
2
 *
 
3
 * PrimeBase Media Stream for MySQL
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
18
 *
 
19
 * Original author: Paul McCullagh (H&G2JCtL)
 
20
 * Continued development: Barry Leslie
 
21
 *
 
22
 * 2007-05-20
 
23
 *
 
24
 * The main exception classes
 
25
 *
 
26
 */
 
27
 
 
28
#include "CSConfig.h"
 
29
 
 
30
#include <sys/signal.h>
 
31
#include <limits.h>
 
32
#include <string.h>
 
33
 
 
34
#include "CSGlobal.h"
 
35
#include "CSException.h"
 
36
#include "CSStrUtil.h"
 
37
#include "CSLog.h"
 
38
 
 
39
void CSException::setStackTrace(CSThread *self, const char *stack)
 
40
{
 
41
        char buffer[CS_EXC_CONTEXT_SIZE];
 
42
 
 
43
        self->myException.iStackTrace.setLength(0);
 
44
        if (stack)
 
45
                self->myException.iStackTrace.append(stack);
 
46
        for (int i=self->callTop-1; i>=0; i--) {
 
47
                cs_format_context(CS_EXC_CONTEXT_SIZE, buffer,
 
48
                        self->callStack[i].cs_func, self->callStack[i].cs_file, self->callStack[i].cs_line);
 
49
                self->myException.iStackTrace.append(buffer);
 
50
                self->myException.iStackTrace.append('\n');
 
51
        }
 
52
}
 
53
 
 
54
void CSException::setStackTrace(CSThread *self)
 
55
{
 
56
        setStackTrace(self, NULL);
 
57
}
 
58
 
 
59
const char *CSException::getStackTrace()
 
60
{
 
61
        return iStackTrace.getCString();
 
62
}
 
63
 
 
64
void CSException::log(CSThread *self)
 
65
{
 
66
        CSL.lock();
 
67
        CSL.log(self, CSLog::Error, getContext());
 
68
        CSL.log(self, CSLog::Error, " ");
 
69
        CSL.log(self, CSLog::Error, getMessage());
 
70
        CSL.eol(self, CSLog::Error);
 
71
        CSL.log(self, CSLog::Error, getStackTrace());
 
72
        CSL.unlock();
 
73
}
 
74
 
 
75
void CSException::log(CSThread *self, const char *message)
 
76
{
 
77
        CSL.lock();
 
78
        CSL.log(self, CSLog::Error, message);
 
79
        CSL.eol(self, CSLog::Error);
 
80
        CSL.log(self, CSLog::Error, getContext());
 
81
        CSL.log(self, CSLog::Error, " ");
 
82
        CSL.log(self, CSLog::Error, getMessage());
 
83
        CSL.eol(self, CSLog::Error);
 
84
        CSL.log(self, CSLog::Error, getStackTrace());
 
85
        CSL.unlock();
 
86
}
 
87
 
 
88
void CSException::initException(const char *func, const char *file, int line, int err, const char *message)
 
89
{
 
90
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
91
        iErrorCode = err;
 
92
        cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, message);
 
93
}
 
94
 
 
95
void CSException::initException(CSException &exception)
 
96
{
 
97
        iErrorCode = exception.iErrorCode;
 
98
        strcpy(iContext, exception.iContext);
 
99
        strcpy(iMessage, exception.iMessage);
 
100
        
 
101
        iStackTrace.setLength(0);
 
102
        iStackTrace.append(exception.iStackTrace.getCString());
 
103
 
 
104
}
 
105
 
 
106
void CSException::initAssertion(const char *func, const char *file, int line, const char *message)
 
107
{
 
108
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
109
        iErrorCode = CS_ERR_ASSERTION;
 
110
        cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, message);
 
111
}
 
112
 
 
113
void CSException::getCoreError(uint32_t size, char *buffer, int err)
 
114
{
 
115
        const char *message = NULL;
 
116
 
 
117
        switch (err) {
 
118
                case CS_ERR_JUMP_OVERFLOW: message = "Jump stack overflow"; break;
 
119
                case CS_ERR_BAD_ADDRESS: message = "Incorrect network address: %"; break;
 
120
                case CS_ERR_UNKNOWN_SERVICE: message = "Unknown network service: %"; break;
 
121
                case CS_ERR_UNKNOWN_HOST:  message = "Unknown host: %"; break;
 
122
                case CS_ERR_UNKNOWN_METHOD: message = "Unknown HTTP method: %"; break;
 
123
                case CS_ERR_NO_LISTENER: message = "Listening port has been closed"; break;
 
124
                case CS_ERR_RELEASE_OVERFLOW: message = "Release stack overflow"; break;
 
125
                case CS_ERR_IMPL_MISSING: message = "Function %s not implemented"; break;
 
126
                case CS_ERR_BAD_HEADER_MAGIC: message = "Incorrect file type"; break;
 
127
                case CS_ERR_VERSION_TOO_NEW: message = "Incompatible file version"; break;
 
128
        }
 
129
        if (message)
 
130
                cs_strcpy(size, buffer, message);
 
131
        else {
 
132
                cs_strcpy(size, buffer, "Unknown system error ");
 
133
                cs_strcat(size, buffer, err);
 
134
        }
 
135
}
 
136
 
 
137
void CSException::initCoreError(const char *func, const char *file, int line, int err)
 
138
{
 
139
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
140
        iErrorCode = err;
 
141
        getCoreError(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
142
}
 
143
 
 
144
void CSException::initCoreError(const char *func, const char *file, int line, int err, const char *item)
 
145
{
 
146
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
147
        iErrorCode = err;
 
148
        getCoreError(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
149
        cs_replace_string(CS_EXC_MESSAGE_SIZE, iMessage, '%', item);
 
150
}
 
151
 
 
152
void CSException::initOSError(const char *func, const char *file, int line, int err)
 
153
{
 
154
        char *msg;
 
155
 
 
156
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
157
        iErrorCode = err;
 
158
 
 
159
#ifdef XT_WIN
 
160
        if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, iMessage, CS_EXC_MESSAGE_SIZE, NULL)) {
 
161
                char *ptr;
 
162
 
 
163
                ptr = &iMessage[strlen(iMessage)];
 
164
                while (ptr-1 > err_msg) {
 
165
                        if (*(ptr-1) != '\n' && *(ptr-1) != '\r' && *(ptr-1) != '.')
 
166
                                break;
 
167
                        ptr--;
 
168
                }
 
169
                *ptr = 0;
 
170
 
 
171
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, " (");
 
172
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
173
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ")");
 
174
                return;
 
175
        }
 
176
#endif
 
177
 
 
178
        msg = strerror(err);
 
179
        if (msg) {
 
180
                cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, msg);
 
181
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, " (");
 
182
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
183
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ")");
 
184
        }
 
185
        else {
 
186
                cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "Unknown OS error code ");
 
187
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
188
        }
 
189
}
 
190
 
 
191
void CSException::initFileError(const char *func, const char *file, int line, const char *path, int err)
 
192
{
 
193
        initOSError(func, file, line, err);
 
194
        cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ": '");
 
195
        cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, path);
 
196
        cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, "'");
 
197
}
 
198
 
 
199
void CSException::initSignal(const char *func, const char *file, int line, int sig)
 
200
{
 
201
        char *str;
 
202
 
 
203
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
204
        iErrorCode = sig;
 
205
        if (!(str = strsignal(sig))) {
 
206
                cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "Unknown signal ");
 
207
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, sig);
 
208
        }
 
209
        else {
 
210
                cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, str);
 
211
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, " (");
 
212
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, sig);
 
213
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ")");
 
214
        }
 
215
}
 
216
 
 
217
void CSException::initEOFError(const char *func, const char *file, int line, const char *path)
 
218
{
 
219
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
220
        iErrorCode = CS_ERR_EOF;
 
221
        cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "EOF encountered: '");
 
222
        cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, path);
 
223
        cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, "'");
 
224
}
 
225
 
 
226
void CSException::RecordException(const char *func, const char *file, int line, int err, const char *message)
 
227
{
 
228
        CSThread *self;
 
229
 
 
230
        if ((self = CSThread::getSelf())) {
 
231
                if (!self->myException.getErrorCode())
 
232
                        self->myException.initException(func, file, line, err, message);
 
233
        }
 
234
}
 
235
 
 
236
void CSException::ClearException()
 
237
{
 
238
        CSThread *self;
 
239
 
 
240
        if ((self = CSThread::getSelf())) {
 
241
                self->myException.setErrorCode(0);
 
242
        }
 
243
}
 
244
 
 
245
void CSException::throwException(const char *func, const char *file, int line, int err, const char *message, const char *stack)
 
246
{
 
247
        CSThread *self;
 
248
 
 
249
        if ((self = CSThread::getSelf())) {
 
250
                self->myException.initException(func, file, line, err, message);
 
251
                self->myException.setStackTrace(self, stack);
 
252
                self->throwException();
 
253
        }
 
254
        else {
 
255
                CSException e;
 
256
                
 
257
                e.initException(func, file, line, err,message);
 
258
                e.log(NULL, "*** Uncaught error");
 
259
        }
 
260
}
 
261
 
 
262
void CSException::throwException(const char *func, const char *file, int line, int err, const char *message)
 
263
{
 
264
        throwException(func, file, line, err, message, NULL);
 
265
}
 
266
 
 
267
void CSException::throwAssertion(const char *func, const char *file, int line, const char *message)
 
268
{
 
269
        CSThread *self;
 
270
 
 
271
        if ((self = CSThread::getSelf())) {
 
272
                self->myException.initAssertion(func, file, line, message);
 
273
                self->myException.setStackTrace(self);
 
274
                self->logException();
 
275
                self->throwException();
 
276
        }
 
277
        else {
 
278
                CSException e;
 
279
                
 
280
                e.initAssertion(func, file, line, message);
 
281
                e.log(NULL, "*** Uncaught error");
 
282
        }
 
283
}
 
284
 
 
285
void CSException::throwCoreError(const char *func, const char *file, int line, int err)
 
286
{
 
287
        CSThread *self;
 
288
 
 
289
        if ((self = CSThread::getSelf())) {
 
290
                self->myException.initCoreError(func, file, line, err);
 
291
                self->myException.setStackTrace(self);
 
292
                self->throwException();
 
293
        }
 
294
        else {
 
295
                CSException e;
 
296
                
 
297
                e.initCoreError(func, file, line, err);
 
298
                e.log(NULL, "*** Uncaught error");
 
299
        }
 
300
}
 
301
 
 
302
void CSException::throwCoreError(const char *func, const char *file, int line, int err, const char *item)
 
303
{
 
304
        CSThread *self;
 
305
 
 
306
        if ((self = CSThread::getSelf())) {
 
307
                self->myException.initCoreError(func, file, line, err, item);
 
308
                self->myException.setStackTrace(self);
 
309
                self->throwException();
 
310
        }
 
311
        else {
 
312
                CSException e;
 
313
                
 
314
                e.initCoreError(func, file, line, err, item);
 
315
                e.log(NULL, "*** Uncaught error");
 
316
        }
 
317
}
 
318
 
 
319
void CSException::throwOSError(const char *func, const char *file, int line, int err)
 
320
{
 
321
        CSThread *self;
 
322
 
 
323
        if ((self = CSThread::getSelf())) {
 
324
                /* A pending signal has priority over a system error,
 
325
                 * In fact, the pending signal may be the reason for
 
326
                 * system error:
 
327
                 */
 
328
                self->interrupted();
 
329
                self->myException.initOSError(func, file, line, err);
 
330
                self->myException.setStackTrace(self);
 
331
                self->throwException();
 
332
        }
 
333
        else {
 
334
                CSException e;
 
335
                
 
336
                e.initOSError(func, file, line, err);
 
337
                e.log(NULL, "*** Uncaught error");
 
338
        }
 
339
}
 
340
 
 
341
void CSException::throwFileError(const char *func, const char *file, int line, const char *path, int err)
 
342
{
 
343
        CSThread *self;
 
344
 
 
345
        if ((self = CSThread::getSelf())) {
 
346
                self->interrupted();
 
347
                self->myException.initFileError(func, file, line, path, err);
 
348
                self->myException.setStackTrace(self);
 
349
                self->throwException();
 
350
        }
 
351
        else {
 
352
                CSException e;
 
353
                
 
354
                e.initFileError(func, file, line, path, err);
 
355
                e.log(NULL, "*** Uncaught error");
 
356
        }
 
357
}
 
358
 
 
359
void CSException::throwFileError(const char *func, const char *file, int line, CSString *path, int err)
 
360
{
 
361
        CSThread *self;
 
362
 
 
363
        if ((self = CSThread::getSelf())) {
 
364
                self->interrupted();
 
365
                self->myException.initFileError(func, file, line, path->getCString(), err);
 
366
                self->myException.setStackTrace(self);
 
367
                self->throwException();
 
368
        }
 
369
        else {
 
370
                CSException e;
 
371
                
 
372
                e.initFileError(func, file, line, path->getCString(), err);
 
373
                e.log(NULL, "*** Uncaught error");
 
374
        }
 
375
}
 
376
 
 
377
void CSException::throwSignal(const char *func, const char *file, int line, int sig)
 
378
{
 
379
        CSThread *self;
 
380
 
 
381
        if ((self = CSThread::getSelf())) {
 
382
                self->myException.initSignal(func, file, line, sig);
 
383
                self->myException.setStackTrace(self);
 
384
                self->throwException();
 
385
        }
 
386
        else {
 
387
                CSException e;
 
388
                
 
389
                e.initSignal(func, file, line, sig);
 
390
                e.log(NULL, "*** Uncaught error");
 
391
        }
 
392
}
 
393
 
 
394
void CSException::throwEOFError(const char *func, const char *file, int line, const char *path)
 
395
{
 
396
        CSThread *self;
 
397
 
 
398
        if ((self = CSThread::getSelf())) {
 
399
                self->interrupted();
 
400
                self->myException.initEOFError(func, file, line, path);
 
401
                self->myException.setStackTrace(self);
 
402
                self->throwException();
 
403
        }
 
404
        else {
 
405
                CSException e;
 
406
                
 
407
                e.initEOFError(func, file, line, path);
 
408
                e.log(NULL, "*** Uncaught error");
 
409
        }
 
410
}
 
411
 
 
412
void CSException::throwLastError(const char *func, const char *file, int line)
 
413
{
 
414
#ifdef OS_WINDOWS
 
415
        throwOSError(func, file, line, (int) getLastError());
 
416
#else
 
417
        throwOSError(func, file, line, (int) errno);
 
418
#endif
 
419
}
 
420
 
 
421
void CSException::logOSError(const char *func, const char *file, int line, int err)
 
422
{
 
423
        CSThread *self;
 
424
 
 
425
        if ((self = CSThread::getSelf())) {
 
426
                self->myException.initOSError(func, file, line, err);
 
427
                self->myException.setStackTrace(self);
 
428
                self->logException();
 
429
        }
 
430
        else {
 
431
                CSException e;
 
432
                
 
433
                e.initOSError(func, file, line, err);
 
434
                e.log(NULL);
 
435
        }
 
436
}
 
437
 
 
438
void CSException::logOSError(CSThread *self, const char *func, const char *file, int line, int err)
 
439
{
 
440
        self->myException.initOSError(func, file, line, err);
 
441
        self->myException.setStackTrace(self);
 
442
        self->logException();
 
443
}
 
444
 
 
445
void CSException::logException(const char *func, const char *file, int line, int err, const char *message)
 
446
{
 
447
        CSThread *self;
 
448
 
 
449
        if ((self = CSThread::getSelf())) {
 
450
                self->myException.initException(func, file, line, err, message);
 
451
                self->logException();
 
452
        }
 
453
        else {
 
454
                CSException e;
 
455
                
 
456
                e.initException(func, file, line, err,message);
 
457
                e.log(NULL);
 
458
        }
 
459
}
 
460
 
 
461