(STRCOLL): Correct test for alloca use.
[kopensolaris-gnu/glibc.git] / string / test-memmove.c
1 /* Test and measure memmove functions.
2    Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Written by Jakub Jelinek <jakub@redhat.com>, 1999.
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 TEST_MAIN
22 #include "test-string.h"
23
24 typedef char *(*proto_t) (char *, const char *, size_t);
25 char *simple_memmove (char *, const char *, size_t);
26
27 IMPL (simple_memmove, 0)
28 IMPL (memmove, 1)
29
30 char *
31 simple_memmove (char *dst, const char *src, size_t n)
32 {
33   char *ret = dst;
34   if (src < dst)
35     {
36       dst += n;
37       src += n;
38       while (n--)
39         *--dst = *--src;
40     }
41   else
42     while (n--)
43       *dst++ = *src++;
44   return ret;
45 }
46
47 static void
48 do_one_test (impl_t *impl, char *dst, char *src, const char *orig_src,
49              size_t len)
50 {
51   char *res;
52
53   memcpy (src, orig_src, len);
54   res = CALL (impl, dst, src, len);
55   if (res != dst)
56     {
57       error (0, 0, "Wrong result in function %s %p %p", impl->name,
58              res, dst);
59       ret = 1;
60       return;
61     }
62
63   if (memcmp (dst, orig_src, len) != 0)
64     {
65       error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"",
66              impl->name, dst, src);
67       ret = 1;
68       return;
69     }
70
71   if (HP_TIMING_AVAIL)
72     {
73       hp_timing_t start __attribute ((unused));
74       hp_timing_t stop __attribute ((unused));
75       hp_timing_t best_time = ~ (hp_timing_t) 0;
76       size_t i;
77
78       for (i = 0; i < 32; ++i)
79         {
80           HP_TIMING_NOW (start);
81           CALL (impl, dst, src, len);
82           HP_TIMING_NOW (stop);
83           HP_TIMING_BEST (best_time, start, stop);
84         }
85
86       printf ("\t%zd", (size_t) best_time);
87     }
88 }
89
90 static void
91 do_test (size_t align1, size_t align2, size_t len)
92 {
93   size_t i, j;
94   char *s1, *s2;
95
96   align1 &= 63;
97   if (align1 + len >= page_size)
98     return;
99
100   align2 &= 63;
101   if (align2 + len >= page_size)
102     return;
103
104   s1 = (char *) (buf1 + align1);
105   s2 = (char *) (buf2 + align2);
106
107   for (i = 0, j = 1; i < len; i++, j += 23)
108     s1[i] = j;
109
110   if (HP_TIMING_AVAIL)
111     printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
112
113   FOR_EACH_IMPL (impl, 0)
114     do_one_test (impl, s2, (char *) (buf2 + align1), s1, len);
115
116   if (HP_TIMING_AVAIL)
117     putchar ('\n');
118 }
119
120 static void
121 do_random_tests (void)
122 {
123   size_t i, n, align1, align2, len, size;
124   size_t srcstart, srcend, dststart, dstend;
125   int c;
126   unsigned char *p1, *p2;
127   unsigned char *res;
128
129   for (n = 0; n < ITERATIONS; n++)
130     {
131       if ((random () & 255) == 0)
132         size = 65536;
133       else
134         size = 512;
135       if (size > page_size)
136         size = page_size;
137       if ((random () & 3) == 0)
138         {
139           len = random () & (size - 1);
140           align1 = size - len - (random () & 31);
141           align2 = size - len - (random () & 31);
142           if (align1 > size)
143             align1 = 0;
144           if (align2 > size)
145             align2 = 0;
146         }
147       else
148         {
149           align1 = random () & (size / 2 - 1);
150           align2 = random () & (size / 2 - 1);
151           len = random () & (size - 1);
152           if (align1 + len > size)
153             align1 = size - len;
154           if (align2 + len > size)
155             align2 = size - len;
156         }
157
158       p1 = buf1 + page_size - size;
159       p2 = buf2 + page_size - size;
160       c = random () & 255;
161       srcend = align1 + len + 256;
162       if (srcend > size)
163         srcend = size;
164       if (align1 > 256)
165         srcstart = align1 - 256;
166       else
167         srcstart = 0;
168       for (i = srcstart; i < srcend; ++i)
169         p1[i] = random () & 255;
170       dstend = align2 + len + 256;
171       if (dstend > size)
172         dstend = size;
173       if (align2 > 256)
174         dststart = align2 - 256;
175       else
176         dststart = 0;
177
178       FOR_EACH_IMPL (impl, 1)
179         {
180           memset (p2 + dststart, c, dstend - dststart);
181           memcpy (p2 + srcstart, p1 + srcstart, srcend - srcstart);
182           res = (unsigned char *) CALL (impl,
183                                         (char *) (p2 + align2),
184                                         (char *) (p2 + align1), len);
185           if (res != p2 + align2)
186             {
187               error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
188                      n, impl->name, align1, align2, len, res, p2 + align2);
189               ret = 1;
190             }
191           if (memcmp (p1 + align1, p2 + align2, len))
192             {
193               error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
194                      n, impl->name, align1, align2, len);
195               ret = 1;
196             }
197           for (i = dststart; i < dstend; ++i)
198             {
199               if (i >= align2 && i < align2 + len)
200                 {
201                   i = align2 + len - 1;
202                   continue;
203                 }
204               if (i >= srcstart && i < srcend)
205                 {
206                   i = srcend - 1;
207                   continue;
208                 }
209               if (p2[i] != c)
210                 {
211                   error (0, 0, "Iteration %zd - garbage in memset area, %s (%zd, %zd, %zd)",
212                          n, impl->name, align1, align2, len);
213                   ret = 1;
214                   break;
215                 }
216             }
217
218           if (srcstart < align2
219               && memcmp (p2 + srcstart, p1 + srcstart,
220                          (srcend > align2 ? align2 : srcend) - srcstart))
221             {
222               error (0, 0, "Iteration %zd - garbage before dst, %s (%zd, %zd, %zd)",
223                      n, impl->name, align1, align2, len);
224               ret = 1;
225               break;
226             }
227
228           i = srcstart > align2 + len ? srcstart : align2 + len;
229           if (srcend > align2 + len
230               && memcmp (p2 + i, p1 + i, srcend - i))
231             {
232               error (0, 0, "Iteration %zd - garbage after dst, %s (%zd, %zd, %zd)",
233                      n, impl->name, align1, align2, len);
234               ret = 1;
235               break;
236             }
237         }
238     }
239 }
240
241 int
242 test_main (void)
243 {
244   size_t i;
245
246   test_init ();
247
248   printf ("%23s", "");
249   FOR_EACH_IMPL (impl, 0)
250     printf ("\t%s", impl->name);
251   putchar ('\n');
252
253   for (i = 0; i < 14; ++i)
254     {
255       do_test (0, 32, 1 << i);
256       do_test (32, 0, 1 << i);
257       do_test (0, i, 1 << i);
258       do_test (i, 0, 1 << i);
259     }
260
261   for (i = 0; i < 32; ++i)
262     {
263       do_test (0, 32, i);
264       do_test (32, 0, i);
265       do_test (0, i, i);
266       do_test (i, 0, i);
267     }
268
269   for (i = 3; i < 32; ++i)
270     {
271       if ((i & (i - 1)) == 0)
272         continue;
273       do_test (0, 32, 16 * i);
274       do_test (32, 0, 16 * i);
275       do_test (0, i, 16 * i);
276       do_test (i, 0, 16 * i);
277     }
278
279   do_random_tests ();
280   return ret;
281 }
282
283 #include "../test-skeleton.c"