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