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