Introduce the function strip_path_suffix()
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Thu, 19 Feb 2009 19:10:49 +0000 (20:10 +0100)
committerJunio C Hamano <gitster@pobox.com>
Fri, 20 Feb 2009 06:45:48 +0000 (22:45 -0800)
The function strip_path_suffix() will try to strip a given suffix from
a given path.  The suffix must start at a directory boundary (i.e. "core"
is not a path suffix of "libexec/git-core", but "git-core" is).

Arbitrary runs of directory separators ("slashes") are assumed identical.

Example:

strip_path_suffix("C:\\msysgit/\\libexec\\git-core",
"libexec///git-core", &prefix)

will set prefix to "C:\\msysgit" and return 0.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
cache.h
path.c
t/t0060-path-utils.sh
test-path-utils.c

diff --git a/cache.h b/cache.h
index 37dfb1c18f5b19082ae82349cf4e89dd110dfdc9..21bbf9b119cccd6e91722dc101d4de85f0014c9d 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -626,6 +626,7 @@ const char *make_nonrelative_path(const char *path);
 const char *make_relative_path(const char *abs, const char *base);
 int normalize_path_copy(char *dst, const char *src);
 int longest_ancestor_length(const char *path, const char *prefix_list);
+char *strip_path_suffix(const char *path, const char *suffix);
 
 /* Read and unpack a sha1 file into memory, write memory to a sha1 file */
 extern int sha1_object_info(const unsigned char *, unsigned long *);
diff --git a/path.c b/path.c
index 4b9107fed10c1f3551acf1f14d2ba5d1ba8a0b84..e332b504a6b8c6b229da2526c4f810b8d0fb9889 100644 (file)
--- a/path.c
+++ b/path.c
@@ -499,3 +499,39 @@ int longest_ancestor_length(const char *path, const char *prefix_list)
 
        return max_len;
 }
+
+/* strip arbitrary amount of directory separators at end of path */
+static inline int chomp_trailing_dir_sep(const char *path, int len)
+{
+       while (len && is_dir_sep(path[len - 1]))
+               len--;
+       return len;
+}
+
+/*
+ * If path ends with suffix (complete path components), returns the
+ * part before suffix (sans trailing directory separators).
+ * Otherwise returns NULL.
+ */
+char *strip_path_suffix(const char *path, const char *suffix)
+{
+       int path_len = strlen(path), suffix_len = strlen(suffix);
+
+       while (suffix_len) {
+               if (!path_len)
+                       return NULL;
+
+               if (is_dir_sep(path[path_len - 1])) {
+                       if (!is_dir_sep(suffix[suffix_len - 1]))
+                               return NULL;
+                       path_len = chomp_trailing_dir_sep(path, path_len);
+                       suffix_len = chomp_trailing_dir_sep(suffix, suffix_len);
+               }
+               else if (path[--path_len] != suffix[--suffix_len])
+                       return NULL;
+       }
+
+       if (path_len && !is_dir_sep(path[path_len - 1]))
+               return NULL;
+       return xstrndup(path, chomp_trailing_dir_sep(path, path_len));
+}
index 4ed1f0b4dde45e679c04df4b3d833982a0a5b74c..8336114f9820aa5972d38efe316de7d9e39bcc5c 100755 (executable)
@@ -85,4 +85,8 @@ ancestor /foo/bar :://foo/.:: 4
 ancestor /foo/bar //foo/./::/bar 4
 ancestor /foo/bar ::/bar -1
 
+test_expect_success 'strip_path_suffix' '
+       test c:/msysgit = $(test-path-utils strip_path_suffix \
+               c:/msysgit/libexec//git-core libexec/git-core)
+'
 test_done
index 5168a8e3dfd5150de8def87980118e31e81296e7..d261398d6c50aeefa7450b99caae23ee5cdff0d0 100644 (file)
@@ -26,6 +26,12 @@ int main(int argc, char **argv)
                return 0;
        }
 
+       if (argc == 4 && !strcmp(argv[1], "strip_path_suffix")) {
+               char *prefix = strip_path_suffix(argv[2], argv[3]);
+               printf("%s\n", prefix ? prefix : "(null)");
+               return 0;
+       }
+
        fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
                argv[1] ? argv[1] : "(there was none)");
        return 1;