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.
316 lines
6.3 KiB
316 lines
6.3 KiB
//
|
|
// Copyright (c) 1996 Microsoft Corporation
|
|
//
|
|
//
|
|
// SYM.C -- Implemtation for Classes:
|
|
// CInfSymbolTable
|
|
// CInfSymbol
|
|
//
|
|
// History:
|
|
// 05/21/96 JosephJ Created
|
|
//
|
|
//
|
|
#include "common.h"
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// CLASS CInfSymbol
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
CInfSymbol::CInfSymbol
|
|
(
|
|
const TCHAR rgchName[],
|
|
UINT cchName,
|
|
DWORD dwChecksum,
|
|
const CInfSymbol * pNext
|
|
)
|
|
: m_rgchText(rgchName),
|
|
m_cchText(cchName),
|
|
m_dwChecksum(dwChecksum),
|
|
m_pNext(pNext),
|
|
m_pPropList(NULL)
|
|
{
|
|
}
|
|
|
|
|
|
CInfSymbol::~CInfSymbol()
|
|
{
|
|
// BUGBUG -- delete all the InfSymbols allocated!
|
|
}
|
|
|
|
|
|
// Return the text associated with this symbol as a null-terminated
|
|
// string
|
|
const TCHAR * CInfSymbol::GetText(void) const
|
|
{
|
|
return (this) ? m_rgchText : TEXT("");
|
|
}
|
|
|
|
|
|
// Return the length of the text associated with this symbol
|
|
UINT CInfSymbol::GetTextLength() const
|
|
{
|
|
return (this) ? m_cchText : 0;
|
|
}
|
|
|
|
|
|
// Release (decrement ref-count) of this symbol
|
|
void CInfSymbol::Release(void) const
|
|
{
|
|
}
|
|
|
|
|
|
// Dump state
|
|
void CInfSymbol::Dump(void) const
|
|
{
|
|
printf("Symbol(0x%08lx) = [%s]\n", this, (this) ? m_rgchText : TEXT(""));
|
|
}
|
|
|
|
|
|
// --------------- SetProp ------------------
|
|
// Not really const -- it modifies the property list
|
|
BOOL
|
|
CInfSymbol::SetProp(const CInfSymbol *pSymPropName, void *pvProp)
|
|
const
|
|
// TODO
|
|
{
|
|
#if 0
|
|
CInfSymProp * pPropRec = (CInfSymProp *) m_pPropList;
|
|
DWORD dwSig = pSymPropName->Checksum();
|
|
BOOL fRet=FALSE;
|
|
|
|
// Search for property
|
|
while(pPropRec)
|
|
{
|
|
const CInfSymbol *pSym = pPropRec->pSymPropName;
|
|
if (dwChecksum == pSym->Checksum())
|
|
{
|
|
if (!lstrcmp(pSymPropName->GetText(), pSym->GetText()))
|
|
{
|
|
// currently we don't allow you to set an already set prop.
|
|
ASSERT(FALSE);
|
|
goto end;
|
|
}
|
|
}
|
|
pPropRec = pPropRec->m_pNext;
|
|
}
|
|
|
|
// Insert property
|
|
pPropRec = new CInfSymProp
|
|
(
|
|
pSymPropName,
|
|
pvProp,
|
|
(CInfSymProp *) m_pPropList
|
|
);
|
|
m_pPropList = (void *) pPropRec;
|
|
|
|
end:
|
|
return fRet;
|
|
#endif // 0
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// --------------- GetProp ------------------
|
|
// TODO
|
|
BOOL
|
|
CInfSymbol::GetProp(const CInfSymbol *pSymPropName, void **ppvProp)
|
|
const
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// --------------- DelProp ------------------
|
|
// Not really const -- it modifies the property list
|
|
// TODO
|
|
BOOL
|
|
CInfSymbol::DelProp(const CInfSymbol *pSymPropName)
|
|
const
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// --------------- GetOrCreatePropLoc --------------
|
|
// Not really const -- it could modify the property list
|
|
// TODO
|
|
BOOL
|
|
CInfSymbol::GetOrCreatePropLoc(
|
|
const CInfSymbol *pSymPropName,
|
|
void ***ppvProp,
|
|
BOOL *pfExists
|
|
)
|
|
const
|
|
{
|
|
static void *pv;
|
|
*pfExists=FALSE;
|
|
*ppvProp = &pv;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// CLASS CInfSymbolTable
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
CInfSymbolTable::CInfSymbolTable(void)
|
|
{
|
|
FillMemory((void*)m_rgpSym, sizeof(m_rgpSym), 0);
|
|
m_cSymbols=0;
|
|
m_pchFree = m_rgchTextStore;
|
|
m_pchLastFree = m_pchFree +
|
|
sizeof(m_rgchTextStore)/sizeof(*m_rgchTextStore)-1;
|
|
}
|
|
|
|
|
|
CInfSymbolTable::~CInfSymbolTable()
|
|
{
|
|
mfn_EnterCrit();
|
|
|
|
// Free resources
|
|
}
|
|
|
|
|
|
// Look up and return the symbol with the specified text.
|
|
// If symbol is not prestent, return NULL if (!fInsert), else
|
|
// insert new symbol and return it.
|
|
// This symbol MUST be released by calling its Release function
|
|
// when it is no longer needed.
|
|
// NULL is returned for the empty string ("")
|
|
const CInfSymbol * CInfSymbolTable::Lookup(const TCHAR rgchName[], BOOL fInsert)
|
|
{
|
|
const TCHAR *pch = rgchName;
|
|
const CInfSymbol *pSym = NULL;
|
|
const UINT cchName = lstrlen(rgchName);
|
|
const DWORD dwChecksum = ::Checksum
|
|
(
|
|
(BYTE *) rgchName,
|
|
cchName*sizeof(TCHAR)
|
|
);
|
|
const UINT u = dwChecksum % SYMTABSIZE; // we use checksum to compute hash.
|
|
|
|
if (!cchName) { goto end; }
|
|
|
|
mfn_EnterCrit();
|
|
|
|
// Look for it
|
|
for (pSym = m_rgpSym[u]; pSym; pSym = pSym->Next())
|
|
{
|
|
// may as well use the checksum as a quick check...
|
|
if (dwChecksum==pSym->Checksum())
|
|
{
|
|
if (!lstrcmp(rgchName, pSym->GetText())) goto end;
|
|
|
|
printf
|
|
(
|
|
"WARNING: CS(%s) == CS(%s) = 0x%08lx\n",
|
|
rgchName,
|
|
pSym->GetText(),
|
|
dwChecksum
|
|
);
|
|
}
|
|
}
|
|
|
|
// Didn't find it -- insert if necessary
|
|
ASSERT(pSym==NULL);
|
|
if (fInsert)
|
|
{
|
|
if ( (m_pchFree+cchName) < m_pchLastFree)
|
|
{
|
|
CopyMemory (
|
|
(void *) m_pchFree,
|
|
(const void *) rgchName,
|
|
(cchName+1)*sizeof(*rgchName) // incl. null term.
|
|
);
|
|
pSym = new CInfSymbol(m_pchFree, cchName, dwChecksum, m_rgpSym[u]);
|
|
if (pSym)
|
|
{
|
|
printf("Inserting. %s @ 0x%08lx..\n", m_pchFree, (DWORD) pSym);
|
|
m_pchFree += (cchName+1);
|
|
ASSERT(m_pchFree<=m_pchLastFree);
|
|
m_rgpSym[u] = pSym;
|
|
}
|
|
}
|
|
}
|
|
|
|
mfn_LeaveCrit();
|
|
|
|
end:
|
|
return pSym;
|
|
}
|
|
|
|
|
|
// Dump state
|
|
void CInfSymbolTable::Dump(void) const
|
|
{
|
|
mfn_EnterCrit();
|
|
|
|
printf("[BEGIN SYMBOL TABLE DUMP]\n");
|
|
for (UINT u=0; u<SYMTABSIZE; u++)
|
|
{
|
|
const CInfSymbol *pSym = m_rgpSym[u];
|
|
|
|
if (pSym)
|
|
{
|
|
printf("---- Location 0x%08lx -----\n", u);
|
|
for (; pSym ; pSym = pSym->Next())
|
|
{
|
|
pSym->Dump();
|
|
}
|
|
}
|
|
}
|
|
printf("[End symbol table dump]\n");
|
|
|
|
mfn_LeaveCrit();
|
|
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// CLASS CInfSymbolList
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// --------------------------- Find -----------------------------
|
|
// Looks for the specified symbol, returns the list element with that symbol.
|
|
// If ppListPrev is non-NULL, sets it to the previous list element
|
|
// (if no previous element, sets it to NULL). If the symbol is not found,
|
|
// *ppListPrev is not touched.
|
|
//
|
|
const CInfSymbolList *
|
|
CInfSymbolList::Find
|
|
(
|
|
const CInfSymbolList *pList,
|
|
const CInfSymbol *pSym,
|
|
const CInfSymbolList **ppListPrev
|
|
)
|
|
{
|
|
DWORD dwChecksum = pSym->Checksum();
|
|
const CInfSymbolList *pListPrev=NULL;
|
|
|
|
while(pList)
|
|
{
|
|
const CInfSymbol *pSym1 = pList->m_pSym;
|
|
if (dwChecksum == pSym1->Checksum())
|
|
{
|
|
if (!lstrcmp(pSym->GetText(), pSym1->GetText()))
|
|
{
|
|
// Found it ...
|
|
if (ppListPrev)
|
|
{
|
|
// Note, if we find the 1st element, *ppListPrev is set
|
|
// to NULL.
|
|
*ppListPrev = pListPrev;
|
|
}
|
|
goto end;
|
|
}
|
|
}
|
|
pListPrev = pList;
|
|
pList = pList->Next();
|
|
}
|
|
|
|
end:
|
|
|
|
return pList;
|
|
}
|