791 lines
20 KiB
C
791 lines
20 KiB
C
|
//
|
||
|
// readbsc.c -- read in a .BSC file and install in mbrmake's vm space
|
||
|
//
|
||
|
// Copyright <C> 1988, Microsoft Corporation
|
||
|
//
|
||
|
// Revision History:
|
||
|
//
|
||
|
// 13-Aug-1989 rm Extracted from mbrapi.c
|
||
|
//
|
||
|
|
||
|
#define LINT_ARGS
|
||
|
|
||
|
#include "mbrmake.h"
|
||
|
|
||
|
#include <stddef.h>
|
||
|
|
||
|
#include "mbrcache.h"
|
||
|
|
||
|
#include "sbrfdef.h" // sbr attributes
|
||
|
#include "sbrbsc.h"
|
||
|
|
||
|
typedef struct _sbrinfo {
|
||
|
WORD fUpdate;
|
||
|
WORD isbr;
|
||
|
} SI, far *LPSI; // sbr info
|
||
|
|
||
|
#define LISTALLOC 50 // Browser max list size
|
||
|
|
||
|
typedef WORD IDX;
|
||
|
|
||
|
// these will be initialized by the reading of the .bsc file
|
||
|
//
|
||
|
// fCase; TRUE for case compare
|
||
|
// MaxSymLen; longest symbol length
|
||
|
// ModCnt; count of modules
|
||
|
// SbrCnt; count of sbr files
|
||
|
// vaUnknownSym; unknown symbol
|
||
|
// vaUnknownMod; unknown module
|
||
|
//
|
||
|
|
||
|
// static data
|
||
|
|
||
|
static BOOL fIncremental; // update will be incremental
|
||
|
static BOOL fFoundSBR; // at least .sbr file matched
|
||
|
|
||
|
static int fhBSC = 0; // .BSC file handle
|
||
|
|
||
|
static IDX Unknown; // UNKNOWN symbol index
|
||
|
|
||
|
static WORD ModSymCnt; // count of modsyms
|
||
|
static WORD SymCnt; // count of symbols
|
||
|
static WORD PropCnt; // count of properties
|
||
|
static DWORD RefCnt; // count of references
|
||
|
static WORD DefCnt; // count of definitions
|
||
|
static WORD CalCnt; // count of calls
|
||
|
static WORD CbyCnt; // count of called bys
|
||
|
static WORD lastAtomPage; // last atom page #
|
||
|
static WORD lastAtomCnt; // last atom page size
|
||
|
|
||
|
static WORD cbModSymCnt; // size of list of modsyms
|
||
|
static WORD cbSymCnt; // size of list of symbols
|
||
|
static WORD cbPropCnt; // size of list of properties
|
||
|
static WORD cbRefCnt; // size of list of references
|
||
|
static WORD cbDefCnt; // size of list of definitions
|
||
|
static WORD cbCalCnt; // size of list of calls
|
||
|
static WORD cbCbyCnt; // size of list of called bys
|
||
|
|
||
|
static WORD MaxModSymCnt; // max list of modsyms
|
||
|
static WORD MaxSymCnt; // max list of symbols
|
||
|
static WORD MaxPropCnt; // max list of properties
|
||
|
static WORD MaxRefCnt; // max list of references
|
||
|
static WORD MaxDefCnt; // max list of definitions
|
||
|
static WORD MaxCalCnt; // max list of calls
|
||
|
static WORD MaxCbyCnt; // max list of called bys
|
||
|
|
||
|
static DWORD lbModSymList; // modsym list file start
|
||
|
static DWORD lbSymList; // symbol list file start
|
||
|
static DWORD lbPropList; // property list file start
|
||
|
static DWORD lbRefList; // reference list file start
|
||
|
static DWORD lbDefList; // defintion list file start
|
||
|
static DWORD lbCalList; // call list file start
|
||
|
static DWORD lbCbyList; // called by list file start
|
||
|
static DWORD lbSbrList; // sbr list file start
|
||
|
static DWORD lbAtomCache; // atom cache file start
|
||
|
|
||
|
static WORD CurModSymPage = 0; // Current page of modsyms
|
||
|
static WORD CurSymPage = 0; // Current page of symbols
|
||
|
static WORD CurPropPage = 0; // Current page of properties
|
||
|
static WORD CurRefPage = 0; // Current page of references
|
||
|
static WORD CurDefPage = 0; // Current page of defintions
|
||
|
static WORD CurCalPage = 0; // Current page of calls
|
||
|
static WORD CurCbyPage = 0; // Current page of called bys
|
||
|
|
||
|
static LSZ lszBSCName = NULL; // name of .bsc file
|
||
|
|
||
|
static MODLIST far *pfModList; // module list cache start
|
||
|
static MODSYMLIST far *pfModSymList; // modsym list cache start
|
||
|
static SYMLIST far *pfSymList; // symbol list cache start
|
||
|
static PROPLIST far *pfPropList; // property list cache start
|
||
|
static REFLIST far *pfRefList; // reference list cache start
|
||
|
static REFLIST far *pfDefList; // def'n list cache start
|
||
|
static USELIST far *pfCalList; // calls list cache start
|
||
|
static USELIST far *pfCbyList; // call bys list cache start
|
||
|
|
||
|
static WORD AtomPageTblMac; // last cache page used
|
||
|
static CACHEPAGE AtomPageTbl[MAXATOMPAGETBL]; // Atom Cache table
|
||
|
|
||
|
#define bMOD(imod) (pfModList[imod])
|
||
|
#define bMODSYM(isym) (pfModSymList[ModSymPAGE(isym)])
|
||
|
#define bSYM(isym) (pfSymList[SymPAGE(isym)])
|
||
|
#define bPROP(iprop) (pfPropList[PropPAGE(iprop)])
|
||
|
|
||
|
#define bREF(iref) (pfRefList[RefPAGE(iref)])
|
||
|
#define bDEF(idef) (pfDefList[DefPAGE(idef)])
|
||
|
|
||
|
#define bCAL(iuse) (pfCalList[CalPAGE(iuse)])
|
||
|
#define bCBY(iuse) (pfCbyList[CbyPAGE(iuse)])
|
||
|
#define bUSE(iuse) (pfCalList[CalPAGE(iuse)])
|
||
|
#define bUBY(iuse) (pfCbyList[CbyPAGE(iuse)])
|
||
|
|
||
|
#define BSCIn(v) ReadBSC(&v, sizeof(v))
|
||
|
|
||
|
// prototypes
|
||
|
//
|
||
|
|
||
|
static VOID GetBSCLsz(LSZ lsz);
|
||
|
static VOID GetBSC (DWORD lpos, LPV lpv, WORD cb);
|
||
|
static VOID ReadBSC(LPV lpv, WORD cb);
|
||
|
static IDX SwapPAGE (DWORD, LPV, WORD, WORD, WORD *, DWORD);
|
||
|
static LPCH GetAtomCache (WORD);
|
||
|
static WORD ModSymPAGE(WORD idx);
|
||
|
static WORD SymPAGE(WORD idx);
|
||
|
static WORD PropPAGE(WORD idx);
|
||
|
static WORD RefPAGE(DWORD idx);
|
||
|
static WORD DefPAGE(WORD idx);
|
||
|
static WORD CalPAGE(WORD idx);
|
||
|
static WORD CbyPAGE(WORD idx);
|
||
|
static LSZ LszNameFrIsym(WORD isym);
|
||
|
static LPSI LpsiCreate(VOID);
|
||
|
|
||
|
static VOID
|
||
|
GetBSCLsz(LSZ lsz)
|
||
|
// read a null terminated string from the current position in the BSC file
|
||
|
//
|
||
|
{
|
||
|
for (;;) {
|
||
|
if (read(fhBSC, lsz, 1) != 1)
|
||
|
ReadError(lszBSCName);
|
||
|
if (*lsz++ == 0) return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static VOID
|
||
|
ReadBSC(LPV lpv, WORD cb)
|
||
|
// read a block of data from the BSC file
|
||
|
//
|
||
|
// the requested number of bytes MUST be present
|
||
|
//
|
||
|
{
|
||
|
if (read(fhBSC, lpv, cb) != (int)cb)
|
||
|
ReadError(lszBSCName);
|
||
|
}
|
||
|
|
||
|
static VOID
|
||
|
GetBSC(DWORD lpos, LPV lpv, WORD cb)
|
||
|
// Read a block of the specified size from the specified position
|
||
|
//
|
||
|
// we have to be tolerant of EOF here because the swapper might ask
|
||
|
// for a whole block when only block when only part of a block is actually
|
||
|
// is actually present
|
||
|
//
|
||
|
{
|
||
|
if (lseek(fhBSC, lpos, SEEK_SET) == -1)
|
||
|
SeekError(lszBSCName);
|
||
|
|
||
|
if (read(fhBSC, lpv, cb) == -1)
|
||
|
ReadError(lszBSCName);
|
||
|
}
|
||
|
|
||
|
static IDX
|
||
|
SwapPAGE (DWORD lbuflist, LPV pfTABLE, WORD tblsiz,
|
||
|
/* */ WORD lstsiz, WORD * pcurpage, DWORD idx)
|
||
|
// SwapPAGE - Swap in the table page for the table pfTABLE[idx]
|
||
|
// and return the table's new index in the page.
|
||
|
{
|
||
|
WORD page;
|
||
|
IDX newidx;
|
||
|
|
||
|
page = (WORD)(idx / lstsiz);
|
||
|
newidx = (WORD)(idx % lstsiz);
|
||
|
|
||
|
if (page == *pcurpage)
|
||
|
return newidx;
|
||
|
|
||
|
GetBSC(lbuflist+((long)tblsiz*(long)page), pfTABLE, tblsiz);
|
||
|
|
||
|
*pcurpage = page;
|
||
|
return newidx;
|
||
|
}
|
||
|
|
||
|
static IDX
|
||
|
ModSymPAGE (IDX idx)
|
||
|
// Swap in the ModSym page for ModSym[idx]
|
||
|
// return the ModSym's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbModSymList, pfModSymList,
|
||
|
cbModSymCnt, MaxModSymCnt, &CurModSymPage, (DWORD)idx);
|
||
|
}
|
||
|
|
||
|
static IDX
|
||
|
SymPAGE (IDX idx)
|
||
|
// Swap in the Symbol page for symbol[idx]
|
||
|
// return the Symbol's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbSymList, pfSymList,
|
||
|
cbSymCnt, MaxSymCnt, &CurSymPage, (DWORD)idx);
|
||
|
}
|
||
|
|
||
|
static IDX
|
||
|
PropPAGE (IDX idx)
|
||
|
// Swap in the Property page for Property[idx]
|
||
|
// return the Property's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbPropList, pfPropList,
|
||
|
cbPropCnt, MaxPropCnt, &CurPropPage, (DWORD)idx);
|
||
|
}
|
||
|
|
||
|
static IDX
|
||
|
RefPAGE (DWORD idx)
|
||
|
// Swap in the Reference page for Reference[idx] (ref/def)
|
||
|
// return the Reference's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbRefList, pfRefList,
|
||
|
cbRefCnt, MaxRefCnt, &CurRefPage, idx);
|
||
|
}
|
||
|
|
||
|
static IDX
|
||
|
DefPAGE (IDX idx)
|
||
|
// Swap in the Reference page for Defintions[idx] (ref/def)
|
||
|
// return the Reference's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbDefList, pfDefList,
|
||
|
cbDefCnt, MaxDefCnt, &CurDefPage, (DWORD)idx);
|
||
|
}
|
||
|
|
||
|
static IDX
|
||
|
CalPAGE (IDX idx)
|
||
|
// Swap in the Usage page for Usage[idx] (cal/cby)
|
||
|
// and return the Usage's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbCalList, pfCalList,
|
||
|
cbCalCnt, MaxCalCnt, &CurCalPage, (DWORD)idx);
|
||
|
}
|
||
|
|
||
|
static IDX
|
||
|
CbyPAGE (IDX idx)
|
||
|
// Swap in the Usage page for Usage[idx] (cal/cby)
|
||
|
// and return the Usage's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbCbyList, pfCbyList,
|
||
|
cbCbyCnt, MaxCbyCnt, &CurCbyPage, (DWORD)idx);
|
||
|
}
|
||
|
|
||
|
static LPCH
|
||
|
GetAtomCache (WORD Page)
|
||
|
// load the requested page into the cache
|
||
|
//
|
||
|
{
|
||
|
WORD ipg;
|
||
|
WORD pagesize;
|
||
|
LPCH pfAtomCsave;
|
||
|
|
||
|
for (ipg = 0; ipg < AtomPageTblMac; ipg++) {
|
||
|
if (AtomPageTbl[ipg].uPage == Page)
|
||
|
return AtomPageTbl[ipg].pfAtomCache;
|
||
|
}
|
||
|
if (ipg == AtomPageTblMac && ipg != MAXATOMPAGETBL)
|
||
|
AtomPageTblMac++;
|
||
|
|
||
|
pfAtomCsave = AtomPageTbl[MAXATOMPAGETBL-1].pfAtomCache;
|
||
|
for (ipg = MAXATOMPAGETBL-1; ipg; ipg--)
|
||
|
AtomPageTbl[ipg] = AtomPageTbl[ipg-1]; // move up
|
||
|
|
||
|
AtomPageTbl[0].pfAtomCache = pfAtomCsave;
|
||
|
AtomPageTbl[0].uPage = Page;
|
||
|
|
||
|
if (Page == lastAtomPage)
|
||
|
pagesize = lastAtomCnt;
|
||
|
else
|
||
|
pagesize = ATOMALLOC;
|
||
|
|
||
|
GetBSC(lbAtomCache+ATOMALLOC*(long)Page,
|
||
|
AtomPageTbl[0].pfAtomCache, pagesize);
|
||
|
|
||
|
return AtomPageTbl[0].pfAtomCache;
|
||
|
}
|
||
|
|
||
|
static LSZ
|
||
|
LszNameFrIsym (IDX isym)
|
||
|
// Swap in the Atom page for the symbol isym
|
||
|
// return the atom's address in the page.
|
||
|
//
|
||
|
{
|
||
|
SYMLIST sym;
|
||
|
|
||
|
sym = bSYM(isym);
|
||
|
return GetAtomCache (sym.Page) + sym.Atom;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
CloseBSC()
|
||
|
// close database and free as much memory as possible
|
||
|
// return TRUE iff successful.
|
||
|
//
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
if (fhBSC) { // if open then close, & free memory
|
||
|
|
||
|
FreeLpv (pfModList); // module table
|
||
|
FreeLpv (pfModSymList); // modsym table
|
||
|
FreeLpv (pfSymList); // symbol table
|
||
|
FreeLpv (pfPropList); // property table
|
||
|
FreeLpv (pfRefList); // reference table
|
||
|
FreeLpv (pfDefList); // definition table
|
||
|
FreeLpv (pfCalList); // call table
|
||
|
FreeLpv (pfCbyList); // called by table
|
||
|
|
||
|
for (i=0; i < MAXATOMPAGETBL; i++)
|
||
|
FreeLpv (AtomPageTbl[i].pfAtomCache); // dispose Atom Cache
|
||
|
|
||
|
close (fhBSC);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
FOpenBSC (LSZ lszName)
|
||
|
// Open the specified data base.
|
||
|
// Allocate buffers for cache areas
|
||
|
// Initialize the data cache from the data base.
|
||
|
//
|
||
|
// Return TRUE iff successful, FALSE if database can't be read
|
||
|
//
|
||
|
{
|
||
|
int i;
|
||
|
WORD pagesize;
|
||
|
|
||
|
BYTE MajorVer; // .bsc version (major)
|
||
|
BYTE MinorVer; // .bsc version (minor)
|
||
|
BYTE UpdatVer; // .bsc version (updat)
|
||
|
|
||
|
WORD MaxModCnt; // max list of modules
|
||
|
WORD cbModCnt; // size of list of modules
|
||
|
DWORD lbModList; // module list file start
|
||
|
|
||
|
lszBSCName = lszName;
|
||
|
|
||
|
fhBSC = open(lszBSCName, O_BINARY|O_RDONLY);
|
||
|
|
||
|
// if the .bsc file doesn't exist then we don't do any work
|
||
|
// this is the cold compile case
|
||
|
//
|
||
|
|
||
|
if (fhBSC == -1)
|
||
|
return FALSE;
|
||
|
|
||
|
// read and check BSC version (major, minor and update)
|
||
|
|
||
|
BSCIn(MajorVer);
|
||
|
BSCIn(MinorVer);
|
||
|
BSCIn(UpdatVer);
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
printf("Browser Data Base: %s ver %d.%d.%d\n\n",
|
||
|
lszBSCName, MajorVer, MinorVer, UpdatVer);
|
||
|
#endif
|
||
|
|
||
|
if ((MajorVer != BSC_MAJ) ||
|
||
|
(MinorVer != BSC_MIN) ||
|
||
|
(UpdatVer != BSC_UPD))
|
||
|
return FALSE;
|
||
|
|
||
|
|
||
|
// we will be attempting an incremental update
|
||
|
|
||
|
fIncremental = TRUE;
|
||
|
|
||
|
// read Case sense switch, max symbol length and Unknown module id
|
||
|
|
||
|
BSCIn(fCase);
|
||
|
BSCIn(MaxSymLen);
|
||
|
BSCIn(Unknown);
|
||
|
|
||
|
// read counts (sizes) of each data area
|
||
|
|
||
|
BSCIn(ModCnt);
|
||
|
BSCIn(ModSymCnt);
|
||
|
BSCIn(SymCnt);
|
||
|
BSCIn(PropCnt);
|
||
|
BSCIn(RefCnt);
|
||
|
BSCIn(DefCnt);
|
||
|
BSCIn(CalCnt);
|
||
|
BSCIn(CbyCnt);
|
||
|
BSCIn(lastAtomPage);
|
||
|
BSCIn(lastAtomCnt);
|
||
|
|
||
|
// read BSC data area offsets
|
||
|
|
||
|
BSCIn(lbModList);
|
||
|
BSCIn(lbModSymList);
|
||
|
BSCIn(lbSymList);
|
||
|
BSCIn(lbPropList);
|
||
|
BSCIn(lbRefList);
|
||
|
BSCIn(lbDefList);
|
||
|
BSCIn(lbCalList);
|
||
|
BSCIn(lbCbyList);
|
||
|
BSCIn(lbAtomCache);
|
||
|
BSCIn(lbSbrList);
|
||
|
|
||
|
// determine data cache area sizes
|
||
|
|
||
|
#define MIN(a,b) ((a)>(b) ? (b) : (a))
|
||
|
|
||
|
MaxModCnt = ModCnt; // max list of modules
|
||
|
MaxModSymCnt = MIN(ModSymCnt , LISTALLOC); // max list of modsyms
|
||
|
MaxSymCnt = MIN(SymCnt+ModCnt, LISTALLOC); // max list of symbols
|
||
|
MaxPropCnt = MIN(PropCnt , LISTALLOC); // max list of props
|
||
|
MaxRefCnt = (WORD)MIN(RefCnt, (long)LISTALLOC); // max list of refs
|
||
|
MaxDefCnt = MIN(DefCnt , LISTALLOC); // max list of defs
|
||
|
MaxCalCnt = MIN(CalCnt , LISTALLOC); // max list of cals
|
||
|
MaxCbyCnt = MIN(CbyCnt , LISTALLOC); // max list of cbys
|
||
|
|
||
|
cbModCnt = sizeof (MODLIST) * MaxModCnt; // size of mods list
|
||
|
cbModSymCnt = sizeof (MODSYMLIST) * MaxModSymCnt; // size of modsyms list
|
||
|
cbSymCnt = sizeof (SYMLIST) * MaxSymCnt; // size of syms list
|
||
|
cbPropCnt = sizeof (PROPLIST) * MaxPropCnt; // size of props list
|
||
|
cbRefCnt = sizeof (REFLIST) * MaxRefCnt; // size of refs list
|
||
|
cbDefCnt = sizeof (REFLIST) * MaxDefCnt; // size of defs list
|
||
|
cbCalCnt = sizeof (USELIST) * MaxCalCnt; // size of cals list
|
||
|
cbCbyCnt = sizeof (USELIST) * MaxCbyCnt; // size of cbys list
|
||
|
|
||
|
// Allocate data cache
|
||
|
|
||
|
pfModList = LpvAllocCb(cbModCnt);
|
||
|
pfModSymList = LpvAllocCb(cbModSymCnt);
|
||
|
pfSymList = LpvAllocCb(cbSymCnt);
|
||
|
pfPropList = LpvAllocCb(cbPropCnt);
|
||
|
pfRefList = LpvAllocCb(cbRefCnt);
|
||
|
pfDefList = LpvAllocCb(cbDefCnt);
|
||
|
pfCalList = LpvAllocCb(cbCalCnt);
|
||
|
pfCbyList = LpvAllocCb(cbCbyCnt);
|
||
|
|
||
|
for (i=0; i < MAXATOMPAGETBL; i++) {
|
||
|
AtomPageTbl[i].uPage = 0;
|
||
|
AtomPageTbl[i].pfAtomCache = LpvAllocCb(ATOMALLOC);
|
||
|
}
|
||
|
AtomPageTblMac = 0; // last cache page used
|
||
|
AtomPageTbl[0].uPage = 65535;
|
||
|
|
||
|
// read data areas
|
||
|
|
||
|
if (lastAtomPage == 0)
|
||
|
pagesize = lastAtomCnt;
|
||
|
else
|
||
|
pagesize = ATOMALLOC;
|
||
|
|
||
|
GetBSC(lbModList, pfModList, cbModCnt); // Init Mod cache
|
||
|
GetBSC(lbModSymList, pfModSymList, cbModSymCnt); // Init ModSym cache
|
||
|
GetBSC(lbSymList, pfSymList, cbSymCnt); // Init Sym cache
|
||
|
GetBSC(lbPropList, pfPropList, cbPropCnt); // Init Prop cache
|
||
|
GetBSC(lbRefList, pfRefList, cbRefCnt); // Init Ref cache
|
||
|
GetBSC(lbDefList, pfDefList, cbDefCnt); // Init Def cache
|
||
|
GetBSC(lbCalList, pfCalList, cbCalCnt); // Init Cal cache
|
||
|
GetBSC(lbCbyList, pfCbyList, cbCbyCnt); // Init Cby cache
|
||
|
|
||
|
GetAtomCache (0); // Init Atom cache
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
InstallBSC()
|
||
|
// Install the currently open BSC into the mbrmake lists
|
||
|
//
|
||
|
{
|
||
|
IDX iprop, imod, isym, idef, ical, icby, isbr, iFirstFileSym;
|
||
|
VA vaSym, vaProp, vaRef, vaFileSym, vaMod;
|
||
|
DWORD iref;
|
||
|
|
||
|
PROPLIST prop, prop0;
|
||
|
MODLIST mod;
|
||
|
|
||
|
DEF def;
|
||
|
CAL cal;
|
||
|
CBY cby;
|
||
|
VA *rgVaProp; // preallocated array of PROPs
|
||
|
VA *rgVaFileSym; // cached SYMs for the filenames
|
||
|
BYTE *rgFModUsed; // is this module used?
|
||
|
|
||
|
SI *mpIsbrSi;
|
||
|
|
||
|
rgVaProp = (VA *)LpvAllocCb(PropCnt * sizeof(VA));
|
||
|
rgVaFileSym = (VA *)LpvAllocCb(ModCnt * sizeof(VA));
|
||
|
rgFModUsed = (BYTE *)LpvAllocCb(ModCnt * sizeof(BYTE));
|
||
|
|
||
|
// make the SBR info for this BSC file
|
||
|
mpIsbrSi = LpsiCreate();
|
||
|
|
||
|
// this relies on the fact that all the SYMs for the files are together
|
||
|
// (they're after all the SYMs for the variables)
|
||
|
iFirstFileSym = bMOD(0).ModName;
|
||
|
|
||
|
for (iprop = 0; iprop < PropCnt; iprop++)
|
||
|
rgVaProp[iprop] = VaAllocGrpCb(grpProp, sizeof(PROP));
|
||
|
|
||
|
for (imod = 0; imod < ModCnt; imod++) {
|
||
|
mod = bMOD(imod);
|
||
|
|
||
|
vaCurMod = VaAllocGrpCb(grpMod, sizeof(MOD));
|
||
|
|
||
|
gMOD(vaCurMod);
|
||
|
cMOD.vaFirstModSym = vaNil;
|
||
|
cMOD.csyms = 0;
|
||
|
cMOD.vaNameSym = MbrAddAtom (LszNameFrIsym (mod.ModName), TRUE);
|
||
|
cMOD.vaNextMod = vaRootMod;
|
||
|
pMOD(vaCurMod);
|
||
|
|
||
|
rgVaFileSym[imod] = cMOD.vaNameSym;
|
||
|
rgFModUsed[imod] = 0;
|
||
|
|
||
|
vaRootMod = vaCurMod;
|
||
|
|
||
|
if (Unknown == mod.ModName) {
|
||
|
vaUnknownSym = cMOD.vaNameSym;
|
||
|
vaUnknownMod = vaCurMod;
|
||
|
}
|
||
|
|
||
|
gSYM(cMOD.vaNameSym).vaFirstProp = vaCurMod; // store ptr to MOD
|
||
|
pSYM(cMOD.vaNameSym);
|
||
|
}
|
||
|
|
||
|
for (isym = 0; isym < SymCnt; isym++) {
|
||
|
|
||
|
vaSym = MbrAddAtom(LszNameFrIsym(isym), FALSE);
|
||
|
|
||
|
iprop = isym ? bSYM((IDX)(isym-1)).PropEnd : 0;
|
||
|
for (; iprop < bSYM(isym).PropEnd; iprop++) {
|
||
|
|
||
|
prop = bPROP(iprop);
|
||
|
|
||
|
if (iprop)
|
||
|
prop0 = bPROP((IDX)(iprop-1));
|
||
|
else {
|
||
|
prop0.DefEnd = 0L;
|
||
|
prop0.RefEnd = 0;
|
||
|
prop0.CalEnd = 0;
|
||
|
prop0.CbyEnd = 0;
|
||
|
}
|
||
|
|
||
|
// the properties were preallocated
|
||
|
vaProp = rgVaProp[iprop];
|
||
|
|
||
|
gSYM(vaSym);
|
||
|
if (cSYM.vaFirstProp == vaNil)
|
||
|
cSYM.vaFirstProp = vaProp;
|
||
|
else
|
||
|
cPROP.vaNextProp = vaProp;
|
||
|
|
||
|
cSYM.cprop++;
|
||
|
pSYM(vaSym);
|
||
|
|
||
|
gPROP(vaProp);
|
||
|
cPROP.vaNameSym = vaSym;
|
||
|
cPROP.sattr = prop.PropAttr;
|
||
|
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
if (isym != prop.PropName)
|
||
|
printf("\t ERROR property points back to wrong symbol!\n"); // DEBUG
|
||
|
#endif
|
||
|
|
||
|
for (idef = prop0.DefEnd; idef < prop.DefEnd; idef++) {
|
||
|
isbr = bDEF(idef).isbr;
|
||
|
|
||
|
// this SBR file is being updated -- ignore incoming info
|
||
|
if (isbr == 0xffff || mpIsbrSi[isbr].fUpdate) continue;
|
||
|
|
||
|
imod = bDEF(idef).RefNam - iFirstFileSym;
|
||
|
def.isbr = mpIsbrSi[isbr].isbr;
|
||
|
def.deflin = bDEF(idef).RefLin;
|
||
|
def.vaFileSym = rgVaFileSym[imod];
|
||
|
|
||
|
rgFModUsed[imod] = 1;
|
||
|
|
||
|
VaAddList(&cPROP.vaDefList, &def, sizeof(def), grpDef);
|
||
|
}
|
||
|
|
||
|
for (iref = prop0.RefEnd; iref < prop.RefEnd; iref++) {
|
||
|
isbr = bREF(iref).isbr;
|
||
|
|
||
|
// this SBR file is being updated -- ignore incoming info
|
||
|
if (mpIsbrSi[isbr].fUpdate) continue;
|
||
|
|
||
|
vaRef = VaAllocGrpCb(grpRef, sizeof(REF));
|
||
|
|
||
|
gREF(vaRef);
|
||
|
imod = bREF(iref).RefNam - iFirstFileSym;
|
||
|
cREF.isbr = mpIsbrSi[isbr].isbr;
|
||
|
cREF.reflin = bREF(iref).RefLin;
|
||
|
vaFileSym = rgVaFileSym[imod];
|
||
|
|
||
|
rgFModUsed[imod] = 1;
|
||
|
|
||
|
MkVpVa(cREF.vpFileSym, vaFileSym);
|
||
|
|
||
|
pREF(vaRef);
|
||
|
|
||
|
AddTail (Ref, REF);
|
||
|
|
||
|
cPROP.cref++; // count references
|
||
|
}
|
||
|
|
||
|
for (ical = prop0.CalEnd; ical < prop.CalEnd; ical++) {
|
||
|
isbr = bCAL(ical).isbr;
|
||
|
|
||
|
// this SBR file is being updated -- ignore incoming info
|
||
|
if (mpIsbrSi[isbr].fUpdate) continue;
|
||
|
|
||
|
cal.isbr = mpIsbrSi[isbr].isbr;
|
||
|
cal.vaCalProp = rgVaProp[bCAL(ical).UseProp];
|
||
|
cal.calcnt = bCAL(ical).UseCnt;
|
||
|
|
||
|
VaAddList(&cPROP.vaCalList, &cal, sizeof(cal), grpCal);
|
||
|
}
|
||
|
|
||
|
for (icby = prop0.CbyEnd; icby < prop.CbyEnd; icby++) {
|
||
|
isbr = bCBY(icby).isbr;
|
||
|
|
||
|
// this SBR file is being updated -- ignore incoming info
|
||
|
if (mpIsbrSi[isbr].fUpdate) continue;
|
||
|
|
||
|
cby.isbr = mpIsbrSi[isbr].isbr;
|
||
|
cby.vaCbyProp = rgVaProp[bCBY(icby).UseProp];
|
||
|
cby.cbycnt = bCBY(icby).UseCnt;
|
||
|
|
||
|
VaAddList(&cPROP.vaCbyList, &cby, sizeof(cby), grpCby);
|
||
|
}
|
||
|
|
||
|
pPROP(vaProp);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (imod = 0; imod < ModCnt; imod++) {
|
||
|
vaMod = gSYM(rgVaFileSym[imod]).vaFirstProp;
|
||
|
gMOD(vaMod);
|
||
|
if (rgFModUsed[imod] == 0) {
|
||
|
cMOD.csyms = 1; // mark this MOD as empty
|
||
|
pMOD(vaMod);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FreeLpv(mpIsbrSi);
|
||
|
FreeLpv(rgFModUsed);
|
||
|
FreeLpv(rgVaFileSym);
|
||
|
FreeLpv(rgVaProp);
|
||
|
}
|
||
|
|
||
|
static LPSI
|
||
|
LpsiCreate()
|
||
|
// create the SBR info records for this .BSC file
|
||
|
//
|
||
|
{
|
||
|
SI FAR *mpIsbrSi;
|
||
|
LSZ lszSbrName;
|
||
|
VA vaSbr;
|
||
|
WORD isbr, isbr2;
|
||
|
WORD fUpdate;
|
||
|
|
||
|
// add the files that are current in the database to the list of .SBR files
|
||
|
//
|
||
|
lszSbrName = LpvAllocCb(PATH_BUF);
|
||
|
lseek(fhBSC, lbSbrList, SEEK_SET);
|
||
|
for (isbr = 0;;isbr++) {
|
||
|
GetBSCLsz(lszSbrName);
|
||
|
if (*lszSbrName == '\0')
|
||
|
break;
|
||
|
|
||
|
vaSbr = VaSbrAdd(SBR_OLD, lszSbrName);
|
||
|
|
||
|
cSBR.isbr = isbr;
|
||
|
pSBR(vaSbr);
|
||
|
}
|
||
|
FreeLpv(lszSbrName);
|
||
|
|
||
|
mpIsbrSi = LpvAllocCb(SbrCnt * sizeof(SI));
|
||
|
|
||
|
// allocate and fill in the new table with the base numbers
|
||
|
// mark files that are staying and those that are going away
|
||
|
// number any new sbr files that we find while doing this.
|
||
|
|
||
|
vaSbr = vaRootSbr;
|
||
|
while (vaSbr) {
|
||
|
gSBR(vaSbr);
|
||
|
|
||
|
if (cSBR.isbr == (WORD)-1) {
|
||
|
cSBR.isbr = isbr++;
|
||
|
pSBR(vaSbr);
|
||
|
}
|
||
|
|
||
|
if (cSBR.fUpdate == SBR_NEW)
|
||
|
Warning(WARN_SBR_TRUNC, cSBR.szName);
|
||
|
else if (cSBR.fUpdate & SBR_NEW)
|
||
|
fFoundSBR = TRUE;
|
||
|
|
||
|
mpIsbrSi[cSBR.isbr].fUpdate = cSBR.fUpdate;
|
||
|
|
||
|
vaSbr = cSBR.vaNextSbr;
|
||
|
}
|
||
|
|
||
|
if (!fFoundSBR) {
|
||
|
// all SBR files were not in the database and were truncated. ERROR!
|
||
|
Error(ERR_ALL_SBR_TRUNC, "");
|
||
|
}
|
||
|
|
||
|
isbr2 = 0;
|
||
|
for (isbr = 0; isbr < SbrCnt; isbr++) {
|
||
|
fUpdate = mpIsbrSi[isbr].fUpdate;
|
||
|
|
||
|
if (fUpdate & SBR_NEW)
|
||
|
mpIsbrSi[isbr].isbr = isbr2++;
|
||
|
else
|
||
|
mpIsbrSi[isbr].isbr = (WORD)-1;
|
||
|
|
||
|
if ((fUpdate & SBR_UPDATE) ||
|
||
|
(fUpdate & SBR_OLD) && (~fUpdate & SBR_NEW))
|
||
|
mpIsbrSi[isbr].fUpdate = TRUE;
|
||
|
else
|
||
|
mpIsbrSi[isbr].fUpdate = FALSE;
|
||
|
|
||
|
}
|
||
|
|
||
|
return mpIsbrSi;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
NumberSBR()
|
||
|
// stub version of LpsiCreate --- call this if FOpenBSC fails to just
|
||
|
// assign new numbers to all the .sbr files that are in the list
|
||
|
//
|
||
|
{
|
||
|
VA vaSbr;
|
||
|
WORD isbr;
|
||
|
|
||
|
// number new sbr files
|
||
|
|
||
|
vaSbr = vaRootSbr;
|
||
|
isbr = 0;
|
||
|
while (vaSbr) {
|
||
|
gSBR(vaSbr);
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
if (cSBR.isbr != (WORD)-1) {
|
||
|
printf("Non initialized SBR file encountered\n"); //DEBUG
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
// if this file is truncated then and there is no
|
||
|
// old version of the file then emit a warning about the file
|
||
|
// and then an error stating that we are not in incremental mode
|
||
|
|
||
|
if (cSBR.fUpdate == SBR_NEW) {
|
||
|
Warning(WARN_SBR_TRUNC, cSBR.szName);
|
||
|
Error(ERR_NO_INCREMENTAL, "");
|
||
|
}
|
||
|
|
||
|
cSBR.isbr = isbr++;
|
||
|
|
||
|
pSBR(vaSbr);
|
||
|
|
||
|
vaSbr = cSBR.vaNextSbr;
|
||
|
}
|
||
|
}
|