static char rcsid[] = "$Header: output.c,v 800.0 85/07/30 13:55:20 root Exp $";
static char sccsid[]="%W% %Y% %Q% %G%";

#
/****************************************************************************

	DEBUGGER - output routines

****************************************************************************/
#include "defs.h"

INT		mkfault;
FILE		*infile;
FILE		*outfile;
INT		maxpos;
INT		hexa;

CHAR		printbuf[MAXLIN];
CHAR		*printptr = printbuf;
CHAR		*digitptr;

eqstr(s1, s2)
register STRING	s1, s2;
{
	WHILE *s1++ == *s2
	DO IF *s2++ == 0
	   THEN return(1);
	   FI
	OD
	return(0);
}

length(s)
register STRING	s;
{
	INT	n = 0;
	WHILE *s++ DO n++; OD
	return(n);
}

printc(c)
CHAR	c;
{
	CHAR	d;
	STRING	q;
	INT	posn, tabs, p;

	IF mkfault
	THEN	return;
	ELIF (*printptr=c)==EOR
	THEN tabs=0; posn=0; q=printbuf;
	     FOR p=0; p<printptr-printbuf; p++
	     DO d=printbuf[p];
		IF (p&7)==0 ANDF posn
		THEN tabs++; posn=0;
		FI
		IF d==SPACE
		THEN posn++;
		ELSE WHILE tabs>0 DO *q++=TB; tabs--; OD
		     WHILE posn>0 DO *q++=SPACE; posn--; OD
		     *q++=d;
		FI
	     OD
	     *q++=EOR;
	     fwrite(printbuf, 1, q-printbuf, outfile);
	     printptr=printbuf;
	ELIF c==TB
	THEN *printptr++=SPACE;
	     WHILE (printptr-printbuf)&7 DO *printptr++=SPACE; OD
	ELIF c
	THEN printptr++;
	FI
}

charpos()
{	return(printptr-printbuf);
}

flushbuf()
{	IF printptr!=printbuf
	THEN printc(EOR);
	FI
}

printf(fmat, a1)
STRING	fmat;
STRING	*a1;
{
	STRING		ecvt();
	STRING		fptr, s;
	INT		*vptr;
	L_INT		*dptr;
	L_REAL		*rptr;
	INT		width, prec;
	CHAR		c, adj;
	INT		x, decpt, n;
	L_INT		lx;
	CHAR		digits[64];

	fptr = fmat; dptr = vptr = (INT *)&a1;
	rptr = (L_REAL *)vptr;

	WHILE c = *fptr++
	DO  IF c!='%'
	    THEN printc(c);
	    ELSE IF *fptr=='-' THEN adj='l'; fptr++; ELSE adj='r'; FI
		 width=convert(&fptr);
		 IF *fptr=='.' THEN fptr++; prec=convert(&fptr);
		 ELSE prec = -1; FI
		 digitptr = digits;
		 rptr = (L_REAL *)vptr;
		 (INT *)dptr = vptr; lx = *dptr; x = *vptr++; s = 0;
		 switch (c = *fptr++)
		 {
		    case 'd':
		    case 'u':
			printnum(x, c, 10); break;
		    case 'o':
			printoct(x, 0); break;
		    case 'q':
			lx = x; printoct(lx, -1); break;
		    case 'x':
			printnum(x, c, 16); break;
		    case 'Y':
			printdate(lx); break;
		    case 'D':
		    case 'U':
			printnum(x, c, 10); break;
		    case 'O':
			printoct(lx, 0); break;
		    case 'Q':
			printoct(lx, -1); break;
		    case 'X':
			printnum(x, c, 16); break;
		    case 'c':
			printc(x); break;
		    case 's':
			s = (STRING) x; break;
		    case 'f':
		    case 'F':
			vptr += 7;
			s=ecvt(*rptr, prec, &decpt, &n);
			*digitptr++=(n?'-':'+');
			*digitptr++ = (decpt<=0 ? '0' : *s++);
			IF decpt>0 THEN decpt--; FI
			*digitptr++ = '.';
			WHILE *s ANDF prec-- DO *digitptr++ = *s++; OD
			WHILE *--digitptr=='0' DONE
			digitptr += (digitptr-digits>=3 ? 1 : 2);
			IF decpt
			THEN *digitptr++ = 'e'; printnum(decpt,'d',10);
			FI
			s=0; prec = -1; break;
		    case 'm':
			vptr--; break;
		    case 'M':
			width = x; break;
		    case 'T':
		    case 't':
			if (c=='T') width = x; else vptr--;
			if (width) width -= charpos() % width;
			break;
		    default:
			printc(c); vptr--;
		}
		if (s == NULL)
		{
			*digitptr = NULL; s = digits;
		}
		n = length(s);
		n = (prec<n && prec>=0 ? prec : n);
		width -= n;
		if (adj=='r') while (width-- > 0) printc(SPACE);
		while (n--) printc(*s++);
		while (width-- > 0) printc(SPACE);
		digitptr = digits;
	    FI
	OD
}

printdate(tvec)
L_INT	tvec;
{
	STRING	ctime();
	register INT		i;
	register STRING	timeptr;
	timeptr = ctime(&tvec);
	FOR i=20; i<24; i++ DO *digitptr++ = *(timeptr+i); OD
	FOR i=3; i<19; i++ DO *digitptr++ = *(timeptr+i); OD
}

prints(s)
char	*s;
{
	printf("%s", s);
}

newline()
{
	printc(EOR);
}

convert(cp)
register STRING	*cp;
{
	register CHAR	c;
	INT		n;
	n=0;
	WHILE ((c = *(*cp)++)>='0') ANDF (c<='9') DO n=n*10+c-'0'; OD
	(*cp)--;
	return(n);
}

printnum(n, fmat, base)
register int	n;
char		fmat;
{
	register char	k;
	register int	*dptr;
	int		digs[15], dnum = 0, i;

	dptr = digs;
	if (hexa) dnum = ((base==10) ? 0 : ((fmat=='x') ? 4 : 8));
	if ((fmat=='x' && (n|0xffff)==-1) ||
			((n < 0) && (fmat=='d' || fmat=='D'))) {
		n = -n;
		*digitptr++ = '-';
	}
	if (base == 16) {*digitptr++ = '0'; *digitptr++ ='x';}
	i = (dnum ? dnum : n);
	while (i)
	{
		*dptr++ = ((unsigned)n) % base;
		n = ((unsigned)n)/base;
		if (dnum) i--; else i = n;
	}
	if (dptr == digs) *dptr++ = NULL;
	while (dptr != digs)
	{
		k = *--dptr;
		*digitptr++ = (k+ ((k <= 9) ? '0' : ('A' - 10)));
	}
}

printoct(o, s)
long	o;
int	s;
{
	INT		i;
	L_INT		po = o;
	CHAR		digs[12];

	IF s
	THEN IF po<0
	     THEN po = -po; *digitptr++='-';
	     ELSE IF s>0 THEN *digitptr++='+'; FI
	     FI
	FI
	FOR i=0;i<=11;i++
	DO digs[i] = po&7; po >>= 3; OD
	digs[10] &= 03; digs[11]=0;
	FOR i=11;i>=0;i--
	DO IF digs[i] THEN break; FI OD
	FOR i++;i>=0;i--
	DO *digitptr++=digs[i]+'0'; OD
}

iclose()
{
	IF infile!=stdin
	THEN	fclose(infile); infile=stdin;
	FI
}

oclose()
{
	IF outfile!=stdout
	THEN	flushbuf(); fclose(outfile); outfile=stdout;
	FI
}

endline()
{
	IF charpos()>=maxpos
	THEN printf("\n");
	FI
}
