]>
Commit | Line | Data |
---|---|---|
fcf40ebe | 1 | /* Test strlen functions. |
688903eb | 2 | Copyright (C) 1999-2018 Free Software Foundation, Inc. |
24fb0f88 UD |
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 | |
59ba27a6 PE |
17 | License along with the GNU C Library; if not, see |
18 | <http://www.gnu.org/licenses/>. */ | |
24fb0f88 UD |
19 | |
20 | #define TEST_MAIN | |
fcf40ebe SL |
21 | #ifndef WIDE |
22 | # define TEST_NAME "strnlen" | |
23 | #else | |
24 | # define TEST_NAME "wcsnlen" | |
25 | #endif /* !WIDE */ | |
24fb0f88 UD |
26 | #include "test-string.h" |
27 | ||
fcf40ebe SL |
28 | #ifndef WIDE |
29 | # define STRNLEN strnlen | |
30 | # define CHAR char | |
31 | # define BIG_CHAR CHAR_MAX | |
32 | # define MIDDLE_CHAR 127 | |
33 | # define SIMPLE_STRNLEN simple_strnlen | |
34 | #else | |
35 | # include <wchar.h> | |
36 | # define STRNLEN wcsnlen | |
37 | # define CHAR wchar_t | |
38 | # define BIG_CHAR WCHAR_MAX | |
39 | # define MIDDLE_CHAR 1121 | |
40 | # define SIMPLE_STRNLEN simple_wcsnlen | |
41 | #endif /* !WIDE */ | |
42 | ||
43 | typedef size_t (*proto_t) (const CHAR *, size_t); | |
44 | size_t SIMPLE_STRNLEN (const CHAR *, size_t); | |
45 | ||
46 | IMPL (SIMPLE_STRNLEN, 0) | |
47 | IMPL (STRNLEN, 1) | |
24fb0f88 UD |
48 | |
49 | size_t | |
fcf40ebe | 50 | SIMPLE_STRNLEN (const CHAR *s, size_t maxlen) |
24fb0f88 UD |
51 | { |
52 | size_t i; | |
53 | ||
54 | for (i = 0; i < maxlen && s[i]; ++i); | |
55 | return i; | |
56 | } | |
57 | ||
58 | static void | |
fcf40ebe | 59 | do_one_test (impl_t *impl, const CHAR *s, size_t maxlen, size_t exp_len) |
24fb0f88 UD |
60 | { |
61 | size_t len = CALL (impl, s, maxlen); | |
62 | if (len != exp_len) | |
63 | { | |
64 | error (0, 0, "Wrong result in function %s %zd %zd", impl->name, | |
65 | len, exp_len); | |
66 | ret = 1; | |
67 | return; | |
68 | } | |
24fb0f88 UD |
69 | } |
70 | ||
71 | static void | |
72 | do_test (size_t align, size_t len, size_t maxlen, int max_char) | |
73 | { | |
74 | size_t i; | |
75 | ||
fcf40ebe SL |
76 | align &= 63; |
77 | if ((align + len) * sizeof (CHAR) >= page_size) | |
24fb0f88 UD |
78 | return; |
79 | ||
fcf40ebe SL |
80 | CHAR *buf = (CHAR *) (buf1); |
81 | ||
24fb0f88 | 82 | for (i = 0; i < len; ++i) |
fcf40ebe SL |
83 | buf[align + i] = 1 + 11111 * i % max_char; |
84 | buf[align + len] = 0; | |
24fb0f88 | 85 | |
24fb0f88 | 86 | FOR_EACH_IMPL (impl, 0) |
fcf40ebe | 87 | do_one_test (impl, (CHAR *) (buf + align), maxlen, MIN (len, maxlen)); |
24fb0f88 UD |
88 | } |
89 | ||
90 | static void | |
91 | do_random_tests (void) | |
92 | { | |
93 | size_t i, j, n, align, len; | |
fcf40ebe | 94 | CHAR *p = (CHAR *) (buf1 + page_size - 512 * sizeof (CHAR)); |
24fb0f88 UD |
95 | |
96 | for (n = 0; n < ITERATIONS; n++) | |
97 | { | |
98 | align = random () & 15; | |
99 | len = random () & 511; | |
100 | if (len + align > 510) | |
101 | len = 511 - align - (random () & 7); | |
102 | j = len + align + 64; | |
103 | if (j > 512) | |
104 | j = 512; | |
105 | ||
106 | for (i = 0; i < j; i++) | |
107 | { | |
108 | if (i == len + align) | |
109 | p[i] = 0; | |
110 | else | |
111 | { | |
112 | p[i] = random () & 255; | |
113 | if (i >= align && i < len + align && !p[i]) | |
114 | p[i] = (random () & 127) + 1; | |
115 | } | |
116 | } | |
117 | ||
118 | FOR_EACH_IMPL (impl, 1) | |
119 | { | |
120 | if (len > 0 | |
fcf40ebe | 121 | && CALL (impl, (CHAR *) (p + align), len - 1) != len - 1) |
24fb0f88 UD |
122 | { |
123 | error (0, 0, "Iteration %zd (limited) - wrong result in function %s (%zd) %zd != %zd, p %p", | |
124 | n, impl->name, align, | |
fcf40ebe | 125 | CALL (impl, (CHAR *) (p + align), len - 1), len - 1, p); |
24fb0f88 UD |
126 | ret = 1; |
127 | } | |
fcf40ebe | 128 | if (CALL (impl, (CHAR *) (p + align), len) != len) |
24fb0f88 UD |
129 | { |
130 | error (0, 0, "Iteration %zd (exact) - wrong result in function %s (%zd) %zd != %zd, p %p", | |
131 | n, impl->name, align, | |
fcf40ebe | 132 | CALL (impl, (CHAR *) (p + align), len), len, p); |
24fb0f88 UD |
133 | ret = 1; |
134 | } | |
fcf40ebe | 135 | if (CALL (impl, (CHAR *) (p + align), len + 1) != len) |
24fb0f88 UD |
136 | { |
137 | error (0, 0, "Iteration %zd (long) - wrong result in function %s (%zd) %zd != %zd, p %p", | |
138 | n, impl->name, align, | |
fcf40ebe | 139 | CALL (impl, (CHAR *) (p + align), len + 1), len, p); |
24fb0f88 UD |
140 | ret = 1; |
141 | } | |
142 | } | |
143 | } | |
144 | } | |
145 | ||
ff65c874 WSM |
146 | /* Tests meant to unveil fail on implementation that does not access bytes |
147 | around the page boundary accordingly. */ | |
148 | static void | |
149 | do_page_tests (void) | |
150 | { | |
151 | size_t i, exp_len, start_offset, offset; | |
152 | /* Calculate the null character offset. */ | |
153 | size_t last_offset = (page_size / sizeof (CHAR)) - 1; | |
154 | ||
155 | CHAR *s = (CHAR *) buf2; | |
156 | memset (s, 65, (last_offset - 1)); | |
157 | s[last_offset] = 0; | |
158 | ||
159 | /* Place short strings ending at page boundary. */ | |
160 | offset = last_offset; | |
161 | for (i = 0; i < 128; i++) | |
162 | { | |
163 | /* Decrease offset to stress several sizes and alignments. */ | |
164 | offset--; | |
165 | exp_len = last_offset - offset; | |
166 | FOR_EACH_IMPL (impl, 0) | |
167 | { | |
168 | /* Varies maxlen value to cover the cases where it is: | |
169 | - larger than length; | |
170 | - slightly greater than length; | |
171 | - equal to length; | |
172 | - slightly less than length. */ | |
173 | do_one_test (impl, (CHAR *) (s + offset), page_size, exp_len); | |
174 | do_one_test (impl, (CHAR *) (s + offset), exp_len + 1, exp_len); | |
175 | do_one_test (impl, (CHAR *) (s + offset), exp_len, exp_len); | |
176 | if (exp_len > 0) | |
177 | do_one_test (impl, (CHAR *) (s + offset), exp_len - 1, exp_len - 1); | |
178 | } | |
179 | } | |
180 | ||
181 | /* Place long strings ending at page boundary. */ | |
182 | start_offset = (last_offset + 1) / 2; | |
183 | for (i = 0; i < 64; ++i) | |
184 | { | |
185 | /* Increase offset to stress several alignments. */ | |
186 | offset = start_offset + i; | |
187 | if (offset >= (last_offset + 1)) | |
188 | break; | |
189 | exp_len = last_offset - offset; | |
190 | FOR_EACH_IMPL (impl, 0) | |
191 | { | |
192 | /* Checks only for maxlen much larger than length because smaller | |
193 | values are already covered in do_random_tests function. */ | |
194 | do_one_test (impl, (CHAR *) (s + offset), page_size, exp_len); | |
195 | } | |
196 | } | |
197 | } | |
198 | ||
24fb0f88 UD |
199 | int |
200 | test_main (void) | |
201 | { | |
202 | size_t i; | |
203 | ||
204 | test_init (); | |
205 | ||
206 | printf ("%20s", ""); | |
207 | FOR_EACH_IMPL (impl, 0) | |
208 | printf ("\t%s", impl->name); | |
209 | putchar ('\n'); | |
210 | ||
211 | for (i = 1; i < 8; ++i) | |
212 | { | |
fcf40ebe SL |
213 | do_test (0, i, i - 1, MIDDLE_CHAR); |
214 | do_test (0, i, i, MIDDLE_CHAR); | |
215 | do_test (0, i, i + 1, MIDDLE_CHAR); | |
24fb0f88 UD |
216 | } |
217 | ||
218 | for (i = 1; i < 8; ++i) | |
219 | { | |
fcf40ebe SL |
220 | do_test (i, i, i - 1, MIDDLE_CHAR); |
221 | do_test (i, i, i, MIDDLE_CHAR); | |
222 | do_test (i, i, i + 1, MIDDLE_CHAR); | |
24fb0f88 UD |
223 | } |
224 | ||
225 | for (i = 2; i <= 10; ++i) | |
226 | { | |
fcf40ebe SL |
227 | do_test (0, 1 << i, 5000, MIDDLE_CHAR); |
228 | do_test (1, 1 << i, 5000, MIDDLE_CHAR); | |
24fb0f88 UD |
229 | } |
230 | ||
231 | for (i = 1; i < 8; ++i) | |
fcf40ebe | 232 | do_test (0, i, 5000, BIG_CHAR); |
24fb0f88 UD |
233 | |
234 | for (i = 1; i < 8; ++i) | |
fcf40ebe | 235 | do_test (i, i, 5000, BIG_CHAR); |
24fb0f88 UD |
236 | |
237 | for (i = 2; i <= 10; ++i) | |
238 | { | |
fcf40ebe SL |
239 | do_test (0, 1 << i, 5000, BIG_CHAR); |
240 | do_test (1, 1 << i, 5000, BIG_CHAR); | |
24fb0f88 UD |
241 | } |
242 | ||
243 | do_random_tests (); | |
ff65c874 | 244 | do_page_tests (); |
24fb0f88 UD |
245 | return ret; |
246 | } | |
247 | ||
fb82116f | 248 | #include <support/test-driver.c> |