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