cmGeneratorExpression.cxx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmGeneratorExpression.h"
  11. #include "cmMakefile.h"
  12. #include "cmTarget.h"
  13. #include "assert.h"
  14. #include <cmsys/String.h>
  15. #include "cmGeneratorExpressionEvaluator.h"
  16. #include "cmGeneratorExpressionLexer.h"
  17. #include "cmGeneratorExpressionParser.h"
  18. #include "cmGeneratorExpressionDAGChecker.h"
  19. //----------------------------------------------------------------------------
  20. cmGeneratorExpression::cmGeneratorExpression(
  21. cmListFileBacktrace const& backtrace):
  22. Backtrace(backtrace)
  23. {
  24. }
  25. //----------------------------------------------------------------------------
  26. cmsys::auto_ptr<cmCompiledGeneratorExpression>
  27. cmGeneratorExpression::Parse(std::string const& input)
  28. {
  29. return this->Parse(input.c_str());
  30. }
  31. //----------------------------------------------------------------------------
  32. cmsys::auto_ptr<cmCompiledGeneratorExpression>
  33. cmGeneratorExpression::Parse(const char* input)
  34. {
  35. return cmsys::auto_ptr<cmCompiledGeneratorExpression>(
  36. new cmCompiledGeneratorExpression(
  37. this->Backtrace,
  38. input));
  39. }
  40. cmGeneratorExpression::~cmGeneratorExpression()
  41. {
  42. }
  43. //----------------------------------------------------------------------------
  44. const char *cmCompiledGeneratorExpression::Evaluate(
  45. cmMakefile* mf, const char* config, bool quiet,
  46. cmTarget *target,
  47. cmGeneratorExpressionDAGChecker *dagChecker) const
  48. {
  49. if (!this->NeedsParsing)
  50. {
  51. return this->Input.c_str();
  52. }
  53. this->Output = "";
  54. std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it
  55. = this->Evaluators.begin();
  56. const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end
  57. = this->Evaluators.end();
  58. cmGeneratorExpressionContext context;
  59. context.Makefile = mf;
  60. context.Config = config;
  61. context.Quiet = quiet;
  62. context.HadError = false;
  63. context.Target = target;
  64. context.Backtrace = this->Backtrace;
  65. for ( ; it != end; ++it)
  66. {
  67. this->Output += (*it)->Evaluate(&context, dagChecker);
  68. if (context.HadError)
  69. {
  70. this->Output = "";
  71. break;
  72. }
  73. }
  74. this->Targets = context.Targets;
  75. // TODO: Return a std::string from here instead?
  76. return this->Output.c_str();
  77. }
  78. cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
  79. cmListFileBacktrace const& backtrace,
  80. const char *input)
  81. : Backtrace(backtrace), Input(input ? input : "")
  82. {
  83. cmGeneratorExpressionLexer l;
  84. std::vector<cmGeneratorExpressionToken> tokens =
  85. l.Tokenize(this->Input.c_str());
  86. this->NeedsParsing = l.GetSawGeneratorExpression();
  87. if (this->NeedsParsing)
  88. {
  89. cmGeneratorExpressionParser p(tokens);
  90. p.Parse(this->Evaluators);
  91. }
  92. }
  93. //----------------------------------------------------------------------------
  94. cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression()
  95. {
  96. std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it
  97. = this->Evaluators.begin();
  98. const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end
  99. = this->Evaluators.end();
  100. for ( ; it != end; ++it)
  101. {
  102. delete *it;
  103. }
  104. }
  105. std::string cmGeneratorExpression::Preprocess(const std::string &input,
  106. PreprocessContext context)
  107. {
  108. if (context != StripAllGeneratorExpressions)
  109. {
  110. assert(!"cmGeneratorExpression::Preprocess called with invalid args");
  111. return std::string();
  112. }
  113. std::string result;
  114. std::string::size_type pos = 0;
  115. std::string::size_type lastPos = pos;
  116. while((pos = input.find("$<", lastPos)) != input.npos)
  117. {
  118. result += input.substr(lastPos, pos - lastPos);
  119. pos += 2;
  120. int nestingLevel = 1;
  121. const char *c = input.c_str() + pos;
  122. const char * const cStart = c;
  123. for ( ; *c; ++c)
  124. {
  125. if(c[0] == '$' && c[1] == '<')
  126. {
  127. ++nestingLevel;
  128. ++c;
  129. continue;
  130. }
  131. if(c[0] == '>')
  132. {
  133. --nestingLevel;
  134. if (nestingLevel == 0)
  135. {
  136. break;
  137. }
  138. }
  139. }
  140. const std::string::size_type traversed = (c - cStart) + 1;
  141. if (!*c)
  142. {
  143. result += "$<" + input.substr(pos, traversed);
  144. }
  145. pos += traversed;
  146. lastPos = pos;
  147. }
  148. result += input.substr(lastPos);
  149. return result;
  150. }