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