Fix strchr test
[platform/upstream/glibc.git] / string / test-rawmemchr.c
1 /* Test and measure memchr functions.
2    Copyright (C) 1999,2002,2003,2005,2009,2011 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 #include <assert.h>
22
23 #define TEST_MAIN
24 #include "test-string.h"
25
26 typedef char *(*proto_t) (const char *, int);
27 char *simple_rawmemchr (const char *, int);
28
29 IMPL (simple_rawmemchr, 0)
30 IMPL (rawmemchr, 1)
31
32 char *
33 simple_rawmemchr (const char *s, int c)
34 {
35   while (1)
36     if (*s++ == (char) c)
37       return (char *) s - 1;
38   return NULL;
39 }
40
41 static void
42 do_one_test (impl_t *impl, const char *s, int c, char *exp_res)
43 {
44   char *res = CALL (impl, s, c);
45   if (res != exp_res)
46     {
47       error (0, 0, "Wrong result in function %s %p %p", impl->name,
48              res, exp_res);
49       ret = 1;
50       return;
51     }
52
53   if (HP_TIMING_AVAIL)
54     {
55       hp_timing_t start __attribute ((unused));
56       hp_timing_t stop __attribute ((unused));
57       hp_timing_t best_time = ~ (hp_timing_t) 0;
58       size_t i;
59
60       for (i = 0; i < 32; ++i)
61         {
62           HP_TIMING_NOW (start);
63           CALL (impl, s, c);
64           HP_TIMING_NOW (stop);
65           HP_TIMING_BEST (best_time, start, stop);
66         }
67
68       printf ("\t%zd", (size_t) best_time);
69     }
70 }
71
72 static void
73 do_test (size_t align, size_t pos, size_t len, int seek_char)
74 {
75   size_t i;
76   char *result;
77
78   align &= 7;
79   if (align + len >= page_size)
80     return;
81
82   for (i = 0; i < len; ++i)
83     {
84       buf1[align + i] = 1 + 23 * i % 127;
85       if (buf1[align + i] == seek_char)
86         buf1[align + i] = seek_char + 1;
87     }
88   buf1[align + len] = 0;
89
90   assert (pos < len);
91
92   buf1[align + pos] = seek_char;
93   buf1[align + len] = -seek_char;
94   result = (char *) (buf1 + align + pos);
95
96   if (HP_TIMING_AVAIL)
97     printf ("Length %4zd, alignment %2zd:", pos, align);
98
99   FOR_EACH_IMPL (impl, 0)
100     do_one_test (impl, (char *) (buf1 + align), seek_char, result);
101
102   if (HP_TIMING_AVAIL)
103     putchar ('\n');
104 }
105
106 static void
107 do_random_tests (void)
108 {
109   size_t i, j, n, align, pos, len;
110   int seek_char;
111   char *result;
112   unsigned char *p = buf1 + page_size - 512;
113
114   for (n = 0; n < ITERATIONS; n++)
115     {
116       align = random () & 15;
117       pos = random () & 511;
118       if (pos + align >= 512)
119         pos = 511 - align - (random () & 7);
120       len = random () & 511;
121       if (len + align >= 512)
122         len = 512 - align - (random () & 7);
123       if (pos >= len)
124         continue;
125       seek_char = random () & 255;
126       j = len + align + 64;
127       if (j > 512)
128         j = 512;
129
130       for (i = 0; i < j; i++)
131         {
132           if (i == pos + align)
133             p[i] = seek_char;
134           else
135             {
136               p[i] = random () & 255;
137               if (i < pos + align && p[i] == seek_char)
138                 p[i] = seek_char + 13;
139             }
140         }
141
142       assert (pos < len);
143       size_t r = random ();
144       if ((r & 31) == 0)
145         len = ~(uintptr_t) (p + align) - ((r >> 5) & 31);
146       result = (char *) (p + pos + align);
147
148       FOR_EACH_IMPL (impl, 1)
149         if (CALL (impl, (char *) (p + align), seek_char) != result)
150           {
151             error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
152                    n, impl->name, align, seek_char, len, pos,
153                    CALL (impl, (char *) (p + align), seek_char),
154                    result, p);
155             ret = 1;
156           }
157     }
158 }
159
160 int
161 test_main (void)
162 {
163   size_t i;
164
165   test_init ();
166
167   printf ("%20s", "");
168   FOR_EACH_IMPL (impl, 0)
169     printf ("\t%s", impl->name);
170   putchar ('\n');
171
172   for (i = 1; i < 7; ++i)
173     {
174       do_test (0, 16 << i, 2048, 23);
175       do_test (i, 64, 256, 23);
176       do_test (0, 16 << i, 2048, 0);
177       do_test (i, 64, 256, 0);
178     }
179   for (i = 1; i < 32; ++i)
180     {
181       do_test (0, i, i + 1, 23);
182       do_test (0, i, i + 1, 0);
183     }
184
185   do_random_tests ();
186   return ret;
187 }
188
189 #include "../test-skeleton.c"