|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.