// // query.c // // perform database queries // #include #include #if defined(OS2) #define INCL_NOCOMMON #define INCL_DOSPROCESS #define INCL_DOSSEMAPHORES #define INCL_DOSFILEMGR #define INCL_DOSERRORS #define INCL_DOSMISC #include #else #include #endif #include #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; } }