SF.net SVN: geany:[2799] trunk
eht16 at users.sourceforge.net
eht16 at xxxxx
Tue Jul 22 13:06:11 UTC 2008
Revision: 2799
http://geany.svn.sourceforge.net/geany/?rev=2799&view=rev
Author: eht16
Date: 2008-07-22 13:06:11 +0000 (Tue, 22 Jul 2008)
Log Message:
-----------
Backport latest HTML/PHP lexer fixes from Scintilla CVS (#2024387).
Modified Paths:
--------------
trunk/ChangeLog
trunk/scintilla/LexHTML.cxx
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2008-07-21 17:25:18 UTC (rev 2798)
+++ trunk/ChangeLog 2008-07-22 13:06:11 UTC (rev 2799)
@@ -1,3 +1,9 @@
+2008-07-22 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
+
+ * scintilla/LexHTML.cxx:
+ Backport latest HTML/PHP lexer fixes from Scintilla CVS (#2024387).
+
+
2008-07-21 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
* src/main.c, src/socket.c, src/main.h:
@@ -21,6 +27,7 @@
Move code to reload configuration files into utils_reload_configuration()
and add it to the plugin API.
+
2008-07-18 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
* plugins/classbuilder.c, plugins/demoplugin.c, plugins/export.c,
Modified: trunk/scintilla/LexHTML.cxx
===================================================================
--- trunk/scintilla/LexHTML.cxx 2008-07-21 17:25:18 UTC (rev 2798)
+++ trunk/scintilla/LexHTML.cxx 2008-07-22 13:06:11 UTC (rev 2799)
@@ -29,7 +29,7 @@
#define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START)
#define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START)
-enum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock };
+enum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock, eScriptComment };
enum script_mode { eHtml = 0, eNonHtmlScript, eNonHtmlPreProc, eNonHtmlScriptPreProc };
static inline bool IsAWordChar(const int ch) {
@@ -249,7 +249,7 @@
static int classifyTagHTML(unsigned int start, unsigned int end,
WordList &keywords, Accessor &styler, bool &tagDontFold,
- bool caseSensitive, bool isXml) {
+ bool caseSensitive, bool isXml, bool allowScripts) {
char s[30 + 2];
// Copy after the '<'
unsigned int i = 0;
@@ -268,31 +268,28 @@
// if the current language is XML, I can fold any tag
// if the current language is HTML, I don't want to fold certain tags (input, meta, etc.)
//...to find it in the list of no-container-tags
- tagDontFold = (!isXml) && (NULL != strstr("meta link img area br hr input ",s));
+ tagDontFold = (!isXml) && (NULL != strstr("meta link img area br hr input ", s));
//now we can remove the trailing space
s[i] = '\0';
- bool isScript = false;
+ // No keywords -> all are known
+ // Name of a closing tag starts at s + 1
char chAttr = SCE_H_TAGUNKNOWN;
if (s[0] == '!') {
chAttr = SCE_H_SGML_DEFAULT;
- } else if (s[0] == '/') { // Closing tag
- if (keywords.InList(s + 1))
- chAttr = SCE_H_TAG;
- } else {
- if (keywords.InList(s)) {
- chAttr = SCE_H_TAG;
- isScript = 0 == strcmp(s, "script");
- }
- }
- if ((chAttr == SCE_H_TAGUNKNOWN) && !keywords) {
- // No keywords -> all are known
+ } else if (!keywords || keywords.InList(s[0] == '/' ? s + 1 : s)) {
chAttr = SCE_H_TAG;
- isScript = 0 == strcmp(s, "script");
}
styler.ColourTo(end, chAttr);
- return isScript ? SCE_H_SCRIPT : chAttr;
+ if (chAttr == SCE_H_TAG) {
+ if (allowScripts && 0 == strcmp(s, "script")) {
+ chAttr = SCE_H_SCRIPT;
+ } else if (!isXml && 0 == strcmp(s, "comment")) {
+ chAttr = SCE_H_COMMENT;
+ }
+ }
+ return chAttr;
}
static void classifyWordHTJS(unsigned int start, unsigned int end,
@@ -411,6 +408,9 @@
case eScriptSGML:
Result = SCE_H_SGML_DEFAULT;
break;
+ case eScriptComment:
+ Result = SCE_H_COMMENT;
+ break;
default :
Result = SCE_HJ_START;
break;
@@ -469,19 +469,51 @@
(state == SCE_HPHP_COMPLEX_VARIABLE);
}
-static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler) {
+static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler, bool &isSimpleString) {
int j;
+ const int beginning = i - 1;
+ bool isValidSimpleString = false;
+
while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t'))
i++;
- phpStringDelimiter[0] = '\n';
- for (j = i; j < lengthDoc && styler[j] != '\n' && styler[j] != '\r'; j++) {
+
+ char ch = styler.SafeGetCharAt(i);
+ const char chNext = styler.SafeGetCharAt(i + 1);
+ if (!IsPhpWordStart(ch)) {
+ if (ch == '\'' && IsPhpWordStart(chNext)) {
+ i++;
+ ch = chNext;
+ isSimpleString = true;
+ } else {
+ phpStringDelimiter[0] = '\0';
+ return beginning;
+ }
+ }
+ phpStringDelimiter[0] = ch;
+ i++;
+
+ for (j = i; j < lengthDoc && !isLineEnd(styler[j]); j++) {
+ if (!IsPhpWordChar(styler[j])) {
+ if (isSimpleString && (styler[j] == '\'') && isLineEnd(styler.SafeGetCharAt(j + 1))) {
+ isValidSimpleString = true;
+ j++;
+ break;
+ } else {
+ phpStringDelimiter[0] = '\0';
+ return beginning;
+ }
+ }
if (j - i < phpStringDelimiterSize - 2)
phpStringDelimiter[j-i+1] = styler[j];
else
i++;
}
- phpStringDelimiter[j-i+1] = '\0';
- return j;
+ if (isSimpleString && !isValidSimpleString) {
+ phpStringDelimiter[0] = '\0';
+ return beginning;
+ }
+ phpStringDelimiter[j-i+1 - (isSimpleString ? 1 : 0)] = '\0';
+ return j - 1;
}
static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
@@ -510,11 +542,15 @@
}
state = SCE_H_DEFAULT;
}
- // String can be heredoc, must find a delimiter first
- while (startPos > 0 && isPHPStringState(state) && state != SCE_HPHP_SIMPLESTRING) {
- startPos--;
- length++;
- state = styler.StyleAt(startPos);
+ // String can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState
+ if (isPHPStringState(state)) {
+ while (startPos > 0 && (isPHPStringState(state) || !isLineEnd(styler[startPos - 1]))) {
+ startPos--;
+ length++;
+ state = styler.StyleAt(startPos);
+ }
+ if (startPos == 0)
+ state = SCE_H_DEFAULT;
}
styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
@@ -536,12 +572,17 @@
int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state
script_type scriptLanguage = ScriptOfState(state);
+ // If eNonHtmlScript coincides with SCE_H_COMMENT, assume eScriptComment
+ if (inScriptType == eNonHtmlScript && state == SCE_H_COMMENT) {
+ scriptLanguage = eScriptComment;
+ }
const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0;
const bool fold = foldHTML && styler.GetPropertyInt("fold", 0);
const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1);
const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
+ const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0;
const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);
const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true);
@@ -686,19 +727,22 @@
case SCE_HP_STRING:
case SCE_HP_TRIPLE:
case SCE_HP_TRIPLEDOUBLE:
+ case SCE_HPHP_HSTRING:
+ case SCE_HPHP_SIMPLESTRING:
+ case SCE_HPHP_COMMENT:
+ case SCE_HPHP_COMMENTLINE:
break;
default :
// check if the closing tag is a script tag
- if (state == SCE_HJ_COMMENTLINE || isXml) {
- char tag[7]; // room for the <script> tag
- int j = 0;
- char chr = styler.SafeGetCharAt(i+2);
- while (j < 6 && !IsASpace(chr)) {
- tag[j++] = static_cast<char>(MakeLowerCase(chr));
- chr = styler.SafeGetCharAt(i+2+j);
- }
- tag[j] = '\0';
- if (strcmp(tag, "script") != 0) break;
+ if (const char *tag =
+ state == SCE_HJ_COMMENTLINE || isXml ? "script" :
+ state == SCE_H_COMMENT ? "comment" : 0) {
+ int j = i + 2;
+ int chr;
+ do {
+ chr = static_cast<int>(*tag++);
+ } while (chr != 0 && chr == MakeLowerCase(styler.SafeGetCharAt(j++)));
+ if (chr != 0) break;
}
// closing tag of the script (it's a closing HTML tag anyway)
styler.ColourTo(i - 1, StateToPrint);
@@ -721,7 +765,7 @@
(ch == '<') &&
(chNext == '?') &&
!IsScriptCommentState(state) ) {
- scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 10, eScriptPHP);
+ scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP);
if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
@@ -1005,7 +1049,7 @@
}
break;
case SCE_H_COMMENT:
- if ((chPrev2 == '-') && (chPrev == '-') && (ch == '>')) {
+ if ((scriptLanguage != eScriptComment) && (chPrev2 == '-') && (chPrev == '-') && (ch == '>')) {
styler.ColourTo(i, StateToPrint);
state = SCE_H_DEFAULT;
levelCurrent--;
@@ -1050,16 +1094,15 @@
case SCE_H_TAGUNKNOWN:
if (!setTagContinue.Contains(ch) && !((ch == '/') && (chPrev == '<'))) {
int eClass = classifyTagHTML(styler.GetStartSegment(),
- i - 1, keywords, styler, tagDontFold, caseSensitive, isXml);
- if (eClass == SCE_H_SCRIPT) {
+ i - 1, keywords, styler, tagDontFold, caseSensitive, isXml, allowScripts);
+ if (eClass == SCE_H_SCRIPT || eClass == SCE_H_COMMENT) {
if (!tagClosing) {
inScriptType = eNonHtmlScript;
- scriptLanguage = clientScript;
- eClass = SCE_H_TAG;
+ scriptLanguage = eClass == SCE_H_SCRIPT ? clientScript : eScriptComment;
} else {
scriptLanguage = eScriptNone;
- eClass = SCE_H_TAG;
}
+ eClass = SCE_H_TAG;
}
if (ch == '>') {
styler.ColourTo(i, eClass);
@@ -1069,7 +1112,7 @@
state = SCE_H_DEFAULT;
}
tagOpened = false;
- if (!tagDontFold){
+ if (!tagDontFold) {
if (tagClosing) {
levelCurrent--;
} else {
@@ -1117,8 +1160,8 @@
state = SCE_H_DEFAULT;
}
tagOpened = false;
- if (!tagDontFold){
- if (tagClosing){
+ if (!tagDontFold) {
+ if (tagClosing) {
levelCurrent--;
} else {
levelCurrent++;
@@ -1143,8 +1186,8 @@
state = SCE_H_DEFAULT;
}
tagOpened = false;
- if (!tagDontFold){
- if (tagClosing){
+ if (!tagDontFold) {
+ if (tagClosing) {
levelCurrent--;
} else {
levelCurrent++;
@@ -1217,8 +1260,8 @@
state = SCE_H_DEFAULT;
}
tagOpened = false;
- if (!tagDontFold){
- if (tagClosing){
+ if (!tagDontFold) {
+ if (tagClosing) {
levelCurrent--;
} else {
levelCurrent++;
@@ -1577,10 +1620,12 @@
state = SCE_HPHP_HSTRING;
strcpy(phpStringDelimiter, "\"");
} else if (styler.Match(i, "<<<")) {
- state = SCE_HPHP_HSTRING;
- i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler);
+ bool isSimpleString = false;
+ i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString);
+ if (strlen(phpStringDelimiter)) state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING);
} else if (ch == '\'') {
state = SCE_HPHP_SIMPLESTRING;
+ strcpy(phpStringDelimiter, "\'");
} else if (ch == '$' && IsPhpWordStart(chNext)) {
state = SCE_HPHP_VARIABLE;
} else if (IsOperator(ch)) {
@@ -1603,12 +1648,9 @@
}
break;
case SCE_HPHP_VARIABLE:
- if (!IsPhpWordChar(ch)) {
- styler.ColourTo(i - 1, SCE_HPHP_VARIABLE);
- if (IsOperator(ch))
- state = SCE_HPHP_OPERATOR;
- else
- state = SCE_HPHP_DEFAULT;
+ if (!IsPhpWordChar(chNext)) {
+ styler.ColourTo(i, SCE_HPHP_VARIABLE);
+ state = SCE_HPHP_DEFAULT;
}
break;
case SCE_HPHP_COMMENT:
@@ -1635,26 +1677,46 @@
styler.ColourTo(i - 1, StateToPrint);
state = SCE_HPHP_HSTRING_VARIABLE;
} else if (styler.Match(i, phpStringDelimiter)) {
+ if (phpStringDelimiter[0] == '\"') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HPHP_DEFAULT;
+ } else if (isLineEnd(chPrev)) {
const int psdLength = strlen(phpStringDelimiter);
- if ((psdLength > 1) && ((i + psdLength) < lengthDoc))
- i += psdLength - 1;
- styler.ColourTo(i, StateToPrint);
- state = SCE_HPHP_DEFAULT;
+ const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
+ const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
+ if (isLineEnd(chAfterPsd) ||
+ (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) {
+ i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HPHP_DEFAULT;
+ }
+ }
}
break;
case SCE_HPHP_SIMPLESTRING:
- if (ch == '\\') {
- // skip the next char
- i++;
- } else if (ch == '\'') {
- styler.ColourTo(i, StateToPrint);
- state = SCE_HPHP_DEFAULT;
+ if (phpStringDelimiter[0] == '\'') {
+ if (ch == '\\') {
+ // skip the next char
+ i++;
+ } else if (ch == '\'') {
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HPHP_DEFAULT;
+ }
+ } else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) {
+ const int psdLength = strlen(phpStringDelimiter);
+ const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
+ const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
+ if (isLineEnd(chAfterPsd) ||
+ (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) {
+ i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;
+ styler.ColourTo(i, StateToPrint);
+ state = SCE_HPHP_DEFAULT;
+ }
}
break;
case SCE_HPHP_HSTRING_VARIABLE:
- if (!IsPhpWordChar(ch)) {
- styler.ColourTo(i - 1, StateToPrint);
- i--; // strange but it works
+ if (!IsPhpWordChar(chNext)) {
+ styler.ColourTo(i, StateToPrint);
state = SCE_HPHP_HSTRING;
}
break;
@@ -1683,10 +1745,12 @@
state = SCE_HPHP_HSTRING;
strcpy(phpStringDelimiter, "\"");
} else if (styler.Match(i, "<<<")) {
- state = SCE_HPHP_HSTRING;
- i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler);
+ bool isSimpleString = false;
+ i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString);
+ if (strlen(phpStringDelimiter)) state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING);
} else if (ch == '\'') {
state = SCE_HPHP_SIMPLESTRING;
+ strcpy(phpStringDelimiter, "\'");
} else if (ch == '$' && IsPhpWordStart(chNext)) {
state = SCE_HPHP_VARIABLE;
} else if (IsOperator(ch)) {
@@ -1742,8 +1806,24 @@
}
}
- StateToPrint = statePrintForState(state, inScriptType);
+ switch (state) {
+ case SCE_HJ_WORD:
+ classifyWordHTJS(styler.GetStartSegment(), lengthDoc - 1, keywords2, styler, inScriptType);
+ break;
+ case SCE_HB_WORD:
+ classifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywords3, styler, inScriptType);
+ break;
+ case SCE_HP_WORD:
+ classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType);
+ break;
+ case SCE_HPHP_WORD:
+ classifyWordHTPHP(styler.GetStartSegment(), lengthDoc - 1, keywords5, styler);
+ break;
+ default:
+ StateToPrint = statePrintForState(state, inScriptType);
styler.ColourTo(lengthDoc - 1, StateToPrint);
+ break;
+ }
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
if (fold) {
@@ -1755,13 +1835,13 @@
static void ColouriseXMLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
// Passing in true because we're lexing XML
- ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists,styler, true);
+ ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, true);
}
static void ColouriseHTMLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
// Passing in false because we're notlexing XML
- ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists,styler, false);
+ ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, false);
}
static bool isASPScript(int state) {
@@ -2058,9 +2138,10 @@
}
static void ColourisePHPScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- if(startPos == 0) initStyle = SCE_HPHP_DEFAULT;
- ColouriseHTMLDoc(startPos,length,initStyle,keywordlists,styler);
+ Accessor &styler) {
+ if (startPos == 0)
+ initStyle = SCE_HPHP_DEFAULT;
+ ColouriseHTMLDoc(startPos, length, initStyle, keywordlists, styler);
}
static const char * const htmlWordListDesc[] = {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Commits
mailing list