/*********************************************************************
Copyright (C) 2001 by
Alexander Berthold, alexander-berthold@web.de.
Hoegestr. 54
79108 Freiburg i. Breisgau
Germany
-- This file is part of cxAnalyzer --
"cxAnalyzer" is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or any later version.
"cxAnalyzer" is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with "cxAnalyzer"; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
---------------------------------------------------------------
If you find any bugs or if you make other corrections/
enhancements, i'd appreciate if you'd let me know about
that. My email is
alexander-berthold@web.de
If you share this code, do not remove this text.
---------------------------------------------------------------
*********************************************************************/
// cxAnalyzerTypeMap.cpp: implementation of the cxAnalyzerTypeMap class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <map>
#include <string>
#include "cxAnalyzerTypeMap.h"
#include "cxAnalyzerException.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cxAnalyzerTypeMap::cxAnalyzerTypeMap()
{
m_nNextID =1;
// Register the default rules
// NULL rule (literal)
m_mapStr.insert(strmap_type::value_type(_T("#literal#"),ATM_ID_LITERAL));
m_mapDW.insert(dwmap_type::value_type(0,ATM_ID_LITERAL));
// nil (beginning/end of statement) - unsupported yet
m_mapStr.insert(strmap_type::value_type(_T("#nil#"),ATM_ID_NIL));
patiSetTypeInfo(ATM_ID_LITERAL,ATM_MTYPE_COMP_TOKEN,0);
// patiSetTypeInfo(ATM_ID_MATCHALL,ATM_MTYPE_COMP_TOKEN,0);
patiSetTypeInfo(ATM_ID_NIL,ATM_MTYPE_COMP_TOKEN,0);
}
cxAnalyzerTypeMap::~cxAnalyzerTypeMap()
{
atmmap_type::const_iterator it;
for(it=m_mapAtmInfo.begin();it!=m_mapAtmInfo.end();it++)
{
cxAnalyzerTypeInfo *patiCur = (*it).second;
delete patiCur;
}
m_mapAtmInfo.clear();
}
//////////////////////////////////////////////////////////////////////
// Protected operations
//////////////////////////////////////////////////////////////////////
void cxAnalyzerTypeMap::vInitFromTokenizerMapData(
const cxTokenizerMapData* ptmdRules)
{
cxTokenizerMapData::const_iterator it;
for(it=ptmdRules->begin();it!=ptmdRules->end();it++)
{
const cxTokenizerMapData* ptmdSub;
const cxTokenizerTokenRule* pttrRule;
ptmdSub =(*it).second;
vInitFromTokenizerMapData(ptmdSub);
pttrRule =ptmdSub->pttrGetRuleConst();
if(pttrRule && (pttrRule->nGetIDValue()!=0))
{
int nMType;
std::tstring strRule = pttrRule->strGetTokenString();
if(pttrRule->fIsFlagSet(ttrf_character_rule))
nMType=ATM_MTYPE_TOKEN,strRule.insert(0,_T("$"));
else
nMType=ATM_MTYPE_COMP_TOKEN,strRule.insert(0,_T("!"));
int nID = nGetAtmTypeFor(strRule);
vSetCustIDToAtmMapping(pttrRule->nGetIDValue(),nID);
m_mapDW.insert(
dwmap_type::value_type(
DWORD(pttrRule),
nID
));
patiSetTypeInfo(nID,nMType,0);
}
}
}
//////////////////////////////////////////////////////////////////////
// Operations
//////////////////////////////////////////////////////////////////////
void cxAnalyzerTypeMap::vInitFromTokenizerMap(const cxTokenizerMap *pmInit)
{
try
{
vInitFromTokenizerMapData(pmInit->ptmdGetFPRules());
vInitFromTokenizerMapData(pmInit->ptmdGetWIRules());
}
catch(cxAnalyzerException& e)
{
if(e.Error()==ANERR_DUPLICATE_CUSTID)
{
dwmap_type::const_iterator it;
for(it=m_mapDW.begin();it!=m_mapDW.end();it++)
{
const cxTokenizerTokenRule* pttr = (const cxTokenizerTokenRule*)it->first;
if(pttr==NULL)
continue;
if(pttr->nGetIDValue()==(int)e.GetData())
{
ASSERT(pttr!=NULL);
e.SetErrorString(pttr->strGetInitString().c_str());
}
}
}
throw e;
}
}
void cxAnalyzerTypeMap::vSetCustIDToAtmMapping(int nCustID, int nAtmID)
{
if(nGetAtmTypeFor(nCustID)!=ATM_ID_INVALID)
throw cxAnalyzerException(ANERR_DUPLICATE_CUSTID,NULL,(DWORD)nCustID);
m_mapCustIDtoAtmID.insert(atm_to_id_map_type::value_type(nCustID,nAtmID));
m_mapAtmIDtoCustID.insert(id_to_atm_map_type::value_type(nAtmID,nCustID));
}
int cxAnalyzerTypeMap::nGetAtmTypeFor(int nCustID) const
{
atm_to_id_map_type::const_iterator it;
it =m_mapCustIDtoAtmID.find(nCustID);
if(it==m_mapCustIDtoAtmID.end())
return ATM_ID_INVALID;
return (*it).second;
}
int cxAnalyzerTypeMap::nGetAtmTypeFor(LPCTSTR lpszString, bool fCreate)
{
std::tstring str;
str =lpszString;
return nGetAtmTypeFor(str,fCreate);
}
int cxAnalyzerTypeMap::nGetAtmTypeFor(const std::tstring& str, bool fCreate)
{
strmap_type::iterator it;
it =m_mapStr.find(str);
if(it==m_mapStr.end())
{
if(!fCreate)
return ATM_ID_INVALID;
it =m_mapStr.insert(strmap_type::value_type(str,m_nNextID)).first;
m_nNextID++;
}
return (*it).second;
}
int cxAnalyzerTypeMap::nGetAtmTypeFor(const cxTokenizerTokenRule* pttrRule) const
{
dwmap_type::const_iterator it;
it =m_mapDW.find( DWORD(pttrRule) );
if(it==m_mapDW.end())
return ATM_ID_INVALID;
return (*it).second;
}
int cxAnalyzerTypeMap::nGetCustIDFor(int nAtmType) const
{
id_to_atm_map_type::const_iterator it;
it =m_mapAtmIDtoCustID.find(nAtmType);
if(it==m_mapAtmIDtoCustID.end())
return 0;
return (*it).second;
}
int cxAnalyzerTypeMap::nNormalizeCustID(int nCustID) const
{
int nAtmType = nGetAtmTypeFor(nCustID);
if(nAtmType==ATM_ID_INVALID)
return 0;
return nGetCustIDFor(nAtmType);
}
cxAnalyzerTypeInfo* cxAnalyzerTypeMap::patiGetTypeInfo(int nID)
{
atmmap_type::iterator it;
it =m_mapAtmInfo.find(nID);
if(it==m_mapAtmInfo.end())
return NULL;
return (*it).second;
}
const cxAnalyzerTypeInfo* cxAnalyzerTypeMap::patiGetTypeInfo(int nID) const
{
atmmap_type::const_iterator it;
it =m_mapAtmInfo.find(nID);
if(it==m_mapAtmInfo.end())
return NULL;
return (*it).second;
}
cxAnalyzerTypeInfo* cxAnalyzerTypeMap::patiSetTypeInfo(int nID,
int nMType,
int nSubType)
{
atmmap_type::iterator it;
cxAnalyzerTypeInfo *patiData = NULL;
it =m_mapAtmInfo.find(nID);
if(it!=m_mapAtmInfo.end())
return NULL;
patiData =new cxAnalyzerTypeInfo(nID,nMType,nSubType);
m_mapAtmInfo.insert(atmmap_type::value_type(nID,patiData));
return patiData;
}
std::tstring cxAnalyzerTypeMap::strGetStringForID(int nID) const
{
strmap_type::const_iterator it;
for(it=m_mapStr.begin();it!=m_mapStr.end();it++)
{
if( (*it).second == nID)
return (*it).first;
}
return _T("");
}
DWORD cxAnalyzerTypeMap::dwGetDWORDForID(int nID) const
{
dwmap_type::const_iterator it;
for(it=m_mapDW.begin();it!=m_mapDW.end();it++)
{
if( (*it).second == nID)
return (*it).first;
}
return 0;
}
void cxAnalyzerTypeMap::vDump() const
{
TRACE(_T("\nDumping cxAnalyzerTypeMap(0x%08lx):\n"),((DWORD)this));
TRACE(_T("*************************************\n"));
strmap_type::const_iterator it;
for(it=m_mapStr.begin();it!=m_mapStr.end();it++)
{
DWORD dwVal = ((cxAnalyzerTypeMap*)this)->dwGetDWORDForID( (*it).second );
TRACE(_T("{%30s},{0x%08lx} -> %d\n"), (*it).first.data(), dwVal, (*it).second);
}
}
/*void cxAnalyzerTypeMap::enumerate(ctkEnumerator<LPCTSTR>& enumerator) const
{
TCHAR szTemp[256];
strmap_type::const_iterator it;
int i = 0;
enumerator.enumBegin();
for(it=m_mapStr.begin();it!=m_mapStr.end();it++)
{
_sntprintf(szTemp,255,_T("AtmID#:%5d, string='%s'"),
it->second, it->first.data() );
enumerator.enumElement(i, szTemp);
}
enumerator.enumEnd();
}
*/