cmCacheManager.cxx 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  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 "cmCacheManager.h"
  14. #include "cmSystemTools.h"
  15. #include "cmCacheManager.h"
  16. #include "cmMakefile.h"
  17. #include "cmake.h"
  18. #include <cmsys/Directory.hxx>
  19. #include <cmsys/Glob.hxx>
  20. #include <cmsys/RegularExpression.hxx>
  21. #if defined(_WIN32) || defined(__CYGWIN__)
  22. # include <windows.h>
  23. #endif // _WIN32
  24. const char* cmCacheManagerTypes[] =
  25. { "BOOL",
  26. "PATH",
  27. "FILEPATH",
  28. "STRING",
  29. "INTERNAL",
  30. "STATIC",
  31. "UNINITIALIZED",
  32. 0
  33. };
  34. const char* cmCacheManager::TypeToString(cmCacheManager::CacheEntryType type)
  35. {
  36. if ( type > 6 )
  37. {
  38. return cmCacheManagerTypes[6];
  39. }
  40. return cmCacheManagerTypes[type];
  41. }
  42. cmCacheManager::CacheEntryType cmCacheManager::StringToType(const char* s)
  43. {
  44. int i = 0;
  45. while(cmCacheManagerTypes[i])
  46. {
  47. if(strcmp(s, cmCacheManagerTypes[i]) == 0)
  48. {
  49. return static_cast<CacheEntryType>(i);
  50. }
  51. ++i;
  52. }
  53. return STRING;
  54. }
  55. bool cmCacheManager::LoadCache(cmMakefile* mf)
  56. {
  57. return this->LoadCache(mf->GetHomeOutputDirectory());
  58. }
  59. bool cmCacheManager::LoadCache(const char* path)
  60. {
  61. return this->LoadCache(path,true);
  62. }
  63. bool cmCacheManager::LoadCache(const char* path,
  64. bool internal)
  65. {
  66. std::set<cmStdString> emptySet;
  67. return this->LoadCache(path, internal, emptySet, emptySet);
  68. }
  69. bool cmCacheManager::ParseEntry(const char* entry,
  70. std::string& var,
  71. std::string& value)
  72. {
  73. // input line is: key:type=value
  74. static cmsys::RegularExpression reg(
  75. "^([^:]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  76. // input line is: "key":type=value
  77. static cmsys::RegularExpression regQuoted(
  78. "^\"([^\"]*)\"=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  79. bool flag = false;
  80. if(regQuoted.find(entry))
  81. {
  82. var = regQuoted.match(1);
  83. value = regQuoted.match(2);
  84. flag = true;
  85. }
  86. else if (reg.find(entry))
  87. {
  88. var = reg.match(1);
  89. value = reg.match(2);
  90. flag = true;
  91. }
  92. // if value is enclosed in single quotes ('foo') then remove them
  93. // it is used to enclose trailing space or tab
  94. if (flag &&
  95. value.size() >= 2 &&
  96. value[0] == '\'' &&
  97. value[value.size() - 1] == '\'')
  98. {
  99. value = value.substr(1,
  100. value.size() - 2);
  101. }
  102. return flag;
  103. }
  104. bool cmCacheManager::ParseEntry(const char* entry,
  105. std::string& var,
  106. std::string& value,
  107. CacheEntryType& type)
  108. {
  109. // input line is: key:type=value
  110. static cmsys::RegularExpression reg(
  111. "^([^:]*):([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  112. // input line is: "key":type=value
  113. static cmsys::RegularExpression regQuoted(
  114. "^\"([^\"]*)\":([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  115. bool flag = false;
  116. if(regQuoted.find(entry))
  117. {
  118. var = regQuoted.match(1);
  119. type = cmCacheManager::StringToType(regQuoted.match(2).c_str());
  120. value = regQuoted.match(3);
  121. flag = true;
  122. }
  123. else if (reg.find(entry))
  124. {
  125. var = reg.match(1);
  126. type = cmCacheManager::StringToType(reg.match(2).c_str());
  127. value = reg.match(3);
  128. flag = true;
  129. }
  130. // if value is enclosed in single quotes ('foo') then remove them
  131. // it is used to enclose trailing space or tab
  132. if (flag &&
  133. value.size() >= 2 &&
  134. value[0] == '\'' &&
  135. value[value.size() - 1] == '\'')
  136. {
  137. value = value.substr(1,
  138. value.size() - 2);
  139. }
  140. return flag;
  141. }
  142. void cmCacheManager::CleanCMakeFiles(const char* path)
  143. {
  144. std::string glob = path;
  145. glob += cmake::GetCMakeFilesDirectory();
  146. glob += "/*.cmake";
  147. cmsys::Glob globIt;
  148. globIt.FindFiles(glob);
  149. std::vector<std::string> files = globIt.GetFiles();
  150. for(std::vector<std::string>::iterator i = files.begin();
  151. i != files.end(); ++i)
  152. {
  153. cmSystemTools::RemoveFile(i->c_str());
  154. }
  155. }
  156. bool cmCacheManager::LoadCache(const char* path,
  157. bool internal,
  158. std::set<cmStdString>& excludes,
  159. std::set<cmStdString>& includes)
  160. {
  161. std::string cacheFile = path;
  162. cacheFile += "/CMakeCache.txt";
  163. // clear the old cache, if we are reading in internal values
  164. if ( internal )
  165. {
  166. this->Cache.clear();
  167. }
  168. if(!cmSystemTools::FileExists(cacheFile.c_str()))
  169. {
  170. this->CleanCMakeFiles(path);
  171. return false;
  172. }
  173. std::ifstream fin(cacheFile.c_str());
  174. if(!fin)
  175. {
  176. return false;
  177. }
  178. const char *realbuffer;
  179. std::string buffer;
  180. std::string entryKey;
  181. while(fin)
  182. {
  183. // Format is key:type=value
  184. CacheEntry e;
  185. cmSystemTools::GetLineFromStream(fin, buffer);
  186. realbuffer = buffer.c_str();
  187. while(*realbuffer != '0' &&
  188. (*realbuffer == ' ' ||
  189. *realbuffer == '\t' ||
  190. *realbuffer == '\r' ||
  191. *realbuffer == '\n'))
  192. {
  193. realbuffer++;
  194. }
  195. // skip blank lines and comment lines
  196. if(realbuffer[0] == '#' || realbuffer[0] == 0)
  197. {
  198. continue;
  199. }
  200. while(realbuffer[0] == '/' && realbuffer[1] == '/')
  201. {
  202. e.Properties["HELPSTRING"] += &realbuffer[2];
  203. cmSystemTools::GetLineFromStream(fin, buffer);
  204. realbuffer = buffer.c_str();
  205. if(!fin)
  206. {
  207. continue;
  208. }
  209. }
  210. if(cmCacheManager::ParseEntry(realbuffer, entryKey, e.Value, e.Type))
  211. {
  212. if ( excludes.find(entryKey) == excludes.end() )
  213. {
  214. // Load internal values if internal is set.
  215. // If the entry is not internal to the cache being loaded
  216. // or if it is in the list of internal entries to be
  217. // imported, load it.
  218. if ( internal || (e.Type != INTERNAL) ||
  219. (includes.find(entryKey) != includes.end()) )
  220. {
  221. // If we are loading the cache from another project,
  222. // make all loaded entries internal so that it is
  223. // not visible in the gui
  224. if (!internal)
  225. {
  226. e.Type = INTERNAL;
  227. e.Properties["HELPSTRING"] = "DO NOT EDIT, ";
  228. e.Properties["HELPSTRING"] += entryKey;
  229. e.Properties["HELPSTRING"] += " loaded from external file. "
  230. "To change this value edit this file: ";
  231. e.Properties["HELPSTRING"] += path;
  232. e.Properties["HELPSTRING"] += "/CMakeCache.txt" ;
  233. }
  234. if ( e.Type == cmCacheManager::INTERNAL &&
  235. (entryKey.size() > strlen("-ADVANCED")) &&
  236. strcmp(entryKey.c_str() + (entryKey.size() -
  237. strlen("-ADVANCED")), "-ADVANCED") == 0 )
  238. {
  239. std::string value = e.Value;
  240. std::string akey =
  241. entryKey.substr(0, (entryKey.size() - strlen("-ADVANCED")));
  242. cmCacheManager::CacheIterator it =
  243. this->GetCacheIterator(akey.c_str());
  244. if ( it.IsAtEnd() )
  245. {
  246. e.Type = cmCacheManager::UNINITIALIZED;
  247. this->Cache[akey] = e;
  248. }
  249. if (!it.Find(akey.c_str()))
  250. {
  251. cmSystemTools::Error("Internal CMake error when reading cache");
  252. }
  253. it.SetProperty("ADVANCED", value.c_str());
  254. }
  255. else if ( e.Type == cmCacheManager::INTERNAL &&
  256. (entryKey.size() > strlen("-MODIFIED")) &&
  257. strcmp(entryKey.c_str() + (entryKey.size() -
  258. strlen("-MODIFIED")), "-MODIFIED") == 0 )
  259. {
  260. std::string value = e.Value;
  261. std::string akey =
  262. entryKey.substr(0, (entryKey.size() - strlen("-MODIFIED")));
  263. cmCacheManager::CacheIterator it =
  264. this->GetCacheIterator(akey.c_str());
  265. if ( it.IsAtEnd() )
  266. {
  267. e.Type = cmCacheManager::UNINITIALIZED;
  268. this->Cache[akey] = e;
  269. }
  270. if (!it.Find(akey.c_str()))
  271. {
  272. cmSystemTools::Error("Internal CMake error when reading cache");
  273. }
  274. it.SetProperty("MODIFIED", value.c_str());
  275. }
  276. else
  277. {
  278. e.Initialized = true;
  279. this->Cache[entryKey] = e;
  280. }
  281. }
  282. }
  283. }
  284. else
  285. {
  286. cmSystemTools::Error("Parse error in cache file ", cacheFile.c_str(),
  287. ". Offending entry: ", realbuffer);
  288. }
  289. }
  290. // if CMAKE version not found in the list file
  291. // add them as version 0.0
  292. if(!this->GetCacheValue("CMAKE_CACHE_MINOR_VERSION"))
  293. {
  294. this->AddCacheEntry("CMAKE_CACHE_MINOR_VERSION", "0",
  295. "Minor version of cmake used to create the "
  296. "current loaded cache", cmCacheManager::INTERNAL);
  297. this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION", "0",
  298. "Major version of cmake used to create the "
  299. "current loaded cache", cmCacheManager::INTERNAL);
  300. }
  301. // check to make sure the cache directory has not
  302. // been moved
  303. if ( internal && this->GetCacheValue("CMAKE_CACHEFILE_DIR") )
  304. {
  305. std::string currentcwd = path;
  306. std::string oldcwd = this->GetCacheValue("CMAKE_CACHEFILE_DIR");
  307. cmSystemTools::ConvertToUnixSlashes(currentcwd);
  308. currentcwd += "/CMakeCache.txt";
  309. oldcwd += "/CMakeCache.txt";
  310. if(!cmSystemTools::SameFile(oldcwd.c_str(), currentcwd.c_str()))
  311. {
  312. std::string message =
  313. std::string("The current CMakeCache.txt directory ") +
  314. currentcwd + std::string(" is different than the directory ") +
  315. std::string(this->GetCacheValue("CMAKE_CACHEFILE_DIR")) +
  316. std::string(" where CMackeCache.txt was created. This may result "
  317. "in binaries being created in the wrong place. If you "
  318. "are not sure, reedit the CMakeCache.txt");
  319. cmSystemTools::Error(message.c_str());
  320. }
  321. }
  322. return true;
  323. }
  324. bool cmCacheManager::SaveCache(cmMakefile* mf)
  325. {
  326. return this->SaveCache(mf->GetHomeOutputDirectory());
  327. }
  328. bool cmCacheManager::SaveCache(const char* path)
  329. {
  330. std::string cacheFile = path;
  331. cacheFile += "/CMakeCache.txt";
  332. std::string tempFile = cacheFile;
  333. tempFile += ".tmp";
  334. std::ofstream fout(tempFile.c_str());
  335. if(!fout)
  336. {
  337. cmSystemTools::Error("Unable to open cache file for save. ",
  338. cacheFile.c_str());
  339. cmSystemTools::ReportLastSystemError("");
  340. return false;
  341. }
  342. // before writing the cache, update the version numbers
  343. // to the
  344. char temp[1024];
  345. sprintf(temp, "%d", cmMakefile::GetMinorVersion());
  346. this->AddCacheEntry("CMAKE_CACHE_MINOR_VERSION", temp,
  347. "Minor version of cmake used to create the "
  348. "current loaded cache", cmCacheManager::INTERNAL);
  349. sprintf(temp, "%d", cmMakefile::GetMajorVersion());
  350. this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION", temp,
  351. "Major version of cmake used to create the "
  352. "current loaded cache", cmCacheManager::INTERNAL);
  353. this->AddCacheEntry("CMAKE_CACHE_RELEASE_VERSION",
  354. cmMakefile::GetReleaseVersion(),
  355. "Major version of cmake used to create the "
  356. "current loaded cache", cmCacheManager::INTERNAL);
  357. // Let us store the current working directory so that if somebody
  358. // Copies it, he will not be surprised
  359. std::string currentcwd = path;
  360. if ( currentcwd[0] >= 'A' && currentcwd[0] <= 'Z' &&
  361. currentcwd[1] == ':' )
  362. {
  363. currentcwd[0] = currentcwd[0] - 'A' + 'a';
  364. }
  365. cmSystemTools::ConvertToUnixSlashes(currentcwd);
  366. this->AddCacheEntry("CMAKE_CACHEFILE_DIR", currentcwd.c_str(),
  367. "This is the directory where this CMakeCahe.txt"
  368. " was created", cmCacheManager::INTERNAL);
  369. fout << "# This is the CMakeCache file.\n"
  370. << "# For build in directory: " << currentcwd << "\n";
  371. cmCacheManager::CacheEntry* cmakeCacheEntry
  372. = this->GetCacheEntry("CMAKE_COMMAND");
  373. if ( cmakeCacheEntry )
  374. {
  375. fout << "# It was generated by CMake: " <<
  376. cmakeCacheEntry->Value << std::endl;
  377. }
  378. fout << "# You can edit this file to change values found and used by cmake."
  379. << std::endl
  380. << "# If you do not want to change any of the values, simply exit the "
  381. "editor." << std::endl
  382. << "# If you do want to change a value, simply edit, save, and exit "
  383. "the editor." << std::endl
  384. << "# The syntax for the file is as follows:\n"
  385. << "# KEY:TYPE=VALUE\n"
  386. << "# KEY is the name of a variable in the cache.\n"
  387. << "# TYPE is a hint to GUI's for the type of VALUE, DO NOT EDIT "
  388. "TYPE!." << std::endl
  389. << "# VALUE is the current value for the KEY.\n\n";
  390. fout << "########################\n";
  391. fout << "# EXTERNAL cache entries\n";
  392. fout << "########################\n";
  393. fout << "\n";
  394. for( std::map<cmStdString, CacheEntry>::const_iterator i =
  395. this->Cache.begin(); i != this->Cache.end(); ++i)
  396. {
  397. const CacheEntry& ce = (*i).second;
  398. CacheEntryType t = ce.Type;
  399. if(t == cmCacheManager::UNINITIALIZED || !ce.Initialized)
  400. {
  401. /*
  402. // This should be added in, but is not for now.
  403. cmSystemTools::Error("Cache entry \"", (*i).first.c_str(),
  404. "\" is uninitialized");
  405. */
  406. }
  407. else if(t != INTERNAL)
  408. {
  409. // Format is key:type=value
  410. std::map<cmStdString,cmStdString>::const_iterator it =
  411. ce.Properties.find("HELPSTRING");
  412. if ( it == ce.Properties.end() )
  413. {
  414. cmCacheManager::OutputHelpString(fout, "Missing description");
  415. }
  416. else
  417. {
  418. cmCacheManager::OutputHelpString(fout, it->second);
  419. }
  420. std::string key;
  421. // support : in key name by double quoting
  422. if((*i).first.find(':') != std::string::npos ||
  423. (*i).first.find("//") == 0)
  424. {
  425. key = "\"";
  426. key += i->first;
  427. key += "\"";
  428. }
  429. else
  430. {
  431. key = i->first;
  432. }
  433. fout << key.c_str() << ":"
  434. << cmCacheManagerTypes[t] << "=";
  435. // if value has trailing space or tab, enclose it in single quotes
  436. if (ce.Value.size() &&
  437. (ce.Value[ce.Value.size() - 1] == ' ' ||
  438. ce.Value[ce.Value.size() - 1] == '\t'))
  439. {
  440. fout << '\'' << ce.Value << '\'';
  441. }
  442. else
  443. {
  444. fout << ce.Value;
  445. }
  446. fout << "\n\n";
  447. }
  448. }
  449. fout << "\n";
  450. fout << "########################\n";
  451. fout << "# INTERNAL cache entries\n";
  452. fout << "########################\n";
  453. fout << "\n";
  454. for( cmCacheManager::CacheIterator i = this->NewIterator();
  455. !i.IsAtEnd(); i.Next())
  456. {
  457. if ( !i.Initialized() )
  458. {
  459. continue;
  460. }
  461. CacheEntryType t = i.GetType();
  462. bool advanced = i.PropertyExists("ADVANCED");
  463. if ( advanced )
  464. {
  465. // Format is key:type=value
  466. std::string key;
  467. std::string rkey = i.GetName();
  468. std::string helpstring;
  469. // If this is advanced variable, we have to do some magic for
  470. // backward compatibility
  471. helpstring = "Advanced flag for variable: ";
  472. helpstring += i.GetName();
  473. rkey += "-ADVANCED";
  474. cmCacheManager::OutputHelpString(fout, helpstring.c_str());
  475. // support : in key name by double quoting
  476. if(rkey.find(':') != std::string::npos ||
  477. rkey.find("//") == 0)
  478. {
  479. key = "\"";
  480. key += rkey;
  481. key += "\"";
  482. }
  483. else
  484. {
  485. key = rkey;
  486. }
  487. fout << key.c_str() << ":INTERNAL="
  488. << (i.GetPropertyAsBool("ADVANCED") ? "1" : "0") << "\n";
  489. }
  490. bool modified = i.PropertyExists("MODIFIED");
  491. if ( modified )
  492. {
  493. // Format is key:type=value
  494. std::string key;
  495. std::string rkey = i.GetName();
  496. std::string helpstring;
  497. // If this is advanced variable, we have to do some magic for
  498. // backward compatibility
  499. helpstring = "Modified flag for variable: ";
  500. helpstring += i.GetName();
  501. rkey += "-MODIFIED";
  502. cmCacheManager::OutputHelpString(fout, helpstring.c_str());
  503. // support : in key name by double quoting
  504. if(rkey.find(':') != std::string::npos ||
  505. rkey.find("//") == 0)
  506. {
  507. key = "\"";
  508. key += rkey;
  509. key += "\"";
  510. }
  511. else
  512. {
  513. key = rkey;
  514. }
  515. fout << key.c_str() << ":INTERNAL="
  516. << (i.GetPropertyAsBool("MODIFIED") ? "1" : "0") << "\n";
  517. }
  518. if(t == cmCacheManager::INTERNAL)
  519. {
  520. // Format is key:type=value
  521. std::string key;
  522. std::string rkey = i.GetName();
  523. std::string helpstring;
  524. const char* hs = i.GetProperty("HELPSTRING");
  525. if ( hs )
  526. {
  527. helpstring = i.GetProperty("HELPSTRING");
  528. }
  529. else
  530. {
  531. helpstring = "";
  532. }
  533. cmCacheManager::OutputHelpString(fout, helpstring.c_str());
  534. // support : in key name by double quoting
  535. if(rkey.find(':') != std::string::npos ||
  536. rkey.find("//") == 0)
  537. {
  538. key = "\"";
  539. key += rkey;
  540. key += "\"";
  541. }
  542. else
  543. {
  544. key = rkey;
  545. }
  546. fout << key.c_str() << ":"
  547. << cmCacheManagerTypes[t] << "=";
  548. // if value has trailing space or tab, enclose it in single quotes
  549. std::string value = i.GetValue();
  550. if (value.size() &&
  551. (value[value.size() - 1] == ' ' ||
  552. value[value.size() - 1] == '\t'))
  553. {
  554. fout << '\'' << value << '\'';
  555. }
  556. else
  557. {
  558. fout << value;
  559. }
  560. fout << "\n";
  561. }
  562. }
  563. fout << "\n";
  564. fout.close();
  565. cmSystemTools::CopyFileIfDifferent(tempFile.c_str(),
  566. cacheFile.c_str());
  567. cmSystemTools::RemoveFile(tempFile.c_str());
  568. std::string checkCacheFile = path;
  569. checkCacheFile += cmake::GetCMakeFilesDirectory();
  570. cmSystemTools::MakeDirectory(checkCacheFile.c_str());
  571. checkCacheFile += "/cmake.check_cache";
  572. std::ofstream checkCache(checkCacheFile.c_str());
  573. if(!checkCache)
  574. {
  575. cmSystemTools::Error("Unable to open check cache file for write. ",
  576. checkCacheFile.c_str());
  577. return false;
  578. }
  579. checkCache << "# This file is generated by cmake for dependency checking "
  580. "of the CMakeCache.txt file\n";
  581. return true;
  582. }
  583. bool cmCacheManager::DeleteCache(const char* path)
  584. {
  585. std::string cacheFile = path;
  586. cmSystemTools::ConvertToUnixSlashes(cacheFile);
  587. std::string cmakeFiles = cacheFile;
  588. cacheFile += "/CMakeCache.txt";
  589. cmSystemTools::RemoveFile(cacheFile.c_str());
  590. // now remove the files in the CMakeFiles directory
  591. // this cleans up language cache files
  592. cmsys::Directory dir;
  593. cmakeFiles += cmake::GetCMakeFilesDirectory();
  594. dir.Load(cmakeFiles.c_str());
  595. for (unsigned long fileNum = 0;
  596. fileNum < dir.GetNumberOfFiles();
  597. ++fileNum)
  598. {
  599. if(!cmSystemTools::
  600. FileIsDirectory(dir.GetFile(fileNum)))
  601. {
  602. std::string fullPath = cmakeFiles;
  603. fullPath += "/";
  604. fullPath += dir.GetFile(fileNum);
  605. cmSystemTools::RemoveFile(fullPath.c_str());
  606. }
  607. }
  608. return true;
  609. }
  610. void cmCacheManager::OutputHelpString(std::ofstream& fout,
  611. const std::string& helpString)
  612. {
  613. std::string::size_type end = helpString.size();
  614. if(end == 0)
  615. {
  616. return;
  617. }
  618. std::string oneLine;
  619. std::string::size_type pos = 0;
  620. std::string::size_type nextBreak = 60;
  621. bool done = false;
  622. while(!done)
  623. {
  624. if(nextBreak >= end)
  625. {
  626. nextBreak = end;
  627. done = true;
  628. }
  629. else
  630. {
  631. while(nextBreak < end && helpString[nextBreak] != ' ')
  632. {
  633. nextBreak++;
  634. }
  635. }
  636. oneLine = helpString.substr(pos, nextBreak - pos);
  637. fout << "//" << oneLine.c_str() << "\n";
  638. pos = nextBreak;
  639. nextBreak += 60;
  640. }
  641. }
  642. void cmCacheManager::RemoveCacheEntry(const char* key)
  643. {
  644. CacheEntryMap::iterator i = this->Cache.find(key);
  645. if(i != this->Cache.end())
  646. {
  647. this->Cache.erase(i);
  648. }
  649. else
  650. {
  651. std::cerr << "Failed to remove entry:" << key << std::endl;
  652. }
  653. }
  654. cmCacheManager::CacheEntry *cmCacheManager::GetCacheEntry(const char* key)
  655. {
  656. CacheEntryMap::iterator i = this->Cache.find(key);
  657. if(i != this->Cache.end())
  658. {
  659. return &i->second;
  660. }
  661. return 0;
  662. }
  663. cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(
  664. const char *key)
  665. {
  666. return CacheIterator(*this, key);
  667. }
  668. const char* cmCacheManager::GetCacheValue(const char* key) const
  669. {
  670. CacheEntryMap::const_iterator i = this->Cache.find(key);
  671. if(i != this->Cache.end() &&
  672. i->second.Initialized)
  673. {
  674. return i->second.Value.c_str();
  675. }
  676. return 0;
  677. }
  678. void cmCacheManager::PrintCache(std::ostream& out) const
  679. {
  680. out << "=================================================" << std::endl;
  681. out << "CMakeCache Contents:" << std::endl;
  682. for(std::map<cmStdString, CacheEntry>::const_iterator i =
  683. this->Cache.begin(); i != this->Cache.end(); ++i)
  684. {
  685. if((*i).second.Type != INTERNAL)
  686. {
  687. out << (*i).first.c_str() << " = " << (*i).second.Value.c_str()
  688. << std::endl;
  689. }
  690. }
  691. out << "\n\n";
  692. out << "To change values in the CMakeCache, "
  693. << std::endl << "edit CMakeCache.txt in your output directory.\n";
  694. out << "=================================================" << std::endl;
  695. }
  696. void cmCacheManager::AddCacheEntry(const char* key,
  697. const char* value,
  698. const char* helpString,
  699. CacheEntryType type)
  700. {
  701. CacheEntry& e = this->Cache[key];
  702. if ( value )
  703. {
  704. e.Value = value;
  705. e.Initialized = true;
  706. }
  707. else
  708. {
  709. e.Value = "";
  710. }
  711. e.Type = type;
  712. // make sure we only use unix style paths
  713. if(type == FILEPATH || type == PATH)
  714. {
  715. cmSystemTools::ConvertToUnixSlashes(e.Value);
  716. }
  717. if ( helpString )
  718. {
  719. e.Properties["HELPSTRING"] = helpString;
  720. }
  721. else
  722. {
  723. e.Properties["HELPSTRING"] =
  724. "(This variable does not exists and should not be used)";
  725. }
  726. this->Cache[key] = e;
  727. }
  728. void cmCacheManager::AddCacheEntry(const char* key, bool v,
  729. const char* helpString)
  730. {
  731. if(v)
  732. {
  733. this->AddCacheEntry(key, "ON", helpString, cmCacheManager::BOOL);
  734. }
  735. else
  736. {
  737. this->AddCacheEntry(key, "OFF", helpString, cmCacheManager::BOOL);
  738. }
  739. }
  740. bool cmCacheManager::CacheIterator::IsAtEnd() const
  741. {
  742. return this->Position == this->Container.Cache.end();
  743. }
  744. void cmCacheManager::CacheIterator::Begin()
  745. {
  746. this->Position = this->Container.Cache.begin();
  747. }
  748. bool cmCacheManager::CacheIterator::Find(const char* key)
  749. {
  750. this->Position = this->Container.Cache.find(key);
  751. return !this->IsAtEnd();
  752. }
  753. void cmCacheManager::CacheIterator::Next()
  754. {
  755. if (!this->IsAtEnd())
  756. {
  757. ++this->Position;
  758. }
  759. }
  760. void cmCacheManager::CacheIterator::SetValue(const char* value)
  761. {
  762. if (this->IsAtEnd())
  763. {
  764. return;
  765. }
  766. CacheEntry* entry = &this->GetEntry();
  767. if ( value )
  768. {
  769. entry->Value = value;
  770. entry->Initialized = true;
  771. }
  772. else
  773. {
  774. entry->Value = "";
  775. }
  776. }
  777. const char* cmCacheManager::CacheIterator::GetProperty(
  778. const char* property) const
  779. {
  780. // make sure it is not at the end
  781. if (this->IsAtEnd())
  782. {
  783. return 0;
  784. }
  785. if ( !strcmp(property, "TYPE") || !strcmp(property, "VALUE") )
  786. {
  787. cmSystemTools::Error("Property \"", property,
  788. "\" cannot be accessed through the GetProperty()");
  789. return 0;
  790. }
  791. const CacheEntry* ent = &this->GetEntry();
  792. std::map<cmStdString,cmStdString>::const_iterator it =
  793. ent->Properties.find(property);
  794. if ( it == ent->Properties.end() )
  795. {
  796. return 0;
  797. }
  798. return it->second.c_str();
  799. }
  800. void cmCacheManager::CacheIterator::SetProperty(const char* p, const char* v)
  801. {
  802. // make sure it is not at the end
  803. if (this->IsAtEnd())
  804. {
  805. return;
  806. }
  807. if ( !strcmp(p, "TYPE") || !strcmp(p, "VALUE") )
  808. {
  809. cmSystemTools::Error("Property \"", p,
  810. "\" cannot be accessed through the SetProperty()");
  811. return;
  812. }
  813. CacheEntry* ent = &this->GetEntry();
  814. ent->Properties[p] = v;
  815. }
  816. bool cmCacheManager::CacheIterator::GetValueAsBool() const
  817. {
  818. return cmSystemTools::IsOn(this->GetEntry().Value.c_str());
  819. }
  820. bool cmCacheManager::CacheIterator::GetPropertyAsBool(
  821. const char* property) const
  822. {
  823. // make sure it is not at the end
  824. if (this->IsAtEnd())
  825. {
  826. return false;
  827. }
  828. if ( !strcmp(property, "TYPE") || !strcmp(property, "VALUE") )
  829. {
  830. cmSystemTools::Error("Property \"", property,
  831. "\" cannot be accessed through the GetPropertyAsBool()");
  832. return false;
  833. }
  834. const CacheEntry* ent = &this->GetEntry();
  835. std::map<cmStdString,cmStdString>::const_iterator it =
  836. ent->Properties.find(property);
  837. if ( it == ent->Properties.end() )
  838. {
  839. return false;
  840. }
  841. return cmSystemTools::IsOn(it->second.c_str());
  842. }
  843. void cmCacheManager::CacheIterator::SetProperty(const char* p, bool v)
  844. {
  845. // make sure it is not at the end
  846. if (this->IsAtEnd())
  847. {
  848. return;
  849. }
  850. if ( !strcmp(p, "TYPE") || !strcmp(p, "VALUE") )
  851. {
  852. cmSystemTools::Error("Property \"", p,
  853. "\" cannot be accessed through the SetProperty()");
  854. return;
  855. }
  856. CacheEntry* ent = &this->GetEntry();
  857. ent->Properties[p] = v ? "ON" : "OFF";
  858. }
  859. bool cmCacheManager::CacheIterator::PropertyExists(const char* property) const
  860. {
  861. // make sure it is not at the end
  862. if (this->IsAtEnd())
  863. {
  864. return false;
  865. }
  866. if ( !strcmp(property, "TYPE") || !strcmp(property, "VALUE") )
  867. {
  868. cmSystemTools::Error("Property \"", property,
  869. "\" cannot be accessed through the PropertyExists()");
  870. return false;
  871. }
  872. const CacheEntry* ent = &this->GetEntry();
  873. std::map<cmStdString,cmStdString>::const_iterator it =
  874. ent->Properties.find(property);
  875. if ( it == ent->Properties.end() )
  876. {
  877. return false;
  878. }
  879. return true;
  880. }