17dd7cddfSDavid du Colombier /***** spin: structs.c *****/ 27dd7cddfSDavid du Colombier 3312a1df1SDavid du Colombier /* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ 47dd7cddfSDavid du Colombier /* All Rights Reserved. This software is for educational purposes only. */ 5312a1df1SDavid du Colombier /* No guarantee whatsoever is expressed or implied by the distribution of */ 6312a1df1SDavid du Colombier /* this code. Permission is given to distribute this code provided that */ 7312a1df1SDavid du Colombier /* this introductory message is not removed and no monies are exchanged. */ 8312a1df1SDavid du Colombier /* Software written by Gerard J. Holzmann. For tool documentation see: */ 9312a1df1SDavid du Colombier /* http://spinroot.com/ */ 10312a1df1SDavid du Colombier /* Send all bug-reports and/or questions to: bugs@spinroot.com */ 117dd7cddfSDavid du Colombier 127dd7cddfSDavid du Colombier #include "spin.h" 137dd7cddfSDavid du Colombier #include "y.tab.h" 147dd7cddfSDavid du Colombier 157dd7cddfSDavid du Colombier typedef struct UType { 167dd7cddfSDavid du Colombier Symbol *nm; /* name of the type */ 177dd7cddfSDavid du Colombier Lextok *cn; /* contents */ 187dd7cddfSDavid du Colombier struct UType *nxt; /* linked list */ 197dd7cddfSDavid du Colombier } UType; 207dd7cddfSDavid du Colombier 217dd7cddfSDavid du Colombier extern Symbol *Fname; 22*00d97012SDavid du Colombier extern int lineno, depth, Expand_Ok, has_hidden, in_for; 237dd7cddfSDavid du Colombier 247dd7cddfSDavid du Colombier Symbol *owner; 257dd7cddfSDavid du Colombier 267dd7cddfSDavid du Colombier static UType *Unames = 0; 277dd7cddfSDavid du Colombier static UType *Pnames = 0; 287dd7cddfSDavid du Colombier 297dd7cddfSDavid du Colombier static Lextok *cpnn(Lextok *, int, int, int); 307dd7cddfSDavid du Colombier extern void sr_mesg(FILE *, int, int); 317dd7cddfSDavid du Colombier 327dd7cddfSDavid du Colombier void 337dd7cddfSDavid du Colombier setuname(Lextok *n) 347dd7cddfSDavid du Colombier { UType *tmp; 357dd7cddfSDavid du Colombier 36*00d97012SDavid du Colombier if (!owner) 37*00d97012SDavid du Colombier fatal("illegal reference inside typedef", (char *) 0); 38*00d97012SDavid du Colombier 397dd7cddfSDavid du Colombier for (tmp = Unames; tmp; tmp = tmp->nxt) 407dd7cddfSDavid du Colombier if (!strcmp(owner->name, tmp->nm->name)) 417dd7cddfSDavid du Colombier { non_fatal("typename %s was defined before", 427dd7cddfSDavid du Colombier tmp->nm->name); 437dd7cddfSDavid du Colombier return; 447dd7cddfSDavid du Colombier } 45*00d97012SDavid du Colombier 467dd7cddfSDavid du Colombier tmp = (UType *) emalloc(sizeof(UType)); 477dd7cddfSDavid du Colombier tmp->nm = owner; 487dd7cddfSDavid du Colombier tmp->cn = n; 497dd7cddfSDavid du Colombier tmp->nxt = Unames; 507dd7cddfSDavid du Colombier Unames = tmp; 517dd7cddfSDavid du Colombier } 527dd7cddfSDavid du Colombier 537dd7cddfSDavid du Colombier static void 547dd7cddfSDavid du Colombier putUname(FILE *fd, UType *tmp) 557dd7cddfSDavid du Colombier { Lextok *fp, *tl; 567dd7cddfSDavid du Colombier 577dd7cddfSDavid du Colombier if (!tmp) return; 587dd7cddfSDavid du Colombier putUname(fd, tmp->nxt); /* postorder */ 597dd7cddfSDavid du Colombier fprintf(fd, "struct %s { /* user defined type */\n", 607dd7cddfSDavid du Colombier tmp->nm->name); 617dd7cddfSDavid du Colombier for (fp = tmp->cn; fp; fp = fp->rgt) 627dd7cddfSDavid du Colombier for (tl = fp->lft; tl; tl = tl->rgt) 637dd7cddfSDavid du Colombier typ2c(tl->sym); 647dd7cddfSDavid du Colombier fprintf(fd, "};\n"); 657dd7cddfSDavid du Colombier } 667dd7cddfSDavid du Colombier 677dd7cddfSDavid du Colombier void 687dd7cddfSDavid du Colombier putunames(FILE *fd) 697dd7cddfSDavid du Colombier { 707dd7cddfSDavid du Colombier putUname(fd, Unames); 717dd7cddfSDavid du Colombier } 727dd7cddfSDavid du Colombier 737dd7cddfSDavid du Colombier int 747dd7cddfSDavid du Colombier isutype(char *t) 757dd7cddfSDavid du Colombier { UType *tmp; 767dd7cddfSDavid du Colombier 777dd7cddfSDavid du Colombier for (tmp = Unames; tmp; tmp = tmp->nxt) 787dd7cddfSDavid du Colombier { if (!strcmp(t, tmp->nm->name)) 797dd7cddfSDavid du Colombier return 1; 807dd7cddfSDavid du Colombier } 817dd7cddfSDavid du Colombier return 0; 827dd7cddfSDavid du Colombier } 837dd7cddfSDavid du Colombier 847dd7cddfSDavid du Colombier Lextok * 857dd7cddfSDavid du Colombier getuname(Symbol *t) 867dd7cddfSDavid du Colombier { UType *tmp; 877dd7cddfSDavid du Colombier 887dd7cddfSDavid du Colombier for (tmp = Unames; tmp; tmp = tmp->nxt) 897dd7cddfSDavid du Colombier { if (!strcmp(t->name, tmp->nm->name)) 907dd7cddfSDavid du Colombier return tmp->cn; 917dd7cddfSDavid du Colombier } 927dd7cddfSDavid du Colombier fatal("%s is not a typename", t->name); 937dd7cddfSDavid du Colombier return (Lextok *)0; 947dd7cddfSDavid du Colombier } 957dd7cddfSDavid du Colombier 967dd7cddfSDavid du Colombier void 977dd7cddfSDavid du Colombier setutype(Lextok *p, Symbol *t, Lextok *vis) /* user-defined types */ 987dd7cddfSDavid du Colombier { int oln = lineno; 997dd7cddfSDavid du Colombier Symbol *ofn = Fname; 1007dd7cddfSDavid du Colombier Lextok *m, *n; 1017dd7cddfSDavid du Colombier 1027dd7cddfSDavid du Colombier m = getuname(t); 1037dd7cddfSDavid du Colombier for (n = p; n; n = n->rgt) 1047dd7cddfSDavid du Colombier { lineno = n->ln; 1057dd7cddfSDavid du Colombier Fname = n->fn; 1067dd7cddfSDavid du Colombier if (n->sym->type) 107*00d97012SDavid du Colombier fatal("redeclaration of '%s'", n->sym->name); 1087dd7cddfSDavid du Colombier 1097dd7cddfSDavid du Colombier if (n->sym->nbits > 0) 1107dd7cddfSDavid du Colombier non_fatal("(%s) only an unsigned can have width-field", 1117dd7cddfSDavid du Colombier n->sym->name); 1127dd7cddfSDavid du Colombier 1137dd7cddfSDavid du Colombier if (Expand_Ok) 1147dd7cddfSDavid du Colombier n->sym->hidden |= (4|8|16); /* formal par */ 1157dd7cddfSDavid du Colombier 1167dd7cddfSDavid du Colombier if (vis) 117*00d97012SDavid du Colombier { if (strncmp(vis->sym->name, ":hide:", (size_t) 6) == 0) 118*00d97012SDavid du Colombier { n->sym->hidden |= 1; 119*00d97012SDavid du Colombier has_hidden++; 120*00d97012SDavid du Colombier } else if (strncmp(vis->sym->name, ":show:", (size_t) 6) == 0) 1217dd7cddfSDavid du Colombier n->sym->hidden |= 2; 122*00d97012SDavid du Colombier else if (strncmp(vis->sym->name, ":local:", (size_t) 7) == 0) 1237dd7cddfSDavid du Colombier n->sym->hidden |= 64; 1247dd7cddfSDavid du Colombier } 1257dd7cddfSDavid du Colombier n->sym->type = STRUCT; /* classification */ 1267dd7cddfSDavid du Colombier n->sym->Slst = m; /* structure itself */ 1277dd7cddfSDavid du Colombier n->sym->Snm = t; /* name of typedef */ 1287dd7cddfSDavid du Colombier n->sym->Nid = 0; /* this is no chan */ 1297dd7cddfSDavid du Colombier n->sym->hidden |= 4; 1307dd7cddfSDavid du Colombier if (n->sym->nel <= 0) 1317dd7cddfSDavid du Colombier non_fatal("bad array size for '%s'", n->sym->name); 1327dd7cddfSDavid du Colombier } 1337dd7cddfSDavid du Colombier lineno = oln; 1347dd7cddfSDavid du Colombier Fname = ofn; 1357dd7cddfSDavid du Colombier } 1367dd7cddfSDavid du Colombier 1377dd7cddfSDavid du Colombier static Symbol * 1387dd7cddfSDavid du Colombier do_same(Lextok *n, Symbol *v, int xinit) 1397dd7cddfSDavid du Colombier { Lextok *tmp, *fp, *tl; 1407dd7cddfSDavid du Colombier int ix = eval(n->lft); 1417dd7cddfSDavid du Colombier int oln = lineno; 1427dd7cddfSDavid du Colombier Symbol *ofn = Fname; 1437dd7cddfSDavid du Colombier 1447dd7cddfSDavid du Colombier lineno = n->ln; 1457dd7cddfSDavid du Colombier Fname = n->fn; 1467dd7cddfSDavid du Colombier 1477dd7cddfSDavid du Colombier /* n->sym->type == STRUCT 1487dd7cddfSDavid du Colombier * index: n->lft 1497dd7cddfSDavid du Colombier * subfields: n->rgt 1507dd7cddfSDavid du Colombier * structure template: n->sym->Slst 1517dd7cddfSDavid du Colombier * runtime values: n->sym->Sval 1527dd7cddfSDavid du Colombier */ 1537dd7cddfSDavid du Colombier if (xinit) ini_struct(v); /* once, at top level */ 1547dd7cddfSDavid du Colombier 1557dd7cddfSDavid du Colombier if (ix >= v->nel || ix < 0) 1567dd7cddfSDavid du Colombier { printf("spin: indexing %s[%d] - size is %d\n", 1577dd7cddfSDavid du Colombier v->name, ix, v->nel); 1587dd7cddfSDavid du Colombier fatal("indexing error \'%s\'", v->name); 1597dd7cddfSDavid du Colombier } 1607dd7cddfSDavid du Colombier if (!n->rgt || !n->rgt->lft) 1617dd7cddfSDavid du Colombier { non_fatal("no subfields %s", v->name); /* i.e., wants all */ 1627dd7cddfSDavid du Colombier lineno = oln; Fname = ofn; 1637dd7cddfSDavid du Colombier return ZS; 1647dd7cddfSDavid du Colombier } 1657dd7cddfSDavid du Colombier 1667dd7cddfSDavid du Colombier if (n->rgt->ntyp != '.') 1677dd7cddfSDavid du Colombier { printf("bad subfield type %d\n", n->rgt->ntyp); 1687dd7cddfSDavid du Colombier alldone(1); 1697dd7cddfSDavid du Colombier } 1707dd7cddfSDavid du Colombier 1717dd7cddfSDavid du Colombier tmp = n->rgt->lft; 1727dd7cddfSDavid du Colombier if (tmp->ntyp != NAME && tmp->ntyp != TYPE) 1737dd7cddfSDavid du Colombier { printf("bad subfield entry %d\n", tmp->ntyp); 1747dd7cddfSDavid du Colombier alldone(1); 1757dd7cddfSDavid du Colombier } 1767dd7cddfSDavid du Colombier for (fp = v->Sval[ix]; fp; fp = fp->rgt) 1777dd7cddfSDavid du Colombier for (tl = fp->lft; tl; tl = tl->rgt) 1787dd7cddfSDavid du Colombier if (!strcmp(tl->sym->name, tmp->sym->name)) 1797dd7cddfSDavid du Colombier { lineno = oln; Fname = ofn; 1807dd7cddfSDavid du Colombier return tl->sym; 1817dd7cddfSDavid du Colombier } 1827dd7cddfSDavid du Colombier fatal("cannot locate subfield %s", tmp->sym->name); 1837dd7cddfSDavid du Colombier return ZS; 1847dd7cddfSDavid du Colombier } 1857dd7cddfSDavid du Colombier 1867dd7cddfSDavid du Colombier int 1877dd7cddfSDavid du Colombier Rval_struct(Lextok *n, Symbol *v, int xinit) /* n varref, v valref */ 1887dd7cddfSDavid du Colombier { Symbol *tl; 1897dd7cddfSDavid du Colombier Lextok *tmp; 1907dd7cddfSDavid du Colombier int ix; 1917dd7cddfSDavid du Colombier 1927dd7cddfSDavid du Colombier if (!n || !(tl = do_same(n, v, xinit))) 1937dd7cddfSDavid du Colombier return 0; 1947dd7cddfSDavid du Colombier 1957dd7cddfSDavid du Colombier tmp = n->rgt->lft; 1967dd7cddfSDavid du Colombier if (tmp->sym->type == STRUCT) 1977dd7cddfSDavid du Colombier { return Rval_struct(tmp, tl, 0); 1987dd7cddfSDavid du Colombier } else if (tmp->rgt) 1997dd7cddfSDavid du Colombier fatal("non-zero 'rgt' on non-structure", 0); 2007dd7cddfSDavid du Colombier 2017dd7cddfSDavid du Colombier ix = eval(tmp->lft); 202*00d97012SDavid du Colombier /* printf("%d: ix: %d (%d) %d\n", depth, ix, tl->nel, tl->val[ix]); */ 2037dd7cddfSDavid du Colombier if (ix >= tl->nel || ix < 0) 2047dd7cddfSDavid du Colombier fatal("indexing error \'%s\'", tl->name); 2057dd7cddfSDavid du Colombier 2067dd7cddfSDavid du Colombier return cast_val(tl->type, tl->val[ix], tl->nbits); 2077dd7cddfSDavid du Colombier } 2087dd7cddfSDavid du Colombier 2097dd7cddfSDavid du Colombier int 2107dd7cddfSDavid du Colombier Lval_struct(Lextok *n, Symbol *v, int xinit, int a) /* a = assigned value */ 2117dd7cddfSDavid du Colombier { Symbol *tl; 2127dd7cddfSDavid du Colombier Lextok *tmp; 2137dd7cddfSDavid du Colombier int ix; 2147dd7cddfSDavid du Colombier 2157dd7cddfSDavid du Colombier if (!(tl = do_same(n, v, xinit))) 2167dd7cddfSDavid du Colombier return 1; 2177dd7cddfSDavid du Colombier 2187dd7cddfSDavid du Colombier tmp = n->rgt->lft; 2197dd7cddfSDavid du Colombier if (tmp->sym->type == STRUCT) 2207dd7cddfSDavid du Colombier return Lval_struct(tmp, tl, 0, a); 2217dd7cddfSDavid du Colombier else if (tmp->rgt) 2227dd7cddfSDavid du Colombier fatal("non-zero 'rgt' on non-structure", 0); 2237dd7cddfSDavid du Colombier 2247dd7cddfSDavid du Colombier ix = eval(tmp->lft); 2257dd7cddfSDavid du Colombier if (ix >= tl->nel || ix < 0) 2267dd7cddfSDavid du Colombier fatal("indexing error \'%s\'", tl->name); 2277dd7cddfSDavid du Colombier 2287dd7cddfSDavid du Colombier if (tl->nbits > 0) 2297dd7cddfSDavid du Colombier a = (a & ((1<<tl->nbits)-1)); 2307dd7cddfSDavid du Colombier 231*00d97012SDavid du Colombier if (a != tl->val[ix]) 232*00d97012SDavid du Colombier { tl->val[ix] = a; 233*00d97012SDavid du Colombier tl->setat = depth; 234*00d97012SDavid du Colombier } 2357dd7cddfSDavid du Colombier return 1; 2367dd7cddfSDavid du Colombier } 2377dd7cddfSDavid du Colombier 2387dd7cddfSDavid du Colombier int 2397dd7cddfSDavid du Colombier Cnt_flds(Lextok *m) 2407dd7cddfSDavid du Colombier { Lextok *fp, *tl, *n; 2417dd7cddfSDavid du Colombier int cnt = 0; 2427dd7cddfSDavid du Colombier 2437dd7cddfSDavid du Colombier if (m->ntyp == ',') 2447dd7cddfSDavid du Colombier { n = m; 2457dd7cddfSDavid du Colombier goto is_lst; 2467dd7cddfSDavid du Colombier } 2477dd7cddfSDavid du Colombier if (!m->sym || m->ntyp != STRUCT) 2487dd7cddfSDavid du Colombier return 1; 2497dd7cddfSDavid du Colombier 2507dd7cddfSDavid du Colombier n = getuname(m->sym); 2517dd7cddfSDavid du Colombier is_lst: 2527dd7cddfSDavid du Colombier for (fp = n; fp; fp = fp->rgt) 2537dd7cddfSDavid du Colombier for (tl = fp->lft; tl; tl = tl->rgt) 2547dd7cddfSDavid du Colombier { if (tl->sym->type == STRUCT) 255*00d97012SDavid du Colombier { if (tl->sym->nel > 1 || tl->sym->isarray) 256312a1df1SDavid du Colombier fatal("array of structures in param list, %s", 2577dd7cddfSDavid du Colombier tl->sym->name); 2587dd7cddfSDavid du Colombier cnt += Cnt_flds(tl->sym->Slst); 2597dd7cddfSDavid du Colombier } else 2607dd7cddfSDavid du Colombier cnt += tl->sym->nel; 2617dd7cddfSDavid du Colombier } 2627dd7cddfSDavid du Colombier return cnt; 2637dd7cddfSDavid du Colombier } 2647dd7cddfSDavid du Colombier 2657dd7cddfSDavid du Colombier int 2667dd7cddfSDavid du Colombier Sym_typ(Lextok *t) 2677dd7cddfSDavid du Colombier { Symbol *s = t->sym; 2687dd7cddfSDavid du Colombier 2697dd7cddfSDavid du Colombier if (!s) return 0; 2707dd7cddfSDavid du Colombier 2717dd7cddfSDavid du Colombier if (s->type != STRUCT) 2727dd7cddfSDavid du Colombier return s->type; 2737dd7cddfSDavid du Colombier 2747dd7cddfSDavid du Colombier if (!t->rgt 275*00d97012SDavid du Colombier || t->rgt->ntyp != '.' /* gh: had ! in wrong place */ 2767dd7cddfSDavid du Colombier || !t->rgt->lft) 277312a1df1SDavid du Colombier return STRUCT; /* not a field reference */ 2787dd7cddfSDavid du Colombier 2797dd7cddfSDavid du Colombier return Sym_typ(t->rgt->lft); 2807dd7cddfSDavid du Colombier } 2817dd7cddfSDavid du Colombier 2827dd7cddfSDavid du Colombier int 2837dd7cddfSDavid du Colombier Width_set(int *wdth, int i, Lextok *n) 2847dd7cddfSDavid du Colombier { Lextok *fp, *tl; 2857dd7cddfSDavid du Colombier int j = i, k; 2867dd7cddfSDavid du Colombier 2877dd7cddfSDavid du Colombier for (fp = n; fp; fp = fp->rgt) 2887dd7cddfSDavid du Colombier for (tl = fp->lft; tl; tl = tl->rgt) 2897dd7cddfSDavid du Colombier { if (tl->sym->type == STRUCT) 2907dd7cddfSDavid du Colombier j = Width_set(wdth, j, tl->sym->Slst); 2917dd7cddfSDavid du Colombier else 2927dd7cddfSDavid du Colombier { for (k = 0; k < tl->sym->nel; k++, j++) 2937dd7cddfSDavid du Colombier wdth[j] = tl->sym->type; 2947dd7cddfSDavid du Colombier } } 2957dd7cddfSDavid du Colombier return j; 2967dd7cddfSDavid du Colombier } 2977dd7cddfSDavid du Colombier 2987dd7cddfSDavid du Colombier void 2997dd7cddfSDavid du Colombier ini_struct(Symbol *s) 3007dd7cddfSDavid du Colombier { int i; Lextok *fp, *tl; 3017dd7cddfSDavid du Colombier 3027dd7cddfSDavid du Colombier if (s->type != STRUCT) /* last step */ 3037dd7cddfSDavid du Colombier { (void) checkvar(s, 0); 3047dd7cddfSDavid du Colombier return; 3057dd7cddfSDavid du Colombier } 3067dd7cddfSDavid du Colombier if (s->Sval == (Lextok **) 0) 3077dd7cddfSDavid du Colombier { s->Sval = (Lextok **) emalloc(s->nel * sizeof(Lextok *)); 3087dd7cddfSDavid du Colombier for (i = 0; i < s->nel; i++) 3097dd7cddfSDavid du Colombier { s->Sval[i] = cpnn(s->Slst, 1, 1, 1); 3107dd7cddfSDavid du Colombier 3117dd7cddfSDavid du Colombier for (fp = s->Sval[i]; fp; fp = fp->rgt) 3127dd7cddfSDavid du Colombier for (tl = fp->lft; tl; tl = tl->rgt) 3137dd7cddfSDavid du Colombier ini_struct(tl->sym); 3147dd7cddfSDavid du Colombier } } 3157dd7cddfSDavid du Colombier } 3167dd7cddfSDavid du Colombier 3177dd7cddfSDavid du Colombier static Lextok * 3187dd7cddfSDavid du Colombier cpnn(Lextok *s, int L, int R, int S) 3197dd7cddfSDavid du Colombier { Lextok *d; extern int Nid; 3207dd7cddfSDavid du Colombier 3217dd7cddfSDavid du Colombier if (!s) return ZN; 3227dd7cddfSDavid du Colombier 3237dd7cddfSDavid du Colombier d = (Lextok *) emalloc(sizeof(Lextok)); 324*00d97012SDavid du Colombier d->uiid = s->uiid; 3257dd7cddfSDavid du Colombier d->ntyp = s->ntyp; 3267dd7cddfSDavid du Colombier d->val = s->val; 3277dd7cddfSDavid du Colombier d->ln = s->ln; 3287dd7cddfSDavid du Colombier d->fn = s->fn; 3297dd7cddfSDavid du Colombier d->sym = s->sym; 3307dd7cddfSDavid du Colombier if (L) d->lft = cpnn(s->lft, 1, 1, S); 3317dd7cddfSDavid du Colombier if (R) d->rgt = cpnn(s->rgt, 1, 1, S); 3327dd7cddfSDavid du Colombier 3337dd7cddfSDavid du Colombier if (S && s->sym) 3347dd7cddfSDavid du Colombier { d->sym = (Symbol *) emalloc(sizeof(Symbol)); 3357dd7cddfSDavid du Colombier memcpy(d->sym, s->sym, sizeof(Symbol)); 3367dd7cddfSDavid du Colombier if (d->sym->type == CHAN) 3377dd7cddfSDavid du Colombier d->sym->Nid = ++Nid; 3387dd7cddfSDavid du Colombier } 3397dd7cddfSDavid du Colombier if (s->sq || s->sl) 3407dd7cddfSDavid du Colombier fatal("cannot happen cpnn", (char *) 0); 3417dd7cddfSDavid du Colombier 3427dd7cddfSDavid du Colombier return d; 3437dd7cddfSDavid du Colombier } 3447dd7cddfSDavid du Colombier 3457dd7cddfSDavid du Colombier int 3467dd7cddfSDavid du Colombier full_name(FILE *fd, Lextok *n, Symbol *v, int xinit) 3477dd7cddfSDavid du Colombier { Symbol *tl; 3487dd7cddfSDavid du Colombier Lextok *tmp; 3497dd7cddfSDavid du Colombier int hiddenarrays = 0; 3507dd7cddfSDavid du Colombier 3517dd7cddfSDavid du Colombier fprintf(fd, "%s", v->name); 3527dd7cddfSDavid du Colombier 3537dd7cddfSDavid du Colombier if (!n || !(tl = do_same(n, v, xinit))) 3547dd7cddfSDavid du Colombier return 0; 3557dd7cddfSDavid du Colombier tmp = n->rgt->lft; 3567dd7cddfSDavid du Colombier 3577dd7cddfSDavid du Colombier if (tmp->sym->type == STRUCT) 3587dd7cddfSDavid du Colombier { fprintf(fd, "."); 3597dd7cddfSDavid du Colombier hiddenarrays = full_name(fd, tmp, tl, 0); 3607dd7cddfSDavid du Colombier goto out; 3617dd7cddfSDavid du Colombier } 3627dd7cddfSDavid du Colombier fprintf(fd, ".%s", tl->name); 363*00d97012SDavid du Colombier out: if (tmp->sym->nel > 1 || tmp->sym->isarray == 1) 3647dd7cddfSDavid du Colombier { fprintf(fd, "[%d]", eval(tmp->lft)); 3657dd7cddfSDavid du Colombier hiddenarrays = 1; 3667dd7cddfSDavid du Colombier } 3677dd7cddfSDavid du Colombier return hiddenarrays; 3687dd7cddfSDavid du Colombier } 3697dd7cddfSDavid du Colombier 3707dd7cddfSDavid du Colombier void 3717dd7cddfSDavid du Colombier validref(Lextok *p, Lextok *c) 3727dd7cddfSDavid du Colombier { Lextok *fp, *tl; 3737dd7cddfSDavid du Colombier char lbuf[512]; 3747dd7cddfSDavid du Colombier 3757dd7cddfSDavid du Colombier for (fp = p->sym->Slst; fp; fp = fp->rgt) 3767dd7cddfSDavid du Colombier for (tl = fp->lft; tl; tl = tl->rgt) 3777dd7cddfSDavid du Colombier if (strcmp(tl->sym->name, c->sym->name) == 0) 3787dd7cddfSDavid du Colombier return; 3797dd7cddfSDavid du Colombier 3807dd7cddfSDavid du Colombier sprintf(lbuf, "no field '%s' defined in structure '%s'\n", 3817dd7cddfSDavid du Colombier c->sym->name, p->sym->name); 3827dd7cddfSDavid du Colombier non_fatal(lbuf, (char *) 0); 3837dd7cddfSDavid du Colombier } 3847dd7cddfSDavid du Colombier 3857dd7cddfSDavid du Colombier void 3867dd7cddfSDavid du Colombier struct_name(Lextok *n, Symbol *v, int xinit, char *buf) 3877dd7cddfSDavid du Colombier { Symbol *tl; 3887dd7cddfSDavid du Colombier Lextok *tmp; 389312a1df1SDavid du Colombier char lbuf[512]; 3907dd7cddfSDavid du Colombier 3917dd7cddfSDavid du Colombier if (!n || !(tl = do_same(n, v, xinit))) 3927dd7cddfSDavid du Colombier return; 3937dd7cddfSDavid du Colombier tmp = n->rgt->lft; 3947dd7cddfSDavid du Colombier if (tmp->sym->type == STRUCT) 3957dd7cddfSDavid du Colombier { strcat(buf, "."); 3967dd7cddfSDavid du Colombier struct_name(tmp, tl, 0, buf); 3977dd7cddfSDavid du Colombier return; 3987dd7cddfSDavid du Colombier } 3997dd7cddfSDavid du Colombier sprintf(lbuf, ".%s", tl->name); 4007dd7cddfSDavid du Colombier strcat(buf, lbuf); 401*00d97012SDavid du Colombier if (tmp->sym->nel > 1 || tmp->sym->isarray == 1) 4027dd7cddfSDavid du Colombier { sprintf(lbuf, "[%d]", eval(tmp->lft)); 4037dd7cddfSDavid du Colombier strcat(buf, lbuf); 4047dd7cddfSDavid du Colombier } 4057dd7cddfSDavid du Colombier } 4067dd7cddfSDavid du Colombier 4077dd7cddfSDavid du Colombier void 4087dd7cddfSDavid du Colombier walk2_struct(char *s, Symbol *z) 4097dd7cddfSDavid du Colombier { Lextok *fp, *tl; 4107dd7cddfSDavid du Colombier char eprefix[128]; 4117dd7cddfSDavid du Colombier int ix; 4127dd7cddfSDavid du Colombier extern void Done_case(char *, Symbol *); 4137dd7cddfSDavid du Colombier 4147dd7cddfSDavid du Colombier ini_struct(z); 415*00d97012SDavid du Colombier if (z->nel == 1 && z->isarray == 0) 4167dd7cddfSDavid du Colombier sprintf(eprefix, "%s%s.", s, z->name); 4177dd7cddfSDavid du Colombier for (ix = 0; ix < z->nel; ix++) 418*00d97012SDavid du Colombier { if (z->nel > 1 || z->isarray == 1) 4197dd7cddfSDavid du Colombier sprintf(eprefix, "%s%s[%d].", s, z->name, ix); 4207dd7cddfSDavid du Colombier for (fp = z->Sval[ix]; fp; fp = fp->rgt) 4217dd7cddfSDavid du Colombier for (tl = fp->lft; tl; tl = tl->rgt) 4227dd7cddfSDavid du Colombier { if (tl->sym->type == STRUCT) 4237dd7cddfSDavid du Colombier walk2_struct(eprefix, tl->sym); 4247dd7cddfSDavid du Colombier else if (tl->sym->type == CHAN) 4257dd7cddfSDavid du Colombier Done_case(eprefix, tl->sym); 4267dd7cddfSDavid du Colombier } } 4277dd7cddfSDavid du Colombier } 4287dd7cddfSDavid du Colombier 4297dd7cddfSDavid du Colombier void 4307dd7cddfSDavid du Colombier walk_struct(FILE *ofd, int dowhat, char *s, Symbol *z, char *a, char *b, char *c) 4317dd7cddfSDavid du Colombier { Lextok *fp, *tl; 4327dd7cddfSDavid du Colombier char eprefix[128]; 4337dd7cddfSDavid du Colombier int ix; 4347dd7cddfSDavid du Colombier 4357dd7cddfSDavid du Colombier ini_struct(z); 436*00d97012SDavid du Colombier if (z->nel == 1 && z->isarray == 0) 4377dd7cddfSDavid du Colombier sprintf(eprefix, "%s%s.", s, z->name); 4387dd7cddfSDavid du Colombier for (ix = 0; ix < z->nel; ix++) 439*00d97012SDavid du Colombier { if (z->nel > 1 || z->isarray == 1) 4407dd7cddfSDavid du Colombier sprintf(eprefix, "%s%s[%d].", s, z->name, ix); 4417dd7cddfSDavid du Colombier for (fp = z->Sval[ix]; fp; fp = fp->rgt) 4427dd7cddfSDavid du Colombier for (tl = fp->lft; tl; tl = tl->rgt) 4437dd7cddfSDavid du Colombier { if (tl->sym->type == STRUCT) 4447dd7cddfSDavid du Colombier walk_struct(ofd, dowhat, eprefix, tl->sym, a,b,c); 4457dd7cddfSDavid du Colombier else 4467dd7cddfSDavid du Colombier do_var(ofd, dowhat, eprefix, tl->sym, a,b,c); 4477dd7cddfSDavid du Colombier } } 4487dd7cddfSDavid du Colombier } 4497dd7cddfSDavid du Colombier 4507dd7cddfSDavid du Colombier void 451312a1df1SDavid du Colombier c_struct(FILE *fd, char *ipref, Symbol *z) 452312a1df1SDavid du Colombier { Lextok *fp, *tl; 453*00d97012SDavid du Colombier char pref[256], eprefix[300]; 454312a1df1SDavid du Colombier int ix; 455312a1df1SDavid du Colombier 456312a1df1SDavid du Colombier ini_struct(z); 457312a1df1SDavid du Colombier 458312a1df1SDavid du Colombier for (ix = 0; ix < z->nel; ix++) 459312a1df1SDavid du Colombier for (fp = z->Sval[ix]; fp; fp = fp->rgt) 460312a1df1SDavid du Colombier for (tl = fp->lft; tl; tl = tl->rgt) 461312a1df1SDavid du Colombier { strcpy(eprefix, ipref); 462*00d97012SDavid du Colombier if (z->nel > 1 || z->isarray == 1) 463312a1df1SDavid du Colombier { /* insert index before last '.' */ 464312a1df1SDavid du Colombier eprefix[strlen(eprefix)-1] = '\0'; 465312a1df1SDavid du Colombier sprintf(pref, "[ %d ].", ix); 466312a1df1SDavid du Colombier strcat(eprefix, pref); 467312a1df1SDavid du Colombier } 468312a1df1SDavid du Colombier if (tl->sym->type == STRUCT) 469312a1df1SDavid du Colombier { strcat(eprefix, tl->sym->name); 470312a1df1SDavid du Colombier strcat(eprefix, "."); 471312a1df1SDavid du Colombier c_struct(fd, eprefix, tl->sym); 472312a1df1SDavid du Colombier } else 473312a1df1SDavid du Colombier c_var(fd, eprefix, tl->sym); 474312a1df1SDavid du Colombier } 475312a1df1SDavid du Colombier } 476312a1df1SDavid du Colombier 477312a1df1SDavid du Colombier void 4787dd7cddfSDavid du Colombier dump_struct(Symbol *z, char *prefix, RunList *r) 4797dd7cddfSDavid du Colombier { Lextok *fp, *tl; 480312a1df1SDavid du Colombier char eprefix[256]; 4817dd7cddfSDavid du Colombier int ix, jx; 4827dd7cddfSDavid du Colombier 4837dd7cddfSDavid du Colombier ini_struct(z); 4847dd7cddfSDavid du Colombier 4857dd7cddfSDavid du Colombier for (ix = 0; ix < z->nel; ix++) 486*00d97012SDavid du Colombier { if (z->nel > 1 || z->isarray == 1) 4877dd7cddfSDavid du Colombier sprintf(eprefix, "%s[%d]", prefix, ix); 4887dd7cddfSDavid du Colombier else 4897dd7cddfSDavid du Colombier strcpy(eprefix, prefix); 4907dd7cddfSDavid du Colombier 4917dd7cddfSDavid du Colombier for (fp = z->Sval[ix]; fp; fp = fp->rgt) 4927dd7cddfSDavid du Colombier for (tl = fp->lft; tl; tl = tl->rgt) 4937dd7cddfSDavid du Colombier { if (tl->sym->type == STRUCT) 494*00d97012SDavid du Colombier { char pref[300]; 4957dd7cddfSDavid du Colombier strcpy(pref, eprefix); 4967dd7cddfSDavid du Colombier strcat(pref, "."); 4977dd7cddfSDavid du Colombier strcat(pref, tl->sym->name); 4987dd7cddfSDavid du Colombier dump_struct(tl->sym, pref, r); 4997dd7cddfSDavid du Colombier } else 5007dd7cddfSDavid du Colombier for (jx = 0; jx < tl->sym->nel; jx++) 5017dd7cddfSDavid du Colombier { if (tl->sym->type == CHAN) 5027dd7cddfSDavid du Colombier doq(tl->sym, jx, r); 5037dd7cddfSDavid du Colombier else 5047dd7cddfSDavid du Colombier { printf("\t\t"); 5057dd7cddfSDavid du Colombier if (r) 5067dd7cddfSDavid du Colombier printf("%s(%d):", r->n->name, r->pid); 5077dd7cddfSDavid du Colombier printf("%s.%s", eprefix, tl->sym->name); 508*00d97012SDavid du Colombier if (tl->sym->nel > 1 || tl->sym->isarray == 1) 5097dd7cddfSDavid du Colombier printf("[%d]", jx); 5107dd7cddfSDavid du Colombier printf(" = "); 5117dd7cddfSDavid du Colombier sr_mesg(stdout, tl->sym->val[jx], 5127dd7cddfSDavid du Colombier tl->sym->type == MTYPE); 5137dd7cddfSDavid du Colombier printf("\n"); 5147dd7cddfSDavid du Colombier } } } 5157dd7cddfSDavid du Colombier } 5167dd7cddfSDavid du Colombier } 5177dd7cddfSDavid du Colombier 5187dd7cddfSDavid du Colombier static int 5197dd7cddfSDavid du Colombier retrieve(Lextok **targ, int i, int want, Lextok *n, int Ntyp) 5207dd7cddfSDavid du Colombier { Lextok *fp, *tl; 5217dd7cddfSDavid du Colombier int j = i, k; 5227dd7cddfSDavid du Colombier 5237dd7cddfSDavid du Colombier for (fp = n; fp; fp = fp->rgt) 5247dd7cddfSDavid du Colombier for (tl = fp->lft; tl; tl = tl->rgt) 5257dd7cddfSDavid du Colombier { if (tl->sym->type == STRUCT) 5267dd7cddfSDavid du Colombier { j = retrieve(targ, j, want, tl->sym->Slst, Ntyp); 5277dd7cddfSDavid du Colombier if (j < 0) 5287dd7cddfSDavid du Colombier { Lextok *x = cpnn(tl, 1, 0, 0); 5297dd7cddfSDavid du Colombier x->rgt = nn(ZN, '.', (*targ), ZN); 5307dd7cddfSDavid du Colombier (*targ) = x; 5317dd7cddfSDavid du Colombier return -1; 5327dd7cddfSDavid du Colombier } 5337dd7cddfSDavid du Colombier } else 5347dd7cddfSDavid du Colombier { for (k = 0; k < tl->sym->nel; k++, j++) 5357dd7cddfSDavid du Colombier { if (j == want) 5367dd7cddfSDavid du Colombier { *targ = cpnn(tl, 1, 0, 0); 5377dd7cddfSDavid du Colombier (*targ)->lft = nn(ZN, CONST, ZN, ZN); 5387dd7cddfSDavid du Colombier (*targ)->lft->val = k; 5397dd7cddfSDavid du Colombier if (Ntyp) 5407dd7cddfSDavid du Colombier (*targ)->ntyp = (short) Ntyp; 5417dd7cddfSDavid du Colombier return -1; 5427dd7cddfSDavid du Colombier } 5437dd7cddfSDavid du Colombier } } } 5447dd7cddfSDavid du Colombier return j; 5457dd7cddfSDavid du Colombier } 5467dd7cddfSDavid du Colombier 5477dd7cddfSDavid du Colombier static int 5487dd7cddfSDavid du Colombier is_explicit(Lextok *n) 5497dd7cddfSDavid du Colombier { 5507dd7cddfSDavid du Colombier if (!n) return 0; 5517dd7cddfSDavid du Colombier if (!n->sym) fatal("unexpected - no symbol", 0); 5527dd7cddfSDavid du Colombier if (n->sym->type != STRUCT) return 1; 5537dd7cddfSDavid du Colombier if (!n->rgt) return 0; 5547dd7cddfSDavid du Colombier if (n->rgt->ntyp != '.') 5557dd7cddfSDavid du Colombier { lineno = n->ln; 5567dd7cddfSDavid du Colombier Fname = n->fn; 5577dd7cddfSDavid du Colombier printf("ntyp %d\n", n->rgt->ntyp); 5587dd7cddfSDavid du Colombier fatal("unexpected %s, no '.'", n->sym->name); 5597dd7cddfSDavid du Colombier } 5607dd7cddfSDavid du Colombier return is_explicit(n->rgt->lft); 5617dd7cddfSDavid du Colombier } 5627dd7cddfSDavid du Colombier 5637dd7cddfSDavid du Colombier Lextok * 5647dd7cddfSDavid du Colombier expand(Lextok *n, int Ok) 5657dd7cddfSDavid du Colombier /* turn rgt-lnked list of struct nms, into ',' list of flds */ 5667dd7cddfSDavid du Colombier { Lextok *x = ZN, *y; 5677dd7cddfSDavid du Colombier 5687dd7cddfSDavid du Colombier if (!Ok) return n; 5697dd7cddfSDavid du Colombier 5707dd7cddfSDavid du Colombier while (n) 5717dd7cddfSDavid du Colombier { y = mk_explicit(n, 1, 0); 5727dd7cddfSDavid du Colombier if (x) 5737dd7cddfSDavid du Colombier (void) tail_add(x, y); 5747dd7cddfSDavid du Colombier else 5757dd7cddfSDavid du Colombier x = y; 5767dd7cddfSDavid du Colombier 5777dd7cddfSDavid du Colombier n = n->rgt; 5787dd7cddfSDavid du Colombier } 5797dd7cddfSDavid du Colombier return x; 5807dd7cddfSDavid du Colombier } 5817dd7cddfSDavid du Colombier 5827dd7cddfSDavid du Colombier Lextok * 5837dd7cddfSDavid du Colombier mk_explicit(Lextok *n, int Ok, int Ntyp) 5847dd7cddfSDavid du Colombier /* produce a single ',' list of fields */ 5857dd7cddfSDavid du Colombier { Lextok *bld = ZN, *x; 5867dd7cddfSDavid du Colombier int i, cnt; extern int IArgs; 5877dd7cddfSDavid du Colombier 5887dd7cddfSDavid du Colombier if (n->sym->type != STRUCT 589*00d97012SDavid du Colombier || in_for 5907dd7cddfSDavid du Colombier || is_explicit(n)) 5917dd7cddfSDavid du Colombier return n; 5927dd7cddfSDavid du Colombier 593*00d97012SDavid du Colombier 594312a1df1SDavid du Colombier if (n->rgt 595312a1df1SDavid du Colombier && n->rgt->ntyp == '.' 596312a1df1SDavid du Colombier && n->rgt->lft 597312a1df1SDavid du Colombier && n->rgt->lft->sym 598312a1df1SDavid du Colombier && n->rgt->lft->sym->type == STRUCT) 599312a1df1SDavid du Colombier { Lextok *y; 600312a1df1SDavid du Colombier bld = mk_explicit(n->rgt->lft, Ok, Ntyp); 601312a1df1SDavid du Colombier for (x = bld; x; x = x->rgt) 602312a1df1SDavid du Colombier { y = cpnn(n, 1, 0, 0); 603312a1df1SDavid du Colombier y->rgt = nn(ZN, '.', x->lft, ZN); 604312a1df1SDavid du Colombier x->lft = y; 605312a1df1SDavid du Colombier } 606312a1df1SDavid du Colombier 607312a1df1SDavid du Colombier return bld; 608312a1df1SDavid du Colombier } 609312a1df1SDavid du Colombier 6107dd7cddfSDavid du Colombier if (!Ok || !n->sym->Slst) 6117dd7cddfSDavid du Colombier { if (IArgs) return n; 6127dd7cddfSDavid du Colombier printf("spin: saw '"); 6137dd7cddfSDavid du Colombier comment(stdout, n, 0); 6147dd7cddfSDavid du Colombier printf("'\n"); 6157dd7cddfSDavid du Colombier fatal("incomplete structure ref '%s'", n->sym->name); 6167dd7cddfSDavid du Colombier } 6177dd7cddfSDavid du Colombier 6187dd7cddfSDavid du Colombier cnt = Cnt_flds(n->sym->Slst); 6197dd7cddfSDavid du Colombier for (i = cnt-1; i >= 0; i--) 6207dd7cddfSDavid du Colombier { bld = nn(ZN, ',', ZN, bld); 6217dd7cddfSDavid du Colombier if (retrieve(&(bld->lft), 0, i, n->sym->Slst, Ntyp) >= 0) 6227dd7cddfSDavid du Colombier { printf("cannot retrieve field %d\n", i); 6237dd7cddfSDavid du Colombier fatal("bad structure %s", n->sym->name); 6247dd7cddfSDavid du Colombier } 6257dd7cddfSDavid du Colombier x = cpnn(n, 1, 0, 0); 6267dd7cddfSDavid du Colombier x->rgt = nn(ZN, '.', bld->lft, ZN); 6277dd7cddfSDavid du Colombier bld->lft = x; 6287dd7cddfSDavid du Colombier } 6297dd7cddfSDavid du Colombier return bld; 6307dd7cddfSDavid du Colombier } 6317dd7cddfSDavid du Colombier 6327dd7cddfSDavid du Colombier Lextok * 6337dd7cddfSDavid du Colombier tail_add(Lextok *a, Lextok *b) 6347dd7cddfSDavid du Colombier { Lextok *t; 6357dd7cddfSDavid du Colombier 6367dd7cddfSDavid du Colombier for (t = a; t->rgt; t = t->rgt) 6377dd7cddfSDavid du Colombier if (t->ntyp != ',') 6387dd7cddfSDavid du Colombier fatal("unexpected type - tail_add", 0); 6397dd7cddfSDavid du Colombier t->rgt = b; 6407dd7cddfSDavid du Colombier return a; 6417dd7cddfSDavid du Colombier } 6427dd7cddfSDavid du Colombier 6437dd7cddfSDavid du Colombier void 6447dd7cddfSDavid du Colombier setpname(Lextok *n) 6457dd7cddfSDavid du Colombier { UType *tmp; 6467dd7cddfSDavid du Colombier 6477dd7cddfSDavid du Colombier for (tmp = Pnames; tmp; tmp = tmp->nxt) 6487dd7cddfSDavid du Colombier if (!strcmp(n->sym->name, tmp->nm->name)) 6497dd7cddfSDavid du Colombier { non_fatal("proctype %s redefined", 6507dd7cddfSDavid du Colombier n->sym->name); 6517dd7cddfSDavid du Colombier return; 6527dd7cddfSDavid du Colombier } 6537dd7cddfSDavid du Colombier tmp = (UType *) emalloc(sizeof(UType)); 6547dd7cddfSDavid du Colombier tmp->nm = n->sym; 6557dd7cddfSDavid du Colombier tmp->nxt = Pnames; 6567dd7cddfSDavid du Colombier Pnames = tmp; 6577dd7cddfSDavid du Colombier } 6587dd7cddfSDavid du Colombier 6597dd7cddfSDavid du Colombier int 6607dd7cddfSDavid du Colombier isproctype(char *t) 6617dd7cddfSDavid du Colombier { UType *tmp; 6627dd7cddfSDavid du Colombier 6637dd7cddfSDavid du Colombier for (tmp = Pnames; tmp; tmp = tmp->nxt) 6647dd7cddfSDavid du Colombier { if (!strcmp(t, tmp->nm->name)) 6657dd7cddfSDavid du Colombier return 1; 6667dd7cddfSDavid du Colombier } 6677dd7cddfSDavid du Colombier return 0; 6687dd7cddfSDavid du Colombier } 669