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