148112Sbostic /*-
2*62195Sbostic * Copyright (c) 1980, 1993
3*62195Sbostic * The Regents of the University of California. All rights reserved.
448112Sbostic *
548112Sbostic * %sccs.include.redist.c%
622246Sdist */
722246Sdist
822246Sdist #ifndef lint
9*62195Sbostic static char sccsid[] = "@(#)yyput.c 8.1 (Berkeley) 06/06/93";
1048112Sbostic #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 */
yyoutline()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 */
yyflush()832871Speter yyflush()
842871Speter {
852871Speter
862871Speter yyoutfl(32767);
872871Speter }
882871Speter
892871Speter /*
902871Speter * Flush the listing to the sequence id toseqid
912871Speter */
yyoutfl(toseqid)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 */
yysync()1202871Speter yysync()
1212871Speter {
1222871Speter
1232871Speter yyoutfl(yyeseqid);
1242871Speter if (lastid != yyeseqid)
1252871Speter yygetline(yyefile, yyseekp, yyeline, yyeseqid);
1262871Speter }
1272871Speter
yySsync()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 */
yygetline(efile,seekp,eline,eseqid)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
yyretrieve()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 */
yyprline(buf,line,file,id)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
yyprintf(cp,line)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
graphic(ch)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 */
yysetfile(file)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 */
yyputfn(cp)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