Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@blender.org>2021-09-27 16:22:53 +0300
committerSybren A. Stüvel <sybren@blender.org>2021-09-27 19:10:47 +0300
commitaafbe111fc90876d801135f0dc5e01e9742f647a (patch)
treeecaa944881ec81c7dc0b4a134270b283238676a9 /source/blender
parent6578db57cd878a94bdbdabe953c8819625c5a811 (diff)
BLI Path: add function `BLI_path_contains()`
Add function `BLI_path_contains(container, containee)` that returns true if and only `container` contains `containee`. Paths are normalised and converted to native path separators before comparing. Relative paths are *not* made absolute, to simplify the function call; if this is necessary the caller has to do this conversion first.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenlib/BLI_path_util.h4
-rw-r--r--source/blender/blenlib/intern/path_util.c28
-rw-r--r--source/blender/blenlib/tests/BLI_path_util_test.cc23
3 files changed, 55 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 2a56d11276a..e4774c58e84 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -55,6 +55,10 @@ bool BLI_path_name_at_index(const char *__restrict path,
int *__restrict r_offset,
int *__restrict r_len) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
+/** Return true only if #containee_path is contained in #container_path. */
+bool BLI_path_contains(const char *container_path,
+ const char *containee_path) ATTR_WARN_UNUSED_RESULT;
+
const char *BLI_path_slash_rfind(const char *string) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
int BLI_path_slash_ensure(char *string) ATTR_NONNULL();
void BLI_path_slash_rstrip(char *string) ATTR_NONNULL();
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 4d0678035ba..4fc59e6cffd 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -1935,6 +1935,34 @@ bool BLI_path_name_at_index(const char *__restrict path,
return false;
}
+bool BLI_path_contains(const char *container_path, const char *containee_path)
+{
+ char container_native[PATH_MAX];
+ char containee_native[PATH_MAX];
+
+ /* Keep space for a trailing slash. If the path is truncated by this, the containee path is
+ * longer than PATH_MAX and the result is ill-defined. */
+ BLI_strncpy(container_native, container_path, PATH_MAX - 1);
+ BLI_strncpy(containee_native, containee_path, PATH_MAX);
+
+ BLI_path_slash_native(container_native);
+ BLI_path_slash_native(containee_native);
+
+ BLI_path_normalize(NULL, container_native);
+ BLI_path_normalize(NULL, containee_native);
+
+ if (STREQ(container_native, containee_native)) {
+ /* The paths are equal, they contain each other. */
+ return true;
+ }
+
+ /* Add a trailing slash to prevent same-prefix directories from matching.
+ * e.g. "/some/path" doesn't contain "/some/pathlib". */
+ BLI_path_slash_ensure(container_native);
+
+ return BLI_str_startswith(containee_native, container_native);
+}
+
/**
* Returns pointer to the leftmost path separator in string. Not actually used anywhere.
*/
diff --git a/source/blender/blenlib/tests/BLI_path_util_test.cc b/source/blender/blenlib/tests/BLI_path_util_test.cc
index cf5135731e2..fde28ebaf55 100644
--- a/source/blender/blenlib/tests/BLI_path_util_test.cc
+++ b/source/blender/blenlib/tests/BLI_path_util_test.cc
@@ -655,3 +655,26 @@ TEST(path_util, PathRelPath)
# undef PATH_REL
#endif
+
+/* BLI_path_contains */
+TEST(path_util, PathContains)
+{
+ EXPECT_TRUE(BLI_path_contains("/some/path", "/some/path")) << "A path contains itself";
+ EXPECT_TRUE(BLI_path_contains("/some/path", "/some/path/inside"))
+ << "A path contains its subdirectory";
+ EXPECT_TRUE(BLI_path_contains("/some/path", "/some/path/../path/inside"))
+ << "Paths should be normalised";
+ EXPECT_TRUE(BLI_path_contains("C:\\some\\path", "C:\\some\\path\\inside"))
+ << "Windows paths should be supported as well";
+
+ EXPECT_FALSE(BLI_path_contains("C:\\some\\path", "C:\\some\\other\\path"))
+ << "Windows paths should be supported as well";
+ EXPECT_FALSE(BLI_path_contains("/some/path", "/"))
+ << "Root directory not be contained in a subdirectory";
+ EXPECT_FALSE(BLI_path_contains("/some/path", "/some/path/../outside"))
+ << "Paths should be normalised";
+ EXPECT_FALSE(BLI_path_contains("/some/path", "/some/path_library"))
+ << "Just sharing a suffix is not enough, path semantics should be followed";
+ EXPECT_FALSE(BLI_path_contains("/some/path", "./contents"))
+ << "Relative paths are not supported";
+}