/[ascend]/trunk/base/generic/compiler/visitinst.c
ViewVC logotype

Annotation of /trunk/base/generic/compiler/visitinst.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 709 - (hide annotations) (download) (as text)
Wed Jun 28 16:28:57 2006 UTC (14 years, 1 month ago) by johnpye
File MIME type: text/x-csrc
File size: 23417 byte(s)
Monster commit!
Lots of recommenting and reorganising of external relations-related stuff.
Replaced a lot of ascmalloc and asccalloc calls with the new ASC_NEW* macros.
Fixed (?) the problem Art is having with icons in PyGTK.
Turned on -Wall in SConstruct and fixed up a stack of warnings.
Removed the redundant exit(2) from after Asc_Panic calls and added __attribute__((noreturn)).
Set doxygen to create callgraphs to level 2, updated doxyfile to version 1.4.7.
Fixed up building of extfntest.c.
1 aw0a 1 /*
2     * Ascend Instance Tree Type Visit Implementation
3     * by Tom Epperly
4     * 9/3/89
5     * Version: $Revision: 1.21 $
6     * Version control file: $RCSfile: visitinst.c,v $
7     * Date last modified: $Date: 1998/02/26 15:59:37 $
8     * Last modified by: $Author: mthomas $
9     *
10     * This file is part of the Ascend Language Interpreter.
11     *
12     * Copyright (C) 1996 Benjamin Allan
13     * based on instance.c
14     * Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
15     *
16     * The Ascend Language Interpreter is free software; you can redistribute
17     * it and/or modify it under the terms of the GNU General Public License as
18     * published by the Free Software Foundation; either version 2 of the
19     * License, or (at your option) any later version.
20     *
21     * The Ascend Language Interpreter is distributed in hope that it will be
22     * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
23     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24     * General Public License for more details.
25     *
26     * You should have received a copy of the GNU General Public License
27     * along with the program; if not, write to the Free Software Foundation,
28     * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
29     * COPYING.
30     *
31     */
32    
33     #include <stdarg.h>
34 johnpye 399 #include <utilities/ascConfig.h>
35     #include <utilities/ascPanic.h>
36     #include <utilities/ascMalloc.h>
37     #include <general/list.h>
38     #include <general/dstring.h>
39     #include "compiler.h"
40     #include "symtab.h"
41     #include "fractions.h"
42     #include "dimen.h"
43     #include "functype.h"
44 johnpye 669 #include "expr_types.h"
45 johnpye 399 #include "child.h"
46     #include "type_desc.h"
47     #include "instance_enum.h"
48     #include "instance_name.h"
49     #include "instquery.h"
50     #include "instance_io.h"
51     #include "instmacro.h"
52     #include "parentchild.h"
53     #include "when_util.h"
54     #include "instance_types.h"
55     #include "tmpnum.h"
56     #include "visitinst.h"
57 aw0a 1
58     #ifndef lint
59     static CONST char InstanceVisitModuleID[] = "$Id: visitinst.c,v 1.21 1998/02/26 15:59:37 mthomas Exp $";
60     #endif
61    
62     unsigned long global_visit_num = 0;
63     int g_iscomplete = 1;
64     /************* VisitInstance stuff **************************************/
65    
66     #define OLDCHECKVISIT 0
67     #if OLDCHECKVISIT
68     /* returns 1 if not visited yet, 0 if been here already. */
69     static int CheckVisitNumber(struct Instance *i)
70     {
71     AssertMemory(i);
72     switch(i->t) {
73     case MODEL_INST:
74     if (global_visit_num > MOD_INST(i)->visited) {
75     MOD_INST(i)->visited = global_visit_num;
76     return 1;
77     }
78     else return 0;
79     case REAL_CONSTANT_INST:
80     if (global_visit_num > RC_INST(i)->visited) {
81     RC_INST(i)->visited = global_visit_num;
82     return 1;
83     }
84     else return 0;
85     case BOOLEAN_CONSTANT_INST:
86     if (global_visit_num > BC_INST(i)->visited) {
87     BC_INST(i)->visited = global_visit_num;
88     return 1;
89     }
90     else return 0;
91     case INTEGER_CONSTANT_INST:
92     if (global_visit_num > IC_INST(i)->visited) {
93     IC_INST(i)->visited = global_visit_num;
94     return 1;
95     }
96     else return 0;
97     case SYMBOL_CONSTANT_INST:
98     if (global_visit_num > SYMC_INST(i)->visited) {
99     SYMC_INST(i)->visited = global_visit_num;
100     return 1;
101     }
102     else return 0;
103     case REAL_ATOM_INST:
104     if (global_visit_num > RA_INST(i)->visited) {
105     RA_INST(i)->visited = global_visit_num;
106     return 1;
107     }
108     else return 0;
109     case BOOLEAN_ATOM_INST:
110     if (global_visit_num > BA_INST(i)->visited) {
111     BA_INST(i)->visited = global_visit_num;
112     return 1;
113     }
114     else return 0;
115     case INTEGER_ATOM_INST:
116     if (global_visit_num > IA_INST(i)->visited) {
117     IA_INST(i)->visited = global_visit_num;
118     return 1;
119     }
120     else return 0;
121     case SET_ATOM_INST:
122     if (global_visit_num > SA_INST(i)->visited) {
123     SA_INST(i)->visited = global_visit_num;
124     return 1;
125     } else {
126     return 0;
127     }
128     case SYMBOL_ATOM_INST:
129     if (global_visit_num > SYMA_INST(i)->visited) {
130     SYMA_INST(i)->visited = global_visit_num;
131     return 1;
132     } else {
133     return 0;
134     }
135     case REL_INST:
136     if (global_visit_num > RELN_INST(i)->visited) {
137     RELN_INST(i)->visited = global_visit_num;
138     return 1;
139     } else {
140     return 0;
141     }
142     case LREL_INST:
143     if (global_visit_num > LRELN_INST(i)->visited) {
144     LRELN_INST(i)->visited = global_visit_num;
145     return 1;
146     } else {
147     return 0;
148     }
149     case WHEN_INST:
150     if (global_visit_num > W_INST(i)->visited) {
151     W_INST(i)->visited = global_visit_num;
152     return 1;
153     } else {
154     return 0;
155     }
156     case ARRAY_INT_INST:
157     case ARRAY_ENUM_INST:
158     if (global_visit_num > ARY_INST(i)->visited) {
159     ARY_INST(i)->visited = global_visit_num;
160     return 1;
161     } else {
162     return 0;
163     }
164     case DUMMY_INST:
165     if (global_visit_num > D_INST(i)->visited) {
166     D_INST(i)->visited = global_visit_num;
167     return 1;
168     } else {
169     return 0;
170     }
171     case REAL_INST:
172     case INTEGER_INST:
173     case BOOLEAN_INST:
174     case SET_INST:
175     case SYMBOL_INST:
176     return 1; /* assumed always unvisited */
177     /* since they have exactly one ATOM parent */
178     default:
179     Asc_Panic(2, "VisitInstanceTree",
180     "Instance tree contains illegal instance.");
181     break;
182     }
183     }
184     #else /* oldcheckvisit alternative, faster? needs testing */
185    
186     /* returns 1 if not visited yet, 0 if been here already or i bogus. */
187     static int CheckVisitNumber(struct Instance *i)
188     {
189     AssertMemory(i);
190     if (i->t & IERRINST) {
191     FPRINTF(ASCERR,"CheckVisitNumber called with bad instance\n");
192     return 0;
193     }
194     /* models arrays atoms relations constants */
195     if (IsCompoundInstance(i)) {
196     /* models arrays, maybe lists in future */
197     if (IsArrayInstance(i)) {
198     /* arrays */
199     if (global_visit_num > ARY_INST(i)->visited) {
200     ARY_INST(i)->visited = global_visit_num;
201     return 1;
202     } else {
203     return 0;
204     }
205     } else {
206     /* models */
207     if (i->t == MODEL_INST && global_visit_num > MOD_INST(i)->visited) {
208     MOD_INST(i)->visited = global_visit_num;
209     return 1;
210     } else {
211     return 0;
212     /* sim instances are assumed visited, especially since they
213     * should never be seen by VisitTree.
214     */
215     }
216     }
217     } else { /* atoms and relations constants */
218     if (IsAtomicInstance(i)) {
219     if (global_visit_num > CA_INST(i)->visited) {
220     CA_INST(i)->visited = global_visit_num;
221     return 1;
222     } else {
223     return 0;
224     }
225     }
226     if (IsConstantInstance(i)) {
227     /* constants */
228     if (global_visit_num > CI_INST(i)->visited) {
229     CI_INST(i)->visited = global_visit_num;
230     return 1;
231     } else {
232     return 0;
233     }
234     }
235     /* would be nice to have a CommonEqnInstance
236     * here for whenrellogrel CE_INST.
237     */
238     if (i->t == REL_INST) {
239     if (global_visit_num > RELN_INST(i)->visited) {
240     RELN_INST(i)->visited = global_visit_num;
241     return 1;
242     } else {
243     return 0;
244     }
245     }
246     if (i->t == LREL_INST) {
247     if (global_visit_num > LRELN_INST(i)->visited) {
248     LRELN_INST(i)->visited = global_visit_num;
249     return 1;
250     } else {
251     return 0;
252     }
253     }
254     if (i->t == WHEN_INST) {
255     if (global_visit_num > W_INST(i)->visited) {
256     W_INST(i)->visited = global_visit_num;
257     return 1;
258     } else {
259     return 0;
260     }
261     }
262     }
263     /* fundamentals and rogues */
264     if (IsFundamentalInstance(i) ) {
265     /* fundamentals assumed always unvisited */
266     return 1;
267     }
268     if ( InstanceKind(i)==DUMMY_INST) {
269     if (global_visit_num > D_INST(i)->visited) {
270     D_INST(i)->visited = global_visit_num;
271     return 1;
272     } else {
273     return 0;
274     }
275     } else {
276     /* rogues */
277     Asc_Panic(2, "VisitInstanceTree",
278     "VisitInstanceTree: Instance tree contains illegal instance.");
279 johnpye 709
280 aw0a 1 }
281     }
282     #endif /* OLDCHECKVISIT */
283    
284 ben.allan 14 #if 0 /* old unused code. might be handy for debugging someday */
285 aw0a 1 /* if visit number of i is nonzero sets it 0 and returns 1, else 0 */
286     static int ZeroVisitNumber(struct Instance *i)
287     {
288     AssertMemory(i);
289     switch(i->t) {
290     case MODEL_INST:
291     if (MOD_INST(i)->visited) {
292     MOD_INST(i)->visited=0;
293     return 1;
294     }
295     else return 0;
296     case REAL_CONSTANT_INST:
297     if (RC_INST(i)->visited) {
298     RC_INST(i)->visited=0;
299     return 1;
300     }
301     else return 0;
302     case BOOLEAN_CONSTANT_INST:
303     if (BC_INST(i)->visited) {
304     BC_INST(i)->visited=0;
305     return 1;
306     }
307     else return 0;
308     case INTEGER_CONSTANT_INST:
309     if (IC_INST(i)->visited) {
310     IC_INST(i)->visited=0;
311     return 1;
312     }
313     else return 0;
314     case SYMBOL_CONSTANT_INST:
315     if (SYMC_INST(i)->visited) {
316     SYMC_INST(i)->visited=0;
317     return 1;
318     }
319     else return 0;
320     case REAL_ATOM_INST:
321     if (RA_INST(i)->visited) {
322     RA_INST(i)->visited=0;
323     return 1;
324     }
325     else return 0;
326     case BOOLEAN_ATOM_INST:
327     if (BA_INST(i)->visited) {
328     BA_INST(i)->visited=0;
329     return 1;
330     }
331     else return 0;
332     case INTEGER_ATOM_INST:
333     if (IA_INST(i)->visited) {
334     IA_INST(i)->visited=0;
335     return 1;
336     }
337     else return 0;
338     case SET_ATOM_INST:
339     if (SA_INST(i)->visited) {
340     SA_INST(i)->visited=0;
341     return 1;
342     }
343     else return 0;
344     case SYMBOL_ATOM_INST:
345     if (SYMA_INST(i)->visited) {
346     SYMA_INST(i)->visited=0;
347     return 1;
348     }
349     else return 0;
350     case REL_INST:
351     if (RELN_INST(i)->visited) {
352     RELN_INST(i)->visited=0;
353     return 1;
354     }
355     else return 0;
356     case LREL_INST:
357     if (LRELN_INST(i)->visited) {
358     LRELN_INST(i)->visited=0;
359     return 1;
360     }
361     else return 0;
362     case WHEN_INST:
363     if (W_INST(i)->visited) {
364     W_INST(i)->visited=0;
365     return 1;
366     }
367     else return 0;
368     case ARRAY_INT_INST:
369     case ARRAY_ENUM_INST:
370     if (ARY_INST(i)->visited) {
371     ARY_INST(i)->visited=0;
372     return 1;
373     }
374     else return 0;
375     case REAL_INST:
376     case INTEGER_INST:
377     case BOOLEAN_INST:
378     case SET_INST:
379     case SYMBOL_INST:
380     case DUMMY_INST:
381     return 0; /* assumed always unvisited */
382     /* since they have exactly one ATOM parent */
383     default:
384     Asc_Panic(2, NULL, "ZeroVisitInstanceTree:"
385     " Instance tree contains illegal instance.\n");
386     /*NOTREACHED*/
387     }
388 johnpye 709
389 aw0a 1 }
390    
391 ben.allan 14 #endif /* old unused code. might be handy for debugging someday */
392 aw0a 1
393     static
394     void WriteWhereNull(FILE *f, struct Instance *i)
395     {
396     (void) i;
397 johnpye 62 FPRINTF(f,"Null instance in tree at ???? (null child of instance of type '%s')\n", SCP(InstanceType(i)) );
398 aw0a 1 g_iscomplete=0;
399     }
400    
401     /* set global_visit_num = 0 after calling this for all instances
402     * in simulation universe and prototype libraries.
403     */
404     void ResetVisitCounts(struct Instance *inst)
405     {
406     unsigned long nc,c;
407     struct Instance *child;
408     AssertMemory(inst);
409     if (InstanceKind(inst) == SIM_INST) return; /* ack!! */
410     if (CheckVisitNumber(inst)){
411     /* subtree has been visited in the past, not 0d */
412     if (NotAtom(inst)) {
413     nc = NumberChildren(inst);
414     for(c=1;c<=nc;c++) {
415     if ((child = InstanceChild(inst,c))!=NULL) {
416     ResetVisitCounts(child);
417     /* don't really care about NULL */
418     }
419     }
420     }
421     }
422     }
423    
424     static void SlowVisitTree(struct Instance *inst,
425     VisitProc proc,
426     int depth, int leaf)
427     {
428     unsigned long nc,c;
429     struct Instance *child;
430     unsigned nullchildren=0;
431    
432     AssertMemory(inst); /* If null got here, die */
433     if (CheckVisitNumber(inst)){ /* Not here another way already.*/
434     if (!depth) (*proc)(inst); /* Apply on the way down, if top down.*/
435     if (leaf||NotAtom(inst)) { /* Go down on all children not null.*/
436     nc = NumberChildren(inst);
437     for(c=1;c<=nc;c++) {
438     if ((child = InstanceChild(inst,c))!=NULL) { /* don't go down NULL */
439     SlowVisitTree(child,proc,depth,leaf);
440     } else {
441     nullchildren++;
442     /* no point in whining about someplace we can't give a name */
443     }
444     }
445     if (nullchildren) {
446 johnpye 222 ERROR_REPORTER_START_HERE(ASC_PROG_ERR);
447 johnpye 188 FPRINTF(ASCERR,"Found %u NULL children of '",nullchildren);
448 aw0a 1 WriteInstanceName(ASCERR,inst,NULL);
449 johnpye 188 FPRINTF(ASCERR,"'.\n");
450     error_reporter_end_flush();
451 aw0a 1 }
452     }
453     if (depth) (*proc)(inst); /* Apply on way up, if bottom up.*/
454     }
455     }
456    
457     void SlowVisitInstanceTree(struct Instance *inst,
458     VisitProc proc,
459     int depth, int leaf)
460     {
461     global_visit_num++;
462     AssertMemory(inst);
463     if (inst!=NULL) {
464     SlowVisitTree(inst,proc,depth,leaf);
465     } else {
466     FPRINTF(ASCERR,"SlowVisitInstanceTree called with NULL.");
467     }
468     }
469    
470     static
471     void FastVisitTree(struct Instance *inst, VisitProc proc,int depth, int leaf)
472     {
473     unsigned long nc,c;
474     struct Instance *child;
475     AssertMemory(inst);
476     if (CheckVisitNumber(inst)){
477     if (!depth) (*proc)(inst);
478     if (leaf||NotAtom(inst)) {
479     nc = NumberChildren(inst);
480     for(c=1;c<=nc;c++)
481     if ((child = InstanceChild(inst,c))!=NULL) {
482     FastVisitTree(child,proc,depth,leaf);
483     } else {
484     WriteWhereNull(ASCERR,inst);
485     }
486     }
487     if (depth) (*proc)(inst);
488     }
489     }
490    
491     static
492     void SilentVisitTree(struct Instance *inst,VisitProc proc, int depth, int leaf)
493     {
494     unsigned long nc,c;
495     struct Instance *child;
496     AssertMemory(inst);
497     if (CheckVisitNumber(inst)){
498     if (!depth) (*proc)(inst);
499     if (leaf||NotAtom(inst)) {
500     nc = NumberChildren(inst);
501     for(c=1;c<=nc;c++) {
502     if ((child = InstanceChild(inst,c))!=NULL) {
503     SilentVisitTree(child,proc,depth,leaf);
504     }
505     }
506     }
507     if (depth) (*proc)(inst);
508     }
509     }
510    
511     void FastVisitInstanceTree(struct Instance *inst, VisitProc proc,
512     int depth, int leaf)
513     {
514     global_visit_num++;
515     AssertMemory(inst);
516     FastVisitTree(inst,proc,depth,leaf);
517     }
518    
519     void SilentVisitInstanceTree(struct Instance *inst, VisitProc proc,
520     int depth, int leaf)
521     {
522     global_visit_num++;
523     AssertMemory(inst);
524     SilentVisitTree(inst,proc,depth,leaf);
525     }
526    
527     #define IVIT_MIN_LEN 20
528     static
529     void IndexedVisitCheckSize(unsigned long **llist, unsigned int *llen, int len)
530     {
531     unsigned long *old;
532     if ( *llen < (unsigned int)len || !(*llen) || llist == NULL) {
533     old = *llist;
534     if (*llist != NULL) {
535     *llist = (unsigned long *)ascrealloc(*llist,
536     sizeof(unsigned long)*(*llen+IVIT_MIN_LEN));
537     } else {
538 johnpye 669 *llist = ASC_NEW_ARRAY(unsigned long,IVIT_MIN_LEN);
539 aw0a 1 }
540     if (*llist == NULL) {
541     *llist = old;
542     Asc_Panic(2,"IndexedVisitInstanceTree","insufficient memory");
543     }
544     }
545     }
546    
547     static
548     void IndexedVisitTree(struct Instance *inst, IndexedVisitProc proc,
549     int depth, int leaf,
550     unsigned long **llist, unsigned int *llen, int len,
551     VOIDPTR userdata)
552     {
553     unsigned long nc,c;
554     struct Instance *child;
555     int oldlen;
556    
557     AssertMemory(inst);
558     if (CheckVisitNumber(inst)){
559     if (!depth) (*proc)(inst,*llist,len,userdata);
560     if (leaf||NotAtom(inst)) {
561     oldlen = len;
562     len++;
563     nc = NumberChildren(inst);
564     IndexedVisitCheckSize(llist,llen,len);
565     for (c = 1; c <= nc; c++) {
566     child = InstanceChild(inst,c);
567     if (child != NULL) {
568     (*llist)[oldlen] = c;
569     IndexedVisitTree(child,proc,depth,leaf,llist,llen,len,userdata);
570     }
571     }
572     len--;
573     }
574     if (depth) (*proc)(inst,*llist,len,userdata);
575     }
576     }
577    
578     void IndexedVisitInstanceTree(struct Instance *inst, IndexedVisitProc proc,
579     int depth, int leaf, unsigned long **llist,
580     unsigned int *llen, VOIDPTR userdata)
581     {
582     global_visit_num++;
583     AssertMemory(inst);
584    
585     assert(llist != NULL);
586     assert(llen != NULL);
587     IndexedVisitCheckSize(llist,llen,IVIT_MIN_LEN);
588    
589     IndexedVisitTree(inst,proc,depth,leaf,llist,llen,0,userdata);
590     }
591     #undef IVIT_MIN_LEN
592    
593     static
594     void SilentVisitTreeTwo(struct Instance *inst,
595     VisitTwoProc proc,
596     int depth, int leaf,VOIDPTR userdata)
597     {
598     unsigned long nc,c;
599     struct Instance *child;
600     AssertMemory(inst);
601     if (CheckVisitNumber(inst)){
602     if (!depth) {
603     (*proc)(inst,userdata);
604     }
605     if (leaf||NotAtom(inst)) {
606     nc = NumberChildren(inst);
607     for(c=1;c<=nc;c++) {
608     if ( (child = InstanceChild(inst,c)) !=NULL) {
609     SilentVisitTreeTwo(child,proc,depth,leaf,userdata);
610     }
611     }
612     }
613     if (depth) {
614     (*proc)(inst,userdata);
615     }
616     }
617     }
618    
619     static
620     void VisitTreeTwo(struct Instance *inst,
621     VisitTwoProc proc,
622     int depth, int leaf,VOIDPTR userdata)
623     {
624     unsigned long nc,c;
625     struct Instance *child;
626     AssertMemory(inst);
627     if (CheckVisitNumber(inst)){
628     if (!depth) {
629     (*proc)(inst,userdata);
630     }
631     if (leaf||NotAtom(inst)) {
632     nc = NumberChildren(inst);
633     for(c=1;c<=nc;c++) {
634     if ( (child = InstanceChild(inst,c)) !=NULL) {
635     VisitTreeTwo(child,proc,depth,leaf,userdata);
636     } else {
637     WriteWhereNull(ASCERR,inst);
638     }
639     }
640     }
641     if (depth) {
642     (*proc)(inst,userdata);
643     }
644     }
645     }
646    
647    
648     void SilentVisitInstanceTreeTwo(struct Instance *inst,
649     VisitTwoProc proc,
650     int depth, int leaf,
651     VOIDPTR userdata)
652     {
653     global_visit_num++;
654     AssertMemory(inst);
655     SilentVisitTreeTwo(inst,proc,depth,leaf,userdata);
656     }
657    
658     void VisitInstanceTreeTwo(struct Instance *inst,
659     VisitTwoProc proc,
660     int depth, int leaf,
661     VOIDPTR userdata)
662     {
663     global_visit_num++;
664     AssertMemory(inst);
665     VisitTreeTwo(inst,proc,depth,leaf,userdata);
666     }
667    
668     static
669     void SilentVisitFringeTwo(struct Instance *inst,
670     VisitTwoProc proc, VisitTwoProc proc2,
671     int depth, int leaf,VOIDPTR userdata)
672     {
673     unsigned long nc,c;
674     struct Instance *child;
675     AssertMemory(inst);
676     if (CheckVisitNumber(inst)){
677     if (!depth) {
678     (*proc)(inst,userdata);
679     }
680     if (leaf||NotAtom(inst)) {
681     nc = NumberChildren(inst);
682     for(c=1;c<=nc;c++) {
683     if ( (child = InstanceChild(inst,c)) !=NULL) {
684     SilentVisitFringeTwo(child,proc,proc2,depth,leaf,userdata);
685     }
686     }
687     }
688     if (depth) {
689     (*proc)(inst,userdata);
690     }
691     } else {
692     /* play it again sam */
693     (*proc2)(inst,userdata);
694     }
695     }
696    
697     static
698     void VisitFringeTwo(struct Instance *inst,
699     VisitTwoProc proc, VisitTwoProc proc2,
700     int depth, int leaf,VOIDPTR userdata)
701     {
702     unsigned long nc,c;
703     struct Instance *child;
704     AssertMemory(inst);
705     if (CheckVisitNumber(inst)){
706     if (!depth) {
707     (*proc)(inst,userdata);
708     }
709     if (leaf||NotAtom(inst)) {
710     nc = NumberChildren(inst);
711     for(c=1;c<=nc;c++) {
712     if ( (child = InstanceChild(inst,c)) !=NULL) {
713     VisitFringeTwo(child,proc,proc2,depth,leaf,userdata);
714     } else {
715     WriteWhereNull(ASCERR,inst);
716     }
717     }
718     }
719     if (depth) {
720     (*proc)(inst,userdata);
721     }
722     } else {
723     /* play it again sam */
724     (*proc2)(inst,userdata);
725     }
726     }
727    
728    
729     void SilentVisitInstanceFringeTwo(struct Instance *inst,
730     VisitTwoProc proc,
731     VisitTwoProc proc2,
732     int depth, int leaf,
733     VOIDPTR userdata)
734     {
735     global_visit_num++;
736     AssertMemory(inst);
737     SilentVisitFringeTwo(inst,proc,proc2,depth,leaf,userdata);
738     }
739    
740     void VisitInstanceFringeTwo(struct Instance *inst,
741     VisitTwoProc proc,
742     VisitTwoProc proc2,
743     int depth, int leaf,
744     VOIDPTR userdata)
745     {
746     global_visit_num++;
747     AssertMemory(inst);
748     VisitFringeTwo(inst,proc,proc2,depth,leaf,userdata);
749     }
750    
751     static
752     void SilentVisitRootsTwo(struct Instance *inst, VisitTwoProc proc,
753     int depth,VOIDPTR userdata)
754     {
755     unsigned long nc,c;
756     struct Instance *parent;
757     AssertMemory(inst);
758     if (CheckVisitNumber(inst)) {
759     if (!depth) {
760     (*proc)(inst,userdata);
761     }
762     nc = NumberParents(inst);
763     for (c=1; c <= nc; c++) {
764     parent = InstanceParent(inst,c);
765     assert(parent != NULL);
766     SilentVisitRootsTwo(parent,proc,depth,userdata);
767     }
768     if (depth) {
769     (*proc)(inst,userdata);
770     }
771     }
772     }
773    
774     void SilentVisitInstanceRootsTwo(struct Instance *inst, VisitTwoProc proc,
775     int depth, VOIDPTR userdata)
776     {
777     global_visit_num++;
778     AssertMemory(inst);
779     SilentVisitRootsTwo(inst,proc,depth,userdata);
780     }
781    
782     /* struct visitmapinfo *MakeVisitMap(i,&len);
783     * Returns a vector len long of visitmapinfos collected showing the instances
784     * and how they are encountered in a visitation.
785     * example: (i, icld, ignd are instance ptrs)
786     *[parent,context,dir,child]
787     * [NULL,root,DOWN,1],
788     * [root,icld,DOWN,1],
789     * [icld,ignd,-UP-,1],
790     * [root,icld,-UP-,1],
791     * [NULL,root,DOWN,2],
792     * [root,icld,-UP-,1],
793     * [NULL,root,-UP-,0].
794     *
795     * The visitation indicated by this mapping (both bottom-up and top-down)
796     * is:
797     * v<i>
798     * v<i>.b
799     * ^<i>.b.f
800     * ^<i>.b
801     * v<i>
802     * ^<i>.c
803     * ^<i>
804     */
805     static
806     void MakeMap(struct Instance *inst,
807     struct Instance *parent,
808     unsigned long parents_child_num_of_i,
809     unsigned long *lensofar,
810     struct visitmapinfo *map)
811     {
812     unsigned long c,nc;
813     struct Instance *ch;
814     /* account for the children if we haven't been here before */
815     if (CheckVisitNumber(inst) && NotAtom(inst)) {
816     nc = NumberChildren(inst);
817     for (c=1; c <= nc; c++) {
818     ch=InstanceChild(inst,c);
819     if (ch != NULL) {
820     map[*lensofar].parent = parent;
821     map[*lensofar].context = inst;
822     map[*lensofar].dir = vimap_DOWN;
823     map[*lensofar].last = -1;
824     map[*lensofar].child = c;
825     (*lensofar)++;
826     MakeMap(ch,inst,c,lensofar,map);
827     }
828     }
829     }
830     /* if been here before or not, must record seeing here. */
831     map[*lensofar].parent = parent;
832     map[*lensofar].context = inst;
833     map[*lensofar].dir = vimap_UP;
834     map[*lensofar].last = (int)GetTmpNum(inst);
835     map[*lensofar].child = parents_child_num_of_i;
836     SetTmpNum(inst,*lensofar);
837     (*lensofar)++;
838     }
839    
840     /*
841     * CalcMapSize(i,&len);
842     * calculate the number of instances seen and reseen in a visit
843     * and return it in len. Init len to 0 before calling.
844     */
845     static
846     void CalcMapSize(struct Instance *inst,unsigned long *lensofar)
847     {
848     unsigned long c,nc;
849     struct Instance *ch;
850     /* account for the children if we haven't been here before */
851     if (CheckVisitNumber(inst) && NotAtom(inst)) {
852     nc = NumberChildren(inst);
853     for (c=1; c <= nc; c++) {
854     ch=InstanceChild(inst,c);
855     if (ch != NULL) {
856     (*lensofar)++;
857     CalcMapSize(ch,lensofar);
858     }
859     }
860     }
861     /* if been here before or not, must record seeing here. */
862     SetTmpNum(inst,INT_MAX);
863     (*lensofar)++;
864     }
865    
866     struct visitmapinfo *MakeVisitMap(struct Instance *root,unsigned long *len)
867     {
868     struct visitmapinfo *map;
869     unsigned long maplen;
870    
871     AssertMemory(root);
872     global_visit_num++;
873     *len = 0; /* we don't count root entry, since we don't know context. */
874     CalcMapSize(root,len);
875 johnpye 709 map = ASC_NEW_ARRAY(struct visitmapinfo,(*len)+1);
876 aw0a 1 if (map==NULL) {
877     return NULL;
878     }
879     /* put some crap at the END that should signal any reasonable program
880     * should also check this for being same before freeing.
881     */
882     map[*len].parent = NULL;
883     map[*len].context = NULL;
884     map[*len].child = 0UL;
885     map[*len].last = INT_MAX;
886     map[*len].dir = vimap_ERROR;
887     /* record info */
888     global_visit_num++;
889     maplen = 0;
890     MakeMap(root,NULL,0,&maplen,map);
891     assert(map[*len].parent==NULL);
892     assert(map[*len].context==NULL);
893     assert(map[*len].child==0UL);
894     assert(maplen==(*len));
895     return map;
896     }

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