Windows2003-3790/sdktools/mep/browser/mbrmake/readbsc.c
2020-09-30 16:53:55 +02:00

791 lines
21 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;
}
}