summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorDavid Cole <david.cole@kitware.com>2012-10-17 20:44:44 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2012-10-17 20:44:44 (GMT)
commit982905c0d23aded548718cf64665002cac350e77 (patch)
tree2b1d75092972373572ff521a2ef043d379743bd4 /Source
parente8b1c1ffc0a9eb3a224fbdb205627096ea6453c0 (diff)
parent79edd00235091475d5b3f1305bcf991cad3e45f4 (diff)
downloadCMake-982905c0d23aded548718cf64665002cac350e77.zip
CMake-982905c0d23aded548718cf64665002cac350e77.tar.gz
CMake-982905c0d23aded548718cf64665002cac350e77.tar.bz2
Merge topic 'generator-expression-bug-fixes'
79edd00 GenEx: Fix reporting about not-found include directories and libraries. f7ef32b GenEx: Replace some failing tests with Borland and NMake makefiles. fd59b10 GenEx: Add some more asserts to verify code-sanity. 6dd2b36 GenEx: Break if there are no more commas in the container e7230c7 GenEx: Fix termination bugs in generator expression parser. 145a4af GenEx: Test the use of generator expressions to generate lists. e2d141d GenEx: Parse colon after arguments separator colon specially.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGeneratorExpression.cxx49
-rw-r--r--Source/cmGeneratorExpression.h7
-rw-r--r--Source/cmGeneratorExpressionParser.cxx60
-rw-r--r--Source/cmGlobalGenerator.cxx22
-rw-r--r--Source/cmMakeDepend.cxx19
5 files changed, 134 insertions, 23 deletions
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 3f8e962..7d8df37 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -13,6 +13,7 @@
#include "cmMakefile.h"
#include "cmTarget.h"
+#include "assert.h"
#include <cmsys/String.h>
@@ -129,3 +130,51 @@ cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression()
delete *it;
}
}
+
+std::string cmGeneratorExpression::Preprocess(const std::string &input,
+ PreprocessContext context)
+{
+ if (context != StripAllGeneratorExpressions)
+ {
+ assert(!"cmGeneratorExpression::Preprocess called with invalid args");
+ return std::string();
+ }
+
+ std::string result;
+ std::string::size_type pos = 0;
+ std::string::size_type lastPos = pos;
+ while((pos = input.find("$<", lastPos)) != input.npos)
+ {
+ result += input.substr(lastPos, pos - lastPos);
+ pos += 2;
+ int nestingLevel = 1;
+ const char *c = input.c_str() + pos;
+ const char * const cStart = c;
+ for ( ; *c; ++c)
+ {
+ if(c[0] == '$' && c[1] == '<')
+ {
+ ++nestingLevel;
+ ++c;
+ continue;
+ }
+ if(c[0] == '>')
+ {
+ --nestingLevel;
+ if (nestingLevel == 0)
+ {
+ break;
+ }
+ }
+ }
+ const std::string::size_type traversed = (c - cStart) + 1;
+ if (!*c)
+ {
+ result += "$<" + input.substr(pos, traversed);
+ }
+ pos += traversed;
+ lastPos = pos;
+ }
+ result += input.substr(lastPos);
+ return result;
+}
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index d37ce97..29d3f44 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -48,6 +48,13 @@ public:
const cmCompiledGeneratorExpression& Parse(std::string const& input);
const cmCompiledGeneratorExpression& Parse(const char* input);
+ enum PreprocessContext {
+ StripAllGeneratorExpressions
+ };
+
+ static std::string Preprocess(const std::string &input,
+ PreprocessContext context);
+
private:
cmGeneratorExpression(const cmGeneratorExpression &);
void operator=(const cmGeneratorExpression &);
diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx
index d95e1cc..7a8fc51 100644
--- a/Source/cmGeneratorExpressionParser.cxx
+++ b/Source/cmGeneratorExpressionParser.cxx
@@ -14,6 +14,8 @@
#include "cmGeneratorExpressionEvaluator.h"
+#include "assert.h"
+
//----------------------------------------------------------------------------
cmGeneratorExpressionParser::cmGeneratorExpressionParser(
const std::vector<cmGeneratorExpressionToken> &tokens)
@@ -75,6 +77,7 @@ static void extendResult(std::vector<cmGeneratorExpressionEvaluator*> &result,
void cmGeneratorExpressionParser::ParseGeneratorExpression(
std::vector<cmGeneratorExpressionEvaluator*> &result)
{
+ assert(this->it != this->Tokens.end());
unsigned int nestedLevel = this->NestingLevel;
++this->NestingLevel;
@@ -96,12 +99,14 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
// ERROR
}
- if (this->it->TokenType == cmGeneratorExpressionToken::EndExpression)
+ if (this->it != this->Tokens.end() &&
+ this->it->TokenType == cmGeneratorExpressionToken::EndExpression)
{
GeneratorExpressionContent *content = new GeneratorExpressionContent(
startToken->Content, this->it->Content
- startToken->Content
+ this->it->Length);
+ assert(this->it != this->Tokens.end());
++this->it;
--this->NestingLevel;
content->SetIdentifier(identifier);
@@ -113,39 +118,58 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
std::vector<std::vector<cmGeneratorExpressionToken>::const_iterator>
commaTokens;
std::vector<cmGeneratorExpressionToken>::const_iterator colonToken;
- if (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator)
+ if (this->it != this->Tokens.end() &&
+ this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator)
{
colonToken = this->it;
parameters.resize(parameters.size() + 1);
+ assert(this->it != this->Tokens.end());
++this->it;
- while (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator)
+
+ while (this->it != this->Tokens.end() &&
+ this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator)
{
commaTokens.push_back(this->it);
parameters.resize(parameters.size() + 1);
+ assert(this->it != this->Tokens.end());
+ ++this->it;
+ }
+ while (this->it != this->Tokens.end() &&
+ this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator)
+ {
+ extendText(*(parameters.end() - 1), this->it);
+ assert(this->it != this->Tokens.end());
++this->it;
}
- while(this->it->TokenType != cmGeneratorExpressionToken::EndExpression)
+ while (this->it != this->Tokens.end() &&
+ this->it->TokenType != cmGeneratorExpressionToken::EndExpression)
{
this->ParseContent(*(parameters.end() - 1));
- while (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator)
+ if (this->it == this->Tokens.end())
+ {
+ break;
+ }
+ while (this->it != this->Tokens.end() &&
+ this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator)
{
commaTokens.push_back(this->it);
parameters.resize(parameters.size() + 1);
+ assert(this->it != this->Tokens.end());
++this->it;
}
- if (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator)
+ while (this->it != this->Tokens.end() &&
+ this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator)
{
extendText(*(parameters.end() - 1), this->it);
+ assert(this->it != this->Tokens.end());
++this->it;
}
- if (this->it == this->Tokens.end())
- {
- break;
- }
}
- if(this->it->TokenType == cmGeneratorExpressionToken::EndExpression)
+ if(this->it != this->Tokens.end()
+ && this->it->TokenType == cmGeneratorExpressionToken::EndExpression)
{
--this->NestingLevel;
+ assert(this->it != this->Tokens.end());
++this->it;
}
}
@@ -168,6 +192,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
parameters.end();
std::vector<TokenVector::const_iterator>::const_iterator commaIt =
commaTokens.begin();
+ assert(parameters.size() > commaTokens.size());
for ( ; pit != pend; ++pit, ++commaIt)
{
extendResult(result, *pit);
@@ -175,6 +200,10 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
{
extendText(result, *commaIt);
}
+ else
+ {
+ break;
+ }
}
}
return;
@@ -194,6 +223,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
void cmGeneratorExpressionParser::ParseContent(
std::vector<cmGeneratorExpressionEvaluator*> &result)
{
+ assert(this->it != this->Tokens.end());
switch(this->it->TokenType)
{
case cmGeneratorExpressionToken::Text:
@@ -210,6 +240,7 @@ void cmGeneratorExpressionParser::ParseContent(
TextContent *textContent =
static_cast<TextContent*>(*(result.end() - 1));
textContent->Extend(this->it->Length);
+ assert(this->it != this->Tokens.end());
++this->it;
return;
}
@@ -217,10 +248,12 @@ void cmGeneratorExpressionParser::ParseContent(
cmGeneratorExpressionEvaluator* n = new TextContent(this->it->Content,
this->it->Length);
result.push_back(n);
+ assert(this->it != this->Tokens.end());
++this->it;
return ;
}
case cmGeneratorExpressionToken::BeginExpression:
+ assert(this->it != this->Tokens.end());
++this->it;
this->ParseGeneratorExpression(result);
return;
@@ -233,10 +266,11 @@ void cmGeneratorExpressionParser::ParseContent(
}
else
{
- // TODO: Unreachable. Assert?
+ assert(!"Got unexpected syntax token.");
}
+ assert(this->it != this->Tokens.end());
++this->it;
return;
}
- // Unreachable. Assert?
+ assert(!"Unhandled token in generator expression.");
}
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 09588f9..23ec08a 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -25,6 +25,7 @@
#include "cmComputeTargetDepends.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
+#include "cmGeneratorExpression.h"
#include <cmsys/Directory.hxx>
@@ -1152,13 +1153,13 @@ void cmGlobalGenerator::CheckLocalGenerators()
{
manager = this->LocalGenerators[i]->GetMakefile()->GetCacheManager();
this->LocalGenerators[i]->ConfigureFinalPass();
- cmGeneratorTargetsType targets =
- this->LocalGenerators[i]->GetMakefile()->GetGeneratorTargets();
- for (cmGeneratorTargetsType::iterator l = targets.begin();
+ cmTargets &targets =
+ this->LocalGenerators[i]->GetMakefile()->GetTargets();
+ for (cmTargets::iterator l = targets.begin();
l != targets.end(); l++)
{
const cmTarget::LinkLibraryVectorType& libs =
- l->second->Target->GetOriginalLinkLibraries();
+ l->second.GetOriginalLinkLibraries();
for(cmTarget::LinkLibraryVectorType::const_iterator lib = libs.begin();
lib != libs.end(); ++lib)
{
@@ -1174,14 +1175,23 @@ void cmGlobalGenerator::CheckLocalGenerators()
}
std::string text = notFoundMap[varName];
text += "\n linked by target \"";
- text += l->second->GetName();
+ text += l->second.GetName();
text += "\" in directory ";
text+=this->LocalGenerators[i]->GetMakefile()->GetCurrentDirectory();
notFoundMap[varName] = text;
}
}
std::vector<std::string> incs;
- this->LocalGenerators[i]->GetIncludeDirectories(incs, l->second);
+ const char *incDirProp = l->second.GetProperty("INCLUDE_DIRECTORIES");
+ if (!incDirProp)
+ {
+ continue;
+ }
+
+ std::string incDirs = cmGeneratorExpression::Preprocess(incDirProp,
+ cmGeneratorExpression::StripAllGeneratorExpressions);
+
+ cmSystemTools::ExpandListArgument(incDirs.c_str(), incs);
for( std::vector<std::string>::const_iterator incDir = incs.begin();
incDir != incs.end(); ++incDir)
diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx
index 75a76a4..2ae35ef 100644
--- a/Source/cmMakeDepend.cxx
+++ b/Source/cmMakeDepend.cxx
@@ -11,6 +11,7 @@
============================================================================*/
#include "cmMakeDepend.h"
#include "cmSystemTools.h"
+#include "cmGeneratorExpression.h"
#include <cmsys/RegularExpression.hxx>
@@ -58,12 +59,22 @@ void cmMakeDepend::SetMakefile(cmMakefile* makefile)
// Now extract any include paths from the targets
std::set<std::string> uniqueIncludes;
std::vector<std::string> orderedAndUniqueIncludes;
- cmGeneratorTargetsType targets = this->Makefile->GetGeneratorTargets();
- for (cmGeneratorTargetsType::iterator l = targets.begin();
+ cmTargets &targets = this->Makefile->GetTargets();
+ for (cmTargets::iterator l = targets.begin();
l != targets.end(); ++l)
{
- const std::vector<std::string>& includes =
- l->second->GetIncludeDirectories();
+ const char *incDirProp = l->second.GetProperty("INCLUDE_DIRECTORIES");
+ if (!incDirProp)
+ {
+ continue;
+ }
+
+ std::string incDirs = cmGeneratorExpression::Preprocess(incDirProp,
+ cmGeneratorExpression::StripAllGeneratorExpressions);
+
+ std::vector<std::string> includes;
+ cmSystemTools::ExpandListArgument(incDirs.c_str(), includes);
+
for(std::vector<std::string>::const_iterator j = includes.begin();
j != includes.end(); ++j)
{