mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
288 lines
5.2 KiB
288 lines
5.2 KiB
//
|
|
// bscquery.cpp
|
|
//
|
|
// Provides limited BOB functionality for backward compatibility
|
|
// with the previous version of the bsc toolkit
|
|
//
|
|
|
|
|
|
#include <tchar.h>
|
|
#include <ctype.h> // for isleadbyte
|
|
#include "vcbudefs.h"
|
|
#include "bsc.h"
|
|
#include "bscapi.h"
|
|
|
|
struct QYCACHE
|
|
{
|
|
BOB * rgbob;
|
|
ULONG cbob;
|
|
BOB bobQy;
|
|
};
|
|
|
|
// current query state...
|
|
// NOTE on usage of rgbob. This is always a pointer to an entry in rgQY, the cache of queries. As such,
|
|
// it should not be freed independently, and it can be written over without worrying about leaks
|
|
|
|
static Bsc * pbscCur = NULL;
|
|
static BOB * rgbob = NULL;
|
|
static ULONG cbob = 0;
|
|
static ULONG ibob = 0;
|
|
static QY qyCur = qyNil;
|
|
static QYCACHE rgQy[qyMac];
|
|
|
|
#ifndef FALSE
|
|
#define FALSE 0
|
|
#define TRUE 1
|
|
#endif
|
|
|
|
static SZ LszBaseName (SZ lsz);
|
|
|
|
BSCAPI (BOOL) OpenBSCQuery (Bsc * pbsc)
|
|
{
|
|
int i;
|
|
// allow only one open query
|
|
if (pbscCur)
|
|
return FALSE;
|
|
|
|
pbscCur = pbsc;
|
|
rgbob = NULL;
|
|
cbob = 0;
|
|
ibob = 0;
|
|
qyCur = qyNil;
|
|
// initialize the cached queries...
|
|
for (i = qyNil; i < qyMac; i++)
|
|
{
|
|
rgQy[i].rgbob = 0;
|
|
rgQy[i].cbob = 0;
|
|
rgQy[i].bobQy = qyNil;
|
|
}
|
|
return (pbscCur != NULL);
|
|
}
|
|
|
|
BSCAPI (BOOL) CloseBSCQuery()
|
|
{
|
|
int i;
|
|
// clear out the cached queries...
|
|
for (i = qyNil; i < qyMac; i++)
|
|
{
|
|
if (rgQy[i].rgbob)
|
|
{
|
|
if (pbscCur)
|
|
pbscCur->disposeArray(rgQy[i].rgbob);
|
|
rgQy[i].rgbob = NULL;
|
|
}
|
|
rgQy[i].cbob = 0;
|
|
rgQy[i].bobQy = bobNil;
|
|
}
|
|
|
|
pbscCur = NULL;
|
|
return TRUE;
|
|
}
|
|
|
|
BSCAPI (BOOL) InitBSCQuery (QY qy, BOB bob)
|
|
{
|
|
if (pbscCur == NULL)
|
|
return FALSE;
|
|
|
|
ibob = 0;
|
|
|
|
if (rgQy[qy].bobQy == bob)
|
|
{
|
|
// NOTE: rgbob is just a copy of the pointer in the array. Do not free it before use.
|
|
rgbob = rgQy[qy].rgbob;
|
|
cbob = rgQy[qy].cbob;
|
|
qyCur = qy;
|
|
return !!cbob; // FUTURE: comment or clarify this interesting line and similar line below
|
|
}
|
|
|
|
if (rgQy[qy].rgbob)
|
|
{
|
|
pbscCur->disposeArray(rgQy[qy].rgbob);
|
|
rgQy[qy].rgbob = NULL;
|
|
rgQy[qy].cbob = 0;
|
|
}
|
|
|
|
rgbob = NULL;
|
|
cbob = 0;
|
|
qyCur = qy;
|
|
|
|
BOOL fRet = FALSE;
|
|
|
|
switch (qy) {
|
|
|
|
case qyNil:
|
|
break;
|
|
|
|
case qyCalls:
|
|
fRet = ClsOfBob(bob) == clsInst &&
|
|
pbscCur->getUsesArray(IinstFrBob(bob), mbfFuncs, &rgbob, &cbob);
|
|
break;
|
|
|
|
case qyCalledBy:
|
|
fRet = ClsOfBob(bob) == clsInst &&
|
|
pbscCur->getUsedByArray(IinstFrBob(bob), mbfFuncs, &rgbob, &cbob);
|
|
break;
|
|
|
|
case qyBaseOf:
|
|
fRet = ClsOfBob(bob) == clsInst &&
|
|
pbscCur->getBaseArray(IinstFrBob(bob), &rgbob, &cbob);
|
|
break;
|
|
|
|
case qyDervOf:
|
|
fRet = ClsOfBob(bob) == clsInst &&
|
|
pbscCur->getDervArray(IinstFrBob(bob), &rgbob, &cbob);
|
|
break;
|
|
|
|
case qyContains:
|
|
fRet = ClsOfBob(bob) == clsMod &&
|
|
pbscCur->getModuleContents(ImodFrBob(bob), mbfAll, &rgbob, &cbob);
|
|
break;
|
|
|
|
case qyDefs:
|
|
fRet = ClsOfBob(bob) == clsInst &&
|
|
pbscCur->getDefArray(IinstFrBob(bob), &rgbob, &cbob);
|
|
break;
|
|
|
|
case qyRefs:
|
|
fRet = ClsOfBob(bob) == clsInst &&
|
|
pbscCur->getRefArray(IinstFrBob(bob), &rgbob, &cbob);
|
|
break;
|
|
|
|
case qyImpMembers:
|
|
fRet = ClsOfBob(bob) == clsInst &&
|
|
pbscCur->getMembersArray(IinstFrBob(bob), mbfAll, &rgbob, &cbob);
|
|
break;
|
|
|
|
}
|
|
|
|
// NOTE: rgbob is just a copy of the pointer in the array.
|
|
// The array will be freed later
|
|
rgQy[qy].rgbob = rgbob;
|
|
rgQy[qy].bobQy = bob;
|
|
rgQy[qy].cbob = cbob;
|
|
|
|
return fRet && !!cbob;
|
|
}
|
|
|
|
BSCAPI (BOB) BobNext()
|
|
{
|
|
if (!rgbob || !cbob || ibob >= cbob)
|
|
return bobNil;
|
|
|
|
BOB bob;
|
|
|
|
if (qyCur == qyDefs)
|
|
bob = BobFrDef(rgbob[ibob]);
|
|
else if (qyCur == qyRefs)
|
|
bob = BobFrRef(rgbob[ibob]);
|
|
else
|
|
bob = BobFrInst(rgbob[ibob]);
|
|
|
|
ibob++;
|
|
|
|
return bob;
|
|
}
|
|
|
|
BSCAPI (SZ) LszNameFrBob(BOB bob)
|
|
// return the name of the given bob
|
|
//
|
|
{
|
|
SZ lsz;
|
|
ATR atr;
|
|
TYP typ;
|
|
LINE line;
|
|
|
|
if (!pbscCur)
|
|
return "?";
|
|
|
|
switch (ClsOfBob(bob)) {
|
|
|
|
case clsMod:
|
|
pbscCur->imodInfo(ImodFrBob(bob), &lsz);
|
|
break;
|
|
|
|
case clsInst:
|
|
pbscCur->iinstInfo(IinstFrBob(bob), &lsz, &typ, &atr);
|
|
break;
|
|
|
|
case clsRef:
|
|
pbscCur->irefInfo(IrefFrBob(bob), &lsz, &line);
|
|
break;
|
|
|
|
case clsDef:
|
|
pbscCur->idefInfo(IrefFrBob(bob), &lsz, &line);
|
|
break;
|
|
|
|
default:
|
|
return "?";
|
|
}
|
|
|
|
return lsz;
|
|
}
|
|
|
|
BSCAPI (BOB) BobFrName (SZ lsz)
|
|
{
|
|
ULONG *rgiinst;
|
|
IMOD *rgimod;
|
|
ULONG cimod;
|
|
ULONG ctmp;
|
|
IMOD imod;
|
|
BOB bob = bobNil;
|
|
|
|
if (!pbscCur) {
|
|
return bobNil;
|
|
}
|
|
|
|
if (pbscCur->getOverloadArray(lsz, mbfAll, &rgiinst, &ctmp)) {
|
|
if (ctmp >= 1) {
|
|
bob = BobFrInst (rgiinst[0]);
|
|
}
|
|
pbscCur->disposeArray(rgiinst);
|
|
if (bobNil != bob)
|
|
return bob;
|
|
}
|
|
|
|
if (pbscCur->getModuleByName(lsz, &imod)) {
|
|
bob = BobFrMod(imod);
|
|
}
|
|
else if (pbscCur->getAllModulesArray(&rgimod, &cimod)){
|
|
// no exact match -- try short names
|
|
SZ szModName;
|
|
lsz = LszBaseName(lsz);
|
|
for (imod = 0; imod < cimod; imod++) {
|
|
if (pbscCur->imodInfo(imod, &szModName) &&
|
|
!_tcsicmp(lsz, LszBaseName(szModName))) {
|
|
bob = BobFrMod(imod);
|
|
break;
|
|
}
|
|
}
|
|
pbscCur->disposeArray(rgimod);
|
|
}
|
|
return bob;
|
|
}
|
|
|
|
|
|
static SZ LszBaseName (SZ lsz)
|
|
// return the base name part of a path
|
|
//
|
|
{
|
|
SZ lszBase;
|
|
|
|
// check for empty string
|
|
|
|
if (!lsz || !lsz[0]) return lsz;
|
|
|
|
// remove drive
|
|
|
|
if (!_istleadbyte((_TUCHAR)lsz[0]) && lsz[1] == _T(':')) lsz += 2;
|
|
|
|
// remove up to trailing backslash
|
|
|
|
if (lszBase = _tcsrchr(lsz, '\\')) lsz = lszBase+1;
|
|
|
|
// then remove up to trailing slash
|
|
|
|
if (lszBase = _tcsrchr(lsz, '/')) lsz = lszBase+1;
|
|
|
|
return lsz;
|
|
}
|