1 /* lexerr.c
2
3 Written by Don Maszle
4 15 September 1991
5
6 Copyright (c) 1991-2017 Free Software Foundation, Inc.
7
8 This file is part of GNU MCSim.
9
10 GNU MCSim is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 3
13 of the License, or (at your option) any later version.
14
15 GNU MCSim is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GNU MCSim; if not, see <http://www.gnu.org/licenses/>
22
23 Reports errors and exits program if fatal.
24 */
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdarg.h>
30
31 #include "lexerr.h"
32 #include "simi.h"
33
34
35 /* -----------------------------------------------------------------------------
36 ReportError
37
38 Reports error iCode to terminal (one of RE_) and optional
39 szMessage. If iSeverity is set to RE_FATAL, exits program.
40 */
41
ReportError(PINPUTBUF pibIn,WORD wCode,PSTR szMsg,PSTR szAltMsg)42 void ReportError (PINPUTBUF pibIn, WORD wCode, PSTR szMsg, PSTR szAltMsg)
43 {
44 char cNull = '\0';
45 BOOL bFatal = wCode & RE_FATAL;
46 BOOL bWarning = wCode & RE_WARNING;
47
48 wCode &= ~(RE_FATAL | RE_WARNING);
49
50 if (!szMsg)
51 szMsg = &cNull;
52
53 if (wCode) {
54 if (bWarning)
55 printf ("Warning: ");
56 else {
57 printf ("Error: ");
58 bFatal |= (pibIn && (pibIn->cErrors++ > MAX_ERRORS));
59 }
60 } /* if */
61
62 if (pibIn) {
63 if (pibIn->pfileIn || pibIn->iLNPrev) { /* Line number is valid */
64 printf ("line %d: ", pibIn->iLineNum);
65 }
66 else {
67 if (wCode != RE_FILENOTFOUND) { /* Dummy pibIn, show buffer */
68 PSTRLEX szTmp;
69 szTmp[MAX_LEX-1] = '\0';
70 printf ("'%s'...\n ", strncpy (szTmp, pibIn->pbufOrg, MAX_LEX-1));
71 } /* if */
72 }
73 }
74
75 switch (wCode) {
76
77 case 0:
78 break;
79
80 default:
81 printf ("Unknown error code %x: %s", wCode, szMsg);
82
83 case RE_INIT:
84 printf ("Initialization error.");
85 break;
86
87 case RE_FILENOTFOUND:
88 printf ("File not found \"%s\".", szMsg);
89 break;
90
91 case RE_CANNOTOPEN:
92 printf ("Cannot open file \"%s\".", szMsg);
93 break;
94
95 case RE_OUTOFMEM:
96 printf ("Out of memory in %s().", szMsg);
97 break;
98
99 case RE_READERROR:
100 printf ("%s file cannot be read\n", szMsg);
101 break;
102
103 case RE_UNEXPECTED:
104 printf ("Unexpected character '%c' in input file.", *szMsg);
105 break;
106
107 case RE_UNEXPNUMBER:
108 printf ("Unexpected number %s in input file.", szMsg);
109 break;
110
111 case RE_EXPECTED:
112 printf ("Expected '%c' before '%c'.", szMsg[1], szMsg[0]);
113 break;
114
115 case RE_LEXEXPECTED:
116 printf ("Expected <%s>", szMsg);
117 if (szAltMsg)
118 printf (" before '%s'", szAltMsg);
119 break;
120
121 case RE_SYNTAXERR:
122 printf("Syntax error %s", szMsg);
123 break;
124
125 case RE_BADCONTEXT:
126 printf ("'%s' used in invalid context.", szMsg);
127 break;
128
129 case RE_TOOMANYLEVELS:
130 printf("Too many levels");
131 break;
132
133 case RE_TOOMANYINST:
134 printf("Too many instances at level %s", szMsg);
135 break;
136
137 case RE_OPENLEVEL:
138 printf("Unclosed level statement");
139 break;
140
141 case RE_LEVINEXPT:
142 printf("Level statement enclosed in Simulation (Experiment) statement");
143 break;
144
145 case RE_TOOMANYPVARS:
146 printf("Too many variables in 'Print(...)' statement");
147 break;
148
149 case RE_EQNTOOLONG:
150 printf ("Equation is too long. Possibly missing terminator.");
151 break;
152
153 case RE_UNDEFINED:
154 printf ("Undefined identifier '%s'.", szMsg);
155 break;
156
157 case RE_TYPENOTMCMC:
158 printf ("The level statement is permitted only in MCMC simulations.\n");
159 break;
160
161 /* Simulation input errors */
162
163 case RE_ERRORSINEXP:
164 printf ("Bad definition of experiment %d\n", *(PINT)szMsg);
165 break;
166
167 case RE_NOOUTPUTS:
168 printf ("Simulation (Experiment) %d has no outputs specified\n",
169 *(PINT)szMsg);
170 break;
171
172 case RE_POSITIVE:
173 printf ("Positive number expected.");
174 break;
175
176 case RE_SPECERR:
177 printf ("in specification: %s", szMsg);
178 break;
179
180 case RE_INSUF_POINTS:
181 printf ("Insufficient points in file \"%s\"\n", szMsg);
182 break;
183
184 case RE_MAXMIN_RANGE:
185 printf ("Max is less than min\n");
186 break;
187
188 case RE_OUTISRESTART:
189 printf ("Output and restart files have the same name\n");
190 break;
191
192 } /* switch */
193
194 printf ("\n");
195 if (szAltMsg && wCode != RE_LEXEXPECTED)
196 printf ("%s\n", szAltMsg);
197
198 if (bFatal) {
199 if ((pibIn != NULL) && (pibIn->pInfo != NULL))
200 FreeLevels((PANALYSIS)pibIn->pInfo);
201
202 printf ("\nFatal errors. Exiting.\n\n");
203
204 exit (wCode);
205
206 } /* if bFatal */
207
208 } /* ReportError */
209
210
211 /* -----------------------------------------------------------------------------
212 ReportRunTimeError
213
214 Reports error iCode to terminal (one of RE_) and optional
215 szMessage. If iSeverity is set to RE_FATAL, exits program.
216 */
217
ReportRunTimeError(PANALYSIS panal,WORD wCode,...)218 void ReportRunTimeError (PANALYSIS panal, WORD wCode, ...)
219 {
220 va_list ap;
221 PSTR szMsg1, szMsg2, szMsg3;
222 BOOL bFatal = wCode & RE_FATAL;
223 BOOL bWarning = wCode & RE_WARNING;
224
225 wCode &= ~(RE_FATAL | RE_WARNING);
226
227 if(wCode)
228 bWarning ? (printf("Warning: ")) : (printf ("Fatal error: "));
229
230 va_start(ap, wCode);
231
232 switch (wCode) {
233
234 case 0:
235 break;
236
237 default:
238 printf("Unknown error code %x", wCode);
239 break;
240
241 case RE_OUTOFMEM:
242 szMsg1 = va_arg(ap, PSTR);
243 printf ("Out of memory in %s().", szMsg1);
244 break;
245
246 case RE_CANNOTOPEN:
247 szMsg1 = va_arg(ap, PSTR);
248 szMsg2 = va_arg(ap, PSTR);
249 printf ("Cannot open file \"%s\" in %s().", szMsg1, szMsg2);
250 break;
251
252 case RE_BADNORMALSD:
253 szMsg1 = va_arg(ap, PSTR);
254 szMsg2 = va_arg(ap, PSTR);
255 szMsg3 = va_arg(ap, PSTR);
256 printf ("SD of normal variate %s = %s in %s().",
257 szMsg1, szMsg2, szMsg3);
258 break;
259
260 case RE_BADLOGNORMALSD:
261 szMsg1 = va_arg(ap, PSTR);
262 szMsg2 = va_arg(ap, PSTR);
263 szMsg3 = va_arg(ap, PSTR);
264 printf ("SD of lognormal variate %s = %s in %s().",
265 szMsg1, szMsg2, szMsg3);
266 break;
267
268 case RE_BADLOGNORMALMEAN:
269 szMsg1 = va_arg(ap, PSTR);
270 szMsg2 = va_arg(ap, PSTR);
271 szMsg3 = va_arg(ap, PSTR);
272 printf ("Mean of lognormal variate %s = %s in %s().",
273 szMsg1, szMsg2, szMsg3);
274 break;
275
276 case RE_BADUNIFORMDIST:
277 szMsg1 = va_arg(ap, PSTR);
278 szMsg2 = va_arg(ap, PSTR);
279 printf ("Max and min of uniform variate %s are equal or inverted in %s().",
280 szMsg1, szMsg2);
281 break;
282
283 case RE_UNKNOWNDIST:
284 szMsg1 = va_arg(ap, PSTR);
285 printf ("Unknown distribution in %s().", szMsg1);
286 break;
287
288 case RE_BADMODEL:
289 printf ("Bad value in output; model is not computable.\n");
290 break;
291
292 case RE_DUPVARINEXPRT:
293 szMsg1 = va_arg(ap, PSTR);
294 szMsg2 = va_arg(ap, PSTR);
295 printf ("Variable %s appears in two or more '%s' statements.\n",
296 szMsg1, szMsg2);
297 break;
298
299 } /* switch */
300
301 printf ("\n");
302
303 va_end(ap);
304
305 if (bFatal) {
306 if (panal != NULL)
307 FreeLevels(panal);
308
309 printf ("\nFatal errors. Exiting.\n\n");
310
311 exit (wCode);
312 }
313
314 } /* ReportRunTimeError */
315
316 /* End. */
317
318