xref: /csrg-svn/usr.bin/pascal/src/yyput.c (revision 62227)
148116Sbostic /*-
2*62227Sbostic  * Copyright (c) 1980, 1993
3*62227Sbostic  *	The Regents of the University of California.  All rights reserved.
448116Sbostic  *
548116Sbostic  * %sccs.include.redist.c%
622213Sdist  */
7793Speter 
814748Sthien #ifndef lint
9*62227Sbostic static char sccsid[] = "@(#)yyput.c	8.1 (Berkeley) 06/06/93";
1048116Sbostic #endif /* not lint */
11793Speter 
12793Speter #include "whoami.h"
13793Speter #include "0.h"
14793Speter #include "tree.h"
1514748Sthien #include "tree_ty.h"	/* must be included for yy.h */
16793Speter #include "yy.h"
17793Speter 
18793Speter /*
19793Speter  * Structure describing queued listing lines during the forward move
20793Speter  * of error recovery.  These lines will be stroed by yyoutline during
21793Speter  * the forward move and flushed by yyoutfl or yyflush when an
22793Speter  * error occurs or a program termination.
23793Speter  */
24793Speter struct	B {
25793Speter 	int	Bmagic;
26793Speter 	int	Bline;
27793Speter 	int	Bseekp;
28793Speter 	char	*Bfile;
29793Speter 	int	Bseqid;
30793Speter 	struct	B *Bnext;
31793Speter } *bottled;
32793Speter 
33793Speter /*
34793Speter  * Filename gives the current input file, lastname is
35793Speter  * the last filename we printed, and lastid is the seqid of the last line
36793Speter  * we printed, to help us avoid printing
37793Speter  * multiple copies of lines.
38793Speter  */
39793Speter extern	char *filename;
40793Speter char	*lastname;
41793Speter int	lastid;
42793Speter 
43793Speter char	hadsome;
44793Speter char	holdbl;
45793Speter 
46793Speter /*
47793Speter  * Print the current line in the input line
48793Speter  * buffer or, in a forward move of the recovery, queue it for printing.
49793Speter  */
yyoutline()50793Speter yyoutline()
51793Speter {
52793Speter 	register struct B *bp;
53793Speter 
54793Speter 	if (Recovery) {
5514748Sthien 		bp = (struct B *) tree(6, T_BOTTLE, yyline, yylinpt, filename,
5614748Sthien 				yyseqid);
57793Speter 		if (bottled != NIL)
58793Speter 			bp->Bnext = bottled->Bnext, bottled->Bnext = bp;
59793Speter 		else
60793Speter 			bp->Bnext = bp;
61793Speter 		bottled = bp;
62793Speter 		return;
63793Speter 	}
64793Speter 	yyoutfl(yyseqid);
65793Speter 	if (yyseqid != lastid)
66793Speter 		yyprline(charbuf, yyline, filename, yyseqid);
67793Speter }
68793Speter 
69793Speter /*
70793Speter  * Flush all the bottled output.
71793Speter  */
yyflush()72793Speter yyflush()
73793Speter {
74793Speter 
75793Speter 	yyoutfl(32767);
76793Speter }
77793Speter 
78793Speter /*
79793Speter  * Flush the listing to the sequence id toseqid
80793Speter  */
yyoutfl(toseqid)81793Speter yyoutfl(toseqid)
82793Speter 	int toseqid;
83793Speter {
84793Speter 	register struct B *bp;
85793Speter 
86793Speter 	bp = bottled;
87793Speter 	if (bp == NIL)
88793Speter 		return;
89793Speter 	bp = bp->Bnext;
90793Speter 	while (bp->Bseqid <= toseqid) {
91793Speter 		yygetline(bp->Bfile, bp->Bseekp, bp->Bline, bp->Bseqid);
92793Speter 		if (bp->Bnext == bp) {
93793Speter 			bottled = NIL;
94793Speter 			break;
95793Speter 		}
96793Speter 		bp = bp->Bnext;
97793Speter 		bottled->Bnext = bp;
98793Speter 	}
99793Speter }
100793Speter 
101793Speter FILE	*yygetunit = NULL;
102793Speter char	*yygetfile;
103793Speter 
104793Speter /*
105793Speter  * Yysync guarantees that the line associated
106793Speter  * with the current token was the last line
107793Speter  * printed for a syntactic error message.
108793Speter  */
yysync()109793Speter yysync()
110793Speter {
111793Speter 
112793Speter 	yyoutfl(yyeseqid);
113793Speter 	if (lastid != yyeseqid)
114793Speter 		yygetline(yyefile, yyseekp, yyeline, yyeseqid);
115793Speter }
116793Speter 
yySsync()117793Speter yySsync()
118793Speter {
119793Speter 
120793Speter 	yyoutfl(OY.Yyeseqid);
121793Speter }
122793Speter 
123793Speter /*
124793Speter  * Yygetline gets a line from a file after we have
125793Speter  * lost it.  The pointer efile gives the name of the file,
126793Speter  * seekp its offset in the file, and eline its line number.
127793Speter  * If this routine has been called before the last file
128793Speter  * it worked on will be open in yygetunit, with the files
129793Speter  * name being given in yygetfile.  Note that this unit must
130793Speter  * be opened independently of the unit in use for normal i/o
131793Speter  * to this file; if it were a dup seeks would seek both files.
132793Speter  */
yygetline(efile,seekp,eline,eseqid)133793Speter yygetline(efile, seekp, eline, eseqid)
134793Speter 	char *efile;
135793Speter 	int seekp, eline, eseqid;
136793Speter {
137793Speter 	register int cnt;
138793Speter 	register char *bp;
139793Speter 	char buf[CBSIZE + 1];
140793Speter 
141793Speter 	if (lastid == eseqid)
142793Speter 		return;
143793Speter 	if (eseqid == yyseqid) {
144793Speter 		bp = charbuf;
145793Speter 		yyprtd++;
146793Speter 	} else {
147793Speter 		bp = buf;
148793Speter 		if (efile != yygetfile) {
149793Speter 			if ( yygetunit != NULL )
15014748Sthien 			    (void) fclose( yygetunit );
151793Speter 			yygetfile = efile;
152793Speter 			yygetunit = fopen( yygetfile , "r" );
15335694Sbostic 			if (yygetunit == 0)
154793Speter oops:
155793Speter 				perror(yygetfile), pexit(DIED);
156793Speter 		}
157793Speter 		if ( fseek( yygetunit , (long) seekp , 0 ) < 0)
158793Speter 			goto oops;
159793Speter 		cnt = fread( bp , sizeof( * bp ) , CBSIZE , yygetunit );
160793Speter 		if (cnt < 0)
161793Speter 			goto oops;
162793Speter 		bp[cnt] = 0;
163793Speter 	}
164793Speter 	yyprline(bp, eline, efile, eseqid);
165793Speter }
166793Speter 
yyretrieve()167793Speter yyretrieve()
168793Speter {
169793Speter 
170793Speter 	yygetline(OY.Yyefile, OY.Yyseekp, OY.Yyeline, OY.Yyeseqid);
171793Speter }
172793Speter 
173793Speter /*
174793Speter  * Print the line in the character buffer which has
175793Speter  * line number line.  The buffer may be terminated by a new
176793Speter  * line character or a null character.  We process
177793Speter  * form feed directives, lines with only a form feed character, and
178793Speter  * suppress numbering lines which are empty here.
179793Speter  */
yyprline(buf,line,file,id)180793Speter yyprline(buf, line, file, id)
181793Speter 	register char *buf;
182793Speter 	int line;
183793Speter 	char *file;
184793Speter 	int id;
185793Speter {
186793Speter 
187793Speter 	lastid = id;
188793Speter 	if (buf[0] == '\f' && buf[1] == '\n') {
189793Speter 		printf("\f\n");
190793Speter 		hadsome = 0;
191793Speter 		holdbl = 0;
192793Speter 		return;
193793Speter 	}
194793Speter 	if (holdbl) {
195793Speter 		pchr('\n');
196793Speter 		holdbl = 0;
197793Speter 	}
198793Speter 	if (buf[0] == '\n')
199793Speter 		holdbl = 1;
200793Speter 	else {
201793Speter 		yysetfile(file);
202793Speter 		yyprintf(buf, line);
203793Speter 	}
204793Speter 	hadsome = 1;
205793Speter }
206793Speter 
yyprintf(cp,line)207793Speter yyprintf(cp, line)
208793Speter 	register char *cp;
209793Speter 	int line;
210793Speter {
211793Speter 
212793Speter 	printf("%6d  ", line);
213793Speter 	while (*cp != 0 && *cp != '\n')
214793Speter 		pchr(graphic(*cp++));
215793Speter 	pchr('\n');
216793Speter }
217793Speter 
graphic(ch)218793Speter graphic(ch)
219793Speter 	register CHAR ch;
220793Speter {
221793Speter 
222793Speter 	switch (ch) {
223793Speter 		default:
224793Speter 			if (ch >= ' ')
225793Speter 				return (ch);
226793Speter 		case 0177:
227793Speter 			return ('?');
228793Speter 		case '\n':
229793Speter 		case '\t':
230793Speter 			return (ch);
231793Speter 	}
232793Speter }
233793Speter 
234793Speter extern	int nopflg;
235793Speter 
2363087Smckusic char	printed = 1;
237793Speter /*
238793Speter  * Set the current file name to be file,
239793Speter  * printing the name, or a header on a new
240793Speter  * page if required.
241793Speter  * there is another yysetfile in error.c
242793Speter  * this one is for PI and PXP that one is for PI1
243793Speter  */
yysetfile(file)244793Speter yysetfile(file)
245793Speter 	register char *file;
246793Speter {
247793Speter 
248793Speter #ifdef PXP
249793Speter 	if (nopflg == 1)
250793Speter 		return;
251793Speter #endif
252793Speter 
253793Speter 	if (lastname == file)
254793Speter 		return;
255793Speter 	if (file == filename && opt('n') && (printed & 02) == 0) {
2563087Smckusic 		printed |= 02;
257793Speter 		header();
258793Speter 	} else
259793Speter 		yyputfn(file);
260793Speter 	lastname = file;
261793Speter }
262793Speter 
263793Speter /*
264793Speter  * Put out an include file name
265793Speter  * if an error occurs but the name has
266793Speter  * not been printed (or if another name
267793Speter  * has been printed since it has).
268793Speter  */
yyputfn(cp)269793Speter yyputfn(cp)
270793Speter 	register char *cp;
271793Speter {
272793Speter 	extern int outcol;
273793Speter 
274793Speter 	if (cp == lastname && printed)
275793Speter 		return;
276793Speter 	lastname = cp;
277793Speter 	printed = 1;
278793Speter #ifdef PXP
279793Speter 	if (outcol)
280793Speter 		pchr('\n');
281793Speter #endif
282793Speter 	gettime( cp );
28314748Sthien 	printf("%s  %s:\n" , myctime( (int *) (&tvec) ) , cp );
284793Speter 	hadsome = 1;
285793Speter }
286