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