1 /* Locale-specific case-ignoring memory comparison.
2 Copyright (C) 2001, 2009-2024 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2001.
5 This file is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 This file 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
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
21 #include "mbmemcasecoll.h"
33 /* Get char32_t, mbrtoc32(), c32rtomb(), c32tolower(). */
40 /* Apply c32tolower() to the multibyte character sequence in INBUF, storing the
41 result as a multibyte character sequence in OUTBUF. */
43 apply_c32tolower (const char *inbuf
, size_t inbufsize
,
44 char *outbuf
, size_t outbufsize
)
46 char *outbuf_orig
= outbuf
;
49 remaining
= inbufsize
;
60 n1
= mbrtoc32 (&wc1
, inbuf
, remaining
, &state
);
62 if (n1
== (size_t)(-1))
64 /* Invalid multibyte character on input.
65 Copy one byte without modification. */
70 else if (n1
== (size_t)(-2))
72 /* Incomplete multibyte sequence on input.
73 Pass it through unmodified. */
85 if (n1
== 0) /* NUL character? */
87 #if !GNULIB_MBRTOC32_REGULAR
88 else if (n1
== (size_t)(-3))
92 wc2
= c32tolower (wc1
);
99 n2
= c32rtomb (outbuf
, wc2
, &state2
);
100 if (n2
!= (size_t)(-1))
102 /* Store the translated multibyte character. */
108 /* Nothing to translate. */
109 memcpy (outbuf
, inbuf
, n1
);
115 #if !GNULIB_MBRTOC32_REGULAR
116 if (mbsinit (&state
))
122 /* Verify the output buffer was large enough. */
123 if (outbuf
- outbuf_orig
> outbufsize
)
126 /* Return the number of written output bytes. */
127 return outbuf
- outbuf_orig
;
130 /* Apply tolower() to the unibyte character sequence in INBUF, storing the
131 result as a unibyte character sequence in OUTBUF. */
133 apply_tolower (const char *inbuf
, char *outbuf
, size_t bufsize
)
135 for (; bufsize
> 0; bufsize
--)
137 *outbuf
= tolower ((unsigned char) *inbuf
);
144 mbmemcasecoll (const char *s1
, size_t s1len
, const char *s2
, size_t s2len
,
145 bool hard_LC_COLLATE
)
156 /* Application of towlower grows each character by a factor 2
163 /* Application of tolower doesn't change the size. */
167 /* Allocate memory for t1 and t2. */
168 memory
= (char *) malloca (t1len
+ 1 + t2len
+ 1);
175 t2
= memory
+ t1len
+ 1;
177 /* Case-fold the two argument strings. */
180 t1len
= apply_c32tolower (s1
, s1len
, t1
, t1len
);
181 t2len
= apply_c32tolower (s2
, s2len
, t2
, t2len
);
185 apply_tolower (s1
, t1
, s1len
);
186 apply_tolower (s2
, t2
, s2len
);
189 /* Compare the two case-folded strings. */
191 cmp
= memcoll (t1
, t1len
, t2
, t2len
);
194 cmp
= memcmp2 (t1
, t1len
, t2
, t2len
);
199 int saved_errno
= errno
;