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