Example #1
0
/*! \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;
}
Example #2
0
/*! \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;
}
Example #3
0
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;
}
Example #4
0
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);
}
Example #5
0
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);
}
Example #6
0
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;
	}
Example #7
0
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;
}
Example #8
0
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;
	}
Example #9
0
/**
 * 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);	
}