1 // Scintilla source code edit control
3 ** Manage substyles for a lexer.
5 // Copyright 2012 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
13 class WordClassifier
{
17 std::map
<std::string
, int> wordToStyle
;
21 explicit WordClassifier(int baseStyle_
) : baseStyle(baseStyle_
), firstStyle(0), lenStyles(0) {
24 void Allocate(int firstStyle_
, int lenStyles_
) {
25 firstStyle
= firstStyle_
;
26 lenStyles
= lenStyles_
;
39 return firstStyle
+ lenStyles
- 1;
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())
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'))
69 if (cpSpace
> identifiers
) {
70 std::string
word(identifiers
, cpSpace
- identifiers
);
71 wordToStyle
[word
] = style
;
73 identifiers
= cpSpace
;
82 const char *baseStyles
;
85 int secondaryDistance
;
87 std::vector
<WordClassifier
> classifiers
;
89 int BlockFromBaseStyle(int baseStyle
) const {
90 for (int b
=0; b
< classifications
; b
++) {
91 if (baseStyle
== baseStyles
[b
])
97 int BlockFromStyle(int style
) const {
99 for (std::vector
<WordClassifier
>::const_iterator it
=classifiers
.begin(); it
!= classifiers
.end(); ++it
) {
100 if (it
->IncludesStyle(style
))
109 SubStyles(const char *baseStyles_
, int styleFirst_
, int stylesAvailable_
, int secondaryDistance_
) :
111 baseStyles(baseStyles_
),
112 styleFirst(styleFirst_
),
113 stylesAvailable(stylesAvailable_
),
114 secondaryDistance(secondaryDistance_
),
116 while (baseStyles
[classifications
]) {
117 classifiers
.push_back(WordClassifier(baseStyles
[classifications
]));
122 int Allocate(int styleBase
, int numberStyles
) {
123 int block
= BlockFromBaseStyle(styleBase
);
125 if ((allocated
+ numberStyles
) > stylesAvailable
)
127 int startBlock
= styleFirst
+ allocated
;
128 allocated
+= numberStyles
;
129 classifiers
[block
].Allocate(startBlock
, numberStyles
);
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
);
149 return classifiers
[block
].Base();
154 int DistanceToSecondaryStyles() const {
155 return secondaryDistance
;
158 int FirstAllocated() const {
160 for (std::vector
<WordClassifier
>::const_iterator it
= classifiers
.begin(); it
!= classifiers
.end(); ++it
) {
161 if (start
> it
->Start())
164 return (start
< 256) ? start
: -1;
167 int LastAllocated() const {
169 for (std::vector
<WordClassifier
>::const_iterator it
= classifiers
.begin(); it
!= classifiers
.end(); ++it
) {
170 if (last
< it
->Last())
176 void SetIdentifiers(int style
, const char *identifiers
) {
177 int block
= BlockFromStyle(style
);
179 classifiers
[block
].SetIdentifiers(style
, identifiers
);
184 for (std::vector
<WordClassifier
>::iterator it
=classifiers
.begin(); it
!= classifiers
.end(); ++it
)
188 const WordClassifier
&Classifier(int baseStyle
) const {
189 const int block
= BlockFromBaseStyle(baseStyle
);
190 return classifiers
[block
>= 0 ? block
: 0];