⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bcgpoutlineparser.cpp

📁 远程网络监视程序的源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// BCGPOutlineParser.cpp: implementation of the CBCGPOutlineParser class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "bcgcbpro.h"
#include "BCGPOutlineParser.h"
#include "BCGPEditCtrl.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBCGPOutlineParser::CBCGPOutlineParser()
{

}

CBCGPOutlineParser::~CBCGPOutlineParser()
{
	RemoveAllBlockTypes ();
}

void CBCGPOutlineParser::RemoveAllBlockTypes ()
{
	for (int i = 0; i <= m_arrBlockTypes.GetUpperBound (); i++)
	{
		delete m_arrBlockTypes.GetAt (i);
	}
	m_arrBlockTypes.RemoveAll ();
}

void CBCGPOutlineParser::Init ()
{
	RemoveAllBlockTypes ();

	// Default init for C++ outline blocks:
	AddEscapeSequence (_T("\\\""));
	AddBlockType (_T("\""),	_T("\""),	_T("\"\""),	FALSE,	TRUE);
	AddBlockType (_T("//"),	_T("\n"),	_T("/**/"),	FALSE,	TRUE);
	AddBlockType (_T("/*"),	_T("*/"),	_T("/**/"),	FALSE,	FALSE);

	CStringList lstKeywords; 
	lstKeywords.AddTail (_T("if"));
	lstKeywords.AddTail (_T("else"));
	lstKeywords.AddTail (_T("while"));
	lstKeywords.AddTail (_T("for"));
	lstKeywords.AddTail (_T("do"));
	lstKeywords.AddTail (_T("switch"));
	lstKeywords.AddTail (_T("class"));
	lstKeywords.AddTail (_T("union"));
	lstKeywords.AddTail (_T("struct"));
	lstKeywords.AddTail (_T("namespace"));
	lstKeywords.AddTail (_T("catch"));
	lstKeywords.AddTail (_T("try"));
	lstKeywords.AddTail (_T("operator"));
	AddBlockType (_T("{"),	_T("}"),	_T("..."),	TRUE,	FALSE, &lstKeywords);
}
//************************************************************************************
void CBCGPOutlineParser::AddBlockType (LPCTSTR lpszOpen, LPCTSTR lpszClose, LPCTSTR lpszReplace, BOOL bNested, BOOL bIgnore, CStringList* pKeywordsList)
{
	ASSERT (lpszOpen != NULL);
	ASSERT (lpszClose != NULL);

	CString strClose = lpszClose;
	if (strClose.IsEmpty ())
	{
		AddEscapeSequence (lpszOpen);
		return;
	}

	BlockType* pNewBlockType = new BlockType (
		lpszOpen, lpszClose, (lpszReplace != NULL) ? lpszReplace : _T("..."), bNested, bIgnore, pKeywordsList);

	m_arrBlockTypes.Add (pNewBlockType);
}
//************************************************************************************
void CBCGPOutlineParser::AddEscapeSequence (LPCTSTR lpszStr)
{
	ASSERT (lpszStr != NULL);
	m_lstEscapeSequences.AddTail (lpszStr);
}
//************************************************************************************
const BlockType* CBCGPOutlineParser::GetBlockType (int nIndex) const
{
	if (nIndex >= 0 && nIndex <= m_arrBlockTypes.GetUpperBound ())
	{
		return m_arrBlockTypes [nIndex];
	}
	else
	{
		ASSERT (FALSE);
		return NULL;
	}
}
/*
	XML format:
	-----------
	<SETTINGS>
		<OUTLINE_DATA>
			<IgnoreOneLineBlocks></IgnoreOneLineBlocks>
			<EscapeSequences>
				<EscapeSequence></EscapeSequence>
			</EscapeSequences>
			<BLOCKS>
				<BLOCK>
					<Start></Start>
					<End></End>
					<ReplaceString></ReplaceString>
					<AllowNestedBlocks></AllowNestedBlocks>
					<Ignore></Ignore>
				</BLOCK>
			</BLOCKS>
		</OUTLINE_DATA>
	</SETTINGS>

	<IgnoreOneLineBlocks>							"False" by default

	<Start>				=>	m_strOpen;
	<End>				=>	m_strClose;
	<ReplaceString>		=>	m_strReplace;			"..." by default
	<AllowNestedBlocks>	=>	m_bAllowNestedBlocks;	"True" by default
	<Ignore>			=>	m_bIgnore				"False" by default

	Default XML settings for C++:
	-----------------------------
	<SETTINGS>
		<OUTLINE_DATA>
			<IgnoreOneLineBlocks>True</IgnoreOneLineBlocks>
			<IncludeSpaceLines>True</IncludeSpaceLines>
			<EscapeSequences>
				<EscapeSequence>\\\"</EscapeSequence>
			</EscapeSequences>
			<BLOCKS>
				<BLOCK>
					<Start>\"</Start>
					<End>\"</End>
					<ReplaceString>\"\"</ReplaceString>
					<AllowNestedBlocks>False</AllowNestedBlocks>
					<Ignore>True</Ignore>
				</BLOCK>
				<BLOCK>
					<Start>{</Start>
					<End>}</End>
					<ReplaceString>..</ReplaceString>
					<KEYWORDS>
						<Keyword>else</Keyword>
						<Keyword>struct</Keyword>
						<Keyword>enum</Keyword>
						<Keyword>switch</Keyword>
						<Keyword>catch</Keyword>
						<Keyword>try</Keyword>
						<Keyword>for</Keyword>
						<Keyword>operator</Keyword>
						<Keyword>class</Keyword>
						<Keyword>if</Keyword>
						<Keyword>union</Keyword>
						<Keyword>do</Keyword>
						<Keyword>while</Keyword>
						<Keyword>namespace</Keyword>
					</KEYWORDS>
				</BLOCK>
				<BLOCK>
					<Start>{</Start>
					<End>}</End>
					<ReplaceString>...</ReplaceString>
				</BLOCK>
*/
//				<BLOCK>
//					<Start>//</Start>
//					<End>\n</End>
//					<ReplaceString>/**/</ReplaceString>
//					<AllowNestedBlocks>False</AllowNestedBlocks>
//				</BLOCK>
//				<BLOCK>
//					<Start>/*</Start>
//					<End>*/</End>
//					<ReplaceString>/**/</ReplaceString>
//					<AllowNestedBlocks>False</AllowNestedBlocks>
//				</BLOCK>
/*
			</BLOCKS>
		</OUTLINE_DATA>
	</SETTINGS>
*/
//************************************************************************************
static BOOL Compare (const CString& strBuffer, const int nBufferOffset, const CString& strCompareWith, int& nEndOffset)
{
	// Returns equal chars num:
	const int nLength = strCompareWith.GetLength ();
	const int nBufLength = strBuffer.GetLength ();
	for (int i = 0; i < nLength && nBufferOffset + i < nBufLength; i++)
	{
		if (strCompareWith [i] != strBuffer [nBufferOffset + i])
		{
			nEndOffset = nBufferOffset;
			return FALSE;
		}
	}

	nEndOffset = nBufferOffset + i - 1;
	return i > 0;
}
//************************************************************************************
BOOL CBCGPOutlineParser::IsEscapeSequence (const CString& strBuffer, int& nBufferOffset) const
{
	for (POSITION pos = m_lstEscapeSequences.GetHeadPosition (); pos != NULL; )
	{
		const CString& str = m_lstEscapeSequences.GetNext (pos);
		int nEndOffset;
		if (str.GetLength () > 0 &&
			Compare (strBuffer, nBufferOffset, str, nEndOffset))
		{
			nBufferOffset += str.GetLength ();
			return TRUE;
		}
	}

	return FALSE;
}
//************************************************************************************
Lexeme CBCGPOutlineParser::GetNext (const CString& strIn, int& nOffset, const int nSearchTo)
{
	while (nOffset >= 0 && nOffset < strIn.GetLength () && nOffset <= nSearchTo)
	{
		if (IsEscapeSequence (strIn, nOffset))
		{
			continue;
		}

		for (int i = 0; i <= m_arrBlockTypes.GetUpperBound (); i++)
		{
			BlockType* pBlockType = m_arrBlockTypes [i];
			ASSERT (pBlockType != NULL);

			// Nested blocks:
			if (pBlockType->m_bAllowNestedBlocks)
			{
				int nEndOffset;
				if (Compare (strIn, nOffset, pBlockType->m_strOpen, nEndOffset))
				{
					Lexeme lexem (i, LT_BlockStart, nOffset, nEndOffset);
					nOffset += pBlockType->m_strOpen.GetLength ();
					return lexem;
				}
				else if (Compare (strIn, nOffset, pBlockType->m_strClose, nEndOffset))
				{
					Lexeme lexem (i, LT_BlockEnd, nOffset, nEndOffset);
					nOffset += pBlockType->m_strClose.GetLength ();
					return lexem;
				}
			}
			// NonNested blocks:
			else
			{
				int nEndOffset;
				if (Compare (strIn, nOffset, pBlockType->m_strOpen, nEndOffset))
				{
					Lexeme lexem (i, LT_CompleteBlock, nOffset, nEndOffset);
					nOffset += pBlockType->m_strOpen.GetLength ();

					if (!pBlockType->m_strClose.IsEmpty ())
					{
						// find close token skipping escape sequences:
						while  (nOffset >= 0 && 
								nOffset < strIn.GetLength () && 
								nOffset <= nSearchTo)
						{
							if (IsEscapeSequence (strIn, nOffset))
							{
								continue;
							}

							if (Compare (strIn, nOffset, pBlockType->m_strClose, nEndOffset))
							{
								nOffset += pBlockType->m_strClose.GetLength ();
								if (pBlockType->m_strClose == _T("\n"))
								{
									nOffset--;
								}

								lexem.m_nEnd = nOffset - 1;
								return lexem;
							}

							nOffset++;
						}
					}
					
					lexem.m_nEnd = strIn.GetLength () - 1;
					return lexem;
				}
			}

		}

		nOffset++;
	}

	return Lexeme (0, LT_EndOfText, 0, 0);
}
//************************************************************************************
void CBCGPOutlineParser::PushResult (Lexeme lexem, CObList& lstResults)
{
	CString str;

	const BlockType* pBlockType = GetBlockType (lexem.m_nBlockType);
	ASSERT (pBlockType != NULL);

	switch (lexem.m_nType)
	{
	case LT_CompleteBlock:
		{
			CBCGPOutlineBaseNode block;
			block.m_nStart		= lexem.m_nStart;
			block.m_nEnd		= lexem.m_nEnd;
			block.m_nNameOffset;
			block.m_strReplace	= pBlockType->m_strReplace;
			block.m_nBlockType	= lexem.m_nBlockType;
			block.m_dwFlags		= g_dwOBFComplete;

			CBCGPOutlineNode* pNode = new CBCGPOutlineNode (block);
			ASSERT_VALID (pNode);

			lstResults.AddTail (pNode);
		}
		str.Format (_T("%s_%d_%d, "), pBlockType->m_strReplace, lexem.m_nStart, lexem.m_nEnd);
		break;
	case LT_BlockStart:
		{
			CBCGPOutlineBaseNode block;
			block.m_nStart		= lexem.m_nStart;
			block.m_nEnd		= lexem.m_nEnd;
			block.m_nNameOffset;
			block.m_strReplace	= pBlockType->m_strReplace;
			block.m_nBlockType	= lexem.m_nBlockType;
			block.m_dwFlags		= g_dwOBFLeft;

			CBCGPOutlineNode* pNode = new CBCGPOutlineNode (block);
			ASSERT_VALID (pNode);

			lstResults.AddTail (pNode);
		}
		str.Format (_T("{_%d, "), lexem.m_nStart);
		break;
	case LT_BlockEnd:
		{
			CBCGPOutlineBaseNode block;
			block.m_nStart		= lexem.m_nStart;
			block.m_nEnd		= lexem.m_nEnd;
			block.m_nNameOffset;
			block.m_strReplace	= pBlockType->m_strReplace;
			block.m_nBlockType	= lexem.m_nBlockType;
			block.m_dwFlags		= g_dwOBFRight;

			CBCGPOutlineNode* pNode = new CBCGPOutlineNode (block);
			ASSERT_VALID (pNode);

			lstResults.AddTail (pNode);
		}
		str.Format (_T("}_%d, "), lexem.m_nEnd);
		break;
	case LT_Eps:
		str = _T("Finished");
		break;
	default:
		str = _T("Error! ");
	}
	m_strOut += str;
}
//************************************************************************************
void CBCGPOutlineParser::DoParse (const CString& strBuffer, 
								  const int nStartOffset, const int nEndOffset, 
								  CObList& lstResults)
{
	ASSERT (nStartOffset >= 0);
	ASSERT (nEndOffset < strBuffer.GetLength ());
	ASSERT (nStartOffset <= nEndOffset);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -