diff options
| author | nyamatongwe <unknown> | 2013-01-19 12:33:20 +1100 | 
|---|---|---|
| committer | nyamatongwe <unknown> | 2013-01-19 12:33:20 +1100 | 
| commit | 5d17740fdedcea321a23ffd3350aa7adbf4c2329 (patch) | |
| tree | 1512465a2bbf066e96eb1ae2d10fdf3fc7dbd42b /lexlib/SubStyles.h | |
| parent | f46c96ecb682ad736453f78f6709fca6c6911886 (diff) | |
| download | scintilla-mirror-5d17740fdedcea321a23ffd3350aa7adbf4c2329.tar.gz | |
Implement generic support for Unicode line ends and sub styles in lexer support classes.
Diffstat (limited to 'lexlib/SubStyles.h')
| -rw-r--r-- | lexlib/SubStyles.h | 158 | 
1 files changed, 158 insertions, 0 deletions
| diff --git a/lexlib/SubStyles.h b/lexlib/SubStyles.h new file mode 100644 index 000000000..7dc7804ef --- /dev/null +++ b/lexlib/SubStyles.h @@ -0,0 +1,158 @@ +// 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; +	} + +	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 | 
