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*6407Speter static char sccsid[] = "@(#)main.c 1.7 03/31/82"; 7759Speter 8759Speter #include "whoami.h" 9759Speter #include "0.h" 10759Speter #include "yy.h" 11759Speter #include <signal.h> 12759Speter #include "objfmt.h" 13*6407Speter #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') 68*6407Speter 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; 73*6407Speter 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) { 89*6407Speter 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 975654Slinton opt('g') = opt('p') = opt('t') = opt('b') = 1; 98759Speter while (argc > 0) { 99759Speter cp = argv[0]; 100759Speter if (*cp++ != '-') 101759Speter break; 102759Speter while (c = *cp++) switch (c) { 103759Speter #ifdef DEBUG 104759Speter case 'k': 105759Speter case 'r': 106759Speter case 'y': 107759Speter togopt(c); 108759Speter continue; 109759Speter case 'K': 110759Speter yycosts(); 111759Speter pexit(NOSTART); 112759Speter case 'A': 1133075Smckusic testtrace = TRUE; 114759Speter case 'F': 1153075Smckusic fulltrace = TRUE; 116759Speter case 'E': 1173075Smckusic errtrace = TRUE; 118759Speter opt('r')++; 119759Speter continue; 120759Speter case 'U': 121759Speter yyunique = 0; 122759Speter continue; 123759Speter #endif 124759Speter case 'b': 125759Speter opt('b') = 2; 126759Speter continue; 127759Speter case 'i': 128759Speter pflist = argv + 1; 129759Speter pflstc = 0; 130759Speter while (argc > 1) { 131759Speter if (dotted(argv[1], 'p')) 132759Speter break; 133759Speter pflstc++, argc--, argv++; 134759Speter } 135759Speter if (pflstc == 0) 136759Speter goto usage; 137759Speter continue; 1385654Slinton case 'g': 139759Speter case 'l': 140759Speter case 'n': 141759Speter case 'p': 142759Speter case 's': 143759Speter case 't': 144759Speter case 'u': 145759Speter case 'w': 146759Speter togopt(c); 147759Speter continue; 148759Speter case 'z': 1493075Smckusic monflg = TRUE; 150759Speter continue; 151759Speter default: 152759Speter usage: 153759Speter Perror( "Usage", usageis); 154759Speter pexit(NOSTART); 155759Speter } 156759Speter argc--, argv++; 157759Speter } 158759Speter # endif OBJ 159759Speter # ifdef PC 160759Speter opt( 'b' ) = 1; 161759Speter opt( 'g' ) = 0; 162759Speter opt( 't' ) = 0; 163759Speter opt( 'p' ) = 0; 164759Speter usageis = pcusage; 165759Speter while ( argc > 0 ) { 166759Speter cp = argv[0]; 167759Speter if ( *cp++ != '-' ) { 168759Speter break; 169759Speter } 170759Speter c = *cp++; 171759Speter switch( c ) { 172759Speter #ifdef DEBUG 173759Speter case 'k': 174759Speter case 'r': 175759Speter case 'y': 176759Speter togopt(c); 177759Speter break; 178759Speter case 'K': 179759Speter yycosts(); 180759Speter pexit(NOSTART); 181759Speter case 'A': 1823138Smckusic testtrace = TRUE; 183759Speter /* and fall through */ 184759Speter case 'F': 1853138Smckusic fulltrace = TRUE; 186759Speter /* and fall through */ 187759Speter case 'E': 1883138Smckusic errtrace = TRUE; 189759Speter opt('r')++; 190759Speter break; 191759Speter case 'U': 192759Speter yyunique = 0; 193759Speter break; 194759Speter #endif 195759Speter case 'b': 196759Speter opt('b') = 2; 197759Speter break; 198759Speter case 'i': 199759Speter pflist = argv + 1; 200759Speter pflstc = 0; 201759Speter while (argc > 1) { 202759Speter if (dotted(argv[1], 'p')) 203759Speter break; 204759Speter pflstc++, argc--, argv++; 205759Speter } 206759Speter if (pflstc == 0) 207759Speter goto usage; 208759Speter break; 209759Speter /* 210759Speter * output file for the first pass 211759Speter */ 212759Speter case 'o': 213759Speter if ( argc < 2 ) { 214759Speter goto usage; 215759Speter } 216759Speter argv++; 217759Speter argc--; 218759Speter pcname = argv[0]; 219759Speter break; 220759Speter case 'C': 221759Speter /* 222759Speter * since -t is an ld switch, use -C 223759Speter * to turn on tests 224759Speter */ 225759Speter togopt( 't' ); 226759Speter break; 227759Speter case 'g': 228759Speter /* 229759Speter * sdb symbol table 230759Speter */ 231759Speter togopt( 'g' ); 232759Speter break; 233759Speter case 'l': 234759Speter case 's': 235759Speter case 'u': 236759Speter case 'w': 237759Speter togopt(c); 238759Speter break; 239759Speter case 'p': 240759Speter /* 241759Speter * -p on the command line means profile 242759Speter */ 2433138Smckusic profflag = TRUE; 244759Speter break; 245759Speter case 'z': 2463138Smckusic monflg = TRUE; 247759Speter break; 248759Speter default: 249759Speter usage: 250759Speter Perror( "Usage", usageis); 251759Speter pexit(NOSTART); 252759Speter } 253759Speter argc--; 254759Speter argv++; 255759Speter } 256759Speter # endif PC 257759Speter if (argc != 1) 258759Speter goto usage; 259*6407Speter efil = open ( err_file, 0 ); 260759Speter if ( efil < 0 ) 261*6407Speter perror(err_file), pexit(NOSTART); 262759Speter filename = argv[0]; 263759Speter if (!dotted(filename, 'p')) { 264759Speter Perror(filename, "Name must end in '.p'"); 265759Speter pexit(NOSTART); 266759Speter } 267759Speter close(0); 268759Speter if ( ( ibuf = fopen( filename , "r" ) ) == NULL ) 269759Speter perror(filename), pexit(NOSTART); 270759Speter ibp = ibuf; 271759Speter # ifdef PC 272759Speter if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) { 273759Speter perror( pcname ); 274759Speter pexit( NOSTART ); 275759Speter } 276759Speter stabsource( filename ); 277759Speter # endif PC 278759Speter # ifdef PTREE 279759Speter # define MAXpPAGES 16 280759Speter if ( ! pCreate( pTreeName , MAXpPAGES ) ) { 281759Speter perror( pTreeName ); 282759Speter pexit( NOSTART ); 283759Speter } 284759Speter # endif PTREE 285759Speter if ( signal( SIGINT , SIG_IGN ) != SIG_IGN ) 286759Speter signal( SIGINT , onintr ); 287759Speter if (opt('l')) { 288759Speter opt('n')++; 289759Speter yysetfile(filename); 290759Speter opt('n')--; 291759Speter } 292759Speter yymain(); 293759Speter /* No return */ 294759Speter } 295759Speter 296759Speter pchr(c) 297759Speter char c; 298759Speter { 299759Speter 300759Speter putc ( c , stdout ); 301759Speter } 302759Speter 303759Speter char ugh[] = "Fatal error in pi\n"; 304759Speter /* 305759Speter * Exit from the Pascal system. 306759Speter * We throw in an ungraceful termination 307759Speter * message if c > 1 indicating a severe 308759Speter * error such as running out of memory 309759Speter * or an internal inconsistency. 310759Speter */ 311759Speter pexit(c) 312759Speter int c; 313759Speter { 314759Speter 315759Speter if (opt('l') && c != DIED && c != NOSTART) 316759Speter while (getline() != -1) 317759Speter continue; 318759Speter yyflush(); 319759Speter switch (c) { 320759Speter case DIED: 321759Speter write(2, ugh, sizeof ugh); 322759Speter case NOSTART: 323759Speter case ERRS: 324759Speter # ifdef OBJ 325759Speter if (ofil > 0) 326759Speter unlink(obj); 3275654Slinton /* 3285654Slinton * remove symbol table temp files 3295654Slinton */ 3305654Slinton removenlfile(); 3315654Slinton 332759Speter # endif OBJ 333759Speter # ifdef PC 334759Speter if ( pcstream != NULL ) { 335759Speter unlink( pcname ); 336759Speter } 337759Speter # endif PC 338759Speter break; 339759Speter case AOK: 340759Speter # ifdef OBJ 341759Speter pflush(); 3425654Slinton /* 3435654Slinton * copy symbol table temp files to obj file 3445654Slinton */ 3455654Slinton copynlfile(); 3465654Slinton 347759Speter # endif OBJ 348759Speter # ifdef PC 349759Speter puteof(); 350759Speter # endif PC 351759Speter break; 352759Speter } 353759Speter /* 354759Speter * this to gather statistics on programs being compiled 355759Speter * taken 20 june 79 ... peter 356759Speter * 357759Speter * if (fork() == 0) { 358759Speter * char *cp = "-0"; 359759Speter * cp[1] += c; 360759Speter * execl("/usr/lib/gather", "gather", cp, filename, 0); 361759Speter * exit(1); 362759Speter * } 363759Speter */ 364759Speter # ifdef PTREE 365759Speter pFinish(); 366759Speter # endif 367759Speter exit(c); 368759Speter } 369759Speter 370759Speter onintr() 371759Speter { 372759Speter 373759Speter signal( SIGINT , SIG_IGN ); 374759Speter pexit(NOSTART); 375759Speter } 376759Speter 377759Speter /* 378759Speter * Get an error message from the error message file 379759Speter */ 380759Speter geterr(seekpt, buf) 381759Speter int seekpt; 382759Speter char *buf; 383759Speter { 384759Speter 385759Speter lseek(efil, (long) seekpt, 0); 386759Speter if (read(efil, buf, 256) <= 0) 387*6407Speter perror(err_file), pexit(DIED); 388759Speter } 389759Speter 390759Speter header() 391759Speter { 392*6407Speter extern char *version; 393759Speter static char anyheaders; 394759Speter 395759Speter gettime( filename ); 396759Speter if (anyheaders && opt('n')) 397759Speter putc( '\f' , stdout ); 398759Speter anyheaders++; 399759Speter # ifdef OBJ 400*6407Speter printf("Berkeley Pascal PI -- Version %s\n\n%s %s\n\n", 401759Speter version, myctime(&tvec), filename); 402759Speter # endif OBJ 403759Speter # ifdef PC 404*6407Speter printf("Berkeley Pascal PC -- Version %s\n\n%s %s\n\n", 405759Speter version, myctime(&tvec), filename); 406759Speter # endif PC 407759Speter } 408