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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2219 - (show annotations) (download) (as text)
Tue Jul 20 13:03:40 2010 UTC (13 years, 11 months ago) by jpye
File MIME type: text/x-csrc
File size: 60118 byte(s)
Fixed misplaced ascfree in the execute_init_fix_or_free fn.
In debian/control, updated dependency name as for 10.04
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/utilities/ascConfig.h>
33 #include <ascend/utilities/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 CONSOLE_DEBUG("Assertion %s.",BooleanValue(value)?"OK":"failed");
875 if(BooleanValue(value)){
876 WriteStatementError(ASC_USER_SUCCESS,stat,0,"Assertion OK");
877 }else{
878 WriteStatementError(ASC_USER_ERROR,stat,1,"Assertion failed");
879 }
880 break;
881 case real_value:
882 fm->flow = FrameError;
883 fm->ErrNo = Proc_if_real_expr;
884 break;
885 case integer_value:
886 fm->flow = FrameError;
887 fm->ErrNo = Proc_if_integer_expr;
888 break;
889 case symbol_value:
890 fm->flow = FrameError;
891 fm->ErrNo = Proc_if_symbol_expr;
892 break;
893 case set_value: /* FALLTHROUGH */
894 case list_value:
895 fm->flow = FrameError;
896 fm->ErrNo = Proc_if_set_expr;
897 break;
898 case error_value:
899 fm->flow = FrameError;
900 fm->ErrNo = Proc_if_expr_error_confused;
901 switch (ErrorValue(value)) {
902 case type_conflict:
903 fm->ErrNo = Proc_if_expr_error_typeconflict;
904 break;
905 case name_unfound:
906 fm->ErrNo = Proc_if_expr_error_nameunfound;
907 break;
908 case incorrect_name:
909 fm->ErrNo = Proc_if_expr_error_incorrectname;
910 break;
911 case undefined_value:
912 fm->ErrNo = Proc_if_expr_error_undefinedvalue;
913 break;
914 case dimension_conflict:
915 fm->ErrNo = Proc_if_expr_error_dimensionconflict;
916 break;
917 case empty_choice:
918 fm->ErrNo = Proc_if_expr_error_emptychoice;
919 break;
920 case empty_intersection:
921 fm->ErrNo = Proc_if_expr_error_emptyintersection;
922 break;
923 default:
924 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unhandled case");
925 }
926 break;
927 default:
928 fm->flow = FrameError;
929 fm->ErrNo = Proc_if_not_logical;
930 break;
931 }
932 if (fm->flow == FrameError && testerr) {
933 ProcWriteIfError(fm,"TEST");
934 }
935 DestroyValue(&value);
936 return;
937 }
938
939 static
940 void ExecuteInitIf(struct procFrame *fm, struct Statement *stat)
941 {
942 struct value_t value;
943 int iferr;
944
945 assert(GetEvaluationContext()==NULL);
946 SetEvaluationContext(fm->i);
947 value = EvaluateExpr(IfStatExpr(stat),NULL,InstanceEvaluateName);
948 SetEvaluationContext(NULL);
949 iferr = 1; /* set 0 on success */
950 switch(ValueKind(value)){
951 case boolean_value:
952 iferr = 0;
953 if (BooleanValue(value)) {
954 ExecuteInitStatements(fm,IfStatThen(stat));
955 } else {
956 if (IfStatElse(stat) != NULL) {
957 ExecuteInitStatements(fm,IfStatElse(stat));
958 }
959 }
960 break;
961 case real_value:
962 fm->flow = FrameError;
963 fm->ErrNo = Proc_if_real_expr;
964 break;
965 case integer_value:
966 fm->flow = FrameError;
967 fm->ErrNo = Proc_if_integer_expr;
968 break;
969 case symbol_value:
970 fm->flow = FrameError;
971 fm->ErrNo = Proc_if_symbol_expr;
972 break;
973 case set_value: /* FALLTHROUGH */
974 case list_value:
975 fm->flow = FrameError;
976 fm->ErrNo = Proc_if_set_expr;
977 break;
978 case error_value:
979 fm->flow = FrameError;
980 fm->ErrNo = Proc_if_expr_error_confused;
981 switch (ErrorValue(value)) {
982 case type_conflict:
983 fm->ErrNo = Proc_if_expr_error_typeconflict;
984 break;
985 case name_unfound:
986 fm->ErrNo = Proc_if_expr_error_nameunfound;
987 break;
988 case incorrect_name:
989 fm->ErrNo = Proc_if_expr_error_incorrectname;
990 break;
991 case undefined_value:
992 fm->ErrNo = Proc_if_expr_error_undefinedvalue;
993 break;
994 case dimension_conflict:
995 fm->ErrNo = Proc_if_expr_error_dimensionconflict;
996 break;
997 case empty_choice:
998 fm->ErrNo = Proc_if_expr_error_emptychoice;
999 break;
1000 case empty_intersection:
1001 fm->ErrNo = Proc_if_expr_error_emptyintersection;
1002 break;
1003 default:
1004 break;
1005 }
1006 break;
1007 default:
1008 fm->flow = FrameError;
1009 fm->ErrNo = Proc_if_not_logical;
1010 break;
1011 }
1012 if (fm->flow == FrameError && iferr) {
1013 ProcWriteIfError(fm,"IF");
1014 }
1015 DestroyValue(&value);
1016 return;
1017 }
1018
1019 /*
1020 */
1021 static
1022 void ExecuteInitWhile(struct procFrame *fm, struct Statement *stat)
1023 {
1024 struct value_t value;
1025 int iferr;
1026 int stop;
1027 long limit = WP_MAXTRIPS;
1028 enum FrameControl oldflow;
1029
1030 assert(GetEvaluationContext()==NULL);
1031 stop = 0;
1032 oldflow = fm->flow;
1033 fm->flow = FrameLoop;
1034 while (!stop) {
1035 assert(fm->flow == FrameLoop);
1036 SetEvaluationContext(fm->i);
1037 value = EvaluateExpr(WhileStatExpr(stat),NULL,InstanceEvaluateName);
1038 SetEvaluationContext(NULL);
1039 iferr = 1; /* set 0 on success */
1040 limit--;
1041 switch(ValueKind(value)){
1042 case boolean_value:
1043 iferr = 0;
1044 if (BooleanValue(value)) {
1045 ExecuteInitStatements(fm,WhileStatBlock(stat));
1046 switch (fm->flow) {
1047 case FrameOK:
1048 case FrameContinue:
1049 fm->flow = FrameLoop;
1050 break;
1051 case FrameLoop:
1052 break;
1053 case FrameBreak: /* break while loop only */
1054 case FrameFallthru: /* while must be inside switch...*/
1055 case FrameReturn:
1056 stop = 1;
1057 break;
1058 case FrameError: /* EISS is not supposed to let this happen */
1059 default: /* should never happen */
1060 #if IDB
1061 FPRINTF(fm->err,"ERR-NEVER3: "); WriteStatement(fm->err,stat,0);
1062 FPRINTF(fm->err,"\n");
1063 #endif
1064 fm->flow = FrameReturn;
1065 break;
1066 }
1067 } else {
1068 stop = 1;
1069 }
1070 break;
1071 case real_value:
1072 fm->flow = FrameError;
1073 fm->ErrNo = Proc_if_real_expr;
1074 break;
1075 case integer_value:
1076 fm->flow = FrameError;
1077 fm->ErrNo = Proc_if_integer_expr;
1078 break;
1079 case symbol_value:
1080 fm->flow = FrameError;
1081 fm->ErrNo = Proc_if_symbol_expr;
1082 break;
1083 case set_value: /* FALLTHROUGH */
1084 case list_value:
1085 fm->flow = FrameError;
1086 fm->ErrNo = Proc_if_set_expr;
1087 break;
1088 case error_value:
1089 fm->flow = FrameError;
1090 fm->ErrNo = Proc_if_expr_error_confused;
1091 switch (ErrorValue(value)) {
1092 case type_conflict:
1093 fm->ErrNo = Proc_if_expr_error_typeconflict;
1094 break;
1095 case name_unfound:
1096 fm->ErrNo = Proc_if_expr_error_nameunfound;
1097 break;
1098 case incorrect_name:
1099 fm->ErrNo = Proc_if_expr_error_incorrectname;
1100 break;
1101 case undefined_value:
1102 fm->ErrNo = Proc_if_expr_error_undefinedvalue;
1103 break;
1104 case dimension_conflict:
1105 fm->ErrNo = Proc_if_expr_error_dimensionconflict;
1106 break;
1107 case empty_choice:
1108 fm->ErrNo = Proc_if_expr_error_emptychoice;
1109 break;
1110 case empty_intersection:
1111 fm->ErrNo = Proc_if_expr_error_emptyintersection;
1112 break;
1113 default:
1114 break;
1115 }
1116 break;
1117 default:
1118 fm->flow = FrameError;
1119 fm->ErrNo = Proc_if_not_logical;
1120 break;
1121 }
1122 if (fm->flow == FrameError && iferr) {
1123 ProcWriteIfError(fm,"WHILE");
1124 }
1125 DestroyValue(&value);
1126 if (limit < 0) {
1127 stop = 1;
1128 fm->flow = FrameError;
1129 fm->ErrNo = Proc_infinite_loop;
1130 ProcWriteIfError(fm,"WHILE");
1131 }
1132 } /* endwhile */
1133 /* post loop processing */
1134 switch (fm->flow) {
1135 case FrameLoop:
1136 case FrameBreak:
1137 fm->flow = oldflow;
1138 break;
1139 default: /* let return, fallthru, out to next scope */
1140 break;
1141 }
1142 return;
1143 }
1144
1145
1146 /*
1147 * Compare current values of the switching variables with
1148 * the set of values in a CASE of a SWITCH statement, and try to find
1149 * is such values are the same.
1150 * If they are, the function will return Proc_case_matched,
1151 * else, it will return Proc_case_unmatched unless there is an error.
1152 * The possible error returns are legion, and this function
1153 * handles issuing error messages for them.
1154 *
1155 * If s given is NULL AND arm is -1, simply verifies that vlist elements
1156 * exist/are assigned. Normally this is only of use in checking
1157 * the OTHERWISE branch of the switch.
1158 * s must NOT be NULL unless arm is -1.
1159 */
1160 static
1161 void AnalyzeSwitchCase(struct procFrame *fm, struct VariableList *vlist,
1162 struct Set *s, int arm)
1163 {
1164 CONST struct Expr *expr;
1165 CONST struct Name *name;
1166 symchar *value;
1167 symchar *symvar;
1168 CONST struct VariableList *vl;
1169 CONST struct Set *values;
1170 int val;
1171 int pos;
1172 int valvar;
1173 struct gl_list_t *instances;
1174 struct Instance *inst;
1175 enum find_errors err;
1176 symchar *str;
1177 struct for_var_t *fvp;
1178
1179 assert(vlist != NULL);
1180 vl = vlist;
1181 fm->ErrNo = Proc_case_matched;
1182 pos = 0;
1183 if (s==NULL && arm == -1) {
1184 /* check vlist only */
1185 while (vl!=NULL) {
1186 pos++;
1187 name = NamePointer(vl);
1188 instances = FindInstances(fm->i,name,&err);
1189 if (instances == NULL){
1190 switch (err) {
1191 case unmade_instance:
1192 fm->ErrNo = Proc_instance_not_found;
1193 break;
1194 case undefined_instance:
1195 fm->ErrNo = Proc_name_not_found;
1196 break;
1197 case impossible_instance:
1198 fm->ErrNo = Proc_illegal_name_use;
1199 break;
1200 case correct_instance:
1201 fm->ErrNo = Proc_CallError;
1202 break;
1203 }
1204 }
1205 if (gl_length(instances)==1) {
1206 inst = (struct Instance *)gl_fetch(instances,1);
1207 gl_destroy(instances);
1208 if (!AtomAssigned(inst)) {
1209 fm->ErrNo = Proc_case_undefined_value;
1210 break; /* while */
1211 }
1212 } else {
1213 fm->ErrNo = Proc_case_extra_values;
1214 gl_destroy(instances);
1215 break; /* while */
1216 }
1217 vl = NextVariableNode(vl);
1218 }
1219 if (fm->ErrNo != Proc_case_matched) {
1220 ProcWriteCaseError(fm,arm,pos);
1221 }
1222 fm->flow = FrameError;
1223 return;
1224 }
1225
1226 assert(s!= NULL);
1227 values = s;
1228
1229 while (vl!=NULL) {
1230 pos++;
1231 name = NamePointer(vl);
1232 expr = GetSingleExpr(values);
1233 instances = FindInstances(fm->i,name,&err);
1234 if (instances == NULL){
1235 switch (err) {
1236 case unmade_instance:
1237 fm->ErrNo = Proc_instance_not_found;
1238 break;
1239 case undefined_instance:
1240 fm->ErrNo = Proc_name_not_found;
1241 break;
1242 case impossible_instance:
1243 fm->ErrNo = Proc_illegal_name_use;
1244 break;
1245 case correct_instance:
1246 fm->ErrNo = Proc_CallError; /* move write to procio */
1247 break;
1248 }
1249 } else {
1250 if (gl_length(instances)==1) {
1251 inst = (struct Instance *)gl_fetch(instances,1);
1252 gl_destroy(instances);
1253 if (!AtomAssigned(inst)) {
1254 fm->ErrNo = Proc_case_undefined_value;
1255 break;
1256 }
1257 switch(ExprType(expr)) {
1258 case e_boolean:
1259 if ((InstanceKind(inst) & IBOOL) == 0) {
1260 fm->ErrNo = Proc_case_boolean_mismatch;
1261 break;
1262 }
1263 val = ExprBValue(expr);
1264 if (val == 2) { /* ANY */
1265 break;
1266 }
1267 valvar = GetBooleanAtomValue(inst);
1268 if (val != valvar) {
1269 fm->ErrNo = Proc_case_unmatched;
1270 }
1271 break;
1272 case e_int:
1273 if ((InstanceKind(inst) & IINT) == 0) {
1274 fm->ErrNo = Proc_case_integer_mismatch;
1275 break;
1276 }
1277 val = ExprIValue(expr);
1278 valvar = GetIntegerAtomValue(inst);
1279 if (val != valvar) {
1280 fm->ErrNo = Proc_case_unmatched;
1281 }
1282 break;
1283 case e_symbol:
1284 if ((InstanceKind(inst) & ISYM) == 0) {
1285 fm->ErrNo = Proc_case_symbol_mismatch;
1286 break;
1287 }
1288 symvar = ExprSymValue(expr);
1289 value = GetSymbolAtomValue(inst);
1290 assert(AscFindSymbol(symvar)!=NULL);
1291 assert(AscFindSymbol(value)!=NULL);
1292 if (symvar != value) {
1293 fm->ErrNo = Proc_case_unmatched;
1294 }
1295 break;
1296 case e_var:
1297 /* evar ok only if a loop index? */
1298 if ((GetEvaluationForTable() != NULL) &&
1299 (NULL != (str = SimpleNameIdPtr(ExprName(expr)))) &&
1300 (NULL != (fvp=FindForVar(GetEvaluationForTable(),str)))) {
1301 switch (GetForKind(fvp)) {
1302 case f_integer:
1303 if ((InstanceKind(inst) & IINT) == 0) {
1304 fm->ErrNo = Proc_case_integer_mismatch;
1305 break;
1306 }
1307 val = GetForInteger(fvp);
1308 valvar = GetIntegerAtomValue(inst);
1309 if (val != valvar) {
1310 fm->ErrNo = Proc_case_unmatched;
1311 }
1312 break;
1313 case f_symbol:
1314 if ((InstanceKind(inst) & ISYM) == 0) {
1315 fm->ErrNo = Proc_case_symbol_mismatch;
1316 break;
1317 }
1318 symvar = GetForSymbol(fvp);
1319 value = GetSymbolAtomValue(inst);
1320 if (symvar != value) {
1321 fm->ErrNo = Proc_case_unmatched;
1322 }
1323 break;
1324 default:
1325 fm->ErrNo = Proc_case_wrong_index;
1326 break;
1327 }
1328 } else {
1329 fm->ErrNo = Proc_case_wrong_index;
1330 }
1331 break;
1332 default:
1333 fm->ErrNo = Proc_case_wrong_value;
1334 }
1335 } else {
1336 gl_destroy(instances);
1337 fm->ErrNo = Proc_case_extra_values;
1338 }
1339 }
1340 if (fm->ErrNo != Proc_case_matched) {
1341 break;
1342 }
1343 vl = NextVariableNode(vl);
1344 values = NextSet(values);
1345 }
1346 if (fm->ErrNo != Proc_case_matched && fm->ErrNo != Proc_case_unmatched) {
1347 ProcWriteCaseError(fm,arm,pos);
1348 fm->flow = FrameError;
1349 }
1350 return;
1351 }
1352
1353 /* This function will determine which case of a SWITCH statement
1354 * applies for the current values of the switching variables.
1355 * this function will call for the execution of the cases which
1356 * match. It handles OTHERWISE properly (case when set == NULL).
1357 */
1358
1359 static
1360 void ExecuteInitSwitch(struct procFrame *fm, struct Statement *stat)
1361 {
1362 struct VariableList *vlist;
1363 struct SwitchList *sw;
1364 struct Set *set;
1365 struct StatementList *sl;
1366 int arm;
1367 int case_match;
1368 int fallthru;
1369 enum FrameControl oldflow;
1370
1371 vlist = SwitchStatVL(stat);
1372 sw = SwitchStatCases(stat);
1373 case_match = 0;
1374
1375 arm = 0;
1376 oldflow = fm->flow;
1377 while (sw!=NULL) { /* && notbreak. fixme */
1378 arm++;
1379 set = SwitchSetList(sw);
1380 sl = SwitchStatementList(sw);
1381 if (set != NULL) {
1382 AnalyzeSwitchCase(fm,vlist,set,arm); /*add fallthru arg */
1383 switch (fm->ErrNo) {
1384 case Proc_case_matched:
1385 case_match++;
1386 /* could put fallthru handling here if in grammar */
1387 fm->ErrNo = Proc_all_ok;
1388 fm->flow = FrameLoop;
1389 ExecuteInitStatements(fm,sl);
1390 switch (fm->flow) {
1391 case FrameLoop:
1392 case FrameOK:
1393 fm->flow = oldflow;
1394 fallthru = 0;
1395 break;
1396 case FrameReturn:
1397 return;
1398 case FrameBreak: /* not properly implemented. fixme */
1399 fallthru = 0;
1400 break;
1401 case FrameContinue:
1402 if (oldflow == FrameLoop) {
1403 return;
1404 }
1405 break;
1406 case FrameFallthru: /* not implemented */
1407 fallthru = 1;
1408 case FrameError: /* EISS not supposed to return this */
1409 default:
1410 break;
1411 }
1412 break;
1413 case Proc_case_unmatched:
1414 break;
1415 default:
1416 /* fixme policy might suppress error return */
1417 fm->flow = FrameError;
1418 return;
1419 }
1420 } else {
1421 /* OTHERWISE arm, which we seem to be assuming comes last */
1422 if (!case_match) {
1423 AnalyzeSwitchCase(fm,vlist,NULL,-1);
1424 if (fm->ErrNo == Proc_case_matched) {
1425 fm->ErrNo = Proc_all_ok;
1426 ExecuteInitStatements(fm,sl);
1427 case_match = 1;
1428 if (fm->ErrNo != Proc_all_ok) {
1429 /* fixme logic */
1430 WriteInitErr(fm,"Error in execution of SWITCH statements\n");
1431 break;
1432 }
1433 }
1434 }
1435 }
1436 sw = NextSwitchCase(sw);
1437 }
1438 if (case_match == 0) {
1439 WriteInitWarn(fm,"No case matched in SWITCH statement\n");
1440 }
1441 return;
1442 }
1443
1444 /* i is generally NOT fm->i, but in the scope of fm->i */
1445 static
1446 void AssignInitValue(struct Instance *i, struct value_t v, struct procFrame *fm)
1447 {
1448 CONST dim_type *dim;
1449 int assignerr = 1; /* set 0 on success */
1450 switch(InstanceKind(i)) {
1451 case MODEL_INST:
1452 case ARRAY_INT_INST:
1453 case ARRAY_ENUM_INST:
1454 case REL_INST:
1455 fm->ErrNo = Proc_nonatom_assignment;
1456 fm->flow = FrameError;
1457 break;
1458 case DUMMY_INST:
1459 /* cpp string concatenation */
1460 assignerr = 0;
1461 WriteInitWarn(fm,"Assignment to an unSELECTed_part ignored."
1462 "SELECT should be shadowed by SWITCH in METHODS");
1463 break;
1464 case INTEGER_INST:
1465 case INTEGER_ATOM_INST:
1466 if (ValueKind(v)!=integer_value){
1467 fm->ErrNo = Proc_noninteger_assignment;
1468 fm->flow = FrameError;
1469 } else {
1470 assignerr = 0;
1471 SetIntegerAtomValue(i,IntegerValue(v),0);
1472 }
1473 break;
1474 case SET_INST:
1475 case SET_ATOM_INST:
1476 case REAL_CONSTANT_INST:
1477 case BOOLEAN_CONSTANT_INST:
1478 case INTEGER_CONSTANT_INST:
1479 case SYMBOL_CONSTANT_INST:
1480 fm->ErrNo = Proc_declarative_constant_assignment;
1481 fm->flow = FrameError;
1482 break;
1483 case REAL_INST:
1484 case REAL_ATOM_INST:
1485 switch(ValueKind(v)){
1486 case real_value:
1487 dim = CheckDimensionsMatch(RealValueDimensions(v),RealAtomDims(i));
1488 if (dim==NULL){
1489 PrintDimenMessage("Inconsistent units in assignment"
1490 ,"LHS",RealAtomDims(i)
1491 ,"RHS",RealValueDimensions(v)
1492 );
1493 fm->ErrNo = Proc_nonconsistent_assignment;
1494 fm->flow = FrameError;
1495 } else {
1496 assignerr = 0;
1497 if (dim!=RealAtomDims(i)) {
1498 SetRealAtomDims(i,dim);
1499 }
1500 SetRealAtomValue(i,RealValue(v),0);
1501 }
1502 break;
1503 case integer_value:
1504 dim = CheckDimensionsMatch(Dimensionless(),RealAtomDims(i));
1505 if (dim==NULL){
1506 PrintDimenMessage("Inconsistent units in assignment"
1507 ,"LHS",RealAtomDims(i)
1508 ,"RHS",RealValueDimensions(v)
1509 );
1510 fm->ErrNo = Proc_nonconsistent_assignment;
1511 fm->flow = FrameError;
1512 } else {
1513 assignerr = 0;
1514 if (dim != RealAtomDims(i)) {
1515 SetRealAtomDims(i,dim);
1516 }
1517 SetRealAtomValue(i,(double)IntegerValue(v),0);
1518 }
1519 break;
1520 default:
1521 fm->ErrNo = Proc_nonreal_assignment;
1522 fm->flow = FrameError;
1523 break;
1524 }
1525 break;
1526 case BOOLEAN_INST:
1527 case BOOLEAN_ATOM_INST:
1528 if (ValueKind(v)!=boolean_value){
1529 fm->ErrNo = Proc_nonboolean_assignment;
1530 fm->flow = FrameError;
1531 } else {
1532 assignerr = 0;
1533 SetBooleanAtomValue(i,BooleanValue(v),0);
1534 }
1535 break;
1536 case SYMBOL_INST:
1537 case SYMBOL_ATOM_INST:
1538 if (ValueKind(v)!=symbol_value){
1539 fm->ErrNo = Proc_nonsymbol_assignment;
1540 fm->flow = FrameError;
1541 } else {
1542 assignerr = 0;
1543 SetSymbolAtomValue(i,SymbolValue(v));
1544 }
1545 break;
1546 default:
1547 fm->ErrNo = Proc_nonsense_assignment;
1548 fm->flow = FrameError;
1549 break;
1550 }
1551 if (assignerr) {
1552 ProcWriteAssignmentError(fm);
1553 }
1554 }
1555
1556 /* this function always returns ok. 5/96 */
1557 static
1558 void ExecuteInitAsgn(struct procFrame *fm, struct Statement *stat)
1559 {
1560 struct gl_list_t *instances;
1561 struct Instance *inst;
1562 unsigned c,len;
1563 enum FrameControl oldflow;
1564 struct value_t value;
1565 enum find_errors err;
1566
1567 instances = FindInstances(fm->i,DefaultStatVar(stat),&err);
1568 if (instances != NULL){
1569 assert(GetEvaluationContext()==NULL);
1570 SetEvaluationContext(fm->i);
1571 value = EvaluateExpr(DefaultStatRHS(stat),NULL,InstanceEvaluateName);
1572 SetEvaluationContext(NULL);
1573 if (ValueKind(value)==error_value) {
1574 fm->ErrNo = Proc_rhs_error;
1575 fm->flow = FrameError;
1576 ProcWriteAssignmentError(fm);
1577 } else {
1578 len = gl_length(instances);
1579 oldflow = fm->flow;
1580 for(c=1;c<=len;c++){
1581 inst = (struct Instance *)gl_fetch(instances,c);
1582 AssignInitValue(inst,value,fm); /* does its own errors */
1583 if (fm->flow == FrameError) {
1584 if (/* fm->policy-check */0) {
1585 fm->flow = oldflow; /* suppress error flow */
1586 } else {
1587 break; /* skip rest of loop */
1588 }
1589 }
1590 }
1591 }
1592 DestroyValue(&value);
1593 gl_destroy(instances);
1594 } else {
1595 /* error finding left hand side */
1596 fm->ErrNo = Proc_lhs_error;
1597 fm->flow = FrameError;
1598 ProcWriteAssignmentError(fm);
1599 }
1600 return /* Proc_all_ok */;
1601 }
1602
1603 static
1604 void ExecuteInitStatement(struct procFrame *fm, struct Statement *stat)
1605 {
1606 #if IDB
1607 FPRINTF(fm->err,"\n");
1608 FPRINTF(fm->err,"EIS-IN: %s\n",FrameControlToString(fm->flow));
1609 FPRINTF(fm->err,"EIS: "); WriteStatement(fm->err,stat,2);
1610 #endif
1611 switch(StatementType(stat)){
1612 case FOR:
1613 ExecuteInitFor(fm,stat);
1614 break;
1615 case ASGN:
1616 ExecuteInitAsgn(fm,stat);
1617 break;
1618 case RUN:
1619 ExecuteInitRun(fm,stat);
1620 break;
1621 case FIX:
1622 ExecuteInitFix(fm,stat);
1623 break;
1624 case FREE:
1625 ExecuteInitFree(fm,stat);
1626 break;
1627 case SOLVER:
1628 ExecuteInitSolver(fm,stat);
1629 break;
1630 case OPTION:
1631 ExecuteInitOption(fm,stat);
1632 break;
1633 case SOLVE:
1634 ExecuteInitSolve(fm,stat);
1635 break;
1636 case FLOW:
1637 ExecuteInitFlow(fm);
1638 break;
1639 case EXT:
1640 /* CONSOLE_DEBUG("ABOUT TO ExecuteInitExt"); */
1641 ExecuteInitExt(fm,stat);
1642 break;
1643 case CALL:
1644 ExecuteInitCall(fm,stat);
1645 break;
1646 case WHILE:
1647 ExecuteInitWhile(fm,stat);
1648 break;
1649 case ASSERT:
1650 ExecuteInitAssert(fm,stat);
1651 break;
1652 case IF:
1653 ExecuteInitIf(fm,stat);
1654 break;
1655 case SWITCH:
1656 ExecuteInitSwitch(fm,stat);
1657 break;
1658 case CASGN:
1659 fm->flow = FrameError;
1660 fm->ErrNo = Proc_declarative_constant_assignment;
1661 WriteInitErr(fm,
1662 "Incorrect statement type (constant assigned)"
1663 " in initialization section");
1664 break;
1665 default:
1666 fm->flow = FrameError;
1667 fm->ErrNo = Proc_bad_statement;
1668 WriteInitErr(fm,"Unexpected statement type in initialization section");
1669 break;
1670 }
1671 #if IDB
1672 FPRINTF(fm->err,"EIS-OUT: %s\n\n",FrameControlToString(fm->flow));
1673 #endif
1674 return;
1675 }
1676
1677 /* This is our central error handling logic control point.
1678 * This function should not itself return fm->flow == FrameError.
1679 * To the maximum extent possible, do not process errors separately
1680 * elsewhere but defer them to here. That makes maintenance of code
1681 * which handles debugging output and execution logic much simpler.
1682 */
1683 static
1684 void ExecuteInitStatements(struct procFrame *fm, struct StatementList *sl)
1685 {
1686 unsigned c,length;
1687 struct gl_list_t *statements;
1688 struct Statement *stat;
1689 enum FrameControl oldflow;
1690 int stop;
1691
1692 statements = GetList(sl);
1693 length = gl_length(statements);
1694 stop = 0;
1695 oldflow = fm->flow;
1696 for (c = 1; c <= length && !stop; c++){
1697 stat = (struct Statement *)gl_fetch(statements,c);
1698 UpdateProcFrame(fm,stat,fm->i);
1699 /* statements should issue their own complaints */
1700 ExecuteInitStatement(fm,stat);
1701 switch (fm->flow) {
1702 case FrameLoop:
1703 case FrameOK:
1704 fm->flow = oldflow;
1705 break;
1706 case FrameError:
1707 #if IDB
1708 FPRINTF(fm->err,"ERR: "); WriteStatement(fm->err,fm->stat,0);
1709 FPRINTF(fm->err,"\n");
1710 #endif
1711 if ((fm->gen & WP_STOPONERR)!= 0) {
1712 fm->flow = FrameReturn;
1713 stop = 1;
1714 } else {
1715 fm->flow = oldflow;
1716 }
1717 break;
1718 case FrameFallthru: /* say what? */
1719 case FrameContinue:
1720 case FrameBreak:
1721 if (oldflow == FrameLoop) {
1722 stop = 1;
1723 } else {
1724 /* whine about missing loop/switch context.
1725 * should be parser enforced.
1726 */
1727 #if IDB
1728 FPRINTF(fm->err,"LOOP-ERR: "); WriteStatement(fm->err,fm->stat,0);
1729 FPRINTF(fm->err,"\n");
1730 #endif
1731 if ((fm->gen & WP_STOPONERR)!= 0) {
1732 fm->flow = FrameReturn;
1733 stop = 1;
1734 } else {
1735 fm->flow = oldflow;
1736 }
1737 }
1738 break;
1739 case FrameReturn:
1740 #if IDB
1741 FPRINTF(fm->err,"ERR-UNWIND: "); WriteStatement(fm->err,fm->stat,0);
1742 FPRINTF(fm->err,"\n");
1743 #endif
1744 if (/* i/o policy check */1) {
1745 /* whine backtrace*/
1746 }
1747 stop = 1;
1748 break;
1749 /* all cases must be handled here. */
1750 }
1751 if (g_procframe_stop) {
1752 g_procframe_stop = 0;
1753 fm->ErrNo = Proc_user_interrupt;
1754 WriteInitErr(fm,"USER interrupted METHOD execution");
1755 fm->flow = FrameReturn;
1756 stop = 1;
1757 }
1758 }
1759 /* UpdateProcFrame(fm,NULL, fm->i); */ /* leave a mess for messages */
1760 assert(fm->flow != FrameError);
1761 }
1762
1763 /*********************************************************************\
1764 * void ExecuteInitProcedure(i,proc)
1765 * struct Instance *i;
1766 * struct InitProcedure *proc;
1767 * This will execute proc on the instance i.
1768 \*********************************************************************/
1769 /*
1770 * Here's where we enforce stack limits (approximately).
1771 * Here's where we unwind the stack in the event of an
1772 * early return.
1773 */
1774 static
1775 void ExecuteInitProcedure(struct procFrame *fm, struct InitProcedure *proc)
1776 {
1777 struct for_table_t *OldForTable;
1778
1779 g_proc.depth++;
1780 assert(fm != NULL && fm->i != NULL && proc != NULL);
1781 if (g_proc.depth > g_proc.limit) {
1782 g_proc.depth--;
1783 fm->ErrNo = Proc_stack_exceeded_this_frame;
1784 fm->flow = FrameError;
1785 return;
1786 }
1787
1788 OldForTable = GetEvaluationForTable();
1789 SetEvaluationForTable(CreateForTable());
1790 ExecuteInitStatements(fm,ProcStatementList(proc));
1791 DestroyForTable(GetEvaluationForTable());
1792 SetEvaluationForTable(OldForTable);
1793 g_proc.depth--;
1794 }
1795
1796 /* returns overflow or ok. possibly either form of overflow. */
1797 static
1798 void RealInitialize(struct procFrame *fm, struct Name *name)
1799 {
1800 struct Name *instname = NULL;
1801 struct Instance *ptr;
1802 enum find_errors err;
1803 struct InitProcedure *proc;
1804 struct gl_list_t *instances;
1805 unsigned long c,length;
1806 char *morename;
1807 struct procFrame *newfm;
1808 symchar *procname=NULL;
1809 int stop;
1810 int previous_context = GetDeclarativeContext();
1811
1812 morename = WriteNameString(name);
1813 #ifdef INIT_DEBUG
1814 CONSOLE_DEBUG("Running method '%s'...",morename);
1815 #endif
1816 ASC_FREE(morename);
1817
1818 SetDeclarativeContext(1); /* set up for procedural processing */
1819 InstanceNamePart(name,&instname,&procname);
1820
1821 if (procname != NULL) {
1822 instances = FindInstances(fm->i, instname, &err);
1823 if (instances != NULL) {
1824 length = gl_length(instances);
1825 stop = 0;
1826 for(c=1; c<=length && !stop; c++){
1827 ptr = (struct Instance *)gl_fetch(instances,c);
1828 proc = FindProcedure(ptr,procname);
1829 if (proc != NULL) {
1830 morename = WriteInstanceNameString(ptr,fm->i);
1831 newfm = AddProcFrame(fm,ptr,
1832 (morename!=NULL)?morename:"",
1833 proc,FrameInherit);
1834 /* this usage probably force memory recycle in proctype.c */
1835 if (morename != NULL) {
1836 ascfree(morename);
1837 }
1838 ExecuteInitProcedure(newfm,proc);
1839 switch (newfm->flow) {
1840 case FrameOK:
1841 case FrameLoop:
1842 /* do nothing */
1843 break;
1844 case FrameBreak:
1845 case FrameContinue:
1846 case FrameFallthru:
1847 /* aren't supposed to work across frames, or are they? */
1848 /* do nothing */
1849 break;
1850 case FrameError:
1851 /* having to check this here sucks, but the stack
1852 * limit is not optional.
1853 */
1854 if ((fm->gen & WP_STOPONERR) != 0 || /* ||, not && */
1855 newfm->ErrNo == Proc_stack_exceeded_this_frame) {
1856 fm->flow = newfm->flow;
1857 fm->ErrNo = newfm->ErrNo;
1858 if (fm->ErrNo == Proc_stack_exceeded_this_frame) {
1859 fm->ErrNo = Proc_stack_exceeded;
1860 }
1861 stop = 1;
1862 }
1863 ProcWriteStackCheck(newfm,NULL,name);
1864 break;
1865 case FrameReturn:
1866 if (newfm->ErrNo != Proc_return) {
1867 fm->flow = newfm->flow;
1868 fm->ErrNo = newfm->ErrNo;
1869 ProcWriteStackCheck(newfm,NULL,name);
1870 } /* else was a c-like RETURN;. don't pass upward */
1871 break;
1872 }
1873 DestroyProcFrame(newfm);
1874 } else {
1875 fm->flow = FrameError;
1876 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"PROCEDURE NOT FOUND (FindProcedure failed).");
1877 fm->ErrNo = Proc_proc_not_found;
1878 }
1879 }
1880 gl_destroy(instances);
1881 } else { /* unable to find instances */
1882 fm->flow = FrameError;
1883 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"PROCEDURE NOT FOUND (FindInstances failed).");
1884 fm->ErrNo = Proc_instance_not_found;
1885 }
1886 } else {
1887 CONSOLE_DEBUG("BAD PROC NAME");
1888 fm->flow = FrameError;
1889 fm->ErrNo = Proc_bad_name;
1890 }
1891 SetDeclarativeContext(previous_context);
1892 DestroyName(instname);
1893 return;
1894 }
1895
1896 /* Convert all those messy result to a proc enum for UI consumption. */
1897 static
1898 enum Proc_enum InitCalcReturn(struct procFrame *fm)
1899 {
1900 switch(fm->flow) {
1901 case FrameOK:
1902 return Proc_all_ok;
1903 case FrameReturn: /* FALLTHROUGH */
1904 case FrameError:
1905 /* whine */
1906 return fm->ErrNo;
1907 case FrameLoop:
1908 /* whine a lot */
1909 case FrameContinue:
1910 return Proc_continue;
1911 case FrameBreak:
1912 return Proc_break;
1913 case FrameFallthru:
1914 return Proc_fallthru;
1915 /* all must be handled in this switch */
1916 }
1917 return -1;
1918 }
1919
1920 /* internal debug head */
1921 static
1922 enum Proc_enum DebugInitialize(struct Instance *context,
1923 struct Name *name,
1924 CONST char *cname,
1925 FILE *err,
1926 wpflags options,
1927 struct gl_list_t *watchpoints,
1928 FILE *log,
1929 struct procFrame *fm)
1930 {
1931 struct procDebug dbi; /* this struct is huge */
1932
1933 CONSOLE_DEBUG("RUNNING METHOD IN DEBUG MODE...");
1934 InitDebugTopProcFrame(fm,context,cname,err,options,&dbi,watchpoints,log);
1935 RealInitialize(fm,name);
1936 return InitCalcReturn(fm);
1937 }
1938
1939 /* internal normal head */
1940 static
1941 enum Proc_enum NormalInitialize(struct procFrame *fm, struct Name *name)
1942 {
1943 RealInitialize(fm,name);
1944 return InitCalcReturn(fm);
1945 }
1946
1947 enum Proc_enum Initialize(struct Instance *context,
1948 struct Name *name,
1949 CONST char *cname,
1950 FILE *err,
1951 wpflags options,
1952 struct gl_list_t *watchpoints,
1953 FILE *log)
1954 {
1955 enum Proc_enum rval;
1956 struct procFrame fm;
1957
1958 #ifdef INIT_DEBUG
1959 CONSOLE_DEBUG("RUNNING METHOD...");
1960 #endif
1961
1962 assert(err != NULL);
1963 g_proc.depth = 0;
1964 Asc_SetMethodUserInterrupt(0);
1965 if (watchpoints == NULL) {
1966 InitNormalTopProcFrame(&fm,context,cname,err,options);
1967 rval = NormalInitialize(&fm,name);
1968 } else {
1969 CONSOLE_DEBUG("Running method with debug...");
1970 rval = DebugInitialize(context,name,cname,err,options,watchpoints,log,&fm);
1971 }
1972 return rval;
1973 }
1974
1975 /*
1976 * This deals with initializations of the form:
1977 * RUN Type::procname; where Type is model or atom type,
1978 * and procname is a procedure defined within that type.
1979 * If the Type happened to have redefined a procedure from its
1980 * parent class, that procedure would be the one on its
1981 * procedure list and hence the one that would be invoked.
1982 *
1983 */
1984 static
1985 void ClassAccessRealInitialize(struct procFrame *fm,
1986 struct Name *class,
1987 struct Name *name)
1988 {
1989 struct InitProcedure *proc;
1990 struct procFrame *newfm;
1991 struct gl_list_t *plist;
1992 symchar *procname;
1993 symchar *typename;
1994 struct TypeDescription *desc,*conformable;
1995 int previous_context = GetDeclarativeContext();
1996
1997 SetDeclarativeContext(1); /* set up for procedural processing */
1998
1999 typename = SimpleNameIdPtr(class);
2000 if (typename != NULL) {
2001 desc = FindType(typename);
2002 if (desc != NULL) {
2003 conformable = InstanceTypeDesc(fm->i);
2004 if (MoreRefined(conformable,desc)) {
2005 plist = GetInitializationList(desc);
2006 if (plist != NULL) {
2007 procname = SimpleNameIdPtr(name);
2008 if (procname != NULL) {
2009 proc = SearchProcList(plist,procname);
2010 if (proc == NULL) {
2011 proc = SearchProcList(GetUniversalProcedureList(),procname);
2012 }
2013 if (proc != NULL) {
2014 newfm = AddProcFrame(fm,fm->i,"",proc,FrameInherit);
2015 /* apf starts newfm with frameok */
2016 ExecuteInitProcedure(newfm,proc);
2017 switch (newfm->flow) {
2018 case FrameOK:
2019 case FrameLoop:
2020 /* do nothing */
2021 break;
2022 case FrameBreak:
2023 case FrameContinue:
2024 case FrameFallthru:
2025 /* aren't supposed to work across frames are they? */
2026 /* do nothing */
2027 break;
2028 case FrameError:
2029 fm->flow = newfm->flow;
2030 fm->ErrNo = newfm->ErrNo;
2031 ProcWriteStackCheck(newfm,class,name);
2032 /* having to check this here sucks, but the stack
2033 * limit is not optional.
2034 */
2035 if (fm->ErrNo == Proc_stack_exceeded_this_frame) {
2036 fm->ErrNo = Proc_stack_exceeded;
2037 }
2038 break;
2039 case FrameReturn:
2040 if (newfm->ErrNo != Proc_return) {
2041 fm->flow = newfm->flow;
2042 fm->ErrNo = newfm->ErrNo;
2043 ProcWriteStackCheck(newfm,class,name); /* fixme?*/
2044 } /* else was a c-like RETURN;. don't pass upward */
2045 break;
2046 }
2047 DestroyProcFrame(newfm);
2048 } else {
2049 fm->flow = FrameError;
2050 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"PROCEDURE NOT FOUND (SearchProcList).");
2051 fm->ErrNo = Proc_proc_not_found;
2052 }
2053 } else {
2054 fm->flow = FrameError;
2055 fm->ErrNo = Proc_illegal_name_use;
2056 }
2057 } else {
2058 fm->flow = FrameError;
2059 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"PROCEDURE NOT FOUND (GetInitializationList is null).");
2060 fm->ErrNo = Proc_proc_not_found;
2061 }
2062 } else {
2063 fm->flow = FrameError;
2064 fm->ErrNo = Proc_illegal_type_use;
2065 }
2066 } else {
2067 fm->flow = FrameError;
2068 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"PROCEDURE NOT FOUND (FindType failed)\n");
2069 fm->ErrNo = Proc_type_not_found;
2070 }
2071 } else {
2072 fm->flow = FrameError;
2073 fm->ErrNo = Proc_illegal_name_use;
2074 }
2075
2076 SetDeclarativeContext(previous_context);
2077 return;
2078 }
2079
2080 /* internal debug head */
2081 static
2082 enum Proc_enum DebugClassAccessInitialize(struct Instance *context,
2083 struct Name *class,
2084 struct Name *name,
2085 CONST char *cname,
2086 FILE *err,
2087 wpflags options,
2088 struct gl_list_t *watchpoints,
2089 FILE *log,
2090 struct procFrame *fm)
2091 {
2092 struct procDebug dbi; /* this struct is huge */
2093
2094 InitDebugTopProcFrame(fm,context,cname,err,options,&dbi,watchpoints,log);
2095 ClassAccessRealInitialize(fm,class,name);
2096 return InitCalcReturn(fm);
2097 }
2098
2099 /* internal normal head */
2100 static
2101 enum Proc_enum NormalClassAccessInitialize(struct procFrame *fm,
2102 struct Name *class,
2103 struct Name *name)
2104 {
2105 ClassAccessRealInitialize(fm,class,name);
2106 return InitCalcReturn(fm);
2107 }
2108
2109 enum Proc_enum ClassAccessInitialize(struct Instance *context,
2110 struct Name *class,
2111 struct Name *name,
2112 char *cname,
2113 FILE *err,
2114 wpflags options,
2115 struct gl_list_t *watchpoints,
2116 FILE *log)
2117 {
2118 struct procFrame fm;
2119
2120 assert(err != NULL);
2121 g_proc.depth = 0;
2122 Asc_SetMethodUserInterrupt(0);
2123 if (watchpoints == NULL) {
2124 InitNormalTopProcFrame(&fm,context,cname,err,options);
2125 return NormalClassAccessInitialize(&fm,class,name);
2126 } else {
2127 return DebugClassAccessInitialize(context,class,name,cname,
2128 err,options,watchpoints,log,&fm);
2129 }
2130 }

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