Update Scintilla to 4.0.4
[TortoiseGit.git] / ext / scintilla / lexlib / SubStyles.h
blob596e7d880cca88cf50330b5b62a77d43913ba2ce
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.
8 #ifndef SUBSTYLES_H
9 #define SUBSTYLES_H
11 namespace Scintilla {
13 class WordClassifier {
14 int baseStyle;
15 int firstStyle;
16 int lenStyles;
17 std::map<std::string, int> wordToStyle;
19 public:
21 explicit WordClassifier(int baseStyle_) : baseStyle(baseStyle_), firstStyle(0), lenStyles(0) {
24 void Allocate(int firstStyle_, int lenStyles_) {
25 firstStyle = firstStyle_;
26 lenStyles = lenStyles_;
27 wordToStyle.clear();
30 int Base() const {
31 return baseStyle;
34 int Start() const {
35 return firstStyle;
38 int Last() const {
39 return firstStyle + lenStyles - 1;
42 int Length() const {
43 return lenStyles;
46 void Clear() {
47 firstStyle = 0;
48 lenStyles = 0;
49 wordToStyle.clear();
52 int ValueFor(const std::string &s) const {
53 std::map<std::string, int>::const_iterator it = wordToStyle.find(s);
54 if (it != wordToStyle.end())
55 return it->second;
56 else
57 return -1;
60 bool IncludesStyle(int style) const {
61 return (style >= firstStyle) && (style < (firstStyle + lenStyles));
64 void SetIdentifiers(int style, const char *identifiers) {
65 while (*identifiers) {
66 const char *cpSpace = identifiers;
67 while (*cpSpace && !(*cpSpace == ' ' || *cpSpace == '\t' || *cpSpace == '\r' || *cpSpace == '\n'))
68 cpSpace++;
69 if (cpSpace > identifiers) {
70 std::string word(identifiers, cpSpace - identifiers);
71 wordToStyle[word] = style;
73 identifiers = cpSpace;
74 if (*identifiers)
75 identifiers++;
80 class SubStyles {
81 int classifications;
82 const char *baseStyles;
83 int styleFirst;
84 int stylesAvailable;
85 int secondaryDistance;
86 int allocated;
87 std::vector<WordClassifier> classifiers;
89 int BlockFromBaseStyle(int baseStyle) const {
90 for (int b=0; b < classifications; b++) {
91 if (baseStyle == baseStyles[b])
92 return b;
94 return -1;
97 int BlockFromStyle(int style) const {
98 int b = 0;
99 for (std::vector<WordClassifier>::const_iterator it=classifiers.begin(); it != classifiers.end(); ++it) {
100 if (it->IncludesStyle(style))
101 return b;
102 b++;
104 return -1;
107 public:
109 SubStyles(const char *baseStyles_, int styleFirst_, int stylesAvailable_, int secondaryDistance_) :
110 classifications(0),
111 baseStyles(baseStyles_),
112 styleFirst(styleFirst_),
113 stylesAvailable(stylesAvailable_),
114 secondaryDistance(secondaryDistance_),
115 allocated(0) {
116 while (baseStyles[classifications]) {
117 classifiers.push_back(WordClassifier(baseStyles[classifications]));
118 classifications++;
122 int Allocate(int styleBase, int numberStyles) {
123 int block = BlockFromBaseStyle(styleBase);
124 if (block >= 0) {
125 if ((allocated + numberStyles) > stylesAvailable)
126 return -1;
127 int startBlock = styleFirst + allocated;
128 allocated += numberStyles;
129 classifiers[block].Allocate(startBlock, numberStyles);
130 return startBlock;
131 } else {
132 return -1;
136 int Start(int styleBase) {
137 int block = BlockFromBaseStyle(styleBase);
138 return (block >= 0) ? classifiers[block].Start() : -1;
141 int Length(int styleBase) {
142 int block = BlockFromBaseStyle(styleBase);
143 return (block >= 0) ? classifiers[block].Length() : 0;
146 int BaseStyle(int subStyle) const {
147 int block = BlockFromStyle(subStyle);
148 if (block >= 0)
149 return classifiers[block].Base();
150 else
151 return subStyle;
154 int DistanceToSecondaryStyles() const {
155 return secondaryDistance;
158 int FirstAllocated() const {
159 int start = 257;
160 for (std::vector<WordClassifier>::const_iterator it = classifiers.begin(); it != classifiers.end(); ++it) {
161 if (start > it->Start())
162 start = it->Start();
164 return (start < 256) ? start : -1;
167 int LastAllocated() const {
168 int last = -1;
169 for (std::vector<WordClassifier>::const_iterator it = classifiers.begin(); it != classifiers.end(); ++it) {
170 if (last < it->Last())
171 last = it->Last();
173 return last;
176 void SetIdentifiers(int style, const char *identifiers) {
177 int block = BlockFromStyle(style);
178 if (block >= 0)
179 classifiers[block].SetIdentifiers(style, identifiers);
182 void Free() {
183 allocated = 0;
184 for (std::vector<WordClassifier>::iterator it=classifiers.begin(); it != classifiers.end(); ++it)
185 it->Clear();
188 const WordClassifier &Classifier(int baseStyle) const {
189 const int block = BlockFromBaseStyle(baseStyle);
190 return classifiers[block >= 0 ? block : 0];
196 #endif