/* diversion processing */

#include "nroff.h"

/* put char out to diversion or somewhere */

dflsh(c)
{
	struct	source	*mp = curdiv;
	int	len;
	char	*s;

	if(c && mp->m_curp < mp->m_eptr){
		*mp->m_curp++ = c;
		return;
	}
	if(mp->m_fp){
		if(mp->m_curp != mp->m_val){
			fwrite(mp->m_val, 1, mp->m_curp - mp->m_val, mp->m_fp);
			mp->m_curp = mp->m_val;
		}
		if(c)
			*mp->m_curp++ = c;
		return;
	}
	if(c == 0)
		return;
	/*
	 * it's a diversion, do something about adding
	 * it to the current value
	 */
	*mp->m_curp = 0;
	len = mp->m_curp - mp->m_val;
	s = mymalloc(len + 1 + LINESIZE, FALSE);
	strcpy(s, mp->m_val);
	myfree(mp->m_val);
	mp->m_val = s;
	mp->m_curp = mp->m_val + len;
	mp->m_eptr = mp->m_curp + LINESIZE;
	*mp->m_curp++ = c;
}

setdiv(buf, cmd)
char	*buf;
{
	char	name[2];
	char	*ttl;
	struct	source	*mp;
	
	if(*buf == '\0'){
		/* end of diversion */
		mp = curdiv;
		if(mp->m_fp){	/* end of diversion with non in operation */
			dlval = 0;
			return;
		}
		*mp->m_curp = '\0';	/* terminate the string */
		curdiv = mp->m_last;
		mp->m_last = 0;
		if(curdiv->m_last == 0)
			bottom = plval - m3val - m4val;	/* reset bottom */
		mp->m_nlines = lineno;
		dlval = lineno;	/* set to length of current diversion */
		lineno = mp->m_ival;
		return;
	}
	for(ttl = name ; *buf && *buf != ' ' ; buf++)
		if(ttl < name + 2)
			*ttl++ = *buf;
	if(ttl == name + 1)
		name[1] = '\0';
	for(mp = macros ; mp ; mp = mp->m_next)
		if(mp->m_name[0] == name[0] && mp->m_name[1] == name[1])
			break;
	if(mp == 0){		/* not found !! */
		mp = (struct source *)mymalloc(sizeof(struct source), TRUE);
		mp->m_name[0] = name[0];
		mp->m_name[1] = name[1];
		mp->m_next = macros;
		macros = mp;
	}
	/*
	 * shame about the current string !! can't do
	 */
	if(mp->m_last || mp == curmacro || mp == curdiv)
		return;

	if(cmd != DA){			/* must junk original str */
		if(mp->m_val)
			myfree(mp->m_val);
		mp->m_val = 0;
		mp->m_nlines = 0;
	}
	mp->m_ival = lineno;	/* start of current diversion */
	lineno = mp->m_nlines;
	if(mp->m_val == 0){
		mp->m_val = mymalloc(LINESIZE +1, FALSE);
		mp->m_eptr = mp->m_val + LINESIZE;
		mp->m_curp = mp->m_val;
	}
	else
		mp->m_eptr = mp->m_curp = mp->m_val + strlen(mp->m_val);
	/*
	 * now put onto output queue
	 */
	bottom = HUGE;
	mp->m_last = curdiv;
	curdiv = mp;
}
