1 ///////////////////////////////////////////////////////////////////////////
4 // Updated: 19-Jul-1998
6 // Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei
7 // E-mail: prantl@ff.cuni.cz
9 // Pascal syntax highlighing definition
11 // You are free to use or modify this code to the following restrictions:
12 // - Acknowledge me somewhere in your about box, simple "Parts of code by.."
13 // will be enough. If you can't (or don't want to), contact me personally.
14 // - LEAVE THIS HEADER INTACT
15 ////////////////////////////////////////////////////////////////////////////
18 #include "crystallineparser.h"
19 #include "SyntaxColors.h"
20 #include "string_util.h"
27 static LPCTSTR s_apszPascalKeywordList[] =
59 _T ("implementation"),
110 IsPascalKeyword (LPCTSTR pszChars, int nLength)
112 return ISXKEYWORDI (s_apszPascalKeywordList, pszChars, nLength);
116 CrystalLineParser::ParseLinePascal (DWORD dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems)
119 return dwCookie & (COOKIE_EXT_COMMENT | COOKIE_EXT_COMMENT2);
121 bool bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0;
122 bool bRedefineBlock = true;
123 bool bDecIndex = false;
124 int nIdentBegin = -1;
127 for (I = 0;; nPrevI = I, I = static_cast<int>(::CharNext(pszChars+I) - pszChars))
131 // CharNext did not advance, so we're at the end of the string
132 // and we already handled this character, so stop
141 if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT | COOKIE_EXT_COMMENT2))
143 DEFINE_BLOCK (nPos, COLORINDEX_COMMENT);
145 else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING))
147 DEFINE_BLOCK (nPos, COLORINDEX_STRING);
151 if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (*::CharPrev(pszChars, pszChars + nPos)) && !xisalpha (*::CharNext(pszChars + nPos))))
153 DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT);
157 DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR);
158 bRedefineBlock = true;
163 bRedefineBlock = false;
168 // Can be bigger than length if there is binary data
169 // See bug #1474782 Crash when comparing SQL with with binary data
170 if (I >= nLength || pszChars[I] == 0)
173 if (dwCookie & COOKIE_COMMENT)
175 DEFINE_BLOCK (I, COLORINDEX_COMMENT);
176 dwCookie |= COOKIE_COMMENT;
180 // String constant "...."
181 if (dwCookie & COOKIE_STRING)
183 if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\')))
185 dwCookie &= ~COOKIE_STRING;
186 bRedefineBlock = true;
191 // Char constant '..'
192 if (dwCookie & COOKIE_CHAR)
194 if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\')))
196 dwCookie &= ~COOKIE_CHAR;
197 bRedefineBlock = true;
202 // Extended comment /*....*/
203 if (dwCookie & COOKIE_EXT_COMMENT)
205 // if (I > 0 && pszChars[I] == ')' && pszChars[nPrevI] == '*')
206 if ((I > 1 && pszChars[I] == ')' && pszChars[nPrevI] == '*' && *::CharPrev(pszChars, pszChars + nPrevI) != '(') || (I == 1 && pszChars[I] == ')' && pszChars[nPrevI] == '*'))
208 dwCookie &= ~COOKIE_EXT_COMMENT;
209 bRedefineBlock = true;
214 // Extended comment {....}
215 if (dwCookie & COOKIE_EXT_COMMENT2)
217 if (pszChars[I] == '}')
219 dwCookie &= ~COOKIE_EXT_COMMENT2;
220 bRedefineBlock = true;
225 if (I > 0 && pszChars[I] == '/' && pszChars[nPrevI] == '/')
227 DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT);
228 dwCookie |= COOKIE_COMMENT;
233 if (pszChars[I] == '"')
235 DEFINE_BLOCK (I, COLORINDEX_STRING);
236 dwCookie |= COOKIE_STRING;
239 if (pszChars[I] == '\'')
241 // 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] == '\'')
242 if (!I || !xisalnum (pszChars[nPrevI]))
244 DEFINE_BLOCK (I, COLORINDEX_STRING);
245 dwCookie |= COOKIE_CHAR;
249 if (I > 0 && pszChars[I] == '*' && pszChars[nPrevI] == '(')
251 DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT);
252 dwCookie |= COOKIE_EXT_COMMENT;
256 if (pszChars[I] == '{')
258 DEFINE_BLOCK (I, COLORINDEX_COMMENT);
259 dwCookie |= COOKIE_EXT_COMMENT2;
265 if (!xisspace (pszChars[I]))
270 continue; // We don't need to extract keywords,
271 // for faster parsing skip the rest of loop
273 if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[nPrevI]) && !xisalpha (pszChars[I + 1])))
275 if (nIdentBegin == -1)
280 if (nIdentBegin >= 0)
282 if (IsPascalKeyword (pszChars + nIdentBegin, I - nIdentBegin))
284 DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
286 else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
288 DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
292 bool bFunction = false;
294 for (int j = I; j < nLength; j++)
296 if (!xisspace (pszChars[j]))
298 if (pszChars[j] == '(')
307 DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME);
310 bRedefineBlock = true;
317 if (nIdentBegin >= 0)
319 if (IsPascalKeyword (pszChars + nIdentBegin, I - nIdentBegin))
321 DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
323 else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
325 DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
329 bool bFunction = false;
331 for (int j = I; j < nLength; j++)
333 if (!xisspace (pszChars[j]))
335 if (pszChars[j] == '(')
344 DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME);
349 if (pszChars[nLength - 1] != '\\' || IsMBSTrail(pszChars, nLength - 1))
350 dwCookie &= (COOKIE_EXT_COMMENT | COOKIE_EXT_COMMENT2);