cmCacheManager.cxx 26 KB

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