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