cmDefinitions.cxx 5.1 KB

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