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.8 04/08/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 'C': 225 /* 226 * since -t is an ld switch, use -C 227 * to turn on tests 228 */ 229 togopt( 't' ); 230 break; 231 case 'g': 232 /* 233 * sdb symbol table 234 */ 235 togopt( 'g' ); 236 break; 237 case 'l': 238 case 's': 239 case 'u': 240 case 'w': 241 togopt(c); 242 break; 243 case 'p': 244 /* 245 * -p on the command line means profile 246 */ 247 profflag = TRUE; 248 break; 249 case 'z': 250 monflg = TRUE; 251 break; 252 default: 253 usage: 254 Perror( "Usage", usageis); 255 pexit(NOSTART); 256 } 257 argc--; 258 argv++; 259 } 260 # endif PC 261 if (argc != 1) 262 goto usage; 263 efil = open ( err_file, 0 ); 264 if ( efil < 0 ) 265 perror(err_file), pexit(NOSTART); 266 filename = argv[0]; 267 if (!dotted(filename, 'p')) { 268 Perror(filename, "Name must end in '.p'"); 269 pexit(NOSTART); 270 } 271 close(0); 272 if ( ( ibuf = fopen( filename , "r" ) ) == NULL ) 273 perror(filename), pexit(NOSTART); 274 ibp = ibuf; 275 # ifdef PC 276 if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) { 277 perror( pcname ); 278 pexit( NOSTART ); 279 } 280 stabsource( filename ); 281 # endif PC 282 # ifdef PTREE 283 # define MAXpPAGES 16 284 if ( ! pCreate( pTreeName , MAXpPAGES ) ) { 285 perror( pTreeName ); 286 pexit( NOSTART ); 287 } 288 # endif PTREE 289 if ( signal( SIGINT , SIG_IGN ) != SIG_IGN ) 290 signal( SIGINT , onintr ); 291 if (opt('l')) { 292 opt('n')++; 293 yysetfile(filename); 294 opt('n')--; 295 } 296 yymain(); 297 /* No return */ 298 } 299 300 pchr(c) 301 char c; 302 { 303 304 putc ( c , stdout ); 305 } 306 307 char ugh[] = "Fatal error in pi\n"; 308 /* 309 * Exit from the Pascal system. 310 * We throw in an ungraceful termination 311 * message if c > 1 indicating a severe 312 * error such as running out of memory 313 * or an internal inconsistency. 314 */ 315 pexit(c) 316 int c; 317 { 318 319 if (opt('l') && c != DIED && c != NOSTART) 320 while (getline() != -1) 321 continue; 322 yyflush(); 323 switch (c) { 324 case DIED: 325 write(2, ugh, sizeof ugh); 326 case NOSTART: 327 case ERRS: 328 # ifdef OBJ 329 if (ofil > 0) 330 unlink(obj); 331 /* 332 * remove symbol table temp files 333 */ 334 removenlfile(); 335 336 # endif OBJ 337 # ifdef PC 338 if ( pcstream != NULL ) { 339 unlink( pcname ); 340 } 341 # endif PC 342 break; 343 case AOK: 344 # ifdef OBJ 345 pflush(); 346 /* 347 * copy symbol table temp files to obj file 348 */ 349 copynlfile(); 350 351 # endif OBJ 352 # ifdef PC 353 puteof(); 354 # endif PC 355 break; 356 } 357 /* 358 * this to gather statistics on programs being compiled 359 * taken 20 june 79 ... peter 360 * 361 * if (fork() == 0) { 362 * char *cp = "-0"; 363 * cp[1] += c; 364 * execl("/usr/lib/gather", "gather", cp, filename, 0); 365 * exit(1); 366 * } 367 */ 368 # ifdef PTREE 369 pFinish(); 370 # endif 371 exit(c); 372 } 373 374 onintr() 375 { 376 377 signal( SIGINT , SIG_IGN ); 378 pexit(NOSTART); 379 } 380 381 /* 382 * Get an error message from the error message file 383 */ 384 geterr(seekpt, buf) 385 int seekpt; 386 char *buf; 387 { 388 389 lseek(efil, (long) seekpt, 0); 390 if (read(efil, buf, 256) <= 0) 391 perror(err_file), pexit(DIED); 392 } 393 394 header() 395 { 396 extern char *version; 397 static char anyheaders; 398 399 gettime( filename ); 400 if (anyheaders && opt('n')) 401 putc( '\f' , stdout ); 402 anyheaders++; 403 # ifdef OBJ 404 printf("Berkeley Pascal PI -- Version %s\n\n%s %s\n\n", 405 version, myctime(&tvec), filename); 406 # endif OBJ 407 # ifdef PC 408 printf("Berkeley Pascal PC -- Version %s\n\n%s %s\n\n", 409 version, myctime(&tvec), filename); 410 # endif PC 411 } 412