|
|
1.1 root 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: */
27: struct 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: */
42: extern char *filename;
43: char *lastname;
44: int lastid;
45:
46: char hadsome;
47: char holdbl;
48:
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: */
53: yyoutline()
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: */
74: yyflush()
75: {
76:
77: yyoutfl(32767);
78: }
79:
80: /*
81: * Flush the listing to the sequence id toseqid
82: */
83: yyoutfl(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:
103: FILE *yygetunit = NULL;
104: char *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: */
111: yysync()
112: {
113:
114: yyoutfl(yyeseqid);
115: if (lastid != yyeseqid)
116: yygetline(yyefile, yyseekp, yyeline, yyeseqid);
117: }
118:
119: yySsync()
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: */
135: yygetline(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)
156: oops:
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:
169: yyretrieve()
170: {
171:
172: yygetline(OY.Yyefile, OY.Yyseekp, OY.Yyeline, OY.Yyeseqid);
173: }
174:
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: */
182: yyprline(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:
209: yyprintf(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:
220: graphic(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:
236: extern int nopflg;
237:
238: char 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: */
244: yysetfile(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: */
269: yyputfn(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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.