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