* string/stratcliff.c (do_test): Add memchr tests..
[platform/upstream/glibc.git] / string / stratcliff.c
1 /* Test for string function add boundaries of usable memory.
2    Copyright (C) 1996,1997,1999-2003,2007, 2009 Free Software Foundation, Inc.
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
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.
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
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #define _GNU_SOURCE 1
22
23 /* Make sure we don't test the optimized inline functions if we want to
24    test the real implementation.  */
25 #undef __USE_STRING_INLINES
26
27 #include <errno.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <sys/mman.h>
32 #include <sys/param.h>
33
34 #ifndef CHAR
35 # define L(c) c
36 # define CHAR char
37 # define MEMSET memset
38 # define STRLEN strlen
39 # define STRNLEN strnlen
40 # define STRCHR strchr
41 # define STRRCHR strrchr
42 # define STRCPY strcpy
43 # define STRNCPY strncpy
44 # define MEMCMP memcmp
45 # define STPCPY stpcpy
46 # define STPNCPY stpncpy
47 # define MEMCPY memcpy
48 # define MEMPCPY mempcpy
49 # define MEMCHR memchr
50 #endif
51
52
53 #define STRINGIFY(s) STRINGIFY2 (s)
54 #define STRINGIFY2(s) #s
55
56
57 static int
58 do_test (void)
59 {
60   int size = sysconf (_SC_PAGESIZE);
61   int nchars = size / sizeof (CHAR);
62   CHAR *adr;
63   CHAR *dest;
64   int result = 0;
65
66   adr = (CHAR *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
67                        MAP_PRIVATE | MAP_ANON, -1, 0);
68   dest = (CHAR *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
69                         MAP_PRIVATE | MAP_ANON, -1, 0);
70   if (adr == MAP_FAILED || dest == MAP_FAILED)
71     {
72       if (errno == ENOSYS)
73         puts ("No test, mmap not available.");
74       else
75         {
76           printf ("mmap failed: %m");
77           result = 1;
78         }
79     }
80   else
81     {
82       int inner, middle, outer;
83
84       mprotect (adr, size, PROT_NONE);
85       mprotect (adr + 2 * nchars, size, PROT_NONE);
86       adr += nchars;
87
88       mprotect (dest, size, PROT_NONE);
89       mprotect (dest + 2 * nchars, size, PROT_NONE);
90       dest += nchars;
91
92       MEMSET (adr, L('T'), nchars);
93
94       /* strlen/wcslen test */
95       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
96         {
97           for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
98             {
99               adr[inner] = L('\0');
100
101               if (STRLEN (&adr[outer]) != (size_t) (inner - outer))
102                 {
103                   printf ("%s flunked for outer = %d, inner = %d\n",
104                           STRINGIFY (STRLEN), outer, inner);
105                   result = 1;
106                 }
107
108               adr[inner] = L('T');
109             }
110         }
111
112       /* strnlen/wcsnlen test */
113       for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
114         {
115           for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
116             {
117               adr[inner] = L('\0');
118
119               if (STRNLEN (&adr[outer], inner - outer + 1)
120                   != (size_t) (inner - outer))
121                 {
122                   printf ("%s flunked for outer = %d, inner = %d\n",
123                           STRINGIFY (STRNLEN), outer, inner);
124                   result = 1;
125                 }
126
127               adr[inner] = L('T');
128             }
129         }
130       for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
131         {
132           for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
133             {
134               if (STRNLEN (&adr[outer], inner - outer + 1)
135                   != (size_t) (inner - outer + 1))
136                 {
137                   printf ("%s flunked bounded for outer = %d, inner = %d\n",
138                           STRINGIFY (STRNLEN), outer, inner);
139                   result = 1;
140                 }
141             }
142         }
143
144       /* strchr/wcschr test */
145       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
146         {
147           for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
148             {
149               for (inner = middle; inner < nchars; ++inner)
150                 {
151                   adr[middle] = L('V');
152                   adr[inner] = L('\0');
153
154                   CHAR *cp = STRCHR (&adr[outer], L('V'));
155
156                   if ((inner == middle && cp != NULL)
157                       || (inner != middle
158                           && (cp - &adr[outer]) != middle - outer))
159                     {
160                       printf ("%s flunked for outer = %d, middle = %d, "
161                               "inner = %d\n",
162                               STRINGIFY (STRCHR), outer, middle, inner);
163                       result = 1;
164                     }
165
166                   adr[inner] = L('T');
167                   adr[middle] = L('T');
168                 }
169             }
170         }
171
172       /* Special test.  */
173       adr[nchars - 1] = L('\0');
174       if (STRCHR (&adr[nchars - 1], L('\n')) != NULL)
175         {
176           printf ("%s flunked test of empty string at end of page\n",
177                   STRINGIFY (STRCHR));
178           result = 1;
179         }
180
181       /* strrchr/wcsrchr test */
182       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
183         {
184           for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
185             {
186               for (inner = middle; inner < nchars; ++inner)
187                 {
188                   adr[middle] = L('V');
189                   adr[inner] = L('\0');
190
191                   CHAR *cp = STRRCHR (&adr[outer], L('V'));
192
193                   if ((inner == middle && cp != NULL)
194                       || (inner != middle
195                           && (cp - &adr[outer]) != middle - outer))
196                     {
197                       printf ("%s flunked for outer = %d, middle = %d, "
198                               "inner = %d\n",
199                               STRINGIFY (STRRCHR), outer, middle, inner);
200                       result = 1;
201                     }
202
203                   adr[inner] = L('T');
204                   adr[middle] = L('T');
205                 }
206             }
207         }
208
209       /* memchr test */
210       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
211         {
212           for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
213             {
214               adr[middle] = L('V');
215
216               CHAR *cp = MEMCHR (&adr[outer], L('V'), 3 * size);
217
218               if (cp - &adr[outer] != middle - outer)
219                 {
220                   printf ("%s flunked for outer = %d, middle = %d\n",
221                           STRINGIFY (MEMCHR), outer, middle);
222                   result = 1;
223                 }
224
225               adr[middle] = L('T');
226             }
227         }
228       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
229         {
230           CHAR *cp = MEMCHR (&adr[outer], L('V'), nchars - outer);
231
232           if (cp != NULL)
233             {
234               printf ("%s flunked for outer = %d\n",
235                       STRINGIFY (MEMCHR), outer);
236               result = 1;
237             }
238         }
239
240       /* This function only exists for single-byte characters.  */
241 #ifndef WCSTEST
242       /* rawmemchr test */
243       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
244         {
245           for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
246             {
247               adr[middle] = L('V');
248
249               CHAR *cp = rawmemchr (&adr[outer], L('V'));
250
251               if (cp - &adr[outer] != middle - outer)
252                 {
253                   printf ("%s flunked for outer = %d, middle = %d\n",
254                           STRINGIFY (rawmemchr), outer, middle);
255                   result = 1;
256                 }
257
258               adr[middle] = L('T');
259             }
260         }
261 #endif
262
263       /* strcpy/wcscpy test */
264       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
265         {
266           for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
267             {
268               adr[inner] = L('\0');
269
270               if (STRCPY (dest, &adr[outer]) != dest
271                   || STRLEN (dest) != (size_t) (inner - outer))
272                 {
273                   printf ("%s flunked for outer = %d, inner = %d\n",
274                           STRINGIFY (STRCPY), outer, inner);
275                   result = 1;
276                 }
277
278               adr[inner] = L('T');
279             }
280         }
281
282       /* strncpy tests */
283       adr[nchars - 1] = L('T');
284       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
285         {
286           size_t len;
287
288           for (len = 0; len < nchars - outer; ++len)
289             {
290               if (STRNCPY (dest, &adr[outer], len) != dest
291                   || MEMCMP (dest, &adr[outer], len) != 0)
292                 {
293                   printf ("outer %s flunked for outer = %d, len = %Zd\n",
294                           STRINGIFY (STRNCPY), outer, len);
295                   result = 1;
296                 }
297             }
298         }
299       adr[nchars - 1] = L('\0');
300
301       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
302         {
303           for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
304             {
305               size_t len;
306
307               adr[inner] = L('\0');
308
309               for (len = 0; len < nchars - outer + 64; ++len)
310                 {
311                   if (STRNCPY (dest, &adr[outer], len) != dest
312                       || MEMCMP (dest, &adr[outer],
313                                  MIN (inner - outer, len)) != 0
314                       || (inner - outer < len
315                           && STRLEN (dest) != (inner - outer)))
316                     {
317                       printf ("%s flunked for outer = %d, inner = %d, "
318                               "len = %Zd\n",
319                               STRINGIFY (STRNCPY), outer, inner, len);
320                       result = 1;
321                     }
322                   if (STRNCPY (dest + 1, &adr[outer], len) != dest + 1
323                       || MEMCMP (dest + 1, &adr[outer],
324                                  MIN (inner - outer, len)) != 0
325                       || (inner - outer < len
326                           && STRLEN (dest + 1) != (inner - outer)))
327                     {
328                       printf ("%s+1 flunked for outer = %d, inner = %d, "
329                               "len = %Zd\n",
330                               STRINGIFY (STRNCPY), outer, inner, len);
331                       result = 1;
332                     }
333                 }
334
335               adr[inner] = L('T');
336             }
337         }
338
339       /* stpcpy/wcpcpy test */
340       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
341         {
342           for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
343             {
344               adr[inner] = L('\0');
345
346               if ((STPCPY (dest, &adr[outer]) - dest) != inner - outer)
347                 {
348                   printf ("%s flunked for outer = %d, inner = %d\n",
349                           STRINGIFY (STPCPY), outer, inner);
350                   result = 1;
351                 }
352
353               adr[inner] = L('T');
354             }
355         }
356
357       /* stpncpy/wcpncpy test */
358       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
359         {
360           for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
361             {
362               adr[middle] = L('\0');
363
364               for (inner = 0; inner < nchars - outer; ++ inner)
365                 {
366                   if ((STPNCPY (dest, &adr[outer], inner) - dest)
367                       != MIN (inner, middle - outer))
368                     {
369                       printf ("%s flunked for outer = %d, middle = %d, "
370                               "inner = %d\n",
371                               STRINGIFY (STPNCPY), outer, middle, inner);
372                       result = 1;
373                     }
374                 }
375
376               adr[middle] = L('T');
377             }
378         }
379
380       /* memcpy/wmemcpy test */
381       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
382         for (inner = 0; inner < nchars - outer; ++inner)
383           if (MEMCPY (dest, &adr[outer], inner) !=  dest)
384             {
385               printf ("%s flunked for outer = %d, inner = %d\n",
386                       STRINGIFY (MEMCPY), outer, inner);
387               result = 1;
388             }
389
390       /* mempcpy/wmempcpy test */
391       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
392         for (inner = 0; inner < nchars - outer; ++inner)
393           if (MEMPCPY (dest, &adr[outer], inner) !=  dest + inner)
394             {
395               printf ("%s flunked for outer = %d, inner = %d\n",
396                       STRINGIFY (MEMPCPY), outer, inner);
397               result = 1;
398             }
399
400       /* This function only exists for single-byte characters.  */
401 #ifndef WCSTEST
402       /* memccpy test */
403       memset (adr, '\0', nchars);
404       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
405         for (inner = 0; inner < nchars - outer; ++inner)
406           if (memccpy (dest, &adr[outer], L('\1'), inner) != NULL)
407             {
408               printf ("memccpy flunked full copy for outer = %d, inner = %d\n",
409                       outer, inner);
410               result = 1;
411             }
412       for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
413         for (middle = 0; middle < nchars - outer; ++middle)
414           {
415             memset (dest, L('\2'), middle + 1);
416             for (inner = 0; inner < middle; ++inner)
417               {
418                 adr[outer + inner] = L('\1');
419
420                 if (memccpy (dest, &adr[outer], '\1', middle + 128)
421                     !=  dest + inner + 1)
422                   {
423                     printf ("\
424 memccpy flunked partial copy for outer = %d, middle = %d, inner = %d\n",
425                             outer, middle, inner);
426                     result = 1;
427                   }
428                 else if (dest[inner + 1] != L('\2'))
429                   {
430                     printf ("\
431 memccpy copied too much for outer = %d, middle = %d, inner = %d\n",
432                             outer, middle, inner);
433                     result = 1;
434                   }
435                 adr[outer + inner] = L('\0');
436               }
437           }
438 #endif
439     }
440
441   return result;
442 }
443
444 #define TEST_FUNCTION do_test ()
445 #include "../test-skeleton.c"