1 /* Casefolding mapping for Unicode substrings (locale dependent).
2 Copyright (C) 2009-2014 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2009.
5 This program is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Lesser General Public License as published
7 by the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 FUNC (const UNIT *s, size_t n,
20 casing_prefix_context_t prefix_context,
21 casing_suffix_context_t suffix_context,
22 const char *iso639_language,
24 UNIT *resultbuf, size_t *lengthp)
26 /* Implement the three definitions of caseless matching, as described in
27 Unicode 5.0, section "Default caseless matching":
28 - If no normalization is requested, simply apply the casefolding.
30 - If canonical normalization is requested, apply it, and apply an NFD
32 X -> NFD(toCasefold(NFD(X))).
33 - If compatibility normalization is requested, apply it twice, apply
34 the normalization after each, and apply an NFD before:
35 X -> NFKD(toCasefold(NFKD(toCasefold(NFD(X))))). */
37 /* X -> toCasefold(X) */
38 return U_CASEMAP (s, n, prefix_context, suffix_context, iso639_language,
39 uc_tocasefold, offsetof (struct special_casing_rule, casefold[0]),
44 uninorm_t nfd = uninorm_decomposing_form (nf);
45 /* X -> nf(toCasefold(NFD(X))) or
46 X -> nf(toCasefold(nfd(toCasefold(NFD(X))))) */
47 int repeat = (uninorm_is_compat_decomposing (nf) ? 2 : 1);
48 UNIT tmpbuf1[2048 / sizeof (UNIT)];
49 UNIT tmpbuf2[2048 / sizeof (UNIT)];
55 tmp1_length = sizeof (tmpbuf1) / sizeof (UNIT);
56 tmp1 = U_NORMALIZE (UNINORM_NFD, s, n, tmpbuf1, &tmp1_length);
58 /* errno is set here. */
63 tmp2_length = sizeof (tmpbuf2) / sizeof (UNIT);
64 tmp2 = U_CASEMAP (tmp1, tmp1_length,
65 prefix_context, suffix_context, iso639_language,
66 uc_tocasefold, offsetof (struct special_casing_rule, casefold[0]),
68 tmpbuf2, &tmp2_length);
71 int saved_errno = errno;
83 tmp1_length = sizeof (tmpbuf1) / sizeof (UNIT);
84 tmp1 = U_NORMALIZE (nfd, tmp2, tmp2_length,
85 tmpbuf1, &tmp1_length);
88 /* Last run through this loop. */
89 tmp1 = U_NORMALIZE (nf, tmp2, tmp2_length,
93 int saved_errno = errno;
103 while (--repeat > 0);