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