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