X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=flower%2Fwarn.cc;h=43eab1add7ec41120fde929b19c42009eb98d4fe;hb=86713eefa608f7dc738420ce0225c2a92c4539b2;hp=1c2f4ed134724bfb04c36fde2f380e7ce710cbf2;hpb=f8702402e51201a2078672532c02b18a31442818;p=lilypond.git diff --git a/flower/warn.cc b/flower/warn.cc index 1c2f4ed134..43eab1add7 100644 --- a/flower/warn.cc +++ b/flower/warn.cc @@ -26,64 +26,167 @@ 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); +}