You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

312 lines
6.7 KiB

  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmCommandArgumentsHelper.h"
  14. cmCommandArgument::cmCommandArgument(cmCommandArgumentsHelper* args,
  15. const char* key,
  16. cmCommandArgumentGroup* group)
  17. :Key(key)
  18. ,Group(group)
  19. ,WasActive(false)
  20. ,ArgumentsBeforeEmpty(true)
  21. ,CurrentIndex(0)
  22. {
  23. if (args!=0)
  24. {
  25. args->AddArgument(this);
  26. }
  27. if (this->Group!=0)
  28. {
  29. this->Group->ContainedArguments.push_back(this);
  30. }
  31. }
  32. void cmCommandArgument::Reset()
  33. {
  34. this->WasActive =false;
  35. this->CurrentIndex = 0;
  36. this->DoReset();
  37. }
  38. void cmCommandArgument::Follows(const cmCommandArgument* arg)
  39. {
  40. this->ArgumentsBeforeEmpty = false;
  41. this->ArgumentsBefore.insert(arg);
  42. }
  43. void cmCommandArgument::FollowsGroup(const cmCommandArgumentGroup* group)
  44. {
  45. if (group!=0)
  46. {
  47. this->ArgumentsBeforeEmpty = false;
  48. for(std::vector<cmCommandArgument*>::const_iterator
  49. argIt= group->ContainedArguments.begin();
  50. argIt != group->ContainedArguments.end();
  51. ++argIt)
  52. {
  53. this->ArgumentsBefore.insert(*argIt);
  54. }
  55. }
  56. }
  57. bool cmCommandArgument::MayFollow(const cmCommandArgument* current) const
  58. {
  59. if (this->ArgumentsBeforeEmpty)
  60. {
  61. return true;
  62. }
  63. std::set<const cmCommandArgument*>::const_iterator argIt
  64. = this->ArgumentsBefore.find(current);
  65. if (argIt != this->ArgumentsBefore.end())
  66. {
  67. return true;
  68. }
  69. return false;
  70. }
  71. bool cmCommandArgument::KeyMatches(const std::string& key) const
  72. {
  73. if ((this->Key==0) || (this->Key[0]=='\0'))
  74. {
  75. return true;
  76. }
  77. return (key==this->Key);
  78. }
  79. void cmCommandArgument::ApplyOwnGroup()
  80. {
  81. if (this->Group!=0)
  82. {
  83. for (std::vector<cmCommandArgument*>::const_iterator
  84. it = this->Group->ContainedArguments.begin();
  85. it != this->Group->ContainedArguments.end();
  86. ++it)
  87. {
  88. if(*it != this)
  89. {
  90. this->ArgumentsBefore.insert(*it);
  91. }
  92. }
  93. }
  94. }
  95. void cmCommandArgument::Activate()
  96. {
  97. this->WasActive = true;
  98. this->CurrentIndex = 0;
  99. }
  100. bool cmCommandArgument::Consume(const std::string& arg)
  101. {
  102. bool res=this->DoConsume(arg, this->CurrentIndex);
  103. this->CurrentIndex++;
  104. return res;
  105. }
  106. cmCAStringVector::cmCAStringVector(cmCommandArgumentsHelper* args,
  107. const char* key,
  108. cmCommandArgumentGroup* group)
  109. :cmCommandArgument(args, key, group)
  110. ,Ignore(0)
  111. {
  112. if ((key==0) || (*key==0))
  113. {
  114. this->DataStart = 0;
  115. }
  116. else
  117. {
  118. this->DataStart = 1;
  119. }
  120. }
  121. bool cmCAStringVector::DoConsume(const std::string& arg,unsigned int index)
  122. {
  123. if (index >= this->DataStart)
  124. {
  125. if ((this->Ignore==0) || (arg != this->Ignore))
  126. {
  127. this->Vector.push_back(arg);
  128. }
  129. }
  130. return false;
  131. }
  132. void cmCAStringVector::DoReset()
  133. {
  134. this->Vector.clear();
  135. }
  136. cmCAString::cmCAString(cmCommandArgumentsHelper* args,
  137. const char* key,
  138. cmCommandArgumentGroup* group)
  139. :cmCommandArgument(args, key, group)
  140. {
  141. if ((key==0) || (*key==0))
  142. {
  143. this->DataStart = 0;
  144. }
  145. else
  146. {
  147. this->DataStart = 1;
  148. }
  149. }
  150. bool cmCAString::DoConsume(const std::string& arg, unsigned int index)
  151. {
  152. if (index == this->DataStart)
  153. {
  154. this->String = arg;
  155. }
  156. return index >= this->DataStart;
  157. }
  158. void cmCAString::DoReset()
  159. {
  160. this->String = this->DefaultString;
  161. }
  162. cmCAEnabler::cmCAEnabler(cmCommandArgumentsHelper* args,
  163. const char* key,
  164. cmCommandArgumentGroup* group)
  165. :cmCommandArgument(args, key, group)
  166. ,Enabled(false)
  167. {}
  168. bool cmCAEnabler::DoConsume(const std::string&, unsigned int index)
  169. {
  170. if (index==0)
  171. {
  172. this->Enabled = true;
  173. }
  174. return true;
  175. }
  176. void cmCAEnabler::DoReset()
  177. {
  178. this->Enabled = false;
  179. }
  180. cmCADisabler::cmCADisabler(cmCommandArgumentsHelper* args,
  181. const char* key,
  182. cmCommandArgumentGroup* group)
  183. :cmCommandArgument(args, key, group)
  184. ,Enabled(true)
  185. {}
  186. bool cmCADisabler::DoConsume(const std::string&, unsigned int index)
  187. {
  188. if (index==0)
  189. {
  190. this->Enabled = false;
  191. }
  192. return true;
  193. }
  194. void cmCADisabler::DoReset()
  195. {
  196. this->Enabled = true;
  197. }
  198. void cmCommandArgumentGroup::Follows(const cmCommandArgument* arg)
  199. {
  200. for(std::vector<cmCommandArgument*>::iterator
  201. it = this->ContainedArguments.begin();
  202. it != this->ContainedArguments.end();
  203. ++it)
  204. {
  205. (*it)->Follows(arg);
  206. }
  207. }
  208. void cmCommandArgumentGroup::FollowsGroup(const cmCommandArgumentGroup* group)
  209. {
  210. for(std::vector<cmCommandArgument*>::iterator
  211. it = this->ContainedArguments.begin();
  212. it != this->ContainedArguments.end();
  213. ++it)
  214. {
  215. (*it)->FollowsGroup(group);
  216. }
  217. }
  218. void cmCommandArgumentsHelper::Parse(const std::vector<std::string>* args,
  219. std::vector<std::string>* unconsumedArgs)
  220. {
  221. if(args==0)
  222. {
  223. return;
  224. }
  225. for(std::vector<cmCommandArgument*>::iterator
  226. argIt = this->Arguments.begin();
  227. argIt != this->Arguments.end();
  228. ++argIt)
  229. {
  230. (*argIt)->ApplyOwnGroup();
  231. (*argIt)->Reset();
  232. }
  233. cmCommandArgument* activeArgument = 0;
  234. const cmCommandArgument* previousArgument = 0;
  235. for(std::vector<std::string>::const_iterator it = args->begin();
  236. it != args->end();
  237. ++it)
  238. {
  239. for(std::vector<cmCommandArgument*>::iterator
  240. argIt = this->Arguments.begin();
  241. argIt != this->Arguments.end();
  242. ++argIt)
  243. {
  244. if ((*argIt)->KeyMatches(*it) && ((*argIt)->MayFollow(previousArgument)))
  245. {
  246. activeArgument = *argIt;
  247. activeArgument->Activate();
  248. break;
  249. }
  250. }
  251. if (activeArgument)
  252. {
  253. bool argDone = activeArgument->Consume(*it);
  254. previousArgument = activeArgument;
  255. if (argDone)
  256. {
  257. activeArgument = 0;
  258. }
  259. }
  260. else
  261. {
  262. if (unconsumedArgs!=0)
  263. {
  264. unconsumedArgs->push_back(*it);
  265. }
  266. }
  267. }
  268. }
  269. void cmCommandArgumentsHelper::AddArgument(cmCommandArgument* arg)
  270. {
  271. this->Arguments.push_back(arg);
  272. }