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