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