Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmCMakeString.hxx
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
4
#pragma once
5
6
#include "cmConfigure.h" // IWYU pragma: keep
7
8
#include <cstddef>
9
#include <string>
10
#include <utility>
11
#include <vector>
12
13
#include <cm/string_view>
14
15
#include "cmList.h"
16
#include "cmRange.h"
17
#include "cmString.hxx"
18
#include "cmStringAlgorithms.h"
19
#include "cmSystemTools.h"
20
#include "cmValue.h"
21
22
class cmMakefile;
23
24
//
25
// Class offering various string operations which is used by
26
// * CMake string() command
27
// * $<STRING> generator expression
28
//
29
30
namespace cm {
31
32
class CMakeString
33
{
34
public:
35
  using size_type = cm::String::size_type;
36
  static auto const npos = cm::String::npos;
37
38
  using string_range = cmRange<std::vector<std::string>::const_iterator>;
39
40
  CMakeString(std::string const& str)
41
0
    : String_(cm::String::borrow(str))
42
0
  {
43
0
  }
44
  CMakeString(cm::string_view str)
45
    : String_(cm::String::borrow(str))
46
0
  {
47
0
  }
48
  CMakeString(cm::String const& str)
49
    : String_(str)
50
0
  {
51
0
  }
52
  CMakeString(cm::String&& str)
53
0
    : String_(std::move(str))
54
0
  {
55
0
  }
56
  CMakeString(cmValue value)
57
0
    : String_(cm::String::borrow(*value))
58
0
  {
59
0
  }
60
  CMakeString(string_range range,
61
              cm::string_view separator = cm::string_view{})
62
0
    : String_(cmJoin(range, separator))
63
0
  {
64
0
  }
65
66
0
  CMakeString() = default;
67
  CMakeString(CMakeString const&) = default;
68
  CMakeString(CMakeString&&) = default;
69
70
  CMakeString& operator=(CMakeString const& string)
71
0
  {
72
0
    if (this != &string) {
73
0
      this->String_ = string.String_;
74
0
    }
75
0
    return *this;
76
0
  }
77
  CMakeString& operator=(CMakeString&& string) noexcept
78
0
  {
79
0
    if (this != &string) {
80
0
      this->String_ = std::move(string.String_);
81
0
    }
82
0
    return *this;
83
0
  }
84
  CMakeString& operator=(cm::string_view string)
85
0
  {
86
0
    this->String_ = string;
87
0
    return *this;
88
0
  }
89
90
  // conversions
91
0
  string_view view() const noexcept { return this->String_.view(); }
92
0
  operator cm::string_view() noexcept { return this->String_.view(); }
93
0
  operator std::string const&() { return this->String_.str(); }
94
95
0
  size_type Size() const { return this->String_.size(); }
96
0
  size_type Length() const { return this->String_.size(); }
97
98
  enum class CompOperator
99
  {
100
    EQUAL,
101
    LESS,
102
    LESS_EQUAL,
103
    GREATER,
104
    GREATER_EQUAL
105
  };
106
  bool Compare(CompOperator op, cm::string_view other);
107
108
  enum class FindFrom
109
  {
110
    Begin,
111
    End
112
  };
113
  size_type Find(cm::string_view substring,
114
                 FindFrom from = FindFrom::Begin) const
115
0
  {
116
0
    return from == FindFrom::Begin ? this->String_.find(substring)
117
0
                                   : this->String_.rfind(substring);
118
0
  }
119
120
  enum class Regex
121
  {
122
    No,
123
    Yes
124
  };
125
  // Throw std::invalid_argument if regular expression is invalid
126
  //       std::runtime_error if replacement failed
127
  CMakeString& Replace(std::string const& matchExpression,
128
                       std::string const& replaceExpression,
129
                       Regex regex = Regex::No,
130
                       cmMakefile* makefile = nullptr);
131
132
  enum class MatchItems
133
  {
134
    Once,
135
    All
136
  };
137
  // Throw std::invalid_argument if regular expression is invalid
138
  cmList Match(std::string const& matchExpression,
139
               MatchItems matchItems = MatchItems::Once,
140
               cmMakefile* makefile = nullptr) const;
141
142
  CMakeString& Append(cm::string_view str)
143
0
  {
144
0
    this->String_.append(str);
145
0
    return *this;
146
0
  }
147
  CMakeString& Append(string_range range)
148
0
  {
149
0
    this->Append(cmJoin(range, {}));
150
0
    return *this;
151
0
  }
152
  CMakeString& Prepend(cm::string_view str)
153
0
  {
154
0
    this->String_.insert(0, str);
155
0
    return *this;
156
0
  }
157
  CMakeString& Prepend(string_range range)
158
0
  {
159
0
    this->Prepend(cmJoin(range, {}));
160
0
    return *this;
161
0
  }
162
163
  CMakeString& ToLower()
164
0
  {
165
0
    this->String_ = cmSystemTools::LowerCase(this->String_);
166
0
    return *this;
167
0
  }
168
  CMakeString& ToLower(cm::string_view str)
169
0
  {
170
0
    this->String_ = cmSystemTools::LowerCase(str);
171
0
    return *this;
172
0
  }
173
  CMakeString& ToUpper()
174
0
  {
175
0
    this->String_ = cmSystemTools::UpperCase(this->String_);
176
0
    return *this;
177
0
  }
178
  CMakeString& ToUpper(cm::string_view str)
179
0
  {
180
0
    this->String_ = cmSystemTools::UpperCase(str);
181
0
    return *this;
182
0
  }
183
184
  // Throw std::out_of_range if pos or count are outside of the expected range
185
  CMakeString Substring(long pos = 0, long count = -1) const;
186
187
  enum class StripItems
188
  {
189
    Space,
190
    Genex
191
  };
192
  CMakeString& Strip(StripItems stripItems = StripItems::Space);
193
194
  // Throw std::runtime_error  if quoting string failed
195
  enum class QuoteItems
196
  {
197
    Regex
198
  };
199
  CMakeString& Quote(QuoteItems quoteItems = QuoteItems::Regex);
200
201
  CMakeString& Repeat(size_type count);
202
203
  // Throw std::invalid_argument if the hash algorithm is invalid
204
  CMakeString& Hash(cm::string_view hashAlgorithm);
205
206
  // Throw std::invalid_argument if one of the codes is invalid
207
  CMakeString& FromASCII(string_range codes);
208
0
  CMakeString& ToHexadecimal() { return this->ToHexadecimal(this->String_); }
209
  CMakeString& ToHexadecimal(cm::string_view str);
210
211
  CMakeString& MakeCIdentifier()
212
0
  {
213
0
    this->String_ = cmSystemTools::MakeCidentifier(this->String_.str());
214
0
    return *this;
215
0
  }
216
  CMakeString& MakeCIdentifier(std::string const& str)
217
0
  {
218
0
    this->String_ = cmSystemTools::MakeCidentifier(str);
219
0
    return *this;
220
0
  }
221
222
  static cm::string_view const RandomDefaultAlphabet;
223
  // Throw std::invalid_argument if the alphabet is invalid
224
  //       std::out_of_range if length is outside valid range
225
  CMakeString& Random(std::size_t length = 5,
226
                      cm::string_view alphabet = RandomDefaultAlphabet)
227
0
  {
228
0
    return this->Random(cmSystemTools::RandomSeed(), length, alphabet);
229
0
  }
230
  CMakeString& Random(unsigned int seed, std::size_t length = 5,
231
                      cm::string_view alphabet = RandomDefaultAlphabet);
232
233
  enum class UTC
234
  {
235
    No,
236
    Yes
237
  };
238
  CMakeString& Timestamp(cm::string_view format, UTC utc = UTC::No);
239
240
  enum class UUIDType
241
  {
242
    MD5,
243
    SHA1
244
  };
245
  enum class Case
246
  {
247
    Lower,
248
    Upper
249
  };
250
  // Throw std::invalid_argument if namespace or the type are invalid
251
  //       std::runtime_error if the UUID cannot be generated
252
  CMakeString& UUID(cm::string_view nameSpace, cm::string_view name,
253
                    UUIDType type, Case uuidCase = Case::Lower);
254
255
private:
256
  static bool Seeded;
257
  cm::String String_;
258
};
259
}