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