-/*
- * Return non-zero if max_depth is negative or path has no more then max_depth
- * slashes.
- */
-static int accept_subdir(const char *path, int max_depth)
-{
- if (max_depth < 0)
- return 1;
-
- while ((path = strchr(path, '/')) != NULL) {
- max_depth--;
- if (max_depth < 0)
- return 0;
- path++;
- }
- return 1;
-}
-
-/*
- * Return non-zero if name is a subdirectory of match and is not too deep.
- */
-static int is_subdir(const char *name, int namelen,
- const char *match, int matchlen, int max_depth)
-{
- if (matchlen > namelen || strncmp(name, match, matchlen))
- return 0;
-
- if (name[matchlen] == '\0') /* exact match */
- return 1;
-
- if (!matchlen || match[matchlen-1] == '/' || name[matchlen] == '/')
- return accept_subdir(name + matchlen + 1, max_depth);
-
- return 0;
-}
-
-/*
- * git grep pathspecs are somewhat different from diff-tree pathspecs;
- * pathname wildcards are allowed.
- */
-static int pathspec_matches(const char **paths, const char *name, int max_depth)
-{
- int namelen, i;
- if (!paths || !*paths)
- return accept_subdir(name, max_depth);
- namelen = strlen(name);
- for (i = 0; paths[i]; i++) {
- const char *match = paths[i];
- int matchlen = strlen(match);
- const char *cp, *meta;
-
- if (is_subdir(name, namelen, match, matchlen, max_depth))
- return 1;
- if (!fnmatch(match, name, 0))
- return 1;
- if (name[namelen-1] != '/')
- continue;
-
- /* We are being asked if the directory ("name") is worth
- * descending into.
- *
- * Find the longest leading directory name that does
- * not have metacharacter in the pathspec; the name
- * we are looking at must overlap with that directory.
- */
- for (cp = match, meta = NULL; cp - match < matchlen; cp++) {
- char ch = *cp;
- if (ch == '*' || ch == '[' || ch == '?') {
- meta = cp;
- break;
- }
- }
- if (!meta)
- meta = cp; /* fully literal */
-
- if (namelen <= meta - match) {
- /* Looking at "Documentation/" and
- * the pattern says "Documentation/howto/", or
- * "Documentation/diff*.txt". The name we
- * have should match prefix.
- */
- if (!memcmp(match, name, namelen))
- return 1;
- continue;
- }
-
- if (meta - match < namelen) {
- /* Looking at "Documentation/howto/" and
- * the pattern says "Documentation/h*";
- * match up to "Do.../h"; this avoids descending
- * into "Documentation/technical/".
- */
- if (!memcmp(match, name, meta - match))
- return 1;
- continue;
- }
- }
- return 0;
-}
-