summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2009-03-10 15:10:59 (GMT)
committerBrad King <brad.king@kitware.com>2009-03-10 15:10:59 (GMT)
commite5e91d617940cab2ea4e8630c6c20cd09794b3a9 (patch)
tree07799700331300e0e2e2a4ffdef98f5040f20736
parentca9fb4826f89722a5a190e0c69e6bf5c26889a55 (diff)
downloadCMake-e5e91d617940cab2ea4e8630c6c20cd09794b3a9.zip
CMake-e5e91d617940cab2ea4e8630c6c20cd09794b3a9.tar.gz
CMake-e5e91d617940cab2ea4e8630c6c20cd09794b3a9.tar.bz2
ENH: Teach set/get_property about CACHE properties
This adds the CACHE option to set_property and get_property commands. This allows full control over cache entry information, so advanced users can tweak their project cache as desired. The set_property command allows only pre-defined CACHE properties to be set since others would not persist anyway.
-rw-r--r--Source/cmCacheManager.cxx12
-rw-r--r--Source/cmCacheManager.h1
-rw-r--r--Source/cmGetPropertyCommand.cxx27
-rw-r--r--Source/cmGetPropertyCommand.h3
-rw-r--r--Source/cmSetPropertyCommand.cxx95
-rw-r--r--Source/cmSetPropertyCommand.h6
-rw-r--r--Tests/Properties/CMakeLists.txt26
7 files changed, 167 insertions, 3 deletions
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index f53ed49..365d052 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -71,6 +71,18 @@ cmCacheManager::CacheEntryType cmCacheManager::StringToType(const char* s)
return STRING;
}
+bool cmCacheManager::IsType(const char* s)
+{
+ for(int i=0; cmCacheManagerTypes[i]; ++i)
+ {
+ if(strcmp(s, cmCacheManagerTypes[i]) == 0)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
bool cmCacheManager::LoadCache(cmMakefile* mf)
{
return this->LoadCache(mf->GetHomeOutputDirectory());
diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h
index e57042b..abd14bd 100644
--- a/Source/cmCacheManager.h
+++ b/Source/cmCacheManager.h
@@ -105,6 +105,7 @@ public:
*/
static CacheEntryType StringToType(const char*);
static const char* TypeToString(CacheEntryType);
+ static bool IsType(const char*);
///! Load a cache for given makefile. Loads from ouput home.
bool LoadCache(cmMakefile*);
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 88a3e7c..3446fb2 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -65,12 +65,16 @@ bool cmGetPropertyCommand
{
scope = cmProperty::VARIABLE;
}
+ else if(args[1] == "CACHE")
+ {
+ scope = cmProperty::CACHE;
+ }
else
{
cmOStringStream e;
e << "given invalid scope " << args[1] << ". "
<< "Valid scopes are "
- << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE.";
+ << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE.";
this->SetError(e.str().c_str());
return false;
}
@@ -187,6 +191,7 @@ bool cmGetPropertyCommand
case cmProperty::SOURCE_FILE: return this->HandleSourceMode();
case cmProperty::TEST: return this->HandleTestMode();
case cmProperty::VARIABLE: return this->HandleVariableMode();
+ case cmProperty::CACHE: return this->HandleCacheMode();
case cmProperty::CACHED_VARIABLE:
break; // should never happen
@@ -359,3 +364,23 @@ bool cmGetPropertyCommand::HandleVariableMode()
return this->StoreResult
(this->Makefile->GetDefinition(this->PropertyName.c_str()));
}
+
+//----------------------------------------------------------------------------
+bool cmGetPropertyCommand::HandleCacheMode()
+{
+ if(this->Name.empty())
+ {
+ this->SetError("not given name for CACHE scope.");
+ return false;
+ }
+
+ const char* value = 0;
+ cmCacheManager::CacheIterator it =
+ this->Makefile->GetCacheManager()->GetCacheIterator(this->Name.c_str());
+ if(!it.IsAtEnd())
+ {
+ value = it.GetProperty(this->PropertyName.c_str());
+ }
+ this->StoreResult(value);
+ return true;
+}
diff --git a/Source/cmGetPropertyCommand.h b/Source/cmGetPropertyCommand.h
index a8976c5..b4ec3cc 100644
--- a/Source/cmGetPropertyCommand.h
+++ b/Source/cmGetPropertyCommand.h
@@ -66,6 +66,7 @@ public:
" TARGET <target> |\n"
" SOURCE <source> |\n"
" TEST <test> |\n"
+ " CACHE <entry> |\n"
" VARIABLE>\n"
" PROPERTY <name>\n"
" [SET | DEFINED | BRIEF_DOCS | FULL_DOCS])\n"
@@ -81,6 +82,7 @@ public:
"TARGET scope must name one existing target.\n"
"SOURCE scope must name one source file.\n"
"TEST scope must name one existing test.\n"
+ "CACHE scope must name one cache entry.\n"
"VARIABLE scope is unique and does not accept a name.\n"
"The required PROPERTY option is immediately followed by the name "
"of the property to get. "
@@ -114,6 +116,7 @@ private:
bool HandleSourceMode();
bool HandleTestMode();
bool HandleVariableMode();
+ bool HandleCacheMode();
};
#endif
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index b683fe7..fbe877b 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -19,6 +19,8 @@
#include "cmSetTestsPropertiesCommand.h"
#include "cmSetSourceFilesPropertiesCommand.h"
+#include "cmCacheManager.h"
+
//----------------------------------------------------------------------------
cmSetPropertyCommand::cmSetPropertyCommand()
{
@@ -59,11 +61,15 @@ bool cmSetPropertyCommand
{
scope = cmProperty::TEST;
}
+ else if(*arg == "CACHE")
+ {
+ scope = cmProperty::CACHE;
+ }
else
{
cmOStringStream e;
e << "given invalid scope " << *arg << ". "
- << "Valid scopes are GLOBAL, DIRECTORY, TARGET, SOURCE, TEST.";
+ << "Valid scopes are GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, CACHE.";
this->SetError(e.str().c_str());
return false;
}
@@ -123,6 +129,7 @@ bool cmSetPropertyCommand
case cmProperty::TARGET: return this->HandleTargetMode();
case cmProperty::SOURCE_FILE: return this->HandleSourceMode();
case cmProperty::TEST: return this->HandleTestMode();
+ case cmProperty::CACHE: return this->HandleCacheMode();
case cmProperty::VARIABLE:
case cmProperty::CACHED_VARIABLE:
@@ -384,3 +391,89 @@ bool cmSetPropertyCommand::HandleTest(cmTest* test)
return true;
}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleCacheMode()
+{
+ if(this->PropertyName == "ADVANCED")
+ {
+ if(!this->Remove &&
+ !cmSystemTools::IsOn(this->PropertyValue.c_str()) &&
+ !cmSystemTools::IsOff(this->PropertyValue.c_str()))
+ {
+ cmOStringStream e;
+ e << "given non-boolean value \"" << this->PropertyValue
+ << "\" for CACHE property \"ADVANCED\". ";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else if(this->PropertyName == "TYPE")
+ {
+ if(!cmCacheManager::IsType(this->PropertyValue.c_str()))
+ {
+ cmOStringStream e;
+ e << "given invalid CACHE entry TYPE \"" << this->PropertyValue << "\"";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else if(this->PropertyName != "HELPSTRING" &&
+ this->PropertyName != "VALUE")
+ {
+ cmOStringStream e;
+ e << "given invalid CACHE property " << this->PropertyName << ". "
+ << "Settable CACHE properties are: "
+ << "ADVANCED, HELPSTRING, TYPE, and VALUE.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end(); ++ni)
+ {
+ // Get the source file.
+ cmMakefile* mf = this->GetMakefile();
+ cmake* cm = mf->GetCMakeInstance();
+ cmCacheManager::CacheIterator it =
+ cm->GetCacheManager()->GetCacheIterator(ni->c_str());
+ if(!it.IsAtEnd())
+ {
+ if(!this->HandleCacheEntry(it))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "could not find CACHE variable " << *ni
+ << ". Perhaps it has not yet been created.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleCacheEntry(cmCacheManager::CacheIterator& it)
+{
+ // Set or append the property.
+ const char* name = this->PropertyName.c_str();
+ const char* value = this->PropertyValue.c_str();
+ if (this->Remove)
+ {
+ value = 0;
+ }
+ if(this->AppendMode)
+ {
+ it.AppendProperty(name, value);
+ }
+ else
+ {
+ it.SetProperty(name, value);
+ }
+
+ return true;
+}
diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
index 8ef0b7c..4d7decf 100644
--- a/Source/cmSetPropertyCommand.h
+++ b/Source/cmSetPropertyCommand.h
@@ -59,7 +59,8 @@ public:
" DIRECTORY [dir] |\n"
" TARGET [target1 [target2 ...]] |\n"
" SOURCE [src1 [src2 ...]] |\n"
- " TEST [test1 [test2 ...]]>\n"
+ " TEST [test1 [test2 ...]] |\n"
+ " CACHE [entry1 [entry2 ...]]>\n"
" [APPEND]\n"
" PROPERTY <name> [value1 [value2 ...]])\n"
"Set one property on zero or more objects of a scope. "
@@ -72,6 +73,7 @@ public:
"TARGET scope may name zero or more existing targets.\n"
"SOURCE scope may name zero or more source files.\n"
"TEST scope may name zero or more existing tests.\n"
+ "CACHE scope must name zero or more cache existing entries.\n"
"The required PROPERTY option is immediately followed by the name "
"of the property to set. Remaining arguments are used to "
"compose the property value in the form of a semicolon-separated "
@@ -104,6 +106,8 @@ private:
bool HandleSource(cmSourceFile* sf);
bool HandleTestMode();
bool HandleTest(cmTest* test);
+ bool HandleCacheMode();
+ bool HandleCacheEntry(cmCacheManager::CacheIterator&);
};
diff --git a/Tests/Properties/CMakeLists.txt b/Tests/Properties/CMakeLists.txt
index 8cdd61b..6f3b539 100644
--- a/Tests/Properties/CMakeLists.txt
+++ b/Tests/Properties/CMakeLists.txt
@@ -97,3 +97,29 @@ if(NOT RESULT4)
" RESULT4=${RESULT4}"
" Properties_SOURCES=[${Properties_SOURCES}]")
endif(NOT RESULT4)
+
+# test CACHE properties
+macro(check_cache_props)
+ foreach(prop VALUE TYPE HELPSTRING ADVANCED)
+ get_property(result CACHE SOME_ENTRY PROPERTY ${prop})
+ if(NOT "x${result}" STREQUAL "x${expect_${prop}}")
+ message(SEND_ERROR "CACHE property ${prop} is [${result}], not [${expect_${prop}}]")
+ endif()
+ endforeach(prop)
+endmacro(check_cache_props)
+set(expect_VALUE "ON")
+set(expect_TYPE "BOOL")
+set(expect_HELPSTRING "sample cache entry")
+set(expect_ADVANCED 0)
+set(SOME_ENTRY "${expect_VALUE}" CACHE ${expect_TYPE} "${expect_HELPSTRING}" FORCE)
+mark_as_advanced(CLEAR SOME_ENTRY)
+check_cache_props()
+set(expect_VALUE "Some string")
+set(expect_TYPE "STRING")
+set(expect_HELPSTRING "sample cache entry help")
+set(expect_ADVANCED 1)
+set_property(CACHE SOME_ENTRY PROPERTY TYPE "${expect_TYPE}")
+set_property(CACHE SOME_ENTRY PROPERTY HELPSTRING "${expect_HELPSTRING}")
+set_property(CACHE SOME_ENTRY PROPERTY VALUE "${expect_VALUE}")
+set_property(CACHE SOME_ENTRY PROPERTY ADVANCED "${expect_ADVANCED}")
+check_cache_props()