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