1
1
/* exclude.c -- exclude file names
3
Copyright (C) 1992-1994, 1997, 1999-2007, 2009-2011 Free Software
3
Copyright (C) 1992-1994, 1997, 1999-2007, 2009-2012 Free Software
6
6
This program is free software: you can redistribute it and/or modify
107
/* The exclude structure keeps a singly-linked list of exclude segments */
107
/* The exclude structure keeps a singly-linked list of exclude segments,
108
maintained in reverse order. */
110
struct exclude_segment *head, *tail;
111
struct exclude_segment *head;
113
/* Return true if str has wildcard characters */
114
/* Return true if STR has or may have wildcards, when matched with OPTIONS.
115
Return false if STR definitely does not have wildcards. */
115
117
fnmatch_pattern_has_wildcards (const char *str, int options)
117
const char *cset = "\\?*[]";
118
if (options & FNM_NOESCAPE)
122
size_t n = strcspn (str, cset);
125
else if (str[n] == '\\')
124
str += ! (options & FNM_NOESCAPE) && *str;
127
case '+': case '@': case '!':
128
if (options & FNM_EXTMATCH && *str == '(')
132
case '?': case '*': case '[':
138
142
unescape_pattern (char *str)
146
q += *q == '\\' && q[1];
154
147
while ((*str++ = *q++));
221
214
/* Create new exclude segment of given TYPE and OPTIONS, and attach it
222
to the tail of list in EX */
223
static struct exclude_segment *
215
to the head of EX. */
224
217
new_exclude_segment (struct exclude *ex, enum exclude_type type, int options)
226
219
struct exclude_segment *sp = xzalloc (sizeof (struct exclude_segment));
350
/* Return true if the exclude_pattern segment SEG excludes F. */
339
/* Return true if the exclude_pattern segment SEG matches F. */
353
excluded_file_pattern_p (struct exclude_segment const *seg, char const *f)
342
file_pattern_matches (struct exclude_segment const *seg, char const *f)
355
344
size_t exclude_count = seg->v.pat.exclude_count;
356
345
struct patopts const *exclude = seg->v.pat.exclude;
358
bool excluded = !! (exclude[0].options & EXCLUDE_INCLUDE);
360
/* Scan through the options, until they change excluded */
361
348
for (i = 0; i < exclude_count; i++)
363
350
char const *pattern = exclude[i].pattern;
364
351
int options = exclude[i].options;
365
352
if (exclude_fnmatch (pattern, f, options))
371
/* Return true if the exclude_hash segment SEG excludes F.
358
/* Return true if the exclude_hash segment SEG matches F.
372
359
BUFFER is an auxiliary storage of the same length as F (with nul
373
360
terminator included) */
375
excluded_file_name_p (struct exclude_segment const *seg, char const *f,
362
file_name_matches (struct exclude_segment const *seg, char const *f,
378
365
int options = seg->options;
379
bool excluded = !! (options & EXCLUDE_INCLUDE);
380
366
Hash_table *table = seg->v.table;
419
406
excluded_file_name (struct exclude const *ex, char const *f)
421
408
struct exclude_segment *seg;
423
410
char *filename = NULL;
425
412
/* If no patterns are given, the default is to include. */
429
/* Otherwise, the default is the opposite of the first option. */
430
excluded = !! (ex->head->options & EXCLUDE_INCLUDE);
431
/* Scan through the segments, seeing whether they change status from
432
excluded to included or vice versa. */
433
for (seg = ex->head; seg; seg = seg->next)
416
/* Scan through the segments, reporting the status of the first match.
417
The segments are in reverse order, so this reports the status of
418
the last match in the original option list. */
419
for (seg = ex->head; ; seg = seg->next)
421
if (seg->type == exclude_hash)
439
case exclude_pattern:
440
rc = excluded_file_pattern_p (seg, f);
445
424
filename = xmalloc (strlen (f) + 1);
446
rc = excluded_file_name_p (seg, f, filename);
425
if (file_name_matches (seg, f, filename))
430
if (file_pattern_matches (seg, f))
436
/* If patterns are given but none match, the default is the
437
opposite of the last segment (i.e., the first in the
438
original option list). For example, in the command
439
'grep -r --exclude="a*" --include="*b" pat dir', the
440
first option is --exclude so any file name matching
441
neither a* nor *b is included. */
448
return invert ^ ! (seg->options & EXCLUDE_INCLUDE);
462
451
/* Append to EX the exclusion PATTERN with OPTIONS. */
472
461
struct exclude_pattern *pat;
473
462
struct patopts *patopts;
475
if (ex->tail && ex->tail->type == exclude_pattern
476
&& ((ex->tail->options & EXCLUDE_INCLUDE) ==
477
(options & EXCLUDE_INCLUDE)))
480
seg = new_exclude_segment (ex, exclude_pattern, options);
464
if (! (ex->head && ex->head->type == exclude_pattern
465
&& ((ex->head->options & EXCLUDE_INCLUDE)
466
== (options & EXCLUDE_INCLUDE))))
467
new_exclude_segment (ex, exclude_pattern, options);
482
470
pat = &seg->v.pat;
483
471
if (pat->exclude_count == pat->exclude_alloc)
493
#define EXCLUDE_HASH_FLAGS (EXCLUDE_INCLUDE|EXCLUDE_ANCHORED|\
494
FNM_LEADING_DIR|FNM_CASEFOLD)
495
if (ex->tail && ex->tail->type == exclude_hash
496
&& ((ex->tail->options & EXCLUDE_HASH_FLAGS) ==
497
(options & EXCLUDE_HASH_FLAGS)))
500
seg = new_exclude_segment (ex, exclude_hash, options);
481
int exclude_hash_flags = (EXCLUDE_INCLUDE | EXCLUDE_ANCHORED
482
| FNM_LEADING_DIR | FNM_CASEFOLD);
483
if (! (ex->head && ex->head->type == exclude_hash
484
&& ((ex->head->options & exclude_hash_flags)
485
== (options & exclude_hash_flags))))
486
new_exclude_segment (ex, exclude_hash, options);
502
489
str = xstrdup (pattern);
503
if (options & EXCLUDE_WILDCARDS)
490
if ((options & (EXCLUDE_WILDCARDS | FNM_NOESCAPE)) == EXCLUDE_WILDCARDS)
504
491
unescape_pattern (str);
505
492
p = hash_insert (seg->v.table, str);