You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3803 lines
84 KiB
C++

// XTPSyntaxEditLexClass.cpp : implementation file
//
// This file is a part of the XTREME TOOLKIT PRO MFC class library.
// (c)1998-2012 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME SYNTAX EDIT LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// support@codejock.com
// http://www.codejock.com
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
// common includes
#include "Common/XTPColorManager.h"
#include "Common/XTPSmartPtrInternalT.h"
#include "Common/XTPVC80Helpers.h"
// syntax editor includes
#include "XTPSyntaxEditDefines.h"
#include "XTPSyntaxEditStruct.h"
#include "XTPSyntaxEditLexPtrs.h"
#include "XTPSyntaxEditLexClassSubObjT.h"
#include "XTPSyntaxEditLexCfgFileReader.h"
#include "XTPSyntaxEditLexClassSubObjDef.h"
#include "XTPSyntaxEditLexClass.h"
#include "XTPSyntaxEditLexParser.h"
#include "XTPSyntaxEditTextIterator.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//#define TRACE_ASSERT ASSERT
#define TRACE_ASSERT(x)
//#define TRACE_MEMORY_LEX_AUTOMAT_MEM_MAN
////////////////////////////////////////////////////////////////////////////
const int c_nPrevClassDepth_default = 1;
using namespace XTPSyntaxEditLexAnalyser;
namespace XTPSyntaxEditLexAnalyser
{
CXTPSyntaxEditLexAutomatMemMan* XTPGetLexAutomatMemMan()
{
static CXTPSyntaxEditLexAutomatMemMan s_LexAutomatMemMan;
return &s_LexAutomatMemMan;
}
////////////////////////////////////////////////////////////////////////////
static const LPCTSTR cszSpecs = _T("~`!@#$%^&*()_-+=\\|{}[];:'\",.<>/?");
//---------------------------------------------------------------------------
const TCHAR* g_arKnownLexClassAttribs[] =
{
XTPLEX_ATTR_TXT_COLORFG,
XTPLEX_ATTR_TXT_COLORBK,
XTPLEX_ATTR_TXT_COLORSELFG,
XTPLEX_ATTR_TXT_COLORSELBK,
XTPLEX_ATTR_TXT_BOLD,
XTPLEX_ATTR_TXT_ITALIC,
XTPLEX_ATTR_TXT_UNDERLINE,
XTPLEX_ATTR_CASESENSITIVE,
XTPLEX_ATTR_COLLAPSABLE,
XTPLEX_ATTR_COLLAPSEDTEXT,
XTPLEX_ATTR_PARSEONSCREEN,
XTPLEX_ATTR_RESTARTRUNLOOP,
XTPLEX_ATTR_ENDCLASSPARENT,
XTPLEX_ATTR_RECURRENCEDEPTH,
XTPLEX_ATTR_DISPLAYNAME,
// Global attributes
XTPLEX_ATTRG_FIRSTPARSEINSEPARATETHREAD,
XTPLEX_ATTRG_EDITREPARCEINSEPARATETHREAD,
XTPLEX_ATTRG_CONFIGCHANGEDREPARCEINSEPARATETHREAD,
XTPLEX_ATTRG_EDITREPARCETIMEOUT_MS,
XTPLEX_ATTRG_MAXBACKPARSEOFFSET,
XTPLEX_ATTRG_ONSCREENSCHCACHELIFETIME_SEC,
XTPLEX_ATTRG_PARSERTHREADIDLELIFETIME_SEC,
};
extern int FindStr(const CStringArray& rarData, LPCTSTR pcszStr, BOOL bCase = FALSE);
extern int Find_noCase(CStringArray& rarData, LPCTSTR strData);
//===========================================================================
BOOL SplitStr(LPCTSTR pcszStr, TCHAR chSplitter, CStringArray& rArProps)
{
rArProps.RemoveAll();
CString str0(pcszStr);
CString strSplitter(chSplitter);
CString str;
do {
str = str0.SpanExcluding(strSplitter);
int nLen = str.GetLength();
int nLenMax = str0.GetLength();
if (nLen)
{
str0.Delete(0, min(nLen+1, nLenMax));
rArProps.Add(str);
}
}
while (!str.IsEmpty());
return TRUE;
}
//---------------------------------------------------------------------------
BOOL PropPathSplit(LPCTSTR pcszPropPath, CStringArray& rArProps)
{
return SplitStr(pcszPropPath, _T(':'), rArProps);
}
//---------------------------------------------------------------------------
CString MakeStr(const CStringArray& rArProps, LPCTSTR strSplitter)
{
CString strResult;
int nCount = (int)rArProps.GetSize();
for (int i = 0; i < nCount; i++)
{
if (i)
{
strResult += strSplitter;
}
CString strI = rArProps[i];
strResult += strI;
}
return strResult;
}
//---------------------------------------------------------------------------
CString PropPathFirstRemove(CString& rStrPropPath)
{
CString strProp;
strProp = rStrPropPath.SpanExcluding(_T(":"));
int nLen = strProp.GetLength();
int nLenMax = rStrPropPath.GetLength();
if (nLen)
{
rStrPropPath.Delete(0, min(nLen+1, nLenMax));
}
return strProp;
}
//---------------------------------------------------------------------------
int PropPathCount(LPCTSTR pcszPropPath)
{
CString strPP(pcszPropPath);
int nCount = 1;
int nLenMax = strPP.GetLength();
for (int nFIndex = 0; nFIndex >= 0 && nFIndex < nLenMax;)
{
nFIndex = strPP.Find(_T(':'), nFIndex);
if (nFIndex >= 0)
{
nFIndex++;
nCount++;
}
}
return nCount;
}
//---------------------------------------------------------------------------
void AddIfNeed(CXTPSyntaxEditLexVariantPtrArray* pArDest, CXTPSyntaxEditLexVariant* pLVar)
{
if (!pArDest || !pLVar)
{
ASSERT(FALSE);
return;
}
int nCount = (int)pArDest->GetSize();
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexVariant* pLV_i = pArDest->GetAt(i, FALSE);
ASSERT(pLV_i);
if (pLV_i && *pLV_i == *pLVar)
{
return;
}
}
//-----------
CXTPSyntaxEditLexVariantPtr ptrLV(pLVar, TRUE);
pArDest->Add(ptrLV);
}
//---------------------------------------------------------------------------
void ConcatenateLVArrays(CXTPSyntaxEditLexVariantPtrArray* pArDest,
CXTPSyntaxEditLexVariantPtrArray* pAr2, int nMaxCount = INT_MAX)
{
if (!pArDest || !pAr2)
{
ASSERT(FALSE);
return;
}
int nCount = min(nMaxCount, (int)pAr2->GetSize());
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexVariant* pLVar = pAr2->GetAt(i, FALSE);
AddIfNeed(pArDest, pLVar);
}
}
//---------------------------------------------------------------------------
int FindStr(CXTPSyntaxEditLexVariantPtrArray* pAr, LPCTSTR pcszStr, BOOL bCase = FALSE, int* pnStrIdx = NULL)
{
if (!pAr || !pcszStr)
{
ASSERT(FALSE);
return -1;
}
int nCount = (int)pAr->GetSize();
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexVariant* pLV_i = pAr->GetAt(i, FALSE);
ASSERT(pLV_i && pLV_i->IsStrType());
if (pLV_i && pLV_i->IsStrType())
{
int nIdx2 = FindStr(pLV_i->m_arStrVals, pcszStr, bCase);
if (nIdx2 >= 0)
{
if (pnStrIdx)
{
*pnStrIdx = nIdx2;
}
return i;
}
}
}
return -1;
}
AFX_INLINE int StrCmp_sort(const CString& rStr1, const CString& rStr2,
BOOL bAscending, BOOL bNoCase)
{
int nCmpRes = 0;
if (bNoCase)
{
nCmpRes = rStr1.CompareNoCase(rStr2);
}
else
{
nCmpRes = rStr1.Compare(rStr2);
}
if (!bAscending)
{
nCmpRes *= -1;
}
return nCmpRes;
}
void SortArray(CStringArray& rarData, BOOL bAscending, BOOL bNoCase)
{
CString strTmp;
int nCount = (int)rarData.GetSize();
for (int i = 0; i < nCount; i++)
{
for (int j = i + 1; j < nCount; j++)
{
int nCmpRes = StrCmp_sort(rarData[i], rarData[j], bAscending, bNoCase);
if (nCmpRes > 0)
{
strTmp = rarData[i];
rarData[i] = rarData[j];
rarData[j] = strTmp;
}
}
}
}
int _cdecl StrCmp_qsort_AnC(const void* p1, const void* p2)
{
return StrCmp_sort(*((CString*)p1), *((CString*)p2), TRUE, TRUE);
}
int _cdecl StrCmp_qsort_AC(const void* p1, const void* p2)
{
return StrCmp_sort(*((CString*)p1), *((CString*)p2), TRUE, FALSE);
}
int _cdecl StrCmp_qsort_DnC(const void* p1, const void* p2)
{
return StrCmp_sort(*((CString*)p1), *((CString*)p2), FALSE, TRUE);
}
int _cdecl StrCmp_qsort_DC(const void* p1, const void* p2)
{
return StrCmp_sort(*((CString*)p1), *((CString*)p2), FALSE, FALSE);
}
void QSortArray(CStringArray& rarData, BOOL bAscending, BOOL bNoCase)
{
int nCount = (int)rarData.GetSize();
if (nCount <= 0)
{
return;
}
//--------------------------------------------------------------------
typedef int (_cdecl* TPFNStrCmp)(const void* p1, const void* p2);
TPFNStrCmp pfnStrCmp = NULL;
if (bAscending && bNoCase)
{
pfnStrCmp = StrCmp_qsort_AnC;
}
else if (bAscending && !bNoCase)
{
pfnStrCmp = StrCmp_qsort_AC;
}
else if (!bAscending && bNoCase)
{
pfnStrCmp = StrCmp_qsort_DnC;
}
else if (!bAscending && !bNoCase)
{
pfnStrCmp = StrCmp_qsort_DC;
}
//--------------------------------------------------------------------
void* pArray = (void*)&rarData[0];
int nDataSize = sizeof(CString*);
qsort(pArray, nCount, nDataSize, pfnStrCmp);
}
BOOL SortTagsInLexVarArray(CXTPSyntaxEditLexVariantPtrArray& rarTags,
BOOL bAscending, BOOL bNoCase)
{
CXTPSyntaxEditLexVariantPtrArray arData;
CXTPSyntaxEditLexVariant lvStrs;
int nCount0 = (int)rarTags.GetSize();
for (int i = 0; i < nCount0; i++)
{
CXTPSyntaxEditLexVariant* pLV = rarTags.GetAt(i, FALSE);
ASSERT(pLV);
if (pLV)
{
if (!(pLV->m_nObjType == xtpEditLVT_valStr || pLV->m_nObjType == xtpEditLVT_valVar))
{
TRACE(_T("ERROR! Tag should be string or variable. \n"));
}
if (pLV->m_nObjType == xtpEditLVT_valStr)
{
lvStrs.m_nObjType = xtpEditLVT_valStr;
lvStrs.m_arStrVals.Append(pLV->m_arStrVals);
}
else
{
CXTPSyntaxEditLexVariant* pClone = pLV->Clone();
if (pClone)
{
arData.AddPtr(pClone, FALSE);
}
else
{
return FALSE;
}
}
}
}
//------------------------------------------------------------------------
if (lvStrs.m_nObjType == xtpEditLVT_valStr)
{
QSortArray(lvStrs.m_arStrVals, bAscending, bNoCase);
CXTPSyntaxEditLexVariantPtr ptrClone = lvStrs.Clone();
if (ptrClone)
{
arData.InsertAt(0, ptrClone);
}
else
{
return FALSE;
}
}
//====================================================================
rarTags.RemoveAll();
rarTags.Append(arData);
return TRUE;
}
}
////////////////////////////////////////////////////////////////////////////
//struct LA_CHAR_NODE
LA_CHAR_NODE::LA_CHAR_NODE()
{
wChar = 0;
wFlags = 0;
pNextMap = NULL;
pNextNode = NULL;
}
LA_CHAR_NODE::~LA_CHAR_NODE()
{
// if (pNextMap
// pNextMap->InternalRelease();
// }
}
void LA_CHAR_NODE::Clear()
{
wChar = 0;
wFlags = 0;
pNextNode = NULL;
if (pNextMap)
{
pNextMap->InternalRelease();
pNextMap = NULL;
}
}
const LA_CHAR_NODE& LA_CHAR_NODE::operator=(const LA_CHAR_NODE& rSrc)
{
if (rSrc.pNextMap)
{
rSrc.pNextMap->InternalAddRef();
}
if (pNextMap)
{
pNextMap->InternalRelease();
}
wChar = rSrc.wChar;
wFlags = rSrc.wFlags;
pNextMap = rSrc.pNextMap;
pNextNode = rSrc.pNextNode;
return *this;
}
////////////////////////////////////////////////////////////////////////////
CXTPSyntaxEditLexAutomatMemMan::CXTPSyntaxEditLexAutomatMemMan()
{
m_lLockCount = 0;
m_pFreeMaps = NULL;
m_pFreeNodes = NULL;
m_pFreeTables = NULL;
m_uAllocatedMaps = 0;
m_uUsedMaps = 0;
m_uAllocatedNodes = 0;
m_uUsedNodes = 0;
m_uAllocatedTables = 0;
m_uUsedTables = 0;
m_uAllocatedTablesBytes = 0;
m_uUsedTablesBytes = 0;
}
CXTPSyntaxEditLexAutomatMemMan::~CXTPSyntaxEditLexAutomatMemMan()
{
FreeAll();
}
DWORD CXTPSyntaxEditLexAutomatMemMan::Lock()
{
return ::InterlockedIncrement(&m_lLockCount);
}
DWORD CXTPSyntaxEditLexAutomatMemMan::Unlok()
{
if (m_lLockCount <=0)
{
ASSERT(FALSE);
return 0;
}
LONG lResult = ::InterlockedDecrement(&m_lLockCount);
if (0 == lResult)
{
FreeAll();
return 0;
}
return (DWORD)lResult;
}
void CXTPSyntaxEditLexAutomatMemMan::FreeAll()
{
ASSERT(m_lLockCount == 0);
POSITION pos;
//- 1 -----------------------------------------------
pos = m_allocatedNodes.GetHeadPosition();
while (pos)
{
delete[] m_allocatedNodes.GetNext(pos);
}
m_allocatedNodes.RemoveAll();
//- 2 -----------------------------------------------
pos = m_allocatedMaps.GetHeadPosition();
while (pos)
{
delete[] m_allocatedMaps.GetNext(pos);
}
m_allocatedMaps.RemoveAll();
//- 3 -----------------------------------------------
pos = m_allocatedTables.GetHeadPosition();
while (pos)
{
delete m_allocatedTables.GetNext(pos);
}
m_allocatedTables.RemoveAll();
m_pFreeMaps = NULL;
m_pFreeNodes = NULL;
m_pFreeTables = NULL;
m_uAllocatedMaps = 0;
m_uUsedMaps = 0;
m_uAllocatedNodes = 0;
m_uUsedNodes = 0;
m_uAllocatedTables = 0;
m_uUsedTables = 0;
m_uAllocatedTablesBytes = 0;
m_uUsedTablesBytes = 0;
}
CXTPSyntaxEditLexAutomatWordsMap* CXTPSyntaxEditLexAutomatMemMan::NewMap(UINT uHashTableSize)
{
if (m_pFreeMaps)
{
m_uUsedMaps += 1;
CXTPSyntaxEditLexAutomatWordsMap* pMap = m_pFreeMaps;
m_pFreeMaps = m_pFreeMaps->pNextFreeObj;
pMap->pNextFreeObj = NULL;
pMap->InitMap(uHashTableSize);
return pMap;
}
int nObjCount = 1024/sizeof(CXTPSyntaxEditLexAutomatWordsMap);
m_pFreeMaps = new CXTPSyntaxEditLexAutomatWordsMap[nObjCount];
if (!m_pFreeMaps)
{
return NULL;
}
m_allocatedMaps.AddTail(m_pFreeMaps);
m_uAllocatedMaps += nObjCount;
for (int i = 1; i < nObjCount; i++)
{
m_pFreeMaps[i-1].pNextFreeObj = &m_pFreeMaps[i];
}
return NewMap(uHashTableSize);
}
LA_CHAR_NODE* CXTPSyntaxEditLexAutomatMemMan::NewNode()
{
if (m_pFreeNodes)
{
m_uUsedNodes += 1;
LA_CHAR_NODE* pObj = m_pFreeNodes;
m_pFreeNodes = m_pFreeNodes->pNextNode;
pObj->pNextNode = NULL;
return pObj;
}
int nObjCount = 1024/sizeof(LA_CHAR_NODE);
m_pFreeNodes = new LA_CHAR_NODE[nObjCount];
if (!m_pFreeNodes)
{
return NULL;
}
m_allocatedNodes.AddTail(m_pFreeNodes);
m_uAllocatedNodes += nObjCount;
for (int i = 1; i < nObjCount; i++)
{
m_pFreeNodes[i-1].pNextNode = &m_pFreeNodes[i];
}
return NewNode();
}
PLA_CHAR_NODE* CXTPSyntaxEditLexAutomatMemMan::NewHashTable(UINT uSize)
{
ASSERT(uSize >= 1);
if (m_pFreeTables)
{
// try find object with the same size
LA_HASH_TABLE** ppHTabPrev = &m_pFreeTables;
LA_HASH_TABLE* pHTab = m_pFreeTables;
while (pHTab)
{
if (pHTab->uSize == uSize)
{
*ppHTabPrev = pHTab->pNextFreeObj;
pHTab->pNextFreeObj = NULL;
m_uUsedTables += 1;
m_uUsedTablesBytes += uSize * sizeof(PLA_CHAR_NODE) + LA_HASH_TABLE::GetHeaderSizeB();
return pHTab->GetData();
}
ppHTabPrev = &(pHTab->pNextFreeObj);
ASSERT(pHTab != pHTab->pNextFreeObj);
pHTab = pHTab->pNextFreeObj;
}
// try find bigger object and cut it
ppHTabPrev = &m_pFreeTables;
pHTab = m_pFreeTables;
UINT uHeaderSize = LA_HASH_TABLE::GetHeaderSize();
while (pHTab)
{
if (pHTab->uSize >= uSize)
{
if (pHTab->uSize - uSize > uHeaderSize)
{
LA_HASH_TABLE* pHTabNext = (LA_HASH_TABLE*) (pHTab->GetData()+ uSize);
pHTabNext->uSize = pHTab->uSize - uSize - uHeaderSize;
pHTab->uSize = uSize;
ASSERT(pHTabNext->uSize > 0);
ASSERT(pHTab != pHTab->pNextFreeObj);
pHTabNext->pNextFreeObj = pHTab->pNextFreeObj;
*ppHTabPrev = pHTabNext;
pHTab->pNextFreeObj = NULL;
m_uAllocatedTables += 1;
}
else
{
ASSERT(pHTab != pHTab->pNextFreeObj);
*ppHTabPrev = pHTab->pNextFreeObj;
pHTab->pNextFreeObj = NULL;
}
m_uUsedTables += 1;
m_uUsedTablesBytes += uSize * sizeof(PLA_CHAR_NODE) + LA_HASH_TABLE::GetHeaderSizeB();
return pHTab->GetData();
}
ppHTabPrev = &pHTab->pNextFreeObj;
ASSERT(pHTab != pHTab->pNextFreeObj);
pHTab = pHTab->pNextFreeObj;
}
}
//=== Allocate new block ===
UINT uDataSize = 1024 * uSize;
LA_HASH_TABLE* pNewTable = (LA_HASH_TABLE*) new PLA_CHAR_NODE[uDataSize];
if (!pNewTable)
{
return NULL;
}
memset(pNewTable, 0, uDataSize * sizeof(PLA_CHAR_NODE));
pNewTable->uSize = uDataSize - LA_HASH_TABLE::GetHeaderSize();
pNewTable->pNextFreeObj = m_pFreeTables;
m_pFreeTables = pNewTable;
ASSERT(m_pFreeTables != m_pFreeTables->pNextFreeObj);
m_allocatedTables.AddTail((PLA_CHAR_NODE*)pNewTable);
m_uAllocatedTables += 1;
m_uAllocatedTablesBytes += uDataSize * sizeof(PLA_CHAR_NODE);
return NewHashTable(uSize);
}
void CXTPSyntaxEditLexAutomatMemMan::FreeObject(CXTPSyntaxEditLexAutomatWordsMap* pObj)
{
pObj->Clear();
pObj->pNextFreeObj = m_pFreeMaps;
m_pFreeMaps = pObj;
m_uUsedMaps --;
}
void CXTPSyntaxEditLexAutomatMemMan::FreeObject(LA_CHAR_NODE* pObj)
{
pObj->Clear();
pObj->pNextNode = m_pFreeNodes;
m_pFreeNodes = pObj;
m_uUsedNodes--;
}
void CXTPSyntaxEditLexAutomatMemMan::FreeObject(PLA_CHAR_NODE* pObj)
{
LA_HASH_TABLE* pHTab = LA_HASH_TABLE::GetHeader(pObj);
pHTab->Clear();
pHTab->pNextFreeObj = m_pFreeTables;
ASSERT(pHTab != pHTab->pNextFreeObj);
m_pFreeTables = pHTab;
m_uUsedTables--;
m_uUsedTablesBytes -= pHTab->uSize * sizeof(PLA_CHAR_NODE) + LA_HASH_TABLE::GetHeaderSizeB();
}
#ifdef _DEBUG
void CXTPSyntaxEditLexAutomatMemMan::Dump(CDumpContext& dc) const
{
UNREFERENCED_PARAMETER(dc);
#ifdef TRACE_MEMORY_LEX_AUTOMAT_MEM_MAN
UINT uAllocatedTotal = (m_uAllocatedMaps*sizeof(CXTPSyntaxEditLexAutomatWordsMap) +
m_uAllocatedNodes*sizeof(LA_CHAR_NODE) +
m_uAllocatedTablesBytes) / 1024;
UINT uUsedTotal = (m_uUsedMaps*sizeof(CXTPSyntaxEditLexAutomatWordsMap) +
m_uUsedNodes*sizeof(LA_CHAR_NODE) +
m_uUsedTablesBytes) / 1024;
dc << _T("*** Lex-Automat Mem Man *** \n ")
<< _T("\n")
<< _T("AllocatedMaps=") << (int)m_uAllocatedMaps << _T(" (") << (int)(m_uAllocatedMaps * sizeof(CXTPSyntaxEditLexAutomatWordsMap) / 1024) << _T(" KB) \n")
<< _T("UsedMaps=") << (int)m_uUsedMaps << _T(" (") << (int)(m_uUsedMaps * sizeof(CXTPSyntaxEditLexAutomatWordsMap) / 1024) << _T(" KB) \n")
<< _T("\n")
<< _T("AllocatedNodes=") << (int)m_uAllocatedNodes << _T(" (") << (int)(m_uAllocatedNodes*sizeof(LA_CHAR_NODE) / 1024) << _T(" KB) \n")
<< _T(" UsedNodes=") << (int)m_uUsedNodes << _T(" (") << (int)(m_uUsedNodes*sizeof(LA_CHAR_NODE) / 1024) << _T(" KB) \n")
<< _T("\n")
<< _T("AllocatedTables=") << (int)m_uAllocatedTables << _T(" (") << (int)(m_uAllocatedTablesBytes / 1024) << _T(" KB) \n")
<< _T("UsedTables=") << (int)m_uUsedTables << _T(" (") << (int)(m_uUsedTablesBytes / 1024) << _T(" KB) \n")
<< _T("\n ")
<< _T("= AllocatedTotal= ") << (int)uAllocatedTotal << _T(" KB, UsedTotal= ") << (int)uUsedTotal << _T(" KB, [Free= ") << ((int)uAllocatedTotal - (int)uUsedTotal) << _T(" KB] \n\n ");
#endif
}
#endif
////////////////////////////////////////////////////////////////////////////
//class CXTPSyntaxEditLexAutomatWordsMap : public CCmdTarget
CXTPSyntaxEditLexAutomatWordsMap::CXTPSyntaxEditLexAutomatWordsMap(UINT uHashTableSize)
{
m_pHashTable = NULL;
ASSERT(uHashTableSize >= 1);
m_uHashTableSize = max(1, uHashTableSize);
pNextFreeObj = NULL;
}
CXTPSyntaxEditLexAutomatWordsMap::~CXTPSyntaxEditLexAutomatWordsMap()
{
//RemoveAll();
}
void CXTPSyntaxEditLexAutomatWordsMap::InitMap(UINT uHashTableSize)
{
if (m_pHashTable)
{
XTPGetLexAutomatMemMan()->FreeObject(m_pHashTable);
m_pHashTable = NULL;
}
ASSERT(uHashTableSize >= 1);
m_uHashTableSize = uHashTableSize;
}
UINT CXTPSyntaxEditLexAutomatWordsMap::GetHashTableSize()
{
return m_uHashTableSize;
}
void CXTPSyntaxEditLexAutomatWordsMap::OnFinalRelease()
{
RemoveAll() ;
XTPGetLexAutomatMemMan()->FreeObject(this);
}
void CXTPSyntaxEditLexAutomatWordsMap::RemoveAll()
{
if (m_pHashTable)
{
for (UINT i = 0; i < m_uHashTableSize; i++)
{
LA_CHAR_NODE* pNode = m_pHashTable[i];
while (pNode)
{
LA_CHAR_NODE* pNode2 = pNode;
pNode = pNode->pNextNode;
XTPGetLexAutomatMemMan()->FreeObject(pNode2);
}
}
XTPGetLexAutomatMemMan()->FreeObject(m_pHashTable);
m_pHashTable = NULL;
}
}
UINT CXTPSyntaxEditLexAutomatWordsMap::PrimeAdjustU_50(UINT uNumber)
{
ASSERT(uNumber <= 50);
static UINT s_arPrimes_50[] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53};
static CUIntArray s_arMap_50;
if (s_arMap_50.GetSize() == 0)
{
int nPrimeIdx = 0;
for (UINT i = 0; i < 50; i++)
{
if (i > s_arPrimes_50[nPrimeIdx] && nPrimeIdx < _countof(s_arPrimes_50))
{
nPrimeIdx++;
ASSERT(i <= s_arPrimes_50[nPrimeIdx]);
}
s_arMap_50.SetAtGrow(i, s_arPrimes_50[nPrimeIdx]);
}
}
if (uNumber < 50)
{
UINT uPrameNum = s_arMap_50[uNumber];
return uPrameNum;
}
return uNumber;
}
UINT CXTPSyntaxEditLexAutomatWordsMap::DivideHTSize(UINT uHashTableSize, UINT uMin)
{
UINT uDiv = 2;
if (uHashTableSize <= 10)
{
uDiv = 2;
}
else if (uHashTableSize <= 20)
{
uDiv = 3;
}
else
{
uDiv = 4;
}
UINT uNewSize = max(uHashTableSize/uDiv, uMin);
uNewSize = PrimeAdjustU_50(uNewSize);
return uNewSize;
}
WORD CXTPSyntaxEditLexAutomatWordsMap::_GetChar(LPCTSTR pcszStr, int& rnCharLen) const
{
WORD wChar = 0;
LPCTSTR p2 = _tcsinc(pcszStr);
rnCharLen = int(p2 - pcszStr);
if (rnCharLen == 1)
{
wChar = *((BYTE*)pcszStr);
}
else if (rnCharLen == 2)
{
wChar = *((WORD*)pcszStr);
}
else
{
ASSERT(FALSE);
rnCharLen = 0;
}
return wChar;
}
WORD CXTPSyntaxEditLexAutomatWordsMap::_ChangeCase(WORD wChar) const
{
WORD dwChar0[2] = {wChar, 0 };
if (_istlower(wChar))
{
STRUPR_S((LPTSTR)&dwChar0, 2);
}
else if (_istupper(wChar))
{
TCSLWR_S((LPTSTR)&dwChar0, 2);
}
return dwChar0[0];
}
WORD CXTPSyntaxEditLexAutomatWordsMap::_MakeLower(WORD wChar) const
{
if (_istupper(wChar))
{
WORD dwChar0[2] = {wChar, 0 };
TCSLWR_S((LPTSTR)&dwChar0, 2);
return dwChar0[0];
}
return wChar;
}
const LA_CHAR_NODE* CXTPSyntaxEditLexAutomatWordsMap::Lookup(WORD wChar) const
{
if (m_pHashTable)
{
UINT uIndex = wChar % m_uHashTableSize;
LA_CHAR_NODE* pNode = m_pHashTable[uIndex];
while (pNode)
{
if (pNode->wChar == wChar)
{
return pNode;
}
pNode = pNode->pNextNode;
}
}
return NULL;
}
const LA_CHAR_NODE* CXTPSyntaxEditLexAutomatWordsMap::SetAt(const LA_CHAR_NODE& newNode)
{
if (!m_pHashTable)
{
ASSERT(m_uHashTableSize >= 1);
m_pHashTable = XTPGetLexAutomatMemMan()->NewHashTable(m_uHashTableSize);
if (!m_pHashTable)
{
return NULL;
}
}
LA_CHAR_NODE* pNode2 = (LA_CHAR_NODE*)Lookup(newNode.wChar);
if (!pNode2)
{
UINT uIndex = newNode.wChar % m_uHashTableSize;
LA_CHAR_NODE* pNode0 = m_pHashTable[uIndex];
pNode2 = XTPGetLexAutomatMemMan()->NewNode();
*pNode2 = newNode;
pNode2->pNextNode = pNode0;
m_pHashTable[uIndex] = pNode2;
}
else
{
ASSERT(pNode2->wChar == newNode.wChar);
*pNode2 = newNode;
}
return pNode2;
}
void CXTPSyntaxEditLexAutomatWordsMap::AddWord(CString strWord, UINT uHashTableSize )
{
int nCharLen = 0;
WORD wChar1 = _GetChar(strWord, nCharLen);
strWord.Delete(0, nCharLen);
BOOL bWordEnded = strWord.GetLength() <= 0;
LA_CHAR_NODE* pWordData = (LA_CHAR_NODE*)Lookup(wChar1);
if (!pWordData)
{
LA_CHAR_NODE wordData2;
wordData2.wChar = wChar1;
pWordData = (LA_CHAR_NODE*)SetAt(wordData2);
if (!pWordData)
{
return;
}
}
if (!bWordEnded && !pWordData->pNextMap)
{
pWordData->pNextMap = XTPGetLexAutomatMemMan()->NewMap(uHashTableSize); //new CXTPSyntaxEditLexAutomatWordsMap;
if (!pWordData->pNextMap)
{
return;
}
}
if (bWordEnded)
{
pWordData->wFlags |= LA_CHAR_NODE::nfSubWordEnd;
}
else
{
pWordData->pNextMap->AddWord(strWord, DivideHTSize(uHashTableSize, 1));
}
}
BOOL CXTPSyntaxEditLexAutomatWordsMap::_FindWord(LPCTSTR pcszBuffer, CString& rstrWord, int nBufSize,
WORD wEndFlags, BOOL bConvertToLowerCase,
BOOL bTryToChangeCaseDyn, BOOL bChangeCase) const
{
ASSERT((bConvertToLowerCase && bTryToChangeCaseDyn) == FALSE);
int nCharLen = 0;
WORD wChar1 = _GetChar(pcszBuffer, nCharLen);
if (bConvertToLowerCase)
{
wChar1 = _MakeLower(wChar1);
}
else if (bChangeCase)
{
wChar1 = _ChangeCase(wChar1);
if (wChar1 == 0)
{
return FALSE;
}
}
LA_CHAR_NODE* pWordData = (LA_CHAR_NODE*)Lookup(wChar1);
if (!pWordData)
{
return FALSE;
}
DWORD dwChar2 = wChar1;
rstrWord += (LPCTSTR)&dwChar2;
if (!pWordData->pNextMap || (pWordData->wFlags & wEndFlags) )
{
return TRUE;
}
if (nBufSize < nCharLen)
{
return FALSE;
}
pcszBuffer += nCharLen;
nBufSize -= nCharLen;
BOOL bRes = pWordData->pNextMap->_FindWord(pcszBuffer, rstrWord, nBufSize,
wEndFlags, bConvertToLowerCase, bTryToChangeCaseDyn, FALSE);
if (!bRes && bTryToChangeCaseDyn)
{
bRes = pWordData->pNextMap->_FindWord(pcszBuffer, rstrWord, nBufSize,
wEndFlags, bConvertToLowerCase, bTryToChangeCaseDyn, TRUE);
}
if (!bRes && (pWordData->wFlags & LA_CHAR_NODE::nfSubWordEnd) )
{
return TRUE;
}
return bRes;
}
BOOL CXTPSyntaxEditLexAutomatWordsMap::FindWord(BOOL bMinWord, LPCTSTR pcszBuffer, CString& rstrWord, int nBufSize,
BOOL bConvertToLowerCase, BOOL bIgnoreCaseDyn) const
{
BOOL bRes = _FindWord(pcszBuffer, rstrWord, nBufSize,
(WORD)(bMinWord ? LA_CHAR_NODE::nfSubWordEnd : 0),
bConvertToLowerCase, bIgnoreCaseDyn, FALSE);
if (!bRes && bIgnoreCaseDyn)
{
bRes = _FindWord(pcszBuffer, rstrWord, nBufSize,
(WORD)(bMinWord ? LA_CHAR_NODE::nfSubWordEnd : 0),
bConvertToLowerCase, bIgnoreCaseDyn, TRUE);
}
return bRes;
}
////////////////////////////////////////////////////////////////////////////
CXTPSyntaxEditLexTagsAutomat::CXTPSyntaxEditLexTagsAutomat()
{
}
CXTPSyntaxEditLexTagsAutomat::~CXTPSyntaxEditLexTagsAutomat()
{
}
void CXTPSyntaxEditLexTagsAutomat::CopyFrom(const CXTPSyntaxEditLexTagsAutomat& rSrc)
{
m_ptrWordsMap = rSrc.m_ptrWordsMap;
m_ptrWordsMap_not = rSrc.m_ptrWordsMap_not;
}
void CXTPSyntaxEditLexTagsAutomat::RemoveAll()
{
m_ptrWordsMap = NULL;
m_ptrWordsMap_not = NULL;
}
UINT CXTPSyntaxEditLexTagsAutomat::_CalcHashTableSize(int nCount)
{
if (!nCount)
{
return 1;
}
UINT uHashTableSize = 29;
if (nCount <= 10)
{ uHashTableSize = 3;
} else if (nCount <= 30) { uHashTableSize = 7;
} else if (nCount <= 60) { uHashTableSize = 11;
} else if (nCount <= 100) { uHashTableSize = 17;
} else if (nCount <= 200) { uHashTableSize = 23; }
return uHashTableSize;
}
void CXTPSyntaxEditLexTagsAutomat::_AddWords(CXTPSyntaxEditLexAutomatWordsMapPtr& rPtrMap, CStringArray& arTags,
BOOL bConvertToLowerCase)
{
int nCount = (int)arTags.GetSize();
if (!nCount)
{
return;
}
if (!rPtrMap)
{
UINT uHashTableSize0 = _CalcHashTableSize(nCount);
rPtrMap = XTPGetLexAutomatMemMan()->NewMap(uHashTableSize0);
if (!rPtrMap)
{
return;
}
}
UINT uHashTableSize = rPtrMap->GetHashTableSize();
for (int i = 0; i < nCount; i++)
{
CString strTag = arTags[i];
if (bConvertToLowerCase)
{
strTag.MakeLower();
}
rPtrMap->AddWord(strTag, CXTPSyntaxEditLexAutomatWordsMap::DivideHTSize(uHashTableSize, 3));
}
}
void CXTPSyntaxEditLexTagsAutomat::AddTagsList(CXTPSyntaxEditLexVariantPtrArray* pArTags, BOOL bConvertToLowerCase)
{
if (!pArTags)
{
ASSERT(FALSE);
return;
}
CStringArray arTags, arTags_not;
int nCount = (int)pArTags->GetSize();
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexVariant* pLV = pArTags->GetAt(i, FALSE);
if (!pLV)
{
ASSERT(FALSE);
continue;
}
ASSERT(pLV->m_nObjType == xtpEditLVT_valStr || pLV->m_nObjType == xtpEditLVT_valVar);
if (pLV->m_nObjType == xtpEditLVT_valStr)
{
arTags.Append(pLV->m_arStrVals);
}
else if (pLV->m_nObjType == xtpEditLVT_valVar)
{
CStringArray arVarData;
pLV->m_Variable.GetVariableData(pLV->m_Variable.m_nVarID, arVarData);
if (pLV->m_Variable.m_nVarFlags & CXTPSyntaxEditLexVariable::xtpEditVarfNot)
{
arTags_not.Append(arVarData);
}
else
{
arTags.Append(arVarData);
}
}
}
_AddWords(m_ptrWordsMap, arTags, bConvertToLowerCase);
_AddWords(m_ptrWordsMap_not, arTags_not, bConvertToLowerCase);
}
BOOL CXTPSyntaxEditLexTagsAutomat::_FindWord(BOOL bMinWord, LPCTSTR pcszBuffer, CString& rstrWord, int nBufSize,
BOOL bConvertToLowerCase, BOOL bIgnoreCaseDyn)
{
rstrWord.Empty();
if (m_ptrWordsMap)
{
if (m_ptrWordsMap->FindWord(bMinWord, pcszBuffer, rstrWord, nBufSize, bConvertToLowerCase, bIgnoreCaseDyn))
{
return TRUE;
}
}
if (m_ptrWordsMap_not)
{
//if (!m_ptrWordsMap->FindWord(bMinWord, pcszBuffer, rstrWord, nBufSize, bConvertToLowerCase, bIgnoreCaseDyn))
if (!m_ptrWordsMap_not->FindWord(bMinWord, pcszBuffer, rstrWord, nBufSize, bConvertToLowerCase, bIgnoreCaseDyn))
{
DWORD dwChar2 = 0;
TCSNCCPY_S((LPTSTR)&dwChar2, 2, pcszBuffer, 1);
rstrWord += (LPCTSTR)&dwChar2;
return TRUE;
}
}
return FALSE;
}
BOOL CXTPSyntaxEditLexTagsAutomat::FindMinWord(LPCTSTR pcszBuffer, CString& rstrWord, int nBufSize,
BOOL bConvertToLowerCase, BOOL bIgnoreCaseDyn)
{
return _FindWord(TRUE, pcszBuffer, rstrWord, nBufSize, bConvertToLowerCase, bIgnoreCaseDyn);
}
BOOL CXTPSyntaxEditLexTagsAutomat::FindMaxWord(LPCTSTR pcszBuffer, CString& rstrWord, int nBufSize,
BOOL bConvertToLowerCase, BOOL bIgnoreCaseDyn)
{
return _FindWord(FALSE, pcszBuffer, rstrWord, nBufSize, bConvertToLowerCase, bIgnoreCaseDyn);
}
BOOL CXTPSyntaxEditLexTagsAutomat::IsEmpty()
{
return m_ptrWordsMap == NULL && m_ptrWordsMap_not == NULL;
}
////////////////////////////////////////////////////////////////////////////
CMapStringToPtr CXTPSyntaxEditLexVariable::s_mapVar2ID;
BOOL CXTPSyntaxEditLexVariable::s_bVarMapInitialized = FALSE;
//////////////////////////////////////////////////////
class CXTPSyntaxEditLexVariable_initializer : public CXTPSyntaxEditLexVariable
{
public:
CXTPSyntaxEditLexVariable_initializer() {
InitStandartVarsIfNeed();
};
} s_LVarIniter;
//////////////////////////////////////////////////////
void CXTPSyntaxEditLexVariable::InitStandartVarsIfNeed()
{
if (s_bVarMapInitialized)
{
return;
}
s_bVarMapInitialized = TRUE;
s_mapVar2ID[_T("@alpha")] = (void*)xtpEditVarID_alpha;
s_mapVar2ID[_T("@digit")] = (void*)xtpEditVarID_digit;
s_mapVar2ID[_T("@hexdigit")] = (void*)xtpEditVarID_HexDigit;
s_mapVar2ID[_T("@specs")] = (void*)xtpEditVarID_specs;
s_mapVar2ID[_T("@eol")] = (void*)xtpEditVarID_EOL;
}
CXTPSyntaxEditLexVariable::CXTPSyntaxEditLexVariable()
{
m_nVarFlags = 0;
m_nVarID = 0;
}
CXTPSyntaxEditLexVariable::~CXTPSyntaxEditLexVariable()
{
}
const CXTPSyntaxEditLexVariable& CXTPSyntaxEditLexVariable::operator=(const CXTPSyntaxEditLexVariable& rSrc)
{
m_strVar = rSrc.m_strVar;
m_nVarFlags = rSrc.m_nVarFlags;
m_nVarID = rSrc.m_nVarID;
return *this;
}
BOOL CXTPSyntaxEditLexVariable::SetVariable(LPCTSTR pcszVarName)
{
m_nVarFlags = 0;
m_nVarID = xtpEditVarID_Unknown;
m_strVar = pcszVarName;
//==================================
CStringArray arVar;
if (!SplitStr(pcszVarName, _T(':'), arVar) || arVar.GetSize() < 1)
{
//TRACE
ASSERT(FALSE);
return FALSE;
}
//----------------------------------
CString strVar = arVar[0];
//----------------------------------
int nVarSize = (int)arVar.GetSize();
if (nVarSize > 1)
{
CString strOp = arVar[1];
if (strOp.CompareNoCase(_T("not")) == 0)
{
m_nVarFlags |= xtpEditVarfNot;
}
}
//==================================
m_nVarID = GetVarID(strVar);
ASSERT(m_nVarID != xtpEditVarID_Unknown);
return m_nVarID != xtpEditVarID_Unknown;
}
int CXTPSyntaxEditLexVariable::GetVarID(LPCTSTR pcszVarName)
{
void* pVarID = 0;
CString strVar = pcszVarName;
strVar.MakeLower();
if (s_mapVar2ID.Lookup(strVar, pVarID))
{
return (int)(INT_PTR)pVarID;
}
return xtpEditVarID_Unknown;
}
BOOL CXTPSyntaxEditLexVariable::operator == (const CXTPSyntaxEditLexVariable& rSrc) const
{
return m_nVarID == rSrc.m_nVarID && m_nVarFlags == rSrc.m_nVarFlags;
}
BOOL CXTPSyntaxEditLexVariable::GetVariableData(int nVarID, CStringArray& rarVarData)
{
CUIntArray arFrom, arTo;
int i;
if (nVarID == CXTPSyntaxEditLexVariable::xtpEditVarID_alpha)
{
arFrom.Add(_T('a')); arTo.Add(_T('z'));
arFrom.Add(_T('A')); arTo.Add(_T('Z'));
}
else if (nVarID == CXTPSyntaxEditLexVariable::xtpEditVarID_digit)
{
arFrom.Add(_T('0')); arTo.Add(_T('9'));
}
else if (nVarID == CXTPSyntaxEditLexVariable::xtpEditVarID_HexDigit)
{
arFrom.Add(_T('0')); arTo.Add(_T('9'));
arFrom.Add(_T('a')); arTo.Add(_T('f'));
arFrom.Add(_T('A')); arTo.Add(_T('F'));
}
for (i = 0; i < arFrom.GetSize(); i++)
{
for (UINT c = arFrom[i]; c <= arTo[i]; c++)
{
CString strChar((TCHAR)c);
rarVarData.Add(strChar);
}
}
if (arFrom.GetSize())
{
return TRUE;
}
//------------------------------------------------------------------------
if (nVarID == CXTPSyntaxEditLexVariable::xtpEditVarID_specs)
{
LPCTSTR pChar = cszSpecs;
int nCountC = (int)_tcsclen(cszSpecs);
for (i = 0; i < nCountC; i++)
{
CString strChar((TCHAR)(*pChar));
rarVarData.Add(strChar);
pChar = _tcsinc(pChar);
}
}
else if (nVarID == CXTPSyntaxEditLexVariable::xtpEditVarID_EOL)
{
rarVarData.Add(_T("\r"));
rarVarData.Add(_T("\n"));
}
else
{
ASSERT(FALSE);
return FALSE;
}
return TRUE;
}
//===========================================================================
CXTPSyntaxEditLexVariant::~CXTPSyntaxEditLexVariant()
{
}
CXTPSyntaxEditLexVariant::CXTPSyntaxEditLexVariant()
{
m_nObjType = xtpEditLVT_Unknown;
m_nValue = 0;
m_ptrLVArrayPtr = NULL;
}
CXTPSyntaxEditLexVariant::CXTPSyntaxEditLexVariant(const CXTPSyntaxEditLexVariant& rSrc)
{
*this = rSrc;
}
CXTPSyntaxEditLexVariant::CXTPSyntaxEditLexVariant(CXTPSyntaxEditLexClass* pClass):
m_ptrClass(pClass, TRUE)
{
m_nObjType = xtpEditLVT_classPtr;
m_nValue = 0;
m_ptrLVArrayPtr = NULL;
}
CXTPSyntaxEditLexVariant::CXTPSyntaxEditLexVariant(CXTPSyntaxEditLexVariantPtrArray* pLVArray)
{
m_nObjType = xtpEditLVT_LVArrayPtr;
m_nValue = 0;
m_ptrLVArrayPtr = pLVArray;
}
CXTPSyntaxEditLexVariant::CXTPSyntaxEditLexVariant(const CXTPSyntaxEditLexVariable& rSrcVar)
{
m_nObjType = xtpEditLVT_valVar;
m_Variable = rSrcVar;
m_nValue = 0;
m_ptrLVArrayPtr = NULL;
}
CXTPSyntaxEditLexVariant::CXTPSyntaxEditLexVariant(LPCTSTR pcszStr, int eType)
{
ASSERT( eType == xtpEditLVT_valStr || eType == xtpEditLVT_className);
m_nObjType = eType;
m_nValue = 0;
m_ptrLVArrayPtr = NULL;
m_arStrVals.SetAtGrow(0, pcszStr);
}
CXTPSyntaxEditLexVariant::CXTPSyntaxEditLexVariant(const CStringArray* pArStrVals)
{
m_nObjType = xtpEditLVT_valStr;
m_nValue = 0;
m_ptrLVArrayPtr = NULL;
if (pArStrVals)
{
m_arStrVals.Append(*pArStrVals);
}
}
CXTPSyntaxEditLexVariant::CXTPSyntaxEditLexVariant(int nValue)
{
m_nObjType = xtpEditLVT_valInt;
m_nValue = nValue;
m_ptrLVArrayPtr = NULL;
}
BOOL CXTPSyntaxEditLexVariant::IsStrType() const
{
if (m_nObjType == xtpEditLVT_valStr || m_nObjType == xtpEditLVT_className)
{
return TRUE;
}
return FALSE;
}
LPCTSTR CXTPSyntaxEditLexVariant::GetStr() const
{
if (IsStrType())
{
if (m_arStrVals.GetSize() > 0)
{
return m_arStrVals[0];
}
return _T("");
}
ASSERT(FALSE);
return _T("");
}
const CXTPSyntaxEditLexVariant& CXTPSyntaxEditLexVariant::operator = (int nVal)
{
m_nValue = nVal;
m_nObjType = xtpEditLVT_valInt;
return *this;
}
const CXTPSyntaxEditLexVariant& CXTPSyntaxEditLexVariant::operator = (const CXTPSyntaxEditLexVariable& rSrcVar)
{
m_nValue = 0;
m_nObjType = xtpEditLVT_valVar;
m_Variable = rSrcVar;
return *this;
}
const CXTPSyntaxEditLexVariant& CXTPSyntaxEditLexVariant::operator = (const CXTPSyntaxEditLexVariant& rSrc)
{
m_nObjType = rSrc.m_nObjType;
m_ptrClass = rSrc.m_ptrClass;
m_ptrLVArrayPtr = rSrc.m_ptrLVArrayPtr;
m_Variable = rSrc.m_Variable;
m_nValue = rSrc.m_nValue;
m_arStrVals.RemoveAll();
m_arStrVals.Append(rSrc.m_arStrVals);
return *this;
}
BOOL CXTPSyntaxEditLexVariant::SetVariable(LPCTSTR pcszVarName)
{
m_nValue = 0;
m_nObjType = xtpEditLVT_valVar;
BOOL bRes = m_Variable.SetVariable(pcszVarName);
return bRes;
}
CXTPSyntaxEditLexVariant* CXTPSyntaxEditLexVariant::Clone() const
{
CXTPSyntaxEditLexVariant* pClone = new CXTPSyntaxEditLexVariant(*this);
return pClone;
}
BOOL CXTPSyntaxEditLexVariant::operator == (const CXTPSyntaxEditLexVariant& rSrc) const
{
if (m_nObjType != rSrc.m_nObjType)
{
return FALSE;
}
switch (m_nObjType)
{
case xtpEditLVT_Unknown:
return TRUE;
case xtpEditLVT_className:
case xtpEditLVT_valStr:
if (m_arStrVals.GetSize() == rSrc.m_arStrVals.GetSize())
{
for (int i = 0; i < m_arStrVals.GetSize(); i++)
{
if (m_arStrVals[i] != rSrc.m_arStrVals[i])
{
return FALSE;
}
}
return TRUE;
}
return FALSE;
case xtpEditLVT_valInt:
return m_nValue == rSrc.m_nValue;
case xtpEditLVT_valVar:
return m_Variable == rSrc.m_Variable;
case xtpEditLVT_classPtr:
return m_ptrClass && rSrc.m_ptrClass &&
m_ptrClass->GetClassName() == rSrc.m_ptrClass->GetClassName();
case xtpEditLVT_LVArrayPtr:
if (m_ptrLVArrayPtr && rSrc.m_ptrLVArrayPtr &&
m_ptrLVArrayPtr->GetSize() == rSrc.m_ptrLVArrayPtr->GetSize())
{
for (int i = 0; i < m_ptrLVArrayPtr->GetSize(); i++)
{
if (!(*m_ptrLVArrayPtr->GetAt(i, FALSE) == *rSrc.m_ptrLVArrayPtr->GetAt(i, FALSE)) )
{
return FALSE;
}
}
return TRUE;
}
return FALSE;
default:
ASSERT(FALSE);
}
return FALSE;
}
#ifdef _DEBUG
void CXTPSyntaxEditLexVariant::Dump(CDumpContext& dc) const
{
if (IsStrType())
{
int nC = (int)m_arStrVals.GetSize();
for (int k = 0; k < nC; k++)
{
CString strTmp = m_arStrVals[k];
if (k)
{
dc << _T(", ");
}
if (m_nObjType == xtpEditLVT_valStr)
{
strTmp = XTPSyntaxEditLexConfig()->ESToStr(strTmp, FALSE);
dc << strTmp;
}
else
{
dc << strTmp;
}
}
}
else if (m_nObjType == xtpEditLVT_valInt)
{
dc << m_nValue;
}
else if (m_nObjType == xtpEditLVT_valVar)
{
dc << m_Variable.m_strVar;
}
else
{
dc << _T(" ?<LV type=") << m_nObjType;
ASSERT(FALSE);
}
}
#endif
////////////////////////////////////////////////////////////////////////////
CXTPSyntaxEditLexOnScreenParseCnt::CXTPSyntaxEditLexOnScreenParseCnt()
{
m_nRowStart = m_nRowEnd = 0;
}
CXTPSyntaxEditLexOnScreenParseCnt::~CXTPSyntaxEditLexOnScreenParseCnt()
{
}
////////////////////////////////////////////////////////////////////////////
CXTPSyntaxEditLexClass_file::CXTPSyntaxEditLexClass_file()
{
m_bExtInitialized = FALSE;
}
CXTPSyntaxEditLexClass_file::~CXTPSyntaxEditLexClass_file()
{
}
CXTPSyntaxEditLexClass* CXTPSyntaxEditLexClass_file::Clone(CXTPSyntaxEditLexClassSchema* pOwnerSch)
{
CXTPSyntaxEditLexClass* pNewClass = NULL;
if (pOwnerSch)
{
pNewClass = pOwnerSch->GetNewClass(TRUE);
}
else
{
pNewClass = new CXTPSyntaxEditLexClass_file();
}
if (pNewClass)
{
pNewClass->CopyFrom(this);
}
return pNewClass;
}
BOOL CXTPSyntaxEditLexClass_file::InternalInitExts(BOOL bReInit)
{
if (m_bExtInitialized && !bReInit)
{
return TRUE;
}
m_bExtInitialized = FALSE;
m_arExt.RemoveAll();
if (!m_Parent.arClassNames.GetSize())
{
TRACE(_T("ERROR! No File extentions string. \n"));
return FALSE;
}
ASSERT(m_Parent.arClassNames.GetSize() == 1);
CString strExtsSet = m_Parent.arClassNames[0];
strExtsSet.TrimLeft();
strExtsSet.TrimRight();
int nESLen = strExtsSet.GetLength();
if (nESLen < 2 || strExtsSet[0] != _T('<') ||
strExtsSet[nESLen-1] != _T('>'))
{
TRACE(_T("ERROR! File extentions bad format: '%s'. Right format: <*.ex1|*.ext2|...> \n"), (LPCTSTR)strExtsSet);
return FALSE;
}
strExtsSet.Delete(nESLen-1);
strExtsSet.Delete(0);
SplitStr(strExtsSet, _T('|'), m_arExt);
int nCount = (int)m_arExt.GetSize();
for (int i = 0; i < nCount; i++)
{
CString strExt = m_arExt[i];
strExt.Replace(_T("*"), _T(""));
strExt.TrimLeft();
strExt.TrimRight();
m_arExt[i] = strExt;
}
//-----------------------------------------------------------------------
m_bExtInitialized = TRUE;
return TRUE;
}
BOOL CXTPSyntaxEditLexClass_file::TestExt(LPCTSTR pcszExt) const
{
ASSERT(m_bExtInitialized);
int nCount = (int)m_arExt.GetSize();
for (int i = 0; i < nCount; i++)
{
CString strExt = m_arExt[i];
if (_tcsicoll(strExt, pcszExt) == 0)
{
return TRUE;
}
}
return FALSE;
}
CXTPSyntaxEditLexVariantPtr CXTPSyntaxEditLexClass_file::PropV(LPCTSTR pcszPropName)
{
CXTPSyntaxEditLexVariantPtr ptrRes = CXTPSyntaxEditLexClass::PropV(pcszPropName);
if (ptrRes)
{
return ptrRes;
}
static LPCTSTR pcszIsExtPref = _T("IsExt=");
static int nIsExtPrefLen = (int)_tcsclen(pcszIsExtPref);
if (_tcsnicmp(pcszPropName, pcszIsExtPref, nIsExtPrefLen) == 0)
{
CString strExt = pcszPropName;
ASSERT(strExt.GetLength() >= nIsExtPrefLen);
strExt.Delete(0, nIsExtPrefLen);
InternalInitExts(TRUE);
BOOL bRes = TestExt(strExt);
CXTPSyntaxEditLexVariant* pV = new CXTPSyntaxEditLexVariant((int)bRes);
return pV;
}
return NULL;
}
int CXTPSyntaxEditLexClass_file::RunParse(CTextIter* pTxtIter,
CXTPSyntaxEditLexTextSchema* pTxtSch,
CXTPSyntaxEditLexTextBlockPtr& rPtrTxtBlock,
CXTPSyntaxEditLexOnScreenParseCnt* pOnScreenRunCnt
)
{
if (!pTxtIter || !pTxtSch)
{
ASSERT(FALSE);
//TRACE
return xtpEditLPR_Error;
}
int nParseRes = 0;
InternalInitExts();
//===========================================================================
BOOL bStarted = (rPtrTxtBlock != NULL);
if (!bStarted )
{
CString strFileExt = pTxtIter->GetFileExt();
bStarted = TestExt(strFileExt);
if (!bStarted )
{
return 0;
}
rPtrTxtBlock = pTxtSch->GetNewBlock();
if (rPtrTxtBlock)
{
rPtrTxtBlock->m_ptrLexClass.SetPtr(this, TRUE);
rPtrTxtBlock->m_PosStartLC = pTxtIter->GetPosLC();
rPtrTxtBlock->m_nStartTagLen = 0;
}
else
{
return xtpEditLPR_StartFound | xtpEditLPR_Error;
}
nParseRes |= xtpEditLPR_StartFound | xtpEditLPR_Iterated;
}
//===========================================================================
// Run End
if (pTxtIter->IsEOF() && rPtrTxtBlock)
{
CSingleLock singleLock(pTxtSch->GetDataLoker(), TRUE);
rPtrTxtBlock->m_PosEndLC = pTxtIter->GetPosLC();
rPtrTxtBlock->m_nEndTagXLCLen = 0;
nParseRes |= xtpEditLPR_EndFound | xtpEditLPR_Iterated;
return nParseRes;
}
if (nParseRes)
{
return nParseRes;
}
//===========================================================================
// *** run childs ***
int nChildsCount = (int)m_arChildrenClasses.GetSize() + (int)m_arDynChildrenClasses.GetSize();
if (nChildsCount)
{
int nCHres = pTxtSch->RunChildren(pTxtIter, rPtrTxtBlock, this,
pOnScreenRunCnt);
nParseRes |= ~(xtpEditLPR_StartFound|xtpEditLPR_EndFound) & nCHres;
if (nParseRes & (xtpEditLPR_Error|xtpEditLPR_RunBreaked|xtpEditLPR_RunFinished))
{
return nParseRes;
}
//---------------------------------------------------------------------------
// Run End
if (pTxtIter->IsEOF() && rPtrTxtBlock)
{
CSingleLock singleLock(pTxtSch->GetDataLoker(), TRUE);
rPtrTxtBlock->m_PosEndLC = pTxtIter->GetPosLC();
rPtrTxtBlock->m_nEndTagXLCLen = 0;
nParseRes |= xtpEditLPR_EndFound;
}
}
return nParseRes;
}
////////////////////////////////////////////////////////////////////////////
CXTPSyntaxEditLexClass::CXTPSyntaxEditLexClass()
{
SetSubMembers();
ClearAttributesCache();
m_Parent.Clear();
m_Children.Clear();
m_nActiv_EndTags_Offset = 0;
}
CXTPSyntaxEditLexClass::~CXTPSyntaxEditLexClass()
{
}
void CXTPSyntaxEditLexClass::ClearAttributesCache()
{
m_bCaseSensitive_Cached = -1; // ask
m_nCollapsable_Cached = -1; // ask
m_bRestartRunLoop_Cached = -1; // ask
m_bEndClassParent_this_Cached = -1; // ask
m_bTxtAttr_cached = FALSE; // ask
}
CXTPSyntaxEditLexVariantPtr CXTPSyntaxEditLexClass::PropV(LPCTSTR pcszPropName)
{
if (_tcsicmp(pcszPropName, _T("name")) == 0)
{
return new CXTPSyntaxEditLexVariant(m_strClassName, xtpEditLVT_className);
}
CXTPSyntaxEditLexVariantPtrArray* ptrData = GetIfMy(pcszPropName);
if (ptrData && ptrData->GetSize())
{
return new CXTPSyntaxEditLexVariant(ptrData);
}
return NULL;
}
void CXTPSyntaxEditLexClass::CloseClasses(CXTPSyntaxEditLexClassPtrArray* pArClasses)
{
if (!pArClasses)
{
ASSERT(FALSE);
return;
}
// 1. ***
int nCount = (int)pArClasses->GetSize();
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrC = pArClasses->GetAt(i);
ASSERT(ptrC);
if (ptrC)
{
ptrC->Close();
}
}
pArClasses->RemoveAll();
}
void CXTPSyntaxEditLexClass::Close()
{
// 1. ***
CXTPSyntaxEditLexClass::CloseClasses(&m_arChildrenClasses);
CXTPSyntaxEditLexClass::CloseClasses(&m_arDynChildrenClasses);
// 2. ***
m_arChildrenSelfRefClasses.RemoveAll();
// 3. ***
TBase::RemoveAll();
m_mapAttributes.RemoveAll();
// 4. ***
m_Parent.ptrDirect = NULL;
}
BOOL CXTPSyntaxEditLexClass::SetProp(const XTP_EDIT_LEXPROPINFO* pPropDesc)
{
if (!pPropDesc || pPropDesc->arPropName.GetSize() < 1)
{
ASSERT(FALSE);
return FALSE;
}
BOOL bProcessed = FALSE;
BOOL bOK = SetProp_ProcessSpecials(pPropDesc, bProcessed);
if (!bOK || bProcessed)
{
return bOK;
}
//-----------------------------------------------------------------------
bProcessed = FALSE;
bOK = SetProp_ProcessSpecObjects(pPropDesc, bProcessed);
if (!bOK || bProcessed)
{
return bOK;
}
//-----------------------------------------------------------------------
bProcessed = FALSE;
bOK = SetProp_ProcessAttributes(pPropDesc, bProcessed);
if (!bOK || bProcessed)
{
return bOK;
}
return FALSE;
}
BOOL CXTPSyntaxEditLexClass::ParseValues(const XTP_EDIT_LEXPROPINFO* pPropDesc,
CXTPSyntaxEditLexVariantPtrArray* pLVArray)
{
if (!pPropDesc || pPropDesc->arPropName.GetSize() < 1 || !pLVArray)
{
ASSERT(FALSE);
return FALSE;
}
pLVArray->RemoveAll();
int nNCount = (int)pPropDesc->arPropName.GetSize();
CString strLastName = pPropDesc->arPropName[nNCount-1];
strLastName.MakeLower();
CString strFullName = MakeStr(pPropDesc->arPropName, _T(":"));
strFullName.MakeLower();
//ref, class, tag, separators
CXTPSyntaxEditLexVariantPtr ptrLexVar;
int nVCount = (int)pPropDesc->arPropValue.GetSize();
for (int i = 0; i < nVCount; i++)
{
CString strVal = pPropDesc->arPropValue[i];
CString strVal2;
int nVType = xtpEditLVT_Unknown;
if (IsQuoted(strVal, &strVal2))
{
if (strLastName == _T("tag") || strLastName == _T("separators"))
{
nVType = xtpEditLVT_valStr;
}
else
{
TRACE_ASSERT(FALSE);
//TRACE
TRACE(_T("ERROR! Quoted values ('%s') are not allowed for <:%s>'. (only for <:tag> and <:separators>) '%s' \n"),
(LPCTSTR)strVal, (LPCTSTR)strLastName, (LPCTSTR)strFullName);
}
}
else if (IsVar(strVal, &strVal2))
{
if (strLastName == _T("tag") || strLastName == _T("separators"))
{
nVType = xtpEditLVT_valVar;
}
else
{
TRACE_ASSERT(FALSE);
//TRACE
TRACE(_T("ERROR! Variable values ('%s') are not allowed for <:%s>'. (only for <:tag> and <:separators>) '%s' \n"),
(LPCTSTR)strVal, (LPCTSTR)strLastName, (LPCTSTR)strFullName);
}
}
else
{
//class
if (strLastName == _T("class"))
{
nVType = xtpEditLVT_className;
strVal2 = strVal;
strVal2.TrimLeft();
strVal2.TrimRight();
}
else
{
TRACE_ASSERT(FALSE);
TRACE(_T("ERROR! Unknown ref-expression '%s' \n"), (LPCTSTR)strVal);
}
}
//----------------------------------
if (ptrLexVar &&
(ptrLexVar->m_nObjType != nVType || !ptrLexVar->IsStrType()) )
{
ASSERT(ptrLexVar->m_nObjType != xtpEditLVT_Unknown);
pLVArray->Add(ptrLexVar);
ptrLexVar = NULL;
}
if (nVType != xtpEditLVT_Unknown)
{
if (!ptrLexVar)
{
ptrLexVar = new CXTPSyntaxEditLexVariant();
}
if (!ptrLexVar)
{
return FALSE;
}
if (nVType == xtpEditLVT_valVar)
{
if (!ptrLexVar->SetVariable(strVal2))
{
TRACE(_T("ERROR! Unknown Variable '%s' \n"), (LPCTSTR)strVal2);
}
}
else
{
ptrLexVar->m_nObjType = nVType;
ptrLexVar->m_arStrVals.Add(strVal2);
ASSERT(ptrLexVar->IsStrType());
}
}
}
//-----------------------------------------
if (ptrLexVar)
{
ASSERT(ptrLexVar->m_nObjType != xtpEditLVT_Unknown);
pLVArray->Add(ptrLexVar);
ptrLexVar = NULL;
}
return TRUE;
}
BOOL CXTPSyntaxEditLexClass::SetProp_ProcessSpecObjects(const XTP_EDIT_LEXPROPINFO* pPropDesc,
BOOL& rbProcessed)
{
rbProcessed = FALSE;
if (!pPropDesc || pPropDesc->arPropName.GetSize() < 1)
{
ASSERT(FALSE);
return FALSE;
}
CString strFullName = MakeStr(pPropDesc->arPropName, _T(":"));
strFullName.MakeLower();
if (IfMy(strFullName))
{
CXTPSyntaxEditLexVariantPtrArray arPtrLVar;
if (!ParseValues(pPropDesc, &arPtrLVar))
{
return FALSE;
}
if (!AppendIfMy(strFullName, arPtrLVar))
{
ASSERT(FALSE);
return FALSE;
}
rbProcessed = TRUE;
return TRUE;
}
return TRUE;
}
BOOL CXTPSyntaxEditLexClass::IsQuoted(CString strValue, CString* pstrUnQuotedVal)
{
CString strTmp = strValue;
strTmp.TrimLeft();
strTmp.TrimRight();
int nLen = strTmp.GetLength();
if (nLen >= 2)
{
if (strTmp[0] == _T('\'') && strTmp[nLen-1] == _T('\'') )
{
if (pstrUnQuotedVal)
{
strTmp.Delete(nLen-1);
strTmp.Delete(0);
*pstrUnQuotedVal = strTmp;
}
return TRUE;
}
}
if (pstrUnQuotedVal)
{
*pstrUnQuotedVal = _T("");
}
return FALSE;
}
BOOL CXTPSyntaxEditLexClass::IsVar(CString strValue, CString* pstrVarVal)
{
CString strTmp = strValue;
strTmp.TrimLeft();
strTmp.TrimRight();
int nLen = strTmp.GetLength();
if (nLen >= 2)
{
if (strTmp[0] == _T('@'))
{
if (pstrVarVal)
{
*pstrVarVal = strTmp;
}
return TRUE;
}
}
if (pstrVarVal)
{
*pstrVarVal = _T("");
}
return FALSE;
}
BOOL CXTPSyntaxEditLexClass::SetProp_ProcessSpecials(const XTP_EDIT_LEXPROPINFO* pPropDesc,
BOOL& rbProcessed)
{
rbProcessed = FALSE;
if (!pPropDesc || pPropDesc->arPropName.GetSize() < 1)
{
ASSERT(FALSE);
return FALSE;
}
int nNCount = (int)pPropDesc->arPropName.GetSize();
CString strMainName = pPropDesc->arPropName[0];
if (strMainName.CompareNoCase(_T("parent")) == 0)
{
if (nNCount == 1)
{
m_Parent.eOpt = xtpEditOptParent_direct;
}
else
{
ASSERT(nNCount == 2);
CString strName2 = pPropDesc->arPropName[1];
if (strName2.CompareNoCase(_T("file")) == 0)
{
m_Parent.eOpt = xtpEditOptParent_file;
}
else if (strName2.CompareNoCase(_T("dyn")) == 0)
{
m_Parent.eOpt = xtpEditOptParent_dyn;
}
else //if (strName2.CompareNoCase(_T("Override")) == 0)
{
ASSERT(FALSE);
return FALSE;
}
}
m_Parent.arClassNames.Append(pPropDesc->arPropValue);
rbProcessed = TRUE;
}
else if (strMainName.CompareNoCase(_T("children")) == 0)
{
int nValCount = (int)pPropDesc->arPropValue.GetSize();
if (nValCount == 0)
{
m_Children.eOpt = xtpEditOptChildren_No;
TRACE_ASSERT(m_Children.arClassNames.GetSize() == 0);
//TRACE(_T(""));
}
else
{
CString strVal0 = pPropDesc->arPropValue[0];
strVal0.TrimLeft();
strVal0.TrimRight();
if (strVal0 == _T("0"))
{
m_Children.eOpt = xtpEditOptChildren_No;
TRACE_ASSERT(m_Children.arClassNames.GetSize() == 0);
}
else
{
TRACE_ASSERT(m_Children.arClassNames.GetSize() == 0 &&
m_Children.eOpt == xtpEditOptChildren_Unknown ||
m_Children.eOpt == xtpEditOptChildren_List);
m_Children.eOpt = xtpEditOptChildren_List;
m_Children.arClassNames.Append(pPropDesc->arPropValue);
}
}
rbProcessed = TRUE;
}
return TRUE;
}
BOOL CXTPSyntaxEditLexClass::SetProp_ProcessAttributes(const XTP_EDIT_LEXPROPINFO* pPropDesc,
BOOL& rbProcessed)
{
rbProcessed = FALSE;
if (!pPropDesc || pPropDesc->arPropName.GetSize() < 1)
{
ASSERT(FALSE);
return FALSE;
}
//-----------------------------------------------------------------------
CString strFullName = MakeStr(pPropDesc->arPropName, _T(":"));
strFullName.MakeLower();
BOOL bKnown = FALSE;
for (int i = 0; i < _countof(g_arKnownLexClassAttribs); i++)
{
if (strFullName.CompareNoCase(g_arKnownLexClassAttribs[i]) == 0)
{
bKnown = TRUE;
break;
}
}
if (!bKnown)
{
TRACE(_T("WARNING! Unknown attribute '%s'. \n"), (LPCTSTR)strFullName);
//return TRUE;
}
//===========================================================================
CXTPSyntaxEditLexVariantPtr ptrLvData = new CXTPSyntaxEditLexVariant();
if (!ptrLvData)
{
return FALSE;
}
//---------------------------------------------------------------------------
int nPCount = (int)pPropDesc->arPropValue.GetSize();
if (nPCount == 1)
{
CString strVal = pPropDesc->arPropValue[0];
CString strVal2;
if (IsQuoted(strVal, &strVal2))
{
*ptrLvData = CXTPSyntaxEditLexVariant(strVal2);
}
else if (strFullName == _T("end:class:parent"))
{
*ptrLvData = CXTPSyntaxEditLexVariant(&pPropDesc->arPropValue);
}
else
{
static const int c_nClrPrefLen = (int)_tcsclen(XTPLEX_ATTR_COLORPREFIX);
TCHAR* pCh = NULL;
int nValue = _tcstol(strVal, &pCh, 0);
if (_tcsnicmp(strFullName, XTPLEX_ATTR_COLORPREFIX, c_nClrPrefLen) == 0)
{
nValue = XTP_EDIT_RGB_INT2CLR(nValue);
}
*ptrLvData = nValue;
}
m_mapAttributes[strFullName] = ptrLvData;
}
else if (nPCount > 1)
{
*ptrLvData = CXTPSyntaxEditLexVariant(&pPropDesc->arPropValue);
m_mapAttributes[strFullName] = ptrLvData;
}
else
{
//TRACE
TRACE(_T("ERROR! There is not values present for attribute '%s' \n"), (LPCTSTR)strFullName);
}
rbProcessed = TRUE;
//-----------------------------------------------------------------------
return TRUE;
}
void CXTPSyntaxEditLexClass::SortTags()
{
BOOL bAsc = FALSE;
BOOL bNoCase = !IsCaseSensitive();
SortTagsInLexVarArray(m_previous.m_tag, bAsc, bNoCase);
SortTagsInLexVarArray(m_previous.m_tag_separators, bAsc, bNoCase);
SortTagsInLexVarArray(m_start.m_tag, bAsc, bNoCase);
SortTagsInLexVarArray(m_end.m_tag, bAsc, bNoCase);
SortTagsInLexVarArray(m_end.m_separators, bAsc, bNoCase);
SortTagsInLexVarArray(m_token.m_tag, bAsc, bNoCase);
SortTagsInLexVarArray(m_token.m_start_separators, bAsc, bNoCase);
SortTagsInLexVarArray(m_token.m_end_separators, bAsc, bNoCase);
SortTagsInLexVarArray(m_skip.m_tag, bAsc, bNoCase);
bAsc = TRUE;
SortTagsInLexVarArray(m_ActiveTags, bAsc, bNoCase);
//m_ActiveTags.BuildAutomat(TRUE);
}
BOOL CXTPSyntaxEditLexClass::IsCaseSensitive()
{
if (m_bCaseSensitive_Cached < 0)
{
m_bCaseSensitive_Cached = FALSE;
CXTPSyntaxEditLexVariantPtr ptrCase = GetAttribute(XTPLEX_ATTR_CASESENSITIVE, TRUE);
if (ptrCase && ptrCase->m_nObjType == xtpEditLVT_valInt)
{
m_bCaseSensitive_Cached = ptrCase->m_nValue > 0;
}
}
return m_bCaseSensitive_Cached;
}
int CXTPSyntaxEditLexClass::IsCollapsable()
{
if (m_nCollapsable_Cached < 0)
{
m_nCollapsable_Cached = FALSE;
CXTPSyntaxEditLexVariantPtr ptrLV = GetAttribute(XTPLEX_ATTR_COLLAPSABLE, FALSE);
if (ptrLV && ptrLV->m_nObjType == xtpEditLVT_valInt)
{
m_nCollapsable_Cached = ptrLV->m_nValue;// > 0;
}
}
return m_nCollapsable_Cached;
}
BOOL CXTPSyntaxEditLexClass::IsEndClassParent_this()
{
if (m_bEndClassParent_this_Cached < 0)
{
m_bEndClassParent_this_Cached = FALSE;
CXTPSyntaxEditLexVariantPtr ptrAttrVal = GetAttribute(XTPLEX_ATTR_ENDCLASSPARENT, FALSE);
ASSERT(!ptrAttrVal || ptrAttrVal && ptrAttrVal->m_nObjType == xtpEditLVT_valStr);
if (ptrAttrVal && ptrAttrVal->m_nObjType == xtpEditLVT_valStr)
{
m_bEndClassParent_this_Cached = Find_noCase(ptrAttrVal->m_arStrVals, _T("this")) >= 0;
}
}
return m_bEndClassParent_this_Cached;
}
BOOL CXTPSyntaxEditLexClass::StrCmpEQ(LPCTSTR pcszStr1, LPCTSTR pcszStr2, int nLen,
BOOL bCaseSensitive,
BOOL bParseDirection_Back)
{
int nRes = 0;
if (bParseDirection_Back)
{
for (int i = 0; i < nLen; i++)
{
nRes = StrCmp(pcszStr1, pcszStr2, 1, bCaseSensitive);
if (nRes)
{
break;
}
if (*pcszStr1 == 0 || *pcszStr2 == 0)
{
break;
}
if (i+1 < nLen)
{
pcszStr1 = _tcsdec(pcszStr1-2, pcszStr1);
pcszStr2 = _tcsdec(pcszStr2-2, pcszStr2);
}
}
}
else
{
nRes = StrCmp(pcszStr1, pcszStr2, nLen, bCaseSensitive);
}
return nRes == 0;
}
BOOL CXTPSyntaxEditLexClass::StrVarCmpEQ(LPCTSTR pcszStr,
const CXTPSyntaxEditLexVariable& lexVar,
CString& rstrValue, BOOL bParseDirection_Back)
{
UNREFERENCED_PARAMETER(bParseDirection_Back);
BOOL bRes = FALSE;
TCHAR chChar = *pcszStr;
if (lexVar.m_nVarID == CXTPSyntaxEditLexVariable::xtpEditVarID_alpha) //a-z, A-Z
{
bRes = chChar >= _T('a') && chChar <= _T('z') ||
chChar >= _T('A') && chChar <= _T('Z');
}
else if (lexVar.m_nVarID == CXTPSyntaxEditLexVariable::xtpEditVarID_digit) // 0-9
{
bRes = chChar >= _T('0') && chChar <= _T('9');
}
else if (lexVar.m_nVarID == CXTPSyntaxEditLexVariable::xtpEditVarID_HexDigit) // 0-9, a-f, A-F
{
bRes = chChar >= _T('0') && chChar <= _T('9') ||
chChar >= _T('a') && chChar <= _T('f') ||
chChar >= _T('A') && chChar <= _T('F');
}
else if (lexVar.m_nVarID == CXTPSyntaxEditLexVariable::xtpEditVarID_specs)
{
TCHAR* pF = _tcschr((TCHAR*)cszSpecs, chChar);
bRes = (pF != NULL);
}
// @EOL
else if (lexVar.m_nVarID == CXTPSyntaxEditLexVariable::xtpEditVarID_EOL)
{
bRes = chChar == _T('\r') || chChar == _T('\n');
}
else
{
ASSERT(FALSE);
TRACE(_T("ERROR! Unknown lexVariable '%s' \n"), (LPCTSTR)lexVar.m_strVar);
return FALSE;
}
if (lexVar.m_nVarFlags & CXTPSyntaxEditLexVariable::xtpEditVarfNot)
{
bRes = !bRes;
}
if (bRes)
{
rstrValue = chChar;
}
return bRes;
}
CXTPSyntaxEditLexClassPtrArray* CXTPSyntaxEditLexClass::GetChildren()
{
return &m_arChildrenClasses;
}
CXTPSyntaxEditLexClassPtrArray* CXTPSyntaxEditLexClass::GetChildrenDyn()
{
return &m_arDynChildrenClasses;
}
CXTPSyntaxEditLexClassPtrArray* CXTPSyntaxEditLexClass::GetChildrenSelfRef()
{
return &m_arChildrenSelfRefClasses;
}
BOOL CXTPSyntaxEditLexClass::AddChild(CXTPSyntaxEditLexClass* pChild, BOOL bDyn)
{
if (!pChild)
{
ASSERT(FALSE);
return FALSE;
}
CXTPSyntaxEditLexClassPtr ptrC(pChild, TRUE);
if (pChild == this)
{
int nCount = (int)m_arChildrenSelfRefClasses.GetSize();
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrCSelf = m_arChildrenSelfRefClasses[i];
if (ptrC == ptrCSelf )
{
return FALSE;
}
}
m_arChildrenSelfRefClasses.Add(ptrC);
return TRUE;
}
pChild->m_Parent.ptrDirect.SetPtr(this, TRUE);
if (bDyn)
{
m_arDynChildrenClasses.Add(ptrC);
}
else
{
m_arChildrenClasses.Add(ptrC);
}
return TRUE;
}
void CXTPSyntaxEditLexClass::GetParentOpt(int& rnOpt, CStringArray& rArData) const
{
rnOpt = m_Parent.eOpt;
rArData.RemoveAll();
rArData.Append(m_Parent.arClassNames);
}
void CXTPSyntaxEditLexClass::GetChildrenOpt(int& rnOpt, CStringArray& rArData) const
{
rnOpt = m_Children.eOpt;
rArData.RemoveAll();
rArData.Append(m_Children.arClassNames);
}
CXTPSyntaxEditLexClass* CXTPSyntaxEditLexClass::FindParent(LPCTSTR pcszClassName)
{
if (!m_Parent.ptrDirect)
{
return NULL;
}
CString strParent = m_Parent.ptrDirect->GetClassName();
if (strParent.CompareNoCase(pcszClassName) == 0)
{
return m_Parent.ptrDirect;
}
return m_Parent.ptrDirect->FindParent(pcszClassName);
}
int CXTPSyntaxEditLexClass::RunParse(CTextIter* pTxtIter,
CXTPSyntaxEditLexTextSchema* pTxtSch,
CXTPSyntaxEditLexTextBlockPtr& rPtrTxtBlock,
CXTPSyntaxEditLexOnScreenParseCnt* pOnScreenRunCnt
)
{
if (!pTxtIter || !pTxtSch)
{
ASSERT(FALSE);
//TRACE
return xtpEditLPR_Error | xtpEditLPR_Iterated;
}
if (!m_token.IsEmpty() && (!m_start.IsEmpty() || !m_end.IsEmpty()) )
{
TRACE(_T("WARNING: Start/End and Token options cannot be used together! '%s' \n"), (LPCTSTR)m_strClassName);
}
int nParseRes = 0;
BOOL bStarted = (rPtrTxtBlock != NULL);
BOOL bPrevCondition = TRUE;
//===========================================================================
if (!bStarted)
{
if (!m_previous.IsEmpty())
{
bPrevCondition = Run_Previous(pTxtIter, pTxtSch, rPtrTxtBlock,
pOnScreenRunCnt);
}
//===========================================================================
if (!m_start.IsEmpty())
{
if (bPrevCondition && !bStarted )
{
int nResStart = Run_Start(pTxtIter, pTxtSch, rPtrTxtBlock,
pOnScreenRunCnt);
bStarted = nResStart & xtpEditLPR_StartFound;
nParseRes |= nResStart;
return nParseRes;
}
}
else if (bPrevCondition)
{
if (!m_token.IsEmpty())
{
int nResToken = Run_Token(pTxtIter, pTxtSch, rPtrTxtBlock);
BOOL bEnded = nResToken & xtpEditLPR_EndFound;
nParseRes |= nResToken;
if (nParseRes & xtpEditLPR_Error)
{
return nParseRes;
}
//---------------------------------------------------------------------------
if (bEnded)
{
return nParseRes;
}
}
else
{
bStarted = TRUE;
nParseRes |= xtpEditLPR_StartFound|xtpEditLPR_Iterated;
rPtrTxtBlock = pTxtSch->GetNewBlock();
if (rPtrTxtBlock)
{
rPtrTxtBlock->m_ptrLexClass.SetPtr(this, TRUE);
rPtrTxtBlock->m_PosStartLC = pTxtIter->GetPosLC();
rPtrTxtBlock->m_nStartTagLen = 0;
}
else
{
nParseRes |= xtpEditLPR_Error;
}
return nParseRes;
}
}
} // if (!bStarted)
//---------------------------------------------------------------------------
if (!bStarted)
{
return 0;
}
//===========================================================================
if (!m_skip.IsEmpty())
{
int nResSkip = Run_Skip(pTxtIter, pTxtSch, rPtrTxtBlock);
nParseRes |= nResSkip;
if (nParseRes & xtpEditLPR_Error)
{
return nParseRes;
}
}
//===========================================================================
if (!m_end.IsEmpty())
{
int nResEnd = Run_End(pTxtIter, pTxtSch, rPtrTxtBlock, pOnScreenRunCnt);
BOOL bEnded = nResEnd & xtpEditLPR_EndFound;
nParseRes |= nResEnd;
if (nParseRes & xtpEditLPR_Error)
{
return nParseRes;
}
//---------------------------------------------------------------------------
if (bEnded)
{
return nParseRes;
}
}
//===========================================================================
// *** run childs ***
int nChildsCount = (int)m_arChildrenClasses.GetSize() +
(int)m_arDynChildrenClasses.GetSize() +
(int)m_arChildrenSelfRefClasses.GetSize();
if (nChildsCount)
{
int nCHres = pTxtSch->RunChildren(pTxtIter, rPtrTxtBlock, this, pOnScreenRunCnt);
nParseRes |= ~(xtpEditLPR_StartFound|xtpEditLPR_EndFound) & nCHres;
if (nParseRes & (xtpEditLPR_Error|xtpEditLPR_RunBreaked|xtpEditLPR_RunFinished))
{
return nParseRes;
}
//---------------------------------------------------------------------------
int nResEnd = Run_End(pTxtIter, pTxtSch, rPtrTxtBlock, pOnScreenRunCnt);
nParseRes |= nResEnd;
}
return nParseRes;
}
BOOL CXTPSyntaxEditLexClass::Run_Previous(CTextIter* pTxtIter,
CXTPSyntaxEditLexTextSchema* pTxtSch,
CXTPSyntaxEditLexTextBlockPtr& rPtrTxtBlock,
CXTPSyntaxEditLexOnScreenParseCnt* pOnScreenRunCnt)
{
UNREFERENCED_PARAMETER(rPtrTxtBlock);
BOOL bRes_Class = TRUE, bRes_Tag = TRUE;
//=======================================================================
if (!m_previous.m_class.IsEmpty())
{
bRes_Class = Run_PrevClass(NULL, pTxtSch, &m_previous.m_class,
c_nPrevClassDepth_default, NULL,
NULL, pOnScreenRunCnt);
if (!bRes_Class)
{
return FALSE;
}
}
//=======================================================================
if (!m_previous.m_tag.IsEmpty())
{
bRes_Tag = FALSE;
if (!m_previous.m_tag_separators.IsEmpty())
{
int nMaxBackOffset = pTxtIter->GetMaxBackOffset();
BOOL bContinue = TRUE;
int nOffset;
for (nOffset = 0; bContinue && labs(nOffset) < nMaxBackOffset; nOffset--)
{
CString strSep;
bContinue = Run_Tags(pTxtIter, pTxtSch, &m_previous.m_tag_separators,
strSep, TRUE);
if (bContinue)
{
pTxtIter->SetTxtOffset(nOffset-1);
}
}
ASSERT(labs(nOffset) < nMaxBackOffset);
}
CString strTag;
bRes_Tag = Run_Tags(pTxtIter, pTxtSch, &m_previous.m_tag, strTag, TRUE);
pTxtIter->SetTxtOffset(0);
}
return bRes_Class && bRes_Tag;
}
BOOL CXTPSyntaxEditLexClass::Run_PrevClass(CXTPSyntaxEditLexTextBlock** ppPrevTB,
CXTPSyntaxEditLexTextSchema* pTxtSch,
CXTPSyntaxEditLexVariantPtrArray* pLVPrevClasses,
int nDepth, XTP_EDIT_LINECOL* pMinPrevPos,
CXTPSyntaxEditLexTextBlock* pPrevForParentBlockOnly,
CXTPSyntaxEditLexOnScreenParseCnt* pOnScreenRunCnt)
{
if (ppPrevTB)
{
*ppPrevTB = NULL;
}
CXTPSyntaxEditLexTextBlock* pTBprev = NULL;
if (pOnScreenRunCnt)
{
pTBprev = pOnScreenRunCnt->m_ptrTBLast;
}
else
{
pTBprev = pTxtSch->GetPrevBlock(FALSE);
}
if (!pLVPrevClasses || !pTBprev || !pTBprev->m_ptrLexClass)
{
return FALSE;
}
if (pPrevForParentBlockOnly && pPrevForParentBlockOnly != pTBprev->m_ptrParent)
{
return FALSE;
}
//=======================================================================
for (int nD = 0;
pTBprev && pTBprev->m_ptrLexClass &&
(!pMinPrevPos || pTBprev->m_PosStartLC >= *pMinPrevPos) &&
nD < nDepth;
nD++, pTBprev = pTBprev->m_ptrPrev)
{
const CString& strPrevClassName = pTBprev->m_ptrLexClass->m_strClassName;
int nPCCont1 = (int)pLVPrevClasses->GetSize();
for (int i = 0; i < nPCCont1; i++)
{
CXTPSyntaxEditLexVariant* pVarPrevC = pLVPrevClasses->GetAt(i, FALSE);
if (!pVarPrevC || !pVarPrevC->IsStrType())
{
ASSERT(FALSE);
continue;
}
ASSERT(pVarPrevC->m_nObjType == xtpEditLVT_className);
int nCCount2 = (int)pVarPrevC->m_arStrVals.GetSize();
for (int k = 0; k < nCCount2; k++)
{
const CString& strCName = pVarPrevC->m_arStrVals[k];
if (strPrevClassName.CompareNoCase(strCName) == 0)
{
if (ppPrevTB)
{
*ppPrevTB = pTBprev;
}
return TRUE;
}
}
}
}
return FALSE;
}
int CXTPSyntaxEditLexClass::Run_Start(CTextIter* pTxtIter,
CXTPSyntaxEditLexTextSchema* pTxtSch,
CXTPSyntaxEditLexTextBlockPtr& rPtrTxtBlock,
CXTPSyntaxEditLexOnScreenParseCnt* pOnScreenRunCnt
)
{
if (!pTxtIter || !pTxtSch)
{
ASSERT(FALSE);
//TRACE
return xtpEditLPR_Error;
}
BOOL bStarted = (rPtrTxtBlock != NULL);
ASSERT(!bStarted);
if (bStarted || m_start.IsEmpty())
{
return 0;
}
//===========================================================================
BOOL bRes_Class = TRUE;
CXTPSyntaxEditLexTextBlock* pPrevClass = NULL;
if (!m_start.m_class.IsEmpty())
{
bRes_Class = Run_PrevClass(&pPrevClass, pTxtSch, &m_start.m_class,
c_nPrevClassDepth_default, NULL, NULL, pOnScreenRunCnt);
if (!bRes_Class)
{
return 0;
}
}
//===========================================================================
BOOL bRes_Tag = TRUE;
CString strTagVal;
BOOL bTag_Empty = m_start.m_tag.IsEmpty();
if (!bTag_Empty)
{
bRes_Tag = Run_Tags(pTxtIter, pTxtSch, &m_start.m_tag, strTagVal);
if (!bRes_Tag)
{
return 0;
}
}
bStarted = bRes_Class && bRes_Tag;
int nRes = 0;
if (bStarted)
{
nRes |= xtpEditLPR_StartFound;
if (!m_start.m_class.IsEmpty() && pPrevClass && pPrevClass->m_ptrLexClass &&
m_Parent.ptrDirect )
{
CString strC0 = m_Parent.ptrDirect->GetClassName();
CString strC1 = pPrevClass->m_ptrLexClass->GetClassName();
if (strC0.CompareNoCase(strC1) != 0)
{
nRes |= xtpEditLPR_TBpop1;
}
}
rPtrTxtBlock = pTxtSch->GetNewBlock();
if (rPtrTxtBlock)
{
rPtrTxtBlock->m_ptrLexClass = this;
rPtrTxtBlock->m_ptrLexClass->InternalAddRef();
if (bRes_Tag && !bTag_Empty)
{
int nLenC = (int)_tcsclen(strTagVal);
ASSERT(nLenC);
rPtrTxtBlock->m_PosStartLC = pTxtIter->GetPosLC();
rPtrTxtBlock->m_nStartTagLen = nLenC;
pTxtIter->SeekNext(nLenC);
nRes |= xtpEditLPR_Iterated;
}
else
{
CSingleLock singleLock(pTxtSch->GetDataLoker(), TRUE);
ASSERT(pPrevClass);
if (pPrevClass)
{
rPtrTxtBlock->m_PosStartLC = pPrevClass->m_PosStartLC;
rPtrTxtBlock->m_nStartTagLen = pPrevClass->m_nStartTagLen;
}
}
}
if (!rPtrTxtBlock)
{
return xtpEditLPR_Error | nRes;
}
}
//---------------------------------------------------------------------------
return nRes;
}
int CXTPSyntaxEditLexClass::Run_Skip(CTextIter* pTxtIter,
CXTPSyntaxEditLexTextSchema* pTxtSch,
CXTPSyntaxEditLexTextBlockPtr& rPtrTxtBlock
)
{
if (!pTxtIter || !pTxtSch)
{
ASSERT(FALSE);
//TRACE
return xtpEditLPR_Error;
}
BOOL bStarted = (rPtrTxtBlock != NULL);
ASSERT(bStarted);
if (!bStarted || m_skip.IsEmpty())
{
return 0;
}
//===========================================================================
CString strTagVal;
if (!m_skip.m_tag.IsEmpty())
{
BOOL bIterated = FALSE;
while (!pTxtIter->IsEOF() && Run_Tags(pTxtIter, pTxtSch, &m_skip.m_tag, strTagVal))
{
int nLen = strTagVal.GetLength();
pTxtIter->SeekNext(nLen);
bIterated = TRUE;
}
if (bIterated)
{
return xtpEditLPR_Iterated;
}
}
return 0;
}
int CXTPSyntaxEditLexClass::Run_End(CTextIter* pTxtIter,
CXTPSyntaxEditLexTextSchema* pTxtSch,
CXTPSyntaxEditLexTextBlockPtr& rPtrTxtBlock,
CXTPSyntaxEditLexOnScreenParseCnt* pOnScreenRunCnt)
{
if (!pTxtIter || !pTxtSch)
{
ASSERT(FALSE);
//TRACE
return xtpEditLPR_Error;
}
BOOL bEnded = FALSE;
if (m_end.IsEmpty())
{
return 0;
}
ASSERT(rPtrTxtBlock);
//===========================================================================
BOOL bRes_Class = TRUE;
CXTPSyntaxEditLexTextBlock* pPrevClass = NULL;
if (!m_end.m_class.IsEmpty())
{
CXTPSyntaxEditLexTextBlock* pTBEndParent = IsEndClassParent_this() ? rPtrTxtBlock : NULL;
bRes_Class = Run_PrevClass(&pPrevClass, pTxtSch, &m_end.m_class,
c_nPrevClassDepth_default, &rPtrTxtBlock->m_PosStartLC,
pTBEndParent, pOnScreenRunCnt);
if (!bRes_Class)
{
return 0;
}
}
//===========================================================================
BOOL bRes_Tag = TRUE;
CString strTagVal;
int nTagLenC = 0;
if (!m_end.m_tag.IsEmpty())
{
bRes_Tag = Run_Tags(pTxtIter, pTxtSch, &m_end.m_tag, strTagVal);
if (!bRes_Tag)
{
return 0;
}
nTagLenC = (int)_tcsclen(strTagVal);
}
//===========================================================================
BOOL bRes_Separators = TRUE;
CString strSepVal;
if (!m_end.m_separators.IsEmpty())
{
pTxtIter->SetTxtOffset(nTagLenC);
bRes_Separators = Run_Tags(pTxtIter, pTxtSch, &m_end.m_separators, strSepVal);
pTxtIter->SetTxtOffset(0);
if (!bRes_Separators)
{
return 0;
}
}
//-----------------------------------------------------------------------
bEnded = bRes_Class && bRes_Tag && bRes_Separators;
int nRes = 0;
if (bEnded)
{
nRes |= xtpEditLPR_EndFound;
nRes |= xtpEditLPR_Iterated;
if (bRes_Tag && !m_end.m_tag.IsEmpty() ||
bRes_Separators && !m_end.m_separators.IsEmpty())
{
CSingleLock singleLock(pTxtSch->GetDataLoker(), TRUE);
XTP_EDIT_LINECOL runLC = pTxtIter->GetPosLC();
if (bRes_Tag && !m_end.m_tag.IsEmpty())
{
pTxtIter->SeekNext(nTagLenC);
}
ASSERT(this == (CXTPSyntaxEditLexClass*)rPtrTxtBlock->m_ptrLexClass);
rPtrTxtBlock->m_PosEndLC = pTxtIter->GetPosLC();
const XTP_EDIT_LINECOL beginLC = {1, 0};
if (rPtrTxtBlock->m_PosEndLC > beginLC)
{
pTxtIter->LCPosDec(rPtrTxtBlock->m_PosEndLC);
}
else
{
TRACE(_T("WARNING (parser): unexpected end position (1, 0) \n"));
}
if (bRes_Separators && !m_end.m_separators.IsEmpty())
{
int nSepLenC = (int)_tcsclen(strSepVal);
XTP_EDIT_LINECOL endLC2 = rPtrTxtBlock->m_PosEndLC;
pTxtIter->LCPosAdd(endLC2, nTagLenC+nSepLenC);
rPtrTxtBlock->m_nEndTagXLCLen = rPtrTxtBlock->m_PosEndLC.GetXLC() -
endLC2.GetXLC();
}
else
{
rPtrTxtBlock->m_nEndTagXLCLen = rPtrTxtBlock->m_PosEndLC.GetXLC() -
runLC.GetXLC();
}
}
else
{
CSingleLock singleLock(pTxtSch->GetDataLoker(), TRUE);
ASSERT(pPrevClass);
if (pPrevClass)
{
rPtrTxtBlock->m_PosEndLC = pPrevClass->m_PosEndLC;
rPtrTxtBlock->m_nEndTagXLCLen = pPrevClass->m_nEndTagXLCLen;
}
}
}
//---------------------------------------------------------------------------
return nRes;
}
int CXTPSyntaxEditLexClass::Run_Token(CTextIter* pTxtIter,
CXTPSyntaxEditLexTextSchema* pTxtSch,
CXTPSyntaxEditLexTextBlockPtr& rPtrTxtBlock )
{
if (!pTxtIter || !pTxtSch)
{
ASSERT(FALSE);
//TRACE
return xtpEditLPR_Error;
}
//===========================================================================
if (!m_token.m_tag.IsEmpty())
{
CString strTokenVal;
//if (Run_Tags(pTxtIter, pTxtSch, &m_token.m_tag, strTokenVal))
//BOOL bTagBegins = Run_Tags(pTxtIter, pTxtSch, &m_token.m_tag, strTokenVal);
BOOL bTagBegins = m_token.m_tag.FindMaxWord(pTxtIter->GetText(1024),
strTokenVal, 1024, FALSE, !IsCaseSensitive());
#ifdef DBG_AUTOMAT
BOOL bTagBeginsX = Run_Tags(pTxtIter, pTxtSch, &m_token.m_tag, strTokenVal);
if (bTagBeginsX != bTagBegins)
{
ASSERT(FALSE);
}
#endif
if (bTagBegins)
{
CString strSeparator1, strSeparator2;
if (Run_TokenSeparators(strTokenVal, pTxtIter, pTxtSch,
strSeparator1, strSeparator2) )
{
int nLenC = (int)_tcsclen(strTokenVal);
rPtrTxtBlock = pTxtSch->GetNewBlock();
if (rPtrTxtBlock)
{
rPtrTxtBlock->m_ptrLexClass.SetPtr(this, TRUE);
rPtrTxtBlock->m_PosStartLC = pTxtIter->GetPosLC();
rPtrTxtBlock->m_nStartTagLen = nLenC;
}
pTxtIter->SeekNext(nLenC);
int nRes = xtpEditLPR_StartFound | xtpEditLPR_EndFound | xtpEditLPR_Iterated;
if (rPtrTxtBlock)
{
rPtrTxtBlock->m_PosEndLC = pTxtIter->GetPosLC();
if (nLenC)
{
pTxtIter->LCPosDec(rPtrTxtBlock->m_PosEndLC);
}
rPtrTxtBlock->m_nEndTagXLCLen = rPtrTxtBlock->m_PosEndLC.GetXLC() -
rPtrTxtBlock->m_PosStartLC.GetXLC();
}
else
{
nRes |= xtpEditLPR_Error;
}
return nRes;
}
}
}
return 0;
}
BOOL CXTPSyntaxEditLexClass::Run_TokenSeparators(CString strToken,
CTextIter* pTxtIter,
CXTPSyntaxEditLexTextSchema* pTxtSch,
CString& rstrSeparator1,
CString& rstrSeparator2)
{
rstrSeparator1.Empty();
rstrSeparator2.Empty();
//===========================================================================
BOOL bTSyes = TRUE;
BOOL bTEyes = TRUE;
if (!m_token.m_start_separators.IsEmpty())
{
bTSyes = Run_Tags(pTxtIter, pTxtSch, &m_token.m_start_separators, rstrSeparator1, TRUE);
}
if (!m_token.m_end_separators.IsEmpty())
{
int nLen = strToken.GetLength();
pTxtIter->SetTxtOffset(nLen);
bTEyes = Run_Tags(pTxtIter, pTxtSch, &m_token.m_end_separators, rstrSeparator2);
pTxtIter->SetTxtOffset(0);
}
return bTSyes && bTEyes;
}
BOOL CXTPSyntaxEditLexClass::Run_Tags(CTextIter* pIter,
CXTPSyntaxEditLexTextSchema* pTxtSch,
CXTPSyntaxEditLexVariantPtrArray* pLVTags,
CString& rstrTagVal, BOOL bParseDirection_Back
)
{
UNREFERENCED_PARAMETER(pTxtSch);
BOOL bCaseSensitive = IsCaseSensitive();
return Run_Tags1(pIter, pLVTags, rstrTagVal, bCaseSensitive, bParseDirection_Back);
}
BOOL CXTPSyntaxEditLexClass::Run_Tags1(CTextIter* pIter,
CXTPSyntaxEditLexVariantPtrArray* pLVTags,
CString& rstrTagVal, BOOL bCaseSensitive,
BOOL bParseDirection_Back
)
{
if (!pLVTags)
{
ASSERT(FALSE);
return FALSE;
}
int nCount = (int)pLVTags->GetSize();
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexVariant* pVTag = pLVTags->GetAt(i, FALSE);
if (Run_Tags2(pIter, pVTag, rstrTagVal, bCaseSensitive, bParseDirection_Back) )
{
return TRUE;
}
}
return FALSE;
}
int CXTPSyntaxEditLexClass::Run_Tags2(CTextIter* pIter,
CXTPSyntaxEditLexVariant* pVTags,
CString& rstrTagVal,
BOOL bCaseSensitive,
BOOL bParseDirection_Back
)
{
LPCTSTR pText = pIter->GetText();
if (!pVTags)
{
ASSERT(FALSE);
//TRACE
return 0;
}
if (pVTags->m_nObjType == xtpEditLVT_valStr)
{
if (bParseDirection_Back)
{
pText = _tcsdec(pText-5, pText);
}
for (int k = 0; k < pVTags->m_arStrVals.GetSize(); k++)
{
LPCTSTR pcszTag = pVTags->m_arStrVals[k];
int nLen = (int)_tcsclen(pcszTag);
if (nLen <= 0)
{
ASSERT(FALSE);
continue;
}
if (bParseDirection_Back)
{
pcszTag = _tcsninc(pcszTag, nLen-1);
}
if (StrCmpEQ(pcszTag, pText, nLen, bCaseSensitive, bParseDirection_Back))
{
rstrTagVal = pcszTag;
return TRUE;
}
}
return FALSE;
}
else if (pVTags->m_nObjType == xtpEditLVT_valVar)
{
if (bParseDirection_Back)
{
pText = _tcsdec(pText-5, pText);
}
if (StrVarCmpEQ(pText, pVTags->m_Variable, rstrTagVal, bParseDirection_Back))
{
return TRUE;
}
return FALSE;
}
else
{
ASSERT(FALSE);
//TRACE
}
return FALSE;
}
void CXTPSyntaxEditLexClass::CopyFrom(const CXTPSyntaxEditLexClass* pSrc)
{
if (!pSrc)
{
ASSERT(FALSE);
return;
}
m_Parent.eOpt = pSrc->m_Parent.eOpt;
m_Parent.ptrDirect = pSrc->m_Parent.ptrDirect;
m_Parent.arClassNames.RemoveAll();
m_Parent.arClassNames.Append(pSrc->m_Parent.arClassNames);
m_Children.eOpt = pSrc->m_Children.eOpt;
m_Children.arClassNames.RemoveAll();
m_Children.arClassNames.Append(pSrc->m_Children.arClassNames);
m_strClassName = pSrc->GetClassName();
TBase::CopyFrom(*pSrc);
CopyAttributes(pSrc);
m_arChildrenClasses.RemoveAll();
m_arDynChildrenClasses.RemoveAll();
m_arChildrenSelfRefClasses.RemoveAll();
}
const CXTPSyntaxEditLexClass& CXTPSyntaxEditLexClass::operator=(const CXTPSyntaxEditLexClass& rSrc)
{
CopyFrom(&rSrc);
return *this;
}
CXTPSyntaxEditLexClass* CXTPSyntaxEditLexClass::Clone(CXTPSyntaxEditLexClassSchema* pOwnerSch)
{
CXTPSyntaxEditLexClass* pNewClass = NULL;
if (pOwnerSch)
{
pNewClass = pOwnerSch->GetNewClass(FALSE);
}
else
{
pNewClass = new CXTPSyntaxEditLexClass();
}
if (pNewClass)
{
pNewClass->CopyFrom(this);
}
return pNewClass;
}
void CXTPSyntaxEditLexClass::RemoveAttributes(LPCTSTR pcszAttrPrefix)
{
ClearAttributesCache();
if (pcszAttrPrefix)
{
int nLenC = (int)_tcsclen(pcszAttrPrefix);
CString strKey;
CStringArray arKeysToRemove;
POSITION pos = m_mapAttributes.GetStartPosition();
while (pos)
{
CXTPSyntaxEditLexVariantPtr ptrVal;
m_mapAttributes.GetNextAssoc(pos, strKey, ptrVal);
if (_tcsnicmp(pcszAttrPrefix, strKey, nLenC) == 0)
{
arKeysToRemove.Add(strKey);
}
}
//-----------------------------------------
int nCount = (int)arKeysToRemove.GetSize();
for (int i = 0; i < nCount; i++)
{
strKey = arKeysToRemove[i];
m_mapAttributes.RemoveKey(strKey);
}
}
else
{
m_mapAttributes.RemoveAll();
}
}
void CXTPSyntaxEditLexClass::CopyAttributes(const CXTPSyntaxEditLexClass* pSrcAttrClass,
LPCTSTR pcszAttrPrefix)
{
RemoveAttributes(pcszAttrPrefix);
if (!pSrcAttrClass)
{
ASSERT(FALSE);
return;
}
int nLenC = pcszAttrPrefix ? (int)(_tcsclen(pcszAttrPrefix)) : 0;
CString strKey;
POSITION pos = pSrcAttrClass->m_mapAttributes.GetStartPosition();
while (pos)
{
CXTPSyntaxEditLexVariantPtr ptrVal;
pSrcAttrClass->m_mapAttributes.GetNextAssoc(pos, strKey, ptrVal);
if (pcszAttrPrefix)
{
if (_tcsnicmp(pcszAttrPrefix, strKey, nLenC) == 0)
{
m_mapAttributes[strKey] = ptrVal;
}
}
else
{
m_mapAttributes[strKey] = ptrVal;
}
}
}
void CXTPSyntaxEditLexClass::SetAttribute(CString strName, const CXTPSyntaxEditLexVariant& rVal)
{
ClearAttributesCache();
strName.MakeLower();
CXTPSyntaxEditLexVariantPtr ptrData = new CXTPSyntaxEditLexVariant(rVal);
m_mapAttributes[strName] = ptrData;
}
CXTPSyntaxEditLexVariantPtr CXTPSyntaxEditLexClass::GetAttribute(LPCTSTR strName, BOOL bDyn) const
{
CString strName_lower = strName;
strName_lower.MakeLower();
CXTPSyntaxEditLexVariantPtr ptrData;
if (m_mapAttributes.Lookup(strName_lower, ptrData))
{
return ptrData;
}
if (bDyn && m_Parent.ptrDirect)
{
ptrData = m_Parent.ptrDirect->GetAttribute(strName_lower, TRUE);
return ptrData;
}
return NULL;
}
#ifdef _DEBUG
void CXTPSyntaxEditLexClass::DumpOffset(CDumpContext& dc, LPCTSTR pcszOffset)
{
if (!pcszOffset)
{
pcszOffset = _T("");
}
int i;
dc << _T("\n");
dc << pcszOffset;
dc << _T("lexClass: NAME=") << m_strClassName << _T(" \n");
//------------------------------------
dc << pcszOffset;
if (m_Parent.eOpt == xtpEditOptParent_file)
{
dc << _T("parent:file = ");
}
else if (m_Parent.eOpt == xtpEditOptParent_direct)
{
dc << _T("parent = ");
}
else if (m_Parent.eOpt == xtpEditOptParent_dyn)
{
dc << _T("parent:dyn = ");
}
else
{
dc << _T("parent:??? = ");
}
for (i = 0; i < m_Parent.arClassNames.GetSize(); i++)
{
dc << m_Parent.arClassNames[i] << _T(", ");
}
if (m_Parent.ptrDirect)
{
dc << _T(" // [parent_by_ptr=[") << m_Parent.ptrDirect->m_strClassName << _T("] ");
}
dc << _T(" \n");
//------------------------------------
if (m_Children.eOpt == xtpEditOptChildren_No)
{
dc << pcszOffset;
dc << _T("children = 0 \n");
}
if (m_Children.eOpt == xtpEditOptChildren_List)
{
dc << pcszOffset;
dc << _T("children = ");
for (i = 0; i < m_Children.arClassNames.GetSize(); i++)
{
dc << m_Children.arClassNames[i] << _T(", ");
}
dc << _T(" \n");
}
//------------------------------------
m_previous.DumpOffset(dc, pcszOffset);
m_start.DumpOffset(dc, pcszOffset);
m_end.DumpOffset(dc, pcszOffset);
m_token.DumpOffset(dc, pcszOffset);
m_skip.DumpOffset(dc, pcszOffset);
m_ActiveTags.DumpOffset(dc, pcszOffset);
}
#endif
void CXTPSyntaxEditLexClass::GetTextAttributes(XTP_EDIT_TEXTBLOCK& rTB)
{
if (!m_bTxtAttr_cached)
{
m_bTxtAttr_cached = TRUE;
m_txtAttr_cached.clrBlock.crText = COLORREF_NULL;
m_txtAttr_cached.clrBlock.crBack = COLORREF_NULL;
m_txtAttr_cached.clrBlock.crHiliteText = COLORREF_NULL;
m_txtAttr_cached.clrBlock.crHiliteBack = COLORREF_NULL;
m_txtAttr_cached.lf.lfWeight = XTP_EDIT_FONTOPTIONS_UNSPEC_OPTION;
m_txtAttr_cached.lf.lfItalic = XTP_EDIT_FONTOPTIONS_UNSPEC_OPTION;
m_txtAttr_cached.lf.lfUnderline = XTP_EDIT_FONTOPTIONS_UNSPEC_OPTION;
//====================================================================
CXTPSyntaxEditLexVariantPtr ptrLVA;
ptrLVA = GetAttribute(XTPLEX_ATTR_TXT_COLORFG, TRUE);
if (ptrLVA && ptrLVA->m_nObjType == xtpEditLVT_valInt)
{
m_txtAttr_cached.clrBlock.crText = (COLORREF)ptrLVA->m_nValue;
}
ptrLVA = GetAttribute(XTPLEX_ATTR_TXT_COLORBK, TRUE);
if (ptrLVA && ptrLVA->m_nObjType == xtpEditLVT_valInt)
{
m_txtAttr_cached.clrBlock.crBack = (COLORREF)ptrLVA->m_nValue;
}
ptrLVA = GetAttribute(XTPLEX_ATTR_TXT_COLORSELFG, TRUE);
if (ptrLVA && ptrLVA->m_nObjType == xtpEditLVT_valInt)
{
m_txtAttr_cached.clrBlock.crHiliteText = (COLORREF)ptrLVA->m_nValue;
}
ptrLVA = GetAttribute(XTPLEX_ATTR_TXT_COLORSELBK, TRUE);
if (ptrLVA && ptrLVA->m_nObjType == xtpEditLVT_valInt)
{
m_txtAttr_cached.clrBlock.crHiliteBack = (COLORREF)ptrLVA->m_nValue;
}
//===========================================================================
ptrLVA = GetAttribute(XTPLEX_ATTR_TXT_BOLD, TRUE);
if (ptrLVA && ptrLVA->m_nObjType == xtpEditLVT_valInt)
{
m_txtAttr_cached.lf.lfWeight =
ptrLVA->m_nValue ? FW_BOLD : XTP_EDIT_FONTOPTIONS_UNSPEC_OPTION;
}
ptrLVA = GetAttribute(XTPLEX_ATTR_TXT_ITALIC, TRUE);
if (ptrLVA && ptrLVA->m_nObjType == xtpEditLVT_valInt)
{
m_txtAttr_cached.lf.lfItalic =
ptrLVA->m_nValue ? (BYTE)1 : XTP_EDIT_FONTOPTIONS_UNSPEC_OPTION;
}
ptrLVA = GetAttribute(XTPLEX_ATTR_TXT_UNDERLINE, TRUE);
if (ptrLVA && ptrLVA->m_nObjType == xtpEditLVT_valInt)
{
m_txtAttr_cached.lf.lfUnderline =
ptrLVA->m_nValue ? (BYTE)1 : XTP_EDIT_FONTOPTIONS_UNSPEC_OPTION;
}
}
//===========================================================================
if (m_txtAttr_cached.clrBlock.crText != COLORREF_NULL)
{
rTB.clrBlock.crText = m_txtAttr_cached.clrBlock.crText;
}
if (m_txtAttr_cached.clrBlock.crBack != COLORREF_NULL)
{
rTB.clrBlock.crBack = m_txtAttr_cached.clrBlock.crBack;
}
if (m_txtAttr_cached.clrBlock.crHiliteText != COLORREF_NULL)
{
rTB.clrBlock.crHiliteText = m_txtAttr_cached.clrBlock.crHiliteText;
}
if (m_txtAttr_cached.clrBlock.crHiliteBack != COLORREF_NULL)
{
rTB.clrBlock.crHiliteBack = m_txtAttr_cached.clrBlock.crHiliteBack;
}
rTB.lf.lfWeight = m_txtAttr_cached.lf.lfWeight;
rTB.lf.lfItalic = m_txtAttr_cached.lf.lfItalic;
rTB.lf.lfUnderline = m_txtAttr_cached.lf.lfUnderline;
}
CXTPSyntaxEditLexVariantPtrArray* CXTPSyntaxEditLexClass::BuildActiveTags(int& rnStartCount)
{
m_ActiveTags.RemoveAll();
m_nActiv_EndTags_Offset = 0;
//== start class tags =====
const TCHAR* s_arActiveTagsObjs1[] = {
_T("start:Tag"),
_T("previous:tag"),
_T("previous:tag:separators"),
_T("Token:tag")
};
//== end class tags =====
const TCHAR* s_arActiveTagsObjs2[] = {
_T("skip:Tag"),
_T("end:Tag"),
_T("end:separators")
};
//== 1. process start tags =====
int a;
for (a = 0; a < _countof(s_arActiveTagsObjs1); a++)
{
CXTPSyntaxEditLexVariantPtrArray* ptrAT = GetIfMy(s_arActiveTagsObjs1[a]);
ASSERT(ptrAT);
if (ptrAT)
{
ConcatenateLVArrays(&m_ActiveTags, ptrAT);
// if start:Tag not empty - skip previous tags.
// else previous tags are used to determine class start.
if (a == 0 && ptrAT->GetSize() > 0)
{
a += 2;
}
}
}
//m_ActiveTags.Dump(_T("~a1~ "));
//== 2. process children and add start tags only =====
CXTPSyntaxEditLexClassPtrArray* arChildren[2];
arChildren[0] = GetChildren();
arChildren[1] = GetChildrenDyn();
int i;
for (i = 0; i < _countof(arChildren); i++)
{
int nKCount = arChildren[i] ? (int)arChildren[i]->GetSize() : 0;
int k;
for (k = 0; k < nKCount; k++)
{
CXTPSyntaxEditLexClass* pCh = arChildren[i]->GetAt(k, FALSE);
ASSERT(pCh);
if (!pCh)
continue;
int nStartCount = 0;
CXTPSyntaxEditLexVariantPtrArray* ptrATch = pCh->BuildActiveTags(nStartCount);
if (ptrATch)
{
ConcatenateLVArrays(&m_ActiveTags, ptrATch, nStartCount);
}
}
}
//== 3. process end tags =====
m_nActiv_EndTags_Offset = (int)m_ActiveTags.GetSize();
for (a = 0; a < _countof(s_arActiveTagsObjs2); a++)
{
CXTPSyntaxEditLexVariantPtrArray* ptrAT = GetIfMy(s_arActiveTagsObjs2[a]);
ASSERT(ptrAT);
if (ptrAT)
{
ConcatenateLVArrays(&m_ActiveTags, ptrAT);
}
}
//m_ActiveTags.Dump(_T("~a2~ "));
//=======================
rnStartCount = m_nActiv_EndTags_Offset;
m_ActiveTags.BuildAutomat(TRUE);
//********************
m_token.m_tag.BuildAutomat(FALSE);
//********************
return &m_ActiveTags;
}