static SCM call_callable(SCM scm_args) { SCM stack = scm_make_stack(SCM_BOOL_T, SCM_EOL); SCM frame = scm_stack_ref(stack, scm_from_int(0)); SCM proc = scm_frame_procedure(frame); PyObject *callable = scm_to_pointer(scm_assq_ref(gsubr_alist, proc)); scm_dynwind_begin(0); PyObject *py_args = scm2py(scm_args); if (py_args == NULL) py2scm_exception(); /* does not return */ scm_dynwind_py_decref(py_args); struct call_callable_data data = { callable, py_args }; PyObject *py_result = (PyObject *)scm_without_guile( (void *(*)(void *))call_callable1, &data); if (py_result == NULL) py2scm_exception(); /* does not return */ scm_dynwind_py_decref(py_result); SCM scm_result = py2scm(py_result); scm_dynwind_end(); return scm_result; }
/*! \brief Process a Scheme error into the log and/or a GError * \par Function Description * Process a captured Guile exception with the given \a s_key and \a * s_args, and optionally the stack trace \a s_stack. The stack trace * and source location are logged, and if a GError return location \a * err is provided, it is populated with an informative error message. */ static void process_error_stack (SCM s_stack, SCM s_key, SCM s_args, GError **err) { char *long_message; char *short_message; SCM s_port, s_subr, s_message, s_message_args, s_rest, s_location; /* Split s_args up */ s_rest = s_args; s_subr = scm_car (s_rest); s_rest = scm_cdr (s_rest); s_message = scm_car (s_rest); s_rest = scm_cdr (s_rest); s_message_args = scm_car (s_rest); s_rest = scm_cdr (s_rest); /* Capture short error message */ s_port = scm_open_output_string (); scm_display_error_message (s_message, s_message_args, s_port); short_message = scm_to_utf8_string (scm_get_output_string (s_port)); scm_close_output_port (s_port); /* Capture long error message (including possible backtrace) */ s_port = scm_open_output_string (); if (scm_is_true (scm_stack_p (s_stack))) { scm_puts (_("\nBacktrace:\n"), s_port); scm_display_backtrace (s_stack, s_port, SCM_BOOL_F, SCM_BOOL_F); scm_puts ("\n", s_port); } s_location = SCM_BOOL_F; #ifdef HAVE_SCM_DISPLAY_ERROR_STACK s_location = s_stack; #endif /* HAVE_SCM_DISPLAY_ERROR_STACK */ #ifdef HAVE_SCM_DISPLAY_ERROR_FRAME s_location = scm_is_true (s_stack) ? scm_stack_ref (s_stack, SCM_INUM0) : SCM_BOOL_F; #endif /* HAVE_SCM_DISPLAY_ERROR_FRAME */ scm_display_error (s_location, s_port, s_subr, s_message, s_message_args, s_rest); long_message = scm_to_utf8_string (scm_get_output_string (s_port)); scm_close_output_port (s_port); /* Send long message to log */ s_log_message ("%s", long_message); /* Populate any GError */ g_set_error (err, EDA_ERROR, EDA_ERROR_SCHEME, "%s", short_message); }
/*! * \brief Get the name of the RC filename being evaluated. * \par Function Description * * Creates a Guile stack object, extracts the topmost frame from that * stack and gets the sourcefile name. * * \returns If the interpreter can resolve the filename, returns a * Scheme object with the full path to the RC file, otherwise #f */ SCM g_rc_rc_filename() { SCM stack, frame, source; stack = scm_make_stack (SCM_BOOL_T, SCM_EOL); if (scm_is_false (stack)) { return SCM_BOOL_F; } frame = scm_stack_ref (stack, scm_from_int(0)); if (scm_is_false (frame)) { return SCM_BOOL_F; } source = scm_frame_source (frame); if (scm_is_false (source)) { return SCM_BOOL_F; } return scm_source_property (source, scm_sym_filename); }