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