📄 cplusplus.cpp
字号:
///////////////////////////////////////////////////////////////////////////
// File: cplusplus.cpp
// Version: 1.2.0.5
// Created: 29-Dec-1998
//
// Copyright: Stcherbatchenko Andrei
// E-mail: windfall@gmx.de
//
// Implementation of the CCrystalEditView class, a part of the Crystal Edit -
// syntax coloring text editor.
//
// You are free to use or modify this code to the following restrictions:
// - Acknowledge me somewhere in your about box, simple "Parts of code by.."
// will be enough. If you can't (or don't want to), contact me personally.
// - LEAVE THIS HEADER INTACT
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// 16-Aug-99
// Ferdinand Prantl:
// + FEATURE: corrected bug in syntax highlighting C comments
// + FEATURE: extended levels 1- 4 of keywords in some languages
//
// ... it's being edited very rapidly so sorry for non-commented
// and maybe "ugly" code ...
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ccrystaltextview.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// C++ keywords (MSVC5.0 + POET5.0)
static LPTSTR s_apszCppKeywordList[] =
{
_T ("_asm"),
_T ("__asm"),
_T ("_far16"),
_T ("__far16"),
_T ("enum"),
_T ("__multiple_inheritance"),
_T ("template"),
_T ("auto"),
_T ("__except"),
_T ("__single_inheritance"),
_T ("this"),
_T ("__based"),
_T ("explicit"),
_T ("__virtual_inheritance"),
_T ("thread"),
_T ("bool"),
_T ("extern"),
_T ("mutable"),
_T ("throw"),
_T ("break"),
_T ("false"),
_T ("naked"),
_T ("true"),
_T ("case"),
_T ("_fastcall"),
_T ("__fastcall"),
_T ("namespace"),
_T ("try"),
_T ("catch"),
_T ("__finally"),
_T ("new"),
_T ("__try"),
_T ("__cdecl"),
_T ("__pascal"),
_T ("_cdecl"),
_T ("_pascal"),
_T ("float"),
_T ("operator"),
_T ("typedef"),
_T ("char"),
_T ("for"),
_T ("private"),
_T ("typeid"),
_T ("class"),
_T ("friend"),
_T ("protected"),
_T ("typename"),
_T ("const"),
_T ("goto"),
_T ("public"),
_T ("union"),
_T ("const_cast"),
_T ("if"),
_T ("register"),
_T ("unsigned"),
_T ("continue"),
_T ("inline"),
_T ("reinterpret_cast"),
_T ("using"),
_T ("__declspec"),
_T ("__inline"),
_T ("return"),
_T ("uuid"),
_T ("default"),
_T ("int"),
_T ("short"),
_T ("__uuidof"),
_T ("delete"),
_T ("__int8"),
_T ("signed"),
_T ("virtual"),
_T ("_export"),
_T ("__export"),
_T ("dllexport"),
_T ("__int16"),
_T ("sizeof"),
_T ("void"),
_T ("dllimport"),
_T ("__int32"),
_T ("static"),
_T ("volatile"),
_T ("do"),
_T ("__int64"),
_T ("static_cast"),
_T ("wmain"),
_T ("double"),
_T ("__leave"),
_T ("_stdcall"),
_T ("__stdcall"),
_T ("_syscall"),
_T ("__syscall"),
_T ("while"),
_T ("dynamic_cast"),
_T ("long"),
_T ("struct"),
_T ("xalloc"),
_T ("else"),
_T ("main"),
_T ("switch"),
_T ("interface"),
// Added by a.s.
_T ("persistent"),
_T ("_persistent"),
_T ("transient"),
_T ("depend"),
_T ("ondemand"),
_T ("transient"),
_T ("cset"),
_T ("useindex"),
_T ("indexdef"),
NULL
};
static LPTSTR s_apszUser1KeywordList[] =
{
_T ("LPTSTR"),
_T ("LPCTSTR"),
_T ("LPWSTR"),
_T ("LPCWSTR"),
_T ("LPTSTR"),
_T ("LPCTSTR"),
_T ("CHAR"),
_T ("WCHAR"),
_T ("TCHAR"),
_T ("BYTE"),
_T ("BOOL"),
_T ("TRUE"),
_T ("FALSE"),
_T ("INT"),
_T ("UINT"),
_T ("WORD"),
_T ("DWORD"),
_T ("WPARAM"),
_T ("LPARAM"),
_T ("LRESULT"),
_T ("CString"),
NULL
};
static BOOL
IsXKeyword (LPTSTR apszKeywords[], LPCTSTR pszChars, int nLength)
{
for (int L = 0; apszKeywords[L] != NULL; L++)
{
if (_tcsncmp (apszKeywords[L], pszChars, nLength) == 0
&& apszKeywords[L][nLength] == 0)
return TRUE;
}
return FALSE;
}
static BOOL
IsCppKeyword (LPCTSTR pszChars, int nLength)
{
return IsXKeyword (s_apszCppKeywordList, pszChars, nLength);
}
static BOOL
IsUser1Keyword (LPCTSTR pszChars, int nLength)
{
return IsXKeyword (s_apszUser1KeywordList, pszChars, nLength);
}
static BOOL
IsCppNumber (LPCTSTR pszChars, int nLength)
{
if (nLength > 2 && pszChars[0] == '0' && pszChars[1] == 'x')
{
for (int I = 2; I < nLength; I++)
{
if (_istdigit (pszChars[I]) || (pszChars[I] >= 'A' && pszChars[I] <= 'F') ||
(pszChars[I] >= 'a' && pszChars[I] <= 'f'))
continue;
return FALSE;
}
return TRUE;
}
if (!_istdigit (pszChars[0]))
return FALSE;
for (int I = 1; I < nLength; I++)
{
if (!_istdigit (pszChars[I]) && pszChars[I] != '+' &&
pszChars[I] != '-' && pszChars[I] != '.' && pszChars[I] != 'e' &&
pszChars[I] != 'E')
return FALSE;
}
return TRUE;
}
#define DEFINE_BLOCK(pos, colorindex) \
ASSERT((pos) >= 0 && (pos) <= nLength);\
if (pBuf != NULL)\
{\
if (nActualItems == 0 || pBuf[nActualItems - 1].m_nCharPos <= (pos)){\
pBuf[nActualItems].m_nCharPos = (pos);\
pBuf[nActualItems].m_nColorIndex = (colorindex);\
nActualItems ++;}\
}
#define COOKIE_COMMENT 0x0001
#define COOKIE_PREPROCESSOR 0x0002
#define COOKIE_EXT_COMMENT 0x0004
#define COOKIE_STRING 0x0008
#define COOKIE_CHAR 0x0010
DWORD CCrystalTextView::
ParseLineC (DWORD dwCookie, int nLineIndex, TEXTBLOCK * pBuf, int &nActualItems)
{
int nLength = GetLineLength (nLineIndex);
if (nLength <= 1)
return dwCookie & COOKIE_EXT_COMMENT;
LPCTSTR pszChars = GetLineChars (nLineIndex);
BOOL bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0;
BOOL bRedefineBlock = TRUE;
BOOL bWasCommentStart = FALSE;
BOOL bDecIndex = FALSE;
int nIdentBegin = -1;
for (int I = 0;; I++)
{
if (bRedefineBlock)
{
int nPos = I;
if (bDecIndex)
nPos--;
if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT))
{
DEFINE_BLOCK (nPos, COLORINDEX_COMMENT);
}
else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING))
{
DEFINE_BLOCK (nPos, COLORINDEX_STRING);
}
else if (dwCookie & COOKIE_PREPROCESSOR)
{
DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR);
}
else
{
if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (pszChars[nPos - 1]) && !xisalpha (pszChars[nPos + 1])))
{
DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT);
}
else
{
DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR);
bRedefineBlock = TRUE;
bDecIndex = TRUE;
goto out;
}
}
bRedefineBlock = FALSE;
bDecIndex = FALSE;
}
out:
if (I == nLength)
break;
if (dwCookie & COOKIE_COMMENT)
{
DEFINE_BLOCK (I, COLORINDEX_COMMENT);
dwCookie |= COOKIE_COMMENT;
break;
}
// String constant "...."
if (dwCookie & COOKIE_STRING)
{
if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\')))
{
dwCookie &= ~COOKIE_STRING;
bRedefineBlock = TRUE;
}
continue;
}
// Char constant '..'
if (dwCookie & COOKIE_CHAR)
{
if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[I - 1] != '\\' || I >= 2 && (pszChars[I - 1] != '\\' || pszChars[I - 1] == '\\' && pszChars[I - 2] == '\\')))
{
dwCookie &= ~COOKIE_CHAR;
bRedefineBlock = TRUE;
}
continue;
}
// Extended comment /*....*/
if (dwCookie & COOKIE_EXT_COMMENT)
{
// if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '*')
if ((I > 1 && pszChars[I] == '/' && pszChars[I - 1] == '*' /*&& pszChars[I - 2] != '/'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == '/' && pszChars[I - 1] == '*'))
{
dwCookie &= ~COOKIE_EXT_COMMENT;
bRedefineBlock = TRUE;
}
bWasCommentStart = FALSE;
continue;
}
if (I > 0 && pszChars[I] == '/' && pszChars[I - 1] == '/')
{
DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT);
dwCookie |= COOKIE_COMMENT;
break;
}
// Preprocessor directive #....
if (dwCookie & COOKIE_PREPROCESSOR)
{
if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/')
{
DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT);
dwCookie |= COOKIE_EXT_COMMENT;
}
continue;
}
// Normal text
if (pszChars[I] == '"')
{
DEFINE_BLOCK (I, COLORINDEX_STRING);
dwCookie |= COOKIE_STRING;
continue;
}
if (pszChars[I] == '\'')
{
// if (I + 1 < nLength && pszChars[I + 1] == '\'' || I + 2 < nLength && pszChars[I + 1] != '\\' && pszChars[I + 2] == '\'' || I + 3 < nLength && pszChars[I + 1] == '\\' && pszChars[I + 3] == '\'')
if (!I || !xisalnum (pszChars[I - 1]))
{
DEFINE_BLOCK (I, COLORINDEX_STRING);
dwCookie |= COOKIE_CHAR;
continue;
}
}
if (I > 0 && pszChars[I] == '*' && pszChars[I - 1] == '/')
{
DEFINE_BLOCK (I - 1, COLORINDEX_COMMENT);
dwCookie |= COOKIE_EXT_COMMENT;
bWasCommentStart = TRUE;
continue;
}
bWasCommentStart = FALSE;
if (bFirstChar)
{
if (pszChars[I] == '#')
{
DEFINE_BLOCK (I, COLORINDEX_PREPROCESSOR);
dwCookie |= COOKIE_PREPROCESSOR;
continue;
}
if (!isspace (pszChars[I]))
bFirstChar = FALSE;
}
if (pBuf == NULL)
continue; // We don't need to extract keywords,
// for faster parsing skip the rest of loop
if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[I - 1]) && !xisalpha (pszChars[I + 1])))
{
if (nIdentBegin == -1)
nIdentBegin = I;
}
else
{
if (nIdentBegin >= 0)
{
if (IsCppKeyword (pszChars + nIdentBegin, I - nIdentBegin))
{
DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
}
else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
{
DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1);
}
else if (IsCppNumber (pszChars + nIdentBegin, I - nIdentBegin))
{
DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
}
else
{
bool bFunction = FALSE;
for (int j = I; j < nLength; j++)
{
if (!isspace (pszChars[j]))
{
if (pszChars[j] == '(')
{
bFunction = TRUE;
}
break;
}
}
if (bFunction)
{
DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME);
}
}
bRedefineBlock = TRUE;
bDecIndex = TRUE;
nIdentBegin = -1;
}
}
}
if (nIdentBegin >= 0)
{
if (IsCppKeyword (pszChars + nIdentBegin, I - nIdentBegin))
{
DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
}
else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
{
DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1);
}
else if (IsCppNumber (pszChars + nIdentBegin, I - nIdentBegin))
{
DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
}
else
{
bool bFunction = FALSE;
for (int j = I; j < nLength; j++)
{
if (!isspace (pszChars[j]))
{
if (pszChars[j] == '(')
{
bFunction = TRUE;
}
break;
}
}
if (bFunction)
{
DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME);
}
}
}
if (pszChars[nLength - 1] != '\\')
dwCookie &= COOKIE_EXT_COMMENT;
return dwCookie;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -