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