Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / inf / inf_main.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI Alliance */
4 /* */
5 /* Produit : YAGLE v1.n */
6 /* Fichier : info.c */
7 /* */
8 /* (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI */
9 /* Tous droits reserves */
10 /* Support : e-mail cao-vlsi@masi.ibp.fr */
11 /* */
12 /* Auteur(s) : Marc LAURENTIN le : 06/09/1991 */
13 /* */
14 /* Modifie par : le : ../../.... */
15 /* Modifie par : le : ../../.... */
16 /* Modifie par : le : ../../.... */
17 /* */
18 /****************************************************************************/
19
20 #include <stdio.h>
21 #include <math.h>
22 #include <stdlib.h>
23 #include MUT_H
24 #include INF_H
25 #include AVT_H
26 #include "inf_grab.h"
27
28 //#define ONEINF
29
30 static void infCleanRegistry(inffig_list *ifl, int location);
31 void infrestart( FILE *input_file ) ;
32
33 extern FILE *infin;
34 extern int inflineno;
35
36 extern char INF_LANG;
37
38 int infParseLine, inf_ignorename=0;
39 static int INFDISPLAYLOAD=0;
40 int infparse();
41
42
43 static int STUCK_SECTION=INF_DEFAULT_LOCATION|INF_LOADED_LOCATION;
44
45 char *infFile, *infname;
46
47 int inf_StuckSection(int val)
48 {
49 int old=STUCK_SECTION;
50 STUCK_SECTION=val;
51 return old;
52 }
53
54 int inf_DisplayLoad(int val)
55 {
56 int old=INFDISPLAYLOAD;
57 INFDISPLAYLOAD=val;
58 return old;
59 }
60 /****************************************************************************
61 * fonction infRead(); *
62 ****************************************************************************/
63
64 /*-------------------------------*
65 | lit le fichier <filename.inf> |
66 *------------------------------*/
67 static ht *INF_HT=NULL;
68 inffig_list *INF_FIG;
69
70 int inf_getinffig_state(inffig_list *ifl)
71 {
72 return ifl->changed;
73 }
74
75 void inf_resetinffig_state(inffig_list *ifl)
76 {
77 ifl->changed=0;
78 }
79
80 inffig_list *getloadedinffig(char *name)
81 {
82 long l;
83
84 name=namealloc(name);
85
86 if (INF_HT==NULL) INF_HT=addht(16);
87 if ((l=gethtitem(INF_HT, name))==EMPTYHT) return NULL;
88 return (inffig_list *)l;
89 }
90
91 inffig_list *addinffig(char *name)
92 {
93 inffig_list *ifig;
94
95 name=namealloc(name);
96
97 if ((ifig=getloadedinffig(name))!=NULL)
98 delinffig(name);
99
100 ifig=(inffig_list *)mbkalloc(sizeof(inffig_list));
101 ifig->NAME=name;
102 ifig->USER=NULL;
103 ifig->changed=0;
104 addhtitem(INF_HT, name, (long)ifig);
105
106 memset(&ifig->DEFAULT, 0, sizeof(INF_INFOSET));
107 memset(&ifig->LOADED, 0, sizeof(INF_INFOSET));
108 return ifig;
109 }
110
111 void inf_renameinffig(char *orig, char *newname)
112 {
113 inffig_list *ifl;
114
115 if ((ifl=getloadedinffig(orig))!=NULL)
116 {
117 delhtitem(INF_HT, ifl->NAME);
118 ifl->NAME=namealloc(newname);
119 delinffig(ifl->NAME);
120 addhtitem(INF_HT, ifl->NAME, (long)ifl);
121 }
122 }
123
124 void infclone(char *name, inffig_list *ifig)
125 {
126 name=namealloc(name);
127
128 if (ifig==NULL) return;
129
130 addhtitem(INF_HT, name, (long)ifig);
131 }
132
133 void delinffig(char *name)
134 {
135 inffig_list *ifig;
136 chain_list *all, *cl;
137
138 name=namealloc(name);
139
140 if ((ifig=getloadedinffig(name))!=NULL)
141 {
142 // pour etre sure d'eliminer tous les clones pointant
143 // sur la meme inffig
144 all=GetAllHTKeys(INF_HT);
145 for (cl=all; cl!=NULL; cl=cl->NEXT)
146 {
147 if (gethtitem(INF_HT, cl->DATA)==(long)ifig)
148 delhtitem(INF_HT, cl->DATA);
149 }
150 freechain(all);
151 // ---------
152
153 infClean(ifig, INF_LOADED_LOCATION);
154 if (ifig->LOADED.REGISTRY!=NULL) delht(ifig->LOADED.REGISTRY);
155 infClean(ifig, INF_DEFAULT_LOCATION);
156 if (ifig->DEFAULT.REGISTRY!=NULL) delht(ifig->DEFAULT.REGISTRY);
157 freeptype(ifig->USER);
158 mbkfree(ifig);
159 // delhtitem(INF_HT, name);
160 }
161 }
162
163 inffig_list *getinffig(char *name)
164 {
165 inffig_list *ifl;
166 ptype_list *pt=NULL;
167
168 if ((ifl=getloadedinffig(name))==NULL
169 || (pt=getptype(ifl->USER, INF_IS_DIRTY))!=NULL
170 || getptype(ifl->USER,INF_LOADED_FROM_DISK)==NULL
171 )
172 {
173 ifl=infRead(name, 1);
174 // if (pt!=NULL && ifl!=NULL) ifl->USER=delptype(ifl->USER, INF_IS_DIRTY);
175 }
176
177 return ifl;
178 }
179
180 static chain_list *Hidden=NULL;
181
182 static int countwild(char *val)
183 {
184 int i, cnt=0;
185 for (i=0;val[i]!='\0';i++) if (val[i]!='*') cnt++;
186 return cnt;
187 }
188 static int infsortnames(const void *a0, const void *b0)
189 {
190 char *a=*(char **)a0, *b=*(char **)b0;
191 int ca, cb;
192 ca=countwild(a);
193 cb=countwild(b);
194 if (strcmp(a,"default")==0)
195 {
196 if (a==b) return 0;
197 return 1;
198 }
199 if (strcmp(b,"default")==0)
200 {
201 if (a==b) return 0;
202 return -1;
203 }
204 if (ca>cb) return -1;
205 if (ca<cb) return 1;
206 return strcmp(a, b);
207 }
208
209 chain_list *inf_SortEntries(chain_list *cl)
210 {
211 int nb, i;
212 char **tab;
213 chain_list *ch;
214 nb=countchain(cl);
215 tab=mbkalloc(sizeof(char *)*nb);
216 for (i=0, ch=cl;i<nb; ch=ch->NEXT, i++) tab[i]=(char *)ch->DATA;
217
218 qsort(tab, nb, sizeof(char *), infsortnames);
219
220 for (i=0, ch=cl;i<nb; ch=ch->NEXT, i++) ch->DATA=tab[i];
221 mbkfree(tab);
222 return cl;
223 }
224
225 void inf_PushAndHideInf(char *name)
226 {
227 inffig_list *ifl;
228
229 if ((ifl=getloadedinffig(name))!=NULL)
230 {
231 delhtitem(INF_HT, ifl->NAME);
232 Hidden=addchain(Hidden, ifl);
233 }
234 else
235 Hidden=addchain(Hidden, NULL);
236 }
237
238 void inf_PopInf()
239 {
240 inffig_list *ifl;
241
242 if (Hidden!=NULL)
243 {
244 ifl=(inffig_list *)Hidden->DATA;
245 if (ifl!=NULL) addhtitem(INF_HT, ifl->NAME, (long)ifl);
246 Hidden=delchain(Hidden, Hidden);
247 }
248 }
249
250 void inf_Dirty(char *name)
251 {
252 chain_list *cl, *all;
253 inffig_list *ifl;
254 if (name==NULL)
255 all=GetAllHTElems(INF_HT);
256 else
257 {
258 if ((ifl=getloadedinffig(name))!=NULL)
259 all=addchain(NULL, ifl);
260 else
261 return;
262 }
263 for (cl=all; cl!=NULL; cl=cl->NEXT)
264 {
265 ifl=(inffig_list *)cl->DATA;
266 infClean(ifl, INF_LOADED_LOCATION);
267 if (getptype(ifl->USER, INF_IS_DIRTY)==NULL)
268 ifl->USER=addptype(ifl->USER, INF_IS_DIRTY, NULL);
269 }
270 freechain(all);
271 }
272
273 extern int infdebug;
274
275 inffig_list *_infRead(char *figname, char *filename, char silent)
276 {
277 static int vierge = 1 ;
278 char buf[1024];
279
280 INF_LANG = 'E';
281 sprintf (buf, "%s", filename);
282 infFile = buf;
283
284 // if (vierge == 0) infclean();
285 infin = mbkfopen(filename, NULL, READ_TEXT);
286 if (infin != NULL)
287 {
288 infParseLine = 1;
289 if (vierge == 0) infrestart(infin) ;
290 vierge = 0 ;
291 INF_ERROR = 0;
292 INF_FIG=NULL;
293 infname=namealloc(figname);
294 // infdebug=1;
295 infparse();
296 fclose(infin) ;
297 if (INFDISPLAYLOAD) avt_error("inf", -1, AVT_INFO, "loading '%s' ... %s\n", filename, INF_ERROR?"failed":"ok");
298 if ((silent & INF_DONTLOG)==0 && AVTLOGFILE!=NULL)
299 {
300 #if 0
301 fprintf(AVTLOGFILE, ">>>> STATE OF INF FOR FIGURE '%s' AFTER READING FILE '%s'\n\n", INF_FIG==NULL||inf_ignorename?infname:INF_FIG->NAME, filename);
302 if (INF_FIG!=NULL) infDrive(INF_FIG, NULL, INF_LOADED_LOCATION|INF_DEFAULT_LOCATION, AVTLOGFILE);
303 fprintf(AVTLOGFILE, "\n<<<<\n\n");
304 #else
305 avt_log(LOGCONFIG, 1, "Loading information file '%s' for figure '%s'\n", filename, INF_FIG==NULL||inf_ignorename?infname:INF_FIG->NAME);
306
307 infin = mbkfopen(filename, NULL, READ_TEXT);
308 if (infin != NULL)
309 {
310 mbk_dumpfile(infin, AVTLOGFILE, 9);
311 fclose(infin);
312 }
313
314 avt_log(LOGCONFIG, 1, " -- Current information taken from inf file --\n");
315 inf_set_print_mode(1);
316 infDrive (INF_FIG, "dummy", INF_LOADED_LOCATION, AVTLOGFILE);
317 inf_set_print_mode(0);
318 avt_log(LOGCONFIG, 1, " -- End --\n");
319
320 #endif
321 }
322 return INF_FIG;//getloadedinffig(namealloc(filename));
323 }
324 else
325 if (!(silent & 1))
326 avt_errmsg(INF_ERRMSG, "012", AVT_WARNING, filename);
327 // avt_error("inf", 1, AVT_WAR, "can not open '%s' information file\n", filename);
328 return NULL;
329 }
330
331 static chain_list *inf_split(char *varname)
332 {
333 char *str;
334 char *l, *tmp;
335 char buf[1024];
336 chain_list *cl=NULL;
337
338 str=avt_gethashvar(varname);
339 if (str!=NULL)
340 {
341 strcpy(buf,str);
342 l=strtok_r(buf, ",", &tmp);
343 do
344 {
345 cl=addchain(cl, mbkstrdup(l));
346 l=strtok_r(NULL, ",", &tmp);
347 } while (l!=NULL);
348 }
349 return reverse(cl);
350 }
351
352 static void inf_freechain(chain_list *cl)
353 {
354 chain_list *ch;
355 for (ch=cl; ch!=NULL; ch=ch->NEXT)
356 mbkfree(ch->DATA);
357 freechain(cl);
358 }
359
360
361 char *inf_GetDefault_AVT_INF_Value()
362 {
363 if (mbk_GetREGEXMODE()=='C')
364 return "$\\.spice\\.inf,$\\.sdc\\.inf,$\\.inf";
365 else
366 return "$.spice.inf,$.sdc.inf,$.inf";
367 }
368
369 inffig_list *infRead(char *name, char silent)
370 {
371 chain_list *regx, *files, *cl;
372 inffig_list *ifl;
373
374 regx=inf_split("AVT_INF");
375 if (regx==NULL) return getloadedinffig(namealloc(name));
376
377 files=BuildFileList(name, regx, 0);
378 inf_freechain(regx);
379
380
381 if (!(files!=NULL && files->NEXT==NULL && strcasecmp(files->DATA, "no")==0))
382 {
383 for (cl=files; cl!=NULL; cl=cl->NEXT)
384 {
385 ifl=_infRead(name, (char *)cl->DATA, silent);
386 }
387 }
388 inf_freechain(files);
389 return getloadedinffig(namealloc(name));
390 }
391
392
393 /*
394 static void double_list_clean(chain_list **ch)
395 {
396 chain_list *ptchain;
397 for (ptchain = *ch; ptchain; ptchain = ptchain->NEXT) {
398 freechain((chain_list *)ptchain->DATA);
399 }
400 freechain(*ch);
401 *ch=NULL;
402 }
403 */
404 static void ptype_list_clean(chain_list **ch)
405 {
406 chain_list *ptchain;
407 for (ptchain = *ch; ptchain; ptchain = ptchain->NEXT) {
408 freeptype((ptype_list *)ptchain->DATA);
409 }
410 freechain(*ch);
411 *ch=NULL;
412 }
413
414 void infClean(inffig_list *ifl, int location)
415 {
416 INF_INFOSET *is;
417
418 if (location==INF_DEFAULT_LOCATION)
419 is=&ifl->DEFAULT;
420 else
421 is=&ifl->LOADED;
422
423 ptype_list_clean(&is->INF_FALSEPATH);
424 ptype_list_clean(&is->INF_FALSESLACK);
425
426 infCleanRegistry(ifl, location);
427 }
428
429 static chain_list *merge_chain(chain_list *first, chain_list *second, int checkdup)
430 {
431 chain_list *res, *cl;
432
433 res=NULL;
434 for (cl=first; cl!=NULL; cl=cl->NEXT) res=addchain(res, cl->DATA);
435 while (second!=NULL)
436 {
437 if (checkdup)
438 {
439 for (cl=first; cl!=NULL; cl=cl->NEXT)
440 if (cl->DATA==second->DATA) break;
441 }
442 else
443 cl=NULL;
444 if (cl==NULL)
445 res=addchain(res, second->DATA);
446 second=second->NEXT;
447 }
448 return reverse(res);
449 }
450 /*
451 static chain_list *merge_ptype(ptype_list *first, ptype_list *second, int checkdup)
452 {
453 chain_list *res;
454 ptype_list *cl;
455
456 res=NULL;
457 for (cl=first; cl!=NULL; cl=cl->NEXT) res=addchain(res, cl);
458 while (second!=NULL)
459 {
460 if (checkdup)
461 {
462 for (cl=first; cl!=NULL; cl=cl->NEXT)
463 if (cl->DATA==second->DATA) break;
464 }
465 else
466 cl=NULL;
467 if (cl==NULL)
468 res=addchain(res, second);
469 second=second->NEXT;
470 }
471 return reverse(res);
472 }
473 */
474 static chain_list *merge_siglist(list_list *first, list_list *second, int checkdup)
475 {
476 list_list *icl;
477 chain_list *res;
478
479 res=NULL;
480 for (icl=first; icl!=NULL; icl=icl->NEXT) res=addchain(res, icl);
481
482 while (second!=NULL)
483 {
484 if (checkdup)
485 {
486 for (icl=first; icl!=NULL; icl=icl->NEXT)
487 if(icl->DATA==second->DATA && icl->TYPE==second->TYPE) break;
488 }
489 else icl=NULL;
490
491 if (icl==NULL)
492 res=addchain(res, second);
493 second=second->NEXT;
494 }
495 return reverse(res);
496 }
497
498 chain_list *infGetInfo(inffig_list *myfig, int type)
499 {
500 if (myfig==NULL) return NULL;
501 switch(type)
502 {
503 case INF_FALSEPATH_INFO : return merge_chain(myfig->LOADED.INF_FALSEPATH, myfig->DEFAULT.INF_FALSEPATH, 0);
504 case INF_SIGLIST_INFO : return merge_siglist(myfig->LOADED.INF_SIGLIST, myfig->DEFAULT.INF_SIGLIST, 1);
505 default :
506 return NULL;
507 }
508 }
509
510 int infHasInfo(inffig_list *myfig, int type)
511 {
512 if (myfig==NULL) return 0;
513 switch(type)
514 {
515 case INF_FALSEPATH_INFO : return myfig->LOADED.INF_FALSEPATH!=NULL || myfig->DEFAULT.INF_FALSEPATH!=NULL;
516 case INF_SIGLIST_INFO : return myfig->LOADED.INF_SIGLIST!=NULL || myfig->DEFAULT.INF_SIGLIST!=NULL;
517 default :
518 return 0;
519 }
520 }
521
522
523 /***********************************************************************
524 * fonction inf_GetList(); *
525 **********************************************************************/
526 list_list *inf_GetList (inffig_list *myfig, char *name, long type)
527 {
528 list_list *list;
529 chain_list *cl, *maincl;
530
531 maincl=infGetInfo(myfig, INF_SIGLIST_INFO);
532
533 for (cl=maincl; cl!=NULL; cl=cl->NEXT)
534 {
535 list=(list_list *)cl->DATA;
536 if (list->DATA==name && list->TYPE==type) return list;
537 }
538
539 freechain(maincl);
540 return NULL;
541 }
542
543
544 /***********************************************************************
545 * fonction infAddList(); *
546 **********************************************************************/
547 list_list *infAddList(inffig_list *ifl, int location, char *data,long level,char prg, void *user, char *where)
548 {
549 list_list *list, *endlist = NULL, *indefault;
550 short flag = 0;
551 INF_INFOSET *addlist;
552
553 if (location==INF_LOADED_LOCATION)
554 {
555 for(indefault= ifl->DEFAULT.INF_SIGLIST ; indefault != NULL ; indefault = indefault->NEXT)
556 if(indefault->DATA==data && indefault->TYPE==level) break;
557
558 addlist=&ifl->LOADED;
559 }
560 else
561 {
562 addlist=&ifl->DEFAULT;
563 indefault=NULL;
564 }
565
566 for(list = addlist->INF_SIGLIST ; list != NULL ; list = list->NEXT)
567 {
568 if((list->DATA == data) && (list->TYPE == level))
569 flag = 1 ;
570
571 endlist = list ;
572 }
573
574 if((flag != 0) && (prg != 't'))
575 {
576 avt_errmsg(INF_ERRMSG, "013", AVT_WARNING, where==NULL?"":where, data);
577 // avt_error("inf", 2, AVT_WAR, "%sinformation on signal %s already read -- ignored\n",where==NULL?"":where, data);
578 return NULL;
579 }
580
581 if (indefault!=NULL)
582 {
583 avt_errmsg(INF_ERRMSG, "014", AVT_WARNING, where==NULL?"":where, data);
584 // avt_error("inf", 3, AVT_WAR, "%sinformation on signal '%s' has already been set elsewhere -- overriding with inf values\n",where==NULL?"":where, data);
585 }
586
587 list = mbkalloc(sizeof(struct list)) ;
588 list->DATA = data ;
589 list->TYPE = level ;
590 list->USER = user ;
591
592 list->NEXT = addlist->INF_SIGLIST;
593 addlist->INF_SIGLIST=list;
594 ifl->changed|=1;
595
596 return list;
597 }
598
599 list_list *infaddll(list_list *head, void *data, long level, ptype_list *user)
600 {
601 list_list *list, *last;
602 list = mbkalloc(sizeof(list_list)) ;
603 list->DATA = data ;
604 list->TYPE = level ;
605 list->USER = user ;
606 list->NEXT = NULL;
607
608 for (last=head; last!=NULL && last->NEXT!=NULL; last=last->NEXT) ;
609 if (last!=NULL)
610 {
611 last->NEXT=list;
612 return head;
613 }
614
615 return list;
616 }
617
618 void inffreell(list_list *ptlist)
619 {
620 list_list *ptnextlist;
621 while (ptlist!=NULL)
622 {
623 ptnextlist = ptlist->NEXT;
624 mbkfree(ptlist);
625 ptlist = ptnextlist;
626 }
627 }
628
629 static void inffreedatavalue(InfValue *iv)
630 {
631 if (iv->datatype=='s' && iv->VAL.string!=NULL) mbkfree(iv->VAL.string);
632 else if (iv->datatype=='p')
633 {
634 if (strcasecmp(iv->pointertype, INF_SPECIN)==0)
635 inf_stb_parse_spec_free((inf_stb_p_s *)iv->VAL.pointer);
636 else if (strcasecmp(iv->pointertype, INF_ASSOCLIST)==0)
637 {
638 chain_list *cl;
639 for (cl=(chain_list *)iv->VAL.pointer; cl!=NULL; cl=cl->NEXT)
640 mbkfree(cl->DATA);
641 freechain((chain_list *)iv->VAL.pointer);
642 }
643 else if (strcasecmp(iv->pointertype, INF_MISCDATA)==0)
644 {
645 mbkfree(iv->VAL.pointer);
646 }
647 }
648 }
649
650 static void inffreevalue(InfValue *iv)
651 {
652 inffreedatavalue(iv);
653 mbkfree(iv);
654 }
655
656 static InfValue *infcreateentrydata(char *type, char datatype)
657 {
658 InfValue *iv;
659
660 iv=(InfValue *)mbkalloc(sizeof(InfValue));
661 iv->infotype=type; //sensitive_namealloc(type);
662 iv->datatype=datatype;
663 iv->pointertype="?";
664 iv->match = 0;
665 return iv;
666 }
667
668 static InfValue *infgetentrydata(chain_list *cl, char *type)
669 {
670 while (cl!=NULL && ((InfValue *)cl->DATA)->infotype!=type) cl=cl->NEXT;
671 if (cl==NULL) return NULL;
672 return (InfValue *)cl->DATA;
673 }
674
675 static chain_list *infgetvals(INF_INFOSET *is, char *key)
676 {
677 long l;
678 if (is->REGISTRY==NULL) return NULL;
679 if ((l=gethtitem(is->REGISTRY, key))!=EMPTYHT) return (chain_list *)l;
680 return NULL;
681 }
682
683 static InfValue *infgetorcreatekey(INF_INFOSET *is, char *key, char *type, char datatype)
684 {
685 InfValue *iv;
686 chain_list *vals;
687
688 key=namealloc(key);
689 vals=infgetvals(is, key);
690 if ((iv=infgetentrydata(vals, type))==NULL)
691 {
692 if (is->REGISTRY==NULL) is->REGISTRY=addht(16);
693 iv=infcreateentrydata(type, datatype);
694 if (datatype=='s') iv->VAL.string=NULL;
695 else if (datatype=='p') iv->VAL.pointer=NULL;
696 vals=addchain(vals, iv);
697 addhtitem(is->REGISTRY, key, (long)vals);
698 }
699 return iv;
700 }
701
702 static InfValue *infgetkey(INF_INFOSET *is, char *key, char *type)
703 {
704 InfValue *iv;
705 chain_list *vals;
706
707 key=namealloc(key);
708 vals=infgetvals(is, key);
709 iv=infgetentrydata(vals, type);
710
711 return iv;
712 }
713
714 inf_assoc *inf_createassoc()
715 {
716 inf_assoc *assoc;
717 assoc=(inf_assoc *)mbkalloc(sizeof(inf_assoc));
718 return assoc;
719 }
720 inf_miscdata *inf_createmiscdata()
721 {
722 inf_miscdata *assoc;
723 assoc=(inf_miscdata *)mbkalloc(sizeof(inf_miscdata));
724 return assoc;
725 }
726
727 void inf_AddString(inffig_list *ifl, int location, char *key, char *type, char *val, char *where)
728 {
729 InfValue *iv;
730 INF_INFOSET *is;
731 int sayit=0;
732 if (ifl==NULL) return;
733 type=sensitive_namealloc(type);
734 if (location==INF_DEFAULT_LOCATION)
735 is=&ifl->DEFAULT;
736 else
737 {
738 is=&ifl->LOADED;
739 if ((iv=infgetkey(&ifl->DEFAULT, key, type))!=NULL)
740 {
741 if (iv->VAL.string==NULL || val==NULL)
742 {
743 if (val!=iv->VAL.string) sayit=1;
744 }
745 else if (strcmp(iv->VAL.string, val)!=0) sayit=1;
746 if (sayit)
747 avt_errmsg(INF_ERRMSG, "015", AVT_WARNING, where==NULL?"":where, type, key, iv->VAL.string, val);
748 // avt_error("inf", 3, AVT_WAR, "%sinformation '%s' for '%s' has already been set to '%s' elsewhere -- overriding with inf value '%s'\n",where==NULL?"":where, type, key, iv->VAL.string, val);
749 }
750 }
751
752 iv=infgetorcreatekey(is, key, type, 's');
753 inffreedatavalue(iv);
754 if (val!=NULL) iv->VAL.string=mbkstrdup(val);
755 else iv->VAL.string=NULL;
756 ifl->changed|=1;
757 }
758
759 void inf_AddPointer(inffig_list *ifl, int location, char *key, char *type, char *pointertype, void *val, char *where)
760 {
761 InfValue *iv;
762 INF_INFOSET *is;
763 if (ifl==NULL) return;
764 type=sensitive_namealloc(type);
765 if (location==INF_DEFAULT_LOCATION)
766 is=&ifl->DEFAULT;
767 else
768 {
769 is=&ifl->LOADED;
770 if (infgetkey(&ifl->DEFAULT, key, type)!=NULL)
771 avt_errmsg(INF_ERRMSG, "016", AVT_WARNING, where==NULL?"":where, type, key);
772 // avt_error("inf", 3, AVT_WAR, "%sinformation '%s' for '%s' has already been set elsewhere -- overriding with inf values\n",where==NULL?"":where, type, key);
773 }
774
775 iv=infgetorcreatekey(is, key, type, 'p');
776 iv->pointertype=pointertype;
777 // inffreedatavalue(iv);
778 // if (val!=NULL) iv->VAL.string=mbkstrdup(val);
779 iv->VAL.pointer=val;
780 ifl->changed|=1;
781 }
782
783 void inf_AddMiscData(inffig_list *ifl, int location, char *key, char *type, char *val0, char *val1, long lval, double dval, double dval1, char *where)
784 {
785 InfValue *iv;
786 INF_INFOSET *is;
787 inf_miscdata *assoc;
788
789 if (ifl==NULL) return;
790 type=sensitive_namealloc(type);
791 if (location==INF_DEFAULT_LOCATION)
792 is=&ifl->DEFAULT;
793 else
794 {
795 is=&ifl->LOADED;
796 if (infgetkey(&ifl->DEFAULT, key, type)!=NULL)
797 avt_errmsg(INF_ERRMSG, "016", AVT_WARNING, where==NULL?"":where, type, key);
798 // avt_error("inf", 3, AVT_WAR, "%sinformation '%s' for '%s' has already been set elsewhere -- overriding with inf values\n",where==NULL?"":where, type, key);
799 }
800
801 iv=infgetorcreatekey(is, key, type, 'p');
802 iv->pointertype=INF_MISCDATA;
803 if (iv->VAL.pointer==NULL)
804 {
805 assoc=inf_createmiscdata();
806 iv->VAL.pointer=assoc;
807 }
808 else
809 assoc=iv->VAL.pointer;
810
811 assoc->orig=val0;
812 assoc->dest=val1;
813 assoc->lval=lval;
814 assoc->dval=dval;
815 assoc->dval1=dval1;
816 ifl->changed|=1;
817 }
818
819 void inf_AddDouble(inffig_list *ifl, int location, char *key, char *type, double val, char *where)
820 {
821 InfValue *iv;
822 INF_INFOSET *is;
823 if (ifl==NULL) return;
824 type=sensitive_namealloc(type);
825 if (location==INF_DEFAULT_LOCATION)
826 is=&ifl->DEFAULT;
827 else
828 {
829 is=&ifl->LOADED;
830 /* if ((iv=infgetkey(&ifl->DEFAULT, key, type))!=NULL && fabs(iv->VAL.dvalue-val)>1e-13)
831 avt_error("inf", 3, AVT_WAR, "%sinformation '%s' for '%s' has already been set to %g elsewhere -- overriding with inf value %g\n",where==NULL?"":where, type, key, iv->VAL.dvalue, val);*/
832 }
833 iv=infgetorcreatekey(is, key, type, 'd');
834 iv->VAL.dvalue=val;
835 where=NULL;
836 ifl->changed|=1;
837 }
838
839 void inf_AddInt(inffig_list *ifl, int location, char *key, char *type, int val, char *where)
840 {
841 InfValue *iv;
842 INF_INFOSET *is;
843 if (ifl==NULL) return;
844 type=sensitive_namealloc(type);
845 if (location==INF_DEFAULT_LOCATION)
846 is=&ifl->DEFAULT;
847 else
848 {
849 is=&ifl->LOADED;
850 if ((iv=infgetkey(&ifl->DEFAULT, key, type))!=NULL && iv->VAL.ivalue!=val)
851 avt_errmsg(INF_ERRMSG, "017", AVT_WARNING, where==NULL?"":where, type, key, iv->VAL.ivalue, val);
852 // avt_error("inf", 3, AVT_WAR, "%sinformation '%s' for '%s' has already been set to %d elsewhere -- overriding with inf value %d\n",where==NULL?"":where, type, key, iv->VAL.ivalue, val);
853 }
854 iv=infgetorcreatekey(is, key, type, 'i');
855 iv->VAL.ivalue=val;
856 ifl->changed|=1;
857 }
858
859 int inf_GetString(inffig_list *ifl, char *key, char *type, char **val)
860 {
861 InfValue *iv=NULL;
862 if (ifl==NULL) return 0;
863 type=sensitive_namealloc(type);
864 if ((STUCK_SECTION & INF_LOADED_LOCATION)!=0) iv=infgetkey(&ifl->LOADED, key, type);
865 if (iv==NULL || iv->datatype!='s')
866 {
867 if ((STUCK_SECTION & INF_DEFAULT_LOCATION)!=0) iv=infgetkey(&ifl->DEFAULT, key, type);
868 if (iv==NULL || iv->datatype!='s')
869 return 0;
870 }
871 *val=iv->VAL.string;
872 return 1;
873 }
874
875 int inf_GetPointer(inffig_list *ifl, char *key, char *type, void **val)
876 {
877 InfValue *iv=NULL;
878 if (ifl==NULL) return 0;
879 type=sensitive_namealloc(type);
880 if ((STUCK_SECTION & INF_LOADED_LOCATION)!=0) iv=infgetkey(&ifl->LOADED, key, type);
881 if (iv==NULL || iv->datatype!='p')
882 {
883 if ((STUCK_SECTION & INF_DEFAULT_LOCATION)!=0) iv=infgetkey(&ifl->DEFAULT, key, type);
884 if (iv==NULL || iv->datatype!='p')
885 return 0;
886 }
887 *val=iv->VAL.pointer;
888 return 1;
889 }
890
891 int inf_GetDouble(inffig_list *ifl, char *key, char *type, double *val)
892 {
893 InfValue *iv=NULL;
894 if (ifl==NULL) return 0;
895 type=sensitive_namealloc(type);
896 if ((STUCK_SECTION & INF_LOADED_LOCATION)!=0) iv=infgetkey(&ifl->LOADED, key, type);
897 if (iv==NULL || iv->datatype!='d')
898 {
899 if ((STUCK_SECTION & INF_DEFAULT_LOCATION)!=0) iv=infgetkey(&ifl->DEFAULT, key, type);
900 if (iv==NULL || iv->datatype!='d')
901 return 0;
902 }
903 *val=iv->VAL.dvalue;
904 return 1;
905 }
906
907 int inf_GetInt(inffig_list *ifl, char *key, char *type, int *val)
908 {
909 InfValue *iv=NULL;
910 if (ifl==NULL) return 0;
911 type=sensitive_namealloc(type);
912 if ((STUCK_SECTION & INF_LOADED_LOCATION)!=0) iv=infgetkey(&ifl->LOADED, key, type);
913 if (iv==NULL || iv->datatype!='i')
914 {
915 if ((STUCK_SECTION & INF_DEFAULT_LOCATION)!=0) iv=infgetkey(&ifl->DEFAULT, key, type);
916 if (iv==NULL || iv->datatype!='i')
917 return 0;
918 }
919 *val=iv->VAL.ivalue;
920 return 1;
921 }
922
923 chain_list *inf_GetEntriesByType(inffig_list *ifl, char *type, char *val)
924 {
925 chain_list *cl, *all, *ret=NULL;
926 InfValue *iv;
927 ht *tempht;
928
929 if (ifl==NULL) return NULL;
930
931 type=sensitive_namealloc(type);
932 tempht=addht(16);
933
934 if ((STUCK_SECTION & INF_LOADED_LOCATION)!=0 && ifl->LOADED.REGISTRY!=NULL)
935 {
936 all=GetAllHTKeys(ifl->LOADED.REGISTRY);
937 for (cl=all; cl!=NULL; cl=cl->NEXT)
938 {
939 iv=infgetkey(&ifl->LOADED, (char*)cl->DATA, type);
940 if (type==NULL || (iv!=NULL && (val==INF_ANY_VALUES || (iv->datatype=='s' && strcmp(iv->VAL.string, val)==0) || (iv->datatype=='i' && iv->VAL.ivalue==(int)(long)val))))
941 {
942 ret=addchain(ret, (char*)cl->DATA);
943 addhtitem(tempht, (char*)cl->DATA, 0);
944 }
945 }
946 freechain(all);
947 }
948
949 if ((STUCK_SECTION & INF_DEFAULT_LOCATION)!=0 && ifl->DEFAULT.REGISTRY!=NULL)
950 {
951 all=GetAllHTKeys(ifl->DEFAULT.REGISTRY);
952 for (cl=all; cl!=NULL; cl=cl->NEXT)
953 {
954 if (gethtitem(tempht, (char*)cl->DATA)==EMPTYHT)
955 {
956 iv=infgetkey(&ifl->DEFAULT, (char*)cl->DATA, type);
957 if (type==NULL || (iv!=NULL && (val==INF_ANY_VALUES || (iv->datatype=='s' && strcmp(iv->VAL.string, val)==0) || (iv->datatype=='i' && iv->VAL.ivalue==(int)(long)val))))
958 {
959 ret=addchain(ret, (char*)cl->DATA);
960 }
961 }
962 }
963 freechain(all);
964 }
965
966 delht(tempht);
967 return inf_SortEntries(ret);
968 }
969
970 chain_list *inf_GetValuesByType(inffig_list *ifl, char *type)
971 {
972 chain_list *cl, *all, *ret=NULL;
973 InfValue *iv;
974 ht *tempht;
975 NameAllocator na;
976 char *nn;
977
978 if (ifl==NULL || type==NULL) return NULL;
979 type=sensitive_namealloc(type);
980 tempht=addht(16);
981 CreateNameAllocator(127, &na, 'n');
982 if ((STUCK_SECTION & INF_LOADED_LOCATION)!=0 && ifl->LOADED.REGISTRY!=NULL)
983 {
984 all=GetAllHTKeys(ifl->LOADED.REGISTRY);
985 for (cl=all; cl!=NULL; cl=cl->NEXT)
986 {
987 iv=infgetkey(&ifl->LOADED, (char*)cl->DATA, type);
988 if (iv!=NULL && iv->datatype=='s')
989 {
990 nn=NameAlloc(&na, iv->VAL.string);
991 if (gethtitem(tempht, nn)==EMPTYHT)
992 {
993 ret=addchain(ret, iv->VAL.string);
994 addhtitem(tempht, nn, 0);
995 }
996 addhtitem(tempht, (char*)cl->DATA, 0);
997 }
998 }
999 freechain(all);
1000 }
1001
1002 if ((STUCK_SECTION & INF_DEFAULT_LOCATION)!=0 && ifl->DEFAULT.REGISTRY!=NULL)
1003 {
1004 all=GetAllHTKeys(ifl->DEFAULT.REGISTRY);
1005 for (cl=all; cl!=NULL; cl=cl->NEXT)
1006 {
1007 if (gethtitem(tempht, (char*)cl->DATA)==EMPTYHT)
1008 {
1009 iv=infgetkey(&ifl->DEFAULT, (char*)cl->DATA, type);
1010 if (iv!=NULL && iv->datatype=='s')
1011 {
1012 nn=NameAlloc(&na, iv->VAL.string);
1013 if (gethtitem(tempht, nn)==EMPTYHT)
1014 {
1015 ret=addchain(ret, iv->VAL.string);
1016 addhtitem(tempht, nn, 0);
1017 }
1018 }
1019 }
1020 }
1021 freechain(all);
1022 }
1023 DeleteNameAllocator(&na);
1024 delht(tempht);
1025 return ret;
1026 }
1027
1028 chain_list *inf_GetLocatedEntriesByType(inffig_list *ifl, int location, char *type, char *val)
1029 {
1030 chain_list *cl, *all, *ret=NULL;
1031 InfValue *iv;
1032 INF_INFOSET *is;
1033
1034 if (ifl==NULL) return NULL;
1035 type=sensitive_namealloc(type);
1036 if (location==INF_DEFAULT_LOCATION)
1037 is=&ifl->DEFAULT;
1038 else
1039 is=&ifl->LOADED;
1040
1041 if (is->REGISTRY!=NULL)
1042 {
1043 all=GetAllHTKeys(is->REGISTRY);
1044 for (cl=all; cl!=NULL; cl=cl->NEXT)
1045 {
1046 iv=infgetkey(&ifl->LOADED, (char*)cl->DATA, type);
1047 if (type==NULL || (iv!=NULL && (val==NULL || (iv->datatype=='s' && strcmp(iv->VAL.string, val)==0) || (iv->datatype=='i' && iv->VAL.ivalue==(int)(long)val))))
1048 {
1049 ret=addchain(ret, (char*)cl->DATA);
1050 }
1051 }
1052 freechain(all);
1053 }
1054 return ret;
1055 }
1056
1057 void inf_RemoveKey(inffig_list *ifl, int location, char *key, char *type)
1058 {
1059 chain_list *ret=NULL, *ch, *prec;
1060 INF_INFOSET *is;
1061
1062 if (ifl==NULL) return;
1063 type=sensitive_namealloc(type);
1064 if (location==INF_DEFAULT_LOCATION)
1065 is=&ifl->DEFAULT;
1066 else
1067 is=&ifl->LOADED;
1068
1069 if (is->REGISTRY==NULL) return;
1070
1071 ret=infgetvals(is, key);
1072 if (type==NULL)
1073 {
1074 for (ch=ret; ch!=NULL; ch=ch->NEXT) inffreevalue((InfValue *)ch->DATA);
1075 freechain(ret);
1076 delhtitem(is->REGISTRY, key);
1077 }
1078 else
1079 {
1080 prec=NULL;
1081 for (ch=ret; ch!=NULL; prec=ch, ch=ch->NEXT)
1082 if (strcasecmp(((InfValue *)ch->DATA)->infotype, type)==0) break;
1083
1084 if (ch!=NULL)
1085 {
1086 inffreevalue((InfValue *)ch->DATA);
1087 if (prec!=NULL) prec->NEXT=ch->NEXT;
1088 else addhtitem(is->REGISTRY, key, (long)ch->NEXT);
1089 ch->NEXT=NULL;
1090 freechain(ch);
1091 }
1092 }
1093 ifl->changed|=1;
1094 }
1095
1096 static void infCleanRegistry(inffig_list *ifl, int location)
1097 {
1098 chain_list *cl, *all;
1099 INF_INFOSET *is;
1100
1101 if (location==INF_DEFAULT_LOCATION)
1102 is=&ifl->DEFAULT;
1103 else
1104 is=&ifl->LOADED;
1105
1106 if (is->REGISTRY==NULL) return;
1107
1108 all=GetAllHTKeys(is->REGISTRY);
1109 for (cl=all; cl!=NULL; cl=cl->NEXT)
1110 {
1111 inf_RemoveKey(ifl, location, (char*)cl->DATA, NULL);
1112 }
1113 freechain(all);
1114 ifl->changed|=1;
1115 }
1116
1117 static char *__getrel(char val)
1118 {
1119 if (val==INF_STB_BEFORE) return "before";
1120 if (val==INF_STB_AFTER) return "after";
1121 return "?";
1122 }
1123
1124 static char *__getstab(char val)
1125 {
1126 if (val==INF_STB_STABLE) return "stable";
1127 if (val==INF_STB_UNSTABLE) return "unstable";
1128 return "?";
1129 }
1130
1131 static char *__getedge(char val)
1132 {
1133 if (val==INF_STB_RISING) return "rising";
1134 if (val==INF_STB_FALLING) return "falling";
1135 if (val==INF_STB_SLOPEALL) return "(all)";
1136 return "?";
1137 }
1138
1139 /*{{{ */
1140 /* */
1141 /* */
1142 /****************************************************************************/
1143 static int
1144 getVerificationLevel(char *token)
1145 {
1146 // I
1147 if (!strcmp(token,INF_MUXU)
1148 || !strcmp(token,INF_MUXD)
1149 || !strcmp(token,INF_CMPU)
1150 || !strcmp(token,INF_CMPD)
1151 || !strcmp(token,INF_INPUTS)
1152 || !strcmp(token,INF_PIN_RISING_SLEW)
1153 || !strcmp(token,INF_PIN_FALLING_SLEW)
1154 || !strcmp(token,INF_PIN_LOW_VOLTAGE)
1155 || !strcmp(token,INF_PIN_HIGH_VOLTAGE)
1156 || !strcmp(token,INF_SLOPEIN)
1157 || !strcmp(token,INF_CAPAOUT)
1158 || !strcmp(token,INF_CAPAOUT_LW)
1159 || !strcmp(token,INF_CAPAOUT_L)
1160 || !strcmp(token,INF_OUTPUT_CAPACITANCE)
1161 || !strcmp(token,INF_ASYNCHRON)
1162 || !strcmp(token,INF_CONNECTOR_DIRECTION)
1163 || !strcmp(token,INF_SPECIN)
1164 || !strcmp(token,INF_SPECOUT))
1165 return 1;
1166 // II
1167 if (!strcmp(token,INF_STOP)
1168 || !strcmp(token,INF_DIROUT)
1169 || !strcmp(token,INF_CKLATCH)
1170 || !strcmp(token,INF_BREAK)
1171 || !strcmp(token,INF_RC)
1172 || !strcmp(token,INF_CLOCK_TYPE)
1173 || !strcmp(token,INF_MIN_RISE_TIME)
1174 || !strcmp(token,INF_MAX_RISE_TIME)
1175 || !strcmp(token,INF_MIN_FALL_TIME)
1176 || !strcmp(token,INF_MAX_FALL_TIME)
1177 || !strcmp(token,INF_CLOCK_PERIOD))
1178 return 2;
1179 // III
1180 if (!strcmp(token,INF_DLATCH)
1181 || !strcmp(token,INF_NOTLATCH)
1182 || !strcmp(token,INF_KEEP_TRISTATE_BEHAVIOUR)
1183 || !strcmp(token,INF_PRECHARGE)
1184 || !strcmp(token,INF_MODELLOOP)
1185 || !strcmp(token,INF_STRICT_SETUP)
1186 || !strcmp(token,INF_STUCK)
1187 || !strcmp(token,INF_BYPASS)
1188 || !strcmp(token,INF_INTER)
1189 //|| token,INF_LL_PATHSIGS)
1190 || !strcmp(token,INF_PATHIN)
1191 || !strcmp(token,INF_PATHOUT)
1192 || !strncmp(token,INF_PATHDELAYMARGINPREFIX,strlen(INF_PATHDELAYMARGINPREFIX))
1193 || !strcmp(token,INF_NORISING)
1194 || !strcmp(token,INF_NOFALLING)
1195 || !strcmp(token,INF_NOCHECK)
1196 || !strcmp(token,INF_CROSSTALKMUXU)
1197 || !strcmp(token,INF_CROSSTALKMUXD))
1198 return 3;
1199 // ??
1200 if (!strcmp(token,INF_IGNORE_INSTANCE)
1201 || !strcmp(token,INF_IGNORE_TRANSISTOR)
1202 || !strcmp(token,INF_IGNORE_CAPACITANCE)
1203 || !strcmp(token,INF_IGNORE_RESISTANCE)
1204 || !strcmp(token,INF_IGNORE_PARASITICS)
1205 || !strcmp(token,INF_IGNORE_NAMES)
1206 || !strcmp(token,INF_VERIF_STATE)
1207 || !strcmp(token,INF_ASYNC_CLOCK_GROUP)
1208 || !strcmp(token,INF_ASYNC_CLOCK_GROUP_PERIOD)
1209 || !strcmp(token,INF_EQUIV_CLOCK_GROUP)
1210 || !strcmp(token,INF_PREFERED_CLOCK))
1211 return -1;
1212 else
1213 return -1;
1214 }
1215
1216 /*}}}************************************************************************/
1217 /*{{{ */
1218 /* */
1219 /* */
1220 /****************************************************************************/
1221 #define INF_VERIFICATION_LEVEL_MAX 50
1222 #define INF_VERIFICATION_DONE 10
1223
1224 static int
1225 getNFillMinVerificationLevel(chain_list *ch, int b)
1226 {
1227 if (ch)
1228 {
1229 int a, min;
1230
1231 a = getVerificationLevel(((InfValue *)ch->DATA)->infotype);
1232 /*
1233 if (a != -1)
1234 printf(" OK \"%s\"\n",((InfValue *)ch->DATA)->infotype);
1235 else
1236 printf(">>>> FAILED \"%s\"\n",((InfValue *)ch->DATA)->infotype);
1237 */
1238 if ((a == -1 && b >= 0) || a > b)
1239 min = getNFillMinVerificationLevel(ch->NEXT,b);
1240 else
1241 min = getNFillMinVerificationLevel(ch->NEXT,a);
1242 ((InfValue *)ch->DATA)->match = min;
1243
1244 return min;
1245 }
1246 else
1247 if (b == INF_VERIFICATION_LEVEL_MAX)
1248 return -1;
1249 else
1250 return b;
1251 }
1252
1253 /*}}}************************************************************************/
1254 /*{{{ */
1255 /* */
1256 /* */
1257 /****************************************************************************/
1258 static void
1259 markChecked(chain_list *ch, int level)
1260 {
1261 if (ch)
1262 {
1263 ((InfValue *)ch->DATA)->match = INF_VERIFICATION_DONE+level;
1264 markChecked(ch->NEXT, level);
1265 }
1266 }
1267
1268 /*}}}************************************************************************/
1269 /*{{{ */
1270 /* */
1271 /* */
1272 /****************************************************************************/
1273 static char *
1274 checkKeys(FILE * f, char *key,INF_INFOSET *is, int level)
1275 {
1276 chain_list *ret;
1277 int match;
1278
1279 ret = infgetvals(is, namealloc(key));
1280 match = ((InfValue *)ret->DATA)->match;
1281
1282 if (match == 0)
1283 match = getNFillMinVerificationLevel(ret,INF_VERIFICATION_LEVEL_MAX);
1284
1285 if ((match < INF_VERIFICATION_DONE && match == level) || (match >= INF_VERIFICATION_DONE && match!=INF_VERIFICATION_DONE-level))
1286 return key;
1287
1288 f=NULL; // supress warning
1289 return NULL;
1290 }
1291
1292 /*}}}************************************************************************/
1293 /*{{{ */
1294 /* */
1295 /* */
1296 /****************************************************************************/
1297 static void
1298 markKeyChecked(char *key,INF_INFOSET *is, int level)
1299 {
1300 chain_list *ret;
1301
1302 ret = infgetvals(is, namealloc(key));
1303
1304 markChecked(ret,level);
1305 }
1306
1307 /*}}}************************************************************************/
1308 /*{{{ */
1309 /* */
1310 /* */
1311 /****************************************************************************/
1312 static void
1313 checkSections(FILE *f, inffig_list *ifl, char *token, int level, chain_list *data, ht *sig_ht)
1314 {
1315 static ht *th = NULL;
1316 chain_list *keys, *c1, *cx;
1317 int done;
1318 char *st;
1319
1320 if (ifl==NULL)
1321 {
1322 if (th!=NULL) delht(th);
1323 th = NULL;
1324 return;
1325 }
1326
1327 if (!th)
1328 th = addht(50);
1329
1330 if (level == 2 && (!strcmp(token,INF_MUXU)
1331 || !strcmp(token,INF_MUXD)
1332 || !strcmp(token,INF_CMPU)
1333 || !strcmp(token,INF_CMPD)
1334 || !strcmp(token,INF_DISABLE_GATE_DELAY)))
1335 {
1336 if (!strcmp(token,INF_DISABLE_GATE_DELAY))
1337 keys=grab_inf_assoc(ifl, INF_DISABLE_GATE_DELAY);
1338 else
1339 keys = grab_inf_Mutex(ifl);
1340
1341 for (c1 = keys; c1; c1 = c1->NEXT)
1342 {
1343 done = 0;
1344 st = (char*)gethtitem(th,c1->DATA);
1345 if (st == (char*)EMPTYHT)
1346 {
1347 if (gethtitem(sig_ht, c1->DATA)==EMPTYHT)
1348 {
1349 for (cx = data; cx; cx = cx->NEXT)
1350 {
1351 /*st = (char*)gethtitem(th,cx->DATA);
1352 if (st != (char*)EMPTYHT && strchr((char *)c1->DATA,'*')==NULL)
1353 continue;*/
1354 if (mbk_TestREGEX(cx->DATA,c1->DATA) || mbk_TestREGEX(mbk_vect(cx->DATA,'[',']'),c1->DATA))
1355 {
1356 done = 1;
1357 break;
1358 }
1359 }
1360 }
1361 else
1362 done=1;
1363 if (!done)
1364 avt_errmsg(INF_ERRMSG, "023", AVT_WARNING, (char *)c1->DATA,level==1?"connector":level==2?"net":"cone");
1365 // avt_error("inf",-1,AVT_ERROR,"name '¤2%s¤.' doesn't match any signal in circuit\n",(char *)c1->DATA);
1366 addhtitem(th,c1->DATA,done);
1367 }
1368 }
1369
1370 freechain(keys);
1371 }
1372 if (level == 3 && (!strcmp(token,INF_CROSSTALKMUXU)
1373 || !strcmp(token,INF_CROSSTALKMUXD)))
1374 {
1375 keys = grab_inf_CrosstalkMutex(ifl);
1376
1377 for (c1 = keys; c1; c1 = c1->NEXT)
1378 {
1379 done = 0;
1380 st = (char*)gethtitem(th,c1->DATA);
1381 if (st == (char*)EMPTYHT)
1382 {
1383 if (gethtitem(sig_ht, c1->DATA)==EMPTYHT)
1384 {
1385 for (cx = data; cx; cx = cx->NEXT)
1386 {
1387 if (mbk_TestREGEX(cx->DATA,c1->DATA) || mbk_TestREGEX(mbk_vect(cx->DATA,'[',']'),c1->DATA))
1388 {
1389 done = 1;
1390 break;
1391 }
1392 }
1393 }
1394 else
1395 done=1;
1396 if (!done)
1397 avt_errmsg(INF_ERRMSG, "023", AVT_WARNING, (char *)c1->DATA,level==1?"connector":level==2?"net":"cone");
1398 // avt_error("inf",-1,AVT_ERROR,"%name '¤2%s¤.' doesn't match any signal in circuit\n",(char *)c1->DATA);
1399 addhtitem(th,c1->DATA,done);
1400 }
1401 }
1402 freechain(keys);
1403 }
1404 f=NULL; // supress warning
1405 }
1406
1407 /*}}}************************************************************************/
1408 /*{{{ */
1409 /* */
1410 /* level composition of data */
1411 /* I chain_list of pin name */
1412 /* II '' of signal name */
1413 /* III '' of cones name */
1414 /* */
1415 /****************************************************************************/
1416 void
1417 inf_CheckRegistry(FILE *f, inffig_list *ifl, int level, chain_list *data)
1418 {
1419 chain_list *cl, *cx, *all;
1420 INF_INFOSET *is;
1421 char *key, *str;
1422 int done;
1423 static int init = 0;
1424 ht *sig_ht;
1425
1426 switch (level)
1427 {
1428 case 1: avt_log(LOGCONFIG, 0, "Check level I (connectors)"); break;
1429 case 2: avt_log(LOGCONFIG, 0, "Check level II (nets)"); break;
1430 case 3: avt_log(LOGCONFIG, 0, "Check level III (cones)"); break;
1431 }
1432 if (!V_BOOL_TAB[__INF_CONF_CHECK].VALUE)
1433 {
1434 avt_log(LOGCONFIG, 0, " disabled\n");
1435 return;
1436 }
1437 else
1438 avt_log(LOGCONFIG, 0, "\n");
1439
1440
1441 if (ifl==NULL)
1442 return;
1443
1444 if (0==INF_DEFAULT_LOCATION)
1445 is=&ifl->DEFAULT;
1446 else
1447 is=&ifl->LOADED;
1448
1449 if (is->REGISTRY==NULL)
1450 return;
1451
1452 sig_ht=addht(1000);
1453 for (cx = data; cx; cx = cx->NEXT) addhtitem(sig_ht, cx->DATA, 0);
1454
1455 all = GetAllHTKeys(is->REGISTRY);
1456
1457 if (!init)
1458 for (cl=all; cl!=NULL; cl=cl->NEXT)
1459 if ((key = (char*)cl->DATA) && strcasecmp(key,"default"))
1460 {
1461 if (key[0] != '+')
1462 /* checkSections(f,ifl,key,level,data);
1463 else */
1464 checkKeys(f,key,is,level);
1465 }
1466
1467 for (cl=all; cl!=NULL; cl=cl->NEXT)
1468 {
1469 done = 0;
1470 key = (char*)cl->DATA;
1471 if (strcasecmp(key,"default"))
1472 {
1473 if (key[0] == '+')
1474 checkSections(f,ifl,key,level,data,sig_ht);
1475 else if (checkKeys(f,key,is,level))
1476 {
1477 if (gethtitem(sig_ht, key)!=EMPTYHT)
1478 done=1;
1479 else {
1480 for (cx = data; cx; cx = cx->NEXT)
1481 {
1482 if (mbk_TestREGEX(cx->DATA,key) || mbk_TestREGEX(mbk_vect(cx->DATA,'[',']'),key))
1483 {
1484 done = 1;
1485 markKeyChecked(key,is,level);
1486 break;
1487 }
1488 }
1489 }
1490 if (!done)
1491 avt_errmsg(INF_ERRMSG, "023", AVT_WARNING, key,level==1?"connector":level==2?"net":"cone");
1492 // avt_error("inf",-1,AVT_ERROR,"name '¤2%s¤.' doesn't match any signal in circuit\n",key);
1493 }
1494 }
1495 }
1496
1497 if (level==2) checkSections(f,ifl,INF_DISABLE_GATE_DELAY,level,data,sig_ht);
1498
1499 freechain(all);
1500 delht(sig_ht);
1501 // reinitialisation au dernier level
1502 if (level==3) checkSections(NULL, NULL, NULL, 0, NULL, NULL);
1503 return;
1504 }
1505
1506 /*}}}************************************************************************/
1507
1508 void inf_DumpRegistry (FILE *f, inffig_list *ifl, int location)
1509 {
1510 chain_list *cl, *all, *ret, *ch;
1511 INF_INFOSET *is;
1512 InfValue *iv;
1513 char *type;
1514
1515 if (ifl==NULL) return;
1516
1517 if (location==INF_DEFAULT_LOCATION)
1518 is=&ifl->DEFAULT;
1519 else
1520 is=&ifl->LOADED;
1521
1522 if (is->REGISTRY==NULL) return;
1523
1524 all=GetAllHTKeys(is->REGISTRY);
1525 for (cl=all; cl!=NULL; cl=cl->NEXT)
1526 {
1527 fprintf(f, "key: \"%s\"\n",(char*)cl->DATA);
1528 ret=infgetvals(is, namealloc((char*)cl->DATA));
1529 for (ch=ret; ch!=NULL; ch=ch->NEXT)
1530 {
1531 iv=(InfValue *)ch->DATA;
1532 switch(iv->datatype)
1533 {
1534 case 'i' : type="int"; break;
1535 case 'd' : type="real"; break;
1536 case 's' : type="string"; break;
1537 case 'p' : type="pointer"; break;
1538 default : type="unknown";
1539 }
1540 fprintf(f, " item: \"%s\", type:%s, val: ",iv->infotype,type);
1541 switch(iv->datatype)
1542 {
1543 case 'i' : fprintf(f, "%d\n", iv->VAL.ivalue); break;
1544 case 'd' : fprintf(f, "%g\n", iv->VAL.dvalue); break;
1545 case 's' : fprintf(f, "\"%s\"\n", iv->VAL.string==NULL?"NULL":iv->VAL.string); break;
1546 case 'p' :
1547 {
1548 // STB SPEC structure
1549 if (strcasecmp(iv->pointertype,INF_SPECIN)==0)
1550 {
1551 inf_stb_p_s *isps;
1552 inf_stb_p_s_stab *stab;
1553 isps=(inf_stb_p_s *)iv->VAL.pointer;
1554 fprintf(f, "\n");
1555 while (isps!=NULL)
1556 {
1557 fprintf(f, " %s from \"%s\" %s\n", __getedge(isps->DATAEDGE)/*,isps->SPECTYPE*/, isps->CKNAME!=NULL?isps->CKNAME:"null", __getedge(isps->CKEDGE));
1558 for (stab=isps->STABILITY; stab!=NULL; stab=stab->NEXT)
1559 {
1560 if (stab->CKNAME==NULL)
1561 {
1562 chain_list *cl;
1563 fprintf(f," %s ", __getstab(stab->STABILITY));
1564 for (cl=stab->TIME_LIST; cl!=NULL; cl=cl->NEXT)
1565 fprintf(f," %g", *(double *)cl->DATA);
1566 fprintf(f,"\n");
1567 }
1568 else
1569 {
1570 fprintf(f, " %s %g %s \"%s\" %s\n", __getstab(stab->STABILITY), stab->DELAY, __getrel(stab->RELATIVITY), stab->CKNAME!=NULL?stab->CKNAME:"null", __getedge(stab->CKEDGE));
1571 }
1572 }
1573 isps=isps->NEXT;
1574 }
1575
1576 }
1577 // INF association list
1578 else if (strcasecmp(iv->pointertype,INF_ASSOCLIST)==0)
1579 {
1580 chain_list *cl;
1581 inf_assoc *assoc;
1582 fprintf(f, "\n");
1583 for (cl=(chain_list *)iv->VAL.pointer; cl!=NULL; cl=cl->NEXT)
1584 {
1585 assoc=(inf_assoc *)cl->DATA;
1586 fprintf(f, " \"%s\" \"%s\" lval:%ld dval:%g\n", assoc->orig!=NULL?assoc->orig:"NULL", assoc->dest!=NULL?assoc->dest:"NULL", assoc->lval, assoc->dval);
1587 }
1588 }
1589 else if (strcasecmp(iv->pointertype,INF_LISTOFLIST)==0)
1590 {
1591 chain_list *cl, *ch;
1592 fprintf(f, "\n");
1593 for (cl=(chain_list *)iv->VAL.pointer; cl!=NULL; cl=cl->NEXT)
1594 {
1595 fprintf(f, " {");
1596 for (ch=(chain_list *)cl->DATA; ch!=NULL; ch=ch->NEXT)
1597 fprintf(f, " \"%s\"", (char *)ch->DATA);
1598 fprintf(f, " }\n");
1599 }
1600 }
1601 // INF misc data
1602 else if (strcasecmp(iv->pointertype,INF_MISCDATA)==0)
1603 {
1604 inf_miscdata *assoc;
1605 fprintf(f, "\n");
1606 assoc=(inf_miscdata *)iv->VAL.pointer;
1607 fprintf(f, " \"%s\" \"%s\" lval:%ld dval:%g dval1:%g\n", assoc->orig!=NULL?assoc->orig:"NULL", assoc->dest!=NULL?assoc->dest:"NULL", assoc->lval, assoc->dval, assoc->dval1);
1608 }
1609 else
1610 fprintf(f, "%p (%s)\n", iv->VAL.pointer, iv->pointertype);
1611 break;
1612 }
1613 default : fprintf(f, "?\n");
1614 }
1615 }
1616 }
1617 freechain(all);
1618
1619 }
1620
1621 void inf_AddAssociation(inffig_list *ifl, int location, char *key, char *type, char *val0, char *val1, long lval, double dval, char *where)
1622 {
1623 InfValue *iv;
1624 INF_INFOSET *is;
1625 chain_list *old;
1626 inf_assoc *assoc;
1627
1628 if (ifl==NULL) return;
1629 type=sensitive_namealloc(type);
1630 if (location==INF_DEFAULT_LOCATION)
1631 is=&ifl->DEFAULT;
1632 else
1633 {
1634 is=&ifl->LOADED;
1635 if (infgetkey(&ifl->DEFAULT, key, type)!=NULL)
1636 avt_errmsg(INF_ERRMSG, "016", AVT_WARNING, where==NULL?"":where, type, key);
1637 // avt_error("inf", 3, AVT_WAR, "%sinformation '%s' for '%s' has already been set elsewhere -- overriding with inf values\n",where==NULL?"":where, type, key);
1638 }
1639
1640 assoc=inf_createassoc();
1641 assoc->orig=val0;
1642 assoc->dest=val1;
1643 assoc->lval=lval;
1644 assoc->dval=dval;
1645 iv=infgetorcreatekey(is, key, type, 'p');
1646 iv->pointertype=sensitive_namealloc(INF_ASSOCLIST);
1647 old=iv->VAL.pointer;
1648 old=append(old, addchain(NULL, assoc));
1649 iv->VAL.pointer=old;
1650 ifl->changed|=1;
1651 }
1652
1653 void inf_AddList(inffig_list *ifl, int location, char *key, char *type, chain_list *val, char *where)
1654 {
1655 InfValue *iv;
1656 INF_INFOSET *is;
1657 chain_list *old;
1658
1659 if (ifl==NULL) return;
1660 type=sensitive_namealloc(type);
1661 if (location==INF_DEFAULT_LOCATION)
1662 is=&ifl->DEFAULT;
1663 else
1664 {
1665 is=&ifl->LOADED;
1666 if (infgetkey(&ifl->DEFAULT, key, type)!=NULL)
1667 avt_errmsg(INF_ERRMSG, "016", AVT_WARNING, where==NULL?"":where, type, key);
1668 // avt_error("inf", 3, AVT_WAR, "%sinformation '%s' for '%s' has already been set elsewhere -- overriding with inf values\n",where==NULL?"":where, type, key);
1669 }
1670
1671 iv=infgetorcreatekey(is, key, type, 'p');
1672 iv->pointertype=sensitive_namealloc(INF_LISTOFLIST);
1673 old=iv->VAL.pointer;
1674 old=append(old, addchain(NULL, val));
1675 iv->VAL.pointer=old;
1676 ifl->changed|=1;
1677 }
1678
1679 static list_list *inf_addsimplell(list_list *ll, inffig_list *ifl, char *infotype, char *val, long lltype)
1680 {
1681 chain_list *lst, *cl;
1682 lst=inf_GetEntriesByType(ifl, infotype, val);
1683 for (cl=lst; cl!=NULL; cl=cl->NEXT)
1684 {
1685 ll=infaddll(ll, (char *)cl->DATA, lltype, NULL);
1686 }
1687 freechain(lst);
1688 return ll;
1689 }
1690
1691
1692 list_list *inf_create_INFSIGLIST(inffig_list *ifl)
1693 {
1694 list_list *tl, *ll;
1695 chain_list *lst, *cl;
1696 int val;
1697 long type;
1698
1699 if (ifl==NULL) return NULL;
1700
1701 ll=NULL;
1702 for (tl=ifl->LOADED.INF_SIGLIST; tl!=NULL; tl=tl->NEXT)
1703 {
1704 ll=infaddll(ll, tl->DATA, tl->TYPE, tl->USER);
1705 }
1706
1707 lst=inf_GetEntriesByType(ifl, INF_STUCK, INF_ANY_VALUES);
1708 for (cl=lst; cl!=NULL; cl=cl->NEXT)
1709 {
1710 inf_GetInt(ifl, (char *)cl->DATA, INF_STUCK, &val);
1711 if (val==0) type=INF_LL_STUCKVSS;
1712 else type=INF_LL_STUCKVDD;
1713 ll=infaddll(ll, inf_reVectName((char *)cl->DATA), type, NULL);
1714 }
1715 freechain(lst);
1716
1717 ll=inf_addsimplell(ll, ifl, INF_PRECHARGE, INF_YES, INF_LL_PRECHARGE);
1718 ll=inf_addsimplell(ll, ifl, INF_PRECHARGE, INF_NO, INF_LL_NOTPRECHARGE);
1719
1720 ll=inf_addsimplell(ll, ifl, INF_ASYNCHRON, INF_ANY_VALUES, INF_LL_ASYNCHRON);
1721
1722 ll=inf_addsimplell(ll, ifl, INF_BYPASS, INF_ALL, INF_LL_BYPASS);
1723 ll=inf_addsimplell(ll, ifl, INF_BYPASS, INF_IN, INF_LL_BYPASSIN);
1724 ll=inf_addsimplell(ll, ifl, INF_BYPASS, INF_OUT, INF_LL_BYPASSOUT);
1725 ll=inf_addsimplell(ll, ifl, INF_BYPASS, INF_ONLYEND, INF_LL_ONLYEND);
1726
1727 ll=inf_addsimplell(ll, ifl, INF_INTER, INF_ANY_VALUES, INF_LL_INTER);
1728
1729 ll=inf_addsimplell(ll, ifl, INF_BREAK, INF_ANY_VALUES, INF_LL_BREAK);
1730 ll=inf_addsimplell(ll, ifl, INF_RC, INF_YES, INF_LL_RC);
1731 ll=inf_addsimplell(ll, ifl, INF_RC, INF_NO, INF_LL_NORC);
1732 ll=inf_addsimplell(ll, ifl, INF_NORISING, INF_ANY_VALUES, INF_LL_NORISING);
1733 ll=inf_addsimplell(ll, ifl, INF_NOFALLING, INF_ANY_VALUES, INF_LL_NOFALLING);
1734 ll=inf_addsimplell(ll, ifl, INF_FLIPFLOP, INF_ANY_VALUES, INF_LL_FLIPFLOP);
1735 return ll;
1736 }
1737
1738 int inf_code_marksig(char *string)
1739 {
1740 int result = 0;
1741 char *c, *tok;
1742 char buf[1024];
1743
1744 strcpy(buf, string);
1745
1746 tok = strtok_r(buf, " ,+", &c);
1747 while (tok!=NULL) {
1748 if (!strcasecmp("Latch",tok) || !strcasecmp("net_Latch",tok)) result |= INF_NET_LATCH;
1749 else if (!strcasecmp("MemSym",tok) || !strcasecmp("net_MemSym",tok)) result |= INF_NET_MEMSYM;
1750 else if (!strcasecmp("RS",tok) || !strcasecmp("net_RS",tok)) result |= INF_NET_RS;
1751 else if (!strcasecmp("FlipFlop",tok) || !strcasecmp("net_FlipFlop",tok)) result |= INF_NET_FLIPFLOP;
1752 else if (!strcasecmp("Master",tok) || !strcasecmp("net_Master",tok)) result |= INF_NET_MASTER;
1753 else if (!strcasecmp("Slave",tok) || !strcasecmp("net_Slave",tok)) result |= INF_NET_SLAVE;
1754 else if (!strcasecmp("Blocker",tok) || !strcasecmp("net_Blocker",tok)) result |= INF_NET_BLOCKER;
1755 else if (!strcasecmp("NoFalseBranch",tok) || !strcasecmp("net_NoFalseBranch",tok)) result |= INF_NET_NOFALSEBRANCH;
1756 else if (!strcasecmp("Vdd",tok) || !strcasecmp("net_Vdd",tok)) result |= INF_NET_VDD;
1757 else if (!strcasecmp("Vss",tok) || !strcasecmp("net_Vss",tok)) result |= INF_NET_VSS;
1758 else avt_errmsg(INF_ERRMSG, "027", AVT_ERROR, tok);
1759 tok = strtok_r(NULL, " ,+", &c);
1760 }
1761 return result;
1762 }
1763
1764 int inf_code_markRS(char *string)
1765 {
1766 if (!strcasecmp(string,"illegal")) return INF_RS_ILLEGAL;
1767 if (!strcasecmp(string,"legal")) return INF_RS_LEGAL;
1768 if (!strcasecmp(string,"mark_only")) return INF_RS_MARKONLY;
1769 avt_errmsg(INF_ERRMSG, "027", AVT_ERROR, string);
1770 return 0;
1771 }
1772
1773 int inf_code_marktrans(char *string)
1774 {
1775 int result = 0;
1776 char *c, *tok;
1777 char buf[1024];
1778
1779 strcpy(buf, string);
1780
1781 tok = strtok_r(buf, " ,+", &c);
1782 while (tok!=NULL) {
1783 if (!strcasecmp("Bleeder",tok) || !strcasecmp("trans_Bleeder",tok)) result |= INF_TRANS_BLEEDER;
1784 else if (!strcasecmp("Feedback",tok) || !strcasecmp("trans_Feedback",tok)) result |= INF_TRANS_FEEDBACK;
1785 else if (!strcasecmp("Command",tok) || !strcasecmp("trans_Command",tok)) result |= INF_TRANS_COMMAND;
1786 else if (!strcasecmp("NonFunctional",tok) || !strcasecmp("trans_NonFunctional",tok)) result |= INF_TRANS_NOT_FUNCTIONAL;
1787 else if (!strcasecmp("Blocker",tok) || !strcasecmp("trans_Blocker",tok)) result |= INF_TRANS_BLOCKER;
1788 else if (!strcasecmp("Short",tok) || !strcasecmp("trans_Short",tok)) result |= INF_TRANS_SHORT;
1789 else if (!strcasecmp("Unused",tok) || !strcasecmp("trans_Unused",tok)) result |= INF_TRANS_UNUSED;
1790 else avt_errmsg(INF_ERRMSG, "027", AVT_ERROR, tok);
1791 tok = strtok_r(NULL, " ,+", &c);
1792 }
1793 return result;
1794 }
1795
1796 void inf_buildmatchrule (inffig_list * ifl, char *section, mbk_match_rules * mr, int canbenonnameallocated)
1797 {
1798 chain_list *cl;
1799 mbk_CreateREGEX (mr, CASE_SENSITIVE, canbenonnameallocated);
1800 if (ifl == NULL)
1801 return;
1802 if (inf_GetPointer (ifl, section, "", (void **)&cl)) {
1803 while (cl != NULL) {
1804 mbk_AddREGEX (mr, ((inf_assoc *) cl->DATA)->orig);
1805 cl = cl->NEXT;
1806 }
1807 }
1808 else
1809 {
1810 cl=inf_GetEntriesByType(ifl, section, INF_ANY_VALUES);
1811 while (cl != NULL) {
1812 mbk_AddREGEX (mr, (char *)cl->DATA);
1813 cl = cl->NEXT;
1814 }
1815 }
1816 }
1817
1818
1819
1820