*** empty log message ***
[anjuta-git-plugin.git] / scintilla / LexSpecman.cxx
blobbf5d639a129b39c637781e474911ebdcb182f76a
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>
15 #include "Platform.h"
17 #include "PropSet.h"
18 #include "Accessor.h"
19 #include "StyleContext.h"
20 #include "KeyWords.h"
21 #include "Scintilla.h"
22 #include "SciLexer.h"
25 static inline bool IsAWordChar(const int ch) {
26 return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
29 static inline bool IsANumberChar(const int ch) {
30 return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '\'');
33 static inline bool IsAWordStart(const int ch) {
34 return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '`');
37 static void ColouriseSpecmanDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
38 Accessor &styler, bool caseSensitive) {
40 WordList &keywords = *keywordlists[0];
41 WordList &keywords2 = *keywordlists[1];
42 WordList &keywords3 = *keywordlists[2];
43 WordList &keywords4 = *keywordlists[3];
45 // Do not leak onto next line
46 if (initStyle == SCE_SN_STRINGEOL)
47 initStyle = SCE_SN_CODE;
49 int visibleChars = 0;
51 StyleContext sc(startPos, length, initStyle, styler);
53 for (; sc.More(); sc.Forward()) {
55 if (sc.atLineStart && (sc.state == SCE_SN_STRING)) {
56 // Prevent SCE_SN_STRINGEOL from leaking back to previous line
57 sc.SetState(SCE_SN_STRING);
60 // Handle line continuation generically.
61 if (sc.ch == '\\') {
62 if (sc.chNext == '\n' || sc.chNext == '\r') {
63 sc.Forward();
64 if (sc.ch == '\r' && sc.chNext == '\n') {
65 sc.Forward();
67 continue;
71 // Determine if the current state should terminate.
72 if (sc.state == SCE_SN_OPERATOR) {
73 sc.SetState(SCE_SN_CODE);
74 } else if (sc.state == SCE_SN_NUMBER) {
75 if (!IsANumberChar(sc.ch)) {
76 sc.SetState(SCE_SN_CODE);
78 } else if (sc.state == SCE_SN_IDENTIFIER) {
79 if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
80 char s[100];
81 if (caseSensitive) {
82 sc.GetCurrent(s, sizeof(s));
83 } else {
84 sc.GetCurrentLowered(s, sizeof(s));
86 if (keywords.InList(s)) {
87 sc.ChangeState(SCE_SN_WORD);
88 } else if (keywords2.InList(s)) {
89 sc.ChangeState(SCE_SN_WORD2);
90 } else if (keywords3.InList(s)) {
91 sc.ChangeState(SCE_SN_WORD3);
92 } else if (keywords4.InList(s)) {
93 sc.ChangeState(SCE_SN_USER);
95 sc.SetState(SCE_SN_CODE);
97 } else if (sc.state == SCE_SN_PREPROCESSOR) {
98 if (IsASpace(sc.ch)) {
99 sc.SetState(SCE_SN_CODE);
101 } else if (sc.state == SCE_SN_DEFAULT) {
102 if (sc.Match('<', '\'')) {
103 sc.Forward();
104 sc.ForwardSetState(SCE_SN_CODE);
106 } else if (sc.state == SCE_SN_COMMENTLINE || sc.state == SCE_SN_COMMENTLINEBANG) {
107 if (sc.atLineEnd) {
108 sc.SetState(SCE_SN_CODE);
109 visibleChars = 0;
111 } else if (sc.state == SCE_SN_STRING) {
112 if (sc.ch == '\\') {
113 if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
114 sc.Forward();
116 } else if (sc.ch == '\"') {
117 sc.ForwardSetState(SCE_SN_CODE);
118 } else if (sc.atLineEnd) {
119 sc.ChangeState(SCE_SN_STRINGEOL);
120 sc.ForwardSetState(SCE_SN_CODE);
121 visibleChars = 0;
123 } else if (sc.state == SCE_SN_SIGNAL) {
124 if (sc.atLineEnd) {
125 sc.ChangeState(SCE_SN_STRINGEOL);
126 sc.ForwardSetState(SCE_SN_CODE);
127 visibleChars = 0;
128 } else if (sc.ch == '\\') {
129 if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
130 sc.Forward();
132 } else if (sc.ch == '\'') {
133 sc.ForwardSetState(SCE_SN_CODE);
135 } else if (sc.state == SCE_SN_REGEXTAG) {
136 if (!IsADigit(sc.ch)) {
137 sc.SetState(SCE_SN_CODE);
141 // Determine if a new state should be entered.
142 if (sc.state == SCE_SN_CODE) {
143 if (sc.ch == '$' && IsADigit(sc.chNext)) {
144 sc.SetState(SCE_SN_REGEXTAG);
145 sc.Forward();
146 } else if (IsADigit(sc.ch)) {
147 sc.SetState(SCE_SN_NUMBER);
148 } else if (IsAWordStart(sc.ch)) {
149 sc.SetState(SCE_SN_IDENTIFIER);
150 } else if (sc.Match('\'', '>')) {
151 sc.SetState(SCE_SN_DEFAULT);
152 sc.Forward(); // Eat the * so it isn't used for the end of the comment
153 } else if (sc.Match('/', '/')) {
154 if (sc.Match("//!")) // Nice to have a different comment style
155 sc.SetState(SCE_SN_COMMENTLINEBANG);
156 else
157 sc.SetState(SCE_SN_COMMENTLINE);
158 } else if (sc.Match('-', '-')) {
159 if (sc.Match("--!")) // Nice to have a different comment style
160 sc.SetState(SCE_SN_COMMENTLINEBANG);
161 else
162 sc.SetState(SCE_SN_COMMENTLINE);
163 } else if (sc.ch == '\"') {
164 sc.SetState(SCE_SN_STRING);
165 } else if (sc.ch == '\'') {
166 sc.SetState(SCE_SN_SIGNAL);
167 } else if (sc.ch == '#' && visibleChars == 0) {
168 // Preprocessor commands are alone on their line
169 sc.SetState(SCE_SN_PREPROCESSOR);
170 // Skip whitespace between # and preprocessor word
171 do {
172 sc.Forward();
173 } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
174 if (sc.atLineEnd) {
175 sc.SetState(SCE_SN_CODE);
177 } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@') {
178 sc.SetState(SCE_SN_OPERATOR);
182 if (sc.atLineEnd) {
183 // Reset states to begining of colourise so no surprises
184 // if different sets of lines lexed.
185 visibleChars = 0;
187 if (!IsASpace(sc.ch)) {
188 visibleChars++;
191 sc.Complete();
194 // Store both the current line's fold level and the next lines in the
195 // level store to make it easy to pick up with each increment
196 // and to make it possible to fiddle the current level for "} else {".
197 static void FoldNoBoxSpecmanDoc(unsigned int startPos, int length, int,
198 Accessor &styler) {
199 bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
200 bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
201 bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
202 unsigned int endPos = startPos + length;
203 int visibleChars = 0;
204 int lineCurrent = styler.GetLine(startPos);
205 int levelCurrent = SC_FOLDLEVELBASE;
206 if (lineCurrent > 0)
207 levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
208 int levelMinCurrent = levelCurrent;
209 int levelNext = levelCurrent;
210 char chNext = styler[startPos];
211 int styleNext = styler.StyleAt(startPos);
212 int style;
213 for (unsigned int i = startPos; i < endPos; i++) {
214 char ch = chNext;
215 chNext = styler.SafeGetCharAt(i + 1);
216 //int stylePrev = style;
217 style = styleNext;
218 styleNext = styler.StyleAt(i + 1);
219 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
220 if (foldComment && (style == SCE_SN_COMMENTLINE)) {
221 if (((ch == '/') && (chNext == '/')) ||
222 ((ch == '-') && (chNext == '-'))) {
223 char chNext2 = styler.SafeGetCharAt(i + 2);
224 if (chNext2 == '{') {
225 levelNext++;
226 } else if (chNext2 == '}') {
227 levelNext--;
231 if (style == SCE_SN_OPERATOR) {
232 if (ch == '{') {
233 // Measure the minimum before a '{' to allow
234 // folding on "} else {"
235 if (levelMinCurrent > levelNext) {
236 levelMinCurrent = levelNext;
238 levelNext++;
239 } else if (ch == '}') {
240 levelNext--;
243 if (atEOL) {
244 int levelUse = levelCurrent;
245 if (foldAtElse) {
246 levelUse = levelMinCurrent;
248 int lev = levelUse | levelNext << 16;
249 if (visibleChars == 0 && foldCompact)
250 lev |= SC_FOLDLEVELWHITEFLAG;
251 if (levelUse < levelNext)
252 lev |= SC_FOLDLEVELHEADERFLAG;
253 if (lev != styler.LevelAt(lineCurrent)) {
254 styler.SetLevel(lineCurrent, lev);
256 lineCurrent++;
257 levelCurrent = levelNext;
258 levelMinCurrent = levelCurrent;
259 visibleChars = 0;
261 if (!isspacechar(ch))
262 visibleChars++;
266 static void FoldSpecmanDoc(unsigned int startPos, int length, int initStyle, WordList *[],
267 Accessor &styler) {
268 FoldNoBoxSpecmanDoc(startPos, length, initStyle, styler);
271 static const char * const specmanWordLists[] = {
272 "Primary keywords and identifiers",
273 "Secondary keywords and identifiers",
274 "Sequence keywords and identifiers",
275 "User defined keywords and identifiers",
276 "Unused",
280 static void ColouriseSpecmanDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
281 Accessor &styler) {
282 ColouriseSpecmanDoc(startPos, length, initStyle, keywordlists, styler, true);
286 LexerModule lmSpecman(SCLEX_SPECMAN, ColouriseSpecmanDocSensitive, "specman", FoldSpecmanDoc, specmanWordLists);