]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexVB.cxx
Upgraded to version 1.39 of Scintilla, and upated wxStyledTextCtrl
[wxWidgets.git] / src / stc / scintilla / src / LexVB.cxx
1 // Scintilla source code edit control
2 /** @file LexVB.cxx
3 ** Lexer for Visual Basic and VBScript.
4 **/
5 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <stdio.h>
12 #include <stdarg.h>
13
14 #include "Platform.h"
15
16 #include "PropSet.h"
17 #include "Accessor.h"
18 #include "KeyWords.h"
19 #include "Scintilla.h"
20 #include "SciLexer.h"
21
22 static int classifyWordVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
23
24 char s[100];
25 bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.') ||
26 (styler[start] == '&' && tolower(styler[start+1]) == 'h');
27 unsigned int i;
28 for (i = 0; i < end - start + 1 && i < 30; i++) {
29 s[i] = static_cast<char>(tolower(styler[start + i]));
30 }
31 s[i] = '\0';
32 char chAttr = SCE_C_DEFAULT;
33 if (wordIsNumber)
34 chAttr = SCE_C_NUMBER;
35 else {
36 if (strcmp(s, "rem") == 0)
37 chAttr = SCE_C_COMMENTLINE;
38 else if (keywords.InList(s))
39 chAttr = SCE_C_WORD;
40 }
41 styler.ColourTo(end, chAttr);
42 if (chAttr == SCE_C_COMMENTLINE)
43 return SCE_C_COMMENTLINE;
44 else
45 return SCE_C_DEFAULT;
46 }
47
48 static bool IsVBComment(Accessor &styler, int pos, int len) {
49 return len>0 && styler[pos]=='\'';
50 }
51
52 static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
53 WordList *keywordlists[], Accessor &styler) {
54
55 WordList &keywords = *keywordlists[0];
56
57 styler.StartAt(startPos);
58
59 int visibleChars = 0;
60 int state = initStyle;
61 char chNext = styler[startPos];
62 styler.StartSegment(startPos);
63 int lengthDoc = startPos + length;
64 for (int i = startPos; i < lengthDoc; i++) {
65 char ch = chNext;
66 chNext = styler.SafeGetCharAt(i + 1);
67
68 if (styler.IsLeadByte(ch)) {
69 chNext = styler.SafeGetCharAt(i + 2);
70 i += 1;
71 continue;
72 }
73
74 if (ch == '\r' || ch == '\n') {
75 // End of line
76 if (state == SCE_C_COMMENTLINE || state == SCE_C_PREPROCESSOR) {
77 styler.ColourTo(i - 1, state);
78 state = SCE_C_DEFAULT;
79 }
80 visibleChars = 0;
81 }
82 if (!isspacechar(ch))
83 visibleChars++;
84
85 if (state == SCE_C_DEFAULT) {
86 if (iswordstart(ch)) {
87 styler.ColourTo(i - 1, state);
88 state = SCE_C_WORD;
89 } else if (ch == '\'') {
90 styler.ColourTo(i - 1, state);
91 state = SCE_C_COMMENTLINE;
92 } else if (ch == '\"') {
93 styler.ColourTo(i - 1, state);
94 state = SCE_C_STRING;
95 } else if (ch == '#' && visibleChars == 1) {
96 // Preprocessor commands are alone on their line
97 styler.ColourTo(i - 1, state);
98 state = SCE_C_PREPROCESSOR;
99 } else if (ch == '&' && tolower(chNext) == 'h') {
100 styler.ColourTo(i - 1, state);
101 state = SCE_C_WORD;
102 } else if (isoperator(ch)) {
103 styler.ColourTo(i - 1, state);
104 styler.ColourTo(i, SCE_C_OPERATOR);
105 }
106 } else if (state == SCE_C_WORD) {
107 if (!iswordchar(ch)) {
108 state = classifyWordVB(styler.GetStartSegment(), i - 1, keywords, styler);
109 if (state == SCE_C_DEFAULT) {
110 if (ch == '\'') {
111 state = SCE_C_COMMENTLINE;
112 } else if (ch == '\"') {
113 state = SCE_C_STRING;
114 } else if (isoperator(ch)) {
115 styler.ColourTo(i - 1, state);
116 styler.ColourTo(i, SCE_C_OPERATOR);
117 }
118 }
119 }
120 } else {
121 if (state == SCE_C_STRING) {
122 // VB doubles quotes to preserve them
123 if (ch == '\"') {
124 styler.ColourTo(i, state);
125 state = SCE_C_DEFAULT;
126 i++;
127 ch = chNext;
128 chNext = styler.SafeGetCharAt(i + 1);
129 }
130 }
131 if (state == SCE_C_DEFAULT) { // One of the above succeeded
132 if (ch == '\'') {
133 state = SCE_C_COMMENTLINE;
134 } else if (ch == '\"') {
135 state = SCE_C_STRING;
136 } else if (iswordstart(ch)) {
137 state = SCE_C_WORD;
138 }
139 }
140 }
141 }
142 styler.ColourTo(lengthDoc, state);
143 }
144
145 static void FoldVBDoc(unsigned int startPos, int length, int initStyle,
146 WordList *[], Accessor &styler) {
147 int lengthDoc = startPos + length;
148
149 // Backtrack to previous line in case need to fix its fold status
150 int lineCurrent = styler.GetLine(startPos);
151 if (startPos > 0) {
152 if (lineCurrent > 0) {
153 lineCurrent--;
154 startPos = styler.LineStart(lineCurrent);
155 if (startPos == 0)
156 initStyle = SCE_P_DEFAULT;
157 else
158 initStyle = styler.StyleAt(startPos-1);
159 }
160 }
161 int state = initStyle & 31;
162 int spaceFlags = 0;
163 int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsVBComment);
164 if ((state == SCE_P_TRIPLE) || (state == SCE_P_TRIPLEDOUBLE))
165 indentCurrent |= SC_FOLDLEVELWHITEFLAG;
166 char chNext = styler[startPos];
167 for (int i = startPos; i < lengthDoc; i++) {
168 char ch = chNext;
169 chNext = styler.SafeGetCharAt(i + 1);
170 int style = styler.StyleAt(i) & 31;
171
172 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) {
173 int lev = indentCurrent;
174 int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsVBComment);
175 if ((style == SCE_P_TRIPLE) || (style== SCE_P_TRIPLEDOUBLE))
176 indentNext |= SC_FOLDLEVELWHITEFLAG;
177 if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
178 // Only non whitespace lines can be headers
179 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
180 lev |= SC_FOLDLEVELHEADERFLAG;
181 } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
182 // Line after is blank so check the next - maybe should continue further?
183 int spaceFlags2 = 0;
184 int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsVBComment);
185 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
186 lev |= SC_FOLDLEVELHEADERFLAG;
187 }
188 }
189 }
190 indentCurrent = indentNext;
191 styler.SetLevel(lineCurrent, lev);
192 lineCurrent++;
193 }
194 }
195 }
196
197 LexerModule lmVB(SCLEX_VB, ColouriseVBDoc, "vb", FoldVBDoc);