1 /* Locale-specific case-ignoring memory comparison.
2 Copyright (C) 2001, 2009-2020 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2001.
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/>. */
21 #include "mbmemcasecoll.h"
30 /* Get mbstate_t, mbrtowc(), wcrtomb(). */
40 #define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
42 /* Apply towlower() to the multibyte character sequence in INBUF, storing the
43 result as a multibyte character sequence in OUTBUF. */
45 apply_towlower (const char *inbuf
, size_t inbufsize
,
46 char *outbuf
, size_t outbufsize
)
48 char *outbuf_orig
= outbuf
;
51 remaining
= inbufsize
;
58 memset (&state
, '\0', sizeof (mbstate_t));
59 n1
= mbrtowc (&wc1
, inbuf
, remaining
, &state
);
60 if (n1
== (size_t)(-2))
62 if (n1
!= (size_t)(-1))
66 if (n1
== 0) /* NUL character? */
74 memset (&state
, '\0', sizeof (mbstate_t));
75 n2
= wcrtomb (outbuf
, wc2
, &state
);
76 if (n2
!= (size_t)(-1))
78 /* Store the translated multibyte character. */
86 /* Nothing to translate. */
87 memcpy (outbuf
, inbuf
, n1
);
94 /* Invalid multibyte character on input.
95 Copy one byte without modification. */
99 /* Incomplete multibyte sequence on input.
100 Pass it through unmodified. */
101 while (remaining
> 0)
103 *outbuf
++ = *inbuf
++;
107 /* Verify the output buffer was large enough. */
108 if (outbuf
- outbuf_orig
> outbufsize
)
111 /* Return the number of written output bytes. */
112 return outbuf
- outbuf_orig
;
115 /* Apply tolower() to the unibyte character sequence in INBUF, storing the
116 result as a unibyte character sequence in OUTBUF. */
118 apply_tolower (const char *inbuf
, char *outbuf
, size_t bufsize
)
120 for (; bufsize
> 0; bufsize
--)
122 *outbuf
= TOLOWER ((unsigned char) *inbuf
);
129 mbmemcasecoll (const char *s1
, size_t s1len
, const char *s2
, size_t s2len
,
130 bool hard_LC_COLLATE
)
141 /* Application of towlower grows each character by a factor 2
148 /* Application of tolower doesn't change the size. */
152 /* Allocate memory for t1 and t2. */
153 memory
= (char *) malloca (t1len
+ 1 + t2len
+ 1);
160 t2
= memory
+ t1len
+ 1;
162 /* Csae-fold the two argument strings. */
165 t1len
= apply_towlower (s1
, s1len
, t1
, t1len
);
166 t2len
= apply_towlower (s2
, s2len
, t2
, t2len
);
170 apply_tolower (s1
, t1
, s1len
);
171 apply_tolower (s2
, t2
, s2len
);
174 /* Compare the two case-folded strings. */
176 cmp
= memcoll (t1
, t1len
, t2
, t2len
);
179 cmp
= memcmp2 (t1
, t1len
, t2
, t2len
);
184 int saved_errno
= errno
;