aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornyamatongwe <devnull@localhost>2005-03-01 02:43:58 +0000
committernyamatongwe <devnull@localhost>2005-03-01 02:43:58 +0000
commitb223aa4de85c2be6bcd74b4f72fb9e02594b3edc (patch)
treee73ca1398031a58afb61579fc722ce8c6e55a1df /src
parentdca41642fb604d358cf93564044d6f86c706dad9 (diff)
downloadscintilla-mirror-b223aa4de85c2be6bcd74b4f72fb9e02594b3edc.tar.gz
Improvements to NSIS support from Angelo Mandato.
Includes line continuation, C style box comments, SectionGroup/SectionGroupEnd, PageEx/PageExEnd and $\r and $\n.
Diffstat (limited to 'src')
-rw-r--r--src/LexNsis.cxx238
1 files changed, 200 insertions, 38 deletions
diff --git a/src/LexNsis.cxx b/src/LexNsis.cxx
index 0f969bbfb..daa3af024 100644
--- a/src/LexNsis.cxx
+++ b/src/LexNsis.cxx
@@ -3,7 +3,7 @@
** Lexer for NSIS
**/
// Copyright 2003, 2004 by Angelo Mandato <angelo [at] spaceblue [dot] com>
-// Last Updated: 02/22/2004
+// Last Updated: 02/26/2005
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
@@ -38,6 +38,11 @@
#define SCE_NSIS_MACRODEF 12
#define SCE_NSIS_STRINGVAR 13
#define SCE_NSIS_NUMBER 14
+// ADDED for Scintilla v1.63
+#define SCE_NSIS_SECTIONGROUP 15
+#define SCE_NSIS_PAGEEX 16
+#define SCE_NSIS_FUNCTIONDEF 17
+#define SCE_NSIS_COMMENTBOX 18
*/
static bool isNsisNumber(char ch)
@@ -55,6 +60,40 @@ static bool isNsisLetter(char ch)
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
+static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler)
+{
+ int nNextLine = -1;
+ for( unsigned int i = start; i < end; i++ )
+ {
+ char cNext = styler.SafeGetCharAt( i );
+ if( cNext == '\n' )
+ {
+ nNextLine = i+1;
+ break;
+ }
+ }
+
+ if( nNextLine == -1 ) // We never foudn the next line...
+ return false;
+
+ for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ )
+ {
+ char cNext = styler.SafeGetCharAt( firstChar );
+ if( cNext == ' ' )
+ continue;
+ if( cNext == '\t' )
+ continue;
+ if( cNext == '!' )
+ {
+ if( styler.Match(firstChar, "!else") )
+ return true;
+ }
+ break;
+ }
+
+ return false;
+}
+
static int NsisCmp( char *s1, char *s2, bool bIgnoreCase )
{
if( bIgnoreCase )
@@ -63,16 +102,19 @@ static int NsisCmp( char *s1, char *s2, bool bIgnoreCase )
return strcmp( s1, s2 );
}
-static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler )
+static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse )
{
+ int style = styler.StyleAt(end);
+
// If the word is too long, it is not what we are looking for
- if( end - start > 13 )
+ if( end - start > 20 )
return foldlevel;
// Check the style at this point, if it is not valid, then return zero
- if( styler.StyleAt(end) != SCE_NSIS_FUNCTION && styler.StyleAt(end) != SCE_NSIS_SECTIONDEF &&
- styler.StyleAt(end) != SCE_NSIS_SUBSECTIONDEF && styler.StyleAt(end) != SCE_NSIS_IFDEFINEDEF &&
- styler.StyleAt(end) != SCE_NSIS_MACRODEF )
+ if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF &&
+ style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF &&
+ style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP &&
+ style != SCE_NSIS_PAGEEX )
return foldlevel;
int newFoldlevel = foldlevel;
@@ -80,8 +122,8 @@ static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel
if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
bIgnoreCase = true;
- char s[15]; // The key word we are looking for has atmost 13 characters
- for (unsigned int i = 0; i < end - start + 1 && i < 14; i++)
+ char s[20]; // The key word we are looking for has atmost 13 characters
+ for (unsigned int i = 0; i < end - start + 1 && i < 19; i++)
{
s[i] = static_cast<char>( styler[ start + i ] );
s[i + 1] = '\0';
@@ -93,15 +135,17 @@ static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel
newFoldlevel++;
else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 )
newFoldlevel--;
+ else if( bElse && NsisCmp(s, "!else", bIgnoreCase) == 0 )
+ newFoldlevel++;
}
else
{
- if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 )
+ if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionGroup", bIgnoreCase ) == 0 || NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 || NsisCmp(s, "PageEx", bIgnoreCase ) == 0 )
newFoldlevel++;
- else if( NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 )
+ else if( NsisCmp(s, "SectionGroupEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase ) == 0 )
newFoldlevel--;
}
-
+
return newFoldlevel;
}
@@ -138,14 +182,23 @@ static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keyw
if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 )
return SCE_NSIS_IFDEFINEDEF;
+ if( NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 )
+ return SCE_NSIS_IFDEFINEDEF;
+
+ if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd
+ return SCE_NSIS_SECTIONGROUP;
+
if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase) == 0 ) // Covers Section and SectionEnd
return SCE_NSIS_SECTIONDEF;
if( NsisCmp(s, "SubSection", bIgnoreCase) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd
return SCE_NSIS_SUBSECTIONDEF;
- if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd
- return SCE_NSIS_FUNCTION;
+ if( NsisCmp(s, "PageEx", bIgnoreCase) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd
+ return SCE_NSIS_PAGEEX;
+
+ if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd
+ return SCE_NSIS_FUNCTIONDEF;
if ( Functions.InList(s) )
return SCE_NSIS_FUNCTION;
@@ -188,9 +241,6 @@ static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keyw
bool bHasSimpleNsisNumber = true;
for (unsigned int j = 1; j < end - start + 1 && j < 99; j++)
{
- if( s[j] == '\0' || s[j] == '\r' || s[j] == '\n' )
- break;
-
if( !isNsisNumber( s[j] ) )
{
bHasSimpleNsisNumber = false;
@@ -208,6 +258,9 @@ static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keyw
static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
{
int state = SCE_NSIS_DEFAULT;
+ if( startPos > 0 )
+ state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox
+
styler.StartAt( startPos );
styler.GetLine( startPos );
@@ -270,35 +323,96 @@ static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *k
break;
}
+
+ if( cCurrChar == '/' && cNextChar == '*' )
+ {
+ styler.ColourTo(i-1,state);
+ state = SCE_NSIS_COMMENTBOX;
+ break;
+ }
+
break;
case SCE_NSIS_COMMENT:
if( cNextChar == '\n' || cNextChar == '\r' )
{
- styler.ColourTo(i,state);
- state = SCE_NSIS_DEFAULT;
+ // Special case:
+ if( cCurrChar == '\\' )
+ {
+ styler.ColourTo(i-2,state);
+ styler.ColourTo(i,SCE_NSIS_DEFAULT);
+ }
+ else
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ }
}
break;
case SCE_NSIS_STRINGDQ:
- if( cCurrChar == '"' || cNextChar == '\r' || cNextChar == '\n' )
+ case SCE_NSIS_STRINGLQ:
+ case SCE_NSIS_STRINGRQ:
+
+ if( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' )
+ break; // Ignore the next character, even if it is a quote of some sort
+
+ if( cCurrChar == '"' && state == SCE_NSIS_STRINGDQ )
{
- styler.ColourTo(i,SCE_NSIS_STRINGDQ);
+ styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
+ break;
}
- break;
- case SCE_NSIS_STRINGLQ:
- if( cCurrChar == '`' || cNextChar == '\r' || cNextChar == '\n' )
- {
- styler.ColourTo(i,SCE_NSIS_STRINGLQ);
+
+ if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ )
+ {
+ styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
+ break;
}
- break;
- case SCE_NSIS_STRINGRQ:
- if( cCurrChar == '\'' || cNextChar == '\r' || cNextChar == '\n' )
+
+ if( cCurrChar == '\'' && state == SCE_NSIS_STRINGRQ )
{
- styler.ColourTo(i,SCE_NSIS_STRINGRQ);
+ styler.ColourTo(i,state);
state = SCE_NSIS_DEFAULT;
+ break;
}
+
+ if( cNextChar == '\r' || cNextChar == '\n' )
+ {
+ int nCurLine = styler.GetLine(i+1);
+ int nBack = i;
+ // We need to check if the previous line has a \ in it...
+ bool bNextLine = false;
+
+ while( nBack > 0 )
+ {
+ if( styler.GetLine(nBack) != nCurLine )
+ break;
+
+ char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here
+
+ if( cTemp == '\\' )
+ {
+ bNextLine = true;
+ break;
+ }
+ if( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' )
+ break;
+
+ nBack--;
+ }
+
+ if( bNextLine )
+ {
+ styler.ColourTo(i+1,state);
+ }
+ if( bNextLine == false )
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ }
+ }
break;
+
case SCE_NSIS_FUNCTION:
// NSIS KeyWord:
@@ -308,7 +422,7 @@ static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *k
state = SCE_NSIS_DEFAULT;
else if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' )
{
- state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler);
+ state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler );
styler.ColourTo( i, state);
state = SCE_NSIS_DEFAULT;
}
@@ -343,9 +457,17 @@ static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *k
}
}
break;
+ case SCE_NSIS_COMMENTBOX:
+
+ if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' )
+ {
+ styler.ColourTo(i,state);
+ state = SCE_NSIS_DEFAULT;
+ }
+ break;
}
- if( state == SCE_NSIS_COMMENT )
+ if( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX )
{
styler.ColourTo(i,state);
}
@@ -361,10 +483,11 @@ static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *k
bVarInString = false;
bIngoreNextDollarSign = true;
}
- else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) )
+ else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) )
{
+ styler.ColourTo( i+1, SCE_NSIS_STRINGVAR);
bVarInString = false;
- bIngoreNextDollarSign = true;
+ bIngoreNextDollarSign = false;
}
// Covers "$INSTDIR and user vars like $MYVAR"
@@ -422,6 +545,9 @@ static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Ac
if( styler.GetPropertyInt("fold") == 0 )
return;
+ bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1;
+ bool blockComment = false;
+
int lineCurrent = styler.GetLine(startPos);
unsigned int safeStartPos = styler.LineStart( lineCurrent );
@@ -432,19 +558,48 @@ static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Ac
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int levelNext = levelCurrent;
+ int style = styler.StyleAt(safeStartPos);
+ if( style == SCE_NSIS_COMMENTBOX )
+ {
+ if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' )
+ levelNext++;
+ blockComment = true;
+ }
for (unsigned int i = safeStartPos; i < startPos + length; i++)
{
char chCurr = styler.SafeGetCharAt(i);
+ style = styler.StyleAt(i);
+ if( blockComment && style != SCE_NSIS_COMMENTBOX )
+ {
+ levelNext--;
+ blockComment = false;
+ }
+ else if( !blockComment && style == SCE_NSIS_COMMENTBOX )
+ {
+ levelNext++;
+ blockComment = true;
+ }
- if( bArg1 ) //&& chCurr != '\n' )
+ if( bArg1 && chCurr != '\n' && !blockComment)
{
if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') )
+ {
nWordStart = i;
- else if( !isNsisLetter(chCurr) && nWordStart > -1 )
+ }
+ else if( isNsisLetter(chCurr) == false && nWordStart > -1 )
{
- int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler );
- if( newLevel != levelNext )
+ int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse );
+
+ if( newLevel == levelNext )
+ {
+ if( foldAtElse )
+ {
+ if( NsisNextLineHasElse(i, startPos + length, styler) )
+ levelNext--;
+ }
+ }
+ else
levelNext = newLevel;
bArg1 = false;
}
@@ -452,10 +607,16 @@ static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Ac
if( chCurr == '\n' )
{
+ if( bArg1 && foldAtElse && !blockComment )
+ {
+ if( NsisNextLineHasElse(i, startPos + length, styler) )
+ levelNext--;
+ }
+
// If we are on a new line...
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
- if (levelUse < levelNext)
+ if (levelUse < levelNext )
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
@@ -484,3 +645,4 @@ static const char * const nsisWordLists[] = {
LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, "nsis", FoldNsisDoc, nsisWordLists);
+