diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2012-06-12 08:46:18 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2012-06-12 09:46:26 -0700 |
commit | 074842d3e3054714a495252e582886f0e4ace4e4 (patch) | |
tree | 7844219e817d1ecca6769fc3adcd03c5824d1031 /src | |
parent | 02f1daa1e7dc80a544b7904d1d9d9841e02e3d8b (diff) | |
download | grep-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')
-rw-r--r-- | src/searchutils.c | 16 |
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; |