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