From ee96dc76864b899684d62b51edd87d3083e80168 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 26 Nov 2012 22:42:00 +0100 Subject: [PATCH 1/3] Genex: Extract a method to parse parameters. --- Source/cmGeneratorExpressionEvaluator.cxx | 21 ++++++++++++++++++--- Source/cmGeneratorExpressionEvaluator.h | 8 ++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 2e123a4d9..23f641d64 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -677,6 +677,23 @@ std::string GeneratorExpressionContent::Evaluate( } std::vector 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 ¶meters) const +{ { std::vector >::const_iterator pit = this->ParamChildren.begin(); @@ -732,10 +749,8 @@ std::string GeneratorExpressionContent::Evaluate( { reportError(context, this->GetOriginalExpression(), "$<" + identifier + "> expression requires at least one parameter."); - return std::string(); } - - return node->Evaluate(parameters, context, this, dagChecker); + return std::string(); } //---------------------------------------------------------------------------- diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 04a2acdc6..642a02ee5 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -33,6 +33,7 @@ struct cmGeneratorExpressionContext }; struct cmGeneratorExpressionDAGChecker; +struct cmGeneratorExpressionNode; //---------------------------------------------------------------------------- struct cmGeneratorExpressionEvaluator @@ -117,6 +118,13 @@ struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator ~GeneratorExpressionContent(); +private: + std::string EvaluateParameters(const cmGeneratorExpressionNode *node, + const std::string &identifier, + cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *dagChecker, + std::vector ¶meters) const; + private: std::vector IdentifierChildren; std::vector > ParamChildren; From 07749e3705cfc0105399c4a7a8349ec9f83ba39c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 26 Nov 2012 22:43:13 +0100 Subject: [PATCH 2/3] Genex: Ensure that $<0:...> has a parameter. --- Source/cmGeneratorExpressionEvaluator.cxx | 16 ++++++++++++++++ .../GeneratorExpression/BadZero-result.txt | 1 + .../GeneratorExpression/BadZero-stderr.txt | 8 ++++++++ Tests/RunCMake/GeneratorExpression/BadZero.cmake | 4 ++++ .../GeneratorExpression/RunCMakeTest.cmake | 1 + 5 files changed, 30 insertions(+) create mode 100644 Tests/RunCMake/GeneratorExpression/BadZero-result.txt create mode 100644 Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt create mode 100644 Tests/RunCMake/GeneratorExpression/BadZero.cmake diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 23f641d64..3c2f7c5fa 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -66,6 +66,8 @@ static const struct ZeroNode : public cmGeneratorExpressionNode virtual bool GeneratesContent() const { return false; } + virtual bool AcceptsSingleArbitraryContentParameter() const { return true; } + std::string Evaluate(const std::vector &, cmGeneratorExpressionContext *, const GeneratorExpressionContent *, @@ -642,6 +644,20 @@ std::string GeneratorExpressionContent::Evaluate( if (!node->GeneratesContent()) { + if (node->AcceptsSingleArbitraryContentParameter()) + { + if (this->ParamChildren.empty()) + { + reportError(context, this->GetOriginalExpression(), + "$<" + identifier + "> expression requires a parameter."); + } + } + else + { + std::vector parameters; + this->EvaluateParameters(node, identifier, context, dagChecker, + parameters); + } return std::string(); } diff --git a/Tests/RunCMake/GeneratorExpression/BadZero-result.txt b/Tests/RunCMake/GeneratorExpression/BadZero-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadZero-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt new file mode 100644 index 000000000..ce044828b --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at BadZero.cmake:2 \(add_custom_target\): + Error evaluating generator expression: + + \$<0> + + \$<0> expression requires a parameter. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/BadZero.cmake b/Tests/RunCMake/GeneratorExpression/BadZero.cmake new file mode 100644 index 000000000..295ab0e20 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadZero.cmake @@ -0,0 +1,4 @@ + +add_custom_target(check ALL COMMAND check + $<0> + VERBATIM) diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake index 18a47ae00..992ba792f 100644 --- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake @@ -5,3 +5,4 @@ run_cmake(BadOR) run_cmake(BadAND) run_cmake(BadNOT) run_cmake(BadStrEqual) +run_cmake(BadZero) From b581be07672e08cce4c29fa279b250d8e9c7aaba Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 26 Nov 2012 22:44:13 +0100 Subject: [PATCH 3/3] Genex: Don't segfault on $ Treat the comma as part of the identifier here. It will later not resolve to a generator expression and the user gets a proper error message. --- Source/cmGeneratorExpressionParser.cxx | 10 +++++++++- Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt | 9 +++++++++ Tests/RunCMake/GeneratorExpression/BadZero.cmake | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index 7a8fc510d..a619cecd0 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -88,7 +88,15 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( while(this->it->TokenType != cmGeneratorExpressionToken::EndExpression && this->it->TokenType != cmGeneratorExpressionToken::ColonSeparator) { - this->ParseContent(identifier); + if (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) + { + extendText(identifier, this->it); + ++this->it; + } + else + { + this->ParseContent(identifier); + } if (this->it == this->Tokens.end()) { break; diff --git a/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt index ce044828b..40db4ae88 100644 --- a/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt +++ b/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt @@ -6,3 +6,12 @@ CMake Error at BadZero.cmake:2 \(add_custom_target\): \$<0> expression requires a parameter. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) ++ +CMake Error at BadZero.cmake:2 \(add_custom_target\): + Error evaluating generator expression: + + \$<0,> + + Expression did not evaluate to a known generator expression +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/BadZero.cmake b/Tests/RunCMake/GeneratorExpression/BadZero.cmake index 295ab0e20..559a9fa3d 100644 --- a/Tests/RunCMake/GeneratorExpression/BadZero.cmake +++ b/Tests/RunCMake/GeneratorExpression/BadZero.cmake @@ -1,4 +1,5 @@ add_custom_target(check ALL COMMAND check $<0> + $<0,> VERBATIM)