File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / usr / src / bin / cdb / format.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:24:19 2019 UTC (6 years, 11 months ago) by root
Branches: bsd, MAIN
CVS tags: v12b, v121, HEAD
Power 6/32 Unix version 1.2b

static char sccsid[] = "@(#)format.c	2.12";

#include <ctype.h>
#include "macdefs.h"
#include "cdb.h"

export int	vcNest;	/* nesting level for printg structures and unions */
export char vsbFmt[20]; /* format spec for addresses */
static char vsbAdr[20]; /* where we stick last address formatted - SbFAdr */

char *vmpBtSb[] = {	/* map basic types into the type names */
	"undefined",
	"Function Argument",
	"char",
	"short",
	"int",
	"long",
	"float",
	"double",
	"struct",
	"union",
	"enum",
	"member of enum",
	"unsigned char",
	"unsigned short",
	"unsigned int",
	"unsigned long"
};


/* S B   F   A D R */

export char * SbFAdr(adrLong, fMask)
long    adrLong;
FLAGT   fMask;
{
	if (vsbFmt[0] == chNull)
		strcpy(vsbFmt, "%lx");
#if (CBINT == CBSHORT)
	if (fMask)
		adrLong &= 0x0000ffffL;
#endif
	sprintf(vsbAdr, vsbFmt, adrLong);
	return(vsbAdr);
} /* SbFAdr */


/* D F   F   T Y */

export DFE DfFTy(ty, fAlternate)
pTYR	ty;
FLAGT	fAlternate;
{
	int		tq;

	tq = TqFTy(ty, 1);
	if ((tq == tqPtr) OR (tq == tqArray)) {
		if ( fAlternate
		    AND (ty->td.bt == btChar)
		    AND ((tq == tqArray AND TqFTy(ty, 2) == tqNil)
		    OR (ty->td.tq1 == tqPtr)) ) {
			return((tq == tqPtr) ? dfPStr : dfStr);	/* so it looks pretty */
		} /* if */
		return(dfAddr);	/* use address display mode */
	} /* if */

	if (ty->td.st == stReg)
		return(dfAddr);	/* a hackers delight */

	switch (ty->td.bt) {
	case btNil:	
		return(dfNil);
	case btUnion:
	case btStruct:
		if (fAlternate)
#ifdef BSD42
			return(dfStruct);
#else
		return(dfAddr);
#endif
		else
			return(dfAddr);
	case btUChar:
	case btUInt:
	case btULong:	
		return(dfUnsigned);
	case btShort:
	case btInt:
	case btLong:	
		return(dfDecimal);
	case btFloat:
	case btDouble:	
		return(dfGFloat);
	case btEType:	
		return(dfEnum);
	case btChar:	
		if (tq == tqArray AND fAlternate)
			return(dfStr);
		else
			return(dfChar);
	} /* switch */
	return(dfDecimal);
} /* DfFTy */


/* C B   F   C H */

export int CbFCh(ch)
char    ch;
{
	switch (ch) {
	case 'b':
	case 'c':       
		return(1);
	case 'e':
	case 'f':
	case 'g':       
		return(CBFLOAT);
	case 'E':
	case 'F':
	case 'G':       
		return(CBDOUBLE);
	case 'D':
	case 'O':
	case 'U':
	case 'X':       
		return(CBLONG);
	case 'd':
	case 'o':
	case 'u':
	case 'x':
	case 'a':
	case 'n':
	case 'p':
	case 's':
	case 'B':
	case 'C':
	case 'S':       
		return(-1);	/* says to use `current' size */
	} /* switch */
	return(-1);
} /* CbFCh */


/* D F   F   C H */

export DFE DfFCh(ch)
char    ch;
{
	switch (ch) {
	case 'a':       
		return(dfStr);
	case 'C':
	case 'c':       
		return(dfChar);
	case 'b':
	case 'D':
	case 'd':       
		return(dfDecimal);
	case 'E':
	case 'e':       
		return(dfEFloat);
	case 'F':
	case 'f':       
		return(dfFFloat);
	case 'G':
	case 'g':       
		return(dfGFloat);
	case 'n':       
		return(dfNil);
	case 'O':
	case 'o':       
		return(dfOctal);
	case 'p':       
		return(dfProc);
	case 'S':       
		return(dfStruct);
	case 's':       
		return(dfPStr);
	case 'U':
	case 'u':       
		return(dfUnsigned);
	case 't':	
		return(dfType);
	case 'X':
	case 'x':       
		return(dfHex);
	} /* switch */
	return(dfNil);
} /* DfFCh */


/* G E T   M O D E */

export void GetMode(mode)
pMODER  mode;
{
	char        ch;
	TKE         tk;

	/* consider the next few tokens as variable formatting info */
	/* NOTE: we assume WE get next token!! */
	tk = TkNext();
	mode->imap = 0;
	if (tk == tkStar) {
		mode->imap = 1;
		tk = TkNext();
	} /* if */
	if (tk == tkNil) {
		return;
	} 
	else if (tk == tkNumber) {
		mode->cnt = atoi(vsbTok);
		tk = TkNext();
	} 
	else {
		mode->cnt = 1;
	} /* if */

	if (tk == tkStr) {
		ch = vsbTok[0];
		/* determine # of bytes based on format */
		mode->len = CbFCh(ch);
		mode->df = DfFCh(ch);
		if (vsbTok[1] != chNull)
			mode->len = (vsbTok[1] == 'b') ? 1 : 
			(vsbTok[1] == 's') ? 2 :
			(vsbTok[1] == 'l') ? 4 : atoi(&vsbTok[1]);
		tk = TkNext();
	} /* if */
} /* GetMode */


/* I N C   F   T Y   M O D E */

export int IncFTyMode(ty, mode)
pTYR    ty;
pMODER  mode;
{
	int		i;

	if ((ty->td.st == stSpc)	/* we do NOT allow inc's of specials */
	    OR (mode->df == dfType))
		return(0);

#ifdef BSD41
	ty->sbVar = -1;      /* because this name is no longer correct */
#else
	ty->sbVar[0] = chNull;      /* because this name is no longer correct */
#endif
	if (ty->td.st == stReg) {
		return(1);
	} 
	else {
		if (mode->df == dfStr) {
			if (mode->len < 0) {
				i = -mode->len;
				mode->len = -1;
				return(i);
			} 
			else {
				return(mode->cnt * mode->len);
			} /* if */
		} 
		else if (mode->df == dfPStr) {
			return(mode->cnt * CBPOINT);
		} 
		else {
			return(mode->cnt * mode->len);
		} /* if */
	} /* if */
} /* IncFTyMode */


/* D I S P   V A L */

export void DispVal(adrLong, tyIn, mode, fShowAdr, fIndirect, fAlternate)
long    adrLong;
pTYR    tyIn;
pMODER  mode;
FLAGT   fShowAdr, fIndirect, fAlternate;
{
	int		modval, width, cPrint, cb;
	int		len, cnt, i;
	FLAGT       fConstant, fCheckNull, fRandomLength;
	char        ch, *sbVar;
	long        mask, val, *pKludge;
	double      valDouble;
	DFE         df;
	STUFFU      stuff;
	MODER	amodeTemp;
	ADRT	adrWorking;
#if (CBINT == CBSHORT)
	short	valMasked;
#else
	long	valMasked;
#endif

	modval = 1;
	/* if the mode is supplied, we ignore the TY, else we use it to build
	     * a plausible display format.
	     */
	if (mode == modeNil) {
		mode = &amodeTemp;
		cnt = 1;
		df = dfNil;
	} 
	else {
		df = mode->df;
		cnt = mode->cnt;
		len = mode->len;
		/* this may not be right, but we need to force the size of what we
		         * are looking at to be the size we requested in the format.
		         * this way, when we say `sbWord/c;<cr>;<cr>;.='H' ' we actually
		         * do the `correct' character assignment.
		         */
		if (len > 0) {
			switch (len) {
			case 1: 
				CopyTy(tyIn, vtyChar);
				if (df == dfUnsigned)
					tyIn->td.bt = btUChar;
				break;
			case 2: 
				CopyTy(tyIn, vtyShort);
				if (df == dfUnsigned)
					tyIn->td.bt = btUShort;
				break;
			case 4: 
				CopyTy(tyIn, vtyLong);
				if (df == dfUnsigned)
					tyIn->td.bt = btULong;
				break;
			} /* switch */
		} /* if */
	} /* if */

	if (df == dfNil) {
		/* they did not specify display format */
		df = DfFTy(tyIn, fAlternate);
		len = (df == dfStr OR df == dfPStr) ? -1 : CbFTy(tyIn);
		/* remember this stuff */
		mode->df = df;
		mode->cnt = cnt;
		mode->len = len;
	} /* if */
	fRandomLength = (len == -1);
	if ((len == -1)
	    AND (df != dfStr)
	    AND (df != dfPStr))
		mode->len = len = CbFTy(tyIn);

#ifdef ONYX
	/* we may want to do this for other than ONYX, too. */
	if (FOdd(adrLong))
		cb = 1;	/* we assume it is actually a single byte */
#endif
	cb = len;
	mask = -1;
	if (df == dfPStr) {
		cb = CBPOINT;
	} 
	else if (df == dfStr) {
		cb = CBCHAR;
		if (fRandomLength)
			mode->len = 0;	/* we will stuff final count in here for Inc */
	} 
	else if (df == dfProc) {
		fShowAdr = false;
		fIndirect = false;
	} 
	else {
		/* here we try to skull out a good width for this size */
		width = 7;
		modval = 8;
		if (len == 1)
			mask = 0x00ff;
		else if (len == 2)
			mask = 0xffff;
		else if (len == 4) {
			mask = 0xffffffff;
			width = 12;
			modval = 4;
		} /* if */
	} /* if */

	if (cnt == 1)
		width = 0; /* we don't try to add anything if there's just one */

	if (df == dfType) {
		fIndirect = false;
		fShowAdr = false;
	} /* if */
	cPrint = 0;
	while (cnt--) {
		vimap = mode->imap;     /* sorta kludgey - sorry */
		/*
			fConstant = tyIn->td.fConstant;
			tyIn->td.fConstant = false;
			*/
		val = (fIndirect) ? ValFAdr(adrLong, tyIn) : adrLong;
		/*
			tyIn->td.fConstant = fConstant;
			*/
		vimap = 0;
		valMasked = val & mask;
		if (cb < 4)
			val = valMasked;
		adrWorking = adrLong;
		if (fShowAdr
		    AND fIndirect
		    AND (!tyIn->td.fConstant)
		    AND (cPrint % modval == 0)) {
			if ((cPrint == 0)
			    AND (tyIn != tyNil)
			    AND (*(sbVar = SbInCore(tyIn[0].sbVar)) != chNull)
			    AND (*sbVar != '*'))
#ifdef BSD41
				printf("%s = ", sbVar);
#else
			printf("%.8s = ", sbVar);
#endif
			else
				printf("%s  ", SbFAdr(adrLong, true));
		} /* if */
		switch (df) {
		case dfType:
			PxTy(tyIn);
			break;
		case dfAddr:
			printf("%*s", width, SbFAdr(val, true));
			break;
		case dfDecimal:
			printf("%*ld", width, val);
			break;
		case dfUnsigned:
			val &= mask;
			printf("%*lu", width, val);
			break;
		case dfOctal:
			val &= mask;
			printf("%*lo", width, val);
			break;
		case dfHex:
			val &= mask;
			printf("%*lx", width, val);
			break;
		case dfChar:
			if (valMasked < ' ')
				printf("^%c (%o)", valMasked+0100, valMasked);
			else printf("%c", valMasked);
			break;
		case dfFFloat:
		case dfEFloat:
		case dfGFloat:
			/* the following tries to get the right
			                 * conversions to happen.
			                 */
			if (cb == 4) {
				stuff.lng = val;
				valDouble = stuff.fl;
			} 
			else {  /* we assume double */
				pKludge = (long *)&valDouble;
				pKludge[0] = val;
				pKludge[1] = ValFAdr(adrLong+4, vtyLong);
			} /* if */
			if (df == dfFFloat)
				printf("%f", valDouble);
			else if (df == dfEFloat)
				printf("%e", valDouble);
			else
				printf("%g", valDouble);
			break;
		case dfEnum:
			PxEnum(val, tyIn);
			break;
		case dfStruct:
			IssFPxStruct(adrWorking, tyIn, true);
			break;
		case dfProc:
			PrintPos(valMasked, fmtFile+fmtProc+fmtLn+fmtPrint+fmtSave);
			break;
		case dfPStr:
			adrWorking = valMasked;    /* and fall through */
		case dfStr: 
			fCheckNull = false;
			if (fRandomLength) {
				if (adrWorking == 0) {
					printf("<null pointer>");
					break;
				} /* if */
				len = 128;
				fCheckNull = true;
			} /* if */
			printf("\"");
			for (i=0; i != len; i++) {
				ch = GetByte((ADRT)(adrWorking+i), spaceData);
				if ((ch == chNull) AND fCheckNull)
					break;
				if (ch < ' ')
					printf("^%c", ch+0100);
				else printf("%c", ch);
			} /* for */
			printf("\"");
			break;
		} /* switch */

		if (fRandomLength) {
			i += 1;	/* if we did /s or /a, this moves us past the chNull */
			if (df == dfStr)
				mode->len -= i;	/* remember size for IncFTyMode */
		} /* if */

		/* advance */
		if (cnt) {
#ifdef BSD41
			tyIn->sbVar = -1;      /* because this name is no longer correct */
#else
			tyIn->sbVar[0] = chNull;/* because this name is no longer correct */
#endif

			adrLong += (df == dfStr) ? i : CbFTy(tyIn);
			if (((++cPrint % modval) == 0)
			    OR (df == dfPStr OR df == dfStr OR df == dfStruct)) {
				printf("\n");
			} /* if */
		} /* if */
	} /* while */
} /* DispVal */


/* P X   E N U M */

export void PxEnum(val, ty)
long	val;
pTYR	ty;
{
#ifndef BSD42
	printf("%ld", val);
#else
	int		i;
	char	*sb, *sbName, *sbType, sbLook[10];
	pXTYR	xty;

	xty = (pXTYR) (ty + 1);
	sbType = SbInCore(xty->issRef);
	sbName = SbInCore(SbSafe(sbType));
	sprintf(sbLook, ":%d,", val);	/* value we are looking for */
	i = IFSbSb(sbType, sbLook);
	if (i == -1) {
		printf("Value %d is not defined for 'enum %s'", val, sbName);
		return;
	}
	sb = sbType + i - 1;
	/* got it - now back up to before the name */
	while ((*sb != ',') AND (*sb != '='))
		sb--;
	if (*sb == '=')
		sb++; /* point past 'e' */
	sb++;	/* past the ',' or the '=' */
	printf("%s", SbInCore(SbSafe(sb)));
#endif
} /* PxEnum */


/* I S S   F   P X   S T R U C T */

export long IssFPxStruct(adr, tyStruct, fDoVal)
ADRT	adr;
pTYR	tyStruct;
FLAGT	fDoVal;
{
#ifndef BSD42
	UError("There is insufficient information to do a structure dump");
#else
	int		i;
	long	adrLong, iss;
	char	chType, *sb, *sbName, *sbEqual, *sbType, sbLook[10];
	char	sbStart[1000];	/* where we stash the type info */
	FLAGT	fDidit;
	TYR		tyField[cTyMax], tyT[cTyMax];
	pXTYR	xty;

	xty = (pXTYR) (tyStruct + 1);
	if (xty->st != stExtend) {
		adrLong = adr;
		printf("%s", SbFAdr(adrLong));
		return(-1);
	}
	iss = xty->issRef;
	strcpy(sbStart, SbInCore(iss));
	sbType = sbStart;
	sbName = SbInCore(SbSafe(sbType));
	i = IFSbSb(sbType, "=");
	sbType += i + 1;
	if ((i == -1)
	    OR ((*sbType != 's') AND (*sbType != 'u')) )
		UError("This does not appear to be a stuct or union");
	chType = *sbType++;
	while (isdigit(*sbType))	/* get past size value */
		sbType++;
	printf("%s %s {\n", (chType == 's') ? "struct" : "union", sbName);
	vcNest++;	/* kick nesting level for indent printing */
	while (*sbType) {
		sbName = SbInCore(SbSafe(sbType));
#ifdef BSD41
		tyField[0].sbVar = bitHigh | (long)sbName;
#else
		strncpy(tyField[0].sbVar, sbName, cbVarMax);
#endif
		tyField[0].td.st = stStruct;
		adrLong = adr;
		adrLong = AdrFField(adrLong, tyStruct, tyField);
		sbEqual = strchr(sbType, '=');
		sb = sbType;	/* remember where we are in case of imbeded struct */
		sbType = strchr(sbType, ';') + 1;
		fDidit = false;
		if ((sbEqual != sbNil) AND (sbEqual < sbType)) {
			if (*++sbEqual == 'a') {
				/* this should get us through the array declaration */
				sbType = strchr(sbEqual, ';') + 1;
				sbType = strchr(sbType, ';') + 1;
				sbType = strchr(sbType, ';') + 1;
				sbType = strchr(sbType, ';') + 1; /* this should be next name */
			} 
			else if (*sbEqual == 's') {
				/* we have a struct, recurse */
				xty = (pXTYR) (tyField + 1);
				xty->issRef = iss + (sb - sbStart);
				for (i=0; i<vcNest; i++)
					printf("    ");
				iss = IssFPxStruct(adrLong, tyField, fDoVal);
				printf("\n");
				strcpy(sbStart, SbInCore(iss));
				sbType = sbStart;
				sbType = strchr(sbType, ';') + 1; /* this should be next name */
				fDidit = true;
			}
		}
		if (!fDidit) {
			for (i=0; i<vcNest; i++)
				printf("    ");
			if (fDoVal)
				DispVal(adrLong, tyField, modeNil, true, true, true);
			else
				PxTy(tyField);
			printf(";\n");
		}
		if (*sbType == ';')
			break;	/* end of the line */
	} /* while */
	for (i=0; i<vcNest; i++)
		printf("    ");
	vcNest--;
	printf("};");
	return(iss+sbType-sbStart+1);	/* points 1 past ending ';;' */
#endif
} /* IssFPxStruct */


/* P X   T Y */

export void PxTy(ty)
pTYR	ty;
{
	int		ipd, i, j, tq, tqLast, st, bt;
	short	*rgDim;
	FLAGT	fDidName, fHaveExtension, fNeedRP;
	pXTYR	xty;

	tqLast = tqNil;
	fDidName = false;
	st = ty->td.st;
	bt = ty->td.bt;
	xty = (pXTYR)(ty+1);
	fHaveExtension = (xty->st == stExtend);
	rgDim = xty->rgDim;

#ifdef BSD41
	if (ty->td.st == stProc) {
		/* BSD 4.1 does not know return type for procedures */
		ipd = IpdFName(SbInCore(ty->sbVar));
		DispFrame(adrNil,ipd, adrNil, adrNil, -1, false, false);
		return;
	}
#ifdef BSD42
	tq = TqFTy(ty, 1);
	if ((tq == tqNil)
	    AND ((bt == btStruct)
	    OR (bt == btUnion))) {
		IssFPxStruct(0L, ty, false);
		fDidName = true;
	} 
	else {
		/* print type name */
		printf("%s ", vmpBtSb[bt]);
		if ((bt == btEType)
		    OR (bt == btStruct)
		    OR (bt == btUnion)) {
			printf("%s ",SbInSafe(xty->issRef));
		}
	}
#else
	/* print type name */
	printf("%s ", vmpBtSb[bt]);
#endif
#else
	/* print type name */
	printf("%s ", vmpBtSb[bt]);
#endif
	fNeedRP = false;
	tqLast = tqNil;
	for (i=1; i<=6; i++) {
		if ((tq = TqFTy(ty, i)) == tqNil)
			break;
		if ((tqLast != tqNil)
		    AND (tq != tqLast)) {
			printf("(");
			fNeedRP = true;
		} /* if */
		switch (tq) {
		case tqPtr:
			printf("*");
			break;
		case tqFunc:
			ipd = IpdFName(SbInCore(ty->sbVar));
			DispFrame(adrNil,ipd, adrNil, adrNil, -1, false, false);
			fDidName = true; /* printed by DispFrame */
			return;
		case tqArray:
			if (!fDidName) {
				printf("%s", SbInCore(ty->sbVar));
				fDidName = true;
			} /* if */
			if (fHaveExtension) {
				for (j=0; (j < 2) AND (rgDim[j] != 0); j++) {
					if (rgDim[j] < 0)
						printf("[]");
					else
						printf("[%d]", rgDim[j]+1);
				}
			} 
			else {
				printf("[]");
			}
			break;
		} /* switch */
		if (fNeedRP) {
			fNeedRP = false;
			printf(")");
		}
		tqLast = tq;
	} /* for */
	if (!fDidName)
		printf("%s", SbInCore(ty->sbVar));
	if (ty->td.width != 0)
		printf(" : %d", ty->td.width);
} /* PxTy */

unix.superglobalmegacorp.com

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