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