aarch64: Remove the unused __read_tp symbol
[glibc.git] / string / test-strncasecmp.c
blobace94e83eca9bd72b1c5dd30146ca8aa41e3bfa6
1 /* Test and measure strncasecmp functions.
2 Copyright (C) 1999-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Written by Jakub Jelinek <jakub@redhat.com>, 1999.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
20 #include <locale.h>
21 #include <ctype.h>
22 #define TEST_MAIN
23 #define TEST_NAME "strncasecmp"
24 #include "test-string.h"
26 typedef int (*proto_t) (const char *, const char *, size_t);
27 static int simple_strncasecmp (const char *, const char *, size_t);
28 static int stupid_strncasecmp (const char *, const char *, size_t);
30 IMPL (stupid_strncasecmp, 0)
31 IMPL (simple_strncasecmp, 0)
32 IMPL (strncasecmp, 1)
34 static int
35 simple_strncasecmp (const char *s1, const char *s2, size_t n)
37 int ret;
39 if (n == 0)
40 return 0;
42 while ((ret = ((unsigned char) tolower (*s1)
43 - (unsigned char) tolower (*s2))) == 0
44 && *s1++)
46 if (--n == 0)
47 return 0;
48 ++s2;
50 return ret;
53 static int
54 stupid_strncasecmp (const char *s1, const char *s2, size_t max)
56 size_t ns1 = strlen (s1) + 1;
57 size_t ns2 = strlen (s2) + 1;
58 size_t n = ns1 < ns2 ? ns1 : ns2;
59 if (n > max)
60 n = max;
61 int ret = 0;
63 while (n--)
65 if ((ret = ((unsigned char) tolower (*s1)
66 - (unsigned char) tolower (*s2))) != 0)
67 break;
68 ++s1;
69 ++s2;
71 return ret;
74 static int
75 check_result (impl_t *impl, const char *s1, const char *s2, size_t n,
76 int exp_result)
78 int result = CALL (impl, s1, s2, n);
79 if ((exp_result == 0 && result != 0)
80 || (exp_result < 0 && result >= 0)
81 || (exp_result > 0 && result <= 0))
83 error (0, 0, "Wrong result in function %s %d %d", impl->name,
84 result, exp_result);
85 ret = 1;
86 return -1;
89 return 0;
92 static void
93 do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n,
94 int exp_result)
96 if (check_result (impl, s1, s2, n, exp_result) < 0)
97 return;
100 static void
101 do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char,
102 int exp_result)
104 size_t i;
105 char *s1, *s2;
107 if (len == 0)
108 return;
110 align1 &= 7;
111 if (align1 + len + 1 >= page_size)
112 return;
114 align2 &= 7;
115 if (align2 + len + 1 >= page_size)
116 return;
118 s1 = (char *) (buf1 + align1);
119 s2 = (char *) (buf2 + align2);
121 for (i = 0; i < len; i++)
123 s1[i] = toupper (1 + 23 * i % max_char);
124 s2[i] = tolower (s1[i]);
127 s1[len] = s2[len] = 0;
128 s1[len + 1] = 23;
129 s2[len + 1] = 24 + exp_result;
130 if ((s2[len - 1] == 'z' && exp_result == -1)
131 || (s2[len - 1] == 'a' && exp_result == 1))
132 s1[len - 1] += exp_result;
133 else
134 s2[len - 1] -= exp_result;
136 FOR_EACH_IMPL (impl, 0)
137 do_one_test (impl, s1, s2, n, exp_result);
140 static void
141 do_page_tests (void)
143 char *s1, *s2;
144 int exp_result;
145 const size_t maxoffset = 64;
147 s1 = (char *) buf1 + BUF1PAGES * page_size - maxoffset;
148 memset (s1, 'a', maxoffset - 1);
149 s1[maxoffset - 1] = '\0';
151 s2 = (char *) buf2 + page_size - maxoffset;
152 memset (s2, 'a', maxoffset - 1);
153 s2[maxoffset - 1] = '\0';
155 /* At this point s1 and s2 point to distinct memory regions containing
156 "aa..." with size of 63 plus '\0'. Also, both strings are bounded to a
157 page with read/write access and the next page is protected with PROT_NONE
158 (meaning that any access outside of the page regions will trigger an
159 invalid memory access).
161 The loop checks for all possible offsets up to maxoffset for both
162 inputs with a size larger than the string (so memory access outside
163 the expected memory regions might trigger invalid access). */
165 for (size_t off1 = 0; off1 < maxoffset; off1++)
167 for (size_t off2 = 0; off2 < maxoffset; off2++)
169 exp_result = (off1 == off2)
171 : off1 < off2
172 ? 'a'
173 : -'a';
175 FOR_EACH_IMPL (impl, 0)
176 check_result (impl, s1 + off1, s2 + off2, maxoffset + 1,
177 exp_result);
182 static void
183 do_random_tests (void)
185 size_t i, j, n, align1, align2, pos, len1, len2;
186 int result;
187 long r;
188 unsigned char *p1 = buf1 + page_size - 512;
189 unsigned char *p2 = buf2 + page_size - 512;
191 for (n = 0; n < ITERATIONS; n++)
193 align1 = random () & 31;
194 if (random () & 1)
195 align2 = random () & 31;
196 else
197 align2 = align1 + (random () & 24);
198 pos = random () & 511;
199 j = align1 > align2 ? align1 : align2;
200 if (pos + j >= 511)
201 pos = 510 - j - (random () & 7);
202 len1 = random () & 511;
203 if (pos >= len1 && (random () & 1))
204 len1 = pos + (random () & 7);
205 if (len1 + j >= 512)
206 len1 = 511 - j - (random () & 7);
207 if (pos >= len1)
208 len2 = len1;
209 else
210 len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0);
211 j = (pos > len2 ? pos : len2) + align1 + 64;
212 if (j > 512)
213 j = 512;
214 for (i = 0; i < j; ++i)
216 p1[i] = tolower (random () & 255);
217 if (i < len1 + align1 && !p1[i])
219 p1[i] = tolower (random () & 255);
220 if (!p1[i])
221 p1[i] = tolower (1 + (random () & 127));
224 for (i = 0; i < j; ++i)
226 p2[i] = toupper (random () & 255);
227 if (i < len2 + align2 && !p2[i])
229 p2[i] = toupper (random () & 255);
230 if (!p2[i])
231 toupper (p2[i] = 1 + (random () & 127));
235 result = 0;
236 memcpy (p2 + align2, p1 + align1, pos);
237 if (pos < len1)
239 if (tolower (p2[align2 + pos]) == p1[align1 + pos])
241 p2[align2 + pos] = toupper (random () & 255);
242 if (tolower (p2[align2 + pos]) == p1[align1 + pos])
243 p2[align2 + pos] = toupper (p1[align1 + pos]
244 + 3 + (random () & 127));
247 if (p1[align1 + pos] < tolower (p2[align2 + pos]))
248 result = -1;
249 else
250 result = 1;
252 p1[len1 + align1] = 0;
253 p2[len2 + align2] = 0;
255 FOR_EACH_IMPL (impl, 1)
257 r = CALL (impl, (char *) (p1 + align1), (char *) (p2 + align2),
258 pos + 1 + (random () & 255));
259 /* Test whether on 64-bit architectures where ABI requires
260 callee to promote has the promotion been done. */
261 asm ("" : "=g" (r) : "0" (r));
262 if ((r == 0 && result)
263 || (r < 0 && result >= 0)
264 || (r > 0 && result <= 0))
266 error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd) %ld != %d, p1 %p p2 %p",
267 n, impl->name, align1, align2, len1, len2, pos, r, result, p1, p2);
268 ret = 1;
274 /* Regression test for BZ #12205 */
275 static void
276 bz12205 (void)
278 static char cp [4096+16] __attribute__ ((aligned(4096)));
279 static char gotrel[4096] __attribute__ ((aligned(4096)));
280 char *s1 = cp + 0xffa;
281 char *s2 = gotrel + 0xcbe;
282 int exp_result;
283 size_t n = 6;
285 strcpy (s1, "gottpoff");
286 strcpy (s2, "GOTPLT");
288 exp_result = simple_strncasecmp (s1, s2, n);
289 FOR_EACH_IMPL (impl, 0)
290 check_result (impl, s1, s2, n, exp_result);
293 /* Regression test for BZ #14195 */
294 static void
295 bz14195 (void)
297 const char *empty_string = "";
298 FOR_EACH_IMPL (impl, 0)
299 check_result (impl, empty_string, "", 5, 0);
302 static void
303 test_locale (const char *locale)
305 size_t i;
307 if (setlocale (LC_CTYPE, locale) == NULL)
309 error (0, 0, "cannot set locale \"%s\"", locale);
310 ret = 1;
313 bz12205 ();
314 bz14195 ();
316 printf ("%23s", locale);
317 FOR_EACH_IMPL (impl, 0)
318 printf ("\t%s", impl->name);
319 putchar ('\n');
321 for (i = 1; i < 16; ++i)
323 do_test (i, i, i - 1, i, 127, 0);
325 do_test (i, i, i, i, 127, 0);
326 do_test (i, i, i, i, 127, 1);
327 do_test (i, i, i, i, 127, -1);
329 do_test (i, i, i + 1, i, 127, 0);
330 do_test (i, i, i + 1, i, 127, 1);
331 do_test (i, i, i + 1, i, 127, -1);
334 for (i = 1; i < 10; ++i)
336 do_test (0, 0, (2 << i) - 1, 2 << i, 127, 0);
337 do_test (0, 0, 2 << i, 2 << i, 254, 0);
338 do_test (0, 0, (2 << i) + 1, 2 << i, 127, 0);
340 do_test (0, 0, (2 << i) + 1, 2 << i, 254, 0);
342 do_test (0, 0, 2 << i, 2 << i, 127, 1);
343 do_test (0, 0, (2 << i) + 10, 2 << i, 127, 1);
345 do_test (0, 0, 2 << i, 2 << i, 254, 1);
346 do_test (0, 0, (2 << i) + 10, 2 << i, 254, 1);
348 do_test (0, 0, 2 << i, 2 << i, 127, -1);
349 do_test (0, 0, (2 << i) + 10, 2 << i, 127, -1);
351 do_test (0, 0, 2 << i, 2 << i, 254, -1);
352 do_test (0, 0, (2 << i) + 10, 2 << i, 254, -1);
355 for (i = 1; i < 8; ++i)
357 do_test (i, 2 * i, (8 << i) - 1, 8 << i, 127, 0);
358 do_test (i, 2 * i, 8 << i, 8 << i, 127, 0);
359 do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 0);
361 do_test (2 * i, i, (8 << i) - 1, 8 << i, 254, 0);
362 do_test (2 * i, i, 8 << i, 8 << i, 254, 0);
363 do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 0);
365 do_test (i, 2 * i, 8 << i, 8 << i, 127, 1);
366 do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 1);
368 do_test (2 * i, i, 8 << i, 8 << i, 254, 1);
369 do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 1);
371 do_test (i, 2 * i, 8 << i, 8 << i, 127, -1);
372 do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, -1);
374 do_test (2 * i, i, 8 << i, 8 << i, 254, -1);
375 do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, -1);
378 do_random_tests ();
379 do_page_tests ();
383 test_main (void)
385 test_init ();
387 test_locale ("C");
388 test_locale ("en_US.ISO-8859-1");
389 test_locale ("en_US.UTF-8");
390 test_locale ("tr_TR.ISO-8859-9");
391 test_locale ("tr_TR.UTF-8");
393 return ret;
396 #include <support/test-driver.c>