r11859: Canonicalize whitespace
[ctsim.git] / libctsupport / syserror.cpp
1 /*****************************************************************************
2 **  This is part of the CTSim program
3 **  Copyright (c) 1983-2001 Kevin Rosenberg
4 **
5 **  $Id$
6 **
7 **  This program is free software; you can redistribute it and/or modify
8 **  it under the terms of the GNU General Public License (version 2) as
9 **  published by the Free Software Foundation.
10 **
11 **  This program is distributed in the hope that it will be useful,
12 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 **  GNU General Public License for more details.
15 **
16 **  You should have received a copy of the GNU General Public License
17 **  along with this program; if not, write to the Free Software
18 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 ******************************************************************************/
20
21 #include <iostream>
22 #include <exception>
23 #include <stdexcept>
24 #include <stdarg.h>
25 #include <ctype.h>
26 #include <string>
27 #include "ct.h"
28
29 #ifdef HAVE_WXWINDOWS
30 #include "../src/ctsim.h"
31 #include <wx/log.h>
32 #endif
33
34 /* NAME
35 *   sys_error                   System error handler
36 *
37 * SYNOPSIS
38 *   sys_error (severity, msg, args . . .)
39 *   int severity                Severity of error
40 *   char *msg                   Error message
41 *   args                        Argument list, direct transfer to printf stack
42 */
43
44 static int s_reportErrorLevel = ERR_TRACE;      // Set error reporting level
45
46
47 void sys_error (int severity, const char *msg, ...)
48 {
49   va_list arg;
50
51   va_start(arg, msg);
52
53   std::string strOutput;
54   sys_verror (strOutput, severity, msg, arg);
55
56 #ifdef HAVE_WXWINDOWS
57   if (g_bRunningWXWindows) {
58     if (theApp) {
59       wxCommandEvent eventLog (wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT );
60       wxString msg (strOutput.c_str());
61       if (msg.length() > 0) {
62         msg += "\n";
63         eventLog.SetString( msg );
64         wxPostEvent( theApp->getMainFrame(), eventLog ); // send log event, thread safe
65       }
66     } else {
67       wxMutexGuiEnter();
68       wxLog::OnLog (wxLOG_Message, strOutput.c_str(), time(NULL));
69       wxMutexGuiLeave();
70     }
71   }
72   else
73     std::cout << strOutput << "\n";
74 #else
75     std::cout << strOutput << "\n";
76 #endif
77
78   va_end(arg);
79 }
80
81 static unsigned long s_nErrorCount = 0;
82 unsigned long int g_lSysErrorMaxCount = 2000;
83
84
85 void sys_verror (std::string& strOutput, int severity, const char *msg, va_list arg)
86 {
87   if (severity < s_reportErrorLevel)
88     return;     // ignore error if less than reporting level
89
90   std::ostringstream os;
91
92   if (severity > ERR_TRACE)
93     s_nErrorCount++;
94
95   if (severity != ERR_FATAL) {
96     if (s_nErrorCount > g_lSysErrorMaxCount)
97       return;
98     else if (s_nErrorCount == g_lSysErrorMaxCount) {
99       os << "*****************************************************************\n";
100       os << "***   M A X I M U M   E R R O R   C O U N T   R E A C H E D   ***\n";
101       os << "***                                                           ***\n";
102       os << "***           No further errors will be reported              ***\n";
103       os << "*****************************************************************\n";
104       strOutput = os.str();
105       return;
106     }
107   }
108
109   switch (severity) {
110   case ERR_FATAL:
111     os << "FATAL ERROR: ";
112     break;
113   case ERR_SEVERE:
114     os << "SEVERE ERROR: ";
115     break;
116   case ERR_WARNING:
117     os << "WARNING ERROR: ";
118     break;
119   case ERR_TRACE:
120     os << "Trace: ";
121     break;
122   default:
123     os << "Illegal error severity #" << severity << ": ";
124   }
125
126   char errStr[2000];
127
128 #if HAVE_VSNPRINTF
129   vsnprintf (errStr, sizeof(errStr), msg, arg);
130 #elif HAVE_VSPRINTF
131   vsprintf (errStr, msg, arg);
132 #else
133   strncpy (errStr, sizeof(errStr), "Error message not available on this platform.");
134 #endif
135
136   os << errStr;
137   strOutput = os.str();
138
139   if (severity == ERR_FATAL) {
140     std::cerr << strOutput << "\n";
141     throw std::runtime_error (strOutput);
142   }
143
144 #if INTERACTIVE_ERROR_DISPLAY
145   std::cout << "A - Abort  C - Continue  W - Turn off warnings? ";
146   //  fflush(stderr);
147   do
148   {
149     int c = cio_kb_waitc("AaBbCcWw", TRUE);       /* get code from keyboard */
150     c = tolower (c);
151     fputc (c, stderr);
152     fputc (NEWLINE, stderr);
153
154     if (c == 'a')
155       exit (1);
156     else if (c == 'c')
157       return;
158     else if (c == 'w')
159     {
160       sys_error_level (ERR_SEVERE);     /* report severe & fatal errors */
161       break;
162     }
163   } while (TRUE);
164 #endif
165 }
166
167
168 /* NAME
169 *   sys_error_level                     Set error reporting level
170 *
171 * SYNOPSIS
172 *   sys_error_level (severity)
173 *   int severity                Report all error as serious as severity and beyond
174 *
175 * DESCRIPTION
176 *   Causes the system to ignore all error below the level of severity
177 *   For example, if severity == ERR_SEVERE, then report severe & fatal
178 *   error and ignore warnings
179 */
180
181 void
182 sys_error_level (int severity)
183 {
184   if (severity == ERR_FATAL ||
185     severity == ERR_SEVERE ||
186     severity == ERR_WARNING ||
187     severity == ERR_TRACE)
188     s_reportErrorLevel = severity;
189   else
190     s_reportErrorLevel = ERR_WARNING;
191 }
192