xref: /original-bsd/usr.bin/pascal/src/yyput.c (revision 552e81d8)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 static	char sccsid[] = "@(#)yyput.c 1.1 08/27/80";
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 }
277