83 lines
1.6 KiB
C
83 lines
1.6 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "../include/except.h"
|
|
|
|
struct Except_Frame *except_stack = NULL;
|
|
|
|
const struct Exception assertion_failed = { "Assertion failed" };
|
|
void asserted(int e){
|
|
if(!e){
|
|
RAISE(assertion_failed);
|
|
}
|
|
}
|
|
|
|
|
|
void except_raise(const struct Exception *e, const char *file,int line)
|
|
{
|
|
#ifdef WIN32
|
|
Except_Frame *p;
|
|
|
|
if (except_index == TLS_OUT_OF_INDEXES)
|
|
except_init();
|
|
p = TlsGetValue(except_index);
|
|
#else
|
|
struct Except_Frame *p = except_stack;
|
|
#endif
|
|
asserted(e != NULL);
|
|
if (p == NULL) {
|
|
fprintf(stderr, "Uncaught exception");
|
|
if (e->reason)
|
|
fprintf(stderr, " %s", e->reason);
|
|
else
|
|
fprintf(stderr, " at 0x%p", (void*)e);
|
|
if (file && line > 0)
|
|
fprintf(stderr, " raised at %s:%d\n", file, line);
|
|
fprintf(stderr, "aborting...\n");
|
|
fflush(stderr);
|
|
abort();
|
|
}
|
|
p->exception = e;
|
|
p->file = file;
|
|
p->line = line;
|
|
#ifdef WIN32
|
|
except_pop();
|
|
#else
|
|
except_stack = except_stack->prev;
|
|
#endif
|
|
longjmp(p->env, EXCEPT_STATE_RAISED);
|
|
}
|
|
|
|
|
|
#ifdef WIN32
|
|
_CRTIMP void __cdecl _assert(void *, void *, unsigned);
|
|
#undef assert
|
|
#define assert(e) ((e) || (_assert(#e, __FILE__, __LINE__), 0))
|
|
|
|
DWORD except_index = -1;
|
|
void except_init(void) {
|
|
BOOL cond;
|
|
|
|
except_index = TlsAlloc();
|
|
assert(except_index != TLS_OUT_OF_INDEXES);
|
|
cond = TlsSetValue(except_index, NULL);
|
|
assert(cond == TRUE);
|
|
}
|
|
|
|
void except_push(Except_Frame *fp) {
|
|
BOOL cond;
|
|
|
|
fp->prev = TlsGetValue(except_index);
|
|
cond = TlsSetValue(except_index, fp);
|
|
assert(cond == TRUE);
|
|
}
|
|
|
|
void except_pop(void) {
|
|
BOOL cond;
|
|
Except_Frame *tos = TlsGetValue(except_index);
|
|
|
|
cond = TlsSetValue(except_index, tos->prev);
|
|
assert(cond == TRUE);
|
|
}
|
|
|
|
#endif
|