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