xref: /csrg-svn/usr.bin/pascal/src/main.c (revision 18348)
1759Speter /* Copyright (c) 1979 Regents of the University of California */
23075Smckusic 
32575Speter static	char copyright[] =
42575Speter 	    "@(#)Copyright (c) 1979 Regents of the University of California";
5759Speter 
6*18348Smckusick static char sccsid[] = "@(#)main.c 1.9.1.1 03/15/85";
7759Speter 
8759Speter #include "whoami.h"
9759Speter #include "0.h"
10759Speter #include "yy.h"
11759Speter #include <signal.h>
12759Speter #include "objfmt.h"
136407Speter #include "config.h"
14759Speter 
15759Speter /*
16759Speter  * This version of pi has been in use at Berkeley since May 1977
173075Smckusic  * and is very stable. Please report any problems with the error
18759Speter  * recovery to the second author at the address given in the file
19759Speter  * READ_ME.  The second author takes full responsibility for any bugs
20759Speter  * in the syntactic error recovery.
21759Speter  */
22759Speter 
23759Speter char	piusage[]	= "pi [ -blnpstuw ] [ -i file ... ] name.p";
24*18348Smckusick char	pixusage[]	= "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]";
25*18348Smckusick char	pcusage[]	= "pc [ options ] [ -o file ] [ -i file ... ] name.p";
26759Speter 
27759Speter char	*usageis	= piusage;
28759Speter 
29759Speter #ifdef OBJ
30*18348Smckusick     char	*obj	= "obj";
31759Speter #endif OBJ
32759Speter #ifdef PC
33*18348Smckusick     char	*pcname = "pc.pc0";
34759Speter #endif PC
35759Speter #ifdef PTREE
36759Speter     char	*pTreeName = "pi.pTree";
37759Speter #endif PTREE
38759Speter 
39759Speter int	onintr();
40759Speter 
41759Speter extern	char *lastname;
42759Speter 
43759Speter FILE	*ibuf;
44*18348Smckusick FILE	*pcstream = NULL;
45759Speter 
46759Speter /*
47759Speter  * these are made real variables
48759Speter  * so they can be changed
49759Speter  * if you are compiling on a smaller machine
50759Speter  */
51759Speter double	MAXINT	=  2147483647.;
52759Speter double	MININT	= -2147483648.;
53759Speter 
54759Speter /*
55759Speter  * Main program for pi.
56759Speter  * Process options, then call yymain
57759Speter  * to do all the real work.
58759Speter  */
59759Speter main(argc, argv)
60759Speter 	int argc;
61759Speter 	char *argv[];
62759Speter {
63759Speter 	register char *cp;
64759Speter 	register c;
65759Speter 	int i;
66759Speter 
67759Speter 	if (argv[0][0] == 'a')
686407Speter 		err_file += err_pathlen , how_file += how_pathlen;
69759Speter #	ifdef OBJ
70759Speter 	    if (argv[0][0] == '-' && argv[0][1] == 'o') {
71759Speter 		    obj = &argv[0][2];
72759Speter 		    usageis = pixusage;
736407Speter 		    how_file[strlen(how_file)] = 'x';
74759Speter 		    ofil = 3;
75759Speter 	    } else {
76759Speter 		    ofil = creat(obj, 0755);
77759Speter 		    if (ofil < 0) {
78759Speter 			    perror(obj);
79759Speter 			    pexit(NOSTART);
80759Speter 		    }
81759Speter 	    }
82759Speter #	endif OBJ
83759Speter 	argv++, argc--;
84759Speter 	if (argc == 0) {
85759Speter 		i = fork();
86759Speter 		if (i == -1)
87759Speter 			goto usage;
88759Speter 		if (i == 0) {
896407Speter 			execl("/bin/cat", "cat", how_file, 0);
90759Speter 			goto usage;
91759Speter 		}
92759Speter 		while (wait(&i) != -1)
93759Speter 			continue;
94759Speter 		pexit(NOSTART);
95759Speter 	}
96759Speter #	ifdef OBJ
9711884Smckusick 	    opt('p') = opt('t') = opt('b') = 1;
9811884Smckusick #ifdef vax
9911884Smckusick 	    /* pdx is currently supported only on the vax */
10011884Smckusick 	    opt('g') = 1;
10111884Smckusick #endif vax
102759Speter 	    while (argc > 0) {
103759Speter 		    cp = argv[0];
104759Speter 		    if (*cp++ != '-')
105759Speter 			    break;
106759Speter 		    while (c = *cp++) switch (c) {
107759Speter #ifdef DEBUG
108759Speter 			    case 'k':
109759Speter 			    case 'r':
110759Speter 			    case 'y':
111759Speter 				    togopt(c);
112759Speter 				    continue;
113759Speter 			    case 'K':
114759Speter 				    yycosts();
115759Speter 				    pexit(NOSTART);
116759Speter 			    case 'A':
1173075Smckusic 				    testtrace = TRUE;
118759Speter 			    case 'F':
1193075Smckusic 				    fulltrace = TRUE;
120759Speter 			    case 'E':
1213075Smckusic 				    errtrace = TRUE;
122759Speter 				    opt('r')++;
123759Speter 				    continue;
124759Speter 			    case 'U':
125*18348Smckusick 				    yyunique = 0;
126759Speter 				    continue;
127759Speter #endif
128759Speter 			    case 'b':
129759Speter 				    opt('b') = 2;
130759Speter 				    continue;
131759Speter 			    case 'i':
132759Speter 				    pflist = argv + 1;
133759Speter 				    pflstc = 0;
134759Speter 				    while (argc > 1) {
135759Speter 					    if (dotted(argv[1], 'p'))
136759Speter 						    break;
137759Speter 					    pflstc++, argc--, argv++;
138759Speter 				    }
139759Speter 				    if (pflstc == 0)
140759Speter 					    goto usage;
141759Speter 				    continue;
1425654Slinton 			    case 'g':
143759Speter 			    case 'l':
144759Speter 			    case 'n':
145759Speter 			    case 'p':
146759Speter 			    case 's':
147759Speter 			    case 't':
148759Speter 			    case 'u':
149759Speter 			    case 'w':
150759Speter 				    togopt(c);
151759Speter 				    continue;
152759Speter 			    case 'z':
1533075Smckusic 				    monflg = TRUE;
154759Speter 				    continue;
155*18348Smckusick 			    case 'L':
156*18348Smckusick 				    togopt( 'L' );
157*18348Smckusick 				    continue;
158759Speter 			    default:
159759Speter     usage:
160759Speter 				    Perror( "Usage", usageis);
161759Speter 				    pexit(NOSTART);
162759Speter 		    }
163759Speter 		    argc--, argv++;
164759Speter 	    }
165759Speter #	endif OBJ
166759Speter #	ifdef PC
167759Speter 	    opt( 'b' ) = 1;
168759Speter 	    opt( 'g' ) = 0;
169759Speter 	    opt( 't' ) = 0;
170759Speter 	    opt( 'p' ) = 0;
171759Speter 	    usageis = pcusage;
172759Speter 	    while ( argc > 0 ) {
173759Speter 		cp = argv[0];
174759Speter 		if ( *cp++ != '-' ) {
175759Speter 		    break;
176759Speter 		}
177759Speter 		c = *cp++;
178759Speter 		switch( c ) {
179759Speter #ifdef DEBUG
180759Speter 		    case 'k':
181759Speter 		    case 'r':
182759Speter 		    case 'y':
183759Speter 			    togopt(c);
184759Speter 			    break;
185759Speter 		    case 'K':
186759Speter 			    yycosts();
187759Speter 			    pexit(NOSTART);
188759Speter 		    case 'A':
1893138Smckusic 			    testtrace = TRUE;
190759Speter 			    /* and fall through */
191759Speter 		    case 'F':
1923138Smckusic 			    fulltrace = TRUE;
193759Speter 			    /* and fall through */
194759Speter 		    case 'E':
1953138Smckusic 			    errtrace = TRUE;
196759Speter 			    opt('r')++;
197759Speter 			    break;
198759Speter 		    case 'U':
199*18348Smckusick 			    yyunique = 0;
200759Speter 			    break;
201759Speter #endif
202759Speter 		    case 'b':
203759Speter 			    opt('b') = 2;
204759Speter 			    break;
205759Speter 		    case 'i':
206759Speter 			    pflist = argv + 1;
207759Speter 			    pflstc = 0;
208759Speter 			    while (argc > 1) {
209759Speter 				    if (dotted(argv[1], 'p'))
210759Speter 					    break;
211759Speter 				    pflstc++, argc--, argv++;
212759Speter 			    }
213759Speter 			    if (pflstc == 0)
214759Speter 				    goto usage;
215759Speter 			    break;
216759Speter 			/*
217759Speter 			 *	output file for the first pass
218759Speter 			 */
219759Speter 		    case 'o':
220759Speter 			    if ( argc < 2 ) {
221759Speter 				goto usage;
222759Speter 			    }
223759Speter 			    argv++;
224759Speter 			    argc--;
225759Speter 			    pcname = argv[0];
226759Speter 			    break;
22712967Smckusick 		    case 'J':
22812967Smckusick 			    togopt( 'J' );
22912967Smckusick 			    break;
230759Speter 		    case 'C':
231759Speter 				/*
232759Speter 				 * since -t is an ld switch, use -C
233759Speter 				 * to turn on tests
234759Speter 				 */
235759Speter 			    togopt( 't' );
236759Speter 			    break;
237759Speter 		    case 'g':
238759Speter 				/*
239759Speter 				 *	sdb symbol table
240759Speter 				 */
241759Speter 			    togopt( 'g' );
242759Speter 			    break;
243759Speter 		    case 'l':
244759Speter 		    case 's':
245759Speter 		    case 'u':
246759Speter 		    case 'w':
247759Speter 			    togopt(c);
248759Speter 			    break;
249759Speter 		    case 'p':
250759Speter 				/*
251759Speter 				 *	-p on the command line means profile
252759Speter 				 */
2533138Smckusic 			    profflag = TRUE;
254759Speter 			    break;
255759Speter 		    case 'z':
2563138Smckusic 			    monflg = TRUE;
257759Speter 			    break;
258*18348Smckusick 		    case 'L':
259*18348Smckusick 			    togopt( 'L' );
260*18348Smckusick 			    break;
261759Speter 		    default:
262759Speter usage:
263759Speter 			    Perror( "Usage", usageis);
264759Speter 			    pexit(NOSTART);
265759Speter 		}
266759Speter 		argc--;
267759Speter 		argv++;
268759Speter 	    }
269759Speter #	endif PC
270759Speter 	if (argc != 1)
271759Speter 		goto usage;
2726407Speter 	efil = open ( err_file, 0 );
273759Speter 	if ( efil < 0 )
2746407Speter 		perror(err_file), pexit(NOSTART);
275759Speter 	filename = argv[0];
276759Speter 	if (!dotted(filename, 'p')) {
277759Speter 		Perror(filename, "Name must end in '.p'");
278759Speter 		pexit(NOSTART);
279759Speter 	}
280759Speter 	close(0);
281759Speter 	if ( ( ibuf = fopen( filename , "r" ) ) == NULL )
282759Speter 		perror(filename), pexit(NOSTART);
283759Speter 	ibp = ibuf;
284759Speter #	ifdef PC
285759Speter 	    if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) {
286759Speter 		perror( pcname );
287759Speter 		pexit( NOSTART );
288759Speter 	    }
289*18348Smckusick 	    stabsource( filename, TRUE );
290759Speter #	endif PC
291759Speter #	ifdef PTREE
292759Speter #	    define	MAXpPAGES	16
293759Speter 	    if ( ! pCreate( pTreeName , MAXpPAGES ) ) {
294759Speter 		perror( pTreeName );
295759Speter 		pexit( NOSTART );
296759Speter 	    }
297759Speter #	endif PTREE
298759Speter 	if ( signal( SIGINT , SIG_IGN ) != SIG_IGN )
299*18348Smckusick 		signal( SIGINT , onintr );
300759Speter 	if (opt('l')) {
301759Speter 		opt('n')++;
302759Speter 		yysetfile(filename);
303759Speter 		opt('n')--;
304759Speter 	}
305759Speter 	yymain();
306759Speter 	/* No return */
307759Speter }
308759Speter 
309759Speter pchr(c)
310759Speter 	char c;
311759Speter {
312759Speter 
313759Speter 	putc ( c , stdout );
314759Speter }
315759Speter 
316759Speter char	ugh[]	= "Fatal error in pi\n";
317759Speter /*
318759Speter  * Exit from the Pascal system.
319759Speter  * We throw in an ungraceful termination
320759Speter  * message if c > 1 indicating a severe
321759Speter  * error such as running out of memory
322759Speter  * or an internal inconsistency.
323759Speter  */
324759Speter pexit(c)
325759Speter 	int c;
326759Speter {
327759Speter 
328759Speter 	if (opt('l') && c != DIED && c != NOSTART)
329759Speter 		while (getline() != -1)
330759Speter 			continue;
331759Speter 	yyflush();
332759Speter 	switch (c) {
333759Speter 		case DIED:
334759Speter 			write(2, ugh, sizeof ugh);
335759Speter 		case NOSTART:
336759Speter 		case ERRS:
337759Speter #			ifdef OBJ
338759Speter 			    if (ofil > 0)
339759Speter 				    unlink(obj);
3405654Slinton 			/*
3415654Slinton 			 * remove symbol table temp files
3425654Slinton 			 */
3435654Slinton 			    removenlfile();
3445654Slinton 
345759Speter #			endif OBJ
346759Speter #			ifdef PC
347759Speter 			    if ( pcstream != NULL ) {
348759Speter 				unlink( pcname );
349759Speter 			    }
350759Speter #			endif PC
351759Speter 			break;
352759Speter 		case AOK:
353759Speter #			ifdef OBJ
354759Speter 			    pflush();
3555654Slinton 			/*
3565654Slinton 			 * copy symbol table temp files to obj file
3575654Slinton 			 */
3585654Slinton 			    copynlfile();
3595654Slinton 
360759Speter #			endif OBJ
361759Speter #			ifdef PC
362759Speter 			    puteof();
363759Speter #			endif PC
364759Speter 			break;
365759Speter 	}
366759Speter 	/*
367759Speter 	 *	this to gather statistics on programs being compiled
368759Speter 	 *	taken 20 june 79 	... peter
369759Speter 	 *
370759Speter 	 *  if (fork() == 0) {
371759Speter 	 *  	char *cp = "-0";
372759Speter 	 *  	cp[1] += c;
373759Speter 	 *  	execl("/usr/lib/gather", "gather", cp, filename, 0);
374759Speter 	 *  	exit(1);
375759Speter 	 *  }
376759Speter 	 */
377759Speter #	ifdef PTREE
378759Speter 	    pFinish();
379759Speter #	endif
380759Speter 	exit(c);
381759Speter }
382759Speter 
383759Speter onintr()
384759Speter {
385759Speter 
386*18348Smckusick 	signal( SIGINT , SIG_IGN );
387759Speter 	pexit(NOSTART);
388759Speter }
389759Speter 
390759Speter /*
391759Speter  * Get an error message from the error message file
392759Speter  */
393759Speter geterr(seekpt, buf)
394759Speter 	int seekpt;
395759Speter 	char *buf;
396759Speter {
397759Speter 
398*18348Smckusick 	lseek(efil, (long) seekpt, 0);
399759Speter 	if (read(efil, buf, 256) <= 0)
4006407Speter 		perror(err_file), pexit(DIED);
401759Speter }
402759Speter 
403759Speter header()
404759Speter {
4056407Speter 	extern char *version;
406759Speter 	static char anyheaders;
407759Speter 
408759Speter 	gettime( filename );
409759Speter 	if (anyheaders && opt('n'))
410759Speter 		putc( '\f' , stdout );
411759Speter 	anyheaders++;
412759Speter #	ifdef OBJ
4136407Speter 	    printf("Berkeley Pascal PI -- Version %s\n\n%s  %s\n\n",
414*18348Smckusick 		    version, myctime(&tvec), filename);
415759Speter #	endif OBJ
416759Speter #	ifdef PC
4176407Speter 	    printf("Berkeley Pascal PC -- Version %s\n\n%s  %s\n\n",
418*18348Smckusick 		    version, myctime(&tvec), filename);
419759Speter #	endif PC
420759Speter }
421