Recognize .exp (Expect) files as Tcl
[geany-mirror.git] / scintilla / lexlib / SubStyles.h
blobf5b15e9cfa7f915f3f0655d3e517320842ec7175
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 #ifdef SCI_NAMESPACE
12 namespace Scintilla {
13 #endif
15 class WordClassifier {
16 int baseStyle;
17 int firstStyle;
18 int lenStyles;
19 std::map<std::string, int> wordToStyle;
21 public:
23 explicit WordClassifier(int baseStyle_) : baseStyle(baseStyle_), firstStyle(0), lenStyles(0) {
26 void Allocate(int firstStyle_, int lenStyles_) {
27 firstStyle = firstStyle_;
28 lenStyles = lenStyles_;
29 wordToStyle.clear();
32 int Base() const {
33 return baseStyle;
36 int Start() const {
37 return firstStyle;
40 int Length() const {
41 return lenStyles;
44 void Clear() {
45 firstStyle = 0;
46 lenStyles = 0;
47 wordToStyle.clear();
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())
53 return it->second;
54 else
55 return -1;
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'))
66 cpSpace++;
67 if (cpSpace > identifiers) {
68 std::string word(identifiers, cpSpace - identifiers);
69 wordToStyle[word] = style;
71 identifiers = cpSpace;
72 if (*identifiers)
73 identifiers++;
78 class SubStyles {
79 int classifications;
80 const char *baseStyles;
81 int styleFirst;
82 int stylesAvailable;
83 int secondaryDistance;
84 int allocated;
85 std::vector<WordClassifier> classifiers;
87 int BlockFromBaseStyle(int baseStyle) const {
88 for (int b=0; b < classifications; b++) {
89 if (baseStyle == baseStyles[b])
90 return b;
92 return -1;
95 int BlockFromStyle(int style) const {
96 int b = 0;
97 for (std::vector<WordClassifier>::const_iterator it=classifiers.begin(); it != classifiers.end(); ++it) {
98 if (it->IncludesStyle(style))
99 return b;
100 b++;
102 return -1;
105 public:
107 SubStyles(const char *baseStyles_, int styleFirst_, int stylesAvailable_, int secondaryDistance_) :
108 classifications(0),
109 baseStyles(baseStyles_),
110 styleFirst(styleFirst_),
111 stylesAvailable(stylesAvailable_),
112 secondaryDistance(secondaryDistance_),
113 allocated(0) {
114 while (baseStyles[classifications]) {
115 classifiers.push_back(WordClassifier(baseStyles[classifications]));
116 classifications++;
120 int Allocate(int styleBase, int numberStyles) {
121 int block = BlockFromBaseStyle(styleBase);
122 if (block >= 0) {
123 if ((allocated + numberStyles) > stylesAvailable)
124 return -1;
125 int startBlock = styleFirst + allocated;
126 allocated += numberStyles;
127 classifiers[block].Allocate(startBlock, numberStyles);
128 return startBlock;
129 } else {
130 return -1;
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);
146 if (block >= 0)
147 return classifiers[block].Base();
148 else
149 return subStyle;
152 int DistanceToSecondaryStyles() const {
153 return secondaryDistance;
156 void SetIdentifiers(int style, const char *identifiers) {
157 int block = BlockFromStyle(style);
158 if (block >= 0)
159 classifiers[block].SetIdentifiers(style, identifiers);
162 void Free() {
163 allocated = 0;
164 for (std::vector<WordClassifier>::iterator it=classifiers.begin(); it != classifiers.end(); ++it)
165 it->Clear();
168 const WordClassifier &Classifier(int baseStyle) const {
169 const int block = BlockFromBaseStyle(baseStyle);
170 return classifiers[block >= 0 ? block : 0];
174 #ifdef SCI_NAMESPACE
176 #endif
178 #endif