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