From 9f1d9ea8ac4f5e35a773581cf3d5ebd9e219bff8 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 25 Apr 2006 18:03:03 +0000 Subject: [PATCH] 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. --- src/ChangeLog | 29 +++++ src/data/file-name.c | 17 ++- src/language/line-buffer.c | 18 +-- src/libpspp/ChangeLog | 14 +++ src/libpspp/automake.mk | 2 + src/libpspp/message.h | 20 +-- src/libpspp/verbose-msg.c | 56 +++++++++ src/libpspp/verbose-msg.h | 29 +++++ src/message.c | 215 ++++--------------------------- src/ui/gui/ChangeLog | 18 +++ src/ui/gui/automake.mk | 6 +- src/ui/gui/message-dialog.c | 69 +++------- src/ui/gui/message-dialog.h | 2 + src/ui/gui/psppire.c | 3 + src/ui/terminal/ChangeLog | 24 ++++ src/ui/terminal/automake.mk | 16 ++- src/ui/terminal/command-line.c | 3 +- src/ui/terminal/main.c | 39 +++--- src/ui/terminal/msg-ui.c | 224 +++++++++++++++++++++++++++++++++ src/ui/terminal/msg-ui.h | 31 +++++ src/ui/terminal/read-line.c | 18 +-- 21 files changed, 546 insertions(+), 307 deletions(-) create mode 100644 src/libpspp/verbose-msg.c create mode 100644 src/libpspp/verbose-msg.h create mode 100644 src/ui/terminal/msg-ui.c create mode 100644 src/ui/terminal/msg-ui.h diff --git a/src/ChangeLog b/src/ChangeLog index 30a56517..e656b93a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,32 @@ +Tue Apr 25 10:47:37 2006 Ben Pfaff + + 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 Continue reforming error message support. In this phase, rename diff --git a/src/data/file-name.c b/src/data/file-name.c index dd512c03..ea950020 100644 --- a/src/data/file-name.c +++ b/src/data/file-name.c @@ -18,19 +18,24 @@ 02110-1301, USA. */ #include -#include + #include "file-name.h" -#include -#include + #include #include -#include +#include +#include + #include "intprops.h" +#include "settings.h" +#include "xreadlink.h" + +#include +#include #include #include -#include "settings.h" +#include #include -#include "xreadlink.h" #include "gettext.h" #define _(msgid) gettext (msgid) diff --git a/src/language/line-buffer.c b/src/language/line-buffer.c index ce0160c5..e4515320 100644 --- a/src/language/line-buffer.c +++ b/src/language/line-buffer.c @@ -18,21 +18,25 @@ 02110-1301, USA. */ #include + #include -#include + #include #include #include -#include -#include -#include + #include -#include #include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include #include +#include #include "gettext.h" #define _(msgid) gettext (msgid) diff --git a/src/libpspp/ChangeLog b/src/libpspp/ChangeLog index 1b634fc9..ce4acf90 100644 --- a/src/libpspp/ChangeLog +++ b/src/libpspp/ChangeLog @@ -1,3 +1,17 @@ +Tue Apr 25 10:54:44 2006 Ben Pfaff + + 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 Continue reforming error message support. In this phase, rename diff --git a/src/libpspp/automake.mk b/src/libpspp/automake.mk index 40e57d61..4d796953 100644 --- a/src/libpspp/automake.mk +++ b/src/libpspp/automake.mk @@ -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 diff --git a/src/libpspp/message.h b/src/libpspp/message.h index 0cf67399..71fe1fa0 100644 --- a/src/libpspp/message.h +++ b/src/libpspp/message.h @@ -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 index 00000000..d4c29afd --- /dev/null +++ b/src/libpspp/verbose-msg.c @@ -0,0 +1,56 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Written by Ben Pfaff . + + 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 + +#include + +#include +#include + +#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 index 00000000..7364a08b --- /dev/null +++ b/src/libpspp/verbose-msg.h @@ -0,0 +1,29 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Written by Ben Pfaff . + + 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 + +void verbose_increment_level (void); +void verbose_msg (int level, const char *format, ...) + PRINTF_FORMAT (2, 3); + +#endif /* verbose-msg.h */ diff --git a/src/message.c b/src/message.c index 974347e0..27fe62d3 100644 --- a/src/message.c +++ b/src/message.c @@ -18,35 +18,28 @@ 02110-1301, USA. */ #include + #include + #include #include #include #include -#include + #include -#include #include -#include -#include +#include #include -#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; - /* 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); } /* 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 ) { diff --git a/src/ui/gui/ChangeLog b/src/ui/gui/ChangeLog index 6692d9aa..f4d3b0d2 100644 --- a/src/ui/gui/ChangeLog +++ b/src/ui/gui/ChangeLog @@ -1,3 +1,21 @@ +Tue Apr 25 10:56:53 2006 Ben Pfaff + + 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 Continue reforming error message support. In this phase, get rid diff --git a/src/ui/gui/automake.mk b/src/ui/gui/automake.mk index cfb082cc..f1dea453 100644 --- a/src/ui/gui/automake.mk +++ b/src/ui/gui/automake.mk @@ -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 diff --git a/src/ui/gui/message-dialog.c b/src/ui/gui/message-dialog.c index f1a18baf..cf1fb851 100644 --- a/src/ui/gui/message-dialog.c +++ b/src/ui/gui/message-dialog.c @@ -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 . diff --git a/src/ui/gui/message-dialog.h b/src/ui/gui/message-dialog.h index 66a33633..bda1608d 100644 --- a/src/ui/gui/message-dialog.h +++ b/src/ui/gui/message-dialog.h @@ -24,4 +24,6 @@ #include +void message_dialog_init (void); + #endif diff --git a/src/ui/gui/psppire.c b/src/ui/gui/psppire.c index 58264d99..b291b0af 100644 --- a/src/ui/gui/psppire.c +++ b/src/ui/gui/psppire.c @@ -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 */ diff --git a/src/ui/terminal/ChangeLog b/src/ui/terminal/ChangeLog index 33b46549..fedd9e3f 100644 --- a/src/ui/terminal/ChangeLog +++ b/src/ui/terminal/ChangeLog @@ -1,3 +1,27 @@ +Tue Apr 25 10:58:19 2006 Ben Pfaff + + 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 * main.c: (terminate) Mark static and NO_RETURN. If called diff --git a/src/ui/terminal/automake.mk b/src/ui/terminal/automake.mk index 7411bbd3..805cd6c2 100644 --- a/src/ui/terminal/automake.mk +++ b/src/ui/terminal/automake.mk @@ -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 \ diff --git a/src/ui/terminal/command-line.c b/src/ui/terminal/command-line.c index 2a1fa41c..94c5eea1 100644 --- a/src/ui/terminal/command-line.c +++ b/src/ui/terminal/command-line.c @@ -36,6 +36,7 @@ #include #include #include +#include #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); diff --git a/src/ui/terminal/main.c b/src/ui/terminal/main.c index 14677ada..16058e45 100644 --- a/src/ui/terminal/main.c +++ b/src/ui/terminal/main.c @@ -18,25 +18,29 @@ 02110-1301, USA. */ #include -#include -#include -#include + #include "command-line.h" -#include -#include +#include "msg-ui.h" +#include "progname.h" +#include "read-line.h" + #include -#include #include #include -#include -#include -#include -#include "progname.h" -#include -#include "read-line.h" #include #include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include + #if HAVE_FPU_CONTROL_H #include @@ -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 index 00000000..3422da02 --- /dev/null +++ b/src/ui/terminal/msg-ui.c @@ -0,0 +1,224 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Written by Ben Pfaff . + + 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 + +#include "msg-ui.h" + +#include "exit.h" +#include "linebreak.h" + +#include +#include +#include + +#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; +} + +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 index 00000000..fc9dcd95 --- /dev/null +++ b/src/ui/terminal/msg-ui.h @@ -0,0 +1,31 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Written by Ben Pfaff . + + 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 + +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 */ diff --git a/src/ui/terminal/read-line.c b/src/ui/terminal/read-line.c index 1a71d77a..2a0bfd5e 100644 --- a/src/ui/terminal/read-line.c +++ b/src/ui/terminal/read-line.c @@ -19,20 +19,23 @@ #include +#include "read-line.h" + #include #include #include #include -#include "read-line.h" -#include +#include "msg-ui.h" + #include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include #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 (); -- 2.30.2