1 // Scintilla source code edit control
2 /** @file StyleContext.h
3 ** Lexer infrastructure.
5 // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
6 // This file is in the public domain.
15 static inline int MakeLowerCase(int ch
) {
16 if (ch
< 'A' || ch
> 'Z')
19 return ch
- 'A' + 'a';
22 // All languages handled so far can treat all characters >= 0x80 as one class
23 // which just continues the current token or starts an identifier if in default.
24 // DBCS treated specially as the second character can be < 0x80 and hence
25 // syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80
28 IDocumentWithLineEnd
*multiByteAccess
;
30 Sci_PositionU lengthDocument
;
32 // Used for optimizing GetRelativeCharacter
33 Sci_PositionU posRelative
;
34 Sci_PositionU currentPosLastRelative
;
35 Sci_Position offsetRelative
;
37 StyleContext
&operator=(const StyleContext
&);
40 if (multiByteAccess
) {
41 chNext
= multiByteAccess
->GetCharacterAndWidth(currentPos
+width
, &widthNext
);
43 chNext
= static_cast<unsigned char>(styler
.SafeGetCharAt(currentPos
+width
, 0));
46 // End of line determined from line end position, allowing CR, LF,
47 // CRLF and Unicode line ends as set by document.
48 if (currentLine
< lineDocEnd
)
49 atLineEnd
= static_cast<Sci_Position
>(currentPos
) >= (lineStartNext
-1);
51 atLineEnd
= static_cast<Sci_Position
>(currentPos
) >= lineStartNext
;
55 Sci_PositionU currentPos
;
56 Sci_Position currentLine
;
57 Sci_Position lineDocEnd
;
58 Sci_Position lineStartNext
;
66 Sci_Position widthNext
;
68 StyleContext(Sci_PositionU startPos
, Sci_PositionU length
,
69 int initStyle
, LexAccessor
&styler_
, char chMask
='\377') :
72 endPos(startPos
+ length
),
74 currentPosLastRelative(0x7FFFFFFF),
80 state(initStyle
& chMask
), // Mask off all bits which aren't in the chMask.
86 if (styler
.Encoding() != enc8bit
) {
87 multiByteAccess
= styler
.MultiByteAccess();
89 styler
.StartAt(startPos
/*, chMask*/);
90 styler
.StartSegment(startPos
);
91 currentLine
= styler
.GetLine(startPos
);
92 lineStartNext
= styler
.LineStart(currentLine
+1);
93 lengthDocument
= static_cast<Sci_PositionU
>(styler
.Length());
94 if (endPos
== lengthDocument
)
96 lineDocEnd
= styler
.GetLine(lengthDocument
);
97 atLineStart
= static_cast<Sci_PositionU
>(styler
.LineStart(currentLine
)) == startPos
;
99 // Variable width is now 0 so GetNextChar gets the char at currentPos into chNext/widthNext
108 styler
.ColourTo(currentPos
- ((currentPos
> lengthDocument
) ? 2 : 1), state
);
112 return currentPos
< endPos
;
115 if (currentPos
< endPos
) {
116 atLineStart
= atLineEnd
;
119 lineStartNext
= styler
.LineStart(currentLine
+1);
134 void Forward(Sci_Position nb
) {
135 for (Sci_Position i
= 0; i
< nb
; i
++) {
139 void ForwardBytes(Sci_Position nb
) {
140 Sci_PositionU forwardPos
= currentPos
+ nb
;
141 while (forwardPos
> currentPos
) {
145 void ChangeState(int state_
) {
148 void SetState(int state_
) {
149 styler
.ColourTo(currentPos
- ((currentPos
> lengthDocument
) ? 2 : 1), state
);
152 void ForwardSetState(int state_
) {
154 styler
.ColourTo(currentPos
- ((currentPos
> lengthDocument
) ? 2 : 1), state
);
157 Sci_Position
LengthCurrent() const {
158 return currentPos
- styler
.GetStartSegment();
160 int GetRelative(Sci_Position n
) {
161 return static_cast<unsigned char>(styler
.SafeGetCharAt(currentPos
+n
, 0));
163 int GetRelativeCharacter(Sci_Position n
) {
166 if (multiByteAccess
) {
167 if ((currentPosLastRelative
!= currentPos
) ||
168 ((n
> 0) && ((offsetRelative
< 0) || (n
< offsetRelative
))) ||
169 ((n
< 0) && ((offsetRelative
> 0) || (n
> offsetRelative
)))) {
170 posRelative
= currentPos
;
173 Sci_Position diffRelative
= n
- offsetRelative
;
174 Sci_Position posNew
= multiByteAccess
->GetRelativePosition(posRelative
, diffRelative
);
175 int chReturn
= multiByteAccess
->GetCharacterAndWidth(posNew
, 0);
176 posRelative
= posNew
;
177 currentPosLastRelative
= currentPos
;
181 // fast version for single byte encodings
182 return static_cast<unsigned char>(styler
.SafeGetCharAt(currentPos
+ n
, 0));
185 bool Match(char ch0
) const {
186 return ch
== static_cast<unsigned char>(ch0
);
188 bool Match(char ch0
, char ch1
) const {
189 return (ch
== static_cast<unsigned char>(ch0
)) && (chNext
== static_cast<unsigned char>(ch1
));
191 bool Match(const char *s
) {
192 if (ch
!= static_cast<unsigned char>(*s
))
197 if (chNext
!= static_cast<unsigned char>(*s
))
200 for (int n
=2; *s
; n
++) {
201 if (*s
!= styler
.SafeGetCharAt(currentPos
+n
, 0))
207 bool MatchIgnoreCase(const char *s
) {
208 if (MakeLowerCase(ch
) != static_cast<unsigned char>(*s
))
211 if (MakeLowerCase(chNext
) != static_cast<unsigned char>(*s
))
214 for (int n
=2; *s
; n
++) {
215 if (static_cast<unsigned char>(*s
) !=
216 MakeLowerCase(static_cast<unsigned char>(styler
.SafeGetCharAt(currentPos
+n
, 0))))
223 void GetCurrent(char *s
, Sci_PositionU len
);
224 void GetCurrentLowered(char *s
, Sci_PositionU len
);