Continue reforming error message support. In this phase, drop actual
authorBen Pfaff <blp@gnu.org>
Tue, 25 Apr 2006 18:03:03 +0000 (18:03 +0000)
committerBen Pfaff <blp@gnu.org>
Tue, 25 Apr 2006 18:03:03 +0000 (18:03 +0000)
message printing from core code, substituting a callback, and add the
callback to each UI.  Also, move verbose_msg() into its own module.

21 files changed:
src/ChangeLog
src/data/file-name.c
src/language/line-buffer.c
src/libpspp/ChangeLog
src/libpspp/automake.mk
src/libpspp/message.h
src/libpspp/verbose-msg.c [new file with mode: 0644]
src/libpspp/verbose-msg.h [new file with mode: 0644]
src/message.c
src/ui/gui/ChangeLog
src/ui/gui/automake.mk
src/ui/gui/message-dialog.c
src/ui/gui/message-dialog.h
src/ui/gui/psppire.c
src/ui/terminal/ChangeLog
src/ui/terminal/automake.mk
src/ui/terminal/command-line.c
src/ui/terminal/main.c
src/ui/terminal/msg-ui.c [new file with mode: 0644]
src/ui/terminal/msg-ui.h [new file with mode: 0644]
src/ui/terminal/read-line.c

index 30a565175a25e2570d98a9b3e9ad10cab130ae6c..e656b93a2c63919b551996ebcebd998992a9bb12 100644 (file)
@@ -1,3 +1,32 @@
+Tue Apr 25 10:47:37 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, drop
+       actual message printing from core code, substituting a callback,
+       and add the callback to each UI.  Also, move verbose_msg() into
+       its own module.
+
+       * message.c: (var err_error_count) Renamed error_count and moved
+       to ui/terminal/msg-ui.c.
+       (var err_warning_count) Renamed warning_count and moved to
+       ui/terminal/msg-ui.c.
+       (err_check_count) Renamed check_msg_count() and moved to
+       ui/terminal/msg-ui.c.
+       (dump_message) Rewrote to take stream instead of function pointer
+       and moved to ui/terminal/msg-ui.c.
+       (msg_emit) Moved its guts to ui/terminal/msg-ui.c as handle_msg()
+       and rewrote to just pass message to callback.
+       
+       (var err_verbosity) Renamed "verbosity" and moved to
+       libpspp/verbose-msg.c.
+       (verbose_msg) Moved to libpspp/verbose-msg.c.
+       
+       (var err_already_flagged) Removed.
+       (puts_stdout) Removed.
+       
+       (var msg_handler) New static variable.
+       (msg_init) New function.
+       (msg_get_command_name) New function.
+       
 Mon Apr 24 17:40:08 2006  Ben Pfaff  <blp@gnu.org>
 
        Continue reforming error message support.  In this phase, rename
index dd512c033680fa03c7e612b1e33a84642753f6ea..ea95002031a5df7e3014769dcecbbcaf00f39267 100644 (file)
    02110-1301, USA. */
 
 #include <config.h>
-#include <libpspp/message.h>
+
 #include "file-name.h"
-#include <stdio.h>
-#include <stdlib.h>
+
 #include <ctype.h>
 #include <errno.h>
-#include <libpspp/alloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+
 #include "intprops.h"
+#include "settings.h"
+#include "xreadlink.h"
+
+#include <libpspp/alloc.h>
+#include <libpspp/message.h>
 #include <libpspp/message.h>
 #include <libpspp/str.h>
-#include "settings.h"
+#include <libpspp/verbose-msg.h>
 #include <libpspp/version.h>
-#include "xreadlink.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
index ce0160c519dbb816eceaa9c2ecce528702cb534c..e451532082b06a9f88ac10ed8fcf0cf6ed289892 100644 (file)
    02110-1301, USA. */
 
 #include <config.h>
+
 #include <language/line-buffer.h>
-#include <libpspp/message.h>
+
 #include <stdio.h>
 #include <errno.h>
 #include <stdlib.h>
-#include <libpspp/alloc.h>
-#include <language/command.h>
-#include <libpspp/message.h>
+
 #include <data/file-name.h>
-#include <language/lexer/lexer.h>
 #include <data/settings.h>
-#include <libpspp/str.h>
-#include <output/table.h>
 #include <data/variable.h>
+#include <language/command.h>
+#include <language/lexer/lexer.h>
+#include <libpspp/alloc.h>
+#include <libpspp/message.h>
+#include <libpspp/message.h>
+#include <libpspp/str.h>
+#include <libpspp/verbose-msg.h>
 #include <libpspp/version.h>
+#include <output/table.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
index 1b634fc98aac86d4a544698ff5b63f0edc6a38b8..ce4acf903c327eebafb94300cd4635e67bacc0ab 100644 (file)
@@ -1,3 +1,17 @@
+Tue Apr 25 10:54:44 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, drop
+       actual message printing from core code, substituting a callback,
+       and add the callback to each UI.  Also, move verbose_msg() into
+       its own module.
+
+       * automake.mk (src_libpspp_libpspp_a_SOURCES): Added
+       verbose-msg.c, verbose-msg.h.
+
+       * verbose-msg.c: New file.
+
+       * verbose-msg.h: New file.
+
 Mon Apr 24 17:26:47 2006  Ben Pfaff  <blp@gnu.org>
 
        Continue reforming error message support.  In this phase, rename
index 40e57d61636f68c9bc650bcb13b5cab6a2167f93..4d7969533b77f68cda482764daceca4a6824b0f7 100644 (file)
@@ -27,6 +27,8 @@ src_libpspp_libpspp_a_SOURCES = \
        src/libpspp/start-date.h \
        src/libpspp/str.c \
        src/libpspp/str.h \
+       src/libpspp/verbose-msg.c \
+       src/libpspp/verbose-msg.h \
        src/libpspp/version.h 
 
 DISTCLEANFILES+=src/libpspp/version.c
index 0cf6739941ba3edbf39102223435f0823562d380..71fe1fa07baa22efa2583657b6031f05429e75f6 100644 (file)
@@ -85,35 +85,21 @@ struct msg
     char *text;                 /* Error text. */
   };
 
-/* Number of errors, warnings reported. */
-extern int err_error_count;
-extern int err_warning_count;
-
-/* If number of allowable errors/warnings is exceeded, then a message
-   is displayed and this flag is set to suppress subsequent
-   messages. */
-extern int err_already_flagged;
-
-/* Nonnegative verbosity level.  Higher value == more verbose. */
-extern int err_verbosity;
-
 /* Initialization. */
+void msg_init (void (*handler) (const struct msg *));
 void msg_done (void);
 
 /* Emitting messages. */
 void msg (enum msg_class, const char *format, ...)
      PRINTF_FORMAT (2, 3);
-void msg_emit (const struct msg *);
-
-void verbose_msg (int level, const char *format, ...)
-     PRINTF_FORMAT (2, 3);
+void msg_emit (struct msg *);
 
 /* Error context. */
 void msg_set_command_name (const char *);
+const char *msg_get_command_name (void);
 void msg_push_msg_locator (const struct msg_locator *);
 void msg_pop_msg_locator (const struct msg_locator *);
 void msg_location (struct msg_locator *);
-void err_check_count (void);
 
 /* Used in panic situations only. */
 void request_bug_report_and_abort (const char *msg);
diff --git a/src/libpspp/verbose-msg.c b/src/libpspp/verbose-msg.c
new file mode 100644 (file)
index 0000000..d4c29af
--- /dev/null
@@ -0,0 +1,56 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program 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 2 of the
+   License, or (at your option) any later version.
+
+   This program 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 this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#include <config.h>
+
+#include <libpspp/verbose-msg.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "progname.h"
+
+/* Level of verbosity.
+   Higher values cause more output. */
+static int verbosity;
+
+/* Increases the verbosity level. */
+void
+verbose_increment_level (void) 
+{
+  verbosity++;
+}
+
+/* Writes MESSAGE formatted with printf, to stderr, if the
+   verbosity level is at least LEVEL. */
+void
+verbose_msg (int level, const char *format, ...)
+{
+  if (level <= verbosity)
+    {
+      va_list args;
+  
+      va_start (args, format);
+      fprintf (stderr, "%s: ", program_name);
+      vfprintf (stderr, format, args);
+      putc ('\n', stderr);
+      va_end (args);
+    }
+}
+
diff --git a/src/libpspp/verbose-msg.h b/src/libpspp/verbose-msg.h
new file mode 100644 (file)
index 0000000..7364a08
--- /dev/null
@@ -0,0 +1,29 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program 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 2 of the
+   License, or (at your option) any later version.
+
+   This program 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 this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#ifndef VERBOSE_MSG_H
+#define VERBOSE_MSG_H 1
+
+#include <libpspp/compiler.h>
+
+void verbose_increment_level (void);
+void verbose_msg (int level, const char *format, ...)
+     PRINTF_FORMAT (2, 3);
+
+#endif /* verbose-msg.h */
index 974347e0493cd872fc27c68c5e089f0154d62f60..27fe62d36d94de36ffc31f4a266cd9939c61a7ec 100644 (file)
    02110-1301, USA. */
 
 #include <config.h>
+
 #include <libpspp/message.h>
+
 #include <ctype.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <libpspp/alloc.h>
+
 #include <data/file-name.h>
-#include <language/line-buffer.h>
 #include <language/lexer/lexer.h>
-#include <data/settings.h>
-#include <ui/terminal/read-line.h>
+#include <libpspp/alloc.h>
 #include <libpspp/version.h>
-#include "exit.h"
-#include "linebreak.h"
-#include "progname.h"
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
 
-int err_error_count;
-int err_warning_count;
+#include "progname.h"
+#include "xvasprintf.h"
 
-int err_already_flagged;
+/* Current command name as set by msg_set_command_name(). */
+static char *command_name;
 
-int err_verbosity;
+/* Message handler as set by msg_init(). */
+static void (*msg_handler) (const struct msg *);
 
-static char *command_name;
-\f
 /* Public functions. */
 
 /* Writes error message in CLASS, with text FORMAT, formatted with
@@ -67,197 +60,28 @@ msg (enum msg_class class, const char *format, ...)
   msg_emit (&m);
 }
 
-/* Writes MESSAGE formatted with printf, to stderr, if the
-   verbosity level is at least LEVEL. */
 void
-verbose_msg (int level, const char *format, ...)
+msg_init (void (*handler) (const struct msg *)) 
 {
-  if (err_verbosity >= level)
-    {
-      va_list args;
-  
-      va_start (args, format);
-      fprintf (stderr, "%s: ", program_name);
-      vfprintf (stderr, format, args);
-      putc ('\n', stderr);
-      va_end (args);
-    }
+  msg_handler = handler;
 }
 
-/* Checks whether we've had so many errors that it's time to quit
-   processing this syntax file. */
-void
-err_check_count (void)
-{
-  if (get_errorbreak() && err_error_count)
-    msg (MN, _("Terminating execution of syntax file due to error."));
-  else if (err_error_count > get_mxerrs() )
-    msg (MN, _("Errors (%d) exceeds limit (%d)."),
-        err_error_count, get_mxerrs());
-  else if (err_error_count + err_warning_count > get_mxwarns() )
-    msg (MN, _("Warnings (%d) exceed limit (%d)."),
-        err_error_count + err_warning_count, get_mxwarns() );
-  else
-    return;
-
-  getl_abort_noninteractive ();
-}
-
-static void puts_stdout (int line_indent, const char *line, size_t length);
-static void dump_message (char *msg,
-                          void (*func) (int line_indent,
-                                        const char *line, size_t length),
-                          unsigned width, unsigned indent);
-
 void
 msg_done (void) 
 {
-  lex_done();
-  getl_uninitialize ();
-  readln_uninitialize();
 }
 
-/* Emits E as an error message.
-   Frees `text' member in E. */
+/* Emits M as an error message.
+   Frees allocated data in M. */
 void
-msg_emit (const struct msg *m)
+msg_emit (struct msg *m) 
 {
-  struct category 
-    {
-      bool show_command_name;   /* Show command name with error? */
-      bool show_file_location;  /* Show syntax file location? */
-    };
-
-  static const struct category categories[] = 
-    {
-      {false, false},           /* MSG_GENERAL. */
-      {true, true},             /* MSG_SYNTAX. */
-      {false, true},            /* MSG_DATA. */
-    };
-
-  struct severity 
-    {
-      const char *name;         /* How to identify this severity. */
-      int *count;               /* Number of msgs with this severity so far. */
-    };
-  
-  static struct severity severities[] = 
-    {
-      {N_("error"), &err_error_count},          /* MSG_ERROR. */
-      {N_("warning"), &err_warning_count},      /* MSG_WARNING. */
-      {NULL, NULL},                             /* MSG_NOTE. */
-    };
-
-  const struct category *category = &categories[m->category];
-  const struct severity *severity = &severities[m->severity];
-  struct string string = DS_INITIALIZER;
-
-  if (category->show_file_location && m->where.file_name)
-    {
-      ds_printf (&string, "%s:", m->where.file_name);
-      if (m->where.line_number != -1)
-       ds_printf (&string, "%d:", m->where.line_number);
-      ds_putc (&string, ' ');
-    }
-
-  if (severity->name != NULL)
-    ds_printf (&string, "%s: ", gettext (severity->name));
-  
-  if (severity->count != NULL)
-    ++*severity->count;
-  
-  if (category->show_command_name && command_name != NULL)
-    ds_printf (&string, "%s: ", command_name);
-
-  ds_puts (&string, m->text);
-
-  /* FIXME: Check set_messages and set_errors to determine where to
-     send errors and messages. */
-  dump_message (ds_c_str (&string), puts_stdout, get_viewwidth (), 8);
-
-  ds_destroy (&string);
+  msg_handler (m);
   free (m->text);
 }
 \f
 /* Private functions. */
 
-/* Write LINE_INDENT spaces, the LENGTH characters in LINE, then
-   a new-line to stdout. */
-static void puts_stdout (int line_indent,
-                         const char *line, size_t length)
-{
-  int i;
-  for (i = 0; i < line_indent; i++)
-    putchar (' ');
-  fwrite (line, 1, length, stdout);
-  putchar ('\n');
-}
-
-/* Divides MSG into lines of WIDTH width for the first line and
-   WIDTH - INDENT width for each succeeding line.  Each line is
-   passed to FUNC as a null-terminated string (no new-line
-   character is included in the string). */
-static void
-dump_message (char *msg,
-              void (*func) (int line_indent, const char *line, size_t length),
-             unsigned width, unsigned indent)
-{
-  size_t length = strlen (msg);
-  char *string, *breaks;
-  int line_indent;
-  size_t line_start, i;
-
-  /* Allocate temporary buffers.
-     If we can't get memory for them, then just dump the whole
-     message. */
-  string = strdup (msg);
-  breaks = malloc (length);
-  if (string == NULL || breaks == NULL)
-    {
-      free (string);
-      free (breaks);
-      func (0, msg, length);
-      return;
-    }
-
-  /* Break into lines. */
-  if (indent > width / 3)
-    indent = width / 3;
-  mbs_width_linebreaks (string, length,
-                        width - indent, -indent, 0,
-                        NULL, locale_charset (), breaks);
-
-  /* Pass lines to FUNC. */
-  line_start = 0;
-  line_indent = 0;
-  for (i = 0; i < length; i++)
-    switch (breaks[i]) 
-      {
-      case UC_BREAK_POSSIBLE:
-        /* Break before this character,
-           and include this character in the next line. */
-        func (line_indent, &string[line_start], i - line_start);
-        line_start = i;
-        line_indent = indent;
-        break;
-      case UC_BREAK_MANDATORY:
-        /* Break before this character,
-           but don't include this character in the next line
-           (because it'string a new-line). */
-        func (line_indent, &string[line_start], i - line_start);
-        line_start = i + 1;
-        line_indent = indent;
-        break;
-      default:
-        break;
-      }
-  if (line_start < length)
-    func (line_indent, &string[line_start], length - line_start);
-
-  free (string);
-  free (breaks);
-}
-
 /* Sets COMMAND_NAME as the command name included in some kinds
    of error messages. */
 void
@@ -267,6 +91,13 @@ msg_set_command_name (const char *command_name_)
   command_name = command_name_ ? xstrdup (command_name_) : NULL;
 }
 
+/* Returns the current command name, or NULL if none. */
+const char *
+msg_get_command_name (void) 
+{
+  return command_name;
+}
+
 void 
 request_bug_report_and_abort(const char *msg )
 {
index 6692d9aa633318ba16f3516cf4a7d81ba367c234..f4d3b0d291b04947d1d4d9d940f23227c1e7a362 100644 (file)
@@ -1,3 +1,21 @@
+Tue Apr 25 10:56:53 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, drop
+       actual message printing from core code, substituting a callback,
+       and add the callback to each UI.  Also, move verbose_msg() into
+       its own module.
+
+       * automake.mk: (src_ui_gui_psppire_SOURCES) Add src/message.c.
+
+       * message-dialog.c: (message_dialog_init) New function.
+       (vmsg) Rename handle_msg(), rewrite as callback function.
+       (msg) Removed.
+       (msg_emit) Removed.
+       (msg_assert_fail) Removed.
+       (verbose_msg) Removed.
+
+       * psppire.c: (main) Call message_dialog_init().
+
 Sun Apr 23 22:07:49 2006  Ben Pfaff  <blp@gnu.org>
 
        Continue reforming error message support.  In this phase, get rid
index cfb082cc0509185502725eadfefa5048f6367f86..f1dea45330e26b8c9f3211a02695c404ceeb0450 100644 (file)
@@ -17,7 +17,7 @@ src_ui_gui_psppire_LDADD = \
         @LIBINTL@ @LIBREADLINE@
 
 src_ui_gui_psppiredir = $(pkgdatadir)
-       
+
 dist_src_ui_gui_psppire_DATA = \
        $(top_srcdir)/src/ui/gui/psppire.glade \
        $(top_srcdir)/src/ui/gui/psppicon.png \
@@ -55,5 +55,5 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/var-sheet.c \
        src/ui/gui/var-sheet.h \
        src/ui/gui/var-type-dialog.c \
-       src/ui/gui/var-type-dialog.h 
-
+       src/ui/gui/var-type-dialog.h \
+       src/message.c
index f1a18baf5bf5caf7080f7f2cb6e4607d0c34c5ff..cf1fb851c9af322a77b77b8b0d4dcda57c50cb1a 100644 (file)
@@ -38,19 +38,24 @@ extern GladeXML *xml;
 
 #define _(A) A
 
+static void handle_msg(const struct msg *);
 
-void 
-vmsg(int klass, const char *fmt, va_list args)
+void
+message_dialog_init (void) 
+{
+  msg_init(handle_msg);
+}
+
+static void
+handle_msg(const struct msg *m)
 {
-  gchar *msg = 0;
-  gchar *text = g_strdup_vprintf (fmt, args);
+  GtkWindow *parent;
+  GtkWidget *dialog;
 
-  GtkWindow *parent ;
-  GtkWidget *dialog ;
-                   
   gint message_type;
+  const char *msg;
 
-  switch (msg_class_to_severity (klass))
+  switch (m->severity)
     {
     case MSG_ERROR:
       message_type = GTK_MESSAGE_ERROR;
@@ -64,19 +69,19 @@ vmsg(int klass, const char *fmt, va_list args)
       break;
     };
   
-  switch (msg_class_to_category (klass)
+  switch (m->category
     {
     case MSG_SYNTAX:
-      msg = g_strdup(_("Script Error"));
+      msg = _("Script Error");
       break;
 
     case MSG_DATA:
-      msg = g_strdup(_("Data File Error"));
+      msg = _("Data File Error");
       break;
 
     case MSG_GENERAL:
     default:
-      msg = g_strdup(_("PSPP Error"));
+      msg = _("PSPP Error");
       break;
     };
   
@@ -88,50 +93,14 @@ vmsg(int klass, const char *fmt, va_list args)
                                  GTK_BUTTONS_CLOSE,
                                  msg);
   
-  gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), text);
-
-  g_free(text);
-  g_free(msg);
+  gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
+                                           "%s", m->text);
     
   gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
 
   gtk_dialog_run(GTK_DIALOG(dialog));
 
   gtk_widget_destroy (dialog);
-
-}
-
-
-void 
-msg(enum msg_class klass, const char *fmt, ...)
-{
-  va_list ap;
-  va_start(ap, fmt);
-  vmsg(klass, fmt, ap);
-  va_end(ap);
-}
-
-
-void
-msg_emit (const struct msg *m)
-{
-  vmsg (msg_class_from_category_and_severity (m->category, m->severity),
-        "%s", m->text);
-}
-
-
-void 
-msg_assert_fail(const char *expr, const char *file, int line)
-{
-  msg(ME, "Assertion failed: %s:%d; (%s)\n",file,line,expr);
-}
-
-/* Writes MESSAGE formatted with printf, to stderr, if the
-   verbosity level is at least LEVEL. */
-void
-verbose_msg (int level, const char *format, ...)
-{
-  /* Do nothing for now. */
 }
 
 /* FIXME: This is a stub .
index 66a33633d25e413f8bf49c4a59cf6949fe608a42..bda1608da6bd309041ef2f72ab7bb31812d0b087 100644 (file)
@@ -24,4 +24,6 @@
 
 #include <libpspp/message.h>
 
+void message_dialog_init (void);
+
 #endif
index 58264d99b0520c1abb4742f7d2b22f6d7b6cf196..b291b0af1a05fba6d74c025c5da2e1c938a00b0c 100644 (file)
@@ -39,6 +39,7 @@
 #include "data-sheet.h"
 #include "var-sheet.h"
 #include "psppire-case-array.h"
+#include "message-dialog.h"
 
 GladeXML *xml;
 
@@ -68,6 +69,8 @@ main(int argc, char *argv[])
 
   glade_init();
 
+  message_dialog_init();
+
   the_dictionary = psppire_dict_new();
 
   /* Create the model for the var_sheet */
index 33b465496e621c9aacf2eeaf1052b2fd6f882127..fedd9e3f5e98467a61bc87187c8bb71143d80059 100644 (file)
@@ -1,3 +1,27 @@
+Tue Apr 25 10:58:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, drop
+       actual message printing from core code, substituting a callback,
+       and add the callback to each UI.  Also, move verbose_msg() into
+       its own module.
+
+       * automake.mk (src_ui_terminal_libui_a_SOURCES): Add msg-ui.c.
+
+       * command-line.c: (parse_command_line) Call
+       verbose_increment_level() instead of increment err_verbosity
+       directly, now that we have a little abstraction.
+
+       * msg-ui.c: New file.
+
+       * msg-ui.h: New file.
+
+       * main.c: (main) Call msg_ui_init().  Use any_errors().
+       (terminate) Call msg_ui_done().  Make termination order more
+       rational.
+
+       * read-line.c: (readln_read) Use reset_msg_count() now we have a
+       little abstraction.
+
 Tue Apr 25 09:39:46 2006  Ben Pfaff  <blp@gnu.org>
 
        * main.c: (terminate) Mark static and NO_RETURN.  If called
index 7411bbd33161430ef5d4452571c4683db48386c2..805cd6c2e48949d7930c97e7661078946a8653de 100644 (file)
@@ -3,16 +3,20 @@
 noinst_LIBRARIES += src/ui/terminal/libui.a
 
 src_ui_terminal_libui_a_SOURCES = \
- src/ui/terminal/command-line.c src/ui/terminal/command-line.h \
- src/ui/terminal/read-line.c src/ui/terminal/read-line.h  \
- src/ui/terminal/main.c
+       src/ui/terminal/command-line.c \
+       src/ui/terminal/command-line.h \
+       src/ui/terminal/read-line.c \
+       src/ui/terminal/read-line.h \
+       src/ui/terminal/main.c \
+       src/ui/terminal/msg-ui.c
 
 
 bin_PROGRAMS += src/ui/terminal/pspp
 
-src_ui_terminal_pspp_SOURCES =                                 \
-       src/message.c                                   \
-       src/procedure.c  src/procedure.h 
+src_ui_terminal_pspp_SOURCES = \
+       src/message.c \
+       src/procedure.c \
+       src/procedure.h
 
 src_ui_terminal_pspp_LDADD =                                   \
        $(top_builddir)/src/language/expressions/libexpressions.a \
index 2a1fa41cda0677e2d2bb2a1db6a10f986b064064..94c5eea10e3acfc3996a3fede7ddaacd57a29b10 100644 (file)
@@ -36,6 +36,7 @@
 #include <data/file-name.h>
 #include <libpspp/str.h>
 #include <libpspp/version.h>
+#include <libpspp/verbose-msg.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -163,7 +164,7 @@ parse_command_line (int argc, char **argv)
          set_safer_mode ();
          break;
        case 'v':
-         err_verbosity++;
+         verbose_increment_level ();
          break;
        case 'V':
          puts (version);
index 14677adad8b1813dabd45370386f5186db89c838..16058e45d33913dda0224d721fc7e188409e93a9 100644 (file)
    02110-1301, USA. */
 
 #include <config.h>
-#include <gsl/gsl_errno.h>
-#include <signal.h>
-#include <stdio.h>
+
 #include "command-line.h"
-#include <language/command.h>
-#include <libpspp/compiler.h>
+#include "msg-ui.h"
+#include "progname.h"
+#include "read-line.h"
+
 #include <data/dictionary.h>
-#include <libpspp/message.h>
 #include <data/file-handle-def.h>
 #include <data/file-name.h>
-#include <language/line-buffer.h>
-#include <language/lexer/lexer.h>
-#include <output/output.h>
-#include "progname.h"
-#include <math/random.h>
-#include "read-line.h"
 #include <data/settings.h>
 #include <data/variable.h>
+#include <gsl/gsl_errno.h>
+#include <language/command.h>
+#include <language/lexer/lexer.h>
+#include <language/line-buffer.h>
+#include <libpspp/compiler.h>
+#include <libpspp/message.h>
 #include <libpspp/version.h>
+#include <math/random.h>
+#include <output/output.h>
+#include <signal.h>
+#include <stdio.h>
+
 
 #if HAVE_FPU_CONTROL_H
 #include <fpu_control.h>
@@ -82,6 +86,7 @@ main (int argc, char **argv)
   gsl_set_error_handler_off ();
 
   outp_init ();
+  msg_ui_init ();
   fn_init ();
   fh_init ();
   getl_initialize ();
@@ -100,7 +105,7 @@ main (int argc, char **argv)
         {
           int retval;
 
-          err_check_count ();
+          check_msg_count ();
 
           retval = execute_command ();
           if (retval == CMD_EOF)
@@ -110,7 +115,7 @@ main (int argc, char **argv)
         }
     }
   
-  terminate (err_error_count == 0);
+  terminate (!any_errors ());
 }
 
 /* Parse and execute a command, returning its return code. */
@@ -252,9 +257,6 @@ terminate (bool success)
     {
       terminating = true;
 
-      msg_done ();
-      outp_done ();
-
       cancel_transformations ();
       dict_destroy (default_dict);
 
@@ -264,6 +266,9 @@ terminate (bool success)
       lex_done ();
       getl_uninitialize ();
       readln_uninitialize ();
+
+      outp_done ();
+      msg_ui_done ();
     }
   exit (success ? EXIT_SUCCESS : EXIT_FAILURE);
 }
diff --git a/src/ui/terminal/msg-ui.c b/src/ui/terminal/msg-ui.c
new file mode 100644 (file)
index 0000000..3422da0
--- /dev/null
@@ -0,0 +1,224 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program 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 2 of the
+   License, or (at your option) any later version.
+
+   This program 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 this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#include <config.h>
+
+#include "msg-ui.h"
+
+#include "exit.h"
+#include "linebreak.h"
+
+#include <language/line-buffer.h>
+#include <data/settings.h>
+#include <libpspp/message.h>
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+/* Number of errors, warnings reported. */
+static int error_count;
+static int warning_count;
+
+static void handle_msg (const struct msg *);
+
+void
+msg_ui_init (void) 
+{
+  msg_init (handle_msg);
+}
+
+void
+msg_ui_done (void) 
+{
+  msg_done ();
+}
+
+/* Checks whether we've had so many errors that it's time to quit
+   processing this syntax file. */
+void
+check_msg_count (void)
+{
+  if (!getl_is_interactive ()) 
+    {
+      if (get_errorbreak () && error_count)
+        msg (MN, _("Terminating execution of syntax file due to error."));
+      else if (error_count > get_mxerrs() )
+        msg (MN, _("Errors (%d) exceeds limit (%d)."),
+             error_count, get_mxerrs());
+      else if (error_count + warning_count > get_mxwarns() )
+        msg (MN, _("Warnings (%d) exceed limit (%d)."),
+             error_count + warning_count, get_mxwarns() );
+      else
+        return;
+
+      getl_abort_noninteractive (); 
+    }
+}
+
+void
+reset_msg_count (void) 
+{
+  error_count = warning_count = 0;
+}
+
+bool
+any_errors (void) 
+{
+  return error_count > 0;
+}
+\f
+static void dump_message (char *msg, unsigned width, unsigned indent, FILE *);
+static void dump_line (int line_indent, const char *line, size_t length,
+                       FILE *);
+
+static void
+handle_msg (const struct msg *m)
+{
+  struct category 
+    {
+      bool show_command_name;   /* Show command name with error? */
+      bool show_file_location;  /* Show syntax file location? */
+    };
+
+  static const struct category categories[] = 
+    {
+      {false, false},           /* MSG_GENERAL. */
+      {true, true},             /* MSG_SYNTAX. */
+      {false, true},            /* MSG_DATA. */
+    };
+
+  struct severity 
+    {
+      const char *name;         /* How to identify this severity. */
+      int *count;               /* Number of msgs with this severity so far. */
+    };
+  
+  static struct severity severities[] = 
+    {
+      {N_("error"), &error_count},          /* MSG_ERROR. */
+      {N_("warning"), &warning_count},      /* MSG_WARNING. */
+      {NULL, NULL},                         /* MSG_NOTE. */
+    };
+
+  const struct category *category = &categories[m->category];
+  const struct severity *severity = &severities[m->severity];
+  struct string string = DS_INITIALIZER;
+
+  if (category->show_file_location && m->where.file_name)
+    {
+      ds_printf (&string, "%s:", m->where.file_name);
+      if (m->where.line_number != -1)
+       ds_printf (&string, "%d:", m->where.line_number);
+      ds_putc (&string, ' ');
+    }
+
+  if (severity->name != NULL)
+    ds_printf (&string, "%s: ", gettext (severity->name));
+  
+  if (severity->count != NULL)
+    ++*severity->count;
+  
+  if (category->show_command_name && msg_get_command_name () != NULL)
+    ds_printf (&string, "%s: ", msg_get_command_name ());
+
+  ds_puts (&string, m->text);
+
+  /* FIXME: Check set_messages and set_errors to determine where to
+     send errors and messages. */
+  dump_message (ds_c_str (&string), get_viewwidth (), 8, stdout);
+
+  ds_destroy (&string);
+}
+
+/* Divides MSG into lines of WIDTH width for the first line and
+   WIDTH - INDENT width for each succeeding line, and writes the
+   lines to STREAM. */
+static void
+dump_message (char *msg, unsigned width, unsigned indent, FILE *stream)
+{
+  size_t length = strlen (msg);
+  char *string, *breaks;
+  int line_indent;
+  size_t line_start, i;
+
+  /* Allocate temporary buffers.
+     If we can't get memory for them, then just dump the whole
+     message. */
+  string = strdup (msg);
+  breaks = malloc (length);
+  if (string == NULL || breaks == NULL)
+    {
+      free (string);
+      free (breaks);
+      fputs (msg, stream);
+      putc ('\n', stream);
+      return;
+    }
+
+  /* Break into lines. */
+  if (indent > width / 3)
+    indent = width / 3;
+  mbs_width_linebreaks (string, length,
+                        width - indent, -indent, 0,
+                        NULL, locale_charset (), breaks);
+
+  /* Write out lines. */
+  line_start = 0;
+  line_indent = 0;
+  for (i = 0; i < length; i++)
+    switch (breaks[i]) 
+      {
+      case UC_BREAK_POSSIBLE:
+        /* Break before this character,
+           and include this character in the next line. */
+        dump_line (line_indent, &string[line_start], i - line_start, stream);
+        line_start = i;
+        line_indent = indent;
+        break;
+      case UC_BREAK_MANDATORY:
+        /* Break before this character,
+           but don't include this character in the next line
+           (because it'string a new-line). */
+        dump_line (line_indent, &string[line_start], i - line_start, stream);
+        line_start = i + 1;
+        line_indent = indent;
+        break;
+      default:
+        break;
+      }
+  if (line_start < length)
+    dump_line (line_indent, &string[line_start], length - line_start, stream);
+
+  free (string);
+  free (breaks);
+}
+
+/* Write LINE_INDENT spaces, the LENGTH characters in LINE, then
+   a new-line to STREAM. */
+static void
+dump_line (int line_indent, const char *line, size_t length, FILE *stream)
+{
+  int i;
+  for (i = 0; i < line_indent; i++)
+    putc (' ', stream);
+  fwrite (line, 1, length, stream);
+  putc ('\n', stream);
+}
+
diff --git a/src/ui/terminal/msg-ui.h b/src/ui/terminal/msg-ui.h
new file mode 100644 (file)
index 0000000..fc9dcd9
--- /dev/null
@@ -0,0 +1,31 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program 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 2 of the
+   License, or (at your option) any later version.
+
+   This program 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 this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#ifndef MSG_UI_H
+#define MSG_UI_H 1
+
+#include <stdbool.h>
+
+void msg_ui_init (void);
+void msg_ui_done (void);
+void check_msg_count (void);
+void reset_msg_count (void);
+bool any_errors (void);
+
+#endif /* msg-ui.h */
index 1a71d77a597689b0f0a5acc989de70afc6073b18..2a0bfd5e2be55ca584ef6c6c2f1088a5a90d22c7 100644 (file)
 
 #include <config.h>
 
+#include "read-line.h"
+
 #include <stdlib.h>
 #include <stdbool.h>
 #include <assert.h>
 #include <errno.h>
 
-#include "read-line.h"
-#include <language/command.h>
+#include "msg-ui.h"
+
 #include <data/file-name.h>
-#include <libpspp/version.h>
-#include <libpspp/str.h>
-#include <output/table.h>
-#include <libpspp/message.h>
 #include <data/file-name.h>
 #include <data/settings.h>
+#include <language/command.h>
+#include <libpspp/message.h>
+#include <libpspp/str.h>
+#include <libpspp/version.h>
+#include <output/table.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -117,8 +120,7 @@ readln_read (struct string *line, const char *prompt)
   
   assert(initialised);
 
-  err_error_count = err_warning_count = 0;
-  err_already_flagged = 0;
+  reset_msg_count ();
 
   welcome ();