1: static char sccsid[] = "%W%"; /* SCCS id keyword */
2: /* Copyright (c) 1979 Regents of the University of California */
3: #
4: /*
5: * pi - Pascal interpreter code translator
6: *
7: * Charles Haley, Bill Joy UCB
8: * Version 1.2 November 1978
9: */
10:
11: #include "whoami"
12: #include "0.h"
13: #include "yy.h"
14:
15: /*
16: * This version of pi has been in use at Berkeley since May 1977
17: * and is very stable, except for the syntactic error recovery which
18: * has just been written. Please report any problems with the error
19: * recovery to the second author at the address given in the file
20: * READ_ME. The second author takes full responsibility for any bugs
21: * in the syntactic error recovery.
22: */
23:
24: char piusage[] = "pi [ -blnpstuw ] [ -i file ... ] name.p";
25: char pixusage[] = "pix [ -blnpstuw ] [ -i file ... ] name.p [ arg ... ]";
26:
27: char *usageis = piusage;
28: char *obj = "obj";
29: /*
30: * Be careful changing errfile and howfile.
31: * There are the "magic" constants 9 and 15 immediately below.
32: */
33: char *errfile = "/usr/lib/pi1.2strings";
34: char *howfile = "/usr/lib/how_pi\0";
35:
36: int onintr();
37:
38: extern char *lastname;
39:
40: FILE *ibuf;
41:
42: /*
43: * these are made real variables
44: * so they can be changed
45: * if you are compiling on a smaller machine
46: */
47: double MAXINT = 2147483647.;
48: double MININT = -2147483648.;
49:
50: /*
51: * Main program for pi.
52: * Process options, then call yymain
53: * to do all the real work.
54: */
55: main(argc, argv)
56: int argc;
57: char *argv[];
58: {
59: register char *cp;
60: register c;
61: int i;
62:
63: if (argv[0][0] == 'a')
64: errfile += 9, howfile += 9;
65: if (argv[0][0] == '-' && argv[0][1] == 'o') {
66: obj = &argv[0][2];
67: usageis = pixusage;
68: howfile[15] = 'x';
69: ofil = 3;
70: } else {
71: ofil = creat(obj, 0755);
72: if (ofil < 0) {
73: perror(obj);
74: pexit(NOSTART);
75: }
76: }
77: argv++, argc--;
78: if (argc == 0) {
79: i = fork();
80: if (i == -1)
81: goto usage;
82: if (i == 0) {
83: execl("/bin/cat", "cat", howfile, 0);
84: goto usage;
85: }
86: while (wait(&i) != -1)
87: continue;
88: pexit(NOSTART);
89: }
90: opt('p') = opt('t') = opt('b') = 1;
91: while (argc > 0) {
92: cp = argv[0];
93: if (*cp++ != '-')
94: break;
95: while (c = *cp++) switch (c) {
96: #ifdef DEBUG
97: case 'c':
98: case 'r':
99: case 'y':
100: togopt(c);
101: continue;
102: case 'C':
103: yycosts();
104: pexit(NOSTART);
105: case 'A':
106: testtrace++;
107: case 'F':
108: fulltrace++;
109: case 'E':
110: errtrace++;
111: opt('r')++;
112: continue;
113: case 'U':
114: yyunique = 0;
115: continue;
116: #endif
117: case 'b':
118: opt('b') = 2;
119: continue;
120: case 'i':
121: pflist = argv + 1;
122: pflstc = 0;
123: while (argc > 1) {
124: if (dotted(argv[1], 'p'))
125: break;
126: pflstc++, argc--, argv++;
127: }
128: if (pflstc == 0)
129: goto usage;
130: continue;
131: case 'l':
132: case 'n':
133: case 'p':
134: case 's':
135: case 't':
136: case 'u':
137: case 'w':
138: togopt(c);
139: continue;
140: case 'z':
141: monflg++;
142: continue;
143: default:
144: usage:
145: Perror( "Usage", usageis);
146: pexit(NOSTART);
147: }
148: argc--, argv++;
149: }
150: if (argc != 1)
151: goto usage;
152: efil = open ( errfile, 0 );
153: if ( efil < 0 )
154: perror(errfile), pexit(NOSTART);
155: filename = argv[0];
156: if (!dotted(filename, 'p')) {
157: Perror(filename, "Name must end in '.p'");
158: pexit(NOSTART);
159: }
160: close(0);
161: if ( ( ibuf = fopen ( filename , "r" ) ) == NULL )
162: perror(filename), pexit(NOSTART);
163: ibp = ibuf;
164: if ((signal(2, 1) & 01) == 0)
165: signal(2, onintr);
166: if (opt('l')) {
167: opt('n')++;
168: yysetfile(filename);
169: opt('n')--;
170: } else
171: lastname = filename;
172: yymain();
173: /* No return */
174: }
175:
176: pchr(c)
177: char c;
178: {
179:
180: putc ( c , stdout );
181: }
182:
183: char ugh[] = "Fatal error in pi\n";
184: /*
185: * Exit from the Pascal system.
186: * We throw in an ungraceful termination
187: * message if c > 1 indicating a severe
188: * error such as running out of memory
189: * or an internal inconsistency.
190: */
191: pexit(c)
192: int c;
193: {
194:
195: if (opt('l') && c != DIED && c != NOSTART)
196: while (getline() != -1)
197: continue;
198: yyflush();
199: switch (c) {
200: case DIED:
201: write(2, ugh, sizeof ugh);
202: case NOSTART:
203: case ERRS:
204: if (ofil > 0)
205: unlink(obj);
206: break;
207: case AOK:
208: pflush();
209: break;
210: }
211: exit(c);
212: }
213:
214: onintr()
215: {
216:
217: signal(2, 1);
218: pexit(NOSTART);
219: }
220:
221: /*
222: * Get an error message from the error message file
223: */
224: geterr(seekpt, buf)
225: int seekpt;
226: char *buf;
227: {
228:
229: lseek(efil, (long) seekpt, 0);
230: if (read(efil, buf, 256) <= 0)
231: perror(errfile), pexit(DIED);
232: }
233:
234: ()
235: {
236: extern char version[];
237: static char anyheaders;
238:
239: gettime();
240: if (anyheaders && opt('n'))
241: putc( '\f' , stdout );
242: anyheaders++;
243: printf("Berkeley Pascal PI -- Version 1.2 (%s)\n\n%s %s\n\n",
244: version, myctime(&tvec), filename);
245: }