Coverage Report

Created: 2026-03-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmPlaceholderExpander.cxx
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#include "cmPlaceholderExpander.h"
4
5
#include "cmsys/String.h"
6
7
std::string& cmPlaceholderExpander::ExpandVariables(std::string& s)
8
0
{
9
0
  std::string::size_type start = s.find('<');
10
  // no variables to expand
11
0
  if (start == std::string::npos) {
12
0
    return s;
13
0
  }
14
0
  std::string::size_type pos = 0;
15
0
  std::string expandedInput;
16
0
  while (start != std::string::npos && start < s.size() - 2) {
17
0
    std::string::size_type end = s.find('>', start);
18
    // if we find a < with no > we are done
19
0
    if (end == std::string::npos) {
20
0
      s = expandedInput;
21
0
      return s;
22
0
    }
23
0
    char c = s[start + 1];
24
    // if the next char after the < is not A-Za-z then
25
    // skip it and try to find the next < in the string
26
0
    if (!cmsysString_isalpha(c)) {
27
0
      start = s.find('<', start + 1);
28
0
    } else {
29
      // extract the var
30
0
      std::string var = s.substr(start + 1, end - start - 1);
31
0
      std::string replace = this->ExpandVariable(var);
32
0
      expandedInput += s.substr(pos, start - pos);
33
34
      // Prevent consecutive whitespace in the output if the rule variable
35
      // expands to an empty string.
36
0
      bool consecutive = replace.empty() && start > 0 && s[start - 1] == ' ' &&
37
0
        end + 1 < s.size() && s[end + 1] == ' ';
38
0
      if (consecutive) {
39
0
        expandedInput.pop_back();
40
0
      }
41
42
0
      expandedInput += replace;
43
44
      // move to next one
45
0
      start = s.find('<', start + var.size() + 2);
46
0
      pos = end + 1;
47
0
    }
48
0
  }
49
  // add the rest of the input
50
0
  expandedInput += s.substr(pos, s.size() - pos);
51
  // remove trailing whitespace
52
0
  if (!expandedInput.empty() && expandedInput.back() == ' ') {
53
0
    expandedInput.pop_back();
54
0
  }
55
0
  s = expandedInput;
56
57
0
  return s;
58
0
}