powerpc: Fix ifuncmain6pie failure with GCC 4.9
[platform/upstream/glibc.git] / string / test-strchr.c
1 /* Test and measure STRCHR functions.
2    Copyright (C) 1999-2015 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
6
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.
11
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.
16
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    <http://www.gnu.org/licenses/>.  */
20
21 #define TEST_MAIN
22 #ifndef WIDE
23 # ifdef USE_FOR_STRCHRNUL
24 #  define TEST_NAME "strchrnul"
25 # else
26 #  define TEST_NAME "strchr"
27 # endif
28 #else
29 # define TEST_NAME "wcschr"
30 #endif
31 #include "test-string.h"
32
33 #ifndef WIDE
34 # ifdef USE_FOR_STRCHRNUL
35 #  define STRCHR strchrnul
36 #  define stupid_STRCHR stupid_STRCHRNUL
37 #  define simple_STRCHR simple_STRCHRNUL
38 # else
39 #  define STRCHR strchr
40 # endif
41 # define STRLEN strlen
42 # define CHAR char
43 # define BIG_CHAR CHAR_MAX
44 # define MIDDLE_CHAR 127
45 # define SMALL_CHAR 23
46 # define UCHAR unsigned char
47 # define L(s) s
48 #else
49 # include <wchar.h>
50 # define STRCHR wcschr
51 # define STRLEN wcslen
52 # define CHAR wchar_t
53 # define BIG_CHAR WCHAR_MAX
54 # define MIDDLE_CHAR 1121
55 # define SMALL_CHAR 851
56 # define UCHAR wchar_t
57 # define L(s) L ## s
58 #endif
59
60 #ifdef USE_FOR_STRCHRNUL
61 # define NULLRET(endptr) endptr
62 #else
63 # define NULLRET(endptr) NULL
64 #endif
65
66
67 typedef CHAR *(*proto_t) (const CHAR *, int);
68
69 CHAR *
70 simple_STRCHR (const CHAR *s, int c)
71 {
72   for (; *s != (CHAR) c; ++s)
73     if (*s == '\0')
74       return NULLRET ((CHAR *) s);
75   return (CHAR *) s;
76 }
77
78 CHAR *
79 stupid_STRCHR (const CHAR *s, int c)
80 {
81   size_t n = STRLEN (s) + 1;
82
83   while (n--)
84     if (*s++ == (CHAR) c)
85       return (CHAR *) s - 1;
86   return NULLRET ((CHAR *) s - 1);
87 }
88
89 IMPL (stupid_STRCHR, 0)
90 IMPL (simple_STRCHR, 0)
91 IMPL (STRCHR, 1)
92
93 static int
94 check_result (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
95 {
96   CHAR *res = CALL (impl, s, c);
97   if (res != exp_res)
98     {
99       error (0, 0, "Wrong result in function %s %#x %p %p", impl->name,
100              c, res, exp_res);
101       ret = 1;
102       return -1;
103     }
104   return 0;
105 }
106
107 static void
108 do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
109 {
110   if (check_result (impl, s, c, exp_res) < 0)
111     return;
112 }
113
114 static void
115 do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
116 /* For wcschr: align here means align not in bytes,
117    but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
118    len for wcschr here isn't in bytes but it's number of wchar_t symbols.  */
119 {
120   size_t i;
121   CHAR *result;
122   CHAR *buf = (CHAR *) buf1;
123   align &= 15;
124   if ((align + len) * sizeof (CHAR) >= page_size)
125     return;
126
127   for (i = 0; i < len; ++i)
128     {
129       buf[align + i] = 32 + 23 * i % max_char;
130       if (buf[align + i] == seek_char)
131         buf[align + i] = seek_char + 1;
132       else if (buf[align + i] == 0)
133         buf[align + i] = 1;
134     }
135   buf[align + len] = 0;
136
137   if (pos < len)
138     {
139       buf[align + pos] = seek_char;
140       result = buf + align + pos;
141     }
142   else if (seek_char == 0)
143     result = buf + align + len;
144   else
145     result = NULLRET (buf + align + len);
146
147   FOR_EACH_IMPL (impl, 0)
148     do_one_test (impl, buf + align, seek_char, result);
149 }
150
151 static void
152 do_random_tests (void)
153 {
154   size_t i, j, n, align, pos, len;
155   int seek_char;
156   CHAR *result;
157   UCHAR *p = (UCHAR *) (buf1 + page_size - 512 * sizeof (CHAR));
158
159   for (n = 0; n < ITERATIONS; n++)
160     {
161       /* For wcschr: align here means align not in bytes, but in wchar_ts,
162          in bytes it will equal to align * (sizeof (wchar_t)).  */
163       align = random () & 15;
164       pos = random () & 511;
165       seek_char = random () & 255;
166       if (pos + align >= 511)
167         pos = 510 - align - (random () & 7);
168       /* len for wcschr here isn't in bytes but it's number of wchar_t
169          symbols.  */
170       len = random () & 511;
171       if ((pos == len && seek_char)
172           || (pos > len && (random () & 1)))
173         len = pos + 1 + (random () & 7);
174       if (len + align >= 512)
175         len = 511 - align - (random () & 7);
176       if (pos == len && seek_char)
177         len = pos + 1;
178       j = (pos > len ? pos : len) + align + 64;
179       if (j > 512)
180         j = 512;
181
182       for (i = 0; i < j; i++)
183         {
184           if (i == pos + align)
185             p[i] = seek_char;
186           else if (i == len + align)
187             p[i] = 0;
188           else
189             {
190               p[i] = random () & 255;
191               if (i < pos + align && p[i] == seek_char)
192                 p[i] = seek_char + 13;
193               if (i < len + align && !p[i])
194                 {
195                   p[i] = seek_char - 13;
196                   if (!p[i])
197                     p[i] = 140;
198                 }
199             }
200         }
201
202       if (pos <= len)
203         result = (CHAR *) (p + pos + align);
204       else if (seek_char == 0)
205         result = (CHAR *) (p + len + align);
206       else
207         result = NULLRET ((CHAR *) (p + len + align));
208
209       FOR_EACH_IMPL (impl, 1)
210         if (CALL (impl, (CHAR *) (p + align), seek_char) != result)
211           {
212             error (0, 0, "Iteration %zd - wrong result in function \
213                    %s (align in bytes: %zd, seek_char: %d, len: %zd, pos: %zd) %p != %p, p %p",
214                    n, impl->name, align * sizeof (CHAR), seek_char, len, pos,
215                    CALL (impl, (CHAR *) (p + align), seek_char), result, p);
216             ret = 1;
217           }
218     }
219 }
220
221 static void
222 check1 (void)
223 {
224   CHAR s[] __attribute__((aligned(16))) = L ("\xff");
225   CHAR c = L ('\xfe');
226   CHAR *exp_result = stupid_STRCHR (s, c);
227
228   FOR_EACH_IMPL (impl, 0)
229     check_result (impl, s, c, exp_result);
230 }
231
232 int
233 test_main (void)
234 {
235   size_t i;
236
237   test_init ();
238
239   check1 ();
240
241   printf ("%20s", "");
242   FOR_EACH_IMPL (impl, 0)
243     printf ("\t%s", impl->name);
244   putchar ('\n');
245
246   for (i = 1; i < 8; ++i)
247     {
248       do_test (0, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR);
249       do_test (i, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR);
250     }
251
252   for (i = 1; i < 8; ++i)
253     {
254       do_test (i, 64, 256, SMALL_CHAR, MIDDLE_CHAR);
255       do_test (i, 64, 256, SMALL_CHAR, BIG_CHAR);
256     }
257
258   for (i = 0; i < 32; ++i)
259     {
260       do_test (0, i, i + 1, SMALL_CHAR, MIDDLE_CHAR);
261       do_test (0, i, i + 1, SMALL_CHAR, BIG_CHAR);
262     }
263
264   for (i = 1; i < 8; ++i)
265     {
266       do_test (0, 16 << i, 2048, 0, MIDDLE_CHAR);
267       do_test (i, 16 << i, 2048, 0, MIDDLE_CHAR);
268     }
269
270   for (i = 1; i < 8; ++i)
271     {
272       do_test (i, 64, 256, 0, MIDDLE_CHAR);
273       do_test (i, 64, 256, 0, BIG_CHAR);
274     }
275
276   for (i = 0; i < 32; ++i)
277     {
278       do_test (0, i, i + 1, 0, MIDDLE_CHAR);
279       do_test (0, i, i + 1, 0, BIG_CHAR);
280     }
281
282   do_random_tests ();
283   return ret;
284 }
285
286 #include "../test-skeleton.c"