1 |
/* ASCEND modelling environment |
2 |
Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly |
3 |
Copyright (C) 2006 Carnegie Mellon University |
4 |
|
5 |
This program is free software; you can redistribute it and/or modify |
6 |
it under the terms of the GNU General Public License as published by |
7 |
the Free Software Foundation; either version 2, or (at your option) |
8 |
any later version. |
9 |
|
10 |
This program is distributed in the hope that it will be useful, |
11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
GNU General Public License for more details. |
14 |
|
15 |
You should have received a copy of the GNU General Public License |
16 |
along with this program; if not, write to the Free Software |
17 |
Foundation, Inc., 59 Temple Place - Suite 330, |
18 |
Boston, MA 02111-1307, USA. |
19 |
*//** @file |
20 |
Temporary Statement Output routines |
21 |
*//* |
22 |
by Tom Epperly |
23 |
Last in CVS: $Revision: 1.41 $ $Date: 1998/04/21 23:49:55 $ $Author: ballan $ |
24 |
*/ |
25 |
|
26 |
#define INDENTATION 4 |
27 |
|
28 |
#include <ascend/utilities/ascConfig.h> |
29 |
#include <ascend/utilities/ascMalloc.h> |
30 |
#include <ascend/utilities/error.h> |
31 |
#include <ascend/general/list.h> |
32 |
#include <ascend/general/dstring.h> |
33 |
|
34 |
#include "functype.h" |
35 |
#include "expr_types.h" |
36 |
#include "stattypes.h" |
37 |
#include "statement.h" |
38 |
#include "statio.h" |
39 |
#include "exprio.h" |
40 |
#include "nameio.h" |
41 |
#include "when.h" |
42 |
#include "select.h" |
43 |
#include "switch.h" |
44 |
#include "vlistio.h" |
45 |
#include "slist.h" |
46 |
#include "setio.h" |
47 |
#include "child.h" |
48 |
#include "type_desc.h" |
49 |
#include "type_descio.h" |
50 |
#include "module.h" |
51 |
#include "forvars.h" |
52 |
#include "find.h" |
53 |
#include "symtab.h" |
54 |
#include "braced.h" |
55 |
#include "instance_enum.h" |
56 |
#include "cmpfunc.h" |
57 |
|
58 |
static int g_show_statement_detail = 1; |
59 |
/* global to control display detail. It's default value 1 means |
60 |
* print the expression with relations. On occasion this is burdensome |
61 |
* and the expression can be suppressed by setting this variable to |
62 |
* any value other than 1. |
63 |
* It should generally be restored to the default state after temporary |
64 |
* modification. |
65 |
*/ |
66 |
|
67 |
static int *g_statio_suppressions = NULL; |
68 |
/* SIS returns TRUE if we do care about suppressions */ |
69 |
#define GSS (g_statio_suppressions!=NULL) |
70 |
/* SUP(s) returns TRUE if statement s is to be suppressed */ |
71 |
#define SUP(s) g_statio_suppressions[StatementType(s)] |
72 |
|
73 |
static const char *g_statio_label[5] = { |
74 |
"Asc-WSEM-bug:", |
75 |
"Asc-Style: ", |
76 |
"Asc-Warning: ", |
77 |
"Asc-Error: ", |
78 |
"Asc-Fatal: " |
79 |
}; |
80 |
|
81 |
/* |
82 |
* g_statio_stattypenames maps to the enum stat_t to strings from the |
83 |
* symbol table. |
84 |
*/ |
85 |
/* |
86 |
* ANSI ASSUMPTION: the contents of g_statio_stattypenames will be |
87 |
* NULL on startup. |
88 |
*/ |
89 |
static |
90 |
symchar *g_statio_stattypenames[WILLBE+1]; |
91 |
/* typenames for the subclasses of FLOW statement */ |
92 |
static |
93 |
symchar *g_statio_flowtypenames[fc_stop+1]; |
94 |
|
95 |
static |
96 |
void Indent(FILE *f, register int i) |
97 |
{ |
98 |
register int tabs; |
99 |
if (i<=0) return; |
100 |
tabs = i / 8; |
101 |
while (tabs--) PUTC('\t',f); |
102 |
i %= 8; |
103 |
while (i--) PUTC(' ',f); |
104 |
} |
105 |
|
106 |
/* return a string of the kind */ |
107 |
static |
108 |
char *ForKindString(enum ForKind fk) |
109 |
{ |
110 |
switch (fk) { |
111 |
case fk_create: |
112 |
return "CREATE"; |
113 |
case fk_do: |
114 |
return "DO"; |
115 |
case fk_check: |
116 |
return "CHECK"; |
117 |
case fk_expect: |
118 |
return "EXPECT"; |
119 |
default: |
120 |
return "ERRFOR"; |
121 |
} |
122 |
} |
123 |
|
124 |
static |
125 |
void WriteOrder(FILE *f, enum ForOrder o) |
126 |
{ |
127 |
switch(o){ |
128 |
case f_increasing: FPRINTF(f," INCREASING"); break; |
129 |
case f_decreasing: FPRINTF(f," DECREASING"); break; |
130 |
default: break; |
131 |
} |
132 |
} |
133 |
|
134 |
static |
135 |
void WriteWhenNode(FILE *f,struct WhenList *w, int i) |
136 |
{ |
137 |
register struct Set *set; |
138 |
Indent(f,i); |
139 |
set = WhenSetList(w); |
140 |
if (set!=NULL){ |
141 |
FPRINTF(f,"CASE "); |
142 |
WriteSet(f,set); |
143 |
} |
144 |
else FPRINTF(f,"OTHERWISE"); |
145 |
FPRINTF(f," :\n"); |
146 |
WriteStatementList(f,WhenStatementList(w),i+INDENTATION); |
147 |
} |
148 |
|
149 |
static |
150 |
void WriteWhenList(FILE *f, struct WhenList *w, int i) |
151 |
{ |
152 |
while (w!=NULL) { |
153 |
WriteWhenNode(f,w,i); |
154 |
w = NextWhenCase(w); |
155 |
} |
156 |
} |
157 |
|
158 |
static |
159 |
void WriteSelectNode(FILE *f, struct SelectList *sel, int i) |
160 |
{ |
161 |
register struct Set *set; |
162 |
Indent(f,i); |
163 |
set = SelectSetList(sel); |
164 |
if (set!=NULL){ |
165 |
FPRINTF(f,"CASE "); |
166 |
WriteSet(f,set); |
167 |
} else { |
168 |
FPRINTF(f,"OTHERWISE"); |
169 |
} |
170 |
FPRINTF(f," :\n"); |
171 |
WriteStatementList(f,SelectStatementList(sel),i+INDENTATION); |
172 |
} |
173 |
|
174 |
static |
175 |
void WriteSelectList(FILE *f, struct SelectList *sel, int i) |
176 |
{ |
177 |
while (sel!=NULL) { |
178 |
WriteSelectNode(f,sel,i); |
179 |
sel = NextSelectCase(sel); |
180 |
} |
181 |
} |
182 |
|
183 |
static |
184 |
void WriteSwitchNode(FILE *f, struct SwitchList *sw, int i) |
185 |
{ |
186 |
register struct Set *set; |
187 |
Indent(f,i); |
188 |
set = SwitchSetList(sw); |
189 |
if (set!=NULL){ |
190 |
FPRINTF(f,"CASE "); |
191 |
WriteSet(f,set); |
192 |
} else { |
193 |
FPRINTF(f,"OTHERWISE"); |
194 |
} |
195 |
FPRINTF(f," :\n"); |
196 |
WriteStatementList(f,SwitchStatementList(sw),i+INDENTATION); |
197 |
} |
198 |
|
199 |
static |
200 |
void WriteSwitchList(FILE *f, struct SwitchList *sw, int i) |
201 |
{ |
202 |
while (sw!=NULL) { |
203 |
WriteSwitchNode(f,sw,i); |
204 |
sw = NextSwitchCase(sw); |
205 |
} |
206 |
} |
207 |
|
208 |
struct gl_list_t *GetTypeNamesFromStatList(CONST struct StatementList *sl) |
209 |
{ |
210 |
register unsigned long len,c; |
211 |
register CONST struct gl_list_t *l=NULL; |
212 |
struct gl_list_t *found=NULL; |
213 |
struct Statement *s=NULL; |
214 |
symchar *td; |
215 |
|
216 |
found=gl_create(20L); |
217 |
if (!sl) return found; |
218 |
l = GetList(sl); |
219 |
len = gl_length(l); |
220 |
for(c=1;c<=len;) { |
221 |
s=(struct Statement *)gl_fetch(l,c++); |
222 |
td=NULL; |
223 |
switch(StatementType(s)) { |
224 |
case ISA: |
225 |
case WILLBE: |
226 |
if (GetStatSetType(s)==NULL) |
227 |
td = GetStatType(s); |
228 |
else |
229 |
td = GetStatSetType(s); |
230 |
break; |
231 |
case IRT: |
232 |
td= GetStatType(s); |
233 |
break; |
234 |
case ALIASES: |
235 |
case ARR: /* possible bug. ben */ |
236 |
case ATS: |
237 |
case WBTS: |
238 |
case WNBTS: |
239 |
case REL: |
240 |
case LOGREL: |
241 |
case AA: |
242 |
case FOR: /* that this isn't handled further may be a bug */ |
243 |
case ASGN: |
244 |
case CASGN: |
245 |
case RUN: |
246 |
case IF: |
247 |
case WHEN: |
248 |
case FNAME: |
249 |
case SELECT: |
250 |
case SWITCH: |
251 |
case COND: |
252 |
case CALL: |
253 |
case FLOW: |
254 |
case WHILE: |
255 |
case EXT: |
256 |
case REF: /* that this isn't handled may be a bug */ |
257 |
break; |
258 |
default: |
259 |
break; |
260 |
} |
261 |
if (td) gl_insert_sorted(found,(VOIDPTR)td,(CmpFunc)CmpSymchar); |
262 |
} |
263 |
return found; |
264 |
} |
265 |
|
266 |
unsigned long StatementListLength(CONST struct StatementList *sl) |
267 |
{ |
268 |
if (sl==NULL) return 0L; |
269 |
if (GetList(sl) == NULL) return 0L; |
270 |
return gl_length(GetList(sl)); |
271 |
} |
272 |
|
273 |
void WriteStatement(FILE *f, CONST struct Statement *s, int i) |
274 |
{ |
275 |
struct Name *n; |
276 |
assert(s!=NULL); |
277 |
if (GSS && SUP(s)) return; |
278 |
Indent(f,i); |
279 |
if (StatWrong(s)) { |
280 |
FPRINTF(f,"(* ERROR *) "); |
281 |
} |
282 |
switch(StatementType(s)) { |
283 |
case ALIASES: |
284 |
WriteVariableList(f,GetStatVarList(s)); |
285 |
FPRINTF(f," ALIASES "); |
286 |
WriteName(f,AliasStatName(s)); |
287 |
FPRINTF(f,";\n"); |
288 |
break; |
289 |
case ARR: |
290 |
WriteVariableList(f,ArrayStatAvlNames(s)); |
291 |
FPRINTF(f," ALIASES ("); |
292 |
WriteVariableList(f,GetStatVarList(s)); |
293 |
|
294 |
FPRINTF(f,")\n"); |
295 |
Indent(f,i+2); |
296 |
FPRINTF(f,"WHERE "); |
297 |
WriteVariableList(f,ArrayStatSetName(s)); |
298 |
FPRINTF(f," IS_A set OF %s", |
299 |
SCP(ArrayStatIntSet(s)? |
300 |
GetBaseTypeName(integer_constant_type): |
301 |
GetBaseTypeName(symbol_constant_type))); |
302 |
if (ArrayStatSetValues(s) != NULL) { |
303 |
FPRINTF(f," WITH_VALUE ("); |
304 |
WriteSet(f,ArrayStatSetValues(s)); |
305 |
FPRINTF(f,");\n"); |
306 |
} else { |
307 |
FPRINTF(f,";\n"); |
308 |
} |
309 |
break; |
310 |
case ISA: |
311 |
WriteVariableList(f,GetStatVarList(s)); |
312 |
if (GetStatSetType(s)==NULL) { |
313 |
FPRINTF(f," IS_A %s",SCP(GetStatType(s))); |
314 |
if (GetStatTypeArgs(s) != NULL) { |
315 |
FPRINTF(f,"("); |
316 |
WriteSet(f,GetStatTypeArgs(s)); |
317 |
FPRINTF(f,");\n"); |
318 |
} else { |
319 |
FPRINTF(f,";\n"); |
320 |
} |
321 |
} else { |
322 |
/* no parameters to sets */ |
323 |
FPRINTF(f," IS_A %s OF %s;\n", |
324 |
SCP(GetStatType(s)),SCP(GetStatSetType(s))); |
325 |
} |
326 |
break; |
327 |
case WILLBE: |
328 |
WriteVariableList(f,GetStatVarList(s)); |
329 |
if (GetStatSetType(s)==NULL) { |
330 |
FPRINTF(f," WILL_BE %s",SCP(GetStatType(s))); |
331 |
if (GetStatTypeArgs(s) != NULL) { |
332 |
FPRINTF(f,"("); |
333 |
WriteSet(f,GetStatTypeArgs(s)); |
334 |
FPRINTF(f,")"); |
335 |
} |
336 |
} else { |
337 |
FPRINTF(f," WILL_BE %s OF %s", |
338 |
SCP(GetStatType(s)),SCP(GetStatSetType(s))); |
339 |
} |
340 |
if (GetStatCheckValue(s)!=NULL ) { |
341 |
FPRINTF(f," WITH_VALUE "); |
342 |
WriteExpr(f,GetStatCheckValue(s)); |
343 |
} |
344 |
FPRINTF(f,";\n"); |
345 |
break; |
346 |
case IRT: |
347 |
WriteVariableList(f,GetStatVarList(s)); |
348 |
FPRINTF(f," IS_REFINED_TO %s",SCP(GetStatType(s))); |
349 |
if (GetStatTypeArgs(s) != NULL) { |
350 |
FPRINTF(f,"("); |
351 |
WriteSet(f,GetStatTypeArgs(s)); |
352 |
FPRINTF(f,");\n"); |
353 |
} else { |
354 |
FPRINTF(f,";\n"); |
355 |
} |
356 |
break; |
357 |
case ATS: |
358 |
WriteVariableList(f,GetStatVarList(s)); |
359 |
FPRINTF(f," ARE_THE_SAME;\n"); |
360 |
break; |
361 |
case WBTS: |
362 |
WriteVariableList(f,GetStatVarList(s)); |
363 |
FPRINTF(f," WILL_BE_THE_SAME;\n"); |
364 |
break; |
365 |
case WNBTS: |
366 |
WriteVariableList(f,GetStatVarList(s)); |
367 |
FPRINTF(f," WILL_NOT_BE_THE_SAME;\n"); |
368 |
break; |
369 |
case AA: |
370 |
WriteVariableList(f,GetStatVarList(s)); |
371 |
FPRINTF(f," ARE_ALIKE;\n"); |
372 |
break; |
373 |
case FOR: |
374 |
{ |
375 |
FPRINTF(f,"FOR %s IN ",SCP(ForStatIndex(s))); |
376 |
WriteExpr(f,ForStatExpr(s)); |
377 |
WriteOrder(f,ForLoopOrder(s)); |
378 |
#ifndef NDEBUG |
379 |
if (g_show_statement_detail==1) { |
380 |
FPRINTF(f," %s (*<contains%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>*)\n", |
381 |
ForKindString(ForLoopKind(s)), |
382 |
(ForContainsRelations(s)) ? " rel" : "", |
383 |
(ForContainsLogRelations(s)) ? " lrel" : "", |
384 |
(ForContainsDefaults(s)) ? " def" : "", |
385 |
(ForContainsCAssigns(s)) ? " con" : "", |
386 |
(ForContainsWhen(s)) ? " when" : "", |
387 |
(ForContainsIsa(s)) ? " isa" : "", |
388 |
(ForContainsSelect(s)) ? " select" : "", |
389 |
(ForContainsConditional(s)) ? " conditional" : "", |
390 |
(ForContainsWillbe(s)) ? " wb" : "", |
391 |
(ForContainsAlike(s)) ? " aa" : "", |
392 |
(ForContainsAlias(s)) ? " ali" : "", |
393 |
(ForContainsArray(s)) ? " arr" : "", |
394 |
(ForContainsWbts(s)) ? " wbts" : "", |
395 |
(ForContainsAts(s)) ? " ats" : "", |
396 |
(ForContainsIrt(s)) ? " irt" : "" |
397 |
); |
398 |
} else { |
399 |
FPRINTF(f," %s\n", ForKindString(ForLoopKind(s))); |
400 |
} |
401 |
#else |
402 |
FPRINTF(f," %s\n", ForKindString(ForLoopKind(s))); |
403 |
#endif |
404 |
WriteStatementList(f,ForStatStmts(s),i+INDENTATION); |
405 |
Indent(f,i); |
406 |
FPRINTF(f,"END;\n"); |
407 |
break; |
408 |
} |
409 |
case REL: |
410 |
if (RelationStatName(s)!=NULL) { |
411 |
WriteName(f,RelationStatName(s)); |
412 |
FPRINTF(f," : "); |
413 |
} |
414 |
if (g_show_statement_detail==1) { |
415 |
WriteExpr(f,RelationStatExpr(s)); |
416 |
FPRINTF(f,";\n"); |
417 |
} else { |
418 |
FPRINTF(f,"(details suppressed);\n"); |
419 |
} |
420 |
break; |
421 |
case LOGREL: |
422 |
if (LogicalRelStatName(s)!=NULL) { |
423 |
WriteName(f,LogicalRelStatName(s)); |
424 |
FPRINTF(f," : "); |
425 |
} |
426 |
if (g_show_statement_detail==1) { |
427 |
WriteExpr(f,LogicalRelStatExpr(s)); |
428 |
FPRINTF(f,";\n"); |
429 |
} else { |
430 |
FPRINTF(f,"(details suppressed);\n"); |
431 |
} |
432 |
break; |
433 |
case EXT: |
434 |
switch (ExternalStatMode(s)) { |
435 |
case ek_method: /* Procedural */ |
436 |
FPRINTF(f," EXTERNAL %s(",ExternalStatFuncName(s)); |
437 |
WriteVariableList(f,ExternalStatVlistMethod(s)); |
438 |
FPRINTF(f,")\n"); |
439 |
break; |
440 |
case ek_glass: /* Glassbox Declarative */ |
441 |
if (ExternalStatNameRelation(s)!=NULL) { |
442 |
WriteName(f,ExternalStatNameRelation(s)); |
443 |
FPRINTF(f," : "); |
444 |
} |
445 |
FPRINTF(f," %s(",ExternalStatFuncName(s)); |
446 |
WriteVariableList(f,ExternalStatVlistRelation(s)); |
447 |
FPRINTF(f," : INPUT/OUTPUT"); |
448 |
if (ExternalStatDataGlassBox(s)!=NULL) { |
449 |
FPRINTF(f,", "); |
450 |
WriteName(f,ExternalStatDataGlassBox(s)); |
451 |
FPRINTF(f," : DATA"); |
452 |
} |
453 |
FPRINTF(f,")\n"); |
454 |
break; |
455 |
case ek_black: /* Blackbox Declarative */ |
456 |
if (ExternalStatNameRelation(s)!=NULL) { |
457 |
WriteName(f,ExternalStatNameRelation(s)); |
458 |
FPRINTF(f," : "); |
459 |
} |
460 |
FPRINTF(f," %s(",ExternalStatFuncName(s)); |
461 |
WriteVariableList(f,ExternalStatVlistRelation(s)); |
462 |
FPRINTF(f," : INPUT/OUTPUT"); |
463 |
if (ExternalStatDataBlackBox(s)!=NULL) { |
464 |
FPRINTF(f,", "); |
465 |
WriteName(f,ExternalStatDataBlackBox(s)); |
466 |
FPRINTF(f," : DATA"); |
467 |
} |
468 |
FPRINTF(f,")\n"); |
469 |
break; |
470 |
} |
471 |
break; |
472 |
case REF: |
473 |
WriteVariableList(f,ReferenceStatVlist(s)); |
474 |
switch (ReferenceStatMode(s)) { |
475 |
case 0: |
476 |
FPRINTF(f," _IS_ "); |
477 |
break; |
478 |
case 1: |
479 |
FPRINTF(f," _REFERS_ "); |
480 |
break; |
481 |
} |
482 |
FPRINTF(f,"%s\n;",SCP(ReferenceStatName(s))); |
483 |
break; |
484 |
case CASGN: |
485 |
WriteName(f,AssignStatVar(s)); |
486 |
FPRINTF(f," :== "); |
487 |
WriteExpr(f,AssignStatRHS(s)); |
488 |
FPRINTF(f,";\n"); |
489 |
break; |
490 |
case ASGN: |
491 |
WriteName(f,DefaultStatVar(s)); |
492 |
FPRINTF(f," := "); |
493 |
WriteExpr(f,DefaultStatRHS(s)); |
494 |
FPRINTF(f,";\n"); |
495 |
break; |
496 |
case RUN: |
497 |
FPRINTF(f,"RUN "); |
498 |
if ( (n=RunStatAccess(s))!=NULL ) { /* class/model/atom access */ |
499 |
WriteName(f,n); |
500 |
FPRINTF(f,"::"); |
501 |
WriteName(f,RunStatName(s)); |
502 |
FPRINTF(f,";\n"); |
503 |
} else { |
504 |
WriteName(f,RunStatName(s)); |
505 |
FPRINTF(f,";\n"); |
506 |
} |
507 |
break; |
508 |
case FIX: |
509 |
FPRINTF(f,"FIX "); |
510 |
WriteVariableList(f,FixFreeStatVars(s)); |
511 |
FPRINTF(f,";\n"); |
512 |
break; |
513 |
case FREE: |
514 |
FPRINTF(f,"FREE "); |
515 |
WriteVariableList(f,FixFreeStatVars(s)); |
516 |
FPRINTF(f,";\n"); |
517 |
break; |
518 |
case SOLVER: |
519 |
FPRINTF(f,"SOLVER %s;\n",s->v.solver.name); |
520 |
break; |
521 |
case OPTION: |
522 |
FPRINTF(f,"OPTION %s ",s->v.option.name); |
523 |
WriteExpr(f,s->v.option.rhs); |
524 |
FPRINTF(f,";\n"); |
525 |
break; |
526 |
case SOLVE: |
527 |
FPRINTF(f,"SOLVE;\n"); |
528 |
break; |
529 |
case CALL: |
530 |
FPRINTF(f,"CALL %s(",SCP(CallStatId(s))); |
531 |
WriteSet(f,CallStatArgs(s)); |
532 |
FPRINTF(f,");\n"); |
533 |
break; |
534 |
case ASSERT: |
535 |
FPRINTF(f,"ASSERT "); |
536 |
WriteExpr(f,AssertStatExpr(s)); |
537 |
FPRINTF(f,"\n"); |
538 |
break; |
539 |
case WHILE: |
540 |
FPRINTF(f,"WHILE ("); |
541 |
WriteExpr(f,WhileStatExpr(s)); |
542 |
FPRINTF(f,") DO\n"); |
543 |
WriteStatementList(f,WhileStatBlock(s),i+INDENTATION); |
544 |
Indent(f,i); |
545 |
FPRINTF(f,"END WHILE;\n"); |
546 |
break; |
547 |
case FLOW: |
548 |
FPRINTF(f,"%s",SCP(StatementTypeString(s))); |
549 |
if (FlowStatMessage(s) != NULL) { |
550 |
FPRINTF(f," {%s}",BCS(FlowStatMessage(s))); |
551 |
} |
552 |
FPRINTF(f,";\n"); |
553 |
break; |
554 |
case IF: |
555 |
FPRINTF(f,"IF ("); |
556 |
WriteExpr(f,IfStatExpr(s)); |
557 |
FPRINTF(f,") THEN\n"); |
558 |
WriteStatementList(f,IfStatThen(s),i+INDENTATION); |
559 |
if (IfStatElse(s)!=NULL) { |
560 |
Indent(f,i); |
561 |
FPRINTF(f,"ELSE\n"); |
562 |
WriteStatementList(f,IfStatElse(s),i+INDENTATION); |
563 |
} |
564 |
Indent(f,i); |
565 |
FPRINTF(f,"END IF;\n"); |
566 |
break; |
567 |
case WHEN: |
568 |
if (WhenStatName(s)!=NULL) { |
569 |
WriteName(f,WhenStatName(s)); |
570 |
FPRINTF(f," : "); |
571 |
} |
572 |
FPRINTF(f,"WHEN "); |
573 |
WriteVariableList(f,WhenStatVL(s)); |
574 |
FPRINTF(f,"\n"); |
575 |
WriteWhenList(f,WhenStatCases(s),i); |
576 |
Indent(f,i); |
577 |
FPRINTF(f,"END;\n"); |
578 |
break; |
579 |
case FNAME: |
580 |
FPRINTF(f,"USE "); |
581 |
WriteName(f,FnameStat(s)); |
582 |
FPRINTF(f,";\n"); |
583 |
break; |
584 |
case SELECT: |
585 |
FPRINTF(f,"SELECT "); |
586 |
WriteVariableList(f,SelectStatVL(s)); |
587 |
FPRINTF(f,"\n"); |
588 |
WriteSelectList(f,SelectStatCases(s),i); |
589 |
Indent(f,i); |
590 |
FPRINTF(f,"END;\n"); |
591 |
break; |
592 |
case SWITCH: |
593 |
FPRINTF(f,"SWITCH "); |
594 |
WriteVariableList(f,SwitchStatVL(s)); |
595 |
FPRINTF(f,"\n"); |
596 |
WriteSwitchList(f,SwitchStatCases(s),i); |
597 |
Indent(f,i); |
598 |
FPRINTF(f,"END;\n"); |
599 |
break; |
600 |
case COND: |
601 |
FPRINTF(f,"CONDITIONAL \n "); |
602 |
WriteStatementList(f,CondStatList(s),i+INDENTATION); |
603 |
Indent(f,i); |
604 |
FPRINTF(f,"END;\n"); |
605 |
break; |
606 |
default: |
607 |
FPRINTF(f,"<Unimplemented statement type in WriteStatement>"); |
608 |
break; |
609 |
} |
610 |
} |
611 |
|
612 |
/* |
613 |
* Modified to avoid printing twice the statements inside a SELECT |
614 |
* VRR. But the "jumping" of the statements is only for the outermost |
615 |
* SELECT, the nested SELECTs do not require it. |
616 |
*/ |
617 |
void WriteStatementList(FILE *f, CONST struct StatementList *sl, int i) |
618 |
{ |
619 |
register unsigned long len,c; |
620 |
register CONST struct gl_list_t *l; |
621 |
struct Statement *stat; |
622 |
l = GetList(sl); |
623 |
len = gl_length(l); |
624 |
for(c=1; c<=len; c++) { |
625 |
stat = (struct Statement *)gl_fetch(l,c); |
626 |
WriteStatement(f,stat,i); |
627 |
if (StatementType(stat)== SELECT && !StatInSELECT(stat)) { |
628 |
c = c + SelectStatNumberStats(stat); |
629 |
} |
630 |
} |
631 |
} |
632 |
|
633 |
/* |
634 |
* Modified to avoid printing twice the statements inside a SELECT |
635 |
* VRR. |
636 |
*/ |
637 |
void WriteDiffStatementList(FILE *f, CONST struct StatementList *sl1, |
638 |
CONST struct StatementList *sl2, int i) |
639 |
{ |
640 |
register unsigned long len1,len2,c; |
641 |
register CONST struct gl_list_t *l; |
642 |
struct Statement *stat; |
643 |
l = GetList(sl1); |
644 |
len1=gl_length(l); |
645 |
l = GetList(sl2); |
646 |
len2 = gl_length(l); |
647 |
for(c=(1+len1);c<=len2;c++) { |
648 |
stat = (struct Statement *)gl_fetch(l,c); |
649 |
WriteStatement(f,stat,i); |
650 |
if (StatementType(stat)== SELECT) { |
651 |
c = c + SelectStatNumberStats(stat); |
652 |
} |
653 |
} |
654 |
} |
655 |
|
656 |
void WriteStatementSuppressed(FILE *f, CONST struct Statement *stat) |
657 |
{ |
658 |
if (stat!=NULL) { |
659 |
FPRINTF(f," Incorrect statement (final warning) at %s:%lu\n", |
660 |
Asc_ModuleBestName(StatementModule(stat)), |
661 |
StatementLineNum(stat)); |
662 |
FPRINTF(f, |
663 |
" All future occurences of this statement will be ignored.\n\n"); |
664 |
} else { |
665 |
FPRINTF(f," Suppressing NULL STATEMENT!!! How odd! Expect crash.\n"); |
666 |
} |
667 |
} |
668 |
|
669 |
void WriteStatementError(const error_severity_t sev |
670 |
, const struct Statement *stat |
671 |
, const int outputstatement |
672 |
, const char *fmt |
673 |
, ... |
674 |
){ |
675 |
va_list args; |
676 |
|
677 |
error_reporter_start(sev,Asc_ModuleFileName(stat->mod),stat->linenum,SCP(StatementTypeString(stat))); |
678 |
va_start(args,fmt); |
679 |
vfprintf_error_reporter(ASCERR,fmt,args); |
680 |
va_end(args); |
681 |
if(outputstatement){ |
682 |
FPRINTF(ASCERR,"\n"); |
683 |
WriteStatement(ASCERR,stat,4); |
684 |
} |
685 |
error_reporter_end_flush(); |
686 |
} |
687 |
|
688 |
void WriteStatementErrorMessage(FILE *f, CONST struct Statement *stat, |
689 |
CONST char *message, int noisy,int level) |
690 |
{ |
691 |
/* old behavior */ |
692 |
const char *filename=NULL; |
693 |
int line=0; |
694 |
error_severity_t sev; |
695 |
|
696 |
if(stat!=NULL){ |
697 |
filename=Asc_ModuleBestName(StatementModule(stat)); |
698 |
line=StatementLineNum(stat); |
699 |
} |
700 |
|
701 |
if(level < 0){ |
702 |
level = 1; |
703 |
} |
704 |
|
705 |
switch(level){ |
706 |
case 1: sev = ASC_USER_NOTE; break; |
707 |
case 2: sev = ASC_USER_WARNING; break; |
708 |
case 3: sev = ASC_USER_ERROR; break; |
709 |
default: |
710 |
sev = ASC_PROG_ERR; |
711 |
} |
712 |
|
713 |
error_reporter_start(sev,filename,line,NULL); |
714 |
FPRINTF(ASCERR,"%s\n",message); |
715 |
|
716 |
if(stat!=NULL){ |
717 |
/* write some more detail */ |
718 |
g_show_statement_detail = ((noisy!=0) ? 1 : 0); |
719 |
WriteStatement(ASCERR,stat,2); |
720 |
g_show_statement_detail = 1; |
721 |
|
722 |
if (GetEvaluationForTable()!=NULL) { |
723 |
WriteForTable(ASCERR,GetEvaluationForTable()); |
724 |
} |
725 |
}else{ |
726 |
FPRINTF(f,"NULL STATEMENT!"); |
727 |
} |
728 |
|
729 |
error_reporter_end_flush(); |
730 |
} |
731 |
|
732 |
CONST char *StatioLabel(int level) |
733 |
{ |
734 |
if (level >4 || level <1) { |
735 |
level = 0; |
736 |
} |
737 |
return g_statio_label[level]; |
738 |
} |
739 |
|
740 |
int *GetStatioSuppressions(void) { |
741 |
/* WILLBE is the last element of the stattype enum. */ |
742 |
int *table; |
743 |
table = ASC_NEW_ARRAY_CLEAR(int,WILLBE+1); |
744 |
assert(table!=NULL); |
745 |
return table; |
746 |
} |
747 |
|
748 |
void DestroySuppressions(int *table) |
749 |
{ |
750 |
assert(table!=NULL); |
751 |
ascfree(table); |
752 |
} |
753 |
|
754 |
|
755 |
void WriteStatementErrorSparse(FILE *f, |
756 |
CONST struct Statement *stat, |
757 |
CONST char *message, int *ignore) |
758 |
{ |
759 |
assert(ignore!=NULL); |
760 |
g_statio_suppressions = ignore; |
761 |
if (!SUP(stat)) { |
762 |
if (message) FPRINTF(f,message); |
763 |
if (stat ){ |
764 |
FPRINTF(f," %s:%lu\n", |
765 |
Asc_ModuleBestName(StatementModule(stat)), |
766 |
StatementLineNum(stat)); |
767 |
WriteStatement(f,stat,0); |
768 |
if (GetEvaluationForTable()!=NULL) { |
769 |
WriteForTable(f,GetEvaluationForTable()); |
770 |
FPRINTF(f,"\n"); |
771 |
} |
772 |
} else { |
773 |
FPRINTF(f,"NULL STATEMENT!!!\n"); |
774 |
} |
775 |
} |
776 |
g_statio_suppressions = NULL; |
777 |
} |
778 |
|
779 |
symchar *StatementTypeString(CONST struct Statement *s) |
780 |
{ |
781 |
static symchar *error_statement_sym; |
782 |
assert(s!=NULL); |
783 |
if (g_statio_stattypenames[0]==NULL) { |
784 |
error_statement_sym = AddSymbol("Unknown-statement-type"); |
785 |
g_statio_stattypenames[ALIASES] = AddSymbol("ALIASES"); |
786 |
g_statio_stattypenames[ISA] = AddSymbol("IS_A"); |
787 |
g_statio_stattypenames[ARR] = AddSymbol("ALIASES/IS_A"); |
788 |
g_statio_stattypenames[IRT] = AddSymbol("IS_REFINED_TO"); |
789 |
g_statio_stattypenames[ATS] = AddSymbol("ARE_THE_SAME"); |
790 |
g_statio_stattypenames[AA] = AddSymbol("ARE_ALIKE"); |
791 |
g_statio_stattypenames[FOR] = AddSymbol("FOR"); |
792 |
g_statio_stattypenames[REL] = GetBaseTypeName(relation_type); |
793 |
g_statio_stattypenames[LOGREL] = GetBaseTypeName(logrel_type); |
794 |
g_statio_stattypenames[ASGN] = AddSymbol("Assignment"); |
795 |
g_statio_stattypenames[CASGN] = AddSymbol("Constant assignment"); |
796 |
g_statio_stattypenames[RUN] = AddSymbol("RUN"); |
797 |
g_statio_stattypenames[IF] = AddSymbol("IF"); |
798 |
g_statio_stattypenames[WHEN] = GetBaseTypeName(when_type); |
799 |
g_statio_stattypenames[FNAME] = AddSymbol("FNAME"); |
800 |
g_statio_stattypenames[SELECT] = AddSymbol("SELECT"); |
801 |
g_statio_stattypenames[SWITCH] = AddSymbol("SWITCH"); |
802 |
g_statio_stattypenames[EXT] = AddSymbol("EXTERNAL"); |
803 |
g_statio_stattypenames[CALL] = AddSymbol("CALL"); |
804 |
g_statio_stattypenames[ASSERT] = AddSymbol("ASSERT"); |
805 |
g_statio_stattypenames[FLOW] = AddSymbol("<flow-control>"); |
806 |
g_statio_stattypenames[WHILE] = AddSymbol("WHILE"); |
807 |
g_statio_stattypenames[REF] = AddSymbol("_IS_"); |
808 |
g_statio_stattypenames[COND] = AddSymbol("CONDITIONAL"); |
809 |
g_statio_stattypenames[WBTS] = AddSymbol("WILL_BE_THE_SAME"); |
810 |
g_statio_stattypenames[WNBTS] = AddSymbol("WILL_NOT_BE_THE_SAME"); |
811 |
g_statio_stattypenames[WILLBE] = AddSymbol("WILL_BE"); |
812 |
g_statio_flowtypenames[fc_return] = AddSymbol("RETURN"); |
813 |
g_statio_flowtypenames[fc_continue] = AddSymbol("CONTINUE"); |
814 |
g_statio_flowtypenames[fc_stop] = AddSymbol("STOP"); |
815 |
g_statio_flowtypenames[fc_break] = AddSymbol("BREAK"); |
816 |
g_statio_flowtypenames[fc_fallthru] = AddSymbol("FALL_THROUGH"); |
817 |
} |
818 |
switch(StatementType(s)) { |
819 |
case ALIASES: |
820 |
case ISA: |
821 |
case ARR: |
822 |
case IRT: |
823 |
case ATS: |
824 |
case AA: |
825 |
case FOR: |
826 |
case REL: |
827 |
case LOGREL: |
828 |
case ASGN: |
829 |
case CASGN: |
830 |
case RUN: |
831 |
case IF: |
832 |
case WHEN: |
833 |
case FNAME: |
834 |
case SELECT: |
835 |
case SWITCH: |
836 |
case EXT: |
837 |
case CALL: |
838 |
case ASSERT: |
839 |
case REF: |
840 |
case COND: |
841 |
case WBTS: |
842 |
case WNBTS: |
843 |
case WILLBE: |
844 |
case WHILE: |
845 |
/* It's a massive fall through to check that we know the statement */ |
846 |
return g_statio_stattypenames[StatementType(s)]; |
847 |
case FLOW: |
848 |
return g_statio_flowtypenames[FlowStatControl(s)]; |
849 |
default: |
850 |
return error_statement_sym; |
851 |
} |
852 |
} |
853 |
|
854 |
void Asc_StatErrMsg_NotAllowedMethod(FILE *f |
855 |
, CONST struct Statement *stat |
856 |
, CONST char *suggestion |
857 |
){ |
858 |
(void)f; |
859 |
error_reporter(ASC_USER_ERROR,Asc_ModuleBestName(StatementModule(stat)) |
860 |
, StatementLineNum(stat), NULL |
861 |
, "In a METHOD, %s statements are not allowed. %s" |
862 |
, SCP(StatementTypeString(stat)) |
863 |
, suggestion |
864 |
); |
865 |
} |
866 |
|
867 |
void Asc_StatErrMsg_NotAllowedDeclarative(FILE *f |
868 |
, CONST struct Statement *stat |
869 |
, CONST char * suggestion |
870 |
){ |
871 |
(void)f; |
872 |
error_reporter(ASC_USER_ERROR,Asc_ModuleBestName(StatementModule(stat)) |
873 |
, StatementLineNum(stat), NULL |
874 |
, "In a MODEL's declarative section, %s statements not allowed. %s" |
875 |
, SCP(StatementTypeString(stat)) |
876 |
, suggestion |
877 |
); |
878 |
} |