|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2: #
3: /*
4: * pi - Pascal interpreter code translator
5: *
6: * Charles Haley, Bill Joy UCB
7: * Version 1.2 January 1979
8: *
9: *
10: * pxp - Pascal execution profiler
11: *
12: * Bill Joy UCB
13: * Version 1.2 January 1979
14: */
15:
16: #include "0.h"
17: #include "tree.h"
18: #include "yy.h"
19:
20: /*
21: * Structure describing queued listing lines during the forward move
22: * of error recovery. These lines will be stroed by yyoutline during
23: * the forward move and flushed by yyoutfl or yyflush when an
24: * error occurs or a program termination.
25: */
26: struct B {
27: int Bmagic;
28: int Bline;
29: int Bseekp;
30: char *Bfile;
31: int Bseqid;
32: struct B *Bnext;
33: } *bottled;
34:
35: /*
36: * Filename gives the current input file, lastname is
37: * the last filename we printed, and lastid is the seqid of the last line
38: * we printed, to help us avoid printing
39: * multiple copies of lines.
40: */
41: extern char *filename;
42: char *lastname;
43: int lastid;
44:
45: char hadsome;
46: char holdbl;
47:
48: /*
49: * Print the current line in the input line
50: * buffer or, in a forward move of the recovery, queue it for printing.
51: */
52: yyoutline()
53: {
54: register struct B *bp;
55:
56: if (Recovery) {
57: bp = tree(6, T_BOTTLE, yyline, yylinpt, filename, yyseqid);
58: if (bottled != NIL)
59: bp->Bnext = bottled->Bnext, bottled->Bnext = bp;
60: else
61: bp->Bnext = bp;
62: bottled = bp;
63: return;
64: }
65: yyoutfl(yyseqid);
66: if (yyseqid != lastid)
67: yyprline(charbuf, yyline, filename, yyseqid);
68: }
69:
70: /*
71: * Flush all the bottled output.
72: */
73: yyflush()
74: {
75:
76: yyoutfl(32767);
77: }
78:
79: /*
80: * Flush the listing to the sequence id toseqid
81: */
82: yyoutfl(toseqid)
83: int toseqid;
84: {
85: register struct B *bp;
86:
87: bp = bottled;
88: if (bp == NIL)
89: return;
90: bp = bp->Bnext;
91: while (bp->Bseqid <= toseqid) {
92: yygetline(bp->Bfile, bp->Bseekp, bp->Bline, bp->Bseqid);
93: if (bp->Bnext == bp) {
94: bottled = NIL;
95: break;
96: }
97: bp = bp->Bnext;
98: bottled->Bnext = bp;
99: }
100: }
101:
102: int yygetunit -1;
103: char *yygetfile;
104:
105: /*
106: * Yysync guarantees that the line associated
107: * with the current token was the last line
108: * printed for a syntactic error message.
109: */
110: yysync()
111: {
112:
113: yyoutfl(yyeseqid);
114: if (lastid != yyeseqid)
115: yygetline(yyefile, yyseekp, yyeline, yyeseqid);
116: }
117:
118: yySsync()
119: {
120:
121: yyoutfl(OY.Yyeseqid);
122: }
123:
124: /*
125: * Yygetline gets a line from a file after we have
126: * lost it. The pointer efile gives the name of the file,
127: * seekp its offset in the file, and eline its line number.
128: * If this routine has been called before the last file
129: * it worked on will be open in yygetunit, with the files
130: * name being given in yygetfile. Note that this unit must
131: * be opened independently of the unit in use for normal i/o
132: * to this file; if it were a dup seeks would seek both files.
133: */
134: yygetline(efile, seekp, eline, eseqid)
135: char *efile;
136: int seekp, eline, eseqid;
137: {
138: register int cnt;
139: register char *bp;
140: char buf[CBSIZE + 1];
141:
142: if (lastid == eseqid)
143: return;
144: if (eseqid == yyseqid) {
145: bp = charbuf;
146: yyprtd++;
147: } else {
148: bp = buf;
149: if (efile != yygetfile) {
150: close(yygetunit);
151: yygetfile = efile;
152: yygetunit = open(yygetfile, 0);
153: if (yygetunit < 0)
154: oops:
155: perror(yygetfile), pexit(DIED);
156: }
157: if (lseek(yygetunit, (long)seekp, 0) < 0)
158: goto oops;
159: cnt = read(yygetunit, bp, CBSIZE);
160: if (cnt < 0)
161: goto oops;
162: bp[cnt] = 0;
163: }
164: yyprline(bp, eline, efile, eseqid);
165: }
166:
167: yyretrieve()
168: {
169:
170: yygetline(OY.Yyefile, OY.Yyseekp, OY.Yyeline, OY.Yyeseqid);
171: }
172:
173: /*
174: * Print the line in the character buffer which has
175: * line number line. The buffer may be terminated by a new
176: * line character or a null character. We process
177: * form feed directives, lines with only a form feed character, and
178: * suppress numbering lines which are empty here.
179: */
180: yyprline(buf, line, file, id)
181: register char *buf;
182: int line;
183: char *file;
184: int id;
185: {
186:
187: lastid = id;
188: if (buf[0] == '\f' && buf[1] == '\n') {
189: printf("\f\n");
190: hadsome = 0;
191: holdbl = 0;
192: return;
193: }
194: if (holdbl) {
195: putchar('\n');
196: holdbl = 0;
197: }
198: if (buf[0] == '\n')
199: holdbl = 1;
200: else {
201: yysetfile(file);
202: yyprintf(buf, line);
203: }
204: hadsome = 1;
205: }
206:
207: yyprintf(cp, line)
208: register char *cp;
209: int line;
210: {
211:
212: printf("%6d ", line);
213: while (*cp != 0 && *cp != '\n')
214: putchar(graphic(*cp++));
215: putchar('\n');
216: }
217:
218: graphic(ch)
219: register CHAR ch;
220: {
221:
222: switch (ch) {
223: default:
224: if (ch >= ' ')
225: return (ch);
226: case 0177:
227: return ('?');
228: case '\n':
229: case '\t':
230: return (ch);
231: }
232: }
233:
234: extern int nopflg;
235:
236: char printed 1;
237: /*
238: * Set the current file name to be file,
239: * printing the name, or a header on a new
240: * page if required.
241: */
242: yysetfile(file)
243: register char *file;
244: {
245:
246: #ifdef PXP
247: if (nopflg == 1)
248: return;
249: #endif
250:
251: if (lastname == file)
252: return;
253: if (file == filename && opt('n') && (printed & 02) == 0) {
254: printed =| 02;
255: header();
256: } else
257: yyputfn(file);
258: lastname = file;
259: }
260:
261: /*
262: * Put out an include file name
263: * if an error occurs but the name has
264: * not been printed (or if another name
265: * has been printed since it has).
266: */
267: yyputfn(cp)
268: register char *cp;
269: {
270: extern int outcol;
271:
272: if (cp == lastname && printed)
273: return;
274: lastname = cp;
275: printed = 1;
276: #ifdef PXP
277: if (outcol)
278: putchar('\n');
279: #endif
280: printf("%s:\n", cp);
281: hadsome = 1;
282: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.