2002-07-29 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ * lily/parse-scm.cc (protected_ly_parse_scm): catch GUILE errors
+ when parsing, and emit useful warning message.
+
* lily/lily-guile.cc (ly_parse_scm): add line/col/file locations
to SCM port for parser.
2002-07-26 Jan Nieuwenhuizen <janneke@gnu.org>
+ * VERSION: 1.5.70 released.
+
* Documentation/user/lilypond-book.itely (Insert music snippets
into your texts using lilypond-book): Briefly mention HTML
documents. Started rewrite, but lost inspiration.
Slice int_list_to_slice (SCM l);
SCM ly_interval2scm (Drul_array<Real>);
-struct Input;
-SCM ly_parse_scm (char const* s, int *, Input);
+
+
SCM ly_quote_scm (SCM s);
SCM ly_type (SCM);
bool type_check_assignment (SCM val, SCM sym, SCM type_symbol) ;
--- /dev/null
+
+#ifndef PARSE_SCM
+#define PARSE_SCM
+
+#include "input.hh"
+#include "lily-guile.hh"
+
+struct Parse_start
+{
+ char const* str;
+ int nchars;
+ Input start_location;
+};
+
+SCM catch_protected_parse_body (void *);
+SCM protected_ly_parse_scm (Parse_start *);
+
+SCM ly_parse_scm (char const* s, int *, Input);
+
+#endif
#include <iostream>
+#include "parse-scm.hh"
#include "score.hh"
#include "lily-guile.hh"
#include "string.hh"
SCM scan_fraction (String);
+SCM (* scm_parse_error_handler) (void *);
+
%}
}
-/*
- Pass string to scm parser, evaluate one expression.
- Return result value and #chars read.
-
- Thanks to Gary Houston <ghouston@freewire.co.uk>
-
- Need guile-1.3.4 (>1.3 anyway) for ftell on str ports -- jcn
-*/
-/*
- should move this func elsewhere (?)
- */
-SCM
-ly_parse_scm (char const* s, int* n, Input ip)
-{
- SCM str = ly_str02scm (s);
- SCM port = scm_mkstrport (SCM_INUM0, str, SCM_OPN | SCM_RDNG,
- "ly_eval_scm_0str");
-
- scm_set_port_filename_x (port, scm_makfrom0str (ip.file_string ().str0()));
- scm_set_port_line_x (port, gh_int2scm (ip.line_number ()));
- scm_set_port_column_x (port, gh_int2scm (ip.column_number()));
-
- SCM from = scm_ftell (port);
-
- SCM form;
- SCM answer = SCM_UNSPECIFIED;
-
- /* Read expression from port */
- if (!SCM_EOF_OBJECT_P (form = scm_read (port)))
- answer = scm_primitive_eval (form);
-
- /*
- After parsing
-
- (begin (foo 1 2))
-
- all seems fine, but after parsing
-
- (foo 1 2)
-
- read_buf has been advanced to read_pos - 1,
- so that scm_ftell returns 1, instead of #parsed chars
- */
-
- /*
- urg: reset read_buf for scm_ftell
- shouldn't scm_read () do this for us?
- */
- scm_fill_input (port);
- SCM to = scm_ftell (port);
- *n = gh_scm2int (to) - gh_scm2int (from);
-
- /* Don't close the port here; if we re-enter this function via a
- continuation, then the next time we enter it, we'll get an error.
- It's a string port anyway, so there's no advantage to closing it
- early.
-
- scm_close_port (port);
- */
-
- return answer;
-}
-
SCM
ly_quote_scm (SCM s)
{
--- /dev/null
+
+#include "lily-guile.hh"
+#include "parse-scm.hh"
+#include "string.hh"
+
+
+/*
+ Pass string to scm parser, evaluate one expression.
+ Return result value and #chars read.
+
+ Thanks to Gary Houston <ghouston@freewire.co.uk>
+
+ Need guile-1.3.4 (>1.3 anyway) for ftell on str ports -- jcn
+*/
+SCM
+internal_ly_parse_scm (Parse_start * ps)
+{
+ SCM str = ly_str02scm (ps->str);
+ SCM port = scm_mkstrport (SCM_INUM0, str, SCM_OPN | SCM_RDNG,
+ "ly_eval_scm_0str");
+
+ scm_set_port_filename_x (port, scm_makfrom0str (ps->start_location.file_string ().get_str0()));
+ scm_set_port_line_x (port, gh_int2scm (ps->start_location.line_number ()));
+ scm_set_port_column_x (port, gh_int2scm (ps->start_location.column_number()));
+
+ SCM from = scm_ftell (port);
+
+ SCM form;
+ SCM answer = SCM_UNSPECIFIED;
+
+ /* Read expression from port */
+ if (!SCM_EOF_OBJECT_P (form = scm_read (port)))
+ answer = scm_primitive_eval (form);
+
+ /*
+ After parsing
+
+ (begin (foo 1 2))
+
+ all seems fine, but after parsing
+
+ (foo 1 2)
+
+ read_buf has been advanced to read_pos - 1,
+ so that scm_ftell returns 1, instead of #parsed chars
+ */
+
+ /*
+ urg: reset read_buf for scm_ftell
+ shouldn't scm_read () do this for us?
+ */
+ scm_fill_input (port);
+ SCM to = scm_ftell (port);
+ ps->nchars = gh_scm2int (to) - gh_scm2int (from);
+
+ /* Don't close the port here; if we re-enter this function via a
+ continuation, then the next time we enter it, we'll get an error.
+ It's a string port anyway, so there's no advantage to closing it
+ early.
+
+ scm_close_port (port);
+ */
+
+ return answer;
+}
+
+
+SCM
+catch_protected_parse_body (void *p)
+{
+ Parse_start *ps = (Parse_start*) p;
+ return internal_ly_parse_scm (ps);
+}
+
+SCM
+parse_handler (void * data, SCM tag, SCM args)
+{
+ Parse_start* ps = (Parse_start*) data;
+
+ ps->start_location.error (_("GUILE signaled an error for the expression begining here"));
+
+ gh_display (args);
+ gh_newline();
+ return SCM_EOL;
+}
+
+/*
+ Do some magical incantations: if not, lily will exit on the first
+ GUILE error, leaving no location trace.
+ */
+SCM
+protected_ly_parse_scm (Parse_start *ps)
+{
+ return scm_internal_catch (scm_misc_error_key, &catch_protected_parse_body,
+ (void*)ps,
+ &parse_handler, (void*)ps);
+
+}
+
+
+SCM
+ly_parse_scm (char const* s, int *n, Input i)
+{
+ Parse_start ps ;
+ ps.str = s;
+ ps.start_location = i;
+
+ SCM ans = protected_ly_parse_scm (&ps);
+ *n = ps.nchars;
+ return ans;
+}
+