xref: /plan9/sys/src/cmd/spin/mesg.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1*219b2ee8SDavid du Colombier /***** spin: mesg.c *****/
2*219b2ee8SDavid du Colombier 
3*219b2ee8SDavid du Colombier /* Copyright (c) 1991,1995 by AT&T Corporation.  All Rights Reserved.     */
4*219b2ee8SDavid du Colombier /* This software is for educational purposes only.                        */
5*219b2ee8SDavid du Colombier /* Permission is given to distribute this code provided that this intro-  */
6*219b2ee8SDavid du Colombier /* ductory message is not removed and no monies are exchanged.            */
7*219b2ee8SDavid du Colombier /* No guarantee is expressed or implied by the distribution of this code. */
8*219b2ee8SDavid du Colombier /* Software written by Gerard J. Holzmann as part of the book:            */
9*219b2ee8SDavid du Colombier /* `Design and Validation of Computer Protocols,' ISBN 0-13-539925-4,     */
10*219b2ee8SDavid du Colombier /* Prentice Hall, Englewood Cliffs, NJ, 07632.                            */
11*219b2ee8SDavid du Colombier /* Send bug-reports and/or questions to: gerard@research.att.com          */
12*219b2ee8SDavid du Colombier 
13*219b2ee8SDavid du Colombier #include "spin.h"
14*219b2ee8SDavid du Colombier #include "y.tab.h"
15*219b2ee8SDavid du Colombier 
16*219b2ee8SDavid du Colombier #define MAXQ	2500		/* default max # queues  */
17*219b2ee8SDavid du Colombier 
18*219b2ee8SDavid du Colombier extern RunList	*X;
19*219b2ee8SDavid du Colombier extern Symbol	*Fname;
20*219b2ee8SDavid du Colombier extern int	verbose, TstOnly, s_trail;
21*219b2ee8SDavid du Colombier extern int	lineno, depth, xspin, m_loss;
22*219b2ee8SDavid du Colombier 
23*219b2ee8SDavid du Colombier Queue	*qtab = (Queue *) 0;	/* linked list of queues */
24*219b2ee8SDavid du Colombier Queue	*ltab[MAXQ];		/* linear list of queues */
25*219b2ee8SDavid du Colombier int	nqs=0;
26*219b2ee8SDavid du Colombier 
27*219b2ee8SDavid du Colombier int
28*219b2ee8SDavid du Colombier cnt_mpars(Lextok *n)
29*219b2ee8SDavid du Colombier {	Lextok *m;
30*219b2ee8SDavid du Colombier 	int i=0;
31*219b2ee8SDavid du Colombier 
32*219b2ee8SDavid du Colombier 	for (m = n; m; m = m->rgt)
33*219b2ee8SDavid du Colombier 		i += Cnt_flds(m);
34*219b2ee8SDavid du Colombier 	return i;
35*219b2ee8SDavid du Colombier }
36*219b2ee8SDavid du Colombier 
37*219b2ee8SDavid du Colombier int
38*219b2ee8SDavid du Colombier qmake(Symbol *s)
39*219b2ee8SDavid du Colombier {	Lextok *m;
40*219b2ee8SDavid du Colombier 	Queue *q;
41*219b2ee8SDavid du Colombier 	int i; extern int analyze;
42*219b2ee8SDavid du Colombier 
43*219b2ee8SDavid du Colombier 	if (!s->ini)
44*219b2ee8SDavid du Colombier 		return 0;
45*219b2ee8SDavid du Colombier 
46*219b2ee8SDavid du Colombier 	if (nqs >= MAXQ)
47*219b2ee8SDavid du Colombier 	{	lineno = s->ini->ln;
48*219b2ee8SDavid du Colombier 		Fname  = s->ini->fn;
49*219b2ee8SDavid du Colombier 		fatal("too many queues (%s)", s->name);
50*219b2ee8SDavid du Colombier 	}
51*219b2ee8SDavid du Colombier 
52*219b2ee8SDavid du Colombier 	if (s->ini->ntyp != CHAN)
53*219b2ee8SDavid du Colombier 		return eval(s->ini);
54*219b2ee8SDavid du Colombier 
55*219b2ee8SDavid du Colombier 	q = (Queue *) emalloc(sizeof(Queue));
56*219b2ee8SDavid du Colombier 	q->qid    = ++nqs;
57*219b2ee8SDavid du Colombier 	q->nslots = s->ini->val;
58*219b2ee8SDavid du Colombier 	q->nflds  = cnt_mpars(s->ini->rgt);
59*219b2ee8SDavid du Colombier 	q->setat  = depth;
60*219b2ee8SDavid du Colombier 
61*219b2ee8SDavid du Colombier 	i = max(1, q->nslots);	/* 0-slot qs get 1 slot minimum */
62*219b2ee8SDavid du Colombier 
63*219b2ee8SDavid du Colombier 	q->contents  = (int *) emalloc(q->nflds*i*sizeof(int));
64*219b2ee8SDavid du Colombier 	q->fld_width = (int *) emalloc(q->nflds*sizeof(int));
65*219b2ee8SDavid du Colombier 
66*219b2ee8SDavid du Colombier 	for (m = s->ini->rgt, i = 0; m; m = m->rgt)
67*219b2ee8SDavid du Colombier 	{	if (m->sym && m->ntyp == STRUCT)
68*219b2ee8SDavid du Colombier 			i = Width_set(q->fld_width, i, getuname(m->sym));
69*219b2ee8SDavid du Colombier 		else
70*219b2ee8SDavid du Colombier 			q->fld_width[i++] = m->ntyp;
71*219b2ee8SDavid du Colombier 	}
72*219b2ee8SDavid du Colombier 	q->nxt = qtab;
73*219b2ee8SDavid du Colombier 	qtab = q;
74*219b2ee8SDavid du Colombier 	ltab[q->qid-1] = q;
75*219b2ee8SDavid du Colombier 
76*219b2ee8SDavid du Colombier 	return q->qid;
77*219b2ee8SDavid du Colombier }
78*219b2ee8SDavid du Colombier 
79*219b2ee8SDavid du Colombier int
80*219b2ee8SDavid du Colombier qfull(Lextok *n)
81*219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
82*219b2ee8SDavid du Colombier 
83*219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
84*219b2ee8SDavid du Colombier 		return (ltab[whichq]->qlen >= ltab[whichq]->nslots);
85*219b2ee8SDavid du Colombier 	return 0;
86*219b2ee8SDavid du Colombier }
87*219b2ee8SDavid du Colombier 
88*219b2ee8SDavid du Colombier int
89*219b2ee8SDavid du Colombier qlen(Lextok *n)
90*219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
91*219b2ee8SDavid du Colombier 
92*219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
93*219b2ee8SDavid du Colombier 		return ltab[whichq]->qlen;
94*219b2ee8SDavid du Colombier 	return 0;
95*219b2ee8SDavid du Colombier }
96*219b2ee8SDavid du Colombier 
97*219b2ee8SDavid du Colombier int
98*219b2ee8SDavid du Colombier q_is_sync(Lextok *n)
99*219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
100*219b2ee8SDavid du Colombier 
101*219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
102*219b2ee8SDavid du Colombier 		return (ltab[whichq]->nslots == 0);
103*219b2ee8SDavid du Colombier 	return 0;
104*219b2ee8SDavid du Colombier }
105*219b2ee8SDavid du Colombier 
106*219b2ee8SDavid du Colombier int
107*219b2ee8SDavid du Colombier qsend(Lextok *n)
108*219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
109*219b2ee8SDavid du Colombier 
110*219b2ee8SDavid du Colombier 	if (whichq == -1)
111*219b2ee8SDavid du Colombier 	{	printf("Error: sending to an uninitialized chan\n");
112*219b2ee8SDavid du Colombier 		whichq = 0;
113*219b2ee8SDavid du Colombier 		return 0;
114*219b2ee8SDavid du Colombier 	}
115*219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
116*219b2ee8SDavid du Colombier 	{	ltab[whichq]->setat = depth;
117*219b2ee8SDavid du Colombier 		if (ltab[whichq]->nslots > 0)
118*219b2ee8SDavid du Colombier 			return a_snd(ltab[whichq], n);
119*219b2ee8SDavid du Colombier 		else
120*219b2ee8SDavid du Colombier 			return s_snd(ltab[whichq], n);
121*219b2ee8SDavid du Colombier 	}
122*219b2ee8SDavid du Colombier 	return 0;
123*219b2ee8SDavid du Colombier }
124*219b2ee8SDavid du Colombier 
125*219b2ee8SDavid du Colombier int
126*219b2ee8SDavid du Colombier qrecv(Lextok *n, int full)
127*219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
128*219b2ee8SDavid du Colombier 
129*219b2ee8SDavid du Colombier 	if (whichq == -1)
130*219b2ee8SDavid du Colombier 	{	printf("Error: receiving from an uninitialized chan\n");
131*219b2ee8SDavid du Colombier 		whichq = 0;
132*219b2ee8SDavid du Colombier 		return 0;
133*219b2ee8SDavid du Colombier 	}
134*219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
135*219b2ee8SDavid du Colombier 	{	ltab[whichq]->setat = depth;
136*219b2ee8SDavid du Colombier 		return a_rcv(ltab[whichq], n, full);
137*219b2ee8SDavid du Colombier 	}
138*219b2ee8SDavid du Colombier 	return 0;
139*219b2ee8SDavid du Colombier }
140*219b2ee8SDavid du Colombier 
141*219b2ee8SDavid du Colombier int
142*219b2ee8SDavid du Colombier sa_snd(Queue *q, Lextok *n)	/* sorted asynchronous */
143*219b2ee8SDavid du Colombier {	Lextok *m;
144*219b2ee8SDavid du Colombier 	int i, j, k;
145*219b2ee8SDavid du Colombier 	int New, Old;
146*219b2ee8SDavid du Colombier 
147*219b2ee8SDavid du Colombier 	for (i = 0; i < q->qlen; i++)
148*219b2ee8SDavid du Colombier 	for (j = 0, m = n->rgt; m && j < q->nflds; m = m->rgt, j++)
149*219b2ee8SDavid du Colombier 	{	New = cast_val(q->fld_width[j], eval(m->lft));
150*219b2ee8SDavid du Colombier 		Old = q->contents[i*q->nflds+j];
151*219b2ee8SDavid du Colombier 		if (New == Old) continue;
152*219b2ee8SDavid du Colombier 		if (New >  Old) break;			/* inner loop */
153*219b2ee8SDavid du Colombier 		if (New <  Old) goto found;
154*219b2ee8SDavid du Colombier 	}
155*219b2ee8SDavid du Colombier found:
156*219b2ee8SDavid du Colombier 	for (j = q->qlen-1; j >= i; j--)
157*219b2ee8SDavid du Colombier 	for (k = 0; k < q->nflds; k++)
158*219b2ee8SDavid du Colombier 	{	q->contents[(j+1)*q->nflds+k] =
159*219b2ee8SDavid du Colombier 			q->contents[j*q->nflds+k];	/* shift up */
160*219b2ee8SDavid du Colombier 	}
161*219b2ee8SDavid du Colombier 	return i*q->nflds;				/* new q offset */
162*219b2ee8SDavid du Colombier }
163*219b2ee8SDavid du Colombier 
164*219b2ee8SDavid du Colombier void
165*219b2ee8SDavid du Colombier typ_ck(int ft, int at, char *s)
166*219b2ee8SDavid du Colombier {
167*219b2ee8SDavid du Colombier 	if (verbose&32 && ft != at
168*219b2ee8SDavid du Colombier 	&& (ft == CHAN || at == CHAN))
169*219b2ee8SDavid du Colombier 	{	char buf[128], tag1[32], tag2[32];
170*219b2ee8SDavid du Colombier 		(void) sputtype(tag1, ft);
171*219b2ee8SDavid du Colombier 		(void) sputtype(tag2, at);
172*219b2ee8SDavid du Colombier 		sprintf(buf, "type-clash in %s, (%s<-> %s)", s, tag1, tag2);
173*219b2ee8SDavid du Colombier 		non_fatal("%s", buf);
174*219b2ee8SDavid du Colombier 	}
175*219b2ee8SDavid du Colombier }
176*219b2ee8SDavid du Colombier 
177*219b2ee8SDavid du Colombier int
178*219b2ee8SDavid du Colombier a_snd(Queue *q, Lextok *n)
179*219b2ee8SDavid du Colombier {	Lextok *m;
180*219b2ee8SDavid du Colombier 	int i = q->qlen*q->nflds;	/* q offset */
181*219b2ee8SDavid du Colombier 	int j = 0;			/* q field# */
182*219b2ee8SDavid du Colombier 
183*219b2ee8SDavid du Colombier 	if (q->nslots > 0 && q->qlen >= q->nslots)
184*219b2ee8SDavid du Colombier 		return m_loss;	/* q is full */
185*219b2ee8SDavid du Colombier 
186*219b2ee8SDavid du Colombier 	if (TstOnly) return 1;
187*219b2ee8SDavid du Colombier 
188*219b2ee8SDavid du Colombier 	if (n->val) i = sa_snd(q, n);	/* sorted insert */
189*219b2ee8SDavid du Colombier 
190*219b2ee8SDavid du Colombier 	for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++)
191*219b2ee8SDavid du Colombier 	{	int New = eval(m->lft);
192*219b2ee8SDavid du Colombier 		q->contents[i+j] = cast_val(q->fld_width[j], New);
193*219b2ee8SDavid du Colombier 		if (verbose&16)
194*219b2ee8SDavid du Colombier 			sr_talk(n, New, "Send ", "->", j, q);
195*219b2ee8SDavid du Colombier 		typ_ck(q->fld_width[j], Sym_typ(m->lft), "send");
196*219b2ee8SDavid du Colombier 	}
197*219b2ee8SDavid du Colombier 	if (verbose&16)
198*219b2ee8SDavid du Colombier 	{	for (i = j; i < q->nflds; i++)
199*219b2ee8SDavid du Colombier 			sr_talk(n, 0, "Send ", "->", i, q);
200*219b2ee8SDavid du Colombier 		if (j < q->nflds)
201*219b2ee8SDavid du Colombier 			printf("\twarning: missing params in send\n");
202*219b2ee8SDavid du Colombier 		if (m)
203*219b2ee8SDavid du Colombier 			printf("\twarning: too many params in send\n");
204*219b2ee8SDavid du Colombier 	}
205*219b2ee8SDavid du Colombier 	q->qlen++;
206*219b2ee8SDavid du Colombier 	return 1;
207*219b2ee8SDavid du Colombier }
208*219b2ee8SDavid du Colombier 
209*219b2ee8SDavid du Colombier int
210*219b2ee8SDavid du Colombier a_rcv(Queue *q, Lextok *n, int full)
211*219b2ee8SDavid du Colombier {	Lextok *m;
212*219b2ee8SDavid du Colombier 	int i=0, j, k;
213*219b2ee8SDavid du Colombier 	extern int Rvous;
214*219b2ee8SDavid du Colombier 
215*219b2ee8SDavid du Colombier 	if (q->qlen == 0) return 0;	/* q is empty */
216*219b2ee8SDavid du Colombier try_slot:
217*219b2ee8SDavid du Colombier 	/* test executability */
218*219b2ee8SDavid du Colombier 	for (m = n->rgt, j=0; m && j < q->nflds; m = m->rgt, j++)
219*219b2ee8SDavid du Colombier 		if (m->lft->ntyp == CONST
220*219b2ee8SDavid du Colombier 		&&  q->contents[i*q->nflds+j] != m->lft->val)
221*219b2ee8SDavid du Colombier 		{	if (n->val == 0		/* fifo recv */
222*219b2ee8SDavid du Colombier 			|| ++i >= q->qlen)	/* last slot */
223*219b2ee8SDavid du Colombier 				return 0;	/* no match  */
224*219b2ee8SDavid du Colombier 			goto try_slot;
225*219b2ee8SDavid du Colombier 		}
226*219b2ee8SDavid du Colombier 
227*219b2ee8SDavid du Colombier 	if (TstOnly) return 1;
228*219b2ee8SDavid du Colombier 
229*219b2ee8SDavid du Colombier 	if (verbose&8)
230*219b2ee8SDavid du Colombier 	{	if (j < q->nflds)
231*219b2ee8SDavid du Colombier 			printf("\twarning: missing params in next recv\n");
232*219b2ee8SDavid du Colombier 		else if (m)
233*219b2ee8SDavid du Colombier 			printf("\twarning: too many params in next recv\n");
234*219b2ee8SDavid du Colombier 	}
235*219b2ee8SDavid du Colombier 
236*219b2ee8SDavid du Colombier 	/* set the fields */
237*219b2ee8SDavid du Colombier 	for (m = n->rgt, j = 0; j < q->nflds; m = (m)?m->rgt:m, j++)
238*219b2ee8SDavid du Colombier 	{	if (verbose&8 && !Rvous)
239*219b2ee8SDavid du Colombier 		sr_talk(n, q->contents[i*q->nflds+j],
240*219b2ee8SDavid du Colombier 				(full)?"Recv ":"[Recv] ", "<-", j, q);
241*219b2ee8SDavid du Colombier 
242*219b2ee8SDavid du Colombier 		if (m && m->lft->ntyp != CONST)
243*219b2ee8SDavid du Colombier 		{	(void) setval(m->lft, q->contents[i*q->nflds+j]);
244*219b2ee8SDavid du Colombier 			typ_ck(q->fld_width[j], Sym_typ(m->lft), "recv");
245*219b2ee8SDavid du Colombier 		}
246*219b2ee8SDavid du Colombier 		for (k = i; full && k < q->qlen-1; k++)
247*219b2ee8SDavid du Colombier 			q->contents[k*q->nflds+j] =
248*219b2ee8SDavid du Colombier 			  q->contents[(k+1)*q->nflds+j];
249*219b2ee8SDavid du Colombier 	}
250*219b2ee8SDavid du Colombier 	if (full) q->qlen--;
251*219b2ee8SDavid du Colombier 	return 1;
252*219b2ee8SDavid du Colombier }
253*219b2ee8SDavid du Colombier 
254*219b2ee8SDavid du Colombier int
255*219b2ee8SDavid du Colombier s_snd(Queue *q, Lextok *n)
256*219b2ee8SDavid du Colombier {	Lextok *m;
257*219b2ee8SDavid du Colombier 	RunList *rX, *sX = X;	/* rX=recvr, sX=sendr */
258*219b2ee8SDavid du Colombier 	int i, j = 0;	/* q field# */
259*219b2ee8SDavid du Colombier 
260*219b2ee8SDavid du Colombier 	for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++)
261*219b2ee8SDavid du Colombier 	{	q->contents[j] = cast_val(q->fld_width[j], eval(m->lft));
262*219b2ee8SDavid du Colombier 		typ_ck(q->fld_width[j], Sym_typ(m->lft), "rv-send");
263*219b2ee8SDavid du Colombier 	}
264*219b2ee8SDavid du Colombier 	q->qlen = 1;
265*219b2ee8SDavid du Colombier 	if (!complete_rendez())
266*219b2ee8SDavid du Colombier 	{	q->qlen = 0;
267*219b2ee8SDavid du Colombier 		return 0;
268*219b2ee8SDavid du Colombier 	}
269*219b2ee8SDavid du Colombier 	if (TstOnly) return 1;
270*219b2ee8SDavid du Colombier 	if (verbose&16)
271*219b2ee8SDavid du Colombier 	{	m = n->rgt;
272*219b2ee8SDavid du Colombier 		rX = X; X = sX;
273*219b2ee8SDavid du Colombier 		for (j = 0; m && j < q->nflds; m = m->rgt, j++)
274*219b2ee8SDavid du Colombier 			sr_talk(n, eval(m->lft), "Sent ", "->", j, q);
275*219b2ee8SDavid du Colombier 		for (i = j; i < q->nflds; i++)
276*219b2ee8SDavid du Colombier 			sr_talk(n, 0, "Sent ", "->", i, q);
277*219b2ee8SDavid du Colombier 		if (j < q->nflds)
278*219b2ee8SDavid du Colombier 			  printf("\twarning: missing params in rv-send\n");
279*219b2ee8SDavid du Colombier 		else if (m)
280*219b2ee8SDavid du Colombier 			  printf("\twarning: too many params in rv-send\n");
281*219b2ee8SDavid du Colombier 		X = rX;
282*219b2ee8SDavid du Colombier 		m = n->rgt;
283*219b2ee8SDavid du Colombier 		if (!s_trail)
284*219b2ee8SDavid du Colombier 		for (j = 0; m && j < q->nflds; m = m->rgt, j++)
285*219b2ee8SDavid du Colombier 			sr_talk(n, eval(m->lft), "Recv ", "<-", j, q);
286*219b2ee8SDavid du Colombier 	}
287*219b2ee8SDavid du Colombier 	return 1;
288*219b2ee8SDavid du Colombier }
289*219b2ee8SDavid du Colombier 
290*219b2ee8SDavid du Colombier void
291*219b2ee8SDavid du Colombier sr_talk(Lextok *n, int v, char *tr, char *a, int j, Queue *q)
292*219b2ee8SDavid du Colombier {	char s[64];
293*219b2ee8SDavid du Colombier 	if (xspin)
294*219b2ee8SDavid du Colombier 	{	if (verbose&4)
295*219b2ee8SDavid du Colombier 		sprintf(s, "(state -)\t[values: %d",
296*219b2ee8SDavid du Colombier 			eval(n->lft));
297*219b2ee8SDavid du Colombier 		else
298*219b2ee8SDavid du Colombier 		sprintf(s, "(state -)\t[%d", eval(n->lft));
299*219b2ee8SDavid du Colombier 		if (strncmp(tr, "Sen", 3) == 0)
300*219b2ee8SDavid du Colombier 			strcat(s, "!");
301*219b2ee8SDavid du Colombier 		else
302*219b2ee8SDavid du Colombier 			strcat(s, "?");
303*219b2ee8SDavid du Colombier 	} else
304*219b2ee8SDavid du Colombier 	{	strcpy(s, tr);
305*219b2ee8SDavid du Colombier 	}
306*219b2ee8SDavid du Colombier 	if (j == 0)
307*219b2ee8SDavid du Colombier 	{	whoruns(1);
308*219b2ee8SDavid du Colombier 		printf("line %3d %s %s",
309*219b2ee8SDavid du Colombier 			n->ln, n->fn->name, s);
310*219b2ee8SDavid du Colombier 	} else
311*219b2ee8SDavid du Colombier 		printf(",");
312*219b2ee8SDavid du Colombier 	sr_mesg(v, q->fld_width[j] == MTYPE);
313*219b2ee8SDavid du Colombier 
314*219b2ee8SDavid du Colombier 	if (j == q->nflds - 1)
315*219b2ee8SDavid du Colombier 	{	if (xspin)
316*219b2ee8SDavid du Colombier 		{	printf("]\n");
317*219b2ee8SDavid du Colombier 			if (!(verbose&4)) printf("\n");
318*219b2ee8SDavid du Colombier 			return;
319*219b2ee8SDavid du Colombier 		}
320*219b2ee8SDavid du Colombier 		printf("\t%s queue %d (", a, eval(n->lft));
321*219b2ee8SDavid du Colombier 		if (n->sym->type == CHAN)
322*219b2ee8SDavid du Colombier 			printf("%s", n->sym->name);
323*219b2ee8SDavid du Colombier 		else if (n->sym->type == NAME)
324*219b2ee8SDavid du Colombier 			printf("%s", lookup(n->sym->name)->name);
325*219b2ee8SDavid du Colombier 		else if (n->sym->type == STRUCT)
326*219b2ee8SDavid du Colombier 		{	Symbol *r = n->sym;
327*219b2ee8SDavid du Colombier 			if (r->context)
328*219b2ee8SDavid du Colombier 				r = findloc(r);
329*219b2ee8SDavid du Colombier 			ini_struct(r);
330*219b2ee8SDavid du Colombier 			printf("%s", r->name);
331*219b2ee8SDavid du Colombier 			struct_name(n->lft, r, 1);
332*219b2ee8SDavid du Colombier 		} else
333*219b2ee8SDavid du Colombier 			printf("-");
334*219b2ee8SDavid du Colombier 		if (n->lft->lft)
335*219b2ee8SDavid du Colombier 			printf("[%d]", eval(n->lft->lft));
336*219b2ee8SDavid du Colombier 		printf(")\n");
337*219b2ee8SDavid du Colombier 	}
338*219b2ee8SDavid du Colombier 	fflush(stdout);
339*219b2ee8SDavid du Colombier }
340*219b2ee8SDavid du Colombier 
341*219b2ee8SDavid du Colombier void
342*219b2ee8SDavid du Colombier sr_mesg(int v, int j)
343*219b2ee8SDavid du Colombier {	extern Lextok *Mtype;
344*219b2ee8SDavid du Colombier 	int cnt = 1;
345*219b2ee8SDavid du Colombier 	Lextok *n;
346*219b2ee8SDavid du Colombier 
347*219b2ee8SDavid du Colombier 	for (n = Mtype; n && j; n = n->rgt, cnt++)
348*219b2ee8SDavid du Colombier 		if (cnt == v)
349*219b2ee8SDavid du Colombier 		{	printf("%s", n->lft->sym->name);
350*219b2ee8SDavid du Colombier 			return;
351*219b2ee8SDavid du Colombier 		}
352*219b2ee8SDavid du Colombier 	printf("%d", v);
353*219b2ee8SDavid du Colombier }
354*219b2ee8SDavid du Colombier 
355*219b2ee8SDavid du Colombier void
356*219b2ee8SDavid du Colombier doq(Symbol *s, int n, RunList *r)
357*219b2ee8SDavid du Colombier {	Queue *q;
358*219b2ee8SDavid du Colombier 	int j, k;
359*219b2ee8SDavid du Colombier 
360*219b2ee8SDavid du Colombier 	if (!s->val)	/* uninitialized queue */
361*219b2ee8SDavid du Colombier 		return;
362*219b2ee8SDavid du Colombier 	for (q = qtab; q; q = q->nxt)
363*219b2ee8SDavid du Colombier 	if (q->qid == s->val[n])
364*219b2ee8SDavid du Colombier 	{	if (xspin > 0
365*219b2ee8SDavid du Colombier 		&& (verbose&4)
366*219b2ee8SDavid du Colombier 		&& q->setat < depth)
367*219b2ee8SDavid du Colombier 			continue;
368*219b2ee8SDavid du Colombier 		if (q->nslots == 0)
369*219b2ee8SDavid du Colombier 			continue; /* rv q always empty */
370*219b2ee8SDavid du Colombier 		printf("\t\tqueue %d (", q->qid);
371*219b2ee8SDavid du Colombier 		if (r)
372*219b2ee8SDavid du Colombier 		printf("%s(%d):", r->n->name, r->pid);
373*219b2ee8SDavid du Colombier 		if (s->nel != 1)
374*219b2ee8SDavid du Colombier 		  printf("%s[%d]): ", s->name, n);
375*219b2ee8SDavid du Colombier 		else
376*219b2ee8SDavid du Colombier 		  printf("%s): ", s->name);
377*219b2ee8SDavid du Colombier 		for (k = 0; k < q->qlen; k++)
378*219b2ee8SDavid du Colombier 		{	printf("[");
379*219b2ee8SDavid du Colombier 			for (j = 0; j < q->nflds; j++)
380*219b2ee8SDavid du Colombier 			{	if (j > 0) printf(",");
381*219b2ee8SDavid du Colombier 				sr_mesg(q->contents[k*q->nflds+j],
382*219b2ee8SDavid du Colombier 					q->fld_width[j] == MTYPE);
383*219b2ee8SDavid du Colombier 			}
384*219b2ee8SDavid du Colombier 			printf("]");
385*219b2ee8SDavid du Colombier 		}
386*219b2ee8SDavid du Colombier 		printf("\n");
387*219b2ee8SDavid du Colombier 		break;
388*219b2ee8SDavid du Colombier 	}
389*219b2ee8SDavid du Colombier }
390