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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2644 - (show annotations) (download) (as text)
Tue Oct 9 12:29:42 2012 UTC (5 years, 11 months ago) by jpye
File MIME type: text/x-csrc
File size: 49949 byte(s)
more info about invalid instance type
1 /* ASCEND modelling environment
2 Copyright (C) 2006 Carnegie Mellon University
3 Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 *//**
20 @file
21 Instance output routines
22 *//*
23 by Tom Epperly
24 Created: 2/8/90
25 Last in CVS: $Revision: 1.45 $ $Date: 1998/04/10 23:25:44 $ $Author: ballan $
26 */
27
28 #include <stdarg.h>
29 #include <ascend/general/platform.h>
30 #include <ascend/general/ascMalloc.h>
31 #include <ascend/general/panic.h>
32 #include <ascend/general/pool.h>
33 #include <ascend/general/list.h>
34 #include <ascend/general/dstring.h>
35 #include <ascend/general/table.h>
36 #include <ascend/utilities/bit.h>
37
38 #include "functype.h"
39 #include "expr_types.h"
40 #include "stattypes.h"
41 #include "statement.h"
42 #include "slist.h"
43 #include "statio.h"
44 #include "instance_enum.h"
45 #include "parentchild.h"
46 #include "instquery.h"
47 #include "atomvalue.h"
48 #include "arrayinst.h"
49 #include "mathinst.h"
50 #include "tmpnum.h"
51 #include "visitinst.h"
52 #include "find.h"
53 #include "relation_util.h"
54 #include "relation_io.h"
55 #include "logical_relation.h"
56 #include "logrel_util.h"
57 #include "logrel_io.h"
58 #include "when_io.h"
59 #include "when_util.h"
60 #include "dimen_io.h"
61 #include "instance_name.h"
62 #include "sets.h"
63 #include "setio.h"
64 #include "setinst_io.h"
65 #include "child.h"
66 #include "type_desc.h"
67 #include "copyinst.h"
68 #include "instance_io.h"
69 #include "module.h"
70
71 /*------------------------------------------------------------------------------
72 globals, forward decls, typedefs
73 */
74
75 static char g_string_buffer[256];
76 #define SB255 g_string_buffer
77
78
79 struct InstanceEnumLookup{
80 enum inst_t t;
81 const char *name;
82 };
83
84 static const struct InstanceEnumLookup g_instancetypenames[] = {
85 #define LIST_D(NAME,VALUE) {NAME,#NAME}
86 #define LIST_X ,
87 ASC_ENUM_DECLS(LIST_D,LIST_X)
88 LIST_X {DUMMY_INST,NULL}
89 #undef LIST_D
90 #undef LIST_X
91
92 };
93
94 /*------------------------------------------------------------------------------
95 INSTANCE TYPE
96 */
97
98 CONST char *instance_typename(CONST struct Instance *inst){
99 int i;
100 AssertMemory(inst);
101 for(i=0; g_instancetypenames[i].name!=NULL; ++i){
102 /* CONSOLE_DEBUG("Testing '%s' (value=%d)",g_instancetypenames[i].name,g_instancetypenames[i].t); */
103 if(g_instancetypenames[i].t == inst->t){
104 /* CONSOLE_DEBUG("MATCHED"); */
105 return g_instancetypenames[i].name;
106 }
107 }
108 CONSOLE_DEBUG("No match");
109 ASC_PANIC("Invalid instance type (inst_t '%d' not found in list)",(int)inst->t);
110 }
111
112 /*------------------------------------------------------------------------------
113 PATH STUFF
114
115 for working out how to output contexted instance names
116 */
117
118 struct gl_list_t *ShortestPath(CONST struct Instance *i,
119 CONST struct Instance *ref,
120 unsigned int height, unsigned int best
121 ){
122 struct gl_list_t *path,*shortest=NULL;
123 unsigned long c,len;
124 unsigned mybest= UINT_MAX;
125 if (height>=best) return NULL;
126 if (i==ref) {
127 shortest = gl_create(1L);
128 gl_append_ptr(shortest,(VOIDPTR)ref);
129 return shortest;
130 }
131 if (0 != (len=NumberParents(i))){
132 for(c=len;c>=1;c--){
133 path = ShortestPath(InstanceParent(i,c),ref,height+1,mybest);
134 if (path!=NULL){
135 if (shortest==NULL){
136 shortest=path;
137 mybest = height+gl_length(path);
138 } else{
139 if (gl_length(path)<gl_length(shortest)){
140 gl_destroy(shortest);
141 shortest = path;
142 mybest = height+gl_length(path);
143 } else {
144 gl_destroy(path);
145 }
146 }
147 }
148 }
149 if (shortest){
150 gl_append_ptr(shortest,NULL);
151 for(c=gl_length(shortest);c>1;c--) {
152 gl_store(shortest,c,gl_fetch(shortest,c-1));
153 }
154 gl_store(shortest,1,(char *)i);
155 assert((ref!=NULL)||(gl_length(shortest)==InstanceShortDepth(i)));
156 }
157 } else {
158 if (ref==NULL) {
159 shortest = gl_create(1L);
160 gl_append_ptr(shortest,(VOIDPTR)i);
161 assert(gl_length(shortest)==InstanceShortDepth(i));
162 } else {
163 return NULL;
164 }
165 }
166 return shortest;
167 }
168
169 int WritePath(FILE *f, CONST struct gl_list_t *path)
170 {
171 CONST struct Instance *parent,*child;
172 struct InstanceName name;
173 unsigned long c;
174 int count = 0;
175
176 if (path!=NULL){
177 parent = gl_fetch(path,gl_length(path));
178 for(c=gl_length(path)-1;c>=1;c--){
179 child = gl_fetch(path,c);
180 name = ParentsName(parent,child);
181 switch (InstanceNameType(name)){
182 case StrName:
183 if (c<(gl_length(path)-1)) PUTC('.',f);
184 FPRINTF(f,SCP(InstanceNameStr(name)));
185 count += SCLEN(InstanceNameStr(name));
186 break;
187 case IntArrayIndex:
188 count += FPRINTF(f,"[%ld]",InstanceIntIndex(name));
189 break;
190 case StrArrayIndex:
191 count += FPRINTF(f,"['%s']",SCP(InstanceStrIndex(name)));
192 break;
193 }
194 parent = child;
195 }
196 }
197 else{
198 FPRINTF(ASCERR,"Cannot print name.\n");
199 FPRINTF(f,"?????");
200 }
201 return count;
202 }
203
204 static void WritePathDS(Asc_DString *dsPtr,CONST struct gl_list_t *path){
205 CONST struct Instance *parent,*child;
206 struct InstanceName name;
207 unsigned long c;
208
209 if (path!=NULL){
210 parent = gl_fetch(path,gl_length(path));
211 for(c=gl_length(path)-1;c>=1;c--){
212 child = gl_fetch(path,c);
213 name = ParentsName(parent,child);
214 switch (InstanceNameType(name)){
215 case StrName:
216 if (c<(gl_length(path)-1)) {
217 Asc_DStringAppend(dsPtr,".",1);
218 }
219 Asc_DStringAppend(dsPtr,SCP(InstanceNameStr(name)),-1);
220 break;
221 case IntArrayIndex:
222 sprintf(SB255,"[%ld]",InstanceIntIndex(name));
223 Asc_DStringAppend(dsPtr,SB255,-1);
224 break;
225 case StrArrayIndex:
226 sprintf(SB255,"['%s']",SCP(InstanceStrIndex(name)));
227 Asc_DStringAppend(dsPtr,SB255,-1);
228 break;
229 }
230 parent = child;
231 }
232 } else{
233 FPRINTF(ASCERR,"Cannot print name.\n");
234 Asc_DStringAppend(dsPtr, "?????",5);
235 }
236 }
237
238 char *WritePathString(CONST struct gl_list_t *path)
239 {
240 char *result;
241 Asc_DString ds, *dsPtr;
242 dsPtr = &ds;
243 Asc_DStringInit(dsPtr);
244 WritePathDS(dsPtr,path);
245 result = Asc_DStringResult(dsPtr);
246 return result;
247 }
248
249 /*------------------------------------------------------------------------------
250 INSTANCE NAME OUTPUTTERS
251 */
252
253 int WriteInstanceName(FILE *f
254 , CONST struct Instance *i, CONST struct Instance *ref
255 ){
256 struct gl_list_t *path;
257 int count;
258 /*if (i==ref && i !=NULL) {
259 FPRINTF(ASCERR,"WriteInstanceName called with i,ref both"
260 " pointing to:\n");
261 WriteInstanceName(ASCERR,i,NULL);
262 FPRINTF(ASCERR,"\n");
263 }
264 */
265 path = ShortestPath(i,ref,0,UINT_MAX);
266 count = WritePath(f,path);
267 gl_destroy(path);
268 return count;
269 }
270
271 void WriteInstanceNameDS(Asc_DString *dsPtr,
272 CONST struct Instance *i,
273 CONST struct Instance *ref)
274 {
275 struct gl_list_t *path;
276 path = ShortestPath(i,ref,0,UINT_MAX);
277 WritePathDS(dsPtr,path);
278 gl_destroy(path);
279 }
280
281 char *WriteInstanceNameString(CONST struct Instance *i,
282 CONST struct Instance *ref)
283 {
284 char *result;
285 Asc_DString ds, *dsPtr;
286 dsPtr = &ds;
287 Asc_DStringInit(dsPtr);
288 WriteInstanceNameDS(dsPtr,i,ref);
289 result = Asc_DStringResult(dsPtr);
290 return result;
291 }
292
293 /**
294 This is a temporary fix for writing out instance names faster
295 than we are now. This is for use in saving simulations. We dont
296 really care if it is the shortest path or not. The third version of
297 this command will be use a stack to keep track of the name segments
298 so that we dont always have to search back to the ref inference.
299 The fourth evolution will allow the sort of filters are now
300 allowed when exporting to the probe, so as to give selective
301 writing of data.
302 KAA
303
304 Ref is completely irrelevant. If it is not, one should use a
305 indexed visit tree so that the paths can be computed properly.
306 Prototype code never dies. As expected, this is a production
307 function now.
308 BAA
309 */
310 static
311 void InstanceAnyPath(struct Instance *i, struct gl_list_t *path)
312 {
313 struct Instance *parent;
314 unsigned long len;
315 if (i==NULL) {
316 return;
317 }
318 gl_append_ptr(path,(VOIDPTR)i);
319 len = NumberParents(i);
320 if (len) {
321 parent = InstanceParent(i,1); /* take the first */
322 InstanceAnyPath(parent,path);
323 }
324 return;
325 }
326
327 int WriteAnyInstanceName(FILE *f, struct Instance *i)
328
329 {
330 struct gl_list_t *path_list;
331 int count;
332 path_list = gl_create(23L);
333 InstanceAnyPath(i,path_list);
334 count = WritePath(f,path_list);
335 gl_destroy(path_list);
336 /* costs nothing. lists are recycled */
337 return count;
338 }
339
340
341 /**
342 Copies all but the last element of path. It allocates new memory
343 for each of the NameNode structures and copies the contents from path.
344 */
345 static struct gl_list_t *CopyPathHead(CONST struct gl_list_t *path){
346 struct gl_list_t *result;
347 struct NameNode *orig, *copy;
348 unsigned long c,length;
349 length = gl_length(path)-1;
350 result = gl_create(length);
351 for(c=1;c<=length;c++){
352 orig = gl_fetch(path,c);
353 copy = ASC_NEW(struct NameNode);
354 copy->inst = orig->inst;
355 copy->index = orig->index;
356 gl_append_ptr(result,(VOIDPTR)copy);
357 }
358 return result;
359 }
360
361 struct gl_list_t *AllPaths(CONST struct Instance *i)
362 {
363 struct gl_list_t *result,*tmp1,*tmp2,*path;
364 CONST struct Instance *parent;
365 struct NameNode *nptr;
366 unsigned long length, cindex;
367 unsigned c,count;
368 if (NumberParents(i)==0){ /* found root. will be sim. */
369 result = gl_create(1);
370 path = gl_create(1);
371 nptr = ASC_NEW(struct NameNode);
372 nptr->inst = i;
373 nptr->index = 0;
374 gl_append_ptr(path,(VOIDPTR)nptr);
375 gl_append_ptr(result,(VOIDPTR)path);
376 } else {
377 if(NumberParents(i)==1){
378 result = AllPaths(InstanceParent(i,1));
379 } else{
380 result = gl_create(0);
381 for(c=NumberParents(i);c>=1;c--){
382 tmp1 = AllPaths(InstanceParent(i,c));
383 tmp2 = gl_concat(result,tmp1);
384 gl_destroy(result); /* these *should* be gl_destroy */
385 gl_destroy(tmp1); /* these *should* be gl_destroy */
386 result = tmp2;
387 }
388 }
389 /* going from the end of the list to the beginning is crucial to the
390 * workings of this loop because additional paths may be appended
391 * onto the end of result
392 */
393 for(c=gl_length(result);c>=1;c--){
394 path = (struct gl_list_t *)gl_fetch(result,c);
395 nptr = gl_fetch(path,gl_length(path));
396 parent = nptr->inst;
397 length = NumberChildren(parent);
398 count=0;
399 for(cindex=1; cindex <= length; cindex++){
400 if (InstanceChild(parent,cindex) == i){
401 if (count++) {
402 tmp1 = CopyPathHead(path);
403 gl_append_ptr(result,(VOIDPTR)tmp1);
404 } else {
405 tmp1 = path;
406 }
407 nptr = ASC_NEW(struct NameNode);
408 nptr->inst = i;
409 nptr->index = cindex;
410 gl_append_ptr(tmp1,(VOIDPTR)nptr);
411 }
412 }
413 assert(count);
414 }
415 }
416 return result;
417 }
418
419 /**
420 @return 0 if a WILL_BE or ALIASES or ARR origin is encountered in path
421 */
422 static
423 int PathOnlyISAs(CONST struct gl_list_t *path)
424 {
425 CONST struct Instance *parent;
426 CONST struct NameNode *nptr;
427 ChildListPtr clist;
428 unsigned int origin;
429 unsigned long c,len;
430
431 if (path!=NULL){
432 len = gl_length(path);
433 nptr = gl_fetch(path,1);
434 parent = nptr->inst;
435 for(c=2; c <= len; c++) {
436 nptr = gl_fetch(path,c); /* move up nptr */
437 if (IsArrayInstance(parent)==0) {
438 clist = GetChildList(InstanceTypeDesc(parent));
439 origin = ChildOrigin(clist,nptr->index);
440 if (origin != origin_ISA && origin != origin_PISA) {
441 return 0;
442 }
443 } /* else skip subscripts with arrays as parents. */
444 parent = nptr->inst; /* move up parent 1 step behind */
445 }
446 return 1;
447 } else {
448 return 0;
449 }
450 }
451
452 struct gl_list_t *ISAPaths(CONST struct gl_list_t *pathlist)
453 {
454 struct gl_list_t *result, *path;
455 unsigned long c,len;
456 if (pathlist == NULL) {
457 FPRINTF(ASCERR,"ISAPaths(p) called with NULL pathlist p!\n");
458 return NULL;
459 }
460 result = gl_create(3);
461 len = gl_length(pathlist);
462 for (c = 1; c <=len; c++) {
463 path = (struct gl_list_t *)gl_fetch(pathlist,c);
464 if (PathOnlyISAs(path) == 1) {
465 gl_append_ptr(result,(VOIDPTR)path);
466 }
467 }
468 return result;
469 }
470
471 /*------------------------------------------------------------------------------
472 STUFF ABOUT ALIASES
473 */
474
475 static
476 void AliasWritePath(FILE *f, CONST struct gl_list_t *path)
477 {
478 CONST struct Instance *parent;
479 CONST struct NameNode *nptr;
480 struct InstanceName name;
481 unsigned long c,len;
482 if (path!=NULL){
483 len = gl_length(path);
484 nptr = gl_fetch(path,1);
485 parent = nptr->inst;
486 for(c=2;c<=len;c++){
487 nptr = gl_fetch(path,c);
488 name = ChildName(parent,nptr->index);
489 switch (InstanceNameType(name)){
490 case StrName:
491 if (c>2) PUTC('.',f);
492 FPRINTF(f,SCP(InstanceNameStr(name)));
493 break;
494 case IntArrayIndex:
495 FPRINTF(f,"[%ld]",InstanceIntIndex(name));
496 break;
497 case StrArrayIndex:
498 FPRINTF(f,"['%s']",SCP(InstanceStrIndex(name)));
499 break;
500 }
501 parent = nptr->inst;
502 }
503 } else{
504 FPRINTF(ASCERR,"Cannot print name.\n");
505 FPRINTF(f,"?????");
506 }
507 }
508
509 static
510 char *AliasWritePathString(CONST struct gl_list_t *path)
511 {
512 char buff[20], *result;
513 CONST struct Instance *parent;
514 CONST struct NameNode *nptr;
515 struct InstanceName name;
516 unsigned long c,len;
517 Asc_DString ds, *dsPtr;
518
519 dsPtr = &ds;
520 Asc_DStringInit(dsPtr);
521
522 if (path!=NULL){
523 len = gl_length(path);
524 nptr = gl_fetch(path,1);
525 parent = nptr->inst;
526 for(c=2;c<=len;c++){
527 nptr = gl_fetch(path,c);
528 name = ChildName(parent,nptr->index);
529 switch (InstanceNameType(name)) {
530 case StrName:
531 if (c>2) Asc_DStringAppend(dsPtr,".",1);
532 Asc_DStringAppend(dsPtr,SCP(InstanceNameStr(name)),-1);
533 break;
534 case IntArrayIndex:
535 sprintf(buff,"[%ld]",InstanceIntIndex(name));
536 Asc_DStringAppend(dsPtr,buff,-1);
537 break;
538 case StrArrayIndex:
539 Asc_DStringAppend(dsPtr,"['",2);
540 Asc_DStringAppend(dsPtr,SCP(InstanceStrIndex(name)),-1);
541 Asc_DStringAppend(dsPtr,"']",2);
542 break;
543 }
544 parent = nptr->inst;
545 }
546 }
547 else{
548 /** @TODO what is the meaning of ????? and when might it happen? */
549 Asc_DStringAppend(dsPtr,"?????",5);
550 }
551 result = Asc_DStringResult(dsPtr);
552 return result;
553 }
554
555 unsigned long CountAliases(CONST struct Instance *i)
556 {
557 struct gl_list_t *paths,*path;
558 unsigned long c,len;
559
560 paths = AllPaths(i);
561 len = gl_length(paths);
562 for(c=1;c<=len;c++){
563 path = (struct gl_list_t *)gl_fetch(paths,c);
564 gl_free_and_destroy(path);
565 }
566 gl_destroy(paths);
567 return len;
568 }
569
570 unsigned long CountISAs(CONST struct Instance *i)
571 {
572 struct gl_list_t *paths, *path, *isapaths;
573 unsigned long c,len;
574
575 paths = AllPaths(i);
576 isapaths = ISAPaths(paths);
577
578 len = gl_length(paths);
579 for(c=1;c<=len;c++){
580 path = (struct gl_list_t *)gl_fetch(paths,c);
581 gl_free_and_destroy(path);
582 }
583 gl_destroy(paths);
584 /* do not fetch from isapaths after this point. it's data
585 * pointers have been freed in destroying paths, but
586 * isapaths doesn't know this.
587 */
588 len = gl_length(isapaths);
589 gl_destroy(isapaths);
590 return len;
591 }
592
593 void WriteAliases(FILE *f, CONST struct Instance *i)
594 {
595 struct gl_list_t *paths,*path;
596 unsigned long c,len;
597 paths = AllPaths(i);
598 len = gl_length(paths);
599 #if 1
600 FPRINTF(f,"Number of names: %lu\n",len);
601 #endif
602 for(c=1;c<=len;c++){
603 path = (struct gl_list_t *)gl_fetch(paths,c);
604 AliasWritePath(f,path);
605 PUTC('\n',f);
606 gl_free_and_destroy(path);
607 }
608 gl_destroy(paths); /* this *should* gl_destroy */
609 }
610
611 void WriteISAs(FILE *f, CONST struct Instance *i)
612 {
613 struct gl_list_t *paths,*path, *isapaths;
614 unsigned long c,len;
615 paths = AllPaths(i);
616 isapaths = ISAPaths(paths);
617 len = gl_length(isapaths);
618 #if 1
619 FPRINTF(f,"Number of names: %lu\n",len);
620 #endif
621 for(c=1;c<=len;c++){
622 path = (struct gl_list_t *)gl_fetch(isapaths,c);
623 AliasWritePath(f,path);
624 PUTC('\n',f);
625 }
626 gl_destroy(isapaths);
627 len = gl_length(paths);
628 for(c=1;c<=len;c++){
629 path = (struct gl_list_t *)gl_fetch(paths,c);
630 gl_free_and_destroy(path);
631 }
632 gl_destroy(paths);
633 }
634
635 struct gl_list_t *WriteAliasStrings(CONST struct Instance *i)
636 {
637 struct gl_list_t *paths,*path,*strings;
638 char *tmp = NULL;
639 unsigned long c,len;
640
641 paths = AllPaths(i);
642 len = gl_length(paths);
643 strings = gl_create(len);
644 for(c=1;c<=len;c++){
645 path = (struct gl_list_t *)gl_fetch(paths,c);
646 tmp = AliasWritePathString(path);
647 gl_append_ptr(strings,(VOIDPTR)tmp);
648 tmp = NULL;
649 gl_free_and_destroy(path);
650 }
651 gl_destroy(paths); /* this *should* gl_destroy */
652 return strings;
653 }
654
655 struct gl_list_t *WriteISAStrings(CONST struct Instance *i)
656 {
657 struct gl_list_t *paths,*path,*strings, *isapaths;
658 char *tmp = NULL;
659 unsigned long c,len;
660
661 paths = AllPaths(i);
662 isapaths = ISAPaths(paths);
663 len = gl_length(isapaths);
664 strings = gl_create(len);
665 for(c = 1; c <= len; c++){
666 path = (struct gl_list_t *)gl_fetch(isapaths,c);
667 tmp = AliasWritePathString(path);
668 gl_append_ptr(strings,(VOIDPTR)tmp);
669 tmp = NULL;
670 }
671 gl_destroy(isapaths);
672 len = gl_length(paths);
673 for(c = 1; c <= len; c++){
674 path = (struct gl_list_t *)gl_fetch(paths,c);
675 gl_free_and_destroy(path);
676 }
677 gl_destroy(paths); /* this *should* gl_destroy */
678 return strings;
679 }
680
681 void WriteClique(FILE *f, CONST struct Instance *i)
682 {
683 CONST struct Instance *tmp;
684 tmp = i;
685 do {
686 WriteAliases(f,tmp);
687 tmp = NextCliqueMember(tmp);
688 } while(tmp != i);
689 }
690
691 /*------------------------------------------------------------------------------
692 STUFF ABOUT PENDING STATEMENTS
693 */
694
695 static
696 void WritePendingStatements(FILE *f, CONST struct Instance *i)
697 {
698 CONST struct BitList *blist;
699 CONST struct TypeDescription *desc;
700 CONST struct StatementList *slist;
701 CONST struct Statement *stat;
702 CONST struct gl_list_t *list;
703 unsigned long c,len;
704 blist = InstanceBitList(i);
705 if ((blist!=NULL)&&(!BitListEmpty(blist))){
706 FPRINTF(f,"PENDING STATEMENTS\n");
707 desc = InstanceTypeDesc(i);
708 slist = GetStatementList(desc);
709 list = GetList(slist);
710 len = gl_length(list);
711 for(c=1;c<=len;c++){
712 if (ReadBit(blist,c-1)){
713 stat = (struct Statement *)gl_fetch(list,c);
714 WriteStatement(f,stat,4);
715 if (StatementType(stat)== SELECT) {
716 c = c + SelectStatNumberStats(stat);
717 }
718 }
719 }
720 }
721 }
722
723 /*------------------------------------------------------------------------------
724 ATOMS AND THEIR CHILDREN
725 (the nuclear family)
726 */
727
728 void WriteAtomValue(FILE *f, CONST struct Instance *i)
729 {
730 if (AtomAssigned(i)){
731 switch(InstanceKind(i)){
732 case REAL_INST:
733 case REAL_ATOM_INST:
734 case REAL_CONSTANT_INST:
735 FPRINTF(f,"%.18g",RealAtomValue(i));
736 break;
737 case INTEGER_INST:
738 case INTEGER_ATOM_INST:
739 case INTEGER_CONSTANT_INST:
740 FPRINTF(f,"%ld",GetIntegerAtomValue(i));
741 break;
742 case SET_INST:
743 case SET_ATOM_INST:
744 WriteInstSet(f,SetAtomList(i));
745 break;
746 case BOOLEAN_INST:
747 case BOOLEAN_ATOM_INST:
748 case BOOLEAN_CONSTANT_INST:
749 FPRINTF(f,GetBooleanAtomValue(i)?"TRUE":"FALSE");
750 break;
751 case SYMBOL_INST:
752 case SYMBOL_ATOM_INST:
753 case SYMBOL_CONSTANT_INST:
754 FPRINTF(f,"'%s'",SCP(GetSymbolAtomValue(i)));
755 break;
756 default:
757 break; /* NOTREACHED normally */
758 }
759 }
760 else{
761 FPRINTF(f,"UNDEFINED");
762 }
763 }
764
765 static
766 void WriteAtomChildren(FILE *f, CONST struct Instance *i)
767 {
768 unsigned long c,len;
769 struct InstanceName rec;
770 CONST struct Instance *child;
771 ChildListPtr clist;
772 int hidecount= 0;
773
774 len = NumberChildren(i);
775 if (len){
776 FPRINTF(f,"CHILDREN VALUES\n");
777 clist = GetChildList(InstanceTypeDesc(i));
778 for(c=1;c<=len;c++){
779 if (ChildVisible(clist,c)) {
780 rec = ChildName(i,c);
781 assert(InstanceNameType(rec)==StrName);
782 FPRINTF(f," %-30s ",SCP(InstanceNameStr(rec)));
783 child = InstanceChild(i,c);
784 WriteAtomValue(f,child);
785 PUTC('\n',f);
786 } else {
787 hidecount++;
788 }
789 }
790 if (hidecount !=0) {
791 FPRINTF(f," and %d hidden children\n",hidecount);
792 }
793 }
794 }
795
796 static
797 void WriteNameRec(FILE *f, CONST struct InstanceName *rec)
798 {
799 unsigned c;
800 switch(InstanceNameType(*rec)){
801 case IntArrayIndex:
802 FPRINTF(f,"%-30ld",InstanceIntIndex(*rec));
803 break;
804 case StrArrayIndex:
805 FPRINTF(f,"'%s'",SCP(InstanceStrIndex(*rec)));
806 c = SCLEN(InstanceStrIndex(*rec))+2;
807 if (c >=30) c =0;
808 else c = 30-c;
809 while (c--) PUTC(' ',f);
810 break;
811 case StrName:
812 FPRINTF(f,"%-30s",SCP(InstanceNameStr(*rec)));
813 break;
814 }
815 }
816
817 static
818 void WriteTypeOrValue(FILE *f, CONST struct Instance *i)
819 {
820 switch(InstanceKind(i)){
821 case REL_INST:
822 case LREL_INST:
823 case MODEL_INST:
824 case WHEN_INST:
825 case DUMMY_INST:
826 FPRINTF(f,SCP(InstanceType(i)));
827 break;
828 case REAL_INST:
829 case REAL_ATOM_INST:
830 case BOOLEAN_INST:
831 case BOOLEAN_ATOM_INST:
832 case INTEGER_INST:
833 case INTEGER_ATOM_INST:
834 case SET_INST:
835 case SET_ATOM_INST:
836 case SYMBOL_INST:
837 case SYMBOL_ATOM_INST:
838 case REAL_CONSTANT_INST:
839 case INTEGER_CONSTANT_INST:
840 case BOOLEAN_CONSTANT_INST:
841 case SYMBOL_CONSTANT_INST:
842 WriteAtomValue(f,i);
843 break;
844 case ARRAY_INT_INST:
845 case ARRAY_ENUM_INST:
846 FPRINTF(f,"ARRAY OF %s REFINEMENTS",
847 SCP(GetName(GetArrayBaseType(InstanceTypeDesc(i)))));
848 break;
849 default:
850 ASC_PANIC("Unknown instance type in WriteTypeOrValue.");
851 break;
852 }
853 }
854
855 static
856 void WriteArrayChildren(FILE *f, CONST struct Instance *i)
857 {
858 unsigned long c,len;
859 CONST struct Instance *child;
860 struct InstanceName rec;
861 len = NumberChildren(i);
862 for(c=1;c<=len;c++){
863 child = InstanceChild(i,c);
864 rec = ChildName(i,c);
865 WriteNameRec(f,&rec);
866 WriteTypeOrValue(f,child);
867 PUTC('\n',f);
868 }
869 }
870
871 static
872 void ListChildren(FILE *f, CONST struct Instance *i)
873 {
874 unsigned long c,length;
875 struct InstanceName name;
876 struct Instance *ch;
877 ChildListPtr clist;
878 int hidecount=0, PorT;
879
880 length = NumberChildren(i);
881 if (length){
882 FPRINTF(f,"CHILDREN\n%-30sType\n","Name");
883 clist = GetChildList(InstanceTypeDesc(i));
884 for(c=1;c<=length;c++){
885 if (ChildVisible(clist,c)) {
886 name = ChildName(i,c);
887 WriteNameRec(f,&name);
888 ch = InstanceChild(i,c);
889 if ( ch != NULL /* && type not hidden */) {
890 FPRINTF(f,"%s\t",SCP(InstanceType(ch)));
891 WriteTypeOrValue(f,ch);
892 #define ATDEBUG 0 /* puts out tmpnum and ptr for debugging classification */
893 #if ATDEBUG
894 FPRINTF(f," TN = %ld ip=0x%p\n",GetTmpNum(ch),ch);
895 #else
896
897 FPRINTF(f,"\n");
898 #endif
899 } else {
900 PorT = (ChildDeclaration(i,c)!=NULL &&
901 StatWrong(ChildDeclaration(i,c)));
902 FPRINTF(f,
903 "NULL_INSTANCE %s\n", PorT ? "PERMANENTLY" : "TEMPORARILY");
904 }
905 } else {
906 hidecount++;
907 }
908 }
909 if (hidecount !=0) {
910 FPRINTF(f," and %d hidden children\n",hidecount);
911 }
912 }
913 }
914
915 /*------------------------------------------------------------------------------
916 OUTPUT FUNCTIONS FOR DEBUGGING
917 */
918
919 void WriteInstance(FILE *f, CONST struct Instance *i)
920 {
921 CONST struct logrelation *lreln;
922 CONST struct relation *reln;
923 enum Expr_enum reltype;
924
925
926 if (i==NULL) {
927 FPRINTF(ASCERR,"WriteInstance called with NULL instance.\n");
928 return;
929 }
930 switch(InstanceKind(i)) {
931 case MODEL_INST:
932 FPRINTF(f,"MODEL INSTANCE.\nType: %s\n",SCP(InstanceType(i)));
933 #if 0 /* old when stuff, probably dead code */
934 if(model_flagbit(i,MODEL_ON)) {
935 FPRINTF(f,"MODEL ON\n");
936 } else {
937 FPRINTF(f,"MODEL OFF\n");
938 }
939 #endif
940 WritePendingStatements(f,i);
941 ListChildren(f,i);
942 break;
943 case REAL_INST:
944 case REAL_ATOM_INST:
945 case REAL_CONSTANT_INST:
946 FPRINTF(f,"REAL INSTANCE.\nType: %s\n",SCP(InstanceType(i)));
947 if (AtomAssigned(i)){
948 FPRINTF(f,"Value: %g\n",RealAtomValue(i));
949 }
950 else{
951 FPRINTF(f,"Value: Undefined\n");
952 }
953 FPRINTF(f,"Dimensions: ");
954 WriteDimensions(f,RealAtomDims(i));
955 PUTC('\n',f);
956 WriteAtomChildren(f,i);
957 break;
958 case BOOLEAN_INST:
959 case BOOLEAN_ATOM_INST:
960 case BOOLEAN_CONSTANT_INST:
961 FPRINTF(f,"BOOLEAN INSTANCE.\nType: %s\n",SCP(InstanceType(i)));
962 if (AtomAssigned(i)){
963 FPRINTF(f,GetBooleanAtomValue(i) ? "Value: TRUE\n" : "Value: FALSE\n");
964 }
965 else{
966 FPRINTF(f,"Value: Undefined\n");
967 }
968 WriteAtomChildren(f,i);
969 break;
970 case INTEGER_INST:
971 case INTEGER_ATOM_INST:
972 case INTEGER_CONSTANT_INST:
973 FPRINTF(f,"INTEGER INSTANCE.\nType: %s\n",SCP(InstanceType(i)));
974 if (AtomAssigned(i)){
975 FPRINTF(f,"Value: %ld\n",GetIntegerAtomValue(i));
976 }
977 else{
978 FPRINTF(f,"Value: Undefined\n");
979 }
980 WriteAtomChildren(f,i);
981 break;
982 case SET_INST:
983 case SET_ATOM_INST:
984 FPRINTF(f,"SET INSTANCE.\nType: %s\n",SCP(InstanceType(i)));
985 if (AtomAssigned(i)){
986 FPRINTF(f,"Value: ");
987 WriteInstSet(f,SetAtomList(i));
988 PUTC('\n',f);
989 }
990 else{
991 FPRINTF(f,"Value: Undefined\n");
992 }
993 WriteAtomChildren(f,i);
994 break;
995 case SYMBOL_INST:
996 case SYMBOL_ATOM_INST:
997 case SYMBOL_CONSTANT_INST:
998 FPRINTF(f,"SYMBOL INSTANCE.\nType: %s\n",SCP(InstanceType(i)));
999 if (AtomAssigned(i)){
1000 FPRINTF(f,"Value: '%s'\n", SCP(GetSymbolAtomValue(i)));
1001 }
1002 else{
1003 FPRINTF(f,"Value: Undefined\n");
1004 }
1005 WriteAtomChildren(f,i);
1006 break;
1007 case REL_INST:
1008 /*
1009 * Using ref as NULL; the correct fix requires finding
1010 * the parent in the case of arrays of relation instances.
1011 */
1012 FPRINTF(f,"RELATION INSTANCE.\nType: %s\n",SCP(InstanceType(i)));
1013 #if 0 /* old WHEN stuff. probably dead code. */
1014 if(relinst_flagbit(((struct RelationInstance *)(i)),RELINST_ON)) {
1015 FPRINTF(f,"RELATION ON\n");
1016 } else {
1017 FPRINTF(f,"RELATION OFF\n");
1018 }
1019 #endif
1020 WriteRelation(f,i,NULL);
1021 PUTC('\n',f);
1022 reln = GetInstanceRelation(i,&reltype);
1023 if (!reln) {
1024 break;
1025 }
1026 #if 0 /* set to 1 if you want to dump multiple formats */
1027 Infix_WriteRelation(f,i,NULL);
1028 PUTC('\n',f);
1029 WriteRelationPostfix(f,i,NULL);
1030 PUTC('\n',f);
1031 #endif
1032 FPRINTF(f,"Residual: %g\n",
1033 RelationResidual(GetInstanceRelation(i,&reltype)));
1034 FPRINTF(f,"Multiplier: %g\n",
1035 RelationMultiplier(GetInstanceRelation(i,&reltype)));
1036 FPRINTF(f,"Nominal: %g\n",
1037 RelationNominal(GetInstanceRelation(i,&reltype)));
1038 FPRINTF(f,RelationIsCond(GetInstanceRelation(i,&reltype)) ?
1039 "Relation is Conditional\n" : "");
1040 WriteAtomChildren(f,i);
1041 break;
1042 case LREL_INST:
1043 FPRINTF(f,"LOGRELATION INSTANCE.\nType: %s\n",SCP(InstanceType(i)));
1044 WriteLogRel(f,i,NULL);
1045 PUTC('\n',f);
1046 lreln = GetInstanceLogRel(i);
1047 if (!lreln) {
1048 break;
1049 }
1050 #if 0 /* set to 1 if you want to dump multiple formats */
1051 WriteLogRelInfix(f,i,NULL);
1052 PUTC('\n',f);
1053 WriteLogRelPostfix(f,i,NULL);
1054 PUTC('\n',f);
1055 #endif
1056 FPRINTF(f,LogRelNominal(GetInstanceLogRel(i)) ?
1057 "Nominal: TRUE\n" : "Nominal: FALSE\n");
1058 FPRINTF(f,LogRelResidual(GetInstanceLogRel(i)) ?
1059 "Residual: TRUE\n" : "Residual: FALSE\n");
1060 FPRINTF(f,LogRelIsCond(GetInstanceLogRel(i)) ?
1061 "Logical Relation is Conditional\n" : "");
1062 WriteAtomChildren(f,i);
1063 break;
1064 case WHEN_INST:
1065 /*
1066 * Using ref as NULL; the correct fix requires finding
1067 * the parent in the case of arrays of when instances.
1068 */
1069 FPRINTF(f,"WHEN INSTANCE.\nType: %s\n",SCP(InstanceType(i)));
1070 WriteWhen(f,i,NULL);
1071 break;
1072 case ARRAY_INT_INST:
1073 FPRINTF(f,"ARRAY INSTANCE INDEXED BY integer.\n");
1074 FPRINTF(f,"Indirected = %ld. Deref# = %lu\n",
1075 InstanceIndirected(i), NumberofDereferences(i));
1076 WriteArrayChildren(f,i);
1077 break;
1078 case ARRAY_ENUM_INST:
1079 FPRINTF(f,"ARRAY INSTANCE INDEXED BY symbol.\n");
1080 FPRINTF(f,"Indirected = %ld. Deref# = %lu\n",
1081 InstanceIndirected(i), NumberofDereferences(i));
1082 WriteArrayChildren(f,i);
1083 break;
1084 case DUMMY_INST:
1085 FPRINTF(f,"GlobalDummyInstance\n");
1086 break;
1087 default:
1088 ASC_PANIC("Unknown instance type in WriteInstance.");
1089 }
1090 }
1091
1092 /**
1093 This is a debugging aid and not intended for
1094 general use
1095 */
1096 void WriteInstanceList(struct gl_list_t *list)
1097 {
1098 unsigned long len,c;
1099 struct Instance *i;
1100 if (list) {
1101 len = gl_length(list);
1102 for (c=1;c<=len;c++) {
1103 i = (struct Instance *)gl_fetch(list,c);
1104 WriteInstanceName(stdout,i,NULL);
1105 FPRINTF(stdout,"\n");
1106 }
1107 }
1108 }
1109
1110 /*------------------------------------------------------------------------------
1111 PERSISTENCE FUNCTIONS
1112 */
1113
1114 /**
1115 @TODO the following mess o' save hacks deserves its own file.,
1116 probably a circular file.
1117 */
1118
1119 /** @TODO what is the status of this? A lot of unused functions here. */
1120
1121 /** @page instancepersistence "Saving/Restoring Instance Trees"
1122
1123 The below code is part of the code for saving/restoring instance
1124 trees. It thus allows the creation of persistent objects. At this
1125 time the format of the save_file is experimental, but has the
1126 following format:
1127 <pre>
1128 $DATE
1129 $VERSION
1130
1131 $TYPES {
1132 name : module ;
1133 [...]
1134 name : module ;
1135 }
1136
1137 $COMPLEX_INST index {
1138 type kind name nchildren/bytesize universal ;
1139 }
1140
1141 $ATOM_INST index {
1142 $VALUE : value units ';'
1143 type kind name value units ';' # -- for the atom children.
1144 type kind name value units ';'
1145 type kind name value units ';'
1146 }
1147
1148 $RELATION index { # -- optional
1149 $VALUE : value units ';'
1150 $VARIABLES :
1151 index -> index ,index [..] ,index ';'
1152 $CONSTANTS :
1153 index -> index ,index [..] ,index ';'
1154 $OPCODES :
1155 index -> index ,index [..] ,index ';'
1156 }
1157
1158
1159 $LRELATION index { # -- optional
1160 $BVARIABLES :
1161 index -> index ,index [..] ,index ';'
1162 $BCONSTANTS :
1163 index -> index ,index [..] ,index ';'
1164 $LOPCODES :
1165 index -> index ,index [..] ,index ';'
1166 }
1167
1168
1169 $GRAPH {
1170 index -> index ,index [..] ,index ';'
1171 [...]
1172 index -> index ,index [..] ,index ';'
1173 }
1174
1175 $CLIQUES {
1176 index -> index ,index [..] ,index ';'
1177 [...]
1178 index -> index ,index [..] ,index ';'
1179 }
1180 </pre>
1181 */
1182
1183 #define TYPE_HASH_SIZE 31
1184
1185 static int CmpDescPtrs(VOIDPTR d1, VOIDPTR d2)
1186 {
1187 return (d1 < d2) ? -1 : ((d1 == d2) ? 0 : 1);
1188 }
1189
1190 static
1191 int ProcessArrayDesc(struct gl_list_t *arraytypelist,
1192 CONST struct TypeDescription *desc)
1193 {
1194 struct TypeDescription *tmp;
1195
1196 /* FIXME how can you cast an array index to a pointer??? */
1197 tmp = (struct TypeDescription *)gl_search(arraytypelist,(VOIDPTR)desc,
1198 (CmpFunc)CmpDescPtrs);
1199 if (tmp==NULL) {
1200 gl_append_ptr(arraytypelist,(VOIDPTR)desc);
1201 return 1; /* indicate if we added or not */
1202 }
1203 return 0; /* indicate if we added or not */
1204 }
1205
1206 /**
1207 Collect a unique list of the types present in the instance
1208 tree (which is stored in the list). We will *not* store
1209 typedescriptions, with NULL names; This can happen in the case
1210 of array types. We could probably filter here for all fundamental
1211 types in fact.
1212
1213 At this time we are doing a hack in type_desc.c to *ensure*
1214 that the arrays have names. This means that name should not
1215 come up NULL *ever* in the type table. If it does, its an
1216 error. We now instead scan for base_types, so that we can
1217 write out some index stuff for arrays.
1218
1219 (BAA: the hack has been institutionalized as MAKEARRAYNAMES
1220 in type_desc.h)
1221 */
1222 static int DoBreakPoint(void)
1223 {
1224 return 1;
1225 }
1226
1227 static
1228 void CollectTypes(struct Table *table,struct gl_list_t *list,
1229 struct gl_list_t *arraytypelist)
1230 {
1231 CONST struct TypeDescription *desc;
1232 char *name;
1233 struct Instance *inst;
1234 enum type_kind kind;
1235 unsigned long len,c;
1236
1237 len = gl_length(list);
1238 for (c=1;c<=len;c++) {
1239 inst = (struct Instance *)gl_fetch(list,c);
1240 desc = InstanceTypeDesc(inst);
1241 name = (char *)SCP(GetName(desc));
1242 if (name==NULL) {
1243 FPRINTF(ASCERR,"Unknown type with no name in instance tree\n");
1244 DoBreakPoint(); /* later we will punt here */
1245 }
1246 kind = GetBaseType(desc);
1247 if (kind==array_type) {
1248 (void)ProcessArrayDesc(arraytypelist,desc);
1249 } else {
1250 AddTableData(table,(void *)desc,name);
1251 }
1252 }
1253 }
1254
1255
1256 static
1257 void WriteIntegrityCheck(FILE *fp, unsigned long count)
1258 {
1259 CONST char *timestring = "not_yet_fiqured_out";
1260 FPRINTF(fp,"$CHECKSUM {\n");
1261 FPRINTF(fp,"\t$DATE \'%s\';\n",timestring);
1262 FPRINTF(fp,"\t$VERSION 1;\n");
1263 FPRINTF(fp,"\t$COUNT %lu;\n",count);
1264 FPRINTF(fp,"}\n\n");
1265 }
1266
1267 /**
1268 Some special care in processing is required here.
1269 The name of the type may be NULL, as in the case of arrays.
1270 The module of the type may be NULL, as in the case of
1271 fundamentals. In collecting the typelist and building the
1272 type table we took care of the NULL type names. We will
1273 write out NULL for types with NULL modules.
1274 NOTE: The module names are written out as single-quoted strings.
1275 NULL modules are simply written as NULL.
1276 */
1277 static
1278 void Save__Types(void *arg1, void *arg2)
1279 {
1280 CONST struct TypeDescription *desc = (CONST struct TypeDescription *)arg1;
1281 FILE *fp = (FILE *)arg2;
1282 symchar *type;
1283 CONST char *module;
1284 struct module_t *mod;
1285
1286 type = GetName(desc);
1287 if (type==NULL) return;
1288 mod = GetModule(desc);
1289 if (mod) {
1290 module = Asc_ModuleName(mod);
1291 FPRINTF(fp,"\t%s : \'%s\';\n",SCP(type),module);
1292 }
1293 else{
1294 FPRINTF(fp,"\t%s : NULL;\n",SCP(type));
1295 }
1296 }
1297
1298 static
1299 void SaveTypes(FILE *fp, struct Table *table)
1300 {
1301 FPRINTF(fp,"$TYPEDESC {\n");
1302 TableApplyAllTwo(table,Save__Types,(void *)fp);
1303 FPRINTF(fp,"}\n\n");
1304 }
1305
1306
1307
1308 #ifdef THIS_IS_AN_UNUSED_FUNCTION
1309 /*
1310 * These functions are concerned with saving arraytypes
1311 * in our special format.
1312 */
1313 static
1314 void SaveIndexList(FILE *fp, struct IndexType *itype)
1315 {
1316 CONST struct Set *sptr, *tmp;
1317 tmp = sptr = GetIndexSet(itype);
1318 /* lots of crappy assumptions here.... */
1319 while (tmp) {
1320 WriteSetNode(fp,tmp);
1321 tmp = NextSet(tmp);
1322 if (tmp)
1323 FPRINTF(fp,", ");
1324 }
1325 }
1326 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
1327
1328 /**
1329 SYNTAX:
1330 arraydef : ARRAYTYPE IDENTIFIER '{' mandatory optional '}'
1331 ;
1332 mandatory: TYPE SYMBOL ',' COUNT INTEGER ';'
1333 ;
1334 optional: (INDEX INTEGER ':' string)* (i.e one or more)
1335
1336 @NOTE It is possible for array to *not* have any indicies.
1337 This can happen for example, when the result of the set
1338 evaluation comes up NULL;
1339 <pre>
1340 foo[fooset] IS_A FOO;
1341 fooset := [];
1342 </pre>
1343 This code appropriately deals with these odd cases.
1344 @ENDNOTE
1345
1346 @NOTE (is that you, Ben?)
1347 You would not believe the stuff that is returned as a
1348 result of this code. Yep the above note about evaluation
1349 is rubbish. What is saved is the index set as found verbatim.
1350 Using the above example what is seens is "fooset". Likewise
1351 if we had foo2[alpha - [beta]], where alpha and beta are
1352 sets, what we see is "alpha [beta] -". I am leaving this
1353 code here for posterity. This craziness might just come in
1354 handy. For example it makes a comparison of 2 index sets
1355 very quick, rather than if we had saved the result of
1356 the evaluations.
1357 */
1358 static
1359 void Save__ArrayTypes(FILE *fp,struct TypeDescription *desc)
1360 {
1361 CONST struct TypeDescription *basetype;
1362 CONST char *tmp;
1363 struct gl_list_t *indexlist;
1364 struct IndexType *itype;
1365 unsigned long len,c;
1366
1367 tmp = SCP(GetName(desc)); /* dump header */
1368 FPRINTF(fp,"$ARRAYTYPE %s {\n",tmp);
1369 basetype = GetArrayBaseType(desc);
1370 assert(basetype!=NULL);
1371 FPRINTF(fp,"\t$TYPE %s, \n",SCP(GetName(basetype)));
1372
1373 indexlist = GetArrayIndexList(desc); /* save index lists strings */
1374 if (!indexlist) {
1375 FPRINTF(fp,"$COUNT 0;\n");
1376 goto trailer;
1377 }
1378 len = gl_length(indexlist);
1379 FPRINTF(fp,"$COUNT %lu;\n",len);
1380 for (c=1;c<=len;c++) {
1381 itype = (struct IndexType *)gl_fetch(indexlist,c);
1382 tmp = SCP(GetIndexSetStr(itype));
1383 assert(tmp!=NULL);
1384 FPRINTF(fp,"\t$INDEXES %lu : \"%s\";\n",c,tmp);
1385 }
1386 trailer: /* dump trailer */
1387 FPRINTF(fp,"}\n\n");
1388 }
1389
1390 static
1391 void SaveArrayTypes(FILE *fp,struct gl_list_t *arraytypelist)
1392 {
1393 struct TypeDescription *desc;
1394 unsigned long len,c;
1395 len = gl_length(arraytypelist);
1396 for (c=1;c<=len;c++) {
1397 desc = (struct TypeDescription *)gl_fetch(arraytypelist,c);
1398 Save__ArrayTypes(fp,desc);
1399 }
1400 }
1401
1402 /**
1403 Write a comma-delimited list of children names.
1404 The caller must add own leaders/trailers.
1405 */
1406 static
1407 void SaveNameRec(FILE *f, CONST struct InstanceName *rec)
1408 {
1409 switch(InstanceNameType(*rec)){
1410 case IntArrayIndex:
1411 FPRINTF(f,"%ld",InstanceIntIndex(*rec));
1412 break;
1413 case StrArrayIndex:
1414 FPRINTF(f,"'%s'",SCP(InstanceStrIndex(*rec)));
1415 break;
1416 case StrName:
1417 FPRINTF(f,"%s",SCP(InstanceNameStr(*rec)));
1418 break;
1419 }
1420 }
1421
1422 static
1423 void Save__ChildrenNames(FILE *fp, struct Instance *inst)
1424 {
1425 unsigned long nch,c;
1426 struct InstanceName rec;
1427
1428 nch = NumberChildren(inst);
1429 if (nch) {
1430 rec = ChildName(inst,1);
1431 SaveNameRec(fp,&rec);
1432 }
1433 for (c=2;c<=nch;c++) { /* notreached for nch < 2 */
1434 FPRINTF(fp," ,");
1435 rec = ChildName(inst,c);
1436 SaveNameRec(fp,&rec);
1437 }
1438 }
1439
1440
1441 static
1442 void Save__ComplexInsts(FILE *fp, struct Instance *inst)
1443 {
1444 CONST struct TypeDescription *desc;
1445 symchar *type;
1446 enum inst_t kind;
1447 unsigned long count;
1448 unsigned int universal, intset = 0;
1449
1450 kind = InstanceKind(inst);
1451 desc = InstanceTypeDesc(inst);
1452 universal = GetUniversalFlag(desc);
1453
1454 switch (kind) {
1455 case SET_ATOM_INST:
1456 intset = GetSetAtomKind(inst);
1457 type = InstanceType(inst);
1458 count = GetByteSize(desc);
1459 FPRINTF(fp,"\t$KIND %d, $TYPE %s, $COUNT %lu;\n",
1460 (int)kind, SCP(type), count);
1461 if (universal)
1462 FPRINTF(fp,"\t$UNIVCHILD %d;\n",universal);
1463 if (intset)
1464 FPRINTF(fp,"\t$INTSET %d;\n",intset);
1465 break;
1466 case REAL_CONSTANT_INST:
1467 case BOOLEAN_CONSTANT_INST:
1468 case INTEGER_CONSTANT_INST:
1469 case SYMBOL_CONSTANT_INST:
1470 case REAL_ATOM_INST:
1471 case BOOLEAN_ATOM_INST:
1472 case INTEGER_ATOM_INST:
1473 case SYMBOL_ATOM_INST:
1474 case LREL_INST:
1475 case REL_INST:
1476 type = InstanceType(inst);
1477 count = GetByteSize(desc);
1478 FPRINTF(fp,"\t$KIND %d, $TYPE %s, $COUNT %lu;\n",
1479 (int)kind, SCP(type), count);
1480 if (universal)
1481 FPRINTF(fp,"\t$UNIVCHILD %d;\n",universal);
1482 break;
1483 case SIM_INST:
1484 case MODEL_INST:
1485 type = InstanceType(inst);
1486 count = NumberChildren(inst);
1487 FPRINTF(fp,"\t$KIND %d, $TYPE %s, $COUNT %lu;\n",
1488 (int)kind, SCP(type), count);
1489 if (universal)
1490 FPRINTF(fp,"\t$UNIVCHILD %d;\n",universal);
1491 break;
1492 case ARRAY_ENUM_INST:
1493 case ARRAY_INT_INST:
1494 type = GetName(desc);
1495 count = NumberChildren(inst);
1496 FPRINTF(fp,"\t$KIND %d, $TYPE %s, $COUNT %lu;\n",
1497 (int)kind, SCP(type), count);
1498 desc = GetArrayBaseType(desc);
1499 type = GetName(desc);
1500 FPRINTF(fp,"\t$BASETYPE %s;\n",SCP(type)); /* the base type */
1501 if (universal)
1502 FPRINTF(fp,"\t$UNIVCHILD %d;\n",universal);
1503 if (0 != (count=NumberofDereferences(inst)))
1504 FPRINTF(fp,"\t$INDIRECT %lu;\n",count);
1505 FPRINTF(fp,"\t$INDEXES : ");
1506 Save__ChildrenNames(fp,inst);
1507 FPRINTF(fp,";\n");
1508 break;
1509 case REAL_INST:
1510 case BOOLEAN_INST:
1511 case INTEGER_INST:
1512 case SET_INST:
1513 break;
1514 case DUMMY_INST:
1515 FPRINTF(fp,"UNSELECTED;\n");
1516 break;
1517 default:
1518 ASC_PANIC("Unknown instance kind in Save__ComplexInsts.");
1519 break;
1520 }
1521 }
1522
1523 static
1524 void SaveComplexInsts(FILE *fp, struct gl_list_t *list)
1525 {
1526 unsigned long len, c;
1527 struct Instance *inst;
1528
1529 len = gl_length(list);
1530 for (c=1;c<=len;c++) {
1531 FPRINTF(fp,"$COMPLEX_INST %lu {\n",c);
1532 inst = (struct Instance *)gl_fetch(list,c);
1533 Save__ComplexInsts(fp,inst);
1534 FPRINTF(fp,"}\n\n");
1535 }
1536 }
1537
1538 #ifdef THIS_IS_AN_UNUSED_FUNCTION
1539 static
1540 void SaveRelations(FILE *fp, struct gl_list_t *list)
1541 {
1542 unsigned long len, c;
1543 struct Instance *relinst;
1544 enum Expr_enum type;
1545
1546
1547 len = gl_length(list);
1548
1549 for (c=1;c<=len;c++) {
1550 relinst = (struct Instance *)gl_fetch(list,c);
1551 if (InstanceKind(relinst)!=REL_INST)
1552 continue;
1553 type = GetInstanceRelationType(relinst);
1554 switch (type) {
1555 case e_token:
1556 SaveTokenRelation(fp,relinst);
1557 break;
1558 case e_opcode:
1559 case e_blackbox:
1560 FPRINTF(ASCERR,"Saving blackbox relations not supported\n");
1561 break;
1562 case e_glassbox:
1563 default:
1564 SaveGlassBoxRelation(fp,relinst);
1565 break;
1566 }
1567 }
1568 }
1569 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
1570
1571
1572 static
1573 void SaveLogRelations(FILE *fp, struct gl_list_t *list)
1574 {
1575 unsigned long len, c;
1576 struct Instance *lrelinst;
1577
1578 len = gl_length(list);
1579
1580 for (c=1;c<=len;c++) {
1581 lrelinst = (struct Instance *)gl_fetch(list,c);
1582 if (InstanceKind(lrelinst)!=LREL_INST)
1583 continue;
1584 SaveLogRel(fp,lrelinst);
1585 }
1586 }
1587
1588
1589 #ifdef THIS_IS_AN_UNUSED_FUNCTION
1590 static
1591 void Save__Atoms(FILE *fp, struct Instance *inst)
1592 {
1593 CONST struct Instance *child;
1594 enum inst_t kind;
1595 unsigned long len,c,index;
1596
1597 kind = InstanceKind(inst);
1598 switch (kind) {
1599 default:
1600 return;
1601 case REAL_CONSTANT_INST:
1602 case BOOLEAN_CONSTANT_INST:
1603 case INTEGER_CONSTANT_INST:
1604 case SYMBOL_CONSTANT_INST:
1605 case REAL_ATOM_INST:
1606 case BOOLEAN_ATOM_INST:
1607 case INTEGER_ATOM_INST:
1608 case SET_ATOM_INST:
1609 case SYMBOL_ATOM_INST:
1610 case REL_INST:
1611 case LREL_INST:
1612 case DUMMY_INST:
1613 break;
1614 }
1615 index = GetTmpNum(inst);
1616 FPRINTF(fp,"$ATOM_INST %lu {\n",index);
1617 FPRINTF(fp,"\t$VALUE : ");
1618 if (kind!=(REL_INST || LREL_INST)) {
1619 WriteAtomValue(fp,inst);
1620 } else {
1621 FPRINTF(fp,"$UNDEFINED");
1622 }
1623 FPRINTF(fp,";\n");
1624
1625 len = NumberChildren(inst);
1626 if (len) {
1627 for (c=1;c<=len;c++) {
1628 child = InstanceChild(inst,c);
1629 FPRINTF(fp,"\t%s ",InstanceType(child));
1630 WriteAtomValue(fp,child);
1631 FPRINTF(fp,";\n");
1632 }
1633 }
1634 FPRINTF(fp,"}\n\n");
1635 }
1636 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
1637
1638
1639 #ifdef THIS_IS_AN_UNUSED_FUNCTION
1640 static
1641 void SaveAtoms(FILE *fp, struct gl_list_t *list)
1642 {
1643 struct Instance *inst;
1644 unsigned long len,c;
1645
1646 len = gl_length(list);
1647 for (c=1;c<=len;c++) {
1648 inst = (struct Instance *)gl_fetch(list,c);
1649 Save__Atoms(fp,inst);
1650 }
1651 }
1652 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
1653
1654
1655 static
1656 void Save__Link(FILE *fp,CONST struct Instance *inst)
1657 {
1658 CONST struct Instance *child;
1659 unsigned long int nch,c,tindex;
1660
1661 nch = NumberChildren(inst);
1662 if (!nch) return;
1663
1664 tindex = GetTmpNum(inst);
1665 FPRINTF(fp,"$GRAPH %lu {\n",tindex);
1666 FPRINTF(fp,"\t%lu -> ",tindex); /* parent tindex */
1667 child = InstanceChild(inst,1); /* treat the first child */
1668 FPRINTF(fp,"%lu",GetTmpNum(child)); /* specially. */
1669 for (c=2;c<=nch;c++) {
1670 child = InstanceChild(inst,c); /* not reached if nch = 1 */
1671 FPRINTF(fp,",%lu",GetTmpNum(child));
1672 }
1673 FPRINTF(fp,";\n");
1674 FPRINTF(fp,"}\n\n");
1675 }
1676
1677
1678 static
1679 void SaveLinks(FILE *fp, struct gl_list_t *list)
1680 {
1681 CONST struct Instance *inst;
1682 unsigned long len,c;
1683
1684 len = gl_length(list);
1685 for (c=1;c<=len;c++) {
1686 inst = (CONST struct Instance *)gl_fetch(list,c);
1687 switch (InstanceKind(inst)) {
1688 case SIM_INST:
1689 case MODEL_INST:
1690 case ARRAY_ENUM_INST:
1691 case ARRAY_INT_INST:
1692 Save__Link(fp,inst);
1693 break;
1694 default:
1695 break;
1696 }
1697 }
1698 }
1699
1700 /*
1701 These functions save the connectivity graph as 1 huge
1702 node of all connections. It is useful for doing graph
1703 algorithms. For saving instances though it is perhaps
1704 better to use SaveLinks.
1705 */
1706 #ifdef THIS_IS_AN_UNUSED_FUNCTION
1707 static
1708 void Save__Graph(FILE *fp, struct gl_list_t *list)
1709 {
1710 CONST struct Instance *inst;
1711 CONST struct Instance *child;
1712 unsigned long len,c,cc,nch,index;
1713
1714 len = gl_length(list);
1715 for (c=1;c<=len;c++) {
1716 inst = (CONST struct Instance *)gl_fetch(list,c);
1717 switch (InstanceKind(inst)) {
1718 case SIM_INST:
1719 case MODEL_INST:
1720 case ARRAY_ENUM_INST:
1721 case ARRAY_INT_INST:
1722 nch = NumberChildren(inst);
1723 if (!nch) break;
1724 index = GetTmpNum(inst);
1725 FPRINTF(fp,"\t%lu -> ",index); /* parent index */
1726 child = InstanceChild(inst,1); /* treat the first child */
1727 FPRINTF(fp,"%lu",GetTmpNum(child)); /* specially. */
1728 for (cc=2;cc<=nch;cc++) {
1729 child = InstanceChild(inst,cc); /* not reached if nch = 1 */
1730 FPRINTF(fp,",%lu",GetTmpNum(child));
1731 }
1732 FPRINTF(fp,";\n");
1733 break;
1734 default:
1735 break;
1736 }
1737 }
1738 }
1739 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
1740
1741
1742 #ifdef THIS_IS_AN_UNUSED_FUNCTION
1743 static
1744 void SaveGraph(FILE *fp, struct gl_list_t *list)
1745 {
1746 FPRINTF(fp,"$GRAPH {\n");
1747 Save__Graph(fp,list);
1748 FPRINTF(fp,"}\n\n");
1749 }
1750 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
1751
1752
1753 static
1754 void SaveCliques(FILE *fp, struct gl_list_t *list)
1755 {
1756 CONST struct Instance *inst;
1757 CONST struct Instance *ptr;
1758 unsigned long len,c,start,tindex;
1759
1760 len = gl_length(list);
1761
1762 for (c=1;c<=len;c++) {
1763 inst = (CONST struct Instance *)gl_fetch(list,c);
1764 ptr = inst;
1765 if (NextCliqueMember(ptr)!=ptr) {
1766 start = GetTmpNum(ptr); /* head of clique */
1767 FPRINTF(fp,"$CLIQUE %lu {\n",start);
1768 FPRINTF(fp,"\t%lu -> ",start);
1769 do {
1770 ptr = NextCliqueMember(ptr);
1771 tindex = GetTmpNum(ptr);
1772 if (tindex)
1773 FPRINTF(fp,"%lu ",tindex); /* white space delimited */
1774 } while (ptr!=inst);
1775 FPRINTF(fp,";\n");
1776 FPRINTF(fp,"}\n\n");
1777 }
1778 }
1779 }
1780
1781 void SaveInstance(FILE *fp, CONST struct Instance *i,
1782 int dorelations)
1783 {
1784 struct gl_list_t *list;
1785 struct gl_list_t *arraytypelist;
1786 struct Table *table = NULL;
1787 unsigned long len;
1788
1789 (void)dorelations; /* stop gcc whine about unused parameter */
1790
1791 if (!i) {
1792 return;
1793 }
1794
1795 list = gl_create(1000L);
1796 arraytypelist = gl_create(50L);
1797 VisitInstanceTreeTwo((struct Instance *)i,(VisitTwoProc)CollectNodes,
1798 1,0,(void *)list);
1799 len = gl_length(list);
1800
1801 if (!len) {
1802 goto error;
1803 }
1804 table = CreateTable((unsigned long)TYPE_HASH_SIZE);
1805 CollectTypes(table,list,arraytypelist);
1806 WriteIntegrityCheck(fp,len);
1807 SaveTypes(fp,table);
1808 SaveArrayTypes(fp,arraytypelist);
1809 SaveComplexInsts(fp,list);
1810 /* SaveAtoms(fp,list); FIX FIX FIX */
1811 SaveLogRelations(fp,list);
1812 SaveLinks(fp,list);
1813 SaveCliques(fp,list);
1814
1815 error:
1816 gl_destroy(list);
1817 gl_destroy(arraytypelist);
1818 DestroyTable(table,0);
1819 }
1820
1821 /**
1822 interface pointer bulk transport to a stack functions
1823 */
1824 struct pipdata {
1825 IPFunc makeip;
1826 struct gl_list_t *old;
1827 void *userdata;
1828 VOIDPTR vp;
1829 };
1830
1831 #define PDC(x) ((struct pipdata *)(x))
1832 static void CollectIpData(struct Instance *i, void *d)
1833 {
1834 if (i!= NULL) {
1835 PDC(d)->userdata = PDC(d)->makeip(i,PDC(d)->vp);
1836 if (PDC(d)->userdata!=NULL) {
1837 gl_append_ptr(PDC(d)->old,(VOIDPTR)i);
1838 gl_append_ptr(PDC(d)->old,(VOIDPTR)GetInterfacePtr(i));
1839 SetInterfacePtr(i,PDC(d)->userdata);
1840 }
1841 }
1842 }
1843
1844 struct gl_list_t *PushInterfacePtrs(struct Instance *i, IPFunc makeip,
1845 unsigned long iest,int visit,VOIDPTR vp)
1846 {
1847 struct pipdata pip;
1848 /* use iest to get an initial list capacity so we don't go
1849 * into list expansion fits with the allocator.
1850 */
1851 if (iest <10) iest = 10;
1852 pip.old = gl_create(2*iest);
1853 if (pip.old == NULL) {
1854 FPRINTF(ASCERR,"Error PushInterfacePtrs out of memory.\n");
1855 return NULL;
1856 }
1857 pip.makeip = makeip;
1858 pip.vp = vp;
1859 if (pip.makeip == NULL) {
1860 FPRINTF(ASCERR,"Error in PushInterfacePtrs call.\n");
1861 return NULL;
1862 }
1863 /* do the stuff */
1864 SilentVisitInstanceTreeTwo(i,CollectIpData,visit,0,(VOIDPTR)&pip);
1865 return pip.old;
1866 }
1867
1868 /* The list old contains in odd entries the instance pointers,
1869 * and in the succeeding even entries, the old interface pointer
1870 * for that preceeding odd entry.
1871 */
1872
1873 void PopInterfacePtrs(struct gl_list_t *old, IPDeleteFunc destroy, VOIDPTR vp)
1874 {
1875 unsigned long c,len;
1876 struct Instance *i;
1877 if (old==NULL) return; /* should whine here */
1878 len = gl_length(old);
1879 if (destroy != NULL) {
1880 for (c=1; c<=len; c+=2) {
1881 i = (struct Instance *)gl_fetch(old,c);
1882 destroy(i, GetInterfacePtr(i),vp);
1883 SetInterfacePtr(i,gl_fetch(old,c+1));
1884 }
1885 } else {
1886 for (c=1; c<=len; c+=2) {
1887 SetInterfacePtr((struct Instance *)gl_fetch(old,c),gl_fetch(old,c+1));
1888 }
1889 }
1890 gl_destroy(old);
1891 }
1892
1893 /**
1894 @TODO is this file the right place for ArrayIsRelation, ArrayIsLogRel, etc?
1895 */
1896
1897 /**
1898 Makes the assumption that the instance sent is not null
1899 and that array children for relations are all of the same
1900 type so that I can look at the first child only. Added to code
1901 to take care of empty sets -- resulting in 0 children.
1902 */
1903 int ArrayIsRelation(struct Instance *i)
1904 {
1905 if (i==NULL) return 0;
1906 /* skip past all the indirection */
1907 while( (InstanceKind(i)==ARRAY_INT_INST) ||
1908 (InstanceKind(i)==ARRAY_ENUM_INST) ) {
1909 if (NumberChildren(i)==0) break;
1910 i = InstanceChild(i,1L);
1911 }
1912 if (InstanceKind(i)==REL_INST) return 1; else return 0;
1913 }
1914
1915
1916 int ArrayIsLogRel(struct Instance *i)
1917 {
1918 if (i==NULL) return 0;
1919 /* skip past all the indirection */
1920 while( (InstanceKind(i)==ARRAY_INT_INST) ||
1921 (InstanceKind(i)==ARRAY_ENUM_INST) ) {
1922 if (NumberChildren(i)==0) break;
1923 i = InstanceChild(i,1L);
1924 }
1925 if (InstanceKind(i)==LREL_INST) return 1; else return 0;
1926 }
1927
1928 int ArrayIsWhen(struct Instance *i)
1929 {
1930 if (i==NULL) return 0;
1931 /* skip past all the indirection */
1932 while( (InstanceKind(i)==ARRAY_INT_INST) ||
1933 (InstanceKind(i)==ARRAY_ENUM_INST) ) {
1934 if (NumberChildren(i)==0) break;
1935 i = InstanceChild(i,1L);
1936 }
1937 if (InstanceKind(i)==WHEN_INST) return 1; else return 0;
1938 }
1939
1940 int ArrayIsModel(struct Instance *i)
1941 {
1942 if (i==NULL) return 0;
1943 while( (InstanceKind(i)==ARRAY_INT_INST) ||
1944 (InstanceKind(i)==ARRAY_ENUM_INST) ) {
1945 if (NumberChildren(i)==0) break;
1946 i = InstanceChild(i,1L);
1947 }
1948 if (InstanceKind(i)==MODEL_INST) return 1; else return 0;
1949 }
1950
1951 /* vim: set ts=8 : */

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