File:  [MW Coherent from dump] / coherent / d / bin / nroff / div.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:39 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * div.c
 * Nroff/Troff.
 * Traps and diversions.
 */

#include "roff.h"

/*
 * Given a name, create and initialize a new diversion.
 * For troff, the processed text in the diversion assumes the current font;
 * if the current font is different when the diversion is read back (executed),
 * the character widths will be wrong.
 * Therefore the diversion starts with a font change to the current font.
 */
newdivn(name)
char name[2];
{
	register DIV *dp;

	dp = (DIV *) nalloc(sizeof (DIV));
	dp->d_next = cdivp;
	dp->d_name[0] = name[0];
	dp->d_name[1] = name[1];
	dp->d_rpos = 0;
	dp->d_nspm = 0;
	dp->d_maxh = 0;
	dp->d_maxw = 0;
	dp->d_seek = tmpseek;
	dp->d_macp = NULL;
	dp->d_stpl = NULL;
	dp->d_trap = NULL;
	dp->d_ctpp = NULL;
	cdivp = dp;
	if (name[0] != '\0')
		dev_font(curfont);
	dprint3(DBGDIVR, "create diversion %c%c\n", name[0], name[1]);
}

/*
 * End a diversion.
 * The diverted text may have changed the current font,
 * but because it was diverted the output writer's notion of the current
 * font remains unchanged.
 * Therefore this writes a change to the current font after the diversion.
 */
enddivn()
{
	register REG *rp;
	register DIV *dp;

	if ((dp = cdivp) == mdivp) {
		printe("cannot end diversion");
		return;
	}
	if ((rp = findreg(dp->d_name, RTEXT)) != (REG *)NULL) {
		rp->t_reg.r_maxh = cdivp->d_maxh;
		rp->t_reg.r_maxw = cdivp->d_maxw;
	}
	nrdnreg->n_reg.r_nval = cdivp->d_maxh;
	nrdlreg->n_reg.r_nval = cdivp->d_maxw;
	cdivp = cdivp->d_next;
	dprint3(DBGDIVR, "ended diversion %c%c\n", dp->d_name[0], dp->d_name[1]);
	nfree((char *)dp);
	dev_font(curfont);
}

/*
 * Append the given buffer onto the end of the current diversion.
 */
flushd(buffer, bufend)
CODE *buffer, *bufend;
{
	register DIV *dp;
	register MAC *mp;
	register unsigned n;

	if((dp = cdivp) == NULL)
		panic("flushd -- current diversion null");
	dprint3(DBGDIVR, "flushing diversion %c%c\n", dp->d_name[0], dp->d_name[1]);
	mp = dp->d_macp;
	if (mp->t_div.m_type!=MDIVN || dp->d_seek!=tmpseek) {
		dp->d_macp = dp->d_macp->t_div.m_next = mp = 
			(MAC *)nalloc(sizeof *mp);
		mp->t_div.m_next = NULL;
		mp->t_div.m_type = MDIVN;
		mp->t_div.m_size = 0;
		mp->t_div.m_core = NULL;
		mp->t_div.m_seek = tmpseek;
	}
	n = bufend - buffer;
	nwrite((char *)buffer, (unsigned)sizeof (CODE), n);
	mp->t_div.m_size += n;
	dp->d_seek = tmpseek;
	if ((n=tmpseek%DBFSIZE) != 0)
		nwrite(miscbuf, 1, DBFSIZE-n);
}

/*
 * Space the required distance after a line has been put out.
 * If we sprung a trap, execute it.
 */
lspace(n)
{
	register DIV *dp;
	register TPL *tp;

#if	0
	fprintf(stderr, "lspace(%d)\n", n);
#endif
	dp = cdivp;
	tp = dp->d_ctpp;
	if (tp!=NULL && dp->d_rpos+n<tp->t_apos)
		tp = NULL;
	scroll(dp, n);
	if (tp != NULL)
		execute(tp->t_name);
}

/*
 * Space to the end of the current page.
 */
pspace()
{
	register DIV *dp;
	register TPL *tp;
	int lpct;
	register int npos;

#if	0
	fprintf(stderr, "pspace()\n");
#endif
	dp = mdivp;
	lpct = pct;
	while (lpct == pct) {
		npos = pgl;
		tp = dp->d_ctpp;
		if (tp!=NULL && npos>=tp->t_apos)
			npos = tp->t_apos;
		if (mdivp==dp && npos>=pgl) {
			scroll(dp, (int)pgl-dp->d_rpos);
			npos = dp->d_rpos;
			tp = dp->d_trap;
		}
		scroll(dp, npos-dp->d_rpos);
		if (tp!=NULL && dp->d_rpos==tp->t_apos)
			execute(tp->t_name);
	}
}

/*
 * Space the distance 'n'.  If a trap is encountered, spring the
 * trap and stop.
 */
sspace(n)
{
	register DIV *dp;
	register TPL *tp;
	register int npos;

#if	0
	fprintf(stderr, "sspace(%d)\n", n);
#endif
	dp = cdivp;
	tp = dp->d_ctpp;
	npos = dp->d_rpos + n;
	if (npos < 0)
		npos = 0;
	if (tp!=NULL && npos>=tp->t_apos)
		npos = tp->t_apos;
	if (mdivp==dp && npos>=pgl) {
		scroll(dp, (int)pgl-dp->d_rpos);
		npos = dp->d_rpos;
		tp = dp->d_trap;
	}
	scroll(dp, npos-dp->d_rpos);
	if (tp!=NULL && dp->d_rpos==tp->t_apos)
		execute(tp->t_name);
}

/*
 * Space down the given distance, resetting page information
 * if we pass a page boundary.  'dp' is a pointer to the
 * diversion we are using.
 */
scroll(dp, n)
register DIV *dp;
{
	CODE code[1];
	register TPL *tp;
	char *s;

#if	0
	fprintf(stderr, "scroll(..., %d)\n", n);
#endif
	code[0].l_arg.c_code = DSPAR;
	code[0].l_arg.c_iarg = n;
	if (dp == mdivp)
		flushl(code, &code[1]);
	else
		flushd(code, &code[1]);
	if ((cdivp->d_rpos+=n) > cdivp->d_maxh)
		cdivp->d_maxh = cdivp->d_rpos;
	while (cdivp->d_rpos >= pgl) {
		if (byeflag) {
#if	ZKLUDGE
			dev_close();
#endif
			s = (lflag) ? POST_L : POST_P;
			if (lib_file(s, 0) == 0 & ntroff == TROFF)
				printe("file \"%s\" not found", s);
			leave(0);
		}
		pct++;
		pno = npn++;
		cdivp->d_rpos -= pgl;
		cdivp->d_maxh = cdivp->d_rpos;
		cdivp->d_ctpp = cdivp->d_trap;
	}
	tp = dp->d_ctpp;
	while (tp!=NULL && tp->t_apos<=dp->d_rpos)
		tp = tp->t_next;
	dp->d_ctpp = tp;
}

/*
 * Execute a macro, given the name.
 */
execute(name)
char name[2];
{
	register REG *rp;

	dprint3(DBGMACX, "execute macro %c%c\n", name[0], name[1]);
	if ((rp=findreg(name, RTEXT)) != (REG *)NULL) {
		adstreg(rp);
		strp->x1.s_eoff = 1;
		process();
	}
}

/* end of div.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.