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++
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;
|
|
}
|