]> git.donarmstrong.com Git - lilypond.git/blobdiff - flower/warn.cc
Proper loglevels: cmd-line option --loglevel=NONE/ERROR/WARN/BASIC/PROGRESS/DEBUG
[lilypond.git] / flower / warn.cc
index 1c2f4ed134724bfb04c36fde2f380e7ce710cbf2..43eab1add7ec41120fde929b19c42009eb98d4fe 100644 (file)
 
 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);
+}