1*48112Sbostic /*- 2*48112Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48112Sbostic * All rights reserved. 4*48112Sbostic * 5*48112Sbostic * %sccs.include.redist.c% 622246Sdist */ 722246Sdist 822246Sdist #ifndef lint 9*48112Sbostic static char sccsid[] = "@(#)yyput.c 5.3 (Berkeley) 04/16/91"; 10*48112Sbostic #endif /* not lint */ 1122246Sdist 1222246Sdist /* 132871Speter * pi - Pascal interpreter code translator 142871Speter * 152871Speter * Charles Haley, Bill Joy UCB 162871Speter * Version 1.2 January 1979 172871Speter * 182871Speter * 192871Speter * pxp - Pascal execution profiler 202871Speter * 212871Speter * Bill Joy UCB 222871Speter * Version 1.2 January 1979 232871Speter */ 242871Speter 2512391Speter #include "whoami.h" 262871Speter #include "0.h" 272871Speter #include "tree.h" 282871Speter #include "yy.h" 292871Speter 302871Speter /* 312871Speter * Structure describing queued listing lines during the forward move 322871Speter * of error recovery. These lines will be stroed by yyoutline during 332871Speter * the forward move and flushed by yyoutfl or yyflush when an 342871Speter * error occurs or a program termination. 352871Speter */ 362871Speter struct B { 372871Speter int Bmagic; 382871Speter int Bline; 392871Speter int Bseekp; 402871Speter char *Bfile; 412871Speter int Bseqid; 422871Speter struct B *Bnext; 432871Speter } *bottled; 442871Speter 452871Speter /* 462871Speter * Filename gives the current input file, lastname is 472871Speter * the last filename we printed, and lastid is the seqid of the last line 482871Speter * we printed, to help us avoid printing 492871Speter * multiple copies of lines. 502871Speter */ 512871Speter extern char *filename; 522871Speter char *lastname; 532871Speter int lastid; 542871Speter 552871Speter char hadsome; 562871Speter char holdbl; 572871Speter 582871Speter /* 592871Speter * Print the current line in the input line 602871Speter * buffer or, in a forward move of the recovery, queue it for printing. 612871Speter */ 622871Speter yyoutline() 632871Speter { 642871Speter register struct B *bp; 652871Speter 662871Speter if (Recovery) { 672871Speter bp = tree(6, T_BOTTLE, yyline, yylinpt, filename, yyseqid); 682871Speter if (bottled != NIL) 692871Speter bp->Bnext = bottled->Bnext, bottled->Bnext = bp; 702871Speter else 712871Speter bp->Bnext = bp; 722871Speter bottled = bp; 732871Speter return; 742871Speter } 752871Speter yyoutfl(yyseqid); 762871Speter if (yyseqid != lastid) 772871Speter yyprline(charbuf, yyline, filename, yyseqid); 782871Speter } 792871Speter 802871Speter /* 812871Speter * Flush all the bottled output. 822871Speter */ 832871Speter yyflush() 842871Speter { 852871Speter 862871Speter yyoutfl(32767); 872871Speter } 882871Speter 892871Speter /* 902871Speter * Flush the listing to the sequence id toseqid 912871Speter */ 922871Speter yyoutfl(toseqid) 932871Speter int toseqid; 942871Speter { 952871Speter register struct B *bp; 962871Speter 972871Speter bp = bottled; 982871Speter if (bp == NIL) 992871Speter return; 1002871Speter bp = bp->Bnext; 1012871Speter while (bp->Bseqid <= toseqid) { 1022871Speter yygetline(bp->Bfile, bp->Bseekp, bp->Bline, bp->Bseqid); 1032871Speter if (bp->Bnext == bp) { 1042871Speter bottled = NIL; 1052871Speter break; 1062871Speter } 1072871Speter bp = bp->Bnext; 1082871Speter bottled->Bnext = bp; 1092871Speter } 1102871Speter } 1112871Speter 1123055Smckusic int yygetunit = -1; 1132871Speter char *yygetfile; 1142871Speter 1152871Speter /* 1162871Speter * Yysync guarantees that the line associated 1172871Speter * with the current token was the last line 1182871Speter * printed for a syntactic error message. 1192871Speter */ 1202871Speter yysync() 1212871Speter { 1222871Speter 1232871Speter yyoutfl(yyeseqid); 1242871Speter if (lastid != yyeseqid) 1252871Speter yygetline(yyefile, yyseekp, yyeline, yyeseqid); 1262871Speter } 1272871Speter 1282871Speter yySsync() 1292871Speter { 1302871Speter 1312871Speter yyoutfl(OY.Yyeseqid); 1322871Speter } 1332871Speter 1342871Speter /* 1352871Speter * Yygetline gets a line from a file after we have 1362871Speter * lost it. The pointer efile gives the name of the file, 1372871Speter * seekp its offset in the file, and eline its line number. 1382871Speter * If this routine has been called before the last file 1392871Speter * it worked on will be open in yygetunit, with the files 1402871Speter * name being given in yygetfile. Note that this unit must 1412871Speter * be opened independently of the unit in use for normal i/o 1422871Speter * to this file; if it were a dup seeks would seek both files. 1432871Speter */ 1442871Speter yygetline(efile, seekp, eline, eseqid) 1452871Speter char *efile; 1462871Speter int seekp, eline, eseqid; 1472871Speter { 1482871Speter register int cnt; 1492871Speter register char *bp; 1502871Speter char buf[CBSIZE + 1]; 1512871Speter 1522871Speter if (lastid == eseqid) 1532871Speter return; 1542871Speter if (eseqid == yyseqid) { 1552871Speter bp = charbuf; 1562871Speter yyprtd++; 1572871Speter } else { 1582871Speter bp = buf; 1592871Speter if (efile != yygetfile) { 1602871Speter close(yygetunit); 1612871Speter yygetfile = efile; 1622871Speter yygetunit = open(yygetfile, 0); 1632871Speter if (yygetunit < 0) 1642871Speter oops: 1652871Speter perror(yygetfile), pexit(DIED); 1662871Speter } 1672871Speter if (lseek(yygetunit, (long)seekp, 0) < 0) 1682871Speter goto oops; 1692871Speter cnt = read(yygetunit, bp, CBSIZE); 1702871Speter if (cnt < 0) 1712871Speter goto oops; 1722871Speter bp[cnt] = 0; 1732871Speter } 1742871Speter yyprline(bp, eline, efile, eseqid); 1752871Speter } 1762871Speter 1772871Speter yyretrieve() 1782871Speter { 1792871Speter 1802871Speter yygetline(OY.Yyefile, OY.Yyseekp, OY.Yyeline, OY.Yyeseqid); 1812871Speter } 1822871Speter 1832871Speter /* 1842871Speter * Print the line in the character buffer which has 1852871Speter * line number line. The buffer may be terminated by a new 1862871Speter * line character or a null character. We process 1872871Speter * form feed directives, lines with only a form feed character, and 1882871Speter * suppress numbering lines which are empty here. 1892871Speter */ 1902871Speter yyprline(buf, line, file, id) 1912871Speter register char *buf; 1922871Speter int line; 1932871Speter char *file; 1942871Speter int id; 1952871Speter { 1962871Speter 1972871Speter lastid = id; 1982871Speter if (buf[0] == '\f' && buf[1] == '\n') { 1992871Speter printf("\f\n"); 2002871Speter hadsome = 0; 2012871Speter holdbl = 0; 2022871Speter return; 2032871Speter } 2042871Speter if (holdbl) { 2052871Speter putchar('\n'); 2062871Speter holdbl = 0; 2072871Speter } 2082871Speter if (buf[0] == '\n') 2092871Speter holdbl = 1; 2102871Speter else { 2112871Speter yysetfile(file); 2122871Speter yyprintf(buf, line); 2132871Speter } 2142871Speter hadsome = 1; 2152871Speter } 2162871Speter 2172871Speter yyprintf(cp, line) 2182871Speter register char *cp; 2192871Speter int line; 2202871Speter { 2212871Speter 2222871Speter printf("%6d ", line); 2232871Speter while (*cp != 0 && *cp != '\n') 2242871Speter putchar(graphic(*cp++)); 2252871Speter putchar('\n'); 2262871Speter } 2272871Speter 2282871Speter graphic(ch) 2292871Speter register CHAR ch; 2302871Speter { 2312871Speter 2322871Speter switch (ch) { 2332871Speter default: 2342871Speter if (ch >= ' ') 2352871Speter return (ch); 2362871Speter case 0177: 2372871Speter return ('?'); 2382871Speter case '\n': 2392871Speter case '\t': 2402871Speter return (ch); 2412871Speter } 2422871Speter } 2432871Speter 2442871Speter extern int nopflg; 2452871Speter 2463055Smckusic char printed = 1; 2472871Speter /* 2482871Speter * Set the current file name to be file, 2492871Speter * printing the name, or a header on a new 2502871Speter * page if required. 2512871Speter */ 2522871Speter yysetfile(file) 2532871Speter register char *file; 2542871Speter { 2552871Speter 2562871Speter #ifdef PXP 2572871Speter if (nopflg == 1) 2582871Speter return; 2592871Speter #endif 2602871Speter 2612871Speter if (lastname == file) 2622871Speter return; 2632871Speter if (file == filename && opt('n') && (printed & 02) == 0) { 26430650Slepreau printed |= 02; 2652871Speter header(); 2662871Speter } else 2672871Speter yyputfn(file); 2682871Speter lastname = file; 2692871Speter } 2702871Speter 2712871Speter /* 2722871Speter * Put out an include file name 2732871Speter * if an error occurs but the name has 2742871Speter * not been printed (or if another name 2752871Speter * has been printed since it has). 2762871Speter */ 2772871Speter yyputfn(cp) 2782871Speter register char *cp; 2792871Speter { 2802871Speter extern int outcol; 2812871Speter 2822871Speter if (cp == lastname && printed) 2832871Speter return; 2842871Speter lastname = cp; 2852871Speter printed = 1; 2862871Speter #ifdef PXP 2872871Speter if (outcol) 2882871Speter putchar('\n'); 2892871Speter #endif 2902871Speter printf("%s:\n", cp); 2912871Speter hadsome = 1; 2922871Speter } 293