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