xref: /csrg-svn/usr.bin/pascal/src/main.c (revision 18449)
1759Speter /* Copyright (c) 1979 Regents of the University of California */
23075Smckusic 
318349Smckusick #ifndef lint
42575Speter static	char copyright[] =
52575Speter 	    "@(#)Copyright (c) 1979 Regents of the University of California";
6759Speter 
7*18449Smckusick static char sccsid[] = "@(#)main.c 2.3 03/20/85";
818349Smckusick #endif
9759Speter 
10759Speter #include "whoami.h"
11759Speter #include "0.h"
1218349Smckusick #include "tree_ty.h"		/* must be included for yy.h */
13759Speter #include "yy.h"
14759Speter #include <signal.h>
15759Speter #include "objfmt.h"
166407Speter #include "config.h"
17759Speter 
18759Speter /*
19759Speter  * This version of pi has been in use at Berkeley since May 1977
203075Smckusic  * and is very stable. Please report any problems with the error
21759Speter  * recovery to the second author at the address given in the file
22759Speter  * READ_ME.  The second author takes full responsibility for any bugs
23759Speter  * in the syntactic error recovery.
24759Speter  */
25759Speter 
26759Speter char	piusage[]	= "pi [ -blnpstuw ] [ -i file ... ] name.p";
27759Speter 
28759Speter char	*usageis	= piusage;
29759Speter 
30759Speter #ifdef OBJ
3118349Smckusick 
3218349Smckusick char	pixusage[]	= "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]";
3318349Smckusick char	*obj	= "obj";
3418349Smckusick 
35759Speter #endif OBJ
3618349Smckusick 
37759Speter #ifdef PC
3818349Smckusick 
3918349Smckusick char	*pcname = "pc.pc0";
4018349Smckusick char	pcusage[]	= "pc [ options ] [ -o file ] [ -i file ... ] name.p";
4118349Smckusick FILE	*pcstream = NULL;
4218349Smckusick 
43759Speter #endif PC
44759Speter #ifdef PTREE
45759Speter     char	*pTreeName = "pi.pTree";
46759Speter #endif PTREE
47759Speter 
48759Speter int	onintr();
49759Speter 
50759Speter extern	char *lastname;
51759Speter 
52759Speter FILE	*ibuf;
53759Speter 
54759Speter /*
55759Speter  * these are made real variables
56759Speter  * so they can be changed
57759Speter  * if you are compiling on a smaller machine
58759Speter  */
59759Speter double	MAXINT	=  2147483647.;
60759Speter double	MININT	= -2147483648.;
61759Speter 
62759Speter /*
63759Speter  * Main program for pi.
64759Speter  * Process options, then call yymain
65759Speter  * to do all the real work.
66759Speter  */
67759Speter main(argc, argv)
68759Speter 	int argc;
69759Speter 	char *argv[];
70759Speter {
71759Speter 	register char *cp;
72759Speter 	register c;
7318349Smckusick 	FILE *fopen();
7418349Smckusick 	extern char *myctime();
7518349Smckusick 	extern long lseek();
76759Speter 	int i;
77759Speter 
78759Speter 	if (argv[0][0] == 'a')
796407Speter 		err_file += err_pathlen , how_file += how_pathlen;
80759Speter #	ifdef OBJ
81759Speter 	    if (argv[0][0] == '-' && argv[0][1] == 'o') {
82759Speter 		    obj = &argv[0][2];
83759Speter 		    usageis = pixusage;
846407Speter 		    how_file[strlen(how_file)] = 'x';
85759Speter 		    ofil = 3;
86759Speter 	    } else {
87759Speter 		    ofil = creat(obj, 0755);
88759Speter 		    if (ofil < 0) {
89759Speter 			    perror(obj);
90759Speter 			    pexit(NOSTART);
91759Speter 		    }
92759Speter 	    }
93759Speter #	endif OBJ
94759Speter 	argv++, argc--;
95759Speter 	if (argc == 0) {
96759Speter 		i = fork();
97759Speter 		if (i == -1)
98759Speter 			goto usage;
99759Speter 		if (i == 0) {
1006407Speter 			execl("/bin/cat", "cat", how_file, 0);
101759Speter 			goto usage;
102759Speter 		}
103759Speter 		while (wait(&i) != -1)
104759Speter 			continue;
105759Speter 		pexit(NOSTART);
106759Speter 	}
107759Speter #	ifdef OBJ
10811884Smckusick 	    opt('p') = opt('t') = opt('b') = 1;
10911884Smckusick #ifdef vax
11011884Smckusick 	    /* pdx is currently supported only on the vax */
11111884Smckusick 	    opt('g') = 1;
11211884Smckusick #endif vax
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':
13618349Smckusick 				    yyunique = FALSE;
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;
1535654Slinton 			    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;
16618348Smckusick 			    case 'L':
16718348Smckusick 				    togopt( 'L' );
16818348Smckusick 				    continue;
169759Speter 			    default:
170759Speter     usage:
171759Speter 				    Perror( "Usage", usageis);
172759Speter 				    pexit(NOSTART);
173759Speter 		    }
174759Speter 		    argc--, argv++;
175759Speter 	    }
176759Speter #	endif OBJ
177759Speter #	ifdef PC
178759Speter 	    opt( 'b' ) = 1;
179759Speter 	    opt( 'g' ) = 0;
180759Speter 	    opt( 't' ) = 0;
181759Speter 	    opt( 'p' ) = 0;
182759Speter 	    usageis = pcusage;
183759Speter 	    while ( argc > 0 ) {
184759Speter 		cp = argv[0];
185759Speter 		if ( *cp++ != '-' ) {
186759Speter 		    break;
187759Speter 		}
188759Speter 		c = *cp++;
189759Speter 		switch( c ) {
190759Speter #ifdef DEBUG
191759Speter 		    case 'k':
192759Speter 		    case 'r':
193759Speter 		    case 'y':
194759Speter 			    togopt(c);
195759Speter 			    break;
196759Speter 		    case 'K':
197759Speter 			    yycosts();
198759Speter 			    pexit(NOSTART);
199759Speter 		    case 'A':
2003138Smckusic 			    testtrace = TRUE;
201759Speter 			    /* and fall through */
202759Speter 		    case 'F':
2033138Smckusic 			    fulltrace = TRUE;
204759Speter 			    /* and fall through */
205759Speter 		    case 'E':
2063138Smckusic 			    errtrace = TRUE;
207759Speter 			    opt('r')++;
208759Speter 			    break;
209759Speter 		    case 'U':
21018349Smckusick 			    yyunique = FALSE;
211759Speter 			    break;
212759Speter #endif
213759Speter 		    case 'b':
214759Speter 			    opt('b') = 2;
215759Speter 			    break;
216759Speter 		    case 'i':
217759Speter 			    pflist = argv + 1;
218759Speter 			    pflstc = 0;
219759Speter 			    while (argc > 1) {
220759Speter 				    if (dotted(argv[1], 'p'))
221759Speter 					    break;
222759Speter 				    pflstc++, argc--, argv++;
223759Speter 			    }
224759Speter 			    if (pflstc == 0)
225759Speter 				    goto usage;
226759Speter 			    break;
227759Speter 			/*
228759Speter 			 *	output file for the first pass
229759Speter 			 */
230759Speter 		    case 'o':
231759Speter 			    if ( argc < 2 ) {
232759Speter 				goto usage;
233759Speter 			    }
234759Speter 			    argv++;
235759Speter 			    argc--;
236759Speter 			    pcname = argv[0];
237759Speter 			    break;
23812967Smckusick 		    case 'J':
23912967Smckusick 			    togopt( 'J' );
24012967Smckusick 			    break;
241759Speter 		    case 'C':
242759Speter 				/*
243759Speter 				 * since -t is an ld switch, use -C
244759Speter 				 * to turn on tests
245759Speter 				 */
246759Speter 			    togopt( 't' );
247759Speter 			    break;
248759Speter 		    case 'g':
249759Speter 				/*
250759Speter 				 *	sdb symbol table
251759Speter 				 */
252759Speter 			    togopt( 'g' );
253759Speter 			    break;
254759Speter 		    case 'l':
255759Speter 		    case 's':
256759Speter 		    case 'u':
257759Speter 		    case 'w':
258759Speter 			    togopt(c);
259759Speter 			    break;
260759Speter 		    case 'p':
261759Speter 				/*
262759Speter 				 *	-p on the command line means profile
263759Speter 				 */
2643138Smckusic 			    profflag = TRUE;
265759Speter 			    break;
266759Speter 		    case 'z':
2673138Smckusic 			    monflg = TRUE;
268759Speter 			    break;
26918348Smckusick 		    case 'L':
27018348Smckusick 			    togopt( 'L' );
27118348Smckusick 			    break;
272759Speter 		    default:
273759Speter usage:
274759Speter 			    Perror( "Usage", usageis);
275759Speter 			    pexit(NOSTART);
276759Speter 		}
277759Speter 		argc--;
278759Speter 		argv++;
279759Speter 	    }
280759Speter #	endif PC
281759Speter 	if (argc != 1)
282759Speter 		goto usage;
2836407Speter 	efil = open ( err_file, 0 );
284759Speter 	if ( efil < 0 )
2856407Speter 		perror(err_file), pexit(NOSTART);
286759Speter 	filename = argv[0];
287759Speter 	if (!dotted(filename, 'p')) {
288759Speter 		Perror(filename, "Name must end in '.p'");
289759Speter 		pexit(NOSTART);
290759Speter 	}
291759Speter 	close(0);
292759Speter 	if ( ( ibuf = fopen( filename , "r" ) ) == NULL )
293759Speter 		perror(filename), pexit(NOSTART);
294759Speter 	ibp = ibuf;
295759Speter #	ifdef PC
296759Speter 	    if ( ( pcstream = fopen( pcname , "w" ) ) == NULL ) {
297759Speter 		perror( pcname );
298759Speter 		pexit( NOSTART );
299759Speter 	    }
30018348Smckusick 	    stabsource( filename, TRUE );
301759Speter #	endif PC
302759Speter #	ifdef PTREE
303759Speter #	    define	MAXpPAGES	16
304759Speter 	    if ( ! pCreate( pTreeName , MAXpPAGES ) ) {
305759Speter 		perror( pTreeName );
306759Speter 		pexit( NOSTART );
307759Speter 	    }
308759Speter #	endif PTREE
309759Speter 	if ( signal( SIGINT , SIG_IGN ) != SIG_IGN )
31018349Smckusick 		(void) signal( SIGINT , onintr );
311759Speter 	if (opt('l')) {
312759Speter 		opt('n')++;
313759Speter 		yysetfile(filename);
314759Speter 		opt('n')--;
315759Speter 	}
316759Speter 	yymain();
317759Speter 	/* No return */
318759Speter }
319759Speter 
320759Speter pchr(c)
321759Speter 	char c;
322759Speter {
323759Speter 
324759Speter 	putc ( c , stdout );
325759Speter }
326759Speter 
327*18449Smckusick #ifdef PC
328*18449Smckusick char	ugh[]	= "Fatal error in pc\n";
329*18449Smckusick #endif
330*18449Smckusick #ifdef OBJ
331759Speter char	ugh[]	= "Fatal error in pi\n";
332*18449Smckusick #endif
333759Speter /*
334759Speter  * Exit from the Pascal system.
335759Speter  * We throw in an ungraceful termination
336759Speter  * message if c > 1 indicating a severe
337759Speter  * error such as running out of memory
338759Speter  * or an internal inconsistency.
339759Speter  */
340759Speter pexit(c)
341759Speter 	int c;
342759Speter {
343759Speter 
344759Speter 	if (opt('l') && c != DIED && c != NOSTART)
345759Speter 		while (getline() != -1)
346759Speter 			continue;
347759Speter 	yyflush();
348759Speter 	switch (c) {
349759Speter 		case DIED:
350759Speter 			write(2, ugh, sizeof ugh);
351759Speter 		case NOSTART:
352759Speter 		case ERRS:
353759Speter #			ifdef OBJ
354759Speter 			    if (ofil > 0)
355759Speter 				    unlink(obj);
3565654Slinton 			/*
3575654Slinton 			 * remove symbol table temp files
3585654Slinton 			 */
3595654Slinton 			    removenlfile();
3605654Slinton 
361759Speter #			endif OBJ
362759Speter #			ifdef PC
363759Speter 			    if ( pcstream != NULL ) {
364759Speter 				unlink( pcname );
365759Speter 			    }
366759Speter #			endif PC
367759Speter 			break;
368759Speter 		case AOK:
369759Speter #			ifdef OBJ
370759Speter 			    pflush();
3715654Slinton 			/*
3725654Slinton 			 * copy symbol table temp files to obj file
3735654Slinton 			 */
3745654Slinton 			    copynlfile();
3755654Slinton 
376759Speter #			endif OBJ
377759Speter #			ifdef PC
378759Speter 			    puteof();
379759Speter #			endif PC
380759Speter 			break;
381759Speter 	}
382759Speter 	/*
383759Speter 	 *	this to gather statistics on programs being compiled
384759Speter 	 *	taken 20 june 79 	... peter
385759Speter 	 *
386759Speter 	 *  if (fork() == 0) {
387759Speter 	 *  	char *cp = "-0";
388759Speter 	 *  	cp[1] += c;
389759Speter 	 *  	execl("/usr/lib/gather", "gather", cp, filename, 0);
390759Speter 	 *  	exit(1);
391759Speter 	 *  }
392759Speter 	 */
393759Speter #	ifdef PTREE
394759Speter 	    pFinish();
395759Speter #	endif
396759Speter 	exit(c);
397759Speter }
398759Speter 
399759Speter onintr()
400759Speter {
401759Speter 
40218349Smckusick 	(void) signal( SIGINT , SIG_IGN );
403759Speter 	pexit(NOSTART);
404759Speter }
405759Speter 
406759Speter /*
407759Speter  * Get an error message from the error message file
408759Speter  */
409759Speter geterr(seekpt, buf)
410759Speter 	int seekpt;
411759Speter 	char *buf;
412759Speter {
413759Speter 
41418349Smckusick 	(void) lseek(efil, (long) seekpt, 0);
415759Speter 	if (read(efil, buf, 256) <= 0)
4166407Speter 		perror(err_file), pexit(DIED);
417759Speter }
418759Speter 
419759Speter header()
420759Speter {
4216407Speter 	extern char *version;
422759Speter 	static char anyheaders;
423759Speter 
424759Speter 	gettime( filename );
425759Speter 	if (anyheaders && opt('n'))
426759Speter 		putc( '\f' , stdout );
427759Speter 	anyheaders++;
428759Speter #	ifdef OBJ
4296407Speter 	    printf("Berkeley Pascal PI -- Version %s\n\n%s  %s\n\n",
43018349Smckusick 		    version, myctime((int *) (&tvec)), filename);
431759Speter #	endif OBJ
432759Speter #	ifdef PC
4336407Speter 	    printf("Berkeley Pascal PC -- Version %s\n\n%s  %s\n\n",
43418349Smckusick 		    version, myctime((int *) (&tvec)), filename);
435759Speter #	endif PC
436759Speter }
437