StyleContext.h 5.7 KB

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