-static void add_sticky(struct exclude *exc, const char *pathname, int pathlen)
-{
- struct strbuf sb = STRBUF_INIT;
- int i;
-
- for (i = exc->sticky_paths.nr - 1; i >= 0; i--) {
- const char *sticky = exc->sticky_paths.items[i].string;
- int len = strlen(sticky);
-
- if (pathlen < len && sticky[pathlen] == '/' &&
- !strncmp(pathname, sticky, pathlen))
- return;
- }
-
- strbuf_add(&sb, pathname, pathlen);
- string_list_append_nodup(&exc->sticky_paths, strbuf_detach(&sb, NULL));
-}
-
-static int match_sticky(struct exclude *exc, const char *pathname, int pathlen, int dtype)
-{
- int i;
-
- for (i = exc->sticky_paths.nr - 1; i >= 0; i--) {
- const char *sticky = exc->sticky_paths.items[i].string;
- int len = strlen(sticky);
-
- if (pathlen == len && dtype == DT_DIR &&
- !strncmp(pathname, sticky, len))
- return 1;
-
- if (pathlen > len && pathname[len] == '/' &&
- !strncmp(pathname, sticky, len))
- return 1;
- }
-
- return 0;
-}
-
-static inline int different_decisions(const struct exclude *a,
- const struct exclude *b)
-{
- return (a->flags & EXC_FLAG_NEGATIVE) != (b->flags & EXC_FLAG_NEGATIVE);
-}
-
-/*
- * Return non-zero if pathname is a directory and an ancestor of the
- * literal path in a pattern.
- */
-static int match_directory_part(const char *pathname, int pathlen,
- int *dtype, struct exclude *x)
-{
- const char *base = x->base;
- int baselen = x->baselen ? x->baselen - 1 : 0;
- const char *pattern = x->pattern;
- int prefix = x->nowildcardlen;
- int patternlen = x->patternlen;
-
- if (*dtype == DT_UNKNOWN)
- *dtype = get_dtype(NULL, pathname, pathlen);
- if (*dtype != DT_DIR)
- return 0;
-
- if (*pattern == '/') {
- pattern++;
- patternlen--;
- prefix--;
- }
-
- if (baselen) {
- if (((pathlen < baselen && base[pathlen] == '/') ||
- pathlen == baselen) &&
- !strncmp_icase(pathname, base, pathlen))
- return 1;
- pathname += baselen + 1;
- pathlen -= baselen + 1;
- }
-
-
- if (prefix &&
- (((pathlen < prefix && pattern[pathlen] == '/') ||
- pathlen == prefix) &&
- !strncmp_icase(pathname, pattern, pathlen)))
- return 1;
-
- return 0;
-}
-
-static struct exclude *should_descend(const char *pathname, int pathlen,
- int *dtype, struct exclude_list *el,
- struct exclude *exc)
-{
- int i;
-
- for (i = el->nr - 1; 0 <= i; i--) {
- struct exclude *x = el->excludes[i];
-
- if (x == exc)
- break;
-
- if (!(x->flags & EXC_FLAG_NODIR) &&
- different_decisions(x, exc) &&
- match_directory_part(pathname, pathlen, dtype, x))
- return x;
- }
- return NULL;
-}
-