1
0

testStringAlgorithms.cxx 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include <cmConfigure.h> // IWYU pragma: keep
  4. #include <iostream>
  5. #include <sstream>
  6. #include <string>
  7. #include <vector>
  8. #include <cm/string_view>
  9. #include "cmStringAlgorithms.h"
  10. int testStringAlgorithms(int /*unused*/, char* /*unused*/ [])
  11. {
  12. int failed = 0;
  13. auto assert_ok = [&failed](bool test, cm::string_view title) {
  14. if (test) {
  15. std::cout << "Passed: " << title << "\n";
  16. } else {
  17. std::cout << "Failed: " << title << "\n";
  18. ++failed;
  19. }
  20. };
  21. auto assert_string = [&failed](cm::string_view generated,
  22. cm::string_view expected,
  23. cm::string_view title) {
  24. if (generated == expected) {
  25. std::cout << "Passed: " << title << "\n";
  26. } else {
  27. std::cout << "Failed: " << title << "\n";
  28. std::cout << "Expected: " << expected << "\n";
  29. std::cout << "Got: " << generated << "\n";
  30. ++failed;
  31. }
  32. };
  33. // ----------------------------------------------------------------------
  34. // Test cmTrimWhitespace
  35. {
  36. std::string base = "base";
  37. std::string spaces = " \f\f\n\n\r\r\t\t\v\v";
  38. assert_string(cmTrimWhitespace(spaces + base), base,
  39. "cmTrimWhitespace front");
  40. assert_string(cmTrimWhitespace(base + spaces), base,
  41. "cmTrimWhitespace back");
  42. assert_string(cmTrimWhitespace(spaces + base + spaces), base,
  43. "cmTrimWhitespace front and back");
  44. }
  45. // ----------------------------------------------------------------------
  46. // Test cmRemoveQuotes
  47. {
  48. auto test = [&assert_string](cm::string_view source,
  49. cm::string_view expected,
  50. cm::string_view title) {
  51. assert_string(cmRemoveQuotes(source), expected, title);
  52. };
  53. test("", "", "cmRemoveQuotes empty");
  54. test("\"", "\"", "cmRemoveQuotes single quote");
  55. test("\"\"", "", "cmRemoveQuotes double quote");
  56. test("\"a", "\"a", "cmRemoveQuotes quote char");
  57. test("\"ab", "\"ab", "cmRemoveQuotes quote char char");
  58. test("a\"", "a\"", "cmRemoveQuotes char quote");
  59. test("ab\"", "ab\"", "cmRemoveQuotes char char quote");
  60. test("a", "a", "cmRemoveQuotes single char");
  61. test("ab", "ab", "cmRemoveQuotes two chars");
  62. test("abc", "abc", "cmRemoveQuotes three chars");
  63. test("\"abc\"", "abc", "cmRemoveQuotes quoted chars");
  64. test("\"\"abc\"\"", "\"abc\"", "cmRemoveQuotes quoted quoted chars");
  65. }
  66. // ----------------------------------------------------------------------
  67. // Test cmEscapeQuotes
  68. {
  69. assert_string(cmEscapeQuotes("plain"), "plain", "cmEscapeQuotes plain");
  70. std::string base = "\"base\"\"";
  71. std::string result = "\\\"base\\\"\\\"";
  72. assert_string(cmEscapeQuotes(base), result, "cmEscapeQuotes escaped");
  73. }
  74. // ----------------------------------------------------------------------
  75. // Test cmJoin
  76. {
  77. typedef std::string ST;
  78. typedef std::vector<std::string> VT;
  79. assert_string(cmJoin(ST("abc"), ";"), "a;b;c", "cmJoin std::string");
  80. assert_string(cmJoin(VT{}, ";"), "", "cmJoin std::vector empty");
  81. assert_string(cmJoin(VT{ "a" }, ";"), "a", "cmJoin std::vector single");
  82. assert_string(cmJoin(VT{ "a", "b", "c" }, ";"), "a;b;c",
  83. "cmJoin std::vector multiple");
  84. assert_string(cmJoin(VT{ "a", "b", "c" }, "<=>"), "a<=>b<=>c",
  85. "cmJoin std::vector long sep");
  86. }
  87. // ----------------------------------------------------------------------
  88. // Test cmTokenize
  89. {
  90. typedef std::vector<std::string> VT;
  91. assert_ok(cmTokenize("", ";") == VT{ "" }, "cmTokenize empty");
  92. assert_ok(cmTokenize(";", ";") == VT{ "" }, "cmTokenize sep");
  93. assert_ok(cmTokenize("abc", ";") == VT{ "abc" }, "cmTokenize item");
  94. assert_ok(cmTokenize("abc;", ";") == VT{ "abc" }, "cmTokenize item sep");
  95. assert_ok(cmTokenize(";abc", ";") == VT{ "abc" }, "cmTokenize sep item");
  96. assert_ok(cmTokenize("abc;;efg", ";") == VT{ "abc", "efg" },
  97. "cmTokenize item sep sep item");
  98. assert_ok(cmTokenize("a1;a2;a3;a4", ";") == VT{ "a1", "a2", "a3", "a4" },
  99. "cmTokenize multiple items");
  100. }
  101. // ----------------------------------------------------------------------
  102. // Test cmStrCat
  103. {
  104. int ni = -1100;
  105. unsigned int nui = 1100u;
  106. long int nli = -12000l;
  107. unsigned long int nuli = 12000ul;
  108. long long int nlli = -130000ll;
  109. unsigned long long int nulli = 130000ull;
  110. std::string val =
  111. cmStrCat("<test>", ni, ',', nui, ',', nli, ",", nuli, ", ", nlli,
  112. std::string(", "), nulli, cm::string_view("</test>"));
  113. std::string expect =
  114. "<test>-1100,1100,-12000,12000, -130000, 130000</test>";
  115. assert_string(val, expect, "cmStrCat strings and integers");
  116. }
  117. {
  118. float const val = 1.5f;
  119. float const div = 0.00001f;
  120. float f = 0.0f;
  121. std::istringstream(cmStrCat("", val)) >> f;
  122. f -= val;
  123. assert_ok((f < div) && (f > -div), "cmStrCat float");
  124. }
  125. {
  126. double const val = 1.5;
  127. double const div = 0.00001;
  128. double d = 0.0;
  129. std::istringstream(cmStrCat("", val)) >> d;
  130. d -= val;
  131. assert_ok((d < div) && (d > -div), "cmStrCat double");
  132. }
  133. // ----------------------------------------------------------------------
  134. // Test cmWrap
  135. {
  136. typedef std::vector<std::string> VT;
  137. assert_string(cmWrap("<", VT{}, ">", "; "), //
  138. "", //
  139. "cmWrap empty, string prefix and suffix");
  140. assert_string(cmWrap("<", VT{ "abc" }, ">", "; "), //
  141. "<abc>", //
  142. "cmWrap single, string prefix and suffix");
  143. assert_string(cmWrap("<", VT{ "a1", "a2", "a3" }, ">", "; "), //
  144. "<a1>; <a2>; <a3>", //
  145. "cmWrap multiple, string prefix and suffix");
  146. assert_string(cmWrap('<', VT{}, '>', "; "), //
  147. "", //
  148. "cmWrap empty, char prefix and suffix");
  149. assert_string(cmWrap('<', VT{ "abc" }, '>', "; "), //
  150. "<abc>", //
  151. "cmWrap single, char prefix and suffix");
  152. assert_string(cmWrap('<', VT{ "a1", "a2", "a3" }, '>', "; "), //
  153. "<a1>; <a2>; <a3>", //
  154. "cmWrap multiple, char prefix and suffix");
  155. }
  156. // ----------------------------------------------------------------------
  157. // Test cmHas(Literal)Prefix and cmHas(Literal)Suffix
  158. {
  159. std::string str("abc");
  160. assert_ok(cmHasPrefix(str, 'a'), "cmHasPrefix char");
  161. assert_ok(!cmHasPrefix(str, 'c'), "cmHasPrefix char not");
  162. assert_ok(cmHasPrefix(str, "ab"), "cmHasPrefix string");
  163. assert_ok(!cmHasPrefix(str, "bc"), "cmHasPrefix string not");
  164. assert_ok(cmHasPrefix(str, str), "cmHasPrefix complete string");
  165. assert_ok(cmHasLiteralPrefix(str, "ab"), "cmHasLiteralPrefix string");
  166. assert_ok(!cmHasLiteralPrefix(str, "bc"), "cmHasLiteralPrefix string not");
  167. assert_ok(cmHasSuffix(str, 'c'), "cmHasSuffix char");
  168. assert_ok(!cmHasSuffix(str, 'a'), "cmHasSuffix char not");
  169. assert_ok(cmHasSuffix(str, "bc"), "cmHasSuffix string");
  170. assert_ok(!cmHasSuffix(str, "ab"), "cmHasSuffix string not");
  171. assert_ok(cmHasSuffix(str, str), "cmHasSuffix complete string");
  172. assert_ok(cmHasLiteralSuffix(str, "bc"), "cmHasLiteralSuffix string");
  173. assert_ok(!cmHasLiteralSuffix(str, "ab"), "cmHasLiteralPrefix string not");
  174. }
  175. // ----------------------------------------------------------------------
  176. // Test cmStrToLong
  177. {
  178. long value;
  179. assert_ok(cmStrToLong("1", &value) && value == 1,
  180. "cmStrToLong parses a positive decimal integer.");
  181. assert_ok(cmStrToLong(" 1", &value) && value == 1,
  182. "cmStrToLong parses a decimal integer after whitespace.");
  183. assert_ok(cmStrToLong("-1", &value) && value == -1,
  184. "cmStrToLong parses a negative decimal integer.");
  185. assert_ok(
  186. cmStrToLong(" -1", &value) && value == -1,
  187. "cmStrToLong parses a negative decimal integer after whitespace.");
  188. assert_ok(!cmStrToLong("1x", &value),
  189. "cmStrToLong rejects trailing content.");
  190. }
  191. // ----------------------------------------------------------------------
  192. // Test cmStrToULong
  193. {
  194. unsigned long value;
  195. assert_ok(cmStrToULong("1", &value) && value == 1,
  196. "cmStrToULong parses a decimal integer.");
  197. assert_ok(cmStrToULong(" 1", &value) && value == 1,
  198. "cmStrToULong parses a decimal integer after whitespace.");
  199. assert_ok(!cmStrToULong("-1", &value),
  200. "cmStrToULong rejects a negative number.");
  201. assert_ok(!cmStrToULong(" -1", &value),
  202. "cmStrToULong rejects a negative number after whitespace.");
  203. assert_ok(!cmStrToULong("1x", &value),
  204. "cmStrToULong rejects trailing content.");
  205. }
  206. // ----------------------------------------------------------------------
  207. // Test cmStrLen
  208. {
  209. constexpr auto len = cmStrLen("Hello world!");
  210. assert_ok(len == 12,
  211. "cmStrLen returns length of non-empty literal string");
  212. assert_ok(cmStrLen("") == 0,
  213. "cmStrLen returns length of empty literal string");
  214. }
  215. return failed;
  216. }