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