]>
Commit | Line | Data |
---|---|---|
2c6fe0bd | 1 | /* Test for string function add boundaries of usable memory. |
688903eb | 2 | Copyright (C) 1996-2018 Free Software Foundation, Inc. |
2c6fe0bd UD |
3 | This file is part of the GNU C Library. |
4 | Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. | |
5 | ||
6 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
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. | |
2c6fe0bd UD |
10 | |
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 | |
41bdb6e2 | 14 | Lesser General Public License for more details. |
2c6fe0bd | 15 | |
41bdb6e2 | 16 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
17 | License along with the GNU C Library; if not, see |
18 | <http://www.gnu.org/licenses/>. */ | |
2c6fe0bd | 19 | |
46ec036d | 20 | #define _GNU_SOURCE 1 |
9a0a462c UD |
21 | |
22 | /* Make sure we don't test the optimized inline functions if we want to | |
23 | test the real implementation. */ | |
24 | #undef __USE_STRING_INLINES | |
25 | ||
46ec036d UD |
26 | #include <errno.h> |
27 | #include <stdio.h> | |
28 | #include <string.h> | |
29 | #include <unistd.h> | |
30 | #include <sys/mman.h> | |
31 | #include <sys/param.h> | |
32 | ||
9cc198f6 UD |
33 | #ifndef CHAR |
34 | # define L(c) c | |
35 | # define CHAR char | |
36 | # define MEMSET memset | |
37 | # define STRLEN strlen | |
38 | # define STRNLEN strnlen | |
39 | # define STRCHR strchr | |
40 | # define STRRCHR strrchr | |
41 | # define STRCPY strcpy | |
42 | # define STRNCPY strncpy | |
43 | # define MEMCMP memcmp | |
44 | # define STPCPY stpcpy | |
45 | # define STPNCPY stpncpy | |
46 | # define MEMCPY memcpy | |
47 | # define MEMPCPY mempcpy | |
ddba0f17 | 48 | # define MEMCHR memchr |
45db99c7 UD |
49 | # define STRCMP strcmp |
50 | # define STRNCMP strncmp | |
46ec036d UD |
51 | #endif |
52 | ||
9cc198f6 UD |
53 | |
54 | #define STRINGIFY(s) STRINGIFY2 (s) | |
55 | #define STRINGIFY2(s) #s | |
56 | ||
57 | ||
fb82116f | 58 | int |
9cc198f6 | 59 | do_test (void) |
46ec036d | 60 | { |
376b40a2 L |
61 | size_t size = sysconf (_SC_PAGESIZE); |
62 | size_t nchars = size / sizeof (CHAR); | |
9cc198f6 UD |
63 | CHAR *adr; |
64 | CHAR *dest; | |
46ec036d UD |
65 | int result = 0; |
66 | ||
9cc198f6 | 67 | adr = (CHAR *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE, |
76e680a8 | 68 | MAP_PRIVATE | MAP_ANON, -1, 0); |
9cc198f6 | 69 | dest = (CHAR *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE, |
76e680a8 | 70 | MAP_PRIVATE | MAP_ANON, -1, 0); |
0413b54c | 71 | if (adr == MAP_FAILED || dest == MAP_FAILED) |
46ec036d UD |
72 | { |
73 | if (errno == ENOSYS) | |
45db99c7 | 74 | puts ("No test, mmap not available."); |
46ec036d | 75 | else |
45db99c7 UD |
76 | { |
77 | printf ("mmap failed: %m"); | |
78 | result = 1; | |
79 | } | |
46ec036d UD |
80 | } |
81 | else | |
82 | { | |
376b40a2 L |
83 | size_t inner, middle, outer, nchars64, max128; |
84 | ||
85 | if (nchars > 64) | |
86 | nchars64 = nchars - 64; | |
87 | else | |
88 | nchars64 = 0; | |
89 | ||
90 | if (nchars > 128) | |
91 | max128 = nchars - 128; | |
92 | else | |
93 | max128 = 0; | |
46ec036d | 94 | |
9cc198f6 UD |
95 | mprotect (adr, size, PROT_NONE); |
96 | mprotect (adr + 2 * nchars, size, PROT_NONE); | |
97 | adr += nchars; | |
ba1ffaa1 | 98 | |
9cc198f6 UD |
99 | mprotect (dest, size, PROT_NONE); |
100 | mprotect (dest + 2 * nchars, size, PROT_NONE); | |
101 | dest += nchars; | |
ba1ffaa1 | 102 | |
9cc198f6 | 103 | MEMSET (adr, L('T'), nchars); |
46ec036d | 104 | |
9cc198f6 | 105 | /* strlen/wcslen test */ |
376b40a2 | 106 | for (outer = nchars - 1; outer >= max128; --outer) |
45db99c7 | 107 | { |
376b40a2 | 108 | for (inner = MAX (outer, nchars64); inner < nchars; ++inner) |
46ec036d | 109 | { |
9cc198f6 | 110 | adr[inner] = L('\0'); |
46ec036d | 111 | |
9cc198f6 | 112 | if (STRLEN (&adr[outer]) != (size_t) (inner - outer)) |
46ec036d | 113 | { |
376b40a2 | 114 | printf ("%s flunked for outer = %zu, inner = %zu\n", |
9cc198f6 | 115 | STRINGIFY (STRLEN), outer, inner); |
46ec036d UD |
116 | result = 1; |
117 | } | |
118 | ||
9cc198f6 | 119 | adr[inner] = L('T'); |
46ec036d | 120 | } |
376b40a2 L |
121 | if (outer == 0) |
122 | break; | |
45db99c7 | 123 | } |
46ec036d | 124 | |
9cc198f6 | 125 | /* strnlen/wcsnlen test */ |
376b40a2 | 126 | for (outer = nchars; outer >= max128; --outer) |
45db99c7 | 127 | { |
376b40a2 | 128 | for (inner = MAX (outer, nchars64); inner < nchars; ++inner) |
46ec036d | 129 | { |
9cc198f6 UD |
130 | adr[inner] = L('\0'); |
131 | ||
132 | if (STRNLEN (&adr[outer], inner - outer + 1) | |
133 | != (size_t) (inner - outer)) | |
46ec036d | 134 | { |
376b40a2 | 135 | printf ("%s flunked for outer = %zu, inner = %zu\n", |
9cc198f6 UD |
136 | STRINGIFY (STRNLEN), outer, inner); |
137 | result = 1; | |
138 | } | |
46ec036d | 139 | |
9cc198f6 UD |
140 | adr[inner] = L('T'); |
141 | } | |
376b40a2 L |
142 | if (outer == 0) |
143 | break; | |
45db99c7 | 144 | } |
376b40a2 | 145 | for (outer = nchars; outer >= max128; --outer) |
45db99c7 | 146 | { |
376b40a2 | 147 | for (inner = MAX (outer, nchars64); inner <= nchars; ++inner) |
9cc198f6 | 148 | { |
15417de3 UD |
149 | if (STRNLEN (&adr[outer], inner - outer) |
150 | != (size_t) (inner - outer)) | |
9cc198f6 | 151 | { |
376b40a2 | 152 | printf ("%s flunked bounded for outer = %zu, inner = %zu\n", |
9cc198f6 UD |
153 | STRINGIFY (STRNLEN), outer, inner); |
154 | result = 1; | |
155 | } | |
156 | } | |
376b40a2 L |
157 | if (outer == 0) |
158 | break; | |
45db99c7 | 159 | } |
9cc198f6 UD |
160 | |
161 | /* strchr/wcschr test */ | |
376b40a2 | 162 | for (outer = nchars - 1; outer >= max128; --outer) |
45db99c7 | 163 | { |
376b40a2 | 164 | for (middle = MAX (outer, nchars64); middle < nchars; ++middle) |
9cc198f6 UD |
165 | { |
166 | for (inner = middle; inner < nchars; ++inner) | |
167 | { | |
168 | adr[middle] = L('V'); | |
169 | adr[inner] = L('\0'); | |
170 | ||
171 | CHAR *cp = STRCHR (&adr[outer], L('V')); | |
46ec036d UD |
172 | |
173 | if ((inner == middle && cp != NULL) | |
174 | || (inner != middle | |
175 | && (cp - &adr[outer]) != middle - outer)) | |
176 | { | |
376b40a2 L |
177 | printf ("%s flunked for outer = %zu, middle = %zu, " |
178 | "inner = %zu\n", | |
9cc198f6 | 179 | STRINGIFY (STRCHR), outer, middle, inner); |
46ec036d UD |
180 | result = 1; |
181 | } | |
182 | ||
9cc198f6 UD |
183 | adr[inner] = L('T'); |
184 | adr[middle] = L('T'); | |
46ec036d UD |
185 | } |
186 | } | |
376b40a2 L |
187 | if (outer == 0) |
188 | break; | |
45db99c7 | 189 | } |
46ec036d | 190 | |
76e680a8 | 191 | /* Special test. */ |
9cc198f6 UD |
192 | adr[nchars - 1] = L('\0'); |
193 | if (STRCHR (&adr[nchars - 1], L('\n')) != NULL) | |
76e680a8 | 194 | { |
9cc198f6 UD |
195 | printf ("%s flunked test of empty string at end of page\n", |
196 | STRINGIFY (STRCHR)); | |
76e680a8 UD |
197 | result = 1; |
198 | } | |
199 | ||
9cc198f6 | 200 | /* strrchr/wcsrchr test */ |
376b40a2 | 201 | for (outer = nchars - 1; outer >= max128; --outer) |
45db99c7 | 202 | { |
376b40a2 | 203 | for (middle = MAX (outer, nchars64); middle < nchars; ++middle) |
46ec036d | 204 | { |
9cc198f6 | 205 | for (inner = middle; inner < nchars; ++inner) |
46ec036d | 206 | { |
9cc198f6 UD |
207 | adr[middle] = L('V'); |
208 | adr[inner] = L('\0'); | |
46ec036d | 209 | |
9cc198f6 | 210 | CHAR *cp = STRRCHR (&adr[outer], L('V')); |
46ec036d UD |
211 | |
212 | if ((inner == middle && cp != NULL) | |
213 | || (inner != middle | |
214 | && (cp - &adr[outer]) != middle - outer)) | |
215 | { | |
376b40a2 L |
216 | printf ("%s flunked for outer = %zu, middle = %zu, " |
217 | "inner = %zu\n", | |
9cc198f6 | 218 | STRINGIFY (STRRCHR), outer, middle, inner); |
46ec036d UD |
219 | result = 1; |
220 | } | |
221 | ||
9cc198f6 UD |
222 | adr[inner] = L('T'); |
223 | adr[middle] = L('T'); | |
46ec036d UD |
224 | } |
225 | } | |
376b40a2 L |
226 | if (outer == 0) |
227 | break; | |
45db99c7 | 228 | } |
46ec036d | 229 | |
ddba0f17 | 230 | /* memchr test */ |
376b40a2 | 231 | for (outer = nchars - 1; outer >= max128; --outer) |
45db99c7 | 232 | { |
376b40a2 | 233 | for (middle = MAX (outer, nchars64); middle < nchars; ++middle) |
ddba0f17 UD |
234 | { |
235 | adr[middle] = L('V'); | |
236 | ||
237 | CHAR *cp = MEMCHR (&adr[outer], L('V'), 3 * size); | |
238 | ||
239 | if (cp - &adr[outer] != middle - outer) | |
240 | { | |
376b40a2 | 241 | printf ("%s flunked for outer = %zu, middle = %zu\n", |
ddba0f17 UD |
242 | STRINGIFY (MEMCHR), outer, middle); |
243 | result = 1; | |
244 | } | |
245 | ||
246 | adr[middle] = L('T'); | |
247 | } | |
376b40a2 L |
248 | if (outer == 0) |
249 | break; | |
45db99c7 | 250 | } |
376b40a2 | 251 | for (outer = nchars; outer >= max128; --outer) |
45db99c7 | 252 | { |
ddba0f17 UD |
253 | CHAR *cp = MEMCHR (&adr[outer], L('V'), nchars - outer); |
254 | ||
255 | if (cp != NULL) | |
256 | { | |
376b40a2 | 257 | printf ("%s flunked for outer = %zu\n", |
ddba0f17 UD |
258 | STRINGIFY (MEMCHR), outer); |
259 | result = 1; | |
260 | } | |
376b40a2 L |
261 | if (outer == 0) |
262 | break; | |
45db99c7 | 263 | } |
ddba0f17 | 264 | |
5298ffa8 | 265 | /* These functions only exist for single-byte characters. */ |
9cc198f6 | 266 | #ifndef WCSTEST |
d9163744 | 267 | /* rawmemchr test */ |
376b40a2 | 268 | for (outer = nchars - 1; outer >= max128; --outer) |
45db99c7 | 269 | { |
376b40a2 | 270 | for (middle = MAX (outer, nchars64); middle < nchars; ++middle) |
d9163744 | 271 | { |
9cc198f6 | 272 | adr[middle] = L('V'); |
d9163744 | 273 | |
9cc198f6 | 274 | CHAR *cp = rawmemchr (&adr[outer], L('V')); |
d9163744 UD |
275 | |
276 | if (cp - &adr[outer] != middle - outer) | |
277 | { | |
376b40a2 | 278 | printf ("%s flunked for outer = %zu, middle = %zu\n", |
9cc198f6 | 279 | STRINGIFY (rawmemchr), outer, middle); |
d9163744 UD |
280 | result = 1; |
281 | } | |
282 | ||
9cc198f6 | 283 | adr[middle] = L('T'); |
d9163744 | 284 | } |
376b40a2 L |
285 | if (outer == 0) |
286 | break; | |
45db99c7 | 287 | } |
5298ffa8 AS |
288 | |
289 | /* memrchr test */ | |
376b40a2 | 290 | for (outer = nchars - 1; outer >= max128; --outer) |
5298ffa8 | 291 | { |
376b40a2 | 292 | for (middle = MAX (outer, nchars64); middle < nchars; ++middle) |
5298ffa8 AS |
293 | { |
294 | adr[middle] = L('V'); | |
295 | ||
296 | CHAR *cp = memrchr (&adr[outer], L('V'), nchars - outer); | |
297 | ||
298 | if (cp - &adr[outer] != middle - outer) | |
299 | { | |
376b40a2 | 300 | printf ("%s flunked for outer = %zu, middle = %zu\n", |
5298ffa8 AS |
301 | STRINGIFY (memrchr), outer, middle); |
302 | result = 1; | |
303 | } | |
304 | ||
305 | adr[middle] = L('T'); | |
306 | } | |
376b40a2 L |
307 | if (outer == 0) |
308 | break; | |
5298ffa8 | 309 | } |
376b40a2 | 310 | for (outer = nchars; outer >= max128; --outer) |
5298ffa8 AS |
311 | { |
312 | CHAR *cp = memrchr (&adr[outer], L('V'), nchars - outer); | |
313 | ||
314 | if (cp != NULL) | |
315 | { | |
376b40a2 | 316 | printf ("%s flunked for outer = %zu\n", |
5298ffa8 AS |
317 | STRINGIFY (memrchr), outer); |
318 | result = 1; | |
319 | } | |
376b40a2 L |
320 | if (outer == 0) |
321 | break; | |
5298ffa8 | 322 | } |
9cc198f6 | 323 | #endif |
d9163744 | 324 | |
9cc198f6 | 325 | /* strcpy/wcscpy test */ |
376b40a2 | 326 | for (outer = nchars - 1; outer >= max128; --outer) |
45db99c7 | 327 | { |
376b40a2 | 328 | for (inner = MAX (outer, nchars64); inner < nchars; ++inner) |
46ec036d | 329 | { |
9cc198f6 | 330 | adr[inner] = L('\0'); |
46ec036d | 331 | |
9cc198f6 UD |
332 | if (STRCPY (dest, &adr[outer]) != dest |
333 | || STRLEN (dest) != (size_t) (inner - outer)) | |
46ec036d | 334 | { |
376b40a2 | 335 | printf ("%s flunked for outer = %zu, inner = %zu\n", |
9cc198f6 | 336 | STRINGIFY (STRCPY), outer, inner); |
46ec036d UD |
337 | result = 1; |
338 | } | |
339 | ||
9cc198f6 | 340 | adr[inner] = L('T'); |
46ec036d | 341 | } |
376b40a2 L |
342 | if (outer == 0) |
343 | break; | |
45db99c7 UD |
344 | } |
345 | ||
346 | /* strcmp/wcscmp tests */ | |
347 | for (outer = 1; outer < 32; ++outer) | |
348 | for (middle = 0; middle < 16; ++middle) | |
349 | { | |
350 | MEMSET (adr + middle, L('T'), 256); | |
351 | adr[256] = L('\0'); | |
352 | MEMSET (dest + nchars - outer, L('T'), outer - 1); | |
353 | dest[nchars - 1] = L('\0'); | |
354 | ||
355 | if (STRCMP (adr + middle, dest + nchars - outer) <= 0) | |
356 | { | |
376b40a2 | 357 | printf ("%s 1 flunked for outer = %zu, middle = %zu\n", |
45db99c7 UD |
358 | STRINGIFY (STRCMP), outer, middle); |
359 | result = 1; | |
360 | } | |
361 | ||
362 | if (STRCMP (dest + nchars - outer, adr + middle) >= 0) | |
363 | { | |
376b40a2 | 364 | printf ("%s 2 flunked for outer = %zu, middle = %zu\n", |
45db99c7 UD |
365 | STRINGIFY (STRCMP), outer, middle); |
366 | result = 1; | |
367 | } | |
368 | } | |
369 | ||
370 | /* strncmp/wcsncmp tests */ | |
371 | for (outer = 1; outer < 32; ++outer) | |
372 | for (middle = 0; middle < 16; ++middle) | |
373 | { | |
374 | MEMSET (adr + middle, L('T'), 256); | |
375 | adr[256] = L('\0'); | |
376 | MEMSET (dest + nchars - outer, L('T'), outer - 1); | |
377 | dest[nchars - 1] = L('U'); | |
378 | ||
379 | for (inner = 0; inner < outer; ++inner) | |
380 | { | |
381 | if (STRNCMP (adr + middle, dest + nchars - outer, inner) != 0) | |
382 | { | |
376b40a2 L |
383 | printf ("%s 1 flunked for outer = %zu, middle = %zu, " |
384 | "inner = %zu\n", | |
45db99c7 UD |
385 | STRINGIFY (STRNCMP), outer, middle, inner); |
386 | result = 1; | |
387 | } | |
388 | ||
389 | if (STRNCMP (dest + nchars - outer, adr + middle, inner) != 0) | |
390 | { | |
376b40a2 L |
391 | printf ("%s 2 flunked for outer = %zu, middle = %zu, " |
392 | "inner = %zu\n", | |
45db99c7 UD |
393 | STRINGIFY (STRNCMP), outer, middle, inner); |
394 | result = 1; | |
395 | } | |
396 | } | |
397 | ||
398 | if (STRNCMP (adr + middle, dest + nchars - outer, outer) >= 0) | |
399 | { | |
376b40a2 | 400 | printf ("%s 1 flunked for outer = %zu, middle = %zu, full\n", |
45db99c7 UD |
401 | STRINGIFY (STRNCMP), outer, middle); |
402 | result = 1; | |
403 | } | |
404 | ||
405 | if (STRNCMP (dest + nchars - outer, adr + middle, outer) <= 0) | |
406 | { | |
376b40a2 | 407 | printf ("%s 2 flunked for outer = %zu, middle = %zu, full\n", |
45db99c7 UD |
408 | STRINGIFY (STRNCMP), outer, middle); |
409 | result = 1; | |
410 | } | |
411 | } | |
46ec036d | 412 | |
15417de3 | 413 | /* strncpy/wcsncpy tests */ |
9cc198f6 | 414 | adr[nchars - 1] = L('T'); |
376b40a2 | 415 | for (outer = nchars; outer >= max128; --outer) |
2836ec90 UD |
416 | { |
417 | size_t len; | |
418 | ||
9cc198f6 | 419 | for (len = 0; len < nchars - outer; ++len) |
2836ec90 | 420 | { |
9cc198f6 UD |
421 | if (STRNCPY (dest, &adr[outer], len) != dest |
422 | || MEMCMP (dest, &adr[outer], len) != 0) | |
2836ec90 | 423 | { |
376b40a2 | 424 | printf ("outer %s flunked for outer = %zu, len = %zu\n", |
9cc198f6 | 425 | STRINGIFY (STRNCPY), outer, len); |
2836ec90 UD |
426 | result = 1; |
427 | } | |
428 | } | |
376b40a2 L |
429 | if (outer == 0) |
430 | break; | |
45db99c7 | 431 | } |
9cc198f6 | 432 | adr[nchars - 1] = L('\0'); |
2836ec90 | 433 | |
376b40a2 | 434 | for (outer = nchars - 1; outer >= max128; --outer) |
45db99c7 | 435 | { |
376b40a2 | 436 | for (inner = MAX (outer, nchars64); inner < nchars; ++inner) |
a5ae1fc2 UD |
437 | { |
438 | size_t len; | |
439 | ||
9cc198f6 | 440 | adr[inner] = L('\0'); |
a5ae1fc2 | 441 | |
9cc198f6 | 442 | for (len = 0; len < nchars - outer + 64; ++len) |
a5ae1fc2 | 443 | { |
9cc198f6 UD |
444 | if (STRNCPY (dest, &adr[outer], len) != dest |
445 | || MEMCMP (dest, &adr[outer], | |
a5ae1fc2 UD |
446 | MIN (inner - outer, len)) != 0 |
447 | || (inner - outer < len | |
9cc198f6 | 448 | && STRLEN (dest) != (inner - outer))) |
a5ae1fc2 | 449 | { |
376b40a2 L |
450 | printf ("%s flunked for outer = %zu, inner = %zu, " |
451 | "len = %zu\n", | |
9cc198f6 | 452 | STRINGIFY (STRNCPY), outer, inner, len); |
a5ae1fc2 UD |
453 | result = 1; |
454 | } | |
9cc198f6 UD |
455 | if (STRNCPY (dest + 1, &adr[outer], len) != dest + 1 |
456 | || MEMCMP (dest + 1, &adr[outer], | |
2836ec90 UD |
457 | MIN (inner - outer, len)) != 0 |
458 | || (inner - outer < len | |
9cc198f6 | 459 | && STRLEN (dest + 1) != (inner - outer))) |
2836ec90 | 460 | { |
376b40a2 L |
461 | printf ("%s+1 flunked for outer = %zu, inner = %zu, " |
462 | "len = %zu\n", | |
9cc198f6 | 463 | STRINGIFY (STRNCPY), outer, inner, len); |
2836ec90 UD |
464 | result = 1; |
465 | } | |
a5ae1fc2 UD |
466 | } |
467 | ||
9cc198f6 | 468 | adr[inner] = L('T'); |
a5ae1fc2 | 469 | } |
376b40a2 L |
470 | if (outer == 0) |
471 | break; | |
45db99c7 | 472 | } |
a5ae1fc2 | 473 | |
9cc198f6 | 474 | /* stpcpy/wcpcpy test */ |
376b40a2 | 475 | for (outer = nchars - 1; outer >= max128; --outer) |
45db99c7 | 476 | { |
376b40a2 | 477 | for (inner = MAX (outer, nchars64); inner < nchars; ++inner) |
46ec036d | 478 | { |
9cc198f6 | 479 | adr[inner] = L('\0'); |
46ec036d | 480 | |
9cc198f6 | 481 | if ((STPCPY (dest, &adr[outer]) - dest) != inner - outer) |
46ec036d | 482 | { |
376b40a2 | 483 | printf ("%s flunked for outer = %zu, inner = %zu\n", |
9cc198f6 | 484 | STRINGIFY (STPCPY), outer, inner); |
46ec036d UD |
485 | result = 1; |
486 | } | |
487 | ||
9cc198f6 | 488 | adr[inner] = L('T'); |
46ec036d | 489 | } |
376b40a2 L |
490 | if (outer == 0) |
491 | break; | |
45db99c7 | 492 | } |
c13f651e | 493 | |
9cc198f6 | 494 | /* stpncpy/wcpncpy test */ |
15417de3 | 495 | adr[nchars - 1] = L('T'); |
376b40a2 | 496 | for (outer = nchars; outer >= max128; --outer) |
15417de3 UD |
497 | { |
498 | size_t len; | |
499 | ||
500 | for (len = 0; len < nchars - outer; ++len) | |
501 | { | |
502 | if (STPNCPY (dest, &adr[outer], len) != dest + len | |
503 | || MEMCMP (dest, &adr[outer], len) != 0) | |
504 | { | |
376b40a2 | 505 | printf ("outer %s flunked for outer = %zu, len = %zu\n", |
15417de3 UD |
506 | STRINGIFY (STPNCPY), outer, len); |
507 | result = 1; | |
508 | } | |
509 | } | |
376b40a2 L |
510 | if (outer == 0) |
511 | break; | |
15417de3 UD |
512 | } |
513 | adr[nchars - 1] = L('\0'); | |
514 | ||
376b40a2 | 515 | for (outer = nchars - 1; outer >= max128; --outer) |
45db99c7 | 516 | { |
376b40a2 | 517 | for (middle = MAX (outer, nchars64); middle < nchars; ++middle) |
c13f651e | 518 | { |
9cc198f6 | 519 | adr[middle] = L('\0'); |
c13f651e | 520 | |
9cc198f6 | 521 | for (inner = 0; inner < nchars - outer; ++ inner) |
c13f651e | 522 | { |
9cc198f6 | 523 | if ((STPNCPY (dest, &adr[outer], inner) - dest) |
c13f651e UD |
524 | != MIN (inner, middle - outer)) |
525 | { | |
376b40a2 L |
526 | printf ("%s flunked for outer = %zu, middle = %zu, " |
527 | "inner = %zu\n", | |
9cc198f6 | 528 | STRINGIFY (STPNCPY), outer, middle, inner); |
c13f651e UD |
529 | result = 1; |
530 | } | |
531 | } | |
532 | ||
9cc198f6 | 533 | adr[middle] = L('T'); |
c13f651e | 534 | } |
376b40a2 L |
535 | if (outer == 0) |
536 | break; | |
45db99c7 | 537 | } |
c13f651e | 538 | |
9cc198f6 | 539 | /* memcpy/wmemcpy test */ |
376b40a2 L |
540 | for (outer = nchars; outer >= max128; --outer) |
541 | { | |
542 | for (inner = 0; inner < nchars - outer; ++inner) | |
543 | if (MEMCPY (dest, &adr[outer], inner) != dest) | |
544 | { | |
545 | printf ("%s flunked for outer = %zu, inner = %zu\n", | |
546 | STRINGIFY (MEMCPY), outer, inner); | |
547 | result = 1; | |
548 | } | |
549 | if (outer == 0) | |
550 | break; | |
551 | } | |
c13f651e | 552 | |
9cc198f6 | 553 | /* mempcpy/wmempcpy test */ |
376b40a2 L |
554 | for (outer = nchars; outer >= max128; --outer) |
555 | { | |
556 | for (inner = 0; inner < nchars - outer; ++inner) | |
557 | if (MEMPCPY (dest, &adr[outer], inner) != dest + inner) | |
558 | { | |
559 | printf ("%s flunked for outer = %zu, inner = %zu\n", | |
560 | STRINGIFY (MEMPCPY), outer, inner); | |
561 | result = 1; | |
562 | } | |
563 | if (outer == 0) | |
564 | break; | |
565 | } | |
2036b767 | 566 | |
9cc198f6 UD |
567 | /* This function only exists for single-byte characters. */ |
568 | #ifndef WCSTEST | |
2036b767 | 569 | /* memccpy test */ |
9cc198f6 | 570 | memset (adr, '\0', nchars); |
376b40a2 L |
571 | for (outer = nchars; outer >= max128; --outer) |
572 | { | |
573 | for (inner = 0; inner < nchars - outer; ++inner) | |
574 | if (memccpy (dest, &adr[outer], L('\1'), inner) != NULL) | |
2036b767 | 575 | { |
376b40a2 L |
576 | printf ("memccpy flunked full copy for outer = %zu, inner = %zu\n", |
577 | outer, inner); | |
578 | result = 1; | |
2036b767 | 579 | } |
376b40a2 L |
580 | if (outer == 0) |
581 | break; | |
582 | } | |
583 | for (outer = nchars - 1; outer >= max128; --outer) | |
584 | { | |
585 | for (middle = 0; middle < nchars - outer; ++middle) | |
586 | { | |
587 | memset (dest, L('\2'), middle + 1); | |
588 | for (inner = 0; inner < middle; ++inner) | |
589 | { | |
590 | adr[outer + inner] = L('\1'); | |
591 | ||
592 | if (memccpy (dest, &adr[outer], '\1', middle + 128) | |
593 | != dest + inner + 1) | |
594 | { | |
595 | printf ("\ | |
596 | memccpy flunked partial copy for outer = %zu, middle = %zu, inner = %zu\n", | |
597 | outer, middle, inner); | |
598 | result = 1; | |
599 | } | |
600 | else if (dest[inner + 1] != L('\2')) | |
601 | { | |
602 | printf ("\ | |
603 | memccpy copied too much for outer = %zu, middle = %zu, inner = %zu\n", | |
604 | outer, middle, inner); | |
605 | result = 1; | |
606 | } | |
607 | adr[outer + inner] = L('\0'); | |
608 | } | |
609 | } | |
610 | if (outer == 0) | |
611 | break; | |
612 | } | |
9cc198f6 | 613 | #endif |
46ec036d UD |
614 | } |
615 | ||
616 | return result; | |
617 | } | |
9cc198f6 | 618 | |
fb82116f | 619 | #include <support/test-driver.c> |