4aca18565d242a2256c89c1600488e8c66e15a30
[ctsim.git] / libctsupport / syserror.cpp
1 /*****************************************************************************
2 **  This is part of the CTSim program
3 **  Copyright (c) 1983-2001 Kevin Rosenberg
4 **
5 **  $Id: syserror.cpp,v 1.24 2003/03/15 14:52:36 kevin Exp $
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 #endif
32
33 /* NAME
34 *   sys_error                   System error handler
35 *
36 * SYNOPSIS
37 *   sys_error (severity, msg, args . . .)
38 *   int severity                Severity of error
39 *   char *msg                   Error message
40 *   args                        Argument list, direct transfer to printf stack
41 */
42
43 static int s_reportErrorLevel = ERR_TRACE;      // Set error reporting level 
44
45
46 void sys_error (int severity, const char *msg, ...)
47 {
48   va_list arg;
49   
50   va_start(arg, msg);
51   
52   std::string strOutput;
53   sys_verror (strOutput, severity, msg, arg);
54  
55 #ifdef HAVE_WXWINDOWS
56   if (g_bRunningWXWindows) {
57     if (theApp) {
58       wxCommandEvent eventLog (wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT );
59       wxString msg (strOutput.c_str());
60       msg += "\n";
61       eventLog.SetString( msg );
62       wxPostEvent( theApp->getMainFrame(), eventLog ); // send log event, thread safe
63     } else {
64       wxMutexGuiEnter();
65       wxLog::OnLog (wxLOG_Message, strOutput.c_str(), time(NULL));
66       wxMutexGuiLeave();
67     }
68   }
69   else
70 #endif
71     std::cout << strOutput << "\n";
72
73   va_end(arg);
74 }
75
76 static int s_nErrorCount = 0;
77 const static int MAX_ERROR_COUNT = 20;
78
79
80 void sys_verror (std::string& strOutput, int severity, const char *msg, va_list arg)
81 {
82   if (severity < s_reportErrorLevel)
83     return;     // ignore error if less than reporting level
84   
85   std::ostringstream os;
86
87   if (severity > ERR_TRACE)
88     s_nErrorCount++;
89
90   if (severity != ERR_FATAL) {
91     if (s_nErrorCount > MAX_ERROR_COUNT)
92       return;
93     else if (s_nErrorCount == MAX_ERROR_COUNT) {
94       os << "*****************************************************************\n";
95       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";
96       os << "***                                                           ***\n";
97       os << "***           No further errors will be reported              ***\n";
98       os << "*****************************************************************\n";
99       strOutput = os.str();
100       return;
101     }
102   }
103   
104   switch (severity) {
105   case ERR_FATAL:
106     os << "FATAL ERROR: ";
107     break;
108   case ERR_SEVERE:
109     os << "SEVERE ERROR: ";
110     break;
111   case ERR_WARNING:
112     os << "WARNING ERROR: ";
113     break;
114   case ERR_TRACE:
115     os << "Trace: ";
116     break;
117   default:
118     os << "Illegal error severity #" << severity << ": ";
119   }
120   
121   char errStr[2000];
122   
123 #if HAVE_VSNPRINTF
124   vsnprintf (errStr, sizeof(errStr), msg, arg);
125 #elif HAVE_VSPRINTF
126   vsprintf (errStr, msg, arg);
127 #else
128   strncpy (errStr, sizeof(errStr), "Error message not available on this platform.");
129 #endif
130   
131   os << errStr;
132   strOutput = os.str();
133   
134   if (severity == ERR_FATAL) {
135     std::cerr << strOutput << "\n";
136     throw std::runtime_error (strOutput); 
137   }
138   
139 #if INTERACTIVE_ERROR_DISPLAY
140   std::cout << "A - Abort  C - Continue  W - Turn off warnings? ";
141   //  fflush(stderr);
142   do 
143   {
144     int c = cio_kb_waitc("AaBbCcWw", TRUE);       /* get code from keyboard */
145     c = tolower (c);
146     fputc (c, stderr);
147     fputc (NEWLINE, stderr);
148     
149     if (c == 'a')
150       exit (1);
151     else if (c == 'c')
152       return;
153     else if (c == 'w') 
154     {
155       sys_error_level (ERR_SEVERE);     /* report severe & fatal errors */
156       break;
157     }
158   } while (TRUE);
159 #endif
160 }
161
162
163 /* NAME
164 *   sys_error_level                     Set error reporting level
165 *
166 * SYNOPSIS
167 *   sys_error_level (severity)
168 *   int severity                Report all error as serious as severity and beyond
169 *
170 * DESCRIPTION
171 *   Causes the system to ignore all error below the level of severity
172 *   For example, if severity == ERR_SEVERE, then report severe & fatal
173 *   error and ignore warnings
174 */
175
176 void 
177 sys_error_level (int severity)
178 {
179   if (severity == ERR_FATAL ||
180     severity == ERR_SEVERE ||
181     severity == ERR_WARNING ||
182     severity == ERR_TRACE)
183     s_reportErrorLevel = severity;
184   else
185     s_reportErrorLevel = ERR_WARNING;
186 }
187