]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexVB.cxx
1 // Scintilla source code edit control
3 ** Lexer for Visual Basic and VBScript.
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.
18 #include "StyleContext.h"
20 #include "Scintilla.h"
23 static bool IsVBComment(Accessor
&styler
, int pos
, int len
) {
24 return len
>0 && styler
[pos
]=='\'';
27 static inline bool IsTypeCharacter(const int ch
) {
28 return ch
== '%' || ch
== '&' || ch
== '@' || ch
== '!' || ch
== '#' || ch
== '$';
31 static inline bool IsAWordChar(const int ch
) {
32 return (ch
< 0x80) && (isalnum(ch
) || ch
== '.' || ch
== '_');
35 static inline bool IsAWordStart(const int ch
) {
36 return (ch
< 0x80) && (isalnum(ch
) || ch
== '_');
39 static inline bool IsADateCharacter(const int ch
) {
41 (isalnum(ch
) || ch
== '|' || ch
== '-' || ch
== '/' || ch
== ':' || ch
== ' ' || ch
== '\t');
44 static void ColouriseVBDoc(unsigned int startPos
, int length
, int initStyle
,
45 WordList
*keywordlists
[], Accessor
&styler
, bool vbScriptSyntax
) {
47 WordList
&keywords
= *keywordlists
[0];
49 styler
.StartAt(startPos
);
53 StyleContext
sc(startPos
, length
, initStyle
, styler
);
55 for (; sc
.More(); sc
.Forward()) {
57 if (sc
.state
== SCE_B_OPERATOR
) {
58 sc
.SetState(SCE_B_DEFAULT
);
59 } else if (sc
.state
== SCE_B_KEYWORD
) {
60 if (!IsAWordChar(sc
.ch
)) {
61 if (vbScriptSyntax
|| !IsTypeCharacter(sc
.ch
)) {
65 sc
.GetCurrentLowered(s
, sizeof(s
));
66 if (keywords
.InList(s
)) {
67 if (strcmp(s
, "rem") == 0) {
68 sc
.ChangeState(SCE_B_COMMENT
);
70 sc
.SetState(SCE_B_DEFAULT
);
73 sc
.SetState(SCE_B_DEFAULT
);
76 sc
.ChangeState(SCE_B_IDENTIFIER
);
77 sc
.SetState(SCE_B_DEFAULT
);
81 } else if (sc
.state
== SCE_B_NUMBER
) {
82 if (!IsAWordChar(sc
.ch
)) {
83 sc
.SetState(SCE_B_DEFAULT
);
85 } else if (sc
.state
== SCE_B_STRING
) {
86 // VB doubles quotes to preserve them, so just end this string
87 // state now as a following quote will start again
89 if (tolower(sc
.chNext
) == 'c') {
92 sc
.ForwardSetState(SCE_B_DEFAULT
);
94 } else if (sc
.state
== SCE_B_COMMENT
) {
96 sc
.SetState(SCE_B_DEFAULT
);
98 } else if (sc
.state
== SCE_B_PREPROCESSOR
) {
100 sc
.SetState(SCE_B_DEFAULT
);
102 } else if (sc
.state
== SCE_B_DATE
) {
103 if (sc
.ch
== '#' || !IsADateCharacter(sc
.chNext
)) {
104 sc
.ForwardSetState(SCE_B_DEFAULT
);
108 if (sc
.state
== SCE_B_DEFAULT
) {
110 sc
.SetState(SCE_B_COMMENT
);
111 } else if (sc
.ch
== '\"') {
112 sc
.SetState(SCE_B_STRING
);
113 } else if (sc
.ch
== '#' && visibleChars
== 0) {
114 // Preprocessor commands are alone on their line
115 sc
.SetState(SCE_B_PREPROCESSOR
);
116 } else if (sc
.ch
== '#') {
119 while ((n
< 100) && (chSeek
== ' ' || chSeek
== '\t')) {
120 chSeek
= sc
.GetRelative(n
);
123 if (IsADigit(chSeek
)) {
124 sc
.SetState(SCE_B_DATE
);
126 sc
.SetState(SCE_B_OPERATOR
);
128 } else if (sc
.ch
== '&' && tolower(sc
.chNext
) == 'h') {
129 sc
.SetState(SCE_B_NUMBER
);
130 } else if (sc
.ch
== '&' && tolower(sc
.chNext
) == 'o') {
131 sc
.SetState(SCE_B_NUMBER
);
132 } else if (IsADigit(sc
.ch
) || (sc
.ch
== '.' && IsADigit(sc
.chNext
))) {
133 sc
.SetState(SCE_B_NUMBER
);
134 } else if (IsAWordStart(sc
.ch
) || (sc
.ch
== '[')) {
135 sc
.SetState(SCE_B_KEYWORD
);
136 } else if (isoperator(static_cast<char>(sc
.ch
)) || (sc
.ch
== '\\')) {
137 sc
.SetState(SCE_B_OPERATOR
);
144 if (!IsASpace(sc
.ch
)) {
151 static void FoldVBDoc(unsigned int startPos
, int length
, int,
152 WordList
*[], Accessor
&styler
) {
153 int endPos
= startPos
+ length
;
155 // Backtrack to previous line in case need to fix its fold status
156 int lineCurrent
= styler
.GetLine(startPos
);
158 if (lineCurrent
> 0) {
160 startPos
= styler
.LineStart(lineCurrent
);
164 int indentCurrent
= styler
.IndentAmount(lineCurrent
, &spaceFlags
, IsVBComment
);
165 char chNext
= styler
[startPos
];
166 for (int i
= startPos
; i
< endPos
; i
++) {
168 chNext
= styler
.SafeGetCharAt(i
+ 1);
170 if ((ch
== '\r' && chNext
!= '\n') || (ch
== '\n') || (i
== endPos
)) {
171 int lev
= indentCurrent
;
172 int indentNext
= styler
.IndentAmount(lineCurrent
+ 1, &spaceFlags
, IsVBComment
);
173 if (!(indentCurrent
& SC_FOLDLEVELWHITEFLAG
)) {
174 // Only non whitespace lines can be headers
175 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext
& SC_FOLDLEVELNUMBERMASK
)) {
176 lev
|= SC_FOLDLEVELHEADERFLAG
;
177 } else if (indentNext
& SC_FOLDLEVELWHITEFLAG
) {
178 // Line after is blank so check the next - maybe should continue further?
180 int indentNext2
= styler
.IndentAmount(lineCurrent
+ 2, &spaceFlags2
, IsVBComment
);
181 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext2
& SC_FOLDLEVELNUMBERMASK
)) {
182 lev
|= SC_FOLDLEVELHEADERFLAG
;
186 indentCurrent
= indentNext
;
187 styler
.SetLevel(lineCurrent
, lev
);
193 static void ColouriseVBNetDoc(unsigned int startPos
, int length
, int initStyle
,
194 WordList
*keywordlists
[], Accessor
&styler
) {
195 ColouriseVBDoc(startPos
, length
, initStyle
, keywordlists
, styler
, false);
198 static void ColouriseVBScriptDoc(unsigned int startPos
, int length
, int initStyle
,
199 WordList
*keywordlists
[], Accessor
&styler
) {
200 ColouriseVBDoc(startPos
, length
, initStyle
, keywordlists
, styler
, true);
203 static const char * const vbWordListDesc
[] = {
208 LexerModule
lmVB(SCLEX_VB
, ColouriseVBNetDoc
, "vb", FoldVBDoc
, vbWordListDesc
);
209 LexerModule
lmVBScript(SCLEX_VBSCRIPT
, ColouriseVBScriptDoc
, "vbscript", FoldVBDoc
, vbWordListDesc
);