grep: Allow case insensitive search of fixed-strings
"git grep" currently an error when you combine the -F and -i flags. This isn't in line with how GNU grep handles it. This patch allows the simultaneous use of those flags. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Brian Collins <bricollins@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Brian Collins committed
Nov 6, 2009 at 01:22 UTC
5183bf67278ce5a0da9779d74f05169beac219b8
4 files changed
+27
-6
builtin-grep.c
+5
-3
@@ -367,7 +367,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
367
push_arg("-h");
368
if (opt->regflags & REG_EXTENDED)
369
push_arg("-E");
370
- if (opt->regflags & REG_ICASE)
370
+ if (opt->ignore_case)
371
push_arg("-i");
372
if (opt->binary == GREP_BINARY_NOMATCH)
373
push_arg("-I");
@@ -706,8 +706,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
706
OPT_GROUP(""),
707
OPT_BOOLEAN('v', "invert-match", &opt.invert,
708
"show non-matching lines"),
709
- OPT_BIT('i', "ignore-case", &opt.regflags,
710
- "case insensitive matching", REG_ICASE),
709
+ OPT_BOOLEAN('i', "ignore-case", &opt.ignore_case,
710
+ "case insensitive matching"),
711
OPT_BOOLEAN('w', "word-regexp", &opt.word_regexp,
712
"match patterns only at word boundaries"),
713
OPT_SET_INT('a', "text", &opt.binary,
@@ -830,6 +830,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
830
external_grep_allowed = 0;
831
if (!opt.pattern_list)
832
die("no pattern given.");
833
+ if (!opt.fixed && opt.ignore_case)
834
+ opt.regflags |= REG_ICASE;
835
if ((opt.regflags != REG_NEWLINE) && opt.fixed)
836
die("cannot mix --fixed-strings and regexp");
837
compile_grep_patterns(&opt);
grep.c
+10
-3
@@ -41,6 +41,7 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
41
int err;
42
43
p->word_regexp = opt->word_regexp;
44
+ p->ignore_case = opt->ignore_case;
45
46
if (opt->fixed || is_fixed(p->pattern))
47
p->fixed = 1;
@@ -262,9 +263,15 @@ static void show_name(struct grep_opt *opt, const char *name)
263
printf("%s%c", name, opt->null_following_name ? '\0' : '\n');
264
}
265
265
-static int fixmatch(const char *pattern, char *line, regmatch_t *match)
266
+
267
+static int fixmatch(const char *pattern, char *line, int ignore_case, regmatch_t *match)
268
{
267
- char *hit = strstr(line, pattern);
269
+ char *hit;
270
+ if (ignore_case)
271
+ hit = strcasestr(line, pattern);
272
+ else
273
+ hit = strstr(line, pattern);
274
+
275
if (!hit) {
276
match->rm_so = match->rm_eo = -1;
277
return REG_NOMATCH;
@@ -326,7 +333,7 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
333
334
again:
335
if (p->fixed)
329
- hit = !fixmatch(p->pattern, bol, pmatch);
336
+ hit = !fixmatch(p->pattern, bol, p->ignore_case, pmatch);
337
else
338
hit = !regexec(&p->regexp, bol, 1, pmatch, eflags);
339
grep.h
+2
@@ -32,6 +32,7 @@ struct grep_pat {
32
enum grep_header_field field;
33
regex_t regexp;
34
unsigned fixed:1;
35
+ unsigned ignore_case:1;
36
unsigned word_regexp:1;
37
};
38
@@ -64,6 +65,7 @@ struct grep_opt {
65
regex_t regexp;
66
int linenum;
67
int invert;
68
+ int ignore_case;
69
int status_only;
70
int name_only;
71
int unmatch_name_only;
t/t7002-grep.sh
+10
@@ -14,6 +14,7 @@ int main(int argc, const char **argv)
14
{
15
printf("Hello world.\n");
16
return 0;
17
+ /* char ?? */
18
}
19
EOF
20
@@ -345,4 +346,13 @@ test_expect_success 'grep from a subdirectory to search wider area (2)' '
346
)
347
'
348
349
+cat >expected <<EOF
350
+hello.c:int main(int argc, const char **argv)
351
+EOF
352
+
353
+test_expect_success 'grep -Fi' '
354
+ git grep -Fi "CHAR *" >actual &&
355
+ test_cmp expected actual
356
+'
357
+
358
test_done