1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 #include "cmSetCommand.h"
16 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
20 this->SetError("called with incorrect number of arguments");
24 // watch for ENV signatures
25 const char* variable = args[0].c_str(); // VAR is always first
26 if (!strncmp(variable,"ENV{",4) && strlen(variable) > 5)
28 // what is the variable name
29 char *varName = new char [strlen(variable)];
30 strncpy(varName,variable+4,strlen(variable)-5);
31 varName[strlen(variable)-5] = '\0';
32 std::string putEnvArg = varName;
35 // what is the current value if any
36 const char *currValue = getenv(varName);
39 // will it be set to something, then set it
40 if (args.size() > 1 && args[1].size())
42 // but only if it is different from current value
43 if (!currValue || strcmp(currValue,args[1].c_str()))
46 cmSystemTools::PutEnv(putEnvArg.c_str());
51 // if it will be cleared, then clear it if it isn;t already clear
54 cmSystemTools::PutEnv(putEnvArg.c_str());
59 // SET (VAR) // Removes the definition of VAR.
62 this->Makefile->RemoveDefinition(args[0].c_str());
66 // here are the remaining options
68 // SET (VAR CACHE TYPE "doc String" [FORCE])
69 // SET (VAR value CACHE TYPE "doc string" [FORCE])
70 std::string value; // optional
71 bool cache = false; // optional
72 bool force = false; // optional
73 bool parentScope = false;
74 cmCacheManager::CacheEntryType type
75 = cmCacheManager::STRING; // required if cache
76 const char* docstring = 0; // required if cache
78 unsigned int ignoreLastArgs = 0;
79 // look for PARENT_SCOPE argument
80 if (args.size() > 1 && args[args.size()-1] == "PARENT_SCOPE")
87 // look for FORCE argument
88 if (args.size() > 4 && args[args.size()-1] == "FORCE")
94 // check for cache signature
95 if (args.size() > 3 && args[args.size() - 3 - (force ? 1 : 0)] == "CACHE")
102 // collect any values into a single semi-colon separated value list
103 if(static_cast<unsigned short>(args.size()) >
104 static_cast<unsigned short>(1 + ignoreLastArgs))
107 size_t endPos = args.size() - ignoreLastArgs;
108 for(size_t i = 2; i < endPos; ++i)
119 this->Makefile->RaiseScope(variable, 0);
123 this->Makefile->RaiseScope(variable, value.c_str());
129 // we should be nice and try to catch some simple screwups if the last or
130 // next to last args are CACHE then they screwed up. If they used FORCE
131 // without CACHE they screwed up
132 if ((args[args.size() - 1] == "CACHE") ||
133 (args.size() > 1 && args[args.size() - 2] == "CACHE") ||
136 this->SetError("given invalid arguments for CACHE mode.");
142 std::string::size_type cacheStart = args.size() - 3 - (force ? 1 : 0);
143 type = cmCacheManager::StringToType(args[cacheStart+1].c_str());
144 docstring = args[cacheStart+2].c_str();
147 // see if this is already in the cache
148 cmCacheManager::CacheIterator it =
149 this->Makefile->GetCacheManager()->GetCacheIterator(variable);
150 if(!it.IsAtEnd() && (it.GetType() != cmCacheManager::UNINITIALIZED))
152 // if the set is trying to CACHE the value but the value
153 // is already in the cache and the type is not internal
154 // then leave now without setting any definitions in the cache
156 if(cache && type != cmCacheManager::INTERNAL && !force)
162 // if it is meant to be in the cache then define it in the cache
165 this->Makefile->AddCacheDefinition(variable,
172 // add the definition
173 this->Makefile->AddDefinition(variable, value.c_str());