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