]>
Commit | Line | Data |
---|---|---|
1 | // SciTE - Scintilla based Text Editor | |
2 | // LexBullant.cxx - lexer for Bullant | |
3 | ||
4 | #include <stdlib.h> | |
5 | #include <string.h> | |
6 | #include <stdio.h> | |
7 | #include <stdarg.h> | |
8 | #include <assert.h> | |
9 | #include <ctype.h> | |
10 | ||
11 | #include "ILexer.h" | |
12 | #include "Scintilla.h" | |
13 | #include "SciLexer.h" | |
14 | ||
15 | #include "WordList.h" | |
16 | #include "LexAccessor.h" | |
17 | #include "Accessor.h" | |
18 | #include "StyleContext.h" | |
19 | #include "CharacterSet.h" | |
20 | #include "LexerModule.h" | |
21 | ||
22 | #ifdef SCI_NAMESPACE | |
23 | using namespace Scintilla; | |
24 | #endif | |
25 | ||
26 | static int classifyWordBullant(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { | |
27 | char s[100]; | |
28 | s[0] = '\0'; | |
29 | for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { | |
30 | s[i] = static_cast<char>(tolower(styler[start + i])); | |
31 | s[i + 1] = '\0'; | |
32 | } | |
33 | int lev= 0; | |
34 | char chAttr = SCE_C_IDENTIFIER; | |
35 | if (isdigit(s[0]) || (s[0] == '.')){ | |
36 | chAttr = SCE_C_NUMBER; | |
37 | } | |
38 | else { | |
39 | if (keywords.InList(s)) { | |
40 | chAttr = SCE_C_WORD; | |
41 | if (strcmp(s, "end") == 0) | |
42 | lev = -1; | |
43 | else if (strcmp(s, "method") == 0 || | |
44 | strcmp(s, "case") == 0 || | |
45 | strcmp(s, "class") == 0 || | |
46 | strcmp(s, "debug") == 0 || | |
47 | strcmp(s, "test") == 0 || | |
48 | strcmp(s, "if") == 0 || | |
49 | strcmp(s, "lock") == 0 || | |
50 | strcmp(s, "transaction") == 0 || | |
51 | strcmp(s, "trap") == 0 || | |
52 | strcmp(s, "until") == 0 || | |
53 | strcmp(s, "while") == 0) | |
54 | lev = 1; | |
55 | } | |
56 | } | |
57 | styler.ColourTo(end, chAttr); | |
58 | return lev; | |
59 | } | |
60 | ||
61 | static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], | |
62 | Accessor &styler) { | |
63 | WordList &keywords = *keywordlists[0]; | |
64 | ||
65 | styler.StartAt(startPos); | |
66 | ||
67 | bool fold = styler.GetPropertyInt("fold") != 0; | |
68 | int lineCurrent = styler.GetLine(startPos); | |
69 | int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; | |
70 | int levelCurrent = levelPrev; | |
71 | ||
72 | int state = initStyle; | |
73 | if (state == SCE_C_STRINGEOL) // Does not leak onto next line | |
74 | state = SCE_C_DEFAULT; | |
75 | char chPrev = ' '; | |
76 | char chNext = styler[startPos]; | |
77 | unsigned int lengthDoc = startPos + length; | |
78 | int visibleChars = 0; | |
79 | styler.StartSegment(startPos); | |
80 | int endFoundThisLine = 0; | |
81 | for (unsigned int i = startPos; i < lengthDoc; i++) { | |
82 | char ch = chNext; | |
83 | chNext = styler.SafeGetCharAt(i + 1); | |
84 | ||
85 | if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { | |
86 | // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) | |
87 | // Avoid triggering two times on Dos/Win | |
88 | // End of line | |
89 | endFoundThisLine = 0; | |
90 | if (state == SCE_C_STRINGEOL) { | |
91 | styler.ColourTo(i, state); | |
92 | state = SCE_C_DEFAULT; | |
93 | } | |
94 | if (fold) { | |
95 | int lev = levelPrev; | |
96 | if (visibleChars == 0) | |
97 | lev |= SC_FOLDLEVELWHITEFLAG; | |
98 | if ((levelCurrent > levelPrev) && (visibleChars > 0)) | |
99 | lev |= SC_FOLDLEVELHEADERFLAG; | |
100 | styler.SetLevel(lineCurrent, lev); | |
101 | lineCurrent++; | |
102 | levelPrev = levelCurrent; | |
103 | } | |
104 | visibleChars = 0; | |
105 | ||
106 | /* int indentBlock = GetLineIndentation(lineCurrent); | |
107 | if (blockChange==1){ | |
108 | lineCurrent++; | |
109 | int pos=SetLineIndentation(lineCurrent, indentBlock + indentSize); | |
110 | } else if (blockChange==-1) { | |
111 | indentBlock -= indentSize; | |
112 | if (indentBlock < 0) | |
113 | indentBlock = 0; | |
114 | SetLineIndentation(lineCurrent, indentBlock); | |
115 | lineCurrent++; | |
116 | } | |
117 | blockChange=0; | |
118 | */ } | |
119 | if (!(isascii(ch) && isspace(ch))) | |
120 | visibleChars++; | |
121 | ||
122 | if (styler.IsLeadByte(ch)) { | |
123 | chNext = styler.SafeGetCharAt(i + 2); | |
124 | chPrev = ' '; | |
125 | i += 1; | |
126 | continue; | |
127 | } | |
128 | ||
129 | if (state == SCE_C_DEFAULT) { | |
130 | if (iswordstart(ch)) { | |
131 | styler.ColourTo(i-1, state); | |
132 | state = SCE_C_IDENTIFIER; | |
133 | } else if (ch == '@' && chNext == 'o') { | |
134 | if ((styler.SafeGetCharAt(i+2) =='f') && (styler.SafeGetCharAt(i+3) == 'f')) { | |
135 | styler.ColourTo(i-1, state); | |
136 | state = SCE_C_COMMENT; | |
137 | } | |
138 | } else if (ch == '#') { | |
139 | styler.ColourTo(i-1, state); | |
140 | state = SCE_C_COMMENTLINE; | |
141 | } else if (ch == '\"') { | |
142 | styler.ColourTo(i-1, state); | |
143 | state = SCE_C_STRING; | |
144 | } else if (ch == '\'') { | |
145 | styler.ColourTo(i-1, state); | |
146 | state = SCE_C_CHARACTER; | |
147 | } else if (isoperator(ch)) { | |
148 | styler.ColourTo(i-1, state); | |
149 | styler.ColourTo(i, SCE_C_OPERATOR); | |
150 | } | |
151 | } else if (state == SCE_C_IDENTIFIER) { | |
152 | if (!iswordchar(ch)) { | |
153 | int levelChange = classifyWordBullant(styler.GetStartSegment(), i - 1, keywords, styler); | |
154 | state = SCE_C_DEFAULT; | |
155 | chNext = styler.SafeGetCharAt(i + 1); | |
156 | if (ch == '#') { | |
157 | state = SCE_C_COMMENTLINE; | |
158 | } else if (ch == '\"') { | |
159 | state = SCE_C_STRING; | |
160 | } else if (ch == '\'') { | |
161 | state = SCE_C_CHARACTER; | |
162 | } else if (isoperator(ch)) { | |
163 | styler.ColourTo(i, SCE_C_OPERATOR); | |
164 | } | |
165 | if (endFoundThisLine == 0) | |
166 | levelCurrent+=levelChange; | |
167 | if (levelChange == -1) | |
168 | endFoundThisLine=1; | |
169 | } | |
170 | } else if (state == SCE_C_COMMENT) { | |
171 | if (ch == '@' && chNext == 'o') { | |
172 | if (styler.SafeGetCharAt(i+2) == 'n') { | |
173 | styler.ColourTo(i+2, state); | |
174 | state = SCE_C_DEFAULT; | |
175 | i+=2; | |
176 | } | |
177 | } | |
178 | } else if (state == SCE_C_COMMENTLINE) { | |
179 | if (ch == '\r' || ch == '\n') { | |
180 | endFoundThisLine = 0; | |
181 | styler.ColourTo(i-1, state); | |
182 | state = SCE_C_DEFAULT; | |
183 | } | |
184 | } else if (state == SCE_C_STRING) { | |
185 | if (ch == '\\') { | |
186 | if (chNext == '\"' || chNext == '\'' || chNext == '\\') { | |
187 | i++; | |
188 | ch = chNext; | |
189 | chNext = styler.SafeGetCharAt(i + 1); | |
190 | } | |
191 | } else if (ch == '\"') { | |
192 | styler.ColourTo(i, state); | |
193 | state = SCE_C_DEFAULT; | |
194 | } else if (chNext == '\r' || chNext == '\n') { | |
195 | endFoundThisLine = 0; | |
196 | styler.ColourTo(i-1, SCE_C_STRINGEOL); | |
197 | state = SCE_C_STRINGEOL; | |
198 | } | |
199 | } else if (state == SCE_C_CHARACTER) { | |
200 | if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { | |
201 | endFoundThisLine = 0; | |
202 | styler.ColourTo(i-1, SCE_C_STRINGEOL); | |
203 | state = SCE_C_STRINGEOL; | |
204 | } else if (ch == '\\') { | |
205 | if (chNext == '\"' || chNext == '\'' || chNext == '\\') { | |
206 | i++; | |
207 | ch = chNext; | |
208 | chNext = styler.SafeGetCharAt(i + 1); | |
209 | } | |
210 | } else if (ch == '\'') { | |
211 | styler.ColourTo(i, state); | |
212 | state = SCE_C_DEFAULT; | |
213 | } | |
214 | } | |
215 | chPrev = ch; | |
216 | } | |
217 | styler.ColourTo(lengthDoc - 1, state); | |
218 | ||
219 | // Fill in the real level of the next line, keeping the current flags as they will be filled in later | |
220 | if (fold) { | |
221 | int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; | |
222 | //styler.SetLevel(lineCurrent, levelCurrent | flagsNext); | |
223 | styler.SetLevel(lineCurrent, levelPrev | flagsNext); | |
224 | ||
225 | } | |
226 | } | |
227 | ||
228 | static const char * const bullantWordListDesc[] = { | |
229 | "Keywords", | |
230 | 0 | |
231 | }; | |
232 | ||
233 | LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc); |