[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
This commit is contained in:
Benoît Minisini 2008-01-25 15:01:02 +00:00
parent 7cc9986bda
commit 9f4ee9e75e
17 changed files with 173 additions and 142 deletions

9
TODO
View File

@ -31,7 +31,6 @@ Do it asap:
- Structure support - Structure support
- Callback support - Callback support
- Sorting two or more arrays at the same time. - Sorting two or more arrays at the same time.
- Creates error objects for each error and not one for all.
DEVELOPMENT ENVIRONMENT DEVELOPMENT ENVIRONMENT
----------------------- -----------------------
@ -67,19 +66,12 @@ DATABASE COMPONENT
- Copy a result line into another one. - Copy a result line into another one.
- Use SAVEPOINT in postgresql to simulate nested transactions. - Use SAVEPOINT in postgresql to simulate nested transactions.
DOCUMENTATION WIKI DOCUMENTATION WIKI
------------------ ------------------
- Mass rename command. - Mass rename command.
- Fix last changes: only those in one language. - Fix last changes: only those in one language.
64 BITS
-------
- X11 Window datatype is a long => Control.Id should return a pointer
OTHER OTHER
----- -----
@ -89,5 +81,4 @@ COMPONENTS
---------- ----------
- gb.corba ? - gb.corba ?
- gb.v4l ?

View File

@ -612,6 +612,8 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db)
db->flags.no_blob = TRUE; db->flags.no_blob = TRUE;
db->flags.no_nest = TRUE; db->flags.no_nest = TRUE;
db->db_name_char = ".";
db->handle = conn; db->handle = conn;
return FALSE; return FALSE;
} }

View File

@ -711,6 +711,8 @@ static int open_database(DB_DESC * desc, DB_DATABASE * db)
db->flags.no_table_type = TRUE; db->flags.no_table_type = TRUE;
db->flags.no_nest = TRUE; db->flags.no_nest = TRUE;
db->db_name_char = ".";
db->handle = conn; db->handle = conn;
return FALSE; return FALSE;
} }

View File

@ -38,8 +38,11 @@
#include "gbx_exec.h" #include "gbx_exec.h"
#include "gbx_api.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 int _lock = 0;
static const char *_message[64] = static const char *_message[64] =
@ -110,7 +113,6 @@ static const char *_message[64] =
NULL NULL
}; };
static ERROR_CONTEXT *_current = NULL;
void ERROR_lock() void ERROR_lock()
@ -124,38 +126,90 @@ void ERROR_unlock()
_lock--; _lock--;
} }
static void ERROR_reset() static void ERROR_reset(ERROR_CONTEXT *err)
{ {
ERROR_info.code = 0; err->info.code = 0;
DEBUG_free_backtrace(&ERROR_info.backtrace); 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() void ERROR_clear()
{ {
if (_lock) if (_lock)
return; return;
ERROR_reset(); ERROR_reset(ERROR_current);
} }
void ERROR_enter(ERROR_CONTEXT *err) void ERROR_enter(ERROR_CONTEXT *err)
{ {
CLEAR(err); CLEAR(err);
err->prev = _current; err->prev = ERROR_current;
_current = err; 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) void ERROR_leave(ERROR_CONTEXT *err)
{ {
if (err->prev != ERROR_LEAVE_DONE) if (err->prev == ERROR_LEAVE_DONE)
return;
#if DEBUG_ERROR
fprintf(stderr, "<< ERROR_leave");
{ {
_current = err->prev; 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; 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) const char *ERROR_get(void)
{ {
/* /*
@ -170,54 +224,43 @@ const char *ERROR_get(void)
void ERROR_define(const char *pattern, char *arg[]) void ERROR_define(const char *pattern, char *arg[])
{ {
int n;
uchar c; uchar c;
boolean subst; boolean subst;
void _add_char(uchar c) void _add_char(uchar c)
{ {
if (n >= MAX_ERROR_MSG)
return;
if (c && c < ' ' && c != '\n') if (c && c < ' ' && c != '\n')
c = ' '; c = ' ';
ERROR_info.msg[n++] = c; STRING_add(&ERROR_current->info.msg, (char *)&c, 1);
} }
void _add_string(const char *s) void _add_string(const char *s)
{ {
if (!s) STRING_add(&ERROR_current->info.msg, s, 0);
s = "";
while (*s)
{
_add_char(*s);
s++;
}
} }
ERROR_clear(); ERROR_clear();
if ((intptr_t)pattern >= 0 && (intptr_t)pattern < 256) 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]; pattern = _message[(int)(intptr_t)pattern];
} }
else if ((intptr_t)pattern == E_ABORT) else if ((intptr_t)pattern == E_ABORT)
{ {
ERROR_info.code = E_ABORT; ERROR_current->info.code = E_ABORT;
pattern = ""; pattern = "";
} }
else else
ERROR_info.code = E_CUSTOM; ERROR_current->info.code = E_CUSTOM;
n = 0;
if (arg) if (arg)
{ {
subst = FALSE; subst = FALSE;
ERROR_current->info.free = TRUE;
for (;;) for (;;)
{ {
c = *pattern++; c = *pattern++;
@ -246,45 +289,23 @@ void ERROR_define(const char *pattern, char *arg[])
} }
else else
{ {
_add_string(pattern); ERROR_current->info.msg = (char *)pattern;
ERROR_current->info.free = FALSE;
} }
_add_char(0); _add_char(0);
ERROR_info.cp = CP; ERROR_current->info.cp = CP;
ERROR_info.fp = FP; ERROR_current->info.fp = FP;
ERROR_info.pc = PC; ERROR_current->info.pc = PC;
if (EXEC_debug || (CP && CP->debug)) if (EXEC_debug || (CP && CP->debug))
{ {
DEBUG_free_backtrace(&ERROR_info.backtrace); //DEBUG_free_backtrace(&ERROR_current->info.backtrace);
ERROR_info.backtrace = DEBUG_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, ...) void THROW(int code, ...)
{ {
va_list args; va_list args;
@ -347,7 +368,7 @@ void ERROR_panic(const char *error, ...)
); );
vfprintf(stderr, error, args); vfprintf(stderr, error, args);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
if (ERROR_info.code) if (ERROR_current->info.code)
{ {
fprintf(stderr, "\n"); fprintf(stderr, "\n");
ERROR_print(); ERROR_print();
@ -361,22 +382,22 @@ void ERROR_panic(const char *error, ...)
void ERROR_print_at(FILE *where, bool msgonly, bool newline) void ERROR_print_at(FILE *where, bool msgonly, bool newline)
{ {
if (!ERROR_info.code) if (!ERROR_current->info.code)
return; return;
if (!msgonly) if (!msgonly)
{ {
if (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_info.cp, ERROR_info.fp, ERROR_info.pc)); fprintf(where, "%s: ", DEBUG_get_position(ERROR_current->info.cp, ERROR_current->info.fp, ERROR_current->info.pc));
else else
fprintf(where, "ERROR: "); fprintf(where, "ERROR: ");
/*if (ERROR_info.code > 0 && ERROR_info.code < 256) /*if (ERROR_current->info.code > 0 && ERROR_current->info.code < 256)
fprintf(where, "%ld:", ERROR_info.code);*/ fprintf(where, "%ld:", ERROR_current->info.code);*/
if (ERROR_info.code > 0) if (ERROR_current->info.code > 0)
fprintf(where, "#%d: ", ERROR_info.code); fprintf(where, "#%d: ", ERROR_current->info.code);
} }
fprintf(where, "%s", ERROR_info.msg); fprintf(where, "%s", ERROR_current->info.msg);
if (newline) if (newline)
fputc('\n', where); fputc('\n', where);
} }
@ -385,7 +406,7 @@ void ERROR_print(void)
{ {
static bool lock = FALSE; static bool lock = FALSE;
DEBUG_BACKTRACE *bt = ERROR_info.backtrace; DEBUG_BACKTRACE *bt = ERROR_current->info.backtrace;
ERROR_print_at(stderr, FALSE, TRUE); ERROR_print_at(stderr, FALSE, TRUE);
@ -401,33 +422,35 @@ void ERROR_print(void)
{ {
lock = TRUE; lock = TRUE;
GAMBAS_DoNotRaiseEvent = 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; lock = FALSE;
} }
} }
void ERROR_save(ERROR_INFO *save) void ERROR_save(ERROR_INFO *save)
{ {
save->code = ERROR_info.code; *save = ERROR_current->info;
save->cp = ERROR_info.cp; ERROR_reset(ERROR_current);
save->fp = ERROR_info.fp; // save->code = ERROR_current->info.code;
save->pc = ERROR_info.pc; // save->cp = ERROR_current->info.cp;
save->backtrace = ERROR_info.backtrace; // save->fp = ERROR_current->info.fp;
ERROR_info.backtrace = NULL; // save->pc = ERROR_current->info.pc;
strlcpy(save->msg, ERROR_info.msg, sizeof(ERROR_info.msg)); // 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) void ERROR_restore(ERROR_INFO *save)
{ {
ERROR_reset(); ERROR_reset(ERROR_current);
ERROR_current->info = *save;
ERROR_info.code = save->code; // ERROR_current->info.code = save->code;
ERROR_info.cp = save->cp; // ERROR_current->info.cp = save->cp;
ERROR_info.cp = save->fp; // ERROR_current->info.cp = save->fp;
ERROR_info.pc = save->pc; // ERROR_current->info.pc = save->pc;
ERROR_info.backtrace = save->backtrace; // ERROR_current->info.backtrace = save->backtrace;
save->backtrace = NULL; // save->backtrace = NULL;
strlcpy(ERROR_info.msg, save->msg, sizeof(ERROR_info.msg)); // strlcpy(ERROR_current->info.msg, save->msg, sizeof(ERROR_current->info.msg));
} }

View File

@ -100,11 +100,13 @@ enum {
typedef typedef
struct { struct {
int code; short code;
bool free;
void *cp; void *cp;
void *fp; void *fp;
void *pc; void *pc;
char msg[MAX_ERROR_MSG + 1]; //char msg[MAX_ERROR_MSG + 1];
char *msg;
void *backtrace; void *backtrace;
} }
ERROR_INFO; ERROR_INFO;
@ -112,16 +114,16 @@ typedef
typedef typedef
struct _ERROR { struct _ERROR {
struct _ERROR *prev; struct _ERROR *prev;
int code;
jmp_buf env; jmp_buf env;
int ret;
ERROR_INFO info;
} }
ERROR_CONTEXT; ERROR_CONTEXT;
#ifndef __GB_ERROR_C #ifndef __GB_ERROR_C
EXTERN ERROR_INFO ERROR_info; EXTERN ERROR_CONTEXT *ERROR_current;
#endif #endif
#define ERROR_LEAVE_DONE ((ERROR_CONTEXT *)-1) #define ERROR_LEAVE_DONE ((ERROR_CONTEXT *)-1)
#define TRY \ #define TRY \
@ -129,27 +131,30 @@ EXTERN ERROR_INFO ERROR_info;
ERROR_CONTEXT __err_context; \ ERROR_CONTEXT __err_context; \
{ \ { \
ERROR_CONTEXT *__err = &__err_context; \ ERROR_CONTEXT *__err = &__err_context; \
/*fprintf(stderr, "TRY %s\n", __FUNCTION__);*/ \
ERROR_enter(__err); \ ERROR_enter(__err); \
__err->code = setjmp(__err->env); \ __err->ret = setjmp(__err->env); \
if (__err->code == 0) if (__err->ret == 0)
#define FINALLY
/*#define CATCH \
fprintf(stderr, "%p == %p ? %d\n", ERROR_current, __err, __err->ret); \
if (__err->ret != 0 && (__err->ret = 2))*/
#define CATCH \ #define CATCH \
if (__err->code != 0 && !(__err->code = 0)) /*if (__err->ret) fprintf(stderr, "CATCH %p\n", __err); \
if (__err->ret)*/ \
#define CATCH_GET(get_it) \ else
if (__err->code != 0 && (get_it = __err->code) && !(__err->code = 0))
#define END_TRY \ #define END_TRY \
if (__err->code == 0) \
ERROR_leave(__err); \ ERROR_leave(__err); \
else \ /*fprintf(stderr, "END TRY %s\n", __FUNCTION__);*/ \
PROPAGATE(); \
} \ } \
} }
//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 const char *ERROR_get(void);
PUBLIC void ERROR_enter(ERROR_CONTEXT *err); 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 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(int code, ...) NORETURN;
PUBLIC void THROW_SYSTEM(int err, const char *path); PUBLIC void THROW_SYSTEM(int err, const char *path);

View File

@ -113,7 +113,6 @@ static void main_exit()
EVENT_exit(); EVENT_exit();
FILE_exit(); FILE_exit();
STRING_exit(); STRING_exit();
ERROR_clear();
STACK_exit(); STACK_exit();
} }
@ -222,7 +221,7 @@ int main(int argc, char **argv)
} }
CATCH 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); ERROR_print_at(stderr, TRUE, TRUE);
main_exit(); main_exit();
_exit(1); _exit(1);
@ -321,7 +320,7 @@ int main(int argc, char **argv)
} }
else else
{ {
if (ERROR_info.code && ERROR_info.code != E_ABORT) if (ERROR->info.code && ERROR->info.code != E_ABORT)
ERROR_print(); ERROR_print();
main_exit(); main_exit();
_exit(1); _exit(1);
@ -358,7 +357,7 @@ int main(int argc, char **argv)
} }
CATCH CATCH
{ {
if (ERROR_info.code && ERROR_info.code != E_ABORT) if (ERROR->info.code && ERROR->info.code != E_ABORT)
{ {
if (EXEC_debug) if (EXEC_debug)
{ {
@ -376,7 +375,6 @@ int main(int argc, char **argv)
} }
END_TRY END_TRY
ERROR_info.code = 0;
main_exit(); main_exit();
if (MEMORY_count) if (MEMORY_count)

View File

@ -101,7 +101,7 @@ void *GAMBAS_Api[] =
(void *)GB_IsProperty, (void *)GB_IsProperty,
(void *)GB_Error, (void *)GB_Error,
(void *)PROPAGATE, (void *)ERROR_propagate,
(void *)GB_GetClass, (void *)GB_GetClass,
(void *)GB_GetClassName, (void *)GB_GetClassName,

View File

@ -45,15 +45,15 @@
BEGIN_PROPERTY(CERROR_code) BEGIN_PROPERTY(CERROR_code)
GB_ReturnInt(ERROR_info.code); GB_ReturnInt(ERROR_current->info.code);
END_PROPERTY END_PROPERTY
BEGIN_PROPERTY(CERROR_text) BEGIN_PROPERTY(CERROR_text)
if (ERROR_info.code) if (ERROR_current->info.code)
GB_ReturnNewZeroString(ERROR_info.msg); GB_ReturnNewZeroString(ERROR_current->info.msg);
else else
GB_ReturnNull(); GB_ReturnNull();
@ -62,8 +62,8 @@ END_PROPERTY
BEGIN_PROPERTY(CERROR_class) BEGIN_PROPERTY(CERROR_class)
if (ERROR_info.code) if (ERROR_current->info.code)
GB_ReturnObject(ERROR_info.cp); GB_ReturnObject(ERROR_current->info.cp);
else else
GB_ReturnNull(); GB_ReturnNull();
@ -72,8 +72,8 @@ END_PROPERTY
BEGIN_PROPERTY(CERROR_where) BEGIN_PROPERTY(CERROR_where)
if (ERROR_info.code) if (ERROR_current->info.code)
GB_ReturnNewZeroString(DEBUG_get_position(ERROR_info.cp, ERROR_info.fp, ERROR_info.pc)); GB_ReturnNewZeroString(DEBUG_get_position(ERROR_current->info.cp, ERROR_current->info.fp, ERROR_current->info.pc));
else else
GB_ReturnNull(); GB_ReturnNull();
@ -97,7 +97,7 @@ END_METHOD
BEGIN_METHOD_VOID(CERROR_propagate) BEGIN_METHOD_VOID(CERROR_propagate)
if (ERROR_info.code) if (ERROR_current->info.code)
GAMBAS_Error = TRUE; GAMBAS_Error = TRUE;
END_METHOD END_METHOD
@ -105,7 +105,7 @@ END_METHOD
BEGIN_PROPERTY(CERROR_backtrace) BEGIN_PROPERTY(CERROR_backtrace)
DEBUG_BACKTRACE *bt = (DEBUG_BACKTRACE *)ERROR_info.backtrace; DEBUG_BACKTRACE *bt = (DEBUG_BACKTRACE *)ERROR_current->info.backtrace;
if (!bt) if (!bt)
GB_ReturnNull(); GB_ReturnNull();

View File

@ -195,7 +195,7 @@ void CLASS_exit(void)
fprintf(stderr, "\n------------------- CLASS_exit -------------------\n\n"); fprintf(stderr, "\n------------------- CLASS_exit -------------------\n\n");
#endif #endif
in_error = ERROR_info.code > 0; in_error = ERROR_current != NULL;
#if DEBUG_LOAD #if DEBUG_LOAD
fprintf(stderr, "Freeing auto-creatable objects...\n"); fprintf(stderr, "Freeing auto-creatable objects...\n");
@ -258,7 +258,7 @@ void CLASS_exit(void)
#endif #endif
/* On force la lib<69>ation de ce qui reste, tant pis */ /* On force la lib<69>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) if (n < nc)
{ {

View File

@ -93,7 +93,7 @@ static bool EVAL_exec()
//AP = ARCH_from_class(CP); //AP = ARCH_from_class(CP);
EXEC_debug = debug; EXEC_debug = debug;
return (ERROR_info.code != 0); return (ERROR_current->info.code != 0);
} }

View File

@ -72,6 +72,7 @@ EXEC_HOOK EXEC_Hook = { NULL };
EXEC_FUNCTION EXEC; EXEC_FUNCTION EXEC;
bool EXEC_main_hook_done = FALSE; bool EXEC_main_hook_done = FALSE;
int EXEC_return_value = 0; int EXEC_return_value = 0;
bool EXEC_got_error = FALSE;
void EXEC_init(void) void EXEC_init(void)
{ {
@ -711,7 +712,7 @@ void EXEC_function_real(bool keep_ret_value)
CATCH CATCH
{ {
// QUIT was called // QUIT was called
if (ERROR_info.code == E_ABORT) if (ERROR->info.code == E_ABORT)
{ {
#if DEBUG_ERROR #if DEBUG_ERROR
printf("#0 QUIT\n"); printf("#0 QUIT\n");

View File

@ -98,7 +98,7 @@ EXTERN CENUM *EXEC_enum;
EXTERN bool EXEC_big_endian; EXTERN bool EXEC_big_endian;
EXTERN bool EXEC_main_hook_done; EXTERN bool EXEC_main_hook_done;
EXTERN int EXEC_return_value; EXTERN int EXEC_return_value;
EXTERN bool EXEC_got_error;
/*EXTERN long EXEC_const[];*/ /*EXTERN long EXEC_const[];*/
#endif #endif

View File

@ -1535,11 +1535,8 @@ _END_TRY:
#endif #endif
/* If EP was reset to null, then there was an error */ /* If EP was reset to null, then there was an error */
if (EP) EXEC_got_error = (EP == NULL);
{
ERROR_clear();
EP = NULL; EP = NULL;
}
EC = ET; EC = ET;
ET = NULL; ET = NULL;
goto _NEXT; goto _NEXT;

View File

@ -59,7 +59,7 @@ static void init_eval()
void SUBR_error(void) void SUBR_error(void)
{ {
SP->type = T_BOOLEAN; SP->type = T_BOOLEAN;
SP->_boolean.value = ERROR_info.code != 0 ? -1 : 0; SP->_boolean.value = EXEC_got_error ? -1 : 0;
SP++; SP++;
} }

View File

@ -165,7 +165,7 @@ BEGIN_METHOD(CDATABASE_add, GB_STRING name)
CCONNECTION *conn = GB.SubCollection.Container(THIS); CCONNECTION *conn = GB.SubCollection.Container(THIS);
char *name = GB.ToZeroString(ARG(name)); char *name = GB.ToZeroString(ARG(name));
if (DB_CheckName(name, "database")) if (DB_CheckNameWith(name, "database", conn->db.db_name_char))
return; return;
if (check_database(conn, name, FALSE)) if (check_database(conn, name, FALSE))

View File

@ -69,6 +69,7 @@ typedef
int pos; /* position of 'limit' keyword */ int pos; /* position of 'limit' keyword */
} }
limit; limit;
char *db_name_char; /* These characters are allowed in a database name */
} }
DB_DATABASE; DB_DATABASE;

View File

@ -143,6 +143,17 @@ typedef
#define Min(a, b) ({ int _a = (a), _b = (b); _a < _b ? _a : _b; }) #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); }) #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" \ #define COPYRIGHT "(c) 2000-2007 Benoit Minisini\n\n" \
"This program is free software; you can redistribute it and/or \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" \ "modify it under the terms of the GNU General Public License as \n" \