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.

4648 lines
114 KiB
C++

// XTPSyntaxEditLexParser.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/XTPNotifyConnection.h"
#include "Common/XTPSmartPtrInternalT.h"
#include "Common/XTPColorManager.h"
// syntax editor includes
#include "XTPSyntaxEditDefines.h"
#include "XTPSyntaxEditStruct.h"
#include "XTPSyntaxEditLexPtrs.h"
#include "XTPSyntaxEditLexClassSubObjT.h"
#include "XTPSyntaxEditTextIterator.h"
#include "XTPSyntaxEditSectionManager.h"
#include "XTPSyntaxEditLexCfgFileReader.h"
#include "XTPSyntaxEditLexClassSubObjDef.h"
#include "XTPSyntaxEditLexClass.h"
#include "XTPSyntaxEditLexParser.h"
#include "XTPSyntaxEditLexColorFileReader.h"
#include "XTPSyntaxEditBufferManager.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#ifdef _DEBUG
// #define DBG_TRACE_LOAD_CLASS_SCH
// Trace text blocks start, end when parser running;
// #define DBG_TRACE_PARSE_START_STOP TRACE
// Trace text blocks start, end when parser running;
// #define DBG_TRACE_PARSE_RUN_BLOCKS TRACE
// Trace updating schema mechanism when parser running;
// #define DBG_TRACE_PARSE_RUN_UPDATE TRACE
// #define DBG_TRACE_PARSE_RUN_RESULTS
// #define DBG_TRACE_PARSE_TIME
// #define DBG_TRACE_PARSE_TIME_DLG
// #define DBG_TRACE_DRAW_BLOCKS
#endif
#ifndef DBG_TRACE_PARSE_RUN_BLOCKS
#define DBG_TRACE_PARSE_RUN_BLOCKS
#endif
#ifndef DBG_TRACE_PARSE_RUN_UPDATE
#define DBG_TRACE_PARSE_RUN_UPDATE
#endif
#ifndef DBG_TRACE_PARSE_START_STOP
#define DBG_TRACE_PARSE_START_STOP
#endif
////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
#define DBG_TRACE_TIME_BEGIN(nID) DWORD dbg_TT_##nID##_dwTime_0 = ::GetTickCount();
#define DBG_TRACE_TIME_END(nID, strComment) { DWORD dwTime1 = ::GetTickCount(); \
TRACE(_T("%s (%.3f sec) \n"), strComment, labs(dwTime1-dbg_TT_##nID##_dwTime_0)/1000.0); }
class CXTPDebugHelper
{
CString m_strComment;
DWORD m_dwTime0;
public:
CXTPDebugHelper(LPCTSTR lpcszComment)
{
m_dwTime0 = ::GetTickCount();
m_strComment = lpcszComment;
};
~CXTPDebugHelper()
{
DWORD dwTime1 = ::GetTickCount();
TRACE(_T("%s (%.3f sec) \n"), (LPCTSTR)m_strComment, labs(dwTime1-m_dwTime0)/1000.0);
};
};
//#define DBG_TRACE_TIME(nID, strComment) CXTPDebugHelper dbg_TT_##nID(strComment);
#endif
#ifndef DBG_TRACE_TIME
#define DBG_TRACE_TIME(nID, strComment)
#endif
////////////////////////////////////////////////////////////////////////////
using namespace XTPSyntaxEditLexAnalyser;
namespace XTPSyntaxEditLexAnalyser
{
extern CXTPSyntaxEditLexAutomatMemMan* XTPGetLexAutomatMemMan();
extern void ConcatenateLVArrays(CXTPSyntaxEditLexVariantPtrArray* pArDest,
CXTPSyntaxEditLexVariantPtrArray* pAr2, int nMaxCount = INT_MAX);
extern BOOL SortTagsInLexVarArray(CXTPSyntaxEditLexVariantPtrArray& rarTags,
BOOL bAscending, BOOL bNoCase);
int FindStrCount(const CStringArray& rarData, LPCTSTR pcszStr, BOOL bCase = FALSE)
{
int nStrCount = 0;
int nCount = (int)rarData.GetSize();
for (int i = 0; i < nCount; i++)
{
const CString& strI = rarData[i];
if (bCase)
{
if (strI.Compare(pcszStr) == 0)
{
nStrCount++;
}
}
else
{
if (strI.CompareNoCase(pcszStr) == 0)
{
nStrCount++;
}
}
}
return nStrCount;
}
int FindStr(const CStringArray& rarData, LPCTSTR pcszStr, BOOL bCase = FALSE)
{
int nCount = (int)rarData.GetSize();
for (int i = 0; i < nCount; i++)
{
const CString& strI = rarData[i];
if (bCase)
{
if (strI.Compare(pcszStr) == 0)
{
return i;
}
}
else
{
if (strI.CompareNoCase(pcszStr) == 0)
{
return i;
}
}
}
return -1;
}
int Find_noCase(CStringArray& rarData, LPCTSTR strData)
{
return FindStr(rarData, strData, FALSE);
}
void AddIfNeed_noCase(CStringArray& rarData, LPCTSTR strNew)
{
int nFIdx = Find_noCase(rarData, strNew);
if (nFIdx < 0)
{
rarData.Add(strNew);
}
}
void ConcatenateArrays_noCase(CStringArray& rarDest, CStringArray& rarSrc)
{
int nCount = (int)rarSrc.GetSize();
for (int i = 0; i < nCount; i++)
{
CString strI = rarSrc[i];
AddIfNeed_noCase(rarDest, strI);
}
}
BOOL IsEventSet(HANDLE hEvent)
{
DWORD dwRes = ::WaitForSingleObject(hEvent, 0);
return dwRes == WAIT_OBJECT_0;
}
BOOL IsMutexLocked(CMutex* pMu)
{
if (!pMu)
{
ASSERT(FALSE);
return FALSE;
}
BOOL bEntered = pMu->Lock(0);
if (bEntered)
{
pMu->Unlock();
}
return !bEntered;
}
CString DBG_TraceIZone(const XTP_EDIT_LINECOL* pLCStart, const XTP_EDIT_LINECOL* pLCEnd)
{
CString sDBGpos, sTmp;
if (pLCStart && !pLCEnd && pLCStart->GetXLC() == XTP_EDIT_XLC(1, 0) )
{
sDBGpos = _T("All:(1, 0 - NULL)");
}
else if (pLCStart || pLCEnd)
{
sDBGpos = _T("Part:(");
sTmp = _T("NULL");
if (pLCStart)
{
sTmp.Format(_T("%d, %d"), pLCStart->nLine, pLCStart->nCol);
}
sDBGpos += sTmp + _T(" - ");
sTmp = _T("NULL");
if (pLCEnd)
{
sTmp.Format(_T("%d, %d"), pLCEnd->nLine, pLCEnd->nCol);
}
sDBGpos += sTmp;
sDBGpos += _T(")");
} else {
sDBGpos = _T("Rest(NULL - NULL)");
}
return sDBGpos;
}
CString DBG_TraceTB_StartEndCls(CXTPSyntaxEditLexTextBlock* pTB)
{
if (!pTB)
{
return _T("?<NULL> (? - ?) - ?");
}
CString str;
str.Format(_T("(%d, %d - %d, %d) - %s"), pTB->m_PosStartLC.nLine,
pTB->m_PosStartLC.nCol, pTB->m_PosEndLC.nLine, pTB->m_PosEndLC.nCol,
pTB->m_ptrLexClass ? (LPCTSTR)pTB->m_ptrLexClass->GetClassName() : _T("???<NULL>") );
return str;
}
}
//BEGIN_IMPLEMENT_XTPSINK(CXTPSyntaxEditLexParser, m_SinkMT)
// ON_XTP_NOTIFICATION(xtpEditOnParserStarted, OnParseEvent_NotificationHandler)
// ON_XTP_NOTIFICATION(xtpEditOnTextBlockParsed, OnParseEvent_NotificationHandler)
// ON_XTP_NOTIFICATION(xtpEditOnParserEnded, OnParseEvent_NotificationHandler)
//END_IMPLEMENT_XTPSINK
////////////////////////////////////////////////////////////////////////////
// CXTPSyntaxEditLexTextSchema
void CXTPSyntaxEditTextRegion::Clear()
{
m_posStart.Clear();
m_posEnd.Clear();
}
void CXTPSyntaxEditTextRegion::Set(const XTP_EDIT_LINECOL* pLCStart, const XTP_EDIT_LINECOL* pLCEnd)
{
m_posStart.nLine = INT_MAX;
m_posStart.nCol = 0;
m_posEnd.Clear();
if (pLCStart)
{
m_posStart = *pLCStart;
}
if (pLCEnd)
{
m_posEnd = *pLCEnd;
}
}
CXTPSyntaxEditLexTokensDef::~CXTPSyntaxEditLexTokensDef()
{
}
CXTPSyntaxEditLexTokensDef::CXTPSyntaxEditLexTokensDef(const CXTPSyntaxEditLexTokensDef& rSrc)
{
m_arTokens.Copy(rSrc.m_arTokens);
m_arStartSeps.Copy(rSrc.m_arStartSeps);
m_arEndSeps.Copy(rSrc.m_arEndSeps);
}
const CXTPSyntaxEditLexTokensDef& CXTPSyntaxEditLexTokensDef::operator=(const CXTPSyntaxEditLexTokensDef& rSrc)
{
m_arTokens.RemoveAll();
m_arStartSeps.RemoveAll();
m_arEndSeps.RemoveAll();
m_arTokens.Append(rSrc.m_arTokens);
m_arStartSeps.Append(rSrc.m_arStartSeps);
m_arEndSeps.Append(rSrc.m_arEndSeps);
return *this;
}
CXTPSyntaxEditLexTextSchema::CXTPSyntaxEditLexTextSchema(LPCTSTR pcszSchName):
m_evBreakParsing(FALSE, TRUE)
{
//m_CloserManager.SetParentObject(this);
m_pClassSchema = new CXTPSyntaxEditLexClassSchema();
m_pConnectMT = new CXTPNotifyConnectionMT();
m_nNoEndedClassesCount = 0;
m_curInvalidZone.Clear();
m_mapLastParsedBlocks.InitHashTable(101);
m_nSeekNext_TagWaitChars = 0;
m_strSchName = pcszSchName;
m_bSendProgressEvents = FALSE;
}
CXTPSyntaxEditLexTextSchema::~CXTPSyntaxEditLexTextSchema()
{
Close();
CMDTARGET_RELEASE(m_pClassSchema);
CMDTARGET_RELEASE(m_pConnectMT);
}
CString CXTPSyntaxEditLexTextSchema::GetSchName() const
{
return m_strSchName;
}
//CXTPSyntaxEditLexTextSchemaCloserManPtr CXTPSyntaxEditLexTextSchema::GetCloserManager()
//{
// CSingleLock singleLockCls(GetClassSchLoker(), TRUE);
// CSingleLock singleLock(GetDataLoker(), TRUE);
//
// ASSERT(m_CloserManager.m_ptrParentObj || m_CloserManager.m_dwRef == 0);
// ASSERT(this == (CXTPSyntaxEditLexTextSchema*)m_CloserManager.m_ptrParentObj || !m_CloserManager.m_ptrParentObj);
//
// m_CloserManager.SetParentObject(this);
//
// CXTPSyntaxEditLexTextSchemaCloserManPtr ptrRes(&m_CloserManager, TRUE);
// return ptrRes;
//}
CXTPNotifyConnection* CXTPSyntaxEditLexTextSchema::GetConnection()
{
return m_pConnectMT;
}
CXTPSyntaxEditLexClassSchema* CXTPSyntaxEditLexTextSchema::GetClassSchema()
{
return m_pClassSchema;
}
CXTPSyntaxEditLexTextSchema* CXTPSyntaxEditLexTextSchema::Clone()
{
CXTPSyntaxEditLexTextSchema* ptrNewSch = new CXTPSyntaxEditLexTextSchema(m_strSchName);
if (!ptrNewSch)
{
return NULL;
}
CSingleLock singleLockCls(GetClassSchLoker(), TRUE);
CSingleLock singleLock(GetDataLoker(), TRUE);
if (!m_pClassSchema->Copy(ptrNewSch->m_pClassSchema))
{
ptrNewSch->InternalRelease();
return NULL;
}
return ptrNewSch;
}
void CXTPSyntaxEditLexTextSchema::Close()
{
CSingleLock singleLockCls(GetClassSchLoker(), TRUE);
CSingleLock singleLock(GetDataLoker(), TRUE);
RemoveAll();
m_pClassSchema->Close();
}
void CXTPSyntaxEditLexTextSchema::RemoveAll()
{
CSingleLock singleLockCls(GetClassSchLoker(), TRUE);
CSingleLock singleLock(GetDataLoker(), TRUE);
Close(m_ptrFirstBlock);
m_ptrFirstBlock = NULL;
m_mapLastParsedBlocks.RemoveAll();
m_ptrLastParsedBlock = NULL;
}
void CXTPSyntaxEditLexTextSchema::Close(CXTPSyntaxEditLexTextBlock* pFirst)
{
CXTPSyntaxEditLexTextBlockPtr ptrChTB(pFirst, TRUE);
while (ptrChTB)
{
CXTPSyntaxEditLexTextBlockPtr ptrChTBnext = ptrChTB->m_ptrNext;
ptrChTB->Close();
ptrChTB = ptrChTBnext;
}
}
BOOL CXTPSyntaxEditLexTextSchema::IsBlockStartStillHere(CTextIter* pTxtIter, CXTPSyntaxEditLexTextBlock* pTB)
{
if (!pTxtIter || !pTB || !pTB->m_ptrLexClass)
{
ASSERT(FALSE);
return FALSE;
}
if (!pTxtIter->SeekPos(pTB->m_PosStartLC, m_evBreakParsing))
{
return FALSE;
}
CXTPSyntaxEditLexTextBlockPtr ptrTBtmp;
int nPres = pTB->m_ptrLexClass->RunParse(pTxtIter, this, ptrTBtmp);
BOOL bStarted = (nPres & xtpEditLPR_StartFound) != 0;
return bStarted;
}
// DEBUG ////////////////////////////////////////////////////////////////
#ifdef DBG_TRACE_PARSE_RUN_RESULTS
#define DBG_TRACE_PARSE_RUN_RESULTS_PROC(bFull) TraceTxtBlocks(bFull);
#else
#define DBG_TRACE_PARSE_RUN_RESULTS_PROC(bFull)
#endif
// END DEBUG ////////////////////////////////////////////////////////////
void CXTPSyntaxEditLexTextSchema::TraceTxtBlocks(BOOL bFull)
{
TRACE(_T("\n*** DBG_TRACE_PARSE_RUN_RESULTS *** --( %s )---------\n"),
bFull ? _T("FULL") : _T("updated part") );
CXTPSyntaxEditLexTextBlockPtr ptrTB = bFull ? m_ptrFirstBlock : m_ptrNewChainTB1;
for (int i = 0; ptrTB && (bFull || ptrTB->m_ptrPrev != m_ptrNewChainTB2); i++)
{
TRACE(_T("(%05d) startPos=(%d, %d) endPos=(%d, %d), [%s]\n"), i,
ptrTB->m_PosStartLC.nLine, ptrTB->m_PosStartLC.nCol,
ptrTB->m_PosEndLC.nLine, ptrTB->m_PosEndLC.nCol,
(LPCTSTR)ptrTB->m_ptrLexClass->m_strClassName);
ptrTB = ptrTB->m_ptrNext;
}
}
int CXTPSyntaxEditLexTextSchema::RunParseUpdate(BOOL bShort, CTextIter* pTxtIter,
const XTP_EDIT_LINECOL* pLCStart,
const XTP_EDIT_LINECOL* pLCEnd,
BOOL bSendProgressEvents)
{
CSingleLock singleLock(GetDataLoker(), TRUE);
m_mapLastParsedBlocks.RemoveAll();
singleLock.Unlock();
if (bSendProgressEvents)
{
m_pConnectMT->PostEvent(xtpEditOnParserStarted, 0, 0,
xtpNotifyGuarantyPost | xtpNotifyDirectCallForOneThread);
}
int nParseRes = Run_ParseUpdate0(bShort, pTxtIter, pLCStart, pLCEnd, bSendProgressEvents);
if (bSendProgressEvents)
{
m_pConnectMT->PostEvent(xtpEditOnParserEnded, nParseRes, 0,
xtpNotifyGuarantyPost|xtpNotifyDirectCallForOneThread);
}
return nParseRes;
}
int CXTPSyntaxEditLexTextSchema::Run_ParseUpdate0(BOOL bShort, CTextIter* pTxtIter,
const XTP_EDIT_LINECOL* pLCStart,
const XTP_EDIT_LINECOL* pLCEnd,
BOOL bSendProgressEvents)
{
if (!pTxtIter)
{
ASSERT(FALSE);
return xtpEditLPR_Error;
}
CSingleLock singleLockCls(GetClassSchLoker(), TRUE);
//-------------------------
m_curInvalidZone.Set(pLCStart, pLCEnd);
m_ptrNewChainTB1 = NULL;
m_ptrNewChainTB2 = NULL;
m_ptrOldChainTBFirst = NULL;
m_nNoEndedClassesCount = 0;
m_bSendProgressEvents = bSendProgressEvents;
int nParseRes = 0;
//** (1) ** -------------------------
CXTPSyntaxEditLexTextBlockPtr ptrStartTB = FindNearestTextBlock(m_curInvalidZone.m_posStart);
if (ptrStartTB)
{
nParseRes = Run_ClassesUpdate1(pTxtIter, ptrStartTB, FALSE);
if (nParseRes != -1)
{
if (nParseRes & (xtpEditLPR_Error|xtpEditLPR_RunBreaked|xtpEditLPR_RunFinished))
{
DBG_TRACE_PARSE_RUN_RESULTS_PROC(TRUE);
DBG_TRACE_PARSE_RUN_RESULTS_PROC(FALSE);
if (m_ptrNewChainTB1)
{
BOOL bByBreak = (nParseRes & (xtpEditLPR_Error|xtpEditLPR_RunBreaked)) != 0;
FinishNewChain(bByBreak, pTxtIter->IsEOF());
}
return nParseRes;
}
}
}
if (!pLCStart || *pLCStart == XTP_EDIT_LINECOL::Pos1 ||
nParseRes == -1 || !ptrStartTB )
{
nParseRes = 0;
m_ptrOldChainTBFirst = m_ptrFirstBlock ? m_ptrFirstBlock->m_ptrNext : NULL;
//** (2) ** -------------------------
CXTPSyntaxEditLexClassPtrArray* ptrArClasses = m_pClassSchema->GetClasses(bShort);
int nCCount = ptrArClasses ? (int)ptrArClasses->GetSize() : 0;
CXTPSyntaxEditLexClassPtr ptrTopClass = nCCount ? ptrArClasses->GetAt(0) : NULL;
BOOL bRunEOF = TRUE;
while (nCCount && (!pTxtIter->IsEOF() || bRunEOF) )
{
bRunEOF = !pTxtIter->IsEOF();
nParseRes = Run_ClassesUpdate2(pTxtIter, ptrArClasses, m_ptrFirstBlock);
if (nParseRes & (xtpEditLPR_Error|xtpEditLPR_RunBreaked|xtpEditLPR_RunFinished))
{
DBG_TRACE_PARSE_RUN_RESULTS_PROC(TRUE);
DBG_TRACE_PARSE_RUN_RESULTS_PROC(FALSE);
if (m_ptrNewChainTB1)
{
BOOL bByBreak = (nParseRes & (xtpEditLPR_Error|xtpEditLPR_RunBreaked)) != 0;
FinishNewChain(bByBreak, pTxtIter->IsEOF());
}
return nParseRes;
}
//** -------------------------------------------------------------
if (!pTxtIter->IsEOF() && nCCount && !(nParseRes & xtpEditLPR_Iterated))
{
if (IsEventSet(m_evBreakParsing))
{
return xtpEditLPR_RunBreaked;
}
SeekNextEx(pTxtIter, ptrTopClass);
}
}
}
DBG_TRACE_PARSE_RUN_RESULTS_PROC(TRUE);
DBG_TRACE_PARSE_RUN_RESULTS_PROC(FALSE);
if (m_ptrNewChainTB1)
{
BOOL bByBreak = (nParseRes & (xtpEditLPR_Error|xtpEditLPR_RunBreaked)) != 0;
FinishNewChain(bByBreak, pTxtIter->IsEOF());
}
return xtpEditLPR_RunFinished;
}
int CXTPSyntaxEditLexTextSchema::Run_ClassesUpdate1(CTextIter* pTxtIter,
CXTPSyntaxEditLexTextBlockPtr ptrStartTB,
BOOL bStarted)
{
if (!pTxtIter || !ptrStartTB || !ptrStartTB->m_ptrLexClass)
{
return xtpEditLPR_Error;
}
BOOL bIterated = FALSE;
int nPres = 0;
BOOL bRunEOF = TRUE;
BOOL bEnded = FALSE;
BOOL bStarted1 = bStarted;
if (!bStarted)
{
CXTPSyntaxEditLexTextBlockPtr ptrTB = ptrStartTB;
XTP_EDIT_LINECOL posStart = ptrStartTB->m_PosStartLC;
bStarted1 = IsBlockStartStillHere(pTxtIter, ptrTB);
while (!bStarted1 && ptrTB->m_ptrPrev)
{
ptrTB = ptrTB->m_ptrPrev;
posStart = ptrTB->m_PosStartLC;
bStarted1 = IsBlockStartStillHere(pTxtIter, ptrTB);
if (IsEventSet(m_evBreakParsing))
{
return xtpEditLPR_RunBreaked;
}
}
if (!bStarted1)
{
return -1; // Full reparse
}
if (m_curInvalidZone.m_posEnd.IsValidData() &&
ptrTB->m_PosEndLC > m_curInvalidZone.m_posEnd)
{
if (ptrTB->m_ptrParent || !ptrTB->m_ptrNext)
{
m_curInvalidZone.m_posEnd = ptrTB->m_PosEndLC;
}
else
{ // level: file
ASSERT(ptrTB->m_ptrNext);
if (ptrTB->m_ptrNext->m_PosEndLC > m_curInvalidZone.m_posEnd)
{
m_curInvalidZone.m_posEnd = ptrTB->m_ptrNext->m_PosEndLC;
}
}
}
m_curInvalidZone.m_posStart = posStart;
DBG_TRACE_PARSE_RUN_BLOCKS(_T("\nREPARSE will start from pos =(%d, %d), Run class [%s] {%d}-noEndedStack \n"),
posStart.nLine, posStart.nCol,
ptrTB->m_ptrParent ?
(ptrTB->m_ptrParent->m_ptrLexClass ?
ptrTB->m_ptrParent->m_ptrLexClass->m_strClassName : _T("?<NULL> (parent)") )
:( ptrTB->m_ptrLexClass ?
ptrTB->m_ptrLexClass->m_strClassName : _T("?<NULL>") )
, m_nNoEndedClassesCount );
CString sDBGzone = DBG_TraceIZone(&m_curInvalidZone.m_posStart, &m_curInvalidZone.m_posEnd);
DBG_TRACE_PARSE_RUN_UPDATE(_T("- Parser change invalid Zone [ %s ] \n"), sDBGzone);
// Seek iterator to begin of the block
if (!pTxtIter->SeekPos(posStart, m_evBreakParsing))
{
return xtpEditLPR_Error;
}
if (IsEventSet(m_evBreakParsing))
{
return xtpEditLPR_RunBreaked;
}
ASSERT(!m_ptrNewChainTB1);
m_ptrNewChainTB1 = ptrTB;
if (ptrTB->m_ptrPrev)
{
m_ptrNewChainTB1 = ptrTB->m_ptrPrev;
}
m_ptrOldChainTBFirst = m_ptrNewChainTB1->m_ptrNext;
DBG_TRACE_PARSE_RUN_UPDATE(_T(" NewChainTB1: %s \n"), DBG_TraceTB_StartEndCls(m_ptrNewChainTB1));
DBG_TRACE_PARSE_RUN_UPDATE(_T(" OldChainTBFirst: %s \n"), DBG_TraceTB_StartEndCls(m_ptrOldChainTBFirst));
ptrStartTB = ptrTB;
}
CXTPSyntaxEditLexClassPtr ptrRunClass = ptrStartTB->m_ptrLexClass;
//** 1 **// Run existing block with children until block end
while (bStarted && !bEnded && (bRunEOF || !pTxtIter->IsEOF()) )
{
if (IsEventSet(m_evBreakParsing))
{
return xtpEditLPR_RunBreaked;
}
bRunEOF = !pTxtIter->IsEOF();
BOOL bSkipIterate = FALSE;
nPres = ptrRunClass->RunParse(pTxtIter, this, ptrStartTB);
if (nPres & (xtpEditLPR_Error|/*xtpEditLPR_RunBreaked|*/xtpEditLPR_RunFinished))
{
return nPres;
}
//---------------------------------------------------------------------------
if (nPres & xtpEditLPR_Iterated)
{
bSkipIterate = TRUE;
bIterated = TRUE;
}
//---------------------------------------------------------------------------
bEnded = (nPres & xtpEditLPR_EndFound) != 0;
if (bEnded)
{
CSingleLock singleLock(GetDataLoker(), TRUE);
m_nNoEndedClassesCount--;
int nECount = ptrStartTB->EndChildren(this);
m_nNoEndedClassesCount -= nECount;
//*** VALIDATION (when reparsing)
if (m_ptrNewChainTB2 && m_ptrNewChainTB2->m_ptrNext)
{
while (m_ptrNewChainTB2->m_ptrNext &&
m_ptrNewChainTB2->m_ptrNext->m_PosStartLC < ptrStartTB->m_PosEndLC)
{
m_ptrNewChainTB2->m_ptrNext = m_ptrNewChainTB2->m_ptrNext->m_ptrNext;
}
}
DBG_TRACE_PARSE_RUN_BLOCKS(_T("(%08x) ENDED startPos=(%d, %d) endPos=(%d, %d), [%s] {%d}-noEndedStack \n"),
(CXTPSyntaxEditLexTextBlock*)ptrStartTB,
ptrStartTB->m_PosStartLC.nLine, ptrStartTB->m_PosStartLC.nCol, ptrStartTB->m_PosEndLC.nLine,
ptrStartTB->m_PosEndLC.nCol, ptrStartTB->m_ptrLexClass->m_strClassName, m_nNoEndedClassesCount);
SendEvent_OnTextBlockParsed(ptrStartTB);
}
//---------------------------------------------------------------------------
if (!bEnded && !bSkipIterate)
{
if (IsEventSet(m_evBreakParsing))
{
return xtpEditLPR_RunBreaked;
}
SeekNextEx(pTxtIter, ptrRunClass);
}
}
//** end run existing **//
if (bStarted && !bEnded && pTxtIter->IsEOF())
{
CXTPSyntaxEditLexTextBlock* pTB2end = ptrStartTB;
for (; pTB2end; pTB2end = pTB2end->m_ptrParent)
{
pTB2end->m_PosEndLC = pTxtIter->GetPosLC();
}
return xtpEditLPR_RunFinished;
}
if (bStarted && bEnded || pTxtIter->IsEOF())
{
return xtpEditLPR_RunFinished;
}
//===========================================================================
CXTPSyntaxEditLexTextBlockPtr ptrTBrun = ptrStartTB;
if (ptrStartTB->m_ptrParent)
{
ptrTBrun = ptrStartTB->m_ptrParent;
bEnded = FALSE;
if (ptrTBrun->m_PosEndLC >= m_curInvalidZone.m_posStart &&
ptrTBrun->m_PosEndLC <= m_curInvalidZone.m_posEnd)
{
m_nNoEndedClassesCount++;
}
}
if (!bEnded && !pTxtIter->IsEOF())
{
if (IsEventSet(m_evBreakParsing))
{
return xtpEditLPR_RunBreaked;
}
nPres = Run_ClassesUpdate1(pTxtIter, ptrTBrun, bStarted1);
if (nPres & (xtpEditLPR_Error|xtpEditLPR_RunBreaked|xtpEditLPR_RunFinished))
{
return nPres;
}
//---------------------------------
if (nPres & xtpEditLPR_Iterated)
{
bIterated = TRUE;
}
}
//---------------------------------------------------------------------------
return (bIterated ? xtpEditLPR_Iterated : 0) | (pTxtIter->IsEOF() ? xtpEditLPR_RunFinished : 0);
}
int CXTPSyntaxEditLexTextSchema::Run_ClassesUpdate2(CTextIter* pTxtIter,
CXTPSyntaxEditLexClassPtrArray* pArClasses,
CXTPSyntaxEditLexTextBlockPtr ptrParentTB,
CXTPSyntaxEditLexOnScreenParseCnt* pOnScreenRunCnt)
{
int nCCount = (int)pArClasses->GetSize();
BOOL bIterated = FALSE;
int nReturn = 0;
for (int i = 0; i < nCCount; i++)
{
CXTPSyntaxEditLexClass* pClass = pArClasses->GetAt(i, FALSE);
ASSERT(pClass);
if (!pClass)
continue;
CXTPSyntaxEditLexTextBlockPtr ptrTB = NULL;
int nPres = 0;
BOOL bStarted = FALSE;
BOOL bEnded = FALSE;
BOOL bRunEOF = FALSE;
do
{
if (IsEventSet(m_evBreakParsing))
{
return xtpEditLPR_RunBreaked;
}
bRunEOF = !pTxtIter->IsEOF();
BOOL bSkipIterate = FALSE;
nPres = pClass->RunParse(pTxtIter, this, ptrTB, pOnScreenRunCnt);
if (nPres & (xtpEditLPR_Error|/*xtpEditLPR_RunBreaked|*/xtpEditLPR_RunFinished))
{
return nPres;
}
//---------------------------------------------------------------------------
if ((nPres & xtpEditLPR_StartFound) && ptrTB && !ptrTB->m_ptrPrev)
{
bStarted = TRUE;
CSingleLock singleLock(GetDataLoker(), TRUE);
ptrTB->m_ptrParent = ptrParentTB;
if (ptrTB->m_ptrParent)
{
ptrTB->m_ptrParent->m_ptrLastChild = ptrTB;
}
if (!pOnScreenRunCnt)
{
//*** VALIDATION (when reparsing)
if (m_ptrNewChainTB2 && m_ptrNewChainTB2->m_ptrNext)
{
while (m_ptrNewChainTB2->m_ptrNext &&
m_ptrNewChainTB2->m_ptrNext->m_PosStartLC < ptrTB->m_PosStartLC)
{
m_ptrNewChainTB2->m_ptrNext = m_ptrNewChainTB2->m_ptrNext->m_ptrNext;
}
if (m_ptrNewChainTB2->m_ptrNext && m_curInvalidZone.m_posEnd.IsValidData() )
{
DBG_TRACE_PARSE_RUN_UPDATE(_T("\n <VALIDATE> TB current: %s \n"), DBG_TraceTB_StartEndCls(ptrTB));
DBG_TRACE_PARSE_RUN_UPDATE(_T(" <VALIDATE> TB next OLD: %s [NoEndedStack=%d]\n"),
DBG_TraceTB_StartEndCls(m_ptrNewChainTB2->m_ptrNext), m_nNoEndedClassesCount);
if (m_ptrNewChainTB2->m_ptrNext->m_PosStartLC == ptrTB->m_PosStartLC &&
ptrTB->IsEqualLexClasses(m_ptrNewChainTB2->m_ptrNext) &&
m_curInvalidZone.m_posEnd.IsValidData() &&
m_ptrNewChainTB2->m_ptrNext->m_PosStartLC > m_curInvalidZone.m_posEnd)
{
// BREAK.
if (m_nNoEndedClassesCount <= 0)
{
FinishNewChain(FALSE, pTxtIter->IsEOF());
return xtpEditLPR_RunFinished;
}
}
}
}
//***
m_nNoEndedClassesCount++;
//**************************
if (!m_ptrNewChainTB1)
{
// Full reparse
m_ptrNewChainTB1 = ptrTB;
m_ptrNewChainTB2 = NULL;
//ASSERT(m_ptrFirstBlock == NULL);
m_ptrFirstBlock = ptrTB;
DBG_TRACE_PARSE_RUN_UPDATE(_T(" NewChainTB1 (&FirstBlock): %s \n"), DBG_TraceTB_StartEndCls(m_ptrNewChainTB1));
}
else if (!m_ptrNewChainTB2)
{
m_ptrNewChainTB2 = m_ptrNewChainTB1;
}
if (nPres&xtpEditLPR_TBpop1)
{
if (m_ptrNewChainTB2)
{
if (m_ptrNewChainTB2->m_ptrPrev)
{
m_ptrNewChainTB2->m_ptrPrev->m_ptrNext = ptrTB;
}
ptrTB->m_ptrPrev = m_ptrNewChainTB2->m_ptrPrev;
ptrTB->m_ptrNext = m_ptrNewChainTB2;
m_ptrNewChainTB2->m_ptrPrev = ptrTB;
m_ptrNewChainTB2->m_ptrParent = ptrTB;
}
else
{
m_ptrNewChainTB2 = ptrTB; //SetPrevBlock(ptrTB);
}
}
else
{
if (m_ptrNewChainTB2)
{
ptrTB->m_ptrNext = m_ptrNewChainTB2->m_ptrNext;
ptrTB->m_ptrPrev = m_ptrNewChainTB2; //GetPrevBlock(); //
m_ptrNewChainTB2->m_ptrNext = ptrTB;
}
m_ptrNewChainTB2 = ptrTB; //SetPrevBlock(ptrTB);
}
//**************************
}
else
{
if (nPres&xtpEditLPR_TBpop1)
{
if (pOnScreenRunCnt->m_ptrTBLast)
{
if (pOnScreenRunCnt->m_ptrTBLast->m_ptrPrev)
{
pOnScreenRunCnt->m_ptrTBLast->m_ptrPrev->m_ptrNext = ptrTB;
}
ptrTB->m_ptrPrev = pOnScreenRunCnt->m_ptrTBLast->m_ptrPrev;
ptrTB->m_ptrNext = pOnScreenRunCnt->m_ptrTBLast;
pOnScreenRunCnt->m_ptrTBLast->m_ptrPrev = ptrTB;
pOnScreenRunCnt->m_ptrTBLast->m_ptrParent = ptrTB;
}
else
{
pOnScreenRunCnt->m_ptrTBLast = ptrTB;
}
}
else
{
ptrTB->m_ptrPrev = pOnScreenRunCnt->m_ptrTBLast;
if (pOnScreenRunCnt->m_ptrTBLast)
{
pOnScreenRunCnt->m_ptrTBLast->m_ptrNext = ptrTB;
}
pOnScreenRunCnt->m_ptrTBLast = ptrTB;
}
}
// DEBUG ////////////////////////////////////////////////////////////////
DBG_TRACE_PARSE_RUN_BLOCKS(_T("(%08x) START startPos=(%d, %d), ______________ [%s] {%d}-noEndedStack \n"),
(CXTPSyntaxEditLexTextBlock*)ptrTB,
ptrTB->m_PosStartLC.nLine, ptrTB->m_PosStartLC.nCol,
ptrTB->m_ptrLexClass->m_strClassName, m_nNoEndedClassesCount);
// END DEBUG ////////////////////////////////////////////////////////////
}
//---------------------------------------------------------------------------
if (nPres & xtpEditLPR_Iterated)
{
bSkipIterate = TRUE;
bIterated = TRUE;
}
//---------------------------------------------------------------------------
bEnded = (nPres & xtpEditLPR_EndFound) != 0;
if (bEnded)
{
CSingleLock singleLock(GetDataLoker(), TRUE);
m_nNoEndedClassesCount--;
int nECount = ptrTB->EndChildren(pOnScreenRunCnt ? NULL : this);
m_nNoEndedClassesCount -= nECount;
// DEBUG ////////////////////////////////////////////////////////////////
DBG_TRACE_PARSE_RUN_BLOCKS(_T("(%08x) ENDED startPos=(%d, %d) endPos=(%d, %d), [%s] {%d}-noEndedStack \n"),
(CXTPSyntaxEditLexTextBlock*)ptrTB,
ptrTB->m_PosStartLC.nLine, ptrTB->m_PosStartLC.nCol,
ptrTB->m_PosEndLC.nLine, ptrTB->m_PosEndLC.nCol,
ptrTB->m_ptrLexClass->m_strClassName, m_nNoEndedClassesCount);
// END DEBUG ////////////////////////////////////////////////////////////
if (!pOnScreenRunCnt)
{
SendEvent_OnTextBlockParsed(ptrTB);
}
}
if (nPres & xtpEditLPR_RunBreaked)
{
return nPres;
}
//---------------------------------------------------------------------------
if (bStarted && !bEnded && !bSkipIterate)
{
if (IsEventSet(m_evBreakParsing))
{
return xtpEditLPR_RunBreaked;
}
SeekNextEx(pTxtIter, pClass, pOnScreenRunCnt);
bIterated = TRUE;
}
//---------------------------------------------------------------------------
if (pOnScreenRunCnt)
{
XTP_EDIT_LINECOL lcTextPos = pTxtIter->GetPosLC();
if (lcTextPos.nLine > pOnScreenRunCnt->m_nRowEnd)
{
return xtpEditLPR_RunFinished;
}
}
}
while (bStarted && !bEnded && (bRunEOF || !pTxtIter->IsEOF()) );
if (bEnded && pClass->IsRestartRunLoop())
{
nReturn |= xtpEditLPR_RunRestart;
break;
}
}
return nReturn | (bIterated ? xtpEditLPR_Iterated : 0);
}
UINT CXTPSyntaxEditLexTextSchema::SendEvent_OnTextBlockParsed(CXTPSyntaxEditLexTextBlock* pTB)
{
CSingleLock singleLock(GetDataLoker(), TRUE);
if (!m_bSendProgressEvents)
{
return 0;
}
CXTPSyntaxEditLexTextBlockPtr ptrTB(pTB, TRUE);
WPARAM dwTBid = (WPARAM)pTB;
m_mapLastParsedBlocks[dwTBid] = ptrTB;
m_ptrLastParsedBlock.SetPtr(pTB, TRUE);
BOOL bIsSubscribers = m_pConnectMT->PostEvent(xtpEditOnTextBlockParsed, dwTBid,
0, xtpNotifyDirectCallForOneThread);
if (bIsSubscribers)
{
// WARNING: Why? EventsWnd must call GetLastParsedBlock()
// to withdraw objects from the map!
//ASSERT(m_mapLastParsedBlocks.GetCount() < 10*1000);
static BOOL s_bAssert = FALSE;
if (!s_bAssert && m_mapLastParsedBlocks.GetCount() > 10*1000)
{
s_bAssert = TRUE;
ASSERT(FALSE);
}
}
else
{
m_mapLastParsedBlocks.RemoveAll();
}
return 0;
}
CXTPSyntaxEditLexTextBlock* CXTPSyntaxEditLexTextSchema::GetLastParsedBlock(WPARAM dwID)
{
CSingleLock singleLock(GetDataLoker(), TRUE);
if (dwID)
{
CXTPSyntaxEditLexTextBlockPtr ptrTB;
if (m_mapLastParsedBlocks.Lookup(dwID, ptrTB))
{
m_mapLastParsedBlocks.RemoveKey(dwID);
return ptrTB.Detach();
}
}
else
{
return m_ptrLastParsedBlock.GetInterface(TRUE);
}
// ASSERT(FALSE);
return NULL;
}
void CXTPSyntaxEditLexTextSchema::FinishNewChain(BOOL bByBreak, BOOL bEOF)
{
CSingleLock singleLock(GetDataLoker(), TRUE);
CXTPSyntaxEditLexTextBlockPtr ptrTBOldLast = NULL;
DBG_TRACE_PARSE_RUN_UPDATE(_T(" <F> NewChainTB1: %s \n"), DBG_TraceTB_StartEndCls(m_ptrNewChainTB1));
if (m_ptrNewChainTB2)
{
DBG_TRACE_PARSE_RUN_UPDATE(_T(" <F> NewChainTB2-raw: %s \n"), DBG_TraceTB_StartEndCls(m_ptrNewChainTB2));
if (bByBreak && !bEOF)
{
// roll back no-ended blocks
while ( !m_ptrNewChainTB2->m_PosEndLC.IsValidData() &&
m_ptrNewChainTB2->m_ptrPrev &&
m_ptrNewChainTB2 != m_ptrNewChainTB1)
{
CXTPSyntaxEditLexTextBlockPtr ptrTBclose = m_ptrNewChainTB2;
m_ptrNewChainTB2 = m_ptrNewChainTB2->m_ptrPrev;
m_ptrNewChainTB2->m_ptrNext = ptrTBclose->m_ptrNext;
DBG_TRACE_PARSE_RUN_UPDATE(_T(" <F> CLOSE TB-RollBacked: %s \n"), DBG_TraceTB_StartEndCls(ptrTBclose));
ptrTBclose->Close();
}
DBG_TRACE_PARSE_RUN_UPDATE(_T(" <F> NewChainTB2-RollBacked: %s \n"), DBG_TraceTB_StartEndCls(m_ptrNewChainTB2));
}
// end no-ended blocks
EndBlocksByParent(m_ptrNewChainTB1, m_ptrNewChainTB2);
if (m_ptrNewChainTB2 == m_ptrNewChainTB1)
{
UpdateLastSchBlock(m_ptrNewChainTB2);
m_ptrOldChainTBFirst = NULL;
return;
}
// synchronize new and old chains
while (m_ptrNewChainTB2->m_ptrNext &&
(m_ptrNewChainTB2->m_ptrNext->m_PosStartLC < m_ptrNewChainTB2->m_PosStartLC ||
m_ptrNewChainTB2->m_ptrNext->m_PosStartLC == m_ptrNewChainTB2->m_PosStartLC &&
m_ptrNewChainTB2->m_ptrNext->IsEqualLexClasses(m_ptrNewChainTB2) )
)
{
m_ptrNewChainTB2->m_ptrNext = m_ptrNewChainTB2->m_ptrNext->m_ptrNext;
}
if (m_ptrNewChainTB2->m_ptrNext)
{
m_ptrNewChainTB2->m_ptrNext->m_ptrPrev = m_ptrNewChainTB2;
m_curInvalidZone.m_posEnd = m_ptrNewChainTB2->m_ptrNext->m_PosStartLC;
}
else
{
m_curInvalidZone.m_posEnd = m_ptrNewChainTB2->m_PosStartLC;
}
if (!bEOF)
{
ptrTBOldLast = m_ptrNewChainTB2->m_ptrNext;
}
}
else if (bByBreak)
{
if (m_ptrNewChainTB2)
{
UpdateLastSchBlock(m_ptrNewChainTB2);
}
m_ptrOldChainTBFirst = NULL;
m_ptrNewChainTB1 = NULL;
m_ptrNewChainTB2 = NULL;
m_nNoEndedClassesCount = 0;
return;
}
else
{
// No new blocks found after chain branch.
// (All rest blocks where deleted)
if (m_ptrNewChainTB1)
{
m_ptrNewChainTB1->m_ptrNext = NULL;
UpdateLastSchBlock(m_ptrNewChainTB1, TRUE);
}
else if (m_ptrFirstBlock)
{
m_ptrFirstBlock->m_ptrNext = NULL;
UpdateLastSchBlock(m_ptrFirstBlock, TRUE);
}
}
DBG_TRACE_PARSE_RUN_UPDATE(_T(" <F> OldChainTBFirst: %s \n"), DBG_TraceTB_StartEndCls(m_ptrOldChainTBFirst));
DBG_TRACE_PARSE_RUN_UPDATE(_T(" <F> TBOldLast: %s \n"), DBG_TraceTB_StartEndCls(ptrTBOldLast));
CXTPSyntaxEditLexTextBlockPtr ptrTBOld = m_ptrOldChainTBFirst;
while (ptrTBOld && ptrTBOld != ptrTBOldLast)
{
CXTPSyntaxEditLexTextBlockPtr ptrTBclose = ptrTBOld;
ptrTBOld = ptrTBOld->m_ptrNext;
ptrTBclose->Close();
}
if (m_ptrNewChainTB2 && m_ptrNewChainTB2->m_ptrNext &&
m_ptrNewChainTB2->m_ptrNext->IsLookLikeClosed())
{
m_ptrNewChainTB2->m_ptrNext = NULL;
UpdateLastSchBlock(m_ptrNewChainTB2, TRUE);
}
//===================================
if (m_ptrNewChainTB2 && m_ptrNewChainTB1)
{
UpdateNewChainParentsChildren();
}
//===================================
if (m_ptrNewChainTB2)
{ // && m_ptrNewChainTB2->m_ptrNext == NULL)
UpdateLastSchBlock(m_ptrNewChainTB2);
}
//-----------------------------------
m_ptrOldChainTBFirst = NULL;
m_ptrNewChainTB1 = NULL;
m_ptrNewChainTB2 = NULL;
m_nNoEndedClassesCount = 0;
}
void CXTPSyntaxEditLexTextSchema::UpdateNewChainParentsChildren()
{
CSingleLock singleLock(GetDataLoker(), TRUE);
if (!m_ptrNewChainTB2 || !m_ptrNewChainTB1)
{
return;
}
if (m_ptrNewChainTB1 != m_ptrFirstBlock)
{
//update children for new chain blocks
CXTPSyntaxEditLexTextBlock* pTB_chi = m_ptrNewChainTB2->m_ptrNext;
for (; pTB_chi; pTB_chi = pTB_chi->m_ptrNext)
{
if (pTB_chi->m_ptrParent && pTB_chi->m_ptrParent->IsLookLikeClosed())
{
CXTPSyntaxEditLexTextBlock* pTB_Par = pTB_chi->m_ptrPrev;
for (; pTB_Par; pTB_Par = pTB_Par->m_ptrPrev)
{
if (pTB_Par->IsInclude(pTB_chi))
{
pTB_chi->m_ptrParent.SetPtr(pTB_Par, TRUE);
ASSERT(!pTB_Par->IsLookLikeClosed());
break;
}
}
}
}
}
}
void CXTPSyntaxEditLexTextSchema::EndBlocksByParent(CXTPSyntaxEditLexTextBlock* pTBStart, CXTPSyntaxEditLexTextBlock* pTBEnd)
{
CSingleLock singleLock(GetDataLoker(), TRUE);
if (!pTBStart)
{
return;
}
CXTPSyntaxEditLexTextBlock* pTB_chi = pTBStart;
for (; pTB_chi != pTBEnd->m_ptrNext; pTB_chi = pTB_chi->m_ptrNext)
{
if (!pTB_chi->m_PosEndLC.IsValidData())
{
//ASSERT(pTB_chi->m_ptrParent && pTB_chi->m_ptrParent->m_PosEndLC.IsValidData());
if (pTB_chi->m_ptrParent && pTB_chi->m_ptrParent->m_PosEndLC.IsValidData())
{
pTB_chi->m_PosEndLC = pTB_chi->m_ptrParent->m_PosEndLC;
}
}
}
}
int CXTPSyntaxEditLexTextSchema::RunChildren(CTextIter* pTxtIter,
CXTPSyntaxEditLexTextBlockPtr ptrTxtBlock,
CXTPSyntaxEditLexClass* pBase,
CXTPSyntaxEditLexOnScreenParseCnt* pOnScreenRunCnt)
{
if (!pTxtIter || !pBase)
{
ASSERT(FALSE);
return xtpEditLPR_Error;
}
int nRes = 0;
CXTPSyntaxEditLexClassPtrArray* pArClasses[3];
pArClasses[0] = pBase->GetChildren();
pArClasses[1] = pBase->GetChildrenDyn();
pArClasses[2] = pBase->GetChildrenSelfRef();
for (int i = 0; i < _countof(pArClasses); i++)
{
if (pArClasses[i] && pArClasses[i]->GetSize())
{
int nResLocal = Run_ClassesUpdate2(pTxtIter, pArClasses[i],
ptrTxtBlock, pOnScreenRunCnt);
nRes |= nResLocal;
if (nRes & (xtpEditLPR_Error|xtpEditLPR_RunBreaked|xtpEditLPR_RunFinished|xtpEditLPR_RunRestart))
{
break;
}
}
}
return nRes;
}
void CXTPSyntaxEditLexTextSchema::SeekNextEx(CTextIter* pTxtIter,
CXTPSyntaxEditLexClass* pRunClass,
CXTPSyntaxEditLexOnScreenParseCnt* pOnScreenRunCnt,
int nChars )
{
if (!pTxtIter || !pRunClass)
{
ASSERT(FALSE);
return;
}
pTxtIter->SeekNext(nChars);
m_nSeekNext_TagWaitChars -= nChars;
CXTPSyntaxEditLexObj_ActiveTags* pAT = m_pClassSchema->GetActiveTagsFor(pRunClass);
if (pAT && m_nSeekNext_TagWaitChars)
{
int i = 0;
//BOOL bCase = FALSE; //pRunClass->IsCaseSensitive();
CString strTmp;
BOOL bTag = FALSE;
while (!bTag && !pTxtIter->IsEOF() && m_nSeekNext_TagWaitChars)
{
//bTag = CXTPSyntaxEditLexClass::Run_Tags1(pTxtIter, pAT, strTmp, bCase, FALSE);
//
bTag = pAT->FindMinWord(pTxtIter->GetText(1024), strTmp, 1024, TRUE, FALSE);
// for test(DEBUG) Only
#ifdef DBG_AUTOMAT
BOOL bCase = FALSE; //pRunClass->IsCaseSensitive();
CString strTmpX;
BOOL bTagX = CXTPSyntaxEditLexClass::Run_Tags1(pTxtIter, pAT, strTmpX, bCase, FALSE);
if (bTagX != bTag)
{
//ASSERT(FALSE);
pAT->BuildAutomat(TRUE);
bTag = pAT->FindMinWord(pTxtIter->GetText(1024), strTmp, 1024, TRUE, FALSE);
}
if (bTag)
{
strTmp.Empty();
bTag = CXTPSyntaxEditLexClass::Run_Tags1(pTxtIter, pAT, strTmp, bCase, FALSE);
}
#endif
if (!bTag)
{
pTxtIter->SeekNext(1);
m_nSeekNext_TagWaitChars--;
}
if (++i%10 == 0 && IsEventSet(m_evBreakParsing))
{
return;
}
if (pOnScreenRunCnt)
{
XTP_EDIT_LINECOL lcTextPos = pTxtIter->GetPosLC();
if (lcTextPos.nLine > pOnScreenRunCnt->m_nRowEnd)
{
return;
}
}
}
ASSERT(bTag || pTxtIter->IsEOF() || !m_nSeekNext_TagWaitChars);
//----------------------
if (bTag)
{
m_nSeekNext_TagWaitChars = (int)_tcsclen(strTmp);
ASSERT(m_nSeekNext_TagWaitChars > 0);
}
}
}
CXTPSyntaxEditLexTextBlock* CXTPSyntaxEditLexTextSchema::GetPrevBlock(BOOL bWithAddRef)
{
CSingleLock singleLock(GetDataLoker(), TRUE);
return m_ptrNewChainTB2.GetInterface(bWithAddRef);
}
void CXTPSyntaxEditLexTextSchema::UpdateLastSchBlock(CXTPSyntaxEditLexTextBlock* pLastTB, BOOL bPermanently)
{
CSingleLock singleLock(GetDataLoker(), TRUE);
if (!pLastTB || !m_ptrLastSchBlock || bPermanently)
{
m_ptrLastSchBlock.SetPtr(pLastTB, TRUE);
return;
}
if (pLastTB->m_PosStartLC >= m_ptrLastSchBlock->m_PosStartLC)
{
m_ptrLastSchBlock.SetPtr(pLastTB, TRUE);
}
}
CXTPSyntaxEditLexTextBlock* CXTPSyntaxEditLexTextSchema::GetLastSchBlock(BOOL bWithAddRef)
{
CSingleLock singleLock(GetDataLoker(), TRUE);
if (m_ptrLastSchBlock && !m_ptrNewChainTB2)
{
return m_ptrLastSchBlock.GetInterface(bWithAddRef);
}
if (!m_ptrLastSchBlock && m_ptrNewChainTB2)
{
return m_ptrNewChainTB2.GetInterface(bWithAddRef);
}
if (m_ptrLastSchBlock && m_ptrNewChainTB2)
{
if (m_ptrLastSchBlock->m_PosStartLC < m_ptrNewChainTB2->m_PosStartLC)
{
return m_ptrNewChainTB2.GetInterface(bWithAddRef);
}
else
{
return m_ptrLastSchBlock.GetInterface(bWithAddRef);
}
}
return NULL;
}
CXTPSyntaxEditLexTextBlock* CXTPSyntaxEditLexTextSchema::GetNewBlock()
{
CXTPSyntaxEditLexTextBlock* p = new CXTPSyntaxEditLexTextBlock();
return p;
}
void CXTPSyntaxEditLexTextSchema::GetTextAttributes(XTP_EDIT_TEXTBLOCK& rTB, CXTPSyntaxEditLexTextBlock* pTextBlock)
{
if (!pTextBlock || !pTextBlock->m_ptrLexClass)
{
return;
}
pTextBlock->m_ptrLexClass->GetTextAttributes(rTB);
}
void CXTPSyntaxEditLexTextSchema::TraceClrBlocks(CXTPSyntaxEditTextBlockArray& arBlocks)
{
// DEBUG ////////////////////////////////////////////////////////////////
#ifdef DBG_TRACE_DRAW_BLOCKS
TRACE(_T("\n*** bloks --------------------\n"));
for (int i = 0; i < arBlocks.GetSize(); i++)
{
XTP_EDIT_TEXTBLOCK BlkI = arBlocks[i];
TRACE(_T("(%02d) start =%d, ?end=%d, color=%X \n"), i, BlkI.nPos,
BlkI.nNextBlockPos, BlkI.clrBlock.crText);
}
TRACE(_T("***\n"));
#else
UNREFERENCED_PARAMETER(arBlocks);
#endif
// END DEBUG ////////////////////////////////////////////////////////////
}
void CXTPSyntaxEditLexTextSchema::AddClrBlock(XTP_EDIT_TEXTBLOCK& rClrB,
CXTPSyntaxEditTextBlockArray& arBlocks)
{
#ifdef DBG_TRACE_DRAW_BLOCKS
TRACE(_T(" --- ADD --- start =%d, ?end=%d, color=%X \n"), rClrB.nPos,
rClrB.nNextBlockPos, rClrB.clrBlock.crText);
#endif
int nCount = (int)arBlocks.GetSize();
//** A. ** new block is included in the existing block
int i;
for (i = 0; i < nCount; i++)
{
XTP_EDIT_TEXTBLOCK& BlkI = arBlocks[i];
if (rClrB.nNextBlockPos < BlkI.nPos ||
rClrB.nPos >= BlkI.nNextBlockPos )
{
continue;
}
XTP_EDIT_TEXTBLOCK BlkI2;// = BlkI;
if (rClrB.nPos >= BlkI.nPos &&
rClrB.nNextBlockPos <= BlkI.nNextBlockPos)
{
// override equal block
if (rClrB.nPos == BlkI.nPos &&
rClrB.nNextBlockPos == BlkI.nNextBlockPos)
{
BlkI = rClrB; //arBlocks[i] = rClrB;
return;
}
// override BEGIN of the existing block
if (rClrB.nPos == BlkI.nPos &&
rClrB.nNextBlockPos < BlkI.nNextBlockPos)
{
BlkI.nPos = rClrB.nNextBlockPos;
//arBlocks[i] = BlkI;
arBlocks.InsertAt(i, rClrB);
return;
}
// override END of the existing block
if (rClrB.nPos > BlkI.nPos &&
rClrB.nNextBlockPos == BlkI.nNextBlockPos)
{
BlkI.nNextBlockPos = rClrB.nPos;
//arBlocks[i] = BlkI;
arBlocks.InsertAt(i+1, rClrB);
return;
}
BlkI2 = BlkI;
// INSERT inside to the existing block
BlkI2.nPos = rClrB.nNextBlockPos;
BlkI.nNextBlockPos = rClrB.nPos;
//arBlocks[i] = BlkI;
arBlocks.InsertAt(i+1, BlkI2);
arBlocks.InsertAt(i+1, rClrB);
return;
}
}
//** B. ** new block is bigger then existing block
nCount = (int)arBlocks.GetSize();
BOOL bInserted = FALSE;
for (i = nCount-1; i >= 0; i--)
{
XTP_EDIT_TEXTBLOCK BlkI = arBlocks[i];
if (rClrB.nNextBlockPos > BlkI.nPos && rClrB.nNextBlockPos < BlkI.nNextBlockPos)
{
BlkI.nPos = rClrB.nNextBlockPos;
arBlocks[i] = BlkI;
if (!bInserted)
{
arBlocks.InsertAt(i, rClrB);
bInserted = TRUE;
}
} else
if (rClrB.nPos <= BlkI.nPos && rClrB.nNextBlockPos >= BlkI.nNextBlockPos)
{
arBlocks.RemoveAt(i);
} else
if (rClrB.nNextBlockPos > BlkI.nPos && rClrB.nNextBlockPos < BlkI.nNextBlockPos )
{
BlkI.nNextBlockPos = rClrB.nPos;
arBlocks[i] = BlkI;
if (!bInserted)
{
arBlocks.InsertAt(i+1, rClrB);
bInserted = TRUE;
}
}
}
//----------------
if (!bInserted)
{
arBlocks.Add(rClrB);
}
}
void CXTPSyntaxEditLexTextSchema::GetRowColors(CTextIter* pTxtIter, int nRow,
int nColFrom, int nColTo,
const XTP_EDIT_COLORVALUES& clrDefault,
CXTPSyntaxEditTextBlockList* rBlocks,
CXTPSyntaxEditLexTextBlockPtr* pptrTBStartCache,
CXTPSyntaxEditLexTextBlock* pFirstSchTB)
{
if (!pTxtIter)
{
ASSERT(FALSE);
return;
}
XTP_EDIT_TEXTBLOCK tmpBlk;
tmpBlk.nPos = 0;
tmpBlk.nNextBlockPos = 0;
tmpBlk.clrBlock = clrDefault;
int nLineLen = pTxtIter->GetLineLen(nRow, FALSE);
if (!nLineLen)
{
return;
}
XTP_EDIT_LINECOL LCStart= {nRow, nColFrom};
XTP_EDIT_LINECOL LCEnd = {nRow, nLineLen};
if (nColTo > 0 && nColTo < nLineLen)
{
LCEnd.nCol = nColTo;
}
CXTPSyntaxEditTextBlockArray arBlocks;
XTP_EDIT_TEXTBLOCK bltTB;
bltTB.nPos = 0;
CSingleLock singleLock(GetDataLoker());
//BOOL bLocked = TryLockCS(&singleLock, GetDataLoker(), 30, 5);
BOOL bLocked = singleLock.Lock(30);
//---------------------------------------------------------------------------
CXTPSyntaxEditLexTextBlockPtr ptrTBfirst, ptrTBstart;
if (bLocked)
{
ptrTBfirst = GetBlocks();
if (pFirstSchTB)
{
ptrTBfirst.SetPtr(pFirstSchTB, TRUE);
}
if (pptrTBStartCache)
{
ptrTBstart = *pptrTBStartCache;
}
if (!ptrTBstart || ptrTBstart == ptrTBfirst ||
ptrTBstart->IsLookLikeClosed())
{
ptrTBstart = ptrTBfirst ? ptrTBfirst->m_ptrNext : NULL;
}
}
//= process first blk ====================================================
//
if (ptrTBfirst)
{
bltTB.clrBlock = clrDefault;
bltTB.lf = tmpBlk.lf;
GetTextAttributes(bltTB, ptrTBfirst);
bltTB.nPos = 0;
bltTB.nNextBlockPos = nLineLen;
AddClrBlock(bltTB, arBlocks);
TraceClrBlocks(arBlocks);
}
//========================================================================
CXTPSyntaxEditLexTextBlockPtrArray arTBStack;
CXTPSyntaxEditLexTextBlockPtr ptrTBStartCache;
for (CXTPSyntaxEditLexTextBlock* pTB = ptrTBstart; pTB; pTB = pTB->m_ptrNext)
{
//BOOL bEndValid = pTB->m_PosEndLC.IsValidData();
//if (bEndValid &&
// (pTB->m_PosEndLC < LCStart || pTB->m_PosEndLC < pTB->m_PosStartLC) ||
// !bEndValid && pTB->m_ptrParent)
if (pTB->GetPosEndLC() < LCStart || pTB->m_PosEndLC < pTB->m_PosStartLC)
{
continue;
}
if (LCEnd < pTB->m_PosStartLC)
{
break;
}
XTP_EDIT_LINECOL TB_PosEndLC = pTB->m_PosEndLC;
if (!pTB->m_PosEndLC.IsValidData() && !pTB->m_ptrParent)
{
TB_PosEndLC.nLine = nRow;
TB_PosEndLC.nCol = nLineLen;
}
if (!ptrTBStartCache)
{
ptrTBStartCache.SetPtr(pTB, TRUE);
ASSERT(pTB->m_ptrParent);
}
CXTPSyntaxEditLexTextBlock* pTBStackLast = NULL;
while (pTB->m_ptrNext && pTB->m_ptrNext->m_PosStartLC <= pTB->m_PosStartLC &&
pTB->m_ptrNext->m_PosEndLC.IsValidData() && pTB->m_PosEndLC.IsValidData() &&
pTB->m_ptrNext->m_PosEndLC > pTB->m_PosEndLC)
{
if (arTBStack.GetSize() == 0)
{
arTBStack.AddPtr(pTB, TRUE);
}
arTBStack.Add(pTB->m_ptrNext);
pTBStackLast = pTB->m_ptrNext;
pTB = pTB->m_ptrNext;
}
int nStackCount = (int)arTBStack.GetSize();
for (;nStackCount >= 0;)
{
if (nStackCount > 0)
{
pTB = arTBStack[nStackCount-1];
}
nStackCount--;
if (nStackCount >= 0)
{
arTBStack.RemoveAt(nStackCount);
TB_PosEndLC = pTB->m_PosEndLC;
if (!pTB->m_PosEndLC.IsValidData() /*&& !pTB->m_ptrParent*/)
{
TB_PosEndLC.nLine = nRow;
TB_PosEndLC.nCol = nLineLen;
}
}
//restore default values
bltTB.clrBlock = clrDefault;
bltTB.lf = tmpBlk.lf;
GetTextAttributes(bltTB, pTB);
if (pTB->m_PosStartLC > LCStart)
{
bltTB.nNextBlockPos = TB_PosEndLC.nLine == nRow ?
min(TB_PosEndLC.nCol+1, nLineLen) : nLineLen;
bltTB.nPos = pTB->m_PosStartLC.nCol;
AddClrBlock(bltTB, arBlocks);
TraceClrBlocks(arBlocks);
}
else
{
bltTB.nNextBlockPos = TB_PosEndLC.nLine == nRow ?
min(TB_PosEndLC.nCol+1, nLineLen) : nLineLen;
bltTB.nPos = 0;
AddClrBlock(bltTB, arBlocks);
TraceClrBlocks(arBlocks);
}
}
//--------------------
if (pTBStackLast)
{
pTB = pTBStackLast;
}
}
//----------------------------------------
if (pptrTBStartCache)
{
ptrTBstart = *pptrTBStartCache;
if (!ptrTBstart || ptrTBstart->IsLookLikeClosed())
{
*pptrTBStartCache = ptrTBStartCache;
ASSERT(!ptrTBStartCache || !ptrTBStartCache->IsLookLikeClosed());
}
}
//-----------------------------
if (bLocked)
{
singleLock.Unlock();
}
//===========================================================================
int nPos = 0;
int i;
for (i = 0; i < arBlocks.GetSize(); i++)
{
XTP_EDIT_TEXTBLOCK BlkI = arBlocks[i];
if (nPos < BlkI.nPos)
{
tmpBlk.nPos = nPos;
tmpBlk.nNextBlockPos = BlkI.nPos;
AddClrBlock(tmpBlk, arBlocks);
TraceClrBlocks(arBlocks);
i++;
}
nPos = BlkI.nNextBlockPos;
}
//===========================================================================
if (arBlocks.GetSize() == 0)
{
tmpBlk.nPos = 0;
tmpBlk.nNextBlockPos = nLineLen;
arBlocks.Add(tmpBlk);
}
else
{
//---------------------------------------------------------------------------
XTP_EDIT_TEXTBLOCK BlkI = arBlocks[arBlocks.GetSize()-1];
if (BlkI.nNextBlockPos < nLineLen)
{
tmpBlk.nPos = BlkI.nNextBlockPos;
tmpBlk.nNextBlockPos = nLineLen;
AddClrBlock(tmpBlk, arBlocks);
TraceClrBlocks(arBlocks);
}
}
//**************************************************************************
// DEBUG ////////////////////////////////////////////////////////////////
#ifdef DBG_TRACE_DRAW_BLOCKS
TRACE(_T("\n*** DBG_TRACE_DRAW_BLOCKS *** --------------------\n"));
TRACE(_T("row=%d, row_len = %d \n"), nRow, nLineLen);
#endif
// END DEBUG ////////////////////////////////////////////////////////////
for (i = 0; i < arBlocks.GetSize(); i++)
{
XTP_EDIT_TEXTBLOCK& BlkI = arBlocks[i];
rBlocks->AddTail(BlkI);
// DEBUG ////////////////////////////////////////////////////////////////
#ifdef DBG_TRACE_DRAW_BLOCKS
TRACE(_T("(%02d) start =%d, ?end=%d, color=%X \n"), i, BlkI.nPos,
BlkI.nNextBlockPos, BlkI.clrBlock.crText);
#endif
// END DEBUG ////////////////////////////////////////////////////////////
}
}
void CXTPSyntaxEditLexTextSchema::GetCollapsableBlocksInfo(int nRow,
CXTPSyntaxEditRowsBlockArray& rArBlocks,
CXTPSyntaxEditLexTextBlockPtr* pptrTBStartCache)
{
static const CString s_strCollapsedText_def = _T("[..]");
rArBlocks.RemoveAll();
CSingleLock singleLock(GetDataLoker());
//BOOL bLocked = TryLockCS(&singleLock, GetDataLoker(), 30);
BOOL bLocked = singleLock.Lock(30);
if (!bLocked)
{
return;
}
XTP_EDIT_ROWSBLOCK tmpCoBlk;
//---------------------------------------------------------------------------
ASSERT(bLocked);
CXTPSyntaxEditLexTextBlockPtr ptrTBstart;
if (pptrTBStartCache)
{
ptrTBstart = *pptrTBStartCache;
}
if (!ptrTBstart || ptrTBstart->IsLookLikeClosed())
{
ptrTBstart = GetBlocks();
}
CXTPSyntaxEditLexTextBlockPtr ptrTBStartCache;
for (CXTPSyntaxEditLexTextBlock* pTB = ptrTBstart; pTB; pTB = pTB->m_ptrNext)
{
if (nRow >= 0 && nRow < pTB->m_PosStartLC.nLine)
{
break;
}
XTP_EDIT_LINECOL TB_PosEndLC = pTB->GetPosEndLC(); // pTB->m_PosEndLC;
if (nRow < 0 || (nRow >= pTB->m_PosStartLC.nLine &&
nRow <= TB_PosEndLC.nLine) )
{
if (!ptrTBStartCache && pTB->m_ptrParent)
{
ptrTBStartCache.SetPtr(pTB, TRUE);
}
if (pTB->m_PosStartLC.nLine < TB_PosEndLC.nLine &&
pTB->m_ptrParent )
{
CXTPSyntaxEditLexClass* pLexClass = pTB->m_ptrLexClass;
ASSERT(pLexClass);
int nCollapsable = pLexClass->IsCollapsable();
if (pLexClass && nCollapsable &&
(nCollapsable == 2 || !pTB->m_bEndByParent && TB_PosEndLC != XTP_EDIT_LINECOL::MAXPOS))
{
tmpCoBlk.lcStart = pTB->m_PosStartLC;
tmpCoBlk.lcEnd = TB_PosEndLC;
CXTPSyntaxEditLexVariantPtr ptrLVtext;
ptrLVtext = pLexClass->GetAttribute(XTPLEX_ATTR_COLLAPSEDTEXT, FALSE);
if (ptrLVtext && ptrLVtext->IsStrType())
{
tmpCoBlk.strCollapsedText = ptrLVtext->GetStr();
} else {
tmpCoBlk.strCollapsedText = s_strCollapsedText_def;
}
rArBlocks.Add(tmpCoBlk);
}
}
}
}
//----------------------------------------
if (pptrTBStartCache)
{
ptrTBstart = *pptrTBStartCache;
if (!ptrTBstart || ptrTBstart->IsLookLikeClosed())
{
*pptrTBStartCache = ptrTBStartCache;
ASSERT(!ptrTBStartCache || !ptrTBStartCache->IsLookLikeClosed());
}
}
}
void CXTPSyntaxEditLexTextSchema::ApplyThemeRecursive(CXTPSyntaxEditColorTheme* pTheme,
CXTPSyntaxEditLexClassPtrArray* ptrClasses)
{
// if pTheme == NULL - Restore default values only
const static CString strAttrPref = XTPLEX_ATTR_TXTPREFIX;
ASSERT(ptrClasses);
int nCount = ptrClasses ? (int)ptrClasses->GetSize() : 0;
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrC = ptrClasses->GetAt(i);
if (!ptrC)
{
ASSERT(FALSE);
continue;
}
// Traverse the tree
ApplyThemeRecursive(pTheme, ptrC->GetChildren());
ApplyThemeRecursive(pTheme, ptrC->GetChildrenDyn());
//-------------------------------------------------------
const CString strCName = ptrC->GetClassName();
// restore default attributes (colors)
CXTPSyntaxEditLexClassPtr ptrCDefault = m_pClassSchema->GetPreBuildClass(strCName);
ASSERT(ptrCDefault);
if (ptrCDefault)
{
ptrC->CopyAttributes(ptrCDefault, XTPLEX_ATTR_TXTPREFIX);
}
CXTPSyntaxEditColorInfo* pColors = pTheme ? pTheme->GetColorInfo(strCName, pTheme->GetFileName()) : NULL;
if (!pColors)
{
continue;
}
// Apply new attributes (colors)
POSITION posParam = pColors->GetFirstParamNamePosition();
while (posParam)
{
static const int c_nClrPrefLen = (int)_tcsclen(XTPLEX_ATTR_COLORPREFIX);
CString strParamName = pColors->GetNextParamName(posParam);
DWORD dwValue = pColors->GetHexParam(strParamName);
CString strAttrName = strAttrPref + strParamName;
if (_tcsnicmp(strAttrName, XTPLEX_ATTR_COLORPREFIX, c_nClrPrefLen) == 0)
{
dwValue = XTP_EDIT_RGB_INT2CLR(dwValue);
}
CXTPSyntaxEditLexVariant lvAttr((int)dwValue);
ptrC->SetAttribute(strAttrName, lvAttr);
}
}
}
void CXTPSyntaxEditLexTextSchema::ApplyTheme(CXTPSyntaxEditColorTheme* pTheme)
{
// if pTheme == NULL - Restore default values only
CSingleLock singleLockCls(GetClassSchLoker(), TRUE);
CSingleLock singleLock(GetDataLoker(), TRUE);
CXTPSyntaxEditLexClassPtrArray* ptrClassesFull = m_pClassSchema->GetClasses(FALSE);
CXTPSyntaxEditLexClassPtrArray* ptrClassesShort = m_pClassSchema->GetClasses(TRUE);
ApplyThemeRecursive(pTheme, ptrClassesFull);
ApplyThemeRecursive(pTheme, ptrClassesShort);
}
////////////////////////////////////////////////////////////////////////////
// CXTPSyntaxEditLexClassSchema
CXTPSyntaxEditLexClassSchema::CXTPSyntaxEditLexClassSchema()
{
XTPGetLexAutomatMemMan()->Lock();
}
CXTPSyntaxEditLexClassSchema::~CXTPSyntaxEditLexClassSchema()
{
XTPGetLexAutomatMemMan()->Unlok();
}
void CXTPSyntaxEditLexClassSchema::AddPreBuildClass(CXTPSyntaxEditLexClass* pClass)
{
CXTPSyntaxEditLexClassPtr ptrC(pClass, TRUE);
m_arPreBuildClassesList.Add(ptrC);
}
CXTPSyntaxEditLexClassPtrArray* CXTPSyntaxEditLexClassSchema::GetChildrenFor(CXTPSyntaxEditLexClass* pClass,
BOOL& rbSelfChild)
{
rbSelfChild = FALSE;
CXTPSyntaxEditLexClassPtrArray arChildren;
BOOL bForFile = pClass == NULL;
int nChidrenOpt = xtpEditOptChildren_Any;
CStringArray arChidrenData;
CString strParentName;
if (pClass)
{
pClass->GetChildrenOpt(nChidrenOpt, arChidrenData);
strParentName = pClass->GetClassName();
}
if (nChidrenOpt == xtpEditOptChildren_No)
{
return NULL;
}
int nCCount = (int)m_arPreBuildClassesList.GetSize();
for (int i = 0; i < nCCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrC = m_arPreBuildClassesList[i];
int nParentOpt;
CStringArray arParentData;
ptrC->GetParentOpt(nParentOpt, arParentData);
CString strCName = ptrC->GetClassName();
if (bForFile && nParentOpt == xtpEditOptParent_file)
{
arChildren.Add(ptrC);
}
else if (!bForFile && nParentOpt == xtpEditOptParent_direct)
{
ASSERT(pClass);
if (nChidrenOpt == xtpEditOptChildren_List)
{
if (Find_noCase(arChidrenData, strCName) < 0)
{
continue;
}
}
int nNCount = (int)arParentData.GetSize();
for (int n = 0; n < nNCount; n++)
{
CString strCN = arParentData[n];
if (strCN.CompareNoCase(strParentName) == 0)
{
if (strCName.CompareNoCase(strParentName) == 0)
{
rbSelfChild = TRUE;
}
else
{
arChildren.Add(ptrC);
}
break;
}
}
}
}
//--------------------------------
CXTPSyntaxEditLexClassPtrArray* pArChildren = NULL;
if (arChildren.GetSize())
{
pArChildren = new CXTPSyntaxEditLexClassPtrArray;
if (pArChildren)
{
pArChildren->Append(arChildren);
}
}
return pArChildren;
}
int CXTPSyntaxEditLexClassSchema::CanBeParentDynForChild(CString strParentName,
CXTPSyntaxEditLexClass* pCChild)
{
if (!pCChild)
{
ASSERT(FALSE);
return FALSE;
}
int nParentOpt;
CStringArray arParentData;
pCChild->GetParentOpt(nParentOpt, arParentData);
if (nParentOpt != xtpEditOptParent_dyn)
{
return -1;
}
int nCCount = (int)m_arPreBuildClassesList.GetSize(), n;
for (int i = 0; i < nCCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrC = m_arPreBuildClassesList[i];
CString strCName = ptrC->GetClassName();
int nNCount = (int)arParentData.GetSize();
for (n = 0; n < nNCount; n++)
{
CString strCN = arParentData[n];
if (strParentName.CompareNoCase(strCN) == 0)
{
return TRUE;
}
}
//-------------------------------------------------------
if (nParentOpt == xtpEditOptParent_dyn )
{
int nDataCount = (int)arParentData.GetSize();
for (n = 0; n < nDataCount; n++)
{
CString strCN = arParentData[n];
if (strCName.CompareNoCase(strCN) == 0)
{
BOOL bCanDyn = CanBeParentDynForChild(strParentName, ptrC);
if (bCanDyn)
{
return TRUE;
}
}
}
}
}
return FALSE;
}
CXTPSyntaxEditLexClass* CXTPSyntaxEditLexClassSchema::GetPreBuildClass(const CString& strName)
{
int nCCount = (int)m_arPreBuildClassesList.GetSize();
for (int i = 0; i < nCCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrC = m_arPreBuildClassesList[i];
const CString strCName = ptrC->GetClassName();
if (strName.CompareNoCase(strCName) == 0)
{
return ptrC.Detach();
}
}
return NULL;
}
void CXTPSyntaxEditLexClassSchema::GetDynParentsList(CXTPSyntaxEditLexClass* pClass,
CStringArray& rarDynParents,
CStringArray& rarProcessedClasses)
{
if (!pClass)
{
ASSERT(FALSE);
return;
}
CString strClassName = pClass->GetClassName();
if (Find_noCase(rarProcessedClasses, strClassName) >= 0)
{
return;
}
rarProcessedClasses.Add(strClassName);
int nParentOpt;
CStringArray arParentData;
pClass->GetParentOpt(nParentOpt, arParentData);
if (nParentOpt == xtpEditOptParent_file)
{
return;
}
ConcatenateArrays_noCase(rarDynParents, arParentData);
int nNCount = (int)arParentData.GetSize();
for (int n = 0; n < nNCount; n++)
{
CString strParent1 = arParentData[n];
if (strClassName.CompareNoCase(strParent1) == 0)
{
continue;
}
CXTPSyntaxEditLexClassPtr ptrC = GetPreBuildClass(strParent1);
if (ptrC)
{
GetDynParentsList(ptrC, rarDynParents, rarProcessedClasses);
}
else
{
//TRACE
}
}
}
CXTPSyntaxEditLexClassPtrArray* CXTPSyntaxEditLexClassSchema::GetDynChildrenFor(CXTPSyntaxEditLexClass* pClass,
BOOL& rbSelfChild)
{
rbSelfChild = FALSE;
int nChidrenOpt = xtpEditOptChildren_Any;
CStringArray arChidrenData;
if (pClass)
{
pClass->GetChildrenOpt(nChidrenOpt, arChidrenData);
}
if (nChidrenOpt == xtpEditOptChildren_No)
{
return NULL;
}
if (!pClass)
return NULL;
CString strMainCName = pClass->GetClassName();
CStringArray arMainParents;
CStringArray arProcessedClasses;
GetDynParentsList(pClass, arMainParents, arProcessedClasses);
CXTPSyntaxEditLexClassPtrArray arDynChildren;
int nCCount = (int)m_arPreBuildClassesList.GetSize();
for (int i = 0; i < nCCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrC = m_arPreBuildClassesList[i];
CString strCName = ptrC->GetClassName();
if (nChidrenOpt == xtpEditOptChildren_List)
{
if (Find_noCase(arChidrenData, strCName) < 0)
{
continue;
}
}
int nCanRes = CanBeParentDynForChild(strMainCName, ptrC);
if (nCanRes > 0)
{
if (strMainCName.CompareNoCase(strCName) == 0)
{
rbSelfChild = TRUE;
}
else
{
arDynChildren.Add(ptrC);
}
continue;
}
if (nCanRes < 0)
{
continue;
}
int nMPCount = (int)arMainParents.GetSize();
for (int n = 0; n < nMPCount; n++)
{
CString strMPName = arMainParents[n];
if (CanBeParentDynForChild(strMPName, ptrC))
{
arDynChildren.Add(ptrC);
break;
}
}
}
//--------------------------------
CXTPSyntaxEditLexClassPtrArray* pArDynChildren = NULL;
if (arDynChildren.GetSize())
{
pArDynChildren = new CXTPSyntaxEditLexClassPtrArray;
if (pArDynChildren)
{
pArDynChildren->Append(arDynChildren);
}
}
return pArDynChildren;
}
CXTPSyntaxEditLexObj_ActiveTags* CXTPSyntaxEditLexClassSchema::GetActiveTagsFor(
CXTPSyntaxEditLexClass* pTopClass)
{
if (!pTopClass)
{
ASSERT(FALSE);
return NULL;
}
return pTopClass->GetActiveTags();
}
BOOL CXTPSyntaxEditLexClassSchema::Copy(CXTPSyntaxEditLexClassSchema* pDest)
{
if (!pDest)
{
ASSERT(FALSE);
return FALSE;
}
//------------------------------------------------------------------------
int nCount = (int)m_arPreBuildClassesList.GetSize();
int i;
for (i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrC0 = m_arPreBuildClassesList.GetAt(i);
if (!ptrC0)
{
continue;
}
CXTPSyntaxEditLexClassPtr ptrC0_new = ptrC0->Clone(this);
if (!ptrC0_new)
{
return FALSE;
}
pDest->m_arPreBuildClassesList.Add(ptrC0_new);
}
//------------------------------------------------------------------------
nCount = (int)m_arClassesTreeFull.GetSize();
for (i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrCfile = m_arClassesTreeFull.GetAt(i);
if (!ptrCfile)
{
continue;
}
CXTPSyntaxEditLexClassPtr ptrCFnew = ptrCfile->Clone(this);
if (!CopyChildrenFor(FALSE, ptrCFnew, ptrCfile, 0))
{
return FALSE;
}
int nStartCount = 0;
ptrCFnew->BuildActiveTags(nStartCount);
// //CXTPSyntaxEditLexVariantPtrArray* ptrAT = ptrCFnew->BuildActiveTags(nStartCount);
// //ConcatenateLVArrays(&pDest->m_arAllActiveTagsFull, ptrAT, nStartCount);
pDest->m_arClassesTreeFull.Add(ptrCFnew);
}
//------------------------------------------------------------------------
BOOL bResShortTree = pDest->Build_ShortTree();
//-* Post Build processing ----------------------------
if (!PostBuild_Step(&pDest->m_arClassesTreeShort))
{
return FALSE;
}
if (!PostBuild_Step(&pDest->m_arClassesTreeFull))
{
return FALSE;
}
return bResShortTree;
}
BOOL CXTPSyntaxEditLexClassSchema::Build()
{
CXTPSyntaxEditLexClass::CloseClasses(&m_arClassesTreeFull);
CXTPSyntaxEditLexClass::CloseClasses(&m_arClassesTreeShort);
int nClassID = 1;
BOOL bUnused;
CXTPSyntaxEditLexClassPtrArray* ptrArCfile = GetChildrenFor(NULL, bUnused);
int nCount = ptrArCfile ? (int)ptrArCfile->GetSize() : 0;
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrCfile = ptrArCfile->GetAt(i);
CXTPSyntaxEditLexClassPtr ptrCFnew = GetNewClass(TRUE);
if (!ptrCFnew)
{
delete ptrArCfile;
return FALSE;
}
ptrCFnew->CopyFrom(ptrCfile);
CXTPSyntaxEditLexVariant lvID(nClassID++);
ptrCFnew->SetAttribute(XTPLEX_ATTRCLASSID, lvID);
#ifdef DBG_TRACE_LOAD_CLASS_SCH
ptrCFnew->Dump(_T(""));
#endif
CString strCNnew = ptrCFnew->GetClassName();
CStringArray arAddedStack;
arAddedStack.Add(strCNnew);
if (!Build_ChildrenFor(FALSE, ptrCFnew, arAddedStack, nClassID, 0))
{
delete ptrArCfile;
return FALSE;
}
arAddedStack.RemoveAll();
if (!Build_ChildrenFor(TRUE, ptrCFnew, arAddedStack, nClassID, 0))
{
delete ptrArCfile;
return FALSE;
}
int nStartCount = 0;
ptrCFnew->BuildActiveTags(nStartCount);
//CXTPSyntaxEditLexVariantPtrArray* ptrAT = ptrCFnew->BuildActiveTags(nStartCount);
//ConcatenateLVArrays(&m_arAllActiveTagsFull, ptrAT, nStartCount);
m_arClassesTreeFull.Add(ptrCFnew);
}
delete ptrArCfile;
#ifdef DBG_TRACE_LOAD_CLASS_SCH
// m_arAllActiveTagsFull.Dump(_T("AllActiveTags FULL=: "));
#endif
if (!Build_ShortTree())
{
return FALSE;
}
//-* Post Build processing ----------------------------
if (!PostBuild_Step(&m_arClassesTreeShort))
{
return FALSE;
}
if (!PostBuild_Step(&m_arClassesTreeFull))
{
return FALSE;
}
//----------------------
//BOOL bAsc = TRUE, bNoCase = FALSE;
//SortTagsInLexVarArray(m_arAllActiveTagsFull, bAsc, bNoCase);
//SortTagsInLexVarArray(m_arAllActiveTagsShort, bAsc, bNoCase);
// m_arAllActiveTagsFull.BuildAutomat();
// m_arAllActiveTagsShort.BuildAutomat();
//-* Post Build END ------------------------------------------------------
#ifdef _DEBUG
AfxDump(XTPGetLexAutomatMemMan());
#endif
//------------------------------------------------------------------------
return TRUE;
}
BOOL CXTPSyntaxEditLexClassSchema::Build_ShortTree()
{
#ifdef DBG_TRACE_LOAD_CLASS_SCH
TRACE(_T("\n****************** Short classes Tree ********************** \n"));
#endif
int nCount = (int)m_arClassesTreeFull.GetSize();
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrCfile = m_arClassesTreeFull.GetAt(i);
if (!ptrCfile || ptrCfile->GetAttribute_BOOL(XTPLEX_ATTR_PARSEONSCREEN, FALSE))
{
continue;
}
CXTPSyntaxEditLexClassPtr ptrCFnew = GetNewClass(TRUE);
if (!ptrCFnew)
{
return FALSE;
}
ptrCFnew->CopyFrom(ptrCfile);
#ifdef DBG_TRACE_LOAD_CLASS_SCH
ptrCFnew->Dump(_T(""));
#endif
if (!CopyChildrenFor(TRUE, ptrCFnew, ptrCfile, 0))
{
return FALSE;
}
int nStartCount = 0;
ptrCFnew->BuildActiveTags(nStartCount);
//CXTPSyntaxEditLexVariantPtrArray* ptrAT = ptrCFnew->BuildActiveTags(nStartCount);
//ConcatenateLVArrays(&m_arAllActiveTagsShort, ptrAT, nStartCount);
m_arClassesTreeShort.Add(ptrCFnew);
}
#ifdef DBG_TRACE_LOAD_CLASS_SCH
// m_arAllActiveTagsShort.Dump(_T("AllActiveTags Short=: "));
#endif
return TRUE;
}
BOOL CXTPSyntaxEditLexClassSchema::CopyChildrenFor(BOOL bShort, CXTPSyntaxEditLexClass* pCDest,
CXTPSyntaxEditLexClass* pCSrc, int nLevel)
{
#ifdef DBG_TRACE_LOAD_CLASS_SCH
CString strTraceOffset0, strTraceOffset;
for (int t = 0; t <= nLevel; t++)
{
strTraceOffset0 += _T(" ");
}
#endif
CXTPSyntaxEditLexClassPtrArray* pArClasses[3];
pArClasses[0] = pCSrc->GetChildren();
pArClasses[1] = pCSrc->GetChildrenDyn();
pArClasses[2] = pCSrc->GetChildrenSelfRef();
for (int nC = 0; nC < _countof(pArClasses); nC++)
{
BOOL bDynamic = (nC == 1);
BOOL bSelf = (nC == 2);
#ifdef DBG_TRACE_LOAD_CLASS_SCH
if (bDynamic)
{
strTraceOffset = strTraceOffset0 + _T("dyn: ");
}
else if (bSelf)
{
strTraceOffset = strTraceOffset0 + _T("self: ");
}
else
{
strTraceOffset = strTraceOffset0;
}
#endif
int nCount = pArClasses[nC] ? (int)pArClasses[nC]->GetSize() : 0;
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrCsrc = pArClasses[nC]->GetAt(i);
if (!ptrCsrc ||
bShort && ptrCsrc->GetAttribute_BOOL(XTPLEX_ATTR_PARSEONSCREEN, FALSE))
{
continue;
}
if (bSelf)
{
pCDest->AddChild(pCDest, FALSE);
#ifdef DBG_TRACE_LOAD_CLASS_SCH
pCDest->Dump(strTraceOffset);
#endif
}
else
{
CXTPSyntaxEditLexClassPtr ptrCnew = GetNewClass(FALSE);
if (!ptrCnew)
{
return FALSE;
}
ptrCnew->CopyFrom(ptrCsrc);
pCDest->AddChild(ptrCnew, bDynamic);
#ifdef DBG_TRACE_LOAD_CLASS_SCH
ptrCnew->Dump(strTraceOffset);
#endif
ASSERT(pCSrc != ptrCsrc);
if (!CopyChildrenFor(bShort, ptrCnew, ptrCsrc, nLevel+1))
{
return FALSE;
}
}
}
}
return TRUE;
}
BOOL CXTPSyntaxEditLexClassSchema::Build_ChildrenFor(BOOL bDynamic,
CXTPSyntaxEditLexClass* pCBase,
CStringArray& rarAdded,
int& rnNextClassID,
int nLevel)
{
if (!pCBase)
{
ASSERT(FALSE);
return FALSE;
}
#ifdef DBG_TRACE_LOAD_CLASS_SCH
CString strTraceOffset;
for (int t = 0; t <= nLevel; t++)
{
strTraceOffset += _T(" ");
}
if (bDynamic)
{
strTraceOffset += _T("dyn: ");
}
#endif
BOOL bSelfChild = FALSE;
CXTPSyntaxEditLexClassPtrArray* ptrArChildren;
if (bDynamic)
{
ptrArChildren = GetDynChildrenFor(pCBase, bSelfChild);
}
else
{
ptrArChildren = GetChildrenFor(pCBase, bSelfChild);
}
int nCount = ptrArChildren ? (int)ptrArChildren->GetSize() : 0;
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrCsrc = ptrArChildren->GetAt(i);
CString strCNsrc = ptrCsrc->GetClassName();
if (nLevel == 0)
{
rarAdded.RemoveAll();
}
//int nFIdx = Find_noCase(rarAdded, strCNsrc);
//if (nFIdx >= 0)
int nClsCount = FindStrCount(rarAdded, strCNsrc, FALSE);
int nRecurrenceDepth = ptrCsrc->GetAttribute_int(XTPLEX_ATTR_RECURRENCEDEPTH, TRUE, 1);;
if (nClsCount >= nRecurrenceDepth)
{
//CXTPSyntaxEditLexClassPtr ptrC(pCBase->FindParent(strCNsrc), TRUE);
//if (ptrC) {
// pCBase->GetChildrenSelfRef()->Add(ptrC);
//#ifdef DBG_TRACE_LOAD_CLASS_SCH
// strTraceOffset += _T("self: ");
// ptrC->Dump(strTraceOffset);
//#endif
//}
continue;
}
rarAdded.Add(strCNsrc);
CXTPSyntaxEditLexClassPtr ptrCnew = GetNewClass(FALSE);
if (!ptrCnew)
{
delete ptrArChildren;
return FALSE;
}
ptrCnew->CopyFrom(ptrCsrc);
CXTPSyntaxEditLexVariant lvID(rnNextClassID++);
ptrCnew->SetAttribute(XTPLEX_ATTRCLASSID, lvID);
pCBase->AddChild(ptrCnew, bDynamic);
#ifdef DBG_TRACE_LOAD_CLASS_SCH
ptrCnew->Dump(strTraceOffset);
#endif
Build_ChildrenFor(bDynamic, ptrCnew, rarAdded, rnNextClassID, nLevel+1);
Build_ChildrenFor(!bDynamic, ptrCnew, rarAdded, rnNextClassID, nLevel+1);
int nStackCount = (int)rarAdded.GetSize();
if (nStackCount > 0)
{
rarAdded.RemoveAt(nStackCount - 1);
}
}
delete ptrArChildren;
//----------------------------------
if (bSelfChild)
{
if (pCBase->AddChild(pCBase, bDynamic))
{
#ifdef DBG_TRACE_LOAD_CLASS_SCH
strTraceOffset += _T("self: ");
pCBase->Dump(strTraceOffset);
#endif
}
}
return TRUE;
}
BOOL CXTPSyntaxEditLexClassSchema::PostBuild_Step(CXTPSyntaxEditLexClassPtrArray* pArClasses)
{
if (!pArClasses)
{
return TRUE;
}
int nCount = (int)pArClasses->GetSize();
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrC = pArClasses->GetAt(i);
ptrC->SortTags();
CXTPSyntaxEditLexClassPtrArray* ptrCh1 = ptrC->GetChildren();
CXTPSyntaxEditLexClassPtrArray* ptrCh2 = ptrC->GetChildrenDyn();
if (!PostBuild_Step(ptrCh1))
{
return FALSE;
}
if (!PostBuild_Step(ptrCh2))
{
return FALSE;
}
}
return TRUE;
}
void CXTPSyntaxEditLexClassSchema::Close()
{
RemoveAll();
}
void CXTPSyntaxEditLexClassSchema::RemoveAll()
{
CXTPSyntaxEditLexClass::CloseClasses(&m_arPreBuildClassesList);
CXTPSyntaxEditLexClass::CloseClasses(&m_arClassesTreeFull);
CXTPSyntaxEditLexClass::CloseClasses(&m_arClassesTreeShort);
}
CXTPSyntaxEditLexClassPtrArray* CXTPSyntaxEditLexClassSchema::GetClasses(BOOL bShortSch)
{
return bShortSch? &m_arClassesTreeShort: &m_arClassesTreeFull;
}
CXTPSyntaxEditLexClassPtrArray* CXTPSyntaxEditLexClassSchema::GetPreBuildClasses()
{
return &m_arPreBuildClassesList;
}
CXTPSyntaxEditLexClass* CXTPSyntaxEditLexClassSchema::GetNewClass(BOOL bForFile)
{
if (bForFile)
{
return new CXTPSyntaxEditLexClass_file();
}
return new CXTPSyntaxEditLexClass();
}
////////////////////////////////////////////////////////////////////////////
// CXTPSyntaxEditLexParseContext
//class CXTPSyntaxEditLexParseContext : public CXTPInternalUnknown
//CXTPSyntaxEditLexParseContext::CXTPSyntaxEditLexParseContext(CXTPSyntaxEditLexTextBlock* pBlock) :
// CXTPInternalUnknown(pBlock)
//{
// ASSERT(pBlock);
//
// m_pTextBlock = pBlock;
//}
//
//CXTPSyntaxEditLexParseContext::~CXTPSyntaxEditLexParseContext()
//{
//}
//
//void CXTPSyntaxEditLexParseContext::Set(LPCTSTR pcszParopPath, CXTPSyntaxEditLexVariant* pVar)
//{
// if (pVar == NULL) {
// m_mapVars.RemoveKey(pcszParopPath);
//
// }
// else {
// CXTPSyntaxEditLexVariantPtr ptrVar = new CXTPSyntaxEditLexVariant(*pVar);
//
// m_mapVars.SetAt(pcszParopPath, ptrVar);
// }
//}
//
//CXTPSyntaxEditLexVariant* CXTPSyntaxEditLexParseContext::Get(LPCTSTR pcszParopPath)
//{
// CXTPSyntaxEditLexVariantPtr ptrVar;
//
// if (m_mapVars.Lookup(pcszParopPath, ptrVar)) {
// return ptrVar.Detach();
// }
// return NULL;
//}
//
//
//CXTPSyntaxEditLexTextBlock* CXTPSyntaxEditLexParseContext::GetTextBlock()
//{
// if (m_pTextBlock) {
// m_pTextBlock->InternalAddRef();
// }
// return m_pTextBlock;
//}
//
//void CXTPSyntaxEditLexParseContext::Close()
//{
// m_pTextBlock = NULL;
// m_mapVars.RemoveAll();
//}
////////////////////////////////////////////////////////////////////////////
// CXTPSyntaxEditLexTextBlock
CXTPSyntaxEditLexTextBlock::CXTPSyntaxEditLexTextBlock() //:
//m_parseContext(this)
{
m_PosStartLC.nLine = 0;
m_PosStartLC.nCol = 0;
m_PosEndLC.nLine = 0;
m_PosEndLC.nCol = 0;
m_nStartTagLen = 0;
m_nEndTagXLCLen = 0;
m_bEndByParent = FALSE;
}
CXTPSyntaxEditLexTextBlock::~CXTPSyntaxEditLexTextBlock()
{
}
void CXTPSyntaxEditLexTextBlock::Close()
{
m_ptrLexClass = NULL;
m_ptrParent = NULL;
m_ptrPrev = NULL;
m_ptrNext= NULL;
m_ptrLastChild = NULL;
}
CXTPSyntaxEditLexTextBlock* CXTPSyntaxEditLexTextBlock::GetPrevChild(CXTPSyntaxEditLexTextBlock* pChild,
BOOL bWithAddRef)
{
while (pChild && pChild != this)
{
if (!pChild->m_ptrPrev)
{
return NULL;
}
pChild = pChild->m_ptrPrev;
if (pChild && (CXTPSyntaxEditLexTextBlock*)pChild->m_ptrParent == this)
{
if (bWithAddRef)
{
pChild->InternalAddRef();
}
return pChild;
}
}
return NULL;
}
int CXTPSyntaxEditLexTextBlock::EndChildren(CXTPSyntaxEditLexTextSchema* pTxtSch, BOOL bEndByParent)
{
int nCount = 0;
//CSingleLock singleLock(GetDataLoker(), TRUE);
CXTPSyntaxEditLexTextBlock* pChTB = m_ptrLastChild;
while (pChTB)
{
if (!pChTB->m_PosEndLC.IsValidData())
{
pChTB->m_PosEndLC = m_PosEndLC;
pChTB->m_nEndTagXLCLen = m_nEndTagXLCLen;
pChTB->m_bEndByParent = bEndByParent;
nCount++;
if (pTxtSch)
{
pTxtSch->SendEvent_OnTextBlockParsed(pChTB);
}
nCount += pChTB->EndChildren(pTxtSch, bEndByParent);
}
pChTB = GetPrevChild(pChTB, FALSE);
}
return nCount;
}
BOOL CXTPSyntaxEditLexTextBlock::IsLookLikeClosed() const
{
if (!m_ptrLexClass && !m_ptrPrev && !m_ptrNext && !m_ptrLastChild &&
!m_ptrParent)
{
return TRUE;
}
return FALSE;
}
BOOL CXTPSyntaxEditLexTextBlock::IsInclude(CXTPSyntaxEditLexTextBlock* pTB2) const
{
if (!pTB2)
{
ASSERT(FALSE);
return FALSE;
}
ASSERT(m_PosStartLC.IsValidData() && pTB2->m_PosStartLC.IsValidData());
if (m_PosStartLC <= pTB2->m_PosStartLC && m_PosEndLC >= pTB2->m_PosEndLC &&
m_PosEndLC.IsValidData() && pTB2->m_PosEndLC.IsValidData() )
{
return TRUE;
}
return FALSE;
}
BOOL CXTPSyntaxEditLexTextBlock::IsEqualLexClasses(CXTPSyntaxEditLexTextBlock* pTB2) const
{
if (!m_ptrLexClass || !pTB2 || !pTB2->m_ptrLexClass)
{
ASSERT(FALSE);
return FALSE;
}
CString strThisClass = m_ptrLexClass->GetClassName();
CString strTB2Class = pTB2->m_ptrLexClass->GetClassName();
int nCmpRes = strThisClass.CompareNoCase(strTB2Class);
return nCmpRes==0;
}
////////////////////////////////////////////////////////////////////////////
// CXTPSyntaxEditLexAnalyser
CXTPSyntaxEditLexParser::CXTPSyntaxEditLexParser()
{
m_pParseThread = NULL;
m_nParseThreadPriority = THREAD_PRIORITY_NORMAL;
// THREAD_PRIORITY_BELOW_NORMAL
// THREAD_PRIORITY_ABOVE_NORMAL;
// m_pSinkMT->SetOuter(this);
m_pSinkMT = new CXTPNotifySinkMT();
m_pConnection = new CXTPNotifyConnection;
m_ptrTextSchema = 0;
m_pSchOptions_default = new CXTPSyntaxEditLexParserSchemaOptions();
}
CXTPSyntaxEditLexParser::~CXTPSyntaxEditLexParser()
{
Close();
ASSERT(m_ptrTextSchema == 0);
#ifdef XTP_DBG_DUMP_OBJ
afxDump.SetDepth( 1 );
#endif
CMDTARGET_RELEASE(m_pConnection);
CMDTARGET_RELEASE(m_pSchOptions_default);
RemoveAllOptions();
m_pSinkMT->Delete();
}
void CXTPSyntaxEditLexParser::RemoveAllOptions()
{
POSITION pos = m_mapSchOptions.GetStartPosition();
while (pos)
{
CXTPSyntaxEditLexParserSchemaOptions* pOptions = NULL;
CString key;
m_mapSchOptions.GetNextAssoc(pos, key, pOptions);
CMDTARGET_RELEASE(pOptions);
}
m_mapSchOptions.RemoveAll();
}
CXTPNotifyConnection* CXTPSyntaxEditLexParser::GetConnection()
{
return m_pConnection;
}
CXTPSyntaxEditLexParser::CXTPSyntaxEditParseThreadParams::CXTPSyntaxEditParseThreadParams()
{
ptrBuffer = NULL;
}
void CXTPSyntaxEditLexParser::CXTPSyntaxEditParseThreadParams::AddParseZone(const CXTPSyntaxEditTextRegion& rZone)
{
const int cnEpsilon = XTP_EDIT_XLC(3, 0);
int nCount = (int)arInvalidZones.GetSize();
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditTextRegion zoneI = arInvalidZones[i];
if (rZone.m_posEnd >= zoneI.m_posStart &&
rZone.m_posStart <= zoneI.m_posStart
||
rZone.m_posEnd.GetXLC()+cnEpsilon >= zoneI.m_posStart.GetXLC() &&
rZone.m_posStart <= zoneI.m_posStart
)
{
zoneI.m_posStart = rZone.m_posStart;
arInvalidZones[i] = zoneI;
return;
}
else if (rZone.m_posStart <= zoneI.m_posEnd &&
rZone.m_posEnd >= zoneI.m_posEnd
||
rZone.m_posStart.GetXLC()-cnEpsilon <= zoneI.m_posEnd.GetXLC() &&
rZone.m_posEnd >= zoneI.m_posEnd
)
{
zoneI.m_posEnd = rZone.m_posEnd;
arInvalidZones[i] = zoneI;
return;
}
else if (rZone.m_posStart >= zoneI.m_posStart
&& rZone.m_posEnd <= zoneI.m_posEnd)
{
return; //nothing
}
}
arInvalidZones.Add(rZone);
}
void CXTPSyntaxEditLexParser::Close()
{
CSingleLock singLockMain(&m_csParserData);
CloseParseThread();
m_pSinkMT->UnadviseAll();
CMDTARGET_RELEASE(m_ptrTextSchema);
}
void CXTPSyntaxEditLexParser::SelfCloseParseThread()
{
ASSERT(m_pParseThread);
if (m_pParseThread)
{
m_pParseThread = NULL;
m_PThreadParams.evExitThread.ResetEvent();
ASSERT(m_PThreadParams.arInvalidZones.GetSize() == 0);
if (m_ptrTextSchema)
{
m_ptrTextSchema->GetBreakParsingEvent()->ResetEvent();
}
}
}
//===========================================================================
//#pragma warning(push)
#pragma warning(disable: 4702) // warning C4702: unreachable code
//----------------------------
void CXTPSyntaxEditLexParser::CloseParseThread()
{
StopParseInThread();
CSingleLock singLockMain(&m_csParserData);
if (m_pParseThread)
{
HANDLE hThread = NULL;
try
{
hThread = m_pParseThread->m_hThread;
}
catch (...)
{
TRACE(_T("ERROR! Parse Thread is not exist. [CloseParseThread()]\n"));
}
m_pParseThread = NULL;
DWORD dwThreadRes = WAIT_TIMEOUT;
for (int i = 0; i < 10 && dwThreadRes == WAIT_TIMEOUT; i++)
{
m_PThreadParams.evParseRun.ResetEvent();
m_PThreadParams.evExitThread.SetEvent();
if (m_ptrTextSchema)
{
m_ptrTextSchema->GetBreakParsingEvent()->SetEvent();
}
if (hThread)
{
dwThreadRes = ::WaitForSingleObject(hThread, 20*1000);
}
else
{
Sleep(5000);
break;
}
}
if (dwThreadRes == WAIT_TIMEOUT && hThread)
{
::TerminateThread(hThread, 0);
TRACE(_T("ERROR! Parser thread was not ended by normal way. It was terminated. \n"));
}
m_PThreadParams.evExitThread.ResetEvent();
m_PThreadParams.arInvalidZones.RemoveAll();
if (m_ptrTextSchema)
{
m_ptrTextSchema->GetBreakParsingEvent()->ResetEvent();
}
}
}
//#pragma warning(pop)
//===========================================================================
CXTPSyntaxEditLexTextBlock* CXTPSyntaxEditLexTextSchema::GetBlocks()
{
return m_ptrFirstBlock.GetInterface(TRUE);
}
CXTPSyntaxEditLexTextBlock* CXTPSyntaxEditLexTextSchema::FindNearestTextBlock(XTP_EDIT_LINECOL posText)
{
CSingleLock singleLock(GetDataLoker(), TRUE);
//---------------------------------------------------------------------------
CXTPSyntaxEditLexTextBlockPtr ptrTBstart = GetBlocks();
CXTPSyntaxEditLexTextBlock* pTBnearest = ptrTBstart;
for (CXTPSyntaxEditLexTextBlock* pTB = ptrTBstart; pTB; pTB = pTB->m_ptrNext)
{
if (posText < pTB->m_PosStartLC)
{
break;
}
pTBnearest = pTB;
}
//--------------------------
while (pTBnearest && pTBnearest->m_ptrPrev &&
pTBnearest->m_PosStartLC == pTBnearest->m_ptrPrev->m_PosStartLC)
{
pTBnearest = pTBnearest->m_ptrPrev;
}
//--------------------------
if (pTBnearest)
{
pTBnearest->InternalAddRef();
}
return pTBnearest;
}
BOOL CXTPSyntaxEditLexTextSchema::UpdateTBNearest(CXTPSyntaxEditLexTextBlock* pNarestTB1,
int nLineDiff, int nColDiff,
XTP_EDIT_LINECOL posFrom, XTP_EDIT_LINECOL posTo,
int eEditAction )
{
int nResult = xtpEditUTBNothing;
CXTPSyntaxEditLexTextBlock* pTB;
for (pTB = pNarestTB1; pTB; pTB = pTB->m_ptrParent)
{
ASSERT(pTB != pTB->m_ptrParent);
//-------------------------------------------------------------
BOOL bIsBlockStartIntersected = eEditAction == xtpEditActDelete &&
pTB->m_PosStartLC >= posFrom && pTB->m_PosStartLC < posTo
||
eEditAction == xtpEditActInsert &&
pTB->m_PosStartLC < posFrom &&
posFrom.GetXLC() < pTB->GetStartTagEndXLC();
if (bIsBlockStartIntersected)
{
nResult |= xtpEditUTBReparse;
if (pTB == pNarestTB1)
{
nResult |= xtpEditUTBNearestUpdated;
}
// set empty
pTB->m_PosEndLC.nLine = pTB->m_PosStartLC.nLine;
pTB->m_PosEndLC.nCol = pTB->m_PosStartLC.nCol-1;
continue;
}
//-------------------------------------------------------------
BOOL bIsEditingFullyInside = eEditAction == xtpEditActInsert &&
pTB->GetStartTagEndXLC() <= posFrom.GetXLC() &&
posFrom.GetXLC() <= pTB->GetEndTagBeginXLC()
||
eEditAction == xtpEditActDelete &&
pTB->GetStartTagEndXLC() <= posFrom.GetXLC() &&
posTo.GetXLC() <= pTB->GetEndTagBeginXLC();
if (bIsEditingFullyInside)
{
if (pTB == pNarestTB1)
{
nResult |= xtpEditUTBNearestUpdated;
}
BOOL bEmpty = FALSE;
pTB->m_PosEndLC.nLine += nLineDiff;
if (pTB->m_PosEndLC.nLine < pTB->m_PosStartLC.nLine)
{
// set empty
bEmpty = TRUE;
pTB->m_PosEndLC.nLine = pTB->m_PosStartLC.nLine;
pTB->m_PosEndLC.nCol = pTB->m_PosStartLC.nCol-1;
}
int nELine = eEditAction == xtpEditActInsert ? posTo.nLine : posFrom.nLine;
if (!bEmpty && pTB->m_PosEndLC.nLine == nELine)
{
pTB->m_PosEndLC.nCol += nColDiff;
if (pTB->m_PosEndLC.nCol < 0)
{
pTB->m_PosEndLC.nCol = 0;
}
}
continue;
}
//-------------------------------------------------------------
BOOL bIsBlockEndIntersected = eEditAction == xtpEditActDelete &&
(!(posTo.GetXLC() <= pTB->GetEndTagBeginXLC() ||
posFrom.GetXLC() > pTB->GetEndTagEndXLC() )
)
||
eEditAction == xtpEditActInsert &&
posFrom.GetXLC() > pTB->GetEndTagBeginXLC() &&
posFrom.GetXLC() <= pTB->GetEndTagEndXLC();
if (bIsBlockEndIntersected)
{
nResult |= xtpEditUTBReparse;
if (pTB == pNarestTB1)
{
nResult |= xtpEditUTBNearestUpdated;
}
// set empty
pTB->m_PosEndLC.nLine = 0;
pTB->m_PosEndLC.nCol = 0;
continue;
}
}
//--------------------
return nResult;
}
int CXTPSyntaxEditLexTextSchema::UpdateTextBlocks(XTP_EDIT_LINECOL posFrom, XTP_EDIT_LINECOL posTo,
int eEditAction )
{
CSingleLock singleLock(GetDataLoker());
//BOOL bLocked = TryLockCS(&singleLock, GetDataLoker(), 5000, 50);
BOOL bLocked = singleLock.Lock(5000);
if (!bLocked)
{
ASSERT(FALSE);
TRACE(_T("ERROR! Cannot enter critical section. [Dead lock, hang up???] CXTPSyntaxEditLexTextSchema::UpdateTextBlocks() \n"));
return xtpEditUTBError;
}
CXTPSyntaxEditLexTextBlockPtr ptrNarestTB1 = FindNearestTextBlock(posFrom);
if (!ptrNarestTB1)
{
return xtpEditUTBNothing;
}
int nLineDiff = posTo.nLine - posFrom.nLine;
int nColDiff = posTo.nCol - posFrom.nCol;
ASSERT(nLineDiff >= 0);
if (eEditAction == xtpEditActDelete)
{
nLineDiff *= -1;
nColDiff *= -1;
}
//- (1)- update FullyInside nearest and parents blocks
int nURes = UpdateTBNearest(ptrNarestTB1, nLineDiff,
nColDiff, posFrom, posTo, eEditAction);
//- (2)- update block after nearest
CXTPSyntaxEditLexTextBlock* pTB = (nURes & xtpEditUTBNearestUpdated) ? ptrNarestTB1->m_ptrNext :
ptrNarestTB1;
for (; pTB; pTB = pTB->m_ptrNext)
{
//-------------------------------------------------------------
BOOL bIsBlockStartIntersected = eEditAction == xtpEditActDelete &&
(!(posTo <= pTB->m_PosStartLC ||
posFrom.GetXLC() >= pTB->GetStartTagEndXLC())
)
||
eEditAction == xtpEditActInsert &&
pTB->m_PosStartLC < posFrom &&
posFrom.GetXLC() < pTB->GetStartTagEndXLC();
if (bIsBlockStartIntersected)
{
nURes |= xtpEditUTBReparse;
// set empty
pTB->m_PosEndLC.nLine = pTB->m_PosStartLC.nLine;
pTB->m_PosEndLC.nCol = pTB->m_PosStartLC.nCol-1;
continue;
}
//-------------------------------------------------------------
BOOL bIsEditingFullyInside = eEditAction == xtpEditActInsert &&
pTB->GetStartTagEndXLC() <= posFrom.GetXLC() &&
posFrom.GetXLC() <= pTB->GetEndTagBeginXLC()
||
eEditAction == xtpEditActDelete &&
pTB->GetStartTagEndXLC() <= posFrom.GetXLC() &&
posTo.GetXLC() <= pTB->GetEndTagBeginXLC(); // ??? +- 1;
if (bIsEditingFullyInside)
{
BOOL bEmpty = FALSE;
pTB->m_PosEndLC.nLine += nLineDiff;
if (pTB->m_PosEndLC.nLine < pTB->m_PosStartLC.nLine)
{
// set empty
bEmpty = TRUE;
pTB->m_PosEndLC.nLine = pTB->m_PosStartLC.nLine;
pTB->m_PosEndLC.nCol = pTB->m_PosStartLC.nCol-1;
}
int nELine = eEditAction == xtpEditActInsert ? posTo.nLine : posFrom.nLine;
if (!bEmpty && pTB->m_PosEndLC.nLine == nELine)
{
pTB->m_PosEndLC.nCol += nColDiff;
if (pTB->m_PosEndLC.nCol < 0)
{
pTB->m_PosEndLC.nCol = 0;
}
}
continue;
}
//-------------------------------------------------------------
BOOL bIsBlockEndIntersected = eEditAction == xtpEditActDelete &&
(!(posTo.GetXLC() <= pTB->GetEndTagBeginXLC() ||
posFrom.GetXLC() > pTB->GetEndTagEndXLC() )
)
||
eEditAction == xtpEditActInsert &&
posFrom.GetXLC() > pTB->GetEndTagBeginXLC() &&
posFrom.GetXLC() <= pTB->GetEndTagEndXLC();
if (bIsBlockEndIntersected)
{
nURes |= xtpEditUTBReparse;
// set empty
pTB->m_PosEndLC.nLine = 0;
pTB->m_PosEndLC.nCol = 0;
continue;
}
//-------------------------------------------------------------------
BOOL bIsBlockOutside = eEditAction == xtpEditActInsert &&
pTB->m_PosStartLC >= posFrom ||
eEditAction == xtpEditActDelete && pTB->m_PosStartLC >= posTo;
//-----------------------------
int nELine = eEditAction == xtpEditActInsert ? posTo.nLine : posFrom.nLine;
if (bIsBlockOutside && nLineDiff == 0 &&
pTB->m_PosStartLC.nLine != nELine &&
pTB->m_PosEndLC.nLine != nELine)
{
break;
}
//-------------------------------------------------------------------
if (bIsBlockOutside )
{
pTB->m_PosStartLC.nLine += nLineDiff;
pTB->m_PosEndLC.nLine += nLineDiff;
if (pTB->m_PosStartLC.nLine == nELine)
{
pTB->m_PosStartLC.nCol += nColDiff;
}
if (pTB->m_PosEndLC.nLine == nELine)
{
pTB->m_PosEndLC.nCol += nColDiff;
}
}
//-------------------------------------------------------------------
}
return nURes;
}
BOOL CXTPSyntaxEditLexTextSchema::LoadClassSchema(CXTPSyntaxEditLexClassInfoArray* arClassInfo)
{
CSingleLock singleLockCls(GetClassSchLoker(), TRUE);
CSingleLock singleLock(GetDataLoker(), TRUE);
RemoveAll();
m_pClassSchema->RemoveAll();
int nCCount = (int)arClassInfo->GetSize();
for (int i = 0; i < nCCount; i++)
{
const XTP_EDIT_LEXCLASSINFO& infoClass = arClassInfo->GetAt(i);
CXTPSyntaxEditLexClassPtr ptrLexClass = m_pClassSchema->GetNewClass(FALSE);
if (!ptrLexClass)
{
return FALSE;
}
ptrLexClass->m_strClassName = infoClass.csClassName;
int nPCount = (int)infoClass.arPropertyDesc.GetSize();
for (int k = 0; k < nPCount; k++)
{
const XTP_EDIT_LEXPROPINFO& infoProp = infoClass.arPropertyDesc[k];
if (!ptrLexClass->SetProp(&infoProp))
{
ASSERT(FALSE);
}
}
m_pClassSchema->AddPreBuildClass(ptrLexClass);
#ifdef DBG_TRACE_LOAD_CLASS_SCH
{
BOOL bEmpty = ptrLexClass->IsEmpty() && ptrLexClass->m_Parent.eOpt != xtpEditOptParent_file;
LPCTSTR cszPref = bEmpty ? _T("* !EMPTY! (it is not used)* ") : _T("* ");
ptrLexClass->Dump(cszPref);
}
#endif
}
return TRUE;
//BOOL bRes = m_pClassSchema->Build();
//return bRes;
}
void CXTPSyntaxEditLexTextSchema::BuildIfNeed()
{
CSingleLock singleLockCls(GetClassSchLoker(), TRUE);
CSingleLock singleLock(GetDataLoker(), TRUE);
CXTPSyntaxEditLexClassPtrArray* ptrArCfile = m_pClassSchema->GetClasses(FALSE);
if (!ptrArCfile || ptrArCfile->GetSize() == 0)
{
m_pClassSchema->Build();
}
}
BOOL CXTPSyntaxEditLexTextSchema::IsFileExtSupported(const CString& strExt)
{
CXTPSyntaxEditLexClassPtr ptrTopCls = GetTopClassForFileExt(strExt);
return ptrTopCls != NULL;
}
CXTPSyntaxEditLexClass* CXTPSyntaxEditLexTextSchema::GetTopClassForFileExt(const CString& strExt)
{
CString strPropName = _T("IsExt=") + strExt;
CXTPSyntaxEditLexClassPtrArray arTopClasses;
CXTPSyntaxEditLexClassPtrArray* ptrArCfile = m_pClassSchema->GetClasses(TRUE);
int nCount = ptrArCfile ? (int)ptrArCfile->GetSize() : 0;
int i;
if (nCount == 0)
{
BOOL bUnused;
ptrArCfile = m_pClassSchema->GetChildrenFor(NULL, bUnused);
nCount = ptrArCfile ? (int)ptrArCfile->GetSize() : 0;
for (i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrCfile = ptrArCfile->GetAt(i);
CXTPSyntaxEditLexClassPtr ptrCFnew = m_pClassSchema->GetNewClass(TRUE);
if (ptrCFnew)
{
ptrCFnew->CopyFrom(ptrCfile);
arTopClasses.AddPtr(ptrCFnew, TRUE);
}
}
SAFE_DELETE(ptrArCfile);
ptrArCfile = &arTopClasses;
}
nCount = ptrArCfile ? (int)ptrArCfile->GetSize() : 0;
for (i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrCfile = ptrArCfile->GetAt(i);
CXTPSyntaxEditLexVariantPtr ptrRes = ptrCfile->PropV(strPropName);
if (!ptrRes || ptrRes->m_nObjType != xtpEditLVT_valInt)
{
ASSERT(FALSE);
continue;
}
if (ptrRes->m_nValue)
{
return ptrCfile.Detach();
}
}
return NULL;
}
CXTPSyntaxEditLexTextSchema* CXTPSyntaxEditLexParser::GetTextSchema()
{
return m_ptrTextSchema;
}
void CXTPSyntaxEditLexParser::SetTextSchema(CXTPSyntaxEditLexTextSchema* pTextSchema)
{
CSingleLock singLockMain(&m_csParserData);
CloseParseThread();
if (m_ptrTextSchema)
{
m_ptrTextSchema->RemoveAll();
}
m_pSinkMT->UnadviseAll();
CMDTARGET_RELEASE(m_ptrTextSchema);
RemoveAllOptions();
if (pTextSchema)
{
pTextSchema->BuildIfNeed();
m_ptrTextSchema = pTextSchema->Clone();
CXTPNotifyConnection* pConnection = m_ptrTextSchema ? m_ptrTextSchema->GetConnection() : NULL;
if (pConnection)
{
m_pSinkMT->Advise(pConnection, xtpEditOnParserStarted, CreateNotfySinkClassDelegate(this, &XTPSyntaxEditLexAnalyser::CXTPSyntaxEditLexParser::OnParseEvent_NotificationHandler));
m_pSinkMT->Advise(pConnection, xtpEditOnTextBlockParsed, CreateNotfySinkClassDelegate(this, &XTPSyntaxEditLexAnalyser::CXTPSyntaxEditLexParser::OnParseEvent_NotificationHandler));
m_pSinkMT->Advise(pConnection, xtpEditOnParserEnded, CreateNotfySinkClassDelegate(this, &XTPSyntaxEditLexAnalyser::CXTPSyntaxEditLexParser::OnParseEvent_NotificationHandler));
}
}
#ifdef _DEBUG
AfxDump(XTPGetLexAutomatMemMan());
#endif
}
BOOL CXTPSyntaxEditLexParser::GetTokensForAutoCompleate(CXTPSyntaxEditLexTokensDefArray& rArTokens,
BOOL bAppend)
{
CSingleLock singLockMain(&m_csParserData);
if (!bAppend)
{
rArTokens.RemoveAll();
}
CXTPSyntaxEditLexTextSchema* ptrTxtSch = GetTextSchema();
CXTPSyntaxEditLexClassSchema* ptrClsSch = ptrTxtSch ? ptrTxtSch->GetClassSchema() : NULL;
CXTPSyntaxEditLexClassPtrArray* ptrArCls = ptrClsSch ? ptrClsSch->GetPreBuildClasses() : NULL;
if (!ptrArCls)
{
return FALSE;
}
//--------------------------------------------------
int nCCount = (int)ptrArCls->GetSize();
for (int i = 0; i < nCCount; i++)
{
CXTPSyntaxEditLexTokensDef tmpTkDef;
CXTPSyntaxEditLexClassPtr ptrCls = ptrArCls->GetAt(i);
CXTPSyntaxEditLexVariantPtr ptrTags = ptrCls->PropV(_T("token:tag"));
if (!ptrTags)
{
continue;
}
GetStrsFromLVArray(ptrTags, tmpTkDef.m_arTokens);
//--------------------
CXTPSyntaxEditLexVariantPtr ptrSartSeps = ptrCls->PropV(_T("token:start:separators"));
CXTPSyntaxEditLexVariantPtr ptrEndSeps = ptrCls->PropV(_T("token:end:separators"));
if (ptrSartSeps)
{
GetStrsFromLVArray(ptrSartSeps, tmpTkDef.m_arStartSeps);
}
if (ptrEndSeps)
{
GetStrsFromLVArray(ptrEndSeps, tmpTkDef.m_arEndSeps);
}
//=================
rArTokens.Add(tmpTkDef);
}
return TRUE;
}
void CXTPSyntaxEditLexParser::GetStrsFromLVArray(CXTPSyntaxEditLexVariant* pLVArray,
CStringArray& rArStrs) const
{
if (!pLVArray || pLVArray->m_nObjType != xtpEditLVT_LVArrayPtr ||
!pLVArray->m_ptrLVArrayPtr)
{
ASSERT(FALSE);
return;
}
int nCount = (int)pLVArray->m_ptrLVArrayPtr->GetSize();
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexVariantPtr ptrLVVal = pLVArray->m_ptrLVArrayPtr->GetAt(i);
ASSERT(ptrLVVal);
if (ptrLVVal && ptrLVVal->m_nObjType == xtpEditLVT_valStr)
{
for (int k = 0; k < ptrLVVal->m_arStrVals.GetSize(); k++)
{
CString strVal = ptrLVVal->m_arStrVals[k];
ASSERT(strVal.GetLength());
if (strVal.GetLength())
{
rArStrs.Add(strVal);
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////
CXTPSyntaxEditLexParser::CXTPSyntaxEditParseThreadParams* CXTPSyntaxEditLexParser::GetParseInThreadParams()
{
return &m_PThreadParams;
}
void CXTPSyntaxEditLexParser::StartParseInThread(CXTPSyntaxEditBufferManager* pBuffer,
const XTP_EDIT_LINECOL* pLCStart, const XTP_EDIT_LINECOL* pLCEnd,
int eEdinAction, BOOL bRunWithoutWait)
{
UNREFERENCED_PARAMETER(eEdinAction);
DBG_TRACE_TIME(1, _T("### ### ### StartParseInThread time = "));
CSingleLock singLockMain(&m_csParserData);
if (!m_ptrTextSchema)
{
return;
}
CSingleLock singLockPrm(&m_PThreadParams.lockThreadParams);
//if (IsCSLocked(m_PThreadParams.lockThreadParams)) {
if (IsMutexLocked(&m_PThreadParams.lockThreadParams))
{
DBG_TRACE_PARSE_START_STOP(_T("- Parser set BREAK Event. \n"));
VERIFY( m_ptrTextSchema->GetBreakParsingEvent()->SetEvent() );
}
if (!singLockPrm.Lock())
{
ASSERT(FALSE);
return;
}
m_PThreadParams.ptrBuffer = pBuffer;
CXTPSyntaxEditTextRegion invZone;
if (pLCStart && !pLCEnd && pLCStart->GetXLC() == XTP_EDIT_XLC(1, 0) )
{
invZone.Set(pLCStart, pLCEnd);
m_PThreadParams.arInvalidZones.RemoveAll();
m_PThreadParams.AddParseZone(invZone);
}
else if (pLCStart || pLCEnd)
{
invZone.Set(pLCStart, pLCEnd);
m_PThreadParams.AddParseZone(invZone);
}
if (!m_pParseThread)
{// create thread
m_pParseThread = AfxBeginThread(ThreadParseProc, this, m_nParseThreadPriority);
if (!m_pParseThread)
{
ASSERT(FALSE);
return;
}
}
if (!SetParseThreadPriority(m_nParseThreadPriority))
{
// try to start a new thread
StartParseInThread(pBuffer, pLCStart, pLCEnd, eEdinAction, bRunWithoutWait);
}
CString sDBGpos = DBG_TraceIZone(pLCStart, pLCEnd);
DBG_TRACE_PARSE_START_STOP(_T("- Parser set START Event. Add invalid Zone [ %s ] \n"), (LPCTSTR)sDBGpos);
if (bRunWithoutWait)
{
VERIFY( m_PThreadParams.evRunWithoutWait.SetEvent() );
}
VERIFY( m_PThreadParams.evParseRun.SetEvent() );
}
void CXTPSyntaxEditLexParser::StopParseInThread()
{
DBG_TRACE_TIME(1, _T("### ### ### STOP Parse In Thread time = "));
CSingleLock singLockMain(&m_csParserData);
if (!m_ptrTextSchema)
{
return;
}
CSingleLock singLockPrm(&m_PThreadParams.lockThreadParams);
CEvent* pBreakEvent = m_ptrTextSchema->GetBreakParsingEvent();
ASSERT(pBreakEvent);
if (!pBreakEvent)
return;
if (IsMutexLocked(&m_PThreadParams.lockThreadParams))
{
VERIFY( pBreakEvent->SetEvent() );
DBG_TRACE_PARSE_START_STOP(_T("- STOP Parser set BREAK Event. \n"));
}
if (!singLockPrm.Lock())
{
ASSERT(FALSE);
return;
}
if (IsEventSet(*pBreakEvent))
{
VERIFY( pBreakEvent->ResetEvent() );
DBG_TRACE_PARSE_START_STOP(_T("- STOP Parser REset BREAK Event. \n"));
}
DBG_TRACE_PARSE_START_STOP(_T("- STOP Parser finished. \n"));
}
int CXTPSyntaxEditLexParser::GetParseThreadPriority()
{
try
{
if (m_pParseThread)
{
int nPriority = m_pParseThread->GetThreadPriority();
return nPriority;
}
}
catch (...)
{
m_pParseThread = NULL;
TRACE(_T("ERROR! Parse Thread is not exist. \n"));
};
return m_nParseThreadPriority;
}
BOOL CXTPSyntaxEditLexParser::SetParseThreadPriority(int nPriority)
{
m_nParseThreadPriority = nPriority;
try
{
if (m_pParseThread)
{
if (m_nParseThreadPriority != m_pParseThread->GetThreadPriority())
{
m_pParseThread->SetThreadPriority(m_nParseThreadPriority);
}
}
}
catch (...)
{
TRACE(_T("ERROR! Parse Thread is not exist. \n"));
m_pParseThread = NULL;
return FALSE;
}
return TRUE;
}
void CXTPSyntaxEditLexParser::OnBeforeEditChanged()
{
//CSingleLock singLockMain(&m_csParserData);
StopParseInThread();
}
void CXTPSyntaxEditLexParser::OnEditChanged(const XTP_EDIT_LINECOL& posFrom,
const XTP_EDIT_LINECOL& posTo, int eEditAction,
CXTPSyntaxEditBufferManager* pBuffer)
{
DBG_TRACE_TIME(1, _T("### ### ### OnEditChanged time = "));
CSingleLock singLockMain(&m_csParserData);
if (!m_ptrTextSchema)
{
return;
}
if (!pBuffer)
{
ASSERT(FALSE);
return;
}
m_ptrTextSchema->UpdateTextBlocks(posFrom, posTo, eEditAction);
BOOL bThreadParse = GetSchemaOptions(pBuffer->GetFileExt())->m_bEditReparceInSeparateThread;
if (bThreadParse)
{
StartParseInThread(pBuffer, &posFrom, &posTo, eEditAction, FALSE);
}
else
{
CXTPSyntaxEditTextIterator txtIter(pBuffer);
m_ptrTextSchema->RunParseUpdate(TRUE, &txtIter, &posFrom, &posTo);
}
}
void CXTPSyntaxEditLexParser::OnParseEvent_NotificationHandler(XTP_NOTIFY_CODE Event,
WPARAM wParam, LPARAM lParam)
{
if (Event == xtpEditOnTextBlockParsed)
{
CXTPSyntaxEditLexTextBlockPtr ptrTBended;
CXTPSyntaxEditLexTextSchema* ptrTextSch = GetTextSchema();
ptrTBended = ptrTextSch ? ptrTextSch->GetLastParsedBlock(wParam) : NULL;
if (ptrTBended)
{
m_pConnection->SendEvent(Event, (WPARAM)(CXTPSyntaxEditLexTextBlock*)ptrTBended, 0);
}
}
else
{
m_pConnection->SendEvent(Event, wParam, lParam);
}
}
UINT CXTPSyntaxEditLexParser::ThreadParseProc(LPVOID pParentParser)
{
DBG_TRACE_PARSE_START_STOP(_T("*** Parser Thread is started. %08x\n"), ::GetCurrentThreadId());
if (!pParentParser)
{
ASSERT(FALSE);
return 111;
}
// try
{
CXTPSyntaxEditLexParserPtr ptrParser((CXTPSyntaxEditLexParser*)pParentParser, TRUE);
CXTPSyntaxEditLexParser::CXTPSyntaxEditParseThreadParams* pPRMs = NULL;
pPRMs = ptrParser->GetParseInThreadParams();
if (!pPRMs)
{
ASSERT(FALSE);
return 222;
}
CSingleLock lockPRMs(&pPRMs->lockThreadParams, TRUE);
HANDLE arWaiters[] = {pPRMs->evParseRun, pPRMs->evExitThread};
HANDLE hRunWithoutWait = pPRMs->evRunWithoutWait;
DWORD dwSelfCloseTimeout_ms = ptrParser->GetSchemaOptions(
pPRMs->ptrBuffer->GetFileExt())->m_dwParserThreadIdleLifeTime_ms;
DWORD dwWaitFilter_ms = ptrParser->GetSchemaOptions(
pPRMs->ptrBuffer->GetFileExt())->m_dwEditReparceTimeout_ms;
lockPRMs.Unlock();
DWORD dwWaitRes = 0;
do
{
dwWaitRes = WaitForMultipleObjects(2, arWaiters, FALSE, dwSelfCloseTimeout_ms);
if (dwWaitRes == WAIT_TIMEOUT)
{
CSingleLock lockPRMs1(&pPRMs->lockThreadParams, TRUE);
if (pPRMs->arInvalidZones.GetSize() == 0)
{
ptrParser->SelfCloseParseThread();
return 1;
}
else
{
continue;
}
}
//=== Wait Filter === (for keyboard input)
if (dwWaitRes == WAIT_OBJECT_0 && !IsEventSet(hRunWithoutWait))
{
do {
dwWaitRes = WaitForMultipleObjects(2, arWaiters, FALSE, dwWaitFilter_ms);
}
while (dwWaitRes == WAIT_OBJECT_0 && !IsEventSet(hRunWithoutWait));
if (dwWaitRes == WAIT_TIMEOUT)
{
dwWaitRes = WAIT_OBJECT_0;
}
}
//=== Wait Filter === (for keyboard input)
if (dwWaitRes == WAIT_OBJECT_0)
{
//***
CSingleLock lockPRMs2(&pPRMs->lockThreadParams, TRUE);
//***
// Update Options
dwSelfCloseTimeout_ms = ptrParser->GetSchemaOptions(
pPRMs->ptrBuffer->GetFileExt())->m_dwParserThreadIdleLifeTime_ms;
dwWaitFilter_ms = ptrParser->GetSchemaOptions(
pPRMs->ptrBuffer->GetFileExt())->m_dwEditReparceTimeout_ms;
// END Update Options
CXTPSyntaxEditTextIterator txtIter(pPRMs->ptrBuffer);
CXTPSyntaxEditLexTextSchema* ptrTextSch = ptrParser->GetTextSchema();
if (!ptrTextSch)
{
continue;
}
CEvent* pBreakEvent = ptrTextSch->GetBreakParsingEvent();
ASSERT(pBreakEvent);
int nZonesCount = 0;
BOOL bParseRestedBlock = FALSE;
BOOL bBreaked = FALSE;
do
{
if (IsEventSet(*pBreakEvent))
{
VERIFY( pBreakEvent->ResetEvent() );
DBG_TRACE_PARSE_START_STOP(_T("* Parser Start BREAKED. \n"));
break;
}
XTP_EDIT_LINECOL* pLCStart = NULL;
XTP_EDIT_LINECOL* pLCEnd = NULL;
CXTPSyntaxEditTextRegion iZone;
nZonesCount = (int)pPRMs->arInvalidZones.GetSize();
//bParseRestedBlock = FALSE; //nZonesCount > 0;
if (nZonesCount)
{
iZone = pPRMs->arInvalidZones[nZonesCount-1];
if (iZone.m_posStart.IsValidData())
{
pLCStart = &iZone.m_posStart;
}
if (iZone.m_posEnd.IsValidData())
{
pLCEnd = &iZone.m_posEnd;
}
}
CString sDBGpos = DBG_TraceIZone(pLCStart, pLCEnd);
DBG_TRACE_PARSE_START_STOP(_T("* Parser Started. Invalid Zone [%s] \n"), sDBGpos);
// run parser
/*DEBUG*/ DWORD dwTime0 = GetTickCount(); //DEBUG
int nParseRes = ptrTextSch->RunParseUpdate(TRUE, &txtIter,
pLCStart, pLCEnd, TRUE);
if (nParseRes & xtpEditLPR_Error)
{
//ASSERT(FALSE);
//::MessageBeep((UINT)-1);
TRACE(_T("Lex Parser ERROR! Try Full reparse. \n"));
ptrTextSch->RemoveAll();
XTP_EDIT_LINECOL posLC1 = {1, 0};
txtIter.SeekBegin();
nParseRes = ptrTextSch->RunParseUpdate(TRUE, &txtIter,
&posLC1, NULL);
pPRMs->arInvalidZones.RemoveAll();
nZonesCount = 0;
if (nParseRes & xtpEditLPR_RunFinished)
{
TRACE(_T("Full reparse - (OK) <F I N I S H E D> \n"));
}
else if (nParseRes & xtpEditLPR_RunBreaked)
{
TRACE(_T("Full reparse - BREAKED \n"));
iZone.Set(NULL, NULL);
pPRMs->arInvalidZones.Add(iZone);
}
else if (nParseRes & xtpEditLPR_Error)
{
TRACE(_T("Full reparse - ERROR \n"));
}
nZonesCount = (int)pPRMs->arInvalidZones.GetSize();
}
/*DEBUG*/ DWORD dwTime1 = GetTickCount();//DEBUG
bBreaked = (nParseRes & xtpEditLPR_RunFinished) == 0 ||
(nParseRes & (xtpEditLPR_RunBreaked|xtpEditLPR_Error)) > 0 ||
IsEventSet(*pBreakEvent);
VERIFY( pBreakEvent->ResetEvent() );
CXTPSyntaxEditTextRegion zoneValid = ptrTextSch->GetUpdatedTextRegion();
if ((nParseRes&xtpEditLPR_RunFinished) && nZonesCount)
{
pPRMs->arInvalidZones.RemoveAt(nZonesCount-1);
nZonesCount--; //pPRMs->UpdateZones(zoneValid);
}
//DEBUG
{
CString sDBGzone = DBG_TraceIZone(&zoneValid.m_posStart, &zoneValid.m_posEnd);
//TRACE(_T("- Parser set START Event. Add invalid Zone [ %s ] \n"), sDBGpos);
DBG_TRACE_PARSE_START_STOP(_T("* Parser Ended. (result=%x) %s%s%s (%.3f sec) VALID Zone[ %s ] \n"),
nParseRes,
(nParseRes&xtpEditLPR_RunBreaked) ? _T(" BREAKED ") : _T(""),
(nParseRes&xtpEditLPR_Error) ? _T(" ERROR ") : _T(""),
(nParseRes&xtpEditLPR_RunFinished) ? _T(" <F I N I S H E D> ") : _T(""),
labs(dwTime1-dwTime0)/1000.0, (LPCTSTR)sDBGzone);
}
}
while ((bParseRestedBlock || nZonesCount) && !bBreaked);
}
}
while (dwWaitRes != WAIT_OBJECT_0+1);
}
// catch(...) {
// TRACE(_T("* EXCEPTION!!! CXTPSyntaxEditLexParser::ThreadParseProc(2)\n"));
// return 333;
// }
DBG_TRACE_PARSE_START_STOP(_T("*** Parser Thread is Ended. (%x)\n"), ::GetCurrentThreadId());
return 0;
}
#ifdef _DEBUG
void CXTPSyntaxEditLexTextBlock::Dump( CDumpContext& dc ) const
{
CObject::Dump( dc );
// Now do the stuff for our specific class.
dc << "\t <<TB>>";
dc << " (ref=" << m_dwRef << ") \n";
dc << "\t start(" << m_PosStartLC.nLine << ", " << m_PosStartLC.nCol << ") ";
dc << "\t end(" << m_PosEndLC.nLine << ", " << m_PosEndLC.nCol << ") \n";
#if _MSC_VER >= 1300
dc << "\t Parent="; dc.DumpAsHex((INT_PTR)(CXTPSyntaxEditLexTextBlock*)m_ptrParent);
dc << ", Prev="; dc.DumpAsHex((INT_PTR)(CXTPSyntaxEditLexTextBlock*)m_ptrPrev);
dc << ", Next="; dc.DumpAsHex((INT_PTR)(CXTPSyntaxEditLexTextBlock*)m_ptrNext);
dc << ", LastChild="; dc.DumpAsHex((INT_PTR)(CXTPSyntaxEditLexTextBlock*)m_ptrLastChild);
#endif
}
#endif
BOOL CXTPSyntaxEditLexTextSchema::RunParseOnScreen(CTextIter* pTxtIter,
int nRowStart, int nRowEnd,
CXTPSyntaxEditLexTextBlockPtr& rPtrScreenSchFirstTB
)
{
if (!pTxtIter || nRowStart <= 0 || nRowEnd <= 0)
{
ASSERT(FALSE);
return FALSE;
}
CSingleLock singleLock(GetDataLoker());
if (!singleLock.Lock(30))
{
TRACE(_T("Cannot enter critical section. CXTPSyntaxEditLexTextSchema::RunParseOnScreen() \n"));
return FALSE;
}
//---------------------------------------------------------------------------
//** (1) ** -------------------------
CXTPSyntaxEditLexTextBlockPtr ptrTBParentToRun;
BOOL bInit = InitScreenSch(pTxtIter, nRowStart, nRowEnd, rPtrScreenSchFirstTB,
ptrTBParentToRun);
if (!bInit)
{
//TRACE(_T("- parser::InitScreenSch return FALSE res.\n"));
return FALSE;
}
XTP_EDIT_LINECOL startLC = {nRowStart, 0};
if (!pTxtIter->SeekPos(startLC))
{
return FALSE;
}
int nParseRes = 0;
CXTPSyntaxEditLexOnScreenParseCnt runCnt;
runCnt.m_nRowStart = nRowStart;
runCnt.m_nRowEnd = nRowEnd;
runCnt.m_ptrTBLast = ptrTBParentToRun;
//** (2) ** -------------------------
CXTPSyntaxEditLexClassPtrArray* ptrArClasses = m_pClassSchema->GetClasses(FALSE);
int nCCount = ptrArClasses ? (int)ptrArClasses->GetSize() : 0;
BOOL bRunEOF = TRUE;
XTP_EDIT_LINECOL lcTextPos = {0, 0};
while (!pTxtIter->IsEOF() && nCCount && bRunEOF)
{
bRunEOF = !pTxtIter->IsEOF();
nParseRes = Run_OnScreenTBStack(pTxtIter, ptrTBParentToRun, &runCnt);
if (nParseRes & (xtpEditLPR_Error|xtpEditLPR_RunBreaked)) // |xtpEditLPR_RunFinished))
{
TRACE(_T("- parser::RunParseOnScreen return by erroe or BREAK. \n"));
return !(nParseRes&xtpEditLPR_Error);
}
//** -------------------------------------------------------------
if (!pTxtIter->IsEOF() && !(nParseRes & xtpEditLPR_Iterated))
{
SeekNextEx(pTxtIter, ptrTBParentToRun->m_ptrLexClass, &runCnt);
}
//---------------------------------------------------------------------------
lcTextPos = pTxtIter->GetPosLC();
if (lcTextPos.nLine > runCnt.m_nRowEnd)
{
break;
}
//---------------------------------------------------------------------------
if (ptrTBParentToRun->m_ptrParent)
{
ptrTBParentToRun = ptrTBParentToRun->m_ptrParent;
}
}
return TRUE;
}
CXTPSyntaxEditLexTextBlockPtr CXTPSyntaxEditLexTextSchema::InitScreenSch_RunTopClass(CTextIter* pTxtIter)
{
CXTPSyntaxEditLexTextBlockPtr ptrTBtop;
CXTPSyntaxEditLexClassPtrArray* ptrClsAr = m_pClassSchema->GetClasses(FALSE);
int nCount = ptrClsAr ? (int)ptrClsAr->GetSize() : 0;
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClassPtr ptrC = ptrClsAr->GetAt(i);
if (!ptrC)
{
ASSERT(FALSE);
continue;
}
ASSERT(ptrTBtop == NULL);
int nParseRes = ptrC->RunParse(pTxtIter, this, ptrTBtop);
if ((nParseRes & xtpEditLPR_StartFound) && ptrTBtop)
{
return ptrTBtop;
}
}
return NULL;
}
BOOL CXTPSyntaxEditLexTextSchema::InitScreenSch(CTextIter* pTxtIter, int nRowStart, int nRowEnd,
CXTPSyntaxEditLexTextBlockPtr& rPtrScreenSchFirstTB,
CXTPSyntaxEditLexTextBlockPtr& rPtrTBParentToRun)
{
CXTPSyntaxEditLexTextBlockPtr ptrTBstart = GetBlocks();
// process first screen parse in the main thread
if (nRowStart == 1 && !ptrTBstart)
{
rPtrTBParentToRun = rPtrScreenSchFirstTB = InitScreenSch_RunTopClass(pTxtIter);
return (rPtrTBParentToRun != NULL);
}
CXTPSyntaxEditLexTextBlock* pLastSchBlock = GetLastSchBlock(FALSE);
if (m_ptrNewChainTB2 && pLastSchBlock &&
(pLastSchBlock->m_PosEndLC.IsValidData() && nRowStart > pLastSchBlock->m_PosEndLC.nLine ||
!pLastSchBlock->m_PosEndLC.IsValidData() && nRowStart > pLastSchBlock->m_PosStartLC.nLine)
)
{
return FALSE;
}
//=======================================================================
CXTPSyntaxEditLexTextBlock* pTBLast = NULL;
XTP_EDIT_LINECOL lcStart = {nRowStart, 0};
// (1) ---
CXTPSyntaxEditLexTextBlock* pTB;
for (pTB = ptrTBstart; pTB; pTB = pTB->m_ptrNext)
{
if (pTB->m_PosStartLC < lcStart &&
pTB->GetPosEndLC() >= lcStart ||
pTB == ptrTBstart )
{
pTBLast = pTB;
}
if (pTB->m_PosStartLC.nLine > nRowEnd)
{
break;
}
}
// (2) ---
CXTPSyntaxEditLexTextBlockPtr ptrTBCopyNext;
for (pTB = pTBLast; pTB; pTB = pTB->m_ptrParent)
{
CXTPSyntaxEditLexTextBlockPtr ptrTBCopy = CopyShortTBtoFull(pTB);
if (!ptrTBCopy)
{
return FALSE;
}
if (pTB == pTBLast)
{
rPtrTBParentToRun = ptrTBCopy;
if (pTB->m_PosStartLC.nLine <= nRowStart &&
pTB->m_PosEndLC.nLine >= nRowStart ||
pTB == ptrTBstart)
{
pTBLast = pTB;
}
}
else
{
ptrTBCopy->m_ptrNext = ptrTBCopyNext;
ptrTBCopyNext->m_ptrPrev = ptrTBCopy;
ptrTBCopyNext->m_ptrParent = ptrTBCopy;
}
rPtrScreenSchFirstTB = ptrTBCopy;
ptrTBCopyNext = ptrTBCopy;
}
return (rPtrTBParentToRun != NULL);
}
CXTPSyntaxEditLexTextBlock* CXTPSyntaxEditLexTextSchema::CopyShortTBtoFull(CXTPSyntaxEditLexTextBlock* pTB)
{
CXTPSyntaxEditLexTextBlockPtr ptrCopyTB = GetNewBlock();
if (!ptrCopyTB || !pTB || !pTB->m_ptrLexClass)
{
#ifdef XTP_FIXED // sometime popup this assert message.
// ASSERT(pTB && pTB->m_ptrLexClass);
#else
ASSERT(pTB && pTB->m_ptrLexClass);
#endif
return NULL;
}
ptrCopyTB->m_PosStartLC = pTB->m_PosStartLC;
ptrCopyTB->m_PosEndLC = pTB->m_PosEndLC;
int nClassID = pTB->m_ptrLexClass->GetAttribute_int(XTPLEX_ATTRCLASSID, FALSE, -1);
ASSERT(nClassID > 0);
CXTPSyntaxEditLexClassPtrArray* ptrTopClassesAr = m_pClassSchema->GetClasses(FALSE);
ptrCopyTB->m_ptrLexClass = FindLexClassByID(ptrTopClassesAr, nClassID);
if (!ptrCopyTB->m_ptrLexClass)
{
ASSERT(FALSE);
return NULL;
}
return ptrCopyTB.Detach();
}
CXTPSyntaxEditLexClass* CXTPSyntaxEditLexTextSchema::FindLexClassByID(CXTPSyntaxEditLexClassPtrArray* pClassesAr, int nClassID)
{
if (!pClassesAr)
{
return NULL;
}
int nCount = (int)pClassesAr->GetSize();
for (int i = 0; i < nCount; i++)
{
CXTPSyntaxEditLexClass* pC = pClassesAr->GetAt(i, FALSE);
int nC_ID = pC->GetAttribute_int(XTPLEX_ATTRCLASSID, FALSE);
if (nC_ID == nClassID)
{
pC->InternalAddRef();
return pC;
}
//-------------------------------------------------------
CXTPSyntaxEditLexClass* pCF2 = FindLexClassByID(pC->GetChildren(), nClassID);
if (pCF2)
{
return pCF2;
}
pCF2 = FindLexClassByID(pC->GetChildrenDyn(), nClassID);
if (pCF2)
{
return pCF2;
}
}
return NULL;
}
int CXTPSyntaxEditLexTextSchema::Run_OnScreenTBStack(CTextIter* pTxtIter,
CXTPSyntaxEditLexTextBlock* pTBParentToRun,
CXTPSyntaxEditLexOnScreenParseCnt* pRunCnt)
{
if (!pTBParentToRun || !pTBParentToRun->m_ptrLexClass || !pRunCnt)
{
ASSERT(FALSE);
return xtpEditLPR_Error;
}
CXTPSyntaxEditLexTextBlockPtr ptrTBParentToRun(pTBParentToRun, TRUE);
CXTPSyntaxEditLexClassPtr ptrRunClass = pTBParentToRun->m_ptrLexClass;
int nPres = 0;
BOOL bIterated = FALSE;
BOOL bEnded = FALSE;
BOOL bRunEOF = TRUE;
XTP_EDIT_LINECOL lcTextPos = {0, 0};
//** 1 **// Run existing block with children until block end
while (!bEnded && (bRunEOF || !pTxtIter->IsEOF()) )
{
bRunEOF = !pTxtIter->IsEOF();
BOOL bSkipIterate = FALSE;
nPres = ptrRunClass->RunParse(pTxtIter, this, ptrTBParentToRun, pRunCnt);
if (nPres & (xtpEditLPR_Error|xtpEditLPR_RunBreaked)) //|xtpEditLPR_RunFinished))
{
return nPres;
}
//---------------------------------------------------------------------------
if (nPres & xtpEditLPR_Iterated)
{
bSkipIterate = TRUE;
bIterated = TRUE;
}
//---------------------------------------------------------------------------
bEnded = (nPres & xtpEditLPR_EndFound) != 0;
if (bEnded)
{
CSingleLock singleLock(GetDataLoker(), TRUE);
ptrTBParentToRun->EndChildren(); //this);
DBG_TRACE_PARSE_RUN_BLOCKS(_T("(%08x) ENDED startPos=(%d, %d) endPos=(%d, %d), [%s] {%d}-noEndedStack \n"),
(CXTPSyntaxEditLexTextBlock*)ptrTBParentToRun,
ptrTBParentToRun->m_PosStartLC.nLine, ptrTBParentToRun->m_PosStartLC.nCol, ptrTBParentToRun->m_PosEndLC.nLine,
ptrTBParentToRun->m_PosEndLC.nCol, ptrTBParentToRun->m_ptrLexClass->m_strClassName, m_nNoEndedClassesCount);
}
//---------------------------------------------------------------------------
if (!bEnded && !bSkipIterate)
{
SeekNextEx(pTxtIter, ptrRunClass, pRunCnt);
}
//---------------------------------------------------------------------------
lcTextPos = pTxtIter->GetPosLC();
if (lcTextPos.nLine > pRunCnt->m_nRowEnd)
{
break;
}
}
// ** end run existing ** //
if (!bEnded)
{
ptrTBParentToRun->m_PosEndLC = pTxtIter->GetPosLC();
ptrTBParentToRun->EndChildren(); //this);
return xtpEditLPR_RunFinished;
}
//===========================================================================
return (bIterated ? xtpEditLPR_Iterated : 0) | (pTxtIter->IsEOF() ? xtpEditLPR_RunFinished : 0);
}
CXTPSyntaxEditLexParserSchemaOptions::CXTPSyntaxEditLexParserSchemaOptions()
{
m_bFirstParseInSeparateThread = TRUE;
m_bEditReparceInSeparateThread = TRUE;
m_bConfigChangedReparceInSeparateThread = TRUE;
m_dwMaxBackParseOffset = XTP_EDIT_LEXPARSER_MAXBACKOFFSETDEFAULT;
m_dwEditReparceTimeout_ms = XTP_EDIT_LEXPARSER_REPARSETIMEOUTMS;
m_dwOnScreenSchCacheLifeTime_sec = XTP_EDIT_LEXPARSER_ONSCREENSCHCACHELIFETIMESEC;
m_dwParserThreadIdleLifeTime_ms = XTP_EDIT_LEXPARSER_THREADIDLELIFETIMESEC * 1000;
}
CXTPSyntaxEditLexParserSchemaOptions::CXTPSyntaxEditLexParserSchemaOptions(const CXTPSyntaxEditLexParserSchemaOptions& rSrc)
{
m_bFirstParseInSeparateThread = rSrc.m_bFirstParseInSeparateThread;
m_bEditReparceInSeparateThread = rSrc.m_bEditReparceInSeparateThread;
m_bConfigChangedReparceInSeparateThread = rSrc.m_bConfigChangedReparceInSeparateThread;
m_dwMaxBackParseOffset = rSrc.m_dwMaxBackParseOffset;
m_dwEditReparceTimeout_ms = rSrc.m_dwEditReparceTimeout_ms;
m_dwOnScreenSchCacheLifeTime_sec = rSrc.m_dwOnScreenSchCacheLifeTime_sec;
m_dwParserThreadIdleLifeTime_ms = rSrc.m_dwParserThreadIdleLifeTime_ms;
}
const CXTPSyntaxEditLexParserSchemaOptions& CXTPSyntaxEditLexParserSchemaOptions::operator=(const CXTPSyntaxEditLexParserSchemaOptions& rSrc)
{
m_bFirstParseInSeparateThread = rSrc.m_bFirstParseInSeparateThread;
m_bEditReparceInSeparateThread = rSrc.m_bEditReparceInSeparateThread;
m_bConfigChangedReparceInSeparateThread = rSrc.m_bConfigChangedReparceInSeparateThread;
m_dwMaxBackParseOffset = rSrc.m_dwMaxBackParseOffset;
m_dwEditReparceTimeout_ms = rSrc.m_dwEditReparceTimeout_ms;
m_dwOnScreenSchCacheLifeTime_sec = rSrc.m_dwOnScreenSchCacheLifeTime_sec;
m_dwParserThreadIdleLifeTime_ms = rSrc.m_dwParserThreadIdleLifeTime_ms;
return *this;
}
BOOL CXTPSyntaxEditLexParser::ReadSchemaOptions(const CString& strExt,
CXTPSyntaxEditLexTextSchema* pTextSchema,
CXTPSyntaxEditLexParserSchemaOptions* pOpt)
{
if (pOpt)
{
*pOpt = *m_pSchOptions_default;
}
if (!pTextSchema || !pOpt)
{
ASSERT(FALSE);
return FALSE;
}
CXTPSyntaxEditLexClassPtr ptrTopCls = pTextSchema->GetTopClassForFileExt(strExt);
if (!ptrTopCls)
{
return FALSE;
}
pOpt->m_bFirstParseInSeparateThread = ptrTopCls->GetAttribute_BOOL(
XTPLEX_ATTRG_FIRSTPARSEINSEPARATETHREAD, FALSE, TRUE);
pOpt->m_bEditReparceInSeparateThread = ptrTopCls->GetAttribute_BOOL(
XTPLEX_ATTRG_EDITREPARCEINSEPARATETHREAD, FALSE, TRUE);
pOpt->m_bConfigChangedReparceInSeparateThread = ptrTopCls->GetAttribute_BOOL(
XTPLEX_ATTRG_CONFIGCHANGEDREPARCEINSEPARATETHREAD, FALSE, TRUE);
pOpt->m_dwMaxBackParseOffset = (DWORD)ptrTopCls->GetAttribute_int(
XTPLEX_ATTRG_MAXBACKPARSEOFFSET, FALSE,
XTP_EDIT_LEXPARSER_MAXBACKOFFSETDEFAULT);
pOpt->m_dwEditReparceTimeout_ms = (DWORD)ptrTopCls->GetAttribute_int(
XTPLEX_ATTRG_EDITREPARCETIMEOUT_MS, FALSE,
XTP_EDIT_LEXPARSER_REPARSETIMEOUTMS);
pOpt->m_dwOnScreenSchCacheLifeTime_sec = (DWORD)ptrTopCls->GetAttribute_int(
XTPLEX_ATTRG_ONSCREENSCHCACHELIFETIME_SEC, FALSE,
XTP_EDIT_LEXPARSER_ONSCREENSCHCACHELIFETIMESEC);
pOpt->m_dwParserThreadIdleLifeTime_ms = (DWORD)ptrTopCls->GetAttribute_int(
XTPLEX_ATTRG_PARSERTHREADIDLELIFETIME_SEC, FALSE,
XTP_EDIT_LEXPARSER_THREADIDLELIFETIMESEC);
if (pOpt->m_dwParserThreadIdleLifeTime_ms != INFINITE)
{
pOpt->m_dwParserThreadIdleLifeTime_ms *= 1000;
}
if (pOpt->m_dwParserThreadIdleLifeTime_ms == 0)
{
pOpt->m_dwParserThreadIdleLifeTime_ms = INFINITE;
}
return TRUE;
}
const CXTPSyntaxEditLexParserSchemaOptions* CXTPSyntaxEditLexParser::GetSchemaOptions(const CString& strExt)
{
CSingleLock singLockMain(&m_csParserData);
if (!m_ptrTextSchema)
{
RemoveAllOptions();
}
CXTPSyntaxEditLexParserSchemaOptions* pOptions = NULL;
if (m_mapSchOptions.Lookup(strExt, pOptions))
{
ASSERT(pOptions);
return pOptions;
}
else if (m_ptrTextSchema)
{
pOptions = new CXTPSyntaxEditLexParserSchemaOptions();
if (ReadSchemaOptions(strExt, m_ptrTextSchema, pOptions))
{
m_mapSchOptions.SetAt(strExt, pOptions);
return pOptions;
}
else
{
CMDTARGET_RELEASE(pOptions);
}
}
return m_pSchOptions_default;
}