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