cmIDEOptions.cxx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmIDEOptions.h"
  11. #include "cmSystemTools.h"
  12. //----------------------------------------------------------------------------
  13. cmIDEOptions::cmIDEOptions()
  14. {
  15. this->DoingDefine = false;
  16. this->AllowDefine = true;
  17. this->AllowSlash = false;
  18. this->DoingFollowing = 0;
  19. for(int i=0; i < FlagTableCount; ++i)
  20. {
  21. this->FlagTable[i] = 0;
  22. }
  23. }
  24. //----------------------------------------------------------------------------
  25. cmIDEOptions::~cmIDEOptions()
  26. {
  27. }
  28. //----------------------------------------------------------------------------
  29. void cmIDEOptions::HandleFlag(const char* flag)
  30. {
  31. // If the last option was -D then this option is the definition.
  32. if(this->DoingDefine)
  33. {
  34. this->DoingDefine = false;
  35. this->Defines.push_back(flag);
  36. return;
  37. }
  38. // If the last option expected a following value, this is it.
  39. if(this->DoingFollowing)
  40. {
  41. this->FlagMapUpdate(this->DoingFollowing, flag);
  42. this->DoingFollowing = 0;
  43. return;
  44. }
  45. // Look for known arguments.
  46. if(flag[0] == '-' || (this->AllowSlash && flag[0] == '/'))
  47. {
  48. // Look for preprocessor definitions.
  49. if(this->AllowDefine && flag[1] == 'D')
  50. {
  51. if(flag[2] == '\0')
  52. {
  53. // The next argument will have the definition.
  54. this->DoingDefine = true;
  55. }
  56. else
  57. {
  58. // Store this definition.
  59. this->Defines.push_back(flag+2);
  60. }
  61. return;
  62. }
  63. // Look through the available flag tables.
  64. bool flag_handled = false;
  65. for(int i=0; i < FlagTableCount && this->FlagTable[i]; ++i)
  66. {
  67. if(this->CheckFlagTable(this->FlagTable[i], flag, flag_handled))
  68. {
  69. return;
  70. }
  71. }
  72. // If any map entry handled the flag we are done.
  73. if(flag_handled)
  74. {
  75. return;
  76. }
  77. }
  78. // This option is not known. Store it in the output flags.
  79. this->StoreUnknownFlag(flag);
  80. }
  81. //----------------------------------------------------------------------------
  82. bool cmIDEOptions::CheckFlagTable(cmIDEFlagTable const* table,
  83. const char* flag, bool& flag_handled)
  84. {
  85. // Look for an entry in the flag table matching this flag.
  86. for(cmIDEFlagTable const* entry = table; entry->IDEName; ++entry)
  87. {
  88. bool entry_found = false;
  89. if(entry->special & cmIDEFlagTable::UserValue)
  90. {
  91. // This flag table entry accepts a user-specified value. If
  92. // the entry specifies UserRequired we must match only if a
  93. // non-empty value is given.
  94. int n = static_cast<int>(strlen(entry->commandFlag));
  95. if(strncmp(flag+1, entry->commandFlag, n) == 0 &&
  96. (!(entry->special & cmIDEFlagTable::UserRequired) ||
  97. static_cast<int>(strlen(flag+1)) > n))
  98. {
  99. this->FlagMapUpdate(entry, flag+n+1);
  100. entry_found = true;
  101. }
  102. }
  103. else if(strcmp(flag+1, entry->commandFlag) == 0)
  104. {
  105. if(entry->special & cmIDEFlagTable::UserFollowing)
  106. {
  107. // This flag expects a value in the following argument.
  108. this->DoingFollowing = entry;
  109. }
  110. else
  111. {
  112. // This flag table entry provides a fixed value.
  113. this->FlagMap[entry->IDEName] = entry->value;
  114. }
  115. entry_found = true;
  116. }
  117. // If the flag has been handled by an entry not requesting a
  118. // search continuation we are done.
  119. if(entry_found && !(entry->special & cmIDEFlagTable::Continue))
  120. {
  121. return true;
  122. }
  123. // If the entry was found the flag has been handled.
  124. flag_handled = flag_handled || entry_found;
  125. }
  126. return false;
  127. }
  128. //----------------------------------------------------------------------------
  129. void cmIDEOptions::FlagMapUpdate(cmIDEFlagTable const* entry,
  130. const char* new_value)
  131. {
  132. if(entry->special & cmIDEFlagTable::UserIgnored)
  133. {
  134. // Ignore the user-specified value.
  135. this->FlagMap[entry->IDEName] = entry->value;
  136. }
  137. else if(entry->special & cmIDEFlagTable::SemicolonAppendable)
  138. {
  139. this->FlagMap[entry->IDEName].push_back(new_value);
  140. }
  141. else
  142. {
  143. // Use the user-specified value.
  144. this->FlagMap[entry->IDEName] = new_value;
  145. }
  146. }
  147. //----------------------------------------------------------------------------
  148. void cmIDEOptions::AddDefine(const std::string& def)
  149. {
  150. this->Defines.push_back(def);
  151. }
  152. //----------------------------------------------------------------------------
  153. void cmIDEOptions::AddDefines(const char* defines)
  154. {
  155. if(defines)
  156. {
  157. // Expand the list of definitions.
  158. cmSystemTools::ExpandListArgument(defines, this->Defines);
  159. }
  160. }
  161. //----------------------------------------------------------------------------
  162. void cmIDEOptions::AddDefines(const std::vector<std::string> &defines)
  163. {
  164. this->Defines.insert(this->Defines.end(), defines.begin(), defines.end());
  165. }
  166. //----------------------------------------------------------------------------
  167. void cmIDEOptions::AddFlag(const char* flag, const char* value)
  168. {
  169. this->FlagMap[flag] = value;
  170. }
  171. //----------------------------------------------------------------------------
  172. void cmIDEOptions::AddFlag(const char* flag,
  173. std::vector<std::string> const& value)
  174. {
  175. this->FlagMap[flag] = value;
  176. }
  177. //----------------------------------------------------------------------------
  178. void cmIDEOptions::AppendFlag(std::string const& flag,
  179. std::string const& value)
  180. {
  181. this->FlagMap[flag].push_back(value);
  182. }
  183. //----------------------------------------------------------------------------
  184. void cmIDEOptions::RemoveFlag(const char* flag)
  185. {
  186. this->FlagMap.erase(flag);
  187. }
  188. //----------------------------------------------------------------------------
  189. const char* cmIDEOptions::GetFlag(const char* flag)
  190. {
  191. // This method works only for single-valued flags!
  192. std::map<std::string, FlagValue>::iterator i = this->FlagMap.find(flag);
  193. if(i != this->FlagMap.end() && i->second.size() == 1)
  194. {
  195. return i->second[0].c_str();
  196. }
  197. return 0;
  198. }