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