change over to new error message format
[unix-history] / usr / src / usr.bin / pascal / pxp / yycomm.c
CommitLineData
16f88651
PK
1static char *sccsid = "@(#)yycomm.c 1.1 (Berkeley) %G%";
2/* Copyright (c) 1979 Regents of the University of California */
3#
4/*
5 * pxp - Pascal execution profiler
6 *
7 * Bill Joy UCB
8 * Version 1.2 January 1979
9 */
10
11#include "0.h"
12#include "yy.h"
13
14/*
15 * COMMENT PROCESSING CLUSTER
16 *
17 * The global organization of this cluster is as follows.
18 * While parsing the program information is saved in the tree which
19 * tells the source text coordinates (sequence numbers and columns)
20 * bounding each production. The comments from the source program
21 * are also saved, with information about their source text position
22 * and a classification as to their kind.
23 *
24 * When printing the reformatted program we flush out the comments
25 * at various points using the information in the comments and the parse
26 * tree to "resynchronize". A number of special cases are recognized to
27 * deal with the vagarities of producing a true "fixed point" so that
28 * a prettyprinted program will re-prettyprint to itself.
29 */
30
31/*
32 * Save sequence id's and column markers bounding a production
33 * for later use in placing comments. We save the sequence id
34 * and column of the leftmost token and the following token, and
35 * the sequence id of the last token in this reduction.
36 * See putcm, putcml, and putcmp below for motivation.
37 */
38line2of(l)
39 int l;
40{
41
42 return (lineNof(l, 2));
43}
44
45lineof(l)
46 int l;
47{
48
49 return (lineNof(l, 1));
50}
51
52lineNof(l, i)
53 int l, i;
54{
55
56 return(tree(6, l, yypw[i].Wseqid, yypw[i].Wcol, yyseqid, yycol, yypw[N].Wseqid));
57}
58
59/*
60 * After a call to setline, Seqid is set to the sequence id
61 * of the symbol which followed the reduction in which the
62 * lineof call was embedded, Col to the associated column,
63 * and LSeqid to the sequence id of the last symbol in the reduction
64 * (Note that this is exact only if the last symbol was a terminal
65 * this is always true when it matters.)
66 */
67int Seqid, Col, LSeqid;
68
69/*
70 * Retrieve the information from a call to lineof before beginning the
71 * output of a tree from a reduction. First flush to the left margin
72 * of the production, and then set so that later calls to putcm, putcml
73 * and putcmp will deal with the right margin of this comment.
74 *
75 * The routine setinfo is called when the lineof has no embedded line
76 * number to avoid trashing the current "line".
77 *
78 * The routine setinfo is often called after completing the output of
79 * the text of a tree to restore Seqid, Col, and LSeqid which may have
80 * been destroyed by the nested processing calls to setline.
81 * In this case the only effect of the call to setinfo is to
82 * modify the above three variables as a side effect.
83 *
84 * We return a word giving information about the comments which were
85 * actually put out. See putcm for details.
86 */
87setline(ip)
88 int *ip;
89{
90
91 line = ip[0];
92 return(setinfo(ip));
93}
94
95setinfo(ip)
96 register int *ip;
97{
98 register int i;
99
100 ip++;
101 Seqid = *ip++;
102 Col = *ip++;
103 i = putcm();
104 Seqid = *ip++;
105 Col = *ip++;
106 LSeqid = *ip++;
107 return (i);
108}
109
110char cmeof, incomm;
111
112/*
113 * Get the text of a comment from the input stream,
114 * recording its type and linking it into the linked
115 * list of comments headed by cmhp.
116 */
117getcm(cmdelim)
118 char cmdelim;
119{
120 int cmjust, col;
121 register struct comment *cp;
122 register struct commline *kp;
123
124 incomm = 1;
125 if (cmdelim == '*' && yycol == 10 || cmdelim == '{' && yycol == 9)
126 cmjust = CLMARG;
127 else if (yytokcnt <= 1)
128 cmjust = CALIGN;
129 else if (yywhcnt < 2)
130 cmjust = CTRAIL;
131 else
132 cmjust = CRMARG;
133 col = yycol - (cmdelim == '{' ? 1 : 2);
134 cp = tree5(NIL, cmdelim, NIL, cmjust, yyseqid);
135 cmeof = 0;
136 do {
137 kp = getcmline(cmdelim);
138 if (cp->cml == NIL) {
139 kp->cml = kp;
140 kp->cmcol = col;
141 } else {
142 kp->cml = cp->cml->cml;
143 cp->cml->cml = kp;
144 switch (cp->cmjust) {
145 case CTRAIL:
146 case CRMARG:
147 cp->cmjust = CALIGN;
148 }
149 }
150 cp->cml = kp;
151 } while (!cmeof);
152 newcomm(cp);
153 incomm = 0;
154}
155
156/*
157 * Chain the new comment at "cp" onto the linked list of comments.
158 */
159newcomm(cp)
160 register struct comment *cp;
161{
162
163 if (cmhp == NIL)
164 cp->cmnext = cp;
165 else {
166 cp->cmnext = cmhp->cmnext;
167 cmhp->cmnext = cp;
168 }
169 cmhp = cp;
170}
171
172
173int nilcml[3];
174
175quickcomm(t)
176 int t;
177{
178
179 if (incomm)
180 return;
181 newcomm(tree5(nilcml, NIL, NIL, t, yyseqid));
182}
183
184commincl(cp, ch)
185 char *cp, ch;
186{
187
188 newcomm(tree5(nilcml, savestr(cp), ch, CINCLUD, yyseqid));
189}
190
191getcmline(cmdelim)
192 char cmdelim;
193{
194 char lastc;
195 register char *tp;
196 register CHAR c;
197 register struct commline *kp;
198
199 c = readch();
200 kp = tree3(NIL, yycol, NIL);
201 tp = token;
202 lastc = 0;
203 for (;;) {
204 switch (c) {
205 case '}':
206 if (cmdelim == '{')
207 goto endcm;
208 break;
209 case ')':
210 if (cmdelim == '*' && lastc == '*') {
211 --tp;
212 goto endcm;
213 }
214 break;
215 case '\n':
216 goto done;
217 case -1:
218 yerror("Comment does not terminate - QUIT");
219 pexit(ERRS);
220 }
221 lastc = c;
222 *tp++ = c;
223 c = readch();
224 }
225endcm:
226 cmeof++;
227done:
228 *tp = 0;
229 kp->cmtext = copystr(token);
230 return (kp);
231}
232
233/*
234 * Flush through the line this token is on.
235 * Ignore if next token on same line as this one.
236 */
237putcml()
238{
239 register int i, SSeqid, SCol;
240
241 if (Seqid == LSeqid)
242 return (1);
243 SSeqid = Seqid, SCol = Col;
244 Seqid = LSeqid, Col = 32767;
245 i = putcm();
246 Seqid = SSeqid, Col = SCol;
247 return (i);
248}
249
250/*
251 * Flush to the beginning of the line this token is on.
252 * Ignore if this token is on the same line as the previous one
253 * (effectively since all such already then flushed.)
254 */
255putcmp()
256{
257 register int i, SSeqid, SCol;
258
259 SSeqid = Seqid, SCol = Col;
260 Seqid = LSeqid, Col = 0;
261 i = putcm();
262 Seqid = SSeqid, Col = SCol;
263 return (i);
264}
265
266/*
267 * Put out the comments to the border indicated by Seqid and Col
268 */
269putcm()
270{
271 register struct comment *cp;
272 register int i;
273
274 cp = cmhp;
275 if (cp == NIL)
276 return (0);
277 i = 0;
278 cp = cp->cmnext;
279 while (cp->cmseqid < Seqid || cp->cmseqid == Seqid && cp->cml->cmcol < Col) {
280 putone(cp);
281 i =| 1 << cp->cmjust;
282 if (cp->cmnext == cp) {
283 cmhp = NIL;
284 break;
285 }
286 cp = cp->cmnext;
287 cmhp->cmnext = cp;
288 }
289 return (i);
290}
291
292/*
293 * Put out one comment.
294 * Note that empty lines, form feeds and #include statements
295 * are treated as comments are regurgitated here.
296 */
297putone(cp)
298 register struct comment *cp;
299{
300 register struct commline *cml, *cmf;
301
302 align(cp);
303 switch (cp->cmjust) {
304 case CINCLUD:
305 /* ppflush() */
306 if (noinclude == 0) {
307 putchar('\f');
308 return;
309 }
310 printf("#include %c%s%c", cp->cml, cp->cmdelim, cp->cml);
311 return;
312 }
313 if (stripcomm)
314 return;
315 switch (cp->cmjust) {
316 case CFORM:
317 ppop("\f");
318 ppnl();
319 case CNL:
320 case CNLBL:
321 return;
322 }
323 ppbra(cp->cmdelim == '{' ? "{" : "(*");
324 cmf = cp->cml->cml;
325 ppid(cmf->cmtext);
326 for (cml = cmf->cml; cml != cmf; cml = cml->cml) {
327 align(cp);
328 oneline(cmf->cmcol, cml);
329 }
330 ppket(cp->cmdelim == '{' ? "}" : "*)");
331}
332
333/*
334 * Do the preliminary horizontal and vertical
335 * motions necessary before beginning a comment,
336 * or between lines of a mult-line comment.
337 */
338align(cp)
339 register struct comment *cp;
340{
341
342 switch (cp->cmjust) {
343 case CNL:
344 ppsnl();
345 break;
346 case CNLBL:
347 ppsnlb();
348 break;
349 case CFORM:
350 case CINCLUD:
351 ppnl();
352 break;
353 case CLMARG:
354 ppnl();
355 if (profile)
356 ppid("\t");
357 break;
358 case CALIGN:
359 ppnl();
360 indent();
361 break;
362 case CTRAIL:
363 ppspac();
364 break;
365 case CRMARG:
366 case CSRMARG:
367 pptab();
368 break;
369 }
370}
371
372/*
373 * One line of a multi-line comment
374 * Deal with alignment and initial white space trimming.
375 * The "margin" indicates where the first line of the
376 * comment began... don't print stuff in this comment
377 * which came before this.
378 */
379oneline(margin, cml)
380 int margin;
381 struct commline *cml;
382{
383 register char *tp;
384 register int i;
385
386 for (i = 8, tp = cml->cmtext; i < margin && *tp; tp++)
387 switch (*tp) {
388 case ' ':
389 i++;
390 continue;
391 case '\t':
392 i =+ 8;
393 i =& ~7;
394 if (i < margin)
395 continue;
396 ppop("\t");
397 default:
398 goto out;
399 }
400out:
401 ppid(tp);
402}
403
404/*
405 * Flush all comments
406 */
407flushcm()
408{
409
410 Seqid = 32767;
411 return(putcm());
412}
413
414#define BLANKS ((1 << CNL) | (1 << CNLBL) | (1 << CFORM))
415noblank(i)
416 int i;
417{
418
419 return ((i & BLANKS) == 0);
420}
421
422int needform, neednlbl, neednl, needseqid;
423
424needtree()
425{
426 register struct comment *cp;
427
428 needform = neednlbl = neednl = 0;
429 cp = cmhp;
430 if (cp == NIL)
431 return (0);
432 do {
433 switch (cp->cmjust) {
434 case CNL:
435 neednl++;
436 goto seq;
437 case CNLBL:
438 neednlbl++;
439 goto seq;
440 case CFORM:
441 needform++;
442seq:
443 needseqid = cp->cmseqid;
444 break;
445 default:
446 neednl = neednlbl = needform = 0;
447 return (1);
448 }
449 cp = cp->cmnext;
450 } while (cp != cmhp);
451 cmhp = NIL;
452 return (0);
453}
454
455packtree()
456{
457 int save;
458
459 save = yyseqid;
460 yyseqid = needseqid;
461 for (; needform > 0; needform--)
462 commform();
463 for (; neednl > 0; neednl--)
464 commnl();
465 for (; neednlbl > 0; neednlbl--)
466 commnlbl();
467 yyseqid = save;
468}