xref: /csrg-svn/usr.bin/pascal/src/main.c (revision 62213)
148115Sbostic /*-
2*62213Sbostic  * Copyright (c) 1980, 1993
3*62213Sbostic  *	The Regents of the University of California.  All rights reserved.
448115Sbostic  *
548115Sbostic  * %sccs.include.redist.c%
622177Sdist  */
73075Smckusic 
818349Smckusick #ifndef lint
9*62213Sbostic static char copyright[] =
10*62213Sbostic "@(#) Copyright (c) 1980, 1993\n\
11*62213Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1248115Sbostic #endif /* not lint */
13759Speter 
1422177Sdist #ifndef lint
15*62213Sbostic static char sccsid[] = "@(#)main.c	8.1 (Berkeley) 06/06/93";
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  */
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();
8318349Smckusick 	extern long lseek();
84759Speter 	int i;
85759Speter 
86759Speter 	if (argv[0][0] == 'a')
876407Speter 		err_file += err_pathlen , how_file += how_pathlen;
88759Speter #	ifdef OBJ
89759Speter 	    if (argv[0][0] == '-' && argv[0][1] == 'o') {
90759Speter 		    obj = &argv[0][2];
91759Speter 		    usageis = pixusage;
926407Speter 		    how_file[strlen(how_file)] = 'x';
93759Speter 		    ofil = 3;
94759Speter 	    } else {
95759Speter 		    ofil = creat(obj, 0755);
96759Speter 		    if (ofil < 0) {
97759Speter 			    perror(obj);
98759Speter 			    pexit(NOSTART);
99759Speter 		    }
100759Speter 	    }
101759Speter #	endif OBJ
102759Speter 	argv++, argc--;
103759Speter 	if (argc == 0) {
104759Speter 		i = fork();
105759Speter 		if (i == -1)
106759Speter 			goto usage;
107759Speter 		if (i == 0) {
1086407Speter 			execl("/bin/cat", "cat", how_file, 0);
109759Speter 			goto usage;
110759Speter 		}
111759Speter 		while (wait(&i) != -1)
112759Speter 			continue;
113759Speter 		pexit(NOSTART);
114759Speter 	}
115759Speter #	ifdef OBJ
11611884Smckusick 	    opt('p') = opt('t') = opt('b') = 1;
11730838Smckusick #if defined(vax) || defined(tahoe)
11830838Smckusick 	    /* pdx is currently supported on the vax and the tahoe */
11911884Smckusick 	    opt('g') = 1;
12030838Smckusick #endif
121759Speter 	    while (argc > 0) {
122759Speter 		    cp = argv[0];
123759Speter 		    if (*cp++ != '-')
124759Speter 			    break;
125759Speter 		    while (c = *cp++) switch (c) {
126759Speter #ifdef DEBUG
127759Speter 			    case 'k':
128759Speter 			    case 'r':
129759Speter 			    case 'y':
130759Speter 				    togopt(c);
131759Speter 				    continue;
132759Speter 			    case 'K':
133759Speter 				    yycosts();
134759Speter 				    pexit(NOSTART);
135759Speter 			    case 'A':
1363075Smckusic 				    testtrace = TRUE;
137759Speter 			    case 'F':
1383075Smckusic 				    fulltrace = TRUE;
139759Speter 			    case 'E':
1403075Smckusic 				    errtrace = TRUE;
141759Speter 				    opt('r')++;
142759Speter 				    continue;
143759Speter 			    case 'U':
14418349Smckusick 				    yyunique = FALSE;
145759Speter 				    continue;
146759Speter #endif
147759Speter 			    case 'b':
148759Speter 				    opt('b') = 2;
149759Speter 				    continue;
150759Speter 			    case 'i':
151759Speter 				    pflist = argv + 1;
152759Speter 				    pflstc = 0;
153759Speter 				    while (argc > 1) {
154759Speter 					    if (dotted(argv[1], 'p'))
155759Speter 						    break;
156759Speter 					    pflstc++, argc--, argv++;
157759Speter 				    }
158759Speter 				    if (pflstc == 0)
159759Speter 					    goto usage;
160759Speter 				    continue;
1615654Slinton 			    case 'g':
162759Speter 			    case 'l':
163759Speter 			    case 'n':
164759Speter 			    case 'p':
165759Speter 			    case 's':
166759Speter 			    case 't':
167759Speter 			    case 'u':
168759Speter 			    case 'w':
169759Speter 				    togopt(c);
170759Speter 				    continue;
171759Speter 			    case 'z':
1723075Smckusic 				    monflg = TRUE;
173759Speter 				    continue;
17418348Smckusick 			    case 'L':
17518348Smckusick 				    togopt( 'L' );
17618348Smckusick 				    continue;
177759Speter 			    default:
178759Speter     usage:
179759Speter 				    Perror( "Usage", usageis);
180759Speter 				    pexit(NOSTART);
181759Speter 		    }
182759Speter 		    argc--, argv++;
183759Speter 	    }
184759Speter #	endif OBJ
185759Speter #	ifdef PC
186759Speter 	    opt( 'b' ) = 1;
187759Speter 	    opt( 'g' ) = 0;
188759Speter 	    opt( 't' ) = 0;
189759Speter 	    opt( 'p' ) = 0;
190759Speter 	    usageis = pcusage;
191759Speter 	    while ( argc > 0 ) {
192759Speter 		cp = argv[0];
193759Speter 		if ( *cp++ != '-' ) {
194759Speter 		    break;
195759Speter 		}
196759Speter 		c = *cp++;
197759Speter 		switch( c ) {
198759Speter #ifdef DEBUG
199759Speter 		    case 'k':
200759Speter 		    case 'r':
201759Speter 		    case 'y':
202759Speter 			    togopt(c);
203759Speter 			    break;
204759Speter 		    case 'K':
205759Speter 			    yycosts();
206759Speter 			    pexit(NOSTART);
207759Speter 		    case 'A':
2083138Smckusic 			    testtrace = TRUE;
209759Speter 			    /* and fall through */
210759Speter 		    case 'F':
2113138Smckusic 			    fulltrace = TRUE;
212759Speter 			    /* and fall through */
213759Speter 		    case 'E':
2143138Smckusic 			    errtrace = TRUE;
215759Speter 			    opt('r')++;
216759Speter 			    break;
217759Speter 		    case 'U':
21818349Smckusick 			    yyunique = FALSE;
219759Speter 			    break;
220759Speter #endif
221759Speter 		    case 'b':
222759Speter 			    opt('b') = 2;
223759Speter 			    break;
224759Speter 		    case 'i':
225759Speter 			    pflist = argv + 1;
226759Speter 			    pflstc = 0;
227759Speter 			    while (argc > 1) {
228759Speter 				    if (dotted(argv[1], 'p'))
229759Speter 					    break;
230759Speter 				    pflstc++, argc--, argv++;
231759Speter 			    }
232759Speter 			    if (pflstc == 0)
233759Speter 				    goto usage;
234759Speter 			    break;
235759Speter 			/*
236759Speter 			 *	output file for the first pass
237759Speter 			 */
238759Speter 		    case 'o':
239759Speter 			    if ( argc < 2 ) {
240759Speter 				goto usage;
241759Speter 			    }
242759Speter 			    argv++;
243759Speter 			    argc--;
244759Speter 			    pcname = argv[0];
245759Speter 			    break;
24612967Smckusick 		    case 'J':
24712967Smckusick 			    togopt( 'J' );
24812967Smckusick 			    break;
249759Speter 		    case 'C':
250759Speter 				/*
251759Speter 				 * since -t is an ld switch, use -C
252759Speter 				 * to turn on tests
253759Speter 				 */
254759Speter 			    togopt( 't' );
255759Speter 			    break;
256759Speter 		    case 'g':
257759Speter 				/*
258759Speter 				 *	sdb symbol table
259759Speter 				 */
260759Speter 			    togopt( 'g' );
261759Speter 			    break;
262759Speter 		    case 'l':
263759Speter 		    case 's':
264759Speter 		    case 'u':
265759Speter 		    case 'w':
266759Speter 			    togopt(c);
267759Speter 			    break;
268759Speter 		    case 'p':
269759Speter 				/*
270759Speter 				 *	-p on the command line means profile
271759Speter 				 */
2723138Smckusic 			    profflag = TRUE;
273759Speter 			    break;
274759Speter 		    case 'z':
2753138Smckusic 			    monflg = TRUE;
276759Speter 			    break;
27718348Smckusick 		    case 'L':
27818348Smckusick 			    togopt( 'L' );
27918348Smckusick 			    break;
280759Speter 		    default:
281759Speter usage:
282759Speter 			    Perror( "Usage", usageis);
283759Speter 			    pexit(NOSTART);
284759Speter 		}
285759Speter 		argc--;
286759Speter 		argv++;
287759Speter 	    }
288759Speter #	endif PC
289759Speter 	if (argc != 1)
290759Speter 		goto usage;
2916407Speter 	efil = open ( err_file, 0 );
292759Speter 	if ( efil < 0 )
2936407Speter 		perror(err_file), pexit(NOSTART);
294759Speter 	filename = argv[0];
295759Speter 	if (!dotted(filename, 'p')) {
296759Speter 		Perror(filename, "Name must end in '.p'");
297759Speter 		pexit(NOSTART);
298759Speter 	}
299759Speter 	close(0);
300759Speter 	if ( ( ibuf = fopen( filename , "r" ) ) == NULL )
301759Speter 		perror(filename), pexit(NOSTART);
302759Speter 	ibp = ibuf;
303759Speter #	ifdef PC
304759Speter 	    if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) {
305759Speter 		perror( pcname );
306759Speter 		pexit( NOSTART );
307759Speter 	    }
30818348Smckusick 	    stabsource( filename, TRUE );
309759Speter #	endif PC
310759Speter #	ifdef PTREE
311759Speter #	    define	MAXpPAGES	16
312759Speter 	    if ( ! pCreate( pTreeName , MAXpPAGES ) ) {
313759Speter 		perror( pTreeName );
314759Speter 		pexit( NOSTART );
315759Speter 	    }
316759Speter #	endif PTREE
317759Speter 	if ( signal( SIGINT , SIG_IGN ) != SIG_IGN )
31818349Smckusick 		(void) signal( SIGINT , onintr );
319759Speter 	if (opt('l')) {
320759Speter 		opt('n')++;
321759Speter 		yysetfile(filename);
322759Speter 		opt('n')--;
323759Speter 	}
324759Speter 	yymain();
325759Speter 	/* No return */
326759Speter }
327759Speter 
328759Speter pchr(c)
329759Speter 	char c;
330759Speter {
331759Speter 
332759Speter 	putc ( c , stdout );
333759Speter }
334759Speter 
33518449Smckusick #ifdef PC
33618449Smckusick char	ugh[]	= "Fatal error in pc\n";
33718449Smckusick #endif
33818449Smckusick #ifdef OBJ
339759Speter char	ugh[]	= "Fatal error in pi\n";
34018449Smckusick #endif
341759Speter /*
342759Speter  * Exit from the Pascal system.
343759Speter  * We throw in an ungraceful termination
344759Speter  * message if c > 1 indicating a severe
345759Speter  * error such as running out of memory
346759Speter  * or an internal inconsistency.
347759Speter  */
348759Speter pexit(c)
349759Speter 	int c;
350759Speter {
351759Speter 
352759Speter 	if (opt('l') && c != DIED && c != NOSTART)
353759Speter 		while (getline() != -1)
354759Speter 			continue;
355759Speter 	yyflush();
356759Speter 	switch (c) {
357759Speter 		case DIED:
358759Speter 			write(2, ugh, sizeof ugh);
359759Speter 		case NOSTART:
360759Speter 		case ERRS:
361759Speter #			ifdef OBJ
362759Speter 			    if (ofil > 0)
363759Speter 				    unlink(obj);
3645654Slinton 			/*
3655654Slinton 			 * remove symbol table temp files
3665654Slinton 			 */
3675654Slinton 			    removenlfile();
3685654Slinton 
369759Speter #			endif OBJ
370759Speter #			ifdef PC
371759Speter 			    if ( pcstream != NULL ) {
372759Speter 				unlink( pcname );
373759Speter 			    }
374759Speter #			endif PC
375759Speter 			break;
376759Speter 		case AOK:
377759Speter #			ifdef OBJ
378759Speter 			    pflush();
3795654Slinton 			/*
3805654Slinton 			 * copy symbol table temp files to obj file
3815654Slinton 			 */
3825654Slinton 			    copynlfile();
3835654Slinton 
384759Speter #			endif OBJ
385759Speter #			ifdef PC
386759Speter 			    puteof();
387759Speter #			endif PC
388759Speter 			break;
389759Speter 	}
390759Speter 	/*
391759Speter 	 *	this to gather statistics on programs being compiled
392759Speter 	 *	taken 20 june 79 	... peter
393759Speter 	 *
394759Speter 	 *  if (fork() == 0) {
395759Speter 	 *  	char *cp = "-0";
396759Speter 	 *  	cp[1] += c;
397759Speter 	 *  	execl("/usr/lib/gather", "gather", cp, filename, 0);
398759Speter 	 *  	exit(1);
399759Speter 	 *  }
400759Speter 	 */
401759Speter #	ifdef PTREE
402759Speter 	    pFinish();
403759Speter #	endif
404759Speter 	exit(c);
405759Speter }
406759Speter 
407759Speter onintr()
408759Speter {
409759Speter 
41018349Smckusick 	(void) signal( SIGINT , SIG_IGN );
411759Speter 	pexit(NOSTART);
412759Speter }
413759Speter 
414759Speter /*
415759Speter  * Get an error message from the error message file
416759Speter  */
417759Speter geterr(seekpt, buf)
418759Speter 	int seekpt;
419759Speter 	char *buf;
420759Speter {
421759Speter 
42218349Smckusick 	(void) lseek(efil, (long) seekpt, 0);
423759Speter 	if (read(efil, buf, 256) <= 0)
4246407Speter 		perror(err_file), pexit(DIED);
425759Speter }
426759Speter 
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