cmDefinitions.cxx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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 "cmDefinitions.h"
  11. //----------------------------------------------------------------------------
  12. cmDefinitions::Def cmDefinitions::NoDef;
  13. //----------------------------------------------------------------------------
  14. cmDefinitions::cmDefinitions(cmDefinitions* parent): Up(parent)
  15. {
  16. }
  17. //----------------------------------------------------------------------------
  18. void cmDefinitions::Reset(cmDefinitions* parent)
  19. {
  20. this->Up = parent;
  21. this->Map.clear();
  22. }
  23. //----------------------------------------------------------------------------
  24. cmDefinitions::Def const&
  25. cmDefinitions::GetInternal(const std::string& key) const
  26. {
  27. MapType::const_iterator i = this->Map.find(key);
  28. if(i != this->Map.end())
  29. {
  30. return i->second;
  31. }
  32. else if(cmDefinitions* up = this->Up)
  33. {
  34. // Query the parent scope.
  35. return up->GetInternal(key);
  36. }
  37. return this->NoDef;
  38. }
  39. //----------------------------------------------------------------------------
  40. cmDefinitions::Def const&
  41. cmDefinitions::SetInternal(const std::string& key, Def const& def)
  42. {
  43. if(this->Up || def.Exists)
  44. {
  45. // In lower scopes we store keys, defined or not.
  46. return (this->Map[key] = def);
  47. }
  48. else
  49. {
  50. // In the top-most scope we need not store undefined keys.
  51. this->Map.erase(key);
  52. return this->NoDef;
  53. }
  54. }
  55. //----------------------------------------------------------------------------
  56. const char* cmDefinitions::Get(const std::string& key) const
  57. {
  58. Def const& def = this->GetInternal(key);
  59. return def.Exists? def.c_str() : 0;
  60. }
  61. //----------------------------------------------------------------------------
  62. void cmDefinitions::Pull(const std::string& key)
  63. {
  64. if (this->Up)
  65. {
  66. Def const& def = this->Up->GetInternal(key);
  67. if (def.Exists)
  68. {
  69. this->SetInternal(key, def);
  70. }
  71. }
  72. }
  73. //----------------------------------------------------------------------------
  74. const char* cmDefinitions::Set(const std::string& key, const char* value)
  75. {
  76. Def const& def = this->SetInternal(key, Def(value));
  77. return def.Exists? def.c_str() : 0;
  78. }
  79. //----------------------------------------------------------------------------
  80. std::set<std::string> cmDefinitions::LocalKeys() const
  81. {
  82. std::set<std::string> keys;
  83. // Consider local definitions.
  84. for(MapType::const_iterator mi = this->Map.begin();
  85. mi != this->Map.end(); ++mi)
  86. {
  87. if (mi->second.Exists)
  88. {
  89. keys.insert(mi->first);
  90. }
  91. }
  92. return keys;
  93. }
  94. //----------------------------------------------------------------------------
  95. cmDefinitions cmDefinitions::Closure() const
  96. {
  97. return cmDefinitions(ClosureTag(), this);
  98. }
  99. //----------------------------------------------------------------------------
  100. cmDefinitions::cmDefinitions(ClosureTag const&, cmDefinitions const* root):
  101. Up(0)
  102. {
  103. std::set<std::string> undefined;
  104. this->ClosureImpl(undefined, root);
  105. }
  106. //----------------------------------------------------------------------------
  107. void cmDefinitions::ClosureImpl(std::set<std::string>& undefined,
  108. cmDefinitions const* defs)
  109. {
  110. // Consider local definitions.
  111. for(MapType::const_iterator mi = defs->Map.begin();
  112. mi != defs->Map.end(); ++mi)
  113. {
  114. // Use this key if it is not already set or unset.
  115. if(this->Map.find(mi->first) == this->Map.end() &&
  116. undefined.find(mi->first) == undefined.end())
  117. {
  118. if(mi->second.Exists)
  119. {
  120. this->Map.insert(*mi);
  121. }
  122. else
  123. {
  124. undefined.insert(mi->first);
  125. }
  126. }
  127. }
  128. // Traverse parents.
  129. if(cmDefinitions const* up = defs->Up)
  130. {
  131. this->ClosureImpl(undefined, up);
  132. }
  133. }
  134. //----------------------------------------------------------------------------
  135. std::set<std::string> cmDefinitions::ClosureKeys() const
  136. {
  137. std::set<std::string> defined;
  138. std::set<std::string> undefined;
  139. this->ClosureKeys(defined, undefined);
  140. return defined;
  141. }
  142. //----------------------------------------------------------------------------
  143. void cmDefinitions::ClosureKeys(std::set<std::string>& defined,
  144. std::set<std::string>& undefined) const
  145. {
  146. // Consider local definitions.
  147. for(MapType::const_iterator mi = this->Map.begin();
  148. mi != this->Map.end(); ++mi)
  149. {
  150. // Use this key if it is not already set or unset.
  151. if(defined.find(mi->first) == defined.end() &&
  152. undefined.find(mi->first) == undefined.end())
  153. {
  154. std::set<std::string>& m = mi->second.Exists? defined : undefined;
  155. m.insert(mi->first);
  156. }
  157. }
  158. // Traverse parents.
  159. if(cmDefinitions const* up = this->Up)
  160. {
  161. up->ClosureKeys(defined, undefined);
  162. }
  163. }