2 parse-scm -- Parse a single SCM expression exactly.
4 source file of the GNU LilyPond music typesetter
6 (c) 2004--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "parse-scm.hh"
14 #include "paper-book.hh"
15 #include "source-file.hh"
17 /* Pass string to scm parser, evaluate one expression.
18 Return result value and #chars read.
20 Thanks to Gary Houston <ghouston@freewire.co.uk> */
22 internal_ly_parse_scm (Parse_start
*ps
)
24 Source_file
*sf
= ps
->start_location_
.get_source_file ();
25 SCM port
= sf
->get_port ();
27 int off
= ps
->start_location_
.start () - sf
->to_str0 ();
29 scm_seek (port
, scm_long2num (off
), scm_long2num (SEEK_SET
));
30 SCM from
= scm_ftell (port
);
32 SCM answer
= SCM_UNSPECIFIED
;
33 SCM form
= scm_read (port
);
35 /* Read expression from port. */
36 if (!SCM_EOF_OBJECT_P (form
))
40 static SCM module
= SCM_BOOL_F
;
41 if (module
== SCM_BOOL_F
)
43 SCM function
= ly_lily_module_constant ("make-safe-lilypond-module");
44 module
= scm_call_0 (function
);
46 answer
= scm_eval (form
, module
);
49 answer
= scm_primitive_eval (form
);
52 /* Reset read_buf for scm_ftell.
53 Shouldn't scm_read () do this for us? */
54 scm_fill_input (port
);
55 SCM to
= scm_ftell (port
);
56 ps
->nchars
= scm_to_int (to
) - scm_to_int (from
);
58 /* Don't close the port here; if we re-enter this function via a
59 continuation, then the next time we enter it, we'll get an error.
60 It's a string port anyway, so there's no advantage to closing it
62 // scm_close_port (port);
68 catch_protected_parse_body (void *p
)
70 Parse_start
*ps
= (Parse_start
*) p
;
72 return internal_ly_parse_scm (ps
);
76 parse_handler (void *data
, SCM tag
, SCM args
)
78 Parse_start
*ps
= (Parse_start
*) data
;
81 ps
->start_location_
.error (_ ("GUILE signaled an error for the expression beginning here"));
83 if (scm_ilength (args
) > 2)
84 scm_display_error_message (scm_cadr (args
), scm_caddr (args
), scm_current_error_port ());
87 The following is a kludge; we should probably search for
88 [a-z][0-9] (a note), and start before that.
96 Do some magical incantations: if not, lily will exit on the first
97 GUILE error, leaving no location trace.
100 #if GUILE_MINOR_VERSION < 7
101 #define READ_ERROR "misc-error"
103 #define READ_ERROR "read-error"
107 protected_ly_parse_scm (Parse_start
*ps
)
109 return scm_internal_catch (ly_symbol2scm (READ_ERROR
),
110 &catch_protected_parse_body
,
112 &parse_handler
, (void *) ps
);
115 bool parse_protect_global
= true;
117 /* Try parsing. Upon failure return SCM_UNDEFINED.
118 FIXME: shouldn't we return SCM_UNSCPECIFIED -- jcn */
120 ly_parse_scm (char const *s
, int *n
, Input i
, bool safe
)
124 ps
.start_location_
= i
;
127 SCM ans
= parse_protect_global
? protected_ly_parse_scm (&ps
)
128 : internal_ly_parse_scm (&ps
);