convert from svn repository: remove tags directory
[lttv.git] / trunk / verif / Spin / Src5.1.6 / structs.c
CommitLineData
0b55f123 1/***** spin: structs.c *****/
2
3/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */
4/* All Rights Reserved. This software is for educational purposes only. */
5/* No guarantee whatsoever is expressed or implied by the distribution of */
6/* this code. Permission is given to distribute this code provided that */
7/* this introductory message is not removed and no monies are exchanged. */
8/* Software written by Gerard J. Holzmann. For tool documentation see: */
9/* http://spinroot.com/ */
10/* Send all bug-reports and/or questions to: bugs@spinroot.com */
11
12#include "spin.h"
13#include "y.tab.h"
14
15typedef struct UType {
16 Symbol *nm; /* name of the type */
17 Lextok *cn; /* contents */
18 struct UType *nxt; /* linked list */
19} UType;
20
21extern Symbol *Fname;
22extern int lineno, depth, Expand_Ok, has_hidden;
23
24Symbol *owner;
25
26static UType *Unames = 0;
27static UType *Pnames = 0;
28
29static Lextok *cpnn(Lextok *, int, int, int);
30extern void sr_mesg(FILE *, int, int);
31
32void
33setuname(Lextok *n)
34{ UType *tmp;
35
36 if (!owner)
37 fatal("illegal reference inside typedef", (char *) 0);
38
39 for (tmp = Unames; tmp; tmp = tmp->nxt)
40 if (!strcmp(owner->name, tmp->nm->name))
41 { non_fatal("typename %s was defined before",
42 tmp->nm->name);
43 return;
44 }
45
46 tmp = (UType *) emalloc(sizeof(UType));
47 tmp->nm = owner;
48 tmp->cn = n;
49 tmp->nxt = Unames;
50 Unames = tmp;
51}
52
53static void
54putUname(FILE *fd, UType *tmp)
55{ Lextok *fp, *tl;
56
57 if (!tmp) return;
58 putUname(fd, tmp->nxt); /* postorder */
59 fprintf(fd, "struct %s { /* user defined type */\n",
60 tmp->nm->name);
61 for (fp = tmp->cn; fp; fp = fp->rgt)
62 for (tl = fp->lft; tl; tl = tl->rgt)
63 typ2c(tl->sym);
64 fprintf(fd, "};\n");
65}
66
67void
68putunames(FILE *fd)
69{
70 putUname(fd, Unames);
71}
72
73int
74isutype(char *t)
75{ UType *tmp;
76
77 for (tmp = Unames; tmp; tmp = tmp->nxt)
78 { if (!strcmp(t, tmp->nm->name))
79 return 1;
80 }
81 return 0;
82}
83
84Lextok *
85getuname(Symbol *t)
86{ UType *tmp;
87
88 for (tmp = Unames; tmp; tmp = tmp->nxt)
89 { if (!strcmp(t->name, tmp->nm->name))
90 return tmp->cn;
91 }
92 fatal("%s is not a typename", t->name);
93 return (Lextok *)0;
94}
95
96void
97setutype(Lextok *p, Symbol *t, Lextok *vis) /* user-defined types */
98{ int oln = lineno;
99 Symbol *ofn = Fname;
100 Lextok *m, *n;
101
102 m = getuname(t);
103 for (n = p; n; n = n->rgt)
104 { lineno = n->ln;
105 Fname = n->fn;
106 if (n->sym->type)
107 non_fatal("redeclaration of '%s'", n->sym->name);
108
109 if (n->sym->nbits > 0)
110 non_fatal("(%s) only an unsigned can have width-field",
111 n->sym->name);
112
113 if (Expand_Ok)
114 n->sym->hidden |= (4|8|16); /* formal par */
115
116 if (vis)
117 { if (strncmp(vis->sym->name, ":hide:", (size_t) 6) == 0)
118 { n->sym->hidden |= 1;
119 has_hidden++;
120 } else if (strncmp(vis->sym->name, ":show:", (size_t) 6) == 0)
121 n->sym->hidden |= 2;
122 else if (strncmp(vis->sym->name, ":local:", (size_t) 7) == 0)
123 n->sym->hidden |= 64;
124 }
125 n->sym->type = STRUCT; /* classification */
126 n->sym->Slst = m; /* structure itself */
127 n->sym->Snm = t; /* name of typedef */
128 n->sym->Nid = 0; /* this is no chan */
129 n->sym->hidden |= 4;
130 if (n->sym->nel <= 0)
131 non_fatal("bad array size for '%s'", n->sym->name);
132 }
133 lineno = oln;
134 Fname = ofn;
135}
136
137static Symbol *
138do_same(Lextok *n, Symbol *v, int xinit)
139{ Lextok *tmp, *fp, *tl;
140 int ix = eval(n->lft);
141 int oln = lineno;
142 Symbol *ofn = Fname;
143
144 lineno = n->ln;
145 Fname = n->fn;
146
147 /* n->sym->type == STRUCT
148 * index: n->lft
149 * subfields: n->rgt
150 * structure template: n->sym->Slst
151 * runtime values: n->sym->Sval
152 */
153 if (xinit) ini_struct(v); /* once, at top level */
154
155 if (ix >= v->nel || ix < 0)
156 { printf("spin: indexing %s[%d] - size is %d\n",
157 v->name, ix, v->nel);
158 fatal("indexing error \'%s\'", v->name);
159 }
160 if (!n->rgt || !n->rgt->lft)
161 { non_fatal("no subfields %s", v->name); /* i.e., wants all */
162 lineno = oln; Fname = ofn;
163 return ZS;
164 }
165
166 if (n->rgt->ntyp != '.')
167 { printf("bad subfield type %d\n", n->rgt->ntyp);
168 alldone(1);
169 }
170
171 tmp = n->rgt->lft;
172 if (tmp->ntyp != NAME && tmp->ntyp != TYPE)
173 { printf("bad subfield entry %d\n", tmp->ntyp);
174 alldone(1);
175 }
176 for (fp = v->Sval[ix]; fp; fp = fp->rgt)
177 for (tl = fp->lft; tl; tl = tl->rgt)
178 if (!strcmp(tl->sym->name, tmp->sym->name))
179 { lineno = oln; Fname = ofn;
180 return tl->sym;
181 }
182 fatal("cannot locate subfield %s", tmp->sym->name);
183 return ZS;
184}
185
186int
187Rval_struct(Lextok *n, Symbol *v, int xinit) /* n varref, v valref */
188{ Symbol *tl;
189 Lextok *tmp;
190 int ix;
191
192 if (!n || !(tl = do_same(n, v, xinit)))
193 return 0;
194
195 tmp = n->rgt->lft;
196 if (tmp->sym->type == STRUCT)
197 { return Rval_struct(tmp, tl, 0);
198 } else if (tmp->rgt)
199 fatal("non-zero 'rgt' on non-structure", 0);
200
201 ix = eval(tmp->lft);
202 if (ix >= tl->nel || ix < 0)
203 fatal("indexing error \'%s\'", tl->name);
204
205 return cast_val(tl->type, tl->val[ix], tl->nbits);
206}
207
208int
209Lval_struct(Lextok *n, Symbol *v, int xinit, int a) /* a = assigned value */
210{ Symbol *tl;
211 Lextok *tmp;
212 int ix;
213
214 if (!(tl = do_same(n, v, xinit)))
215 return 1;
216
217 tmp = n->rgt->lft;
218 if (tmp->sym->type == STRUCT)
219 return Lval_struct(tmp, tl, 0, a);
220 else if (tmp->rgt)
221 fatal("non-zero 'rgt' on non-structure", 0);
222
223 ix = eval(tmp->lft);
224 if (ix >= tl->nel || ix < 0)
225 fatal("indexing error \'%s\'", tl->name);
226
227 if (tl->nbits > 0)
228 a = (a & ((1<<tl->nbits)-1));
229
230 if (a != tl->val[ix])
231 { tl->val[ix] = a;
232 tl->setat = depth;
233 }
234 return 1;
235}
236
237int
238Cnt_flds(Lextok *m)
239{ Lextok *fp, *tl, *n;
240 int cnt = 0;
241
242 if (m->ntyp == ',')
243 { n = m;
244 goto is_lst;
245 }
246 if (!m->sym || m->ntyp != STRUCT)
247 return 1;
248
249 n = getuname(m->sym);
250is_lst:
251 for (fp = n; fp; fp = fp->rgt)
252 for (tl = fp->lft; tl; tl = tl->rgt)
253 { if (tl->sym->type == STRUCT)
254 { if (tl->sym->nel != 1)
255 fatal("array of structures in param list, %s",
256 tl->sym->name);
257 cnt += Cnt_flds(tl->sym->Slst);
258 } else
259 cnt += tl->sym->nel;
260 }
261 return cnt;
262}
263
264int
265Sym_typ(Lextok *t)
266{ Symbol *s = t->sym;
267
268 if (!s) return 0;
269
270 if (s->type != STRUCT)
271 return s->type;
272
273 if (!t->rgt
274 || t->rgt->ntyp != '.' /* gh: had ! in wrong place */
275 || !t->rgt->lft)
276 return STRUCT; /* not a field reference */
277
278 return Sym_typ(t->rgt->lft);
279}
280
281int
282Width_set(int *wdth, int i, Lextok *n)
283{ Lextok *fp, *tl;
284 int j = i, k;
285
286 for (fp = n; fp; fp = fp->rgt)
287 for (tl = fp->lft; tl; tl = tl->rgt)
288 { if (tl->sym->type == STRUCT)
289 j = Width_set(wdth, j, tl->sym->Slst);
290 else
291 { for (k = 0; k < tl->sym->nel; k++, j++)
292 wdth[j] = tl->sym->type;
293 } }
294 return j;
295}
296
297void
298ini_struct(Symbol *s)
299{ int i; Lextok *fp, *tl;
300
301 if (s->type != STRUCT) /* last step */
302 { (void) checkvar(s, 0);
303 return;
304 }
305 if (s->Sval == (Lextok **) 0)
306 { s->Sval = (Lextok **) emalloc(s->nel * sizeof(Lextok *));
307 for (i = 0; i < s->nel; i++)
308 { s->Sval[i] = cpnn(s->Slst, 1, 1, 1);
309
310 for (fp = s->Sval[i]; fp; fp = fp->rgt)
311 for (tl = fp->lft; tl; tl = tl->rgt)
312 ini_struct(tl->sym);
313 } }
314}
315
316static Lextok *
317cpnn(Lextok *s, int L, int R, int S)
318{ Lextok *d; extern int Nid;
319
320 if (!s) return ZN;
321
322 d = (Lextok *) emalloc(sizeof(Lextok));
323 d->ntyp = s->ntyp;
324 d->val = s->val;
325 d->ln = s->ln;
326 d->fn = s->fn;
327 d->sym = s->sym;
328 if (L) d->lft = cpnn(s->lft, 1, 1, S);
329 if (R) d->rgt = cpnn(s->rgt, 1, 1, S);
330
331 if (S && s->sym)
332 { d->sym = (Symbol *) emalloc(sizeof(Symbol));
333 memcpy(d->sym, s->sym, sizeof(Symbol));
334 if (d->sym->type == CHAN)
335 d->sym->Nid = ++Nid;
336 }
337 if (s->sq || s->sl)
338 fatal("cannot happen cpnn", (char *) 0);
339
340 return d;
341}
342
343int
344full_name(FILE *fd, Lextok *n, Symbol *v, int xinit)
345{ Symbol *tl;
346 Lextok *tmp;
347 int hiddenarrays = 0;
348
349 fprintf(fd, "%s", v->name);
350
351 if (!n || !(tl = do_same(n, v, xinit)))
352 return 0;
353 tmp = n->rgt->lft;
354
355 if (tmp->sym->type == STRUCT)
356 { fprintf(fd, ".");
357 hiddenarrays = full_name(fd, tmp, tl, 0);
358 goto out;
359 }
360 fprintf(fd, ".%s", tl->name);
361out: if (tmp->sym->nel > 1)
362 { fprintf(fd, "[%d]", eval(tmp->lft));
363 hiddenarrays = 1;
364 }
365 return hiddenarrays;
366}
367
368void
369validref(Lextok *p, Lextok *c)
370{ Lextok *fp, *tl;
371 char lbuf[512];
372
373 for (fp = p->sym->Slst; fp; fp = fp->rgt)
374 for (tl = fp->lft; tl; tl = tl->rgt)
375 if (strcmp(tl->sym->name, c->sym->name) == 0)
376 return;
377
378 sprintf(lbuf, "no field '%s' defined in structure '%s'\n",
379 c->sym->name, p->sym->name);
380 non_fatal(lbuf, (char *) 0);
381}
382
383void
384struct_name(Lextok *n, Symbol *v, int xinit, char *buf)
385{ Symbol *tl;
386 Lextok *tmp;
387 char lbuf[512];
388
389 if (!n || !(tl = do_same(n, v, xinit)))
390 return;
391 tmp = n->rgt->lft;
392 if (tmp->sym->type == STRUCT)
393 { strcat(buf, ".");
394 struct_name(tmp, tl, 0, buf);
395 return;
396 }
397 sprintf(lbuf, ".%s", tl->name);
398 strcat(buf, lbuf);
399 if (tmp->sym->nel > 1)
400 { sprintf(lbuf, "[%d]", eval(tmp->lft));
401 strcat(buf, lbuf);
402 }
403}
404
405void
406walk2_struct(char *s, Symbol *z)
407{ Lextok *fp, *tl;
408 char eprefix[128];
409 int ix;
410 extern void Done_case(char *, Symbol *);
411
412 ini_struct(z);
413 if (z->nel == 1)
414 sprintf(eprefix, "%s%s.", s, z->name);
415 for (ix = 0; ix < z->nel; ix++)
416 { if (z->nel > 1)
417 sprintf(eprefix, "%s%s[%d].", s, z->name, ix);
418 for (fp = z->Sval[ix]; fp; fp = fp->rgt)
419 for (tl = fp->lft; tl; tl = tl->rgt)
420 { if (tl->sym->type == STRUCT)
421 walk2_struct(eprefix, tl->sym);
422 else if (tl->sym->type == CHAN)
423 Done_case(eprefix, tl->sym);
424 } }
425}
426
427void
428walk_struct(FILE *ofd, int dowhat, char *s, Symbol *z, char *a, char *b, char *c)
429{ Lextok *fp, *tl;
430 char eprefix[128];
431 int ix;
432
433 ini_struct(z);
434 if (z->nel == 1)
435 sprintf(eprefix, "%s%s.", s, z->name);
436 for (ix = 0; ix < z->nel; ix++)
437 { if (z->nel > 1)
438 sprintf(eprefix, "%s%s[%d].", s, z->name, ix);
439 for (fp = z->Sval[ix]; fp; fp = fp->rgt)
440 for (tl = fp->lft; tl; tl = tl->rgt)
441 { if (tl->sym->type == STRUCT)
442 walk_struct(ofd, dowhat, eprefix, tl->sym, a,b,c);
443 else
444 do_var(ofd, dowhat, eprefix, tl->sym, a,b,c);
445 } }
446}
447
448void
449c_struct(FILE *fd, char *ipref, Symbol *z)
450{ Lextok *fp, *tl;
451 char pref[256], eprefix[300];
452 int ix;
453
454 ini_struct(z);
455
456 for (ix = 0; ix < z->nel; ix++)
457 for (fp = z->Sval[ix]; fp; fp = fp->rgt)
458 for (tl = fp->lft; tl; tl = tl->rgt)
459 { strcpy(eprefix, ipref);
460 if (z->nel > 1)
461 { /* insert index before last '.' */
462 eprefix[strlen(eprefix)-1] = '\0';
463 sprintf(pref, "[ %d ].", ix);
464 strcat(eprefix, pref);
465 }
466 if (tl->sym->type == STRUCT)
467 { strcat(eprefix, tl->sym->name);
468 strcat(eprefix, ".");
469 c_struct(fd, eprefix, tl->sym);
470 } else
471 c_var(fd, eprefix, tl->sym);
472 }
473}
474
475void
476dump_struct(Symbol *z, char *prefix, RunList *r)
477{ Lextok *fp, *tl;
478 char eprefix[256];
479 int ix, jx;
480
481 ini_struct(z);
482
483 for (ix = 0; ix < z->nel; ix++)
484 { if (z->nel > 1)
485 sprintf(eprefix, "%s[%d]", prefix, ix);
486 else
487 strcpy(eprefix, prefix);
488
489 for (fp = z->Sval[ix]; fp; fp = fp->rgt)
490 for (tl = fp->lft; tl; tl = tl->rgt)
491 { if (tl->sym->type == STRUCT)
492 { char pref[300];
493 strcpy(pref, eprefix);
494 strcat(pref, ".");
495 strcat(pref, tl->sym->name);
496 dump_struct(tl->sym, pref, r);
497 } else
498 for (jx = 0; jx < tl->sym->nel; jx++)
499 { if (tl->sym->type == CHAN)
500 doq(tl->sym, jx, r);
501 else
502 { printf("\t\t");
503 if (r)
504 printf("%s(%d):", r->n->name, r->pid);
505 printf("%s.%s", eprefix, tl->sym->name);
506 if (tl->sym->nel > 1)
507 printf("[%d]", jx);
508 printf(" = ");
509 sr_mesg(stdout, tl->sym->val[jx],
510 tl->sym->type == MTYPE);
511 printf("\n");
512 } } }
513 }
514}
515
516static int
517retrieve(Lextok **targ, int i, int want, Lextok *n, int Ntyp)
518{ Lextok *fp, *tl;
519 int j = i, k;
520
521 for (fp = n; fp; fp = fp->rgt)
522 for (tl = fp->lft; tl; tl = tl->rgt)
523 { if (tl->sym->type == STRUCT)
524 { j = retrieve(targ, j, want, tl->sym->Slst, Ntyp);
525 if (j < 0)
526 { Lextok *x = cpnn(tl, 1, 0, 0);
527 x->rgt = nn(ZN, '.', (*targ), ZN);
528 (*targ) = x;
529 return -1;
530 }
531 } else
532 { for (k = 0; k < tl->sym->nel; k++, j++)
533 { if (j == want)
534 { *targ = cpnn(tl, 1, 0, 0);
535 (*targ)->lft = nn(ZN, CONST, ZN, ZN);
536 (*targ)->lft->val = k;
537 if (Ntyp)
538 (*targ)->ntyp = (short) Ntyp;
539 return -1;
540 }
541 } } }
542 return j;
543}
544
545static int
546is_explicit(Lextok *n)
547{
548 if (!n) return 0;
549 if (!n->sym) fatal("unexpected - no symbol", 0);
550 if (n->sym->type != STRUCT) return 1;
551 if (!n->rgt) return 0;
552 if (n->rgt->ntyp != '.')
553 { lineno = n->ln;
554 Fname = n->fn;
555 printf("ntyp %d\n", n->rgt->ntyp);
556 fatal("unexpected %s, no '.'", n->sym->name);
557 }
558 return is_explicit(n->rgt->lft);
559}
560
561Lextok *
562expand(Lextok *n, int Ok)
563 /* turn rgt-lnked list of struct nms, into ',' list of flds */
564{ Lextok *x = ZN, *y;
565
566 if (!Ok) return n;
567
568 while (n)
569 { y = mk_explicit(n, 1, 0);
570 if (x)
571 (void) tail_add(x, y);
572 else
573 x = y;
574
575 n = n->rgt;
576 }
577 return x;
578}
579
580Lextok *
581mk_explicit(Lextok *n, int Ok, int Ntyp)
582 /* produce a single ',' list of fields */
583{ Lextok *bld = ZN, *x;
584 int i, cnt; extern int IArgs;
585
586 if (n->sym->type != STRUCT
587 || is_explicit(n))
588 return n;
589
590 if (n->rgt
591 && n->rgt->ntyp == '.'
592 && n->rgt->lft
593 && n->rgt->lft->sym
594 && n->rgt->lft->sym->type == STRUCT)
595 { Lextok *y;
596 bld = mk_explicit(n->rgt->lft, Ok, Ntyp);
597 for (x = bld; x; x = x->rgt)
598 { y = cpnn(n, 1, 0, 0);
599 y->rgt = nn(ZN, '.', x->lft, ZN);
600 x->lft = y;
601 }
602
603 return bld;
604 }
605
606 if (!Ok || !n->sym->Slst)
607 { if (IArgs) return n;
608 printf("spin: saw '");
609 comment(stdout, n, 0);
610 printf("'\n");
611 fatal("incomplete structure ref '%s'", n->sym->name);
612 }
613
614 cnt = Cnt_flds(n->sym->Slst);
615 for (i = cnt-1; i >= 0; i--)
616 { bld = nn(ZN, ',', ZN, bld);
617 if (retrieve(&(bld->lft), 0, i, n->sym->Slst, Ntyp) >= 0)
618 { printf("cannot retrieve field %d\n", i);
619 fatal("bad structure %s", n->sym->name);
620 }
621 x = cpnn(n, 1, 0, 0);
622 x->rgt = nn(ZN, '.', bld->lft, ZN);
623 bld->lft = x;
624 }
625 return bld;
626}
627
628Lextok *
629tail_add(Lextok *a, Lextok *b)
630{ Lextok *t;
631
632 for (t = a; t->rgt; t = t->rgt)
633 if (t->ntyp != ',')
634 fatal("unexpected type - tail_add", 0);
635 t->rgt = b;
636 return a;
637}
638
639void
640setpname(Lextok *n)
641{ UType *tmp;
642
643 for (tmp = Pnames; tmp; tmp = tmp->nxt)
644 if (!strcmp(n->sym->name, tmp->nm->name))
645 { non_fatal("proctype %s redefined",
646 n->sym->name);
647 return;
648 }
649 tmp = (UType *) emalloc(sizeof(UType));
650 tmp->nm = n->sym;
651 tmp->nxt = Pnames;
652 Pnames = tmp;
653}
654
655int
656isproctype(char *t)
657{ UType *tmp;
658
659 for (tmp = Pnames; tmp; tmp = tmp->nxt)
660 { if (!strcmp(t, tmp->nm->name))
661 return 1;
662 }
663 return 0;
664}
This page took 0.046014 seconds and 4 git commands to generate.