xref: /MusicPlayer2/scintilla/lexlib/StyleContext.h (revision 8af74909132ed5e696cb05b6689ae4baf14c1c96)
1*8af74909SZhong Yang // Scintilla source code edit control
2*8af74909SZhong Yang /** @file StyleContext.h
3*8af74909SZhong Yang  ** Lexer infrastructure.
4*8af74909SZhong Yang  **/
5*8af74909SZhong Yang // Copyright 1998-2004 by Neil Hodgson <[email protected]>
6*8af74909SZhong Yang // This file is in the public domain.
7*8af74909SZhong Yang 
8*8af74909SZhong Yang #ifndef STYLECONTEXT_H
9*8af74909SZhong Yang #define STYLECONTEXT_H
10*8af74909SZhong Yang 
11*8af74909SZhong Yang namespace Scintilla {
12*8af74909SZhong Yang 
13*8af74909SZhong Yang // All languages handled so far can treat all characters >= 0x80 as one class
14*8af74909SZhong Yang // which just continues the current token or starts an identifier if in default.
15*8af74909SZhong Yang // DBCS treated specially as the second character can be < 0x80 and hence
16*8af74909SZhong Yang // syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80
17*8af74909SZhong Yang class StyleContext {
18*8af74909SZhong Yang 	LexAccessor &styler;
19*8af74909SZhong Yang 	IDocument *multiByteAccess;
20*8af74909SZhong Yang 	Sci_PositionU endPos;
21*8af74909SZhong Yang 	Sci_PositionU lengthDocument;
22*8af74909SZhong Yang 
23*8af74909SZhong Yang 	// Used for optimizing GetRelativeCharacter
24*8af74909SZhong Yang 	Sci_PositionU posRelative;
25*8af74909SZhong Yang 	Sci_PositionU currentPosLastRelative;
26*8af74909SZhong Yang 	Sci_Position offsetRelative;
27*8af74909SZhong Yang 
GetNextChar()28*8af74909SZhong Yang 	void GetNextChar() {
29*8af74909SZhong Yang 		if (multiByteAccess) {
30*8af74909SZhong Yang 			chNext = multiByteAccess->GetCharacterAndWidth(currentPos+width, &widthNext);
31*8af74909SZhong Yang 		} else {
32*8af74909SZhong Yang 			chNext = static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+width, 0));
33*8af74909SZhong Yang 			widthNext = 1;
34*8af74909SZhong Yang 		}
35*8af74909SZhong Yang 		// End of line determined from line end position, allowing CR, LF,
36*8af74909SZhong Yang 		// CRLF and Unicode line ends as set by document.
37*8af74909SZhong Yang 		if (currentLine < lineDocEnd)
38*8af74909SZhong Yang 			atLineEnd = static_cast<Sci_Position>(currentPos) >= (lineStartNext-1);
39*8af74909SZhong Yang 		else // Last line
40*8af74909SZhong Yang 			atLineEnd = static_cast<Sci_Position>(currentPos) >= lineStartNext;
41*8af74909SZhong Yang 	}
42*8af74909SZhong Yang 
43*8af74909SZhong Yang public:
44*8af74909SZhong Yang 	Sci_PositionU currentPos;
45*8af74909SZhong Yang 	Sci_Position currentLine;
46*8af74909SZhong Yang 	Sci_Position lineDocEnd;
47*8af74909SZhong Yang 	Sci_Position lineStartNext;
48*8af74909SZhong Yang 	bool atLineStart;
49*8af74909SZhong Yang 	bool atLineEnd;
50*8af74909SZhong Yang 	int state;
51*8af74909SZhong Yang 	int chPrev;
52*8af74909SZhong Yang 	int ch;
53*8af74909SZhong Yang 	Sci_Position width;
54*8af74909SZhong Yang 	int chNext;
55*8af74909SZhong Yang 	Sci_Position widthNext;
56*8af74909SZhong Yang 
57*8af74909SZhong Yang 	StyleContext(Sci_PositionU startPos, Sci_PositionU length,
58*8af74909SZhong Yang                         int initStyle, LexAccessor &styler_, char chMask='\377') :
styler(styler_)59*8af74909SZhong Yang 		styler(styler_),
60*8af74909SZhong Yang 		multiByteAccess(nullptr),
61*8af74909SZhong Yang 		endPos(startPos + length),
62*8af74909SZhong Yang 		posRelative(0),
63*8af74909SZhong Yang 		currentPosLastRelative(0x7FFFFFFF),
64*8af74909SZhong Yang 		offsetRelative(0),
65*8af74909SZhong Yang 		currentPos(startPos),
66*8af74909SZhong Yang 		currentLine(-1),
67*8af74909SZhong Yang 		lineStartNext(-1),
68*8af74909SZhong Yang 		atLineEnd(false),
69*8af74909SZhong Yang 		state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
70*8af74909SZhong Yang 		chPrev(0),
71*8af74909SZhong Yang 		ch(0),
72*8af74909SZhong Yang 		width(0),
73*8af74909SZhong Yang 		chNext(0),
74*8af74909SZhong Yang 		widthNext(1) {
75*8af74909SZhong Yang 		if (styler.Encoding() != EncodingType::eightBit) {
76*8af74909SZhong Yang 			multiByteAccess = styler.MultiByteAccess();
77*8af74909SZhong Yang 		}
78*8af74909SZhong Yang 		styler.StartAt(startPos /*, chMask*/);
79*8af74909SZhong Yang 		styler.StartSegment(startPos);
80*8af74909SZhong Yang 		currentLine = styler.GetLine(startPos);
81*8af74909SZhong Yang 		lineStartNext = styler.LineStart(currentLine+1);
82*8af74909SZhong Yang 		lengthDocument = static_cast<Sci_PositionU>(styler.Length());
83*8af74909SZhong Yang 		if (endPos == lengthDocument)
84*8af74909SZhong Yang 			endPos++;
85*8af74909SZhong Yang 		lineDocEnd = styler.GetLine(lengthDocument);
86*8af74909SZhong Yang 		atLineStart = static_cast<Sci_PositionU>(styler.LineStart(currentLine)) == startPos;
87*8af74909SZhong Yang 
88*8af74909SZhong Yang 		// Variable width is now 0 so GetNextChar gets the char at currentPos into chNext/widthNext
89*8af74909SZhong Yang 		width = 0;
90*8af74909SZhong Yang 		GetNextChar();
91*8af74909SZhong Yang 		ch = chNext;
92*8af74909SZhong Yang 		width = widthNext;
93*8af74909SZhong Yang 
94*8af74909SZhong Yang 		GetNextChar();
95*8af74909SZhong Yang 	}
96*8af74909SZhong Yang 	// Deleted so StyleContext objects can not be copied.
97*8af74909SZhong Yang 	StyleContext(const StyleContext &) = delete;
98*8af74909SZhong Yang 	StyleContext &operator=(const StyleContext &) = delete;
Complete()99*8af74909SZhong Yang 	void Complete() {
100*8af74909SZhong Yang 		styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
101*8af74909SZhong Yang 		styler.Flush();
102*8af74909SZhong Yang 	}
More()103*8af74909SZhong Yang 	bool More() const noexcept {
104*8af74909SZhong Yang 		return currentPos < endPos;
105*8af74909SZhong Yang 	}
Forward()106*8af74909SZhong Yang 	void Forward() {
107*8af74909SZhong Yang 		if (currentPos < endPos) {
108*8af74909SZhong Yang 			atLineStart = atLineEnd;
109*8af74909SZhong Yang 			if (atLineStart) {
110*8af74909SZhong Yang 				currentLine++;
111*8af74909SZhong Yang 				lineStartNext = styler.LineStart(currentLine+1);
112*8af74909SZhong Yang 			}
113*8af74909SZhong Yang 			chPrev = ch;
114*8af74909SZhong Yang 			currentPos += width;
115*8af74909SZhong Yang 			ch = chNext;
116*8af74909SZhong Yang 			width = widthNext;
117*8af74909SZhong Yang 			GetNextChar();
118*8af74909SZhong Yang 		} else {
119*8af74909SZhong Yang 			atLineStart = false;
120*8af74909SZhong Yang 			chPrev = ' ';
121*8af74909SZhong Yang 			ch = ' ';
122*8af74909SZhong Yang 			chNext = ' ';
123*8af74909SZhong Yang 			atLineEnd = true;
124*8af74909SZhong Yang 		}
125*8af74909SZhong Yang 	}
Forward(Sci_Position nb)126*8af74909SZhong Yang 	void Forward(Sci_Position nb) {
127*8af74909SZhong Yang 		for (Sci_Position i = 0; i < nb; i++) {
128*8af74909SZhong Yang 			Forward();
129*8af74909SZhong Yang 		}
130*8af74909SZhong Yang 	}
ForwardBytes(Sci_Position nb)131*8af74909SZhong Yang 	void ForwardBytes(Sci_Position nb) {
132*8af74909SZhong Yang 		const Sci_PositionU forwardPos = currentPos + nb;
133*8af74909SZhong Yang 		while (forwardPos > currentPos) {
134*8af74909SZhong Yang 			const Sci_PositionU currentPosStart = currentPos;
135*8af74909SZhong Yang 			Forward();
136*8af74909SZhong Yang 			if (currentPos == currentPosStart) {
137*8af74909SZhong Yang 				// Reached end
138*8af74909SZhong Yang 				return;
139*8af74909SZhong Yang 			}
140*8af74909SZhong Yang 		}
141*8af74909SZhong Yang 	}
ChangeState(int state_)142*8af74909SZhong Yang 	void ChangeState(int state_) noexcept {
143*8af74909SZhong Yang 		state = state_;
144*8af74909SZhong Yang 	}
SetState(int state_)145*8af74909SZhong Yang 	void SetState(int state_) {
146*8af74909SZhong Yang 		styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
147*8af74909SZhong Yang 		state = state_;
148*8af74909SZhong Yang 	}
ForwardSetState(int state_)149*8af74909SZhong Yang 	void ForwardSetState(int state_) {
150*8af74909SZhong Yang 		Forward();
151*8af74909SZhong Yang 		styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
152*8af74909SZhong Yang 		state = state_;
153*8af74909SZhong Yang 	}
LengthCurrent()154*8af74909SZhong Yang 	Sci_Position LengthCurrent() const {
155*8af74909SZhong Yang 		return currentPos - styler.GetStartSegment();
156*8af74909SZhong Yang 	}
157*8af74909SZhong Yang 	int GetRelative(Sci_Position n, char chDefault='\0') {
158*8af74909SZhong Yang 		return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n, chDefault));
159*8af74909SZhong Yang 	}
GetRelativeCharacter(Sci_Position n)160*8af74909SZhong Yang 	int GetRelativeCharacter(Sci_Position n) {
161*8af74909SZhong Yang 		if (n == 0)
162*8af74909SZhong Yang 			return ch;
163*8af74909SZhong Yang 		if (multiByteAccess) {
164*8af74909SZhong Yang 			if ((currentPosLastRelative != currentPos) ||
165*8af74909SZhong Yang 				((n > 0) && ((offsetRelative < 0) || (n < offsetRelative))) ||
166*8af74909SZhong Yang 				((n < 0) && ((offsetRelative > 0) || (n > offsetRelative)))) {
167*8af74909SZhong Yang 				posRelative = currentPos;
168*8af74909SZhong Yang 				offsetRelative = 0;
169*8af74909SZhong Yang 			}
170*8af74909SZhong Yang 			const Sci_Position diffRelative = n - offsetRelative;
171*8af74909SZhong Yang 			const Sci_Position posNew = multiByteAccess->GetRelativePosition(posRelative, diffRelative);
172*8af74909SZhong Yang 			const int chReturn = multiByteAccess->GetCharacterAndWidth(posNew, nullptr);
173*8af74909SZhong Yang 			posRelative = posNew;
174*8af74909SZhong Yang 			currentPosLastRelative = currentPos;
175*8af74909SZhong Yang 			offsetRelative = n;
176*8af74909SZhong Yang 			return chReturn;
177*8af74909SZhong Yang 		} else {
178*8af74909SZhong Yang 			// fast version for single byte encodings
179*8af74909SZhong Yang 			return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos + n, 0));
180*8af74909SZhong Yang 		}
181*8af74909SZhong Yang 	}
Match(char ch0)182*8af74909SZhong Yang 	bool Match(char ch0) const {
183*8af74909SZhong Yang 		return ch == static_cast<unsigned char>(ch0);
184*8af74909SZhong Yang 	}
Match(char ch0,char ch1)185*8af74909SZhong Yang 	bool Match(char ch0, char ch1) const {
186*8af74909SZhong Yang 		return (ch == static_cast<unsigned char>(ch0)) && (chNext == static_cast<unsigned char>(ch1));
187*8af74909SZhong Yang 	}
Match(const char * s)188*8af74909SZhong Yang 	bool Match(const char *s) {
189*8af74909SZhong Yang 		if (ch != static_cast<unsigned char>(*s))
190*8af74909SZhong Yang 			return false;
191*8af74909SZhong Yang 		s++;
192*8af74909SZhong Yang 		if (!*s)
193*8af74909SZhong Yang 			return true;
194*8af74909SZhong Yang 		if (chNext != static_cast<unsigned char>(*s))
195*8af74909SZhong Yang 			return false;
196*8af74909SZhong Yang 		s++;
197*8af74909SZhong Yang 		for (int n=2; *s; n++) {
198*8af74909SZhong Yang 			if (*s != styler.SafeGetCharAt(currentPos+n, 0))
199*8af74909SZhong Yang 				return false;
200*8af74909SZhong Yang 			s++;
201*8af74909SZhong Yang 		}
202*8af74909SZhong Yang 		return true;
203*8af74909SZhong Yang 	}
204*8af74909SZhong Yang 	// Non-inline
205*8af74909SZhong Yang 	bool MatchIgnoreCase(const char *s);
206*8af74909SZhong Yang 	void GetCurrent(char *s, Sci_PositionU len);
207*8af74909SZhong Yang 	void GetCurrentLowered(char *s, Sci_PositionU len);
208*8af74909SZhong Yang };
209*8af74909SZhong Yang 
210*8af74909SZhong Yang }
211*8af74909SZhong Yang 
212*8af74909SZhong Yang #endif
213