]>
Commit | Line | Data |
---|---|---|
b8b0e402 RD |
1 | // Scintilla source code edit control |
2 | /** @file StyleContext.cxx | |
3 | ** Lexer infrastructure. | |
4 | **/ | |
5 | // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> | |
6 | // This file is in the public domain. | |
7 | ||
8 | // All languages handled so far can treat all characters >= 0x80 as one class | |
9 | // which just continues the current token or starts an identifier if in default. | |
10 | // DBCS treated specially as the second character can be < 0x80 and hence | |
11 | // syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80 | |
12 | class StyleContext { | |
13 | Accessor &styler; | |
14 | int endPos; | |
15 | StyleContext& operator=(const StyleContext&) { | |
16 | return *this; | |
17 | } | |
18 | public: | |
19 | int currentPos; | |
20 | bool atLineStart; | |
21 | bool atLineEnd; | |
22 | int state; | |
23 | int chPrev; | |
24 | int ch; | |
25 | int chNext; | |
26 | ||
27 | StyleContext(unsigned int startPos, int length, | |
28 | int initStyle, Accessor &styler_, char chMask=31) : | |
29 | styler(styler_), | |
30 | endPos(startPos + length), | |
31 | currentPos(startPos), | |
32 | atLineStart(true), | |
33 | atLineEnd(false), | |
34 | state(initStyle), | |
35 | chPrev(0), | |
36 | ch(0), | |
37 | chNext(0) { | |
38 | styler.StartAt(startPos, chMask); | |
39 | styler.StartSegment(startPos); | |
40 | int pos = currentPos; | |
41 | ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos)); | |
42 | if (styler.IsLeadByte(static_cast<char>(ch))) { | |
43 | pos++; | |
44 | ch = ch << 8; | |
45 | ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos)); | |
46 | } | |
47 | chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1)); | |
48 | if (styler.IsLeadByte(static_cast<char>(chNext))) { | |
49 | chNext = chNext << 8; | |
50 | chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2)); | |
51 | } | |
52 | atLineEnd = (ch == '\r' && chNext != '\n') || (ch == '\n') || (currentPos >= endPos); | |
53 | } | |
54 | void Complete() { | |
55 | styler.ColourTo(currentPos - 1, state); | |
56 | } | |
57 | bool More() { | |
58 | return currentPos <= endPos; | |
59 | } | |
60 | void Forward() { | |
61 | atLineStart = atLineEnd; | |
62 | // A lot of this is repeated from the constructor - TODO: merge code | |
63 | chPrev = ch; | |
64 | currentPos++; | |
65 | if (ch >= 0x100) | |
66 | currentPos++; | |
67 | ch = chNext; | |
68 | chNext = static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+1)); | |
69 | if (styler.IsLeadByte(static_cast<char>(chNext))) { | |
70 | chNext = chNext << 8; | |
71 | chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(currentPos + 2)); | |
72 | } | |
73 | // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) | |
74 | // Avoid triggering two times on Dos/Win | |
75 | // End of line | |
76 | atLineEnd = (ch == '\r' && chNext != '\n') || (ch == '\n') || (currentPos >= endPos); | |
77 | } | |
78 | void ChangeState(int state_) { | |
79 | state = state_; | |
80 | } | |
81 | void SetState(int state_) { | |
82 | styler.ColourTo(currentPos - 1, state); | |
83 | state = state_; | |
84 | } | |
85 | void ForwardSetState(int state_) { | |
86 | Forward(); | |
87 | styler.ColourTo(currentPos - 1, state); | |
88 | state = state_; | |
89 | } | |
90 | int LengthCurrent() { | |
91 | return currentPos - styler.GetStartSegment(); | |
92 | } | |
93 | int GetRelative(int n) { | |
94 | return styler.SafeGetCharAt(currentPos+n); | |
95 | } | |
96 | bool Match(char ch0) { | |
97 | return ch == ch0; | |
98 | } | |
99 | bool Match(char ch0, char ch1) { | |
100 | return (ch == ch0) && (chNext == ch1); | |
101 | } | |
102 | bool Match(const char *s) { | |
103 | if (ch != *s) | |
104 | return false; | |
105 | s++; | |
106 | if (chNext != *s) | |
107 | return false; | |
108 | s++; | |
109 | for (int n=2; *s; n++) { | |
110 | if (*s != styler.SafeGetCharAt(currentPos+n)) | |
111 | return false; | |
112 | s++; | |
113 | } | |
114 | return true; | |
115 | } | |
116 | // Non-inline | |
117 | void GetCurrent(char *s, int len); | |
118 | void GetCurrentLowered(char *s, int len); | |
119 | }; | |
120 | ||
121 | inline bool IsASpace(unsigned int ch) { | |
122 | return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); | |
123 | } | |
124 | ||
125 | inline bool IsADigit(unsigned int ch) { | |
126 | return (ch >= '0') && (ch <= '9'); | |
127 | } |