summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2009-01-22 18:16:47 (GMT)
committerBrad King <brad.king@kitware.com>2009-01-22 18:16:47 (GMT)
commit3028ca756c8621b3cc37032987eb01fbe61da248 (patch)
tree1a32991d7d25cefaa5b214759d84ab2c20a3c0b5 /Source
parent18eadebc4c0b43443861f40ca243e18dbabb2324 (diff)
downloadCMake-3028ca756c8621b3cc37032987eb01fbe61da248.zip
CMake-3028ca756c8621b3cc37032987eb01fbe61da248.tar.gz
CMake-3028ca756c8621b3cc37032987eb01fbe61da248.tar.bz2
ENH: Better policies for functions and macros
This teaches functions and macros to use policies recorded at creation time when they are invoked. It restores the policies as a weak policy stack entry so that any policies set by a function escape to its caller as before.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmCMakePolicyCommand.h6
-rw-r--r--Source/cmFunctionCommand.cxx8
-rw-r--r--Source/cmFunctionCommand.h6
-rw-r--r--Source/cmMacroCommand.cxx8
-rw-r--r--Source/cmMacroCommand.h6
-rw-r--r--Source/cmMakefile.cxx12
-rw-r--r--Source/cmMakefile.h1
7 files changed, 45 insertions, 2 deletions
diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h
index d2315ea..e74a6cf 100644
--- a/Source/cmCMakePolicyCommand.h
+++ b/Source/cmCMakePolicyCommand.h
@@ -123,6 +123,12 @@ public:
" cmake_policy(POP)\n"
"Each PUSH must have a matching POP to erase any changes. "
"This is useful to make temporary changes to policy settings."
+ "\n"
+ "Functions and macros record policy settings when they are created "
+ "and use the pre-record policies when they are invoked. "
+ "If the function or macro implementation sets policies, the changes "
+ "automatically propagate up through callers until they reach the "
+ "closest nested policy stack entry."
;
}
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 2b5223b..9095961 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -36,6 +36,7 @@ public:
// we must copy when we clone
newC->Args = this->Args;
newC->Functions = this->Functions;
+ newC->Policies = this->Policies;
return newC;
}
@@ -81,6 +82,7 @@ public:
std::vector<std::string> Args;
std::vector<cmListFileFunction> Functions;
+ cmPolicies::PolicyMap Policies;
};
@@ -108,6 +110,10 @@ bool cmFunctionHelperCommand::InvokeInitialPass
cmMakefile::ScopePushPop varScope(this->Makefile);
static_cast<void>(varScope);
+ // Push a weak policy scope which restores the policies recorded at
+ // function creation.
+ cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies);
+
// set the value of argc
cmOStringStream strStream;
strStream << expandedArgs.size();
@@ -165,6 +171,7 @@ bool cmFunctionHelperCommand::InvokeInitialPass
// The error message should have already included the call stack
// so we do not need to report an error here.
lexScope.Quiet();
+ polScope.Quiet();
inStatus.SetNestedError(true);
return false;
}
@@ -206,6 +213,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
cmFunctionHelperCommand *f = new cmFunctionHelperCommand();
f->Args = this->Args;
f->Functions = this->Functions;
+ mf.RecordPolicies(f->Policies);
// Set the FilePath on the arguments to match the function since it is
// not stored and the original values may be freed
diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h
index b9f9010..ced8218 100644
--- a/Source/cmFunctionCommand.h
+++ b/Source/cmFunctionCommand.h
@@ -104,7 +104,11 @@ public:
"will have the actual values of the arguments passed in. This "
"facilitates creating functions with optional arguments. Additionally "
"ARGV holds the list of all arguments given to the function and ARGN "
- "holds the list of argument pass the last expected argument.";
+ "holds the list of argument pass the last expected argument."
+ "\n"
+ "See the cmake_policy() command documentation for the behavior of "
+ "policies inside functions."
+ ;
}
cmTypeMacro(cmFunctionCommand, cmCommand);
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 9cc2653..c736e09 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -36,6 +36,7 @@ public:
// we must copy when we clone
newC->Args = this->Args;
newC->Functions = this->Functions;
+ newC->Policies = this->Policies;
return newC;
}
@@ -81,6 +82,7 @@ public:
std::vector<std::string> Args;
std::vector<cmListFileFunction> Functions;
+ cmPolicies::PolicyMap Policies;
};
@@ -110,6 +112,10 @@ bool cmMacroHelperCommand::InvokeInitialPass
// Enforce matching logical blocks inside the macro.
cmMakefile::LexicalPushPop lexScope(this->Makefile);
+ // Push a weak policy scope which restores the policies recorded at
+ // macro creation.
+ cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies);
+
// set the value of argc
cmOStringStream argcDefStream;
argcDefStream << expandedArgs.size();
@@ -219,6 +225,7 @@ bool cmMacroHelperCommand::InvokeInitialPass
// The error message should have already included the call stack
// so we do not need to report an error here.
lexScope.Quiet();
+ polScope.Quiet();
inStatus.SetNestedError(true);
return false;
}
@@ -264,6 +271,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
cmMacroHelperCommand *f = new cmMacroHelperCommand();
f->Args = this->Args;
f->Functions = this->Functions;
+ mf.RecordPolicies(f->Policies);
std::string newName = "_" + this->Args[0];
mf.GetCMakeInstance()->RenameCommand(this->Args[0].c_str(),
newName.c_str());
diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h
index 3231d71..55da26e 100644
--- a/Source/cmMacroCommand.h
+++ b/Source/cmMacroCommand.h
@@ -111,7 +111,11 @@ public:
"are not variables in the usual CMake sense. They are string "
"replacements much like the c preprocessor would do with a "
"macro. If you want true CMake variables you should look at "
- "the function command.";
+ "the function command."
+ "\n"
+ "See the cmake_policy() command documentation for the behavior of "
+ "policies inside macros."
+ ;
}
cmTypeMacro(cmMacroCommand, cmCommand);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 25d97fa..4442bd3 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -3774,3 +3774,15 @@ cmPolicies *cmMakefile::GetPolicies()
}
return this->GetCMakeInstance()->GetPolicies();
}
+
+//----------------------------------------------------------------------------
+void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
+{
+ /* Record the setting of every policy. */
+ typedef cmPolicies::PolicyID PolicyID;
+ for(PolicyID pid = cmPolicies::CMP0000;
+ pid != cmPolicies::CMPCOUNT; pid = PolicyID(pid+1))
+ {
+ pm[pid] = this->GetPolicyStatus(pid);
+ }
+}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index a5fcec1..1c59313 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -343,6 +343,7 @@ public:
bool SetPolicy(const char *id, cmPolicies::PolicyStatus status);
cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id);
bool SetPolicyVersion(const char *version);
+ void RecordPolicies(cmPolicies::PolicyMap& pm);
//@}
/** Helper class to push and pop policies automatically. */