cmSetCommand.cxx 5.2 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 "cmSetCommand.h"
  11. // cmSetCommand
  12. bool cmSetCommand
  13. ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
  14. {
  15. if(args.size() < 1 )
  16. {
  17. this->SetError("called with incorrect number of arguments");
  18. return false;
  19. }
  20. // watch for ENV signatures
  21. const char* variable = args[0].c_str(); // VAR is always first
  22. if (cmHasLiteralPrefix(variable, "ENV{") && strlen(variable) > 5)
  23. {
  24. // what is the variable name
  25. char *varName = new char [strlen(variable)];
  26. strncpy(varName,variable+4,strlen(variable)-5);
  27. varName[strlen(variable)-5] = '\0';
  28. std::string putEnvArg = varName;
  29. putEnvArg += "=";
  30. // what is the current value if any
  31. const char *currValue = getenv(varName);
  32. delete [] varName;
  33. // will it be set to something, then set it
  34. if (args.size() > 1 && !args[1].empty())
  35. {
  36. // but only if it is different from current value
  37. if (!currValue || strcmp(currValue,args[1].c_str()))
  38. {
  39. putEnvArg += args[1];
  40. cmSystemTools::PutEnv(putEnvArg);
  41. }
  42. return true;
  43. }
  44. // if it will be cleared, then clear it if it isn;t already clear
  45. if (currValue)
  46. {
  47. cmSystemTools::PutEnv(putEnvArg);
  48. }
  49. return true;
  50. }
  51. // SET (VAR) // Removes the definition of VAR.
  52. if (args.size() == 1)
  53. {
  54. this->Makefile->RemoveDefinition(args[0]);
  55. return true;
  56. }
  57. // SET (VAR PARENT_SCOPE) // Removes the definition of VAR
  58. // in the parent scope.
  59. else if (args.size() == 2 && args[args.size()-1] == "PARENT_SCOPE")
  60. {
  61. this->Makefile->RaiseScope(variable, 0);
  62. return true;
  63. }
  64. // here are the remaining options
  65. // SET (VAR value )
  66. // SET (VAR value PARENT_SCOPE)
  67. // SET (VAR CACHE TYPE "doc String" [FORCE])
  68. // SET (VAR value CACHE TYPE "doc string" [FORCE])
  69. std::string value; // optional
  70. bool cache = false; // optional
  71. bool force = false; // optional
  72. bool parentScope = false;
  73. cmCacheManager::CacheEntryType type
  74. = cmCacheManager::STRING; // required if cache
  75. const char* docstring = 0; // required if cache
  76. unsigned int ignoreLastArgs = 0;
  77. // look for PARENT_SCOPE argument
  78. if (args.size() > 1 && args[args.size()-1] == "PARENT_SCOPE")
  79. {
  80. parentScope = true;
  81. ignoreLastArgs++;
  82. }
  83. else
  84. {
  85. // look for FORCE argument
  86. if (args.size() > 4 && args[args.size()-1] == "FORCE")
  87. {
  88. force = true;
  89. ignoreLastArgs++;
  90. }
  91. // check for cache signature
  92. if (args.size() > 3 && args[args.size() - 3 - (force ? 1 : 0)] == "CACHE")
  93. {
  94. cache = true;
  95. ignoreLastArgs+=3;
  96. }
  97. }
  98. // collect any values into a single semi-colon separated value list
  99. if(static_cast<unsigned short>(args.size()) >
  100. static_cast<unsigned short>(1 + ignoreLastArgs))
  101. {
  102. value = args[1];
  103. size_t endPos = args.size() - ignoreLastArgs;
  104. for(size_t i = 2; i < endPos; ++i)
  105. {
  106. value += ";";
  107. value += args[i];
  108. }
  109. }
  110. if (parentScope)
  111. {
  112. this->Makefile->RaiseScope(variable, value.c_str());
  113. return true;
  114. }
  115. // we should be nice and try to catch some simple screwups if the last or
  116. // next to last args are CACHE then they screwed up. If they used FORCE
  117. // without CACHE they screwed up
  118. if ((args[args.size() - 1] == "CACHE") ||
  119. (args.size() > 1 && args[args.size() - 2] == "CACHE") ||
  120. (force && !cache))
  121. {
  122. this->SetError("given invalid arguments for CACHE mode.");
  123. return false;
  124. }
  125. if(cache)
  126. {
  127. std::string::size_type cacheStart = args.size() - 3 - (force ? 1 : 0);
  128. type = cmCacheManager::StringToType(args[cacheStart+1].c_str());
  129. docstring = args[cacheStart+2].c_str();
  130. }
  131. // see if this is already in the cache
  132. cmCacheManager::CacheIterator it =
  133. this->Makefile->GetCacheManager()->GetCacheIterator(variable);
  134. if(!it.IsAtEnd() && (it.GetType() != cmCacheManager::UNINITIALIZED))
  135. {
  136. // if the set is trying to CACHE the value but the value
  137. // is already in the cache and the type is not internal
  138. // then leave now without setting any definitions in the cache
  139. // or the makefile
  140. if(cache && type != cmCacheManager::INTERNAL && !force)
  141. {
  142. return true;
  143. }
  144. }
  145. // if it is meant to be in the cache then define it in the cache
  146. if(cache)
  147. {
  148. this->Makefile->AddCacheDefinition(variable,
  149. value.c_str(),
  150. docstring,
  151. type, force);
  152. }
  153. else
  154. {
  155. // add the definition
  156. this->Makefile->AddDefinition(variable, value.c_str());
  157. }
  158. return true;
  159. }