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