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