elf: Add a way to check if tunable is set (BZ 27069)
[glibc.git] / string / test-strrchr.c
blobc979574c927a20c9156f4e28bcfc464ec21c22bd
1 /* Test and measure STRCHR functions.
2 Copyright (C) 1999-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library 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
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #define TEST_MAIN
20 #ifdef WIDE
21 # define TEST_NAME "wcsrchr"
22 #else
23 # define TEST_NAME "strrchr"
24 #endif
25 #include "test-string.h"
27 #ifdef WIDE
28 # include <wchar.h>
29 # define STRRCHR wcsrchr
30 # define CHAR wchar_t
31 # define UCHAR wchar_t
32 # define BIG_CHAR WCHAR_MAX
33 # define SMALL_CHAR 1273
34 #else
35 # define STRRCHR strrchr
36 # define CHAR char
37 # define UCHAR unsigned char
38 # define BIG_CHAR CHAR_MAX
39 # define SMALL_CHAR 127
40 #endif
42 typedef CHAR *(*proto_t) (const CHAR *, int);
44 IMPL (STRRCHR, 1)
46 /* Also check the generic implementation. */
47 #undef STRRCHR
48 #undef weak_alias
49 #define weak_alias(a, b)
50 #undef libc_hidden_builtin_def
51 #define libc_hidden_builtin_def(a)
52 #undef libc_hidden_def
53 #define libc_hidden_def(a)
54 #undef libc_hidden_weak
55 #define libc_hidden_weak(a)
56 #ifndef WIDE
57 # define STRLEN __strlen_default
58 # include "string/strlen.c"
59 # define MEMRCHR __memrchr_default
60 # include "string/memrchr.c"
61 # define STRRCHR __strrchr_default
62 # include "string/strrchr.c"
63 # define STRRCHR_DEFAULT __strrchr_default
64 #else
65 # define WCSRCHR __wcsrchr_default
66 # include "wcsmbs/wcsrchr.c"
67 # define STRRCHR_DEFAULT __wcsrchr_default
68 #endif
69 IMPL (STRRCHR_DEFAULT, 1)
71 static void
72 do_one_test (impl_t *impl, const CHAR *s, int c, CHAR *exp_res)
74 CHAR *res = CALL (impl, s, c);
75 if (res != exp_res)
77 error (0, 0, "Wrong result in function %s %p %p", impl->name,
78 res, exp_res);
79 ret = 1;
80 return;
84 static void
85 do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
86 /* For wcsrchr: align here means align not in bytes,
87 but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
88 len for wcschr here isn't in bytes but it's number of wchar_t symbols. */
90 size_t i;
91 CHAR *result;
92 CHAR *buf = (CHAR *) buf1;
94 align &= 7;
95 if ( (align + len) * sizeof (CHAR) >= page_size)
96 return;
98 for (i = 0; i < len; ++i)
100 buf[align + i] = (random () * random ()) & max_char;
101 if (!buf[align + i])
102 buf[align + i] = (random () * random ()) & max_char;
103 if (!buf[align + i])
104 buf[align + i] = 1;
105 if ((i > pos || pos >= len) && buf[align + i] == seek_char)
106 buf[align + i] = seek_char + 10 + (random () & 15);
108 buf[align + len] = 0;
110 if (pos < len)
112 buf[align + pos] = seek_char;
113 result = (CHAR *) (buf + align + pos);
115 else if (seek_char == 0)
116 result = (CHAR *) (buf + align + len);
117 else
118 result = NULL;
120 FOR_EACH_IMPL (impl, 0)
121 do_one_test (impl, (CHAR *) (buf + align), seek_char, result);
124 static void
125 do_random_tests (void)
127 size_t i, j, n, align, pos, len;
128 int seek_char;
129 CHAR *result;
130 UCHAR *p = (UCHAR *) (buf1 + page_size) - 512;
132 for (n = 0; n < ITERATIONS; n++)
134 align = random () & (63 / sizeof (CHAR));
135 /* For wcsrchr: align here means align not in bytes, but in wchar_ts,
136 in bytes it will equal to align * (sizeof (wchar_t)).
137 For strrchr we need to check all alignments from 0 to 63 since
138 some assembly implementations have separate prolog for alignments
139 more 48. */
140 pos = random () & 511;
141 if (pos + align >= 511)
142 pos = 510 - align - (random () & 7);
143 len = random () & 511;
144 /* len for wcschr here isn't in bytes but it's number of wchar_t
145 symbols. */
146 if (pos >= len)
147 len = pos + (random () & 7);
148 if (len + align >= 512)
149 len = 511 - align - (random () & 7);
150 seek_char = random () & 255;
151 if (seek_char && pos == len)
153 if (pos)
154 --pos;
155 else
156 ++len;
158 j = len + align + 64;
159 if (j > 512)
160 j = 512;
162 for (i = 0; i < j; i++)
164 if (i == pos + align)
165 p[i] = seek_char;
166 else if (i == len + align)
167 p[i] = 0;
168 else
170 p[i] = random () & 255;
171 if (((i > pos + align && i < len + align) || pos > len)
172 && p[i] == seek_char)
173 p[i] = seek_char + 13;
174 if (i < len + align && !p[i])
176 p[i] = seek_char - 13;
177 if (!p[i])
178 p[i] = 140;
183 if (pos <= len)
184 result = (CHAR *) (p + pos + align);
185 else if (seek_char == 0)
186 result = (CHAR *) (p + len + align);
187 else
188 result = NULL;
190 FOR_EACH_IMPL (impl, 1)
191 if (CALL (impl, (CHAR *) (p + align), seek_char) != result)
193 error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
194 n, impl->name, align, seek_char, len, pos,
195 CALL (impl, (CHAR *) (p + align), seek_char), result, p);
196 ret = 1;
202 test_main (void)
204 size_t i;
206 test_init ();
208 printf ("%20s", "");
209 FOR_EACH_IMPL (impl, 0)
210 printf ("\t%s", impl->name);
211 putchar ('\n');
213 for (i = 1; i < 8; ++i)
215 do_test (0, 16 << i, 2048, 23, SMALL_CHAR);
216 do_test (i, 16 << i, 2048, 23, SMALL_CHAR);
219 for (i = 1; i < 8; ++i)
221 do_test (i, 64, 256, 23, SMALL_CHAR);
222 do_test (i, 64, 256, 23, BIG_CHAR);
225 for (i = 0; i < 32; ++i)
227 do_test (0, i, i + 1, 23, SMALL_CHAR);
228 do_test (0, i, i + 1, 23, BIG_CHAR);
231 for (i = 1; i < 8; ++i)
233 do_test (0, 16 << i, 2048, 0, SMALL_CHAR);
234 do_test (i, 16 << i, 2048, 0, SMALL_CHAR);
237 for (i = 1; i < 8; ++i)
239 do_test (i, 64, 256, 0, SMALL_CHAR);
240 do_test (i, 64, 256, 0, BIG_CHAR);
243 for (i = 0; i < 32; ++i)
245 do_test (0, i, i + 1, 0, SMALL_CHAR);
246 do_test (0, i, i + 1, 0, BIG_CHAR);
249 do_random_tests ();
250 return ret;
253 #include <support/test-driver.c>