diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 4063697cd..d306dee6d 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -250,6 +250,67 @@ static std::string stripExportInterface(const std::string &input, return result; } +//---------------------------------------------------------------------------- +void cmGeneratorExpression::Split(const std::string &input, + std::vector &output) +{ + std::string::size_type pos = 0; + std::string::size_type lastPos = pos; + while((pos = input.find("$<", lastPos)) != input.npos) + { + std::string part = input.substr(lastPos, pos - lastPos); + std::string preGenex; + if (!part.empty()) + { + std::string::size_type startPos = input.rfind(";", pos); + if (startPos != pos - 1 && startPos >= lastPos) + { + part = input.substr(lastPos, startPos - lastPos); + preGenex = input.substr(startPos + 1, pos - startPos - 1); + } + cmSystemTools::ExpandListArgument(part.c_str(), output); + } + 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; + } + } + } + for ( ; *c; ++c) + { + // Capture the part after the genex and before the next ';' + if(c[0] == ';') + { + --c; + break; + } + } + const std::string::size_type traversed = (c - cStart) + 1; + output.push_back(preGenex + "$<" + input.substr(pos, traversed)); + pos += traversed; + lastPos = pos; + } + if (lastPos < input.size()) + { + cmSystemTools::ExpandListArgument(input.substr(lastPos), output); + } +} + //---------------------------------------------------------------------------- std::string cmGeneratorExpression::Preprocess(const std::string &input, PreprocessContext context) diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index b58dde52b..8f1aef677 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -59,6 +59,9 @@ public: static std::string Preprocess(const std::string &input, PreprocessContext context); + static void Split(const std::string &input, + std::vector &output); + private: cmGeneratorExpression(const cmGeneratorExpression &); void operator=(const cmGeneratorExpression &);