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