1 /* Test STRCHR 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.
5 Added wcschr support by Liubov Dmitrieva <liubov.dmitrieva@gmail.com>, 2011
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, see
19 <https://www.gnu.org/licenses/>. */
23 # ifdef USE_FOR_STRCHRNUL
24 # define TEST_NAME "strchrnul"
26 # define TEST_NAME "strchr"
27 # endif /* !USE_FOR_STRCHRNUL */
29 # ifdef USE_FOR_STRCHRNUL
30 # define TEST_NAME "wcschrnul"
32 # define TEST_NAME "wcschr"
33 # endif /* !USE_FOR_STRCHRNUL */
35 #include "test-string.h"
38 # ifdef USE_FOR_STRCHRNUL
39 # define STRCHR strchrnul
40 # define stupid_STRCHR stupid_STRCHRNUL
41 # define simple_STRCHR simple_STRCHRNUL
43 # define STRCHR strchr
44 # endif /* !USE_FOR_STRCHRNUL */
45 # define STRLEN strlen
47 # define BIG_CHAR CHAR_MAX
48 # define MIDDLE_CHAR 127
49 # define SMALL_CHAR 23
50 # define UCHAR unsigned char
54 # ifdef USE_FOR_STRCHRNUL
55 # define STRCHR wcschrnul
56 # define stupid_STRCHR stupid_WCSCHRNUL
57 # define simple_STRCHR simple_WCSCHRNUL
59 # define STRCHR wcschr
60 # endif /* !USE_FOR_STRCHRNUL */
61 # define STRLEN wcslen
63 # define BIG_CHAR WCHAR_MAX
64 # define MIDDLE_CHAR 1121
65 # define SMALL_CHAR 851
66 # define UCHAR wchar_t
70 #ifdef USE_FOR_STRCHRNUL
71 # define NULLRET(endptr) endptr
73 # define NULLRET(endptr) NULL
74 #endif /* !USE_FOR_STRCHRNUL */
77 typedef CHAR
*(*proto_t
) (const CHAR
*, int);
80 simple_STRCHR (const CHAR
*s
, int c
)
82 for (; *s
!= (CHAR
) c
; ++s
)
84 return NULLRET ((CHAR
*) s
);
89 stupid_STRCHR (const CHAR
*s
, int c
)
91 size_t n
= STRLEN (s
) + 1;
95 return (CHAR
*) s
- 1;
96 return NULLRET ((CHAR
*) s
- 1);
99 IMPL (stupid_STRCHR
, 0)
100 IMPL (simple_STRCHR
, 0)
104 check_result (impl_t
*impl
, const CHAR
*s
, int c
, const CHAR
*exp_res
)
106 CHAR
*res
= CALL (impl
, s
, c
);
109 error (0, 0, "Wrong result in function %s %#x %p %p", impl
->name
,
118 do_one_test (impl_t
*impl
, const CHAR
*s
, int c
, const CHAR
*exp_res
)
120 if (check_result (impl
, s
, c
, exp_res
) < 0)
125 do_test (size_t align
, size_t pos
, size_t len
, int seek_char
, int max_char
)
126 /* For wcschr: align here means align not in bytes,
127 but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
128 len for wcschr here isn't in bytes but it's number of wchar_t symbols. */
132 CHAR
*buf
= (CHAR
*) buf1
;
134 if ((align
+ len
) * sizeof (CHAR
) >= page_size
)
137 for (i
= 0; i
< len
; ++i
)
139 buf
[align
+ i
] = 32 + 23 * i
% max_char
;
140 if (buf
[align
+ i
] == seek_char
)
141 buf
[align
+ i
] = seek_char
+ 1;
142 else if (buf
[align
+ i
] == 0)
145 buf
[align
+ len
] = 0;
149 buf
[align
+ pos
] = seek_char
;
150 result
= buf
+ align
+ pos
;
152 else if (seek_char
== 0)
153 result
= buf
+ align
+ len
;
155 result
= NULLRET (buf
+ align
+ len
);
157 FOR_EACH_IMPL (impl
, 0)
158 do_one_test (impl
, buf
+ align
, seek_char
, result
);
162 do_random_tests (void)
164 size_t i
, j
, n
, align
, pos
, len
;
167 UCHAR
*p
= (UCHAR
*) (buf1
+ page_size
- 512 * sizeof (CHAR
));
169 for (n
= 0; n
< ITERATIONS
; n
++)
171 /* For wcschr: align here means align not in bytes, but in wchar_ts,
172 in bytes it will equal to align * (sizeof (wchar_t)). */
173 align
= random () & 15;
174 pos
= random () & 511;
175 seek_char
= random () & 255;
176 if (pos
+ align
>= 511)
177 pos
= 510 - align
- (random () & 7);
178 /* len for wcschr here isn't in bytes but it's number of wchar_t
180 len
= random () & 511;
181 if ((pos
== len
&& seek_char
)
182 || (pos
> len
&& (random () & 1)))
183 len
= pos
+ 1 + (random () & 7);
184 if (len
+ align
>= 512)
185 len
= 511 - align
- (random () & 7);
186 if (pos
== len
&& seek_char
)
188 j
= (pos
> len
? pos
: len
) + align
+ 64;
192 for (i
= 0; i
< j
; i
++)
194 if (i
== pos
+ align
)
196 else if (i
== len
+ align
)
200 p
[i
] = random () & 255;
201 if (i
< pos
+ align
&& p
[i
] == seek_char
)
202 p
[i
] = seek_char
+ 13;
203 if (i
< len
+ align
&& !p
[i
])
205 p
[i
] = seek_char
- 13;
213 result
= (CHAR
*) (p
+ pos
+ align
);
214 else if (seek_char
== 0)
215 result
= (CHAR
*) (p
+ len
+ align
);
217 result
= NULLRET ((CHAR
*) (p
+ len
+ align
));
219 FOR_EACH_IMPL (impl
, 1)
220 if (CALL (impl
, (CHAR
*) (p
+ align
), seek_char
) != result
)
222 error (0, 0, "Iteration %zd - wrong result in function \
223 %s (align in bytes: %zd, seek_char: %d, len: %zd, pos: %zd) %p != %p, p %p",
224 n
, impl
->name
, align
* sizeof (CHAR
), seek_char
, len
, pos
,
225 CALL (impl
, (CHAR
*) (p
+ align
), seek_char
), result
, p
);
234 CHAR s
[] __attribute__((aligned(16))) = L ("\xff");
236 CHAR
*exp_result
= stupid_STRCHR (s
, c
);
238 FOR_EACH_IMPL (impl
, 0)
239 check_result (impl
, s
, c
, exp_result
);
252 FOR_EACH_IMPL (impl
, 0)
253 printf ("\t%s", impl
->name
);
256 for (i
= 1; i
< 8; ++i
)
258 do_test (0, 16 << i
, 2048, SMALL_CHAR
, MIDDLE_CHAR
);
259 do_test (i
, 16 << i
, 2048, SMALL_CHAR
, MIDDLE_CHAR
);
262 for (i
= 1; i
< 8; ++i
)
264 do_test (0, 16 << i
, 4096, SMALL_CHAR
, MIDDLE_CHAR
);
265 do_test (i
, 16 << i
, 4096, SMALL_CHAR
, MIDDLE_CHAR
);
268 for (i
= 1; i
< 8; ++i
)
270 do_test (i
, 64, 256, SMALL_CHAR
, MIDDLE_CHAR
);
271 do_test (i
, 64, 256, SMALL_CHAR
, BIG_CHAR
);
274 for (i
= 0; i
< 8; ++i
)
276 do_test (16 * i
, 256, 512, SMALL_CHAR
, MIDDLE_CHAR
);
277 do_test (16 * i
, 256, 512, SMALL_CHAR
, BIG_CHAR
);
280 for (i
= 0; i
< 32; ++i
)
282 do_test (0, i
, i
+ 1, SMALL_CHAR
, MIDDLE_CHAR
);
283 do_test (0, i
, i
+ 1, SMALL_CHAR
, BIG_CHAR
);
286 for (i
= 1; i
< 8; ++i
)
288 do_test (0, 16 << i
, 2048, 0, MIDDLE_CHAR
);
289 do_test (i
, 16 << i
, 2048, 0, MIDDLE_CHAR
);
292 for (i
= 1; i
< 8; ++i
)
294 do_test (0, 16 << i
, 4096, 0, MIDDLE_CHAR
);
295 do_test (i
, 16 << i
, 4096, 0, MIDDLE_CHAR
);
298 for (i
= 1; i
< 8; ++i
)
300 do_test (i
, 64, 256, 0, MIDDLE_CHAR
);
301 do_test (i
, 64, 256, 0, BIG_CHAR
);
304 for (i
= 0; i
< 8; ++i
)
306 do_test (16 * i
, 256, 512, 0, MIDDLE_CHAR
);
307 do_test (16 * i
, 256, 512, 0, BIG_CHAR
);
310 for (i
= 0; i
< 32; ++i
)
312 do_test (0, i
, i
+ 1, 0, MIDDLE_CHAR
);
313 do_test (0, i
, i
+ 1, 0, BIG_CHAR
);
320 #include <support/test-driver.c>