/** 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; }