mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-16 05:26:58 +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 StartCommandName() const override { return "foreach"_s; }
|
||||||
cm::string_view EndCommandName() const override { return "endforeach"_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,
|
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||||
cmExecutionStatus& inStatus) override;
|
cmExecutionStatus& inStatus) override;
|
||||||
|
|
||||||
@@ -49,20 +51,12 @@ cmForEachFunctionBlocker::~cmForEachFunctionBlocker()
|
|||||||
this->Makefile->PopLoopBlock();
|
this->Makefile->PopLoopBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmForEachFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
bool cmForEachFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
|
||||||
cmMakefile& mf)
|
cmMakefile& mf) const
|
||||||
{
|
{
|
||||||
if (lff.Name.Lower == "endforeach") {
|
|
||||||
std::vector<std::string> expandedArguments;
|
std::vector<std::string> expandedArguments;
|
||||||
mf.ExpandArguments(lff.Arguments, expandedArguments);
|
mf.ExpandArguments(lff.Arguments, expandedArguments);
|
||||||
// if the endforeach has arguments then make sure
|
return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
|
||||||
// they match the begin foreach arguments
|
|
||||||
if ((expandedArguments.empty() ||
|
|
||||||
(expandedArguments[0] == this->Args[0]))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmForEachFunctionBlocker::Replay(
|
bool cmForEachFunctionBlocker::Replay(
|
||||||
|
@@ -2,8 +2,12 @@
|
|||||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||||
#include "cmFunctionBlocker.h"
|
#include "cmFunctionBlocker.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "cmExecutionStatus.h"
|
#include "cmExecutionStatus.h"
|
||||||
#include "cmMakefile.h"
|
#include "cmMakefile.h"
|
||||||
|
#include "cmMessageType.h"
|
||||||
|
|
||||||
bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
|
bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
|
||||||
cmExecutionStatus& status)
|
cmExecutionStatus& status)
|
||||||
@@ -14,7 +18,24 @@ bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
|
|||||||
this->ScopeDepth--;
|
this->ScopeDepth--;
|
||||||
if (this->ScopeDepth == 0U) {
|
if (this->ScopeDepth == 0U) {
|
||||||
cmMakefile& mf = status.GetMakefile();
|
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);
|
return this->Replay(this->Functions, status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -23,15 +23,6 @@ public:
|
|||||||
bool IsFunctionBlocked(cmListFileFunction const& lff,
|
bool IsFunctionBlocked(cmListFileFunction const& lff,
|
||||||
cmExecutionStatus& status);
|
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;
|
virtual ~cmFunctionBlocker() = default;
|
||||||
|
|
||||||
/** Set/Get the context in which this blocker is created. */
|
/** 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 StartCommandName() const = 0;
|
||||||
virtual cm::string_view EndCommandName() 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,
|
virtual bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||||
cmExecutionStatus& status) = 0;
|
cmExecutionStatus& status) = 0;
|
||||||
|
|
||||||
|
@@ -113,29 +113,22 @@ public:
|
|||||||
cm::string_view StartCommandName() const override { return "function"_s; }
|
cm::string_view StartCommandName() const override { return "function"_s; }
|
||||||
cm::string_view EndCommandName() const override { return "endfunction"_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,
|
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||||
cmExecutionStatus& status) override;
|
cmExecutionStatus& status) override;
|
||||||
|
|
||||||
std::vector<std::string> Args;
|
std::vector<std::string> Args;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool cmFunctionFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
bool cmFunctionFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
|
||||||
cmMakefile& mf)
|
cmMakefile& mf) const
|
||||||
{
|
{
|
||||||
if (lff.Name.Lower == "endfunction") {
|
|
||||||
std::vector<std::string> expandedArguments;
|
std::vector<std::string> expandedArguments;
|
||||||
mf.ExpandArguments(lff.Arguments, expandedArguments,
|
mf.ExpandArguments(lff.Arguments, expandedArguments,
|
||||||
this->GetStartingContext().FilePath.c_str());
|
this->GetStartingContext().FilePath.c_str());
|
||||||
// if the endfunction has arguments then make sure
|
return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
|
||||||
// they match the ones in the opening function command
|
|
||||||
if ((expandedArguments.empty() ||
|
|
||||||
(expandedArguments[0] == this->Args[0]))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmFunctionFunctionBlocker::Replay(
|
bool cmFunctionFunctionBlocker::Replay(
|
||||||
|
@@ -38,7 +38,9 @@ public:
|
|||||||
cm::string_view StartCommandName() const override { return "if"_s; }
|
cm::string_view StartCommandName() const override { return "if"_s; }
|
||||||
cm::string_view EndCommandName() const override { return "endif"_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,
|
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||||
cmExecutionStatus& inStatus) override;
|
cmExecutionStatus& inStatus) override;
|
||||||
|
|
||||||
@@ -48,18 +50,10 @@ public:
|
|||||||
bool ElseSeen = false;
|
bool ElseSeen = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
bool cmIfFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
|
||||||
cmMakefile&)
|
cmMakefile&) const
|
||||||
{
|
{
|
||||||
if (lff.Name.Lower == "endif") {
|
return lff.Arguments.empty() || lff.Arguments == this->Args;
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmIfFunctionBlocker::Replay(
|
bool cmIfFunctionBlocker::Replay(
|
||||||
|
@@ -146,29 +146,22 @@ public:
|
|||||||
cm::string_view StartCommandName() const override { return "macro"_s; }
|
cm::string_view StartCommandName() const override { return "macro"_s; }
|
||||||
cm::string_view EndCommandName() const override { return "endmacro"_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,
|
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||||
cmExecutionStatus& status) override;
|
cmExecutionStatus& status) override;
|
||||||
|
|
||||||
std::vector<std::string> Args;
|
std::vector<std::string> Args;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool cmMacroFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
bool cmMacroFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
|
||||||
cmMakefile& mf)
|
cmMakefile& mf) const
|
||||||
{
|
{
|
||||||
if (lff.Name.Lower == "endmacro") {
|
|
||||||
std::vector<std::string> expandedArguments;
|
std::vector<std::string> expandedArguments;
|
||||||
mf.ExpandArguments(lff.Arguments, expandedArguments,
|
mf.ExpandArguments(lff.Arguments, expandedArguments,
|
||||||
this->GetStartingContext().FilePath.c_str());
|
this->GetStartingContext().FilePath.c_str());
|
||||||
// if the endmacro has arguments make sure they
|
return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
|
||||||
// match the arguments of the macro
|
|
||||||
if ((expandedArguments.empty() ||
|
|
||||||
(expandedArguments[0] == this->Args[0]))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmMacroFunctionBlocker::Replay(
|
bool cmMacroFunctionBlocker::Replay(
|
||||||
|
@@ -3220,30 +3220,12 @@ void cmMakefile::AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb)
|
|||||||
this->FunctionBlockers.push(std::move(fb));
|
this->FunctionBlockers.push(std::move(fb));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker(
|
std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker()
|
||||||
cmFunctionBlocker* fb, const cmListFileFunction& lff)
|
|
||||||
{
|
{
|
||||||
assert(!this->FunctionBlockers.empty());
|
assert(!this->FunctionBlockers.empty());
|
||||||
assert(this->FunctionBlockers.top().get() == fb);
|
|
||||||
assert(this->FunctionBlockerBarriers.empty() ||
|
assert(this->FunctionBlockerBarriers.empty() ||
|
||||||
this->FunctionBlockers.size() > this->FunctionBlockerBarriers.back());
|
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());
|
auto b = std::move(this->FunctionBlockers.top());
|
||||||
this->FunctionBlockers.pop();
|
this->FunctionBlockers.pop();
|
||||||
return b;
|
return b;
|
||||||
|
@@ -107,8 +107,7 @@ public:
|
|||||||
* Remove the function blocker whose scope ends with the given command.
|
* Remove the function blocker whose scope ends with the given command.
|
||||||
* This returns ownership of the function blocker object.
|
* This returns ownership of the function blocker object.
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker(
|
std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker();
|
||||||
cmFunctionBlocker* fb, const cmListFileFunction& lff);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try running cmake and building a file. This is used for dynalically
|
* 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 StartCommandName() const override { return "while"_s; }
|
||||||
cm::string_view EndCommandName() const override { return "endwhile"_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,
|
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||||
cmExecutionStatus& inStatus) override;
|
cmExecutionStatus& inStatus) override;
|
||||||
|
|
||||||
@@ -48,17 +50,10 @@ cmWhileFunctionBlocker::~cmWhileFunctionBlocker()
|
|||||||
this->Makefile->PopLoopBlock();
|
this->Makefile->PopLoopBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmWhileFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
bool cmWhileFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
|
||||||
cmMakefile&)
|
cmMakefile&) const
|
||||||
{
|
{
|
||||||
if (lff.Name.Lower == "endwhile") {
|
return lff.Arguments.empty() || lff.Arguments == this->Args;
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmWhileFunctionBlocker::Replay(
|
bool cmWhileFunctionBlocker::Replay(
|
||||||
|
Reference in New Issue
Block a user