1*8af74909SZhong Yang // Scintilla source code edit control 2*8af74909SZhong Yang /** @file LexAccessor.h 3*8af74909SZhong Yang ** Interfaces between Scintilla and lexers. 4*8af74909SZhong Yang **/ 5*8af74909SZhong Yang // Copyright 1998-2010 by Neil Hodgson <[email protected]> 6*8af74909SZhong Yang // The License.txt file describes the conditions under which this software may be distributed. 7*8af74909SZhong Yang 8*8af74909SZhong Yang #ifndef LEXACCESSOR_H 9*8af74909SZhong Yang #define LEXACCESSOR_H 10*8af74909SZhong Yang 11*8af74909SZhong Yang namespace Scintilla { 12*8af74909SZhong Yang 13*8af74909SZhong Yang enum class EncodingType { eightBit, unicode, dbcs }; 14*8af74909SZhong Yang 15*8af74909SZhong Yang class LexAccessor { 16*8af74909SZhong Yang private: 17*8af74909SZhong Yang IDocument *pAccess; 18*8af74909SZhong Yang enum {extremePosition=0x7FFFFFFF}; 19*8af74909SZhong Yang /** @a bufferSize is a trade off between time taken to copy the characters 20*8af74909SZhong Yang * and retrieval overhead. 21*8af74909SZhong Yang * @a slopSize positions the buffer before the desired position 22*8af74909SZhong Yang * in case there is some backtracking. */ 23*8af74909SZhong Yang enum {bufferSize=4000, slopSize=bufferSize/8}; 24*8af74909SZhong Yang char buf[bufferSize+1]; 25*8af74909SZhong Yang Sci_Position startPos; 26*8af74909SZhong Yang Sci_Position endPos; 27*8af74909SZhong Yang int codePage; 28*8af74909SZhong Yang enum EncodingType encodingType; 29*8af74909SZhong Yang Sci_Position lenDoc; 30*8af74909SZhong Yang char styleBuf[bufferSize]; 31*8af74909SZhong Yang Sci_Position validLen; 32*8af74909SZhong Yang Sci_PositionU startSeg; 33*8af74909SZhong Yang Sci_Position startPosStyling; 34*8af74909SZhong Yang int documentVersion; 35*8af74909SZhong Yang Fill(Sci_Position position)36*8af74909SZhong Yang void Fill(Sci_Position position) { 37*8af74909SZhong Yang startPos = position - slopSize; 38*8af74909SZhong Yang if (startPos + bufferSize > lenDoc) 39*8af74909SZhong Yang startPos = lenDoc - bufferSize; 40*8af74909SZhong Yang if (startPos < 0) 41*8af74909SZhong Yang startPos = 0; 42*8af74909SZhong Yang endPos = startPos + bufferSize; 43*8af74909SZhong Yang if (endPos > lenDoc) 44*8af74909SZhong Yang endPos = lenDoc; 45*8af74909SZhong Yang 46*8af74909SZhong Yang pAccess->GetCharRange(buf, startPos, endPos-startPos); 47*8af74909SZhong Yang buf[endPos-startPos] = '\0'; 48*8af74909SZhong Yang } 49*8af74909SZhong Yang 50*8af74909SZhong Yang public: LexAccessor(IDocument * pAccess_)51*8af74909SZhong Yang explicit LexAccessor(IDocument *pAccess_) : 52*8af74909SZhong Yang pAccess(pAccess_), startPos(extremePosition), endPos(0), 53*8af74909SZhong Yang codePage(pAccess->CodePage()), 54*8af74909SZhong Yang encodingType(EncodingType::eightBit), 55*8af74909SZhong Yang lenDoc(pAccess->Length()), 56*8af74909SZhong Yang validLen(0), 57*8af74909SZhong Yang startSeg(0), startPosStyling(0), 58*8af74909SZhong Yang documentVersion(pAccess->Version()) { 59*8af74909SZhong Yang // Prevent warnings by static analyzers about uninitialized buf and styleBuf. 60*8af74909SZhong Yang buf[0] = 0; 61*8af74909SZhong Yang styleBuf[0] = 0; 62*8af74909SZhong Yang switch (codePage) { 63*8af74909SZhong Yang case 65001: 64*8af74909SZhong Yang encodingType = EncodingType::unicode; 65*8af74909SZhong Yang break; 66*8af74909SZhong Yang case 932: 67*8af74909SZhong Yang case 936: 68*8af74909SZhong Yang case 949: 69*8af74909SZhong Yang case 950: 70*8af74909SZhong Yang case 1361: 71*8af74909SZhong Yang encodingType = EncodingType::dbcs; 72*8af74909SZhong Yang } 73*8af74909SZhong Yang } 74*8af74909SZhong Yang char operator[](Sci_Position position) { 75*8af74909SZhong Yang if (position < startPos || position >= endPos) { 76*8af74909SZhong Yang Fill(position); 77*8af74909SZhong Yang } 78*8af74909SZhong Yang return buf[position - startPos]; 79*8af74909SZhong Yang } MultiByteAccess()80*8af74909SZhong Yang IDocument *MultiByteAccess() const noexcept { 81*8af74909SZhong Yang return pAccess; 82*8af74909SZhong Yang } 83*8af74909SZhong Yang /** Safe version of operator[], returning a defined value for invalid position. */ 84*8af74909SZhong Yang char SafeGetCharAt(Sci_Position position, char chDefault=' ') { 85*8af74909SZhong Yang if (position < startPos || position >= endPos) { 86*8af74909SZhong Yang Fill(position); 87*8af74909SZhong Yang if (position < startPos || position >= endPos) { 88*8af74909SZhong Yang // Position is outside range of document 89*8af74909SZhong Yang return chDefault; 90*8af74909SZhong Yang } 91*8af74909SZhong Yang } 92*8af74909SZhong Yang return buf[position - startPos]; 93*8af74909SZhong Yang } IsLeadByte(char ch)94*8af74909SZhong Yang bool IsLeadByte(char ch) const { 95*8af74909SZhong Yang return pAccess->IsDBCSLeadByte(ch); 96*8af74909SZhong Yang } Encoding()97*8af74909SZhong Yang EncodingType Encoding() const noexcept { 98*8af74909SZhong Yang return encodingType; 99*8af74909SZhong Yang } Match(Sci_Position pos,const char * s)100*8af74909SZhong Yang bool Match(Sci_Position pos, const char *s) { 101*8af74909SZhong Yang for (int i=0; *s; i++) { 102*8af74909SZhong Yang if (*s != SafeGetCharAt(pos+i)) 103*8af74909SZhong Yang return false; 104*8af74909SZhong Yang s++; 105*8af74909SZhong Yang } 106*8af74909SZhong Yang return true; 107*8af74909SZhong Yang } StyleAt(Sci_Position position)108*8af74909SZhong Yang char StyleAt(Sci_Position position) const { 109*8af74909SZhong Yang return pAccess->StyleAt(position); 110*8af74909SZhong Yang } GetLine(Sci_Position position)111*8af74909SZhong Yang Sci_Position GetLine(Sci_Position position) const { 112*8af74909SZhong Yang return pAccess->LineFromPosition(position); 113*8af74909SZhong Yang } LineStart(Sci_Position line)114*8af74909SZhong Yang Sci_Position LineStart(Sci_Position line) const { 115*8af74909SZhong Yang return pAccess->LineStart(line); 116*8af74909SZhong Yang } LineEnd(Sci_Position line)117*8af74909SZhong Yang Sci_Position LineEnd(Sci_Position line) const { 118*8af74909SZhong Yang return pAccess->LineEnd(line); 119*8af74909SZhong Yang } LevelAt(Sci_Position line)120*8af74909SZhong Yang int LevelAt(Sci_Position line) const { 121*8af74909SZhong Yang return pAccess->GetLevel(line); 122*8af74909SZhong Yang } Length()123*8af74909SZhong Yang Sci_Position Length() const { 124*8af74909SZhong Yang return lenDoc; 125*8af74909SZhong Yang } Flush()126*8af74909SZhong Yang void Flush() { 127*8af74909SZhong Yang if (validLen > 0) { 128*8af74909SZhong Yang pAccess->SetStyles(validLen, styleBuf); 129*8af74909SZhong Yang startPosStyling += validLen; 130*8af74909SZhong Yang validLen = 0; 131*8af74909SZhong Yang } 132*8af74909SZhong Yang } GetLineState(Sci_Position line)133*8af74909SZhong Yang int GetLineState(Sci_Position line) const { 134*8af74909SZhong Yang return pAccess->GetLineState(line); 135*8af74909SZhong Yang } SetLineState(Sci_Position line,int state)136*8af74909SZhong Yang int SetLineState(Sci_Position line, int state) { 137*8af74909SZhong Yang return pAccess->SetLineState(line, state); 138*8af74909SZhong Yang } 139*8af74909SZhong Yang // Style setting StartAt(Sci_PositionU start)140*8af74909SZhong Yang void StartAt(Sci_PositionU start) { 141*8af74909SZhong Yang pAccess->StartStyling(start); 142*8af74909SZhong Yang startPosStyling = start; 143*8af74909SZhong Yang } GetStartSegment()144*8af74909SZhong Yang Sci_PositionU GetStartSegment() const { 145*8af74909SZhong Yang return startSeg; 146*8af74909SZhong Yang } StartSegment(Sci_PositionU pos)147*8af74909SZhong Yang void StartSegment(Sci_PositionU pos) { 148*8af74909SZhong Yang startSeg = pos; 149*8af74909SZhong Yang } ColourTo(Sci_PositionU pos,int chAttr)150*8af74909SZhong Yang void ColourTo(Sci_PositionU pos, int chAttr) { 151*8af74909SZhong Yang // Only perform styling if non empty range 152*8af74909SZhong Yang if (pos != startSeg - 1) { 153*8af74909SZhong Yang assert(pos >= startSeg); 154*8af74909SZhong Yang if (pos < startSeg) { 155*8af74909SZhong Yang return; 156*8af74909SZhong Yang } 157*8af74909SZhong Yang 158*8af74909SZhong Yang if (validLen + (pos - startSeg + 1) >= bufferSize) 159*8af74909SZhong Yang Flush(); 160*8af74909SZhong Yang const char attr = static_cast<char>(chAttr); 161*8af74909SZhong Yang if (validLen + (pos - startSeg + 1) >= bufferSize) { 162*8af74909SZhong Yang // Too big for buffer so send directly 163*8af74909SZhong Yang pAccess->SetStyleFor(pos - startSeg + 1, attr); 164*8af74909SZhong Yang } else { 165*8af74909SZhong Yang for (Sci_PositionU i = startSeg; i <= pos; i++) { 166*8af74909SZhong Yang assert((startPosStyling + validLen) < Length()); 167*8af74909SZhong Yang styleBuf[validLen++] = attr; 168*8af74909SZhong Yang } 169*8af74909SZhong Yang } 170*8af74909SZhong Yang } 171*8af74909SZhong Yang startSeg = pos+1; 172*8af74909SZhong Yang } SetLevel(Sci_Position line,int level)173*8af74909SZhong Yang void SetLevel(Sci_Position line, int level) { 174*8af74909SZhong Yang pAccess->SetLevel(line, level); 175*8af74909SZhong Yang } IndicatorFill(Sci_Position start,Sci_Position end,int indicator,int value)176*8af74909SZhong Yang void IndicatorFill(Sci_Position start, Sci_Position end, int indicator, int value) { 177*8af74909SZhong Yang pAccess->DecorationSetCurrentIndicator(indicator); 178*8af74909SZhong Yang pAccess->DecorationFillRange(start, value, end - start); 179*8af74909SZhong Yang } 180*8af74909SZhong Yang ChangeLexerState(Sci_Position start,Sci_Position end)181*8af74909SZhong Yang void ChangeLexerState(Sci_Position start, Sci_Position end) { 182*8af74909SZhong Yang pAccess->ChangeLexerState(start, end); 183*8af74909SZhong Yang } 184*8af74909SZhong Yang }; 185*8af74909SZhong Yang 186*8af74909SZhong Yang struct LexicalClass { 187*8af74909SZhong Yang int value; 188*8af74909SZhong Yang const char *name; 189*8af74909SZhong Yang const char *tags; 190*8af74909SZhong Yang const char *description; 191*8af74909SZhong Yang }; 192*8af74909SZhong Yang 193*8af74909SZhong Yang } 194*8af74909SZhong Yang 195*8af74909SZhong Yang #endif 196