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
, has_hidden
;
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);
37 fatal("illegal reference inside typedef", (char *) 0);
39 for (tmp
= Unames
; tmp
; tmp
= tmp
->nxt
)
40 if (!strcmp(owner
->name
, tmp
->nm
->name
))
41 { non_fatal("typename %s was defined before",
46 tmp
= (UType
*) emalloc(sizeof(UType
));
54 putUname(FILE *fd
, UType
*tmp
)
58 putUname(fd
, tmp
->nxt
); /* postorder */
59 fprintf(fd
, "struct %s { /* user defined type */\n",
61 for (fp
= tmp
->cn
; fp
; fp
= fp
->rgt
)
62 for (tl
= fp
->lft
; tl
; tl
= tl
->rgt
)
77 for (tmp
= Unames
; tmp
; tmp
= tmp
->nxt
)
78 { if (!strcmp(t
, tmp
->nm
->name
))
88 for (tmp
= Unames
; tmp
; tmp
= tmp
->nxt
)
89 { if (!strcmp(t
->name
, tmp
->nm
->name
))
92 fatal("%s is not a typename", t
->name
);
97 setutype(Lextok
*p
, Symbol
*t
, Lextok
*vis
) /* user-defined types */
103 for (n
= p
; n
; n
= n
->rgt
)
107 non_fatal("redeclaration of '%s'", n
->sym
->name
);
109 if (n
->sym
->nbits
> 0)
110 non_fatal("(%s) only an unsigned can have width-field",
114 n
->sym
->hidden
|= (4|8|16); /* formal par */
117 { if (strncmp(vis
->sym
->name
, ":hide:", (size_t) 6) == 0)
118 { n
->sym
->hidden
|= 1;
120 } else if (strncmp(vis
->sym
->name
, ":show:", (size_t) 6) == 0)
122 else if (strncmp(vis
->sym
->name
, ":local:", (size_t) 7) == 0)
123 n
->sym
->hidden
|= 64;
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 */
130 if (n
->sym
->nel
<= 0)
131 non_fatal("bad array size for '%s'", n
->sym
->name
);
138 do_same(Lextok
*n
, Symbol
*v
, int xinit
)
139 { Lextok
*tmp
, *fp
, *tl
;
140 int ix
= eval(n
->lft
);
147 /* n->sym->type == STRUCT
150 * structure template: n->sym->Slst
151 * runtime values: n->sym->Sval
153 if (xinit
) ini_struct(v
); /* once, at top level */
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
);
160 if (!n
->rgt
|| !n
->rgt
->lft
)
161 { non_fatal("no subfields %s", v
->name
); /* i.e., wants all */
162 lineno
= oln
; Fname
= ofn
;
166 if (n
->rgt
->ntyp
!= '.')
167 { printf("bad subfield type %d\n", n
->rgt
->ntyp
);
172 if (tmp
->ntyp
!= NAME
&& tmp
->ntyp
!= TYPE
)
173 { printf("bad subfield entry %d\n", tmp
->ntyp
);
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
;
182 fatal("cannot locate subfield %s", tmp
->sym
->name
);
187 Rval_struct(Lextok
*n
, Symbol
*v
, int xinit
) /* n varref, v valref */
192 if (!n
|| !(tl
= do_same(n
, v
, xinit
)))
196 if (tmp
->sym
->type
== STRUCT
)
197 { return Rval_struct(tmp
, tl
, 0);
199 fatal("non-zero 'rgt' on non-structure", 0);
202 if (ix
>= tl
->nel
|| ix
< 0)
203 fatal("indexing error \'%s\'", tl
->name
);
205 return cast_val(tl
->type
, tl
->val
[ix
], tl
->nbits
);
209 Lval_struct(Lextok
*n
, Symbol
*v
, int xinit
, int a
) /* a = assigned value */
214 if (!(tl
= do_same(n
, v
, xinit
)))
218 if (tmp
->sym
->type
== STRUCT
)
219 return Lval_struct(tmp
, tl
, 0, a
);
221 fatal("non-zero 'rgt' on non-structure", 0);
224 if (ix
>= tl
->nel
|| ix
< 0)
225 fatal("indexing error \'%s\'", tl
->name
);
228 a
= (a
& ((1<<tl
->nbits
)-1));
230 if (a
!= tl
->val
[ix
])
239 { Lextok
*fp
, *tl
, *n
;
246 if (!m
->sym
|| m
->ntyp
!= STRUCT
)
249 n
= getuname(m
->sym
);
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",
257 cnt
+= Cnt_flds(tl
->sym
->Slst
);
266 { Symbol
*s
= t
->sym
;
270 if (s
->type
!= STRUCT
)
274 || t
->rgt
->ntyp
!= '.' /* gh: had ! in wrong place */
276 return STRUCT
; /* not a field reference */
278 return Sym_typ(t
->rgt
->lft
);
282 Width_set(int *wdth
, int i
, Lextok
*n
)
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
);
291 { for (k
= 0; k
< tl
->sym
->nel
; k
++, j
++)
292 wdth
[j
] = tl
->sym
->type
;
298 ini_struct(Symbol
*s
)
299 { int i
; Lextok
*fp
, *tl
;
301 if (s
->type
!= STRUCT
) /* last step */
302 { (void) checkvar(s
, 0);
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);
310 for (fp
= s
->Sval
[i
]; fp
; fp
= fp
->rgt
)
311 for (tl
= fp
->lft
; tl
; tl
= tl
->rgt
)
317 cpnn(Lextok
*s
, int L
, int R
, int S
)
318 { Lextok
*d
; extern int Nid
;
322 d
= (Lextok
*) emalloc(sizeof(Lextok
));
328 if (L
) d
->lft
= cpnn(s
->lft
, 1, 1, S
);
329 if (R
) d
->rgt
= cpnn(s
->rgt
, 1, 1, S
);
332 { d
->sym
= (Symbol
*) emalloc(sizeof(Symbol
));
333 memcpy(d
->sym
, s
->sym
, sizeof(Symbol
));
334 if (d
->sym
->type
== CHAN
)
338 fatal("cannot happen cpnn", (char *) 0);
344 full_name(FILE *fd
, Lextok
*n
, Symbol
*v
, int xinit
)
347 int hiddenarrays
= 0;
349 fprintf(fd
, "%s", v
->name
);
351 if (!n
|| !(tl
= do_same(n
, v
, xinit
)))
355 if (tmp
->sym
->type
== STRUCT
)
357 hiddenarrays
= full_name(fd
, tmp
, tl
, 0);
360 fprintf(fd
, ".%s", tl
->name
);
361 out
: if (tmp
->sym
->nel
> 1)
362 { fprintf(fd
, "[%d]", eval(tmp
->lft
));
369 validref(Lextok
*p
, Lextok
*c
)
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)
378 sprintf(lbuf
, "no field '%s' defined in structure '%s'\n",
379 c
->sym
->name
, p
->sym
->name
);
380 non_fatal(lbuf
, (char *) 0);
384 struct_name(Lextok
*n
, Symbol
*v
, int xinit
, char *buf
)
389 if (!n
|| !(tl
= do_same(n
, v
, xinit
)))
392 if (tmp
->sym
->type
== STRUCT
)
394 struct_name(tmp
, tl
, 0, buf
);
397 sprintf(lbuf
, ".%s", tl
->name
);
399 if (tmp
->sym
->nel
> 1)
400 { sprintf(lbuf
, "[%d]", eval(tmp
->lft
));
406 walk2_struct(char *s
, Symbol
*z
)
410 extern void Done_case(char *, Symbol
*);
414 sprintf(eprefix
, "%s%s.", s
, z
->name
);
415 for (ix
= 0; ix
< z
->nel
; ix
++)
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
);
428 walk_struct(FILE *ofd
, int dowhat
, char *s
, Symbol
*z
, char *a
, char *b
, char *c
)
435 sprintf(eprefix
, "%s%s.", s
, z
->name
);
436 for (ix
= 0; ix
< z
->nel
; ix
++)
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
);
444 do_var(ofd
, dowhat
, eprefix
, tl
->sym
, a
,b
,c
);
449 c_struct(FILE *fd
, char *ipref
, Symbol
*z
)
451 char pref
[256], eprefix
[300];
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
);
461 { /* insert index before last '.' */
462 eprefix
[strlen(eprefix
)-1] = '\0';
463 sprintf(pref
, "[ %d ].", ix
);
464 strcat(eprefix
, pref
);
466 if (tl
->sym
->type
== STRUCT
)
467 { strcat(eprefix
, tl
->sym
->name
);
468 strcat(eprefix
, ".");
469 c_struct(fd
, eprefix
, tl
->sym
);
471 c_var(fd
, eprefix
, tl
->sym
);
476 dump_struct(Symbol
*z
, char *prefix
, RunList
*r
)
483 for (ix
= 0; ix
< z
->nel
; ix
++)
485 sprintf(eprefix
, "%s[%d]", prefix
, ix
);
487 strcpy(eprefix
, prefix
);
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
)
493 strcpy(pref
, eprefix
);
495 strcat(pref
, tl
->sym
->name
);
496 dump_struct(tl
->sym
, pref
, r
);
498 for (jx
= 0; jx
< tl
->sym
->nel
; jx
++)
499 { if (tl
->sym
->type
== CHAN
)
504 printf("%s(%d):", r
->n
->name
, r
->pid
);
505 printf("%s.%s", eprefix
, tl
->sym
->name
);
506 if (tl
->sym
->nel
> 1)
509 sr_mesg(stdout
, tl
->sym
->val
[jx
],
510 tl
->sym
->type
== MTYPE
);
517 retrieve(Lextok
**targ
, int i
, int want
, Lextok
*n
, int Ntyp
)
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
);
526 { Lextok
*x
= cpnn(tl
, 1, 0, 0);
527 x
->rgt
= nn(ZN
, '.', (*targ
), ZN
);
532 { for (k
= 0; k
< tl
->sym
->nel
; k
++, j
++)
534 { *targ
= cpnn(tl
, 1, 0, 0);
535 (*targ
)->lft
= nn(ZN
, CONST
, ZN
, ZN
);
536 (*targ
)->lft
->val
= k
;
538 (*targ
)->ntyp
= (short) Ntyp
;
546 is_explicit(Lextok
*n
)
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
!= '.')
555 printf("ntyp %d\n", n
->rgt
->ntyp
);
556 fatal("unexpected %s, no '.'", n
->sym
->name
);
558 return is_explicit(n
->rgt
->lft
);
562 expand(Lextok
*n
, int Ok
)
563 /* turn rgt-lnked list of struct nms, into ',' list of flds */
564 { Lextok
*x
= ZN
, *y
;
569 { y
= mk_explicit(n
, 1, 0);
571 (void) tail_add(x
, y
);
581 mk_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
;
586 if (n
->sym
->type
!= STRUCT
591 && n
->rgt
->ntyp
== '.'
594 && n
->rgt
->lft
->sym
->type
== STRUCT
)
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
);
606 if (!Ok
|| !n
->sym
->Slst
)
607 { if (IArgs
) return n
;
608 printf("spin: saw '");
609 comment(stdout
, n
, 0);
611 fatal("incomplete structure ref '%s'", n
->sym
->name
);
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
);
621 x
= cpnn(n
, 1, 0, 0);
622 x
->rgt
= nn(ZN
, '.', bld
->lft
, ZN
);
629 tail_add(Lextok
*a
, Lextok
*b
)
632 for (t
= a
; t
->rgt
; t
= t
->rgt
)
634 fatal("unexpected type - tail_add", 0);
643 for (tmp
= Pnames
; tmp
; tmp
= tmp
->nxt
)
644 if (!strcmp(n
->sym
->name
, tmp
->nm
->name
))
645 { non_fatal("proctype %s redefined",
649 tmp
= (UType
*) emalloc(sizeof(UType
));
659 for (tmp
= Pnames
; tmp
; tmp
= tmp
->nxt
)
660 { if (!strcmp(t
, tmp
->nm
->name
))
This page took 0.043904 seconds and 4 git commands to generate.