* bc/grep-i-F:
  grep: Allow case insensitive search of fixed-strings
This commit is contained in:
Junio C Hamano 2009-11-22 16:28:29 -08:00
Родитель a1b01c45d5 5183bf6727
Коммит 3fa384d27e
4 изменённых файлов: 27 добавлений и 6 удалений

Просмотреть файл

@ -367,7 +367,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
push_arg("-h"); push_arg("-h");
if (opt->regflags & REG_EXTENDED) if (opt->regflags & REG_EXTENDED)
push_arg("-E"); push_arg("-E");
if (opt->regflags & REG_ICASE) if (opt->ignore_case)
push_arg("-i"); push_arg("-i");
if (opt->binary == GREP_BINARY_NOMATCH) if (opt->binary == GREP_BINARY_NOMATCH)
push_arg("-I"); push_arg("-I");
@ -710,8 +710,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
OPT_GROUP(""), OPT_GROUP(""),
OPT_BOOLEAN('v', "invert-match", &opt.invert, OPT_BOOLEAN('v', "invert-match", &opt.invert,
"show non-matching lines"), "show non-matching lines"),
OPT_BIT('i', "ignore-case", &opt.regflags, OPT_BOOLEAN('i', "ignore-case", &opt.ignore_case,
"case insensitive matching", REG_ICASE), "case insensitive matching"),
OPT_BOOLEAN('w', "word-regexp", &opt.word_regexp, OPT_BOOLEAN('w', "word-regexp", &opt.word_regexp,
"match patterns only at word boundaries"), "match patterns only at word boundaries"),
OPT_SET_INT('a', "text", &opt.binary, OPT_SET_INT('a', "text", &opt.binary,
@ -841,6 +841,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
external_grep_allowed = 0; external_grep_allowed = 0;
if (!opt.pattern_list) if (!opt.pattern_list)
die("no pattern given."); die("no pattern given.");
if (!opt.fixed && opt.ignore_case)
opt.regflags |= REG_ICASE;
if ((opt.regflags != REG_NEWLINE) && opt.fixed) if ((opt.regflags != REG_NEWLINE) && opt.fixed)
die("cannot mix --fixed-strings and regexp"); die("cannot mix --fixed-strings and regexp");
compile_grep_patterns(&opt); compile_grep_patterns(&opt);

13
grep.c
Просмотреть файл

@ -41,6 +41,7 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
int err; int err;
p->word_regexp = opt->word_regexp; p->word_regexp = opt->word_regexp;
p->ignore_case = opt->ignore_case;
if (opt->fixed || is_fixed(p->pattern)) if (opt->fixed || is_fixed(p->pattern))
p->fixed = 1; p->fixed = 1;
@ -262,9 +263,15 @@ static void show_name(struct grep_opt *opt, const char *name)
printf("%s%c", name, opt->null_following_name ? '\0' : '\n'); printf("%s%c", name, opt->null_following_name ? '\0' : '\n');
} }
static int fixmatch(const char *pattern, char *line, regmatch_t *match)
static int fixmatch(const char *pattern, char *line, int ignore_case, regmatch_t *match)
{ {
char *hit = strstr(line, pattern); char *hit;
if (ignore_case)
hit = strcasestr(line, pattern);
else
hit = strstr(line, pattern);
if (!hit) { if (!hit) {
match->rm_so = match->rm_eo = -1; match->rm_so = match->rm_eo = -1;
return REG_NOMATCH; return REG_NOMATCH;
@ -326,7 +333,7 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
again: again:
if (p->fixed) if (p->fixed)
hit = !fixmatch(p->pattern, bol, pmatch); hit = !fixmatch(p->pattern, bol, p->ignore_case, pmatch);
else else
hit = !regexec(&p->regexp, bol, 1, pmatch, eflags); hit = !regexec(&p->regexp, bol, 1, pmatch, eflags);

2
grep.h
Просмотреть файл

@ -32,6 +32,7 @@ struct grep_pat {
enum grep_header_field field; enum grep_header_field field;
regex_t regexp; regex_t regexp;
unsigned fixed:1; unsigned fixed:1;
unsigned ignore_case:1;
unsigned word_regexp:1; unsigned word_regexp:1;
}; };
@ -64,6 +65,7 @@ struct grep_opt {
regex_t regexp; regex_t regexp;
int linenum; int linenum;
int invert; int invert;
int ignore_case;
int status_only; int status_only;
int name_only; int name_only;
int unmatch_name_only; int unmatch_name_only;

Просмотреть файл

@ -14,6 +14,7 @@ int main(int argc, const char **argv)
{ {
printf("Hello world.\n"); printf("Hello world.\n");
return 0; return 0;
/* char ?? */
} }
EOF EOF
@ -416,4 +417,13 @@ test_expect_success 'grep from a subdirectory to search wider area (2)' '
) )
' '
cat >expected <<EOF
hello.c:int main(int argc, const char **argv)
EOF
test_expect_success 'grep -Fi' '
git grep -Fi "CHAR *" >actual &&
test_cmp expected actual
'
test_done test_done