1 ///////////////////////////////////////////////////////////////////////////
4 // Updated: 19-Jul-1998
6 // Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei
7 // E-mail: prantl@ff.cuni.cz
9 // XML 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 "../utils/string_util.h"
26 // C++ keywords (MSVC5.0 + POET5.0)
27 static const TCHAR * s_apszXmlKeywordList[] =
37 static const TCHAR * s_apszUser1KeywordList[] =
64 IsXmlKeyword (const TCHAR *pszChars, int nLength)
66 return ISXKEYWORDI (s_apszXmlKeywordList, pszChars, nLength);
70 IsUser1Keyword (const TCHAR *pszChars, int nLength)
72 return ISXKEYWORDI (s_apszUser1KeywordList, pszChars, nLength);
76 CrystalLineParser::ParseLineXml (unsigned dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems)
79 return dwCookie & COOKIE_EXT_COMMENT;
81 bool bRedefineBlock = true;
82 bool bDecIndex = false;
86 for (I = 0;; nPrevI = I, I = static_cast<int>(::CharNext(pszChars+I) - pszChars))
90 // CharNext did not advance, so we're at the end of the string
91 // and we already handled this character, so stop
100 if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT))
102 DEFINE_BLOCK (nPos, COLORINDEX_COMMENT);
104 else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING))
106 DEFINE_BLOCK (nPos, COLORINDEX_STRING);
108 else if (dwCookie & COOKIE_PREPROCESSOR)
110 DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR);
114 if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.')
116 DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT);
120 DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR);
121 bRedefineBlock = true;
126 bRedefineBlock = false;
131 // Can be bigger than length if there is binary data
132 // See bug #1474782 Crash when comparing SQL with with binary data
133 if (I >= nLength || pszChars[I] == 0)
136 if (dwCookie & COOKIE_COMMENT)
138 DEFINE_BLOCK (I, COLORINDEX_COMMENT);
139 dwCookie |= COOKIE_COMMENT;
143 // String constant "...."
144 if (dwCookie & COOKIE_STRING)
146 if (pszChars[I] == '"')
148 dwCookie &= ~COOKIE_STRING;
149 bRedefineBlock = true;
154 // Char constant '..'
155 if (dwCookie & COOKIE_CHAR)
157 if (pszChars[I] == '\'')
159 dwCookie &= ~COOKIE_CHAR;
160 bRedefineBlock = true;
165 // Extended comment <!--....-->
166 if (dwCookie & COOKIE_EXT_COMMENT)
168 if (I > 1 && pszChars[I] == '>' && pszChars[nPrevI] == '-' && *::CharPrev(pszChars, pszChars + nPrevI) == '-')
170 dwCookie &= ~COOKIE_EXT_COMMENT;
171 bRedefineBlock = true;
176 // Extended comment <?....?>
177 if (dwCookie & COOKIE_EXT_USER1)
179 if (I > 0 && pszChars[I] == '>' && pszChars[nPrevI] == '?')
181 dwCookie &= ~COOKIE_EXT_USER1;
182 bRedefineBlock = true;
188 if (pszChars[I] == '"')
190 DEFINE_BLOCK (I, COLORINDEX_STRING);
191 dwCookie |= COOKIE_STRING;
194 if (pszChars[I] == '\'')
196 // 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] == '\'')
197 if (!I || !xisalnum (pszChars[nPrevI]))
199 DEFINE_BLOCK (I, COLORINDEX_STRING);
200 dwCookie |= COOKIE_CHAR;
204 if (!(dwCookie & COOKIE_EXT_USER1) && I < nLength - 3 && pszChars[I] == '<' && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-')
206 DEFINE_BLOCK (I, COLORINDEX_COMMENT);
208 dwCookie |= COOKIE_EXT_COMMENT;
209 dwCookie &= ~COOKIE_PREPROCESSOR;
214 continue; // We don't need to extract keywords,
215 // for faster parsing skip the rest of loop
217 if (xisalnum (pszChars[I]) || pszChars[I] == '.')
219 if (nIdentBegin == -1)
224 if (nIdentBegin >= 0)
226 if (dwCookie & COOKIE_PREPROCESSOR)
228 if (IsXmlKeyword (pszChars + nIdentBegin, I - nIdentBegin))
230 DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
232 else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
234 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1);
236 else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
238 DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
245 else if (dwCookie & COOKIE_USER1)
247 if (IsHtmlUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin))
249 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2);
256 else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
258 DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
264 bRedefineBlock = true;
270 // Preprocessor start: < or bracket
271 if (!(dwCookie & COOKIE_EXT_USER1) && pszChars[I] == '<' && !(I < nLength - 3 && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-') || pszChars[I] == '{')
273 DEFINE_BLOCK (I, COLORINDEX_PREPROCESSOR);
274 dwCookie |= COOKIE_PREPROCESSOR;
279 // Preprocessor end: > or bracket
280 if (dwCookie & COOKIE_PREPROCESSOR)
282 if (pszChars[I] == '>' || pszChars[I] == '}')
284 dwCookie &= ~COOKIE_PREPROCESSOR;
286 bRedefineBlock = true;
290 // Preprocessor start: &
291 if (pszChars[I] == '&')
293 dwCookie |= COOKIE_USER1;
298 // Preprocessor end: ;
299 if (dwCookie & COOKIE_USER1)
301 if (pszChars[I] == ';')
303 dwCookie &= ~COOKIE_USER1;
311 if (nIdentBegin >= 0 && (dwCookie & COOKIE_PREPROCESSOR))
313 if (IsXmlKeyword (pszChars + nIdentBegin, I - nIdentBegin))
315 DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
317 else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
319 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1);
321 else if (IsHtmlUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin))
323 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2);
325 else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
327 DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
330 // Preprocessor start: < or {
331 if (!(dwCookie & COOKIE_EXT_USER1) && pszChars[I] == '<' && !(I < nLength - 3 && pszChars[I + 1] == '!' && pszChars[I + 2] == '-' && pszChars[I + 3] == '-') || pszChars[I] == '{')
333 DEFINE_BLOCK (I + 1, COLORINDEX_PREPROCESSOR);
334 dwCookie |= COOKIE_PREPROCESSOR;
339 // Preprocessor end: > or }
340 if (dwCookie & COOKIE_PREPROCESSOR)
342 if (pszChars[I] == '>' || pszChars[I] == '}')
344 dwCookie &= ~COOKIE_PREPROCESSOR;
349 dwCookie &= (COOKIE_EXT_COMMENT | COOKIE_STRING | COOKIE_PREPROCESSOR | COOKIE_EXT_USER1);