// 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("? (? - ?) - ?"); } 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("???") ); 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("? (parent)") ) :( ptrTB->m_ptrLexClass ? ptrTB->m_ptrLexClass->m_strClassName : _T("?") ) , 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 TB current: %s \n"), DBG_TraceTB_StartEndCls(ptrTB)); DBG_TRACE_PARSE_RUN_UPDATE(_T(" 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(" NewChainTB1: %s \n"), DBG_TraceTB_StartEndCls(m_ptrNewChainTB1)); if (m_ptrNewChainTB2) { DBG_TRACE_PARSE_RUN_UPDATE(_T(" 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(" CLOSE TB-RollBacked: %s \n"), DBG_TraceTB_StartEndCls(ptrTBclose)); ptrTBclose->Close(); } DBG_TRACE_PARSE_RUN_UPDATE(_T(" 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(" OldChainTBFirst: %s \n"), DBG_TraceTB_StartEndCls(m_ptrOldChainTBFirst)); DBG_TRACE_PARSE_RUN_UPDATE(_T(" 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) \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(" ") : _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 <>"; 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; }