BSD 4 release
[unix-history] / usr / src / cmd / pc0 / main.c
CommitLineData
a330a02a
PK
1/* Copyright (c) 1979 Regents of the University of California */
2
31cef89c 3static 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
20char piusage[] = "pi [ -blnpstuw ] [ -i file ... ] name.p";
21char pixusage[] = "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]";
22char pcusage[] = "pc [ options ] [ -o file ] [ -i file ... ] name.p";
23
24char *usageis = piusage;
25
26char *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
46char *howfile = "/usr/lib/how_pi\0";
47#endif OBJ
48#ifdef PC
49char *howfile = "/usr/lib/how_pc";
50#endif PC
51
52int onintr();
53
54extern char *lastname;
55
56FILE *ibuf;
57FILE *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 */
64double MAXINT = 2147483647.;
65double MININT = -2147483648.;
66
67/*
68 * Main program for pi.
69 * Process options, then call yymain
70 * to do all the real work.
71 */
72main(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:
261usage:
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
308pchr(c)
309 char c;
310{
311
312 putc ( c , stdout );
313}
314
315char 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 */
323pexit(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
372onintr()
373{
374
375 signal( SIGINT , SIG_IGN );
376 pexit(NOSTART);
377}
378
379/*
380 * Get an error message from the error message file
381 */
382geterr(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
392header()
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}