Commit ced645ea by Ramsay Jones Committed by Shawn O. Pearce

Add git__dirname and git__basename utility routines

These routines are intended to extract the directory and
base name from a path string. Note that these routines
do not interact with any filesystem and work only on the
text of the path.

Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
parent 66a4bfac
...@@ -59,3 +59,65 @@ int git__suffixcmp(const char *str, const char *suffix) ...@@ -59,3 +59,65 @@ int git__suffixcmp(const char *str, const char *suffix)
return -1; return -1;
return strcmp(str + (a - b), suffix); return strcmp(str + (a - b), suffix);
} }
int git__dirname(char *dir, size_t n, char *path)
{
char *s;
int len;
assert(dir && n > 1);
if (!path || !*path || !(s = strrchr(path, '/'))) {
strcpy(dir, ".");
return 1;
}
if (s == path) { /* "/[aaa]" */
strcpy(dir, "/");
return 1;
}
if ((len = s - path) >= n)
return GIT_ERROR;
memcpy(dir, path, len);
dir[len] = '\0';
return len;
}
int git__basename(char *base, size_t n, char *path)
{
char *s;
int len;
assert(base && n > 1);
if (!path || !*path) {
strcpy(base, ".");
return 1;
}
len = strlen(path);
if (!(s = strrchr(path, '/'))) {
if (len >= n)
return GIT_ERROR;
strcpy(base, path);
return len;
}
if (s == path && len == 1) { /* "/" */
strcpy(base, "/");
return 1;
}
len -= s - path;
if (len >= n)
return GIT_ERROR;
memcpy(base, s+1, len);
base[len] = '\0';
return len;
}
...@@ -31,6 +31,9 @@ extern int git__fmt(char *, size_t, const char *, ...) ...@@ -31,6 +31,9 @@ extern int git__fmt(char *, size_t, const char *, ...)
extern int git__prefixcmp(const char *str, const char *prefix); extern int git__prefixcmp(const char *str, const char *prefix);
extern int git__suffixcmp(const char *str, const char *suffix); extern int git__suffixcmp(const char *str, const char *suffix);
extern int git__dirname(char *dir, size_t n, char *path);
extern int git__basename(char *base, size_t n, char *path);
/** @return true if p fits into the range of a size_t */ /** @return true if p fits into the range of a size_t */
GIT_INLINE(int) git__is_sizet(off_t p) GIT_INLINE(int) git__is_sizet(off_t p)
{ {
......
...@@ -65,3 +65,61 @@ END_TEST ...@@ -65,3 +65,61 @@ END_TEST
BEGIN_TEST(suffixcmp_zaz_ac) BEGIN_TEST(suffixcmp_zaz_ac)
must_be_true(git__suffixcmp("zaz", "ac") > 0); must_be_true(git__suffixcmp("zaz", "ac") > 0);
END_TEST END_TEST
BEGIN_TEST(dirname)
char dir[64];
must_be_true(!(git__dirname(dir, sizeof(dir), NULL) < 0));
must_be_true(!strcmp(dir, "."));
must_be_true(!(git__dirname(dir, sizeof(dir), "") < 0));
must_be_true(!strcmp(dir, "."));
must_be_true(!(git__dirname(dir, sizeof(dir), "a") < 0));
must_be_true(!strcmp(dir, "."));
must_be_true(!(git__dirname(dir, sizeof(dir), "/") < 0));
must_be_true(!strcmp(dir, "/"));
must_be_true(!(git__dirname(dir, sizeof(dir), "/usr") < 0));
must_be_true(!strcmp(dir, "/"));
/* TODO: should this be "/" instead (ie strip trailing / first) */
must_be_true(!(git__dirname(dir, sizeof(dir), "/usr/") < 0));
must_be_true(!strcmp(dir, "/usr"));
must_be_true(!(git__dirname(dir, sizeof(dir), "/usr/lib") < 0));
must_be_true(!strcmp(dir, "/usr"));
must_be_true(!(git__dirname(dir, sizeof(dir), "usr/lib") < 0));
must_be_true(!strcmp(dir, "usr"));
END_TEST
BEGIN_TEST(basename)
char base[64];
must_be_true(!(git__basename(base, sizeof(base), NULL) < 0));
must_be_true(!strcmp(base, "."));
must_be_true(!(git__basename(base, sizeof(base), "") < 0));
must_be_true(!strcmp(base, "."));
must_be_true(!(git__basename(base, sizeof(base), "a") < 0));
must_be_true(!strcmp(base, "a"));
must_be_true(!(git__basename(base, sizeof(base), "/") < 0));
must_be_true(!strcmp(base, "/"));
must_be_true(!(git__basename(base, sizeof(base), "/usr") < 0));
must_be_true(!strcmp(base, "usr"));
/* TODO: should this be "usr" instead (ie strip trailing / first) */
must_be_true(!(git__basename(base, sizeof(base), "/usr/") < 0));
must_be_true(!strcmp(base, ""));
must_be_true(!(git__basename(base, sizeof(base), "/usr/lib") < 0));
must_be_true(!strcmp(base, "lib"));
must_be_true(!(git__basename(base, sizeof(base), "usr/lib") < 0));
must_be_true(!strcmp(base, "lib"));
END_TEST
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment