From: Han-Wen Nienhuys Date: Mon, 29 Jul 2002 16:00:21 +0000 (+0000) Subject: catch GUILE errors X-Git-Tag: release/1.5.72~86 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=38269bfebef7893a1bd82fd2182155f77a59e5a7;p=lilypond.git catch GUILE errors --- diff --git a/ChangeLog b/ChangeLog index 1b86e387ab..bfa215065a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2002-07-29 Han-Wen Nienhuys + * 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. @@ -32,6 +35,8 @@ 2002-07-26 Jan Nieuwenhuizen + * 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. diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh index e628695860..ed27782fb0 100644 --- a/lily/include/lily-guile.hh +++ b/lily/include/lily-guile.hh @@ -156,8 +156,8 @@ Interval ly_scm2interval (SCM); Slice int_list_to_slice (SCM l); SCM ly_interval2scm (Drul_array); -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) ; diff --git a/lily/include/parse-scm.hh b/lily/include/parse-scm.hh new file mode 100644 index 0000000000..9a33271b4e --- /dev/null +++ b/lily/include/parse-scm.hh @@ -0,0 +1,20 @@ + +#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 diff --git a/lily/lexer.ll b/lily/lexer.ll index f6b0a40a4a..cbaea6e861 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -28,6 +28,7 @@ #include +#include "parse-scm.hh" #include "score.hh" #include "lily-guile.hh" #include "string.hh" @@ -76,6 +77,8 @@ LYRICS ({AA}|{TEX})[^0-9 \t\n\f]* SCM scan_fraction (String); +SCM (* scm_parse_error_handler) (void *); + %} diff --git a/lily/lily-guile.cc b/lily/lily-guile.cc index 7f4ceb80b0..fd87823f56 100644 --- a/lily/lily-guile.cc +++ b/lily/lily-guile.cc @@ -80,69 +80,6 @@ ly_write2scm (SCM s) } -/* - Pass string to scm parser, evaluate one expression. - Return result value and #chars read. - - Thanks to Gary Houston - - 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) { diff --git a/lily/parse-scm.cc b/lily/parse-scm.cc new file mode 100644 index 0000000000..e5228d945c --- /dev/null +++ b/lily/parse-scm.cc @@ -0,0 +1,112 @@ + +#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 + + 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; +} +