...
 
Commits (2)
  • Benoît Minisini's avatar
    Uncatched errors raised from an event handler can be ignored now. · 7a49f039
    Benoît Minisini authored
    [INTERPRETER]
    * NEW: Uncatched errors raised from an event handler can be ignored now.
    
    [GB.GTK]
    * NEW: Uncatched errors raised from an event handler can be ignored now.
    
    [GB.GTK3]
    * NEW: Uncatched errors raised from an event handler can be ignored now.
    
    [GB.QT4]
    * NEW: Uncatched errors raised from an event handler can be ignored now.
    
    [GB.QT5]
    * NEW: Uncatched errors raised from an event handler can be ignored now.
    7a49f039
  • Benoît Minisini's avatar
    Don't leak control reference when raising an error from a click event handler. · 8a188342
    Benoît Minisini authored
    [GB.GTK]
    * BUG: Don't leak control reference when raising an error from a click event handler.
    
    [GB.GTK3]
    * BUG: Don't leak control reference when raising an error from a click event handler.
    
    [GB.QT]
    * BUG: Don't leak control reference when raising an error from a click event handler.
    
    [GB.QT4]
    * BUG: Don't leak control reference when raising an error from a click event handler.
    8a188342
......@@ -29,13 +29,27 @@
DECLARE_EVENT(EVENT_Click);
static void _cleanup_gb_raise_button_Click(intptr_t object)
{
GB.Unref(POINTER(&object));
}
void gb_raise_button_Click(gControl *sender)
{
GB_RAISE_HANDLER handler;
CWIDGET *ob = GetObject(sender);
if (!ob) return;
GB.Ref(ob);
GB.Raise((void*)ob,EVENT_Click,0);
handler.callback = _cleanup_gb_raise_button_Click;
handler.data = (intptr_t)ob;
GB.RaiseBegin(&handler);
GB.Raise((void*)ob, EVENT_Click, 0);
GB.RaiseEnd(&handler);
CACTION_raise(ob);
GB.Unref(POINTER(&ob));
}
......
......@@ -100,11 +100,11 @@ dlg_btn;
static dlg_btn bt;
guint custom_dialog(const gchar *icon,GtkButtonsType btn,char *sg)
guint custom_dialog(const gchar *icon,GtkButtonsType btnbtn,char *sg)
{
GtkWidget *msg, *hrz, *label, *img;
GtkWidget *msg, *hrz, *label, *img, *vbox;
gint resp;
char *buf=NULL;
char *buf = NULL;
char *title;
if (bt.bt1) { gMnemonic_correctText(bt.bt1, &buf); bt.bt1 = buf; }
......@@ -119,12 +119,12 @@ guint custom_dialog(const gchar *icon,GtkButtonsType btn,char *sg)
msg = gtk_dialog_new_with_buttons(title, NULL,
GTK_DIALOG_MODAL,
bt.bt1, 1, bt.bt2, 2, bt.bt3, 3, (char *)NULL);
img = gtk_image_new_from_icon_name(icon,GTK_ICON_SIZE_DIALOG);
img = gtk_image_new_from_icon_name(icon, GTK_ICON_SIZE_DIALOG);
#else
msg = gtk_dialog_new_with_buttons(title, NULL,
(GtkDialogFlags)(GTK_DIALOG_MODAL+GTK_DIALOG_NO_SEPARATOR),
bt.bt1, 1, bt.bt2, 2, bt.bt3, 3, (char *)NULL);
img = gtk_image_new_from_stock(icon,GTK_ICON_SIZE_DIALOG);
img = gtk_image_new_from_stock(icon, GTK_ICON_SIZE_DIALOG);
#endif
label = gtk_label_new("");
......@@ -138,16 +138,21 @@ guint custom_dialog(const gchar *icon,GtkButtonsType btn,char *sg)
g_free(buf);
}
gtk_container_set_border_width(GTK_CONTAINER(msg), gDesktop::scale());
hrz = gtk_hbox_new(FALSE, gDesktop::scale());
gtk_container_set_border_width(GTK_CONTAINER(hrz), gDesktop::scale() * 2);
gtk_container_add (GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(msg))),hrz);
gtk_container_add (GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(msg))), hrz);
vbox = gtk_vbox_new(FALSE, gDesktop::scale());
gtk_container_add (GTK_CONTAINER(hrz), vbox);
gtk_box_set_child_packing(GTK_BOX(hrz), vbox, false, false, 0, GTK_PACK_START);
gtk_container_add (GTK_CONTAINER(hrz),img);
gtk_box_set_child_packing(GTK_BOX(hrz), img, false, false, 0, GTK_PACK_START);
gtk_container_add (GTK_CONTAINER(vbox), img);
gtk_box_set_child_packing(GTK_BOX(vbox), img, false, false, 0, GTK_PACK_START);
gtk_container_add (GTK_CONTAINER(hrz),label);
//gtk_box_set_child_packing(GTK_BOX(hrz), label, true, false, 0, GTK_PACK_END);
gtk_widget_show_all(hrz);
......@@ -177,85 +182,75 @@ guint custom_dialog(const gchar *icon,GtkButtonsType btn,char *sg)
int gMessage::showDelete(char *msg,char *btn1,char *btn2,char *btn3)
{
bt.bt1=MESSAGE_ok;
bt.bt2=NULL;
bt.bt3=NULL;
if (btn1) bt.bt1=btn1;
if (btn2) bt.bt2=btn2;
if (btn3) bt.bt3=btn3;
bt.bt1 = btn1 ? btn1 : GB.Translate(MESSAGE_ok);
bt.bt2 = btn2;
bt.bt3 = btn3;
return custom_dialog(
#ifdef GTK3
"user-trash",
#else
GTK_STOCK_DELETE,
#endif
GTK_BUTTONS_OK,msg);
GTK_BUTTONS_OK, msg);
}
int gMessage::showError(char *msg,char *btn1,char *btn2,char *btn3)
{
bt.bt1=MESSAGE_ok;
bt.bt2=NULL;
bt.bt3=NULL;
if (btn1) bt.bt1=btn1;
if (btn2) bt.bt2=btn2;
if (btn3) bt.bt3=btn3;
bt.bt1 = btn1 ? btn1 : GB.Translate(MESSAGE_ok);
bt.bt2 = btn2;
bt.bt3 = btn3;
return custom_dialog(
#ifdef GTK3
"dialog-error",
#else
GTK_STOCK_DIALOG_ERROR,
#endif
GTK_BUTTONS_OK,msg);
GTK_BUTTONS_OK, msg);
}
int gMessage::showInfo(char *msg,char *btn1)
int gMessage::showInfo(char *msg, char *btn1)
{
bt.bt1=MESSAGE_ok;
bt.bt2=NULL;
bt.bt3=NULL;
if (btn1) bt.bt1=btn1;
bt.bt1 = btn1 ? btn1 : GB.Translate(MESSAGE_ok);
return custom_dialog(
#ifdef GTK3
"dialog-information",
#else
GTK_STOCK_DIALOG_INFO,
#endif
GTK_BUTTONS_OK,msg);
GTK_BUTTONS_OK, msg);
}
int gMessage::showQuestion(char *msg,char *btn1,char *btn2,char *btn3)
int gMessage::showQuestion(char *msg, char *btn1, char *btn2, char *btn3)
{
bt.bt1=MESSAGE_ok;
bt.bt2=NULL;
bt.bt3=NULL;
if (btn1) bt.bt1=btn1;
if (btn2) bt.bt2=btn2;
if (btn3) bt.bt3=btn3;
bt.bt1 = btn1 ? btn1 : GB.Translate(MESSAGE_ok);
bt.bt2 = btn2;
bt.bt3 = btn3;
return custom_dialog(
#ifdef GTK3
"dialog-question",
#else
GTK_STOCK_DIALOG_QUESTION,
#endif
GTK_BUTTONS_OK,msg);
GTK_BUTTONS_OK, msg);
}
int gMessage::showWarning(char *msg,char *btn1,char *btn2,char *btn3)
{
bt.bt1=MESSAGE_ok;
bt.bt2=NULL;
bt.bt3=NULL;
if (btn1) bt.bt1=btn1;
if (btn2) bt.bt2=btn2;
if (btn3) bt.bt3=btn3;
bt.bt1 = btn1 ? btn1 : GB.Translate(MESSAGE_ok);
bt.bt2 = btn2;
bt.bt3 = btn3;
return custom_dialog(
#ifdef GTK3
"dialog-warning",
#else
GTK_STOCK_DIALOG_WARNING,
#endif
GTK_BUTTONS_OK,msg);
GTK_BUTTONS_OK, msg);
}
char *gMessage::title()
......@@ -268,7 +263,7 @@ void gMessage::setTitle(char *title)
if (MESSAGE_title)
{
g_free(MESSAGE_title);
MESSAGE_title=NULL;
MESSAGE_title = NULL;
}
if (title && *title)
......
......@@ -80,15 +80,15 @@ GB_CLASS CLASS_Window;
GB_CLASS CLASS_Printer;
GB_CLASS CLASS_SvgImage;
static void my_lang(char *lang,int rtl1);
static void my_error(int code,char *error,char *where);
static void my_quit (void);
static void my_main(int *argc, char ***argv);
static void my_timer(GB_TIMER *timer,bool on);
static void my_wait(int duration);
static void my_post(void);
static int my_loop();
static void my_watch(int fd, int type, void *callback, intptr_t param);
static void hook_lang(char *lang, int rtl1);
static bool hook_error(int code, char *error, char *where, bool can_ignore);
static void hook_quit(void);
static void hook_main(int *argc, char ***argv);
static void hook_timer(GB_TIMER *timer,bool on);
static void hook_wait(int duration);
static void hook_post(void);
static int hook_loop();
static void hook_watch(int fd, int type, void *callback, intptr_t param);
static GtkWidget *GTK_CreateGLArea(void *_object, void *parent, void (*init)(GtkWidget *));
......@@ -206,15 +206,15 @@ int EXPORT GB_INIT(void)
if (env && atoi(env))
MAIN_debug_busy = true;
GB.Hook(GB_HOOK_QUIT, (void *)my_quit);
_old_hook_main = GB.Hook(GB_HOOK_MAIN, (void *)my_main);
GB.Hook(GB_HOOK_WAIT, (void *)my_wait);
GB.Hook(GB_HOOK_TIMER,(void *)my_timer);
GB.Hook(GB_HOOK_WATCH,(void *)my_watch);
GB.Hook(GB_HOOK_POST,(void*)my_post);
GB.Hook(GB_HOOK_ERROR,(void*)my_error);
GB.Hook(GB_HOOK_LANG,(void*)my_lang);
GB.Hook(GB_HOOK_LOOP, (void *)my_loop);
GB.Hook(GB_HOOK_QUIT, (void *)hook_quit);
_old_hook_main = GB.Hook(GB_HOOK_MAIN, (void *)hook_main);
GB.Hook(GB_HOOK_WAIT, (void *)hook_wait);
GB.Hook(GB_HOOK_TIMER,(void *)hook_timer);
GB.Hook(GB_HOOK_WATCH,(void *)hook_watch);
GB.Hook(GB_HOOK_POST,(void*)hook_post);
GB.Hook(GB_HOOK_ERROR,(void*)hook_error);
GB.Hook(GB_HOOK_LANG,(void*)hook_lang);
GB.Hook(GB_HOOK_LOOP, (void *)hook_loop);
GB.Component.Load("gb.draw");
GB.Component.Load("gb.image");
......@@ -245,7 +245,7 @@ int EXPORT GB_INIT(void)
g_type_init();
#endif /* !defined(GLIB_VERSION_2_36) */
my_lang(GB.System.Language(), GB.System.IsRightToLeft());
hook_lang(GB.System.Language(), GB.System.IsRightToLeft());
return -1;
}
......@@ -336,7 +336,7 @@ void EXPORT GB_SIGNAL(int signal, void *param)
} // extern "C"
void my_quit (void)
void hook_quit (void)
{
GB_FUNCTION func;
......@@ -370,7 +370,7 @@ static bool global_key_event_handler(int type)
return GB.Stopped();
}
static void my_main(int *argc, char ***argv)
static void hook_main(int *argc, char ***argv)
{
static bool init = false;
char *env;
......@@ -425,7 +425,7 @@ typedef
}
MyTimerId;
gboolean my_timer_function(GB_TIMER *timer)
gboolean hook_timer_function(GB_TIMER *timer)
{
if (timer->id)
{
......@@ -441,8 +441,8 @@ gboolean my_timer_function(GB_TIMER *timer)
next = 10;
id->timeout = next;
g_timer_start(t);
id->source = g_timeout_add(next, (GSourceFunc)my_timer_function,(gpointer)timer);
//timer->id = (intptr_t)g_timeout_add(next, (GSourceFunc)my_timer_function,(gpointer)timer);
id->source = g_timeout_add(next, (GSourceFunc)hook_timer_function,(gpointer)timer);
//timer->id = (intptr_t)g_timeout_add(next, (GSourceFunc)hook_timer_function,(gpointer)timer);
//fprintf(stderr, "elapsed = %d delay = %d next = %d\n", elapsed, timer->delay, next);
}
}
......@@ -450,7 +450,7 @@ gboolean my_timer_function(GB_TIMER *timer)
return false;
}
static void my_timer(GB_TIMER *timer,bool on)
static void hook_timer(GB_TIMER *timer,bool on)
{
if (timer->id)
{
......@@ -466,13 +466,13 @@ static void my_timer(GB_TIMER *timer,bool on)
MyTimerId *id = g_new(MyTimerId, 1);
id->timer = g_timer_new();
id->timeout = timer->delay;
id->source = (intptr_t)g_timeout_add(timer->delay,(GSourceFunc)my_timer_function,(gpointer)timer);
id->source = (intptr_t)g_timeout_add(timer->delay,(GSourceFunc)hook_timer_function,(gpointer)timer);
timer->id = (intptr_t)id;
return;
}
}
static void my_post(void)
static void hook_post(void)
{
_post_check = true;
}
......@@ -482,7 +482,7 @@ void MAIN_check_quit()
_must_check_quit = true;
}
static int my_loop()
static int hook_loop()
{
gControl::cleanRemovedControls();
_must_check_quit = true;
......@@ -500,12 +500,12 @@ static int my_loop()
MAIN_do_iteration(false);
}
my_quit();
hook_quit();
return 0;
}
static void my_wait(int duration)
static void hook_wait(int duration)
{
if (gDrawingArea::inAnyDrawEvent())
{
......@@ -526,27 +526,32 @@ static void my_wait(int duration)
MAIN_do_iteration(true, true);
}
static void my_watch(int fd, int type, void *callback, intptr_t param)
static void hook_watch(int fd, int type, void *callback, intptr_t param)
{
CWatcher::Add(fd,type,callback,param);
}
static void my_error(int code,char *error,char *where)
static bool hook_error(int code, char *error, char *where, bool can_ignore)
{
char *showstr;
char scode[10];
bool ignore = FALSE;
sprintf(scode,"%d",code);
sprintf(scode, "%d", code);
showstr=g_strconcat("<b>This application has raised an unexpected<br>error and must abort.</b><p>[", scode, "] ", error, ".\n", where, (void *)NULL);
showstr = g_strconcat("<b>This application has raised an unexpected<br>error and must abort.</b>\n\n[", scode, "] ", error, ".\n\n<tt>", where, "</tt>", (void *)NULL);
gMessage::setTitle(GB.Application.Title());
gMessage::showError(showstr,NULL,NULL,NULL);
if (can_ignore)
ignore = gMessage::showError(showstr, GB.Translate("Ignore"), GB.Translate("Close"), NULL) == 1;
else
gMessage::showError(showstr, NULL, NULL, NULL);
g_free(showstr);
return ignore;
}
static void my_lang(char *lang, int rtl)
static void hook_lang(char *lang, int rtl)
{
int i, n;
gControl *iter;
......
......@@ -879,6 +879,29 @@ bool CWIDGET_is_design(CWIDGET *_object)
return CWIDGET_test_flag(THIS, WF_DESIGN) || CWIDGET_test_flag(THIS, WF_DESIGN_LEADER);
}
static void _cleanup_CWIDGET_raise_event_action(intptr_t object)
{
GB.Unref(POINTER(&object));
}
void CWIDGET_raise_event_action(void *object, int event)
{
GB_RAISE_HANDLER handler;
GB.Ref(object);
handler.callback = _cleanup_CWIDGET_raise_event_action;
handler.data = (intptr_t)object;
GB.RaiseBegin(&handler);
GB.Raise(object, event, 0);
GB.RaiseEnd(&handler);
CACTION_raise(object);
GB.Unref(POINTER(&object));
}
//---------------------------------------------------------------------------
BEGIN_METHOD_VOID(Control_new)
......
......@@ -163,10 +163,7 @@ DECLARE_PROPERTY(Control_Mouse);
if (_object == NULL) \
return; \
\
GB.Ref(_object); \
GB.Raise(_object, _event, 0); \
CACTION_raise(_object); \
GB.Unref(POINTER(&_object)); \
CWIDGET_raise_event_action(_object, _event); \
}
......@@ -232,6 +229,7 @@ void CWIDGET_set_allow_focus(void *_object, bool f);
bool CWIDGET_is_design(CWIDGET *_object);
void CWIDGET_check_visibility(CWIDGET *_object);
void CWIDGET_check_hovered();
void CWIDGET_raise_event_action(void *control, int event);
#ifndef DO_NOT_DECLARE_EVENTS
#ifndef __CWIDGET_CPP
......
......@@ -1087,9 +1087,10 @@ static void hook_post(void)
}
static void hook_error(int code, char *error, char *where)
static bool hook_error(int code, char *error, char *where, bool in_event_loop)
{
QString msg;
int ret;
qApp->restoreOverrideCursor();
while (qApp->activePopupWidget())
......@@ -1100,23 +1101,23 @@ static void hook_error(int code, char *error, char *where)
if (code > 0)
{
msg = msg + "[%1] %2.<br>%3";
msg = msg + "[%1] %2.<br><br><tt>%3</tt>";
msg = msg.arg(code).arg(TO_QSTRING(error)).arg(where);
}
else
{
msg = msg + "%1.<br>%2";
msg = msg + "%1.<br><br><tt>%2</tt>";
msg = msg.arg(TO_QSTRING(error)).arg(where);
}
release_grab();
MAIN_in_message_box++;
QMessageBox::critical(0, TO_QSTRING(GB.Application.Name()), msg);
ret = QMessageBox::critical(0, TO_QSTRING(GB.Application.Name()), msg, in_event_loop ? QMessageBox::Close | QMessageBox::Ignore : QMessageBox::Ok);
MAIN_in_message_box--;
unrelease_grab();
MAIN_check_quit();
//qApp->exit();
return ret == QMessageBox::Ignore;
}
static void QT_Init(void)
......
......@@ -54,7 +54,7 @@ gbx3_SOURCES = \
gbx_watch.h gbx_watch.c \
gbx_expression.h gbx_eval.h gbx_eval.c \
gbx_compare.h gbx_compare.c \
gbx.c \
gbx.c gbx.h \
gbx_number.h gbx_number.c \
gbx_object.h gbx_object.c \
gbx_variant.h \
......
......@@ -33,6 +33,7 @@
#include "gbx_api.h"
#include "gbx_stack.h"
#include "gbx_project.h"
#include "gbx.h"
#include "gb_error.h"
//#define DEBUG_ERROR 1
......@@ -580,7 +581,7 @@ void ERROR_panic(const char *error, ...)
{
fprintf(stderr, "** \n");
_print_prefix = "** ";
ERROR_print();
ERROR_print(FALSE);
_print_prefix = NULL;
}
fprintf(stderr, "** \n** Please send a bug report to the gambas bugtracker [1] or to the gambas mailing-list [2].\n** [1] http://gambaswiki.org/bugtracker\n** [2] https://lists.gambas-basic.org/listinfo/user\n** \n\n");
......@@ -632,17 +633,10 @@ void ERROR_print_at(FILE *where, bool msgonly, bool newline)
fputc('\n', where);
}
void ERROR_print(void)
bool ERROR_print(bool can_ignore)
{
static bool lock = FALSE;
if (EXEC_main_hook_done && !EXEC_debug && EXEC_Hook.error && !lock)
{
lock = TRUE;
GAMBAS_DoNotRaiseEvent = TRUE;
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;
}
bool ignore = FALSE;
ERROR_print_at(stderr, FALSE, TRUE);
......@@ -651,6 +645,17 @@ void ERROR_print(void)
print_prefix(stderr);
DEBUG_print_backtrace(ERROR_backtrace);
}
if (EXEC_main_hook_done && !EXEC_debug && EXEC_Hook.error && !lock)
{
lock = TRUE;
GAMBAS_DoNotRaiseEvent = TRUE;
ignore = 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), can_ignore);
GAMBAS_DoNotRaiseEvent = !ignore;
lock = FALSE;
}
return ignore;
}
static void ERROR_copy(ERROR_INFO *save, ERROR_INFO *last)
......
......@@ -169,7 +169,7 @@ void ERROR_fatal(const char *error, ...) NORETURN;
void ERROR_panic(const char *error, ...) NORETURN;
void ERROR_warning(const char *warning, ...);
void ERROR_print(void);
bool ERROR_print(bool);
void ERROR_print_at(FILE *where, bool msgonly, bool newline);
void ERROR_hook(void);
......
......@@ -62,6 +62,7 @@
#include "gbx_c_file.h"
#include "gbx_c_application.h"
#include "gbx.h"
extern void _exit(int) NORETURN;
FILE *log_file;
......@@ -115,7 +116,7 @@ static void init(const char *file, int argc, char **argv)
}
static void main_exit(bool silent)
void main_exit(bool silent)
{
silent |= EXEC_task;
......@@ -162,6 +163,14 @@ static void main_exit(bool silent)
STRING_exit();
}
void MAIN_exit(bool silent, int ret)
{
main_exit(silent);
_exit(ret);
}
static bool is_option(const char *arg, char option)
{
return (arg[0] == '-' && arg[1] == option && arg[2] == 0);
......@@ -298,13 +307,11 @@ int main(int argc, char *argv[])
{
if (ERROR_current->info.code && ERROR_current->info.code != E_ABORT)
ERROR_print_at(stderr, TRUE, TRUE);
main_exit(TRUE);
_exit(1);
MAIN_exit(TRUE, 1);
}
END_TRY
main_exit(FALSE);
_exit(0);
MAIN_exit(FALSE, 0);
}
for (i = 1; i < argc; i++)
......@@ -412,15 +419,13 @@ int main(int argc, char *argv[])
if (!_welcome)
DEBUG.Main(TRUE);
DEBUG.Main(TRUE);
main_exit(FALSE);
_exit(0);
MAIN_exit(FALSE, 0);
}
else
{
if (ERROR->info.code && ERROR->info.code != E_ABORT)
ERROR_print();
main_exit(TRUE);
_exit(1);
ERROR_print(FALSE);
MAIN_exit(TRUE, 1);
}
}
END_TRY
......@@ -438,8 +443,7 @@ int main(int argc, char *argv[])
if (_quit_after_main)
{
main_exit(TRUE);
_exit(0);
MAIN_exit(TRUE, 0);
}
if (!ret)
......@@ -459,14 +463,12 @@ int main(int argc, char *argv[])
if (EXEC_debug)
{
DEBUG.Main(TRUE);
main_exit(TRUE);
_exit(0);
MAIN_exit(TRUE, 0);
}
else
{
ERROR_print();
main_exit(TRUE);
_exit(1);
ERROR_print(FALSE);
MAIN_exit(TRUE, 1);
}
}
......
/***************************************************************************
gbx.h
(c) 2000-2019 Benoît Minisini <g4mba5@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
***************************************************************************/
#ifndef __GBX_H
#define __GBX_H
void MAIN_exit(bool silent, int ret);
#endif
......@@ -63,7 +63,7 @@
#include "gbx_struct.h"
#include "gbx_signal.h"
#include "gbx_jit.h"
#include "gbx.h"
#include "gambas.h"
#include "gbx_api.h"
......@@ -800,7 +800,31 @@ static bool raise_event(OBJECT *observer, void *object, int func_id, int nparam)
stop_event = GAMBAS_StopEvent;
GAMBAS_StopEvent = FALSE;
EXEC_public_desc(class, observer, desc, nparam);
TRY
{
EXEC_public_desc(class, observer, desc, nparam);
}
CATCH
{
if (ERROR->info.code && ERROR->info.code != E_ABORT)
{
ERROR_hook();
if (EXEC_debug)
{
DEBUG.Main(TRUE);
MAIN_exit(TRUE, 0);
}
else
{
if (!ERROR_print(TRUE))
MAIN_exit(TRUE, 1);
}
}
else
PROPAGATE();
}
END_TRY
if (RP->type == T_VOID)
result = FALSE;
......
......@@ -47,28 +47,21 @@
//#define DEBUG_STACK 1
//#define SHOW_FUNCTION 1
/* Current virtual machine state */
STACK_CONTEXT EXEC_current = { 0 };
/* Stack pointer */
VALUE *SP = NULL;
/* Temporary storage or return value of a native function */
VALUE TEMP;
/* Return value of a gambas function */
VALUE RET;
/* SUPER was used for this stack pointer */
VALUE *EXEC_super = NULL;
/* CPU endianness */
bool EXEC_big_endian;
/* Current iterator */
CENUM *EXEC_enum;
STACK_CONTEXT EXEC_current = { 0 }; // Current virtual machine state
VALUE *SP = NULL; // Stack pointer
VALUE TEMP; // Temporary storage or return value of a native function
VALUE RET; // Return value of a gambas function
VALUE *EXEC_super = NULL; // SUPER was used for this stack pointer
bool EXEC_big_endian; // CPU endianness
CENUM *EXEC_enum; // Current iterator
const char *EXEC_profile_path = NULL; // profile file path
const char *EXEC_fifo_name = NULL; // fifo name
EXEC_HOOK EXEC_Hook = { NULL };
EXEC_GLOBAL EXEC;
uint64_t EXEC_byref = 0;
uchar EXEC_quit_value = 0;
unsigned char EXEC_quit_value = 0; // interpreter return value
bool EXEC_debug = FALSE; // debugging mode
bool EXEC_task = FALSE; // I am a background task
bool EXEC_profile = FALSE; // profiling mode
......@@ -80,6 +73,7 @@ bool EXEC_string_add = FALSE; // next '&' operator is done for a '&='
bool EXEC_main_hook_done = FALSE;
bool EXEC_got_error = FALSE;
bool EXEC_break_on_error = FALSE; // if we must break into the debugger as soon as there is an error.
bool EXEC_in_event_loop = FALSE; // if we are in the event loop
const char EXEC_should_borrow[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2, 0, 0, 1 };
......
......@@ -68,7 +68,7 @@ typedef
void (*watch)();
void (*post)();
void (*quit)();
void (*error)();
bool (*error)();
double (*timeout)();
}
EXEC_HOOK;
......@@ -103,6 +103,7 @@ extern const char *EXEC_fifo_name;
extern bool EXEC_keep_library;
extern bool EXEC_string_add;
extern bool EXEC_break_on_error;
extern bool EXEC_in_event_loop;
extern EXEC_HOOK EXEC_Hook;
......