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