cmLoadCacheCommand.cxx 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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 "cmLoadCacheCommand.h"
  14. // cmLoadCacheCommand
  15. bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& args)
  16. {
  17. if (args.size()< 1)
  18. {
  19. this->SetError("called with wrong number of arguments.");
  20. }
  21. if(args.size() >= 2 && args[1] == "READ_WITH_PREFIX")
  22. {
  23. return this->ReadWithPrefix(args);
  24. }
  25. // Cache entries to be excluded from the import list.
  26. // If this set is empty, all cache entries are brought in
  27. // and they can not be overridden.
  28. bool excludeFiles=false;
  29. unsigned int i;
  30. std::set<std::string> excludes;
  31. for(i=0; i<args.size(); i++)
  32. {
  33. if (excludeFiles)
  34. {
  35. excludes.insert(args[i]);
  36. }
  37. if (args[i] == "EXCLUDE")
  38. {
  39. excludeFiles=true;
  40. }
  41. if (excludeFiles && (args[i] == "INCLUDE_INTERNALS"))
  42. {
  43. break;
  44. }
  45. }
  46. // Internal cache entries to be imported.
  47. // If this set is empty, no internal cache entries are
  48. // brought in.
  49. bool includeFiles=false;
  50. std::set<std::string> includes;
  51. for(i=0; i<args.size(); i++)
  52. {
  53. if (includeFiles)
  54. {
  55. includes.insert(args[i]);
  56. }
  57. if (args[i] == "INCLUDE_INTERNALS")
  58. {
  59. includeFiles=true;
  60. }
  61. if (includeFiles && (args[i] == "EXCLUDE"))
  62. {
  63. break;
  64. }
  65. }
  66. // Loop over each build directory listed in the arguments. Each
  67. // directory has a cache file.
  68. for(i=0; i<args.size(); i++)
  69. {
  70. if ((args[i] == "EXCLUDE") || (args[i] == "INCLUDE_INTERNALS"))
  71. {
  72. break;
  73. }
  74. m_Makefile->GetCacheManager()->LoadCache(args[i].c_str(), false,
  75. excludes, includes);
  76. }
  77. return true;
  78. }
  79. //----------------------------------------------------------------------------
  80. bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args)
  81. {
  82. // Make sure we have a prefix.
  83. if(args.size() < 3)
  84. {
  85. this->SetError("READ_WITH_PREFIX form must specify a prefix.");
  86. return false;
  87. }
  88. // Make sure the cache file exists.
  89. std::string cacheFile = args[0]+"/CMakeCache.txt";
  90. if(!cmSystemTools::FileExists(cacheFile.c_str()))
  91. {
  92. std::string e = "Cannot load cache file from " + cacheFile;
  93. this->SetError(e.c_str());
  94. return false;
  95. }
  96. // Prepare the table of variables to read.
  97. this->Prefix = args[2];
  98. for(unsigned int i=3; i < args.size(); ++i)
  99. {
  100. this->VariablesToRead.insert(args[i]);
  101. }
  102. // Read the cache file.
  103. std::ifstream fin(cacheFile.c_str());
  104. // This is a big hack read loop to overcome a buggy ifstream
  105. // implementation on HP-UX. This should work on all platforms even
  106. // for small buffer sizes.
  107. const int bufferSize = 4096;
  108. char buffer[bufferSize];
  109. std::string line;
  110. while(fin)
  111. {
  112. // Read a block of the file.
  113. fin.read(buffer, bufferSize);
  114. if(fin.gcount())
  115. {
  116. // Parse for newlines directly.
  117. const char* i = buffer;
  118. const char* end = buffer+fin.gcount();
  119. while(i != end)
  120. {
  121. const char* begin = i;
  122. while(i != end && *i != '\n') { ++i; }
  123. if(i == begin || *(i-1) != '\r')
  124. {
  125. // Include this portion of the line.
  126. line += std::string(begin, i-begin);
  127. }
  128. else
  129. {
  130. // Include this portion of the line.
  131. // Don't include the \r in a \r\n pair.
  132. line += std::string(begin, i-1-begin);
  133. }
  134. if(i != end)
  135. {
  136. // Completed a line.
  137. this->CheckLine(line.c_str());
  138. line = "";
  139. // Skip the newline character.
  140. ++i;
  141. }
  142. }
  143. }
  144. }
  145. if(line.length())
  146. {
  147. // Partial last line.
  148. this->CheckLine(line.c_str());
  149. }
  150. return true;
  151. }
  152. //----------------------------------------------------------------------------
  153. void cmLoadCacheCommand::CheckLine(const char* line)
  154. {
  155. // Check one line of the cache file.
  156. std::string var;
  157. std::string value;
  158. if(this->ParseEntry(line, var, value))
  159. {
  160. // Found a real entry. See if this one was requested.
  161. if(this->VariablesToRead.find(var) != this->VariablesToRead.end())
  162. {
  163. // This was requested. Set this variable locally with the given
  164. // prefix.
  165. var = this->Prefix + var;
  166. if(value.length())
  167. {
  168. m_Makefile->AddDefinition(var.c_str(), value.c_str());
  169. }
  170. else
  171. {
  172. m_Makefile->RemoveDefinition(var.c_str());
  173. }
  174. }
  175. }
  176. }
  177. //----------------------------------------------------------------------------
  178. bool cmLoadCacheCommand::ParseEntry(const char* entry, std::string& var,
  179. std::string& value)
  180. {
  181. // input line is: key:type=value
  182. cmRegularExpression reg("^([^:]*):([^=]*)=(.*[^\t ]|[\t ]*)[\t ]*$");
  183. // input line is: "key":type=value
  184. cmRegularExpression regQuoted("^\"([^\"]*)\":([^=]*)=(.*[^\t ]|[\t ]*)[\t ]*$");
  185. bool flag = false;
  186. if(regQuoted.find(entry))
  187. {
  188. var = regQuoted.match(1);
  189. value = regQuoted.match(3);
  190. flag = true;
  191. }
  192. else if (reg.find(entry))
  193. {
  194. var = reg.match(1);
  195. value = reg.match(3);
  196. flag = true;
  197. }
  198. // if value is enclosed in single quotes ('foo') then remove them
  199. // it is used to enclose trailing space or tab
  200. if (flag &&
  201. value.size() >= 2 &&
  202. value[0] == '\'' &&
  203. value[value.size() - 1] == '\'')
  204. {
  205. value = value.substr(1, value.size() - 2);
  206. }
  207. return flag;
  208. }