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