diff options
Diffstat (limited to 'lexlib')
| -rw-r--r-- | lexlib/OptionSet.h | 137 | 
1 files changed, 137 insertions, 0 deletions
| diff --git a/lexlib/OptionSet.h b/lexlib/OptionSet.h new file mode 100644 index 000000000..3a86bb436 --- /dev/null +++ b/lexlib/OptionSet.h @@ -0,0 +1,137 @@ +// Scintilla source code edit control +/** @file OptionSet.h + ** Manage descriptive information about an options struct for a lexer. + ** Hold the names, positions, and descriptions of boolean, integer and string options and + ** allow setting options and retrieving metadata about the options. + **/ +// Copyright 2010 by Neil Hodgson <neilh@scintilla.org> +// The License.txt file describes the conditions under which this software may be distributed. + +#ifndef OPTIONSET_H +#define OPTIONSET_H + +#ifdef SCI_NAMESPACE +namespace Scintilla { +#endif + +template <typename T> +class OptionSet { +	typedef T Target; +	typedef bool T::*plcob; +	typedef int T::*plcoi; +	typedef std::string T::*plcos; +	struct Option { +		int opType; +		union { +			plcob pb; +			plcoi pi; +			plcos ps; +		}; +		std::string description; +		Option(plcob pb_=0, std::string description_="") : +			opType(SC_TYPE_BOOLEAN), pb(pb_), description(description_) { +		} +		Option(plcoi pi_, std::string description_) : +			opType(SC_TYPE_INTEGER), pi(pi_), description(description_) { +		} +		Option(plcos ps_, std::string description_) : +			opType(SC_TYPE_STRING), ps(ps_), description(description_) { +		} +		bool Set(T *base, const char *val) { +			switch (opType) { +			case SC_TYPE_BOOLEAN: { +					bool option = atoi(val) != 0; +					if ((*base).*pb != option) { +						(*base).*pb = option; +						return true; +					} +					break; +				} +			case SC_TYPE_INTEGER: { +					int option = atoi(val); +					if ((*base).*pi != option) { +						(*base).*pi = option; +						return true; +					} +					break; +				} +			case SC_TYPE_STRING: { +					if ((*base).*ps != val) { +						(*base).*ps = val; +						return true; +					} +					break; +				} +			} +			return false; +		} +	}; +	typedef std::map<std::string, Option> OptionMap; +	OptionMap nameToDef; +	std::string names; +	std::string wordLists; + +	void AppendName(const char *name) { +		if (!names.empty()) +			names += "\n"; +		names += name; +	} +public: +	void DefineProperty(const char *name, plcob pb, std::string description="") { +		nameToDef[name] = Option(pb, description); +		AppendName(name); +	} +	void DefineProperty(const char *name, plcoi pi, std::string description="") { +		nameToDef[name] = Option(pi, description); +		AppendName(name); +	} +	void DefineProperty(const char *name, plcos ps, std::string description="") { +		nameToDef[name] = Option(ps, description); +		AppendName(name); +	} +	const char *PropertyNames() { +		return names.c_str(); +	} +	int PropertyType(const char *name) { +		OptionMap::iterator it = nameToDef.find(name); +		if (it != nameToDef.end()) { +			return it->second.opType; +		} +		return SC_TYPE_BOOLEAN; +	} +	const char *DescribeProperty(const char *name) { +		OptionMap::iterator it = nameToDef.find(name); +		if (it != nameToDef.end()) { +			return it->second.description.c_str(); +		} +		return ""; +	} + +	bool PropertySet(T *base, const char *name, const char *val) { +		OptionMap::iterator it = nameToDef.find(name); +		if (it != nameToDef.end()) { +			return it->second.Set(base, val); +		} +		return false; +	} + +	void DefineWordListSets(const char * const wordListDescriptions[]) { +		if (wordListDescriptions) { +			for (size_t wl = 0; wordListDescriptions[wl]; wl++) { +				if (!wordLists.empty()) +					wordLists += "\n"; +				wordLists += wordListDescriptions[wl]; +			} +		} +	} + +	const char *DescribeWordListSets() { +		return wordLists.c_str(); +	} +}; + +#ifdef SCI_NAMESPACE +} +#endif + +#endif | 
