NT4/private/sdktools/vctools/cvpack/obsolete.c
2020-09-30 17:12:29 +02:00

1144 lines
29 KiB
C

/** obsolete.c - to convert obsolete type records to the C7 format
*
*/
#include "compact.h"
#define getbyte(type) ((uchar) *type++)
#define getword(type) (*((short *)type)++)
#define getindex(type) ((getbyte(type) == 0x83) ? getword(type) : -1)
LOCAL uchar *AllocNewStr (TENTRY *OldEntry, ushort length);
LOCAL ushort MergeLists (ushort, ushort, ushort);
LOCAL void C6CnvtArgList (ushort, ushort);
// These functions are called through the C6ConvertTypeFcn table
LOCAL void C6CnvtPtrType (TENTRY *OldEntry);
LOCAL void C6CnvtBasePtrType (TENTRY *OldEntry);
LOCAL void C6CnvtStructType (TENTRY *OldEntry);
LOCAL void C6CnvtArrayType (TENTRY *OldEntry);
LOCAL void C6CnvtProcType (TENTRY *OldEntry);
LOCAL void C6CnvtNilType (TENTRY *OldEntry);
LOCAL void C6CnvtBitfieldType (TENTRY *OldEntry);
LOCAL void C6CnvtLabelType (TENTRY *OldEntry);
LOCAL void C6CnvtNotTranType (TENTRY *OldEntry);
LOCAL void C6CnvtFString (TENTRY *OldEntry);
LOCAL void C6CnvtBArrayType (TENTRY *OldEntry);
LOCAL void C6CnvtCobTypeRef (TENTRY *OldEntry);
LOCAL void C6CnvtCobol (TENTRY *OldEntry);
extern ushort AddNewSymbols;
extern char ptr32;
typedef struct {
uchar oldtyp; // Old C6 Symbol record type
void (*pfcn) (TENTRY *OldEntry);
} converttypefcn;
converttypefcn C6ConvertTypeFcn[] = {
{OLF_POINTER, C6CnvtPtrType},
{OLF_BASEPTR, C6CnvtBasePtrType},
{OLF_STRUCTURE, C6CnvtStructType},
{OLF_ARRAY, C6CnvtArrayType},
{OLF_PROCEDURE, C6CnvtProcType},
{OLF_NIL, C6CnvtNilType},
{OLF_BITFIELD, C6CnvtBitfieldType},
{OLF_LABEL, C6CnvtLabelType},
{OLF_FSTRING, C6CnvtFString},
{OLF_FARRIDX, C6CnvtNotTranType},
{OLF_BARRAY, C6CnvtBArrayType},
{OLF_COBOLTYPEREF, C6CnvtCobTypeRef},
{OLF_COBOL, C6CnvtCobol},
};
#define C6CONVERTTYPECNT (sizeof C6ConvertTypeFcn / sizeof (C6ConvertTypeFcn[0]))
/**
*
* ConvertObsolete
*
* Given the index to a type string, it performs a conversion if the
* string represents an obsolete record like the pointer, based
* pointer, or structure record.
*
*/
void ConvertObsolete (ushort OldIndex)
{
uchar *TypeString;
TENTRY *OldEntry;
int i;
uchar type;
converttypefcn * pTypeFcn;
CV_typ_t forward;
OldEntry = GetTypeEntry (OldIndex, &forward);
DASSERT(!OldEntry->flags.IsNewFormat);
TypeString = OldEntry->TypeString; // get the string
type = TypeString[3];
for (pTypeFcn = C6ConvertTypeFcn, i = 0; i < C6CONVERTTYPECNT; i++, pTypeFcn++) {
if (pTypeFcn->oldtyp == type) {
break;
}
}
if (i != C6CONVERTTYPECNT) {
pTypeFcn->pfcn (OldEntry);
}
else {
// unexpected C6 type - convert to a nil type
// sps - 12/2/92
Warn (WARN_BADTYP, FormatMod (pCurMod), NULL);
C6CnvtNilType (OldEntry);
}
}
LOCAL void C6CnvtPtrType (TENTRY *OldEntry)
{
uchar * pchTypeStr;
lfPointer NewType;
uchar * pchNew;
ushort usNTotal; // New length of symbol including length field
ushort usNewLength; // New paded length excluding length field.
int i;
OldEntry->flags.IsNewFormat = TRUE;
pchTypeStr = OldEntry->TypeString; // get the string
// calculate new length
// M00SPEED - All of these evaluate to constants
usNTotal = LNGTHSZ + offsetof (lfPointer, pbase);
usNewLength = usNTotal - LNGTHSZ;
// Set constant fields
NewType.leaf = LF_POINTER;
switch (pchTypeStr[4]) { // get old model
case OLF_NEAR :
NewType.attr.ptrtype = CV_PTR_NEAR;
break;
case OLF_FAR :
NewType.attr.ptrtype = CV_PTR_FAR;
break;
case OLF_HUGE :
NewType.attr.ptrtype = CV_PTR_HUGE;
break;
default:
DASSERT(FALSE);
break;
}
NewType.attr.ptrmode = CV_PTR_MODE_PTR;
NewType.attr.isvolatile = FALSE;
NewType.attr.isconst = FALSE;
NewType.attr.isflat32 = ptr32;
NewType.attr.unused = 0;
DASSERT(pchTypeStr[5] == OLF_INDEX);
NewType.utype = *((ushort *)(pchTypeStr + 6));
// Just make sure that the string isn't longer than we expect
DASSERT(usNewLength <= (*((ushort UNALIGNED *)(pchTypeStr + 1)) + 1));
// Copy the new symbol over the old one
*((ushort *)(pchTypeStr))++ = usNewLength;
for (pchNew = (uchar *)&NewType, i = usNTotal - LNGTHSZ; i; i--) {
*pchTypeStr++ = *pchNew++;
}
DASSERT(pchTypeStr == OldEntry->TypeString + usNewLength + LNGTHSZ);
}
LOCAL void C6CnvtBasePtrType (TENTRY *OldEntry)
{
uchar * pchTypeStr;
lfPointer NewType;
ushort usNTotal; // New length of symbol including length field
ushort usNewLength; // New paded length excluding length field.
int i;
ushort usVarOff = 0;
uchar chVarData[MAXSTRLEN+1];
ushort usOldLen; // Length of the old record excluding length and link.
ushort usfSymbolBased = FALSE;
uchar * pchSymStr;
uchar * pchSrc;
uchar * pchDest;
OldEntry->flags.IsNewFormat = TRUE;
pchTypeStr = OldEntry->TypeString; // get the string
usOldLen = *((ushort UNALIGNED *)(pchTypeStr + 1));
// Set constant fields
NewType.leaf = LF_POINTER;
DASSERT(pchTypeStr[4] == OLF_INDEX);
NewType.utype = *((ushort UNALIGNED *)(pchTypeStr + 5));
switch (pchTypeStr[7]) { // get old based type
case OLF_BASESEG :
NewType.attr.ptrtype = CV_PTR_BASE_SEG;
*((ushort *)(chVarData + usVarOff)) = *((ushort *)(pchTypeStr + 8));
usVarOff += 2;
break;
case OLF_BASEVAL :
NewType.attr.ptrtype = CV_PTR_BASE_VAL;
usfSymbolBased = TRUE;
break;
case OLF_BASESEGVAL :
NewType.attr.ptrtype = CV_PTR_BASE_SEGVAL;
usfSymbolBased = TRUE;
break;
case OLF_BASEADR :
NewType.attr.ptrtype = CV_PTR_BASE_ADDR;
usfSymbolBased = TRUE;
break;
case OLF_BASESEGADR :
NewType.attr.ptrtype = CV_PTR_BASE_SEGADDR;
usfSymbolBased = TRUE;
break;
case OLF_BASETYPE :
NewType.attr.ptrtype = CV_PTR_BASE_TYPE;
DASSERT(*((ushort *)(pchTypeStr + 8)) == 0);
// Change to old T_VOID value, then let cnvtprim convert it
*((ushort *)chVarData + usVarOff) = 0x80 + 0x1C;
usVarOff += 2;
*(chVarData + usVarOff) = 0; // Zero length name
usVarOff += 1;
break;
case OLF_BASESELF :
NewType.attr.ptrtype = CV_PTR_BASE_SELF;
break;
default:
DASSERT(FALSE);
break;
}
if (usfSymbolBased) {
// Copy the entire symbol into the type.
// Get the address of the C6 Symbol string.
pchSymStr = GetSymString (*((ushort *)(pchTypeStr + 8))); // get sym string
// Convert the C6 Symbol to a C7 Symbol and put it in the variable data.
usVarOff += C6CnvtSymbol (chVarData + usVarOff, pchSymStr);
}
NewType.attr.ptrmode = CV_PTR_MODE_PTR;
NewType.attr.isvolatile = FALSE;
NewType.attr.isconst = FALSE;
NewType.attr.isflat32 = ptr32;
NewType.attr.unused = 0;
// calculate new length
usNTotal = LNGTHSZ + offsetof (lfPointer, pbase) + usVarOff;
usNewLength = usNTotal - LNGTHSZ;
// Determine where the new symbol goes in memory
if (usNewLength <= usOldLen + 3 - LNGTHSZ) {
pchDest = pchTypeStr; // Copy new symbol over the old
}
else {
pchDest = AllocNewStr (OldEntry, (ushort)(usNewLength + LNGTHSZ));
}
// Copy the symbol length
*((ushort *)(pchDest))++ = usNewLength;
// Copy fixed length portion of structure
for (pchSrc = (uchar *)&NewType, i = offsetof (lfPointer, pbase); i; i--) {
*pchDest++ = *pchSrc++;
}
// Copy variable length data including a name if there is one
for (pchSrc = chVarData, i = usVarOff; i; i--) {
*pchDest++ = *pchSrc++;
}
DASSERT(pchDest == OldEntry->TypeString + usNewLength + LNGTHSZ);
}
LOCAL void C6CnvtStructType (TENTRY *OldEntry)
{
uchar *TypeString;
int index;
uchar *OldString;
ushort Count; // number of fields
ulong Length; // length of structure
int fList; // new field spec list
int i;
CV_prop_t property = {0}; // property byte
plfStructure plf;
uchar chName[MAXSTRLEN + 1];
ushort usNTotal; // New length of symbol including length field
ushort usNewLength; // New paded length excluding length field.
uchar chVarData[MAXNUMERICLEN];
uchar *pchVarData = chVarData;
ushort cbVarNew; // Count of bytes of new variable length field
uchar *pchSrc;
uchar *pchDest;
ushort usOldLen;
ulong ulCount;
OldEntry->flags.IsNewFormat = TRUE;
TypeString = OldEntry->TypeString;
usOldLen = *((ushort UNALIGNED *)(TypeString + 1));
AddNewSymbols = TRUE; //???????
OldString = TypeString;
TypeString += 4;
// get length in bits
Length = C6GetLWordFromNumeric (&TypeString, NULL);
// convert to bytes
if (Length != 0) {
Length = (Length - 1) / 8 + 1;
}
// Convert to new style Numeric
cbVarNew = C7StoreLWordAsNumeric (chVarData, Length);
ulCount = C6GetLWordFromNumeric(&TypeString, NULL);
// If the count is above 64K (it should never be) then make it 64K
Count = ulCount <= 0xFFFFL ? (ushort)ulCount : (ushort)0xFFFF;
index = getindex (TypeString); // tList index
fList = MergeLists ((ushort)index, (ushort)(getindex (TypeString)), Count);
chName[0] = 0;
if (TypeString < OldString + LENGTH (OldString) + 3) {
if (*TypeString == OLF_NAME) {
// name present
TypeString++;
memcpy (chName, TypeString, *TypeString + 1);
TypeString += *TypeString + 1;
if (TypeString < OldString + LENGTH (OldString) + 3) {
property.packed = (char)(*TypeString == OLF_PACKED);
}
else {
property.packed = FALSE;
}
}
else {
property.packed = (char)(*TypeString == OLF_PACKED);
}
}
else {
property.packed = FALSE;
}
// calculate new length
usNTotal = LNGTHSZ + offsetof (lfStructure, data) + cbVarNew + chName[0] + 1;
usNewLength = usNTotal - LNGTHSZ;
// Determine where the new symbol goes in memory
if (usNewLength <= usOldLen + 3 - LNGTHSZ) {
pchDest = OldString; // Copy new symbol over the old
}
else {
pchDest = AllocNewStr (OldEntry, (ushort)(usNewLength + LNGTHSZ));
}
*((ushort *)pchDest)++ = usNewLength;
plf = (plfStructure)pchDest;
plf->leaf = LF_STRUCTURE;
plf->count = Count;
plf->field = fList;
plf->property = property;
plf->derived = 0;
plf->vshape = 0;
pchDest += offsetof (lfStructure, data);
// Copy variable length "length" field
for (pchSrc = chVarData, i = cbVarNew; i > 0; i--) {
*pchDest++ = *pchSrc++;
}
// Copy the name field
for (pchSrc = chName, i = chName[0] + 1; i; i--) {
*pchDest++ = *pchSrc++;
}
DASSERT(pchDest == OldEntry->TypeString + usNewLength + LNGTHSZ);
}
LOCAL void C6CnvtBArrayType (TENTRY *OldEntry)
{
lfBArray NewType;
uchar * pchTypeStr;
uchar * pchTypeStrStart;
uchar * pchSrc;
uchar * pchDest;
ushort usNTotal; // New length of symbol including length field
ushort usNewLength; // New paded length excluding length field.
// UNDONE: usOldLen s/b something meaningful, 0 isn't.
ushort usOldLen = 0; // Length of the old record excluding length and link.
int i;
OldEntry->flags.IsNewFormat = TRUE;
// Walk through old record creating the new one on the stack
pchTypeStrStart = pchTypeStr = OldEntry->TypeString; // get the string
NewType.leaf = LF_BARRAY;
pchTypeStr += 4;
DASSERT(*pchTypeStr == OLF_INDEX);
pchTypeStr++;
NewType.utype = *((ushort *)(pchTypeStr))++;
// calculate new length
usNTotal = sizeof (lfBArray) + LNGTHSZ;
usNewLength = usNTotal - LNGTHSZ;
// Determine where the new symbol goes in memory
if (usNewLength <= usOldLen + 3 - LNGTHSZ) {
pchDest = pchTypeStrStart; // Copy new symbol over the old
}
else {
pchDest = AllocNewStr (OldEntry, (ushort)(usNewLength + LNGTHSZ));
}
// Copy the symbol length
*((ushort *)(pchDest))++ = usNewLength;
// Copy fixed length structure
for (pchSrc = (uchar *)&NewType, i = sizeof (lfBArray); i; i--) {
*pchDest++ = *pchSrc++;
}
}
LOCAL void C6CnvtArrayType (TENTRY *OldEntry)
{
uchar * pchTypeStr;
uchar * pchTypeStrStart;
lfArray NewType;
uchar chVarData[MAXNUMERICLEN];
uchar chName[MAXSTRLEN + 1] = {0};
uchar * pchVarData = chVarData;
uchar * pchSrc;
uchar * pchDest;
ushort usNTotal; // New length of symbol including length field
ushort usNewLength; // New paded length excluding length field.
ushort usOldLen; // Length of the old record excluding length and link.
ushort cbVarNew; // Count of bytes of new variable length field
ushort cbVarOld; // Count of bytes of old variable length field
ulong ulLength;
int i;
OldEntry->flags.IsNewFormat = TRUE;
// Walk through old record creating the new one on the stack
pchTypeStrStart = pchTypeStr = OldEntry->TypeString; // get the string
NewType.leaf = LF_ARRAY;
pchTypeStr += 4; // Advance to the length field
// get length in bits
ulLength = C6GetLWordFromNumeric (&pchTypeStr, &cbVarOld);
// convert to bytes
ulLength = ulLength >> 3;
// Convert to new style Numeric
cbVarNew = C7StoreLWordAsNumeric (pchVarData, ulLength);
DASSERT(cbVarNew <= MAXNUMERICLEN);
DASSERT(*pchTypeStr == OLF_INDEX);
pchTypeStr++;
NewType.elemtype = *((ushort *)(pchTypeStr))++;
// Copy the index type if one was supplied
usOldLen = *((ushort UNALIGNED *)(pchTypeStrStart + 1));
if (usOldLen > (ushort)4 + cbVarOld) {
DASSERT(*pchTypeStr == OLF_INDEX);
pchTypeStr++;
NewType.idxtype = *((ushort *)(pchTypeStr))++;
}
else{
NewType.idxtype = 0x80 + 0x05; // Old C7 T_USHORT value
}
// Copy the optional name or create a zero length one
if (usOldLen > (ushort)(4 + cbVarOld + 3)) {
// Old type does contain an optional name
if (*pchTypeStr == OLF_NAME) {
pchTypeStr++;
}
memcpy (chName, pchTypeStr, *pchTypeStr);
}
// calculate new length
usNTotal = LNGTHSZ + offsetof (lfArray, data) + cbVarNew + chName[0] + 1;
usNewLength = usNTotal - LNGTHSZ;
// Determine where the new symbol goes in memory
if (usNewLength <= usOldLen + 3 - LNGTHSZ) {
pchDest = pchTypeStrStart; // Copy new symbol over the old
}
else {
pchDest = AllocNewStr (OldEntry, (ushort)(usNewLength + LNGTHSZ));
}
// Copy the symbol length
*((ushort *)(pchDest))++ = usNewLength;
// Copy fixed length structure
for (pchSrc = (uchar *)&NewType, i = offsetof (lfArray, data); i; i--) {
*pchDest++ = *pchSrc++;
}
// Copy variable length "length" field
for (pchSrc = chVarData, i = cbVarNew; i; i--) {
*pchDest++ = *pchSrc++;
}
// Copy the name field
for (pchSrc = chName, i = chName[0] + 1; i; i--) {
*pchDest++ = *pchSrc++;
}
}
LOCAL void C6CnvtFString (TENTRY *OldEntry)
{
lfArray NewType;
uchar *pchTypeStr;
ushort usNTotal; // New length of symbol including length field
ushort usNewLength; // New paded length excluding length field.
ulong ulLength;
ushort cbVarNew; // Count of bytes of new variable length field
ushort cbVarOld; // Count of bytes of old variable length field
uchar chVarData[MAXNUMERICLEN];
uchar * pchVarData = chVarData;
uchar * pchSrc;
uchar * pchDest;
ushort i;
OldEntry->flags.IsNewFormat = TRUE;
pchTypeStr = OldEntry->TypeString;
switch (*(pchTypeStr + 4)) {
case 0:
// fixed length string
pchTypeStr += 5;
ulLength = C6GetLWordFromNumeric (&pchTypeStr, &cbVarOld);
cbVarNew = C7StoreLWordAsNumeric (pchVarData, ulLength);
DASSERT(cbVarNew <= MAXNUMERICLEN);
NewType.leaf = LF_ARRAY;
NewType.elemtype = T_CHAR;
NewType.idxtype = T_USHORT;
// calculate new length
usNTotal = LNGTHSZ + offsetof (lfArray, data) + cbVarNew + 1;
usNewLength = usNTotal - LNGTHSZ;
pchDest = AllocNewStr (OldEntry, usNTotal);
// Copy the symbol length, fixed data, array length and null name
*((ushort *)(pchDest))++ = usNewLength;
for (pchSrc = (uchar *)&NewType, i = offsetof (lfArray, data); i; i--) {
*pchDest++ = *pchSrc++;
}
for (pchSrc = chVarData, i = cbVarNew; i; i--) {
*pchDest++ = *pchSrc++;
}
*pchDest++ = 0;
break;
case 1:
// variable length string
*((ushort *)pchTypeStr)++ = 2;
*((ushort *)pchTypeStr)++ = LF_NOTTRAN;
break;
default:
// unrecognized tag
DASSERT(FALSE);
break;
}
}
LOCAL void C6CnvtProcType (TENTRY *OldEntry)
{
uchar *pchDest;
uchar *pchTypeStr;
lfProc NewType;
ushort usNTotal; // New length of symbol including length field
ushort usNewLength; // New paded length excluding length field.
ulong ulCount;
OldEntry->flags.IsNewFormat = TRUE;
pchTypeStr = OldEntry->TypeString; // get the string
// calculate new length
usNTotal = LNGTHSZ + sizeof (lfProc);
usNewLength = usNTotal - LNGTHSZ;
// Set constant fields
NewType.leaf = LF_PROCEDURE;
pchTypeStr += 5;
if (*pchTypeStr == OLF_INDEX) {
pchTypeStr++;
NewType.rvtype = *((ushort *)(pchTypeStr))++;
}
else {
NewType.rvtype = *pchTypeStr;
pchTypeStr++;
}
switch (*pchTypeStr++) { // get old call type
case 0x63 :
NewType.calltype = CV_CALL_NEAR_C;
break;
case 0x64 :
NewType.calltype = CV_CALL_FAR_C;
break;
case 0x73 :
NewType.calltype = CV_CALL_FAR_PASCAL;
break;
case 0x74 :
NewType.calltype = CV_CALL_NEAR_PASCAL;
break;
case 0x95 :
NewType.calltype = CV_CALL_NEAR_FAST;
break;
case 0x96 :
NewType.calltype = CV_CALL_FAR_FAST;
break;
case 0x97 :
NewType.calltype = CV_CALL_SKIPPED;
break;
default:
DASSERT(FALSE);
break;
}
NewType.reserved = 0;
ulCount = C6GetLWordFromNumeric (&pchTypeStr, NULL);
NewType.parmcount = (ulCount <= 0xFFFFL) ? (ushort)ulCount : (ushort)0xFFFF;
DASSERT(*pchTypeStr == OLF_INDEX);
pchTypeStr++;
if (NewType.parmcount) {
NewType.arglist = *((ushort *)pchTypeStr);
// Go ahead and convert the arglist type also
C6CnvtArgList(NewType.arglist, NewType.parmcount);
}
else {
NewType.arglist = ZEROARGTYPE; // Reference our own internal predefined type
}
if (usNewLength <= *((ushort UNALIGNED *)(pchTypeStr + 1)) + 3 - LNGTHSZ) {
pchDest = OldEntry->TypeString;
}
else {
pchDest = AllocNewStr (OldEntry, (ushort)(usNewLength + LNGTHSZ));
}
*((ushort *)(pchDest))++ = usNewLength;
*((lfProc *)(pchDest))++ = NewType;
DASSERT(pchDest == OldEntry->TypeString + usNewLength + LNGTHSZ);
}
/**
*
* MergeLists
*
* Given the indices to a type index list, a name offset list, and
* a count, this routine converts them into a field specification
* list with member fields and returns an index to the new list.
*
*/
LOCAL ushort MergeLists (ushort tList, ushort nList, ushort Count)
{
uchar *TypeIndexString, *NameOffsetString;
uchar *ScratchString; // temporary work
uchar *ScratchSave;
uchar *OffsetStart;
ushort Length;
ushort FinalLength;
int i;
CV_fldattr_t mattrib = {0};
TENTRY *TypeEntry, *NameEntry;
CV_typ_t forward;
mattrib.access = CV_public; // public access field
TypeEntry = GetTypeEntry ((CV_typ_t)(tList - 512), &forward);
NameEntry = GetTypeEntry ((CV_typ_t)(nList - 512), &forward);
// Get the two strings to walk
TypeIndexString = TypeEntry->TypeString;
NameOffsetString = NameEntry->TypeString;
// Calculate the longest possible result
// We are intentionally wasting memory to avoid walking the list
// two times.
Length = LNGTHSZ // Size of length field
+ MAXPAD // So we can align the start
+ offsetof (lfFieldList, data) // Field leaf size
+ (LENGTH (NameOffsetString) - 1) // Variable length data size
+ (Count // Number of fields times
* (offsetof (lfMember, offset) // Size LF_MEMBER structure plus
+ MAXPAD // Maximum number of pad bytes per field
+ MAXC6NUMERICGROWTH)); // Maximum possible growth of numeric field
TypeIndexString += 4; // skip to indices
NameOffsetString += 4; // skip to names
ScratchString = GetScratchString (Length); // get a scratch string
//M00SPEED This logic could be moved to GetScratchSize
// This garantees we can do padding when running with any malloc version
while((ulong)ScratchString & MAXPAD) { // Make sure buffer starts on a four byte boundry
ScratchString++;
}
ScratchSave = ScratchString;
// Start building new C7 field list
ScratchString += LNGTHSZ; // Skip Length (fill in later with exact size)
*((ushort *)ScratchString)++ = LF_FIELDLIST;
for (; Count > 0; Count --) {
DASSERT(*NameOffsetString == OLF_NAME);
DASSERT(*TypeIndexString == OLF_INDEX);
NameOffsetString ++; // skip OLF_NAME
*((ushort *)ScratchString)++ = LF_MEMBER;
*((ushort *)ScratchString)++ = getindex (TypeIndexString);
*((CV_fldattr_t *)ScratchString)++ = mattrib;
// Temporarily skip over the string
OffsetStart = NameOffsetString + *NameOffsetString + 1;
ConvertNumeric (&OffsetStart, &ScratchString);
// copy over the name
for (i = *NameOffsetString + 1; i; i --) {
*ScratchString ++ = *NameOffsetString ++;
}
// update the name offset string
NameOffsetString = OffsetStart;
// Pad the new leaf
if ((ulong)ScratchString & MAXPAD) {
*ScratchString = (uchar)(0xF0 + MAXPAD + 1 - ((ulong)ScratchString & MAXPAD));
while((ulong)(++ScratchString) & MAXPAD) {
*ScratchString = 0;
}
}
}
TypeIndexString = TypeEntry->TypeString;
NameOffsetString = NameEntry->TypeString;
FinalLength = ScratchString - ScratchSave;
DASSERT(FinalLength <= Length);
*((ushort *)(ScratchSave)) = FinalLength - LNGTHSZ;
// Allocate memory and copy the type string into it
TypeIndexString = AllocNewStr (TypeEntry, FinalLength);
TypeEntry->flags.IsNewFormat = TRUE;
memcpy (TypeIndexString, ScratchSave, FinalLength);
return (tList);
}
LOCAL void C6CnvtArgList (ushort usArgList, ushort usCount)
{
uchar * pchTypeStr;
uchar * pchTypeStrBase; // The base of the original type string
plfArgList plf;
ushort usNTotal; // New length of symbol including length field
ushort usNewLength; // New paded length excluding length field.
ushort usfInTmp; // True if string stored in temporary buffer
uchar * pchDest;
ushort i;
uchar * pchDestBase;
TENTRY *OldEntry;
CV_typ_t forward;
OldEntry = GetTypeEntry ((CV_typ_t)(usArgList - 512), &forward);
if (OldEntry->flags.IsNewFormat) {
return;
}
OldEntry->flags.IsNewFormat = TRUE;
pchTypeStr = OldEntry->TypeString; // get the string
pchTypeStrBase = pchTypeStr;
DASSERT((pchTypeStr[3] == OLF_LIST) || (pchTypeStr[3] == OLF_ARGLIST) ||
((usCount != 0) && (pchTypeStr[3] == OLF_NIL)));
// calculate new length
usNTotal = LNGTHSZ + offsetof (lfArgList, arg) + (sizeof(CV_typ_t) * usCount);
usNewLength = usNTotal - LNGTHSZ;
// Get some memory to put the result in
if (usNewLength + LNGTHSZ <= LENGTH (pchTypeStr) + 3) {
// Get some scratch memory so we don't wipe out the memory we are
// are attempting to rewrite.
usfInTmp = TRUE;
pchDest = GetScratchString (usNewLength + LNGTHSZ);
}
else {
usfInTmp = FALSE;
pchDest = Alloc (usNewLength + LNGTHSZ);
}
pchDestBase = pchDest;
pchTypeStr += 4; // Skip to the arguments;
*((ushort*)pchDest)++ = usNewLength;
plf = (plfArgList) pchDest;
plf->leaf = LF_ARGLIST;
plf->count = usCount;
// Loop through copying the indexes from the old to the new.
for (i = 0; i < usCount; i++) {
plf->arg[i] = getindex (pchTypeStr);
}
pchDest = (uchar *) &(plf->arg[i]);
if (usfInTmp) {
// Copy the new string over the old one
memcpy (OldEntry->TypeString, pchDestBase, usNewLength + LNGTHSZ);
DASSERT(pchDest == pchDestBase + usNewLength + LNGTHSZ);
}
else {
FreeAllocStrings (OldEntry);
OldEntry->flags.IsMalloced = TRUE;
OldEntry->TypeString = pchDestBase;
DASSERT(pchDest == OldEntry->TypeString + usNewLength + LNGTHSZ);
}
}
LOCAL void C6CnvtNilType (TENTRY *OldEntry)
{
uchar * pchTypeStr;
DASSERT(!OldEntry->flags.IsNewFormat);
OldEntry->flags.IsNewFormat = TRUE;
pchTypeStr = OldEntry->TypeString; // get the string
*((ushort *)pchTypeStr)++ = 2; // Length of leaf
*((ushort *)pchTypeStr)++ = LF_NULL; // The leaf
}
LOCAL void C6CnvtNotTranType (TENTRY *OldEntry)
{
uchar * pchTypeStr;
DASSERT(!OldEntry->flags.IsNewFormat);
//M00BUG - Should add a warning that a type wasn't translated.
OldEntry->flags.IsNewFormat = TRUE;
pchTypeStr = OldEntry->TypeString; // get the string
*((ushort *)pchTypeStr)++ = 2; // Length of leaf
*((ushort *)pchTypeStr)++ = LF_NOTTRAN; // The leaf
}
LOCAL void C6CnvtLabelType (TENTRY *OldEntry)
{
uchar * pchTypeStr;
plfLabel pNewType;
uchar * pchDest;
uchar * pchDestBase; // The start of the new string
ushort usNTotal; // New length of symbol including length field
ushort usNewLength; // New paded length excluding length field.
DASSERT(!OldEntry->flags.IsNewFormat);
OldEntry->flags.IsNewFormat = TRUE;
pchTypeStr = OldEntry->TypeString; // get the string
// calculate new length
// M00SPEED These are all constants
usNTotal = LNGTHSZ + sizeof(lfLabel);
usNewLength = usNTotal - LNGTHSZ;
// Get memory for new type
pchDest = Alloc (usNewLength + LNGTHSZ);
pchDestBase = pchDest;
pNewType = (plfLabel)(pchDest + LNGTHSZ);
// Insert the new length and new type
*((ushort *)pchDest) = usNewLength;
pNewType->leaf = LF_LABEL;
// 0x73 == old LF_FAR, 0x74 == old LF_NEAR
//Make sure the code label is one of the two types
DASSERT(*(pchTypeStr + 5) == 0x73 || *(pchTypeStr + 5) == 0x74);
// Get the new type
if (*(pchTypeStr + 5) == 0x73) {
pNewType->mode = CV_LABEL_FAR;
}
else {
pNewType->mode = CV_LABEL_NEAR;
}
pchDest += LNGTHSZ + sizeof (lfLabel);
// Change entry to point to the new string
FreeAllocStrings (OldEntry);
OldEntry->flags.IsMalloced = TRUE;
OldEntry->TypeString = pchDestBase;
DASSERT(pchDest == OldEntry->TypeString + *((ushort *)(OldEntry->TypeString)) + LNGTHSZ);
}
LOCAL void C6CnvtBitfieldType (TENTRY *OldEntry)
{
uchar * pchTypeStr;
uchar * pchTypeStrStart;
plfBitfield pNewType;
uchar * pchDest;
ushort usNTotal; // New length of symbol including length field
ushort usNewLength; // New paded length excluding length field.
OldEntry->flags.IsNewFormat = TRUE;
// calculate new length
// M00SPEED These are all constants
usNTotal = LNGTHSZ + sizeof(lfBitfield);
usNewLength = usNTotal - LNGTHSZ;
pchTypeStrStart = pchTypeStr = OldEntry->TypeString; // get the string
pchTypeStr += 4; // Advance to the length field
// Get memory for new type
pchDest = Alloc (usNewLength + LNGTHSZ);
pNewType = (plfBitfield)(pchDest + LNGTHSZ);
// Insert the new length and new type
*((ushort *)pchDest) = usNewLength;
pNewType->leaf = LF_BITFIELD;
// Copy the length in bits of the object
pNewType->length = *pchTypeStr++;
// Copy the base type
// Note that 0x7c was UNSINT and 0x7d was SGNINT, in CV3 days.
DASSERT(*pchTypeStr == 0x7c || *pchTypeStr == 0x7d);
DASSERT(pNewType->length <= 32);
if (pNewType->length <= 16) {
pNewType->type = (*pchTypeStr++ == 0x7d) ? T_SHORT : T_USHORT;
}
else {
pNewType->type = (*pchTypeStr++ == 0x7d) ? T_LONG : T_ULONG;
}
// Copy bit position in the byte, word, ect.
pNewType->position = *pchTypeStr++;
// Change entry to point to the new string
FreeAllocStrings (OldEntry);
OldEntry->flags.IsMalloced = TRUE;
OldEntry->TypeString = pchDest;
pchDest += LNGTHSZ + sizeof (lfBitfield);
DASSERT(pchDest == OldEntry->TypeString + *((ushort *)(OldEntry->TypeString)) + LNGTHSZ);
}
/** AllocNewStr - allocate new type string buffer
*
* Entry OldEntry = pointer to type entry structure
* length = length of new type string
*
* Exit OldEntry->TypeString freed and new buffer allocated
*
* Returns pointer to new string
*/
LOCAL uchar *AllocNewStr (TENTRY *OldEntry, ushort length)
{
uchar *pNew;
if ((length + LNGTHSZ) > POOL2SIZE) {
pNew = Alloc (length + LNGTHSZ);
}
else if ((length + LNGTHSZ) > POOLSIZE) {
pNew = Pool2Alloc ();
}
else {
pNew = PoolAlloc ();
}
FreeAllocStrings (OldEntry);
if ((length + LNGTHSZ) > POOL2SIZE) {
OldEntry->flags.IsMalloced = TRUE;
}
else if ((length + LNGTHSZ) > POOLSIZE) {
OldEntry->flags.IsPool2 = TRUE;
}
else {
OldEntry->flags.IsPool = TRUE;
}
OldEntry->TypeString = pNew;
return (pNew);
}
LOCAL void C6CnvtCobTypeRef (TENTRY *OldEntry)
{
uchar * pchTypeStr;
uchar * pchDest;
ushort usNTotal; // New length of symbol including length field
ushort usNewLength; // New paded length excluding length field.
plfCobol0 pNewType;
DASSERT(!OldEntry->flags.IsNewFormat);
IsMFCobol = TRUE;
OldEntry->flags.IsNewFormat = TRUE;
pchTypeStr = OldEntry->TypeString;
// calculate new length. Since all we are doing is copying the old
// data, we just increase the length by to allow for large record type
usNTotal = LNGTHSZ + *((ushort UNALIGNED *)(pchTypeStr + 1)) + 1;
usNewLength = usNTotal - LNGTHSZ;
// Get memory for new type
pchDest = Alloc (usNTotal);
pNewType = (plfCobol0)(pchDest + LNGTHSZ);
// Insert the new length and new type and copy the remainder of
// of the type string over
*((ushort *)pchDest) = usNewLength;
pNewType->leaf = LF_COBOL0;
memmove (&pNewType->type, pchTypeStr + 4, *((ushort UNALIGNED *)(pchTypeStr + 1)) - 1);
// Change entry to point to the new string
FreeAllocStrings (OldEntry);
OldEntry->flags.IsMalloced = TRUE;
OldEntry->TypeString = pchDest;
}
LOCAL void C6CnvtCobol (TENTRY *OldEntry)
{
uchar * pchTypeStr;
uchar * pchDest;
ushort usNTotal; // New length of symbol including length field
ushort usNewLength; // New paded length excluding length field.
plfCobol1 pNewType;
DASSERT(!OldEntry->flags.IsNewFormat);
IsMFCobol = TRUE;
OldEntry->flags.IsNewFormat = TRUE;
pchTypeStr = OldEntry->TypeString;
// calculate new length. Since all we are doing is copying the old
// data, we just increase the length by to allow for large record type
usNTotal = LNGTHSZ + *((ushort UNALIGNED *)(pchTypeStr + 1)) + 1;
usNewLength = usNTotal - LNGTHSZ;
// Get memory for new type
pchDest = Alloc (usNTotal);
pNewType = (plfCobol1)(pchDest + LNGTHSZ);
// Insert the new length and new type and copy the remainder of
// of the type string over
*((ushort *)pchDest) = usNewLength;
pNewType->leaf = LF_COBOL1;
memmove (&pNewType->data, pchTypeStr + 4, *((ushort UNALIGNED *)(pchTypeStr + 1)) - 1);
// Change entry to point to the new string
FreeAllocStrings (OldEntry);
OldEntry->flags.IsMalloced = TRUE;
OldEntry->TypeString = pchDest;
}