windows-nt/Source/XPSP1/NT/sdktools/mep/browser/bsc/query.c
2020-09-26 16:20:57 +08:00

576 lines
9.3 KiB
C

//
// query.c
//
// perform database queries
//
#include <stddef.h>
#include <string.h>
#if defined(OS2)
#define INCL_NOCOMMON
#define INCL_DOSPROCESS
#define INCL_DOSSEMAPHORES
#define INCL_DOSFILEMGR
#define INCL_DOSERRORS
#define INCL_DOSMISC
#include <os2.h>
#else
#include <windows.h>
#endif
#include <dos.h>
#include "hungary.h"
#include "bsc.h"
#include "bscsup.h"
// these keep track of the current query, they are globally visible so
// that users can see how the query is progressing
//
// you may not write on these
IDX far idxQyStart;
IDX far idxQyCur;
IDX far idxQyMac;
// this is auxilliary information about the current bob which some
// queries may choose to make available
//
static BOOL fWorking;
static LSZ lszModLast = NULL; // for removing duplicate modules
// prototypes for the query worker functions
//
static BOB BobQyFiles(VOID);
static BOB BobQySymbols (VOID);
static BOB BobQyContains (VOID);
static BOB BobQyCalls (VOID);
static BOB BobQyCalledBy (VOID);
static BOB BobQyUses (VOID);
static BOB BobQyUsedBy (VOID);
static BOB BobQyUsedIn (VOID);
static BOB BobQyDefinedIn(VOID);
static BOB BobQyRefs(VOID);
static BOB BobQyDefs(VOID);
// current bob worker function
static BOB (*bobFn)(VOID) = NULL;
BOOL BSC_API
InitBSCQuery (QY qy, BOB bob)
// do the request query on the given bob
//
{
fWorking = FALSE;
if (lszModLast == NULL)
lszModLast = LpvAllocCb(1024); // REVIEW -- how much to alloc? [rm]
// no memory -- no query
if (lszModLast == NULL)
return FALSE;
strcpy(lszModLast, "");
switch (qy) {
case qyFiles:
bobFn = BobQyFiles;
idxQyStart = (IDX)0;
idxQyMac = (IDX)ImodMac();
break;
case qySymbols:
bobFn = BobQySymbols;
idxQyStart = (IDX)0;
idxQyMac = (IDX)IinstMac();
break;
case qyContains:
{
IMS ims, imsMac;
bobFn = BobQyContains;
if (ClsOfBob(bob) != clsMod) return FALSE;
MsRangeOfMod(ImodFrBob(bob), &ims, &imsMac);
idxQyStart = (IDX)ims;
idxQyMac = (IDX)imsMac;
break;
}
case qyCalls:
{
IUSE iuse, iuseMac;
bobFn = BobQyCalls;
if (ClsOfBob(bob) != clsInst) return FALSE;
UseRangeOfInst(IinstFrBob(bob), &iuse, &iuseMac);
idxQyStart = (IDX)iuse;
idxQyMac = (IDX)iuseMac;
break;
}
case qyUses:
{
IUSE iuse, iuseMac;
bobFn = BobQyUses;
if (ClsOfBob(bob) != clsInst) return FALSE;
UseRangeOfInst(IinstFrBob(bob), &iuse, &iuseMac);
idxQyStart = (IDX)iuse;
idxQyMac = (IDX)iuseMac;
break;
}
case qyCalledBy:
{
IUBY iuby, iubyMac;
bobFn = BobQyCalledBy;
if (ClsOfBob(bob) != clsInst) return FALSE;
UbyRangeOfInst(IinstFrBob(bob), &iuby, &iubyMac);
idxQyStart = (IDX)iuby;
idxQyMac = (IDX)iubyMac;
break;
}
case qyUsedBy:
{
IUBY iuby, iubyMac;
bobFn = BobQyUsedBy;
if (ClsOfBob(bob) != clsInst) return FALSE;
UbyRangeOfInst(IinstFrBob(bob), &iuby, &iubyMac);
idxQyStart = (IDX)iuby;
idxQyMac = (IDX)iubyMac;
break;
}
case qyUsedIn:
{
IREF iref, irefMac;
bobFn = BobQyUsedIn;
if (ClsOfBob(bob) != clsInst) return FALSE;
RefRangeOfInst(IinstFrBob(bob), &iref, &irefMac);
idxQyStart = (IDX)iref;
idxQyMac = (IDX)irefMac;
break;
}
case qyDefinedIn:
{
IDEF idef, idefMac;
bobFn = BobQyDefinedIn;
if (ClsOfBob(bob) != clsInst) return FALSE;
DefRangeOfInst(IinstFrBob(bob), &idef, &idefMac);
idxQyStart = (IDX)idef;
idxQyMac = (IDX)idefMac;
break;
}
case qyRefs:
{
IINST iinst, iinstMac;
bobFn = BobQyRefs;
switch (ClsOfBob(bob)) {
default:
return FALSE;
case clsSym:
InstRangeOfSym(IsymFrBob(bob), &iinst, &iinstMac);
idxQyStart = (IDX)iinst;
idxQyMac = (IDX)iinstMac;
break;
case clsInst:
idxQyStart = (IDX)IinstFrBob(bob);
idxQyMac = idxQyStart+1;
break;
}
break;
}
case qyDefs:
{
IINST iinst, iinstMac;
bobFn = BobQyDefs;
switch (ClsOfBob(bob)) {
default:
return FALSE;
case clsSym:
InstRangeOfSym(IsymFrBob(bob), &iinst, &iinstMac);
idxQyStart = (IDX)iinst;
idxQyMac = (IDX)iinstMac;
break;
case clsInst:
idxQyStart = (IDX)IinstFrBob(bob);
idxQyMac = idxQyStart+1;
break;
}
break;
}
}
idxQyCur = idxQyStart;
return TRUE;
}
BOB BSC_API
BobNext()
// return the next Bob in the query
{
if (idxQyCur < idxQyMac && bobFn != NULL)
return (*bobFn)();
return bobNil;
}
static BOB
BobQyFiles()
// return the next File in a file query
//
{
BOB bob;
while (idxQyCur < idxQyMac) {
IMS ims1, ims2;
MsRangeOfMod((IMOD)idxQyCur, &ims1, &ims2);
if (ims1 != ims2) {
bob = BobFrClsIdx(clsMod, idxQyCur);
idxQyCur++;
return bob;
}
else
idxQyCur++;
}
return bobNil;
}
static BOB
BobQySymbols ()
// get the next symbol in a symbol query
//
{
BOB bob;
bob = BobFrClsIdx(clsInst, idxQyCur);
idxQyCur++;
return bob;
}
static BOB
BobQyContains ()
// get the next symbol in a contains query
//
{
BOB bob;
bob = BobFrClsIdx(clsInst, IinstOfIms((IMS)idxQyCur));
idxQyCur++;
return bob;
}
static BOB
BobQyCalls ()
// get the next symbol which query focus calls
//
{
WORD cuse;
IINST iinst;
ISYM isym;
TYP typ;
ATR atr;
BOB bob;
for (; idxQyCur < idxQyMac; idxQyCur++) {
UseInfo((IUSE)idxQyCur, &iinst, &cuse);
InstInfo(iinst, &isym, &typ, &atr);
if (typ > INST_TYP_LABEL)
continue;
bob = BobFrClsIdx(clsInst, iinst);
idxQyCur++;
return bob;
}
return bobNil;
}
static BOB
BobQyCalledBy ()
// get the next symbol which query focus is called by
//
{
WORD cuse;
IINST iinst;
ISYM isym;
TYP typ;
ATR atr;
BOB bob;
for (; idxQyCur < idxQyMac; idxQyCur++) {
UbyInfo((IUBY)idxQyCur, &iinst, &cuse);
InstInfo(iinst, &isym, &typ, &atr);
if (typ > INST_TYP_LABEL)
continue;
bob = BobFrClsIdx(clsInst, iinst);
idxQyCur++;
return bob;
}
return bobNil;
}
static BOB
BobQyUses ()
// get the next symbol which query focus calls
//
{
WORD cuse;
IINST iinst;
BOB bob;
UseInfo((IUSE)idxQyCur, &iinst, &cuse);
bob = BobFrClsIdx(clsInst, iinst);
idxQyCur++;
return bob;
}
static BOB
BobQyUsedBy ()
// get the next symbol which query focus calls
//
{
WORD cuse;
IINST iinst;
BOB bob;
UbyInfo((IUBY)idxQyCur, &iinst, &cuse);
bob = BobFrClsIdx(clsInst, iinst);
idxQyCur++;
return bob;
}
static BOB
BobQyUsedIn ()
// get the next module which query focus is used in
//
{
WORD wLine;
BOB bob;
LSZ lszMod;
for ( ; idxQyCur < idxQyMac ; idxQyCur++) {
RefInfo((IREF)idxQyCur, &lszMod, &wLine);
if (strcmp(lszMod, lszModLast) == 0)
continue;
strcpy(lszModLast, lszMod);
bob = BobFrClsIdx(clsMod, ImodFrLsz(lszMod));
idxQyCur++;
return bob;
}
return bobNil;
}
static BOB
BobQyDefinedIn ()
// get the next module which query focus is defined in
//
{
WORD wLine;
LSZ lszMod;
BOB bob;
for ( ; idxQyCur < idxQyMac ; idxQyCur++) {
DefInfo((IDEF)idxQyCur, &lszMod, &wLine);
if (strcmp(lszMod, lszModLast) == 0)
continue;
strcpy(lszModLast, lszMod);
bob = BobFrClsIdx(clsMod, ImodFrLsz(lszMod));
idxQyCur++;
return bob;
}
return bobNil;
}
LSZ BSC_API
LszNameFrBob(BOB bob)
// return the name of the given bob
//
{
switch (ClsOfBob(bob)) {
case clsMod:
return LszNameFrMod(ImodFrBob(bob));
case clsSym:
return LszNameFrSym(IsymFrBob(bob));
case clsInst:
{
ISYM isym;
TYP typ;
ATR atr;
InstInfo(IinstFrBob(bob), &isym, &typ, &atr);
return LszNameFrSym(isym);
}
case clsRef:
{
LSZ lsz;
WORD wLine;
RefInfo(IrefFrBob(bob), &lsz, &wLine);
return lsz;
}
case clsDef:
{
LSZ lsz;
WORD wLine;
DefInfo(IdefFrBob(bob), &lsz, &wLine);
return lsz;
}
default:
return "?";
}
}
BOB BSC_API
BobFrName(LSZ lszName)
// return the best bob we can find from the given name
//
{
ISYM isym;
IMOD imod, imodMac;
IINST iinst, iinstMac;
if ((isym = IsymFrLsz(lszName)) != isymNil) {
InstRangeOfSym(isym, &iinst, &iinstMac);
return BobFrClsIdx(clsInst, iinst);
}
if ((imod = ImodFrLsz(lszName)) != imodNil) {
return BobFrClsIdx(clsMod, imod);
}
imodMac = ImodMac();
// no exact match -- try short names
lszName = LszBaseName(lszName);
for (imod = 0; imod < imodMac; imod++)
if (_stricmp(lszName, LszBaseName(LszNameFrMod(imod))) == 0)
return BobFrClsIdx(clsMod, imod);
return bobNil;
}
static BOB
BobQyRefs()
// return the next File in a file query
//
{
BOB bob;
static IREF iref, irefMac;
for (;;) {
if (!fWorking) {
for ( ; idxQyCur < idxQyMac ; idxQyCur++) {
RefRangeOfInst((IINST)idxQyCur, &iref, &irefMac);
if (iref != irefMac)
break;
}
if (idxQyCur >= idxQyMac)
return bobNil;
fWorking = TRUE;
}
if (iref < irefMac) {
bob = BobFrClsIdx(clsRef, iref);
iref++;
return bob;
}
idxQyCur++;
fWorking = FALSE;
}
}
static BOB
BobQyDefs()
// return the next File in a file query
//
{
BOB bob;
static IDEF idef, idefMac;
for (;;) {
if (!fWorking) {
for ( ; idxQyCur < idxQyMac ; idxQyCur++) {
DefRangeOfInst((IINST)idxQyCur, &idef, &idefMac);
if (idef != idefMac)
break;
}
if (idxQyCur >= idxQyMac)
return bobNil;
fWorking = TRUE;
}
if (idef < idefMac) {
bob = BobFrClsIdx(clsDef, idef);
idef++;
return bob;
}
idxQyCur++;
fWorking = FALSE;
}
}