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

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

	TRIX DEBUGGER

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

MSG		BADMOD;
MSG		NOFORK;
MSG		ADWRAP;
SYMPTR		symbol;
INT		mkfault;
CHAR		*lp;
INT		(*sigint)();
INT		(*sigqit)();
STRING		errflg;
CHAR		lastc;
L_INT		dot;
INT		dotinc;
L_INT		var[];


scanform(icount,ifp,itype,ptype)
L_INT		icount;
STRING		ifp;
{
	STRING		fp;
	CHAR		modifier;
	INT		fcount, init=1;
	L_INT		savdot;

	WHILE icount
	DO  fp=ifp;
	    IF init==0 ANDF findsym(shorten(dot),ptype)==0 ANDF maxoff
	    THEN
		printf("\n%s:%16t",symbol->symc);
	    FI
	    savdot=dot; init=0;

/*	    switch( symbol->symf & 07 )
	    {
	    case N_TEXT:	itype = ISP; break;
	    case N_BSS:		itype = NSP; break;
	    case N_DATA:	itype = DSP; break;
	    }
*/
	    /*now loop over format*/
	    WHILE *fp ANDF errflg==0
	    DO  IF digit(modifier = *fp)
		THEN fcount=0;
		     WHILE digit(modifier = *fp++)
		     DO fcount *= 10;
			fcount += modifier-'0';
		     OD
		     fp--;
		ELSE fcount=1;
		FI

		IF *fp==0 THEN break; FI
		fp=exform(fcount,fp,itype,ptype);
	    OD
	    dotinc=dot-savdot;
	    dot=savdot;

	    IF errflg
	    THEN IF icount<0
		 THEN errflg=0; break;
		 ELSE error(errflg);
		 FI
	    FI
	    IF --icount
	    THEN dot=inkdot(dotinc);
	    FI
	    IF mkfault THEN error(0); FI
	OD
}

STRING	exform(fcount,ifp,itype,ptype)
INT		fcount;
STRING		ifp;
{
	/* execute single format item `fcount' times
	 * sets `dotinc' and moves `dot'
	 * returns address of next format item
	 */
	POS		w;
	L_INT		savdot, wx;
	STRING		fp;
	CHAR		c, modifier;
	INT		longpr;
	L_REAL		fw;

	WHILE fcount>0
	DO	fp = ifp; c = *fp;
#ifdef s32
		longpr = (((c >= 'A') && (c <= 'Z') || c == 'p') ? 1 : 0);
#else s32
		longpr = (((c >= 'A') && (c <= 'Z')) ? 1 : 0);
#endif s32
		if (longpr) dotinc = 4; else dotinc = 2;
		if ((itype == NSP) || (*fp == 'a'))
		{
			wx = dot; w = dot;
		}
		else
		{
			w = get(dot,itype);
			if (longpr) wx = itol68(w, get(inkdot(2), itype));
			else wx = w;
		}
		IF errflg THEN return(fp); FI
		IF mkfault THEN error(0); FI
		var[0] = wx;
		modifier = *fp++;

		IF charpos()==0 ANDF modifier!='a' THEN printf("%16m"); FI

		switch(modifier) {

		    case SPACE: case TB:
			break;

		    case 't': case 'T':
			printf("%T",fcount); return(fp);

		    case 'r': case 'R':
			printf("%M",fcount); return(fp);

		    case 'a':
			psymoff(dot,ptype,":%16t"); dotinc=0; break;

		    case 'p':
			psymoff(var[0],ptype,"%16t"); break;

		    case 'u':
			printf("%-8u",w); break;

		    case 'U':
			printf("%-16U",wx); break;

		    case 'c': case 'C':
			if (itype == NSP) w <<= 8;
			IF modifier=='C'
			THEN printesc((w>>8)&LOBYTE);
			ELSE printc((w>>8)&LOBYTE);
			FI
			dotinc=1; break;

		    case 'b': case 'B':
			printf("%-8o", (w>>8)&LOBYTE);
			dotinc=1; break;

		    case 's': case 'S':
			savdot=dot; dotinc=1;
			WHILE (c = (get(dot,itype)>>8)&LOBYTE) ANDF errflg==0
			DO dot=inkdot(1);
			   IF modifier == 'S'
			   THEN printesc(c);
			   ELSE printc(c);
			   FI
			   endline();
			OD
			dotinc=dot-savdot+1; dot=savdot; break;

		    case 'x':
		    case 'w':
			printf("%-8x",w); break;

		    case 'X':
		    case 'W':
			printf("%-16X", wx); break;

		    case 'Y':
			printf("%-24Y", wx); break;

		    case 'q':
			printf("%-8q", w); break;

		    case 'Q':
			printf("%-16Q", wx); break;

		    case 'o':
			printf("%-8o", w); break;

		    case 'O':
			printf("%-16O", wx); break;

		    case 'i':
			printins(0,itype,w); printc(EOR); break;

		    case 'I':
			printins(1,itype,w); printc(EOR); break;

		    case 'd':
			printf("%-8d", w); break;

		    case 'D':
			printf("%-16D", wx); break;

		    case 'n': case 'N':
			printc('\n'); dotinc=0; break;

		    case '"':
			dotinc=0;
			WHILE *fp != '"' ANDF *fp
			DO printc(*fp++); OD
			IF *fp THEN fp++; FI
			break;

		    case '^':
			dot=inkdot(-dotinc*fcount); return(fp);

		    case '+':
			dot=inkdot(fcount); return(fp);

		    case '-':
			dot=inkdot(-fcount); return(fp);

		    default: error(BADMOD);
		}
		IF itype!=NSP
		THEN	dot=inkdot(dotinc);
		FI
		fcount--; endline();
	OD
	return(fp);
}

unox()
{
	int	rc, status, unixpid;
	char	*argp = lp;

	while (lastc != EOR) rdc();
	if ((unixpid = fork()) == 0)
	{
		signal(SIGINT, sigint);
		signal(SIGQUIT, sigqit);
		*lp = 0;
		execl("/bin/sh", "sh", "-c", argp, 0);
		exit(16);
	}
	else if (unixpid == -1) error(NOFORK);
	else
	{
		signal(SIGINT, SIG_IGN);
		while(((rc = wait(&status)) != unixpid) && (rc != -1));
		signal(SIGINT, sigint);
		prints("!"); lp--;
	}
}

printesc(c)
{
	c &= STRIP;
	IF c<SPACE ORF c>'~' ORF c=='@'
	THEN printf("@%c",(c=='@' ? '@' : (c&(~(c&0140)))|0140));
	ELSE printc(c);
	FI
}

L_INT	inkdot(incr)
{
	return(dot + incr);
}
