xref: /csrg-svn/usr.bin/pascal/src/main.c (revision 30838)
122177Sdist /*
222177Sdist  * Copyright (c) 1980 Regents of the University of California.
322177Sdist  * All rights reserved.  The Berkeley software License Agreement
422177Sdist  * specifies the terms and conditions for redistribution.
522177Sdist  */
63075Smckusic 
718349Smckusick #ifndef lint
822177Sdist char copyright[] =
922177Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
1022177Sdist  All rights reserved.\n";
1122177Sdist #endif not lint
12759Speter 
1322177Sdist #ifndef lint
14*30838Smckusick static char sccsid[] = "@(#)main.c	5.2 (Berkeley) 04/07/87";
1522177Sdist #endif not lint
16759Speter 
17759Speter #include "whoami.h"
18759Speter #include "0.h"
1918349Smckusick #include "tree_ty.h"		/* must be included for yy.h */
20759Speter #include "yy.h"
21759Speter #include <signal.h>
22759Speter #include "objfmt.h"
236407Speter #include "config.h"
24759Speter 
25759Speter /*
26759Speter  * This version of pi has been in use at Berkeley since May 1977
273075Smckusic  * and is very stable. Please report any problems with the error
28759Speter  * recovery to the second author at the address given in the file
29759Speter  * READ_ME.  The second author takes full responsibility for any bugs
30759Speter  * in the syntactic error recovery.
31759Speter  */
32759Speter 
33759Speter char	piusage[]	= "pi [ -blnpstuw ] [ -i file ... ] name.p";
34759Speter 
35759Speter char	*usageis	= piusage;
36759Speter 
37759Speter #ifdef OBJ
3818349Smckusick 
3918349Smckusick char	pixusage[]	= "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]";
4018349Smckusick char	*obj	= "obj";
4118349Smckusick 
42759Speter #endif OBJ
4318349Smckusick 
44759Speter #ifdef PC
4518349Smckusick 
4618349Smckusick char	*pcname = "pc.pc0";
4718349Smckusick char	pcusage[]	= "pc [ options ] [ -o file ] [ -i file ... ] name.p";
4818349Smckusick FILE	*pcstream = NULL;
4918349Smckusick 
50759Speter #endif PC
51759Speter #ifdef PTREE
52759Speter     char	*pTreeName = "pi.pTree";
53759Speter #endif PTREE
54759Speter 
55759Speter int	onintr();
56759Speter 
57759Speter extern	char *lastname;
58759Speter 
59759Speter FILE	*ibuf;
60759Speter 
61759Speter /*
62759Speter  * these are made real variables
63759Speter  * so they can be changed
64759Speter  * if you are compiling on a smaller machine
65759Speter  */
66759Speter double	MAXINT	=  2147483647.;
67759Speter double	MININT	= -2147483648.;
68759Speter 
69759Speter /*
70759Speter  * Main program for pi.
71759Speter  * Process options, then call yymain
72759Speter  * to do all the real work.
73759Speter  */
74759Speter main(argc, argv)
75759Speter 	int argc;
76759Speter 	char *argv[];
77759Speter {
78759Speter 	register char *cp;
79759Speter 	register c;
8018349Smckusick 	FILE *fopen();
8118349Smckusick 	extern char *myctime();
8218349Smckusick 	extern long lseek();
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;
116*30838Smckusick #if defined(vax) || defined(tahoe)
117*30838Smckusick 	    /* pdx is currently supported on the vax and the tahoe */
11811884Smckusick 	    opt('g') = 1;
119*30838Smckusick #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 
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  */
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 
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  */
416759Speter geterr(seekpt, buf)
417759Speter 	int seekpt;
418759Speter 	char *buf;
419759Speter {
420759Speter 
42118349Smckusick 	(void) lseek(efil, (long) seekpt, 0);
422759Speter 	if (read(efil, buf, 256) <= 0)
4236407Speter 		perror(err_file), pexit(DIED);
424759Speter }
425759Speter 
426759Speter header()
427759Speter {
4286407Speter 	extern char *version;
429759Speter 	static char anyheaders;
430759Speter 
431759Speter 	gettime( filename );
432759Speter 	if (anyheaders && opt('n'))
433759Speter 		putc( '\f' , stdout );
434759Speter 	anyheaders++;
435759Speter #	ifdef OBJ
4366407Speter 	    printf("Berkeley Pascal PI -- Version %s\n\n%s  %s\n\n",
43718349Smckusick 		    version, myctime((int *) (&tvec)), filename);
438759Speter #	endif OBJ
439759Speter #	ifdef PC
4406407Speter 	    printf("Berkeley Pascal PC -- Version %s\n\n%s  %s\n\n",
44118349Smckusick 		    version, myctime((int *) (&tvec)), filename);
442759Speter #	endif PC
443759Speter }
444