Blender V5.0
BLI_string_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "testing/testing.h"
6
7#include <array>
8#include <initializer_list>
9#include <ostream> /* NOLINT */
10#include <string>
11#include <utility>
12#include <vector>
13
14#include "MEM_guardedalloc.h"
15
16#include "BLI_string.h"
17#include "BLI_string_utf8.h"
18#include "BLI_string_utils.hh"
19#include "BLI_utildefines.h"
20
21using std::initializer_list;
22using std::pair;
23using std::string;
24using std::vector;
25
26/* -------------------------------------------------------------------- */
29
30TEST(string, StrCat)
31{
32#define STR_N_CAT(dst_init, dst_size, src, result_expect) \
33 { \
34 char dst[dst_size + 1] = dst_init; \
35 dst[dst_size] = 0xff; \
36 BLI_strncat(dst, src, dst_size); \
37 EXPECT_STREQ(dst, result_expect); \
38 EXPECT_EQ(dst[dst_size], 0xff); \
39 }
40
41 STR_N_CAT("", 1, "", "");
42 STR_N_CAT("", 1, "Y", "");
43 STR_N_CAT("", 2, "Y", "Y");
44 STR_N_CAT("", 2, "YZ", "Y");
45 STR_N_CAT("X", 2, "YZ", "X");
46 STR_N_CAT("ABC", 4, "XYZ", "ABC");
47 STR_N_CAT("ABC", 7, "XYZ", "ABCXYZ");
48#undef STR_N_CAT
49}
50
52
53/* -------------------------------------------------------------------- */
56
57TEST(string, StrReplaceRange)
58{
59#define STR_REPLACE_RANGE(src, size, beg, end, dst, result_expect) \
60 { \
61 char string[size] = src; \
62 BLI_string_replace_range(string, sizeof(string), beg, end, dst); \
63 EXPECT_STREQ(string, result_expect); \
64 }
65
66 STR_REPLACE_RANGE("a ", 5, 2, 2, "b!", "a b!");
67 STR_REPLACE_RANGE("a ", 4, 2, 2, "b!", "a b");
68 STR_REPLACE_RANGE("a ", 5, 1, 2, "b!", "ab!");
69 STR_REPLACE_RANGE("XYZ", 5, 1, 1, "A", "XAYZ");
70 STR_REPLACE_RANGE("XYZ", 5, 1, 1, "AB", "XABY");
71 STR_REPLACE_RANGE("XYZ", 5, 1, 1, "ABC", "XABC");
72
73 /* Add at the end when there is no room (no-op). */
74 STR_REPLACE_RANGE("XYZA", 5, 4, 4, "?", "XYZA");
75 /* Add at the start, replace all contents. */
76 STR_REPLACE_RANGE("XYZ", 4, 0, 0, "ABC", "ABC");
77 STR_REPLACE_RANGE("XYZ", 7, 0, 0, "ABC", "ABCXYZ");
78 /* Only remove. */
79 STR_REPLACE_RANGE("XYZ", 4, 1, 3, "", "X");
80 STR_REPLACE_RANGE("XYZ", 4, 0, 2, "", "Z");
81 STR_REPLACE_RANGE("XYZ", 4, 0, 3, "", "");
82 /* Only Add. */
83 STR_REPLACE_RANGE("", 4, 0, 0, "XYZ", "XYZ");
84 STR_REPLACE_RANGE("", 4, 0, 0, "XYZ?", "XYZ");
85 /* Do nothing. */
86 STR_REPLACE_RANGE("", 1, 0, 0, "?", "");
87 STR_REPLACE_RANGE("", 1, 0, 0, "", "");
88
89#undef STR_REPLACE_RANGE
90}
91
93
94/* -------------------------------------------------------------------- */
97
98/* BLI_str_partition */
99TEST(string, StrPartition)
100{
101 const char delim[] = {'-', '.', '_', '~', '\\', '\0'};
102 const char *sep, *suf;
103 size_t pre_len;
104
105 {
106 const char *str = "mat.e-r_ial";
107
108 /* "mat.e-r_ial" -> "mat", '.', "e-r_ial", 3 */
109 pre_len = BLI_str_partition(str, delim, &sep, &suf);
110 EXPECT_EQ(pre_len, 3);
111 EXPECT_EQ(&str[3], sep);
112 EXPECT_STREQ("e-r_ial", suf);
113 }
114
115 /* Corner cases. */
116 {
117 const char *str = ".mate-rial--";
118
119 /* ".mate-rial--" -> "", '.', "mate-rial--", 0 */
120 pre_len = BLI_str_partition(str, delim, &sep, &suf);
121 EXPECT_EQ(pre_len, 0);
122 EXPECT_EQ(&str[0], sep);
123 EXPECT_STREQ("mate-rial--", suf);
124 }
125
126 {
127 const char *str = ".__.--_";
128
129 /* ".__.--_" -> "", '.', "__.--_", 0 */
130 pre_len = BLI_str_partition(str, delim, &sep, &suf);
131 EXPECT_EQ(pre_len, 0);
132 EXPECT_EQ(&str[0], sep);
133 EXPECT_STREQ("__.--_", suf);
134 }
135
136 {
137 const char *str = "";
138
139 /* "" -> "", nullptr, nullptr, 0 */
140 pre_len = BLI_str_partition(str, delim, &sep, &suf);
141 EXPECT_EQ(pre_len, 0);
142 EXPECT_EQ(sep, (void *)nullptr);
143 EXPECT_EQ(suf, (void *)nullptr);
144 }
145
146 {
147 const char *str = "material";
148
149 /* "material" -> "material", nullptr, nullptr, 8 */
150 pre_len = BLI_str_partition(str, delim, &sep, &suf);
151 EXPECT_EQ(pre_len, 8);
152 EXPECT_EQ(sep, (void *)nullptr);
153 EXPECT_EQ(suf, (void *)nullptr);
154 }
155}
156
157/* BLI_str_rpartition */
158TEST(string, StrRPartition)
159{
160 const char delim[] = {'-', '.', '_', '~', '\\', '\0'};
161 const char *sep, *suf;
162 size_t pre_len;
163
164 {
165 const char *str = "mat.e-r_ial";
166
167 /* "mat.e-r_ial" -> "mat.e-r", '_', "ial", 7 */
168 pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
169 EXPECT_EQ(pre_len, 7);
170 EXPECT_EQ(&str[7], sep);
171 EXPECT_STREQ("ial", suf);
172 }
173
174 /* Corner cases. */
175 {
176 const char *str = ".mate-rial--";
177
178 /* ".mate-rial--" -> ".mate-rial-", '-', "", 11 */
179 pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
180 EXPECT_EQ(pre_len, 11);
181 EXPECT_EQ(&str[11], sep);
182 EXPECT_STREQ("", suf);
183 }
184
185 {
186 const char *str = ".__.--_";
187
188 /* ".__.--_" -> ".__.--", '_', "", 6 */
189 pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
190 EXPECT_EQ(pre_len, 6);
191 EXPECT_EQ(&str[6], sep);
192 EXPECT_STREQ("", suf);
193 }
194
195 {
196 const char *str = "";
197
198 /* "" -> "", nullptr, nullptr, 0 */
199 pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
200 EXPECT_EQ(pre_len, 0);
201 EXPECT_EQ(sep, (void *)nullptr);
202 EXPECT_EQ(suf, (void *)nullptr);
203 }
204
205 {
206 const char *str = "material";
207
208 /* "material" -> "material", nullptr, nullptr, 8 */
209 pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
210 EXPECT_EQ(pre_len, 8);
211 EXPECT_EQ(sep, (void *)nullptr);
212 EXPECT_EQ(suf, (void *)nullptr);
213 }
214}
215
216/* BLI_str_partition_ex */
217TEST(string, StrPartitionEx)
218{
219 const char delim[] = {'-', '.', '_', '~', '\\', '\0'};
220 const char *sep, *suf;
221 size_t pre_len;
222
223 /* Only considering 'from_right' cases here. */
224
225 {
226 const char *str = "mat.e-r_ia.l";
227
228 /* "mat.e-r_ia.l" over "mat.e-r" -> "mat.e", '.', "r_ia.l", 3 */
229 pre_len = BLI_str_partition_ex(str, str + 6, delim, &sep, &suf, true);
230 EXPECT_EQ(pre_len, 5);
231 EXPECT_EQ(&str[5], sep);
232 EXPECT_STREQ("r_ia.l", suf);
233 }
234
235 /* Corner cases. */
236 {
237 const char *str = "mate.rial";
238
239 /* "mate.rial" over "mate" -> "mate.rial", nullptr, nullptr, 4 */
240 pre_len = BLI_str_partition_ex(str, str + 4, delim, &sep, &suf, true);
241 EXPECT_EQ(pre_len, 4);
242 EXPECT_EQ(sep, (void *)nullptr);
243 EXPECT_EQ(suf, (void *)nullptr);
244 }
245}
246
247/* BLI_str_partition_utf8 */
248TEST(string, StrPartitionUtf8)
249{
250 const uint delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
251 const char *sep, *suf;
252 size_t pre_len;
253
254 {
255 const char *str = "ma\xc3\xb1te-r\xe2\x98\xafial";
256
257 /* "ma\xc3\xb1te-r\xe2\x98\xafial" -> "ma", '\xc3\xb1', "te-r\xe2\x98\xafial", 2 */
258 pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
259 EXPECT_EQ(pre_len, 2);
260 EXPECT_EQ(&str[2], sep);
261 EXPECT_STREQ("te-r\xe2\x98\xafial", suf);
262 }
263
264 /* Corner cases. */
265 {
266 const char *str = "\xe2\x98\xafmate-rial-\xc3\xb1";
267
268 /* "\xe2\x98\xafmate-rial-\xc3\xb1" -> "", '\xe2\x98\xaf', "mate-rial-\xc3\xb1", 0 */
269 pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
270 EXPECT_EQ(pre_len, 0);
271 EXPECT_EQ(&str[0], sep);
272 EXPECT_STREQ("mate-rial-\xc3\xb1", suf);
273 }
274
275 {
276 const char *str = "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1";
277
278 /* "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1" -> "", '\xe2\x98\xaf', ".\xc3\xb1_.--\xc3\xb1", 0 */
279 pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
280 EXPECT_EQ(pre_len, 0);
281 EXPECT_EQ(&str[0], sep);
282 EXPECT_STREQ(".\xc3\xb1_.--\xc3\xb1", suf);
283 }
284
285 {
286 const char *str = "";
287
288 /* "" -> "", nullptr, nullptr, 0 */
289 pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
290 EXPECT_EQ(pre_len, 0);
291 EXPECT_EQ(sep, (void *)nullptr);
292 EXPECT_EQ(suf, (void *)nullptr);
293 }
294
295 {
296 const char *str = "material";
297
298 /* "material" -> "material", nullptr, nullptr, 8 */
299 pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
300 EXPECT_EQ(pre_len, 8);
301 EXPECT_EQ(sep, (void *)nullptr);
302 EXPECT_EQ(suf, (void *)nullptr);
303 }
304}
305
306/* BLI_str_rpartition_utf8 */
307TEST(string, StrRPartitionUtf8)
308{
309 const uint delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
310 const char *sep, *suf;
311 size_t pre_len;
312
313 {
314 const char *str = "ma\xc3\xb1te-r\xe2\x98\xafial";
315
316 /* "ma\xc3\xb1te-r\xe2\x98\xafial" -> "mat\xc3\xb1te-r", '\xe2\x98\xaf', "ial", 8 */
317 pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
318 EXPECT_EQ(pre_len, 8);
319 EXPECT_EQ(&str[8], sep);
320 EXPECT_STREQ("ial", suf);
321 }
322
323 /* Corner cases. */
324 {
325 const char *str = "\xe2\x98\xafmate-rial-\xc3\xb1";
326
327 /* "\xe2\x98\xafmate-rial-\xc3\xb1" -> "\xe2\x98\xafmate-rial-", '\xc3\xb1', "", 13 */
328 pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
329 EXPECT_EQ(pre_len, 13);
330 EXPECT_EQ(&str[13], sep);
331 EXPECT_STREQ("", suf);
332 }
333
334 {
335 const char *str = "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1";
336
337 /* "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1" -> "\xe2\x98\xaf.\xc3\xb1_.--", '\xc3\xb1', "", 10 */
338 pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
339 EXPECT_EQ(pre_len, 10);
340 EXPECT_EQ(&str[10], sep);
341 EXPECT_STREQ("", suf);
342 }
343
344 {
345 const char *str = "";
346
347 /* "" -> "", nullptr, nullptr, 0 */
348 pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
349 EXPECT_EQ(pre_len, 0);
350 EXPECT_EQ(sep, (void *)nullptr);
351 EXPECT_EQ(suf, (void *)nullptr);
352 }
353
354 {
355 const char *str = "material";
356
357 /* "material" -> "material", nullptr, nullptr, 8 */
358 pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
359 EXPECT_EQ(pre_len, 8);
360 EXPECT_EQ(sep, (void *)nullptr);
361 EXPECT_EQ(suf, (void *)nullptr);
362 }
363}
364
365/* BLI_str_partition_ex_utf8 */
366TEST(string, StrPartitionExUtf8)
367{
368 const uint delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
369 const char *sep, *suf;
370 size_t pre_len;
371
372 /* Only considering 'from_right' cases here. */
373
374 {
375 const char *str = "ma\xc3\xb1te-r\xe2\x98\xafial";
376
377 /* "ma\xc3\xb1te-r\xe2\x98\xafial" over
378 * "ma\xc3\xb1te" -> "ma", '\xc3\xb1', "te-r\xe2\x98\xafial", 2 */
379 pre_len = BLI_str_partition_ex_utf8(str, str + 6, delim, &sep, &suf, true);
380 EXPECT_EQ(pre_len, 2);
381 EXPECT_EQ(&str[2], sep);
382 EXPECT_STREQ("te-r\xe2\x98\xafial", suf);
383 }
384
385 /* Corner cases. */
386 {
387 const char *str = "mate\xe2\x98\xafrial";
388
389 /* "mate\xe2\x98\xafrial" over "mate" -> "mate\xe2\x98\xafrial", nullptr, nullptr, 4 */
390 pre_len = BLI_str_partition_ex_utf8(str, str + 4, delim, &sep, &suf, true);
391 EXPECT_EQ(pre_len, 4);
392 EXPECT_EQ(sep, (void *)nullptr);
393 EXPECT_EQ(suf, (void *)nullptr);
394 }
395}
396
398
399/* -------------------------------------------------------------------- */
402
403/* BLI_str_format_int_grouped */
404TEST(string, StrFormatIntGrouped)
405{
406 char number_str[BLI_STR_FORMAT_INT32_GROUPED_SIZE];
407 int number;
408
409 BLI_str_format_int_grouped(number_str, number = 0);
410 EXPECT_STREQ("0", number_str);
411
412 BLI_str_format_int_grouped(number_str, number = 1);
413 EXPECT_STREQ("1", number_str);
414
415 BLI_str_format_int_grouped(number_str, number = -1);
416 EXPECT_STREQ("-1", number_str);
417
418 BLI_str_format_int_grouped(number_str, number = 1000);
419 EXPECT_STREQ("1,000", number_str);
420
421 BLI_str_format_int_grouped(number_str, number = -1000);
422 EXPECT_STREQ("-1,000", number_str);
423
424 BLI_str_format_int_grouped(number_str, number = 999);
425 EXPECT_STREQ("999", number_str);
426
427 BLI_str_format_int_grouped(number_str, number = -999);
428 EXPECT_STREQ("-999", number_str);
429
430 BLI_str_format_int_grouped(number_str, number = 2147483647);
431 EXPECT_STREQ("2,147,483,647", number_str);
432
433 BLI_str_format_int_grouped(number_str, number = -2147483648);
434 EXPECT_STREQ("-2,147,483,648", number_str);
435 /* Ensure the limit is correct. */
436 EXPECT_EQ(sizeof(number_str), strlen(number_str) + 1);
437}
438
439/* BLI_str_format_uint64_grouped */
440TEST(string, StrFormatUint64Grouped)
441{
442 char number_str[BLI_STR_FORMAT_UINT64_GROUPED_SIZE];
443 uint64_t number;
444
445 BLI_str_format_uint64_grouped(number_str, number = 0);
446 EXPECT_STREQ("0", number_str);
447
448 BLI_str_format_uint64_grouped(number_str, number = 1);
449 EXPECT_STREQ("1", number_str);
450
451 BLI_str_format_uint64_grouped(number_str, number = 999);
452 EXPECT_STREQ("999", number_str);
453
454 BLI_str_format_uint64_grouped(number_str, number = 1000);
455 EXPECT_STREQ("1,000", number_str);
456
457 BLI_str_format_uint64_grouped(number_str, number = 18446744073709551615u);
458 EXPECT_STREQ("18,446,744,073,709,551,615", number_str);
459 /* Ensure the limit is correct. */
460 EXPECT_EQ(sizeof(number_str), strlen(number_str) + 1);
461}
462
464
465/* -------------------------------------------------------------------- */
468
469/* BLI_str_format_byte_unit */
470TEST(string, StrFormatByteUnits)
471{
473 long long int size;
474
475 /* Base 10 */
476 BLI_str_format_byte_unit(size_str, size = 0, true);
477 EXPECT_STREQ("0 B", size_str);
478 BLI_str_format_byte_unit(size_str, size = -0, true);
479 EXPECT_STREQ("0 B", size_str);
480
481 BLI_str_format_byte_unit(size_str, size = 1, true);
482 EXPECT_STREQ("1 B", size_str);
483 BLI_str_format_byte_unit(size_str, size = -1, true);
484 EXPECT_STREQ("-1 B", size_str);
485
486 BLI_str_format_byte_unit(size_str, size = 1000, true);
487 EXPECT_STREQ("1 KB", size_str);
488 BLI_str_format_byte_unit(size_str, size = -1000, true);
489 EXPECT_STREQ("-1 KB", size_str);
490
491 BLI_str_format_byte_unit(size_str, size = 1024, true);
492 EXPECT_STREQ("1 KB", size_str);
493 BLI_str_format_byte_unit(size_str, size = -1024, true);
494 EXPECT_STREQ("-1 KB", size_str);
495
496 /* LLONG_MAX - largest possible value */
497 BLI_str_format_byte_unit(size_str, size = 9223372036854775807, true);
498 EXPECT_STREQ("9223.372 PB", size_str);
499 BLI_str_format_byte_unit(size_str, size = -9223372036854775807, true);
500 EXPECT_STREQ("-9223.372 PB", size_str);
501
502 /* Base 2 */
503 BLI_str_format_byte_unit(size_str, size = 0, false);
504 EXPECT_STREQ("0 B", size_str);
505 BLI_str_format_byte_unit(size_str, size = -0, false);
506 EXPECT_STREQ("0 B", size_str);
507
508 BLI_str_format_byte_unit(size_str, size = 1, false);
509 EXPECT_STREQ("1 B", size_str);
510 BLI_str_format_byte_unit(size_str, size = -1, false);
511 EXPECT_STREQ("-1 B", size_str);
512
513 BLI_str_format_byte_unit(size_str, size = 1000, false);
514 EXPECT_STREQ("1000 B", size_str);
515 BLI_str_format_byte_unit(size_str, size = -1000, false);
516 EXPECT_STREQ("-1000 B", size_str);
517
518 BLI_str_format_byte_unit(size_str, size = 1024, false);
519 EXPECT_STREQ("1 KiB", size_str);
520 BLI_str_format_byte_unit(size_str, size = -1024, false);
521 EXPECT_STREQ("-1 KiB", size_str);
522
523 /* LLONG_MAX - largest possible value */
524 BLI_str_format_byte_unit(size_str, size = 9223372036854775807, false);
525 EXPECT_STREQ("8192.0 PiB", size_str);
526 BLI_str_format_byte_unit(size_str, size = -9223372036854775807, false);
527 EXPECT_STREQ("-8192.0 PiB", size_str);
528
529 /* Test maximum string length. */
530 BLI_str_format_byte_unit(size_str, size = -9223200000000000000, false);
531 EXPECT_STREQ("-8191.8472 PiB", size_str);
532 /* Ensure the limit is correct. */
533 EXPECT_EQ(sizeof(size_str), strlen(size_str) + 1);
534}
535
537
538/* -------------------------------------------------------------------- */
541
542/* BLI_str_format_decimal_unit */
543TEST(string, StrFormatDecimalUnits)
544{
546 int size;
547
548 BLI_str_format_decimal_unit(size_str, size = 0);
549 EXPECT_STREQ("0", size_str);
550 BLI_str_format_decimal_unit(size_str, size = 1);
551 EXPECT_STREQ("1", size_str);
552 BLI_str_format_decimal_unit(size_str, size = 10);
553 EXPECT_STREQ("10", size_str);
554 BLI_str_format_decimal_unit(size_str, size = 15);
555 EXPECT_STREQ("15", size_str);
556 BLI_str_format_decimal_unit(size_str, size = 100);
557 EXPECT_STREQ("100", size_str);
558 BLI_str_format_decimal_unit(size_str, size = 155);
559 EXPECT_STREQ("155", size_str);
560 BLI_str_format_decimal_unit(size_str, size = 1000);
561 EXPECT_STREQ("1.0K", size_str);
562 BLI_str_format_decimal_unit(size_str, size = 1555);
563 EXPECT_STREQ("1.6K", size_str);
564 BLI_str_format_decimal_unit(size_str, size = 10000);
565 EXPECT_STREQ("10.0K", size_str);
566 BLI_str_format_decimal_unit(size_str, size = 15555);
567 EXPECT_STREQ("15.6K", size_str);
568 BLI_str_format_decimal_unit(size_str, size = 100000);
569 EXPECT_STREQ("100K", size_str);
570 BLI_str_format_decimal_unit(size_str, size = 100000);
571 EXPECT_STREQ("100K", size_str);
572 BLI_str_format_decimal_unit(size_str, size = 155555);
573 EXPECT_STREQ("156K", size_str);
574 BLI_str_format_decimal_unit(size_str, size = 1000000);
575 EXPECT_STREQ("1.0M", size_str);
576 BLI_str_format_decimal_unit(size_str, size = 1555555);
577 EXPECT_STREQ("1.6M", size_str);
578 BLI_str_format_decimal_unit(size_str, size = 10000000);
579 EXPECT_STREQ("10.0M", size_str);
580 BLI_str_format_decimal_unit(size_str, size = 15555555);
581 EXPECT_STREQ("15.6M", size_str);
582 BLI_str_format_decimal_unit(size_str, size = 100000000);
583 EXPECT_STREQ("100M", size_str);
584 BLI_str_format_decimal_unit(size_str, size = 155555555);
585 EXPECT_STREQ("156M", size_str);
586 BLI_str_format_decimal_unit(size_str, size = 1000000000);
587 EXPECT_STREQ("1.0B", size_str);
588
589 /* Largest possible value. */
591 EXPECT_STREQ("2.1B", size_str);
592
593 BLI_str_format_decimal_unit(size_str, size = -0);
594 EXPECT_STREQ("0", size_str);
595 BLI_str_format_decimal_unit(size_str, size = -1);
596 EXPECT_STREQ("-1", size_str);
597 BLI_str_format_decimal_unit(size_str, size = -10);
598 EXPECT_STREQ("-10", size_str);
599 BLI_str_format_decimal_unit(size_str, size = -15);
600 EXPECT_STREQ("-15", size_str);
601 BLI_str_format_decimal_unit(size_str, size = -100);
602 EXPECT_STREQ("-100", size_str);
603 BLI_str_format_decimal_unit(size_str, size = -155);
604 EXPECT_STREQ("-155", size_str);
605 BLI_str_format_decimal_unit(size_str, size = -1000);
606 EXPECT_STREQ("-1.0K", size_str);
607 BLI_str_format_decimal_unit(size_str, size = -1555);
608 EXPECT_STREQ("-1.6K", size_str);
609 BLI_str_format_decimal_unit(size_str, size = -10000);
610 EXPECT_STREQ("-10.0K", size_str);
611 BLI_str_format_decimal_unit(size_str, size = -15555);
612 EXPECT_STREQ("-15.6K", size_str);
613 BLI_str_format_decimal_unit(size_str, size = -100000);
614 EXPECT_STREQ("-100K", size_str);
615 BLI_str_format_decimal_unit(size_str, size = -155555);
616 EXPECT_STREQ("-156K", size_str);
617 BLI_str_format_decimal_unit(size_str, size = -1000000);
618 EXPECT_STREQ("-1.0M", size_str);
619 BLI_str_format_decimal_unit(size_str, size = -1555555);
620 EXPECT_STREQ("-1.6M", size_str);
621 BLI_str_format_decimal_unit(size_str, size = -10000000);
622 EXPECT_STREQ("-10.0M", size_str);
623 BLI_str_format_decimal_unit(size_str, size = -15555555);
624 EXPECT_STREQ("-15.6M", size_str);
625 BLI_str_format_decimal_unit(size_str, size = -100000000);
626 EXPECT_STREQ("-100M", size_str);
627 BLI_str_format_decimal_unit(size_str, size = -155555555);
628 EXPECT_STREQ("-156M", size_str);
629 BLI_str_format_decimal_unit(size_str, size = -1000000000);
630 EXPECT_STREQ("-1.0B", size_str);
631
632 /* Smallest possible value. */
634 EXPECT_STREQ("-2.1B", size_str);
635}
636
637/* BLI_str_format_integer_unit */
638TEST(string, StrFormatIntegerUnits)
639{
641 int size;
642
643 BLI_str_format_integer_unit(size_str, size = 0);
644 EXPECT_STREQ("0", size_str);
645 BLI_str_format_integer_unit(size_str, size = 1);
646 EXPECT_STREQ("1", size_str);
647 BLI_str_format_integer_unit(size_str, size = 10);
648 EXPECT_STREQ("10", size_str);
649 BLI_str_format_integer_unit(size_str, size = 15);
650 EXPECT_STREQ("15", size_str);
651 BLI_str_format_integer_unit(size_str, size = 100);
652 EXPECT_STREQ("100", size_str);
653 BLI_str_format_integer_unit(size_str, size = 155);
654 EXPECT_STREQ("155", size_str);
655 BLI_str_format_integer_unit(size_str, size = 1000);
656 EXPECT_STREQ("1K", size_str);
657 BLI_str_format_integer_unit(size_str, size = 1555);
658 EXPECT_STREQ("1K", size_str);
659 BLI_str_format_integer_unit(size_str, size = 10000);
660 EXPECT_STREQ("10K", size_str);
661 BLI_str_format_integer_unit(size_str, size = 15555);
662 EXPECT_STREQ("15K", size_str);
663 BLI_str_format_integer_unit(size_str, size = 100000);
664 EXPECT_STREQ(".1M", size_str);
665 BLI_str_format_integer_unit(size_str, size = 155555);
666 EXPECT_STREQ(".1M", size_str);
667 BLI_str_format_integer_unit(size_str, size = 1000000);
668 EXPECT_STREQ("1M", size_str);
669 BLI_str_format_integer_unit(size_str, size = 1555555);
670 EXPECT_STREQ("1M", size_str);
671 BLI_str_format_integer_unit(size_str, size = 2555555);
672 EXPECT_STREQ("2M", size_str);
673 BLI_str_format_integer_unit(size_str, size = 10000000);
674 EXPECT_STREQ("10M", size_str);
675 BLI_str_format_integer_unit(size_str, size = 15555555);
676 EXPECT_STREQ("15M", size_str);
677 BLI_str_format_integer_unit(size_str, size = 100000000);
678 EXPECT_STREQ(".1B", size_str);
679 BLI_str_format_integer_unit(size_str, size = 155555555);
680 EXPECT_STREQ(".1B", size_str);
681 BLI_str_format_integer_unit(size_str, size = 255555555);
682 EXPECT_STREQ(".2B", size_str);
683 BLI_str_format_integer_unit(size_str, size = 1000000000);
684 EXPECT_STREQ("1B", size_str);
685
686 /* Largest possible value. */
688 EXPECT_STREQ("2B", size_str);
689
690 BLI_str_format_integer_unit(size_str, size = -0);
691 EXPECT_STREQ("0", size_str);
692 BLI_str_format_integer_unit(size_str, size = -1);
693 EXPECT_STREQ("-1", size_str);
694 BLI_str_format_integer_unit(size_str, size = -10);
695 EXPECT_STREQ("-10", size_str);
696 BLI_str_format_integer_unit(size_str, size = -15);
697 EXPECT_STREQ("-15", size_str);
698 BLI_str_format_integer_unit(size_str, size = -100);
699 EXPECT_STREQ("-100", size_str);
700 BLI_str_format_integer_unit(size_str, size = -155);
701 EXPECT_STREQ("-155", size_str);
702 BLI_str_format_integer_unit(size_str, size = -1000);
703 EXPECT_STREQ("-1K", size_str);
704 BLI_str_format_integer_unit(size_str, size = -1555);
705 EXPECT_STREQ("-1K", size_str);
706 BLI_str_format_integer_unit(size_str, size = -10000);
707 EXPECT_STREQ("-10K", size_str);
708 BLI_str_format_integer_unit(size_str, size = -15555);
709 EXPECT_STREQ("-15K", size_str);
710 BLI_str_format_integer_unit(size_str, size = -100000);
711 EXPECT_STREQ("-.1M", size_str);
712 BLI_str_format_integer_unit(size_str, size = -155555);
713 EXPECT_STREQ("-.1M", size_str);
714 BLI_str_format_integer_unit(size_str, size = -1000000);
715 EXPECT_STREQ("-1M", size_str);
716 BLI_str_format_integer_unit(size_str, size = -1555555);
717 EXPECT_STREQ("-1M", size_str);
718 BLI_str_format_integer_unit(size_str, size = -10000000);
719 EXPECT_STREQ("-10M", size_str);
720 BLI_str_format_integer_unit(size_str, size = -15555555);
721 EXPECT_STREQ("-15M", size_str);
722 BLI_str_format_integer_unit(size_str, size = -100000000);
723 EXPECT_STREQ("-.1B", size_str);
724 BLI_str_format_integer_unit(size_str, size = -155555555);
725 EXPECT_STREQ("-.1B", size_str);
726 BLI_str_format_integer_unit(size_str, size = -1000000000);
727 EXPECT_STREQ("-1B", size_str);
728
729 /* Smallest possible value. */
731 EXPECT_STREQ("-2B", size_str);
732}
733
735
736/* -------------------------------------------------------------------- */
739
740TEST(string, StringNLen)
741{
742 EXPECT_EQ(0, BLI_strnlen("", 0));
743 EXPECT_EQ(0, BLI_strnlen("", 1));
744 EXPECT_EQ(0, BLI_strnlen("", 100));
745
746 EXPECT_EQ(0, BLI_strnlen("x", 0));
747 EXPECT_EQ(1, BLI_strnlen("x", 1));
748 EXPECT_EQ(1, BLI_strnlen("x", 100));
749
750 /* `ü` is `\xc3\xbc`. */
751 EXPECT_EQ(2, BLI_strnlen("ü", 100));
752
753 EXPECT_EQ(0, BLI_strnlen("this is a longer string", 0));
754 EXPECT_EQ(1, BLI_strnlen("this is a longer string", 1));
755 EXPECT_EQ(5, BLI_strnlen("this is a longer string", 5));
756 EXPECT_EQ(47, BLI_strnlen("This string writes about an agent without name.", 100));
757}
758
760
761/* -------------------------------------------------------------------- */
764
765#define BUFFER_SIZE 128
766
767static void string_join_array_test_truncate(const char *strings[],
768 int strings_num,
769 char buffer[BUFFER_SIZE])
770{
771 const int buffer_len = BLI_string_join_array(buffer, BUFFER_SIZE, strings, strings_num);
772
773 { /* Ensure the allocated version is the same. */
774 char *buffer_alloc = BLI_string_join_arrayN(strings, strings_num);
775 EXPECT_STREQ(buffer_alloc, buffer);
776 MEM_freeN(buffer_alloc);
777 }
778
779 for (int dst_size = buffer_len + 1; dst_size > 0; dst_size--) {
780 char dst_tmp[BUFFER_SIZE];
781 int dst_tmp_len = BLI_string_join_array(dst_tmp, dst_size, strings, strings_num);
782 EXPECT_EQ(dst_tmp_len + 1, dst_size);
783 EXPECT_EQ(strncmp(dst_tmp, buffer, dst_tmp_len), 0);
784 }
785}
786
787static void string_join_array_with_sep_char_test_truncate(const char *strings[],
788 int strings_num,
789 char buffer[BUFFER_SIZE])
790{
791 const int buffer_len = BLI_string_join_array_by_sep_char(
792 buffer, BUFFER_SIZE, '|', strings, strings_num);
793
794 { /* Ensure the allocated version is the same. */
795 char *buffer_alloc = BLI_string_join_array_by_sep_charN('|', strings, strings_num);
796 EXPECT_STREQ(buffer_alloc, buffer);
797 MEM_freeN(buffer_alloc);
798 }
799
800 for (int dst_size = buffer_len + 1; dst_size > 0; dst_size--) {
801 char dst_tmp[BUFFER_SIZE];
802 int dst_tmp_len = BLI_string_join_array_by_sep_char(
803 dst_tmp, dst_size, '|', strings, strings_num);
804 EXPECT_EQ(dst_tmp_len + 1, dst_size);
805 EXPECT_EQ(strncmp(dst_tmp, buffer, dst_tmp_len), 0);
806 }
807}
808
809TEST(string, StrJoin_Truncate)
810{
811 char buffer[BUFFER_SIZE];
812 { /* Multiple single char words. */
813 const char *strings[] = {"a", "b", "c", "d", "e", "f"};
814 string_join_array_test_truncate(strings, ARRAY_SIZE(strings), buffer);
815 EXPECT_STREQ(buffer, "abcdef");
817 EXPECT_STREQ(buffer, "a|b|c|d|e|f");
818 }
819 { /* Multiple char pair words. */
820 const char *strings[] = {"aa", "bb", "cc", "dd", "ee", "ff"};
821 string_join_array_test_truncate(strings, ARRAY_SIZE(strings), buffer);
822 EXPECT_STREQ(buffer, "aabbccddeeff");
824 EXPECT_STREQ(buffer, "aa|bb|cc|dd|ee|ff");
825 }
826 { /* Multiple empty words. */
827 const char *strings[] = {"", "", "", "", "", ""};
828 string_join_array_test_truncate(strings, ARRAY_SIZE(strings), buffer);
829 EXPECT_STREQ(buffer, "");
831 EXPECT_STREQ(buffer, "|||||");
832 }
833 { /* Single word. */
834 const char *strings[] = {"test"};
835 string_join_array_test_truncate(strings, ARRAY_SIZE(strings), buffer);
836 EXPECT_STREQ(buffer, "test");
838 EXPECT_STREQ(buffer, "test");
839 }
840 { /* Empty item. */
841 const char *strings[] = {""};
842 string_join_array_test_truncate(strings, ARRAY_SIZE(strings), buffer);
843 EXPECT_STREQ(buffer, "");
845 EXPECT_STREQ(buffer, "");
846 }
847 { /* Empty array. */
848 const char *strings[] = {"a"};
849 string_join_array_test_truncate(strings, 0, buffer);
850 EXPECT_STREQ(buffer, "");
852 EXPECT_STREQ(buffer, "");
853 }
854}
855
856#undef BUFFER_SIZE
857
859
860/* -------------------------------------------------------------------- */
863
864struct WordInfo {
865 WordInfo() = default;
866 WordInfo(int start, int end) : start(start), end(end) {}
867 bool operator==(const WordInfo &other) const
868 {
869 return start == other.start && end == other.end;
870 }
871 int start, end;
872};
873static std::ostream &operator<<(std::ostream &os, const WordInfo &word_info)
874{
875 os << "start: " << word_info.start << ", end: " << word_info.end;
876 return os;
877}
878
879class StringFindSplitWords : public testing::Test {
880 protected:
882
883 /* If max_words is -1 it will be initialized from the number of expected
884 * words +1. This way there is no need to pass an explicit number of words,
885 * but is also making it possible to catch situation when too many words
886 * are being returned. */
887 void testStringFindSplitWords(const string &str,
888 const size_t max_length,
889 initializer_list<WordInfo> expected_words_info_init,
890 int max_words = -1)
891 {
892 const vector<WordInfo> expected_words_info = expected_words_info_init;
893 if (max_words != -1) {
894 CHECK_LE(max_words, expected_words_info.size() - 1);
895 }
896 /* Since number of word info is used here, this makes it so we allow one
897 * extra word to be collected from the input. This allows to catch possible
898 * issues with word splitting not doing a correct thing. */
899 const int effective_max_words = (max_words == -1) ? expected_words_info.size() : max_words;
900 /* One extra element for the {-1, -1}. */
901 vector<WordInfo> actual_word_info(effective_max_words + 1, WordInfo(-1, -1));
902 const int actual_word_num = BLI_string_find_split_words(
903 str.c_str(),
904 max_length,
905 ' ',
906 reinterpret_cast<int (*)[2]>(actual_word_info.data()),
907 effective_max_words);
908 /* Schrink actual array to an actual number of words, so we can compare
909 * vectors as-is. */
910 EXPECT_LE(actual_word_num, actual_word_info.size() - 1);
911 actual_word_info.resize(actual_word_num + 1);
912 /* Perform actual comparison. */
913 EXPECT_EQ_VECTOR(actual_word_info, expected_words_info);
914 }
915
916 void testStringFindSplitWords(const string &str,
917 initializer_list<WordInfo> expected_words_info_init)
918 {
919 testStringFindSplitWords(str, str.length(), expected_words_info_init);
920 }
921};
922
923/* BLI_string_find_split_words */
925{
926 testStringFindSplitWords("t", {{0, 1}, {-1, -1}});
927 testStringFindSplitWords("test", {{0, 4}, {-1, -1}});
928}
930{
931 testStringFindSplitWords("f t w", {{0, 1}, {2, 1}, {4, 1}, {-1, -1}});
932 testStringFindSplitWords("find three words", {{0, 4}, {5, 5}, {11, 5}, {-1, -1}});
933}
935{
936 testStringFindSplitWords("# ## ### ####", {{0, 1}, {2, 2}, {5, 3}, {9, 4}, {-1, -1}});
937 testStringFindSplitWords("# # # #", {{0, 1}, {3, 1}, {7, 1}, {12, 1}, {-1, -1}});
938}
940{
941 testStringFindSplitWords(" t", {{3, 1}, {-1, -1}});
942 testStringFindSplitWords(" test", {{3, 4}, {-1, -1}});
943}
945{
946 testStringFindSplitWords("t ", {{0, 1}, {-1, -1}});
947 testStringFindSplitWords("test ", {{0, 4}, {-1, -1}});
948}
949TEST_F(StringFindSplitWords, Trailing_LeftRight)
950{
951 testStringFindSplitWords(" surrounding space test 123 ",
952 {{3, 11}, {15, 5}, {21, 4}, {28, 3}, {-1, -1}});
953}
955{
956 testStringFindSplitWords("", {{-1, -1}});
957}
959{
960 testStringFindSplitWords(" ", {{-1, -1}});
961 testStringFindSplitWords(" ", {{-1, -1}});
962}
964{
965 const string words = "too many chars";
966 const int words_len = words.length();
967 testStringFindSplitWords(words, words_len, {{0, 3}, {4, 4}, {9, 5}, {-1, -1}}, 3);
968 testStringFindSplitWords(words, words_len, {{0, 3}, {4, 4}, {-1, -1}}, 2);
969 testStringFindSplitWords(words, words_len, {{0, 3}, {-1, -1}}, 1);
970 testStringFindSplitWords(words, words_len, {{-1, -1}}, 0);
971}
973{
974 const string words = "too many chars";
975 const int words_len = words.length();
976 testStringFindSplitWords(words, words_len, {{0, 3}, {4, 4}, {9, 5}, {-1, -1}});
977 testStringFindSplitWords(words, words_len - 1, {{0, 3}, {4, 4}, {9, 4}, {-1, -1}});
978 testStringFindSplitWords(words, words_len - 5, {{0, 3}, {4, 4}, {-1, -1}});
979 testStringFindSplitWords(words, 1, {{0, 1}, {-1, -1}});
980 testStringFindSplitWords(words, 0, {{-1, -1}});
981}
982
984
985/* -------------------------------------------------------------------- */
988
989/* #BLI_string_elem_split_by_delim */
990
991TEST(string, StringElemEmpty)
992{
993 EXPECT_FALSE(BLI_string_elem_split_by_delim("A", ':', ""));
994
995 EXPECT_TRUE(BLI_string_elem_split_by_delim("", ':', ""));
996 EXPECT_TRUE(BLI_string_elem_split_by_delim(":", ':', ""));
997 EXPECT_TRUE(BLI_string_elem_split_by_delim("::", ':', ""));
998 EXPECT_TRUE(BLI_string_elem_split_by_delim("A:", ':', ""));
999 EXPECT_TRUE(BLI_string_elem_split_by_delim(":A", ':', ""));
1000}
1001
1002TEST(string, StringElemSingle)
1003{
1004 EXPECT_TRUE(BLI_string_elem_split_by_delim("A", ':', "A"));
1005 EXPECT_FALSE(BLI_string_elem_split_by_delim("A", ':', "B"));
1006
1007 EXPECT_TRUE(BLI_string_elem_split_by_delim("B", 'A', "B"));
1008 EXPECT_FALSE(BLI_string_elem_split_by_delim("A", 'A', "A"));
1009}
1010
1011TEST(string, StringElemComplex)
1012{
1013 EXPECT_TRUE(BLI_string_elem_split_by_delim("TEST", ':', "TEST"));
1014
1015 EXPECT_TRUE(BLI_string_elem_split_by_delim(":TEST", ':', "TEST"));
1016 EXPECT_TRUE(BLI_string_elem_split_by_delim("TEST:", ':', "TEST"));
1017 EXPECT_TRUE(BLI_string_elem_split_by_delim(":TEST:", ':', "TEST"));
1018
1019 EXPECT_TRUE(BLI_string_elem_split_by_delim("::TEST", ':', "TEST"));
1020 EXPECT_TRUE(BLI_string_elem_split_by_delim("TEST::", ':', "TEST"));
1021 EXPECT_TRUE(BLI_string_elem_split_by_delim("::TEST::", ':', "TEST"));
1022
1023 EXPECT_FALSE(BLI_string_elem_split_by_delim(":TEST ", ':', "TEST"));
1024 EXPECT_FALSE(BLI_string_elem_split_by_delim(" TEST:", ':', "TEST"));
1025 EXPECT_FALSE(BLI_string_elem_split_by_delim(": TEST :", ':', "TEST"));
1026
1027 EXPECT_TRUE(BLI_string_elem_split_by_delim("A:B:TEST", ':', "TEST"));
1028 EXPECT_TRUE(BLI_string_elem_split_by_delim("TEST:A:B", ':', "TEST"));
1029 EXPECT_TRUE(BLI_string_elem_split_by_delim("A:TEST:B", ':', "TEST"));
1030 EXPECT_TRUE(BLI_string_elem_split_by_delim(":A:TEST:B:", ':', "TEST"));
1031}
1032
1034
1035/* -------------------------------------------------------------------- */
1038
1039/* BLI_strncasestr */
1040TEST(string, StringStrncasestr)
1041{
1042 const char *str_test0 = "search here";
1043 const char *res;
1044
1045 res = BLI_strncasestr(str_test0, "", 0);
1046 EXPECT_EQ(res, str_test0);
1047
1048 res = BLI_strncasestr(str_test0, " ", 1);
1049 EXPECT_EQ(res, str_test0 + 6);
1050
1051 res = BLI_strncasestr(str_test0, "her", 3);
1052 EXPECT_EQ(res, str_test0 + 7);
1053
1054 res = BLI_strncasestr(str_test0, "ARCh", 4);
1055 EXPECT_EQ(res, str_test0 + 2);
1056
1057 res = BLI_strncasestr(str_test0, "earcq", 4);
1058 EXPECT_EQ(res, str_test0 + 1);
1059
1060 res = BLI_strncasestr(str_test0, "not there", 9);
1061 EXPECT_EQ(res, (void *)nullptr);
1062}
1063
1065
1066/* -------------------------------------------------------------------- */
1069
1070/* BLI_string_max_possible_word_count */
1079
1081
1082/* -------------------------------------------------------------------- */
1085
1086/* BLI_string_is_decimal */
1087TEST(string, StrIsDecimal)
1088{
1089 EXPECT_FALSE(BLI_string_is_decimal(""));
1090 EXPECT_FALSE(BLI_string_is_decimal("je moeder"));
1091 EXPECT_FALSE(BLI_string_is_decimal("je møder"));
1092 EXPECT_FALSE(BLI_string_is_decimal("Agent 327"));
1093 EXPECT_FALSE(BLI_string_is_decimal("Agent\000327"));
1094 EXPECT_FALSE(BLI_string_is_decimal("\000327"));
1095 EXPECT_FALSE(BLI_string_is_decimal("0x16"));
1096 EXPECT_FALSE(BLI_string_is_decimal("16.4"));
1097 EXPECT_FALSE(BLI_string_is_decimal("-1"));
1098
1099 EXPECT_TRUE(BLI_string_is_decimal("0"));
1100 EXPECT_TRUE(BLI_string_is_decimal("1"));
1101 EXPECT_TRUE(BLI_string_is_decimal("001"));
1102 EXPECT_TRUE(BLI_string_is_decimal("11342908713948713498745980171334059871345098713405981734"));
1103}
1104
1106
1107/* -------------------------------------------------------------------- */
1110
1111/* BLI_strcasecmp_natural */
1112class StringCasecmpNatural : public testing::Test {
1113 protected:
1115
1117
1119 {
1120 for (const auto &item : items) {
1121 int res = BLI_strcasecmp_natural(item[0], item[1]);
1122 EXPECT_EQ(res, 0);
1123 }
1124 }
1126 {
1127 for (const auto &item : items) {
1128 int res = BLI_strcasecmp_natural(item[0], item[1]);
1129 EXPECT_LT(res, 0);
1130 }
1131 }
1133 {
1134 for (const auto &item : items) {
1135 int res = BLI_strcasecmp_natural(item[0], item[1]);
1136 EXPECT_GT(res, 0);
1137 }
1138 }
1139
1141 {
1142 CompareWordsArray ret_array;
1143
1144 /* E.g. {{"a", "b"}, {"ab", "cd"}} becomes {{"b", "a"}, {"cd", "ab"}} */
1145
1146 ret_array.reserve(items.size());
1147 for (const auto &item : items) {
1148 ret_array.push_back({item[1], item[0]});
1149 }
1150
1151 return ret_array;
1152 }
1153};
1154
1156
1157/* -------------------------------------------------------------------- */
1160
1162{
1163 const CompareWordsArray equal{
1164 {"", ""},
1165 };
1166 const CompareWordsArray negative{
1167 {"", "a"},
1168 {"", "A"},
1169 };
1170 CompareWordsArray positive = copyWithSwappedWords(negative);
1171
1172 testReturnsZeroForAll(equal);
1173 testReturnsLessThanZeroForAll(negative);
1174 testReturnsMoreThanZeroForAll(positive);
1175}
1176
1178{
1179 const CompareWordsArray equal{
1180 {" ", " "},
1181 {" a", " a"},
1182 {" a ", " a "},
1183 };
1184 const CompareWordsArray negative{
1185 {"", " "},
1186 {"", " a"},
1187 {"", " a "},
1188 {" ", " a"},
1189 };
1190 CompareWordsArray positive = copyWithSwappedWords(negative);
1191
1192 testReturnsZeroForAll(equal);
1193 testReturnsLessThanZeroForAll(negative);
1194 testReturnsMoreThanZeroForAll(positive);
1195}
1196
1197TEST_F(StringCasecmpNatural, TextOnlyLowerCase)
1198{
1199 const CompareWordsArray equal{
1200 {"a", "a"},
1201 {"aa", "aa"},
1202 {"ab", "ab"},
1203 {"ba", "ba"},
1204 {"je møder", "je møder"},
1205 };
1206 const CompareWordsArray negative{
1207 {"a", "b"},
1208 {"a", "aa"},
1209 {"a", "ab"},
1210 {"aa", "b"},
1211 {"je møda", "je møder"},
1212 };
1213 CompareWordsArray positive = copyWithSwappedWords(negative);
1214
1215 testReturnsZeroForAll(equal);
1216 testReturnsLessThanZeroForAll(negative);
1217 testReturnsMoreThanZeroForAll(positive);
1218}
1219
1221{
1222 const CompareWordsArray equal{
1223 {"A", "A"},
1224 {"AA", "AA"},
1225 {"AB", "AB"},
1226 {"Ab", "Ab"},
1227 {"aB", "aB"},
1228 };
1229 const CompareWordsArray negative{
1230 {"A", "a"},
1231 {"A", "B"},
1232 {"A", "b"},
1233 {"a", "B"},
1234 {"AA", "aA"},
1235 {"AA", "aA"},
1236 {"Ab", "ab"},
1237 {"AB", "Ab"},
1238 /* Different lengths */
1239 {"A", "ab"},
1240 {"Aa", "b"},
1241 {"aA", "b"},
1242 {"AA", "b"},
1243 {"A", "Ab"},
1244 {"A", "aB"},
1245 {"Aa", "B"},
1246 {"aA", "B"},
1247 {"AA", "B"},
1248 };
1249 CompareWordsArray positive = copyWithSwappedWords(negative);
1250
1251 testReturnsZeroForAll(equal);
1252 testReturnsLessThanZeroForAll(negative);
1253 testReturnsMoreThanZeroForAll(positive);
1254}
1255
1257{
1258 const CompareWordsArray equal{
1259 {".", "."},
1260 {". ", ". "},
1261 {" .", " ."},
1262 {" . ", " . "},
1263 };
1264 const CompareWordsArray negative{
1265 {".", ". "},
1266 {" .", " . "},
1267 {"foo.bar", "foo 1.bar"},
1268 };
1269 CompareWordsArray positive = copyWithSwappedWords(negative);
1270
1271 testReturnsZeroForAll(equal);
1272 testReturnsLessThanZeroForAll(negative);
1273 testReturnsMoreThanZeroForAll(positive);
1274}
1275
1277{
1278 const CompareWordsArray equal{
1279 {"0", "0"},
1280 {"0001", "0001"},
1281 {"42", "42"},
1282 {"0042", "0042"},
1283 };
1284 const CompareWordsArray negative{
1285 /* If numeric values are equal, number of leading zeros is used as tiebreaker. */
1286 {"1", "0001"},
1287 {"01", "001"},
1288 {"0042", "0043"},
1289 {"0042", "43"},
1290 };
1291 const CompareWordsArray positive = copyWithSwappedWords(negative);
1292
1293 testReturnsZeroForAll(equal);
1294 testReturnsLessThanZeroForAll(negative);
1295 testReturnsMoreThanZeroForAll(positive);
1296}
1297
1299{
1300 const CompareWordsArray equal{
1301 {"00je møder1", "00je møder1"},
1302 {".0 ", ".0 "},
1303 {" 1.", " 1."},
1304 {" .0 ", " .0 "},
1305 };
1306 const CompareWordsArray negative{
1307 {"00je møder0", "00je møder1"},
1308 {"05je møder0", "06je møder1"},
1309 {"Cube", "Cube.001"},
1310 {"Cube.001", "Cube.002"},
1311 {"CUbe.001", "Cube.002"},
1312 {"CUbe.002", "Cube.002"},
1313 };
1314 const CompareWordsArray positive = copyWithSwappedWords(negative);
1315
1316 testReturnsZeroForAll(equal);
1317 testReturnsLessThanZeroForAll(negative);
1318 testReturnsMoreThanZeroForAll(positive);
1319}
1320
1322
1323/* -------------------------------------------------------------------- */
1328
1329class StringEscape : public testing::Test {
1330 protected:
1331 StringEscape() = default;
1332
1334
1336 {
1337 size_t dst_test_len;
1338 char dst_test[64]; /* Must be big enough for all input. */
1339 for (const auto &item : items) {
1340 /* Validate the static size is big enough (test the test itself). */
1341 EXPECT_LT((strlen(item[0]) * 2) + 1, sizeof(dst_test));
1342 /* Escape the string. */
1343 dst_test_len = BLI_str_escape(dst_test, item[0], sizeof(dst_test));
1344 EXPECT_STREQ(dst_test, item[1]);
1345 EXPECT_EQ(dst_test_len, strlen(dst_test));
1346 /* Escape back. */
1347 dst_test_len = BLI_str_unescape(dst_test, item[1], strlen(item[1]));
1348 EXPECT_STREQ(dst_test, item[0]);
1349 EXPECT_EQ(dst_test_len, strlen(dst_test));
1350 }
1351 }
1352};
1353
1355{
1356 /* NOTE: clang-tidy `modernize-raw-string-literal` is disabled as it causes errors with MSVC.
1357 * TODO: investigate resolving with `/Zc:preprocessor` flag. */
1358
1359 const CompareWordsArray equal{
1360 {"", ""},
1361 {"/", "/"},
1362 {"'", "'"},
1363 {"?", "?"},
1364 };
1365
1366 const CompareWordsArray escaped{
1367 {"\\", "\\\\"},
1368 {"A\\", "A\\\\"},
1369 {"\\A", "\\\\A"},
1370 {"A\\B", "A\\\\B"},
1371 {"?", "?"},
1372 /* NOLINTNEXTLINE: modernize-raw-string-literal. */
1373 {"\"\\", "\\\"\\\\"},
1374 /* NOLINTNEXTLINE: modernize-raw-string-literal. */
1375 {"\\\"", "\\\\\\\""},
1376 /* NOLINTNEXTLINE: modernize-raw-string-literal. */
1377 {"\"\\\"", "\\\"\\\\\\\""},
1378
1379 /* NOLINTNEXTLINE: modernize-raw-string-literal. */
1380 {"\"\"\"", "\\\"\\\"\\\""},
1381 /* NOLINTNEXTLINE: modernize-raw-string-literal. */
1382 {"\\\\\\", "\\\\\\\\\\\\"},
1383 };
1384
1385 testEscapeWords(equal);
1386 testEscapeWords(escaped);
1387}
1388
1390{
1391 const CompareWordsArray escaped{
1392 {"\n", "\\n"},
1393 {"\r", "\\r"},
1394 {"\t", "\\t"},
1395 {"\a", "\\a"},
1396 {"\b", "\\b"},
1397 {"\f", "\\f"},
1398 {"A\n", "A\\n"},
1399 {"\nA", "\\nA"},
1400 /* NOLINTNEXTLINE: modernize-raw-string-literal. */
1401 {"\n\r\t\a\b\f", "\\n\\r\\t\\a\\b\\f"},
1402 /* NOLINTNEXTLINE: modernize-raw-string-literal. */
1403 {"\n_\r_\t_\a_\b_\f", "\\n_\\r_\\t_\\a_\\b_\\f"},
1404 /* NOLINTNEXTLINE: modernize-raw-string-literal. */
1405 {"\n\\\r\\\t\\\a\\\b\\\f", "\\n\\\\\\r\\\\\\t\\\\\\a\\\\\\b\\\\\\f"},
1406 };
1407
1408 testEscapeWords(escaped);
1409}
1410
1412
1413TEST(BLI_string, bounded_strcpy)
1414{
1415 {
1416 char str[8];
1417 STRNCPY(str, "Hello");
1418 EXPECT_STREQ(str, "Hello");
1419 }
1420
1421 {
1422 char str[8];
1423 STRNCPY(str, "Hello, World!");
1424 EXPECT_STREQ(str, "Hello, ");
1425 }
1426}
1427
1428TEST(BLI_string, StartsWith)
1429{
1430 EXPECT_TRUE(BLI_str_startswith("ab", "a"));
1431 EXPECT_FALSE(BLI_str_startswith("ab", "b"));
1432 EXPECT_TRUE(BLI_str_startswith("ab", "ab"));
1433 EXPECT_TRUE(BLI_str_startswith("ab", ""));
1434 EXPECT_TRUE(BLI_str_startswith("", ""));
1435}
1436
1437TEST(BLI_string, EndsWith)
1438{
1439 EXPECT_TRUE(BLI_str_endswith("ab", "b"));
1440 EXPECT_FALSE(BLI_str_endswith("ab", "a"));
1441 EXPECT_TRUE(BLI_str_endswith("ab", "ab"));
1442 EXPECT_TRUE(BLI_str_endswith("ab", ""));
1443 EXPECT_TRUE(BLI_str_endswith("", ""));
1444}
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
int bool BLI_str_startswith(const char *__restrict str, const char *__restrict start) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
size_t BLI_str_format_int_grouped(char dst[BLI_STR_FORMAT_INT32_GROUPED_SIZE], int num) ATTR_NONNULL(1)
Definition string.cc:1171
int bool bool bool size_t BLI_str_partition(const char *str, const char delim[], const char **sep, const char **suf) ATTR_NONNULL(1
int bool bool bool size_t size_t size_t int BLI_string_max_possible_word_count(int str_len) ATTR_WARN_UNUSED_RESULT
Definition string.cc:573
size_t size_t size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, size_t src_maxncpy) ATTR_NONNULL(1
#define BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE
Definition BLI_string.h:31
int char char int int int int size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition string.cc:913
#define BLI_STR_FORMAT_INT32_DECIMAL_UNIT_SIZE
Definition BLI_string.h:37
#define BLI_STR_FORMAT_INT32_GROUPED_SIZE
Definition BLI_string.h:28
void BLI_str_format_byte_unit(char dst[BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE], long long int bytes, bool base_10) ATTR_NONNULL(1)
Definition string.cc:1207
int bool bool bool size_t size_t BLI_str_rpartition(const char *str, const char delim[], const char **sep, const char **suf) ATTR_NONNULL(1
#define BLI_STR_FORMAT_INT32_INTEGER_UNIT_SIZE
Definition BLI_string.h:40
#define BLI_STR_FORMAT_UINT64_GROUPED_SIZE
Definition BLI_string.h:22
void BLI_str_format_integer_unit(char dst[BLI_STR_FORMAT_INT32_INTEGER_UNIT_SIZE], int number_to_format) ATTR_NONNULL(1)
Definition string.cc:1294
int char char * BLI_strncasestr(const char *s, const char *find, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
int bool bool bool size_t size_t size_t BLI_str_partition_ex(const char *str, const char *end, const char delim[], const char **sep, const char **suf, bool from_right) ATTR_NONNULL(1
void BLI_str_format_decimal_unit(char dst[BLI_STR_FORMAT_INT32_DECIMAL_UNIT_SIZE], int number_to_format) ATTR_NONNULL(1)
Definition string.cc:1270
int char char int int int BLI_strcasecmp_natural(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
size_t BLI_str_format_uint64_grouped(char dst[BLI_STR_FORMAT_UINT64_GROUPED_SIZE], uint64_t num) ATTR_NONNULL(1)
Definition string.cc:1183
bool bool int bool BLI_string_elem_split_by_delim(const char *haystack, const char delim, const char *needle) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
int bool bool BLI_str_endswith(const char *__restrict str, const char *__restrict end) ATTR_NONNULL(1
bool bool int BLI_string_find_split_words(const char *str, size_t str_maxlen, char delim, int r_words[][2], int words_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
static void string_join_array_with_sep_char_test_truncate(const char *strings[], int strings_num, char buffer[BUFFER_SIZE])
#define STR_N_CAT(dst_init, dst_size, src, result_expect)
#define BUFFER_SIZE
TEST_F(StringFindSplitWords, Simple)
static std::ostream & operator<<(std::ostream &os, const WordInfo &word_info)
TEST(string, StrCat)
static void string_join_array_test_truncate(const char *strings[], int strings_num, char buffer[BUFFER_SIZE])
#define STR_REPLACE_RANGE(src, size, beg, end, dst, result_expect)
size_t size_t BLI_str_rpartition_utf8(const char *str, const unsigned int delim[], const char **r_sep, const char **r_suf) ATTR_NONNULL(1
size_t BLI_str_partition_utf8(const char *str, const unsigned int delim[], const char **r_sep, const char **r_suf) ATTR_NONNULL(1
size_t size_t size_t BLI_str_partition_ex_utf8(const char *str, const char *end, const unsigned int delim[], const char **r_sep, const char **r_suf, bool from_right) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
size_t BLI_string_join_array_by_sep_char(char *result, size_t result_maxncpy, char sep, const char *strings[], uint strings_num) ATTR_NONNULL()
bool BLI_string_is_decimal(const char *string) ATTR_NONNULL(1)
char * BLI_string_join_arrayN(const char *strings[], uint strings_num) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
char * BLI_string_join_array_by_sep_charN(char sep, const char *strings[], uint strings_num) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
size_t BLI_string_join_array(char *result, size_t result_maxncpy, const char *strings[], uint strings_num) ATTR_NONNULL()
unsigned int uint
#define ARRAY_SIZE(arr)
Read Guarded memory(de)allocation.
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void testReturnsMoreThanZeroForAll(const CompareWordsArray &items)
void testReturnsZeroForAll(const CompareWordsArray &items)
void testReturnsLessThanZeroForAll(const CompareWordsArray &items)
vector< std::array< const char *, 2 > > CompareWordsArray
StringCasecmpNatural()=default
CompareWordsArray copyWithSwappedWords(const CompareWordsArray &items)
vector< std::array< const char *, 2 > > CompareWordsArray
StringEscape()=default
void testEscapeWords(const CompareWordsArray &items)
void testStringFindSplitWords(const string &str, initializer_list< WordInfo > expected_words_info_init)
StringFindSplitWords()=default
void testStringFindSplitWords(const string &str, const size_t max_length, initializer_list< WordInfo > expected_words_info_init, int max_words=-1)
#define str(s)
#define INT32_MAX
VecBase< bool, D > equal(VecOp< T, D >, VecOp< T, D >) RET
#define CHECK_LE(a, b)
Definition log.h:123
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
WordInfo()=default
bool operator==(const WordInfo &other) const
WordInfo(int start, int end)