]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexPascal.cxx
This form of the event cloning patch survived my
[wxWidgets.git] / src / stc / scintilla / src / LexPascal.cxx
1 // Scintilla source code edit control
2 /** @file LexPascal.cxx
3 ** Lexer for Pascal.
4 ** Written by Laurent le Tynevez
5 **/
6
7 #include <stdlib.h>
8 #include <string.h>
9 #include <ctype.h>
10 #include <stdio.h>
11 #include <stdarg.h>
12
13 #include "Platform.h"
14
15 #include "PropSet.h"
16 #include "Accessor.h"
17 #include "KeyWords.h"
18 #include "Scintilla.h"
19 #include "SciLexer.h"
20
21
22 static int classifyWordPascal(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;
36 if (strcmp(s, "begin") == 0 || strcmp(s, "object") == 0)
37 lev=1;
38 else if (strcmp(s, "end") == 0)
39 lev=-1;
40 }
41 }
42 styler.ColourTo(end, chAttr);
43 return lev;
44 }
45
46 static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
47 Accessor &styler) {
48 WordList &keywords = *keywordlists[0];
49
50 styler.StartAt(startPos);
51
52 bool fold = styler.GetPropertyInt("fold");
53 int lineCurrent = styler.GetLine(startPos);
54 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
55 int levelCurrent = levelPrev;
56
57 int state = initStyle;
58 if (state == SCE_C_STRINGEOL) // Does not leak onto next line
59 state = SCE_C_DEFAULT;
60 char chPrev = ' ';
61 char chNext = styler[startPos];
62 unsigned int lengthDoc = startPos + length;
63 int visibleChars = 0;
64 styler.StartSegment(startPos);
65 for (unsigned int i = startPos; i < lengthDoc; i++) {
66 char ch = chNext;
67 chNext = styler.SafeGetCharAt(i + 1);
68
69 if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
70 // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
71 // Avoid triggering two times on Dos/Win
72 // End of line
73 if (state == SCE_C_STRINGEOL) {
74 styler.ColourTo(i, state);
75 state = SCE_C_DEFAULT;
76 }
77 if (fold) {
78 int lev = levelPrev;
79 if (visibleChars == 0)
80 lev |= SC_FOLDLEVELWHITEFLAG;
81 if ((levelCurrent > levelPrev) && (visibleChars > 0))
82 lev |= SC_FOLDLEVELHEADERFLAG;
83 styler.SetLevel(lineCurrent, lev);
84 lineCurrent++;
85 levelPrev = levelCurrent;
86 }
87 visibleChars = 0;
88 }
89 if (!isspacechar(ch))
90 visibleChars++;
91
92 if (styler.IsLeadByte(ch)) {
93 chNext = styler.SafeGetCharAt(i + 2);
94 chPrev = ' ';
95 i += 1;
96 continue;
97 }
98
99 if (state == SCE_C_DEFAULT) {
100 if (iswordstart(ch) || (ch == '@')) {
101 styler.ColourTo(i-1, state);
102 state = SCE_C_IDENTIFIER;
103 } else if (ch == '{' && chNext != '$' && chNext != '&') {
104 styler.ColourTo(i-1, state);
105 state = SCE_C_COMMENT;
106 } else if (ch == '(' && chNext == '*'
107 && styler.SafeGetCharAt(i + 2) != '$'
108 && styler.SafeGetCharAt(i + 2) != '&') {
109 styler.ColourTo(i-1, state);
110 state = SCE_C_COMMENTDOC;
111 } else if (ch == '/' && chNext == '/') {
112 styler.ColourTo(i-1, state);
113 state = SCE_C_COMMENTLINE;
114 } else if (ch == '\"') {
115 styler.ColourTo(i-1, state);
116 state = SCE_C_STRING;
117 } else if (ch == '\'') {
118 styler.ColourTo(i-1, state);
119 state = SCE_C_CHARACTER;
120 } else if (ch == '{' && (chNext == '$' || chNext=='&') && visibleChars == 1) {
121 styler.ColourTo(i-1, state);
122 state = SCE_C_PREPROCESSOR;
123 } else if (isoperator(ch)) {
124 styler.ColourTo(i-1, state);
125 styler.ColourTo(i, SCE_C_OPERATOR);
126
127 }
128 } else if (state == SCE_C_IDENTIFIER) {
129 if (!iswordchar(ch)) {
130 int levelChange = classifyWordPascal(styler.GetStartSegment(), i - 1, keywords, styler);
131 state = SCE_C_DEFAULT;
132 chNext = styler.SafeGetCharAt(i + 1);
133 if (ch == '{' && chNext != '$' && chNext != '&') {
134 state = SCE_C_COMMENT;
135 } else if (ch == '(' && chNext == '*'
136 && styler.SafeGetCharAt(i + 2) != '$'
137 && styler.SafeGetCharAt(i + 2) != '&') {
138 styler.ColourTo(i-1, state);
139 state = SCE_C_COMMENTDOC;
140 } else if (ch == '/' && chNext == '/') {
141 state = SCE_C_COMMENTLINE;
142 } else if (ch == '\"') {
143 state = SCE_C_STRING;
144 } else if (ch == '\'') {
145 state = SCE_C_CHARACTER;
146 } else if (isoperator(ch)) {
147 styler.ColourTo(i, SCE_C_OPERATOR);
148 }
149 levelCurrent+=levelChange;
150 }
151 } else {
152 if (state == SCE_C_PREPROCESSOR) {
153 if (ch=='}'){
154 styler.ColourTo(i, state);
155 state = SCE_C_DEFAULT;
156 } else {
157 if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
158 styler.ColourTo(i-1, state);
159 state = SCE_C_DEFAULT;
160 }
161 }
162 } else if (state == SCE_C_COMMENT) {
163 if (ch == '}' ) {
164 styler.ColourTo(i, state);
165 state = SCE_C_DEFAULT;
166 }
167 } else if (state == SCE_C_COMMENTDOC) {
168 if (ch == ')' && chPrev == '*') {
169 if (((i > styler.GetStartSegment() + 2) || (
170 (initStyle == SCE_C_COMMENTDOC) &&
171 (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
172 styler.ColourTo(i, state);
173 state = SCE_C_DEFAULT;
174 }
175 }
176 } else if (state == SCE_C_COMMENTLINE) {
177 if (ch == '\r' || ch == '\n') {
178 styler.ColourTo(i-1, state);
179 state = SCE_C_DEFAULT;
180 }
181 } else if (state == SCE_C_STRING) {
182 if (ch == '\\') {
183 if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
184 i++;
185 ch = chNext;
186 chNext = styler.SafeGetCharAt(i + 1);
187 }
188 } else if (ch == '\"') {
189 styler.ColourTo(i, state);
190 state = SCE_C_DEFAULT;
191 } else if (chNext == '\r' || chNext == '\n') {
192 styler.ColourTo(i-1, SCE_C_STRINGEOL);
193 state = SCE_C_STRINGEOL;
194 }
195 } else if (state == SCE_C_CHARACTER) {
196 if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
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 }
211 chPrev = ch;
212 }
213 styler.ColourTo(lengthDoc - 1, state);
214
215 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
216 if (fold) {
217 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
218 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
219 }
220 }
221
222 LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal");