From 9f4ee9e75ea1a1be1e45d75a9a46e2043641cbb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Fri, 25 Jan 2008 15:01:02 +0000 Subject: [PATCH] [EXAMPLES] * BUG: The Scripting example was fixed. [INTERPRETER] * NEW: The error management was redesigned. [GB.DB] * NEW: Database driver can declare a set of character that are allowed in a database name. [GB.DB.SQLITE2] * NEW: '.' is allowed in database names now. [GB.DB.SQLITE3] * NEW: '.' is allowed in database names now. git-svn-id: svn://localhost/gambas/trunk@1038 867c0c6c-44f3-4631-809d-bfa615b0a4ec --- TODO | 9 -- gb.db.sqlite2/src/main.cpp | 2 + gb.db.sqlite3/src/main.cpp | 2 + main/gbx/gb_error.c | 197 +++++++++++++++++++++---------------- main/gbx/gb_error.h | 43 ++++---- main/gbx/gbx.c | 8 +- main/gbx/gbx_api.c | 2 +- main/gbx/gbx_c_error.c | 18 ++-- main/gbx/gbx_class.c | 4 +- main/gbx/gbx_eval.c | 2 +- main/gbx/gbx_exec.c | 3 +- main/gbx/gbx_exec.h | 2 +- main/gbx/gbx_exec_loop.c | 7 +- main/gbx/gbx_subr_misc.c | 2 +- main/lib/db/CDatabase.c | 2 +- main/lib/db/gb.db.h | 1 + main/share/gb_common.h | 11 +++ 17 files changed, 173 insertions(+), 142 deletions(-) diff --git a/TODO b/TODO index f101d0196..b582efb0e 100644 --- a/TODO +++ b/TODO @@ -31,7 +31,6 @@ Do it asap: - Structure support - Callback support - Sorting two or more arrays at the same time. -- Creates error objects for each error and not one for all. DEVELOPMENT ENVIRONMENT ----------------------- @@ -67,19 +66,12 @@ DATABASE COMPONENT - Copy a result line into another one. - Use SAVEPOINT in postgresql to simulate nested transactions. - DOCUMENTATION WIKI ------------------ - Mass rename command. - Fix last changes: only those in one language. - -64 BITS -------- - -- X11 Window datatype is a long => Control.Id should return a pointer - OTHER ----- @@ -89,5 +81,4 @@ COMPONENTS ---------- - gb.corba ? -- gb.v4l ? diff --git a/gb.db.sqlite2/src/main.cpp b/gb.db.sqlite2/src/main.cpp index fdd927b87..d52552eed 100644 --- a/gb.db.sqlite2/src/main.cpp +++ b/gb.db.sqlite2/src/main.cpp @@ -612,6 +612,8 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db) db->flags.no_blob = TRUE; db->flags.no_nest = TRUE; + db->db_name_char = "."; + db->handle = conn; return FALSE; } diff --git a/gb.db.sqlite3/src/main.cpp b/gb.db.sqlite3/src/main.cpp index 19506d580..0cf5e724d 100644 --- a/gb.db.sqlite3/src/main.cpp +++ b/gb.db.sqlite3/src/main.cpp @@ -711,6 +711,8 @@ static int open_database(DB_DESC * desc, DB_DATABASE * db) db->flags.no_table_type = TRUE; db->flags.no_nest = TRUE; + db->db_name_char = "."; + db->handle = conn; return FALSE; } diff --git a/main/gbx/gb_error.c b/main/gbx/gb_error.c index 971300c7b..4704bae8c 100644 --- a/main/gbx/gb_error.c +++ b/main/gbx/gb_error.c @@ -38,8 +38,11 @@ #include "gbx_exec.h" #include "gbx_api.h" +//#define DEBUG_ERROR -ERROR_INFO ERROR_info = { 0 }; +ERROR_CONTEXT *ERROR_current = NULL; + +//ERROR_current->info ERROR_current->info = { 0 }; static int _lock = 0; static const char *_message[64] = @@ -110,7 +113,6 @@ static const char *_message[64] = NULL }; -static ERROR_CONTEXT *_current = NULL; void ERROR_lock() @@ -124,37 +126,89 @@ void ERROR_unlock() _lock--; } -static void ERROR_reset() +static void ERROR_reset(ERROR_CONTEXT *err) { - ERROR_info.code = 0; - DEBUG_free_backtrace(&ERROR_info.backtrace); + err->info.code = 0; + if (err->info.free) + { + STRING_free(&err->info.msg); + err->info.free = FALSE; + } + else + err->info.msg = NULL; + DEBUG_free_backtrace(&err->info.backtrace); } void ERROR_clear() { if (_lock) return; - ERROR_reset(); + ERROR_reset(ERROR_current); } void ERROR_enter(ERROR_CONTEXT *err) { CLEAR(err); - err->prev = _current; - _current = err; + err->prev = ERROR_current; + ERROR_current = err; + + #if DEBUG_ERROR + fprintf(stderr, ">> ERROR_enter"); + { + ERROR_CONTEXT *e = err; + while (e) + { + fprintf(stderr, " -> %p", e); + e = e->prev; + } + fprintf(stderr, "\n"); + } + #endif } void ERROR_leave(ERROR_CONTEXT *err) { - if (err->prev != ERROR_LEAVE_DONE) - { - _current = err->prev; - err->prev = ERROR_LEAVE_DONE; - } + if (err->prev == ERROR_LEAVE_DONE) + return; + + #if DEBUG_ERROR + fprintf(stderr, "<< ERROR_leave"); + { + ERROR_CONTEXT *e = err; + while (e) + { + fprintf(stderr, " -> %p", e); + e = e->prev; + } + fprintf(stderr, "\n"); + } + #endif + + //if (!err->prev) + // BREAKPOINT(); + + ERROR_current = err->prev; + + if (ERROR_current) + { + ERROR_reset(ERROR_current); + ERROR_current->info = err->info; + } + + err->prev = ERROR_LEAVE_DONE; + //ERROR_reset(err); } +void ERROR_propagate() +{ + if (ERROR_current->ret) + ERROR_leave(ERROR_current); + longjmp(ERROR_current->env, 1); +} + + const char *ERROR_get(void) { @@ -170,54 +224,43 @@ const char *ERROR_get(void) void ERROR_define(const char *pattern, char *arg[]) { - int n; uchar c; boolean subst; void _add_char(uchar c) { - if (n >= MAX_ERROR_MSG) - return; - if (c && c < ' ' && c != '\n') c = ' '; - ERROR_info.msg[n++] = c; + STRING_add(&ERROR_current->info.msg, (char *)&c, 1); } void _add_string(const char *s) { - if (!s) - s = ""; - - while (*s) - { - _add_char(*s); - s++; - } + STRING_add(&ERROR_current->info.msg, s, 0); } ERROR_clear(); if ((intptr_t)pattern >= 0 && (intptr_t)pattern < 256) { - ERROR_info.code = (int)(intptr_t)pattern; + ERROR_current->info.code = (int)(intptr_t)pattern; pattern = _message[(int)(intptr_t)pattern]; } else if ((intptr_t)pattern == E_ABORT) { - ERROR_info.code = E_ABORT; + ERROR_current->info.code = E_ABORT; pattern = ""; } else - ERROR_info.code = E_CUSTOM; - - n = 0; + ERROR_current->info.code = E_CUSTOM; if (arg) { subst = FALSE; + ERROR_current->info.free = TRUE; + for (;;) { c = *pattern++; @@ -246,45 +289,23 @@ void ERROR_define(const char *pattern, char *arg[]) } else { - _add_string(pattern); + ERROR_current->info.msg = (char *)pattern; + ERROR_current->info.free = FALSE; } _add_char(0); - ERROR_info.cp = CP; - ERROR_info.fp = FP; - ERROR_info.pc = PC; + ERROR_current->info.cp = CP; + ERROR_current->info.fp = FP; + ERROR_current->info.pc = PC; if (EXEC_debug || (CP && CP->debug)) { - DEBUG_free_backtrace(&ERROR_info.backtrace); - ERROR_info.backtrace = DEBUG_backtrace(); + //DEBUG_free_backtrace(&ERROR_current->info.backtrace); + ERROR_current->info.backtrace = DEBUG_backtrace(); } } -void PROPAGATE() -{ - ERROR_CONTEXT *err; - - /* - if (_must_free_index) - { - for (i = 0; i < _must_free_index; i++) - OBJECT_UNREF(&_must_free[i], "PROPAGATE"); - - _must_free_index = 0; - } - */ - - if (_current == NULL) - ERROR_panic("Cannot propagate error. No error handler."); - - err = _current; - ERROR_leave(_current); - longjmp(err->env, 1); -} - - void THROW(int code, ...) { va_list args; @@ -347,7 +368,7 @@ void ERROR_panic(const char *error, ...) ); vfprintf(stderr, error, args); fprintf(stderr, "\n"); - if (ERROR_info.code) + if (ERROR_current->info.code) { fprintf(stderr, "\n"); ERROR_print(); @@ -361,22 +382,22 @@ void ERROR_panic(const char *error, ...) void ERROR_print_at(FILE *where, bool msgonly, bool newline) { - if (!ERROR_info.code) + if (!ERROR_current->info.code) return; if (!msgonly) { - if (ERROR_info.cp && ERROR_info.fp && ERROR_info.pc) - fprintf(where, "%s: ", DEBUG_get_position(ERROR_info.cp, ERROR_info.fp, ERROR_info.pc)); + if (ERROR_current->info.cp && ERROR_current->info.fp && ERROR_current->info.pc) + fprintf(where, "%s: ", DEBUG_get_position(ERROR_current->info.cp, ERROR_current->info.fp, ERROR_current->info.pc)); else fprintf(where, "ERROR: "); - /*if (ERROR_info.code > 0 && ERROR_info.code < 256) - fprintf(where, "%ld:", ERROR_info.code);*/ - if (ERROR_info.code > 0) - fprintf(where, "#%d: ", ERROR_info.code); + /*if (ERROR_current->info.code > 0 && ERROR_current->info.code < 256) + fprintf(where, "%ld:", ERROR_current->info.code);*/ + if (ERROR_current->info.code > 0) + fprintf(where, "#%d: ", ERROR_current->info.code); } - fprintf(where, "%s", ERROR_info.msg); + fprintf(where, "%s", ERROR_current->info.msg); if (newline) fputc('\n', where); } @@ -385,7 +406,7 @@ void ERROR_print(void) { static bool lock = FALSE; - DEBUG_BACKTRACE *bt = ERROR_info.backtrace; + DEBUG_BACKTRACE *bt = ERROR_current->info.backtrace; ERROR_print_at(stderr, FALSE, TRUE); @@ -401,33 +422,35 @@ void ERROR_print(void) { lock = TRUE; GAMBAS_DoNotRaiseEvent = TRUE; - HOOK(error)(ERROR_info.code, ERROR_info.msg, DEBUG_get_position(ERROR_info.cp, ERROR_info.fp, ERROR_info.pc)); + HOOK(error)(ERROR_current->info.code, ERROR_current->info.msg, DEBUG_get_position(ERROR_current->info.cp, ERROR_current->info.fp, ERROR_current->info.pc)); lock = FALSE; } } void ERROR_save(ERROR_INFO *save) { - save->code = ERROR_info.code; - save->cp = ERROR_info.cp; - save->fp = ERROR_info.fp; - save->pc = ERROR_info.pc; - save->backtrace = ERROR_info.backtrace; - ERROR_info.backtrace = NULL; - strlcpy(save->msg, ERROR_info.msg, sizeof(ERROR_info.msg)); + *save = ERROR_current->info; + ERROR_reset(ERROR_current); +// save->code = ERROR_current->info.code; +// save->cp = ERROR_current->info.cp; +// save->fp = ERROR_current->info.fp; +// save->pc = ERROR_current->info.pc; +// save->backtrace = ERROR_current->info.backtrace; +// ERROR_current->info.backtrace = NULL; +// strlcpy(save->msg, ERROR_current->info.msg, sizeof(ERROR_current->info.msg)); } void ERROR_restore(ERROR_INFO *save) { - ERROR_reset(); - - ERROR_info.code = save->code; - ERROR_info.cp = save->cp; - ERROR_info.cp = save->fp; - ERROR_info.pc = save->pc; - ERROR_info.backtrace = save->backtrace; - save->backtrace = NULL; - strlcpy(ERROR_info.msg, save->msg, sizeof(ERROR_info.msg)); + ERROR_reset(ERROR_current); + ERROR_current->info = *save; +// ERROR_current->info.code = save->code; +// ERROR_current->info.cp = save->cp; +// ERROR_current->info.cp = save->fp; +// ERROR_current->info.pc = save->pc; +// ERROR_current->info.backtrace = save->backtrace; +// save->backtrace = NULL; +// strlcpy(ERROR_current->info.msg, save->msg, sizeof(ERROR_current->info.msg)); } diff --git a/main/gbx/gb_error.h b/main/gbx/gb_error.h index 0a2277cde..83bf47a03 100644 --- a/main/gbx/gb_error.h +++ b/main/gbx/gb_error.h @@ -100,11 +100,13 @@ enum { typedef struct { - int code; + short code; + bool free; void *cp; void *fp; void *pc; - char msg[MAX_ERROR_MSG + 1]; + //char msg[MAX_ERROR_MSG + 1]; + char *msg; void *backtrace; } ERROR_INFO; @@ -112,16 +114,16 @@ typedef typedef struct _ERROR { struct _ERROR *prev; - int code; jmp_buf env; + int ret; + ERROR_INFO info; } ERROR_CONTEXT; #ifndef __GB_ERROR_C -EXTERN ERROR_INFO ERROR_info; +EXTERN ERROR_CONTEXT *ERROR_current; #endif - #define ERROR_LEAVE_DONE ((ERROR_CONTEXT *)-1) #define TRY \ @@ -129,27 +131,30 @@ EXTERN ERROR_INFO ERROR_info; ERROR_CONTEXT __err_context; \ { \ ERROR_CONTEXT *__err = &__err_context; \ + /*fprintf(stderr, "TRY %s\n", __FUNCTION__);*/ \ ERROR_enter(__err); \ - __err->code = setjmp(__err->env); \ - if (__err->code == 0) - -#define FINALLY + __err->ret = setjmp(__err->env); \ + if (__err->ret == 0) +/*#define CATCH \ + fprintf(stderr, "%p == %p ? %d\n", ERROR_current, __err, __err->ret); \ + if (__err->ret != 0 && (__err->ret = 2))*/ #define CATCH \ - if (__err->code != 0 && !(__err->code = 0)) - -#define CATCH_GET(get_it) \ - if (__err->code != 0 && (get_it = __err->code) && !(__err->code = 0)) + /*if (__err->ret) fprintf(stderr, "CATCH %p\n", __err); \ + if (__err->ret)*/ \ + else #define END_TRY \ - if (__err->code == 0) \ - ERROR_leave(__err); \ - else \ - PROPAGATE(); \ + ERROR_leave(__err); \ + /*fprintf(stderr, "END TRY %s\n", __FUNCTION__);*/ \ } \ } -//PUBLIC void ERROR_clear(void); +#define ERROR __err + +#define PROPAGATE() ERROR_propagate() +//#define PROPAGATE() fprintf(stderr, "PROPAGATE %s\n", __FUNCTION__), ERROR_propagate() + PUBLIC const char *ERROR_get(void); PUBLIC void ERROR_enter(ERROR_CONTEXT *err); @@ -157,7 +162,7 @@ PUBLIC void ERROR_leave(ERROR_CONTEXT *err); PUBLIC void ERROR_define(const char *pattern, char *arg[]); -PUBLIC void PROPAGATE() NORETURN; +PUBLIC void ERROR_propagate() NORETURN; PUBLIC void THROW(int code, ...) NORETURN; PUBLIC void THROW_SYSTEM(int err, const char *path); diff --git a/main/gbx/gbx.c b/main/gbx/gbx.c index 413baa331..0abece0e1 100644 --- a/main/gbx/gbx.c +++ b/main/gbx/gbx.c @@ -113,7 +113,6 @@ static void main_exit() EVENT_exit(); FILE_exit(); STRING_exit(); - ERROR_clear(); STACK_exit(); } @@ -222,7 +221,7 @@ int main(int argc, char **argv) } CATCH { - if (ERROR_info.code && ERROR_info.code != E_ABORT) + if (ERROR_current->info.code && ERROR_current->info.code != E_ABORT) ERROR_print_at(stderr, TRUE, TRUE); main_exit(); _exit(1); @@ -321,7 +320,7 @@ int main(int argc, char **argv) } else { - if (ERROR_info.code && ERROR_info.code != E_ABORT) + if (ERROR->info.code && ERROR->info.code != E_ABORT) ERROR_print(); main_exit(); _exit(1); @@ -358,7 +357,7 @@ int main(int argc, char **argv) } CATCH { - if (ERROR_info.code && ERROR_info.code != E_ABORT) + if (ERROR->info.code && ERROR->info.code != E_ABORT) { if (EXEC_debug) { @@ -376,7 +375,6 @@ int main(int argc, char **argv) } END_TRY - ERROR_info.code = 0; main_exit(); if (MEMORY_count) diff --git a/main/gbx/gbx_api.c b/main/gbx/gbx_api.c index d8d2899f8..5615f7be2 100644 --- a/main/gbx/gbx_api.c +++ b/main/gbx/gbx_api.c @@ -101,7 +101,7 @@ void *GAMBAS_Api[] = (void *)GB_IsProperty, (void *)GB_Error, - (void *)PROPAGATE, + (void *)ERROR_propagate, (void *)GB_GetClass, (void *)GB_GetClassName, diff --git a/main/gbx/gbx_c_error.c b/main/gbx/gbx_c_error.c index 0f266952d..c40146349 100644 --- a/main/gbx/gbx_c_error.c +++ b/main/gbx/gbx_c_error.c @@ -45,15 +45,15 @@ BEGIN_PROPERTY(CERROR_code) - GB_ReturnInt(ERROR_info.code); + GB_ReturnInt(ERROR_current->info.code); END_PROPERTY BEGIN_PROPERTY(CERROR_text) - if (ERROR_info.code) - GB_ReturnNewZeroString(ERROR_info.msg); + if (ERROR_current->info.code) + GB_ReturnNewZeroString(ERROR_current->info.msg); else GB_ReturnNull(); @@ -62,8 +62,8 @@ END_PROPERTY BEGIN_PROPERTY(CERROR_class) - if (ERROR_info.code) - GB_ReturnObject(ERROR_info.cp); + if (ERROR_current->info.code) + GB_ReturnObject(ERROR_current->info.cp); else GB_ReturnNull(); @@ -72,8 +72,8 @@ END_PROPERTY BEGIN_PROPERTY(CERROR_where) - if (ERROR_info.code) - GB_ReturnNewZeroString(DEBUG_get_position(ERROR_info.cp, ERROR_info.fp, ERROR_info.pc)); + if (ERROR_current->info.code) + GB_ReturnNewZeroString(DEBUG_get_position(ERROR_current->info.cp, ERROR_current->info.fp, ERROR_current->info.pc)); else GB_ReturnNull(); @@ -97,7 +97,7 @@ END_METHOD BEGIN_METHOD_VOID(CERROR_propagate) - if (ERROR_info.code) + if (ERROR_current->info.code) GAMBAS_Error = TRUE; END_METHOD @@ -105,7 +105,7 @@ END_METHOD BEGIN_PROPERTY(CERROR_backtrace) - DEBUG_BACKTRACE *bt = (DEBUG_BACKTRACE *)ERROR_info.backtrace; + DEBUG_BACKTRACE *bt = (DEBUG_BACKTRACE *)ERROR_current->info.backtrace; if (!bt) GB_ReturnNull(); diff --git a/main/gbx/gbx_class.c b/main/gbx/gbx_class.c index 93f02cb4f..e7b64185e 100644 --- a/main/gbx/gbx_class.c +++ b/main/gbx/gbx_class.c @@ -195,7 +195,7 @@ void CLASS_exit(void) fprintf(stderr, "\n------------------- CLASS_exit -------------------\n\n"); #endif - in_error = ERROR_info.code > 0; + in_error = ERROR_current != NULL; #if DEBUG_LOAD fprintf(stderr, "Freeing auto-creatable objects...\n"); @@ -258,7 +258,7 @@ void CLASS_exit(void) #endif /* On force la lib�ation de ce qui reste, tant pis */ - /* ERROR_info.code != 0 if we are exiting just after an error */ + /* ERROR_current->info.code != 0 if we are exiting just after an error */ if (n < nc) { diff --git a/main/gbx/gbx_eval.c b/main/gbx/gbx_eval.c index f9c43f861..40577d0ac 100644 --- a/main/gbx/gbx_eval.c +++ b/main/gbx/gbx_eval.c @@ -93,7 +93,7 @@ static bool EVAL_exec() //AP = ARCH_from_class(CP); EXEC_debug = debug; - return (ERROR_info.code != 0); + return (ERROR_current->info.code != 0); } diff --git a/main/gbx/gbx_exec.c b/main/gbx/gbx_exec.c index b6c2f8c7a..31ea78e39 100644 --- a/main/gbx/gbx_exec.c +++ b/main/gbx/gbx_exec.c @@ -72,6 +72,7 @@ EXEC_HOOK EXEC_Hook = { NULL }; EXEC_FUNCTION EXEC; bool EXEC_main_hook_done = FALSE; int EXEC_return_value = 0; +bool EXEC_got_error = FALSE; void EXEC_init(void) { @@ -711,7 +712,7 @@ void EXEC_function_real(bool keep_ret_value) CATCH { // QUIT was called - if (ERROR_info.code == E_ABORT) + if (ERROR->info.code == E_ABORT) { #if DEBUG_ERROR printf("#0 QUIT\n"); diff --git a/main/gbx/gbx_exec.h b/main/gbx/gbx_exec.h index a4f6ec3b5..3bd146ce5 100644 --- a/main/gbx/gbx_exec.h +++ b/main/gbx/gbx_exec.h @@ -98,7 +98,7 @@ EXTERN CENUM *EXEC_enum; EXTERN bool EXEC_big_endian; EXTERN bool EXEC_main_hook_done; EXTERN int EXEC_return_value; - +EXTERN bool EXEC_got_error; /*EXTERN long EXEC_const[];*/ #endif diff --git a/main/gbx/gbx_exec_loop.c b/main/gbx/gbx_exec_loop.c index 534a6d129..57852f44a 100644 --- a/main/gbx/gbx_exec_loop.c +++ b/main/gbx/gbx_exec_loop.c @@ -1535,11 +1535,8 @@ _END_TRY: #endif /* If EP was reset to null, then there was an error */ - if (EP) - { - ERROR_clear(); - EP = NULL; - } + EXEC_got_error = (EP == NULL); + EP = NULL; EC = ET; ET = NULL; goto _NEXT; diff --git a/main/gbx/gbx_subr_misc.c b/main/gbx/gbx_subr_misc.c index 80bfbb7a7..ec0301099 100644 --- a/main/gbx/gbx_subr_misc.c +++ b/main/gbx/gbx_subr_misc.c @@ -59,7 +59,7 @@ static void init_eval() void SUBR_error(void) { SP->type = T_BOOLEAN; - SP->_boolean.value = ERROR_info.code != 0 ? -1 : 0; + SP->_boolean.value = EXEC_got_error ? -1 : 0; SP++; } diff --git a/main/lib/db/CDatabase.c b/main/lib/db/CDatabase.c index 054dd0e4f..20e1cb9ec 100644 --- a/main/lib/db/CDatabase.c +++ b/main/lib/db/CDatabase.c @@ -165,7 +165,7 @@ BEGIN_METHOD(CDATABASE_add, GB_STRING name) CCONNECTION *conn = GB.SubCollection.Container(THIS); char *name = GB.ToZeroString(ARG(name)); - if (DB_CheckName(name, "database")) + if (DB_CheckNameWith(name, "database", conn->db.db_name_char)) return; if (check_database(conn, name, FALSE)) diff --git a/main/lib/db/gb.db.h b/main/lib/db/gb.db.h index 9410aea67..d919793a6 100644 --- a/main/lib/db/gb.db.h +++ b/main/lib/db/gb.db.h @@ -69,6 +69,7 @@ typedef int pos; /* position of 'limit' keyword */ } limit; + char *db_name_char; /* These characters are allowed in a database name */ } DB_DATABASE; diff --git a/main/share/gb_common.h b/main/share/gb_common.h index 4f7f34de0..43c366095 100644 --- a/main/share/gb_common.h +++ b/main/share/gb_common.h @@ -143,6 +143,17 @@ typedef #define Min(a, b) ({ int _a = (a), _b = (b); _a < _b ? _a : _b; }) #define MinMax(v, a, b) ({ int _v = (v), _a = (a), _b = (b); _v < _a ? _a : (_v > _b ? _b : _v); }) +#if (defined (__i386__) || defined (__x86_64__)) && defined (__GNUC__) && __GNUC__ >= 2 +# define BREAKPOINT() { __asm__ __volatile__ ("int $03"); } +#elif (defined (_MSC_VER) || defined (__DMC__)) && defined (_M_IX86) +# define BREAKPOINT() { __asm int 3h }G_STMT_END +#elif defined (__alpha__) && !defined(__osf__) && defined (__GNUC__) && __GNUC__ >= 2 +# define BREAKPOINT() { __asm__ __volatile__ ("bpt"); } +#else /* !__i386__ && !__alpha__ */ +# define BREAKPOINT() { raise (SIGTRAP); } +#endif /* __i386__ */ + + #define COPYRIGHT "(c) 2000-2007 Benoit Minisini\n\n" \ "This program is free software; you can redistribute it and/or \n" \ "modify it under the terms of the GNU General Public License as \n" \