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*18348Smckusick static char sccsid[] = "@(#)main.c 1.9.1.1 03/15/85"; 7759Speter 8759Speter #include "whoami.h" 9759Speter #include "0.h" 10759Speter #include "yy.h" 11759Speter #include <signal.h> 12759Speter #include "objfmt.h" 136407Speter #include "config.h" 14759Speter 15759Speter /* 16759Speter * This version of pi has been in use at Berkeley since May 1977 173075Smckusic * and is very stable. Please report any problems with the error 18759Speter * recovery to the second author at the address given in the file 19759Speter * READ_ME. The second author takes full responsibility for any bugs 20759Speter * in the syntactic error recovery. 21759Speter */ 22759Speter 23759Speter char piusage[] = "pi [ -blnpstuw ] [ -i file ... ] name.p"; 24*18348Smckusick char pixusage[] = "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]"; 25*18348Smckusick char pcusage[] = "pc [ options ] [ -o file ] [ -i file ... ] name.p"; 26759Speter 27759Speter char *usageis = piusage; 28759Speter 29759Speter #ifdef OBJ 30*18348Smckusick char *obj = "obj"; 31759Speter #endif OBJ 32759Speter #ifdef PC 33*18348Smckusick char *pcname = "pc.pc0"; 34759Speter #endif PC 35759Speter #ifdef PTREE 36759Speter char *pTreeName = "pi.pTree"; 37759Speter #endif PTREE 38759Speter 39759Speter int onintr(); 40759Speter 41759Speter extern char *lastname; 42759Speter 43759Speter FILE *ibuf; 44*18348Smckusick FILE *pcstream = NULL; 45759Speter 46759Speter /* 47759Speter * these are made real variables 48759Speter * so they can be changed 49759Speter * if you are compiling on a smaller machine 50759Speter */ 51759Speter double MAXINT = 2147483647.; 52759Speter double MININT = -2147483648.; 53759Speter 54759Speter /* 55759Speter * Main program for pi. 56759Speter * Process options, then call yymain 57759Speter * to do all the real work. 58759Speter */ 59759Speter main(argc, argv) 60759Speter int argc; 61759Speter char *argv[]; 62759Speter { 63759Speter register char *cp; 64759Speter register c; 65759Speter int i; 66759Speter 67759Speter if (argv[0][0] == 'a') 686407Speter err_file += err_pathlen , how_file += how_pathlen; 69759Speter # ifdef OBJ 70759Speter if (argv[0][0] == '-' && argv[0][1] == 'o') { 71759Speter obj = &argv[0][2]; 72759Speter usageis = pixusage; 736407Speter how_file[strlen(how_file)] = 'x'; 74759Speter ofil = 3; 75759Speter } else { 76759Speter ofil = creat(obj, 0755); 77759Speter if (ofil < 0) { 78759Speter perror(obj); 79759Speter pexit(NOSTART); 80759Speter } 81759Speter } 82759Speter # endif OBJ 83759Speter argv++, argc--; 84759Speter if (argc == 0) { 85759Speter i = fork(); 86759Speter if (i == -1) 87759Speter goto usage; 88759Speter if (i == 0) { 896407Speter execl("/bin/cat", "cat", how_file, 0); 90759Speter goto usage; 91759Speter } 92759Speter while (wait(&i) != -1) 93759Speter continue; 94759Speter pexit(NOSTART); 95759Speter } 96759Speter # ifdef OBJ 9711884Smckusick opt('p') = opt('t') = opt('b') = 1; 9811884Smckusick #ifdef vax 9911884Smckusick /* pdx is currently supported only on the vax */ 10011884Smckusick opt('g') = 1; 10111884Smckusick #endif vax 102759Speter while (argc > 0) { 103759Speter cp = argv[0]; 104759Speter if (*cp++ != '-') 105759Speter break; 106759Speter while (c = *cp++) switch (c) { 107759Speter #ifdef DEBUG 108759Speter case 'k': 109759Speter case 'r': 110759Speter case 'y': 111759Speter togopt(c); 112759Speter continue; 113759Speter case 'K': 114759Speter yycosts(); 115759Speter pexit(NOSTART); 116759Speter case 'A': 1173075Smckusic testtrace = TRUE; 118759Speter case 'F': 1193075Smckusic fulltrace = TRUE; 120759Speter case 'E': 1213075Smckusic errtrace = TRUE; 122759Speter opt('r')++; 123759Speter continue; 124759Speter case 'U': 125*18348Smckusick yyunique = 0; 126759Speter continue; 127759Speter #endif 128759Speter case 'b': 129759Speter opt('b') = 2; 130759Speter continue; 131759Speter case 'i': 132759Speter pflist = argv + 1; 133759Speter pflstc = 0; 134759Speter while (argc > 1) { 135759Speter if (dotted(argv[1], 'p')) 136759Speter break; 137759Speter pflstc++, argc--, argv++; 138759Speter } 139759Speter if (pflstc == 0) 140759Speter goto usage; 141759Speter continue; 1425654Slinton case 'g': 143759Speter case 'l': 144759Speter case 'n': 145759Speter case 'p': 146759Speter case 's': 147759Speter case 't': 148759Speter case 'u': 149759Speter case 'w': 150759Speter togopt(c); 151759Speter continue; 152759Speter case 'z': 1533075Smckusic monflg = TRUE; 154759Speter continue; 155*18348Smckusick case 'L': 156*18348Smckusick togopt( 'L' ); 157*18348Smckusick continue; 158759Speter default: 159759Speter usage: 160759Speter Perror( "Usage", usageis); 161759Speter pexit(NOSTART); 162759Speter } 163759Speter argc--, argv++; 164759Speter } 165759Speter # endif OBJ 166759Speter # ifdef PC 167759Speter opt( 'b' ) = 1; 168759Speter opt( 'g' ) = 0; 169759Speter opt( 't' ) = 0; 170759Speter opt( 'p' ) = 0; 171759Speter usageis = pcusage; 172759Speter while ( argc > 0 ) { 173759Speter cp = argv[0]; 174759Speter if ( *cp++ != '-' ) { 175759Speter break; 176759Speter } 177759Speter c = *cp++; 178759Speter switch( c ) { 179759Speter #ifdef DEBUG 180759Speter case 'k': 181759Speter case 'r': 182759Speter case 'y': 183759Speter togopt(c); 184759Speter break; 185759Speter case 'K': 186759Speter yycosts(); 187759Speter pexit(NOSTART); 188759Speter case 'A': 1893138Smckusic testtrace = TRUE; 190759Speter /* and fall through */ 191759Speter case 'F': 1923138Smckusic fulltrace = TRUE; 193759Speter /* and fall through */ 194759Speter case 'E': 1953138Smckusic errtrace = TRUE; 196759Speter opt('r')++; 197759Speter break; 198759Speter case 'U': 199*18348Smckusick yyunique = 0; 200759Speter break; 201759Speter #endif 202759Speter case 'b': 203759Speter opt('b') = 2; 204759Speter break; 205759Speter case 'i': 206759Speter pflist = argv + 1; 207759Speter pflstc = 0; 208759Speter while (argc > 1) { 209759Speter if (dotted(argv[1], 'p')) 210759Speter break; 211759Speter pflstc++, argc--, argv++; 212759Speter } 213759Speter if (pflstc == 0) 214759Speter goto usage; 215759Speter break; 216759Speter /* 217759Speter * output file for the first pass 218759Speter */ 219759Speter case 'o': 220759Speter if ( argc < 2 ) { 221759Speter goto usage; 222759Speter } 223759Speter argv++; 224759Speter argc--; 225759Speter pcname = argv[0]; 226759Speter break; 22712967Smckusick case 'J': 22812967Smckusick togopt( 'J' ); 22912967Smckusick break; 230759Speter case 'C': 231759Speter /* 232759Speter * since -t is an ld switch, use -C 233759Speter * to turn on tests 234759Speter */ 235759Speter togopt( 't' ); 236759Speter break; 237759Speter case 'g': 238759Speter /* 239759Speter * sdb symbol table 240759Speter */ 241759Speter togopt( 'g' ); 242759Speter break; 243759Speter case 'l': 244759Speter case 's': 245759Speter case 'u': 246759Speter case 'w': 247759Speter togopt(c); 248759Speter break; 249759Speter case 'p': 250759Speter /* 251759Speter * -p on the command line means profile 252759Speter */ 2533138Smckusic profflag = TRUE; 254759Speter break; 255759Speter case 'z': 2563138Smckusic monflg = TRUE; 257759Speter break; 258*18348Smckusick case 'L': 259*18348Smckusick togopt( 'L' ); 260*18348Smckusick break; 261759Speter default: 262759Speter usage: 263759Speter Perror( "Usage", usageis); 264759Speter pexit(NOSTART); 265759Speter } 266759Speter argc--; 267759Speter argv++; 268759Speter } 269759Speter # endif PC 270759Speter if (argc != 1) 271759Speter goto usage; 2726407Speter efil = open ( err_file, 0 ); 273759Speter if ( efil < 0 ) 2746407Speter perror(err_file), pexit(NOSTART); 275759Speter filename = argv[0]; 276759Speter if (!dotted(filename, 'p')) { 277759Speter Perror(filename, "Name must end in '.p'"); 278759Speter pexit(NOSTART); 279759Speter } 280759Speter close(0); 281759Speter if ( ( ibuf = fopen( filename , "r" ) ) == NULL ) 282759Speter perror(filename), pexit(NOSTART); 283759Speter ibp = ibuf; 284759Speter # ifdef PC 285759Speter if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) { 286759Speter perror( pcname ); 287759Speter pexit( NOSTART ); 288759Speter } 289*18348Smckusick stabsource( filename, TRUE ); 290759Speter # endif PC 291759Speter # ifdef PTREE 292759Speter # define MAXpPAGES 16 293759Speter if ( ! pCreate( pTreeName , MAXpPAGES ) ) { 294759Speter perror( pTreeName ); 295759Speter pexit( NOSTART ); 296759Speter } 297759Speter # endif PTREE 298759Speter if ( signal( SIGINT , SIG_IGN ) != SIG_IGN ) 299*18348Smckusick signal( SIGINT , onintr ); 300759Speter if (opt('l')) { 301759Speter opt('n')++; 302759Speter yysetfile(filename); 303759Speter opt('n')--; 304759Speter } 305759Speter yymain(); 306759Speter /* No return */ 307759Speter } 308759Speter 309759Speter pchr(c) 310759Speter char c; 311759Speter { 312759Speter 313759Speter putc ( c , stdout ); 314759Speter } 315759Speter 316759Speter char ugh[] = "Fatal error in pi\n"; 317759Speter /* 318759Speter * Exit from the Pascal system. 319759Speter * We throw in an ungraceful termination 320759Speter * message if c > 1 indicating a severe 321759Speter * error such as running out of memory 322759Speter * or an internal inconsistency. 323759Speter */ 324759Speter pexit(c) 325759Speter int c; 326759Speter { 327759Speter 328759Speter if (opt('l') && c != DIED && c != NOSTART) 329759Speter while (getline() != -1) 330759Speter continue; 331759Speter yyflush(); 332759Speter switch (c) { 333759Speter case DIED: 334759Speter write(2, ugh, sizeof ugh); 335759Speter case NOSTART: 336759Speter case ERRS: 337759Speter # ifdef OBJ 338759Speter if (ofil > 0) 339759Speter unlink(obj); 3405654Slinton /* 3415654Slinton * remove symbol table temp files 3425654Slinton */ 3435654Slinton removenlfile(); 3445654Slinton 345759Speter # endif OBJ 346759Speter # ifdef PC 347759Speter if ( pcstream != NULL ) { 348759Speter unlink( pcname ); 349759Speter } 350759Speter # endif PC 351759Speter break; 352759Speter case AOK: 353759Speter # ifdef OBJ 354759Speter pflush(); 3555654Slinton /* 3565654Slinton * copy symbol table temp files to obj file 3575654Slinton */ 3585654Slinton copynlfile(); 3595654Slinton 360759Speter # endif OBJ 361759Speter # ifdef PC 362759Speter puteof(); 363759Speter # endif PC 364759Speter break; 365759Speter } 366759Speter /* 367759Speter * this to gather statistics on programs being compiled 368759Speter * taken 20 june 79 ... peter 369759Speter * 370759Speter * if (fork() == 0) { 371759Speter * char *cp = "-0"; 372759Speter * cp[1] += c; 373759Speter * execl("/usr/lib/gather", "gather", cp, filename, 0); 374759Speter * exit(1); 375759Speter * } 376759Speter */ 377759Speter # ifdef PTREE 378759Speter pFinish(); 379759Speter # endif 380759Speter exit(c); 381759Speter } 382759Speter 383759Speter onintr() 384759Speter { 385759Speter 386*18348Smckusick signal( SIGINT , SIG_IGN ); 387759Speter pexit(NOSTART); 388759Speter } 389759Speter 390759Speter /* 391759Speter * Get an error message from the error message file 392759Speter */ 393759Speter geterr(seekpt, buf) 394759Speter int seekpt; 395759Speter char *buf; 396759Speter { 397759Speter 398*18348Smckusick lseek(efil, (long) seekpt, 0); 399759Speter if (read(efil, buf, 256) <= 0) 4006407Speter perror(err_file), pexit(DIED); 401759Speter } 402759Speter 403759Speter header() 404759Speter { 4056407Speter extern char *version; 406759Speter static char anyheaders; 407759Speter 408759Speter gettime( filename ); 409759Speter if (anyheaders && opt('n')) 410759Speter putc( '\f' , stdout ); 411759Speter anyheaders++; 412759Speter # ifdef OBJ 4136407Speter printf("Berkeley Pascal PI -- Version %s\n\n%s %s\n\n", 414*18348Smckusick version, myctime(&tvec), filename); 415759Speter # endif OBJ 416759Speter # ifdef PC 4176407Speter printf("Berkeley Pascal PC -- Version %s\n\n%s %s\n\n", 418*18348Smckusick version, myctime(&tvec), filename); 419759Speter # endif PC 420759Speter } 421