/[ascend]/trunk/ascend/compiler/initialize.c
ViewVC logotype

Contents of /trunk/ascend/compiler/initialize.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2329 - (show annotations) (download) (as text)
Wed Dec 22 12:52:47 2010 UTC (7 years, 11 months ago) by jpye
File MIME type: text/x-csrc
File size: 60497 byte(s)
Suppressing some console output.
Added test case that current crashes ASCEND/IPOPT with a memory error.
Issue with library.cpp not containing any way to free libascend memory.
1 /* ex:set ts=4: */
2 /*
3 * Initialization Routines
4 * by Tom Epperly
5 * Created: 3/24/1990
6 * Version: $Revision: 1.36 $
7 * Version control file: $RCSfile: initialize.c,v $
8 * Date last modified: $Date: 1998/06/11 15:28:30 $
9 * Last modified by: $Author: ballan $
10 *
11 * This file is part of the Ascend Language Interpreter.
12 *
13 * Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
14 *
15 * The Ascend Language Interpreter is free software; you can redistribute
16 * it and/or modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of the
18 * License, or (at your option) any later version.
19 *
20 * The Ascend Language Interpreter is distributed in hope that it will be
21 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with the program; if not, write to the Free Software Foundation,
27 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
28 * COPYING.
29 *
30 */
31
32 #include <ascend/general/platform.h>
33 #include <ascend/general/ascMalloc.h>
34 #include <ascend/general/list.h>
35 #include <ascend/general/dstring.h>
36
37 #include "symtab.h"
38 #include "functype.h"
39 #include "expr_types.h"
40 #include "forvars.h"
41 #include "name.h"
42 #include "find.h"
43 #include "vlist.h"
44 #include "instance_enum.h"
45 #include "cmpfunc.h"
46 #include "stattypes.h"
47 #include "statement.h"
48 #include "statio.h"
49 #include "switch.h"
50 #include "evaluate.h"
51 #include "value_type.h"
52 #include "setinstval.h"
53 #include "extfunc.h"
54 #include "packages.h"
55 #include "instance_io.h"
56 #include "nameio.h"
57 #include "atomvalue.h"
58 #include "instquery.h"
59 #include "type_desc.h"
60 #include "library.h"
61 #include "extcall.h"
62 #include "proc.h"
63 #include "watchpt.h"
64 #include "procframe.h"
65 #include "procio.h"
66 #include "initialize.h"
67 #include "switch.h"
68 #include "exprs.h"
69 #include "sets.h"
70 #include "parentchild.h"
71 #include "slvreq.h"
72
73 /* set to 1 for tracing execution the hard way. */
74 #define IDB 0
75
76 //#define INIT_DEBUG
77
78 /*********************************************************************\
79 There is a stack of procedure calls kept for tracing and breaking
80 recursion errors.
81 INITSTACKLIMIT is the minimum we will allow internally.
82 This is independent of the procframes until we get those
83 solidly cleaned up.
84 \*********************************************************************/
85
86 static
87 struct {
88 unsigned long limit;
89 unsigned long depth;
90 } g_proc = {INITSTACKLIMIT,0L};
91
92 unsigned long GetProcStackLimit(void)
93 {
94 return g_proc.limit;
95 }
96
97 void SetProcStackLimit(unsigned long lim)
98 {
99 if (lim < 3) {
100 FPRINTF(ASCERR,
101 "SetProcStackLimit called with limit too small (%lu). Ignored.\n",lim);
102 return;
103 }
104 if (g_proc.depth) {
105 FPRINTF(ASCERR, "SetProcStackLimit called during evaluation. Ignored.\n");
106 return;
107 }
108 g_proc.limit = lim;
109 return;
110 }
111
112 /* The following 2 forward declarations have been moved out of the
113 * header, where they had no business being, so we can adequately
114 * guard against recursive functions.
115 * static void ExecuteInitRun(struct procFrame *, struct Statement *);
116 * static void ExecuteInitProcedure(struct procFrame *,
117 * struct InitProcedure *);
118 */
119
120
121 static void ExecuteInitStatements(struct procFrame *,struct StatementList *);
122 static void RealInitialize(struct procFrame *, struct Name *);
123 static void ClassAccessRealInitialize(struct procFrame *, struct Name *, struct Name *);
124
125 /* just forward declarations cause we need it */
126
127 /*
128 * modifies the name given to it, if needed shortening it.
129 * If shortening, destroys the cut off part.
130 */
131 static
132 void InstanceNamePart(struct Name *n, struct Name **copy,
133 symchar **procname)
134 {
135 register struct Name *ptr,*tmp;
136
137 /*FPRINTF(ASCERR,"INSTANCE NAME PART, input is n=");
138 WriteName(ASCERR,n);
139 FPRINTF(ASCERR,"\n");
140 */
141
142 if (n==NULL){
143 FPRINTF(ASCERR,"n IS NULL");
144 *copy = NULL;
145 *procname = NULL;
146 return;
147 }
148 if (NextName(n)==NULL) { /* RUN a; a is the procname */
149 *copy = NULL;
150 if (NameId(n) != 0) {
151 *procname = NameIdPtr(n);
152 } else {
153 *procname = NULL;
154 }
155 } else {
156 /* RUN a.b.c.clear; clear is the procname */
157 ptr = *copy = CopyName(n);
158 while (NextName(NextName(ptr))!=NULL) {
159 ptr = NextName(ptr);
160 }
161 tmp = NextName(ptr);
162 LinkNames(ptr,NULL); /* disconnect last part of name */
163 if (NameId(tmp) != 0) {
164 *procname = NameIdPtr(tmp);
165 } else {
166 *procname = NULL;
167 }
168 DestroyName(tmp);
169 }
170 }
171
172 struct InitProcedure *SearchProcList(CONST struct gl_list_t *l,
173 symchar *name)
174 {
175 register unsigned up,c,low;
176 register struct InitProcedure *ptr;
177 register int cmp;
178 assert(AscFindSymbol(name)!=NULL);
179 if (l == NULL) {
180 return NULL;
181 }
182 up = gl_length(l);
183 low = 1;
184 while(low<=up){
185 c = (low+up)/2;
186 ptr = (struct InitProcedure *)gl_fetch(l,c);
187 cmp = CmpSymchar(ProcName(ptr),name);
188 if (cmp == 0) {
189 return ptr;
190 }
191 if (cmp<0) {
192 low = c+1;
193 } else {
194 up = c-1;
195 }
196 }
197 return NULL;
198 }
199
200 struct InitProcedure *FindProcedure(CONST struct Instance *i,
201 symchar *procname
202 ){
203 struct TypeDescription *desc;
204 desc = InstanceTypeDesc(i);
205 return FindMethod(desc, procname); /* this code in type_desc.c now -- JP */
206 }
207
208
209 /*********************************************************************\
210 * void ExecuteInitRun(fm,stat);
211 * struct procFrame *fm;
212 * struct InitProcedure *proc;
213 * This will execute a run statement, using the given instance as the
214 * context. stat must be a RUN statement. In the event of error will
215 * print appropriate messages to stderr.
216 \*********************************************************************/
217 /*
218 * This returns proc_all_ok in all circumstances except stack overflow.
219 * If within it any other error occurs, it prints the message and
220 * then pretends everything is ok.
221 * This behavior should perhaps be better.
222 */
223 static
224 void ExecuteInitRun(struct procFrame *fm, struct Statement *stat)
225 {
226 struct Name *typename;
227
228 typename = RunStatAccess(stat);
229 if (typename != NULL) {
230 ClassAccessRealInitialize(fm,typename,RunStatName(stat));
231 } else {
232 RealInitialize(fm,RunStatName(stat));
233 }
234 /* an error was encountered */
235 if (fm->flow == FrameError) {
236 ProcWriteRunError(fm);
237 }
238 }
239
240 /**
241 Shared function for FIX and FREE execution
242 @param val is TRUE for 'FIX', or FALSE for 'FREE'.
243 */
244 static void
245 execute_init_fix_or_free(int val, struct procFrame *fm, struct Statement *stat){
246 CONST struct VariableList *vars;
247 enum find_errors e;
248 struct gl_list_t *temp;
249 unsigned i, len;
250 struct Instance *i1, *i2;
251 //char *instname;
252 struct TypeDescription *t, *st;
253 CONST struct Name *name;
254 symchar *fixed;
255 /* setup */
256 fixed = AddSymbol("fixed");
257 st = FindType(AddSymbol("solver_var"));
258 if(st==NULL){
259 ERROR_REPORTER_HERE(ASC_PROG_ERR,"'solver_var' type is not yet in library");
260 fm->ErrNo = Proc_type_not_found;
261 return;
262 }
263
264 #ifdef FIXFREE_DEBUG
265 CONSOLE_DEBUG("STARTING 'FIX'/'FREE' EXECUTION...");
266 WriteStatement(ASCERR,stat,4);
267 #endif
268
269 /* iterate through the variable list */
270 vars = stat->v.fx.vars;
271 while(vars!=NULL){
272 name = NamePointer(vars);
273 temp = FindInstances(fm->i, name, &e);
274 if(temp==NULL){
275 fm->ErrNo = Proc_bad_name;
276 return;
277 }
278 len = gl_length(temp);
279 for(i=1; i<=len; i++){
280 i1 = (struct Instance *)gl_fetch(temp,i);
281 #ifdef FIXFREE_DEBUG
282 instname = WriteInstanceNameString(i1,NULL);
283 if(val){
284 CONSOLE_DEBUG("ABOUT TO FIX %s",instname);
285 }else{
286 CONSOLE_DEBUG("ABOUT TO FREE %s",instname);
287 }
288 ascfree(instname);
289 #endif
290 if(InstanceKind(i1)!=REAL_ATOM_INST){
291 fm->ErrNo = Proc_illegal_type_use;
292 ProcWriteFixError(fm,name);
293 return;
294 }
295 t = InstanceTypeDesc(i1);
296 if(!MoreRefined(t,st)){
297 CONSOLE_DEBUG("Attempted to FIX or FREE variable that is not a refined solver_var.");
298 fm->ErrNo = Proc_illegal_type_use;
299 ProcWriteFixError(fm,name);
300 return;
301 }
302 i2 = ChildByChar(i1,fixed);
303 if(i2==NULL){
304 CONSOLE_DEBUG("Attempted to FIX or FREE a solver_var that doesn't have a 'fixed' child!");
305 fm->ErrNo = Proc_illegal_type_use;
306 ProcWriteFixError(fm,name);
307 return;
308 }
309 if(InstanceKind(i2)!=BOOLEAN_INST){
310 CONSOLE_DEBUG("Attempted to FIX or FREE a solver_var whose 'fixed' child is not boolean!");
311 fm->ErrNo = Proc_illegal_type_use;
312 ProcWriteFixError(fm,name);
313 return;
314 }
315 SetBooleanAtomValue(i2,val,0);
316 }
317 gl_destroy(temp);
318 vars = NextVariableNode(vars);
319 }
320 /* CONSOLE_DEBUG("DONE WITH VARLIST"); */
321
322 /* return 'ok' */
323 fm->ErrNo = Proc_all_ok;
324 }
325
326 static void
327 ExecuteInitFix(struct procFrame *fm, struct Statement *stat){
328 execute_init_fix_or_free(TRUE,fm,stat);
329 }
330
331 static void
332 ExecuteInitFree(struct procFrame *fm, struct Statement *stat){
333 execute_init_fix_or_free(FALSE,fm,stat);
334 }
335
336 static void
337 ExecuteInitSolver(struct procFrame *fm, struct Statement *stat){
338 int res;
339 CONST char *solvername = stat->v.solver.name;
340 assert(fm->i!=NULL);
341 /*CONSOLE_DEBUG("Setting solver to '%s'...",stat->v.solver.name);*/
342 res = slvreq_set_solver(fm->i, solvername);
343 if(res){
344 switch(res){
345 case SLVREQ_NOT_IMPLEMENTED: fm->ErrNo = Proc_slvreq_not_implemented; break;
346 case SLVREQ_SOLVER_HOOK_NOT_SET: fm->ErrNo = Proc_slvreq_unhooked; break;
347 case SLVREQ_UNKNOWN_SOLVER: fm->ErrNo = Proc_slvreq_unknown_solver; break;
348 }
349 ProcWriteSlvReqError(fm);
350 return;
351 }else{
352 fm->ErrNo = Proc_all_ok;
353 }
354 /*CONSOLE_DEBUG("Solver set to %s, OK",stat->v.solver.name);*/
355 }
356
357 static void
358 ExecuteInitOption(struct procFrame *fm, struct Statement *stat){
359 CONST char *optionname = stat->v.option.name;
360 struct value_t value;
361 assert(GetEvaluationContext()==NULL);
362 SetEvaluationContext(fm->i);
363 value = EvaluateExpr(stat->v.option.rhs,NULL,InstanceEvaluateName);
364 SetEvaluationContext(NULL);
365 /*CONSOLE_DEBUG("Setting option '%s'...",optionname);*/
366 int res;
367
368 switch(ValueKind(value)){
369 case integer_value:
370 case real_value:
371 case symbol_value:
372 case boolean_value:
373 res = slvreq_set_option(fm->i, optionname, &value);
374 switch(res){
375 case 0: fm->ErrNo = Proc_all_ok; break;
376 case SLVREQ_OPTION_HOOK_NOT_SET: fm->ErrNo = Proc_slvreq_unhooked; break;
377 case SLVREQ_OPTIONS_UNAVAILABLE: fm->ErrNo = Proc_slvreq_no_solver_selected; break;
378 case SLVREQ_INVALID_OPTION_NAME: fm->ErrNo = Proc_slvreq_invalid_option_name; break;
379 case SLVREQ_WRONG_OPTION_VALUE_TYPE: fm->ErrNo = Proc_slvreq_option_invalid_type; break;
380 case SLVREQ_NOT_IMPLEMENTED: fm->ErrNo = Proc_slvreq_not_implemented; break;
381 default: fm->ErrNo = Proc_slvreq_error; /* unknown error! */
382 }
383 break;
384 case set_value:
385 fm->ErrNo = Proc_slvreq_option_invalid_type;
386 break;
387 case error_value:
388 fm->ErrNo = Proc_if_expr_error_confused;
389 switch (ErrorValue(value)) {
390 case type_conflict:
391 fm->ErrNo = Proc_if_expr_error_typeconflict;
392 break;
393 case name_unfound:
394 fm->ErrNo = Proc_if_expr_error_nameunfound;
395 break;
396 case incorrect_name:
397 fm->ErrNo = Proc_if_expr_error_incorrectname;
398 break;
399 case undefined_value:
400 fm->ErrNo = Proc_if_expr_error_undefinedvalue;
401 break;
402 case dimension_conflict:
403 fm->ErrNo = Proc_if_expr_error_dimensionconflict;
404 break;
405 case empty_choice:
406 fm->ErrNo = Proc_if_expr_error_emptychoice;
407 break;
408 case empty_intersection:
409 fm->ErrNo = Proc_if_expr_error_emptyintersection;
410 break;
411 default:
412 fm->ErrNo = Proc_slvreq_error;
413 }
414 break;
415 default:
416 fm->ErrNo = Proc_slvreq_error;
417 break;
418 }
419 if(fm->ErrNo != Proc_all_ok){
420 ProcWriteSlvReqError(fm);
421 }
422 DestroyValue(&value);
423 return;
424 }
425
426 static void
427 ExecuteInitSolve(struct procFrame *fm, struct Statement *stat){
428 int res;
429 res = slvreq_do_solve(fm->i);
430 if(res){
431 switch(res){
432 case SLVREQ_NO_SOLVER_SELECTED: fm->ErrNo = Proc_slvreq_no_solver_selected; break;
433 case SLVREQ_NOT_IMPLEMENTED: fm->ErrNo = Proc_slvreq_not_implemented; break;
434 case SLVREQ_SOLVE_HOOK_NOT_SET: fm->ErrNo = Proc_slvreq_unhooked; break;
435 default: fm->ErrNo = Proc_slvreq_error; break;
436 }
437 ProcWriteSlvReqError(fm);
438 return;
439 }
440 fm->ErrNo = Proc_all_ok;
441 }
442
443 static
444 void ExecuteInitFlow(struct procFrame *fm)
445 {
446 assert(fm!=NULL);
447 assert(fm->stat!=NULL);
448 assert(StatementType(fm->stat)==FLOW);
449 switch (FlowStatControl(fm->stat)) {
450 case fc_break:
451 fm->ErrNo = Proc_break;
452 fm->flow = FrameBreak;
453 break;
454 case fc_continue:
455 fm->ErrNo = Proc_continue;
456 fm->flow = FrameContinue;
457 break;
458 case fc_fallthru:
459 fm->ErrNo = Proc_fallthru;
460 fm->flow = FrameFallthru;
461 break;
462 case fc_return:
463 fm->ErrNo = Proc_return;
464 fm->flow = FrameReturn; /* needs to be caught automagically to frameok
465 * if errno is proc_return.
466 */
467 break;
468 case fc_stop:
469 fm->ErrNo = Proc_stop;
470 fm->flow = FrameError;
471 ProcWriteIfError(fm,"STOP");
472 break;
473 default:
474 break;
475 }
476 }
477
478 /**
479 The following functions have been made static as they are very similar to those used in instantiate.c. They really should be rationalized and exported by instantiate.c. As usual, any function with Special in the name is written by KAA.
480 */
481 #define SELF_NAME "SELF"
482
483 static
484 int SpecialSelfName(CONST struct Name *n)
485 {
486 symchar *id;
487 if (n == NULL) {
488 return 0;
489 }
490 id = SimpleNameIdPtr(n);
491 if (id == NULL) {
492 return 0;
493 }
494 if (strcmp(SCP(id),SELF_NAME)==0) {
495 return 1;
496 } else {
497 return 0;
498 }
499 }
500
501 /**
502 Produces a list of lists of argument instances. a the list returned is never NULL except when out of memory. Entries in this list may be NULL if some argument search fails. Argument search is successful IFF errlist returned is empty (length 0).
503 */
504 static
505 struct gl_list_t *ProcessExtMethodArgs(struct Instance *inst,
506 CONST struct VariableList *vl,
507 struct gl_list_t *errlist)
508 {
509 struct gl_list_t *arglist;
510 struct gl_list_t *branch;
511 CONST struct Name *n;
512 enum find_errors ferr;
513 unsigned long pos;
514
515 ListMode=1;
516 arglist = gl_create(10L);
517 pos = 1;
518 while(vl!=NULL){
519 n = NamePointer(vl);
520 ferr = correct_instance;
521 branch = FindInstances(inst,n,&ferr);
522 if (branch == NULL || ferr != correct_instance) {
523 /* check for SELF only if find fails, so SELF IS_A foo
524 * overrides the normal self.
525 */
526 if (SpecialSelfName(n)) {
527 if (branch == NULL) {
528 branch = gl_create(1L);
529 } else {
530 gl_reset(branch);
531 }
532 /* Self referential instance */
533 gl_append_ptr(branch,(VOIDPTR)inst);
534 } else {
535 gl_append_ptr(errlist,(VOIDPTR)pos); /* error position */
536 gl_append_ptr(errlist,(VOIDPTR)ferr); /* error code */
537 if (branch == NULL) {
538 branch = gl_create(1L); /* create empty branch */
539 }
540 }
541 }
542 assert(branch != NULL);
543 gl_append_ptr(arglist,(VOIDPTR)branch);
544 vl = NextVariableNode(vl);
545 pos++;
546 }
547 ListMode=0;
548 return arglist;
549 }
550
551 static
552 struct gl_list_t *InitCheckExtCallArgs(struct Instance *inst,
553 struct Statement *stat,
554 struct gl_list_t *errs)
555 {
556 CONST struct VariableList *vl;
557 struct gl_list_t *result;
558
559 vl = ExternalStatVlistMethod(stat);
560 result = ProcessExtMethodArgs(inst,vl,errs);
561 return result;
562 }
563
564 static
565 void ExecuteInitCall(struct procFrame *fm, struct Statement *stat)
566 {
567 (void)fm; /* stop gcc whine about unused parameter */
568 (void)stat; /* stop gcc whine about unused parameter */
569 #if 0 /* guts of CALL statement execution need coding. */
570 /* something like ExecuteInitExt only string driven gllist argument
571 * translation +/- varargs BS, etc, etc
572 */
573 #endif
574 }
575
576 /*
577 * This always returns ok. at least as of 5/96.
578 */
579 static
580 void ExecuteInitExt(struct procFrame *fm, struct Statement *stat)
581 {
582 struct ExternalFunc *efunc;
583 CONST char *funcname;
584 struct gl_list_t *arglist=NULL, *errlist;
585 enum find_errors ferr;
586 unsigned long c,len,pos;
587
588 ExtMethodRun *eval_func;
589 void *user_data;
590 int nok;
591
592 funcname = ExternalStatFuncName(stat);
593 efunc = LookupExtFunc(funcname);
594
595 /*CONSOLE_DEBUG("EXECUTEINITEXT func name:'%s'",funcname);*/
596
597 if (efunc == NULL) {
598 CONSOLE_DEBUG("Failed to look up external function");
599 fm->ErrNo = Proc_CallError;
600 fm->flow = FrameError;
601 ProcWriteExtError(fm,funcname,PE_unloaded,0);
602 return;
603 }
604
605 /* CONSOLE_DEBUG("%s: in:%ld, out:%ld", efunc->name, efunc->n_inputs, efunc->n_outputs); */
606
607 eval_func = GetExtMethodRun(efunc);
608 user_data = GetExtMethodUserData(efunc);
609 if (eval_func == NULL) {
610 CONSOLE_DEBUG("GetValueFunc(efunc) returned NULL");
611 fm->ErrNo = Proc_CallError;
612 fm->flow = FrameError;
613 ProcWriteExtError(fm,funcname,PE_nulleval,0);
614 return;
615 }
616
617 errlist = gl_create(1);
618 arglist = InitCheckExtCallArgs(fm->i,stat,errlist);
619 len = gl_length(errlist);
620 if (len != 0) {
621 CONSOLE_DEBUG("InitCheckExtCallArgs returned items in errlist...");
622 fm->flow = FrameError;
623 ProcWriteExtError(fm,funcname,PE_argswrong,0);
624 c = 1;
625 assert((len & 0x1) == 0); /* must be even */
626 while (c < len) {
627 /* works because error position/code pairs */
628 pos = (unsigned long)gl_fetch(errlist,c);
629 c++; /* Wait, who let that dirty word in here!? */
630 ferr = (enum find_errors)gl_fetch(errlist,c);
631 c++;
632 switch (ferr) {
633 case unmade_instance:
634 fm->ErrNo = Proc_instance_not_found;
635 ProcWriteExtError(fm,funcname,PE_badarg,(int)pos);
636 break;
637 case undefined_instance:
638 fm->ErrNo = Proc_name_not_found;
639 ProcWriteExtError(fm,funcname,PE_badarg,(int)pos);
640 break;
641 case impossible_instance:
642 fm->ErrNo = Proc_illegal_name_use;
643 ProcWriteExtError(fm,funcname,PE_badarg,(int)pos);
644 break; /* move write to procio */
645 case correct_instance:
646 fm->ErrNo = Proc_CallError;
647 ProcWriteExtError(fm,funcname,PE_badarg,(int)pos);
648 break;
649 default:
650 fm->ErrNo = Proc_bad_name;
651 ProcWriteExtError(fm,funcname,PE_badarg,(int)pos);
652 break;
653 }
654 }
655 fm->ErrNo = Proc_CallError;
656 if (arglist != NULL) {
657 DestroySpecialList(arglist);
658 }
659 if (errlist != NULL) {
660 gl_destroy(errlist);
661 }
662 return;
663 }
664
665 /* CONSOLE_DEBUG("CHECKED EXTERNAL ARGS, OK"); */
666
667 nok = (*eval_func)(fm->i,arglist,user_data);
668
669 /* CONSOLE_DEBUG("BACK FROM RUNING FUNC AT %p",eval_func); */
670
671 /* this should switch on Proc_CallXXXXX */
672 /* should switch on proc_enum call bits to translate Proc_Call
673 * flow of control to our fm->flow.
674 */
675 if (nok) {
676 fm->flow = FrameError; /* move write to procio */
677 CONSOLE_DEBUG("NOK");
678 ProcWriteExtError(fm,funcname,PE_evalerr,0);
679 } else {
680 fm->flow = FrameOK;
681 }
682 if (arglist != NULL) {
683 DestroySpecialList(arglist);
684 }
685 if (errlist != NULL) {
686 gl_destroy(errlist);
687 }
688
689 return;
690 }
691
692 /*
693 * executes a for loop
694 */
695 static
696 void ExecuteInitFor(struct procFrame *fm, struct Statement *stat)
697 {
698 symchar *name;
699 struct Expr *ex;
700 struct StatementList *sl;
701 unsigned long c,len;
702 int direction; /* was declared unsigned long, but used as int (JDS 12/11/2005) */
703 struct value_t value;
704 struct set_t *sptr;
705 struct for_var_t *fv;
706 enum FrameControl oldflow;
707
708 c = direction = 1; /* shut up gcc */
709
710 name = ForStatIndex(stat);
711 ex = ForStatExpr(stat);
712 sl = ForStatStmts(stat);
713 fv = FindForVar(GetEvaluationForTable(),name);
714 if (fv != NULL) { /* duplicated for variable */
715 fm->flow = FrameError;
716 fm->ErrNo = Proc_for_duplicate_index;
717 ProcWriteForError(fm);
718 return;
719 }
720 assert(GetEvaluationContext()==NULL);
721 SetEvaluationContext(fm->i);
722 value = EvaluateExpr(ex,NULL,InstanceEvaluateName);
723 SetEvaluationContext(NULL);
724 switch(ValueKind(value)){
725 case error_value:
726 fm->flow = FrameError;
727 fm->ErrNo = Proc_for_set_err;
728 ProcWriteForError(fm);
729 break;
730 case set_value:
731 sptr = SetValue(value);
732 switch(SetKind(sptr)){
733 case empty_set:
734 break;
735 case integer_set:
736 fv = CreateForVar(name);
737 SetForVarType(fv,f_integer);
738 AddLoopVariable(GetEvaluationForTable(),fv);
739 len = Cardinality(sptr);
740 switch(ForLoopOrder(stat)){
741 case f_random:
742 /* fall through, that should never occur due to parser. */
743 case f_increasing:
744 direction = 1;
745 c = 1;
746 break;
747 case f_decreasing:
748 direction = -1;
749 c = len;
750 break;
751 }
752 /* we handle all logic with one for loop to avoid
753 * duplicate code insanity.
754 */
755 oldflow = fm->flow;
756 fm->flow = FrameLoop;
757 for(/* init c in switch above */;
758 c >= 1 && c <= len &&
759 fm->flow != FrameBreak && fm->flow != FrameReturn;
760 c += direction) {
761 SetForInteger(fv,FetchIntMember(sptr,c));
762 ExecuteInitStatements(fm,sl);
763 switch (fm->flow) {
764 case FrameOK:
765 case FrameContinue:
766 fm->flow = FrameLoop;
767 break;
768 case FrameLoop:
769 case FrameBreak:
770 case FrameFallthru:
771 case FrameReturn:
772 break;
773 case FrameError: /*EISS not to return this!*/
774 default: /* should never happen */
775 #if IDB
776 FPRINTF(fm->err,"ERR-NEVER1: "); WriteStatement(fm->err,stat,0);
777 FPRINTF(fm->err,"\n");
778 #endif
779 fm->flow = FrameReturn;
780 break;
781 }
782 }
783 /* post loop flow processing */
784 switch (fm->flow) {
785 case FrameLoop:
786 case FrameBreak:
787 fm->flow = oldflow;
788 break;
789 default:
790 break; /* let return, fallthru out to next level */
791 }
792 RemoveForVariable(GetEvaluationForTable());
793 break; /* integer_set */
794 case string_set:
795 fv = CreateForVar(name);
796 SetForVarType(fv,f_symbol);
797 AddLoopVariable(GetEvaluationForTable(),fv);
798 len = Cardinality(sptr);
799 switch(ForLoopOrder(stat)){
800 case f_random:
801 /* fall through, that should never occur due to parser. */
802 case f_increasing:
803 direction = 1;
804 c = 1;
805 break;
806 case f_decreasing:
807 direction = -1;
808 c = len;
809 break;
810 }
811 oldflow = fm->flow;
812 fm->flow = FrameLoop;
813 for(/* init c in switch above */;
814 c >= 1 && c <= len &&
815 fm->flow != FrameBreak && fm->flow != FrameReturn;
816 c += direction) {
817 SetForSymbol(fv,FetchStrMember(sptr,c));
818 ExecuteInitStatements(fm,sl);
819 switch (fm->flow) {
820 case FrameOK:
821 case FrameContinue:
822 fm->flow = FrameLoop;
823 break;
824 case FrameLoop:
825 case FrameBreak:
826 case FrameReturn:
827 case FrameFallthru:
828 break;
829 case FrameError: /*EISS not to return this!*/
830 default: /* should never happen */
831 #if IDB
832 FPRINTF(fm->err,"ERR-NEVER2: "); WriteStatement(fm->err,stat,0);
833 FPRINTF(fm->err,"\n");
834 #endif
835 fm->flow = FrameReturn;
836 break;
837 }
838 }
839 /* post loop flow processing */
840 switch (fm->flow) {
841 case FrameLoop:
842 case FrameBreak:
843 fm->flow = oldflow;
844 break;
845 default:
846 break;
847 }
848 RemoveForVariable(GetEvaluationForTable());
849 break;
850 }
851 break;
852 default:
853 fm->flow = FrameError;
854 fm->ErrNo = Proc_for_not_set;
855 ProcWriteForError(fm);
856 break;
857 }
858 DestroyValue(&value);
859 return;
860 }
861
862 static void
863 ExecuteInitAssert(struct procFrame *fm, struct Statement *stat){
864 struct value_t value;
865 int testerr;
866 assert(GetEvaluationContext()==NULL);
867 SetEvaluationContext(fm->i);
868 value = EvaluateExpr(AssertStatExpr(stat),NULL,InstanceEvaluateName);
869 SetEvaluationContext(NULL);
870 testerr = 1; /* set 0 on success */
871 switch(ValueKind(value)){
872 case boolean_value:
873 testerr = 0;
874 #ifdef INIT_DEBUG
875 CONSOLE_DEBUG("Assertion %s.",BooleanValue(value)?"OK":"failed");
876 #endif
877 if(BooleanValue(value)){
878 WriteStatementError(ASC_USER_SUCCESS,stat,0,"Assertion OK");
879 }else{
880 WriteStatementError(ASC_USER_ERROR,stat,1,"Assertion failed");
881 }
882 break;
883 case real_value:
884 fm->flow = FrameError;
885 fm->ErrNo = Proc_if_real_expr;
886 break;
887 case integer_value:
888 fm->flow = FrameError;
889 fm->ErrNo = Proc_if_integer_expr;
890 break;
891 case symbol_value:
892 fm->flow = FrameError;
893 fm->ErrNo = Proc_if_symbol_expr;
894 break;
895 case set_value: /* FALLTHROUGH */
896 case list_value:
897 fm->flow = FrameError;
898 fm->ErrNo = Proc_if_set_expr;
899 break;
900 case error_value:
901 fm->flow = FrameError;
902 fm->ErrNo = Proc_if_expr_error_confused;
903 switch (ErrorValue(value)) {
904 case type_conflict:
905 fm->ErrNo = Proc_if_expr_error_typeconflict;
906 break;
907 case name_unfound:
908 fm->ErrNo = Proc_if_expr_error_nameunfound;
909 break;
910 case incorrect_name:
911 fm->ErrNo = Proc_if_expr_error_incorrectname;
912 break;
913 case undefined_value:
914 fm->ErrNo = Proc_if_expr_error_undefinedvalue;
915 break;
916 case dimension_conflict:
917 fm->ErrNo = Proc_if_expr_error_dimensionconflict;
918 break;
919 case empty_choice:
920 fm->ErrNo = Proc_if_expr_error_emptychoice;
921 break;
922 case empty_intersection:
923 fm->ErrNo = Proc_if_expr_error_emptyintersection;
924 break;
925 default:
926 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unhandled case");
927 }
928 break;
929 default:
930 fm->flow = FrameError;
931 fm->ErrNo = Proc_if_not_logical;
932 break;
933 }
934 if (fm->flow == FrameError && testerr) {
935 ProcWriteIfError(fm,"TEST");
936 }
937 DestroyValue(&value);
938 return;
939 }
940
941 static
942 void ExecuteInitIf(struct procFrame *fm, struct Statement *stat)
943 {
944 struct value_t value;
945 int iferr;
946
947 assert(GetEvaluationContext()==NULL);
948 SetEvaluationContext(fm->i);
949 value = EvaluateExpr(IfStatExpr(stat),NULL,InstanceEvaluateName);
950 SetEvaluationContext(NULL);
951 iferr = 1; /* set 0 on success */
952 switch(ValueKind(value)){
953 case boolean_value:
954 iferr = 0;
955 if (BooleanValue(value)) {
956 ExecuteInitStatements(fm,IfStatThen(stat));
957 } else {
958 if (IfStatElse(stat) != NULL) {
959 ExecuteInitStatements(fm,IfStatElse(stat));
960 }
961 }
962 break;
963 case real_value:
964 fm->flow = FrameError;
965 fm->ErrNo = Proc_if_real_expr;
966 break;
967 case integer_value:
968 fm->flow = FrameError;
969 fm->ErrNo = Proc_if_integer_expr;
970 break;
971 case symbol_value:
972 fm->flow = FrameError;
973 fm->ErrNo = Proc_if_symbol_expr;
974 break;
975 case set_value: /* FALLTHROUGH */
976 case list_value:
977 fm->flow = FrameError;
978 fm->ErrNo = Proc_if_set_expr;
979 break;
980 case error_value:
981 fm->flow = FrameError;
982 fm->ErrNo = Proc_if_expr_error_confused;
983 switch (ErrorValue(value)) {
984 case type_conflict:
985 fm->ErrNo = Proc_if_expr_error_typeconflict;
986 break;
987 case name_unfound:
988 fm->ErrNo = Proc_if_expr_error_nameunfound;
989 break;
990 case incorrect_name:
991 fm->ErrNo = Proc_if_expr_error_incorrectname;
992 break;
993 case undefined_value:
994 fm->ErrNo = Proc_if_expr_error_undefinedvalue;
995 break;
996 case dimension_conflict:
997 fm->ErrNo = Proc_if_expr_error_dimensionconflict;
998 break;
999 case empty_choice:
1000 fm->ErrNo = Proc_if_expr_error_emptychoice;
1001 break;
1002 case empty_intersection:
1003 fm->ErrNo = Proc_if_expr_error_emptyintersection;
1004 break;
1005 default:
1006 break;
1007 }
1008 break;
1009 default:
1010 fm->flow = FrameError;
1011 fm->ErrNo = Proc_if_not_logical;
1012 break;
1013 }
1014 if (fm->flow == FrameError && iferr) {
1015 ProcWriteIfError(fm,"IF");
1016 }
1017 DestroyValue(&value);
1018 return;
1019 }
1020
1021 /*
1022 */
1023 static
1024 void ExecuteInitWhile(struct procFrame *fm, struct Statement *stat)
1025 {
1026 struct value_t value;
1027 int iferr;
1028 int stop;
1029 long limit = WP_MAXTRIPS;
1030 enum FrameControl oldflow;
1031
1032 assert(GetEvaluationContext()==NULL);
1033 stop = 0;
1034 oldflow = fm->flow;
1035 fm->flow = FrameLoop;
1036 while (!stop) {
1037 assert(fm->flow == FrameLoop);
1038 SetEvaluationContext(fm->i);
1039 value = EvaluateExpr(WhileStatExpr(stat),NULL,InstanceEvaluateName);
1040 SetEvaluationContext(NULL);
1041 iferr = 1; /* set 0 on success */
1042 limit--;
1043 switch(ValueKind(value)){
1044 case boolean_value:
1045 iferr = 0;
1046 if (BooleanValue(value)) {
1047 ExecuteInitStatements(fm,WhileStatBlock(stat));
1048 switch (fm->flow) {
1049 case FrameOK:
1050 case FrameContinue:
1051 fm->flow = FrameLoop;
1052 break;
1053 case FrameLoop:
1054 break;
1055 case FrameBreak: /* break while loop only */
1056 case FrameFallthru: /* while must be inside switch...*/
1057 case FrameReturn:
1058 stop = 1;
1059 break;
1060 case FrameError: /* EISS is not supposed to let this happen */
1061 default: /* should never happen */
1062 #if IDB
1063 FPRINTF(fm->err,"ERR-NEVER3: "); WriteStatement(fm->err,stat,0);
1064 FPRINTF(fm->err,"\n");
1065 #endif
1066 fm->flow = FrameReturn;
1067 break;
1068 }
1069 } else {
1070 stop = 1;
1071 }
1072 break;
1073 case real_value:
1074 fm->flow = FrameError;
1075 fm->ErrNo = Proc_if_real_expr;
1076 break;
1077 case integer_value:
1078 fm->flow = FrameError;
1079 fm->ErrNo = Proc_if_integer_expr;
1080 break;
1081 case symbol_value:
1082 fm->flow = FrameError;
1083 fm->ErrNo = Proc_if_symbol_expr;
1084 break;
1085 case set_value: /* FALLTHROUGH */
1086 case list_value:
1087 fm->flow = FrameError;
1088 fm->ErrNo = Proc_if_set_expr;
1089 break;
1090 case error_value:
1091 fm->flow = FrameError;
1092 fm->ErrNo = Proc_if_expr_error_confused;
1093 switch (ErrorValue(value)) {
1094 case type_conflict:
1095 fm->ErrNo = Proc_if_expr_error_typeconflict;
1096 break;
1097 case name_unfound:
1098 fm->ErrNo = Proc_if_expr_error_nameunfound;
1099 break;
1100 case incorrect_name:
1101 fm->ErrNo = Proc_if_expr_error_incorrectname;
1102 break;
1103 case undefined_value:
1104 fm->ErrNo = Proc_if_expr_error_undefinedvalue;
1105 break;
1106 case dimension_conflict:
1107 fm->ErrNo = Proc_if_expr_error_dimensionconflict;
1108 break;
1109 case empty_choice:
1110 fm->ErrNo = Proc_if_expr_error_emptychoice;
1111 break;
1112 case empty_intersection:
1113 fm->ErrNo = Proc_if_expr_error_emptyintersection;
1114 break;
1115 default:
1116 break;
1117 }
1118 break;
1119 default:
1120 fm->flow = FrameError;
1121 fm->ErrNo = Proc_if_not_logical;
1122 break;
1123 }
1124 if (fm->flow == FrameError && iferr) {
1125 ProcWriteIfError(fm,"WHILE");
1126 }
1127 DestroyValue(&value);
1128 if (limit < 0) {
1129 stop = 1;
1130 fm->flow = FrameError;
1131 fm->ErrNo = Proc_infinite_loop;
1132 ProcWriteIfError(fm,"WHILE");
1133 }
1134 } /* endwhile */
1135 /* post loop processing */
1136 switch (fm->flow) {
1137 case FrameLoop:
1138 case FrameBreak:
1139 fm->flow = oldflow;
1140 break;
1141 default: /* let return, fallthru, out to next scope */
1142 break;
1143 }
1144 return;
1145 }
1146
1147
1148 /*
1149 * Compare current values of the switching variables with
1150 * the set of values in a CASE of a SWITCH statement, and try to find
1151 * is such values are the same.
1152 * If they are, the function will return Proc_case_matched,
1153 * else, it will return Proc_case_unmatched unless there is an error.
1154 * The possible error returns are legion, and this function
1155 * handles issuing error messages for them.
1156 *
1157 * If s given is NULL AND arm is -1, simply verifies that vlist elements
1158 * exist/are assigned. Normally this is only of use in checking
1159 * the OTHERWISE branch of the switch.
1160 * s must NOT be NULL unless arm is -1.
1161 */
1162 static
1163 void AnalyzeSwitchCase(struct procFrame *fm, struct VariableList *vlist,
1164 struct Set *s, int arm)
1165 {
1166 CONST struct Expr *expr;
1167 CONST struct Name *name;
1168 symchar *value;
1169 symchar *symvar;
1170 CONST struct VariableList *vl;
1171 CONST struct Set *values;
1172 int val;
1173 int pos;
1174 int valvar;
1175 struct gl_list_t *instances;
1176 struct Instance *inst;
1177 enum find_errors err;
1178 symchar *str;
1179 struct for_var_t *fvp;
1180
1181 assert(vlist != NULL);
1182 vl = vlist;
1183 fm->ErrNo = Proc_case_matched;
1184 pos = 0;
1185 if (s==NULL && arm == -1) {
1186 /* check vlist only */
1187 while (vl!=NULL) {
1188 pos++;
1189 name = NamePointer(vl);
1190 instances = FindInstances(fm->i,name,&err);
1191 if (instances == NULL){
1192 switch (err) {
1193 case unmade_instance:
1194 fm->ErrNo = Proc_instance_not_found;
1195 break;
1196 case undefined_instance:
1197 fm->ErrNo = Proc_name_not_found;
1198 break;
1199 case impossible_instance:
1200 fm->ErrNo = Proc_illegal_name_use;
1201 break;
1202 case correct_instance:
1203 fm->ErrNo = Proc_CallError;
1204 break;
1205 }
1206 }
1207 if (gl_length(instances)==1) {
1208 inst = (struct Instance *)gl_fetch(instances,1);
1209 gl_destroy(instances);
1210 if (!AtomAssigned(inst)) {
1211 fm->ErrNo = Proc_case_undefined_value;
1212 break; /* while */
1213 }
1214 } else {
1215 fm->ErrNo = Proc_case_extra_values;
1216 gl_destroy(instances);
1217 break; /* while */
1218 }
1219 vl = NextVariableNode(vl);
1220 }
1221 if (fm->ErrNo != Proc_case_matched) {
1222 ProcWriteCaseError(fm,arm,pos);
1223 }
1224 fm->flow = FrameError;
1225 return;
1226 }
1227
1228 assert(s!= NULL);
1229 values = s;
1230
1231 while (vl!=NULL) {
1232 pos++;
1233 name = NamePointer(vl);
1234 expr = GetSingleExpr(values);
1235 instances = FindInstances(fm->i,name,&err);
1236 if (instances == NULL){
1237 switch (err) {
1238 case unmade_instance:
1239 fm->ErrNo = Proc_instance_not_found;
1240 break;
1241 case undefined_instance:
1242 fm->ErrNo = Proc_name_not_found;
1243 break;
1244 case impossible_instance:
1245 fm->ErrNo = Proc_illegal_name_use;
1246 break;
1247 case correct_instance:
1248 fm->ErrNo = Proc_CallError; /* move write to procio */
1249 break;
1250 }
1251 } else {
1252 if (gl_length(instances)==1) {
1253 inst = (struct Instance *)gl_fetch(instances,1);
1254 gl_destroy(instances);
1255 if (!AtomAssigned(inst)) {
1256 fm->ErrNo = Proc_case_undefined_value;
1257 break;
1258 }
1259 switch(ExprType(expr)) {
1260 case e_boolean:
1261 if ((InstanceKind(inst) & IBOOL) == 0) {
1262 fm->ErrNo = Proc_case_boolean_mismatch;
1263 break;
1264 }
1265 val = ExprBValue(expr);
1266 if (val == 2) { /* ANY */
1267 break;
1268 }
1269 valvar = GetBooleanAtomValue(inst);
1270 if (val != valvar) {
1271 fm->ErrNo = Proc_case_unmatched;
1272 }
1273 break;
1274 case e_int:
1275 if ((InstanceKind(inst) & IINT) == 0) {
1276 fm->ErrNo = Proc_case_integer_mismatch;
1277 break;
1278 }
1279 val = ExprIValue(expr);
1280 valvar = GetIntegerAtomValue(inst);
1281 if (val != valvar) {
1282 fm->ErrNo = Proc_case_unmatched;
1283 }
1284 break;
1285 case e_symbol:
1286 if ((InstanceKind(inst) & ISYM) == 0) {
1287 fm->ErrNo = Proc_case_symbol_mismatch;
1288 break;
1289 }
1290 symvar = ExprSymValue(expr);
1291 value = GetSymbolAtomValue(inst);
1292 assert(AscFindSymbol(symvar)!=NULL);
1293 assert(AscFindSymbol(value)!=NULL);
1294 if (symvar != value) {
1295 fm->ErrNo = Proc_case_unmatched;
1296 }
1297 break;
1298 case e_var:
1299 /* evar ok only if a loop index? */
1300 if ((GetEvaluationForTable() != NULL) &&
1301 (NULL != (str = SimpleNameIdPtr(ExprName(expr)))) &&
1302 (NULL != (fvp=FindForVar(GetEvaluationForTable(),str)))) {
1303 switch (GetForKind(fvp)) {
1304 case f_integer:
1305 if ((InstanceKind(inst) & IINT) == 0) {
1306 fm->ErrNo = Proc_case_integer_mismatch;
1307 break;
1308 }
1309 val = GetForInteger(fvp);
1310 valvar = GetIntegerAtomValue(inst);
1311 if (val != valvar) {
1312 fm->ErrNo = Proc_case_unmatched;
1313 }
1314 break;
1315 case f_symbol:
1316 if ((InstanceKind(inst) & ISYM) == 0) {
1317 fm->ErrNo = Proc_case_symbol_mismatch;
1318 break;
1319 }
1320 symvar = GetForSymbol(fvp);
1321 value = GetSymbolAtomValue(inst);
1322 if (symvar != value) {
1323 fm->ErrNo = Proc_case_unmatched;
1324 }
1325 break;
1326 default:
1327 fm->ErrNo = Proc_case_wrong_index;
1328 break;
1329 }
1330 } else {
1331 fm->ErrNo = Proc_case_wrong_index;
1332 }
1333 break;
1334 default:
1335 fm->ErrNo = Proc_case_wrong_value;
1336 }
1337 } else {
1338 gl_destroy(instances);
1339 fm->ErrNo = Proc_case_extra_values;
1340 }
1341 }
1342 if (fm->ErrNo != Proc_case_matched) {
1343 break;
1344 }
1345 vl = NextVariableNode(vl);
1346 values = NextSet(values);
1347 }
1348 if (fm->ErrNo != Proc_case_matched && fm->ErrNo != Proc_case_unmatched) {
1349 ProcWriteCaseError(fm,arm,pos);
1350 fm->flow = FrameError;
1351 }
1352 return;
1353 }
1354
1355 /* This function will determine which case of a SWITCH statement
1356 * applies for the current values of the switching variables.
1357 * this function will call for the execution of the cases which
1358 * match. It handles OTHERWISE properly (case when set == NULL).
1359 */
1360
1361 static
1362 void ExecuteInitSwitch(struct procFrame *fm, struct Statement *stat)
1363 {
1364 struct VariableList *vlist;
1365 struct SwitchList *sw;
1366 struct Set *set;
1367 struct StatementList *sl;
1368 int arm;
1369 int case_match;
1370 int fallthru;
1371 enum FrameControl oldflow;
1372
1373 vlist = SwitchStatVL(stat);
1374 sw = SwitchStatCases(stat);
1375 case_match = 0;
1376
1377 arm = 0;
1378 oldflow = fm->flow;
1379 while (sw!=NULL) { /* && notbreak. fixme */
1380 arm++;
1381 set = SwitchSetList(sw);
1382 sl = SwitchStatementList(sw);
1383 if (set != NULL) {
1384 AnalyzeSwitchCase(fm,vlist,set,arm); /*add fallthru arg */
1385 switch (fm->ErrNo) {
1386 case Proc_case_matched:
1387 case_match++;
1388 /* could put fallthru handling here if in grammar */
1389 fm->ErrNo = Proc_all_ok;
1390 fm->flow = FrameLoop;
1391 ExecuteInitStatements(fm,sl);
1392 switch (fm->flow) {
1393 case FrameLoop:
1394 case FrameOK:
1395 fm->flow = oldflow;
1396 fallthru = 0;
1397 break;
1398 case FrameReturn:
1399 return;
1400 case FrameBreak: /* not properly implemented. fixme */
1401 fallthru = 0;
1402 break;
1403 case FrameContinue:
1404 if (oldflow == FrameLoop) {
1405 return;
1406 }
1407 break;
1408 case FrameFallthru: /* not implemented */
1409 fallthru = 1;
1410 case FrameError: /* EISS not supposed to return this */
1411 default:
1412 break;
1413 }
1414 break;
1415 case Proc_case_unmatched:
1416 break;
1417 default:
1418 /* fixme policy might suppress error return */
1419 fm->flow = FrameError;
1420 return;
1421 }
1422 } else {
1423 /* OTHERWISE arm, which we seem to be assuming comes last */
1424 if (!case_match) {
1425 AnalyzeSwitchCase(fm,vlist,NULL,-1);
1426 if (fm->ErrNo == Proc_case_matched) {
1427 fm->ErrNo = Proc_all_ok;
1428 ExecuteInitStatements(fm,sl);
1429 case_match = 1;
1430 if (fm->ErrNo != Proc_all_ok) {
1431 /* fixme logic */
1432 WriteInitErr(fm,"Error in execution of SWITCH statements\n");
1433 break;
1434 }
1435 }
1436 }
1437 }
1438 sw = NextSwitchCase(sw);
1439 }
1440 if (case_match == 0) {
1441 WriteInitWarn(fm,"No case matched in SWITCH statement\n");
1442 }
1443 return;
1444 }
1445
1446 /* i is generally NOT fm->i, but in the scope of fm->i */
1447 static
1448 void AssignInitValue(struct Instance *i, struct value_t v, struct procFrame *fm)
1449 {
1450 CONST dim_type *dim;
1451 int assignerr = 1; /* set 0 on success */
1452 switch(InstanceKind(i)) {
1453 case MODEL_INST:
1454 case ARRAY_INT_INST:
1455 case ARRAY_ENUM_INST:
1456 case REL_INST:
1457 fm->ErrNo = Proc_nonatom_assignment;
1458 fm->flow = FrameError;
1459 break;
1460 case DUMMY_INST:
1461 /* cpp string concatenation */
1462 assignerr = 0;
1463 WriteInitWarn(fm,"Assignment to an unSELECTed_part ignored."
1464 "SELECT should be shadowed by SWITCH in METHODS");
1465 break;
1466 case INTEGER_INST:
1467 case INTEGER_ATOM_INST:
1468 if (ValueKind(v)!=integer_value){
1469 fm->ErrNo = Proc_noninteger_assignment;
1470 fm->flow = FrameError;
1471 } else {
1472 assignerr = 0;
1473 SetIntegerAtomValue(i,IntegerValue(v),0);
1474 }
1475 break;
1476 case SET_INST:
1477 case SET_ATOM_INST:
1478 case REAL_CONSTANT_INST:
1479 case BOOLEAN_CONSTANT_INST:
1480 case INTEGER_CONSTANT_INST:
1481 case SYMBOL_CONSTANT_INST:
1482 fm->ErrNo = Proc_declarative_constant_assignment;
1483 fm->flow = FrameError;
1484 break;
1485 case REAL_INST:
1486 case REAL_ATOM_INST:
1487 switch(ValueKind(v)){
1488 case real_value:
1489 dim = CheckDimensionsMatch(RealValueDimensions(v),RealAtomDims(i));
1490 if (dim==NULL){
1491 PrintDimenMessage("Inconsistent units in assignment"
1492 ,"LHS",RealAtomDims(i)
1493 ,"RHS",RealValueDimensions(v)
1494 );
1495 fm->ErrNo = Proc_nonconsistent_assignment;
1496 fm->flow = FrameError;
1497 } else {
1498 assignerr = 0;
1499 if (dim!=RealAtomDims(i)) {
1500 SetRealAtomDims(i,dim);
1501 }
1502 SetRealAtomValue(i,RealValue(v),0);
1503 }
1504 break;
1505 case integer_value:
1506 dim = CheckDimensionsMatch(Dimensionless(),RealAtomDims(i));
1507 if (dim==NULL){
1508 PrintDimenMessage("Inconsistent units in assignment"
1509 ,"LHS",RealAtomDims(i)
1510 ,"RHS",RealValueDimensions(v)
1511 );
1512 fm->ErrNo = Proc_nonconsistent_assignment;
1513 fm->flow = FrameError;
1514 } else {
1515 assignerr = 0;
1516 if (dim != RealAtomDims(i)) {
1517 SetRealAtomDims(i,dim);
1518 }
1519 SetRealAtomValue(i,(double)IntegerValue(v),0);
1520 }
1521 break;
1522 default:
1523 fm->ErrNo = Proc_nonreal_assignment;
1524 fm->flow = FrameError;
1525 break;
1526 }
1527 break;
1528 case BOOLEAN_INST:
1529 case BOOLEAN_ATOM_INST:
1530 if (ValueKind(v)!=boolean_value){
1531 fm->ErrNo = Proc_nonboolean_assignment;
1532 fm->flow = FrameError;
1533 } else {
1534 assignerr = 0;
1535 SetBooleanAtomValue(i,BooleanValue(v),0);
1536 }
1537 break;
1538 case SYMBOL_INST:
1539 case SYMBOL_ATOM_INST:
1540 if (ValueKind(v)!=symbol_value){
1541 fm->ErrNo = Proc_nonsymbol_assignment;
1542 fm->flow = FrameError;
1543 } else {
1544 assignerr = 0;
1545 SetSymbolAtomValue(i,SymbolValue(v));
1546 }
1547 break;
1548 default:
1549 fm->ErrNo = Proc_nonsense_assignment;
1550 fm->flow = FrameError;
1551 break;
1552 }
1553 if (assignerr) {
1554 ProcWriteAssignmentError(fm);
1555 }
1556 }
1557
1558 /* this function always returns ok. 5/96 */
1559 static
1560 void ExecuteInitAsgn(struct procFrame *fm, struct Statement *stat)
1561 {
1562 struct gl_list_t *instances;
1563 struct Instance *inst;
1564 unsigned c,len;
1565 enum FrameControl oldflow;
1566 struct value_t value;
1567 enum find_errors err;
1568
1569 instances = FindInstances(fm->i,DefaultStatVar(stat),&err);
1570 if (instances != NULL){
1571 assert(GetEvaluationContext()==NULL);
1572 SetEvaluationContext(fm->i);
1573 value = EvaluateExpr(DefaultStatRHS(stat),NULL,InstanceEvaluateName);
1574 SetEvaluationContext(NULL);
1575 if (ValueKind(value)==error_value) {
1576 fm->ErrNo = Proc_rhs_error;
1577 fm->flow = FrameError;
1578 ProcWriteAssignmentError(fm);
1579 } else {
1580 len = gl_length(instances);
1581 oldflow = fm->flow;
1582 for(c=1;c<=len;c++){
1583 inst = (struct Instance *)gl_fetch(instances,c);
1584 AssignInitValue(inst,value,fm); /* does its own errors */
1585 if (fm->flow == FrameError) {
1586 if (/* fm->policy-check */0) {
1587 fm->flow = oldflow; /* suppress error flow */
1588 } else {
1589 break; /* skip rest of loop */
1590 }
1591 }
1592 }
1593 }
1594 DestroyValue(&value);
1595 gl_destroy(instances);
1596 } else {
1597 /* error finding left hand side */
1598 fm->ErrNo = Proc_lhs_error;
1599 fm->flow = FrameError;
1600 ProcWriteAssignmentError(fm);
1601 }
1602 return /* Proc_all_ok */;
1603 }
1604
1605 static
1606 void ExecuteInitStatement(struct procFrame *fm, struct Statement *stat)
1607 {
1608 #if IDB
1609 FPRINTF(fm->err,"\n");
1610 FPRINTF(fm->err,"EIS-IN: %s\n",FrameControlToString(fm->flow));
1611 FPRINTF(fm->err,"EIS: "); WriteStatement(fm->err,stat,2);
1612 #endif
1613 switch(StatementType(stat)){
1614 case FOR:
1615 ExecuteInitFor(fm,stat);
1616 break;
1617 case ASGN:
1618 ExecuteInitAsgn(fm,stat);
1619 break;
1620 case RUN:
1621 ExecuteInitRun(fm,stat);
1622 break;
1623 case FIX:
1624 ExecuteInitFix(fm,stat);
1625 break;
1626 case FREE:
1627 ExecuteInitFree(fm,stat);
1628 break;
1629 case SOLVER:
1630 ExecuteInitSolver(fm,stat);
1631 break;
1632 case OPTION:
1633 ExecuteInitOption(fm,stat);
1634 break;
1635 case SOLVE:
1636 ExecuteInitSolve(fm,stat);
1637 break;
1638 case FLOW:
1639 ExecuteInitFlow(fm);
1640 break;
1641 case EXT:
1642 /* CONSOLE_DEBUG("ABOUT TO ExecuteInitExt"); */
1643 ExecuteInitExt(fm,stat);
1644 break;
1645 case CALL:
1646 ExecuteInitCall(fm,stat);
1647 break;
1648 case WHILE:
1649 ExecuteInitWhile(fm,stat);
1650 break;
1651 case ASSERT:
1652 ExecuteInitAssert(fm,stat);
1653 break;
1654 case IF:
1655 ExecuteInitIf(fm,stat);
1656 break;
1657 case SWITCH:
1658 ExecuteInitSwitch(fm,stat);
1659 break;
1660 case CASGN:
1661 fm->flow = FrameError;
1662 fm->ErrNo = Proc_declarative_constant_assignment;
1663 WriteInitErr(fm,
1664 "Incorrect statement type (constant assigned)"
1665 " in initialization section");
1666 break;
1667 default:
1668 fm->flow = FrameError;
1669 fm->ErrNo = Proc_bad_statement;
1670 WriteInitErr(fm,"Unexpected statement type in initialization section");
1671 break;
1672 }
1673 #if IDB
1674 FPRINTF(fm->err,"EIS-OUT: %s\n\n",FrameControlToString(fm->flow));
1675 #endif
1676 return;
1677 }
1678
1679 /* This is our central error handling logic control point.
1680 * This function should not itself return fm->flow == FrameError.
1681 * To the maximum extent possible, do not process errors separately
1682 * elsewhere but defer them to here. That makes maintenance of code
1683 * which handles debugging output and execution logic much simpler.
1684 */
1685 static
1686 void ExecuteInitStatements(struct procFrame *fm, struct StatementList *sl)
1687 {
1688 unsigned c,length;
1689 struct gl_list_t *statements;
1690 struct Statement *stat;
1691 enum FrameControl oldflow;
1692 int stop;
1693
1694 statements = GetList(sl);
1695 length = gl_length(statements);
1696 stop = 0;
1697 oldflow = fm->flow;
1698 for (c = 1; c <= length && !stop; c++){
1699 stat = (struct Statement *)gl_fetch(statements,c);
1700 UpdateProcFrame(fm,stat,fm->i);
1701 /* statements should issue their own complaints */
1702 ExecuteInitStatement(fm,stat);
1703 switch (fm->flow) {
1704 case FrameLoop:
1705 case FrameOK:
1706 fm->flow = oldflow;
1707 break;
1708 case FrameError:
1709 #if IDB
1710 FPRINTF(fm->err,"ERR: "); WriteStatement(fm->err,fm->stat,0);
1711 FPRINTF(fm->err,"\n");
1712 #endif
1713 if ((fm->gen & WP_STOPONERR)!= 0) {
1714 fm->flow = FrameReturn;
1715 stop = 1;
1716 } else {
1717 fm->flow = oldflow;
1718 }
1719 break;
1720 case FrameFallthru: /* say what? */
1721 case FrameContinue:
1722 case FrameBreak:
1723 if (oldflow == FrameLoop) {
1724 stop = 1;
1725 } else {
1726 /* whine about missing loop/switch context.
1727 * should be parser enforced.
1728 */
1729 #if IDB
1730 FPRINTF(fm->err,"LOOP-ERR: "); WriteStatement(fm->err,fm->stat,0);
1731 FPRINTF(fm->err,"\n");
1732 #endif
1733 if ((fm->gen & WP_STOPONERR)!= 0) {
1734 fm->flow = FrameReturn;
1735 stop = 1;
1736 } else {
1737 fm->flow = oldflow;
1738 }
1739 }
1740 break;
1741 case FrameReturn:
1742 #if IDB
1743 FPRINTF(fm->err,"ERR-UNWIND: "); WriteStatement(fm->err,fm->stat,0);
1744 FPRINTF(fm->err,"\n");
1745 #endif
1746 if (/* i/o policy check */1) {
1747 /* whine backtrace*/
1748 }
1749 stop = 1;
1750 break;
1751 /* all cases must be handled here. */
1752 }
1753 if (g_procframe_stop) {
1754 g_procframe_stop = 0;
1755 fm->ErrNo = Proc_user_interrupt;
1756 WriteInitErr(fm,"USER interrupted METHOD execution");
1757 fm->flow = FrameReturn;
1758 stop = 1;
1759 }
1760 }
1761 /* UpdateProcFrame(fm,NULL, fm->i); */ /* leave a mess for messages */
1762 assert(fm->flow != FrameError);
1763 }
1764
1765 /*********************************************************************\
1766 * void ExecuteInitProcedure(i,proc)
1767 * struct Instance *i;
1768 * struct InitProcedure *proc;
1769 * This will execute proc on the instance i.
1770 \*********************************************************************/
1771 /*
1772 * Here's where we enforce stack limits (approximately).
1773 * Here's where we unwind the stack in the event of an
1774 * early return.
1775 */
1776 static
1777 void ExecuteInitProcedure(struct procFrame *fm, struct InitProcedure *proc)
1778 {
1779 struct for_table_t *OldForTable;
1780
1781 g_proc.depth++;
1782 assert(fm != NULL && fm->i != NULL && proc != NULL);
1783 if (g_proc.depth > g_proc.limit) {
1784 g_proc.depth--;
1785 fm->ErrNo = Proc_stack_exceeded_this_frame;
1786 fm->flow = FrameError;
1787 return;
1788 }
1789
1790 OldForTable = GetEvaluationForTable();
1791 SetEvaluationForTable(CreateForTable());
1792 ExecuteInitStatements(fm,ProcStatementList(proc));
1793 DestroyForTable(GetEvaluationForTable());
1794 SetEvaluationForTable(OldForTable);
1795 g_proc.depth--;
1796 }
1797
1798 /* returns overflow or ok. possibly either form of overflow. */
1799 static
1800 void RealInitialize(struct procFrame *fm, struct Name *name)
1801 {
1802 struct Name *instname = NULL;
1803 struct Instance *ptr;
1804 enum find_errors err;
1805 struct InitProcedure *proc;
1806 struct gl_list_t *instances;
1807 unsigned long c,length;
1808 char *morename;
1809 struct procFrame *newfm;
1810 symchar *procname=NULL;
1811 int stop;
1812 int previous_context = GetDeclarativeContext();
1813
1814 morename = WriteNameString(name);
1815 #ifdef INIT_DEBUG
1816 char *name1 = WriteInstanceNameString(fm->i,NULL);
1817 CONSOLE_DEBUG("Running METHOD %s on '%s'",SCP(fm->cname),name1);
1818 ASC_FREE(name1);
1819 #endif
1820 ASC_FREE(morename);
1821
1822 SetDeclarativeContext(1); /* set up for procedural processing */
1823 InstanceNamePart(name,&instname,&procname);
1824
1825 if (procname != NULL) {
1826 instances = FindInstances(fm->i, instname, &err);
1827 if (instances != NULL) {
1828 length = gl_length(instances);
1829 stop = 0;
1830 for(c=1; c<=length && !stop; c++){
1831 ptr = (struct Instance *)gl_fetch(instances,c);
1832 proc = FindProcedure(ptr,procname);
1833 if (proc != NULL) {
1834 morename = WriteInstanceNameString(ptr,fm->i);
1835 newfm = AddProcFrame(fm,ptr,
1836 (morename!=NULL)?morename:"",
1837 proc,FrameInherit);
1838 /* this usage probably force memory recycle in proctype.c */
1839 if (morename != NULL) {
1840 ascfree(morename);
1841 }
1842 ExecuteInitProcedure(newfm,proc);
1843 switch (newfm->flow) {
1844 case FrameOK:
1845 case FrameLoop:
1846 /* do nothing */
1847 break;
1848 case FrameBreak:
1849 case FrameContinue:
1850 case FrameFallthru:
1851 /* aren't supposed to work across frames, or are they? */
1852 /* do nothing */
1853 break;
1854 case FrameError:
1855 /* having to check this here sucks, but the stack
1856 * limit is not optional.
1857 */
1858 if ((fm->gen & WP_STOPONERR) != 0 || /* ||, not && */
1859 newfm->ErrNo == Proc_stack_exceeded_this_frame) {
1860 fm->flow = newfm->flow;
1861 fm->ErrNo = newfm->ErrNo;
1862 if (fm->ErrNo == Proc_stack_exceeded_this_frame) {
1863 fm->ErrNo = Proc_stack_exceeded;
1864 }
1865 stop = 1;
1866 }
1867 ProcWriteStackCheck(newfm,NULL,name);
1868 break;
1869 case FrameReturn:
1870 if (newfm->ErrNo != Proc_return) {
1871 fm->flow = newfm->flow;
1872 fm->ErrNo = newfm->ErrNo;
1873 ProcWriteStackCheck(newfm,NULL,name);
1874 } /* else was a c-like RETURN;. don't pass upward */
1875 break;
1876 }
1877 DestroyProcFrame(newfm);
1878 } else {
1879 fm->flow = FrameError;
1880 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"PROCEDURE NOT FOUND (FindProcedure failed).");
1881 fm->ErrNo = Proc_proc_not_found;
1882 }
1883 }
1884 gl_destroy(instances);
1885 } else { /* unable to find instances */
1886 fm->flow = FrameError;
1887 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"PROCEDURE NOT FOUND (FindInstances failed).");
1888 fm->ErrNo = Proc_instance_not_found;
1889 }
1890 } else {
1891 CONSOLE_DEBUG("BAD PROC NAME");
1892 fm->flow = FrameError;
1893 fm->ErrNo = Proc_bad_name;
1894 }
1895 SetDeclarativeContext(previous_context);
1896 DestroyName(instname);
1897 return;
1898 }
1899
1900 /* Convert all those messy result to a proc enum for UI consumption. */
1901 static
1902 enum Proc_enum InitCalcReturn(struct procFrame *fm)
1903 {
1904 switch(fm->flow) {
1905 case FrameOK:
1906 return Proc_all_ok;
1907 case FrameReturn: /* FALLTHROUGH */
1908 case FrameError:
1909 /* whine */
1910 return fm->ErrNo;
1911 case FrameLoop:
1912 /* whine a lot */
1913 case FrameContinue:
1914 return Proc_continue;
1915 case FrameBreak:
1916 return Proc_break;
1917 case FrameFallthru:
1918 return Proc_fallthru;
1919 /* all must be handled in this switch */
1920 }
1921 return -1;
1922 }
1923
1924 /* internal debug head */
1925 static
1926 enum Proc_enum DebugInitialize(struct Instance *context,
1927 struct Name *name,
1928 CONST char *cname,
1929 FILE *err,
1930 wpflags options,
1931 struct gl_list_t *watchpoints,
1932 FILE *log,
1933 struct procFrame *fm)
1934 {
1935 struct procDebug dbi; /* this struct is huge */
1936
1937 CONSOLE_DEBUG("RUNNING METHOD IN DEBUG MODE...");
1938 InitDebugTopProcFrame(fm,context,cname,err,options,&dbi,watchpoints,log);
1939 RealInitialize(fm,name);
1940 return InitCalcReturn(fm);
1941 }
1942
1943 /* internal normal head */
1944 static
1945 enum Proc_enum NormalInitialize(struct procFrame *fm, struct Name *name)
1946 {
1947 RealInitialize(fm,name);
1948 return InitCalcReturn(fm);
1949 }
1950
1951 enum Proc_enum Initialize(struct Instance *context,
1952 struct Name *name,
1953 CONST char *cname,
1954 FILE *err,
1955 wpflags options,
1956 struct gl_list_t *watchpoints,
1957 FILE *log)
1958 {
1959 enum Proc_enum rval;
1960 struct procFrame fm;
1961
1962 #ifdef INIT_DEBUG
1963 char *instname = WriteInstanceNameString(context,NULL);
1964 const char *insttype =
1965 InstanceKind(context)==SIM_INST ? "SIM_INST" :(
1966 InstanceKind(context)==MODEL_INST ? "MODEL_INST" : (
1967 "UNRECOGNIZED-TYPE"));
1968 CONSOLE_DEBUG("Running method '%s' on %s '%s'...",cname,insttype,instname);
1969 ASC_FREE(instname);
1970 #endif
1971
1972 assert(err != NULL);
1973 g_proc.depth = 0;
1974 Asc_SetMethodUserInterrupt(0);
1975 if (watchpoints == NULL) {
1976 InitNormalTopProcFrame(&fm,context,cname,err,options);
1977 rval = NormalInitialize(&fm,name);
1978 } else {
1979 CONSOLE_DEBUG("Running method with debug...");
1980 rval = DebugInitialize(context,name,cname,err,options,watchpoints,log,&fm);
1981 }
1982 return rval;
1983 }
1984
1985 /*
1986 * This deals with initializations of the form:
1987 * RUN Type::procname; where Type is model or atom type,
1988 * and procname is a procedure defined within that type.
1989 * If the Type happened to have redefined a procedure from its
1990 * parent class, that procedure would be the one on its
1991 * procedure list and hence the one that would be invoked.
1992 *
1993 */
1994 static
1995 void ClassAccessRealInitialize(struct procFrame *fm,
1996 struct Name *class,
1997 struct Name *name)
1998 {
1999 struct InitProcedure *proc;
2000 struct procFrame *newfm;
2001 struct gl_list_t *plist;
2002 symchar *procname;
2003 symchar *typename;
2004 struct TypeDescription *desc,*conformable;
2005 int previous_context = GetDeclarativeContext();
2006
2007 SetDeclarativeContext(1); /* set up for procedural processing */
2008
2009 typename = SimpleNameIdPtr(class);
2010 if (typename != NULL) {
2011 desc = FindType(typename);
2012 if (desc != NULL) {
2013 conformable = InstanceTypeDesc(fm->i);
2014 if (MoreRefined(conformable,desc)) {
2015 plist = GetInitializationList(desc);
2016 if (plist != NULL) {
2017 procname = SimpleNameIdPtr(name);
2018 if (procname != NULL) {
2019 proc = SearchProcList(plist,procname);
2020 if (proc == NULL) {
2021 proc = SearchProcList(GetUniversalProcedureList(),procname);
2022 }
2023 if (proc != NULL) {
2024 newfm = AddProcFrame(fm,fm->i,"",proc,FrameInherit);
2025 /* apf starts newfm with frameok */
2026 ExecuteInitProcedure(newfm,proc);
2027 switch (newfm->flow) {
2028 case FrameOK:
2029 case FrameLoop:
2030 /* do nothing */
2031 break;
2032 case FrameBreak:
2033 case FrameContinue:
2034 case FrameFallthru:
2035 /* aren't supposed to work across frames are they? */
2036 /* do nothing */
2037 break;
2038 case FrameError:
2039 fm->flow = newfm->flow;
2040 fm->ErrNo = newfm->ErrNo;
2041 ProcWriteStackCheck(newfm,class,name);
2042 /* having to check this here sucks, but the stack
2043 * limit is not optional.
2044 */
2045 if (fm->ErrNo == Proc_stack_exceeded_this_frame) {
2046 fm->ErrNo = Proc_stack_exceeded;
2047 }
2048 break;
2049 case FrameReturn:
2050 if (newfm->ErrNo != Proc_return) {
2051 fm->flow = newfm->flow;
2052 fm->ErrNo = newfm->ErrNo;
2053 ProcWriteStackCheck(newfm,class,name); /* fixme?*/
2054 } /* else was a c-like RETURN;. don't pass upward */
2055 break;
2056 }
2057 DestroyProcFrame(newfm);
2058 } else {
2059 fm->flow = FrameError;
2060 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"PROCEDURE NOT FOUND (SearchProcList).");
2061 fm->ErrNo = Proc_proc_not_found;
2062 }
2063 } else {
2064 fm->flow = FrameError;
2065 fm->ErrNo = Proc_illegal_name_use;
2066 }
2067 } else {
2068 fm->flow = FrameError;
2069 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"PROCEDURE NOT FOUND (GetInitializationList is null).");
2070 fm->ErrNo = Proc_proc_not_found;
2071 }
2072 } else {
2073 fm->flow = FrameError;
2074 fm->ErrNo = Proc_illegal_type_use;
2075 }
2076 } else {
2077 fm->flow = FrameError;
2078 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"PROCEDURE NOT FOUND (FindType failed)\n");
2079 fm->ErrNo = Proc_type_not_found;
2080 }
2081 } else {
2082 fm->flow = FrameError;
2083 fm->ErrNo = Proc_illegal_name_use;
2084 }
2085
2086 SetDeclarativeContext(previous_context);
2087 return;
2088 }
2089
2090 /* internal debug head */
2091 static
2092 enum Proc_enum DebugClassAccessInitialize(struct Instance *context,
2093 struct Name *class,
2094 struct Name *name,
2095 CONST char *cname,
2096 FILE *err,
2097 wpflags options,
2098 struct gl_list_t *watchpoints,
2099 FILE *log,
2100 struct procFrame *fm)
2101 {
2102 struct procDebug dbi; /* this struct is huge */
2103
2104 InitDebugTopProcFrame(fm,context,cname,err,options,&dbi,watchpoints,log);
2105 ClassAccessRealInitialize(fm,class,name);
2106 return InitCalcReturn(fm);
2107 }
2108
2109 /* internal normal head */
2110 static
2111 enum Proc_enum NormalClassAccessInitialize(struct procFrame *fm,
2112 struct Name *class,
2113 struct Name *name)
2114 {
2115 ClassAccessRealInitialize(fm,class,name);
2116 return InitCalcReturn(fm);
2117 }
2118
2119 enum Proc_enum ClassAccessInitialize(struct Instance *context,
2120 struct Name *class,
2121 struct Name *name,
2122 char *cname,
2123 FILE *err,
2124 wpflags options,
2125 struct gl_list_t *watchpoints,
2126 FILE *log)
2127 {
2128 struct procFrame fm;
2129
2130 assert(err != NULL);
2131 g_proc.depth = 0;
2132 Asc_SetMethodUserInterrupt(0);
2133 if (watchpoints == NULL) {
2134 InitNormalTopProcFrame(&fm,context,cname,err,options);
2135 return NormalClassAccessInitialize(&fm,class,name);
2136 } else {
2137 return DebugClassAccessInitialize(context,class,name,cname,
2138 err,options,watchpoints,log,&fm);
2139 }
2140 }

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22