5#include "testing/testing.h"
14#define DO_PERF_TESTS 0
24 if (
str[0] ==
'/' &&
str[1] ==
'/') {
39 char *str_dupe = strdup(
str);
50#define NORMALIZE(input, output_expect) \
52 char path[FILE_MAX] = input; \
54 str_replace_char_with_relative_exception(path, '/', '\\'); \
56 const int path_len_test = BLI_path_normalize(path); \
58 BLI_string_replace_char(path, '\\', '/'); \
60 EXPECT_STREQ(path, output_expect); \
61 EXPECT_EQ(path_len_test, strlen(path)); \
66TEST(path_utils, Normalize_Nop)
75TEST(path_utils, Normalize_NopRelative)
85TEST(path_utils, Normalize_Dot)
93TEST(path_utils, Normalize_ComplexAbsolute)
95 NORMALIZE(
"/a/./b/./c/./.././.././",
"/a/");
96 NORMALIZE(
"/a//.//b//.//c//.//..//.//..//.//",
"/a/");
98TEST(path_utils, Normalize_ComplexRelative)
100 NORMALIZE(
"a/b/c/d/e/f/g/../a/../b/../../c/../../../d/../../../..",
".");
101 NORMALIZE(
"a/b/c/d/e/f/g/../a/../../../../b/../../../c/../../d/..",
".");
104TEST(path_utils, Normalize_DoubleSlash)
112TEST(path_utils, Normalize_Parent)
115 NORMALIZE(
"/a/../a/b/../b/c/../c/",
"/a/b/c/");
118TEST(path_utils, Normalize_UnbalancedAbsolute)
122 NORMALIZE(
"/a/b/c/../../../../../d",
"/d");
127 NORMALIZE(
"/home/username/Downloads/../../../../../Users/Example/Desktop/test.jpg",
128 "/Users/Example/Desktop/test.jpg");
132TEST(path_utils, Normalize_UnbalancedRelative)
142 NORMALIZE(
"//./a/../../../",
"//../../");
144 NORMALIZE(
"../a/../../../",
"../../../");
145 NORMALIZE(
"a/b/../c/../../d/../../../e/../../../../f",
"../../../../../f");
146 NORMALIZE(
".../.../a/.../b/../c/../../d/../../../e/../../../.../../f",
"../f");
149TEST(path_utils, Normalize_UnbalancedRelativeTrailing)
174TEST(path_utils, CompareNormalized)
192#define PARENT_DIR(input, output_expect) \
194 char path[FILE_MAX] = input; \
196 BLI_string_replace_char(path, '/', '\\'); \
198 BLI_path_parent_dir(path); \
200 BLI_string_replace_char(path, '\\', '/'); \
202 EXPECT_STREQ(path, output_expect); \
206TEST(path_utils, ParentDir_Simple)
223TEST(path_utils, ParentDir_TrailingPeriod)
236TEST(path_utils, ParentDir_Complex)
252#define AT_INDEX(str_input, index_input, str_expect) \
254 char path[] = str_input; \
257 BLI_string_replace_char(path, '/', '\\'); \
259 const char *expect = str_expect; \
260 int index_output, len_output; \
261 const bool ret = BLI_path_name_at_index(path, index_input, &index_output, &len_output); \
262 if (expect == nullptr) { \
267 EXPECT_EQ(len_output, strlen(expect)); \
268 path[index_output + len_output] = '\0'; \
269 EXPECT_STREQ(&path[index_output], expect); \
274TEST(path_utils, NameAtIndex_Single)
287TEST(path_utils, NameAtIndex_SingleNeg)
301TEST(path_utils, NameAtIndex_Double)
315TEST(path_utils, NameAtIndex_DoublNeg)
329TEST(path_utils, NameAtIndex_Misc)
331 AT_INDEX(
"/how/now/brown/cow", 0,
"how");
332 AT_INDEX(
"/how/now/brown/cow", 1,
"now");
333 AT_INDEX(
"/how/now/brown/cow", 2,
"brown");
334 AT_INDEX(
"/how/now/brown/cow", 3,
"cow");
335 AT_INDEX(
"/how/now/brown/cow", 4,
nullptr);
336 AT_INDEX(
"/how/now/brown/cow/", 4,
nullptr);
339TEST(path_utils, NameAtIndex_MiscNeg)
341 AT_INDEX(
"/how/now/brown/cow", 0,
"how");
342 AT_INDEX(
"/how/now/brown/cow", 1,
"now");
343 AT_INDEX(
"/how/now/brown/cow", 2,
"brown");
344 AT_INDEX(
"/how/now/brown/cow", 3,
"cow");
345 AT_INDEX(
"/how/now/brown/cow", 4,
nullptr);
346 AT_INDEX(
"/how/now/brown/cow/", 4,
nullptr);
349#define TEST_STR "./a/./b/./c/."
351TEST(path_utils, NameAtIndex_SingleDot)
360TEST(path_utils, NameAtIndex_SingleDotNeg)
371#define TEST_STR ".//a//.//b//.//c//.//"
373TEST(path_utils, NameAtIndex_SingleDotDoubleSlash)
382TEST(path_utils, NameAtIndex_SingleDotDoubleSlashNeg)
393TEST(path_utils, NameAtIndex_SingleDotSeries)
395 AT_INDEX(
"abc/././/././xyz", 0,
"abc");
396 AT_INDEX(
"abc/././/././xyz", 1,
"xyz");
397 AT_INDEX(
"abc/././/././xyz", 2,
nullptr);
400TEST(path_utils, NameAtIndex_SingleDotSeriesNeg)
402 AT_INDEX(
"abc/././/././xyz", -3,
nullptr);
403 AT_INDEX(
"abc/././/././xyz", -2,
"abc");
404 AT_INDEX(
"abc/././/././xyz", -1,
"xyz");
407TEST(path_utils, NameAtIndex_MiscComplex)
409 AT_INDEX(
"how//now/brown/cow", 0,
"how");
410 AT_INDEX(
"//how///now//brown/cow", 1,
"now");
411 AT_INDEX(
"/how/now///brown//cow", 2,
"brown");
412 AT_INDEX(
"/how/now/brown/cow///", 3,
"cow");
413 AT_INDEX(
"/how/now/brown//cow", 4,
nullptr);
414 AT_INDEX(
"how/now/brown//cow/", 4,
nullptr);
417TEST(path_utils, NameAtIndex_MiscComplexNeg)
419 AT_INDEX(
"how//now/brown/cow", -4,
"how");
420 AT_INDEX(
"//how///now//brown/cow", -3,
"now");
421 AT_INDEX(
"/how/now///brown//cow", -2,
"brown");
422 AT_INDEX(
"/how/now/brown/cow///", -1,
"cow");
423 AT_INDEX(
"/how/now/brown//cow", -5,
nullptr);
424 AT_INDEX(
"how/now/brown//cow/", -5,
nullptr);
427TEST(path_utils, NameAtIndex_NoneComplex)
435TEST(path_utils, NameAtIndex_NoneComplexNeg)
496TEST(path_utils, IsWin32DriveOnly)
522TEST(path_utils, IsWin32DriveWithSlash)
547#define JOIN_FORWARD_SLASH(str_expect, out_size, ...) \
549 const char *expect = str_expect; \
550 char result[(out_size) + 1024]; \
552 result[out_size] = '\0'; \
553 BLI_path_join(result, out_size, __VA_ARGS__); \
554 EXPECT_STREQ(result, expect); \
555 EXPECT_EQ(result[out_size], '\0'); \
562#define JOIN_BACK_SLASH(str_expect, out_size, ...) \
564 const char *expect = str_expect; \
565 char result[(out_size) + 1024]; \
566 const char *input_forward_slash[] = {__VA_ARGS__}; \
567 char *input_back_slash[ARRAY_SIZE(input_forward_slash)] = {nullptr}; \
568 for (int i = 0; i < ARRAY_SIZE(input_forward_slash); i++) { \
569 input_back_slash[i] = strdup(input_forward_slash[i]); \
570 BLI_string_replace_char(input_back_slash[i], '/', '\\'); \
573 result[out_size] = '\0'; \
574 BLI_path_join_array(result, \
576 const_cast<const char **>(input_back_slash), \
577 ARRAY_SIZE(input_back_slash)); \
578 BLI_string_replace_char(result, '\\', '/'); \
579 EXPECT_STREQ(result, expect); \
580 EXPECT_EQ(result[out_size], '\0'); \
581 for (int i = 0; i < ARRAY_SIZE(input_forward_slash); i++) { \
582 free(input_back_slash[i]); \
588# define JOIN JOIN_BACK_SLASH
590# define JOIN JOIN_FORWARD_SLASH
596 JOIN(
"", 100,
"",
"");
597 JOIN(
"", 100,
"",
"",
"");
598 JOIN(
"/", 100,
"/",
"",
"");
599 JOIN(
"/", 100,
"/",
"/");
600 JOIN(
"/", 100,
"/",
"",
"/");
601 JOIN(
"/", 100,
"/",
"",
"/",
"");
606 JOIN(
"test", 100,
"test");
609 JOIN(
"/a", 100,
"/a");
610 JOIN(
"a/", 100,
"a/");
611 JOIN(
"/a/", 100,
"/a/");
612 JOIN(
"/a/", 100,
"/a//");
613 JOIN(
"//a/", 100,
"//a//");
618 JOIN(
"/a/b/c", 100,
"/a",
"b",
"c");
619 JOIN(
"/a/b/c", 100,
"/a/",
"/b/",
"/c");
620 JOIN(
"/a/b/c", 100,
"/a/b/",
"/c");
621 JOIN(
"/a/b/c", 100,
"/a/b/c");
622 JOIN(
"/a/b/c", 100,
"/",
"a/b/c");
624 JOIN(
"/a/b/c/", 100,
"/a/",
"/b/",
"/c/");
625 JOIN(
"/a/b/c/", 100,
"/a/b/c/");
626 JOIN(
"/a/b/c/", 100,
"/a/b/",
"/c/");
627 JOIN(
"/a/b/c/", 100,
"/a/b/c",
"/");
628 JOIN(
"/a/b/c/", 100,
"/",
"a/b/c",
"/");
631TEST(path_utils, JoinTruncateShort)
635 JOIN(
"a", 2,
"",
"aa");
636 JOIN(
"a", 2,
"",
"a/");
637 JOIN(
"a/b", 4,
"a",
"bc");
638 JOIN(
"ab/", 4,
"ab",
"c");
639 JOIN(
"/a/", 4,
"/a",
"b");
640 JOIN(
"/a/", 4,
"/a/",
"b/");
641 JOIN(
"/a/", 4,
"/a",
"/b/");
642 JOIN(
"/a/", 4,
"/",
"a/b/");
643 JOIN(
"//a", 4,
"//",
"a/b/");
645 JOIN(
"/a/b", 5,
"/a",
"b",
"c");
648TEST(path_utils, JoinTruncateLong)
650 JOIN(
"", 1,
"//",
"//longer",
"path");
651 JOIN(
"/", 2,
"//",
"//longer",
"path");
652 JOIN(
"//", 3,
"//",
"//longer",
"path");
653 JOIN(
"//l", 4,
"//",
"//longer",
"path");
655 JOIN(
"//longe", 8,
"//",
"//longer",
"path");
656 JOIN(
"//longer", 9,
"//",
"//longer",
"path");
657 JOIN(
"//longer/", 10,
"//",
"//longer",
"path");
658 JOIN(
"//longer/p", 11,
"//",
"//longer",
"path");
659 JOIN(
"//longer/pa", 12,
"//",
"//longer",
"path");
660 JOIN(
"//longer/pat", 13,
"//",
"//longer",
"path");
661 JOIN(
"//longer/path", 14,
"//",
"//longer",
"path");
662 JOIN(
"//longer/path", 14,
"//",
"//longer",
"path/");
663 JOIN(
"//longer/path/", 15,
"//",
"//longer",
"path/");
664 JOIN(
"//longer/path/", 15,
"//",
"//longer",
"path/",
"trunc");
665 JOIN(
"//longer/path/t", 16,
"//",
"//longer",
"path/",
"trunc");
670 JOIN(
"/a/b/c/d/e/f/g/", 100,
"/",
"a/b",
"//////c/d",
"",
"e",
"f",
"g//");
671 JOIN(
"/aa/bb/cc/dd/ee/ff/gg/", 100,
"/",
"aa/bb",
"//////cc/dd",
"",
"ee",
"ff",
"gg//");
672 JOIN(
"1/2/3/", 100,
"1",
"////////",
"",
"2",
"3///");
675TEST(path_utils, JoinRelativePrefix)
677 JOIN(
"//a/b/c", 100,
"//a",
"b",
"c");
678 JOIN(
"//a/b/c", 100,
"//",
"//a//",
"//b//",
"//c");
679 JOIN(
"//a/b/c", 100,
"//",
"//",
"a",
"//",
"b",
"//",
"c");
683#undef JOIN_BACK_SLASH
684#undef JOIN_FORWARD_SLASH
693#define APPEND(str_expect, size, path, filename) \
695 const char *expect = str_expect; \
696 char result[(size) + 1024] = path; \
697 char filename_native[] = filename; \
700 BLI_string_replace_char(filename_native, '/', '\\'); \
701 BLI_string_replace_char(result, '/', '\\'); \
703 BLI_path_append(result, size, filename_native); \
705 BLI_string_replace_char(result, '\\', '/'); \
707 EXPECT_STREQ(result, expect); \
713 APPEND(
"a/b", 100,
"a",
"b");
714 APPEND(
"a/b", 100,
"a/",
"b");
717TEST(path_utils, AppendFile_Truncate)
719 APPEND(
"/A", 3,
"/",
"ABC");
720 APPEND(
"/", 2,
"/",
"test");
721 APPEND(
"X", 2,
"X",
"ABC");
722 APPEND(
"X/", 3,
"X/",
"ABC");
741 EXPECT_STREQ(path,
"123");
748 EXPECT_STREQ(path,
"000000000123");
755 EXPECT_STREQ(path,
"test_123");
762 EXPECT_STREQ(path,
"test_000000000001");
766 char path[
FILE_MAX] =
"test_############";
769 EXPECT_STREQ(path,
"test_000000000001");
773 char path[
FILE_MAX] =
"test_#_#_middle";
776 EXPECT_STREQ(path,
"test_#_123_middle");
784 EXPECT_STREQ(path,
"");
788 char path[
FILE_MAX] =
"test_middle";
791 EXPECT_STREQ(path,
"test_middle");
799 EXPECT_STREQ(path,
"test_-0001");
805 EXPECT_STREQ(path,
"test_-0100");
811 memset(path,
'#',
sizeof(path));
812 path[
sizeof(path) - 1] =
'\0';
827 const char *path =
"";
830 EXPECT_STREQ(dir,
"");
831 EXPECT_STREQ(file,
"");
835 const char *path =
"/";
838 EXPECT_STREQ(dir,
"/");
839 EXPECT_STREQ(file,
"");
843 const char *path =
"fileonly";
846 EXPECT_STREQ(dir,
"");
847 EXPECT_STREQ(file,
"fileonly");
851 const char *path =
"dironly/";
854 EXPECT_STREQ(dir,
"dironly/");
855 EXPECT_STREQ(file,
"");
859 const char *path =
"/a/b";
862 EXPECT_STREQ(dir,
"/a/");
863 EXPECT_STREQ(file,
"b");
867 const char *path =
"/dirtoobig/filetoobig";
868 char dir[5], file[5];
870 EXPECT_STREQ(dir,
"/dir");
871 EXPECT_STREQ(file,
"file");
874 EXPECT_STREQ(dir,
"");
875 EXPECT_STREQ(file,
"");
885#define PATH_FRAME_STRIP(input_path, expect_path, expect_ext) \
887 char path[FILE_MAX]; \
888 char ext[FILE_MAX]; \
889 STRNCPY(path, (input_path)); \
890 BLI_path_frame_strip(path, ext, sizeof(ext)); \
891 EXPECT_STREQ(path, expect_path); \
892 EXPECT_STREQ(ext, expect_ext); \
901 PATH_FRAME_STRIP(
"/abspath/to/somefile.001.abc",
"/abspath/to/somefile.###",
".abc");
902 PATH_FRAME_STRIP(
"/ext/longer/somefile.001.alembic",
"/ext/longer/somefile.###",
".alembic");
903 PATH_FRAME_STRIP(
"/ext/shorter/somefile.123001.abc",
"/ext/shorter/somefile.######",
".abc");
905#undef PATH_FRAME_STRIP
944#define PATH_EXTENSION_CHECK(input_path, input_ext, expect_ext) \
946 const bool ret = BLI_path_extension_check(input_path, input_ext); \
947 if (STREQ(input_ext, expect_ext)) { \
956TEST(path_utils, ExtensionCheck)
964 ".veryveryverylonglonglongextension",
965 ".veryveryverylonglonglongextension");
979#undef PATH_EXTENSION_CHECK
987#define PATH_EXTENSION_REPLACE_WITH_MAXLEN( \
988 input_path, input_ext, expect_result, expect_path, maxlen) \
990 BLI_assert(maxlen <= FILE_MAX); \
991 char path[FILE_MAX]; \
992 STRNCPY(path, input_path); \
993 const bool ret = BLI_path_extension_replace(path, maxlen, input_ext); \
994 if (expect_result) { \
1000 EXPECT_STREQ(path, expect_path); \
1004#define PATH_EXTENSION_REPLACE(input_path, input_ext, expect_result, expect_path) \
1005 PATH_EXTENSION_REPLACE_WITH_MAXLEN(input_path, input_ext, expect_result, expect_path, FILE_MAX)
1036TEST(path_utils, ExtensionReplace_Overflow)
1049#undef PATH_EXTENSION_REPLACE
1050#undef PATH_EXTENSION_REPLACE_WITH_MAXLEN
1058#define PATH_EXTENSION_ENSURE_WITH_MAXLEN( \
1059 input_path, input_ext, expect_result, expect_path, maxlen) \
1061 BLI_assert(maxlen <= FILE_MAX); \
1062 char path[FILE_MAX]; \
1063 STRNCPY(path, input_path); \
1064 const bool ret = BLI_path_extension_ensure(path, maxlen, input_ext); \
1065 if (expect_result) { \
1069 EXPECT_FALSE(ret); \
1071 EXPECT_STREQ(path, expect_path); \
1075#define PATH_EXTENSION_ENSURE(input_path, input_ext, expect_result, expect_path) \
1076 PATH_EXTENSION_ENSURE_WITH_MAXLEN(input_path, input_ext, expect_result, expect_path, FILE_MAX)
1104TEST(path_utils, ExtensionEnsure_Overflow)
1114#undef PATH_EXTENSION_ENSURE
1115#undef PATH_EXTENSION_ENSURE_WITH_MAXLEN
1123#define PATH_FRAME_CHECK_CHARS(input_path, expect_hasChars) \
1125 const bool ret = BLI_path_frame_check_chars(input_path); \
1126 if (expect_hasChars) { \
1130 EXPECT_FALSE(ret); \
1152#undef PATH_FRAME_CHECK_CHARS
1160#define PATH_FRAME_RANGE(input_path, sta, end, digits, expect_outpath) \
1162 char path[FILE_MAX]; \
1164 STRNCPY(path, input_path); \
1165 ret = BLI_path_frame_range(path, sizeof(path), sta, end, digits); \
1166 if (expect_outpath == nullptr) { \
1167 EXPECT_FALSE(ret); \
1171 EXPECT_STREQ(path, expect_outpath); \
1187 PATH_FRAME_RANGE(
"", 1, 0, 20,
"00000000000000000001-00000000000000000000");
1189#undef PATH_FRAME_RANGE
1197#define PATH_FRAME_GET(input_path, expect_frame, expect_numdigits, expect_pathisvalid) \
1199 char path[FILE_MAX]; \
1200 int out_frame = -1, out_numdigits = -1; \
1201 STRNCPY(path, input_path); \
1202 const bool ret = BLI_path_frame_get(path, &out_frame, &out_numdigits); \
1203 if (expect_pathisvalid) { \
1207 EXPECT_FALSE(ret); \
1209 EXPECT_EQ(out_frame, expect_frame); \
1210 EXPECT_EQ(out_numdigits, expect_numdigits); \
1218 PATH_FRAME_GET(
"path/to/frame_2810.dummy_quite_long_extension", 2810, 4,
true);
1223#undef PATH_FRAME_GET
1231#define PATH_SEQ_DECODE(path_literal, expect_result, expect_head, expect_tail, expect_numdigits) \
1233 const char *path = path_literal; \
1234 char head[FILE_MAX]; \
1235 char tail[FILE_MAX]; \
1236 ushort numdigits = 0; \
1237 const int result = BLI_path_sequence_decode( \
1238 path, head, sizeof(head), tail, sizeof(tail), &numdigits); \
1239 EXPECT_EQ(result, expect_result); \
1240 EXPECT_STREQ(head, expect_head); \
1241 EXPECT_STREQ(tail, expect_tail); \
1242 EXPECT_EQ(numdigits, expect_numdigits); \
1260#undef PATH_SEQ_DECODE
1268#define PATH_SUFFIX(path_literal, path_literal_max, sep, suffix, expect_result, expect_path) \
1270 char path[FILE_MAX] = path_literal; \
1271 const bool result = BLI_path_suffix(path, path_literal_max, suffix, sep); \
1272 EXPECT_EQ(result, expect_result); \
1273 EXPECT_STREQ(path, expect_path); \
1288 PATH_SUFFIX(
"file.txt", 10,
"A",
"B",
false,
"file.txt");
1290 PATH_SUFFIX(
"file.txt", 11,
"A",
"B",
true,
"fileAB.txt");
1310#define PATH_SLASH_FIND(path, expect_index) \
1312 const char *result = BLI_path_slash_find(path); \
1313 EXPECT_EQ(result, &path[expect_index]); \
1333#undef PATH_SLASH_FIND
1341#define PATH_SLASH_RFIND(path, expect_index) \
1343 const char *result = BLI_path_slash_rfind(path); \
1344 EXPECT_STREQ(result, &path[expect_index]); \
1366#undef PATH_SLASH_RFIND
1374#define PATH_SLASH_ENSURE(input, size, output_expect, length_expect) \
1376 char path[size] = input; \
1377 if (SEP == '\\') { \
1378 BLI_string_replace_char(path, '/', '\\'); \
1380 int result = BLI_path_slash_ensure(path, size); \
1381 if (SEP == '\\') { \
1382 BLI_string_replace_char(path, '\\', '/'); \
1384 EXPECT_STREQ(path, output_expect); \
1385 EXPECT_EQ(result, length_expect); \
1404#undef PATH_SLASH_ENSURE
1412#define PATH_SLASH_RSTRIP(input, expected) \
1414 char path[FILE_MAX] = input; \
1415 if (SEP == '\\') { \
1416 BLI_string_replace_char(path, '/', '\\'); \
1418 BLI_path_slash_rstrip(path); \
1419 if (SEP == '\\') { \
1420 BLI_string_replace_char(path, '\\', '/'); \
1422 EXPECT_STREQ(path, expected); \
1440#undef PATH_SLASH_RSTRIP
1448#define PATH_SLASH_SKIP(input, expected) \
1450 char path[FILE_MAX] = input; \
1451 if (SEP == '\\') { \
1452 BLI_string_replace_char(path, '/', '\\'); \
1454 const char *skipped = BLI_path_slash_skip(path); \
1455 if (SEP == '\\') { \
1456 BLI_string_replace_char(path, '\\', '/'); \
1458 EXPECT_STREQ(skipped, expected); \
1475#undef PATH_SLASH_SKIP
1483#define PATH_SLASH_NATIVE(input, expected) \
1485 char path[FILE_MAX] = input; \
1486 BLI_path_slash_native(path); \
1487 EXPECT_STREQ(path, expected); \
1542#undef PATH_SLASH_NATIVE
1550#define PATH_REL(abs_path, ref_path, rel_path_expect) \
1552 char path[FILE_MAX]; \
1553 const char *ref_path_test = ref_path; \
1554 STRNCPY(path, abs_path); \
1555 if (SEP == '\\') { \
1556 BLI_string_replace_char(path, '/', '\\'); \
1557 ref_path_test = str_replace_char_strdup(ref_path_test, '/', '\\'); \
1559 BLI_path_rel(path, ref_path_test); \
1560 if (SEP == '\\') { \
1561 BLI_string_replace_char(path, '\\', '/'); \
1562 free((void *)ref_path_test); \
1564 EXPECT_STREQ(path, rel_path_expect); \
1569# define ABS_PREFIX "C:"
1571# define ABS_PREFIX ""
1579TEST(path_utils, RelPath_SimpleSubdir)
1584TEST(path_utils, RelPath_BufferOverflowRoot)
1589 abs_path_in[i] =
'A';
1594 abs_path_out[i] =
'A';
1596 abs_path_out[
FILE_MAX - std::max((strlen(abs_prefix) - 1),
size_t(1))] =
'\0';
1597 PATH_REL(abs_path_in, abs_prefix, abs_path_out);
1600TEST(path_utils, RelPath_BufferOverflowSubdir)
1603 const char *ref_path_in =
ABS_PREFIX "/foo/bar/";
1604 const size_t ref_path_in_len = strlen(ref_path_in);
1606 abs_path_in[i] =
'A';
1611 abs_path_out[i] =
'A';
1613 abs_path_out[
FILE_MAX - std::max((ref_path_in_len - 1),
size_t(1))] =
'\0';
1614 PATH_REL(abs_path_in, ref_path_in, abs_path_out);
1685 EXPECT_TRUE(
BLI_path_contains(
"/some/path",
"/some/path")) <<
"A path contains itself";
1687 <<
"A path contains its subdirectory";
1689 <<
"Paths should be normalized";
1691 <<
"Windows paths should be supported as well";
1694 <<
"Windows paths should be supported as well";
1696 <<
"Root directory not be contained in a subdirectory";
1698 <<
"Paths should be normalized";
1700 <<
"Just sharing a suffix is not enough, path semantics should be followed";
1702 <<
"Relative paths are not supported";
1706TEST(path_utils, Contains_Windows_case_insensitive)
1709 <<
"On Windows path comparison should ignore case";
1719TEST(path_utils, HasHiddenComponents)
1783TEST(path_utils, HasHiddenComponents_Performance)
1786 const char *test_paths[] = {
1788 "test/a_fairly_long/path/here/shall_we/ok.txt",
1789 "test/a_fairly_long/path/here/.with_a_hidden_component/shall_we/ok.txt",
1790 "test/.another_path_with_hidden_component/yes.txt",
1791 "test/another/path/with/.hidden_filename",
1793 const int RUN_COUNT = 10'000'000;
1795 for (
int i = 0; i < RUN_COUNT; i++) {
1796 for (
int j = 0; j <
ARRAY_SIZE(test_paths); j++) {
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
File and directory operations.
bool BLI_path_has_hidden_component(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
bool BLI_path_contains(const char *container_path, const char *containee_path) ATTR_NONNULL(1
bool BLI_path_is_win32_drive(const char *path)
bool BLI_path_is_abs_from_cwd(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
void BLI_path_split_dir_file(const char *filepath, char *dir, size_t dir_maxncpy, char *file, size_t file_maxncpy) ATTR_NONNULL(1
bool BLI_path_is_rel(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
const char * BLI_path_slash_find(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
int BLI_path_cmp_normalized(const char *p1, const char *p2) ATTR_NONNULL(1
bool BLI_path_is_win32_drive_only(const char *path)
bool BLI_path_is_win32_drive_with_slash(const char *path)
const char * BLI_path_slash_rfind(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
const char * BLI_path_extension(const char *filepath) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
bool BLI_path_frame(char *path, size_t path_maxncpy, int frame, int digits) ATTR_NONNULL(1)
bool BLI_path_is_unc(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
#define PATH_EXTENSION_REPLACE(input_path, input_ext, expect_result, expect_path)
#define PATH_SLASH_NATIVE(input, expected)
#define PATH_FRAME_RANGE(input_path, sta, end, digits, expect_outpath)
#define PATH_SLASH_RSTRIP(input, expected)
#define PATH_SLASH_ENSURE(input, size, output_expect, length_expect)
#define PATH_EXTENSION_CHECK(input_path, input_ext, expect_ext)
#define PATH_SLASH_FIND(path, expect_index)
#define PATH_FRAME_STRIP(input_path, expect_path, expect_ext)
#define APPEND(str_expect, size, path, filename)
#define PATH_SLASH_RFIND(path, expect_index)
#define PATH_SEQ_DECODE(path_literal, expect_result, expect_head, expect_tail, expect_numdigits)
#define AT_INDEX(str_input, index_input, str_expect)
#define PATH_EXTENSION_REPLACE_WITH_MAXLEN(input_path, input_ext, expect_result, expect_path, maxlen)
static void str_replace_char_with_relative_exception(char *str, char src, char dst)
#define PATH_SLASH_SKIP(input, expected)
#define NORMALIZE(input, output_expect)
TEST(path_utils, Normalize_Nop)
#define PATH_EXTENSION_ENSURE_WITH_MAXLEN(input_path, input_ext, expect_result, expect_path, maxlen)
#define PATH_FRAME_GET(input_path, expect_frame, expect_numdigits, expect_pathisvalid)
#define PATH_FRAME_CHECK_CHARS(input_path, expect_hasChars)
#define PARENT_DIR(input, output_expect)
static char * str_replace_char_strdup(const char *str, char src, char dst)
#define PATH_SUFFIX(path_literal, path_literal_max, sep, suffix, expect_result, expect_path)
#define PATH_REL(abs_path, ref_path, rel_path_expect)
#define PATH_EXTENSION_ENSURE(input_path, input_ext, expect_result, expect_path)
#define STRNCPY_RLEN(dst, src)
int bool bool BLI_str_endswith(const char *__restrict str, const char *__restrict end) ATTR_NONNULL(1
void BLI_string_replace_char(char *str, char src, char dst) ATTR_NONNULL(1)
#define SCOPED_TIMER(name)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int