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