]> git.saurik.com Git - wxWidgets.git/blame - src/stc/scintilla/lexers/LexInno.cxx
Added ability to switch off more components of the size page UI
[wxWidgets.git] / src / stc / scintilla / lexers / LexInno.cxx
CommitLineData
b8193d80
RD
1// Scintilla source code edit control
2/** @file LexInno.cxx
3 ** Lexer for Inno Setup scripts.
4 **/
5// Written by Friedrich Vedder <fvedd@t-online.de>, using code from LexOthers.cxx.
6// The License.txt file describes the conditions under which this software may be distributed.
7
8#include <stdlib.h>
9#include <string.h>
b8193d80
RD
10#include <stdio.h>
11#include <stdarg.h>
1dcf666d
RD
12#include <assert.h>
13#include <ctype.h>
b8193d80 14
1dcf666d
RD
15#include "ILexer.h"
16#include "Scintilla.h"
17#include "SciLexer.h"
b8193d80 18
1dcf666d
RD
19#include "WordList.h"
20#include "LexAccessor.h"
b8193d80
RD
21#include "Accessor.h"
22#include "StyleContext.h"
1dcf666d
RD
23#include "CharacterSet.h"
24#include "LexerModule.h"
b8193d80 25
7e0c58e9
RD
26#ifdef SCI_NAMESPACE
27using namespace Scintilla;
28#endif
29
b8193d80
RD
30static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) {
31 int state = SCE_INNO_DEFAULT;
32 char chPrev;
33 char ch = 0;
34 char chNext = styler[startPos];
35 int lengthDoc = startPos + length;
36 char *buffer = new char[length];
37 int bufferCount = 0;
38 bool isBOL, isEOL, isWS, isBOLWS = 0;
9e96e16f 39 bool isCStyleComment = false;
b8193d80
RD
40
41 WordList &sectionKeywords = *keywordLists[0];
42 WordList &standardKeywords = *keywordLists[1];
43 WordList &parameterKeywords = *keywordLists[2];
44 WordList &preprocessorKeywords = *keywordLists[3];
45 WordList &pascalKeywords = *keywordLists[4];
46 WordList &userKeywords = *keywordLists[5];
47
1dcf666d
RD
48 int curLine = styler.GetLine(startPos);
49 int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
50 bool isCode = (curLineState == 1);
51
b8193d80
RD
52 // Go through all provided text segment
53 // using the hand-written state machine shown below
54 styler.StartAt(startPos);
55 styler.StartSegment(startPos);
56 for (int i = startPos; i < lengthDoc; i++) {
57 chPrev = ch;
58 ch = chNext;
59 chNext = styler.SafeGetCharAt(i + 1);
60
61 if (styler.IsLeadByte(ch)) {
62 chNext = styler.SafeGetCharAt(i + 2);
63 i++;
64 continue;
65 }
66
67 isBOL = (chPrev == 0) || (chPrev == '\n') || (chPrev == '\r' && ch != '\n');
68 isBOLWS = (isBOL) ? 1 : (isBOLWS && (chPrev == ' ' || chPrev == '\t'));
69 isEOL = (ch == '\n' || ch == '\r');
70 isWS = (ch == ' ' || ch == '\t');
71
1dcf666d
RD
72 if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
73 // Remember the line state for future incremental lexing
74 curLine = styler.GetLine(i);
75 styler.SetLineState(curLine, (isCode ? 1 : 0));
76 }
77
b8193d80
RD
78 switch(state) {
79 case SCE_INNO_DEFAULT:
9e96e16f 80 if (!isCode && ch == ';' && isBOLWS) {
b8193d80
RD
81 // Start of a comment
82 state = SCE_INNO_COMMENT;
83 } else if (ch == '[' && isBOLWS) {
84 // Start of a section name
85 bufferCount = 0;
86 state = SCE_INNO_SECTION;
87 } else if (ch == '#' && isBOLWS) {
88 // Start of a preprocessor directive
89 state = SCE_INNO_PREPROC;
9e96e16f
RD
90 } else if (!isCode && ch == '{' && chNext != '{' && chPrev != '{') {
91 // Start of an inline expansion
92 state = SCE_INNO_INLINE_EXPANSION;
93 } else if (isCode && (ch == '{' || (ch == '(' && chNext == '*'))) {
b8193d80
RD
94 // Start of a Pascal comment
95 state = SCE_INNO_COMMENT_PASCAL;
9e96e16f
RD
96 isCStyleComment = false;
97 } else if (isCode && ch == '/' && chNext == '/') {
98 // Apparently, C-style comments are legal, too
99 state = SCE_INNO_COMMENT_PASCAL;
100 isCStyleComment = true;
b8193d80
RD
101 } else if (ch == '"') {
102 // Start of a double-quote string
103 state = SCE_INNO_STRING_DOUBLE;
104 } else if (ch == '\'') {
105 // Start of a single-quote string
106 state = SCE_INNO_STRING_SINGLE;
107 } else if (isascii(ch) && (isalpha(ch) || (ch == '_'))) {
108 // Start of an identifier
109 bufferCount = 0;
110 buffer[bufferCount++] = static_cast<char>(tolower(ch));
111 state = SCE_INNO_IDENTIFIER;
112 } else {
113 // Style it the default style
114 styler.ColourTo(i,SCE_INNO_DEFAULT);
115 }
116 break;
117
118 case SCE_INNO_COMMENT:
119 if (isEOL) {
120 state = SCE_INNO_DEFAULT;
121 styler.ColourTo(i,SCE_INNO_COMMENT);
122 }
123 break;
124
125 case SCE_INNO_IDENTIFIER:
126 if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {
127 buffer[bufferCount++] = static_cast<char>(tolower(ch));
128 } else {
129 state = SCE_INNO_DEFAULT;
130 buffer[bufferCount] = '\0';
131
132 // Check if the buffer contains a keyword
9e96e16f 133 if (!isCode && standardKeywords.InList(buffer)) {
b8193d80 134 styler.ColourTo(i-1,SCE_INNO_KEYWORD);
9e96e16f 135 } else if (!isCode && parameterKeywords.InList(buffer)) {
b8193d80 136 styler.ColourTo(i-1,SCE_INNO_PARAMETER);
9e96e16f 137 } else if (isCode && pascalKeywords.InList(buffer)) {
b8193d80 138 styler.ColourTo(i-1,SCE_INNO_KEYWORD_PASCAL);
9e96e16f 139 } else if (!isCode && userKeywords.InList(buffer)) {
b8193d80
RD
140 styler.ColourTo(i-1,SCE_INNO_KEYWORD_USER);
141 } else {
142 styler.ColourTo(i-1,SCE_INNO_DEFAULT);
143 }
144
145 // Push back the faulty character
146 chNext = styler[i--];
147 ch = chPrev;
148 }
149 break;
150
151 case SCE_INNO_SECTION:
152 if (ch == ']') {
153 state = SCE_INNO_DEFAULT;
154 buffer[bufferCount] = '\0';
155
156 // Check if the buffer contains a section name
157 if (sectionKeywords.InList(buffer)) {
158 styler.ColourTo(i,SCE_INNO_SECTION);
9e96e16f 159 isCode = !CompareCaseInsensitive(buffer, "code");
b8193d80
RD
160 } else {
161 styler.ColourTo(i,SCE_INNO_DEFAULT);
162 }
163 } else if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {
164 buffer[bufferCount++] = static_cast<char>(tolower(ch));
165 } else {
166 state = SCE_INNO_DEFAULT;
167 styler.ColourTo(i,SCE_INNO_DEFAULT);
168 }
169 break;
170
171 case SCE_INNO_PREPROC:
172 if (isWS || isEOL) {
173 if (isascii(chPrev) && isalpha(chPrev)) {
174 state = SCE_INNO_DEFAULT;
175 buffer[bufferCount] = '\0';
176
177 // Check if the buffer contains a preprocessor directive
178 if (preprocessorKeywords.InList(buffer)) {
179 styler.ColourTo(i-1,SCE_INNO_PREPROC);
180 } else {
181 styler.ColourTo(i-1,SCE_INNO_DEFAULT);
182 }
183
184 // Push back the faulty character
185 chNext = styler[i--];
186 ch = chPrev;
187 }
188 } else if (isascii(ch) && isalpha(ch)) {
189 if (chPrev == '#' || chPrev == ' ' || chPrev == '\t')
190 bufferCount = 0;
191 buffer[bufferCount++] = static_cast<char>(tolower(ch));
192 }
193 break;
194
195 case SCE_INNO_STRING_DOUBLE:
196 if (ch == '"' || isEOL) {
197 state = SCE_INNO_DEFAULT;
7e0c58e9 198 styler.ColourTo(i,SCE_INNO_STRING_DOUBLE);
b8193d80
RD
199 }
200 break;
201
202 case SCE_INNO_STRING_SINGLE:
203 if (ch == '\'' || isEOL) {
204 state = SCE_INNO_DEFAULT;
7e0c58e9 205 styler.ColourTo(i,SCE_INNO_STRING_SINGLE);
b8193d80
RD
206 }
207 break;
208
9e96e16f 209 case SCE_INNO_INLINE_EXPANSION:
b8193d80
RD
210 if (ch == '}') {
211 state = SCE_INNO_DEFAULT;
9e96e16f 212 styler.ColourTo(i,SCE_INNO_INLINE_EXPANSION);
b8193d80
RD
213 } else if (isEOL) {
214 state = SCE_INNO_DEFAULT;
215 styler.ColourTo(i,SCE_INNO_DEFAULT);
216 }
217 break;
218
219 case SCE_INNO_COMMENT_PASCAL:
9e96e16f
RD
220 if (isCStyleComment) {
221 if (isEOL) {
222 state = SCE_INNO_DEFAULT;
223 styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
224 }
225 } else {
226 if (ch == '}' || (ch == ')' && chPrev == '*')) {
227 state = SCE_INNO_DEFAULT;
228 styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
229 } else if (isEOL) {
230 state = SCE_INNO_DEFAULT;
231 styler.ColourTo(i,SCE_INNO_DEFAULT);
232 }
b8193d80
RD
233 }
234 break;
235
236 }
237 }
238 delete []buffer;
239}
240
241static const char * const innoWordListDesc[] = {
242 "Sections",
243 "Keywords",
244 "Parameters",
245 "Preprocessor directives",
246 "Pascal keywords",
247 "User defined keywords",
248 0
249};
250
251static void FoldInnoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
b8193d80 252 unsigned int endPos = startPos + length;
9e96e16f
RD
253 char chNext = styler[startPos];
254
b8193d80
RD
255 int lineCurrent = styler.GetLine(startPos);
256
9e96e16f
RD
257 bool sectionFlag = false;
258 int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE;
259 int level;
b8193d80
RD
260
261 for (unsigned int i = startPos; i < endPos; i++) {
262 char ch = chNext;
263 chNext = styler[i+1];
b8193d80 264 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
9e96e16f 265 int style = styler.StyleAt(i);
b8193d80
RD
266
267 if (style == SCE_INNO_SECTION)
9e96e16f
RD
268 sectionFlag = true;
269
270 if (atEOL || i == endPos - 1) {
271 if (sectionFlag) {
272 level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
273 if (level == levelPrev)
274 styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
275 } else {
276 level = levelPrev & SC_FOLDLEVELNUMBERMASK;
277 if (levelPrev & SC_FOLDLEVELHEADERFLAG)
278 level++;
b8193d80
RD
279 }
280
9e96e16f 281 styler.SetLevel(lineCurrent, level);
b8193d80 282
9e96e16f 283 levelPrev = level;
b8193d80 284 lineCurrent++;
9e96e16f 285 sectionFlag = false;
b8193d80 286 }
b8193d80 287 }
b8193d80
RD
288}
289
290LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, "inno", FoldInnoDoc, innoWordListDesc);