1 /***** spin: structs.c *****/
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 */
15 typedef struct UType {
16 Symbol *nm; /* name of the type */
17 Lextok *cn; /* contents */
18 struct UType *nxt; /* linked list */
22 extern int lineno, depth, Expand_Ok;
26 static UType *Unames = 0;
27 static UType *Pnames = 0;
29 static Lextok *cpnn(Lextok *, int, int, int);
30 extern void sr_mesg(FILE *, int, int);
36 for (tmp = Unames; tmp; tmp = tmp->nxt)
37 if (!strcmp(owner->name, tmp->nm->name))
38 { non_fatal("typename %s was defined before",
42 if (!owner) fatal("illegal reference inside typedef",
44 tmp = (UType *) emalloc(sizeof(UType));
52 putUname(FILE *fd, UType *tmp)
56 putUname(fd, tmp->nxt); /* postorder */
57 fprintf(fd, "struct %s { /* user defined type */\n",
59 for (fp = tmp->cn; fp; fp = fp->rgt)
60 for (tl = fp->lft; tl; tl = tl->rgt)
75 for (tmp = Unames; tmp; tmp = tmp->nxt)
76 { if (!strcmp(t, tmp->nm->name))
86 for (tmp = Unames; tmp; tmp = tmp->nxt)
87 { if (!strcmp(t->name, tmp->nm->name))
90 fatal("%s is not a typename", t->name);
95 setutype(Lextok *p, Symbol *t, Lextok *vis) /* user-defined types */
101 for (n = p; n; n = n->rgt)
105 non_fatal("redeclaration of '%s'", n->sym->name);
107 if (n->sym->nbits > 0)
108 non_fatal("(%s) only an unsigned can have width-field",
112 n->sym->hidden |= (4|8|16); /* formal par */
115 { if (strncmp(vis->sym->name, ":hide:", 6) == 0)
117 else if (strncmp(vis->sym->name, ":show:", 6) == 0)
119 else if (strncmp(vis->sym->name, ":local:", 7) == 0)
120 n->sym->hidden |= 64;
122 n->sym->type = STRUCT; /* classification */
123 n->sym->Slst = m; /* structure itself */
124 n->sym->Snm = t; /* name of typedef */
125 n->sym->Nid = 0; /* this is no chan */
127 if (n->sym->nel <= 0)
128 non_fatal("bad array size for '%s'", n->sym->name);
135 do_same(Lextok *n, Symbol *v, int xinit)
136 { Lextok *tmp, *fp, *tl;
137 int ix = eval(n->lft);
144 /* n->sym->type == STRUCT
147 * structure template: n->sym->Slst
148 * runtime values: n->sym->Sval
150 if (xinit) ini_struct(v); /* once, at top level */
152 if (ix >= v->nel || ix < 0)
153 { printf("spin: indexing %s[%d] - size is %d\n",
154 v->name, ix, v->nel);
155 fatal("indexing error \'%s\'", v->name);
157 if (!n->rgt || !n->rgt->lft)
158 { non_fatal("no subfields %s", v->name); /* i.e., wants all */
159 lineno = oln; Fname = ofn;
163 if (n->rgt->ntyp != '.')
164 { printf("bad subfield type %d\n", n->rgt->ntyp);
169 if (tmp->ntyp != NAME && tmp->ntyp != TYPE)
170 { printf("bad subfield entry %d\n", tmp->ntyp);
173 for (fp = v->Sval[ix]; fp; fp = fp->rgt)
174 for (tl = fp->lft; tl; tl = tl->rgt)
175 if (!strcmp(tl->sym->name, tmp->sym->name))
176 { lineno = oln; Fname = ofn;
179 fatal("cannot locate subfield %s", tmp->sym->name);
184 Rval_struct(Lextok *n, Symbol *v, int xinit) /* n varref, v valref */
189 if (!n || !(tl = do_same(n, v, xinit)))
193 if (tmp->sym->type == STRUCT)
194 { return Rval_struct(tmp, tl, 0);
196 fatal("non-zero 'rgt' on non-structure", 0);
199 if (ix >= tl->nel || ix < 0)
200 fatal("indexing error \'%s\'", tl->name);
202 return cast_val(tl->type, tl->val[ix], tl->nbits);
206 Lval_struct(Lextok *n, Symbol *v, int xinit, int a) /* a = assigned value */
211 if (!(tl = do_same(n, v, xinit)))
215 if (tmp->sym->type == STRUCT)
216 return Lval_struct(tmp, tl, 0, a);
218 fatal("non-zero 'rgt' on non-structure", 0);
221 if (ix >= tl->nel || ix < 0)
222 fatal("indexing error \'%s\'", tl->name);
225 a = (a & ((1<<tl->nbits)-1));
234 { Lextok *fp, *tl, *n;
241 if (!m->sym || m->ntyp != STRUCT)
244 n = getuname(m->sym);
246 for (fp = n; fp; fp = fp->rgt)
247 for (tl = fp->lft; tl; tl = tl->rgt)
248 { if (tl->sym->type == STRUCT)
249 { if (tl->sym->nel != 1)
250 fatal("array of structures in param list, %s",
252 cnt += Cnt_flds(tl->sym->Slst);
261 { Symbol *s = t->sym;
265 if (s->type != STRUCT)
269 || !t->rgt->ntyp == '.'
271 return STRUCT; /* not a field reference */
273 return Sym_typ(t->rgt->lft);
277 Width_set(int *wdth, int i, Lextok *n)
281 for (fp = n; fp; fp = fp->rgt)
282 for (tl = fp->lft; tl; tl = tl->rgt)
283 { if (tl->sym->type == STRUCT)
284 j = Width_set(wdth, j, tl->sym->Slst);
286 { for (k = 0; k < tl->sym->nel; k++, j++)
287 wdth[j] = tl->sym->type;
293 ini_struct(Symbol *s)
294 { int i; Lextok *fp, *tl;
296 if (s->type != STRUCT) /* last step */
297 { (void) checkvar(s, 0);
300 if (s->Sval == (Lextok **) 0)
301 { s->Sval = (Lextok **) emalloc(s->nel * sizeof(Lextok *));
302 for (i = 0; i < s->nel; i++)
303 { s->Sval[i] = cpnn(s->Slst, 1, 1, 1);
305 for (fp = s->Sval[i]; fp; fp = fp->rgt)
306 for (tl = fp->lft; tl; tl = tl->rgt)
312 cpnn(Lextok *s, int L, int R, int S)
313 { Lextok *d; extern int Nid;
317 d = (Lextok *) emalloc(sizeof(Lextok));
323 if (L) d->lft = cpnn(s->lft, 1, 1, S);
324 if (R) d->rgt = cpnn(s->rgt, 1, 1, S);
327 { d->sym = (Symbol *) emalloc(sizeof(Symbol));
328 memcpy(d->sym, s->sym, sizeof(Symbol));
329 if (d->sym->type == CHAN)
333 fatal("cannot happen cpnn", (char *) 0);
339 full_name(FILE *fd, Lextok *n, Symbol *v, int xinit)
342 int hiddenarrays = 0;
344 fprintf(fd, "%s", v->name);
346 if (!n || !(tl = do_same(n, v, xinit)))
350 if (tmp->sym->type == STRUCT)
352 hiddenarrays = full_name(fd, tmp, tl, 0);
355 fprintf(fd, ".%s", tl->name);
356 out: if (tmp->sym->nel > 1)
357 { fprintf(fd, "[%d]", eval(tmp->lft));
364 validref(Lextok *p, Lextok *c)
368 for (fp = p->sym->Slst; fp; fp = fp->rgt)
369 for (tl = fp->lft; tl; tl = tl->rgt)
370 if (strcmp(tl->sym->name, c->sym->name) == 0)
373 sprintf(lbuf, "no field '%s' defined in structure '%s'\n",
374 c->sym->name, p->sym->name);
375 non_fatal(lbuf, (char *) 0);
379 struct_name(Lextok *n, Symbol *v, int xinit, char *buf)
384 if (!n || !(tl = do_same(n, v, xinit)))
387 if (tmp->sym->type == STRUCT)
389 struct_name(tmp, tl, 0, buf);
392 sprintf(lbuf, ".%s", tl->name);
394 if (tmp->sym->nel > 1)
395 { sprintf(lbuf, "[%d]", eval(tmp->lft));
401 walk2_struct(char *s, Symbol *z)
405 extern void Done_case(char *, Symbol *);
409 sprintf(eprefix, "%s%s.", s, z->name);
410 for (ix = 0; ix < z->nel; ix++)
412 sprintf(eprefix, "%s%s[%d].", s, z->name, ix);
413 for (fp = z->Sval[ix]; fp; fp = fp->rgt)
414 for (tl = fp->lft; tl; tl = tl->rgt)
415 { if (tl->sym->type == STRUCT)
416 walk2_struct(eprefix, tl->sym);
417 else if (tl->sym->type == CHAN)
418 Done_case(eprefix, tl->sym);
423 walk_struct(FILE *ofd, int dowhat, char *s, Symbol *z, char *a, char *b, char *c)
430 sprintf(eprefix, "%s%s.", s, z->name);
431 for (ix = 0; ix < z->nel; ix++)
433 sprintf(eprefix, "%s%s[%d].", s, z->name, ix);
434 for (fp = z->Sval[ix]; fp; fp = fp->rgt)
435 for (tl = fp->lft; tl; tl = tl->rgt)
436 { if (tl->sym->type == STRUCT)
437 walk_struct(ofd, dowhat, eprefix, tl->sym, a,b,c);
439 do_var(ofd, dowhat, eprefix, tl->sym, a,b,c);
444 c_struct(FILE *fd, char *ipref, Symbol *z)
446 char pref[256], eprefix[256];
451 for (ix = 0; ix < z->nel; ix++)
452 for (fp = z->Sval[ix]; fp; fp = fp->rgt)
453 for (tl = fp->lft; tl; tl = tl->rgt)
454 { strcpy(eprefix, ipref);
456 { /* insert index before last '.' */
457 eprefix[strlen(eprefix)-1] = '\0';
458 sprintf(pref, "[ %d ].", ix);
459 strcat(eprefix, pref);
461 if (tl->sym->type == STRUCT)
462 { strcat(eprefix, tl->sym->name);
463 strcat(eprefix, ".");
464 c_struct(fd, eprefix, tl->sym);
466 c_var(fd, eprefix, tl->sym);
471 dump_struct(Symbol *z, char *prefix, RunList *r)
478 for (ix = 0; ix < z->nel; ix++)
480 sprintf(eprefix, "%s[%d]", prefix, ix);
482 strcpy(eprefix, prefix);
484 for (fp = z->Sval[ix]; fp; fp = fp->rgt)
485 for (tl = fp->lft; tl; tl = tl->rgt)
486 { if (tl->sym->type == STRUCT)
488 strcpy(pref, eprefix);
490 strcat(pref, tl->sym->name);
491 dump_struct(tl->sym, pref, r);
493 for (jx = 0; jx < tl->sym->nel; jx++)
494 { if (tl->sym->type == CHAN)
499 printf("%s(%d):", r->n->name, r->pid);
500 printf("%s.%s", eprefix, tl->sym->name);
501 if (tl->sym->nel > 1)
504 sr_mesg(stdout, tl->sym->val[jx],
505 tl->sym->type == MTYPE);
512 retrieve(Lextok **targ, int i, int want, Lextok *n, int Ntyp)
516 for (fp = n; fp; fp = fp->rgt)
517 for (tl = fp->lft; tl; tl = tl->rgt)
518 { if (tl->sym->type == STRUCT)
519 { j = retrieve(targ, j, want, tl->sym->Slst, Ntyp);
521 { Lextok *x = cpnn(tl, 1, 0, 0);
522 x->rgt = nn(ZN, '.', (*targ), ZN);
527 { for (k = 0; k < tl->sym->nel; k++, j++)
529 { *targ = cpnn(tl, 1, 0, 0);
530 (*targ)->lft = nn(ZN, CONST, ZN, ZN);
531 (*targ)->lft->val = k;
533 (*targ)->ntyp = (short) Ntyp;
541 is_explicit(Lextok *n)
544 if (!n->sym) fatal("unexpected - no symbol", 0);
545 if (n->sym->type != STRUCT) return 1;
546 if (!n->rgt) return 0;
547 if (n->rgt->ntyp != '.')
550 printf("ntyp %d\n", n->rgt->ntyp);
551 fatal("unexpected %s, no '.'", n->sym->name);
553 return is_explicit(n->rgt->lft);
557 expand(Lextok *n, int Ok)
558 /* turn rgt-lnked list of struct nms, into ',' list of flds */
559 { Lextok *x = ZN, *y;
564 { y = mk_explicit(n, 1, 0);
566 (void) tail_add(x, y);
576 mk_explicit(Lextok *n, int Ok, int Ntyp)
577 /* produce a single ',' list of fields */
578 { Lextok *bld = ZN, *x;
579 int i, cnt; extern int IArgs;
581 if (n->sym->type != STRUCT
586 && n->rgt->ntyp == '.'
589 && n->rgt->lft->sym->type == STRUCT)
591 bld = mk_explicit(n->rgt->lft, Ok, Ntyp);
592 for (x = bld; x; x = x->rgt)
593 { y = cpnn(n, 1, 0, 0);
594 y->rgt = nn(ZN, '.', x->lft, ZN);
601 if (!Ok || !n->sym->Slst)
602 { if (IArgs) return n;
603 printf("spin: saw '");
604 comment(stdout, n, 0);
606 fatal("incomplete structure ref '%s'", n->sym->name);
609 cnt = Cnt_flds(n->sym->Slst);
610 for (i = cnt-1; i >= 0; i--)
611 { bld = nn(ZN, ',', ZN, bld);
612 if (retrieve(&(bld->lft), 0, i, n->sym->Slst, Ntyp) >= 0)
613 { printf("cannot retrieve field %d\n", i);
614 fatal("bad structure %s", n->sym->name);
616 x = cpnn(n, 1, 0, 0);
617 x->rgt = nn(ZN, '.', bld->lft, ZN);
624 tail_add(Lextok *a, Lextok *b)
627 for (t = a; t->rgt; t = t->rgt)
629 fatal("unexpected type - tail_add", 0);
638 for (tmp = Pnames; tmp; tmp = tmp->nxt)
639 if (!strcmp(n->sym->name, tmp->nm->name))
640 { non_fatal("proctype %s redefined",
644 tmp = (UType *) emalloc(sizeof(UType));
654 for (tmp = Pnames; tmp; tmp = tmp->nxt)
655 { if (!strcmp(t, tmp->nm->name))