Skip to content

Commit

Permalink
path-util: Add path_simplify_full()
Browse files Browse the repository at this point in the history
Sometimes its useful to keep a trailing slash in the path so let's
add path_simplify_full() and a flag to do just that.
  • Loading branch information
DaanDeMeyer committed Aug 17, 2023
1 parent c0083c9 commit 4541d04
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 23 deletions.
9 changes: 7 additions & 2 deletions src/basic/path-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,8 @@ char **path_strv_resolve_uniq(char **l, const char *root) {
return strv_uniq(l);
}

char *path_simplify(char *path) {
bool add_slash = false;
char *path_simplify_full(char *path, PathSimplifyFlags flags) {
bool add_slash = false, keep_trailing_slash;
char *f = ASSERT_PTR(path);
int r;

Expand All @@ -359,6 +359,8 @@ char *path_simplify(char *path) {
if (isempty(path))
return path;

keep_trailing_slash = FLAGS_SET(flags, PATH_SIMPLIFY_KEEP_TRAILING_SLASH) && endswith(path, "/");

if (path_is_absolute(path))
f++;

Expand Down Expand Up @@ -388,6 +390,9 @@ char *path_simplify(char *path) {
if (f == path)
*f++ = '.';

if (*(f-1) != '/' && keep_trailing_slash)
*f++ = '/';

*f = '\0';
return path;
}
Expand Down
9 changes: 8 additions & 1 deletion src/basic/path-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,14 @@ char* path_extend_internal(char **x, ...);
#define path_extend(x, ...) path_extend_internal(x, __VA_ARGS__, POINTER_MAX)
#define path_join(...) path_extend_internal(NULL, __VA_ARGS__, POINTER_MAX)

char* path_simplify(char *path);
typedef enum PathSimplifyFlags {
PATH_SIMPLIFY_KEEP_TRAILING_SLASH = 1 << 0,
} PathSimplifyFlags;

char *path_simplify_full(char *path, PathSimplifyFlags flags);
static inline char* path_simplify(char *path) {
return path_simplify_full(path, 0);
}

static inline bool path_equal_ptr(const char *a, const char *b) {
return !!a == !!b && (!a || path_equal(a, b));
Expand Down
43 changes: 23 additions & 20 deletions src/test/test-path-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ TEST(path) {
assert_se(!path_equal_ptr(NULL, "/a"));
}

static void test_path_simplify_one(const char *in, const char *out) {
static void test_path_simplify_one(const char *in, const char *out, PathSimplifyFlags flags) {
char *p;

p = strdupa_safe(in);
path_simplify(p);
path_simplify_full(p, flags);
log_debug("/* test_path_simplify(%s) → %s (expected: %s) */", in, p, out);
assert_se(streq(p, out));
}
Expand All @@ -61,34 +61,37 @@ TEST(path_simplify) {
_cleanup_free_ char *hoge = NULL, *hoge_out = NULL;
char foo[NAME_MAX * 2];

test_path_simplify_one("", "");
test_path_simplify_one("aaa/bbb////ccc", "aaa/bbb/ccc");
test_path_simplify_one("//aaa/.////ccc", "/aaa/ccc");
test_path_simplify_one("///", "/");
test_path_simplify_one("///.//", "/");
test_path_simplify_one("///.//.///", "/");
test_path_simplify_one("////.././///../.", "/../..");
test_path_simplify_one(".", ".");
test_path_simplify_one("./", ".");
test_path_simplify_one(".///.//./.", ".");
test_path_simplify_one(".///.//././/", ".");
test_path_simplify_one("", "", 0);
test_path_simplify_one("aaa/bbb////ccc", "aaa/bbb/ccc", 0);
test_path_simplify_one("//aaa/.////ccc", "/aaa/ccc", 0);
test_path_simplify_one("///", "/", 0);
test_path_simplify_one("///", "/", PATH_SIMPLIFY_KEEP_TRAILING_SLASH);
test_path_simplify_one("///.//", "/", 0);
test_path_simplify_one("///.//.///", "/", 0);
test_path_simplify_one("////.././///../.", "/../..", 0);
test_path_simplify_one(".", ".", 0);
test_path_simplify_one("./", ".", 0);
test_path_simplify_one("./", "./", PATH_SIMPLIFY_KEEP_TRAILING_SLASH);
test_path_simplify_one(".///.//./.", ".", 0);
test_path_simplify_one(".///.//././/", ".", 0);
test_path_simplify_one("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.",
"/aaa/.bbb/../c./d.dd/..eeee");
"/aaa/.bbb/../c./d.dd/..eeee", 0);
test_path_simplify_one("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
"/aaa/.bbb/../c./d.dd/..eeee/..");
"/aaa/.bbb/../c./d.dd/..eeee/..", 0);
test_path_simplify_one(".//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
"aaa/.bbb/../c./d.dd/..eeee/..");
"aaa/.bbb/../c./d.dd/..eeee/..", 0);
test_path_simplify_one("..//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
"../aaa/.bbb/../c./d.dd/..eeee/..");
"../aaa/.bbb/../c./d.dd/..eeee/..", 0);
test_path_simplify_one("abc///", "abc/", PATH_SIMPLIFY_KEEP_TRAILING_SLASH);

memset(foo, 'a', sizeof(foo) -1);
char_array_0(foo);

test_path_simplify_one(foo, foo);
test_path_simplify_one(foo, foo, 0);

hoge = strjoin("/", foo);
assert_se(hoge);
test_path_simplify_one(hoge, hoge);
test_path_simplify_one(hoge, hoge, 0);
hoge = mfree(hoge);

hoge = strjoin("a////.//././//./b///././/./c/////././//./", foo, "//.//////d/e/.//f/");
Expand All @@ -97,7 +100,7 @@ TEST(path_simplify) {
hoge_out = strjoin("a/b/c/", foo, "//.//////d/e/.//f/");
assert_se(hoge_out);

test_path_simplify_one(hoge, hoge_out);
test_path_simplify_one(hoge, hoge_out, 0);
}

static void test_path_compare_one(const char *a, const char *b, int expected) {
Expand Down

0 comments on commit 4541d04

Please sign in to comment.