change q_mailer to be index, not pointer
[unix-history] / usr / src / usr.bin / pascal / pxp / yyput.c
CommitLineData
9a071694
PK
1static char *sccsid = "@(#)yyput.c 1.1 (Berkeley) %G%";
2/* Copyright (c) 1979 Regents of the University of California */
3#
4/*
5 * pi - Pascal interpreter code translator
6 *
7 * Charles Haley, Bill Joy UCB
8 * Version 1.2 January 1979
9 *
10 *
11 * pxp - Pascal execution profiler
12 *
13 * Bill Joy UCB
14 * Version 1.2 January 1979
15 */
16
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
103int yygetunit -1;
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 close(yygetunit);
152 yygetfile = efile;
153 yygetunit = open(yygetfile, 0);
154 if (yygetunit < 0)
155oops:
156 perror(yygetfile), pexit(DIED);
157 }
158 if (lseek(yygetunit, (long)seekp, 0) < 0)
159 goto oops;
160 cnt = read(yygetunit, bp, CBSIZE);
161 if (cnt < 0)
162 goto oops;
163 bp[cnt] = 0;
164 }
165 yyprline(bp, eline, efile, eseqid);
166}
167
168yyretrieve()
169{
170
171 yygetline(OY.Yyefile, OY.Yyseekp, OY.Yyeline, OY.Yyeseqid);
172}
173\f
174/*
175 * Print the line in the character buffer which has
176 * line number line. The buffer may be terminated by a new
177 * line character or a null character. We process
178 * form feed directives, lines with only a form feed character, and
179 * suppress numbering lines which are empty here.
180 */
181yyprline(buf, line, file, id)
182 register char *buf;
183 int line;
184 char *file;
185 int id;
186{
187
188 lastid = id;
189 if (buf[0] == '\f' && buf[1] == '\n') {
190 printf("\f\n");
191 hadsome = 0;
192 holdbl = 0;
193 return;
194 }
195 if (holdbl) {
196 putchar('\n');
197 holdbl = 0;
198 }
199 if (buf[0] == '\n')
200 holdbl = 1;
201 else {
202 yysetfile(file);
203 yyprintf(buf, line);
204 }
205 hadsome = 1;
206}
207
208yyprintf(cp, line)
209 register char *cp;
210 int line;
211{
212
213 printf("%6d ", line);
214 while (*cp != 0 && *cp != '\n')
215 putchar(graphic(*cp++));
216 putchar('\n');
217}
218
219graphic(ch)
220 register CHAR ch;
221{
222
223 switch (ch) {
224 default:
225 if (ch >= ' ')
226 return (ch);
227 case 0177:
228 return ('?');
229 case '\n':
230 case '\t':
231 return (ch);
232 }
233}
234\f
235extern int nopflg;
236
237char printed 1;
238/*
239 * Set the current file name to be file,
240 * printing the name, or a header on a new
241 * page if required.
242 */
243yysetfile(file)
244 register char *file;
245{
246
247#ifdef PXP
248 if (nopflg == 1)
249 return;
250#endif
251
252 if (lastname == file)
253 return;
254 if (file == filename && opt('n') && (printed & 02) == 0) {
255 printed =| 02;
256 header();
257 } else
258 yyputfn(file);
259 lastname = file;
260}
261
262/*
263 * Put out an include file name
264 * if an error occurs but the name has
265 * not been printed (or if another name
266 * has been printed since it has).
267 */
268yyputfn(cp)
269 register char *cp;
270{
271 extern int outcol;
272
273 if (cp == lastname && printed)
274 return;
275 lastname = cp;
276 printed = 1;
277#ifdef PXP
278 if (outcol)
279 putchar('\n');
280#endif
281 printf("%s:\n", cp);
282 hadsome = 1;
283}