1*48112Sbostic /*- 2*48112Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48112Sbostic * All rights reserved. 4*48112Sbostic * 5*48112Sbostic * %sccs.include.redist.c% 622243Sdist */ 722243Sdist 822243Sdist #ifndef lint 9*48112Sbostic static char sccsid[] = "@(#)yycomm.c 5.3 (Berkeley) 04/16/91"; 10*48112Sbostic #endif /* not lint */ 1122243Sdist 1222243Sdist /* 132868Speter * pxp - Pascal execution profiler 142868Speter * 152868Speter * Bill Joy UCB 162868Speter * Version 1.2 January 1979 172868Speter */ 182868Speter 1910733Smckusick #include "whoami.h" 202868Speter #include "0.h" 212868Speter #include "yy.h" 222868Speter 232868Speter /* 242868Speter * COMMENT PROCESSING CLUSTER 252868Speter * 262868Speter * The global organization of this cluster is as follows. 272868Speter * While parsing the program information is saved in the tree which 282868Speter * tells the source text coordinates (sequence numbers and columns) 292868Speter * bounding each production. The comments from the source program 302868Speter * are also saved, with information about their source text position 312868Speter * and a classification as to their kind. 322868Speter * 332868Speter * When printing the reformatted program we flush out the comments 342868Speter * at various points using the information in the comments and the parse 352868Speter * tree to "resynchronize". A number of special cases are recognized to 362868Speter * deal with the vagarities of producing a true "fixed point" so that 372868Speter * a prettyprinted program will re-prettyprint to itself. 382868Speter */ 392868Speter 402868Speter /* 412868Speter * Save sequence id's and column markers bounding a production 422868Speter * for later use in placing comments. We save the sequence id 432868Speter * and column of the leftmost token and the following token, and 442868Speter * the sequence id of the last token in this reduction. 452868Speter * See putcm, putcml, and putcmp below for motivation. 462868Speter */ 472868Speter line2of(l) 482868Speter int l; 492868Speter { 502868Speter 512868Speter return (lineNof(l, 2)); 522868Speter } 532868Speter 542868Speter lineof(l) 552868Speter int l; 562868Speter { 572868Speter 582868Speter return (lineNof(l, 1)); 592868Speter } 602868Speter 612868Speter lineNof(l, i) 622868Speter int l, i; 632868Speter { 642868Speter 652868Speter return(tree(6, l, yypw[i].Wseqid, yypw[i].Wcol, yyseqid, yycol, yypw[N].Wseqid)); 662868Speter } 672868Speter 682868Speter /* 692868Speter * After a call to setline, Seqid is set to the sequence id 702868Speter * of the symbol which followed the reduction in which the 712868Speter * lineof call was embedded, Col to the associated column, 722868Speter * and LSeqid to the sequence id of the last symbol in the reduction 732868Speter * (Note that this is exact only if the last symbol was a terminal 742868Speter * this is always true when it matters.) 752868Speter */ 762868Speter int Seqid, Col, LSeqid; 772868Speter 782868Speter /* 792868Speter * Retrieve the information from a call to lineof before beginning the 802868Speter * output of a tree from a reduction. First flush to the left margin 812868Speter * of the production, and then set so that later calls to putcm, putcml 822868Speter * and putcmp will deal with the right margin of this comment. 832868Speter * 842868Speter * The routine setinfo is called when the lineof has no embedded line 852868Speter * number to avoid trashing the current "line". 862868Speter * 872868Speter * The routine setinfo is often called after completing the output of 882868Speter * the text of a tree to restore Seqid, Col, and LSeqid which may have 892868Speter * been destroyed by the nested processing calls to setline. 902868Speter * In this case the only effect of the call to setinfo is to 912868Speter * modify the above three variables as a side effect. 922868Speter * 932868Speter * We return a word giving information about the comments which were 942868Speter * actually put out. See putcm for details. 952868Speter */ 962868Speter setline(ip) 972868Speter int *ip; 982868Speter { 992868Speter 1002868Speter line = ip[0]; 1012868Speter return(setinfo(ip)); 1022868Speter } 1032868Speter 1042868Speter setinfo(ip) 1052868Speter register int *ip; 1062868Speter { 1072868Speter register int i; 1082868Speter 1092868Speter ip++; 1102868Speter Seqid = *ip++; 1112868Speter Col = *ip++; 1122868Speter i = putcm(); 1132868Speter Seqid = *ip++; 1142868Speter Col = *ip++; 1152868Speter LSeqid = *ip++; 1162868Speter return (i); 1172868Speter } 1182868Speter 1192868Speter char cmeof, incomm; 1202868Speter 1212868Speter /* 1222868Speter * Get the text of a comment from the input stream, 1232868Speter * recording its type and linking it into the linked 1242868Speter * list of comments headed by cmhp. 1252868Speter */ 1262868Speter getcm(cmdelim) 1272868Speter char cmdelim; 1282868Speter { 1292868Speter int cmjust, col; 1302868Speter register struct comment *cp; 1312868Speter register struct commline *kp; 1322868Speter 1332868Speter incomm = 1; 1342868Speter if (cmdelim == '*' && yycol == 10 || cmdelim == '{' && yycol == 9) 1352868Speter cmjust = CLMARG; 1362868Speter else if (yytokcnt <= 1) 1372868Speter cmjust = CALIGN; 1382868Speter else if (yywhcnt < 2) 1392868Speter cmjust = CTRAIL; 1402868Speter else 1412868Speter cmjust = CRMARG; 1422868Speter col = yycol - (cmdelim == '{' ? 1 : 2); 1432868Speter cp = tree5(NIL, cmdelim, NIL, cmjust, yyseqid); 1442868Speter cmeof = 0; 1452868Speter do { 1462868Speter kp = getcmline(cmdelim); 1472868Speter if (cp->cml == NIL) { 1482868Speter kp->cml = kp; 1492868Speter kp->cmcol = col; 1502868Speter } else { 1512868Speter kp->cml = cp->cml->cml; 1522868Speter cp->cml->cml = kp; 1532868Speter switch (cp->cmjust) { 1542868Speter case CTRAIL: 1552868Speter case CRMARG: 1562868Speter cp->cmjust = CALIGN; 1572868Speter } 1582868Speter } 1592868Speter cp->cml = kp; 1602868Speter } while (!cmeof); 1612868Speter newcomm(cp); 1622868Speter incomm = 0; 1632868Speter } 1642868Speter 1652868Speter /* 1662868Speter * Chain the new comment at "cp" onto the linked list of comments. 1672868Speter */ 1682868Speter newcomm(cp) 1692868Speter register struct comment *cp; 1702868Speter { 1712868Speter 1722868Speter if (cmhp == NIL) 1732868Speter cp->cmnext = cp; 1742868Speter else { 1752868Speter cp->cmnext = cmhp->cmnext; 1762868Speter cmhp->cmnext = cp; 1772868Speter } 1782868Speter cmhp = cp; 1792868Speter } 1802868Speter 1812868Speter 1822868Speter int nilcml[3]; 1832868Speter 1842868Speter quickcomm(t) 1852868Speter int t; 1862868Speter { 1872868Speter 1882868Speter if (incomm) 1892868Speter return; 1902868Speter newcomm(tree5(nilcml, NIL, NIL, t, yyseqid)); 1912868Speter } 1922868Speter 1932868Speter commincl(cp, ch) 1942868Speter char *cp, ch; 1952868Speter { 1962868Speter 1972868Speter newcomm(tree5(nilcml, savestr(cp), ch, CINCLUD, yyseqid)); 1982868Speter } 1992868Speter 2002868Speter getcmline(cmdelim) 2012868Speter char cmdelim; 2022868Speter { 2032868Speter char lastc; 2042868Speter register char *tp; 2052868Speter register CHAR c; 2062868Speter register struct commline *kp; 2072868Speter 2082868Speter c = readch(); 2092868Speter kp = tree3(NIL, yycol, NIL); 2102868Speter tp = token; 2112868Speter lastc = 0; 2122868Speter for (;;) { 2132868Speter switch (c) { 2142868Speter case '}': 2152868Speter if (cmdelim == '{') 2162868Speter goto endcm; 2172868Speter break; 2182868Speter case ')': 2192868Speter if (cmdelim == '*' && lastc == '*') { 2202868Speter --tp; 2212868Speter goto endcm; 2222868Speter } 2232868Speter break; 2242868Speter case '\n': 2252868Speter goto done; 2262868Speter case -1: 2272868Speter yerror("Comment does not terminate - QUIT"); 2282868Speter pexit(ERRS); 2292868Speter } 2302868Speter lastc = c; 2312868Speter *tp++ = c; 2322868Speter c = readch(); 2332868Speter } 2342868Speter endcm: 2352868Speter cmeof++; 2362868Speter done: 2372868Speter *tp = 0; 2382868Speter kp->cmtext = copystr(token); 2392868Speter return (kp); 2402868Speter } 2412868Speter 2422868Speter /* 2432868Speter * Flush through the line this token is on. 2442868Speter * Ignore if next token on same line as this one. 2452868Speter */ 2462868Speter putcml() 2472868Speter { 2482868Speter register int i, SSeqid, SCol; 2492868Speter 2502868Speter if (Seqid == LSeqid) 2512868Speter return (1); 2522868Speter SSeqid = Seqid, SCol = Col; 2532868Speter Seqid = LSeqid, Col = 32767; 2542868Speter i = putcm(); 2552868Speter Seqid = SSeqid, Col = SCol; 2562868Speter return (i); 2572868Speter } 2582868Speter 2592868Speter /* 2602868Speter * Flush to the beginning of the line this token is on. 2612868Speter * Ignore if this token is on the same line as the previous one 2622868Speter * (effectively since all such already then flushed.) 2632868Speter */ 2642868Speter putcmp() 2652868Speter { 2662868Speter register int i, SSeqid, SCol; 2672868Speter 2682868Speter SSeqid = Seqid, SCol = Col; 2692868Speter Seqid = LSeqid, Col = 0; 2702868Speter i = putcm(); 2712868Speter Seqid = SSeqid, Col = SCol; 2722868Speter return (i); 2732868Speter } 2742868Speter 2752868Speter /* 2762868Speter * Put out the comments to the border indicated by Seqid and Col 2772868Speter */ 2782868Speter putcm() 2792868Speter { 2802868Speter register struct comment *cp; 2812868Speter register int i; 2822868Speter 2832868Speter cp = cmhp; 2842868Speter if (cp == NIL) 2852868Speter return (0); 2862868Speter i = 0; 2872868Speter cp = cp->cmnext; 2882868Speter while (cp->cmseqid < Seqid || cp->cmseqid == Seqid && cp->cml->cmcol < Col) { 2892868Speter putone(cp); 29030650Slepreau i |= 1 << cp->cmjust; 2912868Speter if (cp->cmnext == cp) { 2922868Speter cmhp = NIL; 2932868Speter break; 2942868Speter } 2952868Speter cp = cp->cmnext; 2962868Speter cmhp->cmnext = cp; 2972868Speter } 2982868Speter return (i); 2992868Speter } 3002868Speter 3012868Speter /* 3022868Speter * Put out one comment. 3032868Speter * Note that empty lines, form feeds and #include statements 3042868Speter * are treated as comments are regurgitated here. 3052868Speter */ 3062868Speter putone(cp) 3072868Speter register struct comment *cp; 3082868Speter { 3092868Speter register struct commline *cml, *cmf; 3102868Speter 3112868Speter align(cp); 3122868Speter switch (cp->cmjust) { 3132868Speter case CINCLUD: 3142868Speter /* ppflush() */ 3152868Speter if (noinclude == 0) { 3162868Speter putchar('\f'); 3172868Speter return; 3182868Speter } 3192868Speter printf("#include %c%s%c", cp->cml, cp->cmdelim, cp->cml); 3202868Speter return; 3212868Speter } 3222868Speter if (stripcomm) 3232868Speter return; 3242868Speter switch (cp->cmjust) { 3252868Speter case CFORM: 3262868Speter ppop("\f"); 3272868Speter ppnl(); 3282868Speter case CNL: 3292868Speter case CNLBL: 3302868Speter return; 3312868Speter } 3322868Speter ppbra(cp->cmdelim == '{' ? "{" : "(*"); 3332868Speter cmf = cp->cml->cml; 3342868Speter ppid(cmf->cmtext); 3352868Speter for (cml = cmf->cml; cml != cmf; cml = cml->cml) { 3362868Speter align(cp); 3372868Speter oneline(cmf->cmcol, cml); 3382868Speter } 3392868Speter ppket(cp->cmdelim == '{' ? "}" : "*)"); 3402868Speter } 3412868Speter 3422868Speter /* 3432868Speter * Do the preliminary horizontal and vertical 3442868Speter * motions necessary before beginning a comment, 3452868Speter * or between lines of a mult-line comment. 3462868Speter */ 3472868Speter align(cp) 3482868Speter register struct comment *cp; 3492868Speter { 3502868Speter 3512868Speter switch (cp->cmjust) { 3522868Speter case CNL: 3532868Speter ppsnl(); 3542868Speter break; 3552868Speter case CNLBL: 3562868Speter ppsnlb(); 3572868Speter break; 3582868Speter case CFORM: 3592868Speter case CINCLUD: 3602868Speter ppnl(); 3612868Speter break; 3622868Speter case CLMARG: 3632868Speter ppnl(); 3642868Speter if (profile) 3652868Speter ppid("\t"); 3662868Speter break; 3672868Speter case CALIGN: 3682868Speter ppnl(); 3692868Speter indent(); 3702868Speter break; 3712868Speter case CTRAIL: 3722868Speter ppspac(); 3732868Speter break; 3742868Speter case CRMARG: 3752868Speter case CSRMARG: 3762868Speter pptab(); 3772868Speter break; 3782868Speter } 3792868Speter } 3802868Speter 3812868Speter /* 3822868Speter * One line of a multi-line comment 3832868Speter * Deal with alignment and initial white space trimming. 3842868Speter * The "margin" indicates where the first line of the 3852868Speter * comment began... don't print stuff in this comment 3862868Speter * which came before this. 3872868Speter */ 3882868Speter oneline(margin, cml) 3892868Speter int margin; 3902868Speter struct commline *cml; 3912868Speter { 3922868Speter register char *tp; 3932868Speter register int i; 3942868Speter 3952868Speter for (i = 8, tp = cml->cmtext; i < margin && *tp; tp++) 3962868Speter switch (*tp) { 3972868Speter case ' ': 3982868Speter i++; 3992868Speter continue; 4002868Speter case '\t': 40130650Slepreau i += 8; 40230650Slepreau i &= ~7; 4032868Speter if (i < margin) 4042868Speter continue; 4052868Speter ppop("\t"); 4062868Speter default: 4072868Speter goto out; 4082868Speter } 4092868Speter out: 4102868Speter ppid(tp); 4112868Speter } 4122868Speter 4132868Speter /* 4142868Speter * Flush all comments 4152868Speter */ 4162868Speter flushcm() 4172868Speter { 4182868Speter 4192868Speter Seqid = 32767; 4202868Speter return(putcm()); 4212868Speter } 4222868Speter 4232868Speter #define BLANKS ((1 << CNL) | (1 << CNLBL) | (1 << CFORM)) 4242868Speter noblank(i) 4252868Speter int i; 4262868Speter { 4272868Speter 4282868Speter return ((i & BLANKS) == 0); 4292868Speter } 4302868Speter 4312868Speter int needform, neednlbl, neednl, needseqid; 4322868Speter 4332868Speter needtree() 4342868Speter { 4352868Speter register struct comment *cp; 4362868Speter 4372868Speter needform = neednlbl = neednl = 0; 4382868Speter cp = cmhp; 4392868Speter if (cp == NIL) 4402868Speter return (0); 4412868Speter do { 4422868Speter switch (cp->cmjust) { 4432868Speter case CNL: 4442868Speter neednl++; 4452868Speter goto seq; 4462868Speter case CNLBL: 4472868Speter neednlbl++; 4482868Speter goto seq; 4492868Speter case CFORM: 4502868Speter needform++; 4512868Speter seq: 4522868Speter needseqid = cp->cmseqid; 4532868Speter break; 4542868Speter default: 4552868Speter neednl = neednlbl = needform = 0; 4562868Speter return (1); 4572868Speter } 4582868Speter cp = cp->cmnext; 4592868Speter } while (cp != cmhp); 4602868Speter cmhp = NIL; 4612868Speter return (0); 4622868Speter } 4632868Speter 4642868Speter packtree() 4652868Speter { 4662868Speter int save; 4672868Speter 4682868Speter save = yyseqid; 4692868Speter yyseqid = needseqid; 4702868Speter for (; needform > 0; needform--) 4712868Speter commform(); 4722868Speter for (; neednl > 0; neednl--) 4732868Speter commnl(); 4742868Speter for (; neednlbl > 0; neednlbl--) 4752868Speter commnlbl(); 4762868Speter yyseqid = save; 4772868Speter } 478