1 /* searchutils.c - helper subroutines for grep's matchers.
2 Copyright 1992, 1998, 2000, 2007, 2009-2012 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
23 #define NCHAR (UCHAR_MAX + 1)
26 kwsinit (kwset_t *kwset)
28 static char trans[NCHAR];
31 if (match_icase && MB_CUR_MAX == 1)
33 for (i = 0; i < NCHAR; ++i)
34 trans[i] = tolower (i);
36 *kwset = kwsalloc (trans);
39 *kwset = kwsalloc (NULL);
46 /* Convert the *N-byte string, BEG, to lowercase, and write the
47 NUL-terminated result into malloc'd storage. Upon success, set *N
48 to the length (in bytes) of the resulting string (not including the
49 trailing NUL byte), and return a pointer to the lowercase string.
50 Upon memory allocation failure, this function exits.
51 Note that on input, *N must be larger than zero.
53 Note that while this function returns a pointer to malloc'd storage,
54 the caller must not free it, since this function retains a pointer
55 to the buffer and reuses it on any subsequent call. As a consequence,
56 this function is not thread-safe. */
58 mbtolower (const char *beg, size_t *n)
61 static size_t outalloc;
62 size_t outlen, mb_cur_max;
67 if (*n > outalloc || outalloc == 0)
69 outalloc = MAX(1, *n);
70 out = xrealloc (out, outalloc);
73 /* appease clang-2.6 */
78 memset (&is, 0, sizeof (is));
79 memset (&os, 0, sizeof (os));
82 mb_cur_max = MB_CUR_MAX;
88 size_t mbclen = mbrtowc(&wc, beg, end - beg, &is);
89 if (outlen + mb_cur_max >= outalloc)
91 out = x2nrealloc (out, &outalloc, 1);
95 if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0)
97 /* An invalid sequence, or a truncated multi-octet character.
98 We treat it as a single-octet character. */
101 memset (&is, 0, sizeof (is));
102 memset (&os, 0, sizeof (os));
107 mbclen = wcrtomb (p, towlower ((wint_t) wc), &os);
120 is_mb_middle (const char **good, const char *buf, const char *end,
123 const char *p = *good;
124 const char *prev = p;
127 /* TODO: can be optimized for UTF-8. */
128 memset(&cur_state, 0, sizeof(mbstate_t));
131 size_t mbclen = mbrlen(p, end - p, &cur_state);
133 /* Store the beginning of the previous complete multibyte character. */
134 if (mbclen != (size_t) -2)
137 if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0)
139 /* An invalid sequence, or a truncated multibyte character.
140 We treat it as a single byte character. */
142 memset(&cur_state, 0, sizeof cur_state);
153 return 0 < match_len && match_len < mbrlen (p, end - p, &cur_state);
155 #endif /* MBS_SUPPORT */