1759Speter /* Copyright (c) 1979 Regents of the University of California */ 23075Smckusic 318349Smckusick #ifndef lint 42575Speter static char copyright[] = 52575Speter "@(#)Copyright (c) 1979 Regents of the University of California"; 6759Speter 7*18449Smckusick static char sccsid[] = "@(#)main.c 2.3 03/20/85"; 818349Smckusick #endif 9759Speter 10759Speter #include "whoami.h" 11759Speter #include "0.h" 1218349Smckusick #include "tree_ty.h" /* must be included for yy.h */ 13759Speter #include "yy.h" 14759Speter #include <signal.h> 15759Speter #include "objfmt.h" 166407Speter #include "config.h" 17759Speter 18759Speter /* 19759Speter * This version of pi has been in use at Berkeley since May 1977 203075Smckusic * and is very stable. Please report any problems with the error 21759Speter * recovery to the second author at the address given in the file 22759Speter * READ_ME. The second author takes full responsibility for any bugs 23759Speter * in the syntactic error recovery. 24759Speter */ 25759Speter 26759Speter char piusage[] = "pi [ -blnpstuw ] [ -i file ... ] name.p"; 27759Speter 28759Speter char *usageis = piusage; 29759Speter 30759Speter #ifdef OBJ 3118349Smckusick 3218349Smckusick char pixusage[] = "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]"; 3318349Smckusick char *obj = "obj"; 3418349Smckusick 35759Speter #endif OBJ 3618349Smckusick 37759Speter #ifdef PC 3818349Smckusick 3918349Smckusick char *pcname = "pc.pc0"; 4018349Smckusick char pcusage[] = "pc [ options ] [ -o file ] [ -i file ... ] name.p"; 4118349Smckusick FILE *pcstream = NULL; 4218349Smckusick 43759Speter #endif PC 44759Speter #ifdef PTREE 45759Speter char *pTreeName = "pi.pTree"; 46759Speter #endif PTREE 47759Speter 48759Speter int onintr(); 49759Speter 50759Speter extern char *lastname; 51759Speter 52759Speter FILE *ibuf; 53759Speter 54759Speter /* 55759Speter * these are made real variables 56759Speter * so they can be changed 57759Speter * if you are compiling on a smaller machine 58759Speter */ 59759Speter double MAXINT = 2147483647.; 60759Speter double MININT = -2147483648.; 61759Speter 62759Speter /* 63759Speter * Main program for pi. 64759Speter * Process options, then call yymain 65759Speter * to do all the real work. 66759Speter */ 67759Speter main(argc, argv) 68759Speter int argc; 69759Speter char *argv[]; 70759Speter { 71759Speter register char *cp; 72759Speter register c; 7318349Smckusick FILE *fopen(); 7418349Smckusick extern char *myctime(); 7518349Smckusick extern long lseek(); 76759Speter int i; 77759Speter 78759Speter if (argv[0][0] == 'a') 796407Speter err_file += err_pathlen , how_file += how_pathlen; 80759Speter # ifdef OBJ 81759Speter if (argv[0][0] == '-' && argv[0][1] == 'o') { 82759Speter obj = &argv[0][2]; 83759Speter usageis = pixusage; 846407Speter how_file[strlen(how_file)] = 'x'; 85759Speter ofil = 3; 86759Speter } else { 87759Speter ofil = creat(obj, 0755); 88759Speter if (ofil < 0) { 89759Speter perror(obj); 90759Speter pexit(NOSTART); 91759Speter } 92759Speter } 93759Speter # endif OBJ 94759Speter argv++, argc--; 95759Speter if (argc == 0) { 96759Speter i = fork(); 97759Speter if (i == -1) 98759Speter goto usage; 99759Speter if (i == 0) { 1006407Speter execl("/bin/cat", "cat", how_file, 0); 101759Speter goto usage; 102759Speter } 103759Speter while (wait(&i) != -1) 104759Speter continue; 105759Speter pexit(NOSTART); 106759Speter } 107759Speter # ifdef OBJ 10811884Smckusick opt('p') = opt('t') = opt('b') = 1; 10911884Smckusick #ifdef vax 11011884Smckusick /* pdx is currently supported only on the vax */ 11111884Smckusick opt('g') = 1; 11211884Smckusick #endif vax 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': 13618349Smckusick yyunique = FALSE; 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; 1535654Slinton 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; 16618348Smckusick case 'L': 16718348Smckusick togopt( 'L' ); 16818348Smckusick continue; 169759Speter default: 170759Speter usage: 171759Speter Perror( "Usage", usageis); 172759Speter pexit(NOSTART); 173759Speter } 174759Speter argc--, argv++; 175759Speter } 176759Speter # endif OBJ 177759Speter # ifdef PC 178759Speter opt( 'b' ) = 1; 179759Speter opt( 'g' ) = 0; 180759Speter opt( 't' ) = 0; 181759Speter opt( 'p' ) = 0; 182759Speter usageis = pcusage; 183759Speter while ( argc > 0 ) { 184759Speter cp = argv[0]; 185759Speter if ( *cp++ != '-' ) { 186759Speter break; 187759Speter } 188759Speter c = *cp++; 189759Speter switch( c ) { 190759Speter #ifdef DEBUG 191759Speter case 'k': 192759Speter case 'r': 193759Speter case 'y': 194759Speter togopt(c); 195759Speter break; 196759Speter case 'K': 197759Speter yycosts(); 198759Speter pexit(NOSTART); 199759Speter case 'A': 2003138Smckusic testtrace = TRUE; 201759Speter /* and fall through */ 202759Speter case 'F': 2033138Smckusic fulltrace = TRUE; 204759Speter /* and fall through */ 205759Speter case 'E': 2063138Smckusic errtrace = TRUE; 207759Speter opt('r')++; 208759Speter break; 209759Speter case 'U': 21018349Smckusick yyunique = FALSE; 211759Speter break; 212759Speter #endif 213759Speter case 'b': 214759Speter opt('b') = 2; 215759Speter break; 216759Speter case 'i': 217759Speter pflist = argv + 1; 218759Speter pflstc = 0; 219759Speter while (argc > 1) { 220759Speter if (dotted(argv[1], 'p')) 221759Speter break; 222759Speter pflstc++, argc--, argv++; 223759Speter } 224759Speter if (pflstc == 0) 225759Speter goto usage; 226759Speter break; 227759Speter /* 228759Speter * output file for the first pass 229759Speter */ 230759Speter case 'o': 231759Speter if ( argc < 2 ) { 232759Speter goto usage; 233759Speter } 234759Speter argv++; 235759Speter argc--; 236759Speter pcname = argv[0]; 237759Speter break; 23812967Smckusick case 'J': 23912967Smckusick togopt( 'J' ); 24012967Smckusick break; 241759Speter case 'C': 242759Speter /* 243759Speter * since -t is an ld switch, use -C 244759Speter * to turn on tests 245759Speter */ 246759Speter togopt( 't' ); 247759Speter break; 248759Speter case 'g': 249759Speter /* 250759Speter * sdb symbol table 251759Speter */ 252759Speter togopt( 'g' ); 253759Speter break; 254759Speter case 'l': 255759Speter case 's': 256759Speter case 'u': 257759Speter case 'w': 258759Speter togopt(c); 259759Speter break; 260759Speter case 'p': 261759Speter /* 262759Speter * -p on the command line means profile 263759Speter */ 2643138Smckusic profflag = TRUE; 265759Speter break; 266759Speter case 'z': 2673138Smckusic monflg = TRUE; 268759Speter break; 26918348Smckusick case 'L': 27018348Smckusick togopt( 'L' ); 27118348Smckusick break; 272759Speter default: 273759Speter usage: 274759Speter Perror( "Usage", usageis); 275759Speter pexit(NOSTART); 276759Speter } 277759Speter argc--; 278759Speter argv++; 279759Speter } 280759Speter # endif PC 281759Speter if (argc != 1) 282759Speter goto usage; 2836407Speter efil = open ( err_file, 0 ); 284759Speter if ( efil < 0 ) 2856407Speter perror(err_file), pexit(NOSTART); 286759Speter filename = argv[0]; 287759Speter if (!dotted(filename, 'p')) { 288759Speter Perror(filename, "Name must end in '.p'"); 289759Speter pexit(NOSTART); 290759Speter } 291759Speter close(0); 292759Speter if ( ( ibuf = fopen( filename , "r" ) ) == NULL ) 293759Speter perror(filename), pexit(NOSTART); 294759Speter ibp = ibuf; 295759Speter # ifdef PC 296759Speter if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) { 297759Speter perror( pcname ); 298759Speter pexit( NOSTART ); 299759Speter } 30018348Smckusick stabsource( filename, TRUE ); 301759Speter # endif PC 302759Speter # ifdef PTREE 303759Speter # define MAXpPAGES 16 304759Speter if ( ! pCreate( pTreeName , MAXpPAGES ) ) { 305759Speter perror( pTreeName ); 306759Speter pexit( NOSTART ); 307759Speter } 308759Speter # endif PTREE 309759Speter if ( signal( SIGINT , SIG_IGN ) != SIG_IGN ) 31018349Smckusick (void) signal( SIGINT , onintr ); 311759Speter if (opt('l')) { 312759Speter opt('n')++; 313759Speter yysetfile(filename); 314759Speter opt('n')--; 315759Speter } 316759Speter yymain(); 317759Speter /* No return */ 318759Speter } 319759Speter 320759Speter pchr(c) 321759Speter char c; 322759Speter { 323759Speter 324759Speter putc ( c , stdout ); 325759Speter } 326759Speter 327*18449Smckusick #ifdef PC 328*18449Smckusick char ugh[] = "Fatal error in pc\n"; 329*18449Smckusick #endif 330*18449Smckusick #ifdef OBJ 331759Speter char ugh[] = "Fatal error in pi\n"; 332*18449Smckusick #endif 333759Speter /* 334759Speter * Exit from the Pascal system. 335759Speter * We throw in an ungraceful termination 336759Speter * message if c > 1 indicating a severe 337759Speter * error such as running out of memory 338759Speter * or an internal inconsistency. 339759Speter */ 340759Speter pexit(c) 341759Speter int c; 342759Speter { 343759Speter 344759Speter if (opt('l') && c != DIED && c != NOSTART) 345759Speter while (getline() != -1) 346759Speter continue; 347759Speter yyflush(); 348759Speter switch (c) { 349759Speter case DIED: 350759Speter write(2, ugh, sizeof ugh); 351759Speter case NOSTART: 352759Speter case ERRS: 353759Speter # ifdef OBJ 354759Speter if (ofil > 0) 355759Speter unlink(obj); 3565654Slinton /* 3575654Slinton * remove symbol table temp files 3585654Slinton */ 3595654Slinton removenlfile(); 3605654Slinton 361759Speter # endif OBJ 362759Speter # ifdef PC 363759Speter if ( pcstream != NULL ) { 364759Speter unlink( pcname ); 365759Speter } 366759Speter # endif PC 367759Speter break; 368759Speter case AOK: 369759Speter # ifdef OBJ 370759Speter pflush(); 3715654Slinton /* 3725654Slinton * copy symbol table temp files to obj file 3735654Slinton */ 3745654Slinton copynlfile(); 3755654Slinton 376759Speter # endif OBJ 377759Speter # ifdef PC 378759Speter puteof(); 379759Speter # endif PC 380759Speter break; 381759Speter } 382759Speter /* 383759Speter * this to gather statistics on programs being compiled 384759Speter * taken 20 june 79 ... peter 385759Speter * 386759Speter * if (fork() == 0) { 387759Speter * char *cp = "-0"; 388759Speter * cp[1] += c; 389759Speter * execl("/usr/lib/gather", "gather", cp, filename, 0); 390759Speter * exit(1); 391759Speter * } 392759Speter */ 393759Speter # ifdef PTREE 394759Speter pFinish(); 395759Speter # endif 396759Speter exit(c); 397759Speter } 398759Speter 399759Speter onintr() 400759Speter { 401759Speter 40218349Smckusick (void) signal( SIGINT , SIG_IGN ); 403759Speter pexit(NOSTART); 404759Speter } 405759Speter 406759Speter /* 407759Speter * Get an error message from the error message file 408759Speter */ 409759Speter geterr(seekpt, buf) 410759Speter int seekpt; 411759Speter char *buf; 412759Speter { 413759Speter 41418349Smckusick (void) lseek(efil, (long) seekpt, 0); 415759Speter if (read(efil, buf, 256) <= 0) 4166407Speter perror(err_file), pexit(DIED); 417759Speter } 418759Speter 419759Speter header() 420759Speter { 4216407Speter extern char *version; 422759Speter static char anyheaders; 423759Speter 424759Speter gettime( filename ); 425759Speter if (anyheaders && opt('n')) 426759Speter putc( '\f' , stdout ); 427759Speter anyheaders++; 428759Speter # ifdef OBJ 4296407Speter printf("Berkeley Pascal PI -- Version %s\n\n%s %s\n\n", 43018349Smckusick version, myctime((int *) (&tvec)), filename); 431759Speter # endif OBJ 432759Speter # ifdef PC 4336407Speter printf("Berkeley Pascal PC -- Version %s\n\n%s %s\n\n", 43418349Smckusick version, myctime((int *) (&tvec)), filename); 435759Speter # endif PC 436759Speter } 437