eyacc moves; strip on install
[unix-history] / usr / src / usr.bin / pascal / pxp / yycomm.c
CommitLineData
252367af
DF
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
8static char sccsid[] = "@(#)yycomm.c 5.1 (Berkeley) %G%";
9#endif not lint
10
16f88651
PK
11/*
12 * pxp - Pascal execution profiler
13 *
14 * Bill Joy UCB
15 * Version 1.2 January 1979
16 */
17
5bbe9cdb 18#include "whoami.h"
16f88651
PK
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 */
46line2of(l)
47 int l;
48{
49
50 return (lineNof(l, 2));
51}
52
53lineof(l)
54 int l;
55{
56
57 return (lineNof(l, 1));
58}
59
60lineNof(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 */
75int 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 */
95setline(ip)
96 int *ip;
97{
98
99 line = ip[0];
100 return(setinfo(ip));
101}
102
103setinfo(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
118char 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 */
125getcm(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 */
167newcomm(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
181int nilcml[3];
182
183quickcomm(t)
184 int t;
185{
186
187 if (incomm)
188 return;
189 newcomm(tree5(nilcml, NIL, NIL, t, yyseqid));
190}
191
192commincl(cp, ch)
193 char *cp, ch;
194{
195
196 newcomm(tree5(nilcml, savestr(cp), ch, CINCLUD, yyseqid));
197}
198
199getcmline(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 }
233endcm:
234 cmeof++;
235done:
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 */
245putcml()
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 */
263putcmp()
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 */
277putcm()
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 */
305putone(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 */
346align(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 */
387oneline(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 }
408out:
409 ppid(tp);
410}
411
412/*
413 * Flush all comments
414 */
415flushcm()
416{
417
418 Seqid = 32767;
419 return(putcm());
420}
421
422#define BLANKS ((1 << CNL) | (1 << CNLBL) | (1 << CFORM))
423noblank(i)
424 int i;
425{
426
427 return ((i & BLANKS) == 0);
428}
429
430int needform, neednlbl, neednl, needseqid;
431
432needtree()
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++;
450seq:
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
463packtree()
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}