// ncbsc.cpp // NCB's implementation of Bsc interface: ///////////////////////////////////////////////////////////////////// #include "pdbimpl.h" #include "ncbrowse.h" #include "ncutil.h" ///////////////////////////////////////////// // NOTE: // IINST = 32 bit: // 16 bit Module Index (iModHdr) // 16 bit Instance/property Index (iProp) ///////////////////////////////////////////// ///////////////////////////////////////////// // close() // REVIEW: needs implementation // must check count first, before really // closing the file. ///////////////////////////////////////////// BOOL Ncb::close() { USHORT i; USHORT iBuf; BOOL bClose = FALSE; BOOL bOwnPdb = FALSE; BOOL bRet = TRUE; for (i = 0; i < ms_prgNcbInfo->size(); i++) { if ((*ms_prgNcbInfo)[i].m_pPdb == m_pdb) { (*ms_prgNcbInfo)[i].m_count--; if ((*ms_prgNcbInfo)[i].m_count == 0) { bOwnPdb = (*ms_prgNcbInfo)[i].m_bIOwnPdb; ms_prgNcbInfo->deleteAt(i); bClose = TRUE; } break; } } if (bClose) { while (m_rgRWBuf.size() > 0) { LoadFrWriteToRead (m_rgRWBuf.size()-1, &iBuf); if (!SaveReadModToStream (m_pdb, iBuf)) bRet = FALSE; } if (!SaveTargetsToStream(m_pdb)) bRet = FALSE; if (!SaveModHdrsToStream(m_pdb)) bRet = FALSE; if (!m_pnm->close()) bRet =FALSE; int i; for (i = 0; i < NCB_MOD_BUF_SIZE; i++) { delete [] m_rgContBuf[i].m_rgProp; delete [] m_rgContBuf[i].m_rgUse; delete [] m_rgContBuf[i].m_rgParam; m_rgContBuf[i].m_rgProp = NULL; m_rgContBuf[i].m_rgUse = NULL; m_rgContBuf[i].m_rgParam = NULL; CloseHandle (m_hMutexNCB); CloseHandle (m_hMutex); m_hMutexNCB = NULL; m_hMutex = NULL; } if (bOwnPdb) { if (bRet && !m_pdb->Commit()) bRet = FALSE; m_pdb->Close(); m_pdb = NULL; } delete this; } return bRet; }; /////////////////////////////////////////////// // iinstInfo () // get information regarding IINST /////////////////////////////////////////////// BOOL Ncb::iinstInfo(IINST iinst, OUT SZ *psz, OUT TYP *ptyp, OUT ATR *patr) { NCB_ENTITY en; if (EnFrIinst (iinst, &en)) { *ptyp = en.m_typ; *patr = en.m_atr; *psz = szFrNi (en.m_ni); return TRUE; } return FALSE; }; ///////////////////////////////////////////// // iinstInfo() // get information regarding IINST //////////////////////////////////////////// BOOL Ncb::iinstInfo (HTARGET hTarget, IINST iinst, OUT SZ *psz, OUT TYP *ptyp, OUT ATR * patr) { USHORT iModHdr = IModFrIinst (iinst); if (!isModInTarget (hTarget, iModHdr)) return FALSE; return iinstInfo (iinst, psz, ptyp, patr); }; ////////////////////////////////////////////////////////////////// // szFrNi() ////////////////////////////////////////////////////////////////// SZ Ncb::szFrNi(NI ni) { return ::szFrNi (m_pnm, ni); }; /////////////////////////////////////////////////////////////////// //irefInfo() // NOT USED /////////////////////////////////////////////////////////////////// BOOL Ncb::irefInfo(IREF iref, OUT SZ *pszModule, OUT LINE *piline) { USHORT iModHdr; USHORT iProp; USHORT iBuf; iModHdr = IModFrIinst (iref); iProp = IPropFrIinst (iref); _ASSERT (iModHdr < m_rgModHdr.size()); *pszModule = szFrNi (m_rgModHdr[iModHdr].m_ni); if (m_rgModHdr[iModHdr].m_cProp <= iProp) return FALSE; if (m_rgStat[iModHdr] == NCB_STATMOD_LOAD_WRITE) { if (!FindWriteIndex (iModHdr, &iBuf)) return FALSE; if (m_rgRWBuf[iBuf].m_rgProp.size() <= iProp) return FALSE; *piline = m_rgRWBuf[iBuf].m_rgProp[iProp].m_lnStart; } else { if (!LoadModForRead (m_pdb, iModHdr, &iBuf)) return FALSE; _ASSERT (m_rgStat[iModHdr] == NCB_STATMOD_LOAD_READ); _ASSERT (iBuf< NCB_MOD_BUF_SIZE); *piline = m_rgContBuf[iBuf].m_rgProp[iProp].m_lnStart; } return TRUE; }; /////////////////////////////////////////////////////////////////// // idefInfo() // the same as iinst info // get info based on the IDEF (which is the same thing as IINST) // first, we have to obtain the PROP, and from there, must check // whether it is really a def or not, otherwise must search for // proper definition. /////////////////////////////////////////////////////////////////// BOOL Ncb::idefInfo(IDEF idef, OUT SZ *pszModule, OUT LINE *piline) { return idefInfo ((HTARGET)-1, idef, pszModule, piline); }; //////////////////////////////////////////////////////////////////// BOOL Ncb::idefInfo(HTARGET hTarget, IDEF idef, OUT SZ *pszModule, OUT LINE *piline) { IINST iinst; USHORT iModHdr; USHORT iProp; USHORT iBuf; if (!GetIDef (hTarget, (IINST)idef, (IDEF *)&iinst, &iBuf)) return FALSE; iModHdr = IModFrIinst (iinst); iProp = IPropFrIinst (iinst); _ASSERT (iModHdr < m_rgModHdr.size()); *pszModule = szFrNi (m_rgModHdr[iModHdr].m_ni); if (m_rgModHdr[iModHdr].m_cProp <= iProp) return FALSE; if (m_rgStat[iModHdr] == NCB_STATMOD_LOAD_WRITE) { *piline = m_rgRWBuf[iBuf].m_rgProp[iProp].m_lnStart; } else { _ASSERT (m_rgStat[iModHdr] == NCB_STATMOD_LOAD_READ); _ASSERT (iBuf< NCB_MOD_BUF_SIZE); *piline = m_rgContBuf[iBuf].m_rgProp[iProp].m_lnStart; } return TRUE; }; /////////////////////////////////////////////////////////// // BOOL GetIDef (IINST iinst, OUT IDEF *pIDef, OUT USHORT * piBuf) // get the idef given the iinst: /////////////////////////////////////////////////////////// BOOL Ncb::GetIDef (HTARGET hTarget, IINST iinst, OUT IDEF * piDef, OUT USHORT * piBuf) { USHORT iModHdr = IModFrIinst ((IINST)iinst); USHORT iProp = IPropFrIinst ((IINST)iinst); USHORT index; USHORT cParam; NI * rgParam; NCB_ENTITY * pEn; _ASSERT (iModHdr < m_rgModHdr.size()); if (iProp >= m_rgModHdr[iModHdr].m_cProp) return FALSE; if (hTarget != (HTARGET)-1) { if (!isModInTarget (hTarget, iModHdr)) return FALSE; }; if (m_rgStat[iModHdr] != NCB_STATMOD_LOAD_WRITE) { if (!LoadModForRead (m_pdb, iModHdr, &index)) return FALSE; if (iProp == 0) { rgParam = m_rgContBuf[index].m_rgParam; cParam = m_rgContBuf[index].m_rgProp[0].m_iParam; } else { rgParam = &(m_rgContBuf[index].m_rgParam[m_rgContBuf[index].m_rgProp[iProp-1].m_iParam]); cParam = m_rgContBuf[index].m_rgProp[iProp].m_iParam - m_rgContBuf[index].m_rgProp[iProp-1].m_iParam; } pEn =&(m_rgContBuf[index].m_rgProp[iProp].m_en); // lock the read buffer m_iReadLock = index; } else { if (!FindWriteIndex (iModHdr, &index)) return FALSE; _ASSERT (m_rgRWBuf[index].m_iModHdr == iModHdr); if (m_rgRWBuf[index].m_rgProp.size() <= iProp) return FALSE; cParam = m_rgRWBuf[index].m_rgProp[iProp].m_rgParam.size(); if (cParam > 0) rgParam = &(m_rgRWBuf[index].m_rgProp[iProp].m_rgParam[0]); else rgParam = NULL; pEn = &m_rgRWBuf[index].m_rgProp[iProp].m_en; } // no need to search if it is already a definition: if (pEn->m_atr & INST_NCB_ATR_DEFN) { *piDef = (IDEF) iinst; *piBuf = index; // release the read lock buffer, so the buffer can be overwritten now m_iReadLock = NCB_MOD_BUF_SIZE; return TRUE; } // search for the real definition, given the rgParam and cParam if (!GetIDef (hTarget, pEn, rgParam, cParam, piDef, piBuf)) { // release the read lock buffer, so the buffer can be overwritten now m_iReadLock = NCB_MOD_BUF_SIZE; return FALSE; } // release the read lock buffer, so the buffer can be overwritten now m_iReadLock = NCB_MOD_BUF_SIZE; return TRUE; }; ////////////////////////////////////////////////////////////////////////////////////////////////// // GetIDef() ////////////////////////////////////////////////////////////////////////////////////////////////// BOOL Ncb::GetIDef (HTARGET hTarget, NCB_ENTITY * pEn, NI * rgParam, USHORT cParam, OUT IDEF * piDef, OUT USHORT * piBuf) { BOOL bFound = FALSE; EnumNi enm(hTarget, pEn->m_ni, this); while (enm.GetNext()) { // if it is not in the write buffer then must be in the read buffer if (enm.m_BufType != NCB_STATMOD_LOAD_WRITE) { if (m_rgContBuf[enm.m_index].m_rgProp[enm.m_iProp].m_en.m_typ == pEn->m_typ && (m_rgContBuf[enm.m_index].m_rgProp[enm.m_iProp].m_en.m_atr & INST_NCB_ATR_DEFN)) { if (enm.m_iProp == 0) bFound = CheckParam (rgParam, cParam, m_rgContBuf[enm.m_index].m_rgParam, m_rgContBuf[enm.m_index].m_rgProp[0].m_iParam); else { bFound = CheckParam (rgParam, cParam, &m_rgContBuf[enm.m_index].m_rgParam[m_rgContBuf[enm.m_index].m_rgProp[enm.m_iProp-1].m_iParam], m_rgContBuf[enm.m_index].m_rgProp[enm.m_iProp].m_iParam - m_rgContBuf[enm.m_index].m_rgProp[enm.m_iProp - 1].m_iParam); } if (bFound) { // IINST creation: // REVIEW: should do similar to DupArray() if (piDef == NULL) piDef = (IDEF *) malloc (sizeof (IINST)); *piDef = (enm.m_iModHdr << 16) | enm.m_iProp; *piBuf = enm.m_index; UpdateBuffer(enm.m_index); return TRUE; } } } else // check the write buffer: { if (m_rgRWBuf[enm.m_index].m_rgProp[enm.m_iProp].m_en.m_typ == pEn->m_typ && m_rgRWBuf[enm.m_index].m_rgProp[enm.m_iProp].m_en.m_atr & INST_NCB_ATR_DEFN) { bFound = CheckParam (rgParam, cParam, &m_rgRWBuf[enm.m_index].m_rgProp[enm.m_iProp].m_rgParam[0], m_rgRWBuf[enm.m_index].m_rgProp[enm.m_iProp].m_rgParam.size()); if (bFound) { *piDef = (enm.m_iModHdr << 16) | enm.m_iProp; *piBuf = enm.m_index; return TRUE; } } } } return FALSE; }; // will return TRUE is acceptance ration is > 0.5 for all parameters. #define ACCEPTANCE_RATIO 0.5 ////////////////////////////////////////////////////////////////// // BOOL CheckParam() //for functions and variables: // variables: // will check if it is the same type or not: // function: // checks if it is the same return value, and params. ////////////////////////////////////////////////////////////////// BOOL Ncb::CheckParam(NI * rg1, USHORT c1, NI * rg2, USHORT c2) { double flRatio = 1.0; double flCur; USHORT i; unsigned cbMatch, cbMin; // number of params are not the same so, just return FALSE: if (c1 != c2) return FALSE; i = 1; // ignoring the return type while (flRatio > ACCEPTANCE_RATIO && i < c1) { if (!NiFuzzyMatch (m_pnm, rg1[i], rg2[i], cbMatch, cbMin)) { flCur = (double)cbMatch / (double)cbMin; if (flRatio > flCur) flRatio = flCur; } i++; } if (flRatio > ACCEPTANCE_RATIO) return TRUE; return FALSE; }; ////////////////////////////////////////////////////////////////// // BOOL checkParam() //for functions and variables: // variables: // will check if it is the same type or not: // function: // checks if it is the same return value, and params. ////////////////////////////////////////////////////////////////// BOOL Ncb::checkParams(IINST iinst, SZ * pszParam, ULONG cParam) { double flRatio = 1.0; double flCur; USHORT i; unsigned cbMatch, cbMin; NI * rgParam = NULL; ULONG count = 0; SZ szParam; getParams (iinst, &rgParam, &count); // number of params are not the same so, just return FALSE: if (cParam != count) goto fail; i = 1; // ignoring the return type while (flRatio > ACCEPTANCE_RATIO && i < count) { szParam = szFrNi (rgParam[i]); if (!SzFuzzyMatch (pszParam[i], szParam, cbMatch, cbMin)) { flCur = (double)cbMatch / (double)cbMin; if (flRatio > flCur) flRatio = flCur; } i++; } disposeArray (rgParam); if (flRatio > ACCEPTANCE_RATIO) return TRUE; else return FALSE; fail: disposeArray (rgParam); return FALSE; }; /////////////////////////////////////////////////////////////////// // imodInfo() // returns the name of the module /////////////////////////////////////////////////////////////////// BOOL Ncb::imodInfo(IMOD imod, OUT SZ *pszModule) { _ASSERT (imod < m_rgModHdr.size()); *pszModule = szFrNi (m_rgModHdr[imod].m_ni); return TRUE; }; char *ptypNCBtab[] = { "undef", // SBR_TYP_UNKNOWN "function", // SBR_TYP_FUNCTION "label", // SBR_TYP_LABEL "parameter", // SBR_TYP_PARAMETER "variable", // SBR_TYP_VARIABLE "constant", // SBR_TYP_CONSTANT "macro", // SBR_TYP_MACRO "typedef", // SBR_TYP_TYPEDEF "struct_name", // SBR_TYP_STRUCNAM "enum_name", // SBR_TYP_ENUMNAM "enum_mem", // SBR_TYP_ENUMMEM "union_name", // SBR_TYP_UNIONNAM "segment", // SBR_TYP_SEGMENT "group", // SBR_TYP_GROUP "program", // SBR_TYP_PROGRAM "class", // SBR_TYP_CLASSNAM "mem_func", // SBR_TYP_MEMFUNC "mem_var", // SBR_TYP_MEMVAR }; ////////////////////////////////////////////////////////////////// // szFrTyp() // Get the name of the type ////////////////////////////////////////////////////////////////// SZ Ncb::szFrTyp(TYP typ) { return ptypNCBtab[typ]; }; #define C_NCB_ATR 12 char *patrNCBtab[] = { "local", // SBR_ATR_LOCAL "static", // SBR_ATR_STATIC "shared", // SBR_ATR_SHARED "near", // SBR_ATR_NEAR "common", // SBR_ATR_COMMON "decl_only", // SBR_ATR_DECL_ONLY "public", // SBR_ATR_PUBLIC "named", // SBR_ATR_NAMED "module", // SBR_ATR_MODULE "virtual", // SBR_ATR_VIRTUAL "private", // SBR_ATR_PRIVATE "protected", // SBR_ATR_PROTECT }; //////////////////////////////////////////////////// // szFrAtr (ATR) // get the name of the attributes, separated by a ':' //////////////////////////////////////////////////// SZ Ncb::szFrAtr(ATR atr) { static char buf[512]; buf[0] = 0; for (int i=0; i < C_NCB_ATR; i++) { if (atr & (1< rgProp; *prgProp = NULL; *pcProp = 0; if (*pindex >= NCB_MOD_BUF_SIZE) { // since the bit is set, now we have to load // the module content since it may be in there: if (!LoadModForRead (m_pdb, iModHdr, &index)) return FALSE; } else index = *pindex; // now module content is loaded, so start binary search // we have to call twice, once for classes // and another for other info GetIPropFrMod (ni, m_rgModHdr[iModHdr].m_cClassProp, m_rgContBuf[index].m_rgProp, 0, &rgProp); GetIPropFrMod (ni, m_rgModHdr[iModHdr].m_cProp - m_rgModHdr[iModHdr].m_cClassProp, &m_rgContBuf[index].m_rgProp[m_rgModHdr[iModHdr].m_cClassProp], m_rgModHdr[iModHdr].m_cClassProp, &rgProp); *pindex = index; return DupArray (prgProp, pcProp, rgProp); }; //////////////////////////////////////////////////////// // void GetIPropFrMod (NI ni, USHORT cProp, NCB_PROP * rgProp, OUT Array * prgProp) // get array of iprop given an array of NCB_PROP //////////////////////////////////////////////////////// void Ncb::GetIPropFrMod (NI ni, USHORT cProp, NCB_PROP * rgProp, USHORT disp, OUT Array * prgProp) { // rgProp has a sorted NIs _ASSERT (rgProp); _ASSERT (prgProp); // no prop in this module, so just return. if (cProp == 0) return; // binary search: // rgProp has a sorted strings so it must search all Ni's USHORT i; USHORT iProp; for (i = 0 ; i < cProp; i++) { if (rgProp[i].m_en.m_ni == ni) { iProp = i + disp; prgProp->append (iProp); } } }; //////////////////////////////////////////////////////// // GetiPropFrMod (SZ sz, USHORT iModHdr, OUT USHORT ** prgProp) // given the index for modhdr, and Ni, return an array of iProps ///////////////////////////////////////////////////////// BOOL Ncb::GetIPropFrMod(SZ sz, USHORT iModHdr, OUT USHORT *pindex, OUT USHORT ** prgProp, OUT ULONG * pcProp) { USHORT index; // temporary array to hold iProps that have the same NI // in the module Array rgProp; *prgProp = NULL; *pcProp = 0; if (*pindex >= NCB_MOD_BUF_SIZE) { // since the bit is set, now we have to load // the module content since it may be in there: if (!LoadModForRead (m_pdb, iModHdr, &index)) return FALSE; } else index = *pindex; // now module content is loaded, so start binary search // we have to call twice, once for classes // and another for other info GetIPropFrMod (sz, m_rgModHdr[iModHdr].m_cClassProp, m_rgContBuf[index].m_rgProp, 0, &rgProp); GetIPropFrMod (sz, m_rgModHdr[iModHdr].m_cProp - m_rgModHdr[iModHdr].m_cClassProp, &m_rgContBuf[index].m_rgProp[m_rgModHdr[iModHdr].m_cClassProp], m_rgModHdr[iModHdr].m_cClassProp, &rgProp); *pindex = index; return DupArray (prgProp, pcProp, rgProp); }; //////////////////////////////////////////////////////// // void GetIPropFrMod (SZ sz, USHORT cProp, NCB_PROP * rgProp, OUT Array * prgProp) // get array of iprop given an array of NCB_PROP //////////////////////////////////////////////////////// void Ncb::GetIPropFrMod (SZ sz, USHORT cProp, NCB_PROP * rgProp, USHORT disp, OUT Array * prgProp) { // no prop in this module, so just return. if (cProp == 0) return; // rgProp has a sorted NIs _ASSERT (rgProp); _ASSERT (prgProp); // rgProp has a sorted strings so it must search all Ni's USHORT i; USHORT iProp; if (!FindFirstNi (sz, cProp, rgProp, &i)) return; while (i < cProp) { if (_tcscmp (szFrNi(rgProp[i].m_en.m_ni), sz) == 0) { iProp = i + disp; prgProp->append (iProp); i++; } else break; }; }; /////////////////////////////////////////////////////////// // BOOL FindFirstSz (SZ sz, USHORT cClassProp, NCB_PROP * rgProp, OUT USHORT * piFirst) // do a binary search on array rgProp to find the first matched NI // rgProp has a sorted NIs, and possible multiple NIs //////////////////////////////////////////////////////////// BOOL Ncb::FindFirstNi (SZ sz, USHORT cProp, NCB_PROP * rgProp, OUT USHORT * piFirst) { _ASSERT (rgProp); _ASSERT (cProp); USHORT iMin = 0; USHORT iMax = cProp - 1; USHORT iMid; // full binary search (ie: never breaks since we want to find // the first ni) while (iMin < iMax) { iMid = iMin + (iMax - iMin)/2; if (_tcscmp (szFrNi(rgProp[iMid].m_en.m_ni),sz) >= 0) iMax = iMid; else iMin = iMid + 1; }; if (_tcscmp (szFrNi (rgProp[iMin].m_en.m_ni),sz) == 0) { *piFirst = iMin; return TRUE; } return FALSE; }; /////////////////////////////////////////////////////// // getOverloadArray() //////////////////////////////////////////////////////// BOOL Ncb::getOverloadArray(SZ sz, MBF mbf, OUT IINST **ppiinst, OUT ULONG *pciinst) { return getOverloadArray ((HTARGET)-1, sz, mbf, ppiinst, pciinst); }; /////////////////////////////////////////////////////// // getOverloadArray() //////////////////////////////////////////////////////// BOOL Ncb::getOverloadArray(HTARGET hTarget, SZ sz, MBF mbf, OUT IINST **ppiinst, OUT ULONG *pciinst) { Array rgIinst; IINST iinstArr; *ppiinst = NULL; *pciinst = 0; EnumNi enm(hTarget, sz, this); // iterate each module that has this NI: while (enm.GetNext()) { if (enm.m_BufType == NCB_STATMOD_LOAD_WRITE) { if (!(m_rgRWBuf[enm.m_index].m_rgProp[enm.m_iProp].m_en.m_atr & INST_NCB_ATR_DEFN)) continue; if (TypFilter(m_rgRWBuf[enm.m_index].m_rgProp[enm.m_iProp].m_en.m_typ, mbf)) { iinstArr = (enm.m_iModHdr << 16) | enm.m_iProp; rgIinst.append (iinstArr); } } else { if (!(m_rgContBuf[enm.m_index].m_rgProp[enm.m_iProp].m_en.m_atr & INST_NCB_ATR_DEFN)) continue; if (TypFilter(m_rgContBuf[enm.m_index].m_rgProp[enm.m_iProp].m_en.m_typ, mbf)) { iinstArr = (enm.m_iModHdr << 16) | enm.m_iProp; rgIinst.append (iinstArr); } } } if (rgIinst.size() == 0) return FALSE; return DupArray (ppiinst, pciinst, rgIinst); }; ///////////////////////////////////////////////////////// // getUsesArray() ///////////////////////////////////////////////////////// BOOL Ncb::getUsesArray(IINST iinst, MBF mbf, OUT IINST **ppiinst, OUT ULONG *pciinst) { *ppiinst = NULL; *pciinst = 0; return FALSE; }; ////////////////////////////////////////////////////////// // getUsedByArray() ////////////////////////////////////////////////////////// BOOL Ncb::getUsedByArray(IINST iinst, MBF mbf, OUT IINST **ppiinst, OUT ULONG *pciinst) { *ppiinst = NULL; *pciinst = 0; return FALSE; }; ///////////////////////////////////////////////////////// // getBaseArray() // given the IINST (which I suppose must be a class name), it will return // its base class names. ///////////////////////////////////////////////////////// BOOL Ncb::getBaseArray(IINST iinst, OUT IINST **ppiinst, OUT ULONG *pciinst) { *ppiinst = NULL; *pciinst = 0; return getBaseArray ((HTARGET)-1, iinst, ppiinst, pciinst); }; ///////////////////////////////////////////////////////// BOOL Ncb::getBaseArray(HTARGET hTarget, IINST iinst, OUT IINST **ppiinst, OUT ULONG *pciinst) { IINST iinstDef; USHORT iBuf; USHORT iModHdr; USHORT iProp; USHORT cUse; *ppiinst = NULL; *pciinst = 0; if (!GetIDef (hTarget, iinst, (IDEF *)&iinstDef, &iBuf)) return FALSE; iModHdr = IModFrIinst (iinstDef); iProp = IPropFrIinst (iinstDef); _ASSERT (iModHdr < m_rgModHdr.size()); if (m_rgModHdr[iModHdr].m_cProp <= iProp) return FALSE; if (m_rgStat[iModHdr] == NCB_STATMOD_LOAD_WRITE) { if (m_rgRWBuf[iBuf].m_rgProp[iProp].m_en.m_typ != INST_TYP_CLASSNAM && m_rgRWBuf[iBuf].m_rgProp[iProp].m_en.m_typ != INST_TYP_MSGMAP) return FALSE; cUse = m_rgRWBuf[iBuf].m_rgProp[iProp].m_rgUse.size(); if (cUse == 0) return FALSE; return (getBaseArray (ppiinst, pciinst, iModHdr, &m_rgRWBuf[iBuf].m_rgProp[iProp].m_rgUse[0], cUse)); } else { _ASSERT (m_rgStat[iModHdr] == NCB_STATMOD_LOAD_READ); _ASSERT (iBuf< NCB_MOD_BUF_SIZE); if (m_rgContBuf[iBuf].m_rgProp[iProp].m_en.m_typ != INST_TYP_CLASSNAM && m_rgContBuf[iBuf].m_rgProp[iProp].m_en.m_typ != INST_TYP_MSGMAP) return FALSE; if (iProp == 0) { cUse = m_rgContBuf[iBuf].m_rgProp[0].m_iUse; if (cUse == 0) return FALSE; return getBaseArray (ppiinst, pciinst, iModHdr, m_rgContBuf[iBuf].m_rgUse, cUse); } cUse = m_rgContBuf[iBuf].m_rgProp[iProp].m_iUse - m_rgContBuf[iBuf].m_rgProp[iProp -1].m_iUse; if (cUse == 0) return FALSE; return getBaseArray (ppiinst, pciinst, iModHdr, &m_rgContBuf[iBuf].m_rgUse[m_rgContBuf[iBuf].m_rgProp[iProp-1].m_iUse], cUse); } return FALSE; }; //////////////////////////////////////////////////// // getBaseArray (OUT IINST ** ppiinst, OUT ULONG * pciinst, USHORT iModHdr, NCB_USE * rgUse, USHORT count) ////////////////////////////////////////////////////////// BOOL Ncb::getBaseArray (OUT IINST ** ppiinst, OUT ULONG * pciinst, USHORT iModHdr, NCB_USE * rgUse, USHORT count) { Array rgiinst; USHORT i; IINST iinst; *ppiinst = NULL; *pciinst = 0; for (i = 0; i < count; i++) { if (rgUse[i].m_kind == NCB_KIND_BASECLASS) { iinst = (iModHdr << 16) | rgUse[i].m_iProp; rgiinst.append (iinst); } } if (rgiinst.size() == 0) return FALSE; return (DupArray (ppiinst, pciinst, rgiinst)); }; ////////////////////////////////////////////////////////// // getDervArray() ////////////////////////////////////////////////////////// BOOL Ncb::getDervArray(IINST iinst, OUT IINST **ppiinst, OUT ULONG *pciinst) { *ppiinst = NULL; *pciinst = 0; return getDervArray ((HTARGET)-1, iinst, ppiinst, pciinst); }; //////////////////////////////////////////////////////////////////////////// BOOL Ncb::getDervArray(HTARGET hTarget, IINST iinst, OUT IINST **ppiinst, OUT ULONG *pciinst) { NCB_ENTITY en; USHORT iCurModHdr = (USHORT)-1; Array rgIinst; IINST iinstDerv; USHORT i,j; USHORT iUse; *ppiinst = NULL; *pciinst = 0; if (!EnFrIinst (iinst, &en)) return FALSE; _ASSERT (en.m_typ == INST_TYP_CLASSNAM); EnumNi enm(hTarget, en.m_ni, this); // iterate each module that has this NI: while (enm.GetNext()) { if (enm.m_BufType == NCB_STATMOD_LOAD_WRITE) { for (i = 0; i < m_rgRWBuf[enm.m_index].m_rgProp.size(); i++) { if (m_rgRWBuf[enm.m_index].m_rgProp[i].m_en.m_typ != INST_TYP_CLASSNAM) continue; if (!(m_rgRWBuf[enm.m_index].m_rgProp[i].m_en.m_atr & INST_NCB_ATR_DEFN)) continue; if (m_rgRWBuf[enm.m_index].m_rgProp[i].m_rgUse.size() == 0) continue; for (j = 0; j < m_rgRWBuf[enm.m_index].m_rgProp[i].m_rgUse.size(); j++) { if (m_rgRWBuf[enm.m_index].m_rgProp [m_rgRWBuf[enm.m_index].m_rgProp[i].m_rgUse[j].m_iProp].m_en.m_ni == en.m_ni) { iinstDerv = (enm.m_iModHdr << 16) | i; rgIinst.append (iinstDerv); break; } } } } else { for (i = 0; i < m_rgModHdr[enm.m_iModHdr].m_cClassProp; i++) { if (m_rgContBuf[enm.m_index].m_rgProp[i].m_en.m_atr & INST_NCB_ATR_DEFN) continue; if (i == 0) iUse = 0; else iUse = m_rgContBuf[enm.m_index].m_rgProp[i-1].m_iUse; for (j = iUse; j < m_rgContBuf[enm.m_index].m_rgProp[i].m_iUse; j++) { if (m_rgContBuf[enm.m_index].m_rgProp [m_rgContBuf[enm.m_index].m_rgUse[j].m_iProp].m_en.m_ni == en.m_ni) { iinstDerv = (enm.m_iModHdr << 16) | i; rgIinst.append (iinstDerv); break; } } } } enm.SkipNi(); // skip Nis for this module } if (rgIinst.size() == 0) return FALSE; return DupArray (ppiinst, pciinst, rgIinst); }; ////////////////////////////////////////////////////////// // BOOL EnFrIinst (iinst, en) ////////////////////////////////////////////////////////// BOOL Ncb::EnFrIinst (IINST iinst, NCB_ENTITY * pEn) { USHORT iModHdr = IModFrIinst (iinst); USHORT iProp = IPropFrIinst (iinst); USHORT index; _ASSERT (iModHdr < m_rgModHdr.size()); if (m_rgModHdr[iModHdr].m_cProp <= iProp) return FALSE; if (m_rgStat[iModHdr] != NCB_STATMOD_LOAD_WRITE) { // check item from read-only buffer, loading it if necessary if (!LoadModForRead (m_pdb, iModHdr, &index)) return FALSE; _ASSERT (index < NCB_MOD_BUF_SIZE); if (iProp >= m_rgModHdr[iModHdr].m_cProp) return FALSE; *pEn = m_rgContBuf[index].m_rgProp[iProp].m_en; } else { // check item from write buffer if (!FindWriteIndex (iModHdr, &index)) return FALSE; _ASSERT (index < m_rgRWBuf.size()); if (iProp >= m_rgRWBuf[index].m_rgProp.size()) return FALSE; *pEn = m_rgRWBuf[index].m_rgProp[iProp].m_en; } return TRUE; }; ////////////////////////////////////////////////////////// // BOOL EnFrIinst (iinst, en) ////////////////////////////////////////////////////////// BOOL Ncb::EnFrIinst (IINST iinst, NCB_ENTITY * pEn, HTARGET hTarget) { USHORT iModHdr = IModFrIinst (iinst); USHORT iProp = IPropFrIinst (iinst); if (!isModInTarget (hTarget, iModHdr)) return FALSE; return EnFrIinst (iinst, pEn); }; ////////////////////////////////////////////////////////// // getMembersArray() /////////////////////////////////////////////////////////// BOOL Ncb::getMembersArray(IINST iinst, MBF mbf, OUT IINST **ppiinst, OUT ULONG *pciinst) { *ppiinst = NULL; *pciinst = 0; return getMembersArray ((HTARGET)-1, iinst, mbf, ppiinst, pciinst); }; ///////////////////////////////////////////////////////////// BOOL Ncb::getMembersArray(HTARGET hTarget, IINST iinst, MBF mbf, OUT IINST **ppiinst, OUT ULONG *pciinst) { IINST iinstDef; USHORT iBuf; USHORT iModHdr; USHORT iProp; USHORT i; Array rgiinst; USHORT iCurProp; IINST iinstCur; TYP typ; ATR atr; USHORT iMin = 0; *ppiinst = NULL; *pciinst = 0; if (!GetIDef (hTarget, iinst, (IDEF *)&iinstDef, &iBuf)) return FALSE; iModHdr = IModFrIinst (iinstDef); iProp = IPropFrIinst (iinstDef); _ASSERT (iModHdr < m_rgModHdr.size()); if (m_rgModHdr[iModHdr].m_cProp <= iProp) return FALSE; if (m_rgStat[iModHdr] == NCB_STATMOD_LOAD_WRITE) { if (m_rgRWBuf[iBuf].m_rgProp[iProp].m_en.m_typ != INST_TYP_CLASSNAM && m_rgRWBuf[iBuf].m_rgProp[iProp].m_en.m_typ != INST_TYP_MSGMAP) return FALSE; for (i = 0; i < m_rgRWBuf[iBuf].m_rgProp[iProp].m_rgUse.size() ; i++) { if (m_rgRWBuf[iBuf].m_rgProp[iProp].m_rgUse[i].m_kind != NCB_KIND_CONTAINMENT) continue; iCurProp = m_rgRWBuf[iBuf].m_rgProp[iProp].m_rgUse[i].m_iProp; typ = m_rgRWBuf[iBuf].m_rgProp[iCurProp].m_en.m_typ; atr = m_rgRWBuf[iBuf].m_rgProp[iCurProp].m_en.m_atr; if (TypFilter(typ, mbf)) { if ((typ == INST_TYP_CLASSNAM) && (atr & INST_NCB_ATR_DECL)) continue; iinstCur = (iModHdr << 16) | iCurProp; rgiinst.append (iinstCur); } } } else { _ASSERT (m_rgStat[iModHdr] == NCB_STATMOD_LOAD_READ); _ASSERT (iBuf< NCB_MOD_BUF_SIZE); if (m_rgContBuf[iBuf].m_rgProp[iProp].m_en.m_typ != INST_TYP_CLASSNAM && m_rgContBuf[iBuf].m_rgProp[iProp].m_en.m_typ != INST_TYP_MSGMAP) return FALSE; if (iProp != 0) iMin = m_rgContBuf[iBuf].m_rgProp[iProp-1].m_iUse; for (i = iMin; i < m_rgContBuf[iBuf].m_rgProp[iProp].m_iUse; i++) { if (m_rgContBuf[iBuf].m_rgUse[i].m_kind != NCB_KIND_CONTAINMENT) continue; iCurProp = m_rgContBuf[iBuf].m_rgUse[i].m_iProp; typ = m_rgContBuf[iBuf].m_rgProp[iCurProp].m_en.m_typ; atr = m_rgContBuf[iBuf].m_rgProp[iCurProp].m_en.m_atr; if (TypFilter(typ, mbf)) { if ((typ == INST_TYP_CLASSNAM) && (atr & INST_NCB_ATR_DECL)) continue; iinstCur = (iModHdr << 16) | iCurProp; rgiinst.append (iinstCur); } } } if (rgiinst.size() == 0) return TRUE; return DupArray (ppiinst, pciinst, rgiinst); }; ////////////////////////////////////////////// // TypFilter() ////////////////////////////////////////////// BOOL Ncb::TypFilter (USHORT typ, MBF mbf) { if (mbf == mbfAll) return TRUE; switch (typ) { case INST_TYP_FUNCTION: case INST_TYP_LABEL: case INST_TYP_PROGRAM: case INST_TYP_MEMFUNC: return !!(mbf & mbfFuncs); case INST_TYP_PARAMETER: case INST_TYP_VARIABLE: case INST_TYP_SEGMENT: case INST_TYP_GROUP: case INST_TYP_MEMVAR: return !!(mbf & mbfVars); case INST_TYP_CONSTANT: case INST_TYP_MACRO: case INST_TYP_ENUMMEM: return !!(mbf & mbfMacros); case INST_TYP_TYPEDEF: case INST_TYP_ENUMNAM: case INST_TYP_UNIONNAM: return !!(mbf & mbfTypes); case INST_TYP_CLASSNAM: case INST_TYP_STRUCNAM: return !!(mbf & mbfClass); case INST_TYP_INCL: return !!(mbf & mbfIncl); case INST_TYP_MSGMAP: case INST_TYP_MSGITEM: return !!(mbf & mbfMsgMap); } return FALSE; } // primitives for getting definition and reference information /////////////////////////////////////////////////////////// // getDefArray() /////////////////////////////////////////////////////////// BOOL Ncb::getDefArray(IINST iinst, OUT IDEF **ppidef, OUT ULONG *pciidef) { *ppidef = NULL; *pciidef = 0; return getDefArray ((HTARGET)-1, iinst, ppidef, pciidef); }; //////////////////////////////////////////////////////////// BOOL Ncb::getDefArray(HTARGET hTarget, IINST iinst, OUT IDEF **ppidef, OUT ULONG *pciidef) { USHORT iBuf; *ppidef = NULL; *pciidef = 0; IDEF idef; _ASSERT (ppidef); if (!GetIDef (hTarget, iinst, &idef, &iBuf)) return FALSE; *pciidef = 1; *ppidef = (IDEF *) malloc (sizeof (IDEF)); **ppidef = idef; return TRUE; }; /////////////////////////////////////////////////////////// // getRefArray() /////////////////////////////////////////////////////////// BOOL Ncb::getRefArray(IINST iinst, OUT IREF **ppiref, OUT ULONG *pciiref) { *ppiref = (IREF *) malloc (sizeof (IREF)); **ppiref = iinst; *pciiref = 1; return TRUE; }; // primitives for managing source module contents ///////////////////////////////////////////////////////// // getModuleContents() ///////////////////////////////////////////////////////// BOOL Ncb::getModuleContents(IMOD imod, MBF mbf, OUT IINST **ppiinst, OUT ULONG *pciinst) { USHORT index; Array rgiinst; IINST iinst; USHORT i; *ppiinst = NULL; *pciinst = 0; if (m_rgStat[imod] == NCB_STATMOD_LOAD_WRITE) { if (!FindWriteIndex (imod, &index)) return FALSE; for (i = 0; i < m_rgRWBuf[index].m_rgProp.size() ; i++) { if (mbf != mbfAll) { if (!(m_rgRWBuf[index].m_rgProp[i].m_en.m_atr & INST_NCB_ATR_DEFN)) continue; } if (TypFilter (m_rgRWBuf[index].m_rgProp[i].m_en.m_typ, mbf)) { iinst = (imod << 16) | i; rgiinst.append (iinst); } } } else { if (!LoadModForRead (m_pdb, imod, &index)) return FALSE; for (i = 0; i < m_rgModHdr[imod].m_cProp; i++) { if (!(m_rgContBuf[index].m_rgProp[i].m_en.m_atr & INST_NCB_ATR_DEFN)) continue; if (TypFilter (m_rgContBuf[index].m_rgProp[i].m_en.m_typ, mbf)) { iinst = (imod << 16) | i; rgiinst.append (iinst); } } } if (rgiinst.size() == 0) return FALSE; return DupArray (ppiinst, pciinst, rgiinst); }; ////////////////////////////////////////////////////////// // getModuleByName() ////////////////////////////////////////////////////////// BOOL Ncb::getModuleByName(SZ sz, OUT IMOD *pimod) { USHORT i; for (i = 0; i < m_rgModHdr.size(); i++) { if (_tcsicmp (szFrNi (m_rgModHdr[i].m_ni), sz) == 0) { *pimod = i; return TRUE; } } return FALSE; }; ////////////////////////////////////////////////////////// // getAllModulesArray() // REVIEW: // Needs to utilize the target information!! // Right now it just returns all the modules in the // database. ////////////////////////////////////////////////////////// BOOL Ncb::getAllModulesArray(OUT IMOD **ppimod, OUT ULONG *pcimod) { USHORT i; Array rgimod; *ppimod = NULL; *pcimod = 0; for (i = 0; i < m_rgModHdr.size(); i++) rgimod.append (i); return DupArray(ppimod, pcimod, rgimod); }; ////////////////////////////////////////////////////////// BOOL Ncb::getAllModulesArray (HTARGET hTarget, OUT IMOD **ppimod, OUT ULONG * pcimod) { USHORT i; USHORT iTarget; Array rgimod; if (!FindITarget (hTarget, &iTarget)) return FALSE; for (i = 0; i < m_rgTargetInfo[iTarget].m_rgModInfo.size(); i++) { rgimod.append (m_rgTargetInfo[iTarget].m_rgModInfo[i].m_iModHdr); } return DupArray (ppimod, pcimod, rgimod); }; /////////////////////////////////////////////////////////// // disposeArray() // call this when a computed array is no longer required //////////////////////////////////////////////////////////// void Ncb::disposeArray(void *pAnyArray) { if (pAnyArray) free(pAnyArray); }; //////////////////////////////////////////////////////// // formatDname() // call this to get a pretty form of a decorated name // REVIEW:decided not to decorate name for a moment. // (Is it really needed for NCB?) //////////////////////////////////////////////////////// SZ Ncb::formatDname(SZ szDecor) { return szDecor; }; //////////////////////////////////////////////////////// // fInstFilter() // call this to do category testing on instances //////////////////////////////////////////////////////// BOOL Ncb::fInstFilter(IINST iinst, MBF mbf) { NCB_ENTITY en; if (!EnFrIinst (iinst, &en)) return FALSE; return TypFilter (en.m_typ, mbf); }; ///////////////////////////////////////////////////////// // primitives for converting index types // iinstFrIref (IREF) ///////////////////////////////////////////////////////// IINST Ncb::iinstFrIref(IREF iref) { // return the same id. return iref; }; ////////////////////////////////////////////////////////// // iinstFrIdef() ////////////////////////////////////////////////////////// IINST Ncb::iinstFrIdef(IDEF idef) { return idef; }; /////////////////////////////////////////////////////////// // iinstContextIref() /////////////////////////////////////////////////////////// IINST Ncb::iinstContextIref(IREF iref) { return iref; }; // general size information /////////////////////////////////////////////////////////// // getStatistics () /////////////////////////////////////////////////////////// BOOL Ncb::getStatistics(BSC_STAT *) { //NYI _ASSERT (FALSE); return FALSE; }; ////////////////////////////////////////////////////////// // getModuleStatistics () ////////////////////////////////////////////////////////// BOOL Ncb::getModuleStatistics(IMOD, BSC_STAT *) { // NYI _ASSERT (FALSE); return FALSE; }; ////////////////////////////////////////////////////////// // IModFrIinst () // get the imod from IINST ////////////////////////////////////////////////////////// USHORT Ncb::IModFrIinst (IINST iinst) { return (USHORT)((iinst & 0xffff0000) >> 16); }; ///////////////////////////////////////////////////////// // IPropFrIinst() // get the iProp from IINST ////////////////////////////////////////////////////////// USHORT Ncb::IPropFrIinst (IINST iinst) { return (USHORT) (iinst & 0x0000ffff); }; ////////////////////////////////////////////////////////// // getParams() ////////////////////////////////////////////////////////// SZ Ncb::getParams (IINST iinst) { USHORT iModHdr = IModFrIinst (iinst); USHORT iProp = IPropFrIinst (iinst); static char buf[512]; USHORT i; SZ_CONST szParam; NI * rgParam = NULL; ULONG cParam = 0; buf[0] = NULL; if (m_rgModHdr[iModHdr].m_cProp <= iProp) return FALSE; if (getParams (iinst, &rgParam, &cParam)) { // skip return type: for (i = 1; i < cParam; i++) { m_pnm->getName (rgParam[i], &szParam); if (i == 1) strcat (buf, szParam); else { strcat (buf, ", "); strcat (buf, szParam); } } } disposeArray(rgParam); return buf; }; ////////////////////////////////////////////////////////// // getParams() ////////////////////////////////////////////////////////// BOOL Ncb::getParams (IINST iinst, OUT NI **prgParam, OUT ULONG * pcParam) { USHORT iModHdr = IModFrIinst (iinst); USHORT iProp = IPropFrIinst (iinst); USHORT index; USHORT i, iMin; Array arrParam; _ASSERT (iModHdr < m_rgModHdr.size()); if (m_rgModHdr[iModHdr].m_cProp <= iProp) return FALSE; if (m_rgStat[iModHdr] != NCB_STATMOD_LOAD_WRITE) { if (!LoadModForRead (m_pdb, iModHdr, &index)) return FALSE; _ASSERT (index < NCB_MOD_BUF_SIZE); if (iProp == 0) iMin = 0; else iMin = m_rgContBuf[index].m_rgProp[iProp-1].m_iParam; for (i = iMin ; i < m_rgContBuf[index].m_rgProp[iProp].m_iParam;i++) arrParam.append (m_rgContBuf[index].m_rgParam[i]); } else { if (!FindWriteIndex (iModHdr, &index)) return FALSE; if (m_rgRWBuf[index].m_rgProp.size() <= iProp) return FALSE; _ASSERT (m_rgRWBuf[index].m_iModHdr == iModHdr); for (i = 0; i < m_rgRWBuf[index].m_rgProp[iProp].m_rgParam.size(); i++) arrParam.append (m_rgRWBuf[index].m_rgProp[iProp].m_rgParam[i]); } return DupArray (prgParam, pcParam, arrParam); }; USHORT Ncb::getNumParam (IINST iinst) { USHORT iModHdr = IModFrIinst (iinst); USHORT iProp = IPropFrIinst (iinst); USHORT index; USHORT iMin; _ASSERT (iModHdr < m_rgModHdr.size()); if (m_rgModHdr[iModHdr].m_cProp <= iProp) return FALSE; if (m_rgStat[iModHdr] != NCB_STATMOD_LOAD_WRITE) { if (!LoadModForRead (m_pdb, iModHdr, &index)) return 0; _ASSERT (index < NCB_MOD_BUF_SIZE); if (iProp == 0) iMin = 0; else iMin = m_rgContBuf[index].m_rgProp[iProp-1].m_iParam; // skip the return type return (m_rgContBuf[index].m_rgProp[iProp].m_iParam - iMin - 1); } else { if (!FindWriteIndex (iModHdr, &index)) return 0; _ASSERT (m_rgRWBuf[index].m_iModHdr == iModHdr); // skip the return type if (m_rgRWBuf[index].m_rgProp.size() <= iProp) return 0; return m_rgRWBuf[index].m_rgProp[iProp].m_rgParam.size()-1; } return 0; }; ////////////////////////////////////////////////////////////////////// // getParam() ////////////////////////////////////////////////////////////////////// SZ Ncb::getParam (IINST iinst, USHORT ind) { USHORT iModHdr = IModFrIinst (iinst); USHORT iProp = IPropFrIinst (iinst); USHORT index; static char buf[512]; USHORT iMin; SZ_CONST szParam; _ASSERT (iModHdr < m_rgModHdr.size()); if (m_rgModHdr[iModHdr].m_cProp <= iProp) return FALSE; buf[0] = NULL; if (m_rgStat[iModHdr] != NCB_STATMOD_LOAD_WRITE) { if (!LoadModForRead (m_pdb, iModHdr, &index)) return buf; _ASSERT (index < NCB_MOD_BUF_SIZE); if (iProp == 0) iMin = 0; else iMin = m_rgContBuf[index].m_rgProp[iProp-1].m_iParam; if (iMin + ind + 1 >= m_rgContBuf[index].m_rgProp[iProp].m_iParam) return buf; else { m_pnm->getName (m_rgContBuf[index].m_rgParam[iMin + ind + 1], &szParam); strcat (buf, szParam); } } else { if (!FindWriteIndex (iModHdr, &index)) return buf; _ASSERT (m_rgRWBuf[index].m_iModHdr == iModHdr); // skip the return type if (m_rgRWBuf[index].m_rgProp.size() <= iProp) return buf; if ((ind + 1) >= (USHORT)m_rgRWBuf[index].m_rgProp[iProp].m_rgParam.size()) return buf; m_pnm->getName (m_rgRWBuf[index].m_rgProp[iProp].m_rgParam[ind+1], &szParam); strcat (buf, szParam); } return buf; }; ///////////////////////////////////////////////// // getType() ////////////////////////////////////////////////// SZ Ncb::getType (IINST iinst) { USHORT iModHdr = IModFrIinst (iinst); USHORT iProp = IPropFrIinst (iinst); USHORT index; static char buf[512]; USHORT iMin; SZ_CONST szParam; _ASSERT (iModHdr < m_rgModHdr.size()); buf[0] = NULL; if (m_rgModHdr[iModHdr].m_cProp <= iProp) return FALSE; if (m_rgStat[iModHdr] != NCB_STATMOD_LOAD_WRITE) { if (!LoadModForRead (m_pdb, iModHdr, &index)) return buf; _ASSERT (index < NCB_MOD_BUF_SIZE); if (iProp == 0) iMin = 0; else iMin = m_rgContBuf[index].m_rgProp[iProp-1].m_iParam; // skip the return type if (iMin < m_rgContBuf[index].m_rgProp[iProp].m_iParam) { m_pnm->getName (m_rgContBuf[index].m_rgParam[iMin], &szParam); strcat (buf, szParam); } } else { if (!FindWriteIndex (iModHdr, &index)) return buf; _ASSERT (m_rgRWBuf[index].m_iModHdr == iModHdr); // skip the return type if (m_rgRWBuf[index].m_rgProp.size() <= iProp) return FALSE; if (m_rgRWBuf[index].m_rgProp[iProp].m_rgParam.size() > 0) { m_pnm->getName (m_rgRWBuf[index].m_rgProp[iProp].m_rgParam[0], &szParam); strcat (buf, szParam); } } return buf; }; /////////////////////////////////////////////////// // Ncb::getAllGlobalsArray() // get global information // check for "::" in the symbols: // REVIEW:(should there be an easy way? so I don't have to // getName() all Ni's ?? /////////////////////////////////////////////////// BOOL Ncb::getAllGlobalsArray (MBF mbf, OUT IINST ** ppiinst, OUT ULONG * pciinst) { return getAllGlobalsArray ((HTARGET)-1, mbf, ppiinst, pciinst); }; /////////////////////////////////////////////////// BOOL Ncb::getAllGlobalsArray (HTARGET hTarget, MBF mbf, OUT IINST ** ppiinst, OUT ULONG * pciinst) { Array rgiinst; *ppiinst = NULL; *pciinst = 0; if (mbf & mbfClass) GetGlobalClass (hTarget, &rgiinst); GetGlobalOther (hTarget, mbf, &rgiinst); return DupArray (ppiinst, pciinst, rgiinst); } //////////////////////////////////////////////////////// // Ncb::GetGlobalClass(); //////////////////////////////////////////////////////// BOOL Ncb::GetGlobalClass (HTARGET hTarget, Array * prgiinst) { USHORT i; for (i = 0; i < m_rgModHdr.size(); i++) { if (hTarget != (HTARGET)-1 && !isModInTarget (hTarget, i)) continue; if (!GetGlobalClass (i, prgiinst)) return FALSE; } return TRUE; }; /////////////////////////////////////////////////////// BOOL Ncb::GetGlobalClass (IMOD imod, Array * prgiinst) { USHORT j; USHORT index; IINST iinst; SZ_CONST szName; if (m_rgStat[imod] == NCB_STATMOD_LOAD_WRITE) { if (!FindWriteIndex (imod, &index)) return FALSE; // must search it linearly: for (j = 0; j < m_rgRWBuf[index].m_rgProp.size(); j++) { if (!(m_rgRWBuf[index].m_rgProp[j].m_en.m_atr & INST_NCB_ATR_DEFN)) continue; if (m_rgRWBuf[index].m_rgProp[j].m_en.m_typ == INST_TYP_CLASSNAM) { m_pnm->getName (m_rgRWBuf[index].m_rgProp[j].m_en.m_ni, &szName); if (IsGlobalName (szName)) { iinst = (imod << 16) | j; prgiinst->append(iinst); } } } } else // must load as read { if (!LoadModForRead (m_pdb, imod, &index)) return FALSE; // can search just the first block: for (j = 0; j < m_rgModHdr[imod].m_cClassProp; j++) { if (!(m_rgContBuf[index].m_rgProp[j].m_en.m_atr & INST_NCB_ATR_DEFN)) continue; m_pnm->getName (m_rgContBuf[index].m_rgProp[j].m_en.m_ni, &szName); if (IsGlobalName (szName)) { iinst = (imod << 16) | j; prgiinst->append (iinst); } } } return TRUE; }; ////////////////////////////////////////////////////////////////////// // IsGlobalName (SZ_CONST sz) ////////////////////////////////////////////////////////////////////// BOOL Ncb::IsGlobalName(SZ_CONST sz) { char * pch; pch = strstr (sz, "::"); if (pch == NULL || pch == sz) return TRUE; return FALSE; }; ////////////////////////////////////////////////////////////////////// // GetGlobalOther() ////////////////////////////////////////////////////////////////////// BOOL Ncb::GetGlobalOther(HTARGET hTarget, MBF mbf, Array * prgiinst) { USHORT i; for (i = 0; i < m_rgModHdr.size(); i++) { if (hTarget != (HTARGET)-1 && !isModInTarget (hTarget, i)) continue; if (!GetGlobalOther (i, mbf, prgiinst)) return FALSE; } return TRUE; }; ////////////////////////////////////////////////////// BOOL Ncb::GetGlobalOther(IMOD imod, MBF mbf, Array * prgiinst) { USHORT j; USHORT index; IINST iinst; SZ_CONST szName; if (m_rgStat[imod] == NCB_STATMOD_LOAD_WRITE) { if (!FindWriteIndex (imod, &index)) return FALSE; // must search it linearly: for (j = 0; j < m_rgRWBuf[index].m_rgProp.size(); j++) { if ((!(m_rgRWBuf[index].m_rgProp[j].m_en.m_atr & INST_NCB_ATR_DEFN)) || (m_rgRWBuf[index].m_rgProp[j].m_en.m_atr & INST_ATR_STATIC)) continue; if (TypFilter(m_rgRWBuf[index].m_rgProp[j].m_en.m_typ, mbf) && m_rgRWBuf[index].m_rgProp[j].m_en.m_typ != INST_TYP_CLASSNAM && m_rgRWBuf[index].m_rgProp[j].m_en.m_typ != INST_TYP_MEMVAR && m_rgRWBuf[index].m_rgProp[j].m_en.m_typ != INST_TYP_MEMFUNC) { m_pnm->getName (m_rgRWBuf[index].m_rgProp[j].m_en.m_ni, &szName); if (IsGlobalName (szName)) { iinst = (imod << 16) | j; prgiinst->append(iinst); } } } } else // must load as read { if (!LoadModForRead (m_pdb, imod, &index)) return FALSE; // can search just the first block: for (j = m_rgModHdr[imod].m_cClassProp; j < m_rgModHdr[imod].m_cProp; j++) { if ((!(m_rgContBuf[index].m_rgProp[j].m_en.m_atr & INST_NCB_ATR_DEFN)) || (m_rgContBuf[index].m_rgProp[j].m_en.m_atr & INST_ATR_STATIC)) continue; if (TypFilter (m_rgContBuf[index].m_rgProp[j].m_en.m_typ, mbf) && m_rgContBuf[index].m_rgProp[j].m_en.m_typ != INST_TYP_CLASSNAM && m_rgContBuf[index].m_rgProp[j].m_en.m_typ != INST_TYP_MEMVAR && m_rgContBuf[index].m_rgProp[j].m_en.m_typ != INST_TYP_MEMFUNC) { m_pnm->getName (m_rgContBuf[index].m_rgProp[j].m_en.m_ni, &szName); if (IsGlobalName (szName)) { iinst = (imod << 16) | j; prgiinst->append (iinst); } } } } return TRUE; }; ///////////////////////////////////////////////////////////////////////////// // REVIEW: Ignatius // combine these set of calls together with the one above. ///////////////////////////////////////////////////////////////////////////// BOOL Ncb::getAllGlobalsArray (MBF mbf, OUT IinstInfo ** ppiinstinfo, OUT ULONG * pciinst) { return getAllGlobalsArray ((HTARGET)-1, mbf, ppiinstinfo, pciinst); }; /////////////////////////////////////////////////// BOOL Ncb::getAllGlobalsArray (HTARGET hTarget, MBF mbf, OUT IinstInfo ** ppiinstinfo, OUT ULONG * pciinst) { Array rgiinst; *ppiinstinfo = NULL; *pciinst = 0; if (mbf & mbfClass) GetGlobalClass (hTarget, &rgiinst); GetGlobalOther (hTarget, mbf, &rgiinst); return DupArray (ppiinstinfo, pciinst, rgiinst); } //////////////////////////////////////////////////////// // Ncb::GetGlobalClass(); //////////////////////////////////////////////////////// BOOL Ncb::GetGlobalClass (HTARGET hTarget, Array * prgiinst) { USHORT i; for (i = 0; i < m_rgModHdr.size(); i++) { if (hTarget != (HTARGET)-1 && !isModInTarget (hTarget, i)) continue; if (!GetGlobalClass (i, prgiinst)) return FALSE; } return TRUE; }; /////////////////////////////////////////////////////// BOOL Ncb::GetGlobalClass (IMOD imod, Array * prgiinst) { USHORT j; USHORT index; IinstInfo iinstinfo; SZ_CONST szName; if (m_rgStat[imod] == NCB_STATMOD_LOAD_WRITE) { if (!FindWriteIndex (imod, &index)) return FALSE; // must search it linearly: for (j = 0; j < m_rgRWBuf[index].m_rgProp.size(); j++) { if (!(m_rgRWBuf[index].m_rgProp[j].m_en.m_atr & INST_NCB_ATR_DEFN)) continue; if (m_rgRWBuf[index].m_rgProp[j].m_en.m_typ == INST_TYP_CLASSNAM) { m_pnm->getName (m_rgRWBuf[index].m_rgProp[j].m_en.m_ni, &szName); if (IsGlobalName (szName)) { iinstinfo.m_iinst = (imod << 16) | j; iinstinfo.m_ni = m_rgRWBuf[index].m_rgProp[j].m_en.m_ni; iinstinfo.m_szName = szName; prgiinst->append(iinstinfo); } } } } else // must load as read { if (!LoadModForRead (m_pdb, imod, &index)) return FALSE; // can search just the first block: for (j = 0; j < m_rgModHdr[imod].m_cClassProp; j++) { if (!(m_rgContBuf[index].m_rgProp[j].m_en.m_atr & INST_NCB_ATR_DEFN)) continue; m_pnm->getName (m_rgContBuf[index].m_rgProp[j].m_en.m_ni, &szName); if (IsGlobalName (szName)) { iinstinfo.m_iinst = (imod << 16) | j; iinstinfo.m_ni = m_rgContBuf[index].m_rgProp[j].m_en.m_ni; iinstinfo.m_szName = szName; prgiinst->append(iinstinfo); } } } return TRUE; }; ////////////////////////////////////////////////////////////////////// // GetGlobalOther() ////////////////////////////////////////////////////////////////////// BOOL Ncb::GetGlobalOther(HTARGET hTarget, MBF mbf, Array * prgiinst) { USHORT i; for (i = 0; i < m_rgModHdr.size(); i++) { if (hTarget != (HTARGET)-1 && !isModInTarget (hTarget, i)) continue; if (!GetGlobalOther (i, mbf, prgiinst)) return FALSE; } return TRUE; }; ////////////////////////////////////////////////////// BOOL Ncb::GetGlobalOther(IMOD imod, MBF mbf, Array * prgiinst) { USHORT j; USHORT index; IinstInfo iinstinfo; SZ_CONST szName; if (m_rgStat[imod] == NCB_STATMOD_LOAD_WRITE) { if (!FindWriteIndex (imod, &index)) return FALSE; // must search it linearly: for (j = 0; j < m_rgRWBuf[index].m_rgProp.size(); j++) { if ((!(m_rgRWBuf[index].m_rgProp[j].m_en.m_atr & INST_NCB_ATR_DEFN)) || (m_rgRWBuf[index].m_rgProp[j].m_en.m_atr & INST_ATR_STATIC)) continue; if (TypFilter(m_rgRWBuf[index].m_rgProp[j].m_en.m_typ, mbf) && m_rgRWBuf[index].m_rgProp[j].m_en.m_typ != INST_TYP_CLASSNAM && m_rgRWBuf[index].m_rgProp[j].m_en.m_typ != INST_TYP_MEMVAR && m_rgRWBuf[index].m_rgProp[j].m_en.m_typ != INST_TYP_MEMFUNC) { m_pnm->getName (m_rgRWBuf[index].m_rgProp[j].m_en.m_ni, &szName); if (IsGlobalName (szName)) { iinstinfo.m_iinst = (imod << 16) | j; iinstinfo.m_ni = m_rgRWBuf[index].m_rgProp[j].m_en.m_ni; iinstinfo.m_szName = szName; prgiinst->append(iinstinfo); } } } } else // must load as read { if (!LoadModForRead (m_pdb, imod, &index)) return FALSE; // can search just the first block: for (j = m_rgModHdr[imod].m_cClassProp; j < m_rgModHdr[imod].m_cProp; j++) { if ((!(m_rgContBuf[index].m_rgProp[j].m_en.m_atr & INST_NCB_ATR_DEFN)) || (m_rgContBuf[index].m_rgProp[j].m_en.m_atr & INST_ATR_STATIC)) continue; if (TypFilter (m_rgContBuf[index].m_rgProp[j].m_en.m_typ, mbf) && m_rgContBuf[index].m_rgProp[j].m_en.m_typ != INST_TYP_CLASSNAM && m_rgContBuf[index].m_rgProp[j].m_en.m_typ != INST_TYP_MEMVAR && m_rgContBuf[index].m_rgProp[j].m_en.m_typ != INST_TYP_MEMFUNC) { m_pnm->getName (m_rgContBuf[index].m_rgProp[j].m_en.m_ni, &szName); if (IsGlobalName (szName)) { iinstinfo.m_iinst = (imod << 16) | j; iinstinfo.m_ni = m_rgContBuf[index].m_rgProp[j].m_en.m_ni; iinstinfo.m_szName = szName; prgiinst->append(iinstinfo); } } } } return TRUE; }; ////////////////////////////////////////////////////// // fCaseSeinsitive() /////////////////////////////////////////////////////// BOOL Ncb::fCaseSensitive() { return FALSE; }; ////////////////////////////////////////////////////// // setCaseSeinsitivity() ////////////////////////////////////////////////////// BOOL Ncb::setCaseSensitivity(BOOL) { return FALSE; }; //////////////////////////////////////////////////////// // register notification function: /////////////////////////////////////////////////////// BOOL Ncb::regNotify (pfnNotifyChange pNotify) { return regNotify ((HTARGET)-1, pNotify); }; //////////////////////////////////////////////////////// BOOL Ncb::regNotify (HTARGET hTarget, pfnNotifyChange pNotify) { USHORT index; BOOL bRet = TRUE; NiQ niq; DWORD dw = ::WaitForSingleObject (m_hMutex, INFINITE); index = m_rgNotify.size(); if (!m_rgNotify.setSize(index+1)) bRet = FALSE; else { m_rgNotify[index].m_pfnNotify = pNotify; m_rgNotify[index].m_hTarget = hTarget; if (m_bGraphBuilt) { niq.m_op = refreshAllOp; niq.m_iinstOld = 0; niq.m_iInfoNew.m_iinst = 0; m_rgNotify[index].m_rgQ.append (niq); } } ::ReleaseMutex (m_hMutex); return bRet; }; // stub: should not call this directly // must call regNotify from NcWrap BOOL Ncb::regNotify () { return FALSE; } // stub: should not call this directly // must call getQ from NcWrap BOOL Ncb::getQ (OUT NiQ ** ppQ, OUT ULONG * pcQ) { return FALSE; } BOOL Ncb::regNotify (HTARGET hTarget, ULONG * pindex) { USHORT index,i; BOOL bRet = TRUE; NiQ niq; BOOL bFound = FALSE; DWORD dw = ::WaitForSingleObject (m_hMutex, INFINITE); index = m_rgNotifyQ.size(); for (i = 0; i < index; i++) { if (m_rgNotifyQ[i].m_bDel) { *pindex = (ULONG)i; bFound = TRUE; break; } } if (!bFound) { if (!m_rgNotifyQ.setSize (index + 1)) bRet = FALSE; else *pindex = (ULONG) index; } if (bRet) { m_rgNotifyQ[*pindex].m_hTarget = hTarget; m_rgNotifyQ[*pindex].m_bDel = FALSE; if (m_bGraphBuilt) { niq.m_op = refreshAllOp; niq.m_iinstOld = 0; niq.m_iInfoNew.m_iinst = 0; m_rgNotifyQ[*pindex].m_rgQ.append (niq); } } ::ReleaseMutex (m_hMutex); return bRet; } BOOL Ncb::getQ (ULONG index, HTARGET hTarget, NiQ ** ppQ, ULONG * pcQ) { USHORT cArr = m_rgNotifyQ.size(); BOOL bRet = FALSE; if ((ULONG)cArr < index) return FALSE; if (hTarget != m_rgNotifyQ[index].m_hTarget) return FALSE; bRet = DupArray (ppQ, pcQ, m_rgNotifyQ[index].m_rgQ); if (bRet) m_rgNotifyQ[index].m_rgQ.setSize(0); return bRet; } ///////////////////////////////////////////////////// // unregister notification function // REVIEW : needs to compare hTarget as well! ///////////////////////////////////////////////////// BOOL Ncb::unregNotify (pfnNotifyChange pNotify) { USHORT index,i; BOOL bRet = FALSE; DWORD dw = ::WaitForSingleObject (m_hMutex, INFINITE); index = m_rgNotify.size(); for (i = 0; i < index ;i++) { if (m_rgNotify[i].m_pfnNotify == pNotify) { m_rgNotify.deleteAt (i); bRet = TRUE; break; } } ::ReleaseMutex (m_hMutex); return bRet; }; /////////////////////////////////////////////////////////// BOOL Ncb::unregNotify (ULONG index, HTARGET hTarget) { USHORT cArr; BOOL bRet = FALSE; DWORD dw = ::WaitForSingleObject (m_hMutex, INFINITE); cArr = m_rgNotifyQ.size(); if (cArr < index) { if (hTarget == m_rgNotifyQ[index].m_hTarget) { m_rgNotifyQ[index].m_bDel = TRUE; m_rgNotifyQ[index].m_hTarget = NULL; m_rgNotifyQ[index].m_rgQ.setSize(0); bRet = TRUE; } } ::ReleaseMutex (m_hMutex); return bRet; }; ////////////////////////////////////////////////// // SuspendNotify() /////////////////////////////////////////////////// BOOL Ncb::suspendNotify () { m_bNotifyNow = FALSE; return TRUE; }; ////////////////////////////////////////////////// // RestoreNotify() ////////////////////////////////////////////////// BOOL Ncb::resumeNotify() { m_bNotifyNow = TRUE; // REVIEW: // Notify(); return TRUE; }; ////////////////////////////////////////////////// // IsInQ(Array &rgiinst, IINST iinst, USHORT * pindex) ////////////////////////////////////////////////// BOOL Ncb::IsInQ (Array &rgiinst, IINST iinst, USHORT * pindex) { USHORT i; for (i = 0; i < rgiinst.size(); i++) { if (rgiinst[i].m_iInfoNew.m_iinst == iinst) { *pindex = i; return TRUE; } } return FALSE; }; ///////////////////////////////////////////////////////// // Check if iinst has a member or not ///////////////////////////////////////////////////////// BOOL Ncb::fHasMembers (IINST iinst, MBF mbf) { _ASSERT (FALSE); return FALSE; } ///////////////////////////////////////////////////////// BOOL Ncb::fHasMembers (HTARGET hTarget, IINST iinst, MBF mbf) { if (iinst == IINST_GLOBALS) return fHasGlobals(hTarget, mbf); else { USHORT iModHdr = IModFrIinst (iinst); USHORT iProp = IPropFrIinst (iinst); USHORT index; USHORT i, iStart; TYP typ; ATR atr; _ASSERT (iModHdr < m_rgModHdr.size()); if (m_rgModHdr[iModHdr].m_cProp <= iProp) return FALSE; if (m_rgStat[iModHdr] != NCB_STATMOD_LOAD_WRITE) { if (!LoadModForRead (m_pdb, iModHdr, &index)) return FALSE; if (m_rgContBuf[index].m_rgProp[iProp].m_en.m_typ != INST_TYP_CLASSNAM) return FALSE; iStart = (iProp == 0) ? 0 : (m_rgContBuf[index].m_rgProp[iProp-1].m_iUse); for (i = iStart; i < m_rgContBuf[index].m_rgProp[iProp].m_iUse; i++) { if (m_rgContBuf[index].m_rgUse[i].m_kind == NCB_KIND_CONTAINMENT) { typ = m_rgContBuf[index].m_rgProp[m_rgContBuf[index].m_rgUse[i].m_iProp].m_en.m_typ; atr = m_rgContBuf[index].m_rgProp[m_rgContBuf[index].m_rgUse[i].m_iProp].m_en.m_atr; if (TypFilter(typ, mbf)) { if ((typ == INST_TYP_CLASSNAM) && (atr & INST_NCB_ATR_DECL)) continue; return TRUE; } } } } else { if (!FindWriteIndex (iModHdr, &index)) return FALSE; _ASSERT (m_rgRWBuf[index].m_iModHdr == iModHdr); if (m_rgRWBuf[index].m_rgProp.size() <= iProp) return FALSE; if (m_rgRWBuf[index].m_rgProp[iProp].m_en.m_typ != INST_TYP_CLASSNAM) return FALSE; for (i = 0; i < m_rgRWBuf[index].m_rgProp[iProp].m_rgUse.size(); i++) { if (m_rgRWBuf[index].m_rgProp[iProp].m_rgUse[i].m_kind == NCB_KIND_CONTAINMENT) { typ = m_rgRWBuf[index].m_rgProp[m_rgRWBuf[index].m_rgProp[iProp].m_rgUse[i].m_iProp].m_en.m_typ; atr = m_rgRWBuf[index].m_rgProp[m_rgRWBuf[index].m_rgProp[iProp].m_rgUse[i].m_iProp].m_en.m_atr; if (TypFilter(typ, mbf)) { if ((typ == INST_TYP_CLASSNAM) && (atr & INST_NCB_ATR_DECL)) continue; return TRUE; } } } } } return FALSE; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // BOOL Ncb::fHasGlobals(HTARGET, MBF) ////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL Ncb::fHasGlobals (HTARGET hTarget, MBF mbf) { USHORT iModHdr; USHORT index; USHORT i; for (iModHdr = 0; iModHdr < m_rgStat.size(); iModHdr++) { if (!isModInTarget (hTarget, iModHdr)) continue; if (m_rgStat[iModHdr] != NCB_STATMOD_LOAD_WRITE) { if (!LoadModForRead (m_pdb, iModHdr, &index)) return FALSE; if ((mbf & mbfClass) && (m_rgModHdr[iModHdr].m_cClassProp > 0)) return TRUE; for (i = m_rgModHdr[iModHdr].m_cClassProp; i < m_rgModHdr[iModHdr].m_cProp; i++) { if ((!(m_rgContBuf[index].m_rgProp[i].m_en.m_atr & INST_NCB_ATR_DEFN)) || (m_rgContBuf[index].m_rgProp[i].m_en.m_atr & INST_ATR_STATIC)) continue; if (TypFilter(m_rgContBuf[index].m_rgProp[i].m_en.m_typ, mbf) && m_rgContBuf[index].m_rgProp[i].m_en.m_typ != INST_TYP_CLASSNAM && m_rgContBuf[index].m_rgProp[i].m_en.m_typ != INST_TYP_MEMVAR && m_rgContBuf[index].m_rgProp[i].m_en.m_typ != INST_TYP_MEMFUNC) return TRUE; } } else { if (!FindWriteIndex (iModHdr, &index)) return FALSE; // must search it linearly: for (i = 0; i < m_rgRWBuf[index].m_rgProp.size(); i++) { if ((!(m_rgRWBuf[index].m_rgProp[i].m_en.m_atr & INST_NCB_ATR_DEFN)) || (m_rgRWBuf[index].m_rgProp[i].m_en.m_atr & INST_ATR_STATIC)) continue; if (TypFilter(m_rgRWBuf[index].m_rgProp[i].m_en.m_typ, mbf) && m_rgRWBuf[index].m_rgProp[i].m_en.m_typ != INST_TYP_CLASSNAM && m_rgRWBuf[index].m_rgProp[i].m_en.m_typ != INST_TYP_MEMVAR && m_rgRWBuf[index].m_rgProp[i].m_en.m_typ != INST_TYP_MEMFUNC) return TRUE; } } } return FALSE; }; ////////////////////////////////////////////////////////////////////// // niFrIinst ////////////////////////////////////////////////////////////////////// BOOL Ncb::niFrIinst (IINST iinst, NI *pni) { NCB_ENTITY en; if (EnFrIinst (iinst, &en)) { *pni = en.m_ni; return TRUE; } return FALSE; }