#include "std-string.hh"
-void error (string s);
-void message (string s);
-void non_fatal_error (string);
-void programming_error (string s);
-void progress_indication (string s);
-void warning (string s);
-void successful (string s);
+/* Log-level bitmasks */
+#define LOG_NONE 0
+#define LOG_ERROR 1<<0
+#define LOG_WARN 1<<1
+#define LOG_BASIC 1<<2 // undocumented basic_progress, i.e. input file name and success
+#define LOG_PROGRESS 1<<3
+// Currently, there is no separation between progress and other info messages:
+#define LOG_INFO 1<<4
+#define LOG_DEBUG 1<<8
+
+/* Log-level definitions (or'ed bitmasks) */
+#define LOGLEVEL_NONE (LOG_NONE)
+#define LOGLEVEL_ERROR (LOG_ERROR)
+#define LOGLEVEL_WARN (LOGLEVEL_ERROR | LOG_WARN)
+#define LOGLEVEL_BASIC (LOGLEVEL_WARN | LOG_BASIC)
+#define LOGLEVEL_PROGRESS (LOGLEVEL_BASIC | LOG_PROGRESS)
+// Currently, there is no separation between progress and other info messages:
+#define LOGLEVEL_INFO (LOGLEVEL_PROGRESS | LOG_INFO)
+#define LOGLEVEL_DEBUG (LOGLEVEL_INFO | LOG_DEBUG)
+
+extern int loglevel;
+
+/* output messages, in decreasing order of importance */
+void error (string s, string location = ""); // Fatal error, exits lilypond!
+void programming_error (string s, string location = "");
+void non_fatal_error (string, string location = "");
+void warning (string s, string location = "");
+void successful (string s, string location = "");
+/* progress_indication does by default *NOT* start on a new line */
+void progress_indication (string s, bool newline = false, string location = "");
+void message (string s, bool newline = true, string location = "");
+void debug_output (string s, bool newline = true, string location = "");
+
+/* Helper functions that always print out the message. Callers should ensure
+ that the loglevel is obeyed */
+void print_message (int level, string location, string s, bool newline = true);
+
+bool is_loglevel (int level);
+void set_loglevel (int level);
+void set_loglevel (string level);
#endif /* WARN_HH */
using namespace std;
-/* Is progress indication at NEWLINE? */
-static bool progress_newline = true;
+/** We have several different loglevels, each with its own message function(s):
+ ERROR: error, non_fatal_error, programming_error
+ WARN: warning
+ BASIC_PROGRESS: success/...
+ PROGRESS: progress_indication
+ INFO: message
+ DEBUG: debug
+ All these functions check whether the corresponding loglevel bit is set
+ and print the message only if that's the case
+*/
+
+/* Define the loglevel (default is PROGRESS); for now, PROGRESS=INFO for a
+ all relevant output, so be on the safe side and use INFO as default, just
+ in case some output is generated with INFO */
+int loglevel = LOGLEVEL_INFO;
+
+bool
+is_loglevel (int level)
+{
+ // Check the bitmask containing the loglevel
+ return (loglevel & level);
+}
+
+void
+set_loglevel (int level)
+{
+ loglevel = level;
+ debug_output (_f ("Log level set to %d\n", loglevel));
+}
+
+void
+set_loglevel (string level)
+{
+ /* Convert the loglevel string to lower-case, so we allow
+ both upper- and lower-case loglevels */
+ std::transform (level.begin (), level.end (), level.begin (), ::tolower);
+
+ /* Compare just the first few characters, so the loglevels
+ can be abbreviated */
+ if (level.compare (0, 5, "debug") == 0) // debug
+ set_loglevel (LOGLEVEL_DEBUG);
+ else if (level.compare (0, 4, "info") == 0) // info
+ set_loglevel (LOGLEVEL_INFO);
+ else if (level.compare (0, 4, "prog") == 0) // progress
+ set_loglevel (LOGLEVEL_PROGRESS);
+ else if (level.compare (0, 5, "basic") == 0) // basic progress
+ set_loglevel (LOGLEVEL_BASIC);
+ else if (level.compare (0, 4, "warn") == 0) // warning
+ set_loglevel (LOGLEVEL_WARN);
+ else if (level.compare (0, 3, "err") == 0) // error
+ set_loglevel (LOGLEVEL_ERROR);
+ else if (level.compare (0, 4, "none") == 0) // none
+ set_loglevel (LOGLEVEL_NONE);
+ else
+ {
+ int l;
+ if (sscanf (level.c_str (), "%d", &l))
+ set_loglevel (l);
+ else
+ {
+ non_fatal_error (_f ("unknown log level `%s', using default (PROGRESS)",
+ level));
+ set_loglevel (LOGLEVEL_INFO);
+ }
+ }
+}
+
+
+/**
+ * Helper functions: print_message_part (no newline prepended)
+ * print_message (always starts on a new line)
+ */
+
+/* Is output message at NEWLINE? */
+static bool message_newline = true;
-/* Display user information that is not a full message. */
+/* Display user information as a full message.
+ if newline is true, start the message on a new line.
+*/
void
-progress_indication (string s)
+print_message (int level, string location, string s, bool newline)
{
+ /* Only print the message if the current loglevel allows it: */
+ if (!is_loglevel (level))
+ return;
+ if (newline && !message_newline)
+ fputc ('\n', stderr);
+
/* Test if all silly progress_indication ("\n") can be dropped now. */
if (s == "\n")
return;
+ if (!location.empty ())
+ s = location + ": " + s;
fputs (s.c_str (), stderr);
fflush (stderr);
if (s.length ())
- progress_newline = s[s.length () - 1] == '\n';
+ message_newline = s[s.length () - 1] == '\n';
}
-/* Display a single user message. Always starts on a new line. */
+
+/** The actual output functions to be called in lilypond code.
+ * Sorted in descending order of importance (errors, warnings, progress, info,
+ * debug). Each prints a message on a separate line.
+ */
+
+/* Display a fatal error message. Also exits lilypond. */
void
-message (string s)
+error (string s, string location)
{
- if (!progress_newline)
- fputc ('\n', stderr);
- progress_indication (s);
+ print_message (LOG_ERROR, location, _f ("fatal error: %s", s) + "\n");
+ exit (1);
}
-/* Display a success message. Always starts on a new line. */
+/* Display a severe programming error message, but don't exit. */
void
-successful (string s)
+programming_error (string s, string location)
{
- message (_f ("success: %s", s.c_str ()) + "\n");
+ print_message (LOG_ERROR, location, _f ("programming error: %s", s) + "\n");
+ print_message (LOG_ERROR, location, _ ("continuing, cross fingers") + "\n");
}
-/* Display a warning message. Always starts on a new line. */
+/* Display a non-fatal error message, don't exit. */
void
-warning (string s)
+non_fatal_error (string s, string location)
{
- message (_f ("warning: %s", s.c_str ()) + "\n");
+ print_message (LOG_ERROR, location, _f ("error: %s", s) + "\n");
}
+/* Display a warning message. */
void
-non_fatal_error (string s)
+warning (string s, string location)
{
- message (_f ("error: %s", s.c_str ()) + "\n");
+ print_message (LOG_WARN, location, _f ("warning: %s", s) + "\n");
}
-/* Display an error message. Always starts on a new line. */
+/* Display a success message. */
void
-error (string s)
+successful (string s, string location)
{
- non_fatal_error (s);
- exit (1);
+ print_message (LOG_BASIC, location, _f ("success: %s", s) + "\n", true);
+}
+
+/* Display information about the progress. */
+void
+progress_indication (string s, bool newline, string location)
+{
+ print_message (LOG_PROGRESS, location, s, newline);
}
+/* Display a single info message. */
void
-programming_error (string s)
+message (string s, bool newline, string location)
{
- message (_f ("programming error: %s", s) + "\n");
- message (_ ("continuing, cross fingers") + "\n");
+ // Use the progress loglevel for all normal messages (including progress msg)
+ print_message (LOG_INFO, location, s, newline);
}
+/* Display a debug information, not necessarily on a new line. */
+void
+debug_output (string s, bool newline, string location)
+{
+ print_message (LOG_DEBUG, location, s, newline);
+}
--- /dev/null
+\version "2.15.7"
+
+#(ly:set-option 'warning-as-error #f)
+
+\header{
+ texidoc="
+Test the different loglevels of lilypond. Run this file with --loglevel=NONE,
+ERROR, WARNING, PROGRESS, DEBUG to see the different loglevels. The errors
+are commented out. Comment them in to check the output manually.
+"
+}
+
+%%%% message functions of the Input class:
+#(display "\nMessage functions of the Input class:\n")
+
+messageTest = #(define-music-function (parser location) ()
+ (ly:input-message location "Test ly:input-message" )
+ (make-music 'Music))
+
+{
+% #(display "-) Testing message\n")
+ \messageTest % message
+% #(display "-) Testing warning\n")
+ c4( c( c) % warning
+% #(display "-) Testing error\n")
+% sr % error
+}
+
+%%%% message functions in the warn.hh file:
+#(display "Message functions in the warn.hh file:\n")
+
+% #(display "-) Testing debug\n")
+#(ly:debug "Test debug\n")
+% #(display "-) Testing progress\n")
+#(ly:progress "Test progress\n")
+% #(display "-) Testing message\n")
+#(ly:message "Test message\n")
+% #(display "-) Testing warning\n")
+#(ly:warning "Test warning\n")
+% #(display "-) Testing error\n")
+% #(ly:error "Test error\n")
SCM val;
if (!pango_dict_->try_retrieve (key, &val))
{
- if (be_verbose_global)
- progress_indication ("\n[" + string (pango_fn));
+ debug_output ("[" + string (pango_fn), true); // start on a new line
Pango_font *pf = new Pango_font (pango_ft2_fontmap_,
description,
pango_dict_->set (key, val);
pf->unprotect ();
- if (be_verbose_global)
- progress_indication ("]");
+ debug_output ("]", false);
pf->description_ = scm_cons (SCM_BOOL_F,
scm_from_double (1.0));
if (file_name.empty ())
return 0;
- if (be_verbose_global)
- progress_indication ("\n[" + file_name);
+ debug_output ("[" + file_name, true); // start on a new line
val = Open_type_font::make_otf (file_name);
- if (be_verbose_global)
- progress_indication ("]");
+ debug_output ("]", false);
unsmob_metrics (val)->file_name_ = file_name;
SCM name_string = ly_string2scm (name);
if (!FcConfigAppFontAddDir (0, (const FcChar8 *)d.c_str ()))
error (_f ("failed adding font directory: %s", d.c_str ()));
- else if (be_verbose_global)
- message (_f ("adding font directory: %s", d.c_str ()));
+ else
+ debug_output (_f ("Adding font directory: %s", d.c_str ()));
return SCM_UNSPECIFIED;
}
if (!FcConfigAppFontAddFile (0, (const FcChar8 *)f.c_str ()))
error (_f ("failed adding font file: %s", f.c_str ()));
- else if (be_verbose_global)
- message (_f ("adding font file: %s", f.c_str ()));
+ else
+ debug_output (_f ("Adding font file: %s", f.c_str ()));
return SCM_UNSPECIFIED;
}
void
init_fontconfig ()
{
- if (be_verbose_global)
- message (_ ("Initializing FontConfig..."));
+ debug_output (_ ("Initializing FontConfig..."));
/* TODO: Find a way for Fontconfig to update its cache, if needed. */
font_config_global = FcInitLoadConfig ();
string dir = dirs[i];
if (!FcConfigAppFontAddDir (font_config_global, (FcChar8 *)dir.c_str ()))
error (_f ("failed adding font directory: %s", dir.c_str ()));
- else if (be_verbose_global)
- message (_f ("adding font directory: %s", dir.c_str ()));
+ else
+ debug_output (_f ("Adding font directory: %s", dir.c_str ()));
}
- if (be_verbose_global)
- message (_ ("Building font database..."));
+ debug_output (_ ("Building font database..."));
FcConfigBuildFonts (font_config_global);
FcConfigSetCurrent (font_config_global);
- if (be_verbose_global)
- message ("\n");
+ debug_output ("\n");
}
#include "version.hh"
#include "warn.hh"
+/* Declaration of log function(s) */
+SCM ly_progress (SCM, SCM);
+
LY_DEFINE (ly_start_environment, "ly:start-environment",
0, 0, 0, (),
"Return the environment (a list of strings) that was in"
return scm_from_locale_stringn (contents.c_str (), contents.length ());
}
-LY_DEFINE (ly_error, "ly:error",
- 1, 0, 1, (SCM str, SCM rest),
- "A Scheme callable function to issue the error @var{str}."
- " The error is formatted with @code{format} and @var{rest}.")
-{
- LY_ASSERT_TYPE (scm_is_string, str, 1);
- str = scm_simple_format (SCM_BOOL_F, str, rest);
- error (ly_scm2string (str));
- return SCM_UNSPECIFIED;
-}
-
-LY_DEFINE (ly_message, "ly:message",
- 1, 0, 1, (SCM str, SCM rest),
- "A Scheme callable function to issue the message @var{str}."
- " The message is formatted with @code{format} and @var{rest}.")
-{
- LY_ASSERT_TYPE (scm_is_string, str, 1);
- str = scm_simple_format (SCM_BOOL_F, str, rest);
- message (ly_scm2string (str));
- return SCM_UNSPECIFIED;
-}
-
-LY_DEFINE (ly_progress, "ly:progress",
- 1, 0, 1, (SCM str, SCM rest),
- "A Scheme callable function to print progress @var{str}."
- " The message is formatted with @code{format} and @var{rest}.")
-{
- LY_ASSERT_TYPE (scm_is_string, str, 1);
- str = scm_simple_format (SCM_BOOL_F, str, rest);
- progress_indication (ly_scm2string (str));
- return SCM_UNSPECIFIED;
-}
-
-LY_DEFINE (ly_programming_error, "ly:programming-error",
- 1, 0, 1, (SCM str, SCM rest),
- "A Scheme callable function to issue the internal warning"
- " @var{str}. The message is formatted with @code{format}"
- " and @var{rest}.")
-{
- LY_ASSERT_TYPE (scm_is_string, str, 1);
- str = scm_simple_format (SCM_BOOL_F, str, rest);
-
- if (get_program_option ("warning-as-error"))
- error (ly_scm2string (str));
- else
- programming_error (ly_scm2string (str));
-
- return SCM_UNSPECIFIED;
-}
-
-LY_DEFINE (ly_success, "ly:success",
- 1, 0, 1, (SCM str, SCM rest),
- "A Scheme callable function to issue a success message @var{str}."
- " The message is formatted with @code{format} and @var{rest}.")
-{
- LY_ASSERT_TYPE (scm_is_string, str, 1);
- str = scm_simple_format (SCM_BOOL_F, str, rest);
- successful (ly_scm2string (str));
- return SCM_UNSPECIFIED;
-
-}
-LY_DEFINE (ly_warning, "ly:warning",
- 1, 0, 1, (SCM str, SCM rest),
- "A Scheme callable function to issue the warning @var{str}."
- " The message is formatted with @code{format} and @var{rest}.")
-{
- LY_ASSERT_TYPE (scm_is_string, str, 1);
- str = scm_simple_format (SCM_BOOL_F, str, rest);
-
- if (get_program_option ("warning-as-error"))
- error (ly_scm2string (str));
- else
- warning (ly_scm2string (str));
-
- return SCM_UNSPECIFIED;
-}
LY_DEFINE (ly_dir_p, "ly:dir?",
1, 0, 0, (SCM s),
char *standard_output = 0;
char *standard_error = 0;
- int exit_status = be_verbose_global
- ? ly_run_command (argv, &standard_output, &standard_error)
- : ly_run_command (argv, 0, 0);
+ // Always get the pointer to the stdout/stderr messages
+ int exit_status = ly_run_command (argv, &standard_output, &standard_error);
- if (be_verbose_global)
- {
- fprintf (stderr, "\n%s", standard_output);
- fprintf (stderr, "%s", standard_error);
- }
+ // Print out stdout and stderr only in debug mode
+ debug_output (string ("\n") + standard_output + standard_error, true);
for (int i = 0; i < n; i++)
free (argv[i]);
send_stream_event (g, "Finish", 0, 0);
- if (be_verbose_global)
- message (_f ("elapsed time: %.2f seconds", timer.read ()));
+ debug_output (_f ("elapsed time: %.2f seconds", timer.read ()));
return ctx;
}
for (vsize i = scm_init_funcs_->size (); i--;)
(scm_init_funcs_->at (i)) ();
- if (be_verbose_global)
+ if (is_loglevel (LOG_DEBUG))
{
- progress_indication ("[");
+ debug_output ("[", true);
scm_display (scm_c_eval_string ("(%search-load-path \"lily.scm\")"),
scm_current_error_port ());
- progress_indication ("]\n");
+ debug_output ("]\n", false);
}
scm_primitive_load_path (scm_from_locale_string ("lily.scm"));
if (yy_current_buffer)
state_stack_.push_back (yy_current_buffer);
- if (be_verbose_global)
- {
- string spaces = "";
- for (size_t i = 0; i < state_stack_.size (); i++)
- spaces += " ";
- progress_indication (string ("\n") + spaces + string ("[") + file->name_string ());
- }
+ debug_output (string (state_stack_.size (), ' ') // indentation!
+ + string ("[") + file->name_string ());
include_stack_.push_back (file);
if (yy_current_buffer)
state_stack_.push_back (yy_current_buffer);
- if (be_verbose_global)
- {
- string spaces = "";
- for (size_t i = 0; i < state_stack_.size (); i++)
- spaces += " ";
- progress_indication (string ("\n") + spaces + string ("[") + name);
- }
+ debug_output (string (state_stack_.size (), ' ') // indentation!
+ + string ("[") + name);
include_stack_.push_back (file);
yy_switch_to_buffer (yy_create_buffer (file->get_istream (), YY_BUF_SIZE));
{
include_stack_.pop_back ();
char_count_stack_.pop_back ();
- if (be_verbose_global)
- progress_indication ("]");
+ debug_output ("]", false);
yy_delete_buffer (yy_current_buffer);
#if HAVE_FLEXLEXER_YY_CURRENT_BUFFER
yy_current_buffer = 0;
char const *end () const;
void set (Source_file *, char const *, char const *);
- void warning (string) const;
+ void error (string) const;
void programming_error (string) const;
void non_fatal_error (string) const;
- void error (string) const;
+ void warning (string) const;
void message (string) const;
+ void debug_output (string) const;
void set_spot (Input const &);
void step_forward ();
void set_location (Input const &, Input const &);
Input (Input const &i);
Input ();
+protected:
+ void print_message (int level, string s) const;
};
#include "smobs.hh"
extern string output_backend_global;
extern string output_name_global;
extern bool be_safe_global;
-extern bool be_verbose_global;
extern bool do_internal_type_checking_global;
extern bool point_and_click_global;
extern string lilypond_datadir;
[file:line:column:][warning:]message
*/
void
-Input::message (string s) const
+Input::print_message (int level, string s) const
{
+ string location;
if (source_file_)
- s = location_string () + ": " + s + "\n"
- + source_file_->quote_input (start_) + "\n";
- ::message (s);
+ ::print_message (level, location_string (),
+ s + "\n" + source_file_->quote_input (start_) + "\n");
+ else
+ ::print_message (level, "", s);
+}
+
+void
+Input::error (string s) const
+{
+ print_message (LOG_ERROR, _f ("error: %s", s));
+ // UGH, fix naming or usage (use non_fatal_error in most places, instead)
+ // exit (1);
}
void
Input::programming_error (string s) const
{
if (get_program_option ("warning-as-error"))
- ::error (s);
+ error (s);
else
{
- message (_f ("programming error: %s", s.c_str ()));
- message (_ ("continuing, cross fingers") + "\n");
+ print_message (LOG_ERROR, _f ("programming error: %s", s));
+ print_message (LOG_ERROR, _ ("continuing, cross fingers") + "\n");
}
}
+void
+Input::non_fatal_error (string s) const
+{
+ print_message (LOG_ERROR, _f ("error: %s", s));
+}
+
void
Input::warning (string s) const
{
if (get_program_option ("warning-as-error"))
- ::error (s);
+ error (s);
else
- message (_f ("warning: %s", s));
+ print_message (LOG_WARN, _f ("warning: %s", s));
}
void
-Input::error (string s) const
+Input::message (string s) const
{
- message (_f ("error: %s", s));
- // UGH, fix naming or usage
- // exit (1);
+ print_message (LOG_INFO, s);
}
void
-Input::non_fatal_error (string s) const
+Input::debug_output (string s) const
{
- message (_f ("error: %s", s));
+ print_message (LOG_DEBUG, s);
}
string
LexerError (_ ("stray UTF-8 BOM encountered").c_str ());
exit (1);
}
- if (be_verbose_global)
- message (_ ("Skipping UTF-8 BOM"));
+ debug_output (_ ("Skipping UTF-8 BOM"));
}
<INITIAL,chords,figures,incl,lyrics,markup,notes>{
return s;
}
- if (be_verbose_global)
- progress_indication ("[" + s);
+ debug_output ("[" + s, true);
vector<char> chars = gulp_file (s, size);
string result (&chars[0], chars.size ());
- if (be_verbose_global)
- progress_indication ("]\n");
+ debug_output ("]\n", false);
return result;
}
/* Provide URI links to the original file */
bool point_and_click_global = true;
-/* Verbose progress indication? */
-bool be_verbose_global = false;
-
/* Scheme code to execute before parsing, after .scm init.
This is where -e arguments are appended to. */
string init_scheme_code_global;
"and cd into DIR")
},
#endif
+ {
+ _i ("LOGLEVEL"), "loglevel", 'l', _i ("print log messages according to"
+ " LOGLEVEL. Possible values are:\n"
+ "NONE, ERROR, WARNING, BASIC, PROGRESS (default) and DEBUG.")
+ },
{_i ("FILE"), "output", 'o', _i ("write output to FILE (suffix will be added)")},
{0, "relocate", 0, _i ("relocate using directory of lilypond program")},
+ {0, "silent", 's', _i ("no progress, only error messages (equivalent to loglevel=ERROR)")},
{0, "version", 'v', _i ("show version number and exit")},
- {0, "verbose", 'V', _i ("be verbose")},
+ {0, "verbose", 'V', _i ("be verbose (equivalent to loglevel=DEBUG)")},
{0, "warranty", 'w', _i ("show warranty and copyright")},
{0, 0, 0, 0}
};
prepend_load_path (lilypond_datadir);
prepend_load_path (lilypond_datadir + "/scm");
- if (be_verbose_global)
+ if (is_loglevel (LOG_DEBUG))
dir_info (stderr);
init_scheme_variables_global = "(list " + init_scheme_variables_global + ")";
show_help = true;
break;
case 'V':
- be_verbose_global = true;
+ set_loglevel (LOGLEVEL_DEBUG);
+ break;
+ case 's':
+ set_loglevel (LOGLEVEL_ERROR);
+ break;
+ case 'l':
+ set_loglevel (option_parser->optional_argument_str0_);
break;
default:
programming_error (to_string ("unhandled short option: %c",
if (show_help)
{
ly_usage ();
- if (be_verbose_global)
+ if (is_loglevel (LOG_DEBUG))
dir_info (stdout);
exit (0);
}
start_environment_global.push_back (*p);
if (getenv ("LILYPOND_VERBOSE"))
- be_verbose_global = true;
+ set_loglevel (LOGLEVEL_DEBUG);
+ if (getenv ("LILYPOND_LOGLEVEL"))
+ set_loglevel (getenv ("LILYPOND_LOGLEVEL"));
setup_localisation ();
parse_argv (argc, argv);
- if (isatty (STDIN_FILENO))
+ if (isatty (STDIN_FILENO) && (is_loglevel (LOG_BASIC)))
identify (stderr);
setup_paths (argv[0]);
void
Paper_score::process ()
{
- if (be_verbose_global)
- message (_f ("Element count %d (spanners %d) ",
- system_->element_count (),
- system_->spanner_count ()));
+ debug_output (_f ("Element count %d (spanners %d) ",
+ system_->element_count (),
+ system_->spanner_count ()));
message (_ ("Preprocessing graphical objects..."));
int tracks_ = audio_staffs_.size ();
midi_stream.write (Midi_header (1, tracks_, 384));
- if (be_verbose_global)
- progress_indication (_ ("Track...") + " ");
+ debug_output (_ ("Track...") + " ", false);
for (vsize i = 0; i < audio_staffs_.size (); i++)
{
Audio_staff *s = audio_staffs_[i];
- if (be_verbose_global)
- progress_indication ("[" + to_string (i));
+ debug_output ("[" + to_string (i), true);
s->output (midi_stream, i, ports_);
- if (be_verbose_global)
- progress_indication ("]");
+ debug_output ("]", false);
}
}
string file_name = ly_scm2string (pfb_file_name);
- if (be_verbose_global)
- progress_indication ("\n[" + file_name);
+ debug_output ("[" + file_name); // start message on a new line
vector<char> pfb_string = gulp_file (file_name, 0);
char *pfa = pfb2pfa ((Byte *) &pfb_string[0], pfb_string.size ());
SCM pfa_scm = scm_from_locale_string (pfa);
free (pfa);
- if (be_verbose_global)
- progress_indication ("]");
+ debug_output ("]", false);
return pfa_scm;
}
LY_ASSERT_TYPE (scm_is_string, otf_file_name, 1);
string file_name = ly_scm2string (otf_file_name);
- if (be_verbose_global)
- progress_indication ("\n[" + file_name);
+ debug_output ("[" + file_name); // start message on a new line
FT_Face face = open_ft_face (file_name, 0 /* index */);
string table = get_otf_table (face, "CFF ");
SCM asscm = scm_from_locale_stringn ((char *) table.data (),
table.length ());
- if (be_verbose_global)
- progress_indication ("]");
+ debug_output ("]", false);
return asscm;
}
return ly_string2scm (init_scheme_code_global);
}
-LY_DEFINE (ly_command_line_verbose_p, "ly:command-line-verbose?", 0, 0, 0, (),
- "Was @code{be_verbose_global} set?")
+LY_DEFINE (ly_verbose_output_p, "ly:verbose-output?", 0, 0, 0, (),
+ "Was verbose output requested, i.e. loglevel at least @code{DEBUG}?")
{
- return scm_from_bool (be_verbose_global);
+ return scm_from_bool (is_loglevel (LOG_DEBUG));
}
LY_DEFINE (ly_all_options, "ly:all-options",
string combine = string (key) + "=" + value;
char *s = strdup (combine.c_str ());
- if (be_verbose_global)
- progress_indication (_f ("Setting %s to %s", key, value.c_str ())
- + "\n");
+ debug_output (_f ("Setting %s to %s", key, value.c_str ())
+ + "\n");
int retval = putenv (s);
/*
{
if (is_file (value))
return sane_putenv (key, value, overwrite);
- else if (be_verbose_global)
+ else if (is_loglevel (LOG_DEBUG))
+ // this warning should only be printed in debug mode!
warning (_f ("no such file: %s for %s", value, key));
return -1;
}
{
if (is_dir (value))
return sane_putenv (key, value, false);
- else if (be_verbose_global)
+ else if (is_loglevel (LOG_DEBUG))
+ // this warning should only be printed in debug mode!
warning (_f ("no such directory: %s for %s", value, key));
return -1;
}
{
if (is_dir (value))
{
- if (be_verbose_global)
- progress_indication (_f ("%s=%s (prepend)\n", key, value.c_str ()));
+ debug_output (_f ("%s=%s (prepend)\n", key, value.c_str ()), false);
if (char const *cur = getenv (key))
value += to_string (PATHSEP) + cur;
return sane_putenv (key, value.c_str (), true);
}
- else if (be_verbose_global)
+ else if (is_loglevel (LOG_DEBUG))
+ // this warning should only be printed in debug mode
warning (_f ("no such directory: %s for %s", value, key));
return -1;
}
prepend_env_path ("PATH", bindir);
- if (be_verbose_global)
- warning (_f ("Relocation: compile datadir=%s, new datadir=%s",
- old_lilypond_datadir.c_str (),
- lilypond_datadir.c_str ()));
+ debug_output (_f ("Relocation: compile datadir=%s, new datadir=%s",
+ old_lilypond_datadir.c_str (),
+ lilypond_datadir.c_str ()));
}
/*
static void
framework_relocation (string prefix)
{
- if (be_verbose_global)
- warning (_f ("Relocation: framework_prefix=%s", prefix));
+ debug_output (_f ("Relocation: framework_prefix=%s", prefix));
sane_putenv ("INSTALLER_PREFIX", prefix, true);
if (argv0_filename.is_absolute ())
{
argv0_abs = argv0_filename.to_string ();
- if (be_verbose_global)
- warning (_f ("Relocation: is absolute: argv0=%s", argv0_ptr));
+ debug_output (_f ("Relocation: is absolute: argv0=%s\n", argv0_ptr));
}
else if (argv0_filename.dir_.length ())
{
argv0_abs = get_working_directory ()
+ "/" + string (argv0_filename.to_string ());
- if (be_verbose_global)
- warning (_f ("Relocation: from cwd: argv0=%s", argv0_ptr));
+ debug_output (_f ("Relocation: from cwd: argv0=%s\n", argv0_ptr));
}
else
{
argv0_abs = path.find (argv0_filename.to_string (), ext);
#endif /* __MINGW32__ */
- if (be_verbose_global)
- warning (_f ("Relocation: from PATH=%s\nargv0=%s",
- path.to_string ().c_str (), argv0_ptr));
+ debug_output (_f ("Relocation: from PATH=%s\nargv0=%s",
+ path.to_string ().c_str (), argv0_ptr), true);
if (argv0_abs.empty ())
programming_error ("cannot find absolute argv0");
void
read_relocation_file (string filename)
{
- if (be_verbose_global)
- progress_indication (_f ("Relocation file: %s", filename.c_str ())
- + "\n");
-
+ debug_output (_f ("Relocation file: %s", filename.c_str ()) + "\n");
char const *cname = filename.c_str ();
FILE *f = fopen (cname, "r");
if (!f)
}
}
- if (be_verbose_global)
- message (_f ("Element count %d", count + element_count ()) + "\n");
+ debug_output (_f ("Element count %d", count + element_count ()) + "\n");
}
SCM
SCM lines = scm_c_make_vector (broken_intos_.size (), SCM_EOL);
for (vsize i = 0; i < broken_intos_.size (); i++)
{
- if (be_verbose_global)
- progress_indication ("[");
+ debug_output ("[", false);
System *system = dynamic_cast<System *> (broken_intos_[i]);
scm_vector_set_x (lines, scm_from_int (i),
system->get_paper_system ());
- if (be_verbose_global)
- progress_indication (to_string (i) + "]");
+ debug_output (to_string (i) + "]", false);
}
return lines;
}
for (vsize i = 0; i < all_elements_->size (); i++)
all_elements_->grob (i)->discretionary_processing ();
- if (be_verbose_global)
- message (_f ("Grob count %d", element_count ()));
+ debug_output (_f ("Grob count %d", element_count ()));
/*
order is significant: broken grobs are added to the end of the
}
string file_name = ly_scm2string (ttf_file_name);
- if (be_verbose_global)
- progress_indication ("\n[" + file_name);
+ debug_output ("\n[" + file_name, false);
FT_Face face;
SCM ps_name = scm_from_locale_string (ps_name_str0 ? ps_name_str0 : "");
FT_Done_Face (face);
- if (be_verbose_global)
- progress_indication ("]");
+ debug_output ("]", false);
return ps_name;
}
}
string file_name = ly_scm2string (ttf_file_name);
- if (be_verbose_global)
- progress_indication ("\n[" + file_name);
+ debug_output ("[" + file_name); // Debug message should start on a new line
Memory_out_stream stream;
SCM asscm = scm_from_locale_stringn (stream.get_string (),
stream.get_length ());
- if (be_verbose_global)
- progress_indication ("]");
+ debug_output ("]", false);
return asscm;
}
--- /dev/null
+/*
+ This file is part of LilyPond, the GNU music typesetter.
+
+ Copyright (C) 1998--2011 Jan Nieuwenhuizen <janneke@gnu.org>
+ Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ LilyPond is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ LilyPond is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.hh"
+
+#include "lily-guile.hh"
+#include "program-option.hh"
+#include "version.hh"
+#include "warn.hh"
+
+/*
+ Error / warning / progress / debug message output functions
+*/
+
+LY_DEFINE (ly_error, "ly:error",
+ 1, 0, 1, (SCM str, SCM rest),
+ "A Scheme callable function to issue the error @var{str}."
+ " The error is formatted with @code{format} and @var{rest}.")
+{
+ LY_ASSERT_TYPE (scm_is_string, str, 1);
+ str = scm_simple_format (SCM_BOOL_F, str, rest);
+ error (ly_scm2string (str));
+ return SCM_UNSPECIFIED;
+}
+
+LY_DEFINE (ly_programming_error, "ly:programming-error",
+ 1, 0, 1, (SCM str, SCM rest),
+ "A Scheme callable function to issue the internal warning"
+ " @var{str}. The message is formatted with @code{format}"
+ " and @var{rest}.")
+{
+ LY_ASSERT_TYPE (scm_is_string, str, 1);
+ str = scm_simple_format (SCM_BOOL_F, str, rest);
+
+ if (get_program_option ("warning-as-error"))
+ error (ly_scm2string (str));
+ else
+ programming_error (ly_scm2string (str));
+
+ return SCM_UNSPECIFIED;
+}
+
+LY_DEFINE (ly_warning, "ly:warning",
+ 1, 0, 1, (SCM str, SCM rest),
+ "A Scheme callable function to issue the warning @var{str}."
+ " The message is formatted with @code{format} and @var{rest}.")
+{
+ LY_ASSERT_TYPE (scm_is_string, str, 1);
+ str = scm_simple_format (SCM_BOOL_F, str, rest);
+
+ if (get_program_option ("warning-as-error"))
+ error (ly_scm2string (str));
+ else
+ warning (ly_scm2string (str));
+
+ return SCM_UNSPECIFIED;
+}
+
+LY_DEFINE (ly_progress, "ly:progress",
+ 1, 0, 1, (SCM str, SCM rest),
+ "A Scheme callable function to print progress @var{str}."
+ " The message is formatted with @code{format} and @var{rest}.")
+{
+ LY_ASSERT_TYPE (scm_is_string, str, 1);
+ str = scm_simple_format (SCM_BOOL_F, str, rest);
+ // Calls to ly:progress should in general not start a new line
+ progress_indication (ly_scm2string (str), false);
+ return SCM_UNSPECIFIED;
+}
+
+LY_DEFINE (ly_success, "ly:success",
+ 1, 0, 1, (SCM str, SCM rest),
+ "A Scheme callable function to issue a success message @var{str}."
+ " The message is formatted with @code{format} and @var{rest}.")
+{
+ LY_ASSERT_TYPE (scm_is_string, str, 1);
+ str = scm_simple_format (SCM_BOOL_F, str, rest);
+ successful (ly_scm2string (str));
+ return SCM_UNSPECIFIED;
+}
+
+LY_DEFINE (ly_message, "ly:message",
+ 1, 0, 1, (SCM str, SCM rest),
+ "A Scheme callable function to issue the message @var{str}."
+ " The message is formatted with @code{format} and @var{rest}.")
+{
+ LY_ASSERT_TYPE (scm_is_string, str, 1);
+ str = scm_simple_format (SCM_BOOL_F, str, rest);
+ message (ly_scm2string (str));
+ return SCM_UNSPECIFIED;
+}
+
+LY_DEFINE (ly_debug, "ly:debug",
+ 1, 0, 1, (SCM str, SCM rest),
+ "A Scheme callable function to issue a debug message @var{str}."
+ " The message is formatted with @code{format} and @var{rest}.")
+{
+ // TODO: Add the newline flag!
+ LY_ASSERT_TYPE (scm_is_string, str, 1);
+ str = scm_simple_format (SCM_BOOL_F, str, rest);
+ debug_output (ly_scm2string (str));
+ return SCM_UNSPECIFIED;
+}
+
+LY_DEFINE (ly_warning_located, "ly:warning-located",
+ 2, 0, 1, (SCM location, SCM str, SCM rest),
+ "A Scheme callable function to issue the warning @var{str} at"
+ " the specified location in an input file."
+ " The message is formatted with @code{format} and @var{rest}.")
+{
+ LY_ASSERT_TYPE (scm_is_string, location, 1);
+ LY_ASSERT_TYPE (scm_is_string, str, 2);
+ str = scm_simple_format (SCM_BOOL_F, str, rest);
+
+ if (get_program_option ("warning-as-error"))
+ error (ly_scm2string (str), ly_scm2string (location));
+ else
+ warning (ly_scm2string (str), ly_scm2string (location));
+
+ return SCM_UNSPECIFIED;
+}
(ice-9 optargs))
(define-public (ly:system command)
- (if (ly:get-option 'verbose)
- (begin
- (ly:message (_ "Invoking `~a'...") (string-join command)))
- (ly:progress "\n"))
+ (ly:debug (_ "Invoking `~a'...") (string-join command))
(let ((status (apply ly:spawn command)))
(if (> status 0)
(begin
'())))
(if (pair? alist)
(begin
- (if (ly:get-option 'verbose)
- (ly:message (_ "Using `~a' note names...") str))
+ (ly:debug (_ "Using `~a' note names...") str)
(set! pitchnames alist)
(ly:parser-set-note-names parser alist))
(ly:warning (_ "Could not find language `~a'. Ignoring.") str))))
scaling))
(define-public (version-not-seen-message input-file-name)
- (ly:message
- "~a:0: ~a ~a"
- input-file-name
- (_ "warning:")
- (format #f
- (_ "no \\version statement found, please add~afor future compatibility")
- (format #f "\n\n\\version ~s\n\n" (lilypond-version)))))
+ (ly:warning-located
+ (ly:format "~a:0" input-file-name)
+ (_ "no \\version statement found, please add~afor future compatibility")
+ (format #f "\n\n\\version ~s\n\n" (lilypond-version))))
(define-public (old-relative-not-used-message input-file-name)
- (ly:message
- "~a:0: ~a ~a"
- input-file-name
- (_ "warning:")
+ (ly:warning-located
+ (ly:format "~a:0" input-file-name)
(_ "old relative compatibility not used")))
`FILE.graph'.")
(trace-scheme-coverage #f
"Record coverage of Scheme files in `FILE.cov'.")
- (verbose ,(ly:command-line-verbose?)
-"Value of the --verbose flag (read-only).")
+ (verbose ,(ly:verbose-output?)
+"Verbose output, i.e. loglevel at least DEBUG (read-only).")
(warning-as-error #f
"Change all warning and programming_error
messages into errors.")
(cond
((guile-v2)
- (if (ly:get-option 'verbose)
- (ly:message (_ "Using (ice-9 curried-definitions) module\n")))
+ (ly:debug (_ "Using (ice-9 curried-definitions) module\n"))
(use-modules (ice-9 curried-definitions)))
(else
- (if (ly:get-option 'verbose)
- (ly:message (_ "Guile 1.8\n")))))
+ (ly:debug (_ "Guile 1.8\n"))))
;; TODO add in modules for V1.8.7 deprecated in V2.0 and integrated
;; into Guile base code, like (ice-9 syncase).
(define-public (ly:load x)
(let* ((file-name (%search-load-path x)))
- (if (ly:get-option 'verbose)
- (ly:progress "[~A" file-name))
+ (ly:debug "[~A" file-name)
(if (not file-name)
- (ly:error (_ "cannot find: ~A") x))
+ (ly:error (_ "cannot find: ~A") x))
(primitive-load-path file-name) ;; to support Guile V2 autocompile
+ ;; TODO: Any chance to use ly:debug here? Need to extend it to prevent
+ ;; a newline in this case
(if (ly:get-option 'verbose)
- (ly:progress "]\n"))))
+ (ly:progress "]\n"))))
(define-public DOS
(let ((platform (string-tokenize