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