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

Defined functions

align defined in line 336; used 2 times
commincl defined in line 182; used 1 times
flushcm defined in line 405; used 1 times
getcm defined in line 115; used 2 times
getcmline defined in line 189; used 1 times
line2of defined in line 36; never used
lineNof defined in line 50; used 2 times
lineof defined in line 43; never used
needtree defined in line 422; used 1 times
newcomm defined in line 157; used 3 times
noblank defined in line 413; used 2 times
oneline defined in line 377; used 1 times
packtree defined in line 453; used 1 times
putcmp defined in line 253; used 1 times
putone defined in line 295; used 1 times
quickcomm defined in line 173; used 3 times

Defined variables

Col defined in line 65; used 9 times
LSeqid defined in line 65; used 4 times
Seqid defined in line 65; used 12 times
cmeof defined in line 108; used 3 times
incomm defined in line 108; used 3 times
needform defined in line 420; used 5 times
neednl defined in line 420; used 5 times
neednlbl defined in line 420; used 5 times
needseqid defined in line 420; used 2 times
nilcml defined in line 171; used 2 times

Defined macros

BLANKS defined in line 412; used 1 times
Last modified: 1986-06-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3360
Valid CSS Valid XHTML 1.0 Strict