c657f096f3c16d9679f3bfafff44fa57017d2994
[pspp] / src / ui / terminal / msg-ui.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000, 2006, 2010 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include "ui/terminal/msg-ui.h"
20
21 #include <errno.h>
22 #include <limits.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26
27 #include "data/settings.h"
28 #include "libpspp/getl.h"
29 #include "libpspp/message.h"
30 #include "libpspp/msg-locator.h"
31 #include "libpspp/str.h"
32 #include "output/journal.h"
33 #include "output/driver.h"
34 #include "output/tab.h"
35 #include "output/message-item.h"
36
37 #include "gl/unilbrk.h"
38 #include "gl/localcharset.h"
39
40 #include "gettext.h"
41 #define _(msgid) gettext (msgid)
42 #define N_(msgid) msgid
43
44 /* Number of messages reported, by severity level. */
45 static int counts[MSG_N_SEVERITIES];
46
47 /* True after the maximum number of errors or warnings has been exceeded. */
48 static bool too_many_errors;
49
50 /* True after the maximum number of notes has been exceeded. */
51 static bool too_many_notes;
52
53 static void handle_msg (const struct msg *);
54
55 void
56 msg_ui_init (struct source_stream *ss)
57 {
58   msg_init (ss, handle_msg);
59 }
60
61 void
62 msg_ui_done (void)
63 {
64   msg_done ();
65   msg_locator_done ();
66 }
67
68 /* Checks whether we've had so many errors that it's time to quit
69    processing this syntax file. */
70 bool
71 msg_ui_too_many_errors (void)
72 {
73   return too_many_errors;
74 }
75
76 void
77 msg_ui_reset_counts (void)
78 {
79   int i;
80
81   for (i = 0; i < MSG_N_SEVERITIES; i++)
82     counts[i] = 0;
83   too_many_errors = false;
84   too_many_notes = false;
85 }
86
87 bool
88 msg_ui_any_errors (void)
89 {
90   return counts[MSG_S_ERROR] > 0;
91 }
92
93 static void
94 submit_note (char *s)
95 {
96   struct msg m;
97
98   m.category = MSG_C_GENERAL;
99   m.severity = MSG_S_NOTE;
100   m.where.file_name = NULL;
101   m.where.line_number = -1;
102   m.text = s;
103   message_item_submit (message_item_create (&m));
104   free (s);
105 }
106
107 static void
108 handle_msg (const struct msg *m)
109 {
110   int n_msgs, max_msgs;
111
112   if (too_many_errors || (too_many_notes && m->severity == MSG_S_NOTE))
113     return;
114
115   message_item_submit (message_item_create (m));
116
117   counts[m->severity]++;
118   max_msgs = settings_get_max_messages (m->severity);
119   n_msgs = counts[m->severity];
120   if (m->severity == MSG_S_WARNING)
121     n_msgs += counts[MSG_S_ERROR];
122   if (n_msgs > max_msgs)
123     {
124       if (m->severity == MSG_S_NOTE)
125         {
126           too_many_notes = true;
127           submit_note (xasprintf (_("Notes (%d) exceed limit (%d).  "
128                                     "Suppressing further notes."),
129                                   n_msgs, max_msgs));
130         }
131       else
132         {
133           too_many_errors = true;
134           if (m->severity == MSG_S_WARNING)
135             submit_note (xasprintf (_("Warnings (%d) exceed limit (%d)."),
136                                     n_msgs, max_msgs));
137           else
138             submit_note (xasprintf (_("Errors (%d) exceed limit (%d)."),
139                                     n_msgs, max_msgs));
140         }
141     }
142 }