1 ///////////////////////////////////////////////////////////////////////////
4 // Updated: 19-Jul-1998
6 // Copyright: Ferdinand Prantl, portions by Stcherbatchenko Andrei
7 // E-mail: prantl@ff.cuni.cz
9 // SIOD 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_apszSiodKeywordList[] =
101 static LPCTSTR s_apszUser1KeywordList[] =
114 static LPCTSTR s_apszUser2KeywordList[] =
117 _T("%%closure-code"),
125 _T("*eval-history-ptr*"),
130 _T("access-problem?"),
138 _T("benchmark-eval"),
139 _T("benchmark-funcall1"),
140 _T("benchmark-funcall2"),
152 _T("cpu-usage-limits"),
154 _T("current-resource-usage"),
157 _T("decode-file-mode"),
160 _T("encode-file-mode"),
161 _T("encode-open-flags"),
234 _T("os-classification"),
240 _T("print-to-string"),
250 _T("read-from-string"),
264 _T("set-eval-history"),
265 _T("set-symbol-value!"),
281 _T("string-dimension"),
282 _T("string-downcase"),
285 _T("string-trim-left"),
286 _T("string-trim-right"),
292 _T("substring-equal?"),
301 _T("the-environment"),
308 _T("unix-time->strtime"),
322 IsSiodKeyword (LPCTSTR pszChars, int nLength)
324 return ISXKEYWORDI (s_apszSiodKeywordList, pszChars, nLength);
328 IsUser1Keyword (LPCTSTR pszChars, int nLength)
330 return ISXKEYWORDI (s_apszUser1KeywordList, pszChars, nLength);
334 IsUser2Keyword (LPCTSTR pszChars, int nLength)
336 return ISXKEYWORDI (s_apszUser2KeywordList, pszChars, nLength);
340 CrystalLineParser::ParseLineSiod (DWORD dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems)
343 return dwCookie & COOKIE_EXT_COMMENT;
345 bool bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0;
346 bool bRedefineBlock = true;
347 bool bWasCommentStart = false;
348 bool bDecIndex = false;
349 int nIdentBegin = -1;
354 for (I = 0;; nPrevI = I, I = static_cast<int>(::CharNext(pszChars+I) - pszChars))
358 // CharNext did not advance, so we're at the end of the string
359 // and we already handled this character, so stop
368 if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT))
370 DEFINE_BLOCK (nPos, COLORINDEX_COMMENT);
372 else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING))
374 DEFINE_BLOCK (nPos, COLORINDEX_STRING);
378 if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.')
380 DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT);
384 DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR);
385 bRedefineBlock = true;
390 bRedefineBlock = false;
395 // Can be bigger than length if there is binary data
396 // See bug #1474782 Crash when comparing SQL with with binary data
397 if (I >= nLength || pszChars[I] == 0)
400 if (dwCookie & COOKIE_COMMENT)
402 DEFINE_BLOCK (I, COLORINDEX_COMMENT);
403 dwCookie |= COOKIE_COMMENT;
407 // String constant "...."
408 if (dwCookie & COOKIE_STRING)
410 if (pszChars[I] == '"' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\')))
412 dwCookie &= ~COOKIE_STRING;
413 bRedefineBlock = true;
418 // Char constant '..'
419 if (dwCookie & COOKIE_CHAR)
421 if (pszChars[I] == '\'' && (I == 0 || I == 1 && pszChars[nPrevI] != '\\' || I >= 2 && (pszChars[nPrevI] != '\\' || *::CharPrev(pszChars, pszChars + nPrevI) == '\\')))
423 dwCookie &= ~COOKIE_CHAR;
424 bRedefineBlock = true;
429 // Extended comment /*....*/
430 if (dwCookie & COOKIE_EXT_COMMENT)
432 // if (I > 0 && pszChars[I] == ';' && pszChars[nPrevI] == '|')
433 if ((I > 1 && pszChars[I] == ';' && pszChars[nPrevI] == '|' /*&& *::CharPrev(pszChars, pszChars + nPrevI) != ';'*/ && !bWasCommentStart) || (I == 1 && pszChars[I] == ';' && pszChars[nPrevI] == '|'))
435 dwCookie &= ~COOKIE_EXT_COMMENT;
436 bRedefineBlock = true;
438 bWasCommentStart = false;
442 if (I > 0 && pszChars[I] != '|' && pszChars[nPrevI] == ';')
444 DEFINE_BLOCK (I, COLORINDEX_COMMENT);
445 dwCookie |= COOKIE_COMMENT;
450 if (pszChars[I] == '"')
452 DEFINE_BLOCK (I, COLORINDEX_STRING);
453 dwCookie |= COOKIE_STRING;
456 if (pszChars[I] == '\'')
458 // 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] == '\'')
459 if (!I || !xisalnum (pszChars[nPrevI]))
461 DEFINE_BLOCK (I, COLORINDEX_STRING);
462 dwCookie |= COOKIE_CHAR;
466 if (I > 0 && pszChars[I] == '|' && pszChars[nPrevI] == ';')
468 DEFINE_BLOCK (nPrevI, COLORINDEX_COMMENT);
469 dwCookie |= COOKIE_EXT_COMMENT;
470 bWasCommentStart = true;
474 bWasCommentStart = false;
478 if (!xisspace (pszChars[I]))
483 continue; // We don't need to extract keywords,
484 // for faster parsing skip the rest of loop
486 if (xisalnum (pszChars[I]) || pszChars[I] == '.')
488 if (nIdentBegin == -1)
493 if (nIdentBegin >= 0)
495 if (IsSiodKeyword (pszChars + nIdentBegin, I - nIdentBegin))
497 if (!_tcsnicmp (_T ("defun"), pszChars + nIdentBegin, 5))
501 DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
503 else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
505 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1);
507 else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin))
509 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2);
511 else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
513 DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
517 bool bFunction = false;
521 for (int j = nIdentBegin; --j >= 0;)
523 if (!xisspace (pszChars[j]))
525 if (pszChars[j] == '(')
535 for (int j = I; j >= 0; j--)
537 if (!xisspace (pszChars[j]))
539 if (pszChars[j] == '(')
549 DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME);
552 bRedefineBlock = true;
559 if (nIdentBegin >= 0)
561 if (IsSiodKeyword (pszChars + nIdentBegin, I - nIdentBegin))
563 if (!_tcsnicmp (_T ("defun"), pszChars + nIdentBegin, 5))
567 DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
569 else if (IsUser1Keyword (pszChars + nIdentBegin, I - nIdentBegin))
571 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER1);
573 else if (IsUser2Keyword (pszChars + nIdentBegin, I - nIdentBegin))
575 DEFINE_BLOCK (nIdentBegin, COLORINDEX_USER2);
577 else if (IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
579 DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
583 bool bFunction = false;
587 for (int j = nIdentBegin; --j >= 0;)
589 if (!xisspace (pszChars[j]))
591 if (pszChars[j] == '(')
601 for (int j = I; j >= 0; j--)
603 if (!xisspace (pszChars[j]))
605 if (pszChars[j] == '(')
615 DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME);
620 dwCookie &= COOKIE_EXT_COMMENT;