/*
 * n2.c
 *
 * output, cleanup
 */

#include "tdef.h"
#include "fns.h"
#include "ext.h"
#include <setjmp.h>

#ifdef STRICT
	/* not in ANSI or POSIX */
FILE*	popen(char*, char*);
#endif


extern	jmp_buf	sjbuf;
int	toolate;
int	error;

char	obuf[2*BUFSIZ];
char	*obufp = obuf;

	/* pipe command structure; allows redicously long commends for .pi */
struct Pipe {
	char	*buf;
	int	tick;
	int	cnt;
} Pipe;


int	xon	= 0;	/* records if in middle of \X */

int pchar(Tchar i)
{
	int j;
	static int hx = 0;	/* records if have seen HX */

	if (hx) {
		hx = 0;
		j = absmot(i);
		if (isnmot(i)) {
			if (j > dip->blss)
				dip->blss = j;
		} else {
			if (j > dip->alss)
				dip->alss = j;
			ralss = dip->alss;
		}
		return 0;
	}
	if (ismot(i)) {
		pchar1(i); 
		return 0;
	}
	switch (j = cbits(i)) {
	case 0:
	case IMP:
	case RIGHT:
	case LEFT:
		return 0;
	case HX:
		hx = 1;
		return 0;
	case XON:
		xon++;
		break;
	case XOFF:
		xon--;
		break;
	case PRESC:
		if (!xon && !tflg && dip == &d[0])
			j = eschar;	/* fall through */
	default:
		setcbits(i, trtab[j]);
	}
	if (NROFF & xon)	/* rob fix for man2html */
		return 0;
	pchar1(i);
	return 0;
}


void pchar1(Tchar i)
{
	int j;

	j = cbits(i);
	if (dip != &d[0]) {
		wbf(i);
		dip->op = offset;
		return;
	}
	if (!tflg && !print) {
		if (j == '\n')
			dip->alss = dip->blss = 0;
		return;
	}
	if (j == FILLER && !xon)
		return;
	if (tflg) {	/* transparent mode, undiverted */
		if (print)			/* assumes that it's ok to print */
			/* OUT "%c", j PUT;	/* i.e., is ascii */
			outascii(i);
		return;
	}
	if (TROFF && ascii)
		outascii(i);
	else
		ptout(i);
}


void outweird(int k)	/* like ptchname() but ascii */
{
	char *chn = chname(k);

	switch (chn[0]) {
	case MBchar:
		OUT "%s", chn+1 PUT;	/* \n not needed? */
		break;
	case Number:
		OUT "\\N'%s'", chn+1 PUT;
		break;
	case Troffchar:
		if (strlen(chn+1) == 2)
			OUT "\\(%s", chn+1 PUT;
		else
			OUT "\\C'%s'", chn+1 PUT;
		break;
	default:
		OUT " %s? ", chn PUT;
		break;
	}
}

void outascii(Tchar i)	/* print i in best-guess ascii */
{
	char *p;
	int j = cbits(i);

/* is this ever called with NROFF set? probably doesn't work at all. */

	if (ismot(i))
		oput(' ');
	else if (j < ALPHABET && j >= ' ' || j == '\n' || j == '\t')
		oput(j);
	else if (j == DRAWFCN)
		oputs("\\D");
	else if (j == HYPHEN)
		oput('-');
	else if (j == MINUS)	/* special pleading for strange encodings */
		oputs("\\-");
	else if (j == PRESC)
		oputs("\\e");
	else if (j == FILLER)
		oputs("\\&");
	else if (j == UNPAD)
		oputs("\\ ");
	else if (j == OHC)	/* this will never occur;  stripped out earlier */
		oputs("\\%");
	else if (j == XON)
		oputs("\\X");
	else if (j == XOFF)
		oputs(" ");
	else if (j == LIG_FI)
		oputs("fi");
	else if (j == LIG_FL)
		oputs("fl");
	else if (j == LIG_FF)
		oputs("ff");
	else if (j == LIG_FFI)
		oputs("ffi");
	else if (j == LIG_FFL)
		oputs("ffl");
	else if (j == WORDSP) {		/* nothing at all */
		if (xon)		/* except in \X */
			oput(' ');

	} else
		outweird(j);
}

int flusho(void)
{
	if (NROFF && !toolate && t.twinit)
			fwrite(t.twinit, strlen(t.twinit), 1, ptid);

	if (obufp > obuf) {
		if (pipeflg && !toolate) {
			/* fprintf(stderr, "Pipe to <%s>\n", Pipe.buf); */
			if (!Pipe.buf[0] || (ptid = popen(Pipe.buf, "w")) == NULL)
				ERROR "pipe %s not created.", Pipe.buf WARN;
			if (Pipe.buf)
				free(Pipe.buf);
		}
		if (!toolate)
			toolate++;
		*obufp = 0;
		fputs(obuf, ptid);
		fflush(ptid);
		obufp = obuf;
	}
	return 1;
}


void caseex(void)
{
	done(0);
}


void done(int x) 
{
	int i;

	error |= x;
	app = ds = lgf = 0;
	if (i = em) {
		donef = -1;
		eschar = '\\';
		em = 0;
		if (control(i, 0))
			longjmp(sjbuf, 1);
	}
	if (!nfo)
		done3(0);
	mflg = 0;
	dip = &d[0];
	if (woff)	/* BUG!!! This isn't set anywhere */
		wbf((Tchar)0);
	if (pendw)
		getword(1);
	pendnf = 0;
	if (donef == 1)
		done1(0);
	donef = 1;
	ip = 0;
	frame = stk;
	nxf = frame + 1;
	if (!ejf)
		tbreak();
	nflush++;
	eject((Stack *)0);
	longjmp(sjbuf, 1);
}


void done1(int x) 
{
	error |= x;
	if (numtabp[NL].val) {
		trap = 0;
		eject((Stack *)0);
		longjmp(sjbuf, 1);
	}
	if (!ascii)
		pttrailer();
	done2(0);
}


void done2(int x) 
{
	ptlead();
	if (TROFF && !ascii)
		ptstop();
	flusho();
	done3(x);
}

void done3(int x) 
{
	error |= x;
	flusho();
	if (NROFF)
		twdone();
	if (pipeflg)
		pclose(ptid);
	exit(error);
}


void edone(int x) 
{
	frame = stk;
	nxf = frame + 1;
	ip = 0;
	done(x);
}


void casepi(void)
{
	int j;
	char buf[NTM];

	if (Pipe.buf == NULL) {
		if ((Pipe.buf = (char *)calloc(NTM, sizeof(char))) == NULL) {
			ERROR "No buf space for pipe cmd" WARN;
			return;
		}
		Pipe.tick = 1;
	} else
		Pipe.buf[Pipe.cnt++] = '|';

	getline(buf, NTM);
	j = strlen(buf);
	if (toolate) {
		ERROR "Cannot create pipe to %s", buf WARN;
		return;
	}
	Pipe.cnt += j;
	if (j >= NTM +1) {
		Pipe.tick++;
		if ((Pipe.buf = (char *)realloc(Pipe.buf, Pipe.tick * NTM * sizeof(char))) == NULL) {
			ERROR "No more buf space for pipe cmd" WARN;
			return;
		}
	}
	strcat(Pipe.buf, buf);
	pipeflg++;
}
