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