diff options
| author | nyamatongwe <devnull@localhost> | 2006-01-29 19:32:59 +0000 | 
|---|---|---|
| committer | nyamatongwe <devnull@localhost> | 2006-01-29 19:32:59 +0000 | 
| commit | 3d23c628dbba9673834cf9f4837ca163c4d2646d (patch) | |
| tree | ffd19823e9f9fef824986d13f34fa8f0699fc66d /src/LexInno.cxx | |
| parent | 63fac567212506045ed9ef10a90e4a8da27ae2b3 (diff) | |
| download | scintilla-mirror-3d23c628dbba9673834cf9f4837ca163c4d2646d.tar.gz | |
Inno Setup lexer.
Diffstat (limited to 'src/LexInno.cxx')
| -rw-r--r-- | src/LexInno.cxx | 289 | 
1 files changed, 289 insertions, 0 deletions
| diff --git a/src/LexInno.cxx b/src/LexInno.cxx new file mode 100644 index 000000000..9b500f069 --- /dev/null +++ b/src/LexInno.cxx @@ -0,0 +1,289 @@ +// Scintilla source code edit control +/** @file LexInno.cxx + ** Lexer for Inno Setup scripts. + **/ +// Written by Friedrich Vedder <fvedd@t-online.de>, using code from LexOthers.cxx. +// The License.txt file describes the conditions under which this software may be distributed. + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <stdio.h> +#include <stdarg.h> + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) { +	int state = SCE_INNO_DEFAULT; +	char chPrev; +	char ch = 0; +	char chNext = styler[startPos]; +	int lengthDoc = startPos + length; +	char *buffer = new char[length]; +	int bufferCount = 0; +	bool isBOL, isEOL, isWS, isBOLWS = 0; + +	WordList §ionKeywords = *keywordLists[0]; +	WordList &standardKeywords = *keywordLists[1]; +	WordList ¶meterKeywords = *keywordLists[2]; +	WordList &preprocessorKeywords = *keywordLists[3]; +	WordList &pascalKeywords = *keywordLists[4]; +	WordList &userKeywords = *keywordLists[5]; + +	// Go through all provided text segment +	// using the hand-written state machine shown below +	styler.StartAt(startPos); +	styler.StartSegment(startPos); +	for (int i = startPos; i < lengthDoc; i++) { +		chPrev = ch; +		ch = chNext; +		chNext = styler.SafeGetCharAt(i + 1); + +		if (styler.IsLeadByte(ch)) { +			chNext = styler.SafeGetCharAt(i + 2); +			i++; +			continue; +		} + +		isBOL = (chPrev == 0) || (chPrev == '\n') || (chPrev == '\r' && ch != '\n'); +		isBOLWS = (isBOL) ? 1 : (isBOLWS && (chPrev == ' ' || chPrev == '\t')); +		isEOL = (ch == '\n' || ch == '\r'); +		isWS = (ch == ' ' || ch == '\t'); + +		switch(state) { +			case SCE_INNO_DEFAULT: +				if (ch == ';' && isBOLWS) { +					// Start of a comment +					state = SCE_INNO_COMMENT; +				} else if (ch == '[' && isBOL) { +					// Start of a section name +					bufferCount = 0; +					state = SCE_INNO_SECTION; +				} else if (ch == '#' && isBOLWS) { +					// Start of a preprocessor directive +					state = SCE_INNO_PREPROC; +				} else if (ch == '{' && chNext == '#') { +					// Start of a preprocessor inline directive +					state = SCE_INNO_PREPROC_INLINE; +				} else if (ch == '{' && (chNext == ' ' || chNext == '\t')) { +					// Start of a Pascal comment +					state = SCE_INNO_COMMENT_PASCAL; +				} else if (ch == '"') { +					// Start of a double-quote string +					state = SCE_INNO_STRING_DOUBLE; +				} else if (ch == '\'') { +					// Start of a single-quote string +					state = SCE_INNO_STRING_SINGLE; +				} else if (isascii(ch) && isalpha(ch)) { +					// Start of an identifier +					bufferCount = 0; +					buffer[bufferCount++] = static_cast<char>(tolower(ch)); +					state = SCE_INNO_IDENTIFIER; +				} else { +					// Style it the default style +					styler.ColourTo(i,SCE_INNO_DEFAULT); +				} +				break; + +			case SCE_INNO_COMMENT: +				if (isEOL) { +					state = SCE_INNO_DEFAULT; +					styler.ColourTo(i,SCE_INNO_COMMENT); +				} +				break; + +			case SCE_INNO_IDENTIFIER: +				if (isascii(ch) && isalnum(ch)) { +					buffer[bufferCount++] = static_cast<char>(tolower(ch)); +				} else { +					state = SCE_INNO_DEFAULT; +					buffer[bufferCount] = '\0'; + +					// Check if the buffer contains a keyword or parameter +					if (ch == ':' && parameterKeywords.InList(buffer)) { +						styler.ColourTo(i-1,SCE_INNO_PARAMETER); +					} else if (standardKeywords.InList(buffer)) { +						styler.ColourTo(i-1,SCE_INNO_KEYWORD); +					} else if (pascalKeywords.InList(buffer)) { +						styler.ColourTo(i-1,SCE_INNO_KEYWORD_PASCAL); +					} else if (userKeywords.InList(buffer)) { +						styler.ColourTo(i-1,SCE_INNO_KEYWORD_USER); +					} else { +						styler.ColourTo(i-1,SCE_INNO_DEFAULT); +					} + +					// Push back the faulty character +					chNext = styler[i--]; +					ch = chPrev; +				} +				break; + +			case SCE_INNO_SECTION: +				if (ch == ']') { +					state = SCE_INNO_DEFAULT; +					buffer[bufferCount] = '\0'; + +					// Check if the buffer contains a section name +					if (sectionKeywords.InList(buffer)) { +						styler.ColourTo(i,SCE_INNO_SECTION); +					} else { +						styler.ColourTo(i,SCE_INNO_DEFAULT); +					} +				} else if (isascii(ch) && isalpha(ch)) { +					buffer[bufferCount++] = static_cast<char>(tolower(ch)); +				} else { +					state = SCE_INNO_DEFAULT; +					styler.ColourTo(i,SCE_INNO_DEFAULT); +				} +				break; + +			case SCE_INNO_PREPROC: +				if (isWS || isEOL) { +					if (isascii(chPrev) && isalpha(chPrev)) { +						state = SCE_INNO_DEFAULT; +						buffer[bufferCount] = '\0'; + +						// Check if the buffer contains a preprocessor directive +						if (preprocessorKeywords.InList(buffer)) { +							styler.ColourTo(i-1,SCE_INNO_PREPROC); +						} else { +							styler.ColourTo(i-1,SCE_INNO_DEFAULT); +						} + +						// Push back the faulty character +						chNext = styler[i--]; +						ch = chPrev; +					} +				} else if (isascii(ch) && isalpha(ch)) { +					if (chPrev == '#' || chPrev == ' ' || chPrev == '\t') +						bufferCount = 0; +					buffer[bufferCount++] = static_cast<char>(tolower(ch)); +				} +				break; + +			case SCE_INNO_STRING_DOUBLE: +				if (ch == '"' || isEOL) { +					state = SCE_INNO_DEFAULT; +					styler.ColourTo(i,SCE_INNO_DEFAULT); +				} +				break; + +			case SCE_INNO_STRING_SINGLE: +				if (ch == '\'' || isEOL) { +					state = SCE_INNO_DEFAULT; +					styler.ColourTo(i,SCE_INNO_DEFAULT); +				} +				break; + +			case SCE_INNO_PREPROC_INLINE: +				if (ch == '}') { +					state = SCE_INNO_DEFAULT; +					styler.ColourTo(i,SCE_INNO_PREPROC_INLINE); +				} else if (isEOL) { +					state = SCE_INNO_DEFAULT; +					styler.ColourTo(i,SCE_INNO_DEFAULT); +				} +				break; + +			case SCE_INNO_COMMENT_PASCAL: +				if (ch == '}') { +					state = SCE_INNO_DEFAULT; +					styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL); +				} else if (isEOL) { +					state = SCE_INNO_DEFAULT; +					styler.ColourTo(i,SCE_INNO_DEFAULT); +				} +				break; + +		} +	} +	delete []buffer; +} + +static const char * const innoWordListDesc[] = { +	"Sections", +	"Keywords", +	"Parameters", +	"Preprocessor directives", +	"Pascal keywords", +	"User defined keywords", +	0 +}; + +static void FoldInnoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { +	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + +	unsigned int endPos = startPos + length; +	int visibleChars = 0; +	int lineCurrent = styler.GetLine(startPos); + +	char chNext = styler[startPos]; +	int styleNext = styler.StyleAt(startPos); +	bool headerPoint = false; +	int lev; + +	for (unsigned int i = startPos; i < endPos; i++) { +		char ch = chNext; +		chNext = styler[i+1]; + +		int style = styleNext; +		styleNext = styler.StyleAt(i + 1); +		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + +		if (style == SCE_INNO_SECTION) +			headerPoint = true; + +		if (atEOL) { +			lev = SC_FOLDLEVELBASE; + +			if (lineCurrent > 0) { +				int levelPrevious = styler.LevelAt(lineCurrent - 1); + +				if (levelPrevious & SC_FOLDLEVELHEADERFLAG) +					lev = SC_FOLDLEVELBASE + 1; +				else +					lev = levelPrevious & SC_FOLDLEVELNUMBERMASK; +			} + +			if (headerPoint) +				lev = SC_FOLDLEVELBASE; + +			if (visibleChars == 0 && foldCompact) +				lev |= SC_FOLDLEVELWHITEFLAG; + +			if (headerPoint) +				lev |= SC_FOLDLEVELHEADERFLAG; + +			if (lev != styler.LevelAt(lineCurrent)) +				styler.SetLevel(lineCurrent, lev); + +			lineCurrent++; +			visibleChars = 0; +			headerPoint = false; +		} +		if (!isspacechar(ch)) +			visibleChars++; +	} + +	if (lineCurrent > 0) { +		int levelPrevious = styler.LevelAt(lineCurrent - 1); + +		if (levelPrevious & SC_FOLDLEVELHEADERFLAG) +			lev = SC_FOLDLEVELBASE + 1; +		else +			lev = levelPrevious & SC_FOLDLEVELNUMBERMASK; +	} else { +		lev = SC_FOLDLEVELBASE; +	} +	int flagsNext = styler.LevelAt(lineCurrent); +	styler.SetLevel(lineCurrent, lev | flagsNext & ~SC_FOLDLEVELNUMBERMASK); +} + +LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, "inno", FoldInnoDoc, innoWordListDesc); | 
