1759Speter /* Copyright (c) 1979 Regents of the University of California */ 23075Smckusic 32575Speter static char copyright[] = 42575Speter "@(#)Copyright (c) 1979 Regents of the University of California"; 5759Speter 6*5654Slinton static char sccsid[] = "@(#)main.c 1.5 02/02/82"; 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 163075Smckusic * 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 483075Smckusic char *howfile = HOW_STRNGS; 49759Speter #endif OBJ 50759Speter #ifdef PC 513075Smckusic 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') 833075Smckusic 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; 883075Smckusic 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 112*5654Slinton opt('g') = 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': 1283075Smckusic testtrace = TRUE; 129759Speter case 'F': 1303075Smckusic fulltrace = TRUE; 131759Speter case 'E': 1323075Smckusic 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; 153*5654Slinton case 'g': 154759Speter case 'l': 155759Speter case 'n': 156759Speter case 'p': 157759Speter case 's': 158759Speter case 't': 159759Speter case 'u': 160759Speter case 'w': 161759Speter togopt(c); 162759Speter continue; 163759Speter case 'z': 1643075Smckusic monflg = TRUE; 165759Speter continue; 166759Speter default: 167759Speter usage: 168759Speter Perror( "Usage", usageis); 169759Speter pexit(NOSTART); 170759Speter } 171759Speter argc--, argv++; 172759Speter } 173759Speter # endif OBJ 174759Speter # ifdef PC 175759Speter opt( 'b' ) = 1; 176759Speter opt( 'g' ) = 0; 177759Speter opt( 't' ) = 0; 178759Speter opt( 'p' ) = 0; 179759Speter usageis = pcusage; 180759Speter while ( argc > 0 ) { 181759Speter cp = argv[0]; 182759Speter if ( *cp++ != '-' ) { 183759Speter break; 184759Speter } 185759Speter c = *cp++; 186759Speter switch( c ) { 187759Speter #ifdef DEBUG 188759Speter case 'k': 189759Speter case 'r': 190759Speter case 'y': 191759Speter togopt(c); 192759Speter break; 193759Speter case 'K': 194759Speter yycosts(); 195759Speter pexit(NOSTART); 196759Speter case 'A': 1973138Smckusic testtrace = TRUE; 198759Speter /* and fall through */ 199759Speter case 'F': 2003138Smckusic fulltrace = TRUE; 201759Speter /* and fall through */ 202759Speter case 'E': 2033138Smckusic errtrace = TRUE; 204759Speter opt('r')++; 205759Speter break; 206759Speter case 'U': 207759Speter yyunique = 0; 208759Speter break; 209759Speter #endif 210759Speter case 'b': 211759Speter opt('b') = 2; 212759Speter break; 213759Speter case 'i': 214759Speter pflist = argv + 1; 215759Speter pflstc = 0; 216759Speter while (argc > 1) { 217759Speter if (dotted(argv[1], 'p')) 218759Speter break; 219759Speter pflstc++, argc--, argv++; 220759Speter } 221759Speter if (pflstc == 0) 222759Speter goto usage; 223759Speter break; 224759Speter /* 225759Speter * output file for the first pass 226759Speter */ 227759Speter case 'o': 228759Speter if ( argc < 2 ) { 229759Speter goto usage; 230759Speter } 231759Speter argv++; 232759Speter argc--; 233759Speter pcname = argv[0]; 234759Speter break; 235759Speter case 'C': 236759Speter /* 237759Speter * since -t is an ld switch, use -C 238759Speter * to turn on tests 239759Speter */ 240759Speter togopt( 't' ); 241759Speter break; 242759Speter case 'g': 243759Speter /* 244759Speter * sdb symbol table 245759Speter */ 246759Speter togopt( 'g' ); 247759Speter break; 248759Speter case 'l': 249759Speter case 's': 250759Speter case 'u': 251759Speter case 'w': 252759Speter togopt(c); 253759Speter break; 254759Speter case 'p': 255759Speter /* 256759Speter * -p on the command line means profile 257759Speter */ 2583138Smckusic profflag = TRUE; 259759Speter break; 260759Speter case 'z': 2613138Smckusic monflg = TRUE; 262759Speter break; 263759Speter default: 264759Speter usage: 265759Speter Perror( "Usage", usageis); 266759Speter pexit(NOSTART); 267759Speter } 268759Speter argc--; 269759Speter argv++; 270759Speter } 271759Speter # endif PC 272759Speter if (argc != 1) 273759Speter goto usage; 274759Speter efil = open ( errfile, 0 ); 275759Speter if ( efil < 0 ) 276759Speter perror(errfile), pexit(NOSTART); 277759Speter filename = argv[0]; 278759Speter if (!dotted(filename, 'p')) { 279759Speter Perror(filename, "Name must end in '.p'"); 280759Speter pexit(NOSTART); 281759Speter } 282759Speter close(0); 283759Speter if ( ( ibuf = fopen( filename , "r" ) ) == NULL ) 284759Speter perror(filename), pexit(NOSTART); 285759Speter ibp = ibuf; 286759Speter # ifdef PC 287759Speter if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) { 288759Speter perror( pcname ); 289759Speter pexit( NOSTART ); 290759Speter } 291759Speter stabsource( filename ); 292759Speter # endif PC 293759Speter # ifdef PTREE 294759Speter # define MAXpPAGES 16 295759Speter if ( ! pCreate( pTreeName , MAXpPAGES ) ) { 296759Speter perror( pTreeName ); 297759Speter pexit( NOSTART ); 298759Speter } 299759Speter # endif PTREE 300759Speter if ( signal( SIGINT , SIG_IGN ) != SIG_IGN ) 301759Speter signal( SIGINT , onintr ); 302759Speter if (opt('l')) { 303759Speter opt('n')++; 304759Speter yysetfile(filename); 305759Speter opt('n')--; 306759Speter } 307759Speter yymain(); 308759Speter /* No return */ 309759Speter } 310759Speter 311759Speter pchr(c) 312759Speter char c; 313759Speter { 314759Speter 315759Speter putc ( c , stdout ); 316759Speter } 317759Speter 318759Speter char ugh[] = "Fatal error in pi\n"; 319759Speter /* 320759Speter * Exit from the Pascal system. 321759Speter * We throw in an ungraceful termination 322759Speter * message if c > 1 indicating a severe 323759Speter * error such as running out of memory 324759Speter * or an internal inconsistency. 325759Speter */ 326759Speter pexit(c) 327759Speter int c; 328759Speter { 329759Speter 330759Speter if (opt('l') && c != DIED && c != NOSTART) 331759Speter while (getline() != -1) 332759Speter continue; 333759Speter yyflush(); 334759Speter switch (c) { 335759Speter case DIED: 336759Speter write(2, ugh, sizeof ugh); 337759Speter case NOSTART: 338759Speter case ERRS: 339759Speter # ifdef OBJ 340759Speter if (ofil > 0) 341759Speter unlink(obj); 342*5654Slinton /* 343*5654Slinton * remove symbol table temp files 344*5654Slinton */ 345*5654Slinton removenlfile(); 346*5654Slinton 347759Speter # endif OBJ 348759Speter # ifdef PC 349759Speter if ( pcstream != NULL ) { 350759Speter unlink( pcname ); 351759Speter } 352759Speter # endif PC 353759Speter break; 354759Speter case AOK: 355759Speter # ifdef OBJ 356759Speter pflush(); 357*5654Slinton /* 358*5654Slinton * copy symbol table temp files to obj file 359*5654Slinton */ 360*5654Slinton copynlfile(); 361*5654Slinton 362759Speter # endif OBJ 363759Speter # ifdef PC 364759Speter puteof(); 365759Speter # endif PC 366759Speter break; 367759Speter } 368759Speter /* 369759Speter * this to gather statistics on programs being compiled 370759Speter * taken 20 june 79 ... peter 371759Speter * 372759Speter * if (fork() == 0) { 373759Speter * char *cp = "-0"; 374759Speter * cp[1] += c; 375759Speter * execl("/usr/lib/gather", "gather", cp, filename, 0); 376759Speter * exit(1); 377759Speter * } 378759Speter */ 379759Speter # ifdef PTREE 380759Speter pFinish(); 381759Speter # endif 382759Speter exit(c); 383759Speter } 384759Speter 385759Speter onintr() 386759Speter { 387759Speter 388759Speter signal( SIGINT , SIG_IGN ); 389759Speter pexit(NOSTART); 390759Speter } 391759Speter 392759Speter /* 393759Speter * Get an error message from the error message file 394759Speter */ 395759Speter geterr(seekpt, buf) 396759Speter int seekpt; 397759Speter char *buf; 398759Speter { 399759Speter 400759Speter lseek(efil, (long) seekpt, 0); 401759Speter if (read(efil, buf, 256) <= 0) 402759Speter perror(errfile), pexit(DIED); 403759Speter } 404759Speter 405759Speter header() 406759Speter { 407759Speter extern char version[]; 408759Speter static char anyheaders; 409759Speter 410759Speter gettime( filename ); 411759Speter if (anyheaders && opt('n')) 412759Speter putc( '\f' , stdout ); 413759Speter anyheaders++; 414759Speter # ifdef OBJ 415759Speter printf("Berkeley Pascal PI -- Version 2.0 (%s)\n\n%s %s\n\n", 416759Speter version, myctime(&tvec), filename); 417759Speter # endif OBJ 418759Speter # ifdef PC 419759Speter printf("Berkeley Pascal PC -- Version 2.0 (%s)\n\n%s %s\n\n", 420759Speter version, myctime(&tvec), filename); 421759Speter # endif PC 422759Speter } 423