xref: /MusicPlayer2/scintilla/lexlib/OptionSet.h (revision 8af74909132ed5e696cb05b6689ae4baf14c1c96)
1*8af74909SZhong Yang // Scintilla source code edit control
2*8af74909SZhong Yang /** @file OptionSet.h
3*8af74909SZhong Yang  ** Manage descriptive information about an options struct for a lexer.
4*8af74909SZhong Yang  ** Hold the names, positions, and descriptions of boolean, integer and string options and
5*8af74909SZhong Yang  ** allow setting options and retrieving metadata about the options.
6*8af74909SZhong Yang  **/
7*8af74909SZhong Yang // Copyright 2010 by Neil Hodgson <[email protected]>
8*8af74909SZhong Yang // The License.txt file describes the conditions under which this software may be distributed.
9*8af74909SZhong Yang 
10*8af74909SZhong Yang #ifndef OPTIONSET_H
11*8af74909SZhong Yang #define OPTIONSET_H
12*8af74909SZhong Yang 
13*8af74909SZhong Yang namespace Scintilla {
14*8af74909SZhong Yang 
15*8af74909SZhong Yang template <typename T>
16*8af74909SZhong Yang class OptionSet {
17*8af74909SZhong Yang 	typedef T Target;
18*8af74909SZhong Yang 	typedef bool T::*plcob;
19*8af74909SZhong Yang 	typedef int T::*plcoi;
20*8af74909SZhong Yang 	typedef std::string T::*plcos;
21*8af74909SZhong Yang 	struct Option {
22*8af74909SZhong Yang 		int opType;
23*8af74909SZhong Yang 		union {
24*8af74909SZhong Yang 			plcob pb;
25*8af74909SZhong Yang 			plcoi pi;
26*8af74909SZhong Yang 			plcos ps;
27*8af74909SZhong Yang 		};
28*8af74909SZhong Yang 		std::string value;
29*8af74909SZhong Yang 		std::string description;
OptionOption30*8af74909SZhong Yang 		Option() :
31*8af74909SZhong Yang 			opType(SC_TYPE_BOOLEAN), pb(0), description("") {
32*8af74909SZhong Yang 		}
33*8af74909SZhong Yang 		Option(plcob pb_, std::string description_="") :
opTypeOption34*8af74909SZhong Yang 			opType(SC_TYPE_BOOLEAN), pb(pb_), description(description_) {
35*8af74909SZhong Yang 		}
OptionOption36*8af74909SZhong Yang 		Option(plcoi pi_, std::string description_) :
37*8af74909SZhong Yang 			opType(SC_TYPE_INTEGER), pi(pi_), description(description_) {
38*8af74909SZhong Yang 		}
OptionOption39*8af74909SZhong Yang 		Option(plcos ps_, std::string description_) :
40*8af74909SZhong Yang 			opType(SC_TYPE_STRING), ps(ps_), description(description_) {
41*8af74909SZhong Yang 		}
SetOption42*8af74909SZhong Yang 		bool Set(T *base, const char *val) {
43*8af74909SZhong Yang 			value = val;
44*8af74909SZhong Yang 			switch (opType) {
45*8af74909SZhong Yang 			case SC_TYPE_BOOLEAN: {
46*8af74909SZhong Yang 					bool option = atoi(val) != 0;
47*8af74909SZhong Yang 					if ((*base).*pb != option) {
48*8af74909SZhong Yang 						(*base).*pb = option;
49*8af74909SZhong Yang 						return true;
50*8af74909SZhong Yang 					}
51*8af74909SZhong Yang 					break;
52*8af74909SZhong Yang 				}
53*8af74909SZhong Yang 			case SC_TYPE_INTEGER: {
54*8af74909SZhong Yang 					int option = atoi(val);
55*8af74909SZhong Yang 					if ((*base).*pi != option) {
56*8af74909SZhong Yang 						(*base).*pi = option;
57*8af74909SZhong Yang 						return true;
58*8af74909SZhong Yang 					}
59*8af74909SZhong Yang 					break;
60*8af74909SZhong Yang 				}
61*8af74909SZhong Yang 			case SC_TYPE_STRING: {
62*8af74909SZhong Yang 					if ((*base).*ps != val) {
63*8af74909SZhong Yang 						(*base).*ps = val;
64*8af74909SZhong Yang 						return true;
65*8af74909SZhong Yang 					}
66*8af74909SZhong Yang 					break;
67*8af74909SZhong Yang 				}
68*8af74909SZhong Yang 			}
69*8af74909SZhong Yang 			return false;
70*8af74909SZhong Yang 		}
GetOption71*8af74909SZhong Yang 		const char *Get() const noexcept {
72*8af74909SZhong Yang 			return value.c_str();
73*8af74909SZhong Yang 		}
74*8af74909SZhong Yang 	};
75*8af74909SZhong Yang 	typedef std::map<std::string, Option> OptionMap;
76*8af74909SZhong Yang 	OptionMap nameToDef;
77*8af74909SZhong Yang 	std::string names;
78*8af74909SZhong Yang 	std::string wordLists;
79*8af74909SZhong Yang 
AppendName(const char * name)80*8af74909SZhong Yang 	void AppendName(const char *name) {
81*8af74909SZhong Yang 		if (!names.empty())
82*8af74909SZhong Yang 			names += "\n";
83*8af74909SZhong Yang 		names += name;
84*8af74909SZhong Yang 	}
85*8af74909SZhong Yang public:
86*8af74909SZhong Yang 	void DefineProperty(const char *name, plcob pb, std::string description="") {
87*8af74909SZhong Yang 		nameToDef[name] = Option(pb, description);
88*8af74909SZhong Yang 		AppendName(name);
89*8af74909SZhong Yang 	}
90*8af74909SZhong Yang 	void DefineProperty(const char *name, plcoi pi, std::string description="") {
91*8af74909SZhong Yang 		nameToDef[name] = Option(pi, description);
92*8af74909SZhong Yang 		AppendName(name);
93*8af74909SZhong Yang 	}
94*8af74909SZhong Yang 	void DefineProperty(const char *name, plcos ps, std::string description="") {
95*8af74909SZhong Yang 		nameToDef[name] = Option(ps, description);
96*8af74909SZhong Yang 		AppendName(name);
97*8af74909SZhong Yang 	}
PropertyNames()98*8af74909SZhong Yang 	const char *PropertyNames() const noexcept {
99*8af74909SZhong Yang 		return names.c_str();
100*8af74909SZhong Yang 	}
PropertyType(const char * name)101*8af74909SZhong Yang 	int PropertyType(const char *name) {
102*8af74909SZhong Yang 		typename OptionMap::iterator it = nameToDef.find(name);
103*8af74909SZhong Yang 		if (it != nameToDef.end()) {
104*8af74909SZhong Yang 			return it->second.opType;
105*8af74909SZhong Yang 		}
106*8af74909SZhong Yang 		return SC_TYPE_BOOLEAN;
107*8af74909SZhong Yang 	}
DescribeProperty(const char * name)108*8af74909SZhong Yang 	const char *DescribeProperty(const char *name) {
109*8af74909SZhong Yang 		typename OptionMap::iterator it = nameToDef.find(name);
110*8af74909SZhong Yang 		if (it != nameToDef.end()) {
111*8af74909SZhong Yang 			return it->second.description.c_str();
112*8af74909SZhong Yang 		}
113*8af74909SZhong Yang 		return "";
114*8af74909SZhong Yang 	}
115*8af74909SZhong Yang 
PropertySet(T * base,const char * name,const char * val)116*8af74909SZhong Yang 	bool PropertySet(T *base, const char *name, const char *val) {
117*8af74909SZhong Yang 		typename OptionMap::iterator it = nameToDef.find(name);
118*8af74909SZhong Yang 		if (it != nameToDef.end()) {
119*8af74909SZhong Yang 			return it->second.Set(base, val);
120*8af74909SZhong Yang 		}
121*8af74909SZhong Yang 		return false;
122*8af74909SZhong Yang 	}
123*8af74909SZhong Yang 
PropertyGet(const char * name)124*8af74909SZhong Yang 	const char *PropertyGet(const char *name) {
125*8af74909SZhong Yang 		typename OptionMap::iterator it = nameToDef.find(name);
126*8af74909SZhong Yang 		if (it != nameToDef.end()) {
127*8af74909SZhong Yang 			return it->second.Get();
128*8af74909SZhong Yang 		}
129*8af74909SZhong Yang 		return nullptr;
130*8af74909SZhong Yang 	}
131*8af74909SZhong Yang 
DefineWordListSets(const char * const wordListDescriptions[])132*8af74909SZhong Yang 	void DefineWordListSets(const char * const wordListDescriptions[]) {
133*8af74909SZhong Yang 		if (wordListDescriptions) {
134*8af74909SZhong Yang 			for (size_t wl = 0; wordListDescriptions[wl]; wl++) {
135*8af74909SZhong Yang 				if (!wordLists.empty())
136*8af74909SZhong Yang 					wordLists += "\n";
137*8af74909SZhong Yang 				wordLists += wordListDescriptions[wl];
138*8af74909SZhong Yang 			}
139*8af74909SZhong Yang 		}
140*8af74909SZhong Yang 	}
141*8af74909SZhong Yang 
DescribeWordListSets()142*8af74909SZhong Yang 	const char *DescribeWordListSets() const noexcept {
143*8af74909SZhong Yang 		return wordLists.c_str();
144*8af74909SZhong Yang 	}
145*8af74909SZhong Yang };
146*8af74909SZhong Yang 
147*8af74909SZhong Yang }
148*8af74909SZhong Yang 
149*8af74909SZhong Yang #endif
150