1*759Speter /* Copyright (c) 1979 Regents of the University of California */ 2*759Speter 3*759Speter static char sccsid[] = "@(#)main.c 1.1 08/27/80"; 4*759Speter 5*759Speter #include "whoami.h" 6*759Speter #include "0.h" 7*759Speter #include "yy.h" 8*759Speter #include <signal.h> 9*759Speter #include "objfmt.h" 10*759Speter 11*759Speter /* 12*759Speter * This version of pi has been in use at Berkeley since May 1977 13*759Speter * and is very stable, except for the syntactic error recovery which 14*759Speter * has just been written. Please report any problems with the error 15*759Speter * recovery to the second author at the address given in the file 16*759Speter * READ_ME. The second author takes full responsibility for any bugs 17*759Speter * in the syntactic error recovery. 18*759Speter */ 19*759Speter 20*759Speter char piusage[] = "pi [ -blnpstuw ] [ -i file ... ] name.p"; 21*759Speter char pixusage[] = "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]"; 22*759Speter char pcusage[] = "pc [ options ] [ -o file ] [ -i file ... ] name.p"; 23*759Speter 24*759Speter char *usageis = piusage; 25*759Speter 26*759Speter char *errfile = ERR_STRNGS; 27*759Speter 28*759Speter #ifdef OBJ 29*759Speter char *obj = "obj"; 30*759Speter #endif OBJ 31*759Speter #ifdef PC 32*759Speter char *pcname = "pc.pc1"; 33*759Speter #endif PC 34*759Speter #ifdef PTREE 35*759Speter char *pTreeName = "pi.pTree"; 36*759Speter #endif PTREE 37*759Speter 38*759Speter /* 39*759Speter * Be careful changing errfile and howfile. 40*759Speter * There are the "magic" constants 9 and 15 immediately below. 41*759Speter * errfile is now defined by ERR_STRNGS, in objfmt.h, 42*759Speter * and its leading path name length is ERR_PATHLEN long. 43*759Speter * this for executing out of the current directory if running as `a.something'. 44*759Speter */ 45*759Speter #ifdef OBJ 46*759Speter char *howfile = "/usr/lib/how_pi\0"; 47*759Speter #endif OBJ 48*759Speter #ifdef PC 49*759Speter char *howfile = "/usr/lib/how_pc"; 50*759Speter #endif PC 51*759Speter 52*759Speter int onintr(); 53*759Speter 54*759Speter extern char *lastname; 55*759Speter 56*759Speter FILE *ibuf; 57*759Speter FILE *pcstream = NULL; 58*759Speter 59*759Speter /* 60*759Speter * these are made real variables 61*759Speter * so they can be changed 62*759Speter * if you are compiling on a smaller machine 63*759Speter */ 64*759Speter double MAXINT = 2147483647.; 65*759Speter double MININT = -2147483648.; 66*759Speter 67*759Speter /* 68*759Speter * Main program for pi. 69*759Speter * Process options, then call yymain 70*759Speter * to do all the real work. 71*759Speter */ 72*759Speter main(argc, argv) 73*759Speter int argc; 74*759Speter char *argv[]; 75*759Speter { 76*759Speter register char *cp; 77*759Speter register c; 78*759Speter int i; 79*759Speter 80*759Speter if (argv[0][0] == 'a') 81*759Speter errfile += ERR_PATHLEN , howfile += 9; 82*759Speter # ifdef OBJ 83*759Speter if (argv[0][0] == '-' && argv[0][1] == 'o') { 84*759Speter obj = &argv[0][2]; 85*759Speter usageis = pixusage; 86*759Speter howfile[15] = 'x'; 87*759Speter ofil = 3; 88*759Speter } else { 89*759Speter ofil = creat(obj, 0755); 90*759Speter if (ofil < 0) { 91*759Speter perror(obj); 92*759Speter pexit(NOSTART); 93*759Speter } 94*759Speter } 95*759Speter # endif OBJ 96*759Speter argv++, argc--; 97*759Speter if (argc == 0) { 98*759Speter i = fork(); 99*759Speter if (i == -1) 100*759Speter goto usage; 101*759Speter if (i == 0) { 102*759Speter execl("/bin/cat", "cat", howfile, 0); 103*759Speter goto usage; 104*759Speter } 105*759Speter while (wait(&i) != -1) 106*759Speter continue; 107*759Speter pexit(NOSTART); 108*759Speter } 109*759Speter # ifdef OBJ 110*759Speter opt('p') = opt('t') = opt('b') = 1; 111*759Speter while (argc > 0) { 112*759Speter cp = argv[0]; 113*759Speter if (*cp++ != '-') 114*759Speter break; 115*759Speter while (c = *cp++) switch (c) { 116*759Speter #ifdef DEBUG 117*759Speter case 'k': 118*759Speter case 'r': 119*759Speter case 'y': 120*759Speter togopt(c); 121*759Speter continue; 122*759Speter case 'K': 123*759Speter yycosts(); 124*759Speter pexit(NOSTART); 125*759Speter case 'A': 126*759Speter testtrace++; 127*759Speter case 'F': 128*759Speter fulltrace++; 129*759Speter case 'E': 130*759Speter errtrace++; 131*759Speter opt('r')++; 132*759Speter continue; 133*759Speter case 'U': 134*759Speter yyunique = 0; 135*759Speter continue; 136*759Speter #endif 137*759Speter case 'b': 138*759Speter opt('b') = 2; 139*759Speter continue; 140*759Speter case 'i': 141*759Speter pflist = argv + 1; 142*759Speter pflstc = 0; 143*759Speter while (argc > 1) { 144*759Speter if (dotted(argv[1], 'p')) 145*759Speter break; 146*759Speter pflstc++, argc--, argv++; 147*759Speter } 148*759Speter if (pflstc == 0) 149*759Speter goto usage; 150*759Speter continue; 151*759Speter case 'l': 152*759Speter case 'n': 153*759Speter case 'p': 154*759Speter case 's': 155*759Speter case 't': 156*759Speter case 'u': 157*759Speter case 'w': 158*759Speter togopt(c); 159*759Speter continue; 160*759Speter case 'z': 161*759Speter monflg++; 162*759Speter continue; 163*759Speter default: 164*759Speter usage: 165*759Speter Perror( "Usage", usageis); 166*759Speter pexit(NOSTART); 167*759Speter } 168*759Speter argc--, argv++; 169*759Speter } 170*759Speter # endif OBJ 171*759Speter # ifdef PC 172*759Speter opt( 'b' ) = 1; 173*759Speter opt( 'g' ) = 0; 174*759Speter opt( 't' ) = 0; 175*759Speter opt( 'p' ) = 0; 176*759Speter usageis = pcusage; 177*759Speter while ( argc > 0 ) { 178*759Speter cp = argv[0]; 179*759Speter if ( *cp++ != '-' ) { 180*759Speter break; 181*759Speter } 182*759Speter c = *cp++; 183*759Speter switch( c ) { 184*759Speter #ifdef DEBUG 185*759Speter case 'k': 186*759Speter case 'r': 187*759Speter case 'y': 188*759Speter togopt(c); 189*759Speter break; 190*759Speter case 'K': 191*759Speter yycosts(); 192*759Speter pexit(NOSTART); 193*759Speter case 'A': 194*759Speter testtrace++; 195*759Speter /* and fall through */ 196*759Speter case 'F': 197*759Speter fulltrace++; 198*759Speter /* and fall through */ 199*759Speter case 'E': 200*759Speter errtrace++; 201*759Speter opt('r')++; 202*759Speter break; 203*759Speter case 'U': 204*759Speter yyunique = 0; 205*759Speter break; 206*759Speter #endif 207*759Speter case 'b': 208*759Speter opt('b') = 2; 209*759Speter break; 210*759Speter case 'i': 211*759Speter pflist = argv + 1; 212*759Speter pflstc = 0; 213*759Speter while (argc > 1) { 214*759Speter if (dotted(argv[1], 'p')) 215*759Speter break; 216*759Speter pflstc++, argc--, argv++; 217*759Speter } 218*759Speter if (pflstc == 0) 219*759Speter goto usage; 220*759Speter break; 221*759Speter /* 222*759Speter * output file for the first pass 223*759Speter */ 224*759Speter case 'o': 225*759Speter if ( argc < 2 ) { 226*759Speter goto usage; 227*759Speter } 228*759Speter argv++; 229*759Speter argc--; 230*759Speter pcname = argv[0]; 231*759Speter break; 232*759Speter case 'C': 233*759Speter /* 234*759Speter * since -t is an ld switch, use -C 235*759Speter * to turn on tests 236*759Speter */ 237*759Speter togopt( 't' ); 238*759Speter break; 239*759Speter case 'g': 240*759Speter /* 241*759Speter * sdb symbol table 242*759Speter */ 243*759Speter togopt( 'g' ); 244*759Speter break; 245*759Speter case 'l': 246*759Speter case 's': 247*759Speter case 'u': 248*759Speter case 'w': 249*759Speter togopt(c); 250*759Speter break; 251*759Speter case 'p': 252*759Speter /* 253*759Speter * -p on the command line means profile 254*759Speter */ 255*759Speter profflag++; 256*759Speter break; 257*759Speter case 'z': 258*759Speter monflg++; 259*759Speter break; 260*759Speter default: 261*759Speter usage: 262*759Speter Perror( "Usage", usageis); 263*759Speter pexit(NOSTART); 264*759Speter } 265*759Speter argc--; 266*759Speter argv++; 267*759Speter } 268*759Speter # endif PC 269*759Speter if (argc != 1) 270*759Speter goto usage; 271*759Speter efil = open ( errfile, 0 ); 272*759Speter if ( efil < 0 ) 273*759Speter perror(errfile), pexit(NOSTART); 274*759Speter filename = argv[0]; 275*759Speter if (!dotted(filename, 'p')) { 276*759Speter Perror(filename, "Name must end in '.p'"); 277*759Speter pexit(NOSTART); 278*759Speter } 279*759Speter close(0); 280*759Speter if ( ( ibuf = fopen( filename , "r" ) ) == NULL ) 281*759Speter perror(filename), pexit(NOSTART); 282*759Speter ibp = ibuf; 283*759Speter # ifdef PC 284*759Speter if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) { 285*759Speter perror( pcname ); 286*759Speter pexit( NOSTART ); 287*759Speter } 288*759Speter stabsource( filename ); 289*759Speter # endif PC 290*759Speter # ifdef PTREE 291*759Speter # define MAXpPAGES 16 292*759Speter if ( ! pCreate( pTreeName , MAXpPAGES ) ) { 293*759Speter perror( pTreeName ); 294*759Speter pexit( NOSTART ); 295*759Speter } 296*759Speter # endif PTREE 297*759Speter if ( signal( SIGINT , SIG_IGN ) != SIG_IGN ) 298*759Speter signal( SIGINT , onintr ); 299*759Speter if (opt('l')) { 300*759Speter opt('n')++; 301*759Speter yysetfile(filename); 302*759Speter opt('n')--; 303*759Speter } 304*759Speter yymain(); 305*759Speter /* No return */ 306*759Speter } 307*759Speter 308*759Speter pchr(c) 309*759Speter char c; 310*759Speter { 311*759Speter 312*759Speter putc ( c , stdout ); 313*759Speter } 314*759Speter 315*759Speter char ugh[] = "Fatal error in pi\n"; 316*759Speter /* 317*759Speter * Exit from the Pascal system. 318*759Speter * We throw in an ungraceful termination 319*759Speter * message if c > 1 indicating a severe 320*759Speter * error such as running out of memory 321*759Speter * or an internal inconsistency. 322*759Speter */ 323*759Speter pexit(c) 324*759Speter int c; 325*759Speter { 326*759Speter 327*759Speter if (opt('l') && c != DIED && c != NOSTART) 328*759Speter while (getline() != -1) 329*759Speter continue; 330*759Speter yyflush(); 331*759Speter switch (c) { 332*759Speter case DIED: 333*759Speter write(2, ugh, sizeof ugh); 334*759Speter case NOSTART: 335*759Speter case ERRS: 336*759Speter # ifdef OBJ 337*759Speter if (ofil > 0) 338*759Speter unlink(obj); 339*759Speter # endif OBJ 340*759Speter # ifdef PC 341*759Speter if ( pcstream != NULL ) { 342*759Speter unlink( pcname ); 343*759Speter } 344*759Speter # endif PC 345*759Speter break; 346*759Speter case AOK: 347*759Speter # ifdef OBJ 348*759Speter pflush(); 349*759Speter # endif OBJ 350*759Speter # ifdef PC 351*759Speter puteof(); 352*759Speter # endif PC 353*759Speter break; 354*759Speter } 355*759Speter /* 356*759Speter * this to gather statistics on programs being compiled 357*759Speter * taken 20 june 79 ... peter 358*759Speter * 359*759Speter * if (fork() == 0) { 360*759Speter * char *cp = "-0"; 361*759Speter * cp[1] += c; 362*759Speter * execl("/usr/lib/gather", "gather", cp, filename, 0); 363*759Speter * exit(1); 364*759Speter * } 365*759Speter */ 366*759Speter # ifdef PTREE 367*759Speter pFinish(); 368*759Speter # endif 369*759Speter exit(c); 370*759Speter } 371*759Speter 372*759Speter onintr() 373*759Speter { 374*759Speter 375*759Speter signal( SIGINT , SIG_IGN ); 376*759Speter pexit(NOSTART); 377*759Speter } 378*759Speter 379*759Speter /* 380*759Speter * Get an error message from the error message file 381*759Speter */ 382*759Speter geterr(seekpt, buf) 383*759Speter int seekpt; 384*759Speter char *buf; 385*759Speter { 386*759Speter 387*759Speter lseek(efil, (long) seekpt, 0); 388*759Speter if (read(efil, buf, 256) <= 0) 389*759Speter perror(errfile), pexit(DIED); 390*759Speter } 391*759Speter 392*759Speter header() 393*759Speter { 394*759Speter extern char version[]; 395*759Speter static char anyheaders; 396*759Speter 397*759Speter gettime( filename ); 398*759Speter if (anyheaders && opt('n')) 399*759Speter putc( '\f' , stdout ); 400*759Speter anyheaders++; 401*759Speter # ifdef OBJ 402*759Speter printf("Berkeley Pascal PI -- Version 2.0 (%s)\n\n%s %s\n\n", 403*759Speter version, myctime(&tvec), filename); 404*759Speter # endif OBJ 405*759Speter # ifdef PC 406*759Speter printf("Berkeley Pascal PC -- Version 2.0 (%s)\n\n%s %s\n\n", 407*759Speter version, myctime(&tvec), filename); 408*759Speter # endif PC 409*759Speter } 410