1 /* Copyright (c) 1979 Regents of the University of California */ 2 3 static char copyright[] = 4 "@(#)Copyright (c) 1979 Regents of the University of California"; 5 6 static char sccsid[] = "@(#)main.c 1.6 03/30/82"; 7 8 #include "whoami.h" 9 #include "0.h" 10 #include "yy.h" 11 #include <signal.h> 12 #include "objfmt.h" 13 14 /* 15 * This version of pi has been in use at Berkeley since May 1977 16 * and is very stable. Please report any problems with the error 17 * recovery to the second author at the address given in the file 18 * READ_ME. The second author takes full responsibility for any bugs 19 * in the syntactic error recovery. 20 */ 21 22 char piusage[] = "pi [ -blnpstuw ] [ -i file ... ] name.p"; 23 char pixusage[] = "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]"; 24 char pcusage[] = "pc [ options ] [ -o file ] [ -i file ... ] name.p"; 25 26 char *usageis = piusage; 27 28 char *errfile = ERR_STRNGS; 29 30 #ifdef OBJ 31 char *obj = "obj"; 32 #endif OBJ 33 #ifdef PC 34 char *pcname = "pc.pc0"; 35 #endif PC 36 #ifdef PTREE 37 char *pTreeName = "pi.pTree"; 38 #endif PTREE 39 40 /* 41 * Be careful changing errfile and howfile. 42 * There are the "magic" constants 9 and 15 immediately below. 43 * errfile is now defined by ERR_STRNGS, in objfmt.h, 44 * and its leading path name length is ERR_PATHLEN long. 45 * this for executing out of the current directory if running as `a.something'. 46 */ 47 #ifdef OBJ 48 char *howfile = HOW_STRNGS; 49 #endif OBJ 50 #ifdef PC 51 char *howfile = HOW_STRNGS; 52 #endif PC 53 54 int onintr(); 55 56 extern char *lastname; 57 58 FILE *ibuf; 59 FILE *pcstream = NULL; 60 61 /* 62 * these are made real variables 63 * so they can be changed 64 * if you are compiling on a smaller machine 65 */ 66 double MAXINT = 2147483647.; 67 double MININT = -2147483648.; 68 69 /* 70 * Main program for pi. 71 * Process options, then call yymain 72 * to do all the real work. 73 */ 74 main(argc, argv) 75 int argc; 76 char *argv[]; 77 { 78 register char *cp; 79 register c; 80 int i; 81 82 if (argv[0][0] == 'a') 83 errfile += ERR_PATHLEN , howfile += HOW_PATHLEN; 84 # ifdef OBJ 85 if (argv[0][0] == '-' && argv[0][1] == 'o') { 86 obj = &argv[0][2]; 87 usageis = pixusage; 88 howfile[HOW_PATHLEN+6] = 'x'; 89 ofil = 3; 90 } else { 91 ofil = creat(obj, 0755); 92 if (ofil < 0) { 93 perror(obj); 94 pexit(NOSTART); 95 } 96 } 97 # endif OBJ 98 argv++, argc--; 99 if (argc == 0) { 100 i = fork(); 101 if (i == -1) 102 goto usage; 103 if (i == 0) { 104 execl("/bin/cat", "cat", howfile, 0); 105 goto usage; 106 } 107 while (wait(&i) != -1) 108 continue; 109 pexit(NOSTART); 110 } 111 # ifdef OBJ 112 opt('g') = opt('p') = opt('t') = opt('b') = 1; 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 = 0; 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 = 0; 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 'C': 236 /* 237 * since -t is an ld switch, use -C 238 * to turn on tests 239 */ 240 togopt( 't' ); 241 break; 242 case 'g': 243 /* 244 * sdb symbol table 245 */ 246 togopt( 'g' ); 247 break; 248 case 'l': 249 case 's': 250 case 'u': 251 case 'w': 252 togopt(c); 253 break; 254 case 'p': 255 /* 256 * -p on the command line means profile 257 */ 258 profflag = TRUE; 259 break; 260 case 'z': 261 monflg = TRUE; 262 break; 263 default: 264 usage: 265 Perror( "Usage", usageis); 266 pexit(NOSTART); 267 } 268 argc--; 269 argv++; 270 } 271 # endif PC 272 if (argc != 1) 273 goto usage; 274 efil = open ( errfile, 0 ); 275 if ( efil < 0 ) 276 perror(errfile), pexit(NOSTART); 277 filename = argv[0]; 278 if (!dotted(filename, 'p')) { 279 Perror(filename, "Name must end in '.p'"); 280 pexit(NOSTART); 281 } 282 close(0); 283 if ( ( ibuf = fopen( filename , "r" ) ) == NULL ) 284 perror(filename), pexit(NOSTART); 285 ibp = ibuf; 286 # ifdef PC 287 if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) { 288 perror( pcname ); 289 pexit( NOSTART ); 290 } 291 stabsource( filename ); 292 # endif PC 293 # ifdef PTREE 294 # define MAXpPAGES 16 295 if ( ! pCreate( pTreeName , MAXpPAGES ) ) { 296 perror( pTreeName ); 297 pexit( NOSTART ); 298 } 299 # endif PTREE 300 if ( signal( SIGINT , SIG_IGN ) != SIG_IGN ) 301 signal( SIGINT , onintr ); 302 if (opt('l')) { 303 opt('n')++; 304 yysetfile(filename); 305 opt('n')--; 306 } 307 yymain(); 308 /* No return */ 309 } 310 311 pchr(c) 312 char c; 313 { 314 315 putc ( c , stdout ); 316 } 317 318 char ugh[] = "Fatal error in pi\n"; 319 /* 320 * Exit from the Pascal system. 321 * We throw in an ungraceful termination 322 * message if c > 1 indicating a severe 323 * error such as running out of memory 324 * or an internal inconsistency. 325 */ 326 pexit(c) 327 int c; 328 { 329 330 if (opt('l') && c != DIED && c != NOSTART) 331 while (getline() != -1) 332 continue; 333 yyflush(); 334 switch (c) { 335 case DIED: 336 write(2, ugh, sizeof ugh); 337 case NOSTART: 338 case ERRS: 339 # ifdef OBJ 340 if (ofil > 0) 341 unlink(obj); 342 /* 343 * remove symbol table temp files 344 */ 345 removenlfile(); 346 347 # endif OBJ 348 # ifdef PC 349 if ( pcstream != NULL ) { 350 unlink( pcname ); 351 } 352 # endif PC 353 break; 354 case AOK: 355 # ifdef OBJ 356 pflush(); 357 /* 358 * copy symbol table temp files to obj file 359 */ 360 copynlfile(); 361 362 # endif OBJ 363 # ifdef PC 364 puteof(); 365 # endif PC 366 break; 367 } 368 /* 369 * this to gather statistics on programs being compiled 370 * taken 20 june 79 ... peter 371 * 372 * if (fork() == 0) { 373 * char *cp = "-0"; 374 * cp[1] += c; 375 * execl("/usr/lib/gather", "gather", cp, filename, 0); 376 * exit(1); 377 * } 378 */ 379 # ifdef PTREE 380 pFinish(); 381 # endif 382 exit(c); 383 } 384 385 onintr() 386 { 387 388 signal( SIGINT , SIG_IGN ); 389 pexit(NOSTART); 390 } 391 392 /* 393 * Get an error message from the error message file 394 */ 395 geterr(seekpt, buf) 396 int seekpt; 397 char *buf; 398 { 399 400 lseek(efil, (long) seekpt, 0); 401 if (read(efil, buf, 256) <= 0) 402 perror(errfile), pexit(DIED); 403 } 404 405 header() 406 { 407 extern char version[]; 408 static char anyheaders; 409 410 gettime( filename ); 411 if (anyheaders && opt('n')) 412 putc( '\f' , stdout ); 413 anyheaders++; 414 # ifdef OBJ 415 printf("Berkeley Pascal PI -- Version 2.0 (%s)\n\n%s %s\n\n", 416 version, myctime(&tvec), filename); 417 # endif OBJ 418 # ifdef PC 419 printf("Berkeley Pascal PC -- Version 2.0 (%s)\n\n%s %s\n\n", 420 version, myctime(&tvec), filename); 421 # endif PC 422 } 423