xref: /csrg-svn/usr.bin/pascal/src/main.c (revision 5654)
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*5654Slinton static char sccsid[] = "@(#)main.c 1.5 02/02/82";
7759Speter 
8759Speter #include "whoami.h"
9759Speter #include "0.h"
10759Speter #include "yy.h"
11759Speter #include <signal.h>
12759Speter #include "objfmt.h"
13759Speter 
14759Speter /*
15759Speter  * This version of pi has been in use at Berkeley since May 1977
163075Smckusic  * and is very stable. Please report any problems with the error
17759Speter  * recovery to the second author at the address given in the file
18759Speter  * READ_ME.  The second author takes full responsibility for any bugs
19759Speter  * in the syntactic error recovery.
20759Speter  */
21759Speter 
22759Speter char	piusage[]	= "pi [ -blnpstuw ] [ -i file ... ] name.p";
23759Speter char	pixusage[]	= "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]";
24759Speter char	pcusage[]	= "pc [ options ] [ -o file ] [ -i file ... ] name.p";
25759Speter 
26759Speter char	*usageis	= piusage;
27759Speter 
28759Speter char	*errfile = ERR_STRNGS;
29759Speter 
30759Speter #ifdef OBJ
31759Speter     char	*obj	= "obj";
32759Speter #endif OBJ
33759Speter #ifdef PC
34759Speter     char	*pcname = "pc.pc1";
35759Speter #endif PC
36759Speter #ifdef PTREE
37759Speter     char	*pTreeName = "pi.pTree";
38759Speter #endif PTREE
39759Speter 
40759Speter /*
41759Speter  * Be careful changing errfile and howfile.
42759Speter  * There are the "magic" constants 9 and 15 immediately below.
43759Speter  * errfile is now defined by ERR_STRNGS, in objfmt.h,
44759Speter  * and its leading path name length is ERR_PATHLEN long.
45759Speter  * this for executing out of the current directory if running as `a.something'.
46759Speter  */
47759Speter #ifdef OBJ
483075Smckusic char	*howfile	= HOW_STRNGS;
49759Speter #endif OBJ
50759Speter #ifdef PC
513075Smckusic char	*howfile	= HOW_STRNGS;
52759Speter #endif PC
53759Speter 
54759Speter int	onintr();
55759Speter 
56759Speter extern	char *lastname;
57759Speter 
58759Speter FILE	*ibuf;
59759Speter FILE	*pcstream = NULL;
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;
80759Speter 	int i;
81759Speter 
82759Speter 	if (argv[0][0] == 'a')
833075Smckusic 		errfile += ERR_PATHLEN , howfile += HOW_PATHLEN;
84759Speter #	ifdef OBJ
85759Speter 	    if (argv[0][0] == '-' && argv[0][1] == 'o') {
86759Speter 		    obj = &argv[0][2];
87759Speter 		    usageis = pixusage;
883075Smckusic 		    howfile[HOW_PATHLEN+6] = 'x';
89759Speter 		    ofil = 3;
90759Speter 	    } else {
91759Speter 		    ofil = creat(obj, 0755);
92759Speter 		    if (ofil < 0) {
93759Speter 			    perror(obj);
94759Speter 			    pexit(NOSTART);
95759Speter 		    }
96759Speter 	    }
97759Speter #	endif OBJ
98759Speter 	argv++, argc--;
99759Speter 	if (argc == 0) {
100759Speter 		i = fork();
101759Speter 		if (i == -1)
102759Speter 			goto usage;
103759Speter 		if (i == 0) {
104759Speter 			execl("/bin/cat", "cat", howfile, 0);
105759Speter 			goto usage;
106759Speter 		}
107759Speter 		while (wait(&i) != -1)
108759Speter 			continue;
109759Speter 		pexit(NOSTART);
110759Speter 	}
111759Speter #	ifdef OBJ
112*5654Slinton 	    opt('g') = opt('p') = opt('t') = opt('b') = 1;
113759Speter 	    while (argc > 0) {
114759Speter 		    cp = argv[0];
115759Speter 		    if (*cp++ != '-')
116759Speter 			    break;
117759Speter 		    while (c = *cp++) switch (c) {
118759Speter #ifdef DEBUG
119759Speter 			    case 'k':
120759Speter 			    case 'r':
121759Speter 			    case 'y':
122759Speter 				    togopt(c);
123759Speter 				    continue;
124759Speter 			    case 'K':
125759Speter 				    yycosts();
126759Speter 				    pexit(NOSTART);
127759Speter 			    case 'A':
1283075Smckusic 				    testtrace = TRUE;
129759Speter 			    case 'F':
1303075Smckusic 				    fulltrace = TRUE;
131759Speter 			    case 'E':
1323075Smckusic 				    errtrace = TRUE;
133759Speter 				    opt('r')++;
134759Speter 				    continue;
135759Speter 			    case 'U':
136759Speter 				    yyunique = 0;
137759Speter 				    continue;
138759Speter #endif
139759Speter 			    case 'b':
140759Speter 				    opt('b') = 2;
141759Speter 				    continue;
142759Speter 			    case 'i':
143759Speter 				    pflist = argv + 1;
144759Speter 				    pflstc = 0;
145759Speter 				    while (argc > 1) {
146759Speter 					    if (dotted(argv[1], 'p'))
147759Speter 						    break;
148759Speter 					    pflstc++, argc--, argv++;
149759Speter 				    }
150759Speter 				    if (pflstc == 0)
151759Speter 					    goto usage;
152759Speter 				    continue;
153*5654Slinton 			    case 'g':
154759Speter 			    case 'l':
155759Speter 			    case 'n':
156759Speter 			    case 'p':
157759Speter 			    case 's':
158759Speter 			    case 't':
159759Speter 			    case 'u':
160759Speter 			    case 'w':
161759Speter 				    togopt(c);
162759Speter 				    continue;
163759Speter 			    case 'z':
1643075Smckusic 				    monflg = TRUE;
165759Speter 				    continue;
166759Speter 			    default:
167759Speter     usage:
168759Speter 				    Perror( "Usage", usageis);
169759Speter 				    pexit(NOSTART);
170759Speter 		    }
171759Speter 		    argc--, argv++;
172759Speter 	    }
173759Speter #	endif OBJ
174759Speter #	ifdef PC
175759Speter 	    opt( 'b' ) = 1;
176759Speter 	    opt( 'g' ) = 0;
177759Speter 	    opt( 't' ) = 0;
178759Speter 	    opt( 'p' ) = 0;
179759Speter 	    usageis = pcusage;
180759Speter 	    while ( argc > 0 ) {
181759Speter 		cp = argv[0];
182759Speter 		if ( *cp++ != '-' ) {
183759Speter 		    break;
184759Speter 		}
185759Speter 		c = *cp++;
186759Speter 		switch( c ) {
187759Speter #ifdef DEBUG
188759Speter 		    case 'k':
189759Speter 		    case 'r':
190759Speter 		    case 'y':
191759Speter 			    togopt(c);
192759Speter 			    break;
193759Speter 		    case 'K':
194759Speter 			    yycosts();
195759Speter 			    pexit(NOSTART);
196759Speter 		    case 'A':
1973138Smckusic 			    testtrace = TRUE;
198759Speter 			    /* and fall through */
199759Speter 		    case 'F':
2003138Smckusic 			    fulltrace = TRUE;
201759Speter 			    /* and fall through */
202759Speter 		    case 'E':
2033138Smckusic 			    errtrace = TRUE;
204759Speter 			    opt('r')++;
205759Speter 			    break;
206759Speter 		    case 'U':
207759Speter 			    yyunique = 0;
208759Speter 			    break;
209759Speter #endif
210759Speter 		    case 'b':
211759Speter 			    opt('b') = 2;
212759Speter 			    break;
213759Speter 		    case 'i':
214759Speter 			    pflist = argv + 1;
215759Speter 			    pflstc = 0;
216759Speter 			    while (argc > 1) {
217759Speter 				    if (dotted(argv[1], 'p'))
218759Speter 					    break;
219759Speter 				    pflstc++, argc--, argv++;
220759Speter 			    }
221759Speter 			    if (pflstc == 0)
222759Speter 				    goto usage;
223759Speter 			    break;
224759Speter 			/*
225759Speter 			 *	output file for the first pass
226759Speter 			 */
227759Speter 		    case 'o':
228759Speter 			    if ( argc < 2 ) {
229759Speter 				goto usage;
230759Speter 			    }
231759Speter 			    argv++;
232759Speter 			    argc--;
233759Speter 			    pcname = argv[0];
234759Speter 			    break;
235759Speter 		    case 'C':
236759Speter 				/*
237759Speter 				 * since -t is an ld switch, use -C
238759Speter 				 * to turn on tests
239759Speter 				 */
240759Speter 			    togopt( 't' );
241759Speter 			    break;
242759Speter 		    case 'g':
243759Speter 				/*
244759Speter 				 *	sdb symbol table
245759Speter 				 */
246759Speter 			    togopt( 'g' );
247759Speter 			    break;
248759Speter 		    case 'l':
249759Speter 		    case 's':
250759Speter 		    case 'u':
251759Speter 		    case 'w':
252759Speter 			    togopt(c);
253759Speter 			    break;
254759Speter 		    case 'p':
255759Speter 				/*
256759Speter 				 *	-p on the command line means profile
257759Speter 				 */
2583138Smckusic 			    profflag = TRUE;
259759Speter 			    break;
260759Speter 		    case 'z':
2613138Smckusic 			    monflg = TRUE;
262759Speter 			    break;
263759Speter 		    default:
264759Speter usage:
265759Speter 			    Perror( "Usage", usageis);
266759Speter 			    pexit(NOSTART);
267759Speter 		}
268759Speter 		argc--;
269759Speter 		argv++;
270759Speter 	    }
271759Speter #	endif PC
272759Speter 	if (argc != 1)
273759Speter 		goto usage;
274759Speter 	efil = open ( errfile, 0 );
275759Speter 	if ( efil < 0 )
276759Speter 		perror(errfile), pexit(NOSTART);
277759Speter 	filename = argv[0];
278759Speter 	if (!dotted(filename, 'p')) {
279759Speter 		Perror(filename, "Name must end in '.p'");
280759Speter 		pexit(NOSTART);
281759Speter 	}
282759Speter 	close(0);
283759Speter 	if ( ( ibuf = fopen( filename , "r" ) ) == NULL )
284759Speter 		perror(filename), pexit(NOSTART);
285759Speter 	ibp = ibuf;
286759Speter #	ifdef PC
287759Speter 	    if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) {
288759Speter 		perror( pcname );
289759Speter 		pexit( NOSTART );
290759Speter 	    }
291759Speter 	    stabsource( filename );
292759Speter #	endif PC
293759Speter #	ifdef PTREE
294759Speter #	    define	MAXpPAGES	16
295759Speter 	    if ( ! pCreate( pTreeName , MAXpPAGES ) ) {
296759Speter 		perror( pTreeName );
297759Speter 		pexit( NOSTART );
298759Speter 	    }
299759Speter #	endif PTREE
300759Speter 	if ( signal( SIGINT , SIG_IGN ) != SIG_IGN )
301759Speter 		signal( SIGINT , onintr );
302759Speter 	if (opt('l')) {
303759Speter 		opt('n')++;
304759Speter 		yysetfile(filename);
305759Speter 		opt('n')--;
306759Speter 	}
307759Speter 	yymain();
308759Speter 	/* No return */
309759Speter }
310759Speter 
311759Speter pchr(c)
312759Speter 	char c;
313759Speter {
314759Speter 
315759Speter 	putc ( c , stdout );
316759Speter }
317759Speter 
318759Speter char	ugh[]	= "Fatal error in pi\n";
319759Speter /*
320759Speter  * Exit from the Pascal system.
321759Speter  * We throw in an ungraceful termination
322759Speter  * message if c > 1 indicating a severe
323759Speter  * error such as running out of memory
324759Speter  * or an internal inconsistency.
325759Speter  */
326759Speter pexit(c)
327759Speter 	int c;
328759Speter {
329759Speter 
330759Speter 	if (opt('l') && c != DIED && c != NOSTART)
331759Speter 		while (getline() != -1)
332759Speter 			continue;
333759Speter 	yyflush();
334759Speter 	switch (c) {
335759Speter 		case DIED:
336759Speter 			write(2, ugh, sizeof ugh);
337759Speter 		case NOSTART:
338759Speter 		case ERRS:
339759Speter #			ifdef OBJ
340759Speter 			    if (ofil > 0)
341759Speter 				    unlink(obj);
342*5654Slinton 			/*
343*5654Slinton 			 * remove symbol table temp files
344*5654Slinton 			 */
345*5654Slinton 			    removenlfile();
346*5654Slinton 
347759Speter #			endif OBJ
348759Speter #			ifdef PC
349759Speter 			    if ( pcstream != NULL ) {
350759Speter 				unlink( pcname );
351759Speter 			    }
352759Speter #			endif PC
353759Speter 			break;
354759Speter 		case AOK:
355759Speter #			ifdef OBJ
356759Speter 			    pflush();
357*5654Slinton 			/*
358*5654Slinton 			 * copy symbol table temp files to obj file
359*5654Slinton 			 */
360*5654Slinton 			    copynlfile();
361*5654Slinton 
362759Speter #			endif OBJ
363759Speter #			ifdef PC
364759Speter 			    puteof();
365759Speter #			endif PC
366759Speter 			break;
367759Speter 	}
368759Speter 	/*
369759Speter 	 *	this to gather statistics on programs being compiled
370759Speter 	 *	taken 20 june 79 	... peter
371759Speter 	 *
372759Speter 	 *  if (fork() == 0) {
373759Speter 	 *  	char *cp = "-0";
374759Speter 	 *  	cp[1] += c;
375759Speter 	 *  	execl("/usr/lib/gather", "gather", cp, filename, 0);
376759Speter 	 *  	exit(1);
377759Speter 	 *  }
378759Speter 	 */
379759Speter #	ifdef PTREE
380759Speter 	    pFinish();
381759Speter #	endif
382759Speter 	exit(c);
383759Speter }
384759Speter 
385759Speter onintr()
386759Speter {
387759Speter 
388759Speter 	signal( SIGINT , SIG_IGN );
389759Speter 	pexit(NOSTART);
390759Speter }
391759Speter 
392759Speter /*
393759Speter  * Get an error message from the error message file
394759Speter  */
395759Speter geterr(seekpt, buf)
396759Speter 	int seekpt;
397759Speter 	char *buf;
398759Speter {
399759Speter 
400759Speter 	lseek(efil, (long) seekpt, 0);
401759Speter 	if (read(efil, buf, 256) <= 0)
402759Speter 		perror(errfile), pexit(DIED);
403759Speter }
404759Speter 
405759Speter header()
406759Speter {
407759Speter 	extern char version[];
408759Speter 	static char anyheaders;
409759Speter 
410759Speter 	gettime( filename );
411759Speter 	if (anyheaders && opt('n'))
412759Speter 		putc( '\f' , stdout );
413759Speter 	anyheaders++;
414759Speter #	ifdef OBJ
415759Speter 	    printf("Berkeley Pascal PI -- Version 2.0 (%s)\n\n%s  %s\n\n",
416759Speter 		    version, myctime(&tvec), filename);
417759Speter #	endif OBJ
418759Speter #	ifdef PC
419759Speter 	    printf("Berkeley Pascal PC -- Version 2.0 (%s)\n\n%s  %s\n\n",
420759Speter 		    version, myctime(&tvec), filename);
421759Speter #	endif PC
422759Speter }
423