mirror of
https://https.git.savannah.gnu.org/git/grep.git
synced 2026-01-26 15:39:06 +00:00
grep: --exclude matches trailing parts of args
Problem reported by Vincent Lefevre in: http://bugs.gnu.org/22144 * NEWS: * doc/grep.texi (File and Directory Selection): Document this. * src/grep.c (excluded_patterns, excluded_directory_patterns): Now 2-element arrays, with one element for subfiles and another for command-line args. All uses changed. This implements the change. (exclude_options): New function. * tests/include-exclude: Test the change.
This commit is contained in:
parent
abc6e54e75
commit
f9c58376ca
5
NEWS
5
NEWS
@ -8,6 +8,11 @@ GNU grep NEWS -*- outline -*-
|
||||
invalid UTF8 just before a match.
|
||||
[bug introduced in grep-2.22]
|
||||
|
||||
--exclude and related options are now matched against trailing
|
||||
parts of command-line arguments, not against the entire arguments.
|
||||
This partly reverts the --exclude-related change in 2.22.
|
||||
[bug introduced in grep-2.22]
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.22 (2015-11-01) [stable]
|
||||
|
||||
|
||||
@ -661,8 +661,10 @@ this is equivalent to the @option{-r} option.
|
||||
@opindex --exclude
|
||||
@cindex exclude files
|
||||
@cindex searching directory trees
|
||||
Skip files whose name matches the pattern @var{glob}, using wildcard
|
||||
matching. When searching recursively, skip any subfile whose base
|
||||
Skip any command-line file with a name suffix that matches the pattern
|
||||
@var{glob}, using wildcard matching; a name suffix is either the whole
|
||||
name, or any suffix starting after a @samp{/} and before a
|
||||
non-@samp{/}. When searching recursively, skip any subfile whose base
|
||||
name matches @var{glob}; the base name is the part after the last
|
||||
@samp{/}. A pattern can use
|
||||
@samp{*}, @samp{?}, and @samp{[}...@samp{]} as wildcards,
|
||||
@ -679,9 +681,10 @@ under @option{--exclude}).
|
||||
@item --exclude-dir=@var{glob}
|
||||
@opindex --exclude-dir
|
||||
@cindex exclude directories
|
||||
Skip any directory whose name matches the pattern @var{glob}. When
|
||||
searching recursively, skip any subdirectory whose base name matches
|
||||
@var{glob}. Ignore any redundant trailing slashes in @var{glob}.
|
||||
Skip any command-line directory with a name suffix that matches the
|
||||
pattern @var{glob}. When searching recursively, skip any subdirectory
|
||||
whose base name matches @var{glob}. Ignore any redundant trailing
|
||||
slashes in @var{glob}.
|
||||
|
||||
@item -I
|
||||
Process a binary file as if it did not contain matching data;
|
||||
|
||||
65
src/grep.c
65
src/grep.c
@ -296,8 +296,8 @@ static const struct color_cap color_dict[] =
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static struct exclude *excluded_patterns;
|
||||
static struct exclude *excluded_directory_patterns;
|
||||
static struct exclude *excluded_patterns[2];
|
||||
static struct exclude *excluded_directory_patterns[2];
|
||||
/* Short options. */
|
||||
static char const short_options[] =
|
||||
"0123456789A:B:C:D:EFGHIPTUVX:abcd:e:f:hiLlm:noqRrsuvwxyZz";
|
||||
@ -640,19 +640,30 @@ context_length_arg (char const *str, intmax_t *out)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the add_exclude options suitable for excluding a file name.
|
||||
If COMMAND_LINE, it is a command-line file name. */
|
||||
static int
|
||||
exclude_options (bool command_line)
|
||||
{
|
||||
return EXCLUDE_WILDCARDS | (command_line ? 0 : EXCLUDE_ANCHORED);
|
||||
}
|
||||
|
||||
/* Return true if the file with NAME should be skipped.
|
||||
If COMMAND_LINE, it is a command-line argument.
|
||||
If IS_DIR, it is a directory. */
|
||||
static bool
|
||||
skipped_file (char const *name, bool command_line, bool is_dir)
|
||||
{
|
||||
return (is_dir
|
||||
? (directories == SKIP_DIRECTORIES
|
||||
|| (! (command_line && omit_dot_slash)
|
||||
&& excluded_directory_patterns
|
||||
&& excluded_file_name (excluded_directory_patterns, name)))
|
||||
: (excluded_patterns
|
||||
&& excluded_file_name (excluded_patterns, name)));
|
||||
struct exclude **pats;
|
||||
if (! is_dir)
|
||||
pats = excluded_patterns;
|
||||
else if (directories == SKIP_DIRECTORIES)
|
||||
return true;
|
||||
else if (command_line && omit_dot_slash)
|
||||
return false;
|
||||
else
|
||||
pats = excluded_directory_patterns;
|
||||
return pats[command_line] && excluded_file_name (pats[command_line], name);
|
||||
}
|
||||
|
||||
/* Hairy buffering mechanism for grep. The intent is to keep
|
||||
@ -2446,28 +2457,36 @@ main (int argc, char **argv)
|
||||
|
||||
case EXCLUDE_OPTION:
|
||||
case INCLUDE_OPTION:
|
||||
if (!excluded_patterns)
|
||||
excluded_patterns = new_exclude ();
|
||||
add_exclude (excluded_patterns, optarg,
|
||||
(EXCLUDE_ANCHORED | EXCLUDE_WILDCARDS
|
||||
| (opt == INCLUDE_OPTION ? EXCLUDE_INCLUDE : 0)));
|
||||
for (int cmd = 0; cmd < 2; cmd++)
|
||||
{
|
||||
if (!excluded_patterns[cmd])
|
||||
excluded_patterns[cmd] = new_exclude ();
|
||||
add_exclude (excluded_patterns[cmd], optarg,
|
||||
((opt == INCLUDE_OPTION ? EXCLUDE_INCLUDE : 0)
|
||||
| exclude_options (cmd)));
|
||||
}
|
||||
break;
|
||||
case EXCLUDE_FROM_OPTION:
|
||||
if (!excluded_patterns)
|
||||
excluded_patterns = new_exclude ();
|
||||
if (add_exclude_file (add_exclude, excluded_patterns, optarg,
|
||||
EXCLUDE_ANCHORED | EXCLUDE_WILDCARDS, '\n') != 0)
|
||||
for (int cmd = 0; cmd < 2; cmd++)
|
||||
{
|
||||
error (EXIT_TROUBLE, errno, "%s", optarg);
|
||||
if (!excluded_patterns[cmd])
|
||||
excluded_patterns[cmd] = new_exclude ();
|
||||
if (add_exclude_file (add_exclude, excluded_patterns[cmd],
|
||||
optarg, exclude_options (cmd), '\n')
|
||||
!= 0)
|
||||
error (EXIT_TROUBLE, errno, "%s", optarg);
|
||||
}
|
||||
break;
|
||||
|
||||
case EXCLUDE_DIRECTORY_OPTION:
|
||||
if (!excluded_directory_patterns)
|
||||
excluded_directory_patterns = new_exclude ();
|
||||
strip_trailing_slashes (optarg);
|
||||
add_exclude (excluded_directory_patterns, optarg,
|
||||
EXCLUDE_ANCHORED | EXCLUDE_WILDCARDS);
|
||||
for (int cmd = 0; cmd < 2; cmd++)
|
||||
{
|
||||
if (!excluded_directory_patterns[cmd])
|
||||
excluded_directory_patterns[cmd] = new_exclude ();
|
||||
add_exclude (excluded_directory_patterns[cmd], optarg,
|
||||
exclude_options (cmd));
|
||||
}
|
||||
break;
|
||||
|
||||
case GROUP_SEPARATOR_OPTION:
|
||||
|
||||
@ -66,9 +66,11 @@ for exclude in 'x' 'x*'; do
|
||||
grep -rl --exclude-dir="$exclude" . x > out
|
||||
test $? -eq 1 || fail=1
|
||||
compare /dev/null out || fail=1
|
||||
done
|
||||
|
||||
for exclude in 'x' 'x*' './x' './x*'; do
|
||||
grep -rl --exclude-dir="$exclude" . ./x | sort > out || fail=1
|
||||
compare exp-dotnames out || fail=1
|
||||
compare /dev/null out || fail=1
|
||||
done
|
||||
|
||||
Exit $fail
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user