xref: /plan9/sys/src/cmd/spin/mesg.c (revision 00d970127b9d44d2b22f4f656717a212dec1f1d2)
1219b2ee8SDavid du Colombier /***** spin: mesg.c *****/
2219b2ee8SDavid 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            */
11219b2ee8SDavid du Colombier 
12219b2ee8SDavid du Colombier #include "spin.h"
13219b2ee8SDavid du Colombier #include "y.tab.h"
14219b2ee8SDavid du Colombier 
15312a1df1SDavid du Colombier #ifndef MAXQ
16219b2ee8SDavid du Colombier #define MAXQ	2500		/* default max # queues  */
17312a1df1SDavid du Colombier #endif
18219b2ee8SDavid du Colombier 
19219b2ee8SDavid du Colombier extern RunList	*X;
20219b2ee8SDavid du Colombier extern Symbol	*Fname;
217dd7cddfSDavid du Colombier extern Lextok	*Mtype;
227dd7cddfSDavid du Colombier extern int	verbose, TstOnly, s_trail, analyze, columns;
237dd7cddfSDavid du Colombier extern int	lineno, depth, xspin, m_loss, jumpsteps;
247dd7cddfSDavid du Colombier extern int	nproc, nstop;
257dd7cddfSDavid du Colombier extern short	Have_claim;
26219b2ee8SDavid du Colombier 
27219b2ee8SDavid du Colombier Queue	*qtab = (Queue *) 0;	/* linked list of queues */
28219b2ee8SDavid du Colombier Queue	*ltab[MAXQ];		/* linear list of queues */
297dd7cddfSDavid du Colombier int	nqs = 0, firstrow = 1;
307dd7cddfSDavid du Colombier char	Buf[4096];
317dd7cddfSDavid du Colombier 
327dd7cddfSDavid du Colombier static Lextok	*n_rem = (Lextok *) 0;
337dd7cddfSDavid du Colombier static Queue	*q_rem = (Queue  *) 0;
347dd7cddfSDavid du Colombier 
357dd7cddfSDavid du Colombier static int	a_rcv(Queue *, Lextok *, int);
367dd7cddfSDavid du Colombier static int	a_snd(Queue *, Lextok *);
377dd7cddfSDavid du Colombier static int	sa_snd(Queue *, Lextok *);
387dd7cddfSDavid du Colombier static int	s_snd(Queue *, Lextok *);
397dd7cddfSDavid du Colombier extern void	sr_buf(int, int);
407dd7cddfSDavid du Colombier extern void	sr_mesg(FILE *, int, int);
417dd7cddfSDavid du Colombier extern void	putarrow(int, int);
427dd7cddfSDavid du Colombier static void	sr_talk(Lextok *, int, char *, char *, int, Queue *);
43219b2ee8SDavid du Colombier 
44219b2ee8SDavid du Colombier int
cnt_mpars(Lextok * n)45219b2ee8SDavid du Colombier cnt_mpars(Lextok *n)
46219b2ee8SDavid du Colombier {	Lextok *m;
47219b2ee8SDavid du Colombier 	int i=0;
48219b2ee8SDavid du Colombier 
49219b2ee8SDavid du Colombier 	for (m = n; m; m = m->rgt)
50219b2ee8SDavid du Colombier 		i += Cnt_flds(m);
51219b2ee8SDavid du Colombier 	return i;
52219b2ee8SDavid du Colombier }
53219b2ee8SDavid du Colombier 
54219b2ee8SDavid du Colombier int
qmake(Symbol * s)55219b2ee8SDavid du Colombier qmake(Symbol *s)
56219b2ee8SDavid du Colombier {	Lextok *m;
57219b2ee8SDavid du Colombier 	Queue *q;
58312a1df1SDavid du Colombier 	int i;
59219b2ee8SDavid du Colombier 
60219b2ee8SDavid du Colombier 	if (!s->ini)
61219b2ee8SDavid du Colombier 		return 0;
62219b2ee8SDavid du Colombier 
63219b2ee8SDavid du Colombier 	if (nqs >= MAXQ)
64219b2ee8SDavid du Colombier 	{	lineno = s->ini->ln;
65219b2ee8SDavid du Colombier 		Fname  = s->ini->fn;
66219b2ee8SDavid du Colombier 		fatal("too many queues (%s)", s->name);
67219b2ee8SDavid du Colombier 	}
687dd7cddfSDavid du Colombier 	if (analyze && nqs >= 255)
697dd7cddfSDavid du Colombier 	{	fatal("too many channel types", (char *)0);
707dd7cddfSDavid du Colombier 	}
71219b2ee8SDavid du Colombier 
72219b2ee8SDavid du Colombier 	if (s->ini->ntyp != CHAN)
73219b2ee8SDavid du Colombier 		return eval(s->ini);
74219b2ee8SDavid du Colombier 
75219b2ee8SDavid du Colombier 	q = (Queue *) emalloc(sizeof(Queue));
76219b2ee8SDavid du Colombier 	q->qid    = ++nqs;
77219b2ee8SDavid du Colombier 	q->nslots = s->ini->val;
78219b2ee8SDavid du Colombier 	q->nflds  = cnt_mpars(s->ini->rgt);
79219b2ee8SDavid du Colombier 	q->setat  = depth;
80219b2ee8SDavid du Colombier 
81219b2ee8SDavid du Colombier 	i = max(1, q->nslots);	/* 0-slot qs get 1 slot minimum */
82219b2ee8SDavid du Colombier 
83219b2ee8SDavid du Colombier 	q->contents  = (int *) emalloc(q->nflds*i*sizeof(int));
84219b2ee8SDavid du Colombier 	q->fld_width = (int *) emalloc(q->nflds*sizeof(int));
857dd7cddfSDavid du Colombier 	q->stepnr = (int *)   emalloc(i*sizeof(int));
86219b2ee8SDavid du Colombier 
87219b2ee8SDavid du Colombier 	for (m = s->ini->rgt, i = 0; m; m = m->rgt)
88219b2ee8SDavid du Colombier 	{	if (m->sym && m->ntyp == STRUCT)
89219b2ee8SDavid du Colombier 			i = Width_set(q->fld_width, i, getuname(m->sym));
90219b2ee8SDavid du Colombier 		else
91219b2ee8SDavid du Colombier 			q->fld_width[i++] = m->ntyp;
92219b2ee8SDavid du Colombier 	}
93219b2ee8SDavid du Colombier 	q->nxt = qtab;
94219b2ee8SDavid du Colombier 	qtab = q;
95219b2ee8SDavid du Colombier 	ltab[q->qid-1] = q;
96219b2ee8SDavid du Colombier 
97219b2ee8SDavid du Colombier 	return q->qid;
98219b2ee8SDavid du Colombier }
99219b2ee8SDavid du Colombier 
100219b2ee8SDavid du Colombier int
qfull(Lextok * n)101219b2ee8SDavid du Colombier qfull(Lextok *n)
102219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
103219b2ee8SDavid du Colombier 
104219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
105219b2ee8SDavid du Colombier 		return (ltab[whichq]->qlen >= ltab[whichq]->nslots);
106219b2ee8SDavid du Colombier 	return 0;
107219b2ee8SDavid du Colombier }
108219b2ee8SDavid du Colombier 
109219b2ee8SDavid du Colombier int
qlen(Lextok * n)110219b2ee8SDavid du Colombier qlen(Lextok *n)
111219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
112219b2ee8SDavid du Colombier 
113219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
114219b2ee8SDavid du Colombier 		return ltab[whichq]->qlen;
115219b2ee8SDavid du Colombier 	return 0;
116219b2ee8SDavid du Colombier }
117219b2ee8SDavid du Colombier 
118219b2ee8SDavid du Colombier int
q_is_sync(Lextok * n)119219b2ee8SDavid du Colombier q_is_sync(Lextok *n)
120219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
121219b2ee8SDavid du Colombier 
122219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
123219b2ee8SDavid du Colombier 		return (ltab[whichq]->nslots == 0);
124219b2ee8SDavid du Colombier 	return 0;
125219b2ee8SDavid du Colombier }
126219b2ee8SDavid du Colombier 
127219b2ee8SDavid du Colombier int
qsend(Lextok * n)128219b2ee8SDavid du Colombier qsend(Lextok *n)
129219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
130219b2ee8SDavid du Colombier 
131219b2ee8SDavid du Colombier 	if (whichq == -1)
132219b2ee8SDavid du Colombier 	{	printf("Error: sending to an uninitialized chan\n");
133219b2ee8SDavid du Colombier 		whichq = 0;
134219b2ee8SDavid du Colombier 		return 0;
135219b2ee8SDavid du Colombier 	}
136219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
137219b2ee8SDavid du Colombier 	{	ltab[whichq]->setat = depth;
138219b2ee8SDavid du Colombier 		if (ltab[whichq]->nslots > 0)
139219b2ee8SDavid du Colombier 			return a_snd(ltab[whichq], n);
140219b2ee8SDavid du Colombier 		else
141219b2ee8SDavid du Colombier 			return s_snd(ltab[whichq], n);
142219b2ee8SDavid du Colombier 	}
143219b2ee8SDavid du Colombier 	return 0;
144219b2ee8SDavid du Colombier }
145219b2ee8SDavid du Colombier 
146219b2ee8SDavid du Colombier int
qrecv(Lextok * n,int full)147219b2ee8SDavid du Colombier qrecv(Lextok *n, int full)
148219b2ee8SDavid du Colombier {	int whichq = eval(n->lft)-1;
149219b2ee8SDavid du Colombier 
150219b2ee8SDavid du Colombier 	if (whichq == -1)
1517dd7cddfSDavid du Colombier 	{	if (n->sym && !strcmp(n->sym->name, "STDIN"))
1527dd7cddfSDavid du Colombier 		{	Lextok *m;
1537dd7cddfSDavid du Colombier 
1547dd7cddfSDavid du Colombier 			if (TstOnly) return 1;
1557dd7cddfSDavid du Colombier 
1567dd7cddfSDavid du Colombier 			for (m = n->rgt; m; m = m->rgt)
1577dd7cddfSDavid du Colombier 			if (m->lft->ntyp != CONST && m->lft->ntyp != EVAL)
1587dd7cddfSDavid du Colombier 			{	int c = getchar();
1597dd7cddfSDavid du Colombier 				(void) setval(m->lft, c);
1607dd7cddfSDavid du Colombier 			} else
1617dd7cddfSDavid du Colombier 				fatal("invalid use of STDIN", (char *)0);
1627dd7cddfSDavid du Colombier 
1637dd7cddfSDavid du Colombier 			whichq = 0;
1647dd7cddfSDavid du Colombier 			return 1;
1657dd7cddfSDavid du Colombier 		}
1667dd7cddfSDavid du Colombier 		printf("Error: receiving from an uninitialized chan %s\n",
1677dd7cddfSDavid du Colombier 			n->sym?n->sym->name:"");
168219b2ee8SDavid du Colombier 		whichq = 0;
169219b2ee8SDavid du Colombier 		return 0;
170219b2ee8SDavid du Colombier 	}
171219b2ee8SDavid du Colombier 	if (whichq < MAXQ && whichq >= 0 && ltab[whichq])
172219b2ee8SDavid du Colombier 	{	ltab[whichq]->setat = depth;
173219b2ee8SDavid du Colombier 		return a_rcv(ltab[whichq], n, full);
174219b2ee8SDavid du Colombier 	}
175219b2ee8SDavid du Colombier 	return 0;
176219b2ee8SDavid du Colombier }
177219b2ee8SDavid du Colombier 
1787dd7cddfSDavid du Colombier static int
sa_snd(Queue * q,Lextok * n)179219b2ee8SDavid du Colombier sa_snd(Queue *q, Lextok *n)	/* sorted asynchronous */
180219b2ee8SDavid du Colombier {	Lextok *m;
181219b2ee8SDavid du Colombier 	int i, j, k;
182219b2ee8SDavid du Colombier 	int New, Old;
183219b2ee8SDavid du Colombier 
184219b2ee8SDavid du Colombier 	for (i = 0; i < q->qlen; i++)
185219b2ee8SDavid du Colombier 	for (j = 0, m = n->rgt; m && j < q->nflds; m = m->rgt, j++)
1867dd7cddfSDavid du Colombier 	{	New = cast_val(q->fld_width[j], eval(m->lft), 0);
187219b2ee8SDavid du Colombier 		Old = q->contents[i*q->nflds+j];
188*00d97012SDavid du Colombier 		if (New == Old)
189*00d97012SDavid du Colombier 			continue;
190*00d97012SDavid du Colombier 		if (New >  Old)
191*00d97012SDavid du Colombier 			break;	/* inner loop */
192*00d97012SDavid du Colombier 		goto found;	/* New < Old */
193219b2ee8SDavid du Colombier 	}
194219b2ee8SDavid du Colombier found:
195219b2ee8SDavid du Colombier 	for (j = q->qlen-1; j >= i; j--)
196219b2ee8SDavid du Colombier 	for (k = 0; k < q->nflds; k++)
197219b2ee8SDavid du Colombier 	{	q->contents[(j+1)*q->nflds+k] =
198219b2ee8SDavid du Colombier 			q->contents[j*q->nflds+k];	/* shift up */
1997dd7cddfSDavid du Colombier 		if (k == 0)
2007dd7cddfSDavid du Colombier 			q->stepnr[j+1] = q->stepnr[j];
201219b2ee8SDavid du Colombier 	}
202219b2ee8SDavid du Colombier 	return i*q->nflds;				/* new q offset */
203219b2ee8SDavid du Colombier }
204219b2ee8SDavid du Colombier 
205219b2ee8SDavid du Colombier void
typ_ck(int ft,int at,char * s)206219b2ee8SDavid du Colombier typ_ck(int ft, int at, char *s)
207219b2ee8SDavid du Colombier {
2087dd7cddfSDavid du Colombier 	if ((verbose&32) && ft != at
209219b2ee8SDavid du Colombier 	&& (ft == CHAN || at == CHAN))
2107dd7cddfSDavid du Colombier 	{	char buf[128], tag1[64], tag2[64];
211219b2ee8SDavid du Colombier 		(void) sputtype(tag1, ft);
212219b2ee8SDavid du Colombier 		(void) sputtype(tag2, at);
213219b2ee8SDavid du Colombier 		sprintf(buf, "type-clash in %s, (%s<-> %s)", s, tag1, tag2);
214219b2ee8SDavid du Colombier 		non_fatal("%s", buf);
215219b2ee8SDavid du Colombier 	}
216219b2ee8SDavid du Colombier }
217219b2ee8SDavid du Colombier 
2187dd7cddfSDavid du Colombier static int
a_snd(Queue * q,Lextok * n)219219b2ee8SDavid du Colombier a_snd(Queue *q, Lextok *n)
220219b2ee8SDavid du Colombier {	Lextok *m;
221219b2ee8SDavid du Colombier 	int i = q->qlen*q->nflds;	/* q offset */
222219b2ee8SDavid du Colombier 	int j = 0;			/* q field# */
223219b2ee8SDavid du Colombier 
224219b2ee8SDavid du Colombier 	if (q->nslots > 0 && q->qlen >= q->nslots)
225219b2ee8SDavid du Colombier 		return m_loss;	/* q is full */
226219b2ee8SDavid du Colombier 
227219b2ee8SDavid du Colombier 	if (TstOnly) return 1;
228219b2ee8SDavid du Colombier 
229219b2ee8SDavid du Colombier 	if (n->val) i = sa_snd(q, n);	/* sorted insert */
230219b2ee8SDavid du Colombier 
2317dd7cddfSDavid du Colombier 	q->stepnr[i/q->nflds] = depth;
2327dd7cddfSDavid du Colombier 
233219b2ee8SDavid du Colombier 	for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++)
234219b2ee8SDavid du Colombier 	{	int New = eval(m->lft);
2357dd7cddfSDavid du Colombier 		q->contents[i+j] = cast_val(q->fld_width[j], New, 0);
2367dd7cddfSDavid du Colombier 		if ((verbose&16) && depth >= jumpsteps)
237219b2ee8SDavid du Colombier 			sr_talk(n, New, "Send ", "->", j, q);
238219b2ee8SDavid du Colombier 		typ_ck(q->fld_width[j], Sym_typ(m->lft), "send");
239219b2ee8SDavid du Colombier 	}
2407dd7cddfSDavid du Colombier 	if ((verbose&16) && depth >= jumpsteps)
241219b2ee8SDavid du Colombier 	{	for (i = j; i < q->nflds; i++)
242219b2ee8SDavid du Colombier 			sr_talk(n, 0, "Send ", "->", i, q);
243219b2ee8SDavid du Colombier 		if (j < q->nflds)
2447dd7cddfSDavid du Colombier 			printf("%3d: warning: missing params in send\n",
2457dd7cddfSDavid du Colombier 				depth);
246219b2ee8SDavid du Colombier 		if (m)
2477dd7cddfSDavid du Colombier 			printf("%3d: warning: too many params in send\n",
2487dd7cddfSDavid du Colombier 				depth);
249219b2ee8SDavid du Colombier 	}
250219b2ee8SDavid du Colombier 	q->qlen++;
251219b2ee8SDavid du Colombier 	return 1;
252219b2ee8SDavid du Colombier }
253219b2ee8SDavid du Colombier 
2547dd7cddfSDavid du Colombier static int
a_rcv(Queue * q,Lextok * n,int full)255219b2ee8SDavid du Colombier a_rcv(Queue *q, Lextok *n, int full)
256219b2ee8SDavid du Colombier {	Lextok *m;
2577dd7cddfSDavid du Colombier 	int i=0, oi, j, k;
258219b2ee8SDavid du Colombier 	extern int Rvous;
259219b2ee8SDavid du Colombier 
2607dd7cddfSDavid du Colombier 	if (q->qlen == 0)
2617dd7cddfSDavid du Colombier 		return 0;	/* q is empty */
262219b2ee8SDavid du Colombier try_slot:
263219b2ee8SDavid du Colombier 	/* test executability */
264219b2ee8SDavid du Colombier 	for (m = n->rgt, j=0; m && j < q->nflds; m = m->rgt, j++)
2657dd7cddfSDavid du Colombier 		if ((m->lft->ntyp == CONST
266219b2ee8SDavid du Colombier 		   && q->contents[i*q->nflds+j] != m->lft->val)
2677dd7cddfSDavid du Colombier 		||  (m->lft->ntyp == EVAL
2687dd7cddfSDavid du Colombier 		   && q->contents[i*q->nflds+j] != eval(m->lft->lft)))
269219b2ee8SDavid du Colombier 		{	if (n->val == 0		/* fifo recv */
2707dd7cddfSDavid du Colombier 			||  n->val == 2		/* fifo poll */
271219b2ee8SDavid du Colombier 			|| ++i >= q->qlen)	/* last slot */
272219b2ee8SDavid du Colombier 				return 0;	/* no match  */
273219b2ee8SDavid du Colombier 			goto try_slot;
274219b2ee8SDavid du Colombier 		}
275219b2ee8SDavid du Colombier 	if (TstOnly) return 1;
276219b2ee8SDavid du Colombier 
277219b2ee8SDavid du Colombier 	if (verbose&8)
278219b2ee8SDavid du Colombier 	{	if (j < q->nflds)
2797dd7cddfSDavid du Colombier 			printf("%3d: warning: missing params in next recv\n",
2807dd7cddfSDavid du Colombier 				depth);
281219b2ee8SDavid du Colombier 		else if (m)
2827dd7cddfSDavid du Colombier 			printf("%3d: warning: too many params in next recv\n",
2837dd7cddfSDavid du Colombier 				depth);
284219b2ee8SDavid du Colombier 	}
285219b2ee8SDavid du Colombier 
286219b2ee8SDavid du Colombier 	/* set the fields */
2877dd7cddfSDavid du Colombier 	if (Rvous)
2887dd7cddfSDavid du Colombier 	{	n_rem = n;
2897dd7cddfSDavid du Colombier 		q_rem = q;
2907dd7cddfSDavid du Colombier 	}
291219b2ee8SDavid du Colombier 
2927dd7cddfSDavid du Colombier 	oi = q->stepnr[i];
2937dd7cddfSDavid du Colombier 	for (m = n->rgt, j = 0; m && j < q->nflds; m = m->rgt, j++)
2947dd7cddfSDavid du Colombier 	{	if (columns && !full)	/* was columns == 1 */
2957dd7cddfSDavid du Colombier 			continue;
2967dd7cddfSDavid du Colombier 		if ((verbose&8) && !Rvous && depth >= jumpsteps)
2977dd7cddfSDavid du Colombier 		{	sr_talk(n, q->contents[i*q->nflds+j],
2987dd7cddfSDavid du Colombier 			(full && n->val < 2)?"Recv ":"[Recv] ", "<-", j, q);
2997dd7cddfSDavid du Colombier 		}
3007dd7cddfSDavid du Colombier 		if (!full)
3017dd7cddfSDavid du Colombier 			continue;	/* test */
3027dd7cddfSDavid du Colombier 		if (m && m->lft->ntyp != CONST && m->lft->ntyp != EVAL)
303219b2ee8SDavid du Colombier 		{	(void) setval(m->lft, q->contents[i*q->nflds+j]);
304219b2ee8SDavid du Colombier 			typ_ck(q->fld_width[j], Sym_typ(m->lft), "recv");
305219b2ee8SDavid du Colombier 		}
3067dd7cddfSDavid du Colombier 		if (n->val < 2)		/* not a poll */
3077dd7cddfSDavid du Colombier 		for (k = i; k < q->qlen-1; k++)
3087dd7cddfSDavid du Colombier 		{	q->contents[k*q->nflds+j] =
309219b2ee8SDavid du Colombier 			  q->contents[(k+1)*q->nflds+j];
3107dd7cddfSDavid du Colombier 			if (j == 0)
3117dd7cddfSDavid du Colombier 			  q->stepnr[k] = q->stepnr[k+1];
312219b2ee8SDavid du Colombier 		}
3137dd7cddfSDavid du Colombier 	}
3147dd7cddfSDavid du Colombier 
3157dd7cddfSDavid du Colombier 	if ((!columns || full)
3167dd7cddfSDavid du Colombier 	&& (verbose&8) && !Rvous && depth >= jumpsteps)
3177dd7cddfSDavid du Colombier 	for (i = j; i < q->nflds; i++)
3187dd7cddfSDavid du Colombier 	{	sr_talk(n, 0,
3197dd7cddfSDavid du Colombier 		(full && n->val < 2)?"Recv ":"[Recv] ", "<-", i, q);
3207dd7cddfSDavid du Colombier 	}
3217dd7cddfSDavid du Colombier 	if (columns == 2 && full && !Rvous && depth >= jumpsteps)
3227dd7cddfSDavid du Colombier 		putarrow(oi, depth);
3237dd7cddfSDavid du Colombier 
3247dd7cddfSDavid du Colombier 	if (full && n->val < 2)
3257dd7cddfSDavid du Colombier 		q->qlen--;
326219b2ee8SDavid du Colombier 	return 1;
327219b2ee8SDavid du Colombier }
328219b2ee8SDavid du Colombier 
3297dd7cddfSDavid du Colombier static int
s_snd(Queue * q,Lextok * n)330219b2ee8SDavid du Colombier s_snd(Queue *q, Lextok *n)
331219b2ee8SDavid du Colombier {	Lextok *m;
332219b2ee8SDavid du Colombier 	RunList *rX, *sX = X;	/* rX=recvr, sX=sendr */
333219b2ee8SDavid du Colombier 	int i, j = 0;	/* q field# */
334219b2ee8SDavid du Colombier 
335219b2ee8SDavid du Colombier 	for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++)
3367dd7cddfSDavid du Colombier 	{	q->contents[j] = cast_val(q->fld_width[j], eval(m->lft), 0);
337219b2ee8SDavid du Colombier 		typ_ck(q->fld_width[j], Sym_typ(m->lft), "rv-send");
338219b2ee8SDavid du Colombier 	}
339219b2ee8SDavid du Colombier 	q->qlen = 1;
340219b2ee8SDavid du Colombier 	if (!complete_rendez())
341219b2ee8SDavid du Colombier 	{	q->qlen = 0;
342219b2ee8SDavid du Colombier 		return 0;
343219b2ee8SDavid du Colombier 	}
3447dd7cddfSDavid du Colombier 	if (TstOnly)
3457dd7cddfSDavid du Colombier 	{	q->qlen = 0;
3467dd7cddfSDavid du Colombier 		return 1;
3477dd7cddfSDavid du Colombier 	}
3487dd7cddfSDavid du Colombier 	q->stepnr[0] = depth;
3497dd7cddfSDavid du Colombier 	if ((verbose&16) && depth >= jumpsteps)
350219b2ee8SDavid du Colombier 	{	m = n->rgt;
351219b2ee8SDavid du Colombier 		rX = X; X = sX;
352219b2ee8SDavid du Colombier 		for (j = 0; m && j < q->nflds; m = m->rgt, j++)
353219b2ee8SDavid du Colombier 			sr_talk(n, eval(m->lft), "Sent ", "->", j, q);
354219b2ee8SDavid du Colombier 		for (i = j; i < q->nflds; i++)
355219b2ee8SDavid du Colombier 			sr_talk(n, 0, "Sent ", "->", i, q);
356219b2ee8SDavid du Colombier 		if (j < q->nflds)
3577dd7cddfSDavid du Colombier 			  printf("%3d: warning: missing params in rv-send\n",
3587dd7cddfSDavid du Colombier 				depth);
359219b2ee8SDavid du Colombier 		else if (m)
3607dd7cddfSDavid du Colombier 			  printf("%3d: warning: too many params in rv-send\n",
3617dd7cddfSDavid du Colombier 				depth);
3627dd7cddfSDavid du Colombier 		X = rX;	/* restore receiver's context */
363219b2ee8SDavid du Colombier 		if (!s_trail)
3647dd7cddfSDavid du Colombier 		{	if (!n_rem || !q_rem)
3657dd7cddfSDavid du Colombier 				fatal("cannot happen, s_snd", (char *) 0);
3667dd7cddfSDavid du Colombier 			m = n_rem->rgt;
367219b2ee8SDavid du Colombier 			for (j = 0; m && j < q->nflds; m = m->rgt, j++)
3687dd7cddfSDavid du Colombier 			{	if (m->lft->ntyp != NAME
3697dd7cddfSDavid du Colombier 				||  strcmp(m->lft->sym->name, "_") != 0)
3707dd7cddfSDavid du Colombier 					i = eval(m->lft);
3717dd7cddfSDavid du Colombier 				else	i = 0;
372312a1df1SDavid du Colombier 
373312a1df1SDavid du Colombier 				if (verbose&8)
3747dd7cddfSDavid du Colombier 				sr_talk(n_rem,i,"Recv ","<-",j,q_rem);
3757dd7cddfSDavid du Colombier 			}
376312a1df1SDavid du Colombier 			if (verbose&8)
3777dd7cddfSDavid du Colombier 			for (i = j; i < q->nflds; i++)
3787dd7cddfSDavid du Colombier 				sr_talk(n_rem, 0, "Recv ", "<-", j, q_rem);
3797dd7cddfSDavid du Colombier 			if (columns == 2)
3807dd7cddfSDavid du Colombier 				putarrow(depth, depth);
3817dd7cddfSDavid du Colombier 		}
3827dd7cddfSDavid du Colombier 		n_rem = (Lextok *) 0;
3837dd7cddfSDavid du Colombier 		q_rem = (Queue *) 0;
384219b2ee8SDavid du Colombier 	}
385219b2ee8SDavid du Colombier 	return 1;
386219b2ee8SDavid du Colombier }
387219b2ee8SDavid du Colombier 
388*00d97012SDavid du Colombier static void
channm(Lextok * n)3897dd7cddfSDavid du Colombier channm(Lextok *n)
390312a1df1SDavid du Colombier {	char lbuf[512];
3917dd7cddfSDavid du Colombier 
3927dd7cddfSDavid du Colombier 	if (n->sym->type == CHAN)
3937dd7cddfSDavid du Colombier 		strcat(Buf, n->sym->name);
3947dd7cddfSDavid du Colombier 	else if (n->sym->type == NAME)
3957dd7cddfSDavid du Colombier 		strcat(Buf, lookup(n->sym->name)->name);
3967dd7cddfSDavid du Colombier 	else if (n->sym->type == STRUCT)
3977dd7cddfSDavid du Colombier 	{	Symbol *r = n->sym;
3987dd7cddfSDavid du Colombier 		if (r->context)
399*00d97012SDavid du Colombier 		{	r = findloc(r);
400*00d97012SDavid du Colombier 			if (!r)
401*00d97012SDavid du Colombier 			{	strcat(Buf, "*?*");
402*00d97012SDavid du Colombier 				return;
403*00d97012SDavid du Colombier 		}	}
4047dd7cddfSDavid du Colombier 		ini_struct(r);
4057dd7cddfSDavid du Colombier 		printf("%s", r->name);
406312a1df1SDavid du Colombier 		strcpy(lbuf, "");
4077dd7cddfSDavid du Colombier 		struct_name(n->lft, r, 1, lbuf);
4087dd7cddfSDavid du Colombier 		strcat(Buf, lbuf);
4097dd7cddfSDavid du Colombier 	} else
4107dd7cddfSDavid du Colombier 		strcat(Buf, "-");
4117dd7cddfSDavid du Colombier 	if (n->lft->lft)
4127dd7cddfSDavid du Colombier 	{	sprintf(lbuf, "[%d]", eval(n->lft->lft));
4137dd7cddfSDavid du Colombier 		strcat(Buf, lbuf);
4147dd7cddfSDavid du Colombier 	}
4157dd7cddfSDavid du Colombier }
4167dd7cddfSDavid du Colombier 
4177dd7cddfSDavid du Colombier static void
difcolumns(Lextok * n,char * tr,int v,int j,Queue * q)4187dd7cddfSDavid du Colombier difcolumns(Lextok *n, char *tr, int v, int j, Queue *q)
419312a1df1SDavid du Colombier {	extern int pno;
4207dd7cddfSDavid du Colombier 
4217dd7cddfSDavid du Colombier 	if (j == 0)
4227dd7cddfSDavid du Colombier 	{	Buf[0] = '\0';
4237dd7cddfSDavid du Colombier 		channm(n);
4247dd7cddfSDavid du Colombier 		strcat(Buf, (strncmp(tr, "Sen", 3))?"?":"!");
4257dd7cddfSDavid du Colombier 	} else
4267dd7cddfSDavid du Colombier 		strcat(Buf, ",");
4277dd7cddfSDavid du Colombier 	if (tr[0] == '[') strcat(Buf, "[");
4287dd7cddfSDavid du Colombier 	sr_buf(v, q->fld_width[j] == MTYPE);
4297dd7cddfSDavid du Colombier 	if (j == q->nflds - 1)
4307dd7cddfSDavid du Colombier 	{	int cnr;
4317dd7cddfSDavid du Colombier 		if (s_trail) cnr = pno; else cnr = X?X->pid - Have_claim:0;
4327dd7cddfSDavid du Colombier 		if (tr[0] == '[') strcat(Buf, "]");
4337dd7cddfSDavid du Colombier 		pstext(cnr, Buf);
4347dd7cddfSDavid du Colombier 	}
4357dd7cddfSDavid du Colombier }
4367dd7cddfSDavid du Colombier 
4377dd7cddfSDavid du Colombier static void
docolumns(Lextok * n,char * tr,int v,int j,Queue * q)4387dd7cddfSDavid du Colombier docolumns(Lextok *n, char *tr, int v, int j, Queue *q)
4397dd7cddfSDavid du Colombier {	int i;
4407dd7cddfSDavid du Colombier 
4417dd7cddfSDavid du Colombier 	if (firstrow)
4427dd7cddfSDavid du Colombier 	{	printf("q\\p");
4437dd7cddfSDavid du Colombier 		for (i = 0; i < nproc-nstop - Have_claim; i++)
4447dd7cddfSDavid du Colombier 			printf(" %3d", i);
4457dd7cddfSDavid du Colombier 		printf("\n");
4467dd7cddfSDavid du Colombier 		firstrow = 0;
4477dd7cddfSDavid du Colombier 	}
4487dd7cddfSDavid du Colombier 	if (j == 0)
4497dd7cddfSDavid du Colombier 	{	printf("%3d", q->qid);
4507dd7cddfSDavid du Colombier 		if (X)
4517dd7cddfSDavid du Colombier 		for (i = 0; i < X->pid - Have_claim; i++)
4527dd7cddfSDavid du Colombier 			printf("   .");
4537dd7cddfSDavid du Colombier 		printf("   ");
4547dd7cddfSDavid du Colombier 		Buf[0] = '\0';
4557dd7cddfSDavid du Colombier 		channm(n);
4567dd7cddfSDavid du Colombier 		printf("%s%c", Buf, (strncmp(tr, "Sen", 3))?'?':'!');
4577dd7cddfSDavid du Colombier 	} else
4587dd7cddfSDavid du Colombier 		printf(",");
4597dd7cddfSDavid du Colombier 	if (tr[0] == '[') printf("[");
4607dd7cddfSDavid du Colombier 	sr_mesg(stdout, v, q->fld_width[j] == MTYPE);
4617dd7cddfSDavid du Colombier 	if (j == q->nflds - 1)
4627dd7cddfSDavid du Colombier 	{	if (tr[0] == '[') printf("]");
4637dd7cddfSDavid du Colombier 		printf("\n");
4647dd7cddfSDavid du Colombier 	}
4657dd7cddfSDavid du Colombier }
4667dd7cddfSDavid du Colombier 
4677dd7cddfSDavid du Colombier typedef struct QH {
4687dd7cddfSDavid du Colombier 	int	n;
4697dd7cddfSDavid du Colombier 	struct	QH *nxt;
4707dd7cddfSDavid du Colombier } QH;
471*00d97012SDavid du Colombier static QH *qh;
4727dd7cddfSDavid du Colombier 
4737dd7cddfSDavid du Colombier void
qhide(int q)4747dd7cddfSDavid du Colombier qhide(int q)
4757dd7cddfSDavid du Colombier {	QH *p = (QH *) emalloc(sizeof(QH));
4767dd7cddfSDavid du Colombier 	p->n = q;
4777dd7cddfSDavid du Colombier 	p->nxt = qh;
4787dd7cddfSDavid du Colombier 	qh = p;
4797dd7cddfSDavid du Colombier }
4807dd7cddfSDavid du Colombier 
4817dd7cddfSDavid du Colombier int
qishidden(int q)4827dd7cddfSDavid du Colombier qishidden(int q)
4837dd7cddfSDavid du Colombier {	QH *p;
4847dd7cddfSDavid du Colombier 	for (p = qh; p; p = p->nxt)
4857dd7cddfSDavid du Colombier 		if (p->n == q)
4867dd7cddfSDavid du Colombier 			return 1;
4877dd7cddfSDavid du Colombier 	return 0;
4887dd7cddfSDavid du Colombier }
4897dd7cddfSDavid du Colombier 
4907dd7cddfSDavid du Colombier static void
sr_talk(Lextok * n,int v,char * tr,char * a,int j,Queue * q)491219b2ee8SDavid du Colombier sr_talk(Lextok *n, int v, char *tr, char *a, int j, Queue *q)
492*00d97012SDavid du Colombier {	char s[128];
4937dd7cddfSDavid du Colombier 
4947dd7cddfSDavid du Colombier 	if (qishidden(eval(n->lft)))
4957dd7cddfSDavid du Colombier 		return;
4967dd7cddfSDavid du Colombier 
4977dd7cddfSDavid du Colombier 	if (columns)
4987dd7cddfSDavid du Colombier 	{	if (columns == 2)
4997dd7cddfSDavid du Colombier 			difcolumns(n, tr, v, j, q);
5007dd7cddfSDavid du Colombier 		else
5017dd7cddfSDavid du Colombier 			docolumns(n, tr, v, j, q);
5027dd7cddfSDavid du Colombier 		return;
5037dd7cddfSDavid du Colombier 	}
504219b2ee8SDavid du Colombier 	if (xspin)
5057dd7cddfSDavid du Colombier 	{	if ((verbose&4) && tr[0] != '[')
506219b2ee8SDavid du Colombier 		sprintf(s, "(state -)\t[values: %d",
507219b2ee8SDavid du Colombier 			eval(n->lft));
508219b2ee8SDavid du Colombier 		else
509219b2ee8SDavid du Colombier 		sprintf(s, "(state -)\t[%d", eval(n->lft));
510219b2ee8SDavid du Colombier 		if (strncmp(tr, "Sen", 3) == 0)
511219b2ee8SDavid du Colombier 			strcat(s, "!");
512219b2ee8SDavid du Colombier 		else
513219b2ee8SDavid du Colombier 			strcat(s, "?");
514219b2ee8SDavid du Colombier 	} else
515219b2ee8SDavid du Colombier 	{	strcpy(s, tr);
516219b2ee8SDavid du Colombier 	}
5177dd7cddfSDavid du Colombier 
518219b2ee8SDavid du Colombier 	if (j == 0)
519*00d97012SDavid du Colombier 	{	char snm[128];
520*00d97012SDavid du Colombier 		whoruns(1);
521*00d97012SDavid du Colombier 		{	char *ptr = n->fn->name;
522*00d97012SDavid du Colombier 			char *qtr = snm;
523*00d97012SDavid du Colombier 			while (*ptr != '\0')
524*00d97012SDavid du Colombier 			{	if (*ptr != '\"')
525*00d97012SDavid du Colombier 				{	*qtr++ = *ptr;
526*00d97012SDavid du Colombier 				}
527*00d97012SDavid du Colombier 				ptr++;
528*00d97012SDavid du Colombier 			}
529*00d97012SDavid du Colombier 			*qtr = '\0';
530*00d97012SDavid du Colombier 			printf("%s:%d %s",
531*00d97012SDavid du Colombier 				snm, n->ln, s);
532*00d97012SDavid du Colombier 		}
533219b2ee8SDavid du Colombier 	} else
534219b2ee8SDavid du Colombier 		printf(",");
5357dd7cddfSDavid du Colombier 	sr_mesg(stdout, v, q->fld_width[j] == MTYPE);
536219b2ee8SDavid du Colombier 
537219b2ee8SDavid du Colombier 	if (j == q->nflds - 1)
538219b2ee8SDavid du Colombier 	{	if (xspin)
539219b2ee8SDavid du Colombier 		{	printf("]\n");
540219b2ee8SDavid du Colombier 			if (!(verbose&4)) printf("\n");
541219b2ee8SDavid du Colombier 			return;
542219b2ee8SDavid du Colombier 		}
543219b2ee8SDavid du Colombier 		printf("\t%s queue %d (", a, eval(n->lft));
5447dd7cddfSDavid du Colombier 		Buf[0] = '\0';
5457dd7cddfSDavid du Colombier 		channm(n);
5467dd7cddfSDavid du Colombier 		printf("%s)\n", Buf);
547219b2ee8SDavid du Colombier 	}
548219b2ee8SDavid du Colombier 	fflush(stdout);
549219b2ee8SDavid du Colombier }
550219b2ee8SDavid du Colombier 
551219b2ee8SDavid du Colombier void
sr_buf(int v,int j)5527dd7cddfSDavid du Colombier sr_buf(int v, int j)
5537dd7cddfSDavid du Colombier {	int cnt = 1; Lextok *n;
554f3793cddSDavid du Colombier 	char lbuf[512];
555219b2ee8SDavid du Colombier 
556219b2ee8SDavid du Colombier 	for (n = Mtype; n && j; n = n->rgt, cnt++)
557219b2ee8SDavid du Colombier 		if (cnt == v)
558f3793cddSDavid du Colombier 		{	if(strlen(n->lft->sym->name) >= sizeof(lbuf))
559f3793cddSDavid du Colombier 			{	non_fatal("mtype name %s too long", n->lft->sym->name);
560f3793cddSDavid du Colombier 				break;
561f3793cddSDavid du Colombier 			}
562f3793cddSDavid du Colombier 			sprintf(lbuf, "%s", n->lft->sym->name);
5637dd7cddfSDavid du Colombier 			strcat(Buf, lbuf);
564219b2ee8SDavid du Colombier 			return;
565219b2ee8SDavid du Colombier 		}
5667dd7cddfSDavid du Colombier 	sprintf(lbuf, "%d", v);
5677dd7cddfSDavid du Colombier 	strcat(Buf, lbuf);
5687dd7cddfSDavid du Colombier }
5697dd7cddfSDavid du Colombier 
5707dd7cddfSDavid du Colombier void
sr_mesg(FILE * fd,int v,int j)5717dd7cddfSDavid du Colombier sr_mesg(FILE *fd, int v, int j)
5727dd7cddfSDavid du Colombier {	Buf[0] ='\0';
5737dd7cddfSDavid du Colombier 	sr_buf(v, j);
5747dd7cddfSDavid du Colombier 	fprintf(fd, Buf);
575219b2ee8SDavid du Colombier }
576219b2ee8SDavid du Colombier 
577219b2ee8SDavid du Colombier void
doq(Symbol * s,int n,RunList * r)578219b2ee8SDavid du Colombier doq(Symbol *s, int n, RunList *r)
579219b2ee8SDavid du Colombier {	Queue *q;
580219b2ee8SDavid du Colombier 	int j, k;
581219b2ee8SDavid du Colombier 
582219b2ee8SDavid du Colombier 	if (!s->val)	/* uninitialized queue */
583219b2ee8SDavid du Colombier 		return;
584219b2ee8SDavid du Colombier 	for (q = qtab; q; q = q->nxt)
585219b2ee8SDavid du Colombier 	if (q->qid == s->val[n])
586219b2ee8SDavid du Colombier 	{	if (xspin > 0
587219b2ee8SDavid du Colombier 		&& (verbose&4)
588219b2ee8SDavid du Colombier 		&& q->setat < depth)
589219b2ee8SDavid du Colombier 			continue;
590219b2ee8SDavid du Colombier 		if (q->nslots == 0)
591219b2ee8SDavid du Colombier 			continue; /* rv q always empty */
592*00d97012SDavid du Colombier #if 0
593*00d97012SDavid du Colombier 		if (q->qlen == 0)	/* new 7/10 -- dont show if queue is empty */
594*00d97012SDavid du Colombier 		{	continue;
595*00d97012SDavid du Colombier 		}
596*00d97012SDavid du Colombier #endif
597219b2ee8SDavid du Colombier 		printf("\t\tqueue %d (", q->qid);
598219b2ee8SDavid du Colombier 		if (r)
5997dd7cddfSDavid du Colombier 		printf("%s(%d):", r->n->name, r->pid - Have_claim);
600*00d97012SDavid du Colombier 		if (s->nel > 1 || s->isarray)
601219b2ee8SDavid du Colombier 		  printf("%s[%d]): ", s->name, n);
602219b2ee8SDavid du Colombier 		else
603219b2ee8SDavid du Colombier 		  printf("%s): ", s->name);
604219b2ee8SDavid du Colombier 		for (k = 0; k < q->qlen; k++)
605219b2ee8SDavid du Colombier 		{	printf("[");
606219b2ee8SDavid du Colombier 			for (j = 0; j < q->nflds; j++)
607219b2ee8SDavid du Colombier 			{	if (j > 0) printf(",");
6087dd7cddfSDavid du Colombier 				sr_mesg(stdout, q->contents[k*q->nflds+j],
609219b2ee8SDavid du Colombier 					q->fld_width[j] == MTYPE);
610219b2ee8SDavid du Colombier 			}
611219b2ee8SDavid du Colombier 			printf("]");
612219b2ee8SDavid du Colombier 		}
613219b2ee8SDavid du Colombier 		printf("\n");
614219b2ee8SDavid du Colombier 		break;
615219b2ee8SDavid du Colombier 	}
616219b2ee8SDavid du Colombier }
6177dd7cddfSDavid du Colombier 
6187dd7cddfSDavid du Colombier void
nochan_manip(Lextok * p,Lextok * n,int d)6197dd7cddfSDavid du Colombier nochan_manip(Lextok *p, Lextok *n, int d)
6207dd7cddfSDavid du Colombier {	int e = 1;
6217dd7cddfSDavid du Colombier 
6227dd7cddfSDavid du Colombier 	if (d == 0 && p->sym && p->sym->type == CHAN)
623312a1df1SDavid du Colombier 	{	setaccess(p->sym, ZS, 0, 'L');
624312a1df1SDavid du Colombier 
625312a1df1SDavid du Colombier 		if (n && n->ntyp == CONST)
626312a1df1SDavid du Colombier 			fatal("invalid asgn to chan", (char *) 0);
627312a1df1SDavid du Colombier 
628312a1df1SDavid du Colombier 		if (n && n->sym && n->sym->type == CHAN)
629312a1df1SDavid du Colombier 		{	setaccess(n->sym, ZS, 0, 'V');
630312a1df1SDavid du Colombier 			return;
631312a1df1SDavid du Colombier 		}
632312a1df1SDavid du Colombier 	}
6337dd7cddfSDavid du Colombier 
634*00d97012SDavid du Colombier 	/* ok on the rhs of an assignment: */
635*00d97012SDavid du Colombier 	if (!n || n->ntyp == LEN || n->ntyp == RUN
636*00d97012SDavid du Colombier 	||  n->ntyp == FULL  || n->ntyp == NFULL
637*00d97012SDavid du Colombier 	||  n->ntyp == EMPTY || n->ntyp == NEMPTY)
6387dd7cddfSDavid du Colombier 		return;
6397dd7cddfSDavid du Colombier 
6407dd7cddfSDavid du Colombier 	if (n->sym && n->sym->type == CHAN)
6417dd7cddfSDavid du Colombier 	{	if (d == 1)
6427dd7cddfSDavid du Colombier 			fatal("invalid use of chan name", (char *) 0);
6437dd7cddfSDavid du Colombier 		else
6447dd7cddfSDavid du Colombier 			setaccess(n->sym, ZS, 0, 'V');
6457dd7cddfSDavid du Colombier 	}
6467dd7cddfSDavid du Colombier 
6477dd7cddfSDavid du Colombier 	if (n->ntyp == NAME
6487dd7cddfSDavid du Colombier 	||  n->ntyp == '.')
6497dd7cddfSDavid du Colombier 		e = 0;	/* array index or struct element */
6507dd7cddfSDavid du Colombier 
6517dd7cddfSDavid du Colombier 	nochan_manip(p, n->lft, e);
6527dd7cddfSDavid du Colombier 	nochan_manip(p, n->rgt, 1);
6537dd7cddfSDavid du Colombier }
654f3793cddSDavid du Colombier 
655*00d97012SDavid du Colombier typedef struct BaseName {
656*00d97012SDavid du Colombier 	char *str;
657*00d97012SDavid du Colombier 	int cnt;
658*00d97012SDavid du Colombier 	struct BaseName *nxt;
659*00d97012SDavid du Colombier } BaseName;
660*00d97012SDavid du Colombier BaseName *bsn;
661*00d97012SDavid du Colombier 
662*00d97012SDavid du Colombier void
newbasename(char * s)663*00d97012SDavid du Colombier newbasename(char *s)
664*00d97012SDavid du Colombier {	BaseName *b;
665*00d97012SDavid du Colombier 
666*00d97012SDavid du Colombier /*	printf("+++++++++%s\n", s);	*/
667*00d97012SDavid du Colombier 	for (b = bsn; b; b = b->nxt)
668*00d97012SDavid du Colombier 		if (strcmp(b->str, s) == 0)
669*00d97012SDavid du Colombier 		{	b->cnt++;
670*00d97012SDavid du Colombier 			return;
671*00d97012SDavid du Colombier 		}
672*00d97012SDavid du Colombier 	b = (BaseName *) emalloc(sizeof(BaseName));
673*00d97012SDavid du Colombier 	b->str = emalloc(strlen(s)+1);
674*00d97012SDavid du Colombier 	b->cnt = 1;
675*00d97012SDavid du Colombier 	strcpy(b->str, s);
676*00d97012SDavid du Colombier 	b->nxt = bsn;
677*00d97012SDavid du Colombier 	bsn = b;
678*00d97012SDavid du Colombier }
679*00d97012SDavid du Colombier 
680*00d97012SDavid du Colombier void
delbasename(char * s)681*00d97012SDavid du Colombier delbasename(char *s)
682*00d97012SDavid du Colombier {	BaseName *b, *prv = (BaseName *) 0;
683*00d97012SDavid du Colombier 
684*00d97012SDavid du Colombier 	for (b = bsn; b; prv = b, b = b->nxt)
685*00d97012SDavid du Colombier 	{	if (strcmp(b->str, s) == 0)
686*00d97012SDavid du Colombier 		{	b->cnt--;
687*00d97012SDavid du Colombier 			if (b->cnt == 0)
688*00d97012SDavid du Colombier 			{	if (prv)
689*00d97012SDavid du Colombier 				{	prv->nxt = b->nxt;
690*00d97012SDavid du Colombier 				} else
691*00d97012SDavid du Colombier 				{	bsn = b->nxt;
692*00d97012SDavid du Colombier 			}	}
693*00d97012SDavid du Colombier /*	printf("---------%s\n", s);	*/
694*00d97012SDavid du Colombier 			break;
695*00d97012SDavid du Colombier 	}	}
696*00d97012SDavid du Colombier }
697*00d97012SDavid du Colombier 
698*00d97012SDavid du Colombier void
checkindex(char * s,char * t)699*00d97012SDavid du Colombier checkindex(char *s, char *t)
700*00d97012SDavid du Colombier {	BaseName *b;
701*00d97012SDavid du Colombier 
702*00d97012SDavid du Colombier /*	printf("xxx Check %s (%s)\n", s, t);	*/
703*00d97012SDavid du Colombier 	for (b = bsn; b; b = b->nxt)
704*00d97012SDavid du Colombier 	{
705*00d97012SDavid du Colombier /*		printf("	%s\n", b->str);	*/
706*00d97012SDavid du Colombier 		if (strcmp(b->str, s) == 0)
707*00d97012SDavid du Colombier 		{	non_fatal("do not index an array with itself (%s)", t);
708*00d97012SDavid du Colombier 			break;
709*00d97012SDavid du Colombier 	}	}
710*00d97012SDavid du Colombier }
711*00d97012SDavid du Colombier 
712*00d97012SDavid du Colombier void
scan_tree(Lextok * t,char * mn,char * mx)713*00d97012SDavid du Colombier scan_tree(Lextok *t, char *mn, char *mx)
714*00d97012SDavid du Colombier {	char sv[512];
715*00d97012SDavid du Colombier 	char tmp[32];
716*00d97012SDavid du Colombier 	int oln = lineno;
717*00d97012SDavid du Colombier 
718*00d97012SDavid du Colombier 	if (!t) return;
719*00d97012SDavid du Colombier 
720*00d97012SDavid du Colombier 	lineno = t->ln;
721*00d97012SDavid du Colombier 
722*00d97012SDavid du Colombier 	if (t->ntyp == NAME)
723*00d97012SDavid du Colombier 	{	strcat(mn, t->sym->name);
724*00d97012SDavid du Colombier 		strcat(mx, t->sym->name);
725*00d97012SDavid du Colombier 		if (t->lft)		/* array index */
726*00d97012SDavid du Colombier 		{	strcat(mn, "[]");
727*00d97012SDavid du Colombier 			newbasename(mn);
728*00d97012SDavid du Colombier 				strcpy(sv, mn);		/* save */
729*00d97012SDavid du Colombier 				strcpy(mn, "");		/* clear */
730*00d97012SDavid du Colombier 				strcat(mx, "[");
731*00d97012SDavid du Colombier 				scan_tree(t->lft, mn, mx);	/* index */
732*00d97012SDavid du Colombier 				strcat(mx, "]");
733*00d97012SDavid du Colombier 				checkindex(mn, mx);	/* match against basenames */
734*00d97012SDavid du Colombier 				strcpy(mn, sv);		/* restore */
735*00d97012SDavid du Colombier 			delbasename(mn);
736*00d97012SDavid du Colombier 		}
737*00d97012SDavid du Colombier 		if (t->rgt)	/* structure element */
738*00d97012SDavid du Colombier 		{	scan_tree(t->rgt, mn, mx);
739*00d97012SDavid du Colombier 		}
740*00d97012SDavid du Colombier 	} else if (t->ntyp == CONST)
741*00d97012SDavid du Colombier 	{	strcat(mn, "1"); /* really: t->val */
742*00d97012SDavid du Colombier 		sprintf(tmp, "%d", t->val);
743*00d97012SDavid du Colombier 		strcat(mx, tmp);
744*00d97012SDavid du Colombier 	} else if (t->ntyp == '.')
745*00d97012SDavid du Colombier 	{	strcat(mn, ".");
746*00d97012SDavid du Colombier 		strcat(mx, ".");
747*00d97012SDavid du Colombier 		scan_tree(t->lft, mn, mx);
748*00d97012SDavid du Colombier 	} else
749*00d97012SDavid du Colombier 	{	strcat(mn, "??");
750*00d97012SDavid du Colombier 		strcat(mx, "??");
751*00d97012SDavid du Colombier 	}
752*00d97012SDavid du Colombier 	lineno = oln;
753*00d97012SDavid du Colombier }
754*00d97012SDavid du Colombier 
755*00d97012SDavid du Colombier void
no_nested_array_refs(Lextok * n)756*00d97012SDavid du Colombier no_nested_array_refs(Lextok *n)	/* a [ a[1] ] with a[1] = 1, causes trouble in pan.b */
757*00d97012SDavid du Colombier {	char mn[512];
758*00d97012SDavid du Colombier 	char mx[512];
759*00d97012SDavid du Colombier 
760*00d97012SDavid du Colombier /*	printf("==================================ZAP\n");	*/
761*00d97012SDavid du Colombier 	bsn = (BaseName *) 0;	/* start new list */
762*00d97012SDavid du Colombier 	strcpy(mn, "");
763*00d97012SDavid du Colombier 	strcpy(mx, "");
764*00d97012SDavid du Colombier 
765*00d97012SDavid du Colombier 	scan_tree(n, mn, mx);
766*00d97012SDavid du Colombier /*	printf("==> %s\n", mn);	*/
767*00d97012SDavid du Colombier }
768*00d97012SDavid du Colombier 
769f3793cddSDavid du Colombier void
no_internals(Lextok * n)770f3793cddSDavid du Colombier no_internals(Lextok *n)
771f3793cddSDavid du Colombier {	char *sp;
772f3793cddSDavid du Colombier 
773f3793cddSDavid du Colombier 	if (!n->sym
774f3793cddSDavid du Colombier 	||  !n->sym->name)
775f3793cddSDavid du Colombier 		return;
776f3793cddSDavid du Colombier 
777f3793cddSDavid du Colombier 	sp = n->sym->name;
778f3793cddSDavid du Colombier 
779f3793cddSDavid du Colombier 	if ((strlen(sp) == strlen("_nr_pr") && strcmp(sp, "_nr_pr") == 0)
780f3793cddSDavid du Colombier 	||  (strlen(sp) == strlen("_p") && strcmp(sp, "_p") == 0))
781f3793cddSDavid du Colombier 	{	fatal("attempt to assign value to system variable %s", sp);
782f3793cddSDavid du Colombier 	}
783*00d97012SDavid du Colombier 
784*00d97012SDavid du Colombier 	no_nested_array_refs(n);
785f3793cddSDavid du Colombier }
786