Recognize .exp (Expect) files as Tcl
[geany-mirror.git] / scintilla / lexlib / StyleContext.h
blobc8aa4ab020e78de6a17c22fd6b2fa4046b408539
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 #ifdef SCI_NAMESPACE
12 namespace Scintilla {
13 #endif
15 static inline int MakeLowerCase(int ch) {
16 if (ch < 'A' || ch > 'Z')
17 return ch;
18 else
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
26 class StyleContext {
27 LexAccessor &styler;
28 IDocumentWithLineEnd *multiByteAccess;
29 Sci_PositionU endPos;
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 &);
39 void GetNextChar() {
40 if (multiByteAccess) {
41 chNext = multiByteAccess->GetCharacterAndWidth(currentPos+width, &widthNext);
42 } else {
43 chNext = static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+width, 0));
44 widthNext = 1;
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);
50 else // Last line
51 atLineEnd = static_cast<Sci_Position>(currentPos) >= lineStartNext;
54 public:
55 Sci_PositionU currentPos;
56 Sci_Position currentLine;
57 Sci_Position lineDocEnd;
58 Sci_Position lineStartNext;
59 bool atLineStart;
60 bool atLineEnd;
61 int state;
62 int chPrev;
63 int ch;
64 Sci_Position width;
65 int chNext;
66 Sci_Position widthNext;
68 StyleContext(Sci_PositionU startPos, Sci_PositionU length,
69 int initStyle, LexAccessor &styler_, char chMask='\377') :
70 styler(styler_),
71 multiByteAccess(0),
72 endPos(startPos + length),
73 posRelative(0),
74 currentPosLastRelative(0x7FFFFFFF),
75 offsetRelative(0),
76 currentPos(startPos),
77 currentLine(-1),
78 lineStartNext(-1),
79 atLineEnd(false),
80 state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
81 chPrev(0),
82 ch(0),
83 width(0),
84 chNext(0),
85 widthNext(1) {
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)
95 endPos++;
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
100 width = 0;
101 GetNextChar();
102 ch = chNext;
103 width = widthNext;
105 GetNextChar();
107 void Complete() {
108 styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
109 styler.Flush();
111 bool More() const {
112 return currentPos < endPos;
114 void Forward() {
115 if (currentPos < endPos) {
116 atLineStart = atLineEnd;
117 if (atLineStart) {
118 currentLine++;
119 lineStartNext = styler.LineStart(currentLine+1);
121 chPrev = ch;
122 currentPos += width;
123 ch = chNext;
124 width = widthNext;
125 GetNextChar();
126 } else {
127 atLineStart = false;
128 chPrev = ' ';
129 ch = ' ';
130 chNext = ' ';
131 atLineEnd = true;
134 void Forward(Sci_Position nb) {
135 for (Sci_Position i = 0; i < nb; i++) {
136 Forward();
139 void ForwardBytes(Sci_Position nb) {
140 Sci_PositionU forwardPos = currentPos + nb;
141 while (forwardPos > currentPos) {
142 Forward();
145 void ChangeState(int state_) {
146 state = state_;
148 void SetState(int state_) {
149 styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
150 state = state_;
152 void ForwardSetState(int state_) {
153 Forward();
154 styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
155 state = 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) {
164 if (n == 0)
165 return ch;
166 if (multiByteAccess) {
167 if ((currentPosLastRelative != currentPos) ||
168 ((n > 0) && ((offsetRelative < 0) || (n < offsetRelative))) ||
169 ((n < 0) && ((offsetRelative > 0) || (n > offsetRelative)))) {
170 posRelative = currentPos;
171 offsetRelative = 0;
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;
178 offsetRelative = n;
179 return chReturn;
180 } else {
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))
193 return false;
194 s++;
195 if (!*s)
196 return true;
197 if (chNext != static_cast<unsigned char>(*s))
198 return false;
199 s++;
200 for (int n=2; *s; n++) {
201 if (*s != styler.SafeGetCharAt(currentPos+n, 0))
202 return false;
203 s++;
205 return true;
207 bool MatchIgnoreCase(const char *s) {
208 if (MakeLowerCase(ch) != static_cast<unsigned char>(*s))
209 return false;
210 s++;
211 if (MakeLowerCase(chNext) != static_cast<unsigned char>(*s))
212 return false;
213 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))))
217 return false;
218 s++;
220 return true;
222 // Non-inline
223 void GetCurrent(char *s, Sci_PositionU len);
224 void GetCurrentLowered(char *s, Sci_PositionU len);
227 #ifdef SCI_NAMESPACE
229 #endif
231 #endif