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