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