xref: /plan9-contrib/sys/src/cmd/spin/mesg.c (revision de2caf28f9ba1a56e70be94a699435d36eb50311)
1219b2ee8SDavid du Colombier /***** spin: mesg.c *****/
2219b2ee8SDavid du Colombier 
3*de2caf28SDavid du Colombier /*
4*de2caf28SDavid du Colombier  * This file is part of the public release of Spin. It is subject to the
5*de2caf28SDavid du Colombier  * terms in the LICENSE file that is included in this source directory.
6*de2caf28SDavid du Colombier  * Tool documentation is available at http://spinroot.com
7*de2caf28SDavid du Colombier  */
8219b2ee8SDavid du Colombier 
9*de2caf28SDavid du Colombier #include <stdlib.h>
10*de2caf28SDavid du Colombier #include <assert.h>
11219b2ee8SDavid du Colombier #include "spin.h"
12219b2ee8SDavid du Colombier #include "y.tab.h"
13219b2ee8SDavid du Colombier 
14312a1df1SDavid du Colombier #ifndef MAXQ
15219b2ee8SDavid du Colombier #define MAXQ	2500		/* default max # queues  */
16312a1df1SDavid du Colombier #endif
17219b2ee8SDavid du Colombier 
18*de2caf28SDavid du Colombier extern RunList	*X_lst;
19219b2ee8SDavid du Colombier extern Symbol	*Fname;
207dd7cddfSDavid du Colombier extern int	verbose, TstOnly, s_trail, analyze, columns;
217dd7cddfSDavid du Colombier extern int	lineno, depth, xspin, m_loss, jumpsteps;
227dd7cddfSDavid du Colombier extern int	nproc, nstop;
237dd7cddfSDavid du Colombier extern short	Have_claim;
24219b2ee8SDavid du Colombier 
25*de2caf28SDavid du Colombier QH	*qh_lst;
26219b2ee8SDavid du Colombier Queue	*qtab = (Queue *) 0;	/* linked list of queues */
27219b2ee8SDavid du Colombier Queue	*ltab[MAXQ];		/* linear list of queues */
28*de2caf28SDavid du Colombier int	nrqs = 0, firstrow = 1, has_stdin = 0;
29*de2caf28SDavid du Colombier char	GBuf[4096];
307dd7cddfSDavid du Colombier 
317dd7cddfSDavid du Colombier static Lextok	*n_rem = (Lextok *) 0;
327dd7cddfSDavid du Colombier static Queue	*q_rem = (Queue  *) 0;
337dd7cddfSDavid du Colombier 
347dd7cddfSDavid du Colombier static int	a_rcv(Queue *, Lextok *, int);
357dd7cddfSDavid du Colombier static int	a_snd(Queue *, Lextok *);
367dd7cddfSDavid du Colombier static int	sa_snd(Queue *, Lextok *);
377dd7cddfSDavid du Colombier static int	s_snd(Queue *, Lextok *);
38*de2caf28SDavid du Colombier extern Lextok	**find_mtype_list(const char *);
39*de2caf28SDavid du Colombier extern char	*which_mtype(const char *);
40*de2caf28SDavid du Colombier extern void	sr_buf(int, int, const char *);
41*de2caf28SDavid du Colombier extern void	sr_mesg(FILE *, int, int, const char *);
427dd7cddfSDavid du Colombier extern void	putarrow(int, int);
437dd7cddfSDavid du Colombier static void	sr_talk(Lextok *, int, char *, char *, int, Queue *);
44219b2ee8SDavid du Colombier 
45219b2ee8SDavid du Colombier int
cnt_mpars(Lextok * n)46219b2ee8SDavid du Colombier cnt_mpars(Lextok *n)
47219b2ee8SDavid du Colombier {	Lextok *m;
48219b2ee8SDavid du Colombier 	int i=0;
49219b2ee8SDavid du Colombier 
50219b2ee8SDavid du Colombier 	for (m = n; m; m = m->rgt)
51219b2ee8SDavid du Colombier 		i += Cnt_flds(m);
52219b2ee8SDavid du Colombier 	return i;
53219b2ee8SDavid du Colombier }
54219b2ee8SDavid du Colombier 
55219b2ee8SDavid du Colombier int
qmake(Symbol * s)56219b2ee8SDavid du Colombier qmake(Symbol *s)
57219b2ee8SDavid du Colombier {	Lextok *m;
58219b2ee8SDavid du Colombier 	Queue *q;
59*de2caf28SDavid du Colombier 	int i, j;
60219b2ee8SDavid du Colombier 
61219b2ee8SDavid du Colombier 	if (!s->ini)
62219b2ee8SDavid du Colombier 		return 0;
63219b2ee8SDavid du Colombier 
64*de2caf28SDavid du Colombier 	if (nrqs >= MAXQ)
65219b2ee8SDavid du Colombier 	{	lineno = s->ini->ln;
66219b2ee8SDavid du Colombier 		Fname  = s->ini->fn;
67219b2ee8SDavid du Colombier 		fatal("too many queues (%s)", s->name);
68219b2ee8SDavid du Colombier 	}
69*de2caf28SDavid du Colombier 	if (analyze && nrqs >= 255)
707dd7cddfSDavid du Colombier 	{	fatal("too many channel types", (char *)0);
717dd7cddfSDavid du Colombier 	}
72219b2ee8SDavid du Colombier 
73219b2ee8SDavid du Colombier 	if (s->ini->ntyp != CHAN)
74219b2ee8SDavid du Colombier 		return eval(s->ini);
75219b2ee8SDavid du Colombier 
76219b2ee8SDavid du Colombier 	q = (Queue *) emalloc(sizeof(Queue));
77*de2caf28SDavid du Colombier 	q->qid    = (short) ++nrqs;
78219b2ee8SDavid du Colombier 	q->nslots = s->ini->val;
79219b2ee8SDavid du Colombier 	q->nflds  = cnt_mpars(s->ini->rgt);
80219b2ee8SDavid du Colombier 	q->setat  = depth;
81219b2ee8SDavid du Colombier 
82219b2ee8SDavid du Colombier 	i = max(1, q->nslots);	/* 0-slot qs get 1 slot minimum */
83*de2caf28SDavid du Colombier 	j = q->nflds * i;
84219b2ee8SDavid du Colombier 
85*de2caf28SDavid du Colombier 	q->contents  = (int *) emalloc(j*sizeof(int));
86219b2ee8SDavid du Colombier 	q->fld_width = (int *) emalloc(q->nflds*sizeof(int));
87*de2caf28SDavid du Colombier 	q->mtp       = (char **) emalloc(q->nflds*sizeof(char *));
887dd7cddfSDavid du Colombier 	q->stepnr    = (int *) emalloc(i*sizeof(int));
89219b2ee8SDavid du Colombier 
90219b2ee8SDavid du Colombier 	for (m = s->ini->rgt, i = 0; m; m = m->rgt)
91219b2ee8SDavid du Colombier 	{	if (m->sym && m->ntyp == STRUCT)
92*de2caf28SDavid du Colombier 		{	i = Width_set(q->fld_width, i, getuname(m->sym));
93*de2caf28SDavid du Colombier 		} else
94*de2caf28SDavid du Colombier 		{	if (m->sym)
95*de2caf28SDavid du Colombier 			{	q->mtp[i] = m->sym->name;
96219b2ee8SDavid du Colombier 			}
97*de2caf28SDavid du Colombier 			q->fld_width[i++] = m->ntyp;
98*de2caf28SDavid du Colombier 	}	}
99219b2ee8SDavid du Colombier 	q->nxt = qtab;
100219b2ee8SDavid du Colombier 	qtab = q;
101219b2ee8SDavid du Colombier 	ltab[q->qid-1] = q;
102219b2ee8SDavid du Colombier 
103219b2ee8SDavid du Colombier 	return q->qid;
104219b2ee8SDavid du Colombier }
105219b2ee8SDavid du Colombier 
106219b2ee8SDavid du Colombier int
qfull(Lextok * n)107219b2ee8SDavid du Colombier qfull(Lextok *n)
108219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
109219b2ee8SDavid du Colombier 
110219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
111219b2ee8SDavid du Colombier 		return (ltab[whichq]->qlen >= ltab[whichq]->nslots);
112219b2ee8SDavid du Colombier 	return 0;
113219b2ee8SDavid du Colombier }
114219b2ee8SDavid du Colombier 
115219b2ee8SDavid du Colombier int
qlen(Lextok * n)116219b2ee8SDavid du Colombier qlen(Lextok *n)
117219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
118219b2ee8SDavid du Colombier 
119219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
120219b2ee8SDavid du Colombier 		return ltab[whichq]->qlen;
121219b2ee8SDavid du Colombier 	return 0;
122219b2ee8SDavid du Colombier }
123219b2ee8SDavid du Colombier 
124219b2ee8SDavid du Colombier int
q_is_sync(Lextok * n)125219b2ee8SDavid du Colombier q_is_sync(Lextok *n)
126219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
127219b2ee8SDavid du Colombier 
128219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
129219b2ee8SDavid du Colombier 		return (ltab[whichq]->nslots == 0);
130219b2ee8SDavid du Colombier 	return 0;
131219b2ee8SDavid du Colombier }
132219b2ee8SDavid du Colombier 
133219b2ee8SDavid du Colombier int
qsend(Lextok * n)134219b2ee8SDavid du Colombier qsend(Lextok *n)
135219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
136219b2ee8SDavid du Colombier 
137219b2ee8SDavid du Colombier 	if (whichq == -1)
138219b2ee8SDavid du Colombier 	{	printf("Error: sending to an uninitialized chan\n");
139*de2caf28SDavid du Colombier 		/* whichq = 0; */
140219b2ee8SDavid du Colombier 		return 0;
141219b2ee8SDavid du Colombier 	}
142219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
143219b2ee8SDavid du Colombier 	{	ltab[whichq]->setat = depth;
144219b2ee8SDavid du Colombier 		if (ltab[whichq]->nslots > 0)
145*de2caf28SDavid du Colombier 		{	return a_snd(ltab[whichq], n);;
146*de2caf28SDavid du Colombier 		} else
147*de2caf28SDavid du Colombier 		{	return s_snd(ltab[whichq], n);
148*de2caf28SDavid du Colombier 	}	}
149219b2ee8SDavid du Colombier 	return 0;
150219b2ee8SDavid du Colombier }
151219b2ee8SDavid du Colombier 
152*de2caf28SDavid du Colombier #ifndef PC
153*de2caf28SDavid du Colombier  #include <termios.h>
154*de2caf28SDavid du Colombier  static struct termios initial_settings, new_settings;
155*de2caf28SDavid du Colombier 
156*de2caf28SDavid du Colombier  void
peek_ch_init(void)157*de2caf28SDavid du Colombier  peek_ch_init(void)
158*de2caf28SDavid du Colombier  {
159*de2caf28SDavid du Colombier 	tcgetattr(0,&initial_settings);
160*de2caf28SDavid du Colombier 
161*de2caf28SDavid du Colombier 	new_settings = initial_settings;
162*de2caf28SDavid du Colombier 	new_settings.c_lflag &= ~ICANON;
163*de2caf28SDavid du Colombier 	new_settings.c_lflag &= ~ECHO;
164*de2caf28SDavid du Colombier 	new_settings.c_lflag &= ~ISIG;
165*de2caf28SDavid du Colombier 	new_settings.c_cc[VMIN] = 0;
166*de2caf28SDavid du Colombier 	new_settings.c_cc[VTIME] = 0;
167*de2caf28SDavid du Colombier  }
168*de2caf28SDavid du Colombier 
169*de2caf28SDavid du Colombier  int
peek_ch(void)170*de2caf28SDavid du Colombier  peek_ch(void)
171*de2caf28SDavid du Colombier  {	int n;
172*de2caf28SDavid du Colombier 
173*de2caf28SDavid du Colombier 	has_stdin = 1;
174*de2caf28SDavid du Colombier 
175*de2caf28SDavid du Colombier 	tcsetattr(0, TCSANOW, &new_settings);
176*de2caf28SDavid du Colombier 	n = getchar();
177*de2caf28SDavid du Colombier 	tcsetattr(0, TCSANOW, &initial_settings);
178*de2caf28SDavid du Colombier 
179*de2caf28SDavid du Colombier 	return n;
180*de2caf28SDavid du Colombier  }
181*de2caf28SDavid du Colombier #endif
182*de2caf28SDavid du Colombier 
183219b2ee8SDavid du Colombier int
qrecv(Lextok * n,int full)184219b2ee8SDavid du Colombier qrecv(Lextok *n, int full)
185219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
186219b2ee8SDavid du Colombier 
187219b2ee8SDavid du Colombier 	if (whichq == -1)
1887dd7cddfSDavid du Colombier 	{	if (n->sym && !strcmp(n->sym->name, "STDIN"))
1897dd7cddfSDavid du Colombier 		{	Lextok *m;
190*de2caf28SDavid du Colombier #ifndef PC
191*de2caf28SDavid du Colombier 			static int did_once = 0;
192*de2caf28SDavid du Colombier 			if (!did_once) /* 6.2.4 */
193*de2caf28SDavid du Colombier 			{	peek_ch_init();
194*de2caf28SDavid du Colombier 				did_once = 1;
195*de2caf28SDavid du Colombier 			}
196*de2caf28SDavid du Colombier #endif
1977dd7cddfSDavid du Colombier 			if (TstOnly) return 1;
1987dd7cddfSDavid du Colombier 
1997dd7cddfSDavid du Colombier 			for (m = n->rgt; m; m = m->rgt)
2007dd7cddfSDavid du Colombier 			if (m->lft->ntyp != CONST && m->lft->ntyp != EVAL)
201*de2caf28SDavid du Colombier 			{
202*de2caf28SDavid du Colombier #ifdef PC
203*de2caf28SDavid du Colombier 				int c = getchar();
204*de2caf28SDavid du Colombier #else
205*de2caf28SDavid du Colombier 				int c = peek_ch();	/* 6.2.4, was getchar(); */
206*de2caf28SDavid du Colombier #endif
207*de2caf28SDavid du Colombier 				if (c == 27 || c == 3)	/* escape or control-c */
208*de2caf28SDavid du Colombier 				{	printf("quit\n");
209*de2caf28SDavid du Colombier 					exit(0);
210*de2caf28SDavid du Colombier 				} /* else: non-blocking */
211*de2caf28SDavid du Colombier 				if (c == EOF) return 0;	/* no char available */
2127dd7cddfSDavid du Colombier 				(void) setval(m->lft, c);
2137dd7cddfSDavid du Colombier 			} else
214*de2caf28SDavid du Colombier 			{	fatal("invalid use of STDIN", (char *)0);
215*de2caf28SDavid du Colombier 			}
2167dd7cddfSDavid du Colombier 			return 1;
2177dd7cddfSDavid du Colombier 		}
2187dd7cddfSDavid du Colombier 		printf("Error: receiving from an uninitialized chan %s\n",
2197dd7cddfSDavid du Colombier 			n->sym?n->sym->name:"");
220*de2caf28SDavid du Colombier 		/* whichq = 0; */
221219b2ee8SDavid du Colombier 		return 0;
222219b2ee8SDavid du Colombier 	}
223219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
224219b2ee8SDavid du Colombier 	{	ltab[whichq]->setat = depth;
225219b2ee8SDavid du Colombier 		return a_rcv(ltab[whichq], n, full);
226219b2ee8SDavid du Colombier 	}
227219b2ee8SDavid du Colombier 	return 0;
228219b2ee8SDavid du Colombier }
229219b2ee8SDavid du Colombier 
2307dd7cddfSDavid du Colombier static int
sa_snd(Queue * q,Lextok * n)231219b2ee8SDavid du Colombier sa_snd(Queue *q, Lextok *n)	/* sorted asynchronous */
232219b2ee8SDavid du Colombier {	Lextok *m;
233219b2ee8SDavid du Colombier 	int i, j, k;
234219b2ee8SDavid du Colombier 	int New, Old;
235219b2ee8SDavid du Colombier 
236219b2ee8SDavid du Colombier 	for (i = 0; i < q->qlen; i++)
237219b2ee8SDavid du Colombier 	for (j = 0, m = n->rgt; m && j < q->nflds; m = m->rgt, j++)
2387dd7cddfSDavid du Colombier 	{	New = cast_val(q->fld_width[j], eval(m->lft), 0);
239219b2ee8SDavid du Colombier 		Old = q->contents[i*q->nflds+j];
24000d97012SDavid du Colombier 		if (New == Old)
24100d97012SDavid du Colombier 			continue;
24200d97012SDavid du Colombier 		if (New >  Old)
24300d97012SDavid du Colombier 			break;	/* inner loop */
24400d97012SDavid du Colombier 		goto found;	/* New < Old */
245219b2ee8SDavid du Colombier 	}
246219b2ee8SDavid du Colombier found:
247219b2ee8SDavid du Colombier 	for (j = q->qlen-1; j >= i; j--)
248219b2ee8SDavid du Colombier 	for (k = 0; k < q->nflds; k++)
249219b2ee8SDavid du Colombier 	{	q->contents[(j+1)*q->nflds+k] =
250219b2ee8SDavid du Colombier 			q->contents[j*q->nflds+k];	/* shift up */
2517dd7cddfSDavid du Colombier 		if (k == 0)
2527dd7cddfSDavid du Colombier 			q->stepnr[j+1] = q->stepnr[j];
253219b2ee8SDavid du Colombier 	}
254219b2ee8SDavid du Colombier 	return i*q->nflds;				/* new q offset */
255219b2ee8SDavid du Colombier }
256219b2ee8SDavid du Colombier 
257219b2ee8SDavid du Colombier void
typ_ck(int ft,int at,char * s)258219b2ee8SDavid du Colombier typ_ck(int ft, int at, char *s)
259219b2ee8SDavid du Colombier {
2607dd7cddfSDavid du Colombier 	if ((verbose&32) && ft != at
261*de2caf28SDavid du Colombier 	&& (ft == CHAN || at == CHAN)
262*de2caf28SDavid du Colombier 	&& (at != PREDEF || strcmp(s, "recv") != 0))
263*de2caf28SDavid du Colombier 	{	char buf[256], tag1[64], tag2[64];
264219b2ee8SDavid du Colombier 		(void) sputtype(tag1, ft);
265219b2ee8SDavid du Colombier 		(void) sputtype(tag2, at);
266219b2ee8SDavid du Colombier 		sprintf(buf, "type-clash in %s, (%s<-> %s)", s, tag1, tag2);
267219b2ee8SDavid du Colombier 		non_fatal("%s", buf);
268219b2ee8SDavid du Colombier 	}
269219b2ee8SDavid du Colombier }
270219b2ee8SDavid du Colombier 
271*de2caf28SDavid du Colombier static void
mtype_ck(char * p,Lextok * arg)272*de2caf28SDavid du Colombier mtype_ck(char *p, Lextok *arg)
273*de2caf28SDavid du Colombier {	char *t, *s = p?p:"_unnamed_";
274*de2caf28SDavid du Colombier 
275*de2caf28SDavid du Colombier 	if (!arg
276*de2caf28SDavid du Colombier 	||  !arg->sym)
277*de2caf28SDavid du Colombier 	{	return;
278*de2caf28SDavid du Colombier 	}
279*de2caf28SDavid du Colombier 
280*de2caf28SDavid du Colombier 	switch (arg->ntyp) {
281*de2caf28SDavid du Colombier 	case NAME:
282*de2caf28SDavid du Colombier 		if (arg->sym->mtype_name)
283*de2caf28SDavid du Colombier 		{	t = arg->sym->mtype_name->name;
284*de2caf28SDavid du Colombier 		} else
285*de2caf28SDavid du Colombier 		{	t = "_unnamed_";
286*de2caf28SDavid du Colombier 		}
287*de2caf28SDavid du Colombier 		break;
288*de2caf28SDavid du Colombier 	case CONST:
289*de2caf28SDavid du Colombier 		t = which_mtype(arg->sym->name);
290*de2caf28SDavid du Colombier 		break;
291*de2caf28SDavid du Colombier 	default:
292*de2caf28SDavid du Colombier 		t = "expression";
293*de2caf28SDavid du Colombier 		break;
294*de2caf28SDavid du Colombier 	}
295*de2caf28SDavid du Colombier 
296*de2caf28SDavid du Colombier 	if (strcmp(s, t) != 0)
297*de2caf28SDavid du Colombier 	{	printf("spin: %s:%d, Error: '%s' is type '%s', but ",
298*de2caf28SDavid du Colombier 			arg->fn?arg->fn->name:"", arg->ln,
299*de2caf28SDavid du Colombier 			arg->sym->name, t);
300*de2caf28SDavid du Colombier 		printf("should be type '%s'\n", s);
301*de2caf28SDavid du Colombier 		non_fatal("incorrect type of '%s'", arg->sym->name);
302*de2caf28SDavid du Colombier 	}
303*de2caf28SDavid du Colombier }
304*de2caf28SDavid du Colombier 
3057dd7cddfSDavid du Colombier static int
a_snd(Queue * q,Lextok * n)306219b2ee8SDavid du Colombier a_snd(Queue *q, Lextok *n)
307219b2ee8SDavid du Colombier {	Lextok *m;
308219b2ee8SDavid du Colombier 	int i = q->qlen*q->nflds;	/* q offset */
309219b2ee8SDavid du Colombier 	int j = 0;			/* q field# */
310219b2ee8SDavid du Colombier 
311219b2ee8SDavid du Colombier 	if (q->nslots > 0 && q->qlen >= q->nslots)
312*de2caf28SDavid du Colombier 	{	return m_loss;	/* q is full */
313*de2caf28SDavid du Colombier 	}
314219b2ee8SDavid du Colombier 
315*de2caf28SDavid du Colombier 	if (TstOnly)
316*de2caf28SDavid du Colombier 	{	return 1;
317*de2caf28SDavid du Colombier 	}
318219b2ee8SDavid du Colombier 	if (n->val) i = sa_snd(q, n);	/* sorted insert */
319219b2ee8SDavid du Colombier 
3207dd7cddfSDavid du Colombier 	q->stepnr[i/q->nflds] = depth;
3217dd7cddfSDavid du Colombier 
322219b2ee8SDavid du Colombier 	for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++)
323219b2ee8SDavid du Colombier 	{	int New = eval(m->lft);
3247dd7cddfSDavid du Colombier 		q->contents[i+j] = cast_val(q->fld_width[j], New, 0);
325*de2caf28SDavid du Colombier 
326*de2caf28SDavid du Colombier 		if (q->fld_width[i+j] == MTYPE)
327*de2caf28SDavid du Colombier 		{	mtype_ck(q->mtp[i+j], m->lft);	/* 6.4.8 */
328219b2ee8SDavid du Colombier 		}
3297dd7cddfSDavid du Colombier 		if ((verbose&16) && depth >= jumpsteps)
330*de2caf28SDavid du Colombier 		{	sr_talk(n, New, "Send ", "->", j, q); /* XXX j was i+j in 6.4.8 */
331*de2caf28SDavid du Colombier 		}
332*de2caf28SDavid du Colombier 		typ_ck(q->fld_width[i+j], Sym_typ(m->lft), "send");
333*de2caf28SDavid du Colombier 	}
334*de2caf28SDavid du Colombier 
335*de2caf28SDavid du Colombier 	if ((verbose&16) && depth >= jumpsteps)
336219b2ee8SDavid du Colombier 	{	for (i = j; i < q->nflds; i++)
337*de2caf28SDavid du Colombier 		{	sr_talk(n, 0, "Send ", "->", i, q);
338*de2caf28SDavid du Colombier 		}
339219b2ee8SDavid du Colombier 		if (j < q->nflds)
340*de2caf28SDavid du Colombier 		{	printf("%3d: warning: missing params in send\n",
3417dd7cddfSDavid du Colombier 				depth);
342219b2ee8SDavid du Colombier 		}
343*de2caf28SDavid du Colombier 		if (m)
344*de2caf28SDavid du Colombier 		{	printf("%3d: warning: too many params in send\n",
345*de2caf28SDavid du Colombier 				depth);
346*de2caf28SDavid du Colombier 	}	}
347219b2ee8SDavid du Colombier 	q->qlen++;
348219b2ee8SDavid du Colombier 	return 1;
349219b2ee8SDavid du Colombier }
350219b2ee8SDavid du Colombier 
3517dd7cddfSDavid du Colombier static int
a_rcv(Queue * q,Lextok * n,int full)352219b2ee8SDavid du Colombier a_rcv(Queue *q, Lextok *n, int full)
353219b2ee8SDavid du Colombier {	Lextok *m;
3547dd7cddfSDavid du Colombier 	int i=0, oi, j, k;
355219b2ee8SDavid du Colombier 	extern int Rvous;
356219b2ee8SDavid du Colombier 
3577dd7cddfSDavid du Colombier 	if (q->qlen == 0)
358*de2caf28SDavid du Colombier 	{	return 0;	/* q is empty */
359*de2caf28SDavid du Colombier 	}
360219b2ee8SDavid du Colombier try_slot:
361219b2ee8SDavid du Colombier 	/* test executability */
362219b2ee8SDavid du Colombier 	for (m = n->rgt, j=0; m && j < q->nflds; m = m->rgt, j++)
363*de2caf28SDavid du Colombier 	{
364*de2caf28SDavid du Colombier 		if (q->fld_width[i*q->nflds+j] == MTYPE)
365*de2caf28SDavid du Colombier 		{	mtype_ck(q->mtp[i*q->nflds+j], m->lft);	/* 6.4.8 */
366*de2caf28SDavid du Colombier 		}
367*de2caf28SDavid du Colombier 
368*de2caf28SDavid du Colombier 		if (m->lft->ntyp == CONST
369219b2ee8SDavid du Colombier 		&&  q->contents[i*q->nflds+j] != m->lft->val)
370*de2caf28SDavid du Colombier 		{
371*de2caf28SDavid du Colombier 			if (n->val == 0		/* fifo recv */
372*de2caf28SDavid du Colombier 			||  n->val == 2		/* fifo poll */
373*de2caf28SDavid du Colombier 			|| ++i >= q->qlen)	/* last slot */
374*de2caf28SDavid du Colombier 			{	return 0;	/* no match  */
375*de2caf28SDavid du Colombier 			}
376*de2caf28SDavid du Colombier 			goto try_slot;		/* random recv */
377*de2caf28SDavid du Colombier 		}
378*de2caf28SDavid du Colombier 
379*de2caf28SDavid du Colombier 		if (m->lft->ntyp == EVAL)
380*de2caf28SDavid du Colombier 		{	Lextok *fix = m->lft->lft;
381*de2caf28SDavid du Colombier 
382*de2caf28SDavid du Colombier 			if (fix->ntyp == ',')	/* new, usertype7 */
383*de2caf28SDavid du Colombier 			{	do {
384*de2caf28SDavid du Colombier 					assert(j < q->nflds);
385*de2caf28SDavid du Colombier 					if (q->contents[i*q->nflds+j] != eval(fix->lft))
386*de2caf28SDavid du Colombier 					{	if (n->val == 0
387*de2caf28SDavid du Colombier 						||  n->val == 2
388*de2caf28SDavid du Colombier 						||  ++i >= q->qlen)
389*de2caf28SDavid du Colombier 						{	return 0;
390*de2caf28SDavid du Colombier 						}
391*de2caf28SDavid du Colombier 						goto try_slot;	/* random recv */
392*de2caf28SDavid du Colombier 					}
393*de2caf28SDavid du Colombier 					j++;
394*de2caf28SDavid du Colombier 					fix = fix->rgt;
395*de2caf28SDavid du Colombier 				} while (fix && fix->ntyp == ',');
396*de2caf28SDavid du Colombier 				j--;
397*de2caf28SDavid du Colombier 			} else
398*de2caf28SDavid du Colombier 			{	if (q->contents[i*q->nflds+j] != eval(fix))
399219b2ee8SDavid du Colombier 				{	if (n->val == 0		/* fifo recv */
4007dd7cddfSDavid du Colombier 					||  n->val == 2		/* fifo poll */
401219b2ee8SDavid du Colombier 					|| ++i >= q->qlen)	/* last slot */
402*de2caf28SDavid du Colombier 					{	return 0;	/* no match  */
403219b2ee8SDavid du Colombier 					}
404*de2caf28SDavid du Colombier 					goto try_slot;		/* random recv */
405*de2caf28SDavid du Colombier 		}	}	}
406*de2caf28SDavid du Colombier 	}
407*de2caf28SDavid du Colombier 
408219b2ee8SDavid du Colombier 	if (TstOnly) return 1;
409219b2ee8SDavid du Colombier 
410219b2ee8SDavid du Colombier 	if (verbose&8)
411219b2ee8SDavid du Colombier 	{	if (j < q->nflds)
412*de2caf28SDavid du Colombier 		{	printf("%3d: warning: missing params in next recv\n",
4137dd7cddfSDavid du Colombier 				depth);
414*de2caf28SDavid du Colombier 		} else if (m)
415*de2caf28SDavid du Colombier 		{	printf("%3d: warning: too many params in next recv\n",
4167dd7cddfSDavid du Colombier 				depth);
417*de2caf28SDavid du Colombier 	}	}
418219b2ee8SDavid du Colombier 
419219b2ee8SDavid du Colombier 	/* set the fields */
4207dd7cddfSDavid du Colombier 	if (Rvous)
4217dd7cddfSDavid du Colombier 	{	n_rem = n;
4227dd7cddfSDavid du Colombier 		q_rem = q;
4237dd7cddfSDavid du Colombier 	}
424219b2ee8SDavid du Colombier 
4257dd7cddfSDavid du Colombier 	oi = q->stepnr[i];
4267dd7cddfSDavid du Colombier 	for (m = n->rgt, j = 0; m && j < q->nflds; m = m->rgt, j++)
4277dd7cddfSDavid du Colombier 	{	if (columns && !full)	/* was columns == 1 */
4287dd7cddfSDavid du Colombier 			continue;
4297dd7cddfSDavid du Colombier 		if ((verbose&8) && !Rvous && depth >= jumpsteps)
4307dd7cddfSDavid du Colombier 		{	sr_talk(n, q->contents[i*q->nflds+j],
4317dd7cddfSDavid du Colombier 			(full && n->val < 2)?"Recv ":"[Recv] ", "<-", j, q);
4327dd7cddfSDavid du Colombier 		}
4337dd7cddfSDavid du Colombier 		if (!full)
4347dd7cddfSDavid du Colombier 			continue;	/* test */
4357dd7cddfSDavid du Colombier 		if (m && m->lft->ntyp != CONST && m->lft->ntyp != EVAL)
436219b2ee8SDavid du Colombier 		{	(void) setval(m->lft, q->contents[i*q->nflds+j]);
437219b2ee8SDavid du Colombier 			typ_ck(q->fld_width[j], Sym_typ(m->lft), "recv");
438219b2ee8SDavid du Colombier 		}
4397dd7cddfSDavid du Colombier 		if (n->val < 2)		/* not a poll */
4407dd7cddfSDavid du Colombier 		for (k = i; k < q->qlen-1; k++)
4417dd7cddfSDavid du Colombier 		{	q->contents[k*q->nflds+j] =
442219b2ee8SDavid du Colombier 			  q->contents[(k+1)*q->nflds+j];
4437dd7cddfSDavid du Colombier 			if (j == 0)
4447dd7cddfSDavid du Colombier 			  q->stepnr[k] = q->stepnr[k+1];
445219b2ee8SDavid du Colombier 		}
4467dd7cddfSDavid du Colombier 	}
4477dd7cddfSDavid du Colombier 
4487dd7cddfSDavid du Colombier 	if ((!columns || full)
4497dd7cddfSDavid du Colombier 	&& (verbose&8) && !Rvous && depth >= jumpsteps)
4507dd7cddfSDavid du Colombier 	for (i = j; i < q->nflds; i++)
4517dd7cddfSDavid du Colombier 	{	sr_talk(n, 0,
4527dd7cddfSDavid du Colombier 		(full && n->val < 2)?"Recv ":"[Recv] ", "<-", i, q);
4537dd7cddfSDavid du Colombier 	}
4547dd7cddfSDavid du Colombier 	if (columns == 2 && full && !Rvous && depth >= jumpsteps)
4557dd7cddfSDavid du Colombier 		putarrow(oi, depth);
4567dd7cddfSDavid du Colombier 
4577dd7cddfSDavid du Colombier 	if (full && n->val < 2)
4587dd7cddfSDavid du Colombier 		q->qlen--;
459219b2ee8SDavid du Colombier 	return 1;
460219b2ee8SDavid du Colombier }
461219b2ee8SDavid du Colombier 
4627dd7cddfSDavid du Colombier static int
s_snd(Queue * q,Lextok * n)463219b2ee8SDavid du Colombier s_snd(Queue *q, Lextok *n)
464219b2ee8SDavid du Colombier {	Lextok *m;
465*de2caf28SDavid du Colombier 	RunList *rX, *sX = X_lst;	/* rX=recvr, sX=sendr */
466219b2ee8SDavid du Colombier 	int i, j = 0;	/* q field# */
467219b2ee8SDavid du Colombier 
468219b2ee8SDavid du Colombier 	for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++)
4697dd7cddfSDavid du Colombier 	{	q->contents[j] = cast_val(q->fld_width[j], eval(m->lft), 0);
470219b2ee8SDavid du Colombier 		typ_ck(q->fld_width[j], Sym_typ(m->lft), "rv-send");
471*de2caf28SDavid du Colombier 
472*de2caf28SDavid du Colombier 		if (q->fld_width[j] == MTYPE)
473*de2caf28SDavid du Colombier 		{	mtype_ck(q->mtp[j], m->lft);	/* 6.4.8 */
474*de2caf28SDavid du Colombier 	}	}
475*de2caf28SDavid du Colombier 
476219b2ee8SDavid du Colombier 	q->qlen = 1;
477219b2ee8SDavid du Colombier 	if (!complete_rendez())
478219b2ee8SDavid du Colombier 	{	q->qlen = 0;
479219b2ee8SDavid du Colombier 		return 0;
480219b2ee8SDavid du Colombier 	}
4817dd7cddfSDavid du Colombier 	if (TstOnly)
4827dd7cddfSDavid du Colombier 	{	q->qlen = 0;
4837dd7cddfSDavid du Colombier 		return 1;
4847dd7cddfSDavid du Colombier 	}
4857dd7cddfSDavid du Colombier 	q->stepnr[0] = depth;
4867dd7cddfSDavid du Colombier 	if ((verbose&16) && depth >= jumpsteps)
487219b2ee8SDavid du Colombier 	{	m = n->rgt;
488*de2caf28SDavid du Colombier 		rX = X_lst; X_lst = sX;
489*de2caf28SDavid du Colombier 
490219b2ee8SDavid du Colombier 		for (j = 0; m && j < q->nflds; m = m->rgt, j++)
491*de2caf28SDavid du Colombier 		{	sr_talk(n, eval(m->lft), "Sent ", "->", j, q);
492*de2caf28SDavid du Colombier 		}
493*de2caf28SDavid du Colombier 
494219b2ee8SDavid du Colombier 		for (i = j; i < q->nflds; i++)
495*de2caf28SDavid du Colombier 		{	sr_talk(n, 0, "Sent ", "->", i, q);
496*de2caf28SDavid du Colombier 		}
497*de2caf28SDavid du Colombier 
498219b2ee8SDavid du Colombier 		if (j < q->nflds)
499*de2caf28SDavid du Colombier 		{	  printf("%3d: warning: missing params in rv-send\n",
5007dd7cddfSDavid du Colombier 				depth);
501*de2caf28SDavid du Colombier 		} else if (m)
502*de2caf28SDavid du Colombier 		{	  printf("%3d: warning: too many params in rv-send\n",
5037dd7cddfSDavid du Colombier 				depth);
504*de2caf28SDavid du Colombier 		}
505*de2caf28SDavid du Colombier 
506*de2caf28SDavid du Colombier 		X_lst = rX;	/* restore receiver's context */
507219b2ee8SDavid du Colombier 		if (!s_trail)
5087dd7cddfSDavid du Colombier 		{	if (!n_rem || !q_rem)
5097dd7cddfSDavid du Colombier 				fatal("cannot happen, s_snd", (char *) 0);
5107dd7cddfSDavid du Colombier 			m = n_rem->rgt;
511219b2ee8SDavid du Colombier 			for (j = 0; m && j < q->nflds; m = m->rgt, j++)
512*de2caf28SDavid du Colombier 			{
513*de2caf28SDavid du Colombier 				if (q->fld_width[j] == MTYPE)
514*de2caf28SDavid du Colombier 				{	mtype_ck(q->mtp[j], m->lft);	/* 6.4.8 */
515*de2caf28SDavid du Colombier 				}
516312a1df1SDavid du Colombier 
517*de2caf28SDavid du Colombier 				if (m->lft->ntyp != NAME
518*de2caf28SDavid du Colombier 				||  strcmp(m->lft->sym->name, "_") != 0)
519*de2caf28SDavid du Colombier 				{	i = eval(m->lft);
520*de2caf28SDavid du Colombier 				} else
521*de2caf28SDavid du Colombier 				{	i = 0;
522*de2caf28SDavid du Colombier 				}
523312a1df1SDavid du Colombier 				if (verbose&8)
5247dd7cddfSDavid du Colombier 				sr_talk(n_rem,i,"Recv ","<-",j,q_rem);
5257dd7cddfSDavid du Colombier 			}
526312a1df1SDavid du Colombier 			if (verbose&8)
5277dd7cddfSDavid du Colombier 			for (i = j; i < q->nflds; i++)
5287dd7cddfSDavid du Colombier 				sr_talk(n_rem, 0, "Recv ", "<-", j, q_rem);
5297dd7cddfSDavid du Colombier 			if (columns == 2)
5307dd7cddfSDavid du Colombier 				putarrow(depth, depth);
5317dd7cddfSDavid du Colombier 		}
5327dd7cddfSDavid du Colombier 		n_rem = (Lextok *) 0;
5337dd7cddfSDavid du Colombier 		q_rem = (Queue *) 0;
534219b2ee8SDavid du Colombier 	}
535219b2ee8SDavid du Colombier 	return 1;
536219b2ee8SDavid du Colombier }
537219b2ee8SDavid du Colombier 
53800d97012SDavid du Colombier static void
channm(Lextok * n)5397dd7cddfSDavid du Colombier channm(Lextok *n)
540312a1df1SDavid du Colombier {	char lbuf[512];
5417dd7cddfSDavid du Colombier 
5427dd7cddfSDavid du Colombier 	if (n->sym->type == CHAN)
543*de2caf28SDavid du Colombier 		strcat(GBuf, n->sym->name);
5447dd7cddfSDavid du Colombier 	else if (n->sym->type == NAME)
545*de2caf28SDavid du Colombier 		strcat(GBuf, lookup(n->sym->name)->name);
5467dd7cddfSDavid du Colombier 	else if (n->sym->type == STRUCT)
5477dd7cddfSDavid du Colombier 	{	Symbol *r = n->sym;
5487dd7cddfSDavid du Colombier 		if (r->context)
54900d97012SDavid du Colombier 		{	r = findloc(r);
55000d97012SDavid du Colombier 			if (!r)
551*de2caf28SDavid du Colombier 			{	strcat(GBuf, "*?*");
55200d97012SDavid du Colombier 				return;
55300d97012SDavid du Colombier 		}	}
5547dd7cddfSDavid du Colombier 		ini_struct(r);
5557dd7cddfSDavid du Colombier 		printf("%s", r->name);
556312a1df1SDavid du Colombier 		strcpy(lbuf, "");
5577dd7cddfSDavid du Colombier 		struct_name(n->lft, r, 1, lbuf);
558*de2caf28SDavid du Colombier 		strcat(GBuf, lbuf);
5597dd7cddfSDavid du Colombier 	} else
560*de2caf28SDavid du Colombier 		strcat(GBuf, "-");
5617dd7cddfSDavid du Colombier 	if (n->lft->lft)
5627dd7cddfSDavid du Colombier 	{	sprintf(lbuf, "[%d]", eval(n->lft->lft));
563*de2caf28SDavid du Colombier 		strcat(GBuf, lbuf);
5647dd7cddfSDavid du Colombier 	}
5657dd7cddfSDavid du Colombier }
5667dd7cddfSDavid du Colombier 
5677dd7cddfSDavid du Colombier static void
difcolumns(Lextok * n,char * tr,int v,int j,Queue * q)5687dd7cddfSDavid du Colombier difcolumns(Lextok *n, char *tr, int v, int j, Queue *q)
569*de2caf28SDavid du Colombier {	extern int prno;
5707dd7cddfSDavid du Colombier 
5717dd7cddfSDavid du Colombier 	if (j == 0)
572*de2caf28SDavid du Colombier 	{	GBuf[0] = '\0';
5737dd7cddfSDavid du Colombier 		channm(n);
574*de2caf28SDavid du Colombier 		strcat(GBuf, (strncmp(tr, "Sen", 3))?"?":"!");
5757dd7cddfSDavid du Colombier 	} else
576*de2caf28SDavid du Colombier 		strcat(GBuf, ",");
577*de2caf28SDavid du Colombier 	if (tr[0] == '[') strcat(GBuf, "[");
578*de2caf28SDavid du Colombier 	sr_buf(v, q->fld_width[j] == MTYPE, q->mtp[j]);
5797dd7cddfSDavid du Colombier 	if (j == q->nflds - 1)
5807dd7cddfSDavid du Colombier 	{	int cnr;
581*de2caf28SDavid du Colombier 		if (s_trail)
582*de2caf28SDavid du Colombier 		{	cnr = prno - Have_claim;
583*de2caf28SDavid du Colombier 		} else
584*de2caf28SDavid du Colombier 		{	cnr = X_lst?X_lst->pid - Have_claim:0;
585*de2caf28SDavid du Colombier 		}
586*de2caf28SDavid du Colombier 		if (tr[0] == '[') strcat(GBuf, "]");
587*de2caf28SDavid du Colombier 		pstext(cnr, GBuf);
5887dd7cddfSDavid du Colombier 	}
5897dd7cddfSDavid du Colombier }
5907dd7cddfSDavid du Colombier 
5917dd7cddfSDavid du Colombier static void
docolumns(Lextok * n,char * tr,int v,int j,Queue * q)5927dd7cddfSDavid du Colombier docolumns(Lextok *n, char *tr, int v, int j, Queue *q)
5937dd7cddfSDavid du Colombier {	int i;
5947dd7cddfSDavid du Colombier 
5957dd7cddfSDavid du Colombier 	if (firstrow)
5967dd7cddfSDavid du Colombier 	{	printf("q\\p");
5977dd7cddfSDavid du Colombier 		for (i = 0; i < nproc-nstop - Have_claim; i++)
5987dd7cddfSDavid du Colombier 			printf(" %3d", i);
5997dd7cddfSDavid du Colombier 		printf("\n");
6007dd7cddfSDavid du Colombier 		firstrow = 0;
6017dd7cddfSDavid du Colombier 	}
6027dd7cddfSDavid du Colombier 	if (j == 0)
6037dd7cddfSDavid du Colombier 	{	printf("%3d", q->qid);
604*de2caf28SDavid du Colombier 		if (X_lst)
605*de2caf28SDavid du Colombier 		for (i = 0; i < X_lst->pid - Have_claim; i++)
6067dd7cddfSDavid du Colombier 			printf("   .");
6077dd7cddfSDavid du Colombier 		printf("   ");
608*de2caf28SDavid du Colombier 		GBuf[0] = '\0';
6097dd7cddfSDavid du Colombier 		channm(n);
610*de2caf28SDavid du Colombier 		printf("%s%c", GBuf, (strncmp(tr, "Sen", 3))?'?':'!');
6117dd7cddfSDavid du Colombier 	} else
6127dd7cddfSDavid du Colombier 		printf(",");
6137dd7cddfSDavid du Colombier 	if (tr[0] == '[') printf("[");
614*de2caf28SDavid du Colombier 	sr_mesg(stdout, v, q->fld_width[j] == MTYPE, q->mtp[j]);
6157dd7cddfSDavid du Colombier 	if (j == q->nflds - 1)
6167dd7cddfSDavid du Colombier 	{	if (tr[0] == '[') printf("]");
6177dd7cddfSDavid du Colombier 		printf("\n");
6187dd7cddfSDavid du Colombier 	}
6197dd7cddfSDavid du Colombier }
6207dd7cddfSDavid du Colombier 
6217dd7cddfSDavid du Colombier void
qhide(int q)6227dd7cddfSDavid du Colombier qhide(int q)
6237dd7cddfSDavid du Colombier {	QH *p = (QH *) emalloc(sizeof(QH));
6247dd7cddfSDavid du Colombier 	p->n = q;
625*de2caf28SDavid du Colombier 	p->nxt = qh_lst;
626*de2caf28SDavid du Colombier 	qh_lst = p;
6277dd7cddfSDavid du Colombier }
6287dd7cddfSDavid du Colombier 
6297dd7cddfSDavid du Colombier int
qishidden(int q)6307dd7cddfSDavid du Colombier qishidden(int q)
6317dd7cddfSDavid du Colombier {	QH *p;
632*de2caf28SDavid du Colombier 	for (p = qh_lst; p; p = p->nxt)
6337dd7cddfSDavid du Colombier 		if (p->n == q)
6347dd7cddfSDavid du Colombier 			return 1;
6357dd7cddfSDavid du Colombier 	return 0;
6367dd7cddfSDavid du Colombier }
6377dd7cddfSDavid du Colombier 
6387dd7cddfSDavid du Colombier static void
sr_talk(Lextok * n,int v,char * tr,char * a,int j,Queue * q)639219b2ee8SDavid du Colombier sr_talk(Lextok *n, int v, char *tr, char *a, int j, Queue *q)
64000d97012SDavid du Colombier {	char s[128];
6417dd7cddfSDavid du Colombier 
6427dd7cddfSDavid du Colombier 	if (qishidden(eval(n->lft)))
6437dd7cddfSDavid du Colombier 		return;
6447dd7cddfSDavid du Colombier 
6457dd7cddfSDavid du Colombier 	if (columns)
6467dd7cddfSDavid du Colombier 	{	if (columns == 2)
6477dd7cddfSDavid du Colombier 			difcolumns(n, tr, v, j, q);
6487dd7cddfSDavid du Colombier 		else
6497dd7cddfSDavid du Colombier 			docolumns(n, tr, v, j, q);
6507dd7cddfSDavid du Colombier 		return;
6517dd7cddfSDavid du Colombier 	}
652219b2ee8SDavid du Colombier 	if (xspin)
6537dd7cddfSDavid du Colombier 	{	if ((verbose&4) && tr[0] != '[')
654219b2ee8SDavid du Colombier 		sprintf(s, "(state -)\t[values: %d",
655219b2ee8SDavid du Colombier 			eval(n->lft));
656219b2ee8SDavid du Colombier 		else
657219b2ee8SDavid du Colombier 		sprintf(s, "(state -)\t[%d", eval(n->lft));
658219b2ee8SDavid du Colombier 		if (strncmp(tr, "Sen", 3) == 0)
659219b2ee8SDavid du Colombier 			strcat(s, "!");
660219b2ee8SDavid du Colombier 		else
661219b2ee8SDavid du Colombier 			strcat(s, "?");
662219b2ee8SDavid du Colombier 	} else
663219b2ee8SDavid du Colombier 	{	strcpy(s, tr);
664219b2ee8SDavid du Colombier 	}
6657dd7cddfSDavid du Colombier 
666219b2ee8SDavid du Colombier 	if (j == 0)
66700d97012SDavid du Colombier 	{	char snm[128];
66800d97012SDavid du Colombier 		whoruns(1);
66900d97012SDavid du Colombier 		{	char *ptr = n->fn->name;
67000d97012SDavid du Colombier 			char *qtr = snm;
67100d97012SDavid du Colombier 			while (*ptr != '\0')
67200d97012SDavid du Colombier 			{	if (*ptr != '\"')
67300d97012SDavid du Colombier 				{	*qtr++ = *ptr;
67400d97012SDavid du Colombier 				}
67500d97012SDavid du Colombier 				ptr++;
67600d97012SDavid du Colombier 			}
67700d97012SDavid du Colombier 			*qtr = '\0';
67800d97012SDavid du Colombier 			printf("%s:%d %s",
67900d97012SDavid du Colombier 				snm, n->ln, s);
68000d97012SDavid du Colombier 		}
681219b2ee8SDavid du Colombier 	} else
682*de2caf28SDavid du Colombier 	{	printf(",");
683*de2caf28SDavid du Colombier 	}
684*de2caf28SDavid du Colombier 	sr_mesg(stdout, v, q->fld_width[j] == MTYPE, q->mtp[j]);
685219b2ee8SDavid du Colombier 
686219b2ee8SDavid du Colombier 	if (j == q->nflds - 1)
687219b2ee8SDavid du Colombier 	{	if (xspin)
688219b2ee8SDavid du Colombier 		{	printf("]\n");
689219b2ee8SDavid du Colombier 			if (!(verbose&4)) printf("\n");
690219b2ee8SDavid du Colombier 			return;
691219b2ee8SDavid du Colombier 		}
692219b2ee8SDavid du Colombier 		printf("\t%s queue %d (", a, eval(n->lft));
693*de2caf28SDavid du Colombier 		GBuf[0] = '\0';
6947dd7cddfSDavid du Colombier 		channm(n);
695*de2caf28SDavid du Colombier 		printf("%s)\n", GBuf);
696219b2ee8SDavid du Colombier 	}
697219b2ee8SDavid du Colombier 	fflush(stdout);
698219b2ee8SDavid du Colombier }
699219b2ee8SDavid du Colombier 
700219b2ee8SDavid du Colombier void
sr_buf(int v,int j,const char * s)701*de2caf28SDavid du Colombier sr_buf(int v, int j, const char *s)
7027dd7cddfSDavid du Colombier {	int cnt = 1; Lextok *n;
703f3793cddSDavid du Colombier 	char lbuf[512];
704*de2caf28SDavid du Colombier 	Lextok *Mtype = ZN;
705219b2ee8SDavid du Colombier 
706*de2caf28SDavid du Colombier 	if (j)
707*de2caf28SDavid du Colombier 	{	Mtype = *find_mtype_list(s?s:"_unnamed_");
708*de2caf28SDavid du Colombier 	}
709219b2ee8SDavid du Colombier 	for (n = Mtype; n && j; n = n->rgt, cnt++)
710*de2caf28SDavid du Colombier 	{	if (cnt == v)
711f3793cddSDavid du Colombier 		{	if(strlen(n->lft->sym->name) >= sizeof(lbuf))
712f3793cddSDavid du Colombier 			{	non_fatal("mtype name %s too long", n->lft->sym->name);
713f3793cddSDavid du Colombier 				break;
714f3793cddSDavid du Colombier 			}
715f3793cddSDavid du Colombier 			sprintf(lbuf, "%s", n->lft->sym->name);
716*de2caf28SDavid du Colombier 			strcat(GBuf, lbuf);
717219b2ee8SDavid du Colombier 			return;
718*de2caf28SDavid du Colombier 	}	}
7197dd7cddfSDavid du Colombier 	sprintf(lbuf, "%d", v);
720*de2caf28SDavid du Colombier 	strcat(GBuf, lbuf);
7217dd7cddfSDavid du Colombier }
7227dd7cddfSDavid du Colombier 
7237dd7cddfSDavid du Colombier void
sr_mesg(FILE * fd,int v,int j,const char * s)724*de2caf28SDavid du Colombier sr_mesg(FILE *fd, int v, int j, const char *s)
725*de2caf28SDavid du Colombier {	GBuf[0] ='\0';
726*de2caf28SDavid du Colombier 
727*de2caf28SDavid du Colombier 	sr_buf(v, j, s);
728*de2caf28SDavid du Colombier 	fprintf(fd, GBuf, (char *) 0); /* prevent compiler warning */
729219b2ee8SDavid du Colombier }
730219b2ee8SDavid du Colombier 
731219b2ee8SDavid du Colombier void
doq(Symbol * s,int n,RunList * r)732219b2ee8SDavid du Colombier doq(Symbol *s, int n, RunList *r)
733219b2ee8SDavid du Colombier {	Queue *q;
734219b2ee8SDavid du Colombier 	int j, k;
735219b2ee8SDavid du Colombier 
736219b2ee8SDavid du Colombier 	if (!s->val)	/* uninitialized queue */
737219b2ee8SDavid du Colombier 		return;
738219b2ee8SDavid du Colombier 	for (q = qtab; q; q = q->nxt)
739219b2ee8SDavid du Colombier 	if (q->qid == s->val[n])
740219b2ee8SDavid du Colombier 	{	if (xspin > 0
741219b2ee8SDavid du Colombier 		&& (verbose&4)
742219b2ee8SDavid du Colombier 		&& q->setat < depth)
74300d97012SDavid du Colombier 		{	continue;
74400d97012SDavid du Colombier 		}
745*de2caf28SDavid du Colombier 		if (q->nslots == 0)
746*de2caf28SDavid du Colombier 		{	continue;	/* rv q always empty */
747*de2caf28SDavid du Colombier 		}
748*de2caf28SDavid du Colombier 
749219b2ee8SDavid du Colombier 		printf("\t\tqueue %d (", q->qid);
750219b2ee8SDavid du Colombier 		if (r)
751*de2caf28SDavid du Colombier 		{	printf("%s(%d):", r->n->name, r->pid - Have_claim);
752*de2caf28SDavid du Colombier 		}
753*de2caf28SDavid du Colombier 
75400d97012SDavid du Colombier 		if (s->nel > 1 || s->isarray)
755*de2caf28SDavid du Colombier 		{	printf("%s[%d]): ", s->name, n);
756*de2caf28SDavid du Colombier 		} else
757*de2caf28SDavid du Colombier 		{	printf("%s): ", s->name);
758*de2caf28SDavid du Colombier 		}
759*de2caf28SDavid du Colombier 
760219b2ee8SDavid du Colombier 		for (k = 0; k < q->qlen; k++)
761219b2ee8SDavid du Colombier 		{	printf("[");
762219b2ee8SDavid du Colombier 			for (j = 0; j < q->nflds; j++)
763219b2ee8SDavid du Colombier 			{	if (j > 0) printf(",");
764*de2caf28SDavid du Colombier 				sr_mesg(stdout,
765*de2caf28SDavid du Colombier 					q->contents[k*q->nflds+j],
766*de2caf28SDavid du Colombier 					q->fld_width[j] == MTYPE,
767*de2caf28SDavid du Colombier 					q->mtp[j]);
768219b2ee8SDavid du Colombier 			}
769219b2ee8SDavid du Colombier 			printf("]");
770219b2ee8SDavid du Colombier 		}
771219b2ee8SDavid du Colombier 		printf("\n");
772219b2ee8SDavid du Colombier 		break;
773219b2ee8SDavid du Colombier 	}
774219b2ee8SDavid du Colombier }
7757dd7cddfSDavid du Colombier 
7767dd7cddfSDavid du Colombier void
nochan_manip(Lextok * p,Lextok * n,int d)777*de2caf28SDavid du Colombier nochan_manip(Lextok *p, Lextok *n, int d)	/* p=lhs n=rhs */
7787dd7cddfSDavid du Colombier {	int e = 1;
7797dd7cddfSDavid du Colombier 
780*de2caf28SDavid du Colombier 	if (!n
781*de2caf28SDavid du Colombier 	||  !p
782*de2caf28SDavid du Colombier 	||  !p->sym
783*de2caf28SDavid du Colombier 	||   p->sym->type == STRUCT)
784*de2caf28SDavid du Colombier 	{	/* if a struct, assignments to structure fields arent checked yet */
785*de2caf28SDavid du Colombier 		return;
786*de2caf28SDavid du Colombier 	}
787*de2caf28SDavid du Colombier 
7887dd7cddfSDavid du Colombier 	if (d == 0 && p->sym && p->sym->type == CHAN)
789312a1df1SDavid du Colombier 	{	setaccess(p->sym, ZS, 0, 'L');
790312a1df1SDavid du Colombier 
791312a1df1SDavid du Colombier 		if (n && n->ntyp == CONST)
792312a1df1SDavid du Colombier 			fatal("invalid asgn to chan", (char *) 0);
793312a1df1SDavid du Colombier 
794312a1df1SDavid du Colombier 		if (n && n->sym && n->sym->type == CHAN)
795312a1df1SDavid du Colombier 		{	setaccess(n->sym, ZS, 0, 'V');
796312a1df1SDavid du Colombier 			return;
797312a1df1SDavid du Colombier 		}
798312a1df1SDavid du Colombier 	}
7997dd7cddfSDavid du Colombier 
800*de2caf28SDavid du Colombier 	if (!d && n && n->ismtyp)	/* rhs is an mtype value (a constant) */
801*de2caf28SDavid du Colombier 	{	char *lhs = "_unnamed_", *rhs = "_unnamed_";
802*de2caf28SDavid du Colombier 
803*de2caf28SDavid du Colombier 		if (p->sym)
804*de2caf28SDavid du Colombier 		{	lhs = p->sym->mtype_name?p->sym->mtype_name->name:"_unnamed_";
805*de2caf28SDavid du Colombier 		}
806*de2caf28SDavid du Colombier 		if (n->sym)
807*de2caf28SDavid du Colombier 		{	rhs = which_mtype(n->sym->name); /* only for constants */
808*de2caf28SDavid du Colombier 		}
809*de2caf28SDavid du Colombier 
810*de2caf28SDavid du Colombier 		if (p->sym && !p->sym->mtype_name && n->sym)
811*de2caf28SDavid du Colombier 		{	p->sym->mtype_name = (Symbol *) emalloc(sizeof(Symbol));
812*de2caf28SDavid du Colombier 			p->sym->mtype_name->name = rhs;
813*de2caf28SDavid du Colombier 		} else if (strcmp(lhs, rhs) != 0)
814*de2caf28SDavid du Colombier 		{	fprintf(stderr, "spin: %s:%d, Error: '%s' is type '%s' but '%s' is type '%s'\n",
815*de2caf28SDavid du Colombier 				p->fn->name, p->ln,
816*de2caf28SDavid du Colombier 				p->sym?p->sym->name:"?", lhs,
817*de2caf28SDavid du Colombier 				n->sym?n->sym->name:"?", rhs);
818*de2caf28SDavid du Colombier 			non_fatal("type error", (char *) 0);
819*de2caf28SDavid du Colombier 	}	}
820*de2caf28SDavid du Colombier 
82100d97012SDavid du Colombier 	/* ok on the rhs of an assignment: */
822*de2caf28SDavid du Colombier 	if (!n
823*de2caf28SDavid du Colombier 	||  n->ntyp == LEN   || n->ntyp == RUN
82400d97012SDavid du Colombier 	||  n->ntyp == FULL  || n->ntyp == NFULL
825*de2caf28SDavid du Colombier 	||  n->ntyp == EMPTY || n->ntyp == NEMPTY
826*de2caf28SDavid du Colombier 	||  n->ntyp == 'R')
8277dd7cddfSDavid du Colombier 		return;
8287dd7cddfSDavid du Colombier 
8297dd7cddfSDavid du Colombier 	if (n->sym && n->sym->type == CHAN)
8307dd7cddfSDavid du Colombier 	{	if (d == 1)
8317dd7cddfSDavid du Colombier 			fatal("invalid use of chan name", (char *) 0);
8327dd7cddfSDavid du Colombier 		else
8337dd7cddfSDavid du Colombier 			setaccess(n->sym, ZS, 0, 'V');
8347dd7cddfSDavid du Colombier 	}
8357dd7cddfSDavid du Colombier 
8367dd7cddfSDavid du Colombier 	if (n->ntyp == NAME
8377dd7cddfSDavid du Colombier 	||  n->ntyp == '.')
838*de2caf28SDavid du Colombier 	{	e = 0;	/* array index or struct element */
839*de2caf28SDavid du Colombier 	}
8407dd7cddfSDavid du Colombier 
8417dd7cddfSDavid du Colombier 	nochan_manip(p, n->lft, e);
8427dd7cddfSDavid du Colombier 	nochan_manip(p, n->rgt, 1);
8437dd7cddfSDavid du Colombier }
844f3793cddSDavid du Colombier 
84500d97012SDavid du Colombier typedef struct BaseName {
84600d97012SDavid du Colombier 	char *str;
84700d97012SDavid du Colombier 	int cnt;
84800d97012SDavid du Colombier 	struct BaseName *nxt;
84900d97012SDavid du Colombier } BaseName;
850*de2caf28SDavid du Colombier 
851*de2caf28SDavid du Colombier static BaseName *bsn;
85200d97012SDavid du Colombier 
85300d97012SDavid du Colombier void
newbasename(char * s)85400d97012SDavid du Colombier newbasename(char *s)
85500d97012SDavid du Colombier {	BaseName *b;
85600d97012SDavid du Colombier 
85700d97012SDavid du Colombier /*	printf("+++++++++%s\n", s);	*/
85800d97012SDavid du Colombier 	for (b = bsn; b; b = b->nxt)
85900d97012SDavid du Colombier 		if (strcmp(b->str, s) == 0)
86000d97012SDavid du Colombier 		{	b->cnt++;
86100d97012SDavid du Colombier 			return;
86200d97012SDavid du Colombier 		}
86300d97012SDavid du Colombier 	b = (BaseName *) emalloc(sizeof(BaseName));
86400d97012SDavid du Colombier 	b->str = emalloc(strlen(s)+1);
86500d97012SDavid du Colombier 	b->cnt = 1;
86600d97012SDavid du Colombier 	strcpy(b->str, s);
86700d97012SDavid du Colombier 	b->nxt = bsn;
86800d97012SDavid du Colombier 	bsn = b;
86900d97012SDavid du Colombier }
87000d97012SDavid du Colombier 
87100d97012SDavid du Colombier void
delbasename(char * s)87200d97012SDavid du Colombier delbasename(char *s)
87300d97012SDavid du Colombier {	BaseName *b, *prv = (BaseName *) 0;
87400d97012SDavid du Colombier 
87500d97012SDavid du Colombier 	for (b = bsn; b; prv = b, b = b->nxt)
87600d97012SDavid du Colombier 	{	if (strcmp(b->str, s) == 0)
87700d97012SDavid du Colombier 		{	b->cnt--;
87800d97012SDavid du Colombier 			if (b->cnt == 0)
87900d97012SDavid du Colombier 			{	if (prv)
88000d97012SDavid du Colombier 				{	prv->nxt = b->nxt;
88100d97012SDavid du Colombier 				} else
88200d97012SDavid du Colombier 				{	bsn = b->nxt;
88300d97012SDavid du Colombier 			}	}
88400d97012SDavid du Colombier /*	printf("---------%s\n", s);	*/
88500d97012SDavid du Colombier 			break;
88600d97012SDavid du Colombier 	}	}
88700d97012SDavid du Colombier }
88800d97012SDavid du Colombier 
88900d97012SDavid du Colombier void
checkindex(char * s,char * t)89000d97012SDavid du Colombier checkindex(char *s, char *t)
89100d97012SDavid du Colombier {	BaseName *b;
89200d97012SDavid du Colombier 
89300d97012SDavid du Colombier /*	printf("xxx Check %s (%s)\n", s, t);	*/
89400d97012SDavid du Colombier 	for (b = bsn; b; b = b->nxt)
89500d97012SDavid du Colombier 	{
89600d97012SDavid du Colombier /*		printf("	%s\n", b->str);	*/
89700d97012SDavid du Colombier 		if (strcmp(b->str, s) == 0)
89800d97012SDavid du Colombier 		{	non_fatal("do not index an array with itself (%s)", t);
89900d97012SDavid du Colombier 			break;
90000d97012SDavid du Colombier 	}	}
90100d97012SDavid du Colombier }
90200d97012SDavid du Colombier 
90300d97012SDavid du Colombier void
scan_tree(Lextok * t,char * mn,char * mx)90400d97012SDavid du Colombier scan_tree(Lextok *t, char *mn, char *mx)
90500d97012SDavid du Colombier {	char sv[512];
90600d97012SDavid du Colombier 	char tmp[32];
90700d97012SDavid du Colombier 	int oln = lineno;
90800d97012SDavid du Colombier 
90900d97012SDavid du Colombier 	if (!t) return;
91000d97012SDavid du Colombier 
91100d97012SDavid du Colombier 	lineno = t->ln;
91200d97012SDavid du Colombier 
91300d97012SDavid du Colombier 	if (t->ntyp == NAME)
914*de2caf28SDavid du Colombier 	{	if (strlen(t->sym->name) + strlen(mn) > 256) // conservative
915*de2caf28SDavid du Colombier 		{	fatal("name too long", t->sym->name);
916*de2caf28SDavid du Colombier 		}
917*de2caf28SDavid du Colombier 
918*de2caf28SDavid du Colombier 		strcat(mn, t->sym->name);
91900d97012SDavid du Colombier 		strcat(mx, t->sym->name);
92000d97012SDavid du Colombier 		if (t->lft)		/* array index */
92100d97012SDavid du Colombier 		{	strcat(mn, "[]");
92200d97012SDavid du Colombier 			newbasename(mn);
92300d97012SDavid du Colombier 				strcpy(sv, mn);		/* save */
92400d97012SDavid du Colombier 				strcpy(mn, "");		/* clear */
92500d97012SDavid du Colombier 				strcat(mx, "[");
92600d97012SDavid du Colombier 				scan_tree(t->lft, mn, mx);	/* index */
92700d97012SDavid du Colombier 				strcat(mx, "]");
92800d97012SDavid du Colombier 				checkindex(mn, mx);	/* match against basenames */
92900d97012SDavid du Colombier 				strcpy(mn, sv);		/* restore */
93000d97012SDavid du Colombier 			delbasename(mn);
93100d97012SDavid du Colombier 		}
93200d97012SDavid du Colombier 		if (t->rgt)	/* structure element */
93300d97012SDavid du Colombier 		{	scan_tree(t->rgt, mn, mx);
93400d97012SDavid du Colombier 		}
93500d97012SDavid du Colombier 	} else if (t->ntyp == CONST)
93600d97012SDavid du Colombier 	{	strcat(mn, "1"); /* really: t->val */
93700d97012SDavid du Colombier 		sprintf(tmp, "%d", t->val);
93800d97012SDavid du Colombier 		strcat(mx, tmp);
93900d97012SDavid du Colombier 	} else if (t->ntyp == '.')
94000d97012SDavid du Colombier 	{	strcat(mn, ".");
94100d97012SDavid du Colombier 		strcat(mx, ".");
94200d97012SDavid du Colombier 		scan_tree(t->lft, mn, mx);
94300d97012SDavid du Colombier 	} else
94400d97012SDavid du Colombier 	{	strcat(mn, "??");
94500d97012SDavid du Colombier 		strcat(mx, "??");
94600d97012SDavid du Colombier 	}
94700d97012SDavid du Colombier 	lineno = oln;
94800d97012SDavid du Colombier }
94900d97012SDavid du Colombier 
95000d97012SDavid du Colombier void
no_nested_array_refs(Lextok * n)95100d97012SDavid du Colombier no_nested_array_refs(Lextok *n)	/* a [ a[1] ] with a[1] = 1, causes trouble in pan.b */
95200d97012SDavid du Colombier {	char mn[512];
95300d97012SDavid du Colombier 	char mx[512];
95400d97012SDavid du Colombier 
95500d97012SDavid du Colombier /*	printf("==================================ZAP\n");	*/
95600d97012SDavid du Colombier 	bsn = (BaseName *) 0;	/* start new list */
95700d97012SDavid du Colombier 	strcpy(mn, "");
95800d97012SDavid du Colombier 	strcpy(mx, "");
95900d97012SDavid du Colombier 
96000d97012SDavid du Colombier 	scan_tree(n, mn, mx);
96100d97012SDavid du Colombier /*	printf("==> %s\n", mn);	*/
96200d97012SDavid du Colombier }
96300d97012SDavid du Colombier 
964f3793cddSDavid du Colombier void
no_internals(Lextok * n)965f3793cddSDavid du Colombier no_internals(Lextok *n)
966f3793cddSDavid du Colombier {	char *sp;
967f3793cddSDavid du Colombier 
968f3793cddSDavid du Colombier 	if (!n->sym
969f3793cddSDavid du Colombier 	||  !n->sym->name)
970f3793cddSDavid du Colombier 		return;
971f3793cddSDavid du Colombier 
972f3793cddSDavid du Colombier 	sp = n->sym->name;
973f3793cddSDavid du Colombier 
974f3793cddSDavid du Colombier 	if ((strlen(sp) == strlen("_nr_pr") && strcmp(sp, "_nr_pr") == 0)
975*de2caf28SDavid du Colombier 	||  (strlen(sp) == strlen("_pid") && strcmp(sp, "_pid") == 0)
976f3793cddSDavid du Colombier 	||  (strlen(sp) == strlen("_p") && strcmp(sp, "_p") == 0))
977*de2caf28SDavid du Colombier 	{	fatal("invalid assignment to %s", sp);
978f3793cddSDavid du Colombier 	}
97900d97012SDavid du Colombier 
98000d97012SDavid du Colombier 	no_nested_array_refs(n);
981f3793cddSDavid du Colombier }
982