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*11884Smckusick static char sccsid[] = "@(#)main.c 1.8 04/08/83"; 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"; 24759Speter char pixusage[] = "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]"; 25759Speter char pcusage[] = "pc [ options ] [ -o file ] [ -i file ... ] name.p"; 26759Speter 27759Speter char *usageis = piusage; 28759Speter 29759Speter #ifdef OBJ 30759Speter char *obj = "obj"; 31759Speter #endif OBJ 32759Speter #ifdef PC 336375Speter 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; 44759Speter 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 97*11884Smckusick opt('p') = opt('t') = opt('b') = 1; 98*11884Smckusick #ifdef vax 99*11884Smckusick /* pdx is currently supported only on the vax */ 100*11884Smckusick opt('g') = 1; 101*11884Smckusick #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': 125759Speter 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; 155759Speter default: 156759Speter usage: 157759Speter Perror( "Usage", usageis); 158759Speter pexit(NOSTART); 159759Speter } 160759Speter argc--, argv++; 161759Speter } 162759Speter # endif OBJ 163759Speter # ifdef PC 164759Speter opt( 'b' ) = 1; 165759Speter opt( 'g' ) = 0; 166759Speter opt( 't' ) = 0; 167759Speter opt( 'p' ) = 0; 168759Speter usageis = pcusage; 169759Speter while ( argc > 0 ) { 170759Speter cp = argv[0]; 171759Speter if ( *cp++ != '-' ) { 172759Speter break; 173759Speter } 174759Speter c = *cp++; 175759Speter switch( c ) { 176759Speter #ifdef DEBUG 177759Speter case 'k': 178759Speter case 'r': 179759Speter case 'y': 180759Speter togopt(c); 181759Speter break; 182759Speter case 'K': 183759Speter yycosts(); 184759Speter pexit(NOSTART); 185759Speter case 'A': 1863138Smckusic testtrace = TRUE; 187759Speter /* and fall through */ 188759Speter case 'F': 1893138Smckusic fulltrace = TRUE; 190759Speter /* and fall through */ 191759Speter case 'E': 1923138Smckusic errtrace = TRUE; 193759Speter opt('r')++; 194759Speter break; 195759Speter case 'U': 196759Speter yyunique = 0; 197759Speter break; 198759Speter #endif 199759Speter case 'b': 200759Speter opt('b') = 2; 201759Speter break; 202759Speter case 'i': 203759Speter pflist = argv + 1; 204759Speter pflstc = 0; 205759Speter while (argc > 1) { 206759Speter if (dotted(argv[1], 'p')) 207759Speter break; 208759Speter pflstc++, argc--, argv++; 209759Speter } 210759Speter if (pflstc == 0) 211759Speter goto usage; 212759Speter break; 213759Speter /* 214759Speter * output file for the first pass 215759Speter */ 216759Speter case 'o': 217759Speter if ( argc < 2 ) { 218759Speter goto usage; 219759Speter } 220759Speter argv++; 221759Speter argc--; 222759Speter pcname = argv[0]; 223759Speter break; 224759Speter case 'C': 225759Speter /* 226759Speter * since -t is an ld switch, use -C 227759Speter * to turn on tests 228759Speter */ 229759Speter togopt( 't' ); 230759Speter break; 231759Speter case 'g': 232759Speter /* 233759Speter * sdb symbol table 234759Speter */ 235759Speter togopt( 'g' ); 236759Speter break; 237759Speter case 'l': 238759Speter case 's': 239759Speter case 'u': 240759Speter case 'w': 241759Speter togopt(c); 242759Speter break; 243759Speter case 'p': 244759Speter /* 245759Speter * -p on the command line means profile 246759Speter */ 2473138Smckusic profflag = TRUE; 248759Speter break; 249759Speter case 'z': 2503138Smckusic monflg = TRUE; 251759Speter break; 252759Speter default: 253759Speter usage: 254759Speter Perror( "Usage", usageis); 255759Speter pexit(NOSTART); 256759Speter } 257759Speter argc--; 258759Speter argv++; 259759Speter } 260759Speter # endif PC 261759Speter if (argc != 1) 262759Speter goto usage; 2636407Speter efil = open ( err_file, 0 ); 264759Speter if ( efil < 0 ) 2656407Speter perror(err_file), pexit(NOSTART); 266759Speter filename = argv[0]; 267759Speter if (!dotted(filename, 'p')) { 268759Speter Perror(filename, "Name must end in '.p'"); 269759Speter pexit(NOSTART); 270759Speter } 271759Speter close(0); 272759Speter if ( ( ibuf = fopen( filename , "r" ) ) == NULL ) 273759Speter perror(filename), pexit(NOSTART); 274759Speter ibp = ibuf; 275759Speter # ifdef PC 276759Speter if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) { 277759Speter perror( pcname ); 278759Speter pexit( NOSTART ); 279759Speter } 280759Speter stabsource( filename ); 281759Speter # endif PC 282759Speter # ifdef PTREE 283759Speter # define MAXpPAGES 16 284759Speter if ( ! pCreate( pTreeName , MAXpPAGES ) ) { 285759Speter perror( pTreeName ); 286759Speter pexit( NOSTART ); 287759Speter } 288759Speter # endif PTREE 289759Speter if ( signal( SIGINT , SIG_IGN ) != SIG_IGN ) 290759Speter signal( SIGINT , onintr ); 291759Speter if (opt('l')) { 292759Speter opt('n')++; 293759Speter yysetfile(filename); 294759Speter opt('n')--; 295759Speter } 296759Speter yymain(); 297759Speter /* No return */ 298759Speter } 299759Speter 300759Speter pchr(c) 301759Speter char c; 302759Speter { 303759Speter 304759Speter putc ( c , stdout ); 305759Speter } 306759Speter 307759Speter char ugh[] = "Fatal error in pi\n"; 308759Speter /* 309759Speter * Exit from the Pascal system. 310759Speter * We throw in an ungraceful termination 311759Speter * message if c > 1 indicating a severe 312759Speter * error such as running out of memory 313759Speter * or an internal inconsistency. 314759Speter */ 315759Speter pexit(c) 316759Speter int c; 317759Speter { 318759Speter 319759Speter if (opt('l') && c != DIED && c != NOSTART) 320759Speter while (getline() != -1) 321759Speter continue; 322759Speter yyflush(); 323759Speter switch (c) { 324759Speter case DIED: 325759Speter write(2, ugh, sizeof ugh); 326759Speter case NOSTART: 327759Speter case ERRS: 328759Speter # ifdef OBJ 329759Speter if (ofil > 0) 330759Speter unlink(obj); 3315654Slinton /* 3325654Slinton * remove symbol table temp files 3335654Slinton */ 3345654Slinton removenlfile(); 3355654Slinton 336759Speter # endif OBJ 337759Speter # ifdef PC 338759Speter if ( pcstream != NULL ) { 339759Speter unlink( pcname ); 340759Speter } 341759Speter # endif PC 342759Speter break; 343759Speter case AOK: 344759Speter # ifdef OBJ 345759Speter pflush(); 3465654Slinton /* 3475654Slinton * copy symbol table temp files to obj file 3485654Slinton */ 3495654Slinton copynlfile(); 3505654Slinton 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) 3916407Speter perror(err_file), pexit(DIED); 392759Speter } 393759Speter 394759Speter header() 395759Speter { 3966407Speter 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 4046407Speter printf("Berkeley Pascal PI -- Version %s\n\n%s %s\n\n", 405759Speter version, myctime(&tvec), filename); 406759Speter # endif OBJ 407759Speter # ifdef PC 4086407Speter printf("Berkeley Pascal PC -- Version %s\n\n%s %s\n\n", 409759Speter version, myctime(&tvec), filename); 410759Speter # endif PC 411759Speter } 412