1*48116Sbostic /*- 2*48116Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48116Sbostic * All rights reserved. 4*48116Sbostic * 5*48116Sbostic * %sccs.include.redist.c% 622213Sdist */ 7793Speter 814748Sthien #ifndef lint 9*48116Sbostic static char sccsid[] = "@(#)yyput.c 5.3 (Berkeley) 04/16/91"; 10*48116Sbostic #endif /* not lint */ 11793Speter 12793Speter #include "whoami.h" 13793Speter #include "0.h" 14793Speter #include "tree.h" 1514748Sthien #include "tree_ty.h" /* must be included for yy.h */ 16793Speter #include "yy.h" 17793Speter 18793Speter /* 19793Speter * Structure describing queued listing lines during the forward move 20793Speter * of error recovery. These lines will be stroed by yyoutline during 21793Speter * the forward move and flushed by yyoutfl or yyflush when an 22793Speter * error occurs or a program termination. 23793Speter */ 24793Speter struct B { 25793Speter int Bmagic; 26793Speter int Bline; 27793Speter int Bseekp; 28793Speter char *Bfile; 29793Speter int Bseqid; 30793Speter struct B *Bnext; 31793Speter } *bottled; 32793Speter 33793Speter /* 34793Speter * Filename gives the current input file, lastname is 35793Speter * the last filename we printed, and lastid is the seqid of the last line 36793Speter * we printed, to help us avoid printing 37793Speter * multiple copies of lines. 38793Speter */ 39793Speter extern char *filename; 40793Speter char *lastname; 41793Speter int lastid; 42793Speter 43793Speter char hadsome; 44793Speter char holdbl; 45793Speter 46793Speter /* 47793Speter * Print the current line in the input line 48793Speter * buffer or, in a forward move of the recovery, queue it for printing. 49793Speter */ 50793Speter yyoutline() 51793Speter { 52793Speter register struct B *bp; 53793Speter 54793Speter if (Recovery) { 5514748Sthien bp = (struct B *) tree(6, T_BOTTLE, yyline, yylinpt, filename, 5614748Sthien yyseqid); 57793Speter if (bottled != NIL) 58793Speter bp->Bnext = bottled->Bnext, bottled->Bnext = bp; 59793Speter else 60793Speter bp->Bnext = bp; 61793Speter bottled = bp; 62793Speter return; 63793Speter } 64793Speter yyoutfl(yyseqid); 65793Speter if (yyseqid != lastid) 66793Speter yyprline(charbuf, yyline, filename, yyseqid); 67793Speter } 68793Speter 69793Speter /* 70793Speter * Flush all the bottled output. 71793Speter */ 72793Speter yyflush() 73793Speter { 74793Speter 75793Speter yyoutfl(32767); 76793Speter } 77793Speter 78793Speter /* 79793Speter * Flush the listing to the sequence id toseqid 80793Speter */ 81793Speter yyoutfl(toseqid) 82793Speter int toseqid; 83793Speter { 84793Speter register struct B *bp; 85793Speter 86793Speter bp = bottled; 87793Speter if (bp == NIL) 88793Speter return; 89793Speter bp = bp->Bnext; 90793Speter while (bp->Bseqid <= toseqid) { 91793Speter yygetline(bp->Bfile, bp->Bseekp, bp->Bline, bp->Bseqid); 92793Speter if (bp->Bnext == bp) { 93793Speter bottled = NIL; 94793Speter break; 95793Speter } 96793Speter bp = bp->Bnext; 97793Speter bottled->Bnext = bp; 98793Speter } 99793Speter } 100793Speter 101793Speter FILE *yygetunit = NULL; 102793Speter char *yygetfile; 103793Speter 104793Speter /* 105793Speter * Yysync guarantees that the line associated 106793Speter * with the current token was the last line 107793Speter * printed for a syntactic error message. 108793Speter */ 109793Speter yysync() 110793Speter { 111793Speter 112793Speter yyoutfl(yyeseqid); 113793Speter if (lastid != yyeseqid) 114793Speter yygetline(yyefile, yyseekp, yyeline, yyeseqid); 115793Speter } 116793Speter 117793Speter yySsync() 118793Speter { 119793Speter 120793Speter yyoutfl(OY.Yyeseqid); 121793Speter } 122793Speter 123793Speter /* 124793Speter * Yygetline gets a line from a file after we have 125793Speter * lost it. The pointer efile gives the name of the file, 126793Speter * seekp its offset in the file, and eline its line number. 127793Speter * If this routine has been called before the last file 128793Speter * it worked on will be open in yygetunit, with the files 129793Speter * name being given in yygetfile. Note that this unit must 130793Speter * be opened independently of the unit in use for normal i/o 131793Speter * to this file; if it were a dup seeks would seek both files. 132793Speter */ 133793Speter yygetline(efile, seekp, eline, eseqid) 134793Speter char *efile; 135793Speter int seekp, eline, eseqid; 136793Speter { 137793Speter register int cnt; 138793Speter register char *bp; 139793Speter char buf[CBSIZE + 1]; 140793Speter 141793Speter if (lastid == eseqid) 142793Speter return; 143793Speter if (eseqid == yyseqid) { 144793Speter bp = charbuf; 145793Speter yyprtd++; 146793Speter } else { 147793Speter bp = buf; 148793Speter if (efile != yygetfile) { 149793Speter if ( yygetunit != NULL ) 15014748Sthien (void) fclose( yygetunit ); 151793Speter yygetfile = efile; 152793Speter yygetunit = fopen( yygetfile , "r" ); 15335694Sbostic if (yygetunit == 0) 154793Speter oops: 155793Speter perror(yygetfile), pexit(DIED); 156793Speter } 157793Speter if ( fseek( yygetunit , (long) seekp , 0 ) < 0) 158793Speter goto oops; 159793Speter cnt = fread( bp , sizeof( * bp ) , CBSIZE , yygetunit ); 160793Speter if (cnt < 0) 161793Speter goto oops; 162793Speter bp[cnt] = 0; 163793Speter } 164793Speter yyprline(bp, eline, efile, eseqid); 165793Speter } 166793Speter 167793Speter yyretrieve() 168793Speter { 169793Speter 170793Speter yygetline(OY.Yyefile, OY.Yyseekp, OY.Yyeline, OY.Yyeseqid); 171793Speter } 172793Speter 173793Speter /* 174793Speter * Print the line in the character buffer which has 175793Speter * line number line. The buffer may be terminated by a new 176793Speter * line character or a null character. We process 177793Speter * form feed directives, lines with only a form feed character, and 178793Speter * suppress numbering lines which are empty here. 179793Speter */ 180793Speter yyprline(buf, line, file, id) 181793Speter register char *buf; 182793Speter int line; 183793Speter char *file; 184793Speter int id; 185793Speter { 186793Speter 187793Speter lastid = id; 188793Speter if (buf[0] == '\f' && buf[1] == '\n') { 189793Speter printf("\f\n"); 190793Speter hadsome = 0; 191793Speter holdbl = 0; 192793Speter return; 193793Speter } 194793Speter if (holdbl) { 195793Speter pchr('\n'); 196793Speter holdbl = 0; 197793Speter } 198793Speter if (buf[0] == '\n') 199793Speter holdbl = 1; 200793Speter else { 201793Speter yysetfile(file); 202793Speter yyprintf(buf, line); 203793Speter } 204793Speter hadsome = 1; 205793Speter } 206793Speter 207793Speter yyprintf(cp, line) 208793Speter register char *cp; 209793Speter int line; 210793Speter { 211793Speter 212793Speter printf("%6d ", line); 213793Speter while (*cp != 0 && *cp != '\n') 214793Speter pchr(graphic(*cp++)); 215793Speter pchr('\n'); 216793Speter } 217793Speter 218793Speter graphic(ch) 219793Speter register CHAR ch; 220793Speter { 221793Speter 222793Speter switch (ch) { 223793Speter default: 224793Speter if (ch >= ' ') 225793Speter return (ch); 226793Speter case 0177: 227793Speter return ('?'); 228793Speter case '\n': 229793Speter case '\t': 230793Speter return (ch); 231793Speter } 232793Speter } 233793Speter 234793Speter extern int nopflg; 235793Speter 2363087Smckusic char printed = 1; 237793Speter /* 238793Speter * Set the current file name to be file, 239793Speter * printing the name, or a header on a new 240793Speter * page if required. 241793Speter * there is another yysetfile in error.c 242793Speter * this one is for PI and PXP that one is for PI1 243793Speter */ 244793Speter yysetfile(file) 245793Speter register char *file; 246793Speter { 247793Speter 248793Speter #ifdef PXP 249793Speter if (nopflg == 1) 250793Speter return; 251793Speter #endif 252793Speter 253793Speter if (lastname == file) 254793Speter return; 255793Speter if (file == filename && opt('n') && (printed & 02) == 0) { 2563087Smckusic printed |= 02; 257793Speter header(); 258793Speter } else 259793Speter yyputfn(file); 260793Speter lastname = file; 261793Speter } 262793Speter 263793Speter /* 264793Speter * Put out an include file name 265793Speter * if an error occurs but the name has 266793Speter * not been printed (or if another name 267793Speter * has been printed since it has). 268793Speter */ 269793Speter yyputfn(cp) 270793Speter register char *cp; 271793Speter { 272793Speter extern int outcol; 273793Speter 274793Speter if (cp == lastname && printed) 275793Speter return; 276793Speter lastname = cp; 277793Speter printed = 1; 278793Speter #ifdef PXP 279793Speter if (outcol) 280793Speter pchr('\n'); 281793Speter #endif 282793Speter gettime( cp ); 28314748Sthien printf("%s %s:\n" , myctime( (int *) (&tvec) ) , cp ); 284793Speter hadsome = 1; 285793Speter } 286