1 /* Casefolding mapping for Unicode strings (locale dependent).
2 Copyright (C) 2009 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, const char *iso639_language,
21 UNIT *resultbuf, size_t *lengthp)
23 /* Implement the three definitions of caseless matching, as described in
24 Unicode 5.0, section "Default caseless matching":
25 - If no normalization is requested, simply apply the casefolding.
27 - If canonical normalization is requested, apply it, and apply an NFD
29 X -> NFD(toCasefold(NFD(X))).
30 - If compatibility normalization is requested, apply it twice, apply
31 the normalization after each, and apply an NFD before:
32 X -> NFKD(toCasefold(NFKD(toCasefold(NFD(X))))). */
34 /* X -> toCasefold(X) */
35 return U_CASEMAP (s, n, iso639_language,
36 uc_tocasefold, offsetof (struct special_casing_rule, casefold[0]),
41 uninorm_t nfd = uninorm_decomposing_form (nf);
42 /* X -> nf(toCasefold(NFD(X))) or
43 X -> nf(toCasefold(nfd(toCasefold(NFD(X))))) */
44 int repeat = (uninorm_is_compat_decomposing (nf) ? 2 : 1);
45 UNIT tmpbuf1[2048 / sizeof (UNIT)];
46 UNIT tmpbuf2[2048 / sizeof (UNIT)];
52 tmp1_length = sizeof (tmpbuf1) / sizeof (UNIT);
53 tmp1 = U_NORMALIZE (UNINORM_NFD, s, n, tmpbuf1, &tmp1_length);
55 /* errno is set here. */
60 tmp2_length = sizeof (tmpbuf2) / sizeof (UNIT);
61 tmp2 = U_CASEMAP (tmp1, tmp1_length, iso639_language,
62 uc_tocasefold, offsetof (struct special_casing_rule, casefold[0]),
64 tmpbuf2, &tmp2_length);
67 int saved_errno = errno;
79 tmp1_length = sizeof (tmpbuf1) / sizeof (UNIT);
80 tmp1 = U_NORMALIZE (nfd, tmp2, tmp2_length,
81 tmpbuf1, &tmp1_length);
84 /* Last run through this loop. */
85 tmp1 = U_NORMALIZE (nf, tmp2, tmp2_length,
89 int saved_errno = errno;