Update Scintilla to 4.0.4
[TortoiseGit.git] / ext / scintilla / lexlib / StyleContext.h
blobfc5f07e1638a17ff90a200ea88994d470b8ba17d
1 // Scintilla source code edit control
2 /** @file StyleContext.h
3 ** Lexer infrastructure.
4 **/
5 // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
6 // This file is in the public domain.
8 #ifndef STYLECONTEXT_H
9 #define STYLECONTEXT_H
11 namespace Scintilla {
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
17 class StyleContext {
18 LexAccessor &styler;
19 IDocument *multiByteAccess;
20 Sci_PositionU endPos;
21 Sci_PositionU lengthDocument;
23 // Used for optimizing GetRelativeCharacter
24 Sci_PositionU posRelative;
25 Sci_PositionU currentPosLastRelative;
26 Sci_Position offsetRelative;
28 void GetNextChar() {
29 if (multiByteAccess) {
30 chNext = multiByteAccess->GetCharacterAndWidth(currentPos+width, &widthNext);
31 } else {
32 chNext = static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+width, 0));
33 widthNext = 1;
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);
39 else // Last line
40 atLineEnd = static_cast<Sci_Position>(currentPos) >= lineStartNext;
43 public:
44 Sci_PositionU currentPos;
45 Sci_Position currentLine;
46 Sci_Position lineDocEnd;
47 Sci_Position lineStartNext;
48 bool atLineStart;
49 bool atLineEnd;
50 int state;
51 int chPrev;
52 int ch;
53 Sci_Position width;
54 int chNext;
55 Sci_Position widthNext;
57 StyleContext(Sci_PositionU startPos, Sci_PositionU length,
58 int initStyle, LexAccessor &styler_, char chMask='\377') :
59 styler(styler_),
60 multiByteAccess(0),
61 endPos(startPos + length),
62 posRelative(0),
63 currentPosLastRelative(0x7FFFFFFF),
64 offsetRelative(0),
65 currentPos(startPos),
66 currentLine(-1),
67 lineStartNext(-1),
68 atLineEnd(false),
69 state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
70 chPrev(0),
71 ch(0),
72 width(0),
73 chNext(0),
74 widthNext(1) {
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)
84 endPos++;
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
89 width = 0;
90 GetNextChar();
91 ch = chNext;
92 width = widthNext;
94 GetNextChar();
96 // Deleted so StyleContext objects can not be copied.
97 StyleContext(const StyleContext &) = delete;
98 StyleContext &operator=(const StyleContext &) = delete;
99 void Complete() {
100 styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
101 styler.Flush();
103 bool More() const {
104 return currentPos < endPos;
106 void Forward() {
107 if (currentPos < endPos) {
108 atLineStart = atLineEnd;
109 if (atLineStart) {
110 currentLine++;
111 lineStartNext = styler.LineStart(currentLine+1);
113 chPrev = ch;
114 currentPos += width;
115 ch = chNext;
116 width = widthNext;
117 GetNextChar();
118 } else {
119 atLineStart = false;
120 chPrev = ' ';
121 ch = ' ';
122 chNext = ' ';
123 atLineEnd = true;
126 void Forward(Sci_Position nb) {
127 for (Sci_Position i = 0; i < nb; i++) {
128 Forward();
131 void ForwardBytes(Sci_Position nb) {
132 const Sci_PositionU forwardPos = currentPos + nb;
133 while (forwardPos > currentPos) {
134 const Sci_PositionU currentPosStart = currentPos;
135 Forward();
136 if (currentPos == currentPosStart) {
137 // Reached end
138 return;
142 void ChangeState(int state_) {
143 state = state_;
145 void SetState(int state_) {
146 styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
147 state = state_;
149 void ForwardSetState(int state_) {
150 Forward();
151 styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
152 state = state_;
154 Sci_Position LengthCurrent() const {
155 return currentPos - styler.GetStartSegment();
157 int GetRelative(Sci_Position n) {
158 return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n, 0));
160 int GetRelativeCharacter(Sci_Position n) {
161 if (n == 0)
162 return ch;
163 if (multiByteAccess) {
164 if ((currentPosLastRelative != currentPos) ||
165 ((n > 0) && ((offsetRelative < 0) || (n < offsetRelative))) ||
166 ((n < 0) && ((offsetRelative > 0) || (n > offsetRelative)))) {
167 posRelative = currentPos;
168 offsetRelative = 0;
170 Sci_Position diffRelative = n - offsetRelative;
171 Sci_Position posNew = multiByteAccess->GetRelativePosition(posRelative, diffRelative);
172 const int chReturn = multiByteAccess->GetCharacterAndWidth(posNew, 0);
173 posRelative = posNew;
174 currentPosLastRelative = currentPos;
175 offsetRelative = n;
176 return chReturn;
177 } else {
178 // fast version for single byte encodings
179 return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos + n, 0));
182 bool Match(char ch0) const {
183 return ch == static_cast<unsigned char>(ch0);
185 bool Match(char ch0, char ch1) const {
186 return (ch == static_cast<unsigned char>(ch0)) && (chNext == static_cast<unsigned char>(ch1));
188 bool Match(const char *s) {
189 if (ch != static_cast<unsigned char>(*s))
190 return false;
191 s++;
192 if (!*s)
193 return true;
194 if (chNext != static_cast<unsigned char>(*s))
195 return false;
196 s++;
197 for (int n=2; *s; n++) {
198 if (*s != styler.SafeGetCharAt(currentPos+n, 0))
199 return false;
200 s++;
202 return true;
204 // Non-inline
205 bool MatchIgnoreCase(const char *s);
206 void GetCurrent(char *s, Sci_PositionU len);
207 void GetCurrentLowered(char *s, Sci_PositionU len);
212 #endif