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