123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmGeneratorExpressionEvaluator.h"
- #include "cmAlgorithms.h"
- #include "cmGeneratorExpressionContext.h"
- #include "cmGeneratorExpressionNode.h"
- #include <algorithm>
- #include <sstream>
- GeneratorExpressionContent::GeneratorExpressionContent(
- const char* startContent, size_t length)
- : StartContent(startContent)
- , ContentLength(length)
- {
- }
- std::string GeneratorExpressionContent::GetOriginalExpression() const
- {
- return std::string(this->StartContent, this->ContentLength);
- }
- std::string GeneratorExpressionContent::ProcessArbitraryContent(
- const cmGeneratorExpressionNode* node, const std::string& identifier,
- cmGeneratorExpressionContext* context,
- cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator
- pit) const
- {
- std::string result;
- const std::vector<
- std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator pend =
- 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) {
- reportError(context, this->GetOriginalExpression(), "$<" +
- identifier + "> expression requires literal input.");
- return std::string();
- }
- }
- result += (*it)->Evaluate(context, dagChecker);
- if (context->HadError) {
- return std::string();
- }
- }
- if ((pit + 1) != pend) {
- result += ",";
- }
- }
- if (node->RequiresLiteralInput()) {
- std::vector<std::string> parameters;
- parameters.push_back(result);
- return node->Evaluate(parameters, context, this, dagChecker);
- }
- return result;
- }
- std::string GeneratorExpressionContent::Evaluate(
- cmGeneratorExpressionContext* context,
- cmGeneratorExpressionDAGChecker* dagChecker) const
- {
- std::string identifier;
- {
- 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();
- }
- }
- }
- const cmGeneratorExpressionNode* node =
- cmGeneratorExpressionNode::GetNode(identifier);
- if (!node) {
- reportError(context, this->GetOriginalExpression(),
- "Expression did not evaluate to a known generator expression");
- return std::string();
- }
- if (!node->GeneratesContent()) {
- if (node->NumExpectedParameters() == 1 &&
- node->AcceptsArbitraryContentParameter()) {
- if (this->ParamChildren.empty()) {
- reportError(context, this->GetOriginalExpression(),
- "$<" + identifier + "> expression requires a parameter.");
- }
- } else {
- std::vector<std::string> parameters;
- this->EvaluateParameters(node, identifier, context, dagChecker,
- parameters);
- }
- return std::string();
- }
- std::vector<std::string> parameters;
- this->EvaluateParameters(node, identifier, context, dagChecker, parameters);
- if (context->HadError) {
- return std::string();
- }
- return node->Evaluate(parameters, context, this, dagChecker);
- }
- std::string GeneratorExpressionContent::EvaluateParameters(
- const cmGeneratorExpressionNode* node, const std::string& identifier,
- cmGeneratorExpressionContext* context,
- cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<std::string>& parameters) const
- {
- const int numExpected = node->NumExpectedParameters();
- {
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator
- pit = this->ParamChildren.begin();
- const std::vector<
- std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator pend =
- this->ParamChildren.end();
- const bool acceptsArbitraryContent =
- node->AcceptsArbitraryContentParameter();
- int counter = 1;
- for (; pit != pend; ++pit, ++counter) {
- if (acceptsArbitraryContent && counter == numExpected) {
- parameters.push_back(this->ProcessArbitraryContent(
- node, identifier, context, dagChecker, pit));
- return std::string();
- }
- 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();
- }
- }
- parameters.push_back(std::move(parameter));
- }
- }
- if ((numExpected > cmGeneratorExpressionNode::DynamicParameters &&
- static_cast<unsigned int>(numExpected) != parameters.size())) {
- if (numExpected == 0) {
- reportError(context, this->GetOriginalExpression(),
- "$<" + identifier + "> expression requires no parameters.");
- } else if (numExpected == 1) {
- reportError(context, this->GetOriginalExpression(), "$<" + identifier +
- "> expression requires "
- "exactly one parameter.");
- } else {
- std::ostringstream e;
- e << "$<" + identifier + "> expression requires " << numExpected
- << " comma separated parameters, but got " << parameters.size()
- << " instead.";
- reportError(context, this->GetOriginalExpression(), e.str());
- }
- return std::string();
- }
- if (numExpected == cmGeneratorExpressionNode::OneOrMoreParameters &&
- parameters.empty()) {
- reportError(context, this->GetOriginalExpression(), "$<" + identifier +
- "> expression requires at least one parameter.");
- }
- if (numExpected == cmGeneratorExpressionNode::OneOrZeroParameters &&
- parameters.size() > 1) {
- reportError(context, this->GetOriginalExpression(), "$<" + identifier +
- "> expression requires one or zero parameters.");
- }
- return std::string();
- }
- GeneratorExpressionContent::~GeneratorExpressionContent()
- {
- cmDeleteAll(this->IdentifierChildren);
- std::for_each(this->ParamChildren.begin(), this->ParamChildren.end(),
- cmDeleteAll<std::vector<cmGeneratorExpressionEvaluator*>>);
- }
|