153 lines
3.6 KiB
C++
153 lines
3.6 KiB
C++
// stab.cpp - symbol table for created UDT syms
|
|
#include "shinc.hpp"
|
|
|
|
struct STAB {
|
|
public:
|
|
BOOL fFindSym(LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase, UDTPTR* ppsym, unsigned *piHash);
|
|
BOOL fAddSym(LPSSTR lpsstr, unsigned iHash, UDTPTR* ppsym);
|
|
STAB();
|
|
~STAB();
|
|
|
|
private:
|
|
unsigned itMac;
|
|
unsigned itEntries;
|
|
UDTPTR* rgpsym;
|
|
BOOL fCreateNewUDTSym(LPSSTR lpsstr, unsigned iHash, UDTPTR* ppsym);
|
|
BOOL resize();
|
|
|
|
unsigned hash(LPB lpName)
|
|
{
|
|
return hashPbCb(lpName + 1, *lpName, itMac);
|
|
}
|
|
unsigned hash(LPSSTR lpsstr)
|
|
{
|
|
return hashPbCb(lpsstr->lpName, lpsstr->cb, itMac);
|
|
}
|
|
};
|
|
|
|
BOOL STABOpen(STAB **ppstab)
|
|
{
|
|
*ppstab = new STAB;
|
|
return *ppstab != 0;
|
|
}
|
|
|
|
BOOL STABFindUDTSym(STAB* pstab, LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase, UDTPTR *ppsym, unsigned *piHash)
|
|
{
|
|
*piHash = 0;
|
|
assert(pstab);
|
|
return pstab->fFindSym(lpsstr, pfnCmp, fCase, (UDTPTR *)ppsym, piHash);
|
|
}
|
|
|
|
BOOL STABAddUDTSym(STAB* pstab, LPSSTR lpsstr, unsigned iHash, UDTPTR* ppsym)
|
|
{
|
|
assert(pstab);
|
|
return pstab->fAddSym(lpsstr, iHash, (UDTPTR *)ppsym);
|
|
}
|
|
|
|
void STABClose(STAB* pstab)
|
|
{
|
|
delete pstab;
|
|
}
|
|
|
|
STAB::STAB()
|
|
{
|
|
itEntries = 0;
|
|
itMac = 1024;
|
|
rgpsym = (UDTPTR *) MHAlloc(itMac * sizeof(UDTPTR));
|
|
memset(rgpsym, 0, itMac * sizeof(UDTPTR));
|
|
}
|
|
|
|
STAB::~STAB()
|
|
{
|
|
for (unsigned i = 0; i < itMac; i++)
|
|
if (rgpsym[i])
|
|
MHFree(rgpsym[i]);
|
|
|
|
MHFree(rgpsym);
|
|
itEntries = 0;
|
|
itMac = 1024;
|
|
rgpsym = 0;
|
|
|
|
}
|
|
|
|
BOOL STAB::fFindSym(LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase, UDTPTR* ppsym, unsigned* piHash)
|
|
{
|
|
*ppsym = 0;
|
|
|
|
// nothing but S_UDTs here - if were looking for a specific type of sym
|
|
// and its not a S_UDT - don't bother
|
|
if ((lpsstr->searchmask & SSTR_symboltype ) &&
|
|
( lpsstr->symtype != S_UDT ))
|
|
return FALSE;
|
|
|
|
for (*piHash = hash(lpsstr);
|
|
rgpsym[*piHash];
|
|
*piHash = (*piHash < itMac) ? *piHash + 1: 0) {
|
|
// thats right pfnCmp returns 0 if compare succeeds
|
|
if (!(*pfnCmp) ( lpsstr, (SYMPTR)rgpsym[*piHash], (char *)(rgpsym[*piHash]->name), fCase )) {
|
|
// got it - return the sym
|
|
*ppsym = rgpsym[*piHash];
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL STAB::fAddSym(LPSSTR lpsstr, unsigned iHash, UDTPTR* ppsym)
|
|
{
|
|
if (!fCreateNewUDTSym(lpsstr, iHash, ppsym))
|
|
return FALSE;
|
|
|
|
if ((itEntries >> 1) > itMac) {
|
|
// over half full - double itMac and rehash the table
|
|
if (!resize())
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL STAB::fCreateNewUDTSym(LPSSTR lpsstr, unsigned iHash, UDTPTR* ppsym)
|
|
{
|
|
*ppsym = rgpsym[iHash] = (UDTPTR) MHAlloc(sizeof(UDTSYM) + lpsstr->cb);
|
|
|
|
if (*ppsym) {
|
|
(*ppsym)->reclen = sizeof(UDTSYM) + lpsstr->cb;
|
|
(*ppsym)->rectyp = S_UDT;
|
|
(*ppsym)->typind = 0;
|
|
(*ppsym)->name[0] = lpsstr->cb;
|
|
memcpy((*ppsym)->name + 1, lpsstr->lpName, lpsstr->cb);
|
|
itEntries++;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL STAB::resize()
|
|
{
|
|
unsigned itMac_ = itMac;
|
|
itMac *= 2; // double size of hash table
|
|
UDTPTR *rgpsym_ = rgpsym;
|
|
rgpsym = (UDTPTR *) MHAlloc(itMac * sizeof(UDTPTR));
|
|
if (!rgpsym) {
|
|
rgpsym = rgpsym_;
|
|
return FALSE;
|
|
}
|
|
|
|
memset(rgpsym, 0, itMac * sizeof(UDTPTR));
|
|
|
|
for (unsigned i_ = 0; i_ < itMac_; i_++) {
|
|
if (rgpsym_[i_]) {
|
|
for (unsigned i = hash((LPB)(rgpsym_[i_]->name));
|
|
rgpsym[i];
|
|
i = (i < itMac) ? i + 1: 0);
|
|
rgpsym[i] = rgpsym_[i_];
|
|
}
|
|
}
|
|
|
|
MHFree(rgpsym_);
|
|
return TRUE;
|
|
}
|