|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: # ! 3: /* ! 4: * pi - Pascal interpreter code translator ! 5: * ! 6: * Charles Haley, Bill Joy UCB ! 7: * Version 1.2 January 1979 ! 8: * ! 9: * ! 10: * pxp - Pascal execution profiler ! 11: * ! 12: * Bill Joy UCB ! 13: * Version 1.2 January 1979 ! 14: */ ! 15: ! 16: #include "0.h" ! 17: #include "tree.h" ! 18: #include "yy.h" ! 19: ! 20: /* ! 21: * Structure describing queued listing lines during the forward move ! 22: * of error recovery. These lines will be stroed by yyoutline during ! 23: * the forward move and flushed by yyoutfl or yyflush when an ! 24: * error occurs or a program termination. ! 25: */ ! 26: struct B { ! 27: int Bmagic; ! 28: int Bline; ! 29: int Bseekp; ! 30: char *Bfile; ! 31: int Bseqid; ! 32: struct B *Bnext; ! 33: } *bottled; ! 34: ! 35: /* ! 36: * Filename gives the current input file, lastname is ! 37: * the last filename we printed, and lastid is the seqid of the last line ! 38: * we printed, to help us avoid printing ! 39: * multiple copies of lines. ! 40: */ ! 41: extern char *filename; ! 42: char *lastname; ! 43: int lastid; ! 44: ! 45: char hadsome; ! 46: char holdbl; ! 47: ! 48: /* ! 49: * Print the current line in the input line ! 50: * buffer or, in a forward move of the recovery, queue it for printing. ! 51: */ ! 52: yyoutline() ! 53: { ! 54: register struct B *bp; ! 55: ! 56: if (Recovery) { ! 57: bp = tree(6, T_BOTTLE, yyline, yylinpt, filename, yyseqid); ! 58: if (bottled != NIL) ! 59: bp->Bnext = bottled->Bnext, bottled->Bnext = bp; ! 60: else ! 61: bp->Bnext = bp; ! 62: bottled = bp; ! 63: return; ! 64: } ! 65: yyoutfl(yyseqid); ! 66: if (yyseqid != lastid) ! 67: yyprline(charbuf, yyline, filename, yyseqid); ! 68: } ! 69: ! 70: /* ! 71: * Flush all the bottled output. ! 72: */ ! 73: yyflush() ! 74: { ! 75: ! 76: yyoutfl(32767); ! 77: } ! 78: ! 79: /* ! 80: * Flush the listing to the sequence id toseqid ! 81: */ ! 82: yyoutfl(toseqid) ! 83: int toseqid; ! 84: { ! 85: register struct B *bp; ! 86: ! 87: bp = bottled; ! 88: if (bp == NIL) ! 89: return; ! 90: bp = bp->Bnext; ! 91: while (bp->Bseqid <= toseqid) { ! 92: yygetline(bp->Bfile, bp->Bseekp, bp->Bline, bp->Bseqid); ! 93: if (bp->Bnext == bp) { ! 94: bottled = NIL; ! 95: break; ! 96: } ! 97: bp = bp->Bnext; ! 98: bottled->Bnext = bp; ! 99: } ! 100: } ! 101: ! 102: int yygetunit -1; ! 103: char *yygetfile; ! 104: ! 105: /* ! 106: * Yysync guarantees that the line associated ! 107: * with the current token was the last line ! 108: * printed for a syntactic error message. ! 109: */ ! 110: yysync() ! 111: { ! 112: ! 113: yyoutfl(yyeseqid); ! 114: if (lastid != yyeseqid) ! 115: yygetline(yyefile, yyseekp, yyeline, yyeseqid); ! 116: } ! 117: ! 118: yySsync() ! 119: { ! 120: ! 121: yyoutfl(OY.Yyeseqid); ! 122: } ! 123: ! 124: /* ! 125: * Yygetline gets a line from a file after we have ! 126: * lost it. The pointer efile gives the name of the file, ! 127: * seekp its offset in the file, and eline its line number. ! 128: * If this routine has been called before the last file ! 129: * it worked on will be open in yygetunit, with the files ! 130: * name being given in yygetfile. Note that this unit must ! 131: * be opened independently of the unit in use for normal i/o ! 132: * to this file; if it were a dup seeks would seek both files. ! 133: */ ! 134: yygetline(efile, seekp, eline, eseqid) ! 135: char *efile; ! 136: int seekp, eline, eseqid; ! 137: { ! 138: register int cnt; ! 139: register char *bp; ! 140: char buf[CBSIZE + 1]; ! 141: ! 142: if (lastid == eseqid) ! 143: return; ! 144: if (eseqid == yyseqid) { ! 145: bp = charbuf; ! 146: yyprtd++; ! 147: } else { ! 148: bp = buf; ! 149: if (efile != yygetfile) { ! 150: close(yygetunit); ! 151: yygetfile = efile; ! 152: yygetunit = open(yygetfile, 0); ! 153: if (yygetunit < 0) ! 154: oops: ! 155: perror(yygetfile), pexit(DIED); ! 156: } ! 157: if (lseek(yygetunit, (long)seekp, 0) < 0) ! 158: goto oops; ! 159: cnt = read(yygetunit, bp, CBSIZE); ! 160: if (cnt < 0) ! 161: goto oops; ! 162: bp[cnt] = 0; ! 163: } ! 164: yyprline(bp, eline, efile, eseqid); ! 165: } ! 166: ! 167: yyretrieve() ! 168: { ! 169: ! 170: yygetline(OY.Yyefile, OY.Yyseekp, OY.Yyeline, OY.Yyeseqid); ! 171: } ! 172: ! 173: /* ! 174: * Print the line in the character buffer which has ! 175: * line number line. The buffer may be terminated by a new ! 176: * line character or a null character. We process ! 177: * form feed directives, lines with only a form feed character, and ! 178: * suppress numbering lines which are empty here. ! 179: */ ! 180: yyprline(buf, line, file, id) ! 181: register char *buf; ! 182: int line; ! 183: char *file; ! 184: int id; ! 185: { ! 186: ! 187: lastid = id; ! 188: if (buf[0] == '\f' && buf[1] == '\n') { ! 189: printf("\f\n"); ! 190: hadsome = 0; ! 191: holdbl = 0; ! 192: return; ! 193: } ! 194: if (holdbl) { ! 195: putchar('\n'); ! 196: holdbl = 0; ! 197: } ! 198: if (buf[0] == '\n') ! 199: holdbl = 1; ! 200: else { ! 201: yysetfile(file); ! 202: yyprintf(buf, line); ! 203: } ! 204: hadsome = 1; ! 205: } ! 206: ! 207: yyprintf(cp, line) ! 208: register char *cp; ! 209: int line; ! 210: { ! 211: ! 212: printf("%6d ", line); ! 213: while (*cp != 0 && *cp != '\n') ! 214: putchar(graphic(*cp++)); ! 215: putchar('\n'); ! 216: } ! 217: ! 218: graphic(ch) ! 219: register CHAR ch; ! 220: { ! 221: ! 222: switch (ch) { ! 223: default: ! 224: if (ch >= ' ') ! 225: return (ch); ! 226: case 0177: ! 227: return ('?'); ! 228: case '\n': ! 229: case '\t': ! 230: return (ch); ! 231: } ! 232: } ! 233: ! 234: extern int nopflg; ! 235: ! 236: char printed 1; ! 237: /* ! 238: * Set the current file name to be file, ! 239: * printing the name, or a header on a new ! 240: * page if required. ! 241: */ ! 242: yysetfile(file) ! 243: register char *file; ! 244: { ! 245: ! 246: #ifdef PXP ! 247: if (nopflg == 1) ! 248: return; ! 249: #endif ! 250: ! 251: if (lastname == file) ! 252: return; ! 253: if (file == filename && opt('n') && (printed & 02) == 0) { ! 254: printed =| 02; ! 255: header(); ! 256: } else ! 257: yyputfn(file); ! 258: lastname = file; ! 259: } ! 260: ! 261: /* ! 262: * Put out an include file name ! 263: * if an error occurs but the name has ! 264: * not been printed (or if another name ! 265: * has been printed since it has). ! 266: */ ! 267: yyputfn(cp) ! 268: register char *cp; ! 269: { ! 270: extern int outcol; ! 271: ! 272: if (cp == lastname && printed) ! 273: return; ! 274: lastname = cp; ! 275: printed = 1; ! 276: #ifdef PXP ! 277: if (outcol) ! 278: putchar('\n'); ! 279: #endif ! 280: printf("%s:\n", cp); ! 281: hadsome = 1; ! 282: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.