Move pathspec matching from builtin-add.c into dir.c
authorLinus Torvalds <torvalds@osdl.org>
Fri, 19 May 2006 23:07:51 +0000 (16:07 -0700)
committerJunio C Hamano <junkio@cox.net>
Fri, 19 May 2006 23:14:50 +0000 (16:14 -0700)
I'll use it for builtin-rm.c too.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
builtin-add.c
dir.c
dir.h

index 37243f8..6166f66 100644 (file)
 static const char builtin_add_usage[] =
 "git-add [-n] [-v] <filepattern>...";
 
-static int common_prefix(const char **pathspec)
-{
-       const char *path, *slash, *next;
-       int prefix;
-
-       if (!pathspec)
-               return 0;
-
-       path = *pathspec;
-       slash = strrchr(path, '/');
-       if (!slash)
-               return 0;
-
-       prefix = slash - path + 1;
-       while ((next = *++pathspec) != NULL) {
-               int len = strlen(next);
-               if (len >= prefix && !memcmp(path, next, len))
-                       continue;
-               for (;;) {
-                       if (!len)
-                               return 0;
-                       if (next[--len] != '/')
-                               continue;
-                       if (memcmp(path, next, len+1))
-                               continue;
-                       prefix = len + 1;
-                       break;
-               }
-       }
-       return prefix;
-}
-
-static int match_one(const char *match, const char *name, int namelen)
-{
-       int matchlen;
-
-       /* If the match was just the prefix, we matched */
-       matchlen = strlen(match);
-       if (!matchlen)
-               return 1;
-
-       /*
-        * If we don't match the matchstring exactly,
-        * we need to match by fnmatch
-        */
-       if (strncmp(match, name, matchlen))
-               return !fnmatch(match, name, 0);
-
-       /*
-        * If we did match the string exactly, we still
-        * need to make sure that it happened on a path
-        * component boundary (ie either the last character
-        * of the match was '/', or the next character of
-        * the name was '/' or the terminating NUL.
-        */
-       return  match[matchlen-1] == '/' ||
-               name[matchlen] == '/' ||
-               !name[matchlen];
-}
-
-static int match(const char **pathspec, const char *name, int namelen, int prefix, char *seen)
-{
-       int retval;
-       const char *match;
-
-       name += prefix;
-       namelen -= prefix;
-
-       for (retval = 0; (match = *pathspec++) != NULL; seen++) {
-               if (retval & *seen)
-                       continue;
-               match += prefix;
-               if (match_one(match, name, namelen)) {
-                       retval = 1;
-                       *seen = 1;
-               }
-       }
-       return retval;
-}
-
 static void prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
 {
        char *seen;
@@ -107,7 +27,7 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p
        i = dir->nr;
        while (--i >= 0) {
                struct dir_entry *entry = *src++;
-               if (!match(pathspec, entry->name, entry->len, prefix, seen)) {
+               if (!match_pathspec(pathspec, entry->name, entry->len, prefix, seen)) {
                        free(entry);
                        continue;
                }
diff --git a/dir.c b/dir.c
index d40b62e..d778ecd 100644 (file)
--- a/dir.c
+++ b/dir.c
 #include "cache.h"
 #include "dir.h"
 
+int common_prefix(const char **pathspec)
+{
+       const char *path, *slash, *next;
+       int prefix;
+
+       if (!pathspec)
+               return 0;
+
+       path = *pathspec;
+       slash = strrchr(path, '/');
+       if (!slash)
+               return 0;
+
+       prefix = slash - path + 1;
+       while ((next = *++pathspec) != NULL) {
+               int len = strlen(next);
+               if (len >= prefix && !memcmp(path, next, len))
+                       continue;
+               for (;;) {
+                       if (!len)
+                               return 0;
+                       if (next[--len] != '/')
+                               continue;
+                       if (memcmp(path, next, len+1))
+                               continue;
+                       prefix = len + 1;
+                       break;
+               }
+       }
+       return prefix;
+}
+
+static int match_one(const char *match, const char *name, int namelen)
+{
+       int matchlen;
+
+       /* If the match was just the prefix, we matched */
+       matchlen = strlen(match);
+       if (!matchlen)
+               return 1;
+
+       /*
+        * If we don't match the matchstring exactly,
+        * we need to match by fnmatch
+        */
+       if (strncmp(match, name, matchlen))
+               return !fnmatch(match, name, 0);
+
+       /*
+        * If we did match the string exactly, we still
+        * need to make sure that it happened on a path
+        * component boundary (ie either the last character
+        * of the match was '/', or the next character of
+        * the name was '/' or the terminating NUL.
+        */
+       return  match[matchlen-1] == '/' ||
+               name[matchlen] == '/' ||
+               !name[matchlen];
+}
+
+int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen)
+{
+       int retval;
+       const char *match;
+
+       name += prefix;
+       namelen -= prefix;
+
+       for (retval = 0; (match = *pathspec++) != NULL; seen++) {
+               if (retval & *seen)
+                       continue;
+               match += prefix;
+               if (match_one(match, name, namelen)) {
+                       retval = 1;
+                       *seen = 1;
+               }
+       }
+       return retval;
+}
+
 void add_exclude(const char *string, const char *base,
                 int baselen, struct exclude_list *which)
 {
diff --git a/dir.h b/dir.h
index 4f65f57..56a1b7f 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -39,6 +39,9 @@ struct dir_struct {
        struct exclude_list exclude_list[3];
 };
 
+extern int common_prefix(const char **pathspec);
+extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
+
 extern int read_directory(struct dir_struct *, const char *path, const char *base, int baselen);
 extern int excluded(struct dir_struct *, const char *);
 extern void add_excludes_from_file(struct dir_struct *, const char *fname);