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