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.
13 // All languages handled so far can treat all characters >= 0x80 as one class
14 // which just continues the current token or starts an identifier if in default.
15 // DBCS treated specially as the second character can be < 0x80 and hence
16 // syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80
19 IDocument
*multiByteAccess
;
21 Sci_PositionU lengthDocument
;
23 // Used for optimizing GetRelativeCharacter
24 Sci_PositionU posRelative
;
25 Sci_PositionU currentPosLastRelative
;
26 Sci_Position offsetRelative
;
29 if (multiByteAccess
) {
30 chNext
= multiByteAccess
->GetCharacterAndWidth(currentPos
+width
, &widthNext
);
32 chNext
= static_cast<unsigned char>(styler
.SafeGetCharAt(currentPos
+width
, 0));
35 // End of line determined from line end position, allowing CR, LF,
36 // CRLF and Unicode line ends as set by document.
37 if (currentLine
< lineDocEnd
)
38 atLineEnd
= static_cast<Sci_Position
>(currentPos
) >= (lineStartNext
-1);
40 atLineEnd
= static_cast<Sci_Position
>(currentPos
) >= lineStartNext
;
44 Sci_PositionU currentPos
;
45 Sci_Position currentLine
;
46 Sci_Position lineDocEnd
;
47 Sci_Position lineStartNext
;
55 Sci_Position widthNext
;
57 StyleContext(Sci_PositionU startPos
, Sci_PositionU length
,
58 int initStyle
, LexAccessor
&styler_
, char chMask
='\377') :
61 endPos(startPos
+ length
),
63 currentPosLastRelative(0x7FFFFFFF),
69 state(initStyle
& chMask
), // Mask off all bits which aren't in the chMask.
75 if (styler
.Encoding() != enc8bit
) {
76 multiByteAccess
= styler
.MultiByteAccess();
78 styler
.StartAt(startPos
/*, chMask*/);
79 styler
.StartSegment(startPos
);
80 currentLine
= styler
.GetLine(startPos
);
81 lineStartNext
= styler
.LineStart(currentLine
+1);
82 lengthDocument
= static_cast<Sci_PositionU
>(styler
.Length());
83 if (endPos
== lengthDocument
)
85 lineDocEnd
= styler
.GetLine(lengthDocument
);
86 atLineStart
= static_cast<Sci_PositionU
>(styler
.LineStart(currentLine
)) == startPos
;
88 // Variable width is now 0 so GetNextChar gets the char at currentPos into chNext/widthNext
96 // Deleted so StyleContext objects can not be copied.
97 StyleContext(const StyleContext
&) = delete;
98 StyleContext
&operator=(const StyleContext
&) = delete;
100 styler
.ColourTo(currentPos
- ((currentPos
> lengthDocument
) ? 2 : 1), state
);
104 return currentPos
< endPos
;
107 if (currentPos
< endPos
) {
108 atLineStart
= atLineEnd
;
111 lineStartNext
= styler
.LineStart(currentLine
+1);
126 void Forward(Sci_Position nb
) {
127 for (Sci_Position i
= 0; i
< nb
; i
++) {
131 void ForwardBytes(Sci_Position nb
) {
132 const Sci_PositionU forwardPos
= currentPos
+ nb
;
133 while (forwardPos
> currentPos
) {
137 void ChangeState(int state_
) {
140 void SetState(int state_
) {
141 styler
.ColourTo(currentPos
- ((currentPos
> lengthDocument
) ? 2 : 1), state
);
144 void ForwardSetState(int state_
) {
146 styler
.ColourTo(currentPos
- ((currentPos
> lengthDocument
) ? 2 : 1), state
);
149 Sci_Position
LengthCurrent() const {
150 return currentPos
- styler
.GetStartSegment();
152 int GetRelative(Sci_Position n
) {
153 return static_cast<unsigned char>(styler
.SafeGetCharAt(currentPos
+n
, 0));
155 int GetRelativeCharacter(Sci_Position n
) {
158 if (multiByteAccess
) {
159 if ((currentPosLastRelative
!= currentPos
) ||
160 ((n
> 0) && ((offsetRelative
< 0) || (n
< offsetRelative
))) ||
161 ((n
< 0) && ((offsetRelative
> 0) || (n
> offsetRelative
)))) {
162 posRelative
= currentPos
;
165 Sci_Position diffRelative
= n
- offsetRelative
;
166 Sci_Position posNew
= multiByteAccess
->GetRelativePosition(posRelative
, diffRelative
);
167 const int chReturn
= multiByteAccess
->GetCharacterAndWidth(posNew
, 0);
168 posRelative
= posNew
;
169 currentPosLastRelative
= currentPos
;
173 // fast version for single byte encodings
174 return static_cast<unsigned char>(styler
.SafeGetCharAt(currentPos
+ n
, 0));
177 bool Match(char ch0
) const {
178 return ch
== static_cast<unsigned char>(ch0
);
180 bool Match(char ch0
, char ch1
) const {
181 return (ch
== static_cast<unsigned char>(ch0
)) && (chNext
== static_cast<unsigned char>(ch1
));
183 bool Match(const char *s
) {
184 if (ch
!= static_cast<unsigned char>(*s
))
189 if (chNext
!= static_cast<unsigned char>(*s
))
192 for (int n
=2; *s
; n
++) {
193 if (*s
!= styler
.SafeGetCharAt(currentPos
+n
, 0))
200 bool MatchIgnoreCase(const char *s
);
201 void GetCurrent(char *s
, Sci_PositionU len
);
202 void GetCurrentLowered(char *s
, Sci_PositionU len
);