mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-15 20:46:37 +08:00
cmFunctionBlocker: Move check for matching args
This commit is contained in:
@@ -28,7 +28,9 @@ public:
|
||||
cm::string_view StartCommandName() const override { return "foreach"_s; }
|
||||
cm::string_view EndCommandName() const override { return "endforeach"_s; }
|
||||
|
||||
bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
|
||||
bool ArgumentsMatch(cmListFileFunction const& lff,
|
||||
cmMakefile& mf) const override;
|
||||
|
||||
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& inStatus) override;
|
||||
|
||||
@@ -49,20 +51,12 @@ cmForEachFunctionBlocker::~cmForEachFunctionBlocker()
|
||||
this->Makefile->PopLoopBlock();
|
||||
}
|
||||
|
||||
bool cmForEachFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||
cmMakefile& mf)
|
||||
bool cmForEachFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
|
||||
cmMakefile& mf) const
|
||||
{
|
||||
if (lff.Name.Lower == "endforeach") {
|
||||
std::vector<std::string> expandedArguments;
|
||||
mf.ExpandArguments(lff.Arguments, expandedArguments);
|
||||
// if the endforeach has arguments then make sure
|
||||
// they match the begin foreach arguments
|
||||
if ((expandedArguments.empty() ||
|
||||
(expandedArguments[0] == this->Args[0]))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
std::vector<std::string> expandedArguments;
|
||||
mf.ExpandArguments(lff.Arguments, expandedArguments);
|
||||
return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
|
||||
}
|
||||
|
||||
bool cmForEachFunctionBlocker::Replay(
|
||||
|
@@ -2,8 +2,12 @@
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmFunctionBlocker.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
#include "cmExecutionStatus.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
|
||||
bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
|
||||
cmExecutionStatus& status)
|
||||
@@ -14,7 +18,24 @@ bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
|
||||
this->ScopeDepth--;
|
||||
if (this->ScopeDepth == 0U) {
|
||||
cmMakefile& mf = status.GetMakefile();
|
||||
auto self = mf.RemoveFunctionBlocker(this, lff);
|
||||
auto self = mf.RemoveFunctionBlocker();
|
||||
assert(self.get() == this);
|
||||
|
||||
if (!this->ArgumentsMatch(lff, mf)) {
|
||||
cmListFileContext const& lfc = this->GetStartingContext();
|
||||
cmListFileContext closingContext =
|
||||
cmListFileContext::FromCommandContext(lff, lfc.FilePath);
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e << "A logical block opening on the line\n"
|
||||
<< " " << lfc << "\n"
|
||||
<< "closes on the line\n"
|
||||
<< " " << closingContext << "\n"
|
||||
<< "with mis-matching arguments.";
|
||||
/* clang-format on */
|
||||
mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str());
|
||||
}
|
||||
|
||||
return this->Replay(this->Functions, status);
|
||||
}
|
||||
}
|
||||
|
@@ -23,15 +23,6 @@ public:
|
||||
bool IsFunctionBlocked(cmListFileFunction const& lff,
|
||||
cmExecutionStatus& status);
|
||||
|
||||
/**
|
||||
* should this function blocker be removed, useful when one function adds a
|
||||
* blocker and another must remove it
|
||||
*/
|
||||
virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual ~cmFunctionBlocker() = default;
|
||||
|
||||
/** Set/Get the context in which this blocker is created. */
|
||||
@@ -48,6 +39,9 @@ private:
|
||||
virtual cm::string_view StartCommandName() const = 0;
|
||||
virtual cm::string_view EndCommandName() const = 0;
|
||||
|
||||
virtual bool ArgumentsMatch(cmListFileFunction const& lff,
|
||||
cmMakefile& mf) const = 0;
|
||||
|
||||
virtual bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& status) = 0;
|
||||
|
||||
|
@@ -113,29 +113,22 @@ public:
|
||||
cm::string_view StartCommandName() const override { return "function"_s; }
|
||||
cm::string_view EndCommandName() const override { return "endfunction"_s; }
|
||||
|
||||
bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override;
|
||||
bool ArgumentsMatch(cmListFileFunction const&,
|
||||
cmMakefile& mf) const override;
|
||||
|
||||
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& status) override;
|
||||
|
||||
std::vector<std::string> Args;
|
||||
};
|
||||
|
||||
bool cmFunctionFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||
cmMakefile& mf)
|
||||
bool cmFunctionFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
|
||||
cmMakefile& mf) const
|
||||
{
|
||||
if (lff.Name.Lower == "endfunction") {
|
||||
std::vector<std::string> expandedArguments;
|
||||
mf.ExpandArguments(lff.Arguments, expandedArguments,
|
||||
this->GetStartingContext().FilePath.c_str());
|
||||
// if the endfunction has arguments then make sure
|
||||
// they match the ones in the opening function command
|
||||
if ((expandedArguments.empty() ||
|
||||
(expandedArguments[0] == this->Args[0]))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
std::vector<std::string> expandedArguments;
|
||||
mf.ExpandArguments(lff.Arguments, expandedArguments,
|
||||
this->GetStartingContext().FilePath.c_str());
|
||||
return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
|
||||
}
|
||||
|
||||
bool cmFunctionFunctionBlocker::Replay(
|
||||
|
@@ -38,7 +38,9 @@ public:
|
||||
cm::string_view StartCommandName() const override { return "if"_s; }
|
||||
cm::string_view EndCommandName() const override { return "endif"_s; }
|
||||
|
||||
bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
|
||||
bool ArgumentsMatch(cmListFileFunction const& lff,
|
||||
cmMakefile&) const override;
|
||||
|
||||
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& inStatus) override;
|
||||
|
||||
@@ -48,18 +50,10 @@ public:
|
||||
bool ElseSeen = false;
|
||||
};
|
||||
|
||||
bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||
cmMakefile&)
|
||||
bool cmIfFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
|
||||
cmMakefile&) const
|
||||
{
|
||||
if (lff.Name.Lower == "endif") {
|
||||
// if the endif has arguments, then make sure
|
||||
// they match the arguments of the matching if
|
||||
if (lff.Arguments.empty() || lff.Arguments == this->Args) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return lff.Arguments.empty() || lff.Arguments == this->Args;
|
||||
}
|
||||
|
||||
bool cmIfFunctionBlocker::Replay(
|
||||
|
@@ -146,29 +146,22 @@ public:
|
||||
cm::string_view StartCommandName() const override { return "macro"_s; }
|
||||
cm::string_view EndCommandName() const override { return "endmacro"_s; }
|
||||
|
||||
bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override;
|
||||
bool ArgumentsMatch(cmListFileFunction const&,
|
||||
cmMakefile& mf) const override;
|
||||
|
||||
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& status) override;
|
||||
|
||||
std::vector<std::string> Args;
|
||||
};
|
||||
|
||||
bool cmMacroFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||
cmMakefile& mf)
|
||||
bool cmMacroFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
|
||||
cmMakefile& mf) const
|
||||
{
|
||||
if (lff.Name.Lower == "endmacro") {
|
||||
std::vector<std::string> expandedArguments;
|
||||
mf.ExpandArguments(lff.Arguments, expandedArguments,
|
||||
this->GetStartingContext().FilePath.c_str());
|
||||
// if the endmacro has arguments make sure they
|
||||
// match the arguments of the macro
|
||||
if ((expandedArguments.empty() ||
|
||||
(expandedArguments[0] == this->Args[0]))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
std::vector<std::string> expandedArguments;
|
||||
mf.ExpandArguments(lff.Arguments, expandedArguments,
|
||||
this->GetStartingContext().FilePath.c_str());
|
||||
return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
|
||||
}
|
||||
|
||||
bool cmMacroFunctionBlocker::Replay(
|
||||
|
@@ -3220,30 +3220,12 @@ void cmMakefile::AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb)
|
||||
this->FunctionBlockers.push(std::move(fb));
|
||||
}
|
||||
|
||||
std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker(
|
||||
cmFunctionBlocker* fb, const cmListFileFunction& lff)
|
||||
std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker()
|
||||
{
|
||||
assert(!this->FunctionBlockers.empty());
|
||||
assert(this->FunctionBlockers.top().get() == fb);
|
||||
assert(this->FunctionBlockerBarriers.empty() ||
|
||||
this->FunctionBlockers.size() > this->FunctionBlockerBarriers.back());
|
||||
|
||||
// Warn if the arguments do not match, but always remove.
|
||||
if (!fb->ShouldRemove(lff, *this)) {
|
||||
cmListFileContext const& lfc = fb->GetStartingContext();
|
||||
cmListFileContext closingContext =
|
||||
cmListFileContext::FromCommandContext(lff, lfc.FilePath);
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e << "A logical block opening on the line\n"
|
||||
<< " " << lfc << "\n"
|
||||
<< "closes on the line\n"
|
||||
<< " " << closingContext << "\n"
|
||||
<< "with mis-matching arguments.";
|
||||
/* clang-format on */
|
||||
this->IssueMessage(MessageType::AUTHOR_WARNING, e.str());
|
||||
}
|
||||
|
||||
auto b = std::move(this->FunctionBlockers.top());
|
||||
this->FunctionBlockers.pop();
|
||||
return b;
|
||||
|
@@ -107,8 +107,7 @@ public:
|
||||
* Remove the function blocker whose scope ends with the given command.
|
||||
* This returns ownership of the function blocker object.
|
||||
*/
|
||||
std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker(
|
||||
cmFunctionBlocker* fb, const cmListFileFunction& lff);
|
||||
std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker();
|
||||
|
||||
/**
|
||||
* Try running cmake and building a file. This is used for dynalically
|
||||
|
@@ -27,7 +27,9 @@ public:
|
||||
cm::string_view StartCommandName() const override { return "while"_s; }
|
||||
cm::string_view EndCommandName() const override { return "endwhile"_s; }
|
||||
|
||||
bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
|
||||
bool ArgumentsMatch(cmListFileFunction const& lff,
|
||||
cmMakefile& mf) const override;
|
||||
|
||||
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& inStatus) override;
|
||||
|
||||
@@ -48,17 +50,10 @@ cmWhileFunctionBlocker::~cmWhileFunctionBlocker()
|
||||
this->Makefile->PopLoopBlock();
|
||||
}
|
||||
|
||||
bool cmWhileFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||
cmMakefile&)
|
||||
bool cmWhileFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
|
||||
cmMakefile&) const
|
||||
{
|
||||
if (lff.Name.Lower == "endwhile") {
|
||||
// if the endwhile has arguments, then make sure
|
||||
// they match the arguments of the matching while
|
||||
if (lff.Arguments.empty() || lff.Arguments == this->Args) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return lff.Arguments.empty() || lff.Arguments == this->Args;
|
||||
}
|
||||
|
||||
bool cmWhileFunctionBlocker::Replay(
|
||||
|
Reference in New Issue
Block a user