1 ///////////////////////////////////////////////////////////////////////////
4 // Updated: 19-Jul-1998
6 // Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei
7 // E-mail: prantl@ff.cuni.cz
9 // FORTRAN 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"
26 // C++ keywords (MSVC5.0 + POET5.0)
27 static LPCTSTR s_apszFortranKeywordList[] =
84 _T ("doubleprecision"),
184 _T ("random_number"),
201 _T ("selected_int_kind"),
202 _T ("selected_real_kind"),
237 IsFortranKeyword (LPCTSTR pszChars, int nLength)
239 return ISXKEYWORDI (s_apszFortranKeywordList, pszChars, nLength);
243 CrystalLineParser::ParseLineFortran (DWORD dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems)
246 return dwCookie & COOKIE_EXT_COMMENT;
248 bool bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0;
249 bool bRedefineBlock = true;
250 bool bDecIndex = false;
251 int nIdentBegin = -1;
254 for (I = 0;; nPrevI = I, I = static_cast<int>(::CharNext(pszChars+I) - pszChars))
258 // CharNext did not advance, so we're at the end of the string
259 // and we already handled this character, so stop
268 if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT))
270 DEFINE_BLOCK (nPos, COLORINDEX_COMMENT);
272 else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING))
274 DEFINE_BLOCK (nPos, COLORINDEX_STRING);
278 if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (*::CharPrev(pszChars, pszChars + nPos)) && !xisalpha (*::CharNext(pszChars + nPos))))
280 DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT);
284 DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR);
285 bRedefineBlock = true;
290 bRedefineBlock = false;
295 // Can be bigger than length if there is binary data
296 // See bug #1474782 Crash when comparing SQL with with binary data
297 if (I >= nLength || pszChars[I] == 0)
300 if (dwCookie & COOKIE_COMMENT)
302 DEFINE_BLOCK (I, COLORINDEX_COMMENT);
303 dwCookie |= COOKIE_COMMENT;
307 // String constant "...."
308 if (dwCookie & COOKIE_STRING)
310 if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\')))
312 dwCookie &= ~COOKIE_STRING;
313 bRedefineBlock = true;
318 // Char constant '..'
319 if (dwCookie & COOKIE_CHAR)
321 if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\')))
323 dwCookie &= ~COOKIE_CHAR;
324 bRedefineBlock = true;
329 if (pszChars[I] == '!' || !I && (pszChars[I] == 'C' || pszChars[I] == 'c'))
331 DEFINE_BLOCK (I, COLORINDEX_COMMENT);
332 dwCookie |= COOKIE_COMMENT;
337 if (pszChars[I] == '"')
339 DEFINE_BLOCK (I, COLORINDEX_STRING);
340 dwCookie |= COOKIE_STRING;
343 if (pszChars[I] == '\'')
345 // 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] == '\'')
346 if (!I || !xisalnum (pszChars[nPrevI]))
348 DEFINE_BLOCK (I, COLORINDEX_STRING);
349 dwCookie |= COOKIE_CHAR;
356 if (!xisspace (pszChars[I]))
361 continue; // We don't need to extract keywords,
362 // for faster parsing skip the rest of loop
364 if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[nPrevI]) && !xisalpha (pszChars[I + 1])))
366 if (nIdentBegin == -1)
371 if (nIdentBegin >= 0)
373 if (IsFortranKeyword (pszChars + nIdentBegin, I - nIdentBegin))
375 DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
377 else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
379 DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
381 bRedefineBlock = true;
388 if (nIdentBegin >= 0)
390 if (IsFortranKeyword (pszChars + nIdentBegin, I - nIdentBegin))
392 DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
394 else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
396 DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
400 if (pszChars[nLength - 1] != '\\' || IsMBSTrail(pszChars, nLength - 1))
401 dwCookie &= COOKIE_EXT_COMMENT;