xref: /plan9/sys/src/cmd/spin/main.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1219b2ee8SDavid du Colombier /***** spin: main.c *****/
2219b2ee8SDavid du Colombier 
3*7dd7cddfSDavid du Colombier /* Copyright (c) 1991-2000 by Lucent Technologies - Bell Laboratories     */
4*7dd7cddfSDavid du Colombier /* All Rights Reserved.  This software is for educational purposes only.  */
5219b2ee8SDavid du Colombier /* Permission is given to distribute this code provided that this intro-  */
6219b2ee8SDavid du Colombier /* ductory message is not removed and no monies are exchanged.            */
7219b2ee8SDavid du Colombier /* No guarantee is expressed or implied by the distribution of this code. */
8219b2ee8SDavid du Colombier /* Software written by Gerard J. Holzmann as part of the book:            */
9219b2ee8SDavid du Colombier /* `Design and Validation of Computer Protocols,' ISBN 0-13-539925-4,     */
10219b2ee8SDavid du Colombier /* Prentice Hall, Englewood Cliffs, NJ, 07632.                            */
11*7dd7cddfSDavid du Colombier /* Send bug-reports and/or questions to: gerard@research.bell-labs.com    */
12219b2ee8SDavid du Colombier 
13219b2ee8SDavid du Colombier #include <stdlib.h>
14*7dd7cddfSDavid du Colombier #include "spin.h"
15*7dd7cddfSDavid du Colombier #include "version.h"
16*7dd7cddfSDavid du Colombier #include <signal.h>
17*7dd7cddfSDavid du Colombier /* #include <malloc.h> */
18*7dd7cddfSDavid du Colombier #include <time.h>
19*7dd7cddfSDavid du Colombier #ifdef PC
20*7dd7cddfSDavid du Colombier #include <io.h>
21*7dd7cddfSDavid du Colombier #include "y_tab.h"
22*7dd7cddfSDavid du Colombier #else
23219b2ee8SDavid du Colombier #include <unistd.h>
24219b2ee8SDavid du Colombier #include "y.tab.h"
25*7dd7cddfSDavid du Colombier #endif
26219b2ee8SDavid du Colombier 
27*7dd7cddfSDavid du Colombier extern int	DstepStart, lineno, tl_terse;
28*7dd7cddfSDavid du Colombier extern FILE	*yyin, *yyout, *tl_out;
29*7dd7cddfSDavid du Colombier extern Symbol	*context;
30*7dd7cddfSDavid du Colombier extern char	*claimproc;
31*7dd7cddfSDavid du Colombier extern void	qhide(int);
32219b2ee8SDavid du Colombier 
33219b2ee8SDavid du Colombier Symbol	*Fname, *oFname;
34219b2ee8SDavid du Colombier 
35*7dd7cddfSDavid du Colombier int	Etimeouts=0;	/* nr timeouts in program */
36*7dd7cddfSDavid du Colombier int	Ntimeouts=0;	/* nr timeouts in never claim */
37*7dd7cddfSDavid du Colombier int	analyze=0, columns=0, dumptab=0, has_remote=0;
38*7dd7cddfSDavid du Colombier int	interactive=0, jumpsteps=0, m_loss=0, nr_errs=0;
39*7dd7cddfSDavid du Colombier int	s_trail=0, ntrail=0, verbose=0, xspin=0, no_print=0, no_wrapup = 0, Caccess=0;
40*7dd7cddfSDavid du Colombier int	limited_vis=0, like_java=0;
41*7dd7cddfSDavid du Colombier int	dataflow = 1, merger = 1, deadvar = 1, rvopt = 0, ccache = 1;
42*7dd7cddfSDavid du Colombier int	separate = 0;	/* separate compilation option */
43*7dd7cddfSDavid du Colombier #if 0
44*7dd7cddfSDavid du Colombier meaning of flags on verbose:
45*7dd7cddfSDavid du Colombier 	1	-g global variable values
46*7dd7cddfSDavid du Colombier 	2	-l local variable values
47*7dd7cddfSDavid du Colombier 	4	-p all process actions
48*7dd7cddfSDavid du Colombier 	8	-r receives
49*7dd7cddfSDavid du Colombier 	16	-s sends
50*7dd7cddfSDavid du Colombier 	32	-v verbose
51*7dd7cddfSDavid du Colombier 	64	-w very verbose
52*7dd7cddfSDavid du Colombier #endif
53*7dd7cddfSDavid du Colombier 
54*7dd7cddfSDavid du Colombier static Element	*Same;
55*7dd7cddfSDavid du Colombier static int	IsAsgn = 0, OrIsAsgn = 0;
56*7dd7cddfSDavid du Colombier static char	Operator[] = "operator: ";
57*7dd7cddfSDavid du Colombier static char	Keyword[]  = "keyword: ";
58*7dd7cddfSDavid du Colombier static char	Function[] = "function-name: ";
59*7dd7cddfSDavid du Colombier static char	**add_ltl  = (char **)0;
60*7dd7cddfSDavid du Colombier static char	**ltl_file = (char **)0;
61*7dd7cddfSDavid du Colombier static char	**nvr_file = (char **)0;
62*7dd7cddfSDavid du Colombier static char	*PreArg[64];
63*7dd7cddfSDavid du Colombier static int	PreCnt = 0;
64*7dd7cddfSDavid du Colombier static char	out1[64];
65*7dd7cddfSDavid du Colombier static void	explain(int);
66*7dd7cddfSDavid du Colombier 
67*7dd7cddfSDavid du Colombier #ifndef CPP
68*7dd7cddfSDavid du Colombier 		/* OS2:		"spin -Picc -E/Pd+ -E/Q+"    */
69*7dd7cddfSDavid du Colombier 		/* Visual C++:	"spin -PCL  -E/E             */
70*7dd7cddfSDavid du Colombier #ifdef PC
71*7dd7cddfSDavid du Colombier #define CPP	"cpp"		/*  or specify a full path    */
72*7dd7cddfSDavid du Colombier #else
73*7dd7cddfSDavid du Colombier #ifdef SOLARIS
74*7dd7cddfSDavid du Colombier #define CPP	"/usr/ccs/lib/cpp"
75*7dd7cddfSDavid du Colombier #else
76*7dd7cddfSDavid du Colombier #ifdef __FreeBSD__
77*7dd7cddfSDavid du Colombier #define CPP	"cpp"
78*7dd7cddfSDavid du Colombier #else
79*7dd7cddfSDavid du Colombier #define CPP	"/bin/cpp"
80*7dd7cddfSDavid du Colombier #endif
81*7dd7cddfSDavid du Colombier #endif
82*7dd7cddfSDavid du Colombier #endif
83*7dd7cddfSDavid du Colombier 
84*7dd7cddfSDavid du Colombier #endif
85*7dd7cddfSDavid du Colombier static char	*PreProc = CPP;
86219b2ee8SDavid du Colombier 
87219b2ee8SDavid du Colombier void
88*7dd7cddfSDavid du Colombier alldone(int estatus)
89*7dd7cddfSDavid du Colombier {
90*7dd7cddfSDavid du Colombier 	if (strlen(out1) > 0)
91*7dd7cddfSDavid du Colombier 		(void) unlink((const char *)out1);
92*7dd7cddfSDavid du Colombier 	if (xspin && (analyze || s_trail))
93*7dd7cddfSDavid du Colombier 	{	if (estatus)
94*7dd7cddfSDavid du Colombier 			printf("spin: %d error(s) - aborting\n",
95*7dd7cddfSDavid du Colombier 			estatus);
96*7dd7cddfSDavid du Colombier 		else
97*7dd7cddfSDavid du Colombier 			printf("Exit-Status 0\n");
98*7dd7cddfSDavid du Colombier 	}
99*7dd7cddfSDavid du Colombier 	exit(estatus);
100*7dd7cddfSDavid du Colombier }
101219b2ee8SDavid du Colombier 
102*7dd7cddfSDavid du Colombier void
103*7dd7cddfSDavid du Colombier preprocess(char *a, char *b, int a_tmp)
104*7dd7cddfSDavid du Colombier {	char precmd[128], cmd[256]; int i;
105*7dd7cddfSDavid du Colombier #ifdef PC
106*7dd7cddfSDavid du Colombier 	extern int try_zpp(char *, char *);
107*7dd7cddfSDavid du Colombier 	if (try_zpp(a, b)) goto out;
108*7dd7cddfSDavid du Colombier #endif
109*7dd7cddfSDavid du Colombier 	strcpy(precmd, PreProc);
110*7dd7cddfSDavid du Colombier 	for (i = 1; i <= PreCnt; i++)
111*7dd7cddfSDavid du Colombier 	{	strcat(precmd, " ");
112*7dd7cddfSDavid du Colombier 		strcat(precmd, PreArg[i]);
113*7dd7cddfSDavid du Colombier 	}
114*7dd7cddfSDavid du Colombier 	sprintf(cmd, "%s %s > %s", precmd, a, b);
115*7dd7cddfSDavid du Colombier 	if (system((const char *)cmd))
116*7dd7cddfSDavid du Colombier 	{	(void) unlink((const char *) b);
117*7dd7cddfSDavid du Colombier 		if (a_tmp) (void) unlink((const char *) a);
118*7dd7cddfSDavid du Colombier 		alldone(1); /* failed */
119*7dd7cddfSDavid du Colombier 	}
120*7dd7cddfSDavid du Colombier out:	if (a_tmp) (void) unlink((const char *) a);
121*7dd7cddfSDavid du Colombier }
122*7dd7cddfSDavid du Colombier 
123*7dd7cddfSDavid du Colombier FILE *
124*7dd7cddfSDavid du Colombier cpyfile(char *src, char *tgt)
125*7dd7cddfSDavid du Colombier {	FILE *inp, *out;
126*7dd7cddfSDavid du Colombier 	char buf[1024];
127*7dd7cddfSDavid du Colombier 
128*7dd7cddfSDavid du Colombier 	inp = fopen(src, "r");
129*7dd7cddfSDavid du Colombier 	out = fopen(tgt, "w");
130*7dd7cddfSDavid du Colombier 	if (!inp || !out)
131*7dd7cddfSDavid du Colombier 	{	printf("spin: cannot cp %s to %s\n", src, tgt);
132*7dd7cddfSDavid du Colombier 		alldone(1);
133*7dd7cddfSDavid du Colombier 	}
134*7dd7cddfSDavid du Colombier 	while (fgets(buf, 1024, inp))
135*7dd7cddfSDavid du Colombier 		fprintf(out, "%s", buf);
136*7dd7cddfSDavid du Colombier 	fclose(inp);
137*7dd7cddfSDavid du Colombier 	return out;
138*7dd7cddfSDavid du Colombier }
139*7dd7cddfSDavid du Colombier 
140*7dd7cddfSDavid du Colombier void
141*7dd7cddfSDavid du Colombier usage(void)
142*7dd7cddfSDavid du Colombier {
143*7dd7cddfSDavid du Colombier 	printf("use: spin [-option] ... [-option] file\n");
144*7dd7cddfSDavid du Colombier 	printf("\tNote: file must always be the last argument\n");
145*7dd7cddfSDavid du Colombier 	printf("\t-a generate a verifier in pan.c\n");
146*7dd7cddfSDavid du Colombier 	printf("\t-B no final state details in simulations\n");
147*7dd7cddfSDavid du Colombier 	printf("\t-b don't execute printfs in simulation\n");
148*7dd7cddfSDavid du Colombier 	printf("\t-C print channel access info (structview)\n");
149*7dd7cddfSDavid du Colombier 	printf("\t-c columnated -s -r simulation output\n");
150219b2ee8SDavid du Colombier 	printf("\t-d produce symbol-table information\n");
151*7dd7cddfSDavid du Colombier 	printf("\t-Dyyy pass -Dyyy to the preprocessor\n");
152*7dd7cddfSDavid du Colombier 	printf("\t-Eyyy pass yyy to the preprocessor\n");
153*7dd7cddfSDavid du Colombier 	printf("\t-f \"..formula..\"  translate LTL ");
154*7dd7cddfSDavid du Colombier 	printf("into never claim\n");
155*7dd7cddfSDavid du Colombier 	printf("\t-F file  like -f, but with the LTL ");
156*7dd7cddfSDavid du Colombier 	printf("formula stored in a 1-line file\n");
157219b2ee8SDavid du Colombier 	printf("\t-g print all global variables\n");
158219b2ee8SDavid du Colombier 	printf("\t-i interactive (random simulation)\n");
159*7dd7cddfSDavid du Colombier 	printf("\t-J reverse eval order of nested unlesses\n");
160*7dd7cddfSDavid du Colombier 	printf("\t-jN skip the first N steps ");
161*7dd7cddfSDavid du Colombier 	printf("in simulation trail\n");
162219b2ee8SDavid du Colombier 	printf("\t-l print all local variables\n");
163*7dd7cddfSDavid du Colombier 	printf("\t-M print msc-flow in Postscript\n");
164219b2ee8SDavid du Colombier 	printf("\t-m lose msgs sent to full queues\n");
165*7dd7cddfSDavid du Colombier 	printf("\t-N file use never claim stored in file\n");
166219b2ee8SDavid du Colombier 	printf("\t-nN seed for random nr generator\n");
167*7dd7cddfSDavid du Colombier 	printf("\t-o1 turn off dataflow-optimizations in verifier\n");
168*7dd7cddfSDavid du Colombier 	printf("\t-o2 turn off dead variables elimination in verifier\n");
169*7dd7cddfSDavid du Colombier 	printf("\t-o3 turn off statement merging in verifier\n");
170*7dd7cddfSDavid du Colombier 	printf("\t-Pxxx use xxx for preprocessing\n");
171219b2ee8SDavid du Colombier 	printf("\t-p print all statements\n");
172*7dd7cddfSDavid du Colombier 	printf("\t-qN suppress io for queue N in printouts\n");
173219b2ee8SDavid du Colombier 	printf("\t-r print receive events\n");
174219b2ee8SDavid du Colombier 	printf("\t-s print send events\n");
175219b2ee8SDavid du Colombier 	printf("\t-v verbose, more warnings\n");
176*7dd7cddfSDavid du Colombier 	printf("\t-w very verbose (when combined with -l or -g)\n");
177*7dd7cddfSDavid du Colombier 	printf("\t-t[N] follow [Nth] simulation trail\n");
178*7dd7cddfSDavid du Colombier 	printf("\t-[XYZ] reserved for use by xspin interface\n");
179219b2ee8SDavid du Colombier 	printf("\t-V print version number and exit\n");
180*7dd7cddfSDavid du Colombier 	alldone(1);
181*7dd7cddfSDavid du Colombier }
182*7dd7cddfSDavid du Colombier 
183*7dd7cddfSDavid du Colombier void
184*7dd7cddfSDavid du Colombier optimizations(char nr)
185*7dd7cddfSDavid du Colombier {
186*7dd7cddfSDavid du Colombier 	switch (nr) {
187*7dd7cddfSDavid du Colombier 	case '1':
188*7dd7cddfSDavid du Colombier 		dataflow = 1 - dataflow; /* dataflow */
189*7dd7cddfSDavid du Colombier 		if (verbose&32)
190*7dd7cddfSDavid du Colombier 		printf("spin: dataflow optimizations turned %s\n",
191*7dd7cddfSDavid du Colombier 			dataflow?"on":"off");
192*7dd7cddfSDavid du Colombier 		break;
193*7dd7cddfSDavid du Colombier 	case '2':
194*7dd7cddfSDavid du Colombier 		/* dead variable elimination */
195*7dd7cddfSDavid du Colombier 		deadvar = 1 - deadvar;
196*7dd7cddfSDavid du Colombier 		if (verbose&32)
197*7dd7cddfSDavid du Colombier 		printf("spin: dead variable elimination turned %s\n",
198*7dd7cddfSDavid du Colombier 			deadvar?"on":"off");
199*7dd7cddfSDavid du Colombier 		break;
200*7dd7cddfSDavid du Colombier 	case '3':
201*7dd7cddfSDavid du Colombier 		/* statement merging */
202*7dd7cddfSDavid du Colombier 		merger = 1 - merger;
203*7dd7cddfSDavid du Colombier 		if (verbose&32)
204*7dd7cddfSDavid du Colombier 		printf("spin: statement merging turned %s\n",
205*7dd7cddfSDavid du Colombier 			merger?"on":"off");
206*7dd7cddfSDavid du Colombier 		break;
207*7dd7cddfSDavid du Colombier 
208*7dd7cddfSDavid du Colombier 	case '4':
209*7dd7cddfSDavid du Colombier 		/* rv optimization */
210*7dd7cddfSDavid du Colombier 		rvopt = 1 - rvopt;
211*7dd7cddfSDavid du Colombier 		if (verbose&32)
212*7dd7cddfSDavid du Colombier 		printf("spin: rendezvous optimization turned %s\n",
213*7dd7cddfSDavid du Colombier 			rvopt?"on":"off");
214*7dd7cddfSDavid du Colombier 		break;
215*7dd7cddfSDavid du Colombier 	case '5':
216*7dd7cddfSDavid du Colombier 		/* case caching */
217*7dd7cddfSDavid du Colombier 		ccache = 1 - ccache;
218*7dd7cddfSDavid du Colombier 		if (verbose&32)
219*7dd7cddfSDavid du Colombier 		printf("spin: case caching turned %s\n",
220*7dd7cddfSDavid du Colombier 			ccache?"on":"off");
221*7dd7cddfSDavid du Colombier 		break;
222*7dd7cddfSDavid du Colombier 	default:
223*7dd7cddfSDavid du Colombier 		printf("spin: bad or missing parameter on -o\n");
224*7dd7cddfSDavid du Colombier 		usage();
225*7dd7cddfSDavid du Colombier 		break;
226*7dd7cddfSDavid du Colombier 	}
227*7dd7cddfSDavid du Colombier }
228*7dd7cddfSDavid du Colombier 
229*7dd7cddfSDavid du Colombier int
230*7dd7cddfSDavid du Colombier main(int argc, char *argv[])
231*7dd7cddfSDavid du Colombier {	Symbol *s; int preprocessonly = 0;
232*7dd7cddfSDavid du Colombier 	int T = (int) time((time_t *)0);
233*7dd7cddfSDavid du Colombier 	int usedopts = 0;
234*7dd7cddfSDavid du Colombier 	extern void ana_src(int, int);
235*7dd7cddfSDavid du Colombier 
236*7dd7cddfSDavid du Colombier 	yyin  = stdin;
237*7dd7cddfSDavid du Colombier 	yyout = stdout;
238*7dd7cddfSDavid du Colombier 	tl_out = stdout;
239*7dd7cddfSDavid du Colombier 
240*7dd7cddfSDavid du Colombier 	/* unused flags: e, w, x, y, z, A, G, I, L, O, Q, R, S, T, W */
241*7dd7cddfSDavid du Colombier 	while (argc > 1 && argv[1][0] == '-')
242*7dd7cddfSDavid du Colombier 	{	switch (argv[1][1]) {
243*7dd7cddfSDavid du Colombier 
244*7dd7cddfSDavid du Colombier 		/* generate code for separate compilation: S1 or S2 */
245*7dd7cddfSDavid du Colombier 		case 'S': separate = atoi(&argv[1][2]);
246*7dd7cddfSDavid du Colombier 			  /* fall through */
247*7dd7cddfSDavid du Colombier 
248*7dd7cddfSDavid du Colombier 		case 'a': analyze  = 1; break;
249*7dd7cddfSDavid du Colombier 		case 'B': no_wrapup = 1; break;
250*7dd7cddfSDavid du Colombier 		case 'b': no_print = 1; break;
251*7dd7cddfSDavid du Colombier 		case 'C': Caccess = 1; break;
252*7dd7cddfSDavid du Colombier 		case 'c': columns = 1; break;
253*7dd7cddfSDavid du Colombier 		case 'D': PreArg[++PreCnt] = (char *) &argv[1][0];
254*7dd7cddfSDavid du Colombier 			  break;
255*7dd7cddfSDavid du Colombier 		case 'd': dumptab =  1; break;
256*7dd7cddfSDavid du Colombier 		case 'E': PreArg[++PreCnt] = (char *) &argv[1][2];
257*7dd7cddfSDavid du Colombier 			  break;
258*7dd7cddfSDavid du Colombier 		case 'F': ltl_file = (char **) (argv+2);
259*7dd7cddfSDavid du Colombier 			  argc--; argv++; break;
260*7dd7cddfSDavid du Colombier 		case 'f': add_ltl = (char **) argv;
261*7dd7cddfSDavid du Colombier 			  argc--; argv++; break;
262*7dd7cddfSDavid du Colombier 		case 'g': verbose +=  1; break;
263*7dd7cddfSDavid du Colombier 		case 'i': interactive = 1; break;
264*7dd7cddfSDavid du Colombier 		case 'J': like_java = 1; break;
265*7dd7cddfSDavid du Colombier 		case 'j': jumpsteps = atoi(&argv[1][2]); break;
266*7dd7cddfSDavid du Colombier 		case 'l': verbose +=  2; break;
267*7dd7cddfSDavid du Colombier 		case 'M': columns = 2; break;
268*7dd7cddfSDavid du Colombier 		case 'm': m_loss   =  1; break;
269*7dd7cddfSDavid du Colombier 		case 'N': nvr_file = (char **) (argv+2);
270*7dd7cddfSDavid du Colombier 			  argc--; argv++; break;
271*7dd7cddfSDavid du Colombier 		case 'n': T = atoi(&argv[1][2]); tl_terse = 1; break;
272*7dd7cddfSDavid du Colombier 		case 'o': optimizations(argv[1][2]);
273*7dd7cddfSDavid du Colombier 			  usedopts = 1; break;
274*7dd7cddfSDavid du Colombier 		case 'P': PreProc = (char *) &argv[1][2]; break;
275*7dd7cddfSDavid du Colombier 		case 'p': verbose +=  4; break;
276*7dd7cddfSDavid du Colombier 		case 'q': if (isdigit(argv[1][2]))
277*7dd7cddfSDavid du Colombier 				qhide(atoi(&argv[1][2]));
278*7dd7cddfSDavid du Colombier 			  break;
279*7dd7cddfSDavid du Colombier 		case 'r': verbose +=  8; break;
280*7dd7cddfSDavid du Colombier 		case 's': verbose += 16; break;
281*7dd7cddfSDavid du Colombier 		case 't': s_trail  =  1;
282*7dd7cddfSDavid du Colombier 			  if (isdigit(argv[1][2]))
283*7dd7cddfSDavid du Colombier 				ntrail = atoi(&argv[1][2]);
284*7dd7cddfSDavid du Colombier 			  break;
285*7dd7cddfSDavid du Colombier 		case 'v': verbose += 32; break;
286*7dd7cddfSDavid du Colombier 		case 'V': printf("%s\n", Version);
287*7dd7cddfSDavid du Colombier 			  alldone(0);
288*7dd7cddfSDavid du Colombier 			  break;
289*7dd7cddfSDavid du Colombier 		case 'w': verbose += 64; break;
290*7dd7cddfSDavid du Colombier 		case 'X': xspin = 1;
291*7dd7cddfSDavid du Colombier #ifndef PC
292*7dd7cddfSDavid du Colombier 			  signal(SIGPIPE, alldone); /* not posix... */
293*7dd7cddfSDavid du Colombier #endif
294*7dd7cddfSDavid du Colombier 			  break;
295*7dd7cddfSDavid du Colombier 		case 'Y': limited_vis = 1; break;	/* used by xspin */
296*7dd7cddfSDavid du Colombier 		case 'Z': preprocessonly = 1; break;	/* used by xspin */
297*7dd7cddfSDavid du Colombier 
298*7dd7cddfSDavid du Colombier 		default : usage(); break;
299219b2ee8SDavid du Colombier 		}
300219b2ee8SDavid du Colombier 		argc--, argv++;
301219b2ee8SDavid du Colombier 	}
302*7dd7cddfSDavid du Colombier 	if (usedopts && !analyze)
303*7dd7cddfSDavid du Colombier 		printf("spin: warning -o[123] option ignored in simulations\n");
304219b2ee8SDavid du Colombier 
305*7dd7cddfSDavid du Colombier 	if (ltl_file)
306*7dd7cddfSDavid du Colombier 	{	char formula[4096];
307*7dd7cddfSDavid du Colombier 		add_ltl = ltl_file-2; add_ltl[1][1] = 'f';
308*7dd7cddfSDavid du Colombier 		if (!(tl_out = fopen(*ltl_file, "r")))
309*7dd7cddfSDavid du Colombier 		{	printf("spin: cannot open %s\n", *ltl_file);
310*7dd7cddfSDavid du Colombier 			alldone(1);
311219b2ee8SDavid du Colombier 		}
312*7dd7cddfSDavid du Colombier 		fgets(formula, 4096, tl_out);
313*7dd7cddfSDavid du Colombier 		fclose(tl_out);
314*7dd7cddfSDavid du Colombier 		tl_out = stdout;
315*7dd7cddfSDavid du Colombier 		*ltl_file = (char *) formula;
316*7dd7cddfSDavid du Colombier 	}
317*7dd7cddfSDavid du Colombier 	if (argc > 1)
318*7dd7cddfSDavid du Colombier 	{	char cmd[128], out2[64];
319*7dd7cddfSDavid du Colombier #ifdef PC
320*7dd7cddfSDavid du Colombier 		strcpy(out1, "_tmp1_");
321*7dd7cddfSDavid du Colombier 		strcpy(out2, "_tmp2_");
322*7dd7cddfSDavid du Colombier #else
323*7dd7cddfSDavid du Colombier 		/* extern char *tmpnam(char *);  in stdio.h */
324*7dd7cddfSDavid du Colombier 		if (add_ltl || nvr_file)
325*7dd7cddfSDavid du Colombier 		{	/* must remain in current dir */
326*7dd7cddfSDavid du Colombier 			strcpy(out1, "_tmp1_");
327*7dd7cddfSDavid du Colombier 			strcpy(out2, "_tmp2_");
328*7dd7cddfSDavid du Colombier 		} else
329*7dd7cddfSDavid du Colombier 		{	(void) tmpnam(out1);
330*7dd7cddfSDavid du Colombier 			(void) tmpnam(out2);
331*7dd7cddfSDavid du Colombier 		}
332*7dd7cddfSDavid du Colombier #endif
333*7dd7cddfSDavid du Colombier 		if (add_ltl)
334*7dd7cddfSDavid du Colombier 		{	tl_out = cpyfile(argv[1], out2);
335*7dd7cddfSDavid du Colombier 			nr_errs = tl_main(2, add_ltl);	/* in tl_main.c */
336*7dd7cddfSDavid du Colombier 			fclose(tl_out);
337*7dd7cddfSDavid du Colombier 			preprocess(out2, out1, 1);
338*7dd7cddfSDavid du Colombier 		} else if (nvr_file)
339*7dd7cddfSDavid du Colombier 		{	FILE *fd; char buf[1024];
340*7dd7cddfSDavid du Colombier 
341*7dd7cddfSDavid du Colombier 			if ((fd = fopen(*nvr_file, "r")) == NULL)
342*7dd7cddfSDavid du Colombier 			{	printf("spin: cannot open %s\n",
343*7dd7cddfSDavid du Colombier 					*nvr_file);
344*7dd7cddfSDavid du Colombier 				alldone(1);
345*7dd7cddfSDavid du Colombier 			}
346*7dd7cddfSDavid du Colombier 			tl_out = cpyfile(argv[1], out2);
347*7dd7cddfSDavid du Colombier 			while (fgets(buf, 1024, fd))
348*7dd7cddfSDavid du Colombier 				fprintf(tl_out, "%s", buf);
349*7dd7cddfSDavid du Colombier 			fclose(tl_out);
350*7dd7cddfSDavid du Colombier 			fclose(fd);
351*7dd7cddfSDavid du Colombier 			preprocess(out2, out1, 1);
352*7dd7cddfSDavid du Colombier 		} else
353*7dd7cddfSDavid du Colombier 			preprocess(argv[1], out1, 0);
354*7dd7cddfSDavid du Colombier 
355*7dd7cddfSDavid du Colombier 		if (preprocessonly)
356*7dd7cddfSDavid du Colombier 		{	(void) unlink("pan.pre"); /* remove old version */
357*7dd7cddfSDavid du Colombier 			if (rename((const char *) out1, "pan.pre") != 0)
358*7dd7cddfSDavid du Colombier 			{	printf("spin: rename %s failed\n", out1);
359*7dd7cddfSDavid du Colombier 				alldone(1);
360*7dd7cddfSDavid du Colombier 			}
361*7dd7cddfSDavid du Colombier 			alldone(0);
362*7dd7cddfSDavid du Colombier 		}
363*7dd7cddfSDavid du Colombier 		if (!(yyin = fopen(out1, "r")))
364*7dd7cddfSDavid du Colombier 		{	printf("spin: cannot open %s\n", out1);
365*7dd7cddfSDavid du Colombier 			alldone(1);
366*7dd7cddfSDavid du Colombier 		}
367*7dd7cddfSDavid du Colombier 
368*7dd7cddfSDavid du Colombier 		if (strncmp(argv[1], "progress", 8) == 0
369*7dd7cddfSDavid du Colombier 		||  strncmp(argv[1], "accept", 6) == 0)
370*7dd7cddfSDavid du Colombier 			sprintf(cmd, "_%s", argv[1]);
371*7dd7cddfSDavid du Colombier 		else
372*7dd7cddfSDavid du Colombier 			strcpy(cmd, argv[1]);
373*7dd7cddfSDavid du Colombier 		oFname = Fname = lookup(cmd);
374219b2ee8SDavid du Colombier 		if (oFname->name[0] == '\"')
375219b2ee8SDavid du Colombier 		{	int i = strlen(oFname->name);
376219b2ee8SDavid du Colombier 			oFname->name[i-1] = '\0';
377219b2ee8SDavid du Colombier 			oFname = lookup(&oFname->name[1]);
378219b2ee8SDavid du Colombier 		}
379219b2ee8SDavid du Colombier 	} else
380*7dd7cddfSDavid du Colombier 	{	oFname = Fname = lookup("<stdin>");
381*7dd7cddfSDavid du Colombier 		if (add_ltl)
382*7dd7cddfSDavid du Colombier 		{	if (argc > 0)
383*7dd7cddfSDavid du Colombier 				exit(tl_main(2, add_ltl));
384*7dd7cddfSDavid du Colombier 			printf("spin: missing argument to -f\n");
385*7dd7cddfSDavid du Colombier 			alldone(1);
386*7dd7cddfSDavid du Colombier 		}
387*7dd7cddfSDavid du Colombier 		printf("%s\n", Version);
388*7dd7cddfSDavid du Colombier 		printf("reading input from stdin:\n");
389*7dd7cddfSDavid du Colombier 		fflush(stdout);
390*7dd7cddfSDavid du Colombier 	}
391*7dd7cddfSDavid du Colombier 	if (columns == 2)
392*7dd7cddfSDavid du Colombier 	{	extern void putprelude(void);
393*7dd7cddfSDavid du Colombier 		if (xspin || verbose&(1|4|8|16|32))
394*7dd7cddfSDavid du Colombier 		{	printf("spin: -c precludes all flags except -t\n");
395*7dd7cddfSDavid du Colombier 			alldone(1);
396*7dd7cddfSDavid du Colombier 		}
397*7dd7cddfSDavid du Colombier 		putprelude();
398*7dd7cddfSDavid du Colombier 	}
399*7dd7cddfSDavid du Colombier 	if (columns && !(verbose&8) && !(verbose&16))
400*7dd7cddfSDavid du Colombier 		verbose += (8+16);
401*7dd7cddfSDavid du Colombier 	if (columns == 2 && limited_vis)
402*7dd7cddfSDavid du Colombier 		verbose += (1+4);
403219b2ee8SDavid du Colombier 	Srand(T);	/* defined in run.c */
404*7dd7cddfSDavid du Colombier 	s = lookup("_");	s->type = PREDEF; /* a write only global var */
405219b2ee8SDavid du Colombier 	s = lookup("_p");	s->type = PREDEF;
406219b2ee8SDavid du Colombier 	s = lookup("_pid");	s->type = PREDEF;
407219b2ee8SDavid du Colombier 	s = lookup("_last");	s->type = PREDEF;
408*7dd7cddfSDavid du Colombier 	s = lookup("_nr_pr");	s->type = PREDEF; /* new 3.3.10 */
409219b2ee8SDavid du Colombier 	yyparse();
410*7dd7cddfSDavid du Colombier 	fclose(yyin);
411*7dd7cddfSDavid du Colombier 	chanaccess();
412*7dd7cddfSDavid du Colombier 	if (!s_trail && (dataflow || merger))
413*7dd7cddfSDavid du Colombier 		ana_src(dataflow, merger);
414*7dd7cddfSDavid du Colombier 	sched();
415*7dd7cddfSDavid du Colombier 	alldone(nr_errs);
416*7dd7cddfSDavid du Colombier 	return 0;	/* can't get here */
417219b2ee8SDavid du Colombier }
418219b2ee8SDavid du Colombier 
419219b2ee8SDavid du Colombier int
420219b2ee8SDavid du Colombier yywrap(void)	/* dummy routine */
421219b2ee8SDavid du Colombier {
422219b2ee8SDavid du Colombier 	return 1;
423219b2ee8SDavid du Colombier }
424219b2ee8SDavid du Colombier 
425219b2ee8SDavid du Colombier void
426219b2ee8SDavid du Colombier non_fatal(char *s1, char *s2)
427*7dd7cddfSDavid du Colombier {	extern char yytext[];
428219b2ee8SDavid du Colombier 
429*7dd7cddfSDavid du Colombier 	printf("spin: line %3d %s, Error: ",
430*7dd7cddfSDavid du Colombier 		lineno, Fname?Fname->name:"nofilename");
431219b2ee8SDavid du Colombier 	if (s2)
432219b2ee8SDavid du Colombier 		printf(s1, s2);
433219b2ee8SDavid du Colombier 	else
434219b2ee8SDavid du Colombier 		printf(s1);
435*7dd7cddfSDavid du Colombier #if 0
436219b2ee8SDavid du Colombier 	if (yychar != -1 && yychar != 0)
437219b2ee8SDavid du Colombier 	{	printf("	saw '");
438219b2ee8SDavid du Colombier 		explain(yychar);
439219b2ee8SDavid du Colombier 		printf("'");
440219b2ee8SDavid du Colombier 	}
441*7dd7cddfSDavid du Colombier #endif
442219b2ee8SDavid du Colombier 	if (yytext && strlen(yytext)>1)
443219b2ee8SDavid du Colombier 		printf(" near '%s'", yytext);
444*7dd7cddfSDavid du Colombier 	printf("\n");
445219b2ee8SDavid du Colombier 	nr_errs++;
446219b2ee8SDavid du Colombier }
447219b2ee8SDavid du Colombier 
448219b2ee8SDavid du Colombier void
449219b2ee8SDavid du Colombier fatal(char *s1, char *s2)
450219b2ee8SDavid du Colombier {
451219b2ee8SDavid du Colombier 	non_fatal(s1, s2);
452*7dd7cddfSDavid du Colombier 	alldone(1);
453219b2ee8SDavid du Colombier }
454219b2ee8SDavid du Colombier 
455219b2ee8SDavid du Colombier char *
456219b2ee8SDavid du Colombier emalloc(int n)
457219b2ee8SDavid du Colombier {	char *tmp;
458219b2ee8SDavid du Colombier 
459219b2ee8SDavid du Colombier 	if (!(tmp = (char *) malloc(n)))
460219b2ee8SDavid du Colombier 		fatal("not enough memory", (char *)0);
461219b2ee8SDavid du Colombier 	memset(tmp, 0, n);
462219b2ee8SDavid du Colombier 	return tmp;
463219b2ee8SDavid du Colombier }
464219b2ee8SDavid du Colombier 
465*7dd7cddfSDavid du Colombier void
466*7dd7cddfSDavid du Colombier trapwonly(Lextok *n, char *s)
467*7dd7cddfSDavid du Colombier {	extern int realread;
468*7dd7cddfSDavid du Colombier 	short i = (n->sym)?n->sym->type:0;
469*7dd7cddfSDavid du Colombier 
470*7dd7cddfSDavid du Colombier 	if (i != MTYPE
471*7dd7cddfSDavid du Colombier 	&&  i != BIT
472*7dd7cddfSDavid du Colombier 	&&  i != BYTE
473*7dd7cddfSDavid du Colombier 	&&  i != SHORT
474*7dd7cddfSDavid du Colombier 	&&  i != INT
475*7dd7cddfSDavid du Colombier 	&&  i != UNSIGNED)
476*7dd7cddfSDavid du Colombier 		return;
477*7dd7cddfSDavid du Colombier 
478*7dd7cddfSDavid du Colombier 	if (realread)
479*7dd7cddfSDavid du Colombier 	n->sym->hidden |= 32;	/* var is read at least once */
480*7dd7cddfSDavid du Colombier }
481*7dd7cddfSDavid du Colombier 
482*7dd7cddfSDavid du Colombier void
483*7dd7cddfSDavid du Colombier setaccess(Symbol *sp, Symbol *what, int cnt, int t)
484*7dd7cddfSDavid du Colombier {	Access *a;
485*7dd7cddfSDavid du Colombier 
486*7dd7cddfSDavid du Colombier 	for (a = sp->access; a; a = a->lnk)
487*7dd7cddfSDavid du Colombier 		if (a->who == context
488*7dd7cddfSDavid du Colombier 		&&  a->what == what
489*7dd7cddfSDavid du Colombier 		&&  a->cnt == cnt
490*7dd7cddfSDavid du Colombier 		&&  a->typ == t)
491*7dd7cddfSDavid du Colombier 			return;
492*7dd7cddfSDavid du Colombier 
493*7dd7cddfSDavid du Colombier 	a = (Access *) emalloc(sizeof(Access));
494*7dd7cddfSDavid du Colombier 	a->who = context;
495*7dd7cddfSDavid du Colombier 	a->what = what;
496*7dd7cddfSDavid du Colombier 	a->cnt = cnt;
497*7dd7cddfSDavid du Colombier 	a->typ = t;
498*7dd7cddfSDavid du Colombier 	a->lnk = sp->access;
499*7dd7cddfSDavid du Colombier 	sp->access = a;
500*7dd7cddfSDavid du Colombier }
501*7dd7cddfSDavid du Colombier 
502219b2ee8SDavid du Colombier Lextok *
503219b2ee8SDavid du Colombier nn(Lextok *s, int t, Lextok *ll, Lextok *rl)
504219b2ee8SDavid du Colombier {	Lextok *n = (Lextok *) emalloc(sizeof(Lextok));
505219b2ee8SDavid du Colombier 
506*7dd7cddfSDavid du Colombier 	n->ntyp = (short) t;
507219b2ee8SDavid du Colombier 	if (s && s->fn)
508219b2ee8SDavid du Colombier 	{	n->ln = s->ln;
509219b2ee8SDavid du Colombier 		n->fn = s->fn;
510219b2ee8SDavid du Colombier 	} else if (rl && rl->fn)
511219b2ee8SDavid du Colombier 	{	n->ln = rl->ln;
512219b2ee8SDavid du Colombier 		n->fn = rl->fn;
513219b2ee8SDavid du Colombier 	} else if (ll && ll->fn)
514219b2ee8SDavid du Colombier 	{	n->ln = ll->ln;
515219b2ee8SDavid du Colombier 		n->fn = ll->fn;
516219b2ee8SDavid du Colombier 	} else
517219b2ee8SDavid du Colombier 	{	n->ln = lineno;
518219b2ee8SDavid du Colombier 		n->fn = Fname;
519219b2ee8SDavid du Colombier 	}
520219b2ee8SDavid du Colombier 	if (s) n->sym  = s->sym;
521219b2ee8SDavid du Colombier 	n->lft  = ll;
522219b2ee8SDavid du Colombier 	n->rgt  = rl;
523219b2ee8SDavid du Colombier 	n->indstep = DstepStart;
524219b2ee8SDavid du Colombier 
525219b2ee8SDavid du Colombier 	if (t == TIMEOUT) Etimeouts++;
526219b2ee8SDavid du Colombier 
527*7dd7cddfSDavid du Colombier 	if (!context) return n;
528*7dd7cddfSDavid du Colombier 
529*7dd7cddfSDavid du Colombier 	if (t == 'r' || t == 's')
530*7dd7cddfSDavid du Colombier 		setaccess(n->sym, ZS, 0, t);
531*7dd7cddfSDavid du Colombier 	if (t == 'R')
532*7dd7cddfSDavid du Colombier 		setaccess(n->sym, ZS, 0, 'P');
533*7dd7cddfSDavid du Colombier 
534219b2ee8SDavid du Colombier 	if (context->name == claimproc)
535*7dd7cddfSDavid du Colombier 	{	int forbidden = separate;
536*7dd7cddfSDavid du Colombier 		switch (t) {
537*7dd7cddfSDavid du Colombier 		case ASGN:
538*7dd7cddfSDavid du Colombier 			printf("spin: Warning, never claim has side-effect\n");
539*7dd7cddfSDavid du Colombier 			break;
540*7dd7cddfSDavid du Colombier 		case 'r': case 's':
541*7dd7cddfSDavid du Colombier 			non_fatal("never claim contains i/o stmnts",(char *)0);
542219b2ee8SDavid du Colombier 			break;
543219b2ee8SDavid du Colombier 		case TIMEOUT:
544219b2ee8SDavid du Colombier 			/* never claim polls timeout */
545*7dd7cddfSDavid du Colombier 			if (Ntimeouts && Etimeouts)
546*7dd7cddfSDavid du Colombier 				forbidden = 0;
547219b2ee8SDavid du Colombier 			Ntimeouts++; Etimeouts--;
548219b2ee8SDavid du Colombier 			break;
549219b2ee8SDavid du Colombier 		case LEN: case EMPTY: case FULL:
550219b2ee8SDavid du Colombier 		case 'R': case NFULL: case NEMPTY:
551*7dd7cddfSDavid du Colombier 			/* status becomes non-exclusive */
552*7dd7cddfSDavid du Colombier 			if (n->sym && !(n->sym->xu&XX))
553*7dd7cddfSDavid du Colombier 			{	n->sym->xu |= XX;
554*7dd7cddfSDavid du Colombier 				if (separate == 2) {
555*7dd7cddfSDavid du Colombier 				printf("spin: warning, make sure that the S1 model\n");
556*7dd7cddfSDavid du Colombier 				printf("      also polls channel '%s' in its claim\n",
557*7dd7cddfSDavid du Colombier 				n->sym->name);
558*7dd7cddfSDavid du Colombier 			}	}
559*7dd7cddfSDavid du Colombier 			forbidden = 0;
560219b2ee8SDavid du Colombier 			break;
561219b2ee8SDavid du Colombier 		default:
562*7dd7cddfSDavid du Colombier 			forbidden = 0;
563219b2ee8SDavid du Colombier 			break;
564219b2ee8SDavid du Colombier 		}
565*7dd7cddfSDavid du Colombier 		if (forbidden)
566*7dd7cddfSDavid du Colombier 		{	printf("spin: never, saw "); explain(t); printf("\n");
567*7dd7cddfSDavid du Colombier 			fatal("incompatible with separate compilation",(char *)0);
568*7dd7cddfSDavid du Colombier 		}
569*7dd7cddfSDavid du Colombier 	} else if (t == ENABLED || t == PC_VAL)
570*7dd7cddfSDavid du Colombier 	{	printf("spin: Warning, using %s outside never-claim\n",
571*7dd7cddfSDavid du Colombier 			(t == ENABLED)?"enabled()":"pc_value()");
572*7dd7cddfSDavid du Colombier 	} else if (t == NONPROGRESS)
573*7dd7cddfSDavid du Colombier 	{	fatal("spin: Error, using np_ outside never-claim\n", (char *)0);
574*7dd7cddfSDavid du Colombier 	}
575219b2ee8SDavid du Colombier 	return n;
576219b2ee8SDavid du Colombier }
577219b2ee8SDavid du Colombier 
578219b2ee8SDavid du Colombier Lextok *
579219b2ee8SDavid du Colombier rem_lab(Symbol *a, Lextok *b, Symbol *c)
580219b2ee8SDavid du Colombier {	Lextok *tmp1, *tmp2, *tmp3;
581219b2ee8SDavid du Colombier 
582219b2ee8SDavid du Colombier 	has_remote++;
583219b2ee8SDavid du Colombier 	fix_dest(c, a);	/* in case target is jump */
584219b2ee8SDavid du Colombier 	tmp1 = nn(ZN, '?',   b, ZN); tmp1->sym = a;
585219b2ee8SDavid du Colombier 	tmp1 = nn(ZN, 'p', tmp1, ZN);
586219b2ee8SDavid du Colombier 	tmp1->sym = lookup("_p");
587219b2ee8SDavid du Colombier 	tmp2 = nn(ZN, NAME,  ZN, ZN); tmp2->sym = a;
588219b2ee8SDavid du Colombier 	tmp3 = nn(ZN, 'q', tmp2, ZN); tmp3->sym = c;
589219b2ee8SDavid du Colombier 	return nn(ZN, EQ, tmp1, tmp3);
590219b2ee8SDavid du Colombier }
591219b2ee8SDavid du Colombier 
592*7dd7cddfSDavid du Colombier static void
593219b2ee8SDavid du Colombier explain(int n)
594*7dd7cddfSDavid du Colombier {	FILE *fd = stdout;
595219b2ee8SDavid du Colombier 	switch (n) {
596219b2ee8SDavid du Colombier 	default:	if (n > 0 && n < 256)
597*7dd7cddfSDavid du Colombier 				fprintf(fd, "%c' = '", n);
598*7dd7cddfSDavid du Colombier 			fprintf(fd, "%d", n);
599219b2ee8SDavid du Colombier 			break;
600*7dd7cddfSDavid du Colombier 	case '\b':	fprintf(fd, "\\b"); break;
601*7dd7cddfSDavid du Colombier 	case '\t':	fprintf(fd, "\\t"); break;
602*7dd7cddfSDavid du Colombier 	case '\f':	fprintf(fd, "\\f"); break;
603*7dd7cddfSDavid du Colombier 	case '\n':	fprintf(fd, "\\n"); break;
604*7dd7cddfSDavid du Colombier 	case '\r':	fprintf(fd, "\\r"); break;
605*7dd7cddfSDavid du Colombier 	case 'c':	fprintf(fd, "condition"); break;
606*7dd7cddfSDavid du Colombier 	case 's':	fprintf(fd, "send"); break;
607*7dd7cddfSDavid du Colombier 	case 'r':	fprintf(fd, "recv"); break;
608*7dd7cddfSDavid du Colombier 	case 'R':	fprintf(fd, "recv poll %s", Operator); break;
609*7dd7cddfSDavid du Colombier 	case '@':	fprintf(fd, "@"); break;
610*7dd7cddfSDavid du Colombier 	case '?':	fprintf(fd, "(x->y:z)"); break;
611*7dd7cddfSDavid du Colombier 	case ACTIVE:	fprintf(fd, "%sactive",	Keyword); break;
612*7dd7cddfSDavid du Colombier 	case AND:	fprintf(fd, "%s&&",	Operator); break;
613*7dd7cddfSDavid du Colombier 	case ASGN:	fprintf(fd, "%s=",	Operator); break;
614*7dd7cddfSDavid du Colombier 	case ASSERT:	fprintf(fd, "%sassert",	Function); break;
615*7dd7cddfSDavid du Colombier 	case ATOMIC:	fprintf(fd, "%satomic",	Keyword); break;
616*7dd7cddfSDavid du Colombier 	case BREAK:	fprintf(fd, "%sbreak",	Keyword); break;
617*7dd7cddfSDavid du Colombier 	case CLAIM:	fprintf(fd, "%snever",	Keyword); break;
618*7dd7cddfSDavid du Colombier 	case CONST:	fprintf(fd, "a constant"); break;
619*7dd7cddfSDavid du Colombier 	case DECR:	fprintf(fd, "%s--",	Operator); break;
620*7dd7cddfSDavid du Colombier 	case D_STEP:	fprintf(fd, "%sd_step",	Keyword); break;
621*7dd7cddfSDavid du Colombier 	case DO:	fprintf(fd, "%sdo",	Keyword); break;
622*7dd7cddfSDavid du Colombier 	case DOT:	fprintf(fd, "."); break;
623*7dd7cddfSDavid du Colombier 	case ELSE:	fprintf(fd, "%selse",	Keyword); break;
624*7dd7cddfSDavid du Colombier 	case EMPTY:	fprintf(fd, "%sempty",	Function); break;
625*7dd7cddfSDavid du Colombier 	case ENABLED:	fprintf(fd, "%senabled",Function); break;
626*7dd7cddfSDavid du Colombier 	case EQ:	fprintf(fd, "%s==",	Operator); break;
627*7dd7cddfSDavid du Colombier 	case EVAL:	fprintf(fd, "%seval",	Function); break;
628*7dd7cddfSDavid du Colombier 	case FI:	fprintf(fd, "%sfi",	Keyword); break;
629*7dd7cddfSDavid du Colombier 	case FULL:	fprintf(fd, "%sfull",	Function); break;
630*7dd7cddfSDavid du Colombier 	case GE:	fprintf(fd, "%s>=",	Operator); break;
631*7dd7cddfSDavid du Colombier 	case GOTO:	fprintf(fd, "%sgoto",	Keyword); break;
632*7dd7cddfSDavid du Colombier 	case GT:	fprintf(fd, "%s>",	Operator); break;
633*7dd7cddfSDavid du Colombier 	case IF:	fprintf(fd, "%sif",	Keyword); break;
634*7dd7cddfSDavid du Colombier 	case INCR:	fprintf(fd, "%s++",	Operator); break;
635*7dd7cddfSDavid du Colombier 	case INAME:	fprintf(fd, "inline name"); break;
636*7dd7cddfSDavid du Colombier 	case INLINE:	fprintf(fd, "%sinline",	Keyword); break;
637*7dd7cddfSDavid du Colombier 	case INIT:	fprintf(fd, "%sinit",	Keyword); break;
638*7dd7cddfSDavid du Colombier 	case LABEL:	fprintf(fd, "a label-name"); break;
639*7dd7cddfSDavid du Colombier 	case LE:	fprintf(fd, "%s<=",	Operator); break;
640*7dd7cddfSDavid du Colombier 	case LEN:	fprintf(fd, "%slen",	Function); break;
641*7dd7cddfSDavid du Colombier 	case LSHIFT:	fprintf(fd, "%s<<",	Operator); break;
642*7dd7cddfSDavid du Colombier 	case LT:	fprintf(fd, "%s<",	Operator); break;
643*7dd7cddfSDavid du Colombier 	case MTYPE:	fprintf(fd, "%smtype",	Keyword); break;
644*7dd7cddfSDavid du Colombier 	case NAME:	fprintf(fd, "an identifier"); break;
645*7dd7cddfSDavid du Colombier 	case NE:	fprintf(fd, "%s!=",	Operator); break;
646*7dd7cddfSDavid du Colombier 	case NEG:	fprintf(fd, "%s! (not)",Operator); break;
647*7dd7cddfSDavid du Colombier 	case NEMPTY:	fprintf(fd, "%snempty",	Function); break;
648*7dd7cddfSDavid du Colombier 	case NFULL:	fprintf(fd, "%snfull",	Function); break;
649*7dd7cddfSDavid du Colombier 	case NON_ATOMIC: fprintf(fd, "sub-sequence"); break;
650*7dd7cddfSDavid du Colombier 	case NONPROGRESS: fprintf(fd, "%snp_",	Function); break;
651*7dd7cddfSDavid du Colombier 	case OD:	fprintf(fd, "%sod",	Keyword); break;
652*7dd7cddfSDavid du Colombier 	case OF:	fprintf(fd, "%sof",	Keyword); break;
653*7dd7cddfSDavid du Colombier 	case OR:	fprintf(fd, "%s||",	Operator); break;
654*7dd7cddfSDavid du Colombier 	case O_SND:	fprintf(fd, "%s!!",	Operator); break;
655*7dd7cddfSDavid du Colombier 	case PC_VAL:	fprintf(fd, "%spc_value",Function); break;
656*7dd7cddfSDavid du Colombier 	case PNAME:	fprintf(fd, "process name"); break;
657*7dd7cddfSDavid du Colombier 	case PRINT:	fprintf(fd, "%sprintf",	Function); break;
658*7dd7cddfSDavid du Colombier 	case PROCTYPE:	fprintf(fd, "%sproctype",Keyword); break;
659*7dd7cddfSDavid du Colombier 	case RCV:	fprintf(fd, "%s?",	Operator); break;
660*7dd7cddfSDavid du Colombier 	case R_RCV:	fprintf(fd, "%s??",	Operator); break;
661*7dd7cddfSDavid du Colombier 	case RSHIFT:	fprintf(fd, "%s>>",	Operator); break;
662*7dd7cddfSDavid du Colombier 	case RUN:	fprintf(fd, "%srun",	Operator); break;
663*7dd7cddfSDavid du Colombier 	case SEP:	fprintf(fd, "token: ::"); break;
664*7dd7cddfSDavid du Colombier 	case SEMI:	fprintf(fd, ";"); break;
665*7dd7cddfSDavid du Colombier 	case SND:	fprintf(fd, "%s!",	Operator); break;
666*7dd7cddfSDavid du Colombier 	case STRING:	fprintf(fd, "a string"); break;
667*7dd7cddfSDavid du Colombier 	case TIMEOUT:	fprintf(fd, "%stimeout",Keyword); break;
668*7dd7cddfSDavid du Colombier 	case TYPE:	fprintf(fd, "data typename"); break;
669*7dd7cddfSDavid du Colombier 	case TYPEDEF:	fprintf(fd, "%stypedef",Keyword); break;
670*7dd7cddfSDavid du Colombier 	case XU:	fprintf(fd, "%sx[rs]",	Keyword); break;
671*7dd7cddfSDavid du Colombier 	case UMIN:	fprintf(fd, "%s- (unary minus)", Operator); break;
672*7dd7cddfSDavid du Colombier 	case UNAME:	fprintf(fd, "a typename"); break;
673*7dd7cddfSDavid du Colombier 	case UNLESS:	fprintf(fd, "%sunless",	Keyword); break;
674219b2ee8SDavid du Colombier 	}
675219b2ee8SDavid du Colombier }
676