diff options
author | Anas Nashif <anas.nashif@intel.com> | 2013-02-13 18:21:12 -0800 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2013-02-13 18:21:12 -0800 |
commit | ef8aa19c33e83ff019595fd7f8fdc29c35c336a3 (patch) | |
tree | 6501b44707b5c6a88fa5f817adee1a3ffcb0012d /Source/cmGeneratorExpressionParser.cxx | |
parent | 035c7fabc3b82cbc9a346c11abe2e9462b4c0379 (diff) | |
download | cmake-ef8aa19c33e83ff019595fd7f8fdc29c35c336a3.tar.gz cmake-ef8aa19c33e83ff019595fd7f8fdc29c35c336a3.tar.bz2 cmake-ef8aa19c33e83ff019595fd7f8fdc29c35c336a3.zip |
Imported Upstream version 2.8.10.2upstream/2.8.10.2
Diffstat (limited to 'Source/cmGeneratorExpressionParser.cxx')
-rw-r--r-- | Source/cmGeneratorExpressionParser.cxx | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx new file mode 100644 index 000000000..7a8fc510d --- /dev/null +++ b/Source/cmGeneratorExpressionParser.cxx @@ -0,0 +1,276 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmGeneratorExpressionParser.h" + +#include "cmGeneratorExpressionEvaluator.h" + +#include "assert.h" + +//---------------------------------------------------------------------------- +cmGeneratorExpressionParser::cmGeneratorExpressionParser( + const std::vector<cmGeneratorExpressionToken> &tokens) + : Tokens(tokens), NestingLevel(0) +{ +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionParser::Parse( + std::vector<cmGeneratorExpressionEvaluator*> &result) +{ + it = this->Tokens.begin(); + + while (this->it != this->Tokens.end()) + { + this->ParseContent(result); + } +} + +//---------------------------------------------------------------------------- +static void extendText(std::vector<cmGeneratorExpressionEvaluator*> &result, + std::vector<cmGeneratorExpressionToken>::const_iterator it) +{ + if (result.size() > 0 + && (*(result.end() - 1))->GetType() + == cmGeneratorExpressionEvaluator::Text) + { + TextContent *textContent = static_cast<TextContent*>(*(result.end() - 1)); + textContent->Extend(it->Length); + } + else + { + TextContent *textContent = new TextContent(it->Content, it->Length); + result.push_back(textContent); + } +} + +//---------------------------------------------------------------------------- +static void extendResult(std::vector<cmGeneratorExpressionEvaluator*> &result, + const std::vector<cmGeneratorExpressionEvaluator*> &contents) +{ + if (result.size() > 0 + && (*(result.end() - 1))->GetType() + == cmGeneratorExpressionEvaluator::Text + && (*contents.begin())->GetType() + == cmGeneratorExpressionEvaluator::Text) + { + TextContent *textContent = static_cast<TextContent*>(*(result.end() - 1)); + textContent->Extend( + static_cast<TextContent*>(*contents.begin())->GetLength()); + delete *contents.begin(); + result.insert(result.end(), contents.begin() + 1, contents.end()); + } else { + result.insert(result.end(), contents.begin(), contents.end()); + } +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionParser::ParseGeneratorExpression( + std::vector<cmGeneratorExpressionEvaluator*> &result) +{ + assert(this->it != this->Tokens.end()); + unsigned int nestedLevel = this->NestingLevel; + ++this->NestingLevel; + + std::vector<cmGeneratorExpressionToken>::const_iterator startToken + = this->it - 1; + + std::vector<cmGeneratorExpressionEvaluator*> identifier; + while(this->it->TokenType != cmGeneratorExpressionToken::EndExpression + && this->it->TokenType != cmGeneratorExpressionToken::ColonSeparator) + { + this->ParseContent(identifier); + if (this->it == this->Tokens.end()) + { + break; + } + } + if (identifier.empty()) + { + // ERROR + } + + 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); + result.push_back(content); + return; + } + + std::vector<std::vector<cmGeneratorExpressionEvaluator*> > parameters; + std::vector<std::vector<cmGeneratorExpressionToken>::const_iterator> + commaTokens; + std::vector<cmGeneratorExpressionToken>::const_iterator colonToken; + 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 != 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 != this->Tokens.end() && + this->it->TokenType != cmGeneratorExpressionToken::EndExpression) + { + this->ParseContent(*(parameters.end() - 1)); + 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; + } + 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() + && this->it->TokenType == cmGeneratorExpressionToken::EndExpression) + { + --this->NestingLevel; + assert(this->it != this->Tokens.end()); + ++this->it; + } + } + + if (nestedLevel != this->NestingLevel) + { + // There was a '$<' in the text, but no corresponding '>'. Rebuild to + // treat the '$<' as having been plain text, along with the + // corresponding : and , tokens that might have been found. + extendText(result, startToken); + extendResult(result, identifier); + if (!parameters.empty()) + { + extendText(result, colonToken); + + typedef std::vector<cmGeneratorExpressionEvaluator*> EvaluatorVector; + typedef std::vector<cmGeneratorExpressionToken> TokenVector; + std::vector<EvaluatorVector>::const_iterator pit = parameters.begin(); + const std::vector<EvaluatorVector>::const_iterator pend = + 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); + if (commaIt != commaTokens.end()) + { + extendText(result, *commaIt); + } + else + { + break; + } + } + } + return; + } + + int contentLength = ((this->it - 1)->Content + - startToken->Content) + + (this->it - 1)->Length; + GeneratorExpressionContent *content = new GeneratorExpressionContent( + startToken->Content, contentLength); + content->SetIdentifier(identifier); + content->SetParameters(parameters); + result.push_back(content); +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionParser::ParseContent( + std::vector<cmGeneratorExpressionEvaluator*> &result) +{ + assert(this->it != this->Tokens.end()); + switch(this->it->TokenType) + { + case cmGeneratorExpressionToken::Text: + { + if (this->NestingLevel == 0) + { + if (result.size() > 0 + && (*(result.end() - 1))->GetType() + == cmGeneratorExpressionEvaluator::Text) + { + // A comma in 'plain text' could have split text that should + // otherwise be continuous. Extend the last text content instead of + // creating a new one. + TextContent *textContent = + static_cast<TextContent*>(*(result.end() - 1)); + textContent->Extend(this->it->Length); + assert(this->it != this->Tokens.end()); + ++this->it; + return; + } + } + 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; + case cmGeneratorExpressionToken::EndExpression: + case cmGeneratorExpressionToken::ColonSeparator: + case cmGeneratorExpressionToken::CommaSeparator: + if (this->NestingLevel == 0) + { + extendText(result, this->it); + } + else + { + assert(!"Got unexpected syntax token."); + } + assert(this->it != this->Tokens.end()); + ++this->it; + return; + } + assert(!"Unhandled token in generator expression."); +} |