| 1 skipped line |
| 2 | U | 2 | U | /** @file LexHTML.cxx |
|
|
|
| 5 | C | // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> | | 5 | C | // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> |
| 6 | U | 6 | U | // The License.txt file describes the conditions under which this software may be distributed. |
|
|
|
| 26 skipped lines |
| 35 | U | 35 | U | return (ch < 0x80) && (isalnum(ch) || ch == '_'); |
|
|
|
| | | 38 | C | static inline int MakeLowerCase(int ch) { |
| | | 39 | C | if (ch < 'A' || ch > 'Z') |
| | | 40 | C | return ch; |
| | | 41 | C | else |
| | | 42 | C | return ch - 'A' + 'a'; |
| | | 43 | C | } |
| | | 44 | C | |
| 38 | C | static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, script_type prevValue) { | | 45 | C | static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) { |
| 39 | C | char s[30 + 1]; | | |
| 40 | C | unsigned int i = 0; | | 46 | C | size_t i = 0; |
| 41 | C | for (; i < end - start + 1 && i < 30; i++) { | | 47 | C | for (; (i < end - start + 1) && (i < len-1); i++) { |
| 42 | C | s[i] = static_cast<char>(tolower(styler[start + i])); | | 48 | C | s[i] = static_cast<char>(MakeLowerCase(styler[start + i])); |
|
|
| | | 51 | A | } |
| | | 52 | A | |
| | | 53 | A | static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, script_type prevValue) { |
| | | 54 | A | char s[100]; |
| | | 55 | A | GetTextSegment(styler, start, end, s, sizeof(s)); |
| 45 | U | 56 | U | //Platform::DebugPrintf("Scripting indicator [%s]\n", s); |
|
| 46 | U | 57 | U | if (strstr(s, "src")) // External script |
|
| 47 | U | 58 | U | return eScriptNone; |
|
| 15 skipped lines |
|
| 64 | U | 75 | U | static int PrintScriptingIndicatorOffset(Accessor &styler, unsigned int start, unsigned int end) { |
|
|
| 66 | C | char s[30 + 1]; | | 77 | C | char s[100]; |
| 67 | C | unsigned int i = 0; | | |
| 68 | C | for (; i < end - start + 1 && i < 30; i++) { | | 78 | C | GetTextSegment(styler, start, end, s, sizeof(s)); |
| 69 | C | s[i] = static_cast<char>(tolower(styler[start + i])); | | |
| 70 | C | } | | |
| 71 | C | s[i] = '\0'; | | |
| 72 | U | 79 | U | if (0 == strncmp(s, "php", 3)) { |
|
|
|
| 108 skipped lines |
| 183 | U | 190 | U | if (wordIsNumber) { |
|
| 184 | U | 191 | U | chAttr = SCE_H_NUMBER; |
|
|
| 186 | C | char s[30 + 1]; | | 193 | C | char s[100]; |
| 187 | C | unsigned int i = 0; | | |
| 188 | C | for (; i < end - start + 1 && i < 30; i++) { | | 194 | C | GetTextSegment(styler, start, end, s, sizeof(s)); |
| 189 | C | s[i] = static_cast<char>(tolower(styler[start + i])); | | |
| 190 | C | } | | |
| 191 | C | s[i] = '\0'; | | |
| 192 | U | 195 | U | if (keywords.InList(s)) |
|
| 193 | U | 196 | U | chAttr = SCE_H_ATTRIBUTE; |
|
|
| 12 skipped lines |
| 207 | U | 210 | U | for (unsigned int cPos = start; cPos <= end && i < 30; cPos++) { |
|
| 208 | U | 211 | U | char ch = styler[cPos]; |
|
| 209 | U | 212 | U | if ((ch != '<') && (ch != '/')) { |
|
| 210 | C | s[i++] = caseSensitive ? ch : static_cast<char>(tolower(ch)); | | 213 | C | s[i++] = caseSensitive ? ch : static_cast<char>(MakeLowerCase(ch)); |
|
|
|
| 56 skipped lines |
| 270 | U | 273 | U | if (wordIsNumber) |
|
| 271 | U | 274 | U | chAttr = SCE_HB_NUMBER; |
|
|
| 273 | C | char s[30 + 1]; | | 276 | C | char s[100]; |
| 274 | C | unsigned int i = 0; | | |
| 275 | C | for (; i < end - start + 1 && i < 30; i++) { | | 277 | C | GetTextSegment(styler, start, end, s, sizeof(s)); |
| 276 | C | s[i] = static_cast<char>(tolower(styler[start + i])); | | |
| 277 | C | } | | |
| 278 | C | s[i] = '\0'; | | |
| 279 | U | 278 | U | if (keywords.InList(s)) { |
|
| 280 | U | 279 | U | chAttr = SCE_HB_WORD; |
|
| 281 | U | 280 | U | if (strcmp(s, "rem") == 0) |
|
| 36 skipped lines |
| 318 | U | 317 | U | if (wordIsNumber) |
|
| 319 | U | 318 | U | chAttr = SCE_HPHP_NUMBER; |
|
|
| 321 | C | char s[100 + 1]; | | 320 | C | char s[100]; |
| 322 | C | unsigned int i = 0; | | |
| 323 | C | for (; i < end - start + 1 && i < 100; i++) { | | 321 | C | GetTextSegment(styler, start, end, s, sizeof(s)); |
| 324 | C | s[i] = static_cast<char>(tolower(styler[start + i])); | | |
| 325 | C | } | | |
| 326 | C | s[i] = '\0'; | | |
| 327 | U | 322 | U | if (keywords.InList(s)) |
|
| 328 | U | 323 | U | chAttr = SCE_HPHP_WORD; |
|
|
| 76 skipped lines |
| 406 | U | 401 | U | return state == SCE_H_COMMENT || state == SCE_H_SGML_COMMENT; |
|
|
|
| | | 404 | A | static bool IsScriptCommentState(const int state) { |
| | | 405 | A | return state == SCE_HJ_COMMENT || state == SCE_HJ_COMMENTLINE || state == SCE_HJA_COMMENT || |
| | | 406 | A | state == SCE_HJA_COMMENTLINE || state == SCE_HB_COMMENTLINE || state == SCE_HBA_COMMENTLINE; |
| | | 407 | A | } |
| | | 408 | A | |
| 409 | U | 409 | U | static bool isLineEnd(char ch) { |
|
| 410 | U | 410 | U | return ch == '\r' || ch == '\n'; |
|
|
| 12 skipped lines |
|
| 425 | U | 425 | U | static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler) { |
|
|
| | | 427 | A | while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t')) |
| | | 428 | A | i++; |
| 427 | U | 429 | U | phpStringDelimiter[0] = '\n'; |
|
| 428 | U | 430 | U | for (j = i; j < lengthDoc && styler[j] != '\n' && styler[j] != '\r'; j++) { |
|
| 429 | U | 431 | U | if (j - i < phpStringDelimiterSize - 2) |
|
| 71 skipped lines |
| 501 | U | 503 | U | char chPrev = ' '; |
|
|
| 503 | U | 505 | U | char chPrevNonWhite = ' '; |
|
| | | 506 | A | // look back to set chPrevNonWhite properly for better regex colouring |
| | | 507 | A | if (scriptLanguage == eScriptJS && startPos > 0) { |
| | | 508 | A | int back = startPos; |
| | | 509 | A | int style = 0; |
| | | 510 | A | while (--back) { |
| 5 skipped lines |
| | | 516 | A | if (style == SCE_HJ_SYMBOLS) { |
| | | 517 | A | chPrevNonWhite = styler.SafeGetCharAt(back); |
| | | 518 | A | } |
| | | 519 | A | } |
| | | 520 | A | |
| 504 | U | 521 | U | styler.StartSegment(startPos); |
|
| 505 | U | 522 | U | const int lengthDoc = startPos + length; |
|
| 506 | U | 523 | U | for (int i = startPos; i < lengthDoc; i++) { |
|
| 507 | U | 524 | U | const char chPrev2 = chPrev; |
|
|
| 509 | C | if (ch != ' ' && ch != '\t') | | 526 | C | if (!isspacechar(ch) && state != SCE_HJ_COMMENT && |
| | | 527 | C | state != SCE_HJ_COMMENTLINE && state != SCE_HJ_COMMENTDOC) |
| 510 | U | 528 | U | chPrevNonWhite = ch; |
|
|
| 512 | U | 530 | U | char chNext = styler.SafeGetCharAt(i + 1); |
|
| 92 skipped lines |
| 605 | U | 623 | U | case SCE_H_SINGLESTRING: |
|
| 606 | U | 624 | U | case SCE_HJ_COMMENT: |
|
| 607 | U | 625 | U | case SCE_HJ_COMMENTDOC: |
|
| 608 | C | // SCE_HJ_COMMENTLINE removed as this is a common thing done to hide | | 626 | C | //case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide |
| 609 | C | // the end of script marker from some JS interpreters. | | 627 | C | // the end of script marker from some JS interpreters. |
| 610 | C | //case SCE_HJ_COMMENTLINE: | | |
| 611 | U | 628 | U | case SCE_HJ_DOUBLESTRING: |
|
| 612 | U | 629 | U | case SCE_HJ_SINGLESTRING: |
|
| 613 | U | 630 | U | case SCE_HJ_REGEX: |
|
| 3 skipped lines |
| 617 | U | 634 | U | case SCE_HP_TRIPLEDOUBLE: |
|
|
|
| | | 637 | A | // check if the closing tag is a script tag |
| | | 638 | A | if (state == SCE_HJ_COMMENTLINE) { |
| | | 639 | A | char tag[7]; // room for the <script> tag |
| | | 640 | A | char chr; // current char |
| | | 641 | A | int j=0; |
| 3 skipped lines |
| | | 645 | A | chr = styler.SafeGetCharAt(i+2+j); |
| | | 646 | A | } |
| | | 647 | A | tag[j] = '\0'; |
| | | 648 | A | if (strcmp(tag, "script") != 0) break; |
| | | 649 | A | } |
| 620 | U | 650 | U | // closing tag of the script (it's a closing HTML tag anyway) |
|
| 621 | U | 651 | U | styler.ColourTo(i - 1, StateToPrint); |
|
| 622 | U | 652 | U | state = SCE_H_TAGUNKNOWN; |
|
| 13 skipped lines |
| 636 | U | 666 | U | !isPHPStringState(state) && |
|
| 637 | U | 667 | U | (state != SCE_HPHP_COMMENT) && |
|
|
| 639 | C | (chNext == '?')) { | | 669 | C | (chNext == '?') && |
| | | 670 | C | !IsScriptCommentState(state) ) { |
| 640 | U | 671 | U | scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment() + 2, i + 10, eScriptPHP); |
|
| 641 | U | 672 | U | if (scriptLanguage != eScriptPHP && isStringState(state)) continue; |
|
| 642 | U | 673 | U | styler.ColourTo(i - 1, StateToPrint); |
|
| 10 skipped lines |
| 653 | U | 684 | U | inScriptType = eNonHtmlScriptPreProc; |
|
|
| 655 | U | 686 | U | inScriptType = eNonHtmlPreProc; |
|
| 656 | C | // fold whole script | | 687 | C | // Fold whole script, but not if the XML first tag (all XML-like tags in this case) |
| 657 | C | if (foldHTMLPreprocessor){ | | 688 | C | if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) { |
|
| 659 | R | if (scriptLanguage == eScriptXML) | | |
| 660 | R | levelCurrent--; // no folding of the XML first tag (all XML-like tags in this case) | | |
|
| 662 | U | 691 | U | // should be better |
|
| 663 | U | 692 | U | ch = styler.SafeGetCharAt(i); |
|
| 1 skipped line |
|
|
| 667 | U | 696 | U | // handle the start of ASP pre-processor = Non-HTML |
|
| 668 | C | else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%')) { | | 697 | C | else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) { |
| 669 | U | 698 | U | styler.ColourTo(i - 1, StateToPrint); |
|
| 670 | U | 699 | U | beforePreProc = state; |
|
| 671 | U | 700 | U | if (inScriptType == eNonHtmlScript) |
|
| 34 skipped lines |
| 706 | U | 735 | U | ///////////////////////////////////// |
|
| 707 | U | 736 | U | // handle the start of SGML language (DTD) |
|
| 708 | U | 737 | U | else if (((scriptLanguage == eScriptNone) || (scriptLanguage == eScriptXML)) && |
|
| 709 | C | (chPrev == '<') && | | 738 | C | (chPrev == '<') && |
| 710 | C | (ch == '!') && | | 739 | C | (ch == '!') && |
| 711 | C | (StateToPrint != SCE_H_CDATA) && (!IsCommentState(StateToPrint))) { | | 740 | C | (StateToPrint != SCE_H_CDATA) && |
| | | 741 | C | (!IsCommentState(StateToPrint)) && |
| | | 742 | C | (!IsScriptCommentState(StateToPrint)) ) { |
| 712 | U | 743 | U | beforePreProc = state; |
|
| 713 | U | 744 | U | styler.ColourTo(i - 2, StateToPrint); |
|
| 714 | U | 745 | U | if ((chNext == '-') && (chNext2 == '-')) { |
|
| 715 | U | 746 | U | state = SCE_H_COMMENT; // wait for a pending command |
|
| 716 | C | } | | 747 | C | styler.ColourTo(i + 2, SCE_H_COMMENT); |
| | | 748 | C | i += 2; // follow styling after the -- |
| 717 | C | else if (isWordCdata(i + 1, i + 7, styler)) { | | 749 | C | } else if (isWordCdata(i + 1, i + 7, styler)) { |
| 718 | U | 750 | U | state = SCE_H_CDATA; |
|
|
| 720 | U | 752 | U | styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default |
|
| 12 skipped lines |
| 733 | U | 765 | U | || (inScriptType == eNonHtmlScriptPreProc)) && ( |
|
| 734 | U | 766 | U | ((scriptLanguage == eScriptPHP) && (ch == '?') && !isPHPStringState(state) && (state != SCE_HPHP_COMMENT)) || |
|
| 735 | U | 767 | U | ((scriptLanguage != eScriptNone) && !isStringState(state) && |
|
| 736 | C | (ch == '%')) | | 768 | C | ((ch == '%') || (ch == '?'))) |
| 737 | U | 769 | U | ) && (chNext == '>')) || |
|
| 738 | U | 770 | U | ((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) { |
|
| 739 | U | 771 | U | if (state == SCE_H_ASPAT) { |
|
| 38 skipped lines |
| 778 | U | 810 | U | inScriptType = eNonHtmlScript; |
|
|
| 780 | U | 812 | U | inScriptType = eHtml; |
|
| 781 | C | scriptLanguage = eScriptNone; | | |
| 782 | C | // unfold all scripting languages | | 813 | C | // Unfold all scripting languages, except for XML tag |
| 783 | C | if (foldHTMLPreprocessor) | | 814 | C | if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) { |
|
| | | 816 | A | } |
| | | 817 | A | scriptLanguage = eScriptNone; |
|
|
| 787 | U | 820 | U | ///////////////////////////////////// |
|
| 431 skipped lines |
| 1219 | U | 1252 | U | if (ch == '/' && chPrev == '*') { |
|
| 1220 | U | 1253 | U | styler.ColourTo(i, StateToPrint); |
|
| 1221 | U | 1254 | U | state = SCE_HJ_DEFAULT; |
|
| | | 1255 | A | ch = ' '; |
|
|
| 1224 | U | 1258 | U | case SCE_HJ_COMMENTLINE: |
|
| 1225 | U | 1259 | U | if (ch == '\r' || ch == '\n') { |
|
| 1226 | U | 1260 | U | styler.ColourTo(i - 1, statePrintForState(SCE_HJ_COMMENTLINE, inScriptType)); |
|
| 1227 | U | 1261 | U | state = SCE_HJ_DEFAULT; |
|
| | | 1262 | A | ch = ' '; |
|
|
| 1230 | U | 1265 | U | case SCE_HJ_DOUBLESTRING: |
|
| 41 skipped lines |
|
| 1273 | U | 1308 | U | case SCE_HJ_REGEX: |
|
| 1274 | U | 1309 | U | if (ch == '\r' || ch == '\n' || ch == '/') { |
|
| | | 1310 | A | if (ch == '/') { |
| | | 1311 | A | while (isascii(chNext) && islower(chNext)) { // gobble regex flags |
| | | 1312 | A | i++; |
| | | 1313 | A | ch = chNext; |
| | | 1314 | A | chNext = styler.SafeGetCharAt(i + 1); |
| | | 1315 | A | } |
| | | 1316 | A | } |
| 1275 | U | 1317 | U | styler.ColourTo(i, StateToPrint); |
|
| 1276 | U | 1318 | U | state = SCE_HJ_DEFAULT; |
|
| 1277 | U | 1319 | U | } else if (ch == '\\') { |
|
| 218 skipped lines |
|
|
| 1498 | U | 1540 | U | case SCE_HPHP_NUMBER: |
|
| | | 1541 | C | // recognize bases 8,10 or 16 integers OR floating-point numbers |
| | | 1542 | C | if (!IsADigit(ch) |
| | | 1543 | C | && strchr(".xXabcdefABCDEF", ch) == NULL |
| 1499 | C | if (!IsADigit(ch) && ch != '.' && ch != 'e' && ch != 'E' && (ch != '-' || (chPrev != 'e' && chPrev != 'E'))) { | | 1544 | C | && ((ch != '-' && ch != '+') || (chPrev != 'e' && chPrev != 'E'))) { |
| 1500 | U | 1545 | U | styler.ColourTo(i - 1, SCE_HPHP_NUMBER); |
|
| 1501 | U | 1546 | U | if (isoperator(ch)) |
|
| 1502 | U | 1547 | U | state = SCE_HPHP_OPERATOR; |
|
| 443 skipped lines |
| 1946 | U | 1991 | U | sc.Complete(); |
|
|
|
| | | 1994 | A | static void ColourisePHPScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], |
| | | 1995 | A | Accessor &styler) { |
| | | 1996 | A | if(startPos == 0) initStyle = SCE_HPHP_DEFAULT; |
| | | 1997 | A | ColouriseHyperTextDoc(startPos,length,initStyle,keywordlists,styler); |
| | | 1998 | A | } |
| | | 1999 | A | |
| 1949 | U | 2000 | U | static const char * const htmlWordListDesc[] = { |
|
| 1950 | U | 2001 | U | "HTML elements and attributes", |
|
| 1951 | U | 2002 | U | "JavaScript keywords", |
|
| 4 skipped lines |
|
|
|
| | | 2010 | C | static const char * const phpscriptWordListDesc[] = { |
| | | 2011 | C | "", //Unused |
| | | 2012 | C | "", //Unused |
| | | 2013 | C | "", //Unused |
| | | 2014 | C | "", //Unused |
| | | 2015 | C | "PHP keywords", |
| | | 2016 | C | "", //Unused |
| | | 2017 | C | 0, |
| | | 2018 | C | }; |
| | | 2019 | C | |
| 1959 | C | LexerModule lmHTML(SCLEX_HTML, ColouriseHyperTextDoc, "hypertext", 0, htmlWordListDesc); | | 2020 | C | LexerModule lmHTML(SCLEX_HTML, ColouriseHyperTextDoc, "hypertext", 0, htmlWordListDesc, 7); |
| 1960 | C | LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc, "xml", 0, htmlWordListDesc); | | 2021 | C | LexerModule lmXML(SCLEX_XML, ColouriseHyperTextDoc, "xml", 0, htmlWordListDesc, 7); |
| | | 2022 | C | // SCLEX_ASP and SCLEX_PHP should not be used in new code: use SCLEX_HTML instead. |
| 1961 | C | LexerModule lmASP(SCLEX_ASP, ColouriseASPDoc, "asp", 0, htmlWordListDesc); | | 2023 | C | LexerModule lmASP(SCLEX_ASP, ColouriseASPDoc, "asp", 0, htmlWordListDesc, 7); |
| 1962 | C | LexerModule lmPHP(SCLEX_PHP, ColourisePHPDoc, "php", 0, htmlWordListDesc); | | 2024 | C | LexerModule lmPHP(SCLEX_PHP, ColourisePHPDoc, "php", 0, htmlWordListDesc, 7); |
| | | 2025 | C | LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc, 7); |
|