xref: /csrg-svn/usr.bin/pascal/src/yyput.c (revision 22213)
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) 06/05/85";
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 }
285