scintilla: Update scintilla with changeset 3662:1d1c06df8a2f using gtk+3
[anjuta-extras.git] / plugins / scintilla / scintilla / LexSpecman.cxx
blob1b96482ea0e312f3463851474ae0f19fd86707ce
1 // Scintilla source code edit control
2 /** @file LexSpecman.cxx
3 ** Lexer for Specman E language.
4 ** Written by Avi Yegudin, based on C++ lexer by Neil Hodgson
5 **/
6 // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
7 // The License.txt file describes the conditions under which this software may be distributed.
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.h>
12 #include <stdio.h>
13 #include <stdarg.h>
14 #include <assert.h>
16 #include "ILexer.h"
17 #include "Scintilla.h"
18 #include "SciLexer.h"
20 #include "WordList.h"
21 #include "LexAccessor.h"
22 #include "Accessor.h"
23 #include "StyleContext.h"
24 #include "CharacterSet.h"
25 #include "LexerModule.h"
27 #ifdef SCI_NAMESPACE
28 using namespace Scintilla;
29 #endif
31 static inline bool IsAWordChar(const int ch) {
32 return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
35 static inline bool IsANumberChar(const int ch) {
36 return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '\'');
39 static inline bool IsAWordStart(const int ch) {
40 return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '`');
43 static void ColouriseSpecmanDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
44 Accessor &styler, bool caseSensitive) {
46 WordList &keywords = *keywordlists[0];
47 WordList &keywords2 = *keywordlists[1];
48 WordList &keywords3 = *keywordlists[2];
49 WordList &keywords4 = *keywordlists[3];
51 // Do not leak onto next line
52 if (initStyle == SCE_SN_STRINGEOL)
53 initStyle = SCE_SN_CODE;
55 int visibleChars = 0;
57 StyleContext sc(startPos, length, initStyle, styler);
59 for (; sc.More(); sc.Forward()) {
61 if (sc.atLineStart && (sc.state == SCE_SN_STRING)) {
62 // Prevent SCE_SN_STRINGEOL from leaking back to previous line
63 sc.SetState(SCE_SN_STRING);
66 // Handle line continuation generically.
67 if (sc.ch == '\\') {
68 if (sc.chNext == '\n' || sc.chNext == '\r') {
69 sc.Forward();
70 if (sc.ch == '\r' && sc.chNext == '\n') {
71 sc.Forward();
73 continue;
77 // Determine if the current state should terminate.
78 if (sc.state == SCE_SN_OPERATOR) {
79 sc.SetState(SCE_SN_CODE);
80 } else if (sc.state == SCE_SN_NUMBER) {
81 if (!IsANumberChar(sc.ch)) {
82 sc.SetState(SCE_SN_CODE);
84 } else if (sc.state == SCE_SN_IDENTIFIER) {
85 if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
86 char s[100];
87 if (caseSensitive) {
88 sc.GetCurrent(s, sizeof(s));
89 } else {
90 sc.GetCurrentLowered(s, sizeof(s));
92 if (keywords.InList(s)) {
93 sc.ChangeState(SCE_SN_WORD);
94 } else if (keywords2.InList(s)) {
95 sc.ChangeState(SCE_SN_WORD2);
96 } else if (keywords3.InList(s)) {
97 sc.ChangeState(SCE_SN_WORD3);
98 } else if (keywords4.InList(s)) {
99 sc.ChangeState(SCE_SN_USER);
101 sc.SetState(SCE_SN_CODE);
103 } else if (sc.state == SCE_SN_PREPROCESSOR) {
104 if (IsASpace(sc.ch)) {
105 sc.SetState(SCE_SN_CODE);
107 } else if (sc.state == SCE_SN_DEFAULT) {
108 if (sc.Match('<', '\'')) {
109 sc.Forward();
110 sc.ForwardSetState(SCE_SN_CODE);
112 } else if (sc.state == SCE_SN_COMMENTLINE || sc.state == SCE_SN_COMMENTLINEBANG) {
113 if (sc.atLineEnd) {
114 sc.SetState(SCE_SN_CODE);
115 visibleChars = 0;
117 } else if (sc.state == SCE_SN_STRING) {
118 if (sc.ch == '\\') {
119 if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
120 sc.Forward();
122 } else if (sc.ch == '\"') {
123 sc.ForwardSetState(SCE_SN_CODE);
124 } else if (sc.atLineEnd) {
125 sc.ChangeState(SCE_SN_STRINGEOL);
126 sc.ForwardSetState(SCE_SN_CODE);
127 visibleChars = 0;
129 } else if (sc.state == SCE_SN_SIGNAL) {
130 if (sc.atLineEnd) {
131 sc.ChangeState(SCE_SN_STRINGEOL);
132 sc.ForwardSetState(SCE_SN_CODE);
133 visibleChars = 0;
134 } else if (sc.ch == '\\') {
135 if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
136 sc.Forward();
138 } else if (sc.ch == '\'') {
139 sc.ForwardSetState(SCE_SN_CODE);
141 } else if (sc.state == SCE_SN_REGEXTAG) {
142 if (!IsADigit(sc.ch)) {
143 sc.SetState(SCE_SN_CODE);
147 // Determine if a new state should be entered.
148 if (sc.state == SCE_SN_CODE) {
149 if (sc.ch == '$' && IsADigit(sc.chNext)) {
150 sc.SetState(SCE_SN_REGEXTAG);
151 sc.Forward();
152 } else if (IsADigit(sc.ch)) {
153 sc.SetState(SCE_SN_NUMBER);
154 } else if (IsAWordStart(sc.ch)) {
155 sc.SetState(SCE_SN_IDENTIFIER);
156 } else if (sc.Match('\'', '>')) {
157 sc.SetState(SCE_SN_DEFAULT);
158 sc.Forward(); // Eat the * so it isn't used for the end of the comment
159 } else if (sc.Match('/', '/')) {
160 if (sc.Match("//!")) // Nice to have a different comment style
161 sc.SetState(SCE_SN_COMMENTLINEBANG);
162 else
163 sc.SetState(SCE_SN_COMMENTLINE);
164 } else if (sc.Match('-', '-')) {
165 if (sc.Match("--!")) // Nice to have a different comment style
166 sc.SetState(SCE_SN_COMMENTLINEBANG);
167 else
168 sc.SetState(SCE_SN_COMMENTLINE);
169 } else if (sc.ch == '\"') {
170 sc.SetState(SCE_SN_STRING);
171 } else if (sc.ch == '\'') {
172 sc.SetState(SCE_SN_SIGNAL);
173 } else if (sc.ch == '#' && visibleChars == 0) {
174 // Preprocessor commands are alone on their line
175 sc.SetState(SCE_SN_PREPROCESSOR);
176 // Skip whitespace between # and preprocessor word
177 do {
178 sc.Forward();
179 } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
180 if (sc.atLineEnd) {
181 sc.SetState(SCE_SN_CODE);
183 } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@') {
184 sc.SetState(SCE_SN_OPERATOR);
188 if (sc.atLineEnd) {
189 // Reset states to begining of colourise so no surprises
190 // if different sets of lines lexed.
191 visibleChars = 0;
193 if (!IsASpace(sc.ch)) {
194 visibleChars++;
197 sc.Complete();
200 // Store both the current line's fold level and the next lines in the
201 // level store to make it easy to pick up with each increment
202 // and to make it possible to fiddle the current level for "} else {".
203 static void FoldNoBoxSpecmanDoc(unsigned int startPos, int length, int,
204 Accessor &styler) {
205 bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
206 bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
207 bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
208 unsigned int endPos = startPos + length;
209 int visibleChars = 0;
210 int lineCurrent = styler.GetLine(startPos);
211 int levelCurrent = SC_FOLDLEVELBASE;
212 if (lineCurrent > 0)
213 levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
214 int levelMinCurrent = levelCurrent;
215 int levelNext = levelCurrent;
216 char chNext = styler[startPos];
217 int styleNext = styler.StyleAt(startPos);
218 int style;
219 for (unsigned int i = startPos; i < endPos; i++) {
220 char ch = chNext;
221 chNext = styler.SafeGetCharAt(i + 1);
222 //int stylePrev = style;
223 style = styleNext;
224 styleNext = styler.StyleAt(i + 1);
225 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
226 if (foldComment && (style == SCE_SN_COMMENTLINE)) {
227 if (((ch == '/') && (chNext == '/')) ||
228 ((ch == '-') && (chNext == '-'))) {
229 char chNext2 = styler.SafeGetCharAt(i + 2);
230 if (chNext2 == '{') {
231 levelNext++;
232 } else if (chNext2 == '}') {
233 levelNext--;
237 if (style == SCE_SN_OPERATOR) {
238 if (ch == '{') {
239 // Measure the minimum before a '{' to allow
240 // folding on "} else {"
241 if (levelMinCurrent > levelNext) {
242 levelMinCurrent = levelNext;
244 levelNext++;
245 } else if (ch == '}') {
246 levelNext--;
249 if (atEOL) {
250 int levelUse = levelCurrent;
251 if (foldAtElse) {
252 levelUse = levelMinCurrent;
254 int lev = levelUse | levelNext << 16;
255 if (visibleChars == 0 && foldCompact)
256 lev |= SC_FOLDLEVELWHITEFLAG;
257 if (levelUse < levelNext)
258 lev |= SC_FOLDLEVELHEADERFLAG;
259 if (lev != styler.LevelAt(lineCurrent)) {
260 styler.SetLevel(lineCurrent, lev);
262 lineCurrent++;
263 levelCurrent = levelNext;
264 levelMinCurrent = levelCurrent;
265 visibleChars = 0;
267 if (!isspacechar(ch))
268 visibleChars++;
272 static void FoldSpecmanDoc(unsigned int startPos, int length, int initStyle, WordList *[],
273 Accessor &styler) {
274 FoldNoBoxSpecmanDoc(startPos, length, initStyle, styler);
277 static const char * const specmanWordLists[] = {
278 "Primary keywords and identifiers",
279 "Secondary keywords and identifiers",
280 "Sequence keywords and identifiers",
281 "User defined keywords and identifiers",
282 "Unused",
286 static void ColouriseSpecmanDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
287 Accessor &styler) {
288 ColouriseSpecmanDoc(startPos, length, initStyle, keywordlists, styler, true);
292 LexerModule lmSpecman(SCLEX_SPECMAN, ColouriseSpecmanDocSensitive, "specman", FoldSpecmanDoc, specmanWordLists);