1 |
/* |
2 |
* Temporary Procedure Output |
3 |
* by Tom Epperly |
4 |
* Created: 1/10/90 |
5 |
* Version: $Revision: 1.11 $ |
6 |
* Version control file: $RCSfile: procio.c,v $ |
7 |
* Date last modified: $Date: 1998/05/12 19:57:43 $ |
8 |
* Last modified by: $Author: ballan $ |
9 |
* |
10 |
* This file is part of the Ascend Language Interpreter. |
11 |
* |
12 |
* Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly |
13 |
* |
14 |
* The Ascend Language Interpreter is free software; you can redistribute |
15 |
* it and/or modify it under the terms of the GNU General Public License as |
16 |
* published by the Free Software Foundation; either version 2 of the |
17 |
* License, or (at your option) any later version. |
18 |
* |
19 |
* The Ascend Language Interpreter is distributed in hope that it will be |
20 |
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
22 |
* General Public License for more details. |
23 |
* |
24 |
* You should have received a copy of the GNU General Public License along |
25 |
* with the program; if not, write to the Free Software Foundation, Inc., 675 |
26 |
* Mass Ave, Cambridge, MA 02139 USA. Check the file named COPYING. |
27 |
*/ |
28 |
#include<math.h> |
29 |
#include<stdio.h> |
30 |
#include <ascend/general/platform.h> |
31 |
#include <ascend/general/ascMalloc.h> |
32 |
|
33 |
#include <ascend/general/dstring.h> |
34 |
#include <ascend/general/list.h> |
35 |
|
36 |
|
37 |
#include "functype.h" |
38 |
#include "expr_types.h" |
39 |
#include "stattypes.h" |
40 |
#include "statement.h" |
41 |
#include "statio.h" |
42 |
#include "instance_enum.h" |
43 |
#include "instance_io.h" |
44 |
#include "nameio.h" |
45 |
#include "module.h" |
46 |
#include "proc.h" |
47 |
#include "watchpt.h" |
48 |
#include "procframe.h" |
49 |
#include "initialize.h" |
50 |
#include "procio.h" |
51 |
|
52 |
void WriteInitWarn(struct procFrame *fm, const char *str){ |
53 |
WriteStatementErrorMessage(fm->err, fm->stat, str, 0,2); |
54 |
} |
55 |
|
56 |
void WriteInitErr(struct procFrame *fm, const char *str){ |
57 |
WSEM(fm->err,fm->stat,str); |
58 |
FFLUSH(fm->err); |
59 |
} |
60 |
|
61 |
void ProcWriteCaseError(struct procFrame *fm, int arm, int pos){ |
62 |
static char nostr[] = ""; |
63 |
char *fmt; |
64 |
char *tail; |
65 |
char armstr[20]; |
66 |
char errmsg[100]; |
67 |
|
68 |
sprintf(armstr,"in arm %d.",arm); |
69 |
|
70 |
switch (fm->ErrNo) { |
71 |
case Proc_instance_not_found: |
72 |
fmt = "NULL (as yet unmade) instance for SWITCH argument %d %s"; |
73 |
tail = nostr; |
74 |
break; |
75 |
case Proc_name_not_found: |
76 |
fmt = "Undefined name for SWITCH argument %d %s"; |
77 |
tail = nostr; |
78 |
break; |
79 |
case Proc_illegal_name_use: |
80 |
fmt = "Incorrect name (subscript?) for SWITCH argument %d %s"; |
81 |
tail = nostr; |
82 |
break; |
83 |
case Proc_CallError: |
84 |
fmt = "Unexpected 'OK' message for SWITCH argument %d %s"; |
85 |
tail = nostr; |
86 |
break; |
87 |
case Proc_case_undefined_value: |
88 |
fmt = "Variable %d value UNDEFINED in SWITCH %s"; |
89 |
tail = nostr; |
90 |
break; |
91 |
case Proc_case_boolean_mismatch: |
92 |
fmt = "Nonboolean instance for argument %d %s"; |
93 |
tail = armstr; |
94 |
break; |
95 |
case Proc_case_integer_mismatch: |
96 |
fmt = "Noninteger instance for argument %d %s"; |
97 |
tail = armstr; |
98 |
break; |
99 |
case Proc_case_symbol_mismatch: |
100 |
fmt = "Nonsymbol instance for argument %d %s"; |
101 |
tail = armstr; |
102 |
break; |
103 |
case Proc_case_wrong_index: |
104 |
fmt = "Incorrect index expression in AnalyzeSwitchCase"; |
105 |
tail = nostr; |
106 |
break; |
107 |
case Proc_case_wrong_value: |
108 |
fmt = "Wrong value expression in AnalyzeSwitchCase"; |
109 |
tail = nostr; |
110 |
break; |
111 |
case Proc_case_extra_values: |
112 |
fmt = "Multiple instances for a variable in a SWITCH statement"; |
113 |
tail = nostr; |
114 |
break; |
115 |
default: |
116 |
fmt = "Confusion in ProcWriteCaseError, %d %s"; |
117 |
tail = armstr; |
118 |
break; |
119 |
} |
120 |
sprintf(errmsg,fmt,pos,tail); |
121 |
WriteInitErr(fm,errmsg); |
122 |
} |
123 |
|
124 |
void ProcWriteIfError(struct procFrame *fm, CONST char *cname){ |
125 |
char em[85]; |
126 |
char cn[20]; |
127 |
|
128 |
if (strlen(cname) > 19) { |
129 |
strncpy(cn,cname,19); |
130 |
cn[19] = '\0'; |
131 |
} else { |
132 |
strcpy(cn,cname); |
133 |
} |
134 |
switch (fm->ErrNo) { |
135 |
case Proc_if_expr_error_emptyintersection: |
136 |
sprintf(em,"%s expression - empty set intersection",cn); |
137 |
break; |
138 |
case Proc_if_expr_error_emptychoice: |
139 |
sprintf(em,"%s expression - CHOICE on empty set",cn); |
140 |
break; |
141 |
case Proc_if_expr_error_dimensionconflict: |
142 |
sprintf(em,"%s expression - real dimensionality conflict",cn); |
143 |
break; |
144 |
case Proc_if_expr_error_undefinedvalue: |
145 |
sprintf(em,"%s expression - unassigned variable value",cn); |
146 |
break; |
147 |
case Proc_if_expr_error_incorrectname: |
148 |
sprintf(em,"%s expression - name of impossible variable",cn); |
149 |
break; |
150 |
case Proc_if_expr_error_typeconflict: |
151 |
sprintf(em,"%s expression - type conflict of operands",cn); |
152 |
break; |
153 |
case Proc_if_expr_error_nameunfound: |
154 |
sprintf(em,"%s expression - variable not found",cn); |
155 |
break; |
156 |
case Proc_if_expr_error_confused: |
157 |
sprintf(em,"evaluating confusing %s expression",cn); |
158 |
break; |
159 |
case Proc_if_real_expr: |
160 |
sprintf(em,"%s (expression) : real valued expression illegal",cn); |
161 |
break; |
162 |
case Proc_if_integer_expr: |
163 |
sprintf(em,"%s (expression) : integer valued expression illegal",cn); |
164 |
break; |
165 |
case Proc_if_symbol_expr: |
166 |
sprintf(em,"%s (expression) : symbol valued expression illegal",cn); |
167 |
break; |
168 |
case Proc_if_set_expr: |
169 |
sprintf(em,"%s (expression) : set valued expression illegal",cn); |
170 |
break; |
171 |
case Proc_if_not_logical: |
172 |
sprintf(em,"%s (expression) : expression is not boolean-valued",cn); |
173 |
break; |
174 |
case Proc_infinite_loop: |
175 |
sprintf(em,"%s (expression) : looping infinitely?",cn); |
176 |
break; |
177 |
case Proc_stop: |
178 |
sprintf(em,"Found %s statement in METHOD",cn); |
179 |
break; |
180 |
default: |
181 |
sprintf(em,"%s unexpected error message",cn); |
182 |
break; |
183 |
} |
184 |
WriteInitErr(fm,em); |
185 |
} |
186 |
|
187 |
void ProcWriteAssignmentError(struct procFrame *fm){ |
188 |
switch (fm->ErrNo) { |
189 |
case Proc_nonatom_assignment: |
190 |
WriteInitErr(fm,"Assignment to a non-atomic instance"); |
191 |
break; |
192 |
case Proc_noninteger_assignment: |
193 |
WriteInitErr(fm,"Right hand side of assignment is not an integer"); |
194 |
break; |
195 |
case Proc_declarative_constant_assignment: |
196 |
WriteInitErr(fm, "Assignment to a set or constant instance"); |
197 |
break; |
198 |
case Proc_nonconsistent_assignment: |
199 |
WriteInitErr(fm,"Dimensionally inconsistent assignment"); |
200 |
break; |
201 |
case Proc_nonreal_assignment: |
202 |
WriteInitErr(fm, "Right hand side of assignment is not a real expression"); |
203 |
break; |
204 |
case Proc_nonboolean_assignment: |
205 |
WriteInitErr(fm,"Right hand side of assignment is not a boolean"); |
206 |
break; |
207 |
case Proc_nonsymbol_assignment: |
208 |
WriteInitErr(fm,"Right hand side of assignment is not a symbol"); |
209 |
break; |
210 |
case Proc_nonsense_assignment: |
211 |
WriteInitErr(fm,"Assignment to bogus instance type."); |
212 |
break; |
213 |
case Proc_rhs_error: |
214 |
WriteInitErr(fm,"Error evaluating assignment right hand side"); |
215 |
break; |
216 |
case Proc_lhs_error: |
217 |
WriteInitErr(fm,"Unrecognized variable name on left-hand side of ':='."); |
218 |
break; |
219 |
default: |
220 |
WriteInitErr(fm,"Assignment (:=) unexpected error message"); |
221 |
break; |
222 |
} |
223 |
} |
224 |
|
225 |
void ProcWriteForError(struct procFrame *fm){ |
226 |
switch (fm->ErrNo) { |
227 |
case Proc_for_duplicate_index: |
228 |
WriteInitErr(fm,"FOR/DO uses duplicate index variable."); |
229 |
break; |
230 |
case Proc_for_set_err: |
231 |
WriteInitErr(fm,"Error evaluating FOR/DO index set."); |
232 |
break; |
233 |
case Proc_for_not_set: |
234 |
WriteInitErr(fm,"FOR/DO index expression is not a set"); |
235 |
break; |
236 |
default: |
237 |
WriteInitErr(fm,"FOR/DO unexpected error message."); |
238 |
break; |
239 |
} |
240 |
} |
241 |
|
242 |
/* error messages for oldstyle external functions */ |
243 |
void ProcWriteExtError(struct procFrame *fm, CONST char *funcname, |
244 |
enum ProcExtError peerr, int pos |
245 |
){ |
246 |
char *errmsg; |
247 |
assert(funcname != NULL); |
248 |
errmsg = ASC_NEW_ARRAY(char,80+strlen(funcname)); |
249 |
switch (peerr) { |
250 |
case PE_unloaded: |
251 |
WriteInitErr(fm,"External function has not been loaded."); |
252 |
break; |
253 |
case PE_nulleval: |
254 |
WriteInitErr(fm,"Nonexistent Evaluation for old-style external function."); |
255 |
break; |
256 |
case PE_argswrong: |
257 |
WriteInitErr(fm,"Incorrect arguments to old-style external function."); |
258 |
break; |
259 |
case PE_badarg: |
260 |
switch (fm->ErrNo) { |
261 |
case Proc_instance_not_found: |
262 |
sprintf(errmsg, |
263 |
"EXTERNAL %s: NULL (as yet unmade) instance for argument %d.", |
264 |
funcname,pos); |
265 |
WriteStatementErrorMessage(fm->err,fm->stat,errmsg, 0,3); |
266 |
break; |
267 |
case Proc_name_not_found: |
268 |
sprintf(errmsg,"EXTERNAL %s: Undefined name for argument %d.", |
269 |
funcname, pos); |
270 |
WriteStatementErrorMessage(fm->err,fm->stat,errmsg, 0,3); |
271 |
break; |
272 |
case Proc_illegal_name_use: |
273 |
sprintf(errmsg, |
274 |
"EXTERNAL %s: Incorrect name (subscript?) for argument %d.", |
275 |
funcname, pos); |
276 |
WriteStatementErrorMessage(fm->err,fm->stat,errmsg, 0,3); |
277 |
break; |
278 |
case Proc_bad_name: |
279 |
sprintf(errmsg,"EXTERNAL %s: Unknown error message for argument %u.", |
280 |
funcname, pos); |
281 |
WriteStatementErrorMessage(fm->err,fm->stat,errmsg, 0,3); |
282 |
FPRINTF(fm->err," Expect crash soon!\n"); |
283 |
break; |
284 |
case Proc_CallError: |
285 |
sprintf(errmsg,"EXTERNAL %s: Unexpected 'OK' message for argument %u.", |
286 |
funcname, pos); |
287 |
WriteStatementErrorMessage(fm->err,fm->stat,errmsg, 0,3); |
288 |
fm->ErrNo = Proc_CallError; |
289 |
default: |
290 |
break; |
291 |
} |
292 |
break; |
293 |
case PE_evalerr: |
294 |
WriteInitErr(fm,"Error in evaluating external function."); |
295 |
break; |
296 |
} |
297 |
ascfree(errmsg); |
298 |
} |
299 |
|
300 |
void ProcWriteStackCheck(struct procFrame *fm, |
301 |
struct Name *class, struct Name *name |
302 |
){ |
303 |
int unwind = 0; |
304 |
if ( fm->ErrNo == Proc_return) { |
305 |
return; |
306 |
} |
307 |
if(fm->stat != NULL){ |
308 |
error_reporter_start(ASC_PROG_ERROR,SCP(Asc_ModuleBestName(StatementModule(fm->stat))),StatementLineNum(fm->stat),NULL); |
309 |
}else{ |
310 |
error_reporter_start(ASC_PROG_ERROR,NULL,0,NULL); |
311 |
} |
312 |
|
313 |
if (fm->ErrNo == Proc_stack_exceeded_this_frame) { |
314 |
/* stack error message not suppressible */ |
315 |
unwind = 1; |
316 |
FPRINTF(fm->err, |
317 |
"Initialization stack overflow (possible recursion) in call to\n"); |
318 |
} else { |
319 |
if (fm->gen & WP_BTUIFSTOP || fm->ErrNo == Proc_stack_exceeded) { |
320 |
unwind = 1; |
321 |
FPRINTF(fm->err," In call to"); |
322 |
} |
323 |
} |
324 |
if(!unwind){ |
325 |
/* FIXME use _end_clean instead, if available. */ |
326 |
error_reporter_end_flush(); |
327 |
return; |
328 |
} |
329 |
FPRINTF(fm->err," METHOD "); |
330 |
if (class != NULL) { |
331 |
WriteName(fm->err,class); |
332 |
FPRINTF(fm->err,"::"); |
333 |
} |
334 |
WriteName(fm->err,name); |
335 |
FPRINTF(fm->err," (depth %d) in instance %s\n", fm->depth, fm->cname); |
336 |
|
337 |
error_reporter_end_flush(); |
338 |
} |
339 |
|
340 |
void ProcWriteRunError(struct procFrame *fm){ |
341 |
char *errmsg; |
342 |
errmsg = "Unexpected RUN statement error"; |
343 |
switch (fm->ErrNo) { |
344 |
case Proc_bad_name: |
345 |
errmsg = "Bad method name in RUN statement"; |
346 |
break; |
347 |
case Proc_proc_not_found: |
348 |
errmsg = "Method not found in RUN statement"; |
349 |
break; |
350 |
case Proc_illegal_name_use: |
351 |
errmsg = "Illegal name use in RUN statement"; |
352 |
break; |
353 |
case Proc_type_not_found: |
354 |
errmsg = "Type name not found in RUN statement"; |
355 |
break; |
356 |
case Proc_illegal_type_use: |
357 |
errmsg = "Unconformable types in RUN statement"; |
358 |
break; |
359 |
case Proc_stack_exceeded_this_frame: |
360 |
case Proc_stack_exceeded: |
361 |
errmsg = "METHOD call too deeply nested in statement"; |
362 |
break; |
363 |
default: |
364 |
errmsg = "Type name not found in RUN statement"; |
365 |
break; |
366 |
} |
367 |
WriteInitErr(fm,errmsg); |
368 |
} |
369 |
|
370 |
void ProcWriteFixError(struct procFrame *fm, CONST struct Name *var){ |
371 |
char errmsg[255]; |
372 |
char *name; |
373 |
name = WriteNameString(var); |
374 |
strcpy(errmsg,"Unexpected FIX statement error"); |
375 |
switch(fm->ErrNo){ |
376 |
case Proc_type_not_found: |
377 |
strcpy(errmsg, "Bad setup for FIX statement (Is 'solver_var' present in the library?)"); |
378 |
break; |
379 |
case Proc_illegal_type_use: |
380 |
strcpy(errmsg, "Incorrect type for variable being fixed (must be a refined solver_var)"); |
381 |
break; |
382 |
case Proc_bad_name: |
383 |
strcpy(errmsg, "Unknown variable in FIX statement"); |
384 |
break; |
385 |
default: |
386 |
strcpy(errmsg, "Unexpected error in FIX statement"); |
387 |
break; |
388 |
} |
389 |
strcat(errmsg,", for variable '"); |
390 |
strncat(errmsg,name,40); |
391 |
strcat(errmsg,"'"); |
392 |
ascfree(name); |
393 |
WriteInitErr(fm,errmsg); |
394 |
} |
395 |
|
396 |
void ProcWriteSlvReqError(struct procFrame *fm){ |
397 |
const char *msg; |
398 |
switch(fm->ErrNo){ |
399 |
case Proc_slvreq_unhooked: msg = "Statement not available with this user interface"; break; |
400 |
case Proc_slvreq_unknown_solver: msg = "Bad solver name (or solver had not yet been loaded)"; break; |
401 |
case Proc_slvreq_no_solver_selected: msg = "No solver has been selected yet"; break; |
402 |
case Proc_slvreq_invalid_option_name: msg = "Invalid option name (check the solver documentation?)"; break; |
403 |
case Proc_slvreq_option_invalid_type: msg= "Option value is not of expected type (check solver documentation)"; break; |
404 |
case Proc_slvreq_no_system: msg = "No system (probably a bug in your user interface)"; break; |
405 |
case Proc_slvreq_presolve_fail: msg = "Pre-solve failed"; break; |
406 |
case Proc_slvreq_solve_fail: msg = "Solve failed"; break; |
407 |
case Proc_slvreq_error: msg = "General solver-request error"; break; |
408 |
case Proc_slvreq_not_implemented: msg = "Not implemented"; break; |
409 |
default: msg = "Unknown error"; |
410 |
} |
411 |
WriteInitErr(fm,msg); |
412 |
} |
413 |
|
414 |
|
415 |
|