cmCommandArgumentsHelper.cxx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmCommandArgumentsHelper.h"
  4. cmCommandArgument::cmCommandArgument(cmCommandArgumentsHelper* args,
  5. const char* key,
  6. cmCommandArgumentGroup* group)
  7. : Key(key)
  8. , Group(group)
  9. , WasActive(false)
  10. , ArgumentsBeforeEmpty(true)
  11. , CurrentIndex(0)
  12. {
  13. if (args != nullptr) {
  14. args->AddArgument(this);
  15. }
  16. if (this->Group != nullptr) {
  17. this->Group->ContainedArguments.push_back(this);
  18. }
  19. }
  20. void cmCommandArgument::Reset()
  21. {
  22. this->WasActive = false;
  23. this->CurrentIndex = 0;
  24. this->DoReset();
  25. }
  26. void cmCommandArgument::Follows(const cmCommandArgument* arg)
  27. {
  28. this->ArgumentsBeforeEmpty = false;
  29. this->ArgumentsBefore.insert(arg);
  30. }
  31. void cmCommandArgument::FollowsGroup(const cmCommandArgumentGroup* group)
  32. {
  33. if (group != nullptr) {
  34. this->ArgumentsBeforeEmpty = false;
  35. this->ArgumentsBefore.insert(group->ContainedArguments.begin(),
  36. group->ContainedArguments.end());
  37. }
  38. }
  39. bool cmCommandArgument::MayFollow(const cmCommandArgument* current) const
  40. {
  41. if (this->ArgumentsBeforeEmpty) {
  42. return true;
  43. }
  44. return this->ArgumentsBefore.find(current) != this->ArgumentsBefore.end();
  45. }
  46. bool cmCommandArgument::KeyMatches(const std::string& key) const
  47. {
  48. if ((this->Key == nullptr) || (this->Key[0] == '\0')) {
  49. return true;
  50. }
  51. return (key == this->Key);
  52. }
  53. void cmCommandArgument::ApplyOwnGroup()
  54. {
  55. if (this->Group != nullptr) {
  56. for (std::vector<cmCommandArgument*>::const_iterator it =
  57. this->Group->ContainedArguments.begin();
  58. it != this->Group->ContainedArguments.end(); ++it) {
  59. if (*it != this) {
  60. this->ArgumentsBefore.insert(*it);
  61. }
  62. }
  63. }
  64. }
  65. void cmCommandArgument::Activate()
  66. {
  67. this->WasActive = true;
  68. this->CurrentIndex = 0;
  69. }
  70. bool cmCommandArgument::Consume(const std::string& arg)
  71. {
  72. bool res = this->DoConsume(arg, this->CurrentIndex);
  73. this->CurrentIndex++;
  74. return res;
  75. }
  76. cmCAStringVector::cmCAStringVector(cmCommandArgumentsHelper* args,
  77. const char* key,
  78. cmCommandArgumentGroup* group)
  79. : cmCommandArgument(args, key, group)
  80. , Ignore(nullptr)
  81. {
  82. if ((key == nullptr) || (*key == 0)) {
  83. this->DataStart = 0;
  84. } else {
  85. this->DataStart = 1;
  86. }
  87. }
  88. bool cmCAStringVector::DoConsume(const std::string& arg, unsigned int index)
  89. {
  90. if (index >= this->DataStart) {
  91. if ((this->Ignore == nullptr) || (arg != this->Ignore)) {
  92. this->Vector.push_back(arg);
  93. }
  94. }
  95. return false;
  96. }
  97. void cmCAStringVector::DoReset()
  98. {
  99. this->Vector.clear();
  100. }
  101. cmCAString::cmCAString(cmCommandArgumentsHelper* args, const char* key,
  102. cmCommandArgumentGroup* group)
  103. : cmCommandArgument(args, key, group)
  104. {
  105. if ((key == nullptr) || (*key == 0)) {
  106. this->DataStart = 0;
  107. } else {
  108. this->DataStart = 1;
  109. }
  110. }
  111. bool cmCAString::DoConsume(const std::string& arg, unsigned int index)
  112. {
  113. if (index == this->DataStart) {
  114. this->String = arg;
  115. }
  116. return index >= this->DataStart;
  117. }
  118. void cmCAString::DoReset()
  119. {
  120. this->String = "";
  121. }
  122. cmCAEnabler::cmCAEnabler(cmCommandArgumentsHelper* args, const char* key,
  123. cmCommandArgumentGroup* group)
  124. : cmCommandArgument(args, key, group)
  125. , Enabled(false)
  126. {
  127. }
  128. bool cmCAEnabler::DoConsume(const std::string&, unsigned int index)
  129. {
  130. if (index == 0) {
  131. this->Enabled = true;
  132. }
  133. return true;
  134. }
  135. void cmCAEnabler::DoReset()
  136. {
  137. this->Enabled = false;
  138. }
  139. cmCADisabler::cmCADisabler(cmCommandArgumentsHelper* args, const char* key,
  140. cmCommandArgumentGroup* group)
  141. : cmCommandArgument(args, key, group)
  142. , Enabled(true)
  143. {
  144. }
  145. bool cmCADisabler::DoConsume(const std::string&, unsigned int index)
  146. {
  147. if (index == 0) {
  148. this->Enabled = false;
  149. }
  150. return true;
  151. }
  152. void cmCADisabler::DoReset()
  153. {
  154. this->Enabled = true;
  155. }
  156. void cmCommandArgumentGroup::Follows(const cmCommandArgument* arg)
  157. {
  158. for (std::vector<cmCommandArgument*>::iterator it =
  159. this->ContainedArguments.begin();
  160. it != this->ContainedArguments.end(); ++it) {
  161. (*it)->Follows(arg);
  162. }
  163. }
  164. void cmCommandArgumentGroup::FollowsGroup(const cmCommandArgumentGroup* group)
  165. {
  166. for (std::vector<cmCommandArgument*>::iterator it =
  167. this->ContainedArguments.begin();
  168. it != this->ContainedArguments.end(); ++it) {
  169. (*it)->FollowsGroup(group);
  170. }
  171. }
  172. void cmCommandArgumentsHelper::Parse(const std::vector<std::string>* args,
  173. std::vector<std::string>* unconsumedArgs)
  174. {
  175. if (args == nullptr) {
  176. return;
  177. }
  178. for (std::vector<cmCommandArgument*>::iterator argIt =
  179. this->Arguments.begin();
  180. argIt != this->Arguments.end(); ++argIt) {
  181. (*argIt)->ApplyOwnGroup();
  182. (*argIt)->Reset();
  183. }
  184. cmCommandArgument* activeArgument = nullptr;
  185. const cmCommandArgument* previousArgument = nullptr;
  186. for (std::vector<std::string>::const_iterator it = args->begin();
  187. it != args->end(); ++it) {
  188. for (std::vector<cmCommandArgument*>::iterator argIt =
  189. this->Arguments.begin();
  190. argIt != this->Arguments.end(); ++argIt) {
  191. if ((*argIt)->KeyMatches(*it) &&
  192. ((*argIt)->MayFollow(previousArgument))) {
  193. activeArgument = *argIt;
  194. activeArgument->Activate();
  195. break;
  196. }
  197. }
  198. if (activeArgument) {
  199. bool argDone = activeArgument->Consume(*it);
  200. previousArgument = activeArgument;
  201. if (argDone) {
  202. activeArgument = nullptr;
  203. }
  204. } else {
  205. if (unconsumedArgs != nullptr) {
  206. unconsumedArgs->push_back(*it);
  207. }
  208. }
  209. }
  210. }
  211. void cmCommandArgumentsHelper::AddArgument(cmCommandArgument* arg)
  212. {
  213. this->Arguments.push_back(arg);
  214. }