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.
This commit is contained in:
Brad King 2009-03-10 11:10:59 -04:00
parent ca9fb4826f
commit e5e91d6179
7 changed files with 167 additions and 3 deletions

View File

@ -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());

View File

@ -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*);

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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&);
};

View File

@ -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()