X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Flily-parser-scheme.cc;h=83c3826dbdf7bf625f4becc951695b18e19a2d01;hb=9e69cb84d6ee5b0a861cd97869b10e3bdf0c833c;hp=212ca92e682b8e783323f6d820c2a1b972e22ec8;hpb=b37e3f652677ae0298423db9fa0e552e5fce0c92;p=lilypond.git diff --git a/lily/lily-parser-scheme.cc b/lily/lily-parser-scheme.cc index 212ca92e68..83c3826dbd 100644 --- a/lily/lily-parser-scheme.cc +++ b/lily/lily-parser-scheme.cc @@ -36,10 +36,10 @@ LY_DEFINE (ly_parse_file, "ly:parse-file", "Upon failure, throw @code{ly-file-failed} key.") { SCM_ASSERT_TYPE (scm_is_string (name), name, SCM_ARG1, __FUNCTION__, "string"); - char const *file = scm_i_string_chars (name); + string file = ly_scm2string (name); char const *extensions[] = {"ly", "", 0}; - std::string file_name = global_path.find (file, extensions); + string file_name = global_path.find (file, extensions); /* By default, use base name of input file for output file name, write output to cwd; do not use root and directory parts of input @@ -64,32 +64,42 @@ LY_DEFINE (ly_parse_file, "ly:parse-file", if (!output_name_global.empty ()) { + /* Interpret --output=DIR to mean --output=DIR/BASE. */ + string dir; if (is_dir (output_name_global)) { - char cwd[PATH_MAX]; - getcwd (cwd, PATH_MAX); - - if (output_name_global != cwd) + dir = output_name_global; + output_name_global = ""; + } + else + { + File_name out (output_name_global); + if (is_dir (out.dir_part ())) { - global_path.prepend (cwd); - message (_f ("Changing working directory to `%s'", - output_name_global.c_str ())); - chdir (output_name_global.c_str ()); + dir = out.dir_part (); + out_file_name = out.file_part (); } - output_name_global = ""; + } + + if (dir != "" && dir != "." && dir != get_working_directory ()) + { + global_path.prepend (get_working_directory ()); + message (_f ("Changing working directory to `%s'", + dir.c_str ())); + chdir (dir.c_str ()); } else out_file_name = File_name (output_name_global); } - std::string init; + string init; if (!init_name_global.empty ()) init = init_name_global; else init = "init.ly"; - std::string out_file = out_file_name.to_string (); + string out_file = out_file_name.to_string (); if (init.length () && global_path.find (init).empty ()) { @@ -99,18 +109,19 @@ LY_DEFINE (ly_parse_file, "ly:parse-file", exit (2); } - if ((file_name != "-") && global_path.find (file_name).empty ()) + + bool error = false; + if ((file_name != "-") && file_name.empty ()) { - warning (_f ("can't find file: `%s'", file_name)); - scm_throw (ly_symbol2scm ("ly-file-failed"), - scm_list_1 (scm_makfrom0str (file_name.c_str ()))); + warning (_f ("can't find file: `%s'", file)); + error = true; } else { Sources sources; sources.set_path (&global_path); - std::string mapped_fn = map_file_name (file_name); + string mapped_fn = map_file_name (file_name); message (_f ("Processing `%s'", mapped_fn.c_str ())); progress_indication ("\n"); @@ -118,14 +129,20 @@ LY_DEFINE (ly_parse_file, "ly:parse-file", parser->parse_file (init, file_name, out_file); - bool error = parser->error_level_; + error = parser->error_level_; + + parser->clear (); parser->unprotect (); - parser = 0; - if (error) - /* TODO: pass renamed input file too. */ - scm_throw (ly_symbol2scm ("ly-file-failed"), - scm_list_1 (scm_makfrom0str (file_name.c_str ()))); } + + /* + outside the if-else to ensure cleanup fo Sources object, + */ + if (error) + /* TODO: pass renamed input file too. */ + scm_throw (ly_symbol2scm ("ly-file-failed"), + scm_list_1 (scm_makfrom0str (file_name.c_str ()))); + return SCM_UNSPECIFIED; } @@ -146,7 +163,15 @@ LY_DEFINE (ly_parse_string, "ly:parse-string", return SCM_UNSPECIFIED; } -LY_DEFINE (ly_clone_parser, "ly:clone-parser", +LY_DEFINE (ly_parser_lexer, "ly:parser-lexer", + 1, 0, 0, (SCM parser_smob), + "Return the lexer for PARSER_SMOB.") +{ + Lily_parser *parser = unsmob_lily_parser (parser_smob); + return parser->lexer_->self_scm (); +} + +LY_DEFINE (ly_parser_clone, "ly:parser-clone", 1, 0, 0, (SCM parser_smob), "Return a clone of PARSER_SMOB.") { @@ -228,4 +253,20 @@ LY_DEFINE (ly_parser_output_name, "ly:parser-output-name", return scm_makfrom0str (p->output_basename_.c_str ()); } +LY_DEFINE (ly_parser_error, "ly:parser-error", + 2, 1, 0, (SCM parser, SCM msg, SCM input), + "Display an error message, and make the parser fail") +{ + Lily_parser *p = unsmob_lily_parser (parser); + SCM_ASSERT_TYPE (p, parser, SCM_ARG1, __FUNCTION__, "Lilypond parser"); + SCM_ASSERT_TYPE (scm_is_string (msg), msg, SCM_ARG2, __FUNCTION__, "string"); + string s = ly_scm2string (msg); + + Input *i = unsmob_input (input); + if (i) + p->parser_error (*i, s); + else + p->parser_error (s); + return parser; +}