~ubuntu-branches/ubuntu/trusty/presage/trusty-proposed

« back to all changes in this revision

Viewing changes to apps/gtk/gprompter/scintilla/lexers/LexInno.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Matteo Vescovi
  • Date: 2011-08-06 09:26:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110806092615-0wvhajaht9974ncx
Tags: upstream-0.8.6
ImportĀ upstreamĀ versionĀ 0.8.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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>
 
10
#include <stdio.h>
 
11
#include <stdarg.h>
 
12
#include <assert.h>
 
13
#include <ctype.h>
 
14
 
 
15
#include "ILexer.h"
 
16
#include "Scintilla.h"
 
17
#include "SciLexer.h"
 
18
 
 
19
#include "WordList.h"
 
20
#include "LexAccessor.h"
 
21
#include "Accessor.h"
 
22
#include "StyleContext.h"
 
23
#include "CharacterSet.h"
 
24
#include "LexerModule.h"
 
25
 
 
26
#ifdef SCI_NAMESPACE
 
27
using namespace Scintilla;
 
28
#endif
 
29
 
 
30
static 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;
 
39
        bool isCStyleComment = false;
 
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
 
 
48
        int curLine = styler.GetLine(startPos);
 
49
        int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
 
50
        bool isCode = (curLineState == 1);
 
51
 
 
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
 
 
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
 
 
78
                switch(state) {
 
79
                        case SCE_INNO_DEFAULT:
 
80
                                if (!isCode && ch == ';' && isBOLWS) {
 
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;
 
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 == '*'))) {
 
94
                                        // Start of a Pascal comment
 
95
                                        state = SCE_INNO_COMMENT_PASCAL;
 
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;
 
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
 
133
                                        if (!isCode && standardKeywords.InList(buffer)) {
 
134
                                                styler.ColourTo(i-1,SCE_INNO_KEYWORD);
 
135
                                        } else if (!isCode && parameterKeywords.InList(buffer)) {
 
136
                                                styler.ColourTo(i-1,SCE_INNO_PARAMETER);
 
137
                                        } else if (isCode && pascalKeywords.InList(buffer)) {
 
138
                                                styler.ColourTo(i-1,SCE_INNO_KEYWORD_PASCAL);
 
139
                                        } else if (!isCode && userKeywords.InList(buffer)) {
 
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);
 
159
                                                isCode = !CompareCaseInsensitive(buffer, "code");
 
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;
 
198
                                        styler.ColourTo(i,SCE_INNO_STRING_DOUBLE);
 
199
                                }
 
200
                                break;
 
201
 
 
202
                        case SCE_INNO_STRING_SINGLE:
 
203
                                if (ch == '\'' || isEOL) {
 
204
                                        state = SCE_INNO_DEFAULT;
 
205
                                        styler.ColourTo(i,SCE_INNO_STRING_SINGLE);
 
206
                                }
 
207
                                break;
 
208
 
 
209
                        case SCE_INNO_INLINE_EXPANSION:
 
210
                                if (ch == '}') {
 
211
                                        state = SCE_INNO_DEFAULT;
 
212
                                        styler.ColourTo(i,SCE_INNO_INLINE_EXPANSION);
 
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:
 
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
                                        }
 
233
                                }
 
234
                                break;
 
235
 
 
236
                }
 
237
        }
 
238
        delete []buffer;
 
239
}
 
240
 
 
241
static const char * const innoWordListDesc[] = {
 
242
        "Sections",
 
243
        "Keywords",
 
244
        "Parameters",
 
245
        "Preprocessor directives",
 
246
        "Pascal keywords",
 
247
        "User defined keywords",
 
248
        0
 
249
};
 
250
 
 
251
static void FoldInnoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
 
252
        unsigned int endPos = startPos + length;
 
253
        char chNext = styler[startPos];
 
254
 
 
255
        int lineCurrent = styler.GetLine(startPos);
 
256
 
 
257
        bool sectionFlag = false;
 
258
        int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE;
 
259
        int level;
 
260
 
 
261
        for (unsigned int i = startPos; i < endPos; i++) {
 
262
                char ch = chNext;
 
263
                chNext = styler[i+1];
 
264
                bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 
265
                int style = styler.StyleAt(i);
 
266
 
 
267
                if (style == SCE_INNO_SECTION)
 
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++;
 
279
                        }
 
280
 
 
281
                        styler.SetLevel(lineCurrent, level);
 
282
 
 
283
                        levelPrev = level;
 
284
                        lineCurrent++;
 
285
                        sectionFlag = false;
 
286
                }
 
287
        }
 
288
}
 
289
 
 
290
LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, "inno", FoldInnoDoc, innoWordListDesc);