summaryrefslogtreecommitdiffstats
path: root/Source/cmPlaceholderExpander.cxx
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2021-11-24 15:45:22 (GMT)
committerMarc Chevrier <marc.chevrier@gmail.com>2022-02-06 13:32:24 (GMT)
commit78dd7d5292cef930b3d435e6901cc3b10ee02513 (patch)
tree7cb78e4301177a68c55d7fd8eddd2fc225ec8c68 /Source/cmPlaceholderExpander.cxx
parent4b55828a9f2afbc6c37e53f7cb0d4adec0fa73b5 (diff)
downloadCMake-78dd7d5292cef930b3d435e6901cc3b10ee02513.zip
CMake-78dd7d5292cef930b3d435e6901cc3b10ee02513.tar.gz
CMake-78dd7d5292cef930b3d435e6901cc3b10ee02513.tar.bz2
cmRulePlaceholderExpander: add base class for placeholder expansion reuse
Diffstat (limited to 'Source/cmPlaceholderExpander.cxx')
-rw-r--r--Source/cmPlaceholderExpander.cxx54
1 files changed, 54 insertions, 0 deletions
diff --git a/Source/cmPlaceholderExpander.cxx b/Source/cmPlaceholderExpander.cxx
new file mode 100644
index 0000000..118017e
--- /dev/null
+++ b/Source/cmPlaceholderExpander.cxx
@@ -0,0 +1,54 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmPlaceholderExpander.h"
+
+#include <cctype>
+
+std::string& cmPlaceholderExpander::ExpandVariables(std::string& s)
+{
+ std::string::size_type start = s.find('<');
+ // no variables to expand
+ if (start == std::string::npos) {
+ return s;
+ }
+ std::string::size_type pos = 0;
+ std::string expandedInput;
+ while (start != std::string::npos && start < s.size() - 2) {
+ std::string::size_type end = s.find('>', start);
+ // if we find a < with no > we are done
+ if (end == std::string::npos) {
+ s = expandedInput;
+ return s;
+ }
+ char c = s[start + 1];
+ // if the next char after the < is not A-Za-z then
+ // skip it and try to find the next < in the string
+ if (!isalpha(c)) {
+ start = s.find('<', start + 1);
+ } else {
+ // extract the var
+ std::string var = s.substr(start + 1, end - start - 1);
+ std::string replace = this->ExpandVariable(var);
+ expandedInput += s.substr(pos, start - pos);
+
+ // Prevent consecutive whitespace in the output if the rule variable
+ // expands to an empty string.
+ bool consecutive = replace.empty() && start > 0 && s[start - 1] == ' ' &&
+ end + 1 < s.size() && s[end + 1] == ' ';
+ if (consecutive) {
+ expandedInput.pop_back();
+ }
+
+ expandedInput += replace;
+
+ // move to next one
+ start = s.find('<', start + var.size() + 2);
+ pos = end + 1;
+ }
+ }
+ // add the rest of the input
+ expandedInput += s.substr(pos, s.size() - pos);
+ s = expandedInput;
+
+ return s;
+}