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