/*! \brief Evaluate a Scheme expression safely. * \par Function Description * * Often a libgeda program (or libgeda itself) will need to call out * to Scheme code, for example to load a Scheme configuration file. * If an error or exception caused by such code goes uncaught, it * locks up the Scheme interpreter, stopping any further Scheme code * from being run until the program is restarted. * * This function is equivalent to scm_eval (), with the important * difference that any errors or exceptions caused by the evaluated * expression \a exp are caught and reported via the libgeda logging * mechanism. If an error occurs during evaluation, this function * returns SCM_BOOL_F. If \a module_or_state is undefined, uses the * current interaction environment. * * \param exp Expression to evaluate * \param module_or_state Environment in which to evaluate \a exp * * \returns Evaluation results or SCM_BOOL_F if exception caught. */ SCM g_scm_eval_protected (SCM exp, SCM module_or_state) { SCM stack = SCM_BOOL_T; SCM body_data; SCM result; if (module_or_state == SCM_UNDEFINED) { body_data = scm_list_2 (exp, scm_interaction_environment ()); } else { body_data = scm_list_2 (exp, module_or_state); } result = scm_c_catch (SCM_BOOL_T, protected_body_eval, /* catch body */ &body_data, /* body data */ protected_post_unwind_handler, /* post handler */ &stack, /* post data */ protected_pre_unwind_handler, /* pre handler */ &stack /* pre data */ ); scm_remember_upto_here_2 (body_data, stack); return result; }
/*! \brief Load a Scheme file, catching and logging errors. * \par Function Description * Loads \a filename, catching any uncaught errors and logging them. * * \bug Most other functions in the libgeda API return TRUE on success * and FALSE on failure. g_read_file() shouldn't be an exception. * * \param toplevel The TOPLEVEL structure. * \param filename The file name of the Scheme file to load. * \param err Return location for errors, or NULL. * \return TRUE on success, FALSE on failure. */ gboolean g_read_file(TOPLEVEL *toplevel, const gchar *filename, GError **err) { struct g_read_file_data_t data; g_return_val_if_fail ((filename != NULL), FALSE); data.stack = SCM_BOOL_F; data.filename = scm_from_utf8_string (filename); data.err = NULL; scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE); edascm_dynwind_toplevel (toplevel); scm_c_catch (SCM_BOOL_T, (scm_t_catch_body) g_read_file__body, &data, (scm_t_catch_handler) g_read_file__post_handler, &data, (scm_t_catch_handler) g_read_file__pre_handler, &data); scm_dynwind_end (); /* If no error occurred, indicate success. */ if (data.err == NULL) return TRUE; g_propagate_error (err, data.err); return FALSE; }
SCM xscm_c_resolve_module (const char *name) { SCM ret = scm_c_catch (SCM_BOOL_T, _xscm_c_resolve_module_safe_body, (void *) name, _xscm_false_error_handler, (void *) name, NULL, NULL); return ret; }
SCM xscm_c_eval_string (const gchar *string) { g_return_val_if_fail (string != NULL && strlen (string) > 0, SCM_BOOL_F); return scm_c_catch (SCM_BOOL_T, (scm_t_catch_body) scm_c_eval_string, (void *) string, (scm_t_catch_handler) eval_string_catch_handler, (void *) string, (scm_t_catch_handler) NULL, (void *) NULL); }
SCM xscm_c_primitive_load (const gchar *filename) { g_return_val_if_fail (filename != NULL && strlen (filename) > 0, SCM_BOOL_F); return scm_c_catch (SCM_BOOL_T, (scm_t_catch_body) scm_c_primitive_load, (void *) filename, (scm_t_catch_handler) primitive_load_catch_handler, (void *) filename, (scm_t_catch_handler) NULL, (void *) NULL); }
static void line_handler(char *line) { if (line == NULL) { running = 0; return; } add_history(line); scm_c_catch(SCM_BOOL_T, body_proc, (void *)line, catch_proc, "line handler", grab_stack, &captured_stack); free(line); return; }
static void * gdbscm_with_catch (void *data) { struct with_catch_data *d = data; d->catch_result = scm_c_catch (SCM_BOOL_T, d->func, d->data, d->unwind_handler, d, d->pre_unwind_handler, d); #if HAVE_GUILE_MANUAL_FINALIZATION scm_run_finalizers (); #endif return NULL; }
static void process_line(int fd) { int n; char linebuf[1024]; if (isatty(fd)) { rl_callback_read_char(); return; } n = read(fd, linebuf, sizeof(linebuf)); if (n == 0) { running = 0; return; } if (n < 0) { log_msg("err: %d, %s\n", errno, strerror(errno)); return; } linebuf[n] = '\0'; scm_c_catch(SCM_BOOL_T, body_proc, linebuf, catch_proc, "process line", grab_stack, &captured_stack); return; }
/** * load_scm_file: * @btn : le bouton [inutilisé] * @data : [inutilisé] * * Charge un fichier scm dans l'interprêteur * afin que les fonctions soit chargées globalement * pour toute la calculette */ void load_scm_file (GtkAction* btn, gpointer data) { GtkFileFilter *filter; GtkWidget *chooser; gchar *chemin = NULL; SCM result; chooser = gtk_file_chooser_dialog_new ("Ouvrir...", GTK_WINDOW(SCM_CALC (data)->window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); gtk_window_set_modal(GTK_WINDOW(chooser), TRUE); filter = gtk_file_filter_new (); gtk_file_filter_add_pattern (filter, "*.scm"); gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter); if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT) { chemin = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser)); result = scm_c_catch (SCM_BOOL_T, wrapper_body_proc, (gpointer) chemin, wrapper_handler_proc, NULL, NULL, NULL); g_free (chemin); } gtk_widget_destroy (chooser); }