SubStyles.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // Scintilla source code edit control
  2. /** @file SubStyles.h
  3. ** Manage substyles for a lexer.
  4. **/
  5. // Copyright 2012 by Neil Hodgson <neilh@scintilla.org>
  6. // The License.txt file describes the conditions under which this software may be distributed.
  7. #ifndef SUBSTYLES_H
  8. #define SUBSTYLES_H
  9. #ifdef SCI_NAMESPACE
  10. namespace Scintilla {
  11. #endif
  12. class WordClassifier {
  13. int baseStyle;
  14. int firstStyle;
  15. int lenStyles;
  16. std::map<std::string, int> wordToStyle;
  17. public:
  18. explicit WordClassifier(int baseStyle_) : baseStyle(baseStyle_), firstStyle(0), lenStyles(0) {
  19. }
  20. void Allocate(int firstStyle_, int lenStyles_) {
  21. firstStyle = firstStyle_;
  22. lenStyles = lenStyles_;
  23. wordToStyle.clear();
  24. }
  25. int Base() const {
  26. return baseStyle;
  27. }
  28. int Start() const {
  29. return firstStyle;
  30. }
  31. int Length() const {
  32. return lenStyles;
  33. }
  34. void Clear() {
  35. firstStyle = 0;
  36. lenStyles = 0;
  37. wordToStyle.clear();
  38. }
  39. int ValueFor(const std::string &s) const {
  40. std::map<std::string, int>::const_iterator it = wordToStyle.find(s);
  41. if (it != wordToStyle.end())
  42. return it->second;
  43. else
  44. return -1;
  45. }
  46. bool IncludesStyle(int style) const {
  47. return (style >= firstStyle) && (style < (firstStyle + lenStyles));
  48. }
  49. void SetIdentifiers(int style, const char *identifiers) {
  50. while (*identifiers) {
  51. const char *cpSpace = identifiers;
  52. while (*cpSpace && !(*cpSpace == ' ' || *cpSpace == '\t' || *cpSpace == '\r' || *cpSpace == '\n'))
  53. cpSpace++;
  54. if (cpSpace > identifiers) {
  55. std::string word(identifiers, cpSpace - identifiers);
  56. wordToStyle[word] = style;
  57. }
  58. identifiers = cpSpace;
  59. if (*identifiers)
  60. identifiers++;
  61. }
  62. }
  63. };
  64. class SubStyles {
  65. int classifications;
  66. const char *baseStyles;
  67. int styleFirst;
  68. int stylesAvailable;
  69. int secondaryDistance;
  70. int allocated;
  71. std::vector<WordClassifier> classifiers;
  72. int BlockFromBaseStyle(int baseStyle) const {
  73. for (int b=0; b < classifications; b++) {
  74. if (baseStyle == baseStyles[b])
  75. return b;
  76. }
  77. return -1;
  78. }
  79. int BlockFromStyle(int style) const {
  80. int b = 0;
  81. for (std::vector<WordClassifier>::const_iterator it=classifiers.begin(); it != classifiers.end(); ++it) {
  82. if (it->IncludesStyle(style))
  83. return b;
  84. b++;
  85. }
  86. return -1;
  87. }
  88. public:
  89. SubStyles(const char *baseStyles_, int styleFirst_, int stylesAvailable_, int secondaryDistance_) :
  90. classifications(0),
  91. baseStyles(baseStyles_),
  92. styleFirst(styleFirst_),
  93. stylesAvailable(stylesAvailable_),
  94. secondaryDistance(secondaryDistance_),
  95. allocated(0) {
  96. while (baseStyles[classifications]) {
  97. classifiers.push_back(WordClassifier(baseStyles[classifications]));
  98. classifications++;
  99. }
  100. }
  101. int Allocate(int styleBase, int numberStyles) {
  102. int block = BlockFromBaseStyle(styleBase);
  103. if (block >= 0) {
  104. if ((allocated + numberStyles) > stylesAvailable)
  105. return -1;
  106. int startBlock = styleFirst + allocated;
  107. allocated += numberStyles;
  108. classifiers[block].Allocate(startBlock, numberStyles);
  109. return startBlock;
  110. } else {
  111. return -1;
  112. }
  113. }
  114. int Start(int styleBase) {
  115. int block = BlockFromBaseStyle(styleBase);
  116. return (block >= 0) ? classifiers[block].Start() : -1;
  117. }
  118. int Length(int styleBase) {
  119. int block = BlockFromBaseStyle(styleBase);
  120. return (block >= 0) ? classifiers[block].Length() : 0;
  121. }
  122. int BaseStyle(int subStyle) const {
  123. int block = BlockFromStyle(subStyle);
  124. if (block >= 0)
  125. return classifiers[block].Base();
  126. else
  127. return subStyle;
  128. }
  129. int DistanceToSecondaryStyles() const {
  130. return secondaryDistance;
  131. }
  132. void SetIdentifiers(int style, const char *identifiers) {
  133. int block = BlockFromStyle(style);
  134. if (block >= 0)
  135. classifiers[block].SetIdentifiers(style, identifiers);
  136. }
  137. void Free() {
  138. allocated = 0;
  139. for (std::vector<WordClassifier>::iterator it=classifiers.begin(); it != classifiers.end(); ++it)
  140. it->Clear();
  141. }
  142. const WordClassifier &Classifier(int baseStyle) const {
  143. const int block = BlockFromBaseStyle(baseStyle);
  144. return classifiers[block >= 0 ? block : 0];
  145. }
  146. };
  147. #ifdef SCI_NAMESPACE
  148. }
  149. #endif
  150. #endif