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