122177Sdist /* 222177Sdist * Copyright (c) 1980 Regents of the University of California. 322177Sdist * All rights reserved. The Berkeley software License Agreement 422177Sdist * specifies the terms and conditions for redistribution. 522177Sdist */ 63075Smckusic 718349Smckusick #ifndef lint 822177Sdist char copyright[] = 922177Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1022177Sdist All rights reserved.\n"; 1122177Sdist #endif not lint 12759Speter 1322177Sdist #ifndef lint 14*30838Smckusick static char sccsid[] = "@(#)main.c 5.2 (Berkeley) 04/07/87"; 1522177Sdist #endif not lint 16759Speter 17759Speter #include "whoami.h" 18759Speter #include "0.h" 1918349Smckusick #include "tree_ty.h" /* must be included for yy.h */ 20759Speter #include "yy.h" 21759Speter #include <signal.h> 22759Speter #include "objfmt.h" 236407Speter #include "config.h" 24759Speter 25759Speter /* 26759Speter * This version of pi has been in use at Berkeley since May 1977 273075Smckusic * and is very stable. Please report any problems with the error 28759Speter * recovery to the second author at the address given in the file 29759Speter * READ_ME. The second author takes full responsibility for any bugs 30759Speter * in the syntactic error recovery. 31759Speter */ 32759Speter 33759Speter char piusage[] = "pi [ -blnpstuw ] [ -i file ... ] name.p"; 34759Speter 35759Speter char *usageis = piusage; 36759Speter 37759Speter #ifdef OBJ 3818349Smckusick 3918349Smckusick char pixusage[] = "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]"; 4018349Smckusick char *obj = "obj"; 4118349Smckusick 42759Speter #endif OBJ 4318349Smckusick 44759Speter #ifdef PC 4518349Smckusick 4618349Smckusick char *pcname = "pc.pc0"; 4718349Smckusick char pcusage[] = "pc [ options ] [ -o file ] [ -i file ... ] name.p"; 4818349Smckusick FILE *pcstream = NULL; 4918349Smckusick 50759Speter #endif PC 51759Speter #ifdef PTREE 52759Speter char *pTreeName = "pi.pTree"; 53759Speter #endif PTREE 54759Speter 55759Speter int onintr(); 56759Speter 57759Speter extern char *lastname; 58759Speter 59759Speter FILE *ibuf; 60759Speter 61759Speter /* 62759Speter * these are made real variables 63759Speter * so they can be changed 64759Speter * if you are compiling on a smaller machine 65759Speter */ 66759Speter double MAXINT = 2147483647.; 67759Speter double MININT = -2147483648.; 68759Speter 69759Speter /* 70759Speter * Main program for pi. 71759Speter * Process options, then call yymain 72759Speter * to do all the real work. 73759Speter */ 74759Speter main(argc, argv) 75759Speter int argc; 76759Speter char *argv[]; 77759Speter { 78759Speter register char *cp; 79759Speter register c; 8018349Smckusick FILE *fopen(); 8118349Smckusick extern char *myctime(); 8218349Smckusick extern long lseek(); 83759Speter int i; 84759Speter 85759Speter if (argv[0][0] == 'a') 866407Speter err_file += err_pathlen , how_file += how_pathlen; 87759Speter # ifdef OBJ 88759Speter if (argv[0][0] == '-' && argv[0][1] == 'o') { 89759Speter obj = &argv[0][2]; 90759Speter usageis = pixusage; 916407Speter how_file[strlen(how_file)] = 'x'; 92759Speter ofil = 3; 93759Speter } else { 94759Speter ofil = creat(obj, 0755); 95759Speter if (ofil < 0) { 96759Speter perror(obj); 97759Speter pexit(NOSTART); 98759Speter } 99759Speter } 100759Speter # endif OBJ 101759Speter argv++, argc--; 102759Speter if (argc == 0) { 103759Speter i = fork(); 104759Speter if (i == -1) 105759Speter goto usage; 106759Speter if (i == 0) { 1076407Speter execl("/bin/cat", "cat", how_file, 0); 108759Speter goto usage; 109759Speter } 110759Speter while (wait(&i) != -1) 111759Speter continue; 112759Speter pexit(NOSTART); 113759Speter } 114759Speter # ifdef OBJ 11511884Smckusick opt('p') = opt('t') = opt('b') = 1; 116*30838Smckusick #if defined(vax) || defined(tahoe) 117*30838Smckusick /* pdx is currently supported on the vax and the tahoe */ 11811884Smckusick opt('g') = 1; 119*30838Smckusick #endif 120759Speter while (argc > 0) { 121759Speter cp = argv[0]; 122759Speter if (*cp++ != '-') 123759Speter break; 124759Speter while (c = *cp++) switch (c) { 125759Speter #ifdef DEBUG 126759Speter case 'k': 127759Speter case 'r': 128759Speter case 'y': 129759Speter togopt(c); 130759Speter continue; 131759Speter case 'K': 132759Speter yycosts(); 133759Speter pexit(NOSTART); 134759Speter case 'A': 1353075Smckusic testtrace = TRUE; 136759Speter case 'F': 1373075Smckusic fulltrace = TRUE; 138759Speter case 'E': 1393075Smckusic errtrace = TRUE; 140759Speter opt('r')++; 141759Speter continue; 142759Speter case 'U': 14318349Smckusick yyunique = FALSE; 144759Speter continue; 145759Speter #endif 146759Speter case 'b': 147759Speter opt('b') = 2; 148759Speter continue; 149759Speter case 'i': 150759Speter pflist = argv + 1; 151759Speter pflstc = 0; 152759Speter while (argc > 1) { 153759Speter if (dotted(argv[1], 'p')) 154759Speter break; 155759Speter pflstc++, argc--, argv++; 156759Speter } 157759Speter if (pflstc == 0) 158759Speter goto usage; 159759Speter continue; 1605654Slinton case 'g': 161759Speter case 'l': 162759Speter case 'n': 163759Speter case 'p': 164759Speter case 's': 165759Speter case 't': 166759Speter case 'u': 167759Speter case 'w': 168759Speter togopt(c); 169759Speter continue; 170759Speter case 'z': 1713075Smckusic monflg = TRUE; 172759Speter continue; 17318348Smckusick case 'L': 17418348Smckusick togopt( 'L' ); 17518348Smckusick continue; 176759Speter default: 177759Speter usage: 178759Speter Perror( "Usage", usageis); 179759Speter pexit(NOSTART); 180759Speter } 181759Speter argc--, argv++; 182759Speter } 183759Speter # endif OBJ 184759Speter # ifdef PC 185759Speter opt( 'b' ) = 1; 186759Speter opt( 'g' ) = 0; 187759Speter opt( 't' ) = 0; 188759Speter opt( 'p' ) = 0; 189759Speter usageis = pcusage; 190759Speter while ( argc > 0 ) { 191759Speter cp = argv[0]; 192759Speter if ( *cp++ != '-' ) { 193759Speter break; 194759Speter } 195759Speter c = *cp++; 196759Speter switch( c ) { 197759Speter #ifdef DEBUG 198759Speter case 'k': 199759Speter case 'r': 200759Speter case 'y': 201759Speter togopt(c); 202759Speter break; 203759Speter case 'K': 204759Speter yycosts(); 205759Speter pexit(NOSTART); 206759Speter case 'A': 2073138Smckusic testtrace = TRUE; 208759Speter /* and fall through */ 209759Speter case 'F': 2103138Smckusic fulltrace = TRUE; 211759Speter /* and fall through */ 212759Speter case 'E': 2133138Smckusic errtrace = TRUE; 214759Speter opt('r')++; 215759Speter break; 216759Speter case 'U': 21718349Smckusick yyunique = FALSE; 218759Speter break; 219759Speter #endif 220759Speter case 'b': 221759Speter opt('b') = 2; 222759Speter break; 223759Speter case 'i': 224759Speter pflist = argv + 1; 225759Speter pflstc = 0; 226759Speter while (argc > 1) { 227759Speter if (dotted(argv[1], 'p')) 228759Speter break; 229759Speter pflstc++, argc--, argv++; 230759Speter } 231759Speter if (pflstc == 0) 232759Speter goto usage; 233759Speter break; 234759Speter /* 235759Speter * output file for the first pass 236759Speter */ 237759Speter case 'o': 238759Speter if ( argc < 2 ) { 239759Speter goto usage; 240759Speter } 241759Speter argv++; 242759Speter argc--; 243759Speter pcname = argv[0]; 244759Speter break; 24512967Smckusick case 'J': 24612967Smckusick togopt( 'J' ); 24712967Smckusick break; 248759Speter case 'C': 249759Speter /* 250759Speter * since -t is an ld switch, use -C 251759Speter * to turn on tests 252759Speter */ 253759Speter togopt( 't' ); 254759Speter break; 255759Speter case 'g': 256759Speter /* 257759Speter * sdb symbol table 258759Speter */ 259759Speter togopt( 'g' ); 260759Speter break; 261759Speter case 'l': 262759Speter case 's': 263759Speter case 'u': 264759Speter case 'w': 265759Speter togopt(c); 266759Speter break; 267759Speter case 'p': 268759Speter /* 269759Speter * -p on the command line means profile 270759Speter */ 2713138Smckusic profflag = TRUE; 272759Speter break; 273759Speter case 'z': 2743138Smckusic monflg = TRUE; 275759Speter break; 27618348Smckusick case 'L': 27718348Smckusick togopt( 'L' ); 27818348Smckusick break; 279759Speter default: 280759Speter usage: 281759Speter Perror( "Usage", usageis); 282759Speter pexit(NOSTART); 283759Speter } 284759Speter argc--; 285759Speter argv++; 286759Speter } 287759Speter # endif PC 288759Speter if (argc != 1) 289759Speter goto usage; 2906407Speter efil = open ( err_file, 0 ); 291759Speter if ( efil < 0 ) 2926407Speter perror(err_file), pexit(NOSTART); 293759Speter filename = argv[0]; 294759Speter if (!dotted(filename, 'p')) { 295759Speter Perror(filename, "Name must end in '.p'"); 296759Speter pexit(NOSTART); 297759Speter } 298759Speter close(0); 299759Speter if ( ( ibuf = fopen( filename , "r" ) ) == NULL ) 300759Speter perror(filename), pexit(NOSTART); 301759Speter ibp = ibuf; 302759Speter # ifdef PC 303759Speter if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) { 304759Speter perror( pcname ); 305759Speter pexit( NOSTART ); 306759Speter } 30718348Smckusick stabsource( filename, TRUE ); 308759Speter # endif PC 309759Speter # ifdef PTREE 310759Speter # define MAXpPAGES 16 311759Speter if ( ! pCreate( pTreeName , MAXpPAGES ) ) { 312759Speter perror( pTreeName ); 313759Speter pexit( NOSTART ); 314759Speter } 315759Speter # endif PTREE 316759Speter if ( signal( SIGINT , SIG_IGN ) != SIG_IGN ) 31718349Smckusick (void) signal( SIGINT , onintr ); 318759Speter if (opt('l')) { 319759Speter opt('n')++; 320759Speter yysetfile(filename); 321759Speter opt('n')--; 322759Speter } 323759Speter yymain(); 324759Speter /* No return */ 325759Speter } 326759Speter 327759Speter pchr(c) 328759Speter char c; 329759Speter { 330759Speter 331759Speter putc ( c , stdout ); 332759Speter } 333759Speter 33418449Smckusick #ifdef PC 33518449Smckusick char ugh[] = "Fatal error in pc\n"; 33618449Smckusick #endif 33718449Smckusick #ifdef OBJ 338759Speter char ugh[] = "Fatal error in pi\n"; 33918449Smckusick #endif 340759Speter /* 341759Speter * Exit from the Pascal system. 342759Speter * We throw in an ungraceful termination 343759Speter * message if c > 1 indicating a severe 344759Speter * error such as running out of memory 345759Speter * or an internal inconsistency. 346759Speter */ 347759Speter pexit(c) 348759Speter int c; 349759Speter { 350759Speter 351759Speter if (opt('l') && c != DIED && c != NOSTART) 352759Speter while (getline() != -1) 353759Speter continue; 354759Speter yyflush(); 355759Speter switch (c) { 356759Speter case DIED: 357759Speter write(2, ugh, sizeof ugh); 358759Speter case NOSTART: 359759Speter case ERRS: 360759Speter # ifdef OBJ 361759Speter if (ofil > 0) 362759Speter unlink(obj); 3635654Slinton /* 3645654Slinton * remove symbol table temp files 3655654Slinton */ 3665654Slinton removenlfile(); 3675654Slinton 368759Speter # endif OBJ 369759Speter # ifdef PC 370759Speter if ( pcstream != NULL ) { 371759Speter unlink( pcname ); 372759Speter } 373759Speter # endif PC 374759Speter break; 375759Speter case AOK: 376759Speter # ifdef OBJ 377759Speter pflush(); 3785654Slinton /* 3795654Slinton * copy symbol table temp files to obj file 3805654Slinton */ 3815654Slinton copynlfile(); 3825654Slinton 383759Speter # endif OBJ 384759Speter # ifdef PC 385759Speter puteof(); 386759Speter # endif PC 387759Speter break; 388759Speter } 389759Speter /* 390759Speter * this to gather statistics on programs being compiled 391759Speter * taken 20 june 79 ... peter 392759Speter * 393759Speter * if (fork() == 0) { 394759Speter * char *cp = "-0"; 395759Speter * cp[1] += c; 396759Speter * execl("/usr/lib/gather", "gather", cp, filename, 0); 397759Speter * exit(1); 398759Speter * } 399759Speter */ 400759Speter # ifdef PTREE 401759Speter pFinish(); 402759Speter # endif 403759Speter exit(c); 404759Speter } 405759Speter 406759Speter onintr() 407759Speter { 408759Speter 40918349Smckusick (void) signal( SIGINT , SIG_IGN ); 410759Speter pexit(NOSTART); 411759Speter } 412759Speter 413759Speter /* 414759Speter * Get an error message from the error message file 415759Speter */ 416759Speter geterr(seekpt, buf) 417759Speter int seekpt; 418759Speter char *buf; 419759Speter { 420759Speter 42118349Smckusick (void) lseek(efil, (long) seekpt, 0); 422759Speter if (read(efil, buf, 256) <= 0) 4236407Speter perror(err_file), pexit(DIED); 424759Speter } 425759Speter 426759Speter header() 427759Speter { 4286407Speter extern char *version; 429759Speter static char anyheaders; 430759Speter 431759Speter gettime( filename ); 432759Speter if (anyheaders && opt('n')) 433759Speter putc( '\f' , stdout ); 434759Speter anyheaders++; 435759Speter # ifdef OBJ 4366407Speter printf("Berkeley Pascal PI -- Version %s\n\n%s %s\n\n", 43718349Smckusick version, myctime((int *) (&tvec)), filename); 438759Speter # endif OBJ 439759Speter # ifdef PC 4406407Speter printf("Berkeley Pascal PC -- Version %s\n\n%s %s\n\n", 44118349Smckusick version, myctime((int *) (&tvec)), filename); 442759Speter # endif PC 443759Speter } 444