]> git.donarmstrong.com Git - lilypond.git/commitdiff
catch GUILE errors
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 29 Jul 2002 16:00:21 +0000 (16:00 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 29 Jul 2002 16:00:21 +0000 (16:00 +0000)
ChangeLog
lily/include/lily-guile.hh
lily/include/parse-scm.hh [new file with mode: 0644]
lily/lexer.ll
lily/lily-guile.cc
lily/parse-scm.cc [new file with mode: 0644]

index 1b86e387abc8d11fd906b628bd39b07e0e910612..bfa215065af48b2e8fbf8e869a365ae9eea73721 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 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.
 
@@ -32,6 +35,8 @@
 
 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.
index e6286958601205ef37e975f2af5797e557083d3e..ed27782fb00408112e3fa35d57bb1151d0bdb5f1 100644 (file)
@@ -156,8 +156,8 @@ Interval ly_scm2interval (SCM);
 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) ;
diff --git a/lily/include/parse-scm.hh b/lily/include/parse-scm.hh
new file mode 100644 (file)
index 0000000..9a33271
--- /dev/null
@@ -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
index f6b0a40a4ad2c8a14043dff8a0a5517bc113fbae..cbaea6e8612dbec8cd7d0192a200b7a78e20c52e 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <iostream>
 
+#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 *);
+
 
 %}
 
index 7f4ceb80b086e67eeb5814b0fb53a28ac8bcf600..fd87823f56b8b696b0e14444b4c866ced767b1b8 100644 (file)
@@ -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 <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)
 {
diff --git a/lily/parse-scm.cc b/lily/parse-scm.cc
new file mode 100644 (file)
index 0000000..e5228d9
--- /dev/null
@@ -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 <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;  
+}
+