diff options
| -rw-r--r-- | doc/ScintillaHistory.html | 13 | ||||
| -rw-r--r-- | include/SciLexer.h | 20 | ||||
| -rw-r--r-- | include/Scintilla.iface | 22 | ||||
| -rw-r--r-- | lexers/LexSTTXT.cxx | 401 | ||||
| -rw-r--r-- | src/Catalogue.cxx | 1 | ||||
| -rw-r--r-- | win32/scintilla.mak | 3 | 
6 files changed, 460 insertions, 0 deletions
| diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 9b8bfa9ac..6a3174c95 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -423,6 +423,7 @@        </tr><tr>  	<td>kudah</td>  	<td>Igor Shaula</td> +	<td>Pavel Bulochkin</td>      </tr>      </table>      <p> @@ -435,6 +436,18 @@        </li>      </ul>      <h3> +       <a href="http://prdownloads.sourceforge.net/scintilla/scite333.zip?download">Release 3.3.3</a> +    </h3> +    <ul> +	<li> +	Released 22 December 2013. +	</li> +	<li> +	Lexer and folder added for Structured Text language. +	<a href="http://sourceforge.net/p/scintilla/feature-requests/959/">Feature #959.</a> +	</li> +    </ul> +    <h3>         <a href="http://prdownloads.sourceforge.net/scintilla/scite332.zip?download">Release 3.3.2</a>      </h3>      <ul> diff --git a/include/SciLexer.h b/include/SciLexer.h index 1ddf628bd..18cdb984c 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -121,6 +121,7 @@  #define SCLEX_OSCRIPT 106  #define SCLEX_VISUALPROLOG 107  #define SCLEX_LITERATEHASKELL 108 +#define SCLEX_STTXT 109  #define SCLEX_AUTOMATIC 1000  #define SCE_P_DEFAULT 0  #define SCE_P_COMMENTLINE 1 @@ -1627,6 +1628,25 @@  #define SCE_VISUALPROLOG_STRING_VERBATIM 20  #define SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL 21  #define SCE_VISUALPROLOG_STRING_VERBATIM_EOL 22 +#define SCE_STTXT_DEFAULT 0 +#define SCE_STTXT_COMMENT 1 +#define SCE_STTXT_COMMENTLINE 2 +#define SCE_STTXT_KEYWORD 3 +#define SCE_STTXT_TYPE 4 +#define SCE_STTXT_FUNCTION 5 +#define SCE_STTXT_FB 6 +#define SCE_STTXT_NUMBER 7 +#define SCE_STTXT_HEXNUMBER 8 +#define SCE_STTXT_PRAGMA 9 +#define SCE_STTXT_OPERATOR 10 +#define SCE_STTXT_CHARACTER 11 +#define SCE_STTXT_STRING1 12 +#define SCE_STTXT_STRING2 13 +#define SCE_STTXT_STRINGEOL 14 +#define SCE_STTXT_IDENTIFIER 15 +#define SCE_STTXT_DATETIME 16 +#define SCE_STTXT_VARS 17 +#define SCE_STTXT_PRAGMAS 18  /* --Autogenerated -- end of section automatically generated from Scintilla.iface */  #endif diff --git a/include/Scintilla.iface b/include/Scintilla.iface index d15050e1d..120a5433d 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2579,6 +2579,7 @@ val SCLEX_ECL=105  val SCLEX_OSCRIPT=106  val SCLEX_VISUALPROLOG=107  val SCLEX_LITERATEHASKELL=108 +val SCLEX_STTXT=109  # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a  # value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -4283,6 +4284,27 @@ val SCE_VISUALPROLOG_STRING_EOL_OPEN=19  val SCE_VISUALPROLOG_STRING_VERBATIM=20  val SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL=21  val SCE_VISUALPROLOG_STRING_VERBATIM_EOL=22 +# Lexical states for SCLEX_STTXT +lex StructuredText=SCLEX_STTXT SCE_STTXT_ +val SCE_STTXT_DEFAULT=0 +val SCE_STTXT_COMMENT=1 +val SCE_STTXT_COMMENTLINE=2 +val SCE_STTXT_KEYWORD=3 +val SCE_STTXT_TYPE=4 +val SCE_STTXT_FUNCTION=5 +val SCE_STTXT_FB=6 +val SCE_STTXT_NUMBER=7 +val SCE_STTXT_HEXNUMBER=8 +val SCE_STTXT_PRAGMA=9 +val SCE_STTXT_OPERATOR=10 +val SCE_STTXT_CHARACTER=11 +val SCE_STTXT_STRING1=12 +val SCE_STTXT_STRING2=13 +val SCE_STTXT_STRINGEOL=14 +val SCE_STTXT_IDENTIFIER=15 +val SCE_STTXT_DATETIME=16 +val SCE_STTXT_VARS=17 +val SCE_STTXT_PRAGMAS=18  # Events diff --git a/lexers/LexSTTXT.cxx b/lexers/LexSTTXT.cxx new file mode 100644 index 000000000..c58d054aa --- /dev/null +++ b/lexers/LexSTTXT.cxx @@ -0,0 +1,401 @@ +// Scintilla source code edit control +/** @file LexSTTXT.cxx + ** Lexer for Structured Text language. + ** Written by Pavel Bulochkin + **/ +// The License.txt file describes the conditions under which this software may be distributed. + + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> +#include <assert.h> +#include <ctype.h> + +#include "ILexer.h" +#include "Scintilla.h" +#include "SciLexer.h" + +#include "WordList.h" +#include "LexAccessor.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "CharacterSet.h" +#include "LexerModule.h" + +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + +static void ClassifySTTXTWord(WordList *keywordlists[], StyleContext &sc) +{ +	char s[256] = { 0 }; +	sc.GetCurrentLowered(s, sizeof(s)); + + 	if ((*keywordlists[0]).InList(s)) { + 		sc.ChangeState(SCE_STTXT_KEYWORD); + 	} + +	else if ((*keywordlists[1]).InList(s)) { +		sc.ChangeState(SCE_STTXT_TYPE); +	} + +	else if ((*keywordlists[2]).InList(s)) { +		sc.ChangeState(SCE_STTXT_FUNCTION); +	} + +	else if ((*keywordlists[3]).InList(s)) { +		sc.ChangeState(SCE_STTXT_FB); +	} + +	else if ((*keywordlists[4]).InList(s)) { +		sc.ChangeState(SCE_STTXT_VARS); +	} + +	else if ((*keywordlists[5]).InList(s)) { +		sc.ChangeState(SCE_STTXT_PRAGMAS); +	} + +	sc.SetState(SCE_STTXT_DEFAULT); +} + +static void ColouriseSTTXTDoc (unsigned int startPos, int length, int initStyle, +							  WordList *keywordlists[], Accessor &styler) +{ +	StyleContext sc(startPos, length, initStyle, styler); + +	CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); +	CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); +	CharacterSet setNumber(CharacterSet::setDigits, "_.eE"); +	CharacterSet setHexNumber(CharacterSet::setDigits, "_abcdefABCDEF"); +	CharacterSet setOperator(CharacterSet::setNone,",.+-*/:;<=>[]()%&"); +	CharacterSet setDataTime(CharacterSet::setDigits,"_.-:dmshDMSH"); + + 	for ( ; sc.More() ; sc.Forward()) + 	{ +		if(sc.atLineStart && sc.state != SCE_STTXT_COMMENT) +			sc.SetState(SCE_STTXT_DEFAULT); + +		switch(sc.state) +		{ +			case SCE_STTXT_NUMBER: { +				if(!setNumber.Contains(sc.ch)) +					sc.SetState(SCE_STTXT_DEFAULT); +				break; +			} +			case SCE_STTXT_HEXNUMBER: { +				if(setHexNumber.Contains(sc.ch)) +					continue; +				else if(setDataTime.Contains(sc.ch)) +					sc.SetState(SCE_STTXT_DATETIME); +				else +					sc.SetState(SCE_STTXT_DEFAULT); + +				break; +			} +			case SCE_STTXT_DATETIME: { +				if(!setDataTime.Contains(sc.ch)) +					sc.SetState(SCE_STTXT_DEFAULT); +				break; +			} +			case SCE_STTXT_OPERATOR: { +				sc.SetState(SCE_STTXT_DEFAULT); +				break; +			} +			case SCE_STTXT_PRAGMA: { +				if (sc.ch == '}') +					sc.ForwardSetState(SCE_STTXT_DEFAULT); +				break; +			} +			case SCE_STTXT_COMMENTLINE: { +				if (sc.atLineStart) +					sc.SetState(SCE_STTXT_DEFAULT); +				break; +			} +			case SCE_STTXT_COMMENT: { +				if(sc.Match('*',')')) +				{ +					sc.Forward(); +					sc.ForwardSetState(SCE_STTXT_DEFAULT); +				} +				break; +			} +			case SCE_STTXT_STRING1: { +				if(sc.atLineEnd) +					sc.SetState(SCE_STTXT_STRINGEOL); +				else if(sc.ch == '\'' && sc.chPrev != '$') +					sc.ForwardSetState(SCE_STTXT_DEFAULT); +				break; +			} +			case SCE_STTXT_STRING2: { +				if (sc.atLineEnd) +					sc.SetState(SCE_STTXT_STRINGEOL); +				else if(sc.ch == '\"' && sc.chPrev != '$') +					sc.ForwardSetState(SCE_STTXT_DEFAULT); +				break; +			} +			case SCE_STTXT_STRINGEOL: { +				if(sc.atLineStart) +					sc.SetState(SCE_STTXT_DEFAULT); +				break; +			} +			case SCE_STTXT_CHARACTER: { +				if(setHexNumber.Contains(sc.ch)) +					sc.SetState(SCE_STTXT_HEXNUMBER); +				else if(setDataTime.Contains(sc.ch)) +					sc.SetState(SCE_STTXT_DATETIME); +				else sc.SetState(SCE_STTXT_DEFAULT); +				break; +			} +			case SCE_STTXT_IDENTIFIER: { +				if(!setWord.Contains(sc.ch)) +					ClassifySTTXTWord(keywordlists, sc); +				break; +			} +		} + +		if(sc.state == SCE_STTXT_DEFAULT) +		{ +			if(IsADigit(sc.ch)) +				sc.SetState(SCE_STTXT_NUMBER); +			else if (setWordStart.Contains(sc.ch)) +				sc.SetState(SCE_STTXT_IDENTIFIER); +			else if (sc.Match('/', '/')) +				sc.SetState(SCE_STTXT_COMMENTLINE); +			else if(sc.Match('(', '*')) +				sc.SetState(SCE_STTXT_COMMENT); +			else if (sc.ch == '{') +				sc.SetState(SCE_STTXT_PRAGMA); +			else if (sc.ch == '\'') +				sc.SetState(SCE_STTXT_STRING1); +			else if (sc.ch == '\"') +				sc.SetState(SCE_STTXT_STRING2); +			else if(sc.ch == '#') +				sc.SetState(SCE_STTXT_CHARACTER); +			else if (setOperator.Contains(sc.ch)) +				sc.SetState(SCE_STTXT_OPERATOR); +		} + 	} + +	if (sc.state == SCE_STTXT_IDENTIFIER && setWord.Contains(sc.chPrev)) +		ClassifySTTXTWord(keywordlists, sc); + +	sc.Complete(); +} + +static const char * const STTXTWordListDesc[] = { +	"Keywords", +	"Types", +	"Functions", +	"FB", +	"Local_Var", +	"Local_Pragma", +	0 +}; + +static bool IsCommentLine(int line, Accessor &styler, bool type) +{ +	int pos = styler.LineStart(line); +	int eolPos = styler.LineStart(line + 1) - 1; + +	for (int i = pos; i < eolPos; i++) +	{ +		char ch = styler[i]; +		char chNext = styler.SafeGetCharAt(i + 1); +		int style = styler.StyleAt(i); + +		if(type) { +			 if (ch == '/' && chNext == '/' && style == SCE_STTXT_COMMENTLINE) +				return true; +		} +		else if (ch == '(' && chNext == '*' && style == SCE_STTXT_COMMENT) +			break; + +		if (!IsASpaceOrTab(ch)) +			return false; +	} + +	for (int i = eolPos-2; i>pos; i--) +	{ +		char ch = styler[i]; +		char chPrev = styler.SafeGetCharAt(i-1); +		int style = styler.StyleAt(i); + +		if(ch == ')' && chPrev == '*' && style == SCE_STTXT_COMMENT) +			return true; +		if(!IsASpaceOrTab(ch)) +			return false; +	} + +	return false; +} + +static bool IsPragmaLine(int line, Accessor &styler) +{ +	int pos = styler.LineStart(line); +	int eolPos = styler.LineStart(line+1) - 1; + +	for (int i = pos ; i < eolPos ; i++) +	{ +		char ch = styler[i]; +		int style = styler.StyleAt(i); + +		if(ch == '{' && style == SCE_STTXT_PRAGMA) +			return true; +		else if (!IsASpaceOrTab(ch)) +			return false; +	} +	return false; +} + +static void GetRangeUpper(unsigned int start,unsigned int end,Accessor &styler,char *s,unsigned int len) +{ +	unsigned int i = 0; +	while ((i < end - start + 1) && (i < len-1)) { +		s[i] = static_cast<char>(toupper(styler[start + i])); +		i++; +	} +	s[i] = '\0'; +} + +static void ClassifySTTXTWordFoldPoint(int &levelCurrent,unsigned int lastStart, +									 unsigned int currentPos, Accessor &styler) +{ +	char s[256]; +	GetRangeUpper(lastStart, currentPos, styler, s, sizeof(s)); + +	// See Table C.2 - Keywords +	if (!strcmp(s, "ACTION") || +		!strcmp(s, "CASE") || +		!strcmp(s, "CONFIGURATION") || +		!strcmp(s, "FOR") || +		!strcmp(s, "FUNCTION") || +		!strcmp(s, "FUNCTION_BLOCK") || +		!strcmp(s, "IF") || +		!strcmp(s, "INITIAL_STEP") || +		!strcmp(s, "REPEAT") || +		!strcmp(s, "RESOURCE") || +		!strcmp(s, "STEP") || +		!strcmp(s, "STRUCT") || +		!strcmp(s, "TRANSITION") || +		!strcmp(s, "TYPE") || +		!strcmp(s, "VAR") || +		!strcmp(s, "VAR_INPUT") || +		!strcmp(s, "VAR_OUTPUT") || +		!strcmp(s, "VAR_IN_OUT") || +		!strcmp(s, "VAR_TEMP") || +		!strcmp(s, "VAR_EXTERNAL") || +		!strcmp(s, "VAR_ACCESS") || +		!strcmp(s, "VAR_CONFIG") || +		!strcmp(s, "VAR_GLOBAL") || +		!strcmp(s, "WHILE")) +	{ +		levelCurrent++; +	} +	else if (!strcmp(s, "END_ACTION") || +		!strcmp(s, "END_CASE") || +		!strcmp(s, "END_CONFIGURATION") || +		!strcmp(s, "END_FOR") || +		!strcmp(s, "END_FUNCTION") || +		!strcmp(s, "END_FUNCTION_BLOCK") || +		!strcmp(s, "END_IF") || +		!strcmp(s, "END_REPEAT") || +		!strcmp(s, "END_RESOURCE") || +		!strcmp(s, "END_STEP") || +		!strcmp(s, "END_STRUCT") || +		!strcmp(s, "END_TRANSITION") || +		!strcmp(s, "END_TYPE") || +		!strcmp(s, "END_VAR") || +		!strcmp(s, "END_WHILE")) +	{ +		levelCurrent--; +		if (levelCurrent < SC_FOLDLEVELBASE) { +			levelCurrent = SC_FOLDLEVELBASE; +		} +	} +} + +static void FoldSTTXTDoc(unsigned int startPos, int length, int initStyle, WordList *[],Accessor &styler) +{ +	bool foldComment = styler.GetPropertyInt("fold.comment") != 0; +	bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; +	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; +	unsigned int endPos = startPos + length; +	int visibleChars = 0; +	int lineCurrent = styler.GetLine(startPos); +	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; +	int levelCurrent = levelPrev; +	char chNext = styler[startPos]; +	int styleNext = styler.StyleAt(startPos); +	int style = initStyle; +	int lastStart = 0; + +	CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); + +	for (unsigned int i = startPos; i < endPos; i++) +	{ +		char ch = chNext; +		chNext = styler.SafeGetCharAt(i + 1); +		int stylePrev = style; +		style = styleNext; +		styleNext = styler.StyleAt(i + 1); +		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + +		if (foldComment && style == SCE_STTXT_COMMENT) { +			if(stylePrev != SCE_STTXT_COMMENT) +				levelCurrent++; +			else if(styleNext != SCE_STTXT_COMMENT && !atEOL) +				levelCurrent--; +		} +		if ( foldComment && atEOL && ( IsCommentLine(lineCurrent, styler,false) +			|| IsCommentLine(lineCurrent,styler,true))) { + 			if(!IsCommentLine(lineCurrent-1, styler,true) && IsCommentLine(lineCurrent+1, styler,true)) +				levelCurrent++; +			if (IsCommentLine(lineCurrent-1, styler,true) && !IsCommentLine(lineCurrent+1, styler,true)) +				levelCurrent--; +			if (!IsCommentLine(lineCurrent-1, styler,false) && IsCommentLine(lineCurrent+1, styler,false)) +				levelCurrent++; +			if (IsCommentLine(lineCurrent-1, styler,false) && !IsCommentLine(lineCurrent+1, styler,false)) +				levelCurrent--; +		} +		if(foldPreprocessor && atEOL && IsPragmaLine(lineCurrent, styler)) { +			if(!IsPragmaLine(lineCurrent-1, styler) && IsPragmaLine(lineCurrent+1, styler )) +				levelCurrent++; +			else if(IsPragmaLine(lineCurrent-1, styler) && !IsPragmaLine(lineCurrent+1, styler)) +				levelCurrent--; +		} +		if (stylePrev != SCE_STTXT_KEYWORD && style == SCE_STTXT_KEYWORD) { +				lastStart = i; +		} +		if(stylePrev == SCE_STTXT_KEYWORD) { +			if(setWord.Contains(ch) && !setWord.Contains(chNext)) +				ClassifySTTXTWordFoldPoint(levelCurrent,lastStart, i, styler); +		} +		if (!IsASpace(ch)) { +			visibleChars++; +		} +		if (atEOL) { +			int lev = levelPrev; +			if (visibleChars == 0 && foldCompact) +				lev |= SC_FOLDLEVELWHITEFLAG; +			if ((levelCurrent > levelPrev) && (visibleChars > 0)) +				lev |= SC_FOLDLEVELHEADERFLAG; +			if (lev != styler.LevelAt(lineCurrent)) +				styler.SetLevel(lineCurrent, lev); + +			lineCurrent++; +			levelPrev = levelCurrent; +			visibleChars = 0; +		} + +		// If we didn't reach the EOL in previous loop, store line level and whitespace information. +		// The rest will be filled in later... +		int lev = levelPrev; +		if (visibleChars == 0 && foldCompact) +			lev |= SC_FOLDLEVELWHITEFLAG; +		styler.SetLevel(lineCurrent, lev); +	} +} + +LexerModule lmSTTXT(SCLEX_STTXT, ColouriseSTTXTDoc, "fcST", FoldSTTXTDoc, STTXTWordListDesc); diff --git a/src/Catalogue.cxx b/src/Catalogue.cxx index 0ca6e67a5..84d003e08 100644 --- a/src/Catalogue.cxx +++ b/src/Catalogue.cxx @@ -172,6 +172,7 @@ int Scintilla_LinkLexers() {  	LINK_LEXER(lmSpecman);  	LINK_LEXER(lmSpice);  	LINK_LEXER(lmSQL); +	LINK_LEXER(lmSTTXT);  	LINK_LEXER(lmTACL);  	LINK_LEXER(lmTADS3);  	LINK_LEXER(lmTAL); diff --git a/win32/scintilla.mak b/win32/scintilla.mak index a943609b1..708aac07d 100644 --- a/win32/scintilla.mak +++ b/win32/scintilla.mak @@ -164,6 +164,7 @@ LEXOBJS=\  	$(DIR_O)\LexSpecman.obj \  	$(DIR_O)\LexSpice.obj \  	$(DIR_O)\LexSQL.obj \ +	$(DIR_O)\LexSTTXT.obj \  	$(DIR_O)\LexTACL.obj \  	$(DIR_O)\LexTADS3.obj \  	$(DIR_O)\LexTAL.obj \ @@ -446,6 +447,8 @@ $(DIR_O)\LexSpice.obj: ..\lexers\LexSpice.cxx $(LEX_HEADERS)  $(DIR_O)\LexSQL.obj: ..\lexers\LexSQL.cxx $(LEX_HEADERS) +$(DIR_O)\LexSTTXT.obj: ..\lexers\LexSTTXT.cxx $(LEX_HEADERS) +  $(DIR_O)\LexTACL.obj: ..\lexers\LexTACL.cxx $(LEX_HEADERS)  $(DIR_O)\LexTADS3.obj: ..\lexers\LexTADS3.cxx $(LEX_HEADERS) | 
