1 /*- 2 * Copyright (c) 1980, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char copyright[] = 10 "@(#) Copyright (c) 1980, 1993\n\ 11 The Regents of the University of California. All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 05/24/94"; 16 #endif /* not lint */ 17 18 #include "whoami.h" 19 #include "0.h" 20 #include "tree_ty.h" /* must be included for yy.h */ 21 #include "yy.h" 22 #include <signal.h> 23 #include "objfmt.h" 24 #include "config.h" 25 26 /* 27 * This version of pi has been in use at Berkeley since May 1977 28 * and is very stable. Please report any problems with the error 29 * recovery to the second author at the address given in the file 30 * READ_ME. The second author takes full responsibility for any bugs 31 * in the syntactic error recovery. 32 */ 33 34 char piusage[] = "pi [ -blnpstuw ] [ -i file ... ] name.p"; 35 36 char *usageis = piusage; 37 38 #ifdef OBJ 39 40 char pixusage[] = "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]"; 41 char *obj = "obj"; 42 43 #endif OBJ 44 45 #ifdef PC 46 47 char *pcname = "pc.pc0"; 48 char pcusage[] = "pc [ options ] [ -o file ] [ -i file ... ] name.p"; 49 FILE *pcstream = NULL; 50 51 #endif PC 52 #ifdef PTREE 53 char *pTreeName = "pi.pTree"; 54 #endif PTREE 55 56 int onintr(); 57 58 extern char *lastname; 59 60 FILE *ibuf; 61 62 /* 63 * these are made real variables 64 * so they can be changed 65 * if you are compiling on a smaller machine 66 */ 67 double MAXINT = 2147483647.; 68 double MININT = -2147483648.; 69 70 /* 71 * Main program for pi. 72 * Process options, then call yymain 73 * to do all the real work. 74 */ 75 main(argc, argv) 76 int argc; 77 char *argv[]; 78 { 79 register char *cp; 80 register c; 81 FILE *fopen(); 82 extern char *myctime(); 83 int i; 84 85 if (argv[0][0] == 'a') 86 err_file += err_pathlen , how_file += how_pathlen; 87 # ifdef OBJ 88 if (argv[0][0] == '-' && argv[0][1] == 'o') { 89 obj = &argv[0][2]; 90 usageis = pixusage; 91 how_file[strlen(how_file)] = 'x'; 92 ofil = 3; 93 } else { 94 ofil = creat(obj, 0755); 95 if (ofil < 0) { 96 perror(obj); 97 pexit(NOSTART); 98 } 99 } 100 # endif OBJ 101 argv++, argc--; 102 if (argc == 0) { 103 i = fork(); 104 if (i == -1) 105 goto usage; 106 if (i == 0) { 107 execl("/bin/cat", "cat", how_file, 0); 108 goto usage; 109 } 110 while (wait(&i) != -1) 111 continue; 112 pexit(NOSTART); 113 } 114 # ifdef OBJ 115 opt('p') = opt('t') = opt('b') = 1; 116 #if defined(vax) || defined(tahoe) 117 /* pdx is currently supported on the vax and the tahoe */ 118 opt('g') = 1; 119 #endif 120 while (argc > 0) { 121 cp = argv[0]; 122 if (*cp++ != '-') 123 break; 124 while (c = *cp++) switch (c) { 125 #ifdef DEBUG 126 case 'k': 127 case 'r': 128 case 'y': 129 togopt(c); 130 continue; 131 case 'K': 132 yycosts(); 133 pexit(NOSTART); 134 case 'A': 135 testtrace = TRUE; 136 case 'F': 137 fulltrace = TRUE; 138 case 'E': 139 errtrace = TRUE; 140 opt('r')++; 141 continue; 142 case 'U': 143 yyunique = FALSE; 144 continue; 145 #endif 146 case 'b': 147 opt('b') = 2; 148 continue; 149 case 'i': 150 pflist = argv + 1; 151 pflstc = 0; 152 while (argc > 1) { 153 if (dotted(argv[1], 'p')) 154 break; 155 pflstc++, argc--, argv++; 156 } 157 if (pflstc == 0) 158 goto usage; 159 continue; 160 case 'g': 161 case 'l': 162 case 'n': 163 case 'p': 164 case 's': 165 case 't': 166 case 'u': 167 case 'w': 168 togopt(c); 169 continue; 170 case 'z': 171 monflg = TRUE; 172 continue; 173 case 'L': 174 togopt( 'L' ); 175 continue; 176 default: 177 usage: 178 Perror( "Usage", usageis); 179 pexit(NOSTART); 180 } 181 argc--, argv++; 182 } 183 # endif OBJ 184 # ifdef PC 185 opt( 'b' ) = 1; 186 opt( 'g' ) = 0; 187 opt( 't' ) = 0; 188 opt( 'p' ) = 0; 189 usageis = pcusage; 190 while ( argc > 0 ) { 191 cp = argv[0]; 192 if ( *cp++ != '-' ) { 193 break; 194 } 195 c = *cp++; 196 switch( c ) { 197 #ifdef DEBUG 198 case 'k': 199 case 'r': 200 case 'y': 201 togopt(c); 202 break; 203 case 'K': 204 yycosts(); 205 pexit(NOSTART); 206 case 'A': 207 testtrace = TRUE; 208 /* and fall through */ 209 case 'F': 210 fulltrace = TRUE; 211 /* and fall through */ 212 case 'E': 213 errtrace = TRUE; 214 opt('r')++; 215 break; 216 case 'U': 217 yyunique = FALSE; 218 break; 219 #endif 220 case 'b': 221 opt('b') = 2; 222 break; 223 case 'i': 224 pflist = argv + 1; 225 pflstc = 0; 226 while (argc > 1) { 227 if (dotted(argv[1], 'p')) 228 break; 229 pflstc++, argc--, argv++; 230 } 231 if (pflstc == 0) 232 goto usage; 233 break; 234 /* 235 * output file for the first pass 236 */ 237 case 'o': 238 if ( argc < 2 ) { 239 goto usage; 240 } 241 argv++; 242 argc--; 243 pcname = argv[0]; 244 break; 245 case 'J': 246 togopt( 'J' ); 247 break; 248 case 'C': 249 /* 250 * since -t is an ld switch, use -C 251 * to turn on tests 252 */ 253 togopt( 't' ); 254 break; 255 case 'g': 256 /* 257 * sdb symbol table 258 */ 259 togopt( 'g' ); 260 break; 261 case 'l': 262 case 's': 263 case 'u': 264 case 'w': 265 togopt(c); 266 break; 267 case 'p': 268 /* 269 * -p on the command line means profile 270 */ 271 profflag = TRUE; 272 break; 273 case 'z': 274 monflg = TRUE; 275 break; 276 case 'L': 277 togopt( 'L' ); 278 break; 279 default: 280 usage: 281 Perror( "Usage", usageis); 282 pexit(NOSTART); 283 } 284 argc--; 285 argv++; 286 } 287 # endif PC 288 if (argc != 1) 289 goto usage; 290 efil = open ( err_file, 0 ); 291 if ( efil < 0 ) 292 perror(err_file), pexit(NOSTART); 293 filename = argv[0]; 294 if (!dotted(filename, 'p')) { 295 Perror(filename, "Name must end in '.p'"); 296 pexit(NOSTART); 297 } 298 close(0); 299 if ( ( ibuf = fopen( filename , "r" ) ) == NULL ) 300 perror(filename), pexit(NOSTART); 301 ibp = ibuf; 302 # ifdef PC 303 if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) { 304 perror( pcname ); 305 pexit( NOSTART ); 306 } 307 stabsource( filename, TRUE ); 308 # endif PC 309 # ifdef PTREE 310 # define MAXpPAGES 16 311 if ( ! pCreate( pTreeName , MAXpPAGES ) ) { 312 perror( pTreeName ); 313 pexit( NOSTART ); 314 } 315 # endif PTREE 316 if ( signal( SIGINT , SIG_IGN ) != SIG_IGN ) 317 (void) signal( SIGINT , onintr ); 318 if (opt('l')) { 319 opt('n')++; 320 yysetfile(filename); 321 opt('n')--; 322 } 323 yymain(); 324 /* No return */ 325 } 326 327 pchr(c) 328 char c; 329 { 330 331 putc ( c , stdout ); 332 } 333 334 #ifdef PC 335 char ugh[] = "Fatal error in pc\n"; 336 #endif 337 #ifdef OBJ 338 char ugh[] = "Fatal error in pi\n"; 339 #endif 340 /* 341 * Exit from the Pascal system. 342 * We throw in an ungraceful termination 343 * message if c > 1 indicating a severe 344 * error such as running out of memory 345 * or an internal inconsistency. 346 */ 347 pexit(c) 348 int c; 349 { 350 351 if (opt('l') && c != DIED && c != NOSTART) 352 while (getline() != -1) 353 continue; 354 yyflush(); 355 switch (c) { 356 case DIED: 357 write(2, ugh, sizeof ugh); 358 case NOSTART: 359 case ERRS: 360 # ifdef OBJ 361 if (ofil > 0) 362 unlink(obj); 363 /* 364 * remove symbol table temp files 365 */ 366 removenlfile(); 367 368 # endif OBJ 369 # ifdef PC 370 if ( pcstream != NULL ) { 371 unlink( pcname ); 372 } 373 # endif PC 374 break; 375 case AOK: 376 # ifdef OBJ 377 pflush(); 378 /* 379 * copy symbol table temp files to obj file 380 */ 381 copynlfile(); 382 383 # endif OBJ 384 # ifdef PC 385 puteof(); 386 # endif PC 387 break; 388 } 389 /* 390 * this to gather statistics on programs being compiled 391 * taken 20 june 79 ... peter 392 * 393 * if (fork() == 0) { 394 * char *cp = "-0"; 395 * cp[1] += c; 396 * execl("/usr/lib/gather", "gather", cp, filename, 0); 397 * exit(1); 398 * } 399 */ 400 # ifdef PTREE 401 pFinish(); 402 # endif 403 exit(c); 404 } 405 406 onintr() 407 { 408 409 (void) signal( SIGINT , SIG_IGN ); 410 pexit(NOSTART); 411 } 412 413 /* 414 * Get an error message from the error message file 415 */ 416 geterr(seekpt, buf) 417 int seekpt; 418 char *buf; 419 { 420 421 if (lseek(efil, (off_t) seekpt, 0) == -1) 422 perror(err_file), pexit(DIED); 423 if (read(efil, buf, 256) <= 0) 424 perror(err_file), pexit(DIED); 425 } 426 427 header() 428 { 429 extern char *version; 430 static char anyheaders; 431 432 gettime( filename ); 433 if (anyheaders && opt('n')) 434 putc( '\f' , stdout ); 435 anyheaders++; 436 # ifdef OBJ 437 printf("Berkeley Pascal PI -- Version %s\n\n%s %s\n\n", 438 version, myctime((int *) (&tvec)), filename); 439 # endif OBJ 440 # ifdef PC 441 printf("Berkeley Pascal PC -- Version %s\n\n%s %s\n\n", 442 version, myctime((int *) (&tvec)), filename); 443 # endif PC 444 } 445