xref: /MusicPlayer2/scintilla/lexlib/SubStyles.h (revision 8af74909132ed5e696cb05b6689ae4baf14c1c96)
1*8af74909SZhong Yang // Scintilla source code edit control
2*8af74909SZhong Yang /** @file SubStyles.h
3*8af74909SZhong Yang  ** Manage substyles for a lexer.
4*8af74909SZhong Yang  **/
5*8af74909SZhong Yang // Copyright 2012 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 SUBSTYLES_H
9*8af74909SZhong Yang #define SUBSTYLES_H
10*8af74909SZhong Yang 
11*8af74909SZhong Yang namespace Scintilla {
12*8af74909SZhong Yang 
13*8af74909SZhong Yang class WordClassifier {
14*8af74909SZhong Yang 	int baseStyle;
15*8af74909SZhong Yang 	int firstStyle;
16*8af74909SZhong Yang 	int lenStyles;
17*8af74909SZhong Yang 	std::map<std::string, int> wordToStyle;
18*8af74909SZhong Yang 
19*8af74909SZhong Yang public:
20*8af74909SZhong Yang 
WordClassifier(int baseStyle_)21*8af74909SZhong Yang 	explicit WordClassifier(int baseStyle_) : baseStyle(baseStyle_), firstStyle(0), lenStyles(0) {
22*8af74909SZhong Yang 	}
23*8af74909SZhong Yang 
Allocate(int firstStyle_,int lenStyles_)24*8af74909SZhong Yang 	void Allocate(int firstStyle_, int lenStyles_) {
25*8af74909SZhong Yang 		firstStyle = firstStyle_;
26*8af74909SZhong Yang 		lenStyles = lenStyles_;
27*8af74909SZhong Yang 		wordToStyle.clear();
28*8af74909SZhong Yang 	}
29*8af74909SZhong Yang 
Base()30*8af74909SZhong Yang 	int Base() const noexcept {
31*8af74909SZhong Yang 		return baseStyle;
32*8af74909SZhong Yang 	}
33*8af74909SZhong Yang 
Start()34*8af74909SZhong Yang 	int Start() const noexcept {
35*8af74909SZhong Yang 		return firstStyle;
36*8af74909SZhong Yang 	}
37*8af74909SZhong Yang 
Last()38*8af74909SZhong Yang 	int Last() const noexcept {
39*8af74909SZhong Yang 		return firstStyle + lenStyles - 1;
40*8af74909SZhong Yang 	}
41*8af74909SZhong Yang 
Length()42*8af74909SZhong Yang 	int Length() const noexcept {
43*8af74909SZhong Yang 		return lenStyles;
44*8af74909SZhong Yang 	}
45*8af74909SZhong Yang 
Clear()46*8af74909SZhong Yang 	void Clear() noexcept {
47*8af74909SZhong Yang 		firstStyle = 0;
48*8af74909SZhong Yang 		lenStyles = 0;
49*8af74909SZhong Yang 		wordToStyle.clear();
50*8af74909SZhong Yang 	}
51*8af74909SZhong Yang 
ValueFor(const std::string & s)52*8af74909SZhong Yang 	int ValueFor(const std::string &s) const {
53*8af74909SZhong Yang 		std::map<std::string, int>::const_iterator it = wordToStyle.find(s);
54*8af74909SZhong Yang 		if (it != wordToStyle.end())
55*8af74909SZhong Yang 			return it->second;
56*8af74909SZhong Yang 		else
57*8af74909SZhong Yang 			return -1;
58*8af74909SZhong Yang 	}
59*8af74909SZhong Yang 
IncludesStyle(int style)60*8af74909SZhong Yang 	bool IncludesStyle(int style) const noexcept {
61*8af74909SZhong Yang 		return (style >= firstStyle) && (style < (firstStyle + lenStyles));
62*8af74909SZhong Yang 	}
63*8af74909SZhong Yang 
RemoveStyle(int style)64*8af74909SZhong Yang 	void RemoveStyle(int style) {
65*8af74909SZhong Yang 		std::map<std::string, int>::iterator it = wordToStyle.begin();
66*8af74909SZhong Yang 		while (it != wordToStyle.end()) {
67*8af74909SZhong Yang 			if (it->second == style) {
68*8af74909SZhong Yang 				it = wordToStyle.erase(it);
69*8af74909SZhong Yang 			} else {
70*8af74909SZhong Yang 				++it;
71*8af74909SZhong Yang 			}
72*8af74909SZhong Yang 		}
73*8af74909SZhong Yang 	}
74*8af74909SZhong Yang 
SetIdentifiers(int style,const char * identifiers)75*8af74909SZhong Yang 	void SetIdentifiers(int style, const char *identifiers) {
76*8af74909SZhong Yang 		RemoveStyle(style);
77*8af74909SZhong Yang 		while (*identifiers) {
78*8af74909SZhong Yang 			const char *cpSpace = identifiers;
79*8af74909SZhong Yang 			while (*cpSpace && !(*cpSpace == ' ' || *cpSpace == '\t' || *cpSpace == '\r' || *cpSpace == '\n'))
80*8af74909SZhong Yang 				cpSpace++;
81*8af74909SZhong Yang 			if (cpSpace > identifiers) {
82*8af74909SZhong Yang 				std::string word(identifiers, cpSpace - identifiers);
83*8af74909SZhong Yang 				wordToStyle[word] = style;
84*8af74909SZhong Yang 			}
85*8af74909SZhong Yang 			identifiers = cpSpace;
86*8af74909SZhong Yang 			if (*identifiers)
87*8af74909SZhong Yang 				identifiers++;
88*8af74909SZhong Yang 		}
89*8af74909SZhong Yang 	}
90*8af74909SZhong Yang };
91*8af74909SZhong Yang 
92*8af74909SZhong Yang class SubStyles {
93*8af74909SZhong Yang 	int classifications;
94*8af74909SZhong Yang 	const char *baseStyles;
95*8af74909SZhong Yang 	int styleFirst;
96*8af74909SZhong Yang 	int stylesAvailable;
97*8af74909SZhong Yang 	int secondaryDistance;
98*8af74909SZhong Yang 	int allocated;
99*8af74909SZhong Yang 	std::vector<WordClassifier> classifiers;
100*8af74909SZhong Yang 
BlockFromBaseStyle(int baseStyle)101*8af74909SZhong Yang 	int BlockFromBaseStyle(int baseStyle) const noexcept {
102*8af74909SZhong Yang 		for (int b=0; b < classifications; b++) {
103*8af74909SZhong Yang 			if (baseStyle == baseStyles[b])
104*8af74909SZhong Yang 				return b;
105*8af74909SZhong Yang 		}
106*8af74909SZhong Yang 		return -1;
107*8af74909SZhong Yang 	}
108*8af74909SZhong Yang 
BlockFromStyle(int style)109*8af74909SZhong Yang 	int BlockFromStyle(int style) const {
110*8af74909SZhong Yang 		int b = 0;
111*8af74909SZhong Yang 		for (std::vector<WordClassifier>::const_iterator it=classifiers.begin(); it != classifiers.end(); ++it) {
112*8af74909SZhong Yang 			if (it->IncludesStyle(style))
113*8af74909SZhong Yang 				return b;
114*8af74909SZhong Yang 			b++;
115*8af74909SZhong Yang 		}
116*8af74909SZhong Yang 		return -1;
117*8af74909SZhong Yang 	}
118*8af74909SZhong Yang 
119*8af74909SZhong Yang public:
120*8af74909SZhong Yang 
SubStyles(const char * baseStyles_,int styleFirst_,int stylesAvailable_,int secondaryDistance_)121*8af74909SZhong Yang 	SubStyles(const char *baseStyles_, int styleFirst_, int stylesAvailable_, int secondaryDistance_) :
122*8af74909SZhong Yang 		classifications(0),
123*8af74909SZhong Yang 		baseStyles(baseStyles_),
124*8af74909SZhong Yang 		styleFirst(styleFirst_),
125*8af74909SZhong Yang 		stylesAvailable(stylesAvailable_),
126*8af74909SZhong Yang 		secondaryDistance(secondaryDistance_),
127*8af74909SZhong Yang 		allocated(0) {
128*8af74909SZhong Yang 		while (baseStyles[classifications]) {
129*8af74909SZhong Yang 			classifiers.push_back(WordClassifier(baseStyles[classifications]));
130*8af74909SZhong Yang 			classifications++;
131*8af74909SZhong Yang 		}
132*8af74909SZhong Yang 	}
133*8af74909SZhong Yang 
Allocate(int styleBase,int numberStyles)134*8af74909SZhong Yang 	int Allocate(int styleBase, int numberStyles) {
135*8af74909SZhong Yang 		const int block = BlockFromBaseStyle(styleBase);
136*8af74909SZhong Yang 		if (block >= 0) {
137*8af74909SZhong Yang 			if ((allocated + numberStyles) > stylesAvailable)
138*8af74909SZhong Yang 				return -1;
139*8af74909SZhong Yang 			const int startBlock = styleFirst + allocated;
140*8af74909SZhong Yang 			allocated += numberStyles;
141*8af74909SZhong Yang 			classifiers[block].Allocate(startBlock, numberStyles);
142*8af74909SZhong Yang 			return startBlock;
143*8af74909SZhong Yang 		} else {
144*8af74909SZhong Yang 			return -1;
145*8af74909SZhong Yang 		}
146*8af74909SZhong Yang 	}
147*8af74909SZhong Yang 
Start(int styleBase)148*8af74909SZhong Yang 	int Start(int styleBase) noexcept {
149*8af74909SZhong Yang 		const int block = BlockFromBaseStyle(styleBase);
150*8af74909SZhong Yang 		return (block >= 0) ? classifiers[block].Start() : -1;
151*8af74909SZhong Yang 	}
152*8af74909SZhong Yang 
Length(int styleBase)153*8af74909SZhong Yang 	int Length(int styleBase) noexcept {
154*8af74909SZhong Yang 		const int block = BlockFromBaseStyle(styleBase);
155*8af74909SZhong Yang 		return (block >= 0) ? classifiers[block].Length() : 0;
156*8af74909SZhong Yang 	}
157*8af74909SZhong Yang 
BaseStyle(int subStyle)158*8af74909SZhong Yang 	int BaseStyle(int subStyle) const {
159*8af74909SZhong Yang 		const int block = BlockFromStyle(subStyle);
160*8af74909SZhong Yang 		if (block >= 0)
161*8af74909SZhong Yang 			return classifiers[block].Base();
162*8af74909SZhong Yang 		else
163*8af74909SZhong Yang 			return subStyle;
164*8af74909SZhong Yang 	}
165*8af74909SZhong Yang 
DistanceToSecondaryStyles()166*8af74909SZhong Yang 	int DistanceToSecondaryStyles() const noexcept {
167*8af74909SZhong Yang 		return secondaryDistance;
168*8af74909SZhong Yang 	}
169*8af74909SZhong Yang 
FirstAllocated()170*8af74909SZhong Yang 	int FirstAllocated() const {
171*8af74909SZhong Yang 		int start = 257;
172*8af74909SZhong Yang 		for (std::vector<WordClassifier>::const_iterator it = classifiers.begin(); it != classifiers.end(); ++it) {
173*8af74909SZhong Yang 			if (start > it->Start())
174*8af74909SZhong Yang 				start = it->Start();
175*8af74909SZhong Yang 		}
176*8af74909SZhong Yang 		return (start < 256) ? start : -1;
177*8af74909SZhong Yang 	}
178*8af74909SZhong Yang 
LastAllocated()179*8af74909SZhong Yang 	int LastAllocated() const {
180*8af74909SZhong Yang 		int last = -1;
181*8af74909SZhong Yang 		for (std::vector<WordClassifier>::const_iterator it = classifiers.begin(); it != classifiers.end(); ++it) {
182*8af74909SZhong Yang 			if (last < it->Last())
183*8af74909SZhong Yang 				last = it->Last();
184*8af74909SZhong Yang 		}
185*8af74909SZhong Yang 		return last;
186*8af74909SZhong Yang 	}
187*8af74909SZhong Yang 
SetIdentifiers(int style,const char * identifiers)188*8af74909SZhong Yang 	void SetIdentifiers(int style, const char *identifiers) {
189*8af74909SZhong Yang 		const int block = BlockFromStyle(style);
190*8af74909SZhong Yang 		if (block >= 0)
191*8af74909SZhong Yang 			classifiers[block].SetIdentifiers(style, identifiers);
192*8af74909SZhong Yang 	}
193*8af74909SZhong Yang 
Free()194*8af74909SZhong Yang 	void Free() {
195*8af74909SZhong Yang 		allocated = 0;
196*8af74909SZhong Yang 		for (std::vector<WordClassifier>::iterator it=classifiers.begin(); it != classifiers.end(); ++it)
197*8af74909SZhong Yang 			it->Clear();
198*8af74909SZhong Yang 	}
199*8af74909SZhong Yang 
Classifier(int baseStyle)200*8af74909SZhong Yang 	const WordClassifier &Classifier(int baseStyle) const noexcept {
201*8af74909SZhong Yang 		const int block = BlockFromBaseStyle(baseStyle);
202*8af74909SZhong Yang 		return classifiers[block >= 0 ? block : 0];
203*8af74909SZhong Yang 	}
204*8af74909SZhong Yang };
205*8af74909SZhong Yang 
206*8af74909SZhong Yang }
207*8af74909SZhong Yang 
208*8af74909SZhong Yang #endif
209