OptionSet.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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 <neilh@scintilla.org>
  8. // The License.txt file describes the conditions under which this software may be distributed.
  9. #ifndef OPTIONSET_H
  10. #define OPTIONSET_H
  11. #ifdef SCI_NAMESPACE
  12. namespace Scintilla {
  13. #endif
  14. template <typename T>
  15. class OptionSet {
  16. typedef T Target;
  17. typedef bool T::*plcob;
  18. typedef int T::*plcoi;
  19. typedef std::string T::*plcos;
  20. struct Option {
  21. int opType;
  22. union {
  23. plcob pb;
  24. plcoi pi;
  25. plcos ps;
  26. };
  27. std::string description;
  28. Option() :
  29. opType(SC_TYPE_BOOLEAN), pb(0), description("") {
  30. }
  31. Option(plcob pb_, std::string description_="") :
  32. opType(SC_TYPE_BOOLEAN), pb(pb_), description(description_) {
  33. }
  34. Option(plcoi pi_, std::string description_) :
  35. opType(SC_TYPE_INTEGER), pi(pi_), description(description_) {
  36. }
  37. Option(plcos ps_, std::string description_) :
  38. opType(SC_TYPE_STRING), ps(ps_), description(description_) {
  39. }
  40. bool Set(T *base, const char *val) const {
  41. switch (opType) {
  42. case SC_TYPE_BOOLEAN: {
  43. bool option = atoi(val) != 0;
  44. if ((*base).*pb != option) {
  45. (*base).*pb = option;
  46. return true;
  47. }
  48. break;
  49. }
  50. case SC_TYPE_INTEGER: {
  51. int option = atoi(val);
  52. if ((*base).*pi != option) {
  53. (*base).*pi = option;
  54. return true;
  55. }
  56. break;
  57. }
  58. case SC_TYPE_STRING: {
  59. if ((*base).*ps != val) {
  60. (*base).*ps = val;
  61. return true;
  62. }
  63. break;
  64. }
  65. }
  66. return false;
  67. }
  68. };
  69. typedef std::map<std::string, Option> OptionMap;
  70. OptionMap nameToDef;
  71. std::string names;
  72. std::string wordLists;
  73. void AppendName(const char *name) {
  74. if (!names.empty())
  75. names += "\n";
  76. names += name;
  77. }
  78. public:
  79. virtual ~OptionSet() {
  80. }
  81. void DefineProperty(const char *name, plcob pb, std::string description="") {
  82. nameToDef[name] = Option(pb, description);
  83. AppendName(name);
  84. }
  85. void DefineProperty(const char *name, plcoi pi, std::string description="") {
  86. nameToDef[name] = Option(pi, description);
  87. AppendName(name);
  88. }
  89. void DefineProperty(const char *name, plcos ps, std::string description="") {
  90. nameToDef[name] = Option(ps, description);
  91. AppendName(name);
  92. }
  93. const char *PropertyNames() const {
  94. return names.c_str();
  95. }
  96. int PropertyType(const char *name) {
  97. typename OptionMap::iterator it = nameToDef.find(name);
  98. if (it != nameToDef.end()) {
  99. return it->second.opType;
  100. }
  101. return SC_TYPE_BOOLEAN;
  102. }
  103. const char *DescribeProperty(const char *name) {
  104. typename OptionMap::iterator it = nameToDef.find(name);
  105. if (it != nameToDef.end()) {
  106. return it->second.description.c_str();
  107. }
  108. return "";
  109. }
  110. bool PropertySet(T *base, const char *name, const char *val) {
  111. typename OptionMap::iterator it = nameToDef.find(name);
  112. if (it != nameToDef.end()) {
  113. return it->second.Set(base, val);
  114. }
  115. return false;
  116. }
  117. void DefineWordListSets(const char * const wordListDescriptions[]) {
  118. if (wordListDescriptions) {
  119. for (size_t wl = 0; wordListDescriptions[wl]; wl++) {
  120. if (!wordLists.empty())
  121. wordLists += "\n";
  122. wordLists += wordListDescriptions[wl];
  123. }
  124. }
  125. }
  126. const char *DescribeWordListSets() const {
  127. return wordLists.c_str();
  128. }
  129. };
  130. #ifdef SCI_NAMESPACE
  131. }
  132. #endif
  133. #endif