d50471ef4f1e504aac49fa806ca76d348fab8373
[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.20 2001/01/30 02:20:50 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 *                               Can take 24 byte transfer
42 */
43
44 static int s_reportErrorLevel = ERR_WARNING;    // 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       *theApp->getLog() << strOutput.c_str() << "\n";
60     else
61       wxLog::OnLog (wxLOG_Message, strOutput.c_str(), time(NULL));
62   }
63   else
64 #endif
65     std::cout << strOutput;
66
67   va_end(arg);
68 }
69
70 static int s_nErrorCount = 0;
71 const static int MAX_ERROR_COUNT = 20;
72
73
74 void sys_verror (std::string& strOutput, int severity, const char *msg, va_list arg)
75 {
76   if (severity < s_reportErrorLevel)
77     return;     // ignore error if less than reporting level
78   
79   std::ostringstream os;
80
81   s_nErrorCount++;
82   if (severity != ERR_FATAL) {
83     if (s_nErrorCount > MAX_ERROR_COUNT)
84       return;
85     else if (s_nErrorCount == MAX_ERROR_COUNT) {
86       os << "*****************************************************************\n";
87       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";
88       os << "***                                                           ***\n";
89       os << "***           No further errors will be reported              ***\n";
90       os << "*****************************************************************\n";
91       strOutput = os.str();
92       return;
93     }
94   }
95   
96   switch (severity) {
97   case ERR_FATAL:
98     os << "FATAL ERROR: ";
99     break;
100   case ERR_SEVERE:
101     os << "SEVERE ERROR: ";
102     break;
103   case ERR_WARNING:
104     os << "WARNING ERROR: ";
105     break;
106   case ERR_TRACE:
107     os << "Trace: ";
108     break;
109   default:
110     os << "Illegal error severity #" << severity << ": ";
111   }
112   
113   char errStr[2000];
114   
115 #if HAVE_VSNPRINTF
116   vsnprintf (errStr, sizeof(errStr), msg, arg);
117 #elif HAVE_VSPRINTF
118   vsprintf (errStr, msg, arg);
119 #else
120   strncpy (errStr, sizeof(errStr), "Error message not available on this platform.");
121 #endif
122   
123   os << errStr << "\n";
124   strOutput = os.str();
125   
126   if (severity == ERR_FATAL) {
127     std::cerr << strOutput;
128     throw std::runtime_error (strOutput); 
129   }
130   
131 #if INTERACTIVE_ERROR_DISPLAY
132   std::cout << "A - Abort  C - Continue  W - Turn off warnings? ";
133   //  fflush(stderr);
134   do 
135   {
136     int c = cio_kb_waitc("AaBbCcWw", TRUE);       /* get code from keyboard */
137     c = tolower (c);
138     fputc (c, stderr);
139     fputc (NEWLINE, stderr);
140     
141     if (c == 'a')
142       exit (1);
143     else if (c == 'c')
144       return;
145     else if (c == 'w') 
146     {
147       sys_error_level (ERR_SEVERE);     /* report severe & fatal errors */
148       break;
149     }
150   } while (TRUE);
151 #endif
152 }
153
154
155 /* NAME
156 *   sys_error_level                     Set error reporting level
157 *
158 * SYNOPSIS
159 *   sys_error_level (severity)
160 *   int severity                Report all error as serious as severity and beyond
161 *
162 * DESCRIPTION
163 *   Causes the system to ignore all error below the level of severity
164 *   For example, if severity == ERR_SEVERE, then report severe & fatal
165 *   error and ignore warnings
166 */
167
168 void 
169 sys_error_level (int severity)
170 {
171   if (severity == ERR_FATAL ||
172     severity == ERR_SEVERE ||
173     severity == ERR_WARNING ||
174     severity == ERR_TRACE)
175     s_reportErrorLevel = severity;
176   else
177     s_reportErrorLevel = ERR_WARNING;
178 }
179