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