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