cmCMakeString.hxx 6.2 KB

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