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*12967Smckusick static char sccsid[] = "@(#)main.c 1.9 06/10/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 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': 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; 224*12967Smckusick case 'J': 225*12967Smckusick togopt( 'J' ); 226*12967Smckusick break; 227759Speter case 'C': 228759Speter /* 229759Speter * since -t is an ld switch, use -C 230759Speter * to turn on tests 231759Speter */ 232759Speter togopt( 't' ); 233759Speter break; 234759Speter case 'g': 235759Speter /* 236759Speter * sdb symbol table 237759Speter */ 238759Speter togopt( 'g' ); 239759Speter break; 240759Speter case 'l': 241759Speter case 's': 242759Speter case 'u': 243759Speter case 'w': 244759Speter togopt(c); 245759Speter break; 246759Speter case 'p': 247759Speter /* 248759Speter * -p on the command line means profile 249759Speter */ 2503138Smckusic profflag = TRUE; 251759Speter break; 252759Speter case 'z': 2533138Smckusic monflg = TRUE; 254759Speter break; 255759Speter default: 256759Speter usage: 257759Speter Perror( "Usage", usageis); 258759Speter pexit(NOSTART); 259759Speter } 260759Speter argc--; 261759Speter argv++; 262759Speter } 263759Speter # endif PC 264759Speter if (argc != 1) 265759Speter goto usage; 2666407Speter efil = open ( err_file, 0 ); 267759Speter if ( efil < 0 ) 2686407Speter perror(err_file), pexit(NOSTART); 269759Speter filename = argv[0]; 270759Speter if (!dotted(filename, 'p')) { 271759Speter Perror(filename, "Name must end in '.p'"); 272759Speter pexit(NOSTART); 273759Speter } 274759Speter close(0); 275759Speter if ( ( ibuf = fopen( filename , "r" ) ) == NULL ) 276759Speter perror(filename), pexit(NOSTART); 277759Speter ibp = ibuf; 278759Speter # ifdef PC 279759Speter if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) { 280759Speter perror( pcname ); 281759Speter pexit( NOSTART ); 282759Speter } 283759Speter stabsource( filename ); 284759Speter # endif PC 285759Speter # ifdef PTREE 286759Speter # define MAXpPAGES 16 287759Speter if ( ! pCreate( pTreeName , MAXpPAGES ) ) { 288759Speter perror( pTreeName ); 289759Speter pexit( NOSTART ); 290759Speter } 291759Speter # endif PTREE 292759Speter if ( signal( SIGINT , SIG_IGN ) != SIG_IGN ) 293759Speter signal( SIGINT , onintr ); 294759Speter if (opt('l')) { 295759Speter opt('n')++; 296759Speter yysetfile(filename); 297759Speter opt('n')--; 298759Speter } 299759Speter yymain(); 300759Speter /* No return */ 301759Speter } 302759Speter 303759Speter pchr(c) 304759Speter char c; 305759Speter { 306759Speter 307759Speter putc ( c , stdout ); 308759Speter } 309759Speter 310759Speter char ugh[] = "Fatal error in pi\n"; 311759Speter /* 312759Speter * Exit from the Pascal system. 313759Speter * We throw in an ungraceful termination 314759Speter * message if c > 1 indicating a severe 315759Speter * error such as running out of memory 316759Speter * or an internal inconsistency. 317759Speter */ 318759Speter pexit(c) 319759Speter int c; 320759Speter { 321759Speter 322759Speter if (opt('l') && c != DIED && c != NOSTART) 323759Speter while (getline() != -1) 324759Speter continue; 325759Speter yyflush(); 326759Speter switch (c) { 327759Speter case DIED: 328759Speter write(2, ugh, sizeof ugh); 329759Speter case NOSTART: 330759Speter case ERRS: 331759Speter # ifdef OBJ 332759Speter if (ofil > 0) 333759Speter unlink(obj); 3345654Slinton /* 3355654Slinton * remove symbol table temp files 3365654Slinton */ 3375654Slinton removenlfile(); 3385654Slinton 339759Speter # endif OBJ 340759Speter # ifdef PC 341759Speter if ( pcstream != NULL ) { 342759Speter unlink( pcname ); 343759Speter } 344759Speter # endif PC 345759Speter break; 346759Speter case AOK: 347759Speter # ifdef OBJ 348759Speter pflush(); 3495654Slinton /* 3505654Slinton * copy symbol table temp files to obj file 3515654Slinton */ 3525654Slinton copynlfile(); 3535654Slinton 354759Speter # endif OBJ 355759Speter # ifdef PC 356759Speter puteof(); 357759Speter # endif PC 358759Speter break; 359759Speter } 360759Speter /* 361759Speter * this to gather statistics on programs being compiled 362759Speter * taken 20 june 79 ... peter 363759Speter * 364759Speter * if (fork() == 0) { 365759Speter * char *cp = "-0"; 366759Speter * cp[1] += c; 367759Speter * execl("/usr/lib/gather", "gather", cp, filename, 0); 368759Speter * exit(1); 369759Speter * } 370759Speter */ 371759Speter # ifdef PTREE 372759Speter pFinish(); 373759Speter # endif 374759Speter exit(c); 375759Speter } 376759Speter 377759Speter onintr() 378759Speter { 379759Speter 380759Speter signal( SIGINT , SIG_IGN ); 381759Speter pexit(NOSTART); 382759Speter } 383759Speter 384759Speter /* 385759Speter * Get an error message from the error message file 386759Speter */ 387759Speter geterr(seekpt, buf) 388759Speter int seekpt; 389759Speter char *buf; 390759Speter { 391759Speter 392759Speter lseek(efil, (long) seekpt, 0); 393759Speter if (read(efil, buf, 256) <= 0) 3946407Speter perror(err_file), pexit(DIED); 395759Speter } 396759Speter 397759Speter header() 398759Speter { 3996407Speter extern char *version; 400759Speter static char anyheaders; 401759Speter 402759Speter gettime( filename ); 403759Speter if (anyheaders && opt('n')) 404759Speter putc( '\f' , stdout ); 405759Speter anyheaders++; 406759Speter # ifdef OBJ 4076407Speter printf("Berkeley Pascal PI -- Version %s\n\n%s %s\n\n", 408759Speter version, myctime(&tvec), filename); 409759Speter # endif OBJ 410759Speter # ifdef PC 4116407Speter printf("Berkeley Pascal PC -- Version %s\n\n%s %s\n\n", 412759Speter version, myctime(&tvec), filename); 413759Speter # endif PC 414759Speter } 415