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