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