diff options
Diffstat (limited to 'scintilla/lexlib/SubStyles.h')
-rw-r--r-- | scintilla/lexlib/SubStyles.h | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/scintilla/lexlib/SubStyles.h b/scintilla/lexlib/SubStyles.h new file mode 100644 index 0000000..e6c34e0 --- /dev/null +++ b/scintilla/lexlib/SubStyles.h @@ -0,0 +1,162 @@ +// Scintilla source code edit control +/** @file SubStyles.h + ** Manage substyles for a lexer. + **/ +// Copyright 2012 by Neil Hodgson <neilh@scintilla.org> +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef SUBSTYLES_H +#define SUBSTYLES_H + +#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + +class WordClassifier { + int firstStyle; + int lenStyles; + std::map<std::string, int> wordToStyle; + +public: + + WordClassifier() : firstStyle(0), lenStyles(0) { + } + + void Allocate(int firstStyle_, int lenStyles_) { + firstStyle = firstStyle_; + lenStyles = lenStyles_; + wordToStyle.clear(); + } + + int Start() const { + return firstStyle; + } + + int Length() const { + return lenStyles; + } + + void Clear() { + firstStyle = 0; + lenStyles = 0; + wordToStyle.clear(); + } + + int ValueFor(const std::string &s) const { + std::map<std::string, int>::const_iterator it = wordToStyle.find(s); + if (it != wordToStyle.end()) + return it->second; + else + return -1; + } + + bool IncludesStyle(int style) const { + return (style >= firstStyle) && (style < (firstStyle + lenStyles)); + } + + void SetIdentifiers(int style, const char *identifiers) { + while (*identifiers) { + const char *cpSpace = identifiers; + while (*cpSpace && *cpSpace != ' ') + cpSpace++; + std::string word(identifiers, cpSpace - identifiers); + wordToStyle[word] = style; + identifiers = cpSpace; + if (*identifiers) + identifiers++; + } + } +}; + +class SubStyles { + int classifications; + const char *baseStyles; + int styleFirst; + int stylesAvailable; + int secondaryDistance; + int allocated; + std::vector<WordClassifier> classifiers; + + int BlockFromBaseStyle(int baseStyle) const { + for (int b=0; b < classifications; b++) { + if (baseStyle == baseStyles[b]) + return b; + } + return -1; + } + + int BlockFromStyle(int style) const { + int b = 0; + for (std::vector<WordClassifier>::const_iterator it=classifiers.begin(); it != classifiers.end(); ++it) { + if (it->IncludesStyle(style)) + return b; + b++; + } + return -1; + } + +public: + + SubStyles(const char *baseStyles_, int styleFirst_, int stylesAvailable_, int secondaryDistance_) : + classifications(0), + baseStyles(baseStyles_), + styleFirst(styleFirst_), + stylesAvailable(stylesAvailable_), + secondaryDistance(secondaryDistance_), + allocated(0) { + while (baseStyles[classifications]) { + classifications++; + classifiers.push_back(WordClassifier()); + } + } + + int Allocate(int styleBase, int numberStyles) { + int block = BlockFromBaseStyle(styleBase); + if (block >= 0) { + if ((allocated + numberStyles) > stylesAvailable) + return -1; + int startBlock = styleFirst + allocated; + allocated += numberStyles; + classifiers[block].Allocate(startBlock, numberStyles); + return startBlock; + } else { + return -1; + } + } + + int Start(int styleBase) { + int block = BlockFromBaseStyle(styleBase); + return (block >= 0) ? classifiers[block].Start() : -1; + } + + int Length(int styleBase) { + int block = BlockFromBaseStyle(styleBase); + return (block >= 0) ? classifiers[block].Length() : 0; + } + + int DistanceToSecondaryStyles() const { + return secondaryDistance; + } + + void SetIdentifiers(int style, const char *identifiers) { + int block = BlockFromStyle(style); + if (block >= 0) + classifiers[block].SetIdentifiers(style, identifiers); + } + + void Free() { + allocated = 0; + for (std::vector<WordClassifier>::iterator it=classifiers.begin(); it != classifiers.end(); ++it) + it->Clear(); + } + + const WordClassifier &Classifier(int baseStyle) const { + return classifiers[BlockFromBaseStyle(baseStyle)]; + } +}; + +#ifdef SCI_NAMESPACE +} +#endif + +#endif |