1219b2ee8SDavid du Colombier /***** spin: main.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 <stdlib.h>
137dd7cddfSDavid du Colombier #include "spin.h"
147dd7cddfSDavid du Colombier #include "version.h"
15*00d97012SDavid du Colombier #include <sys/types.h>
16*00d97012SDavid du Colombier #include <sys/stat.h>
177dd7cddfSDavid du Colombier #include <signal.h>
187dd7cddfSDavid du Colombier /* #include <malloc.h> */
197dd7cddfSDavid du Colombier #include <time.h>
207dd7cddfSDavid du Colombier #ifdef PC
217dd7cddfSDavid du Colombier #include <io.h>
22312a1df1SDavid du Colombier extern int unlink(const char *);
237dd7cddfSDavid du Colombier #else
24219b2ee8SDavid du Colombier #include <unistd.h>
257dd7cddfSDavid du Colombier #endif
26f3793cddSDavid du Colombier #include "y.tab.h"
27219b2ee8SDavid du Colombier
287dd7cddfSDavid du Colombier extern int DstepStart, lineno, tl_terse;
297dd7cddfSDavid du Colombier extern FILE *yyin, *yyout, *tl_out;
307dd7cddfSDavid du Colombier extern Symbol *context;
317dd7cddfSDavid du Colombier extern char *claimproc;
32312a1df1SDavid du Colombier extern void repro_src(void);
337dd7cddfSDavid du Colombier extern void qhide(int);
34*00d97012SDavid du Colombier extern char CurScope[MAXSCOPESZ];
35219b2ee8SDavid du Colombier
36219b2ee8SDavid du Colombier Symbol *Fname, *oFname;
37219b2ee8SDavid du Colombier
38312a1df1SDavid du Colombier int Etimeouts; /* nr timeouts in program */
39312a1df1SDavid du Colombier int Ntimeouts; /* nr timeouts in never claim */
40312a1df1SDavid du Colombier int analyze, columns, dumptab, has_remote, has_remvar;
41312a1df1SDavid du Colombier int interactive, jumpsteps, m_loss, nr_errs, cutoff;
42312a1df1SDavid du Colombier int s_trail, ntrail, verbose, xspin, notabs, rvopt;
43312a1df1SDavid du Colombier int no_print, no_wrapup, Caccess, limited_vis, like_java;
44312a1df1SDavid du Colombier int separate; /* separate compilation */
45312a1df1SDavid du Colombier int export_ast; /* pangen5.c */
46*00d97012SDavid du Colombier int old_scope_rules; /* use pre 5.3.0 rules */
47*00d97012SDavid du Colombier int split_decl = 1, product, Strict;
48312a1df1SDavid du Colombier
49*00d97012SDavid du Colombier int merger = 1, deadvar = 1;
50*00d97012SDavid du Colombier int ccache = 0; /* oyvind teig: 5.2.0 case caching off by default */
51312a1df1SDavid du Colombier
52312a1df1SDavid du Colombier static int preprocessonly, SeedUsed;
53*00d97012SDavid du Colombier static int seedy; /* be verbose about chosen seed */
54*00d97012SDavid du Colombier static int inlineonly; /* show inlined code */
55*00d97012SDavid du Colombier static int dataflow = 1;
56312a1df1SDavid du Colombier
577dd7cddfSDavid du Colombier #if 0
587dd7cddfSDavid du Colombier meaning of flags on verbose:
597dd7cddfSDavid du Colombier 1 -g global variable values
607dd7cddfSDavid du Colombier 2 -l local variable values
617dd7cddfSDavid du Colombier 4 -p all process actions
627dd7cddfSDavid du Colombier 8 -r receives
637dd7cddfSDavid du Colombier 16 -s sends
647dd7cddfSDavid du Colombier 32 -v verbose
657dd7cddfSDavid du Colombier 64 -w very verbose
667dd7cddfSDavid du Colombier #endif
677dd7cddfSDavid du Colombier
687dd7cddfSDavid du Colombier static char Operator[] = "operator: ";
697dd7cddfSDavid du Colombier static char Keyword[] = "keyword: ";
707dd7cddfSDavid du Colombier static char Function[] = "function-name: ";
717dd7cddfSDavid du Colombier static char **add_ltl = (char **) 0;
727dd7cddfSDavid du Colombier static char **ltl_file = (char **) 0;
737dd7cddfSDavid du Colombier static char **nvr_file = (char **) 0;
74*00d97012SDavid du Colombier static char *ltl_claims = (char *) 0;
75*00d97012SDavid du Colombier static FILE *fd_ltl = (FILE *) 0;
767dd7cddfSDavid du Colombier static char *PreArg[64];
777dd7cddfSDavid du Colombier static int PreCnt = 0;
787dd7cddfSDavid du Colombier static char out1[64];
797dd7cddfSDavid du Colombier
80*00d97012SDavid du Colombier char **trailfilename; /* new option 'k' */
81*00d97012SDavid du Colombier
82*00d97012SDavid du Colombier void explain(int);
83*00d97012SDavid du Colombier
84*00d97012SDavid du Colombier /* to use visual C++:
85*00d97012SDavid du Colombier #define CPP "CL -E/E"
86*00d97012SDavid du Colombier or call spin as: "spin -PCL -E/E"
87*00d97012SDavid du Colombier
88*00d97012SDavid du Colombier on OS2:
89*00d97012SDavid du Colombier #define CPP "icc -E/Pd+ -E/Q+"
90*00d97012SDavid du Colombier or call spin as: "spin -Picc -E/Pd+ -E/Q+"
91*00d97012SDavid du Colombier */
927dd7cddfSDavid du Colombier #ifndef CPP
93*00d97012SDavid du Colombier #if defined(PC) || defined(MAC)
94*00d97012SDavid du Colombier #define CPP "gcc -E -x c" /* most systems have gcc or cpp */
95*00d97012SDavid du Colombier /* if gcc-4 is available, this setting is modified below */
967dd7cddfSDavid du Colombier #else
977dd7cddfSDavid du Colombier #ifdef SOLARIS
987dd7cddfSDavid du Colombier #define CPP "/usr/ccs/lib/cpp"
997dd7cddfSDavid du Colombier #else
100f3793cddSDavid du Colombier #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
1017dd7cddfSDavid du Colombier #define CPP "cpp"
1027dd7cddfSDavid du Colombier #else
103312a1df1SDavid du Colombier #define CPP "/bin/cpp" /* classic Unix systems */
1047dd7cddfSDavid du Colombier #endif
1057dd7cddfSDavid du Colombier #endif
1067dd7cddfSDavid du Colombier #endif
1077dd7cddfSDavid du Colombier #endif
108*00d97012SDavid du Colombier
1097dd7cddfSDavid du Colombier static char *PreProc = CPP;
110312a1df1SDavid du Colombier extern int depth; /* at least some steps were made */
111219b2ee8SDavid du Colombier
112219b2ee8SDavid du Colombier void
alldone(int estatus)1137dd7cddfSDavid du Colombier alldone(int estatus)
1147dd7cddfSDavid du Colombier {
115312a1df1SDavid du Colombier if (preprocessonly == 0
116312a1df1SDavid du Colombier && strlen(out1) > 0)
1177dd7cddfSDavid du Colombier (void) unlink((const char *)out1);
118312a1df1SDavid du Colombier
119312a1df1SDavid du Colombier if (seedy && !analyze && !export_ast
120312a1df1SDavid du Colombier && !s_trail && !preprocessonly && depth > 0)
121312a1df1SDavid du Colombier printf("seed used: %d\n", SeedUsed);
122312a1df1SDavid du Colombier
1237dd7cddfSDavid du Colombier if (xspin && (analyze || s_trail))
1247dd7cddfSDavid du Colombier { if (estatus)
1257dd7cddfSDavid du Colombier printf("spin: %d error(s) - aborting\n",
1267dd7cddfSDavid du Colombier estatus);
1277dd7cddfSDavid du Colombier else
1287dd7cddfSDavid du Colombier printf("Exit-Status 0\n");
1297dd7cddfSDavid du Colombier }
1307dd7cddfSDavid du Colombier exit(estatus);
1317dd7cddfSDavid du Colombier }
132219b2ee8SDavid du Colombier
1337dd7cddfSDavid du Colombier void
preprocess(char * a,char * b,int a_tmp)1347dd7cddfSDavid du Colombier preprocess(char *a, char *b, int a_tmp)
135*00d97012SDavid du Colombier { char precmd[1024], cmd[2048]; int i;
136*00d97012SDavid du Colombier #if defined(WIN32) || defined(WIN64)
137*00d97012SDavid du Colombier struct _stat x;
138*00d97012SDavid du Colombier /* struct stat x; */
139*00d97012SDavid du Colombier #endif
1407dd7cddfSDavid du Colombier #ifdef PC
1417dd7cddfSDavid du Colombier extern int try_zpp(char *, char *);
142*00d97012SDavid du Colombier if (PreCnt == 0 && try_zpp(a, b))
143*00d97012SDavid du Colombier { goto out;
144*00d97012SDavid du Colombier }
145*00d97012SDavid du Colombier #endif
146*00d97012SDavid du Colombier #if defined(WIN32) || defined(WIN64)
147*00d97012SDavid du Colombier if (strncmp(PreProc, "gcc -E -x c", strlen("gcc -E -x c")) == 0)
148*00d97012SDavid du Colombier { if (stat("/bin/gcc-4.exe", (struct stat *)&x) == 0 /* for PCs with cygwin */
149*00d97012SDavid du Colombier || stat("c:/cygwin/bin/gcc-4.exe", (struct stat *)&x) == 0)
150*00d97012SDavid du Colombier { PreProc = "gcc-4 -E -x c";
151*00d97012SDavid du Colombier } else if (stat("/bin/gcc-3.exe", (struct stat *)&x) == 0
152*00d97012SDavid du Colombier || stat("c:/cygwin/bin/gcc-3.exe", (struct stat *)&x) == 0)
153*00d97012SDavid du Colombier { PreProc = "gcc-3 -E -x c";
154*00d97012SDavid du Colombier } }
1557dd7cddfSDavid du Colombier #endif
1567dd7cddfSDavid du Colombier strcpy(precmd, PreProc);
1577dd7cddfSDavid du Colombier for (i = 1; i <= PreCnt; i++)
1587dd7cddfSDavid du Colombier { strcat(precmd, " ");
1597dd7cddfSDavid du Colombier strcat(precmd, PreArg[i]);
1607dd7cddfSDavid du Colombier }
161*00d97012SDavid du Colombier if (strlen(precmd) > sizeof(precmd))
162*00d97012SDavid du Colombier { fprintf(stdout, "spin: too many -D args, aborting\n");
163*00d97012SDavid du Colombier alldone(1);
164*00d97012SDavid du Colombier }
1657dd7cddfSDavid du Colombier sprintf(cmd, "%s %s > %s", precmd, a, b);
1667dd7cddfSDavid du Colombier if (system((const char *)cmd))
1677dd7cddfSDavid du Colombier { (void) unlink((const char *) b);
1687dd7cddfSDavid du Colombier if (a_tmp) (void) unlink((const char *) a);
169312a1df1SDavid du Colombier fprintf(stdout, "spin: preprocessing failed\n"); /* 4.1.2 was stderr */
170312a1df1SDavid du Colombier alldone(1); /* no return, error exit */
1717dd7cddfSDavid du Colombier }
172312a1df1SDavid du Colombier #ifdef PC
173312a1df1SDavid du Colombier out:
174312a1df1SDavid du Colombier #endif
175312a1df1SDavid du Colombier if (a_tmp) (void) unlink((const char *) a);
1767dd7cddfSDavid du Colombier }
1777dd7cddfSDavid du Colombier
1787dd7cddfSDavid du Colombier void
usage(void)1797dd7cddfSDavid du Colombier usage(void)
1807dd7cddfSDavid du Colombier {
1817dd7cddfSDavid du Colombier printf("use: spin [-option] ... [-option] file\n");
1827dd7cddfSDavid du Colombier printf("\tNote: file must always be the last argument\n");
183312a1df1SDavid du Colombier printf("\t-A apply slicing algorithm\n");
1847dd7cddfSDavid du Colombier printf("\t-a generate a verifier in pan.c\n");
1857dd7cddfSDavid du Colombier printf("\t-B no final state details in simulations\n");
1867dd7cddfSDavid du Colombier printf("\t-b don't execute printfs in simulation\n");
187312a1df1SDavid du Colombier printf("\t-C print channel access info (combine with -g etc.)\n");
1887dd7cddfSDavid du Colombier printf("\t-c columnated -s -r simulation output\n");
189219b2ee8SDavid du Colombier printf("\t-d produce symbol-table information\n");
1907dd7cddfSDavid du Colombier printf("\t-Dyyy pass -Dyyy to the preprocessor\n");
1917dd7cddfSDavid du Colombier printf("\t-Eyyy pass yyy to the preprocessor\n");
192*00d97012SDavid du Colombier printf("\t-e compute synchronous product of multiple never claims (modified by -L)\n");
1937dd7cddfSDavid du Colombier printf("\t-f \"..formula..\" translate LTL ");
1947dd7cddfSDavid du Colombier printf("into never claim\n");
195*00d97012SDavid du Colombier printf("\t-F file like -f, but with the LTL formula stored in a 1-line file\n");
196219b2ee8SDavid du Colombier printf("\t-g print all global variables\n");
197312a1df1SDavid du Colombier printf("\t-h at end of run, print value of seed for random nr generator used\n");
198219b2ee8SDavid du Colombier printf("\t-i interactive (random simulation)\n");
199312a1df1SDavid du Colombier printf("\t-I show result of inlining and preprocessing\n");
2007dd7cddfSDavid du Colombier printf("\t-J reverse eval order of nested unlesses\n");
2017dd7cddfSDavid du Colombier printf("\t-jN skip the first N steps ");
2027dd7cddfSDavid du Colombier printf("in simulation trail\n");
203*00d97012SDavid du Colombier printf("\t-k fname use the trailfile stored in file fname, see also -t\n");
204*00d97012SDavid du Colombier printf("\t-L when using -e, use strict language intersection\n");
205219b2ee8SDavid du Colombier printf("\t-l print all local variables\n");
2067dd7cddfSDavid du Colombier printf("\t-M print msc-flow in Postscript\n");
207219b2ee8SDavid du Colombier printf("\t-m lose msgs sent to full queues\n");
208*00d97012SDavid du Colombier printf("\t-N fname use never claim stored in file fname\n");
209219b2ee8SDavid du Colombier printf("\t-nN seed for random nr generator\n");
210*00d97012SDavid du Colombier printf("\t-O use old scope rules (pre 5.3.0)\n");
2117dd7cddfSDavid du Colombier printf("\t-o1 turn off dataflow-optimizations in verifier\n");
212312a1df1SDavid du Colombier printf("\t-o2 don't hide write-only variables in verifier\n");
2137dd7cddfSDavid du Colombier printf("\t-o3 turn off statement merging in verifier\n");
214*00d97012SDavid du Colombier printf("\t-o4 turn on rendezvous optiomizations in verifier\n");
215*00d97012SDavid du Colombier printf("\t-o5 turn on case caching (reduces size of pan.m, but affects reachability reports)\n");
2167dd7cddfSDavid du Colombier printf("\t-Pxxx use xxx for preprocessing\n");
217219b2ee8SDavid du Colombier printf("\t-p print all statements\n");
2187dd7cddfSDavid du Colombier printf("\t-qN suppress io for queue N in printouts\n");
219219b2ee8SDavid du Colombier printf("\t-r print receive events\n");
220312a1df1SDavid du Colombier printf("\t-S1 and -S2 separate pan source for claim and model\n");
221219b2ee8SDavid du Colombier printf("\t-s print send events\n");
222312a1df1SDavid du Colombier printf("\t-T do not indent printf output\n");
223*00d97012SDavid du Colombier printf("\t-t[N] follow [Nth] simulation trail, see also -k\n");
224312a1df1SDavid du Colombier printf("\t-Uyyy pass -Uyyy to the preprocessor\n");
225312a1df1SDavid du Colombier printf("\t-uN stop a simulation run after N steps\n");
226219b2ee8SDavid du Colombier printf("\t-v verbose, more warnings\n");
2277dd7cddfSDavid du Colombier printf("\t-w very verbose (when combined with -l or -g)\n");
2287dd7cddfSDavid du Colombier printf("\t-[XYZ] reserved for use by xspin interface\n");
229219b2ee8SDavid du Colombier printf("\t-V print version number and exit\n");
2307dd7cddfSDavid du Colombier alldone(1);
2317dd7cddfSDavid du Colombier }
2327dd7cddfSDavid du Colombier
2337dd7cddfSDavid du Colombier void
optimizations(int nr)234*00d97012SDavid du Colombier optimizations(int nr)
2357dd7cddfSDavid du Colombier {
2367dd7cddfSDavid du Colombier switch (nr) {
2377dd7cddfSDavid du Colombier case '1':
2387dd7cddfSDavid du Colombier dataflow = 1 - dataflow; /* dataflow */
2397dd7cddfSDavid du Colombier if (verbose&32)
2407dd7cddfSDavid du Colombier printf("spin: dataflow optimizations turned %s\n",
2417dd7cddfSDavid du Colombier dataflow?"on":"off");
2427dd7cddfSDavid du Colombier break;
2437dd7cddfSDavid du Colombier case '2':
2447dd7cddfSDavid du Colombier /* dead variable elimination */
2457dd7cddfSDavid du Colombier deadvar = 1 - deadvar;
2467dd7cddfSDavid du Colombier if (verbose&32)
2477dd7cddfSDavid du Colombier printf("spin: dead variable elimination turned %s\n",
2487dd7cddfSDavid du Colombier deadvar?"on":"off");
2497dd7cddfSDavid du Colombier break;
2507dd7cddfSDavid du Colombier case '3':
2517dd7cddfSDavid du Colombier /* statement merging */
2527dd7cddfSDavid du Colombier merger = 1 - merger;
2537dd7cddfSDavid du Colombier if (verbose&32)
2547dd7cddfSDavid du Colombier printf("spin: statement merging turned %s\n",
2557dd7cddfSDavid du Colombier merger?"on":"off");
2567dd7cddfSDavid du Colombier break;
2577dd7cddfSDavid du Colombier
2587dd7cddfSDavid du Colombier case '4':
2597dd7cddfSDavid du Colombier /* rv optimization */
2607dd7cddfSDavid du Colombier rvopt = 1 - rvopt;
2617dd7cddfSDavid du Colombier if (verbose&32)
2627dd7cddfSDavid du Colombier printf("spin: rendezvous optimization turned %s\n",
2637dd7cddfSDavid du Colombier rvopt?"on":"off");
2647dd7cddfSDavid du Colombier break;
2657dd7cddfSDavid du Colombier case '5':
2667dd7cddfSDavid du Colombier /* case caching */
2677dd7cddfSDavid du Colombier ccache = 1 - ccache;
2687dd7cddfSDavid du Colombier if (verbose&32)
2697dd7cddfSDavid du Colombier printf("spin: case caching turned %s\n",
2707dd7cddfSDavid du Colombier ccache?"on":"off");
2717dd7cddfSDavid du Colombier break;
2727dd7cddfSDavid du Colombier default:
2737dd7cddfSDavid du Colombier printf("spin: bad or missing parameter on -o\n");
2747dd7cddfSDavid du Colombier usage();
2757dd7cddfSDavid du Colombier break;
2767dd7cddfSDavid du Colombier }
2777dd7cddfSDavid du Colombier }
2787dd7cddfSDavid du Colombier
2797dd7cddfSDavid du Colombier int
main(int argc,char * argv[])2807dd7cddfSDavid du Colombier main(int argc, char *argv[])
281312a1df1SDavid du Colombier { Symbol *s;
2827dd7cddfSDavid du Colombier int T = (int) time((time_t *)0);
2837dd7cddfSDavid du Colombier int usedopts = 0;
2847dd7cddfSDavid du Colombier extern void ana_src(int, int);
2857dd7cddfSDavid du Colombier
2867dd7cddfSDavid du Colombier yyin = stdin;
2877dd7cddfSDavid du Colombier yyout = stdout;
2887dd7cddfSDavid du Colombier tl_out = stdout;
289*00d97012SDavid du Colombier strcpy(CurScope, "_");
2907dd7cddfSDavid du Colombier
291*00d97012SDavid du Colombier /* unused flags: y, z, G, L, Q, R, W */
2927dd7cddfSDavid du Colombier while (argc > 1 && argv[1][0] == '-')
2937dd7cddfSDavid du Colombier { switch (argv[1][1]) {
2947dd7cddfSDavid du Colombier /* generate code for separate compilation: S1 or S2 */
2957dd7cddfSDavid du Colombier case 'S': separate = atoi(&argv[1][2]);
2967dd7cddfSDavid du Colombier /* fall through */
2977dd7cddfSDavid du Colombier case 'a': analyze = 1; break;
298312a1df1SDavid du Colombier case 'A': export_ast = 1; break;
2997dd7cddfSDavid du Colombier case 'B': no_wrapup = 1; break;
3007dd7cddfSDavid du Colombier case 'b': no_print = 1; break;
3017dd7cddfSDavid du Colombier case 'C': Caccess = 1; break;
3027dd7cddfSDavid du Colombier case 'c': columns = 1; break;
3037dd7cddfSDavid du Colombier case 'D': PreArg[++PreCnt] = (char *) &argv[1][0];
304312a1df1SDavid du Colombier break; /* define */
3057dd7cddfSDavid du Colombier case 'd': dumptab = 1; break;
3067dd7cddfSDavid du Colombier case 'E': PreArg[++PreCnt] = (char *) &argv[1][2];
3077dd7cddfSDavid du Colombier break;
308*00d97012SDavid du Colombier case 'e': product++; break; /* see also 'L' */
3097dd7cddfSDavid du Colombier case 'F': ltl_file = (char **) (argv+2);
3107dd7cddfSDavid du Colombier argc--; argv++; break;
3117dd7cddfSDavid du Colombier case 'f': add_ltl = (char **) argv;
3127dd7cddfSDavid du Colombier argc--; argv++; break;
3137dd7cddfSDavid du Colombier case 'g': verbose += 1; break;
314312a1df1SDavid du Colombier case 'h': seedy = 1; break;
3157dd7cddfSDavid du Colombier case 'i': interactive = 1; break;
316312a1df1SDavid du Colombier case 'I': inlineonly = 1; break;
3177dd7cddfSDavid du Colombier case 'J': like_java = 1; break;
3187dd7cddfSDavid du Colombier case 'j': jumpsteps = atoi(&argv[1][2]); break;
319*00d97012SDavid du Colombier case 'k': s_trail = 1;
320*00d97012SDavid du Colombier trailfilename = (char **) (argv+2);
321*00d97012SDavid du Colombier argc--; argv++; break;
322*00d97012SDavid du Colombier case 'L': Strict++; break; /* modified -e */
3237dd7cddfSDavid du Colombier case 'l': verbose += 2; break;
3247dd7cddfSDavid du Colombier case 'M': columns = 2; break;
3257dd7cddfSDavid du Colombier case 'm': m_loss = 1; break;
3267dd7cddfSDavid du Colombier case 'N': nvr_file = (char **) (argv+2);
3277dd7cddfSDavid du Colombier argc--; argv++; break;
3287dd7cddfSDavid du Colombier case 'n': T = atoi(&argv[1][2]); tl_terse = 1; break;
329*00d97012SDavid du Colombier case 'O': old_scope_rules = 1; break;
3307dd7cddfSDavid du Colombier case 'o': optimizations(argv[1][2]);
3317dd7cddfSDavid du Colombier usedopts = 1; break;
3327dd7cddfSDavid du Colombier case 'P': PreProc = (char *) &argv[1][2]; break;
3337dd7cddfSDavid du Colombier case 'p': verbose += 4; break;
334*00d97012SDavid du Colombier case 'q': if (isdigit((int) argv[1][2]))
3357dd7cddfSDavid du Colombier qhide(atoi(&argv[1][2]));
3367dd7cddfSDavid du Colombier break;
3377dd7cddfSDavid du Colombier case 'r': verbose += 8; break;
3387dd7cddfSDavid du Colombier case 's': verbose += 16; break;
339312a1df1SDavid du Colombier case 'T': notabs = 1; break;
3407dd7cddfSDavid du Colombier case 't': s_trail = 1;
341*00d97012SDavid du Colombier if (isdigit((int)argv[1][2]))
3427dd7cddfSDavid du Colombier ntrail = atoi(&argv[1][2]);
3437dd7cddfSDavid du Colombier break;
344312a1df1SDavid du Colombier case 'U': PreArg[++PreCnt] = (char *) &argv[1][0];
345312a1df1SDavid du Colombier break; /* undefine */
346312a1df1SDavid du Colombier case 'u': cutoff = atoi(&argv[1][2]); break; /* new 3.4.14 */
3477dd7cddfSDavid du Colombier case 'v': verbose += 32; break;
348*00d97012SDavid du Colombier case 'V': printf("%s\n", SpinVersion);
3497dd7cddfSDavid du Colombier alldone(0);
3507dd7cddfSDavid du Colombier break;
3517dd7cddfSDavid du Colombier case 'w': verbose += 64; break;
352*00d97012SDavid du Colombier #if 0
353*00d97012SDavid du Colombier case 'x': split_decl = 0; break; /* experimental */
354*00d97012SDavid du Colombier #endif
355312a1df1SDavid du Colombier case 'X': xspin = notabs = 1;
3567dd7cddfSDavid du Colombier #ifndef PC
3577dd7cddfSDavid du Colombier signal(SIGPIPE, alldone); /* not posix... */
3587dd7cddfSDavid du Colombier #endif
3597dd7cddfSDavid du Colombier break;
3607dd7cddfSDavid du Colombier case 'Y': limited_vis = 1; break; /* used by xspin */
3617dd7cddfSDavid du Colombier case 'Z': preprocessonly = 1; break; /* used by xspin */
3627dd7cddfSDavid du Colombier
3637dd7cddfSDavid du Colombier default : usage(); break;
364219b2ee8SDavid du Colombier }
365f3793cddSDavid du Colombier argc--; argv++;
366219b2ee8SDavid du Colombier }
367*00d97012SDavid du Colombier
3687dd7cddfSDavid du Colombier if (usedopts && !analyze)
3697dd7cddfSDavid du Colombier printf("spin: warning -o[123] option ignored in simulations\n");
370219b2ee8SDavid du Colombier
3717dd7cddfSDavid du Colombier if (ltl_file)
3727dd7cddfSDavid du Colombier { char formula[4096];
3737dd7cddfSDavid du Colombier add_ltl = ltl_file-2; add_ltl[1][1] = 'f';
3747dd7cddfSDavid du Colombier if (!(tl_out = fopen(*ltl_file, "r")))
3757dd7cddfSDavid du Colombier { printf("spin: cannot open %s\n", *ltl_file);
3767dd7cddfSDavid du Colombier alldone(1);
377219b2ee8SDavid du Colombier }
378*00d97012SDavid du Colombier if (!fgets(formula, 4096, tl_out))
379*00d97012SDavid du Colombier { printf("spin: cannot read %s\n", *ltl_file);
380*00d97012SDavid du Colombier }
3817dd7cddfSDavid du Colombier fclose(tl_out);
3827dd7cddfSDavid du Colombier tl_out = stdout;
3837dd7cddfSDavid du Colombier *ltl_file = (char *) formula;
3847dd7cddfSDavid du Colombier }
3857dd7cddfSDavid du Colombier if (argc > 1)
386*00d97012SDavid du Colombier { FILE *fd = stdout;
387*00d97012SDavid du Colombier char cmd[512], out2[512];
388312a1df1SDavid du Colombier
389312a1df1SDavid du Colombier /* must remain in current dir */
390312a1df1SDavid du Colombier strcpy(out1, "pan.pre");
391312a1df1SDavid du Colombier
3927dd7cddfSDavid du Colombier if (add_ltl || nvr_file)
393*00d97012SDavid du Colombier { sprintf(out2, "%s.nvr", argv[1]);
394*00d97012SDavid du Colombier if ((fd = fopen(out2, MFLAGS)) == NULL)
395*00d97012SDavid du Colombier { printf("spin: cannot create tmp file %s\n",
396*00d97012SDavid du Colombier out2);
3977dd7cddfSDavid du Colombier alldone(1);
3987dd7cddfSDavid du Colombier }
399*00d97012SDavid du Colombier fprintf(fd, "#include \"%s\"\n", argv[1]);
400*00d97012SDavid du Colombier }
401*00d97012SDavid du Colombier
402*00d97012SDavid du Colombier if (add_ltl)
403*00d97012SDavid du Colombier { tl_out = fd;
404*00d97012SDavid du Colombier nr_errs = tl_main(2, add_ltl);
405*00d97012SDavid du Colombier fclose(fd);
406*00d97012SDavid du Colombier preprocess(out2, out1, 1);
407*00d97012SDavid du Colombier } else if (nvr_file)
408*00d97012SDavid du Colombier { fprintf(fd, "#include \"%s\"\n", *nvr_file);
4097dd7cddfSDavid du Colombier fclose(fd);
4107dd7cddfSDavid du Colombier preprocess(out2, out1, 1);
4117dd7cddfSDavid du Colombier } else
412*00d97012SDavid du Colombier { preprocess(argv[1], out1, 0);
413*00d97012SDavid du Colombier }
4147dd7cddfSDavid du Colombier
4157dd7cddfSDavid du Colombier if (preprocessonly)
4167dd7cddfSDavid du Colombier alldone(0);
417312a1df1SDavid du Colombier
4187dd7cddfSDavid du Colombier if (!(yyin = fopen(out1, "r")))
4197dd7cddfSDavid du Colombier { printf("spin: cannot open %s\n", out1);
4207dd7cddfSDavid du Colombier alldone(1);
4217dd7cddfSDavid du Colombier }
4227dd7cddfSDavid du Colombier
423*00d97012SDavid du Colombier if (strncmp(argv[1], "progress", (size_t) 8) == 0
424*00d97012SDavid du Colombier || strncmp(argv[1], "accept", (size_t) 6) == 0)
4257dd7cddfSDavid du Colombier sprintf(cmd, "_%s", argv[1]);
4267dd7cddfSDavid du Colombier else
4277dd7cddfSDavid du Colombier strcpy(cmd, argv[1]);
4287dd7cddfSDavid du Colombier oFname = Fname = lookup(cmd);
429219b2ee8SDavid du Colombier if (oFname->name[0] == '\"')
430312a1df1SDavid du Colombier { int i = (int) strlen(oFname->name);
431219b2ee8SDavid du Colombier oFname->name[i-1] = '\0';
432219b2ee8SDavid du Colombier oFname = lookup(&oFname->name[1]);
433219b2ee8SDavid du Colombier }
434219b2ee8SDavid du Colombier } else
4357dd7cddfSDavid du Colombier { oFname = Fname = lookup("<stdin>");
4367dd7cddfSDavid du Colombier if (add_ltl)
4377dd7cddfSDavid du Colombier { if (argc > 0)
4387dd7cddfSDavid du Colombier exit(tl_main(2, add_ltl));
4397dd7cddfSDavid du Colombier printf("spin: missing argument to -f\n");
4407dd7cddfSDavid du Colombier alldone(1);
4417dd7cddfSDavid du Colombier }
442*00d97012SDavid du Colombier printf("%s\n", SpinVersion);
443*00d97012SDavid du Colombier fprintf(stderr, "spin: error, no filename specified");
4447dd7cddfSDavid du Colombier fflush(stdout);
445*00d97012SDavid du Colombier alldone(1);
4467dd7cddfSDavid du Colombier }
4477dd7cddfSDavid du Colombier if (columns == 2)
4487dd7cddfSDavid du Colombier { extern void putprelude(void);
4497dd7cddfSDavid du Colombier if (xspin || verbose&(1|4|8|16|32))
4507dd7cddfSDavid du Colombier { printf("spin: -c precludes all flags except -t\n");
4517dd7cddfSDavid du Colombier alldone(1);
4527dd7cddfSDavid du Colombier }
4537dd7cddfSDavid du Colombier putprelude();
4547dd7cddfSDavid du Colombier }
4557dd7cddfSDavid du Colombier if (columns && !(verbose&8) && !(verbose&16))
4567dd7cddfSDavid du Colombier verbose += (8+16);
4577dd7cddfSDavid du Colombier if (columns == 2 && limited_vis)
4587dd7cddfSDavid du Colombier verbose += (1+4);
459*00d97012SDavid du Colombier Srand((unsigned int) T); /* defined in run.c */
460312a1df1SDavid du Colombier SeedUsed = T;
461312a1df1SDavid du Colombier s = lookup("_"); s->type = PREDEF; /* write-only global var */
462219b2ee8SDavid du Colombier s = lookup("_p"); s->type = PREDEF;
463219b2ee8SDavid du Colombier s = lookup("_pid"); s->type = PREDEF;
464219b2ee8SDavid du Colombier s = lookup("_last"); s->type = PREDEF;
4657dd7cddfSDavid du Colombier s = lookup("_nr_pr"); s->type = PREDEF; /* new 3.3.10 */
466312a1df1SDavid du Colombier
467219b2ee8SDavid du Colombier yyparse();
4687dd7cddfSDavid du Colombier fclose(yyin);
469*00d97012SDavid du Colombier
470*00d97012SDavid du Colombier if (ltl_claims)
471*00d97012SDavid du Colombier { Symbol *r;
472*00d97012SDavid du Colombier fclose(fd_ltl);
473*00d97012SDavid du Colombier if (!(yyin = fopen(ltl_claims, "r")))
474*00d97012SDavid du Colombier { fatal("cannot open %s", ltl_claims);
475*00d97012SDavid du Colombier }
476*00d97012SDavid du Colombier r = oFname;
477*00d97012SDavid du Colombier oFname = Fname = lookup(ltl_claims);
478*00d97012SDavid du Colombier lineno = 0;
479*00d97012SDavid du Colombier yyparse();
480*00d97012SDavid du Colombier fclose(yyin);
481*00d97012SDavid du Colombier oFname = Fname = r;
482*00d97012SDavid du Colombier if (0)
483*00d97012SDavid du Colombier { (void) unlink(ltl_claims);
484*00d97012SDavid du Colombier } }
485*00d97012SDavid du Colombier
486312a1df1SDavid du Colombier loose_ends();
487312a1df1SDavid du Colombier
488312a1df1SDavid du Colombier if (inlineonly)
489312a1df1SDavid du Colombier { repro_src();
490312a1df1SDavid du Colombier return 0;
491312a1df1SDavid du Colombier }
492312a1df1SDavid du Colombier
4937dd7cddfSDavid du Colombier chanaccess();
494312a1df1SDavid du Colombier if (!Caccess)
495312a1df1SDavid du Colombier { if (!s_trail && (dataflow || merger))
4967dd7cddfSDavid du Colombier ana_src(dataflow, merger);
4977dd7cddfSDavid du Colombier sched();
4987dd7cddfSDavid du Colombier alldone(nr_errs);
499312a1df1SDavid du Colombier }
500312a1df1SDavid du Colombier return 0;
501219b2ee8SDavid du Colombier }
502219b2ee8SDavid du Colombier
503*00d97012SDavid du Colombier void
ltl_list(char * nm,char * fm)504*00d97012SDavid du Colombier ltl_list(char *nm, char *fm)
505*00d97012SDavid du Colombier {
506*00d97012SDavid du Colombier if (analyze || dumptab) /* when generating pan.c only */
507*00d97012SDavid du Colombier { if (!ltl_claims)
508*00d97012SDavid du Colombier { ltl_claims = "_spin_nvr.tmp";
509*00d97012SDavid du Colombier if ((fd_ltl = fopen(ltl_claims, MFLAGS)) == NULL)
510*00d97012SDavid du Colombier { fatal("cannot open tmp file %s", ltl_claims);
511*00d97012SDavid du Colombier }
512*00d97012SDavid du Colombier tl_out = fd_ltl;
513*00d97012SDavid du Colombier }
514*00d97012SDavid du Colombier
515*00d97012SDavid du Colombier add_ltl = (char **) emalloc(5 * sizeof(char *));
516*00d97012SDavid du Colombier add_ltl[1] = "-c";
517*00d97012SDavid du Colombier add_ltl[2] = nm;
518*00d97012SDavid du Colombier add_ltl[3] = "-f";
519*00d97012SDavid du Colombier add_ltl[4] = (char *) emalloc(strlen(fm)+4);
520*00d97012SDavid du Colombier strcpy(add_ltl[4], "!(");
521*00d97012SDavid du Colombier strcat(add_ltl[4], fm);
522*00d97012SDavid du Colombier strcat(add_ltl[4], ")");
523*00d97012SDavid du Colombier /* add_ltl[4] = fm; */
524*00d97012SDavid du Colombier
525*00d97012SDavid du Colombier nr_errs += tl_main(4, add_ltl);
526*00d97012SDavid du Colombier
527*00d97012SDavid du Colombier fflush(tl_out);
528*00d97012SDavid du Colombier /* should read this file after the main file is read */
529*00d97012SDavid du Colombier }
530*00d97012SDavid du Colombier }
531*00d97012SDavid du Colombier
532219b2ee8SDavid du Colombier int
yywrap(void)533219b2ee8SDavid du Colombier yywrap(void) /* dummy routine */
534219b2ee8SDavid du Colombier {
535219b2ee8SDavid du Colombier return 1;
536219b2ee8SDavid du Colombier }
537219b2ee8SDavid du Colombier
538219b2ee8SDavid du Colombier void
non_fatal(char * s1,char * s2)539219b2ee8SDavid du Colombier non_fatal(char *s1, char *s2)
5407dd7cddfSDavid du Colombier { extern char yytext[];
541219b2ee8SDavid du Colombier
542*00d97012SDavid du Colombier printf("spin: %s:%d, Error: ",
543*00d97012SDavid du Colombier oFname?oFname->name:"nofilename", lineno);
544219b2ee8SDavid du Colombier if (s2)
545219b2ee8SDavid du Colombier printf(s1, s2);
546219b2ee8SDavid du Colombier else
547219b2ee8SDavid du Colombier printf(s1);
548*00d97012SDavid du Colombier if (strlen(yytext)>1)
549219b2ee8SDavid du Colombier printf(" near '%s'", yytext);
5507dd7cddfSDavid du Colombier printf("\n");
551219b2ee8SDavid du Colombier nr_errs++;
552219b2ee8SDavid du Colombier }
553219b2ee8SDavid du Colombier
554219b2ee8SDavid du Colombier void
fatal(char * s1,char * s2)555219b2ee8SDavid du Colombier fatal(char *s1, char *s2)
556219b2ee8SDavid du Colombier {
557219b2ee8SDavid du Colombier non_fatal(s1, s2);
558*00d97012SDavid du Colombier (void) unlink("pan.b");
559*00d97012SDavid du Colombier (void) unlink("pan.c");
560*00d97012SDavid du Colombier (void) unlink("pan.h");
561*00d97012SDavid du Colombier (void) unlink("pan.m");
562*00d97012SDavid du Colombier (void) unlink("pan.t");
563*00d97012SDavid du Colombier (void) unlink("pan.pre");
5647dd7cddfSDavid du Colombier alldone(1);
565219b2ee8SDavid du Colombier }
566219b2ee8SDavid du Colombier
567219b2ee8SDavid du Colombier char *
emalloc(size_t n)568*00d97012SDavid du Colombier emalloc(size_t n)
569219b2ee8SDavid du Colombier { char *tmp;
570*00d97012SDavid du Colombier static unsigned long cnt = 0;
571219b2ee8SDavid du Colombier
572f3793cddSDavid du Colombier if (n == 0)
573f3793cddSDavid du Colombier return NULL; /* robert shelton 10/20/06 */
574f3793cddSDavid du Colombier
575219b2ee8SDavid du Colombier if (!(tmp = (char *) malloc(n)))
576*00d97012SDavid du Colombier { printf("spin: allocated %ld Gb, wanted %d bytes more\n",
577*00d97012SDavid du Colombier cnt/(1024*1024*1024), (int) n);
578219b2ee8SDavid du Colombier fatal("not enough memory", (char *)0);
579*00d97012SDavid du Colombier }
580*00d97012SDavid du Colombier cnt += (unsigned long) n;
581219b2ee8SDavid du Colombier memset(tmp, 0, n);
582219b2ee8SDavid du Colombier return tmp;
583219b2ee8SDavid du Colombier }
584219b2ee8SDavid du Colombier
5857dd7cddfSDavid du Colombier void
trapwonly(Lextok * n)586*00d97012SDavid du Colombier trapwonly(Lextok *n /* , char *unused */)
5877dd7cddfSDavid du Colombier { extern int realread;
5887dd7cddfSDavid du Colombier short i = (n->sym)?n->sym->type:0;
5897dd7cddfSDavid du Colombier
5907dd7cddfSDavid du Colombier if (i != MTYPE
5917dd7cddfSDavid du Colombier && i != BIT
5927dd7cddfSDavid du Colombier && i != BYTE
5937dd7cddfSDavid du Colombier && i != SHORT
5947dd7cddfSDavid du Colombier && i != INT
5957dd7cddfSDavid du Colombier && i != UNSIGNED)
5967dd7cddfSDavid du Colombier return;
5977dd7cddfSDavid du Colombier
5987dd7cddfSDavid du Colombier if (realread)
599f3793cddSDavid du Colombier n->sym->hidden |= 128; /* var is read at least once */
6007dd7cddfSDavid du Colombier }
6017dd7cddfSDavid du Colombier
6027dd7cddfSDavid du Colombier void
setaccess(Symbol * sp,Symbol * what,int cnt,int t)6037dd7cddfSDavid du Colombier setaccess(Symbol *sp, Symbol *what, int cnt, int t)
6047dd7cddfSDavid du Colombier { Access *a;
6057dd7cddfSDavid du Colombier
6067dd7cddfSDavid du Colombier for (a = sp->access; a; a = a->lnk)
6077dd7cddfSDavid du Colombier if (a->who == context
6087dd7cddfSDavid du Colombier && a->what == what
6097dd7cddfSDavid du Colombier && a->cnt == cnt
6107dd7cddfSDavid du Colombier && a->typ == t)
6117dd7cddfSDavid du Colombier return;
6127dd7cddfSDavid du Colombier
6137dd7cddfSDavid du Colombier a = (Access *) emalloc(sizeof(Access));
6147dd7cddfSDavid du Colombier a->who = context;
6157dd7cddfSDavid du Colombier a->what = what;
6167dd7cddfSDavid du Colombier a->cnt = cnt;
6177dd7cddfSDavid du Colombier a->typ = t;
6187dd7cddfSDavid du Colombier a->lnk = sp->access;
6197dd7cddfSDavid du Colombier sp->access = a;
6207dd7cddfSDavid du Colombier }
6217dd7cddfSDavid du Colombier
622219b2ee8SDavid du Colombier Lextok *
nn(Lextok * s,int t,Lextok * ll,Lextok * rl)623219b2ee8SDavid du Colombier nn(Lextok *s, int t, Lextok *ll, Lextok *rl)
624219b2ee8SDavid du Colombier { Lextok *n = (Lextok *) emalloc(sizeof(Lextok));
625312a1df1SDavid du Colombier static int warn_nn = 0;
626219b2ee8SDavid du Colombier
627*00d97012SDavid du Colombier n->uiid = is_inline(); /* record origin of the statement */
6287dd7cddfSDavid du Colombier n->ntyp = (short) t;
629219b2ee8SDavid du Colombier if (s && s->fn)
630219b2ee8SDavid du Colombier { n->ln = s->ln;
631219b2ee8SDavid du Colombier n->fn = s->fn;
632219b2ee8SDavid du Colombier } else if (rl && rl->fn)
633219b2ee8SDavid du Colombier { n->ln = rl->ln;
634219b2ee8SDavid du Colombier n->fn = rl->fn;
635219b2ee8SDavid du Colombier } else if (ll && ll->fn)
636219b2ee8SDavid du Colombier { n->ln = ll->ln;
637219b2ee8SDavid du Colombier n->fn = ll->fn;
638219b2ee8SDavid du Colombier } else
639219b2ee8SDavid du Colombier { n->ln = lineno;
640219b2ee8SDavid du Colombier n->fn = Fname;
641219b2ee8SDavid du Colombier }
642219b2ee8SDavid du Colombier if (s) n->sym = s->sym;
643219b2ee8SDavid du Colombier n->lft = ll;
644219b2ee8SDavid du Colombier n->rgt = rl;
645219b2ee8SDavid du Colombier n->indstep = DstepStart;
646219b2ee8SDavid du Colombier
647219b2ee8SDavid du Colombier if (t == TIMEOUT) Etimeouts++;
648219b2ee8SDavid du Colombier
6497dd7cddfSDavid du Colombier if (!context) return n;
6507dd7cddfSDavid du Colombier
6517dd7cddfSDavid du Colombier if (t == 'r' || t == 's')
6527dd7cddfSDavid du Colombier setaccess(n->sym, ZS, 0, t);
6537dd7cddfSDavid du Colombier if (t == 'R')
6547dd7cddfSDavid du Colombier setaccess(n->sym, ZS, 0, 'P');
6557dd7cddfSDavid du Colombier
656219b2ee8SDavid du Colombier if (context->name == claimproc)
6577dd7cddfSDavid du Colombier { int forbidden = separate;
6587dd7cddfSDavid du Colombier switch (t) {
6597dd7cddfSDavid du Colombier case ASGN:
6607dd7cddfSDavid du Colombier printf("spin: Warning, never claim has side-effect\n");
6617dd7cddfSDavid du Colombier break;
6627dd7cddfSDavid du Colombier case 'r': case 's':
6637dd7cddfSDavid du Colombier non_fatal("never claim contains i/o stmnts",(char *)0);
664219b2ee8SDavid du Colombier break;
665219b2ee8SDavid du Colombier case TIMEOUT:
666219b2ee8SDavid du Colombier /* never claim polls timeout */
6677dd7cddfSDavid du Colombier if (Ntimeouts && Etimeouts)
6687dd7cddfSDavid du Colombier forbidden = 0;
669219b2ee8SDavid du Colombier Ntimeouts++; Etimeouts--;
670219b2ee8SDavid du Colombier break;
671219b2ee8SDavid du Colombier case LEN: case EMPTY: case FULL:
672219b2ee8SDavid du Colombier case 'R': case NFULL: case NEMPTY:
6737dd7cddfSDavid du Colombier /* status becomes non-exclusive */
6747dd7cddfSDavid du Colombier if (n->sym && !(n->sym->xu&XX))
6757dd7cddfSDavid du Colombier { n->sym->xu |= XX;
6767dd7cddfSDavid du Colombier if (separate == 2) {
6777dd7cddfSDavid du Colombier printf("spin: warning, make sure that the S1 model\n");
6787dd7cddfSDavid du Colombier printf(" also polls channel '%s' in its claim\n",
6797dd7cddfSDavid du Colombier n->sym->name);
6807dd7cddfSDavid du Colombier } }
6817dd7cddfSDavid du Colombier forbidden = 0;
682219b2ee8SDavid du Colombier break;
683312a1df1SDavid du Colombier case 'c':
684312a1df1SDavid du Colombier AST_track(n, 0); /* register as a slice criterion */
685312a1df1SDavid du Colombier /* fall thru */
686219b2ee8SDavid du Colombier default:
6877dd7cddfSDavid du Colombier forbidden = 0;
688219b2ee8SDavid du Colombier break;
689219b2ee8SDavid du Colombier }
6907dd7cddfSDavid du Colombier if (forbidden)
6917dd7cddfSDavid du Colombier { printf("spin: never, saw "); explain(t); printf("\n");
6927dd7cddfSDavid du Colombier fatal("incompatible with separate compilation",(char *)0);
6937dd7cddfSDavid du Colombier }
694312a1df1SDavid du Colombier } else if ((t == ENABLED || t == PC_VAL) && !(warn_nn&t))
695312a1df1SDavid du Colombier { printf("spin: Warning, using %s outside never claim\n",
6967dd7cddfSDavid du Colombier (t == ENABLED)?"enabled()":"pc_value()");
697312a1df1SDavid du Colombier warn_nn |= t;
6987dd7cddfSDavid du Colombier } else if (t == NONPROGRESS)
699312a1df1SDavid du Colombier { fatal("spin: Error, using np_ outside never claim\n", (char *)0);
7007dd7cddfSDavid du Colombier }
701219b2ee8SDavid du Colombier return n;
702219b2ee8SDavid du Colombier }
703219b2ee8SDavid du Colombier
704219b2ee8SDavid du Colombier Lextok *
rem_lab(Symbol * a,Lextok * b,Symbol * c)705312a1df1SDavid du Colombier rem_lab(Symbol *a, Lextok *b, Symbol *c) /* proctype name, pid, label name */
706219b2ee8SDavid du Colombier { Lextok *tmp1, *tmp2, *tmp3;
707219b2ee8SDavid du Colombier
708219b2ee8SDavid du Colombier has_remote++;
709312a1df1SDavid du Colombier c->type = LABEL; /* refered to in global context here */
710312a1df1SDavid du Colombier fix_dest(c, a); /* in case target of rem_lab is jump */
711219b2ee8SDavid du Colombier tmp1 = nn(ZN, '?', b, ZN); tmp1->sym = a;
712219b2ee8SDavid du Colombier tmp1 = nn(ZN, 'p', tmp1, ZN);
713219b2ee8SDavid du Colombier tmp1->sym = lookup("_p");
714219b2ee8SDavid du Colombier tmp2 = nn(ZN, NAME, ZN, ZN); tmp2->sym = a;
715219b2ee8SDavid du Colombier tmp3 = nn(ZN, 'q', tmp2, ZN); tmp3->sym = c;
716219b2ee8SDavid du Colombier return nn(ZN, EQ, tmp1, tmp3);
717312a1df1SDavid du Colombier #if 0
718312a1df1SDavid du Colombier .---------------EQ-------.
719312a1df1SDavid du Colombier / \
720312a1df1SDavid du Colombier 'p' -sym-> _p 'q' -sym-> c (label name)
721312a1df1SDavid du Colombier / /
722312a1df1SDavid du Colombier '?' -sym-> a (proctype) NAME -sym-> a (proctype name)
723312a1df1SDavid du Colombier /
724312a1df1SDavid du Colombier b (pid expr)
725312a1df1SDavid du Colombier #endif
726312a1df1SDavid du Colombier }
727312a1df1SDavid du Colombier
728312a1df1SDavid du Colombier Lextok *
rem_var(Symbol * a,Lextok * b,Symbol * c,Lextok * ndx)729312a1df1SDavid du Colombier rem_var(Symbol *a, Lextok *b, Symbol *c, Lextok *ndx)
730312a1df1SDavid du Colombier { Lextok *tmp1;
731312a1df1SDavid du Colombier
732312a1df1SDavid du Colombier has_remote++;
733312a1df1SDavid du Colombier has_remvar++;
734312a1df1SDavid du Colombier dataflow = 0; /* turn off dead variable resets 4.2.5 */
735312a1df1SDavid du Colombier tmp1 = nn(ZN, '?', b, ZN); tmp1->sym = a;
736312a1df1SDavid du Colombier tmp1 = nn(ZN, 'p', tmp1, ndx);
737312a1df1SDavid du Colombier tmp1->sym = c;
738312a1df1SDavid du Colombier return tmp1;
739312a1df1SDavid du Colombier #if 0
740312a1df1SDavid du Colombier cannot refer to struct elements
741312a1df1SDavid du Colombier only to scalars and arrays
742312a1df1SDavid du Colombier
743312a1df1SDavid du Colombier 'p' -sym-> c (variable name)
744312a1df1SDavid du Colombier / \______ possible arrayindex on c
745312a1df1SDavid du Colombier /
746312a1df1SDavid du Colombier '?' -sym-> a (proctype)
747312a1df1SDavid du Colombier /
748312a1df1SDavid du Colombier b (pid expr)
749312a1df1SDavid du Colombier #endif
750219b2ee8SDavid du Colombier }
751219b2ee8SDavid du Colombier
752*00d97012SDavid du Colombier void
explain(int n)753219b2ee8SDavid du Colombier explain(int n)
7547dd7cddfSDavid du Colombier { FILE *fd = stdout;
755219b2ee8SDavid du Colombier switch (n) {
756219b2ee8SDavid du Colombier default: if (n > 0 && n < 256)
757*00d97012SDavid du Colombier fprintf(fd, "'%c' = ", n);
758*00d97012SDavid du Colombier fprintf(fd, "%d", n);
759219b2ee8SDavid du Colombier break;
7607dd7cddfSDavid du Colombier case '\b': fprintf(fd, "\\b"); break;
7617dd7cddfSDavid du Colombier case '\t': fprintf(fd, "\\t"); break;
7627dd7cddfSDavid du Colombier case '\f': fprintf(fd, "\\f"); break;
7637dd7cddfSDavid du Colombier case '\n': fprintf(fd, "\\n"); break;
7647dd7cddfSDavid du Colombier case '\r': fprintf(fd, "\\r"); break;
7657dd7cddfSDavid du Colombier case 'c': fprintf(fd, "condition"); break;
7667dd7cddfSDavid du Colombier case 's': fprintf(fd, "send"); break;
7677dd7cddfSDavid du Colombier case 'r': fprintf(fd, "recv"); break;
7687dd7cddfSDavid du Colombier case 'R': fprintf(fd, "recv poll %s", Operator); break;
7697dd7cddfSDavid du Colombier case '@': fprintf(fd, "@"); break;
7707dd7cddfSDavid du Colombier case '?': fprintf(fd, "(x->y:z)"); break;
771*00d97012SDavid du Colombier #if 1
772*00d97012SDavid du Colombier case NEXT: fprintf(fd, "X"); break;
773*00d97012SDavid du Colombier case ALWAYS: fprintf(fd, "[]"); break;
774*00d97012SDavid du Colombier case EVENTUALLY: fprintf(fd, "<>"); break;
775*00d97012SDavid du Colombier case IMPLIES: fprintf(fd, "->"); break;
776*00d97012SDavid du Colombier case EQUIV: fprintf(fd, "<->"); break;
777*00d97012SDavid du Colombier case UNTIL: fprintf(fd, "U"); break;
778*00d97012SDavid du Colombier case WEAK_UNTIL: fprintf(fd, "W"); break;
779*00d97012SDavid du Colombier case IN: fprintf(fd, "%sin", Keyword); break;
780*00d97012SDavid du Colombier #endif
7817dd7cddfSDavid du Colombier case ACTIVE: fprintf(fd, "%sactive", Keyword); break;
7827dd7cddfSDavid du Colombier case AND: fprintf(fd, "%s&&", Operator); break;
7837dd7cddfSDavid du Colombier case ASGN: fprintf(fd, "%s=", Operator); break;
7847dd7cddfSDavid du Colombier case ASSERT: fprintf(fd, "%sassert", Function); break;
7857dd7cddfSDavid du Colombier case ATOMIC: fprintf(fd, "%satomic", Keyword); break;
7867dd7cddfSDavid du Colombier case BREAK: fprintf(fd, "%sbreak", Keyword); break;
787312a1df1SDavid du Colombier case C_CODE: fprintf(fd, "%sc_code", Keyword); break;
788312a1df1SDavid du Colombier case C_DECL: fprintf(fd, "%sc_decl", Keyword); break;
789312a1df1SDavid du Colombier case C_EXPR: fprintf(fd, "%sc_expr", Keyword); break;
790312a1df1SDavid du Colombier case C_STATE: fprintf(fd, "%sc_state",Keyword); break;
791312a1df1SDavid du Colombier case C_TRACK: fprintf(fd, "%sc_track",Keyword); break;
7927dd7cddfSDavid du Colombier case CLAIM: fprintf(fd, "%snever", Keyword); break;
7937dd7cddfSDavid du Colombier case CONST: fprintf(fd, "a constant"); break;
7947dd7cddfSDavid du Colombier case DECR: fprintf(fd, "%s--", Operator); break;
7957dd7cddfSDavid du Colombier case D_STEP: fprintf(fd, "%sd_step", Keyword); break;
796312a1df1SDavid du Colombier case D_PROCTYPE: fprintf(fd, "%sd_proctype", Keyword); break;
7977dd7cddfSDavid du Colombier case DO: fprintf(fd, "%sdo", Keyword); break;
7987dd7cddfSDavid du Colombier case DOT: fprintf(fd, "."); break;
7997dd7cddfSDavid du Colombier case ELSE: fprintf(fd, "%selse", Keyword); break;
8007dd7cddfSDavid du Colombier case EMPTY: fprintf(fd, "%sempty", Function); break;
8017dd7cddfSDavid du Colombier case ENABLED: fprintf(fd, "%senabled",Function); break;
8027dd7cddfSDavid du Colombier case EQ: fprintf(fd, "%s==", Operator); break;
8037dd7cddfSDavid du Colombier case EVAL: fprintf(fd, "%seval", Function); break;
8047dd7cddfSDavid du Colombier case FI: fprintf(fd, "%sfi", Keyword); break;
8057dd7cddfSDavid du Colombier case FULL: fprintf(fd, "%sfull", Function); break;
8067dd7cddfSDavid du Colombier case GE: fprintf(fd, "%s>=", Operator); break;
8077dd7cddfSDavid du Colombier case GOTO: fprintf(fd, "%sgoto", Keyword); break;
8087dd7cddfSDavid du Colombier case GT: fprintf(fd, "%s>", Operator); break;
809312a1df1SDavid du Colombier case HIDDEN: fprintf(fd, "%shidden", Keyword); break;
8107dd7cddfSDavid du Colombier case IF: fprintf(fd, "%sif", Keyword); break;
8117dd7cddfSDavid du Colombier case INCR: fprintf(fd, "%s++", Operator); break;
8127dd7cddfSDavid du Colombier case INAME: fprintf(fd, "inline name"); break;
8137dd7cddfSDavid du Colombier case INLINE: fprintf(fd, "%sinline", Keyword); break;
8147dd7cddfSDavid du Colombier case INIT: fprintf(fd, "%sinit", Keyword); break;
815312a1df1SDavid du Colombier case ISLOCAL: fprintf(fd, "%slocal", Keyword); break;
8167dd7cddfSDavid du Colombier case LABEL: fprintf(fd, "a label-name"); break;
8177dd7cddfSDavid du Colombier case LE: fprintf(fd, "%s<=", Operator); break;
8187dd7cddfSDavid du Colombier case LEN: fprintf(fd, "%slen", Function); break;
8197dd7cddfSDavid du Colombier case LSHIFT: fprintf(fd, "%s<<", Operator); break;
8207dd7cddfSDavid du Colombier case LT: fprintf(fd, "%s<", Operator); break;
8217dd7cddfSDavid du Colombier case MTYPE: fprintf(fd, "%smtype", Keyword); break;
8227dd7cddfSDavid du Colombier case NAME: fprintf(fd, "an identifier"); break;
8237dd7cddfSDavid du Colombier case NE: fprintf(fd, "%s!=", Operator); break;
8247dd7cddfSDavid du Colombier case NEG: fprintf(fd, "%s! (not)",Operator); break;
8257dd7cddfSDavid du Colombier case NEMPTY: fprintf(fd, "%snempty", Function); break;
8267dd7cddfSDavid du Colombier case NFULL: fprintf(fd, "%snfull", Function); break;
8277dd7cddfSDavid du Colombier case NON_ATOMIC: fprintf(fd, "sub-sequence"); break;
8287dd7cddfSDavid du Colombier case NONPROGRESS: fprintf(fd, "%snp_", Function); break;
8297dd7cddfSDavid du Colombier case OD: fprintf(fd, "%sod", Keyword); break;
8307dd7cddfSDavid du Colombier case OF: fprintf(fd, "%sof", Keyword); break;
8317dd7cddfSDavid du Colombier case OR: fprintf(fd, "%s||", Operator); break;
8327dd7cddfSDavid du Colombier case O_SND: fprintf(fd, "%s!!", Operator); break;
8337dd7cddfSDavid du Colombier case PC_VAL: fprintf(fd, "%spc_value",Function); break;
8347dd7cddfSDavid du Colombier case PNAME: fprintf(fd, "process name"); break;
8357dd7cddfSDavid du Colombier case PRINT: fprintf(fd, "%sprintf", Function); break;
836312a1df1SDavid du Colombier case PRINTM: fprintf(fd, "%sprintm", Function); break;
837312a1df1SDavid du Colombier case PRIORITY: fprintf(fd, "%spriority", Keyword); break;
8387dd7cddfSDavid du Colombier case PROCTYPE: fprintf(fd, "%sproctype",Keyword); break;
839312a1df1SDavid du Colombier case PROVIDED: fprintf(fd, "%sprovided",Keyword); break;
8407dd7cddfSDavid du Colombier case RCV: fprintf(fd, "%s?", Operator); break;
8417dd7cddfSDavid du Colombier case R_RCV: fprintf(fd, "%s??", Operator); break;
8427dd7cddfSDavid du Colombier case RSHIFT: fprintf(fd, "%s>>", Operator); break;
8437dd7cddfSDavid du Colombier case RUN: fprintf(fd, "%srun", Operator); break;
8447dd7cddfSDavid du Colombier case SEP: fprintf(fd, "token: ::"); break;
8457dd7cddfSDavid du Colombier case SEMI: fprintf(fd, ";"); break;
846312a1df1SDavid du Colombier case SHOW: fprintf(fd, "%sshow", Keyword); break;
8477dd7cddfSDavid du Colombier case SND: fprintf(fd, "%s!", Operator); break;
8487dd7cddfSDavid du Colombier case STRING: fprintf(fd, "a string"); break;
849312a1df1SDavid du Colombier case TRACE: fprintf(fd, "%strace", Keyword); break;
8507dd7cddfSDavid du Colombier case TIMEOUT: fprintf(fd, "%stimeout",Keyword); break;
8517dd7cddfSDavid du Colombier case TYPE: fprintf(fd, "data typename"); break;
8527dd7cddfSDavid du Colombier case TYPEDEF: fprintf(fd, "%stypedef",Keyword); break;
8537dd7cddfSDavid du Colombier case XU: fprintf(fd, "%sx[rs]", Keyword); break;
8547dd7cddfSDavid du Colombier case UMIN: fprintf(fd, "%s- (unary minus)", Operator); break;
8557dd7cddfSDavid du Colombier case UNAME: fprintf(fd, "a typename"); break;
8567dd7cddfSDavid du Colombier case UNLESS: fprintf(fd, "%sunless", Keyword); break;
857219b2ee8SDavid du Colombier }
858219b2ee8SDavid du Colombier }
859*00d97012SDavid du Colombier
860*00d97012SDavid du Colombier
861