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