1759Speter /* Copyright (c) 1979 Regents of the University of California */ 2*3075Smckusic 32575Speter static char copyright[] = 42575Speter "@(#)Copyright (c) 1979 Regents of the University of California"; 5759Speter 6*3075Smckusic static char sccsid[] = "@(#)main.c 1.3 03/08/81"; 7759Speter 8759Speter #include "whoami.h" 9759Speter #include "0.h" 10759Speter #include "yy.h" 11759Speter #include <signal.h> 12759Speter #include "objfmt.h" 13759Speter 14759Speter /* 15759Speter * This version of pi has been in use at Berkeley since May 1977 16*3075Smckusic * and is very stable. Please report any problems with the error 17759Speter * recovery to the second author at the address given in the file 18759Speter * READ_ME. The second author takes full responsibility for any bugs 19759Speter * in the syntactic error recovery. 20759Speter */ 21759Speter 22759Speter char piusage[] = "pi [ -blnpstuw ] [ -i file ... ] name.p"; 23759Speter char pixusage[] = "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]"; 24759Speter char pcusage[] = "pc [ options ] [ -o file ] [ -i file ... ] name.p"; 25759Speter 26759Speter char *usageis = piusage; 27759Speter 28759Speter char *errfile = ERR_STRNGS; 29759Speter 30759Speter #ifdef OBJ 31759Speter char *obj = "obj"; 32759Speter #endif OBJ 33759Speter #ifdef PC 34759Speter char *pcname = "pc.pc1"; 35759Speter #endif PC 36759Speter #ifdef PTREE 37759Speter char *pTreeName = "pi.pTree"; 38759Speter #endif PTREE 39759Speter 40759Speter /* 41759Speter * Be careful changing errfile and howfile. 42759Speter * There are the "magic" constants 9 and 15 immediately below. 43759Speter * errfile is now defined by ERR_STRNGS, in objfmt.h, 44759Speter * and its leading path name length is ERR_PATHLEN long. 45759Speter * this for executing out of the current directory if running as `a.something'. 46759Speter */ 47759Speter #ifdef OBJ 48*3075Smckusic char *howfile = HOW_STRNGS; 49759Speter #endif OBJ 50759Speter #ifdef PC 51*3075Smckusic char *howfile = HOW_STRNGS; 52759Speter #endif PC 53759Speter 54759Speter int onintr(); 55759Speter 56759Speter extern char *lastname; 57759Speter 58759Speter FILE *ibuf; 59759Speter FILE *pcstream = NULL; 60759Speter 61759Speter /* 62759Speter * these are made real variables 63759Speter * so they can be changed 64759Speter * if you are compiling on a smaller machine 65759Speter */ 66759Speter double MAXINT = 2147483647.; 67759Speter double MININT = -2147483648.; 68759Speter 69759Speter /* 70759Speter * Main program for pi. 71759Speter * Process options, then call yymain 72759Speter * to do all the real work. 73759Speter */ 74759Speter main(argc, argv) 75759Speter int argc; 76759Speter char *argv[]; 77759Speter { 78759Speter register char *cp; 79759Speter register c; 80759Speter int i; 81759Speter 82759Speter if (argv[0][0] == 'a') 83*3075Smckusic errfile += ERR_PATHLEN , howfile += HOW_PATHLEN; 84759Speter # ifdef OBJ 85759Speter if (argv[0][0] == '-' && argv[0][1] == 'o') { 86759Speter obj = &argv[0][2]; 87759Speter usageis = pixusage; 88*3075Smckusic howfile[HOW_PATHLEN+6] = 'x'; 89759Speter ofil = 3; 90759Speter } else { 91759Speter ofil = creat(obj, 0755); 92759Speter if (ofil < 0) { 93759Speter perror(obj); 94759Speter pexit(NOSTART); 95759Speter } 96759Speter } 97759Speter # endif OBJ 98759Speter argv++, argc--; 99759Speter if (argc == 0) { 100759Speter i = fork(); 101759Speter if (i == -1) 102759Speter goto usage; 103759Speter if (i == 0) { 104759Speter execl("/bin/cat", "cat", howfile, 0); 105759Speter goto usage; 106759Speter } 107759Speter while (wait(&i) != -1) 108759Speter continue; 109759Speter pexit(NOSTART); 110759Speter } 111759Speter # ifdef OBJ 112759Speter opt('p') = opt('t') = opt('b') = 1; 113759Speter while (argc > 0) { 114759Speter cp = argv[0]; 115759Speter if (*cp++ != '-') 116759Speter break; 117759Speter while (c = *cp++) switch (c) { 118759Speter #ifdef DEBUG 119759Speter case 'k': 120759Speter case 'r': 121759Speter case 'y': 122759Speter togopt(c); 123759Speter continue; 124759Speter case 'K': 125759Speter yycosts(); 126759Speter pexit(NOSTART); 127759Speter case 'A': 128*3075Smckusic testtrace = TRUE; 129759Speter case 'F': 130*3075Smckusic fulltrace = TRUE; 131759Speter case 'E': 132*3075Smckusic errtrace = TRUE; 133759Speter opt('r')++; 134759Speter continue; 135759Speter case 'U': 136759Speter yyunique = 0; 137759Speter continue; 138759Speter #endif 139759Speter case 'b': 140759Speter opt('b') = 2; 141759Speter continue; 142759Speter case 'i': 143759Speter pflist = argv + 1; 144759Speter pflstc = 0; 145759Speter while (argc > 1) { 146759Speter if (dotted(argv[1], 'p')) 147759Speter break; 148759Speter pflstc++, argc--, argv++; 149759Speter } 150759Speter if (pflstc == 0) 151759Speter goto usage; 152759Speter continue; 153759Speter case 'l': 154759Speter case 'n': 155759Speter case 'p': 156759Speter case 's': 157759Speter case 't': 158759Speter case 'u': 159759Speter case 'w': 160759Speter togopt(c); 161759Speter continue; 162759Speter case 'z': 163*3075Smckusic monflg = TRUE; 164759Speter continue; 165759Speter default: 166759Speter usage: 167759Speter Perror( "Usage", usageis); 168759Speter pexit(NOSTART); 169759Speter } 170759Speter argc--, argv++; 171759Speter } 172759Speter # endif OBJ 173759Speter # ifdef PC 174759Speter opt( 'b' ) = 1; 175759Speter opt( 'g' ) = 0; 176759Speter opt( 't' ) = 0; 177759Speter opt( 'p' ) = 0; 178759Speter usageis = pcusage; 179759Speter while ( argc > 0 ) { 180759Speter cp = argv[0]; 181759Speter if ( *cp++ != '-' ) { 182759Speter break; 183759Speter } 184759Speter c = *cp++; 185759Speter switch( c ) { 186759Speter #ifdef DEBUG 187759Speter case 'k': 188759Speter case 'r': 189759Speter case 'y': 190759Speter togopt(c); 191759Speter break; 192759Speter case 'K': 193759Speter yycosts(); 194759Speter pexit(NOSTART); 195759Speter case 'A': 196759Speter testtrace++; 197759Speter /* and fall through */ 198759Speter case 'F': 199759Speter fulltrace++; 200759Speter /* and fall through */ 201759Speter case 'E': 202759Speter errtrace++; 203759Speter opt('r')++; 204759Speter break; 205759Speter case 'U': 206759Speter yyunique = 0; 207759Speter break; 208759Speter #endif 209759Speter case 'b': 210759Speter opt('b') = 2; 211759Speter break; 212759Speter case 'i': 213759Speter pflist = argv + 1; 214759Speter pflstc = 0; 215759Speter while (argc > 1) { 216759Speter if (dotted(argv[1], 'p')) 217759Speter break; 218759Speter pflstc++, argc--, argv++; 219759Speter } 220759Speter if (pflstc == 0) 221759Speter goto usage; 222759Speter break; 223759Speter /* 224759Speter * output file for the first pass 225759Speter */ 226759Speter case 'o': 227759Speter if ( argc < 2 ) { 228759Speter goto usage; 229759Speter } 230759Speter argv++; 231759Speter argc--; 232759Speter pcname = argv[0]; 233759Speter break; 234759Speter case 'C': 235759Speter /* 236759Speter * since -t is an ld switch, use -C 237759Speter * to turn on tests 238759Speter */ 239759Speter togopt( 't' ); 240759Speter break; 241759Speter case 'g': 242759Speter /* 243759Speter * sdb symbol table 244759Speter */ 245759Speter togopt( 'g' ); 246759Speter break; 247759Speter case 'l': 248759Speter case 's': 249759Speter case 'u': 250759Speter case 'w': 251759Speter togopt(c); 252759Speter break; 253759Speter case 'p': 254759Speter /* 255759Speter * -p on the command line means profile 256759Speter */ 257759Speter profflag++; 258759Speter break; 259759Speter case 'z': 260759Speter monflg++; 261759Speter break; 262759Speter default: 263759Speter usage: 264759Speter Perror( "Usage", usageis); 265759Speter pexit(NOSTART); 266759Speter } 267759Speter argc--; 268759Speter argv++; 269759Speter } 270759Speter # endif PC 271759Speter if (argc != 1) 272759Speter goto usage; 273759Speter efil = open ( errfile, 0 ); 274759Speter if ( efil < 0 ) 275759Speter perror(errfile), pexit(NOSTART); 276759Speter filename = argv[0]; 277759Speter if (!dotted(filename, 'p')) { 278759Speter Perror(filename, "Name must end in '.p'"); 279759Speter pexit(NOSTART); 280759Speter } 281759Speter close(0); 282759Speter if ( ( ibuf = fopen( filename , "r" ) ) == NULL ) 283759Speter perror(filename), pexit(NOSTART); 284759Speter ibp = ibuf; 285759Speter # ifdef PC 286759Speter if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) { 287759Speter perror( pcname ); 288759Speter pexit( NOSTART ); 289759Speter } 290759Speter stabsource( filename ); 291759Speter # endif PC 292759Speter # ifdef PTREE 293759Speter # define MAXpPAGES 16 294759Speter if ( ! pCreate( pTreeName , MAXpPAGES ) ) { 295759Speter perror( pTreeName ); 296759Speter pexit( NOSTART ); 297759Speter } 298759Speter # endif PTREE 299759Speter if ( signal( SIGINT , SIG_IGN ) != SIG_IGN ) 300759Speter signal( SIGINT , onintr ); 301759Speter if (opt('l')) { 302759Speter opt('n')++; 303759Speter yysetfile(filename); 304759Speter opt('n')--; 305759Speter } 306759Speter yymain(); 307759Speter /* No return */ 308759Speter } 309759Speter 310759Speter pchr(c) 311759Speter char c; 312759Speter { 313759Speter 314759Speter putc ( c , stdout ); 315759Speter } 316759Speter 317759Speter char ugh[] = "Fatal error in pi\n"; 318759Speter /* 319759Speter * Exit from the Pascal system. 320759Speter * We throw in an ungraceful termination 321759Speter * message if c > 1 indicating a severe 322759Speter * error such as running out of memory 323759Speter * or an internal inconsistency. 324759Speter */ 325759Speter pexit(c) 326759Speter int c; 327759Speter { 328759Speter 329759Speter if (opt('l') && c != DIED && c != NOSTART) 330759Speter while (getline() != -1) 331759Speter continue; 332759Speter yyflush(); 333759Speter switch (c) { 334759Speter case DIED: 335759Speter write(2, ugh, sizeof ugh); 336759Speter case NOSTART: 337759Speter case ERRS: 338759Speter # ifdef OBJ 339759Speter if (ofil > 0) 340759Speter unlink(obj); 341759Speter # endif OBJ 342759Speter # ifdef PC 343759Speter if ( pcstream != NULL ) { 344759Speter unlink( pcname ); 345759Speter } 346759Speter # endif PC 347759Speter break; 348759Speter case AOK: 349759Speter # ifdef OBJ 350759Speter pflush(); 351759Speter # endif OBJ 352759Speter # ifdef PC 353759Speter puteof(); 354759Speter # endif PC 355759Speter break; 356759Speter } 357759Speter /* 358759Speter * this to gather statistics on programs being compiled 359759Speter * taken 20 june 79 ... peter 360759Speter * 361759Speter * if (fork() == 0) { 362759Speter * char *cp = "-0"; 363759Speter * cp[1] += c; 364759Speter * execl("/usr/lib/gather", "gather", cp, filename, 0); 365759Speter * exit(1); 366759Speter * } 367759Speter */ 368759Speter # ifdef PTREE 369759Speter pFinish(); 370759Speter # endif 371759Speter exit(c); 372759Speter } 373759Speter 374759Speter onintr() 375759Speter { 376759Speter 377759Speter signal( SIGINT , SIG_IGN ); 378759Speter pexit(NOSTART); 379759Speter } 380759Speter 381759Speter /* 382759Speter * Get an error message from the error message file 383759Speter */ 384759Speter geterr(seekpt, buf) 385759Speter int seekpt; 386759Speter char *buf; 387759Speter { 388759Speter 389759Speter lseek(efil, (long) seekpt, 0); 390759Speter if (read(efil, buf, 256) <= 0) 391759Speter perror(errfile), pexit(DIED); 392759Speter } 393759Speter 394759Speter header() 395759Speter { 396759Speter extern char version[]; 397759Speter static char anyheaders; 398759Speter 399759Speter gettime( filename ); 400759Speter if (anyheaders && opt('n')) 401759Speter putc( '\f' , stdout ); 402759Speter anyheaders++; 403759Speter # ifdef OBJ 404759Speter printf("Berkeley Pascal PI -- Version 2.0 (%s)\n\n%s %s\n\n", 405759Speter version, myctime(&tvec), filename); 406759Speter # endif OBJ 407759Speter # ifdef PC 408759Speter printf("Berkeley Pascal PC -- Version 2.0 (%s)\n\n%s %s\n\n", 409759Speter version, myctime(&tvec), filename); 410759Speter # endif PC 411759Speter } 412