summaryrefslogtreecommitdiff
path: root/src/searchutils.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2012-06-12 08:46:18 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2012-06-12 09:46:26 -0700
commit074842d3e3054714a495252e582886f0e4ace4e4 (patch)
tree7844219e817d1ecca6769fc3adcd03c5824d1031 /src/searchutils.c
parent02f1daa1e7dc80a544b7904d1d9d9841e02e3d8b (diff)
downloadgrep-074842d3e3054714a495252e582886f0e4ace4e4.tar.gz
grep: handle -i when chars differ in length but line does not
* src/searchutils.c (mbtolower): Return the map back to the caller if any input character's length differs from the corresponding output character's, not merely if the total string length differs. Problem reported by Johannes Mercer in <http://lists.gnu.org/archive/html/bug-grep/2012-06/msg00029.html>.
Diffstat (limited to 'src/searchutils.c')
-rw-r--r--src/searchutils.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/src/searchutils.c b/src/searchutils.c
index 4942c516..c1fb656d 100644
--- a/src/searchutils.c
+++ b/src/searchutils.c
@@ -55,7 +55,8 @@ kwsinit (kwset_t *kwset)
to the buffer and reuses it on any subsequent call. As a consequence,
this function is not thread-safe.
- When the lowercase result string has the same length as the input string,
+ When all the characters in the lowercase result string have the
+ same length as corresponding characters in the input string,
set *LEN_MAP_P to NULL. Otherwise, set it to a malloc'd buffer (like the
returned buffer, this must not be freed by caller) of the same length as
the result string. (*LEN_MAP_P)[J] is one less than the length-in-bytes
@@ -74,6 +75,7 @@ mbtolower (const char *beg, size_t *n, unsigned char **len_map_p)
const char *end;
char *p;
unsigned char *m;
+ bool lengths_differ = false;
if (*n > outalloc || outalloc == 0)
{
@@ -99,7 +101,7 @@ mbtolower (const char *beg, size_t *n, unsigned char **len_map_p)
while (beg < end)
{
wchar_t wc;
- size_t mbclen = mbrtowc(&wc, beg, end - beg, &is);
+ size_t mbclen = mbrtowc (&wc, beg, end - beg, &is);
if (outlen + mb_cur_max >= outalloc)
{
size_t dm = m - len_map;
@@ -123,14 +125,14 @@ mbtolower (const char *beg, size_t *n, unsigned char **len_map_p)
{
*m++ = mbclen - 1;
beg += mbclen;
- mbclen = wcrtomb (p, towlower ((wint_t) wc), &os);
- p += mbclen;
- outlen += mbclen;
+ size_t ombclen = wcrtomb (p, towlower ((wint_t) wc), &os);
+ p += ombclen;
+ outlen += ombclen;
+ lengths_differ |= (mbclen != ombclen);
}
}
- /* If the new length differs from the original, give caller the map. */
- *len_map_p = p - out == *n ? NULL : len_map;
+ *len_map_p = lengths_differ ? len_map : NULL;
*n = p - out;
*p = 0;
return out;