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.
15 class WordClassifier
{
19 std::map
<std::string
, int> wordToStyle
;
23 explicit WordClassifier(int baseStyle_
) : baseStyle(baseStyle_
), firstStyle(0), lenStyles(0) {
26 void Allocate(int firstStyle_
, int lenStyles_
) {
27 firstStyle
= firstStyle_
;
28 lenStyles
= lenStyles_
;
50 int ValueFor(const std::string
&s
) const {
51 std::map
<std::string
, int>::const_iterator it
= wordToStyle
.find(s
);
52 if (it
!= wordToStyle
.end())
58 bool IncludesStyle(int style
) const {
59 return (style
>= firstStyle
) && (style
< (firstStyle
+ lenStyles
));
62 void SetIdentifiers(int style
, const char *identifiers
) {
63 while (*identifiers
) {
64 const char *cpSpace
= identifiers
;
65 while (*cpSpace
&& !(*cpSpace
== ' ' || *cpSpace
== '\t' || *cpSpace
== '\r' || *cpSpace
== '\n'))
67 if (cpSpace
> identifiers
) {
68 std::string
word(identifiers
, cpSpace
- identifiers
);
69 wordToStyle
[word
] = style
;
71 identifiers
= cpSpace
;
80 const char *baseStyles
;
83 int secondaryDistance
;
85 std::vector
<WordClassifier
> classifiers
;
87 int BlockFromBaseStyle(int baseStyle
) const {
88 for (int b
=0; b
< classifications
; b
++) {
89 if (baseStyle
== baseStyles
[b
])
95 int BlockFromStyle(int style
) const {
97 for (std::vector
<WordClassifier
>::const_iterator it
=classifiers
.begin(); it
!= classifiers
.end(); ++it
) {
98 if (it
->IncludesStyle(style
))
107 SubStyles(const char *baseStyles_
, int styleFirst_
, int stylesAvailable_
, int secondaryDistance_
) :
109 baseStyles(baseStyles_
),
110 styleFirst(styleFirst_
),
111 stylesAvailable(stylesAvailable_
),
112 secondaryDistance(secondaryDistance_
),
114 while (baseStyles
[classifications
]) {
115 classifiers
.push_back(WordClassifier(baseStyles
[classifications
]));
120 int Allocate(int styleBase
, int numberStyles
) {
121 int block
= BlockFromBaseStyle(styleBase
);
123 if ((allocated
+ numberStyles
) > stylesAvailable
)
125 int startBlock
= styleFirst
+ allocated
;
126 allocated
+= numberStyles
;
127 classifiers
[block
].Allocate(startBlock
, numberStyles
);
134 int Start(int styleBase
) {
135 int block
= BlockFromBaseStyle(styleBase
);
136 return (block
>= 0) ? classifiers
[block
].Start() : -1;
139 int Length(int styleBase
) {
140 int block
= BlockFromBaseStyle(styleBase
);
141 return (block
>= 0) ? classifiers
[block
].Length() : 0;
144 int BaseStyle(int subStyle
) const {
145 int block
= BlockFromStyle(subStyle
);
147 return classifiers
[block
].Base();
152 int DistanceToSecondaryStyles() const {
153 return secondaryDistance
;
156 void SetIdentifiers(int style
, const char *identifiers
) {
157 int block
= BlockFromStyle(style
);
159 classifiers
[block
].SetIdentifiers(style
, identifiers
);
164 for (std::vector
<WordClassifier
>::iterator it
=classifiers
.begin(); it
!= classifiers
.end(); ++it
)
168 const WordClassifier
&Classifier(int baseStyle
) const {
169 const int block
= BlockFromBaseStyle(baseStyle
);
170 return classifiers
[block
>= 0 ? block
: 0];