grep/pcre: prepare locale-dependent tables for icase matching

The default tables are usually built with C locale and only suitable
for LANG=C or similar.  This should make case insensitive search work
correctly for all single-byte charsets.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy 2016-06-25 07:22:33 +02:00 committed by Junio C Hamano
parent e944d9d932
commit 9d9babb84d
3 changed files with 26 additions and 2 deletions

8
grep.c
View file

@ -324,11 +324,14 @@ static void compile_pcre_regexp(struct grep_pat *p, const struct grep_opt *opt)
int erroffset;
int options = PCRE_MULTILINE;
if (opt->ignore_case)
if (opt->ignore_case) {
if (has_non_ascii(p->pattern))
p->pcre_tables = pcre_maketables();
options |= PCRE_CASELESS;
}
p->pcre_regexp = pcre_compile(p->pattern, options, &error, &erroffset,
NULL);
p->pcre_tables);
if (!p->pcre_regexp)
compile_regexp_failed(p, error);
@ -362,6 +365,7 @@ static void free_pcre_regexp(struct grep_pat *p)
{
pcre_free(p->pcre_regexp);
pcre_free(p->pcre_extra_info);
pcre_free((void *)p->pcre_tables);
}
#else /* !USE_LIBPCRE */
static void compile_pcre_regexp(struct grep_pat *p, const struct grep_opt *opt)

1
grep.h
View file

@ -48,6 +48,7 @@ struct grep_pat {
regex_t regexp;
pcre *pcre_regexp;
pcre_extra *pcre_extra_info;
const unsigned char *pcre_tables;
kwset_t kws;
unsigned fixed:1;
unsigned ignore_case:1;

19
t/t7813-grep-icase-iso.sh Executable file
View file

@ -0,0 +1,19 @@
#!/bin/sh
test_description='grep icase on non-English locales'
. ./lib-gettext.sh
test_expect_success GETTEXT_ISO_LOCALE 'setup' '
printf "TILRAUN: Halló Heimur!" >file &&
git add file &&
LC_ALL="$is_IS_iso_locale" &&
export LC_ALL
'
test_expect_success GETTEXT_ISO_LOCALE,LIBPCRE 'grep pcre string' '
git grep --perl-regexp -i "TILRAUN: H.lló Heimur!" &&
git grep --perl-regexp -i "TILRAUN: H.LLÓ HEIMUR!"
'
test_done