148115Sbostic /*-
262213Sbostic * Copyright (c) 1980, 1993
362213Sbostic * The Regents of the University of California. All rights reserved.
448115Sbostic *
548115Sbostic * %sccs.include.redist.c%
622177Sdist */
73075Smckusic
818349Smckusick #ifndef lint
962213Sbostic static char copyright[] =
1062213Sbostic "@(#) Copyright (c) 1980, 1993\n\
1162213Sbostic The Regents of the University of California. All rights reserved.\n";
1248115Sbostic #endif /* not lint */
13759Speter
1422177Sdist #ifndef lint
15*67239Smckusick static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 05/24/94";
1648115Sbostic #endif /* not lint */
17759Speter
18759Speter #include "whoami.h"
19759Speter #include "0.h"
2018349Smckusick #include "tree_ty.h" /* must be included for yy.h */
21759Speter #include "yy.h"
22759Speter #include <signal.h>
23759Speter #include "objfmt.h"
246407Speter #include "config.h"
25759Speter
26759Speter /*
27759Speter * This version of pi has been in use at Berkeley since May 1977
283075Smckusic * and is very stable. Please report any problems with the error
29759Speter * recovery to the second author at the address given in the file
30759Speter * READ_ME. The second author takes full responsibility for any bugs
31759Speter * in the syntactic error recovery.
32759Speter */
33759Speter
34759Speter char piusage[] = "pi [ -blnpstuw ] [ -i file ... ] name.p";
35759Speter
36759Speter char *usageis = piusage;
37759Speter
38759Speter #ifdef OBJ
3918349Smckusick
4018349Smckusick char pixusage[] = "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]";
4118349Smckusick char *obj = "obj";
4218349Smckusick
43759Speter #endif OBJ
4418349Smckusick
45759Speter #ifdef PC
4618349Smckusick
4718349Smckusick char *pcname = "pc.pc0";
4818349Smckusick char pcusage[] = "pc [ options ] [ -o file ] [ -i file ... ] name.p";
4918349Smckusick FILE *pcstream = NULL;
5018349Smckusick
51759Speter #endif PC
52759Speter #ifdef PTREE
53759Speter char *pTreeName = "pi.pTree";
54759Speter #endif PTREE
55759Speter
56759Speter int onintr();
57759Speter
58759Speter extern char *lastname;
59759Speter
60759Speter FILE *ibuf;
61759Speter
62759Speter /*
63759Speter * these are made real variables
64759Speter * so they can be changed
65759Speter * if you are compiling on a smaller machine
66759Speter */
67759Speter double MAXINT = 2147483647.;
68759Speter double MININT = -2147483648.;
69759Speter
70759Speter /*
71759Speter * Main program for pi.
72759Speter * Process options, then call yymain
73759Speter * to do all the real work.
74759Speter */
main(argc,argv)75759Speter main(argc, argv)
76759Speter int argc;
77759Speter char *argv[];
78759Speter {
79759Speter register char *cp;
80759Speter register c;
8118349Smckusick FILE *fopen();
8218349Smckusick extern char *myctime();
83759Speter int i;
84759Speter
85759Speter if (argv[0][0] == 'a')
866407Speter err_file += err_pathlen , how_file += how_pathlen;
87759Speter # ifdef OBJ
88759Speter if (argv[0][0] == '-' && argv[0][1] == 'o') {
89759Speter obj = &argv[0][2];
90759Speter usageis = pixusage;
916407Speter how_file[strlen(how_file)] = 'x';
92759Speter ofil = 3;
93759Speter } else {
94759Speter ofil = creat(obj, 0755);
95759Speter if (ofil < 0) {
96759Speter perror(obj);
97759Speter pexit(NOSTART);
98759Speter }
99759Speter }
100759Speter # endif OBJ
101759Speter argv++, argc--;
102759Speter if (argc == 0) {
103759Speter i = fork();
104759Speter if (i == -1)
105759Speter goto usage;
106759Speter if (i == 0) {
1076407Speter execl("/bin/cat", "cat", how_file, 0);
108759Speter goto usage;
109759Speter }
110759Speter while (wait(&i) != -1)
111759Speter continue;
112759Speter pexit(NOSTART);
113759Speter }
114759Speter # ifdef OBJ
11511884Smckusick opt('p') = opt('t') = opt('b') = 1;
11630838Smckusick #if defined(vax) || defined(tahoe)
11730838Smckusick /* pdx is currently supported on the vax and the tahoe */
11811884Smckusick opt('g') = 1;
11930838Smckusick #endif
120759Speter while (argc > 0) {
121759Speter cp = argv[0];
122759Speter if (*cp++ != '-')
123759Speter break;
124759Speter while (c = *cp++) switch (c) {
125759Speter #ifdef DEBUG
126759Speter case 'k':
127759Speter case 'r':
128759Speter case 'y':
129759Speter togopt(c);
130759Speter continue;
131759Speter case 'K':
132759Speter yycosts();
133759Speter pexit(NOSTART);
134759Speter case 'A':
1353075Smckusic testtrace = TRUE;
136759Speter case 'F':
1373075Smckusic fulltrace = TRUE;
138759Speter case 'E':
1393075Smckusic errtrace = TRUE;
140759Speter opt('r')++;
141759Speter continue;
142759Speter case 'U':
14318349Smckusick yyunique = FALSE;
144759Speter continue;
145759Speter #endif
146759Speter case 'b':
147759Speter opt('b') = 2;
148759Speter continue;
149759Speter case 'i':
150759Speter pflist = argv + 1;
151759Speter pflstc = 0;
152759Speter while (argc > 1) {
153759Speter if (dotted(argv[1], 'p'))
154759Speter break;
155759Speter pflstc++, argc--, argv++;
156759Speter }
157759Speter if (pflstc == 0)
158759Speter goto usage;
159759Speter continue;
1605654Slinton case 'g':
161759Speter case 'l':
162759Speter case 'n':
163759Speter case 'p':
164759Speter case 's':
165759Speter case 't':
166759Speter case 'u':
167759Speter case 'w':
168759Speter togopt(c);
169759Speter continue;
170759Speter case 'z':
1713075Smckusic monflg = TRUE;
172759Speter continue;
17318348Smckusick case 'L':
17418348Smckusick togopt( 'L' );
17518348Smckusick continue;
176759Speter default:
177759Speter usage:
178759Speter Perror( "Usage", usageis);
179759Speter pexit(NOSTART);
180759Speter }
181759Speter argc--, argv++;
182759Speter }
183759Speter # endif OBJ
184759Speter # ifdef PC
185759Speter opt( 'b' ) = 1;
186759Speter opt( 'g' ) = 0;
187759Speter opt( 't' ) = 0;
188759Speter opt( 'p' ) = 0;
189759Speter usageis = pcusage;
190759Speter while ( argc > 0 ) {
191759Speter cp = argv[0];
192759Speter if ( *cp++ != '-' ) {
193759Speter break;
194759Speter }
195759Speter c = *cp++;
196759Speter switch( c ) {
197759Speter #ifdef DEBUG
198759Speter case 'k':
199759Speter case 'r':
200759Speter case 'y':
201759Speter togopt(c);
202759Speter break;
203759Speter case 'K':
204759Speter yycosts();
205759Speter pexit(NOSTART);
206759Speter case 'A':
2073138Smckusic testtrace = TRUE;
208759Speter /* and fall through */
209759Speter case 'F':
2103138Smckusic fulltrace = TRUE;
211759Speter /* and fall through */
212759Speter case 'E':
2133138Smckusic errtrace = TRUE;
214759Speter opt('r')++;
215759Speter break;
216759Speter case 'U':
21718349Smckusick yyunique = FALSE;
218759Speter break;
219759Speter #endif
220759Speter case 'b':
221759Speter opt('b') = 2;
222759Speter break;
223759Speter case 'i':
224759Speter pflist = argv + 1;
225759Speter pflstc = 0;
226759Speter while (argc > 1) {
227759Speter if (dotted(argv[1], 'p'))
228759Speter break;
229759Speter pflstc++, argc--, argv++;
230759Speter }
231759Speter if (pflstc == 0)
232759Speter goto usage;
233759Speter break;
234759Speter /*
235759Speter * output file for the first pass
236759Speter */
237759Speter case 'o':
238759Speter if ( argc < 2 ) {
239759Speter goto usage;
240759Speter }
241759Speter argv++;
242759Speter argc--;
243759Speter pcname = argv[0];
244759Speter break;
24512967Smckusick case 'J':
24612967Smckusick togopt( 'J' );
24712967Smckusick break;
248759Speter case 'C':
249759Speter /*
250759Speter * since -t is an ld switch, use -C
251759Speter * to turn on tests
252759Speter */
253759Speter togopt( 't' );
254759Speter break;
255759Speter case 'g':
256759Speter /*
257759Speter * sdb symbol table
258759Speter */
259759Speter togopt( 'g' );
260759Speter break;
261759Speter case 'l':
262759Speter case 's':
263759Speter case 'u':
264759Speter case 'w':
265759Speter togopt(c);
266759Speter break;
267759Speter case 'p':
268759Speter /*
269759Speter * -p on the command line means profile
270759Speter */
2713138Smckusic profflag = TRUE;
272759Speter break;
273759Speter case 'z':
2743138Smckusic monflg = TRUE;
275759Speter break;
27618348Smckusick case 'L':
27718348Smckusick togopt( 'L' );
27818348Smckusick break;
279759Speter default:
280759Speter usage:
281759Speter Perror( "Usage", usageis);
282759Speter pexit(NOSTART);
283759Speter }
284759Speter argc--;
285759Speter argv++;
286759Speter }
287759Speter # endif PC
288759Speter if (argc != 1)
289759Speter goto usage;
2906407Speter efil = open ( err_file, 0 );
291759Speter if ( efil < 0 )
2926407Speter perror(err_file), pexit(NOSTART);
293759Speter filename = argv[0];
294759Speter if (!dotted(filename, 'p')) {
295759Speter Perror(filename, "Name must end in '.p'");
296759Speter pexit(NOSTART);
297759Speter }
298759Speter close(0);
299759Speter if ( ( ibuf = fopen( filename , "r" ) ) == NULL )
300759Speter perror(filename), pexit(NOSTART);
301759Speter ibp = ibuf;
302759Speter # ifdef PC
303759Speter if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) {
304759Speter perror( pcname );
305759Speter pexit( NOSTART );
306759Speter }
30718348Smckusick stabsource( filename, TRUE );
308759Speter # endif PC
309759Speter # ifdef PTREE
310759Speter # define MAXpPAGES 16
311759Speter if ( ! pCreate( pTreeName , MAXpPAGES ) ) {
312759Speter perror( pTreeName );
313759Speter pexit( NOSTART );
314759Speter }
315759Speter # endif PTREE
316759Speter if ( signal( SIGINT , SIG_IGN ) != SIG_IGN )
31718349Smckusick (void) signal( SIGINT , onintr );
318759Speter if (opt('l')) {
319759Speter opt('n')++;
320759Speter yysetfile(filename);
321759Speter opt('n')--;
322759Speter }
323759Speter yymain();
324759Speter /* No return */
325759Speter }
326759Speter
pchr(c)327759Speter pchr(c)
328759Speter char c;
329759Speter {
330759Speter
331759Speter putc ( c , stdout );
332759Speter }
333759Speter
33418449Smckusick #ifdef PC
33518449Smckusick char ugh[] = "Fatal error in pc\n";
33618449Smckusick #endif
33718449Smckusick #ifdef OBJ
338759Speter char ugh[] = "Fatal error in pi\n";
33918449Smckusick #endif
340759Speter /*
341759Speter * Exit from the Pascal system.
342759Speter * We throw in an ungraceful termination
343759Speter * message if c > 1 indicating a severe
344759Speter * error such as running out of memory
345759Speter * or an internal inconsistency.
346759Speter */
pexit(c)347759Speter pexit(c)
348759Speter int c;
349759Speter {
350759Speter
351759Speter if (opt('l') && c != DIED && c != NOSTART)
352759Speter while (getline() != -1)
353759Speter continue;
354759Speter yyflush();
355759Speter switch (c) {
356759Speter case DIED:
357759Speter write(2, ugh, sizeof ugh);
358759Speter case NOSTART:
359759Speter case ERRS:
360759Speter # ifdef OBJ
361759Speter if (ofil > 0)
362759Speter unlink(obj);
3635654Slinton /*
3645654Slinton * remove symbol table temp files
3655654Slinton */
3665654Slinton removenlfile();
3675654Slinton
368759Speter # endif OBJ
369759Speter # ifdef PC
370759Speter if ( pcstream != NULL ) {
371759Speter unlink( pcname );
372759Speter }
373759Speter # endif PC
374759Speter break;
375759Speter case AOK:
376759Speter # ifdef OBJ
377759Speter pflush();
3785654Slinton /*
3795654Slinton * copy symbol table temp files to obj file
3805654Slinton */
3815654Slinton copynlfile();
3825654Slinton
383759Speter # endif OBJ
384759Speter # ifdef PC
385759Speter puteof();
386759Speter # endif PC
387759Speter break;
388759Speter }
389759Speter /*
390759Speter * this to gather statistics on programs being compiled
391759Speter * taken 20 june 79 ... peter
392759Speter *
393759Speter * if (fork() == 0) {
394759Speter * char *cp = "-0";
395759Speter * cp[1] += c;
396759Speter * execl("/usr/lib/gather", "gather", cp, filename, 0);
397759Speter * exit(1);
398759Speter * }
399759Speter */
400759Speter # ifdef PTREE
401759Speter pFinish();
402759Speter # endif
403759Speter exit(c);
404759Speter }
405759Speter
onintr()406759Speter onintr()
407759Speter {
408759Speter
40918349Smckusick (void) signal( SIGINT , SIG_IGN );
410759Speter pexit(NOSTART);
411759Speter }
412759Speter
413759Speter /*
414759Speter * Get an error message from the error message file
415759Speter */
geterr(seekpt,buf)416759Speter geterr(seekpt, buf)
417759Speter int seekpt;
418759Speter char *buf;
419759Speter {
420759Speter
421*67239Smckusick if (lseek(efil, (off_t) seekpt, 0) == -1)
422*67239Smckusick perror(err_file), pexit(DIED);
423759Speter if (read(efil, buf, 256) <= 0)
4246407Speter perror(err_file), pexit(DIED);
425759Speter }
426759Speter
header()427759Speter header()
428759Speter {
4296407Speter extern char *version;
430759Speter static char anyheaders;
431759Speter
432759Speter gettime( filename );
433759Speter if (anyheaders && opt('n'))
434759Speter putc( '\f' , stdout );
435759Speter anyheaders++;
436759Speter # ifdef OBJ
4376407Speter printf("Berkeley Pascal PI -- Version %s\n\n%s %s\n\n",
43818349Smckusick version, myctime((int *) (&tvec)), filename);
439759Speter # endif OBJ
440759Speter # ifdef PC
4416407Speter printf("Berkeley Pascal PC -- Version %s\n\n%s %s\n\n",
44218349Smckusick version, myctime((int *) (&tvec)), filename);
443759Speter # endif PC
444759Speter }
445