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

Defined functions

align defined in line 346; used 2 times
commincl defined in line 192; never used
flushcm defined in line 415; used 1 times
getcm defined in line 125; never used
getcmline defined in line 199; used 1 times
line2of defined in line 46; never used
lineNof defined in line 60; used 2 times
lineof defined in line 53; never used
needtree defined in line 432; never used
newcomm defined in line 167; used 3 times
noblank defined in line 423; used 2 times
oneline defined in line 387; used 1 times
packtree defined in line 463; never used
putcmp defined in line 263; used 1 times
putone defined in line 305; used 1 times
quickcomm defined in line 183; never used

Defined variables

Col defined in line 75; used 9 times
LSeqid defined in line 75; used 4 times
Seqid defined in line 75; used 12 times
cmeof defined in line 118; used 3 times
incomm defined in line 118; used 3 times
needform defined in line 430; used 5 times
neednl defined in line 430; used 5 times
neednlbl defined in line 430; used 5 times
needseqid defined in line 430; used 2 times
nilcml defined in line 181; used 2 times
sccsid defined in line 8; never used

Defined macros

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