735 lines
18 KiB
C
735 lines
18 KiB
C
|
//
|
||
|
// bsc.c -- manage queries on the database
|
||
|
//
|
||
|
// Copyright <C> 1988, Microsoft Corporation
|
||
|
//
|
||
|
// Revision History:
|
||
|
//
|
||
|
//
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <io.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <string.h>
|
||
|
#include <stddef.h>
|
||
|
#define LINT_ARGS
|
||
|
#if defined(OS2)
|
||
|
#define INCL_NOCOMMON
|
||
|
#define INCL_DOSPROCESS
|
||
|
#define INCL_DOSSEMAPHORES
|
||
|
#define INCL_DOSFILEMGR
|
||
|
#define INCL_DOSERRORS
|
||
|
#define INCL_DOSMISC
|
||
|
#include <os2.h>
|
||
|
#include <dos.h>
|
||
|
#else
|
||
|
#include <windows.h>
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
#include "hungary.h"
|
||
|
#include "mbrcache.h"
|
||
|
#include "version.h"
|
||
|
#include "sbrbsc.h"
|
||
|
#include "bsc.h"
|
||
|
|
||
|
#define LISTALLOC 50 // Browser max list size
|
||
|
|
||
|
// static data
|
||
|
|
||
|
static FILEHANDLE fhBSC = (FILEHANDLE)(-1); // .BSC file handle
|
||
|
|
||
|
static BYTE fCase; // TRUE for case compare
|
||
|
static BYTE MaxSymLen; // longest symbol length
|
||
|
static WORD ModCnt; // count of modules
|
||
|
|
||
|
static ISYM 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 references
|
||
|
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; // def'n list file start
|
||
|
static DWORD lbCalList; // calls list file start
|
||
|
static DWORD lbCbyList; // call bys 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 definitions
|
||
|
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 = NULL; // module list cache start
|
||
|
static MODSYMLIST far *pfModSymList = NULL; // modsym list cache start
|
||
|
static SYMLIST far *pfSymList = NULL; // symbol list cache start
|
||
|
static PROPLIST far *pfPropList = NULL; // property list cache start
|
||
|
static REFLIST far *pfRefList = NULL; // reference list cache start
|
||
|
static REFLIST far *pfDefList = NULL; // def'n list cache start
|
||
|
static USELIST far *pfCalList = NULL; // calls list cache start
|
||
|
static USELIST far *pfCbyList = NULL; // call bys list cache start
|
||
|
|
||
|
static WORD AtomPageTblMac = 0; // last cache page used
|
||
|
static CACHEPAGE AtomPageTbl[MAXATOMPAGETBL]; // Atom Cache table
|
||
|
|
||
|
#define bMOD(imod) (pfModList[imod])
|
||
|
#define bMODSYM(isym) (pfModSymList[isym])
|
||
|
#define bSYM(isym) (pfSymList[isym])
|
||
|
#define bPROP(iprop) (pfPropList[iprop])
|
||
|
|
||
|
#define bREF(iref) (pfRefList[iref])
|
||
|
#define bDEF(idef) (pfDefList[idef])
|
||
|
|
||
|
#define bCAL(iuse) (pfCalList[iuse])
|
||
|
#define bCBY(iuse) (pfCbyList[iuse])
|
||
|
#define bUSE(iuse) (pfCalList[iuse])
|
||
|
#define bUBY(iuse) (pfCbyList[iuse])
|
||
|
|
||
|
// prototypes
|
||
|
//
|
||
|
|
||
|
#define BSCIn(v) ReadBSC(&v, sizeof(v));
|
||
|
|
||
|
static VOID GetBSC (DWORD lpos, LPV lpv, WORD cb);
|
||
|
static VOID ReadBSC(LPV lpv, WORD cb);
|
||
|
static WORD SwapPAGE (DWORD, LPV, WORD, WORD, WORD *, DWORD);
|
||
|
static LPCH GetAtomCache (WORD);
|
||
|
|
||
|
static VOID
|
||
|
ReadBSC(LPV lpv, WORD cb)
|
||
|
// read a block of data from the BSC file
|
||
|
//
|
||
|
{
|
||
|
if (BSCRead(fhBSC, lpv, cb) != cb)
|
||
|
ReadError(lszBSCName);
|
||
|
}
|
||
|
|
||
|
static VOID
|
||
|
GetBSC(DWORD lpos, LPV lpv, WORD cb)
|
||
|
// Read a block of the specified size from the specified position
|
||
|
//
|
||
|
{
|
||
|
#if defined (OS2)
|
||
|
if (BSCSeek(fhBSC, lpos, SEEK_SET) == -1)
|
||
|
#else
|
||
|
if (BSCSeek(fhBSC, lpos, FILE_BEGIN) == -1)
|
||
|
SeekError(lszBSCName);
|
||
|
#endif
|
||
|
|
||
|
if (BSCRead(fhBSC, lpv, cb) != cb)
|
||
|
ReadError(lszBSCName);
|
||
|
}
|
||
|
|
||
|
static WORD
|
||
|
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;
|
||
|
WORD 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 WORD
|
||
|
ModSymPAGE (IMOD imod)
|
||
|
// Swap in the ModSym page for ModSym[imod]
|
||
|
// return the ModSym's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbModSymList, pfModSymList,
|
||
|
cbModSymCnt, MaxModSymCnt, &CurModSymPage, (IDX)imod);
|
||
|
}
|
||
|
|
||
|
static WORD
|
||
|
SymPAGE (ISYM isym)
|
||
|
// Swap in the Symbol page for symbol[isym]
|
||
|
// return the Symbol's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbSymList, pfSymList,
|
||
|
cbSymCnt, MaxSymCnt, &CurSymPage, (IDX)isym);
|
||
|
}
|
||
|
|
||
|
static WORD
|
||
|
PropPAGE (IINST iinst)
|
||
|
// Swap in the Property page for Property[idx]
|
||
|
// return the Property's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbPropList, pfPropList,
|
||
|
cbPropCnt, MaxPropCnt, &CurPropPage, (IDX)iinst);
|
||
|
}
|
||
|
|
||
|
static WORD
|
||
|
RefPAGE (IREF iref)
|
||
|
// Swap in the Reference page for Reference[idx]
|
||
|
// return the Reference's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbRefList, pfRefList,
|
||
|
cbRefCnt, MaxRefCnt, &CurRefPage, (IDX)iref);
|
||
|
}
|
||
|
|
||
|
static WORD
|
||
|
DefPAGE (IDEF idef)
|
||
|
// Swap in the Deference page for Definition[idef]
|
||
|
// return the Definitions index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbDefList, pfDefList,
|
||
|
cbDefCnt, MaxDefCnt, &CurDefPage, (IDX)idef);
|
||
|
}
|
||
|
|
||
|
static WORD
|
||
|
CalPAGE (IUSE iuse)
|
||
|
// Swap in the Usage page for Usage[iuse] (cal/cby)
|
||
|
// and return the Usage's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbCalList, pfCalList,
|
||
|
cbCalCnt, MaxCalCnt, &CurCalPage, (IDX)iuse);
|
||
|
}
|
||
|
|
||
|
static WORD
|
||
|
CbyPAGE (IUSE iuse)
|
||
|
// Swap in the Usage page for Usage[iuse] (cal/cby)
|
||
|
// and return the Usage's index in the page.
|
||
|
//
|
||
|
{
|
||
|
return SwapPAGE (lbCbyList, pfCbyList,
|
||
|
cbCbyCnt, MaxCbyCnt, &CurCbyPage, (IDX)iuse);
|
||
|
}
|
||
|
|
||
|
static LPCH
|
||
|
GetAtomCache (WORD Page)
|
||
|
// load the requested page into the cache
|
||
|
//
|
||
|
{
|
||
|
register WORD ipg;
|
||
|
WORD pagesize;
|
||
|
LPCH pfAtomCsave;
|
||
|
|
||
|
for (ipg = 0; ipg < AtomPageTblMac; ipg++) {
|
||
|
if (AtomPageTbl[ipg].uPage == Page)
|
||
|
return AtomPageTbl[ipg].pfAtomCache;
|
||
|
}
|
||
|
|
||
|
if (ipg != MAXATOMPAGETBL) {
|
||
|
if (AtomPageTbl[ipg].pfAtomCache ||
|
||
|
(AtomPageTbl[ipg].pfAtomCache = LpvAllocCb(ATOMALLOC)))
|
||
|
AtomPageTblMac++;
|
||
|
}
|
||
|
|
||
|
pfAtomCsave = AtomPageTbl[AtomPageTblMac-1].pfAtomCache;
|
||
|
|
||
|
for (ipg = AtomPageTblMac-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;
|
||
|
}
|
||
|
|
||
|
LSZ BSC_API
|
||
|
LszNameFrSym (ISYM 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;
|
||
|
}
|
||
|
|
||
|
LSZ BSC_API
|
||
|
LszNameFrMod (IMOD imod)
|
||
|
// Swap in the Atom page for the module isym
|
||
|
// return the atom's address in the page.
|
||
|
//
|
||
|
{
|
||
|
return LszNameFrSym(bMOD(imod).ModName);
|
||
|
}
|
||
|
|
||
|
int BSC_API
|
||
|
CaseCmp(LSZ lsz1, LSZ lsz2)
|
||
|
//
|
||
|
// think of lsz1 and lsz2 being in a list of things that are sorted
|
||
|
// case insensitively and then case sensitively within that. This is
|
||
|
// the case for browser symbols
|
||
|
//
|
||
|
// return -1, 0, or 1 if lsz1 before, at, or after lsz2 in the list
|
||
|
//
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
// do case insensitive compare
|
||
|
ret = _stricmp(lsz1, lsz2);
|
||
|
|
||
|
// if this is good enough then use it, or if we are only doing
|
||
|
// a case insensitive search then this is good enough
|
||
|
|
||
|
if (ret || !fCase) return ret;
|
||
|
|
||
|
// if we must, do the case sensitive compare
|
||
|
|
||
|
return strcmp(lsz1, lsz2);
|
||
|
}
|
||
|
|
||
|
|
||
|
ISYM BSC_API
|
||
|
IsymFrLsz (LSZ lszReqd)
|
||
|
// find the symbol with the specifed name
|
||
|
//
|
||
|
{
|
||
|
ISYM Lo, Hi, Mid;
|
||
|
int Cmp;
|
||
|
LSZ lszCur;
|
||
|
|
||
|
Lo = 0;
|
||
|
Hi = (ISYM)(SymCnt - 1);
|
||
|
|
||
|
while (Lo <= Hi) {
|
||
|
Mid = (ISYM)((Hi + Lo) / 2);
|
||
|
|
||
|
lszCur = LszNameFrSym (Mid);
|
||
|
Cmp = CaseCmp (lszReqd, lszCur);
|
||
|
|
||
|
if (Cmp == 0)
|
||
|
return Mid;
|
||
|
|
||
|
if (Cmp < 0)
|
||
|
Hi = (ISYM)(Mid - 1);
|
||
|
else
|
||
|
Lo = (ISYM)(Mid + 1);
|
||
|
}
|
||
|
return isymNil;
|
||
|
}
|
||
|
|
||
|
IMOD BSC_API
|
||
|
ImodFrLsz (LSZ lszReqd)
|
||
|
// find the module with the specifed name
|
||
|
//
|
||
|
{
|
||
|
IMOD imod;
|
||
|
|
||
|
for (imod = 0; imod < ModCnt; imod++) {
|
||
|
if (_stricmp (lszReqd, LszNameFrSym (bMOD(imod).ModName)) == 0)
|
||
|
return imod;
|
||
|
}
|
||
|
|
||
|
return imodNil;
|
||
|
}
|
||
|
|
||
|
ISYM BSC_API
|
||
|
IsymMac()
|
||
|
// return the biggest isym in this database
|
||
|
//
|
||
|
{
|
||
|
return SymCnt;
|
||
|
}
|
||
|
|
||
|
IMOD BSC_API
|
||
|
ImodMac()
|
||
|
// return the biggest imod in this database
|
||
|
//
|
||
|
{
|
||
|
return ModCnt;
|
||
|
}
|
||
|
|
||
|
IINST BSC_API
|
||
|
IinstMac()
|
||
|
// return the biggest iinst in this database
|
||
|
//
|
||
|
{
|
||
|
return PropCnt;
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
MsRangeOfMod(IMOD imod, IMS *pimsFirst, IMS *pimsLast)
|
||
|
// fill in the module information
|
||
|
//
|
||
|
{
|
||
|
*pimsFirst = imod ? bMOD(imod-1).mSymEnd : 0;
|
||
|
*pimsLast = bMOD(imod).mSymEnd;
|
||
|
}
|
||
|
|
||
|
IINST BSC_API
|
||
|
IinstOfIms(IMS ims)
|
||
|
// give the instance (PROP) index of the modsym
|
||
|
//
|
||
|
{
|
||
|
return bMODSYM(ims).ModSymProp;
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
InstRangeOfSym(ISYM isym, IINST *piinstFirst, IINST *piinstLast)
|
||
|
// fill in the range of inst values for this symbol
|
||
|
//
|
||
|
{
|
||
|
*piinstFirst = isym ? bSYM(isym-1).PropEnd:0;
|
||
|
*piinstLast = bSYM(isym).PropEnd;
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
InstInfo(IINST iinst, ISYM *pisymInst, TYP *pTyp, ATR *pAtr)
|
||
|
// get the information that qualifies this instance
|
||
|
//
|
||
|
{
|
||
|
*pisymInst = bPROP(iinst).PropName;
|
||
|
*pAtr = bPROP(iinst).PropAttr & 0x3ff;
|
||
|
*pTyp = (bPROP(iinst).PropAttr >> 11) & 0x1f;
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
RefRangeOfInst(IINST iinst, IREF *pirefFirst, IREF *pirefLast)
|
||
|
// fill in the reference ranges from the inst
|
||
|
//
|
||
|
{
|
||
|
*pirefFirst = iinst ? bPROP(iinst-1).RefEnd : 0;
|
||
|
*pirefLast = bPROP(iinst).RefEnd;
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
DefRangeOfInst(IINST iinst, IDEF *pidefFirst, IDEF *pidefLast)
|
||
|
// fill in the definition ranges from the inst
|
||
|
//
|
||
|
{
|
||
|
*pidefFirst = iinst ? bPROP(iinst-1).DefEnd : 0;
|
||
|
*pidefLast = bPROP(iinst).DefEnd;
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
UseRangeOfInst(IINST iinst, IUSE *piuseFirst, IUSE *piuseLast)
|
||
|
// fill in the use ranges from the inst
|
||
|
//
|
||
|
{
|
||
|
*piuseFirst = iinst ? bPROP(iinst-1).CalEnd : 0;
|
||
|
*piuseLast = bPROP(iinst).CalEnd;
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
UbyRangeOfInst(IINST iinst, IUBY *piubyFirst, IUBY *piubyLast)
|
||
|
// fill in the used by ranges from the inst
|
||
|
//
|
||
|
{
|
||
|
*piubyFirst = iinst ? bPROP(iinst-1).CbyEnd : 0;
|
||
|
*piubyLast = bPROP(iinst).CbyEnd;
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
UseInfo(IUSE iuse, IINST *piinst, WORD *pcnt)
|
||
|
// fill in the information about this things which an inst uses
|
||
|
//
|
||
|
{
|
||
|
*piinst = bUSE(iuse).UseProp;
|
||
|
*pcnt = bUSE(iuse).UseCnt;
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
UbyInfo(IUBY iuby, IINST *piinst, WORD *pcnt)
|
||
|
// fill in the information about this things which an inst is used by
|
||
|
//
|
||
|
{
|
||
|
*piinst = bUBY(iuby).UseProp;
|
||
|
*pcnt = bUBY(iuby).UseCnt;
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
RefInfo(IREF iref, LSZ *plszName, WORD *pline)
|
||
|
// fill in the information about this reference
|
||
|
//
|
||
|
{
|
||
|
*pline = bREF(iref).RefLin;
|
||
|
*plszName = LszNameFrSym(bREF(iref).RefNam);
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
DefInfo(IDEF idef, LSZ *plszName, WORD *pline)
|
||
|
// fill in the information about this definition
|
||
|
//
|
||
|
{
|
||
|
*pline = bDEF(idef).RefLin;
|
||
|
*plszName = LszNameFrSym(bDEF(idef).RefNam);
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
CloseBSC()
|
||
|
// close database and free as much memory as possible
|
||
|
//
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
// close file if open
|
||
|
|
||
|
if (fhBSC != (FILEHANDLE)(-1)) {
|
||
|
BSCClose (fhBSC);
|
||
|
fhBSC = (FILEHANDLE)(-1);
|
||
|
}
|
||
|
|
||
|
// free any memory we may have allocated
|
||
|
|
||
|
if (pfModList) { FreeLpv (pfModList); pfModList = NULL; }
|
||
|
if (pfModSymList) { FreeLpv (pfModSymList); pfModSymList = NULL; }
|
||
|
if (pfSymList) { FreeLpv (pfSymList); pfSymList = NULL; }
|
||
|
if (pfPropList) { FreeLpv (pfPropList); pfPropList = NULL; }
|
||
|
if (pfRefList) { FreeLpv (pfRefList); pfRefList = NULL; }
|
||
|
if (pfDefList) { FreeLpv (pfDefList); pfDefList = NULL; }
|
||
|
if (pfCalList) { FreeLpv (pfCalList); pfCalList = NULL; }
|
||
|
if (pfCbyList) { FreeLpv (pfCbyList); pfCbyList = NULL; }
|
||
|
|
||
|
for (i=0; i < MAXATOMPAGETBL; i++) {
|
||
|
if (AtomPageTbl[i].pfAtomCache) {
|
||
|
FreeLpv (AtomPageTbl[i].pfAtomCache); // dispose Atom Cache
|
||
|
AtomPageTbl[i].pfAtomCache = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL BSC_API
|
||
|
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
|
||
|
//
|
||
|
{
|
||
|
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
|
||
|
|
||
|
int i;
|
||
|
|
||
|
#define ABORT_OPEN CloseBSC(); return FALSE;
|
||
|
|
||
|
lszBSCName = lszName;
|
||
|
|
||
|
#if defined (OS2)
|
||
|
fhBSC = BSCOpen(lszBSCName, O_BINARY|O_RDONLY);
|
||
|
#else
|
||
|
fhBSC = BSCOpen(lszBSCName, GENERIC_READ);
|
||
|
#endif
|
||
|
|
||
|
// if the .bsc file doesn't exist then we don't do any work
|
||
|
// this is the cold compile case
|
||
|
//
|
||
|
|
||
|
if (fhBSC == (FILEHANDLE)(-1)) {ABORT_OPEN;}
|
||
|
|
||
|
// read and check BSC version (major, minor and update)
|
||
|
|
||
|
BSCIn(MajorVer);
|
||
|
BSCIn(MinorVer);
|
||
|
BSCIn(UpdatVer);
|
||
|
|
||
|
BSCPrintf("Browser Data Base: %s ver %d.%d.%d\n\n",
|
||
|
lszBSCName, MajorVer, MinorVer, UpdatVer);
|
||
|
|
||
|
if ((MajorVer != BSC_MAJ) ||
|
||
|
(MinorVer != BSC_MIN) ||
|
||
|
(UpdatVer != BSC_UPD)) {
|
||
|
|
||
|
CloseBSC();
|
||
|
BadBSCVer(lszBSCName);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// read Case sense switch, max symbol length and Unknown module id
|
||
|
|
||
|
BSCIn(fCase);
|
||
|
BSCIn(MaxSymLen);
|
||
|
BSCIn(Unknown);
|
||
|
|
||
|
// this will make the formatting look more reasonable if there are
|
||
|
// only very short names in the database
|
||
|
|
||
|
if (MaxSymLen < 8 ) MaxSymLen = 8;
|
||
|
|
||
|
// 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 = ModSymCnt; // max list of modsyms
|
||
|
MaxSymCnt = SymCnt+ModCnt; // max list of symbols
|
||
|
MaxPropCnt = PropCnt; // max list of props
|
||
|
MaxRefCnt = RefCnt; // max list of refs
|
||
|
MaxDefCnt = DefCnt; // max list of defs
|
||
|
MaxCalCnt = CalCnt; // max list of cals
|
||
|
MaxCbyCnt = CbyCnt; // 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 buffers for each of the object types
|
||
|
|
||
|
if (!(pfModList = LpvAllocCb(cbModCnt))) { ABORT_OPEN; }
|
||
|
if (!(pfModSymList = LpvAllocCb(cbModSymCnt))) { ABORT_OPEN; }
|
||
|
if (!(pfSymList = LpvAllocCb(cbSymCnt))) { ABORT_OPEN; }
|
||
|
if (!(pfPropList = LpvAllocCb(cbPropCnt))) { ABORT_OPEN; }
|
||
|
if (!(pfRefList = LpvAllocCb(cbRefCnt))) { ABORT_OPEN; }
|
||
|
if (!(pfDefList = LpvAllocCb(cbDefCnt))) { ABORT_OPEN; }
|
||
|
if (!(pfCalList = LpvAllocCb(cbCalCnt))) { ABORT_OPEN; }
|
||
|
if (!(pfCbyList = LpvAllocCb(cbCbyCnt))) { ABORT_OPEN; }
|
||
|
|
||
|
// read data areas
|
||
|
|
||
|
if (lastAtomPage == 0)
|
||
|
pagesize = lastAtomCnt;
|
||
|
else
|
||
|
pagesize = ATOMALLOC;
|
||
|
|
||
|
// clear out the atom cache
|
||
|
// we must be able to allocate at least one page
|
||
|
|
||
|
AtomPageTblMac = 0;
|
||
|
|
||
|
for (i=0; i < MAXATOMPAGETBL; i++)
|
||
|
AtomPageTbl[i].pfAtomCache = NULL;
|
||
|
|
||
|
AtomPageTbl[0].uPage = 65535;
|
||
|
AtomPageTbl[0].pfAtomCache = LpvAllocCb(pagesize);
|
||
|
if (!AtomPageTbl[0].pfAtomCache) { ABORT_OPEN; }
|
||
|
|
||
|
|
||
|
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
|
||
|
|
||
|
// current page for all database items is now page zero
|
||
|
|
||
|
CurModSymPage = 0;
|
||
|
CurSymPage = 0;
|
||
|
CurPropPage = 0;
|
||
|
CurRefPage = 0;
|
||
|
CurDefPage = 0;
|
||
|
CurCalPage = 0;
|
||
|
CurCbyPage = 0;
|
||
|
|
||
|
GetAtomCache (0); // Init Atom cache
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
WORD BSC_API
|
||
|
BSCMaxSymLen()
|
||
|
// return the length of the largest symbol in the database
|
||
|
//
|
||
|
{
|
||
|
return MaxSymLen;
|
||
|
}
|
||
|
|
||
|
BOOL BSC_API
|
||
|
FCaseBSC()
|
||
|
// is this database built with a case sensitive language?
|
||
|
//
|
||
|
{
|
||
|
return fCase;
|
||
|
}
|
||
|
|
||
|
VOID BSC_API
|
||
|
SetCaseBSC(BOOL fNewCase)
|
||
|
// set case sensitivity of database
|
||
|
//
|
||
|
{
|
||
|
fCase = (BYTE)!!fNewCase;
|
||
|
}
|