1 /* Casefolding mapping for Unicode substrings (locale dependent).
2 Copyright (C) 2009-2020 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 <https://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);