void add_exclude (struct exclude *ex, char const *pattern, int options) { struct exclude_segment *seg; if ((options & EXCLUDE_WILDCARDS) && fnmatch_pattern_has_wildcards (pattern, options)) { struct exclude_pattern *pat; struct patopts *patopts; if (ex->tail && ex->tail->type == exclude_pattern && ((ex->tail->options & EXCLUDE_INCLUDE) == (options & EXCLUDE_INCLUDE))) seg = ex->tail; else seg = new_exclude_segment (ex, exclude_pattern, options); pat = &seg->v.pat; if (pat->exclude_count == pat->exclude_alloc) pat->exclude = x2nrealloc (pat->exclude, &pat->exclude_alloc, sizeof *pat->exclude); patopts = &pat->exclude[pat->exclude_count++]; patopts->pattern = pattern; patopts->options = options; } else { char *str, *p; #define EXCLUDE_HASH_FLAGS (EXCLUDE_INCLUDE|EXCLUDE_ANCHORED|\ FNM_LEADING_DIR|FNM_CASEFOLD) if (ex->tail && ex->tail->type == exclude_hash && ((ex->tail->options & EXCLUDE_HASH_FLAGS) == (options & EXCLUDE_HASH_FLAGS))) seg = ex->tail; else seg = new_exclude_segment (ex, exclude_hash, options); str = xstrdup (pattern); if (options & EXCLUDE_WILDCARDS) unescape_pattern (str); p = hash_insert (seg->v.table, str); if (p != str) free (str); } }
void add_exclude (struct exclude *ex, char const *pattern, int options) { struct exclude_segment *seg; struct exclude_pattern *pat; struct patopts *patopts; if ((options & (EXCLUDE_REGEX|EXCLUDE_WILDCARDS)) && fnmatch_pattern_has_wildcards (pattern, options)) { if (! (ex->head && ex->head->type == exclude_pattern && ((ex->head->options & EXCLUDE_INCLUDE) == (options & EXCLUDE_INCLUDE)))) new_exclude_segment (ex, exclude_pattern, options); seg = ex->head; pat = &seg->v.pat; if (pat->exclude_count == pat->exclude_alloc) pat->exclude = x2nrealloc (pat->exclude, &pat->exclude_alloc, sizeof *pat->exclude); patopts = &pat->exclude[pat->exclude_count++]; patopts->options = options; if (options & EXCLUDE_REGEX) { int rc; int cflags = REG_NOSUB|REG_EXTENDED| ((options & FNM_CASEFOLD) ? REG_ICASE : 0); if (options & FNM_LEADING_DIR) { char *tmp; size_t len = strlen (pattern); while (len > 0 && ISSLASH (pattern[len-1])) --len; if (len == 0) rc = 1; else { tmp = xmalloc (len + 7); memcpy (tmp, pattern, len); strcpy (tmp + len, "(/.*)?"); rc = regcomp (&patopts->v.re, tmp, cflags); free (tmp); } } else rc = regcomp (&patopts->v.re, pattern, cflags); if (rc) { pat->exclude_count--; return; } } else { if (options & EXCLUDE_ALLOC) { pattern = xstrdup (pattern); exclude_add_pattern_buffer (ex, (char*) pattern); } patopts->v.pattern = pattern; } } else { char *str, *p; int exclude_hash_flags = (EXCLUDE_INCLUDE | EXCLUDE_ANCHORED | FNM_LEADING_DIR | FNM_CASEFOLD); if (! (ex->head && ex->head->type == exclude_hash && ((ex->head->options & exclude_hash_flags) == (options & exclude_hash_flags)))) new_exclude_segment (ex, exclude_hash, options); seg = ex->head; str = xstrdup (pattern); if ((options & (EXCLUDE_WILDCARDS | FNM_NOESCAPE)) == EXCLUDE_WILDCARDS) unescape_pattern (str); p = hash_insert (seg->v.table, str); if (p != str) free (str); } }