123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- // 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 baseStyle;
- int firstStyle;
- int lenStyles;
- std::map<std::string, int> wordToStyle;
- public:
- explicit WordClassifier(int baseStyle_) : baseStyle(baseStyle_), firstStyle(0), lenStyles(0) {
- }
- void Allocate(int firstStyle_, int lenStyles_) {
- firstStyle = firstStyle_;
- lenStyles = lenStyles_;
- wordToStyle.clear();
- }
- int Base() const {
- return baseStyle;
- }
- 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 == '\t' || *cpSpace == '\r' || *cpSpace == '\n'))
- cpSpace++;
- if (cpSpace > identifiers) {
- 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]) {
- classifiers.push_back(WordClassifier(baseStyles[classifications]));
- classifications++;
- }
- }
- 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 BaseStyle(int subStyle) const {
- int block = BlockFromStyle(subStyle);
- if (block >= 0)
- return classifiers[block].Base();
- else
- return subStyle;
- }
- 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 {
- const int block = BlockFromBaseStyle(baseStyle);
- return classifiers[block >= 0 ? block : 0];
- }
- };
- #ifdef SCI_NAMESPACE
- }
- #endif
- #endif
|