xref: /csrg-svn/usr.bin/pascal/pxp/yyput.c (revision 30650)
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