cmake/Source/cmGeneratorExpressionEvaluator.cxx

196 lines
6.6 KiB
C++
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
2013-03-16 19:13:01 +02:00
#include "cmGeneratorExpressionEvaluator.h"
2016-07-09 11:21:54 +02:00
#include "cmAlgorithms.h"
2016-10-30 18:24:19 +01:00
#include "cmGeneratorExpressionContext.h"
2015-08-17 11:37:30 +02:00
#include "cmGeneratorExpressionNode.h"
2013-03-16 19:13:01 +02:00
2016-10-30 18:24:19 +01:00
#include <algorithm>
#include <sstream>
2013-03-16 19:13:01 +02:00
GeneratorExpressionContent::GeneratorExpressionContent(
2016-07-09 11:21:54 +02:00
const char* startContent, size_t length)
: StartContent(startContent)
, ContentLength(length)
2013-03-16 19:13:01 +02:00
{
}
std::string GeneratorExpressionContent::GetOriginalExpression() const
{
return std::string(this->StartContent, this->ContentLength);
}
2013-11-03 12:27:13 +02:00
std::string GeneratorExpressionContent::ProcessArbitraryContent(
2016-07-09 11:21:54 +02:00
const cmGeneratorExpressionNode* node, const std::string& identifier,
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker,
2018-01-26 17:06:56 +01:00
std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator
2013-11-03 12:27:13 +02:00
pit) const
{
std::string result;
2016-07-09 11:21:54 +02:00
const std::vector<
2018-01-26 17:06:56 +01:00
std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator pend =
2016-07-09 11:21:54 +02:00
this->ParamChildren.end();
for (; pit != pend; ++pit) {
std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it =
pit->begin();
const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end =
pit->end();
for (; it != end; ++it) {
if (node->RequiresLiteralInput()) {
if ((*it)->GetType() != cmGeneratorExpressionEvaluator::Text) {
2018-08-09 18:06:22 +02:00
reportError(context, this->GetOriginalExpression(),
"$<" + identifier +
"> expression requires literal input.");
2013-11-03 12:27:13 +02:00
return std::string();
}
2016-07-09 11:21:54 +02:00
}
2013-11-03 12:27:13 +02:00
result += (*it)->Evaluate(context, dagChecker);
2016-07-09 11:21:54 +02:00
if (context->HadError) {
2013-11-03 12:27:13 +02:00
return std::string();
}
}
2016-07-09 11:21:54 +02:00
if ((pit + 1) != pend) {
result += ",";
}
}
if (node->RequiresLiteralInput()) {
2013-11-03 12:27:13 +02:00
std::vector<std::string> parameters;
parameters.push_back(result);
return node->Evaluate(parameters, context, this, dagChecker);
2016-07-09 11:21:54 +02:00
}
2013-11-03 12:27:13 +02:00
return result;
}
2013-03-16 19:13:01 +02:00
std::string GeneratorExpressionContent::Evaluate(
2016-07-09 11:21:54 +02:00
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker) const
2013-03-16 19:13:01 +02:00
{
std::string identifier;
{
2016-07-09 11:21:54 +02:00
std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it =
this->IdentifierChildren.begin();
const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end =
this->IdentifierChildren.end();
for (; it != end; ++it) {
identifier += (*it)->Evaluate(context, dagChecker);
if (context->HadError) {
return std::string();
2013-03-16 19:13:01 +02:00
}
}
}
2016-07-09 11:21:54 +02:00
const cmGeneratorExpressionNode* node =
cmGeneratorExpressionNode::GetNode(identifier);
2013-03-16 19:13:01 +02:00
2016-07-09 11:21:54 +02:00
if (!node) {
2013-03-16 19:13:01 +02:00
reportError(context, this->GetOriginalExpression(),
2016-07-09 11:21:54 +02:00
"Expression did not evaluate to a known generator expression");
2013-03-16 19:13:01 +02:00
return std::string();
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
2016-07-09 11:21:54 +02:00
if (!node->GeneratesContent()) {
if (node->NumExpectedParameters() == 1 &&
node->AcceptsArbitraryContentParameter()) {
if (this->ParamChildren.empty()) {
2013-03-16 19:13:01 +02:00
reportError(context, this->GetOriginalExpression(),
2016-07-09 11:21:54 +02:00
"$<" + identifier + "> expression requires a parameter.");
2013-03-16 19:13:01 +02:00
}
2016-07-09 11:21:54 +02:00
} else {
2013-03-16 19:13:01 +02:00
std::vector<std::string> parameters;
this->EvaluateParameters(node, identifier, context, dagChecker,
parameters);
}
2016-07-09 11:21:54 +02:00
return std::string();
}
2013-03-16 19:13:01 +02:00
std::vector<std::string> parameters;
this->EvaluateParameters(node, identifier, context, dagChecker, parameters);
2016-07-09 11:21:54 +02:00
if (context->HadError) {
2013-03-16 19:13:01 +02:00
return std::string();
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
return node->Evaluate(parameters, context, this, dagChecker);
}
std::string GeneratorExpressionContent::EvaluateParameters(
2016-07-09 11:21:54 +02:00
const cmGeneratorExpressionNode* node, const std::string& identifier,
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker,
std::vector<std::string>& parameters) const
2013-03-16 19:13:01 +02:00
{
2013-11-03 12:27:13 +02:00
const int numExpected = node->NumExpectedParameters();
2013-03-16 19:13:01 +02:00
{
2018-01-26 17:06:56 +01:00
std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator
2016-07-09 11:21:54 +02:00
pit = this->ParamChildren.begin();
const std::vector<
2018-01-26 17:06:56 +01:00
std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator pend =
2016-07-09 11:21:54 +02:00
this->ParamChildren.end();
const bool acceptsArbitraryContent =
node->AcceptsArbitraryContentParameter();
int counter = 1;
for (; pit != pend; ++pit, ++counter) {
if (acceptsArbitraryContent && counter == numExpected) {
2018-04-23 21:13:27 +02:00
parameters.push_back(this->ProcessArbitraryContent(
node, identifier, context, dagChecker, pit));
2016-07-09 11:21:54 +02:00
return std::string();
2016-10-30 18:24:19 +01:00
}
std::string parameter;
std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it =
pit->begin();
const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end =
pit->end();
for (; it != end; ++it) {
parameter += (*it)->Evaluate(context, dagChecker);
if (context->HadError) {
return std::string();
2014-08-03 19:52:23 +02:00
}
}
2018-04-23 21:13:27 +02:00
parameters.push_back(std::move(parameter));
2013-03-16 19:13:01 +02:00
}
}
2016-07-09 11:21:54 +02:00
if ((numExpected > cmGeneratorExpressionNode::DynamicParameters &&
2018-01-26 17:06:56 +01:00
static_cast<unsigned int>(numExpected) != parameters.size())) {
2016-07-09 11:21:54 +02:00
if (numExpected == 0) {
2013-03-16 19:13:01 +02:00
reportError(context, this->GetOriginalExpression(),
"$<" + identifier + "> expression requires no parameters.");
2016-07-09 11:21:54 +02:00
} else if (numExpected == 1) {
2018-08-09 18:06:22 +02:00
reportError(context, this->GetOriginalExpression(),
"$<" + identifier +
2016-07-09 11:21:54 +02:00
"> expression requires "
"exactly one parameter.");
} else {
2015-04-27 22:25:09 +02:00
std::ostringstream e;
2016-07-09 11:21:54 +02:00
e << "$<" + identifier + "> expression requires " << numExpected
<< " comma separated parameters, but got " << parameters.size()
<< " instead.";
2013-03-16 19:13:01 +02:00
reportError(context, this->GetOriginalExpression(), e.str());
}
2016-07-09 11:21:54 +02:00
return std::string();
}
2013-03-16 19:13:01 +02:00
2016-07-09 11:21:54 +02:00
if (numExpected == cmGeneratorExpressionNode::OneOrMoreParameters &&
parameters.empty()) {
2018-08-09 18:06:22 +02:00
reportError(context, this->GetOriginalExpression(),
"$<" + identifier +
2016-07-09 11:21:54 +02:00
"> expression requires at least one parameter.");
}
if (numExpected == cmGeneratorExpressionNode::OneOrZeroParameters &&
parameters.size() > 1) {
2018-08-09 18:06:22 +02:00
reportError(context, this->GetOriginalExpression(),
"$<" + identifier +
2016-07-09 11:21:54 +02:00
"> expression requires one or zero parameters.");
}
2013-03-16 19:13:01 +02:00
return std::string();
}
GeneratorExpressionContent::~GeneratorExpressionContent()
{
2015-04-27 22:25:09 +02:00
cmDeleteAll(this->IdentifierChildren);
std::for_each(this->ParamChildren.begin(), this->ParamChildren.end(),
2018-01-26 17:06:56 +01:00
cmDeleteAll<std::vector<cmGeneratorExpressionEvaluator*>>);
2013-03-16 19:13:01 +02:00
}