]>
Commit | Line | Data |
---|---|---|
f63abf58 | 1 | /* Test and measure memmem functions. |
04277e02 | 2 | Copyright (C) 2008-2019 Free Software Foundation, Inc. |
f63abf58 UD |
3 | This file is part of the GNU C Library. |
4 | Written by Ulrich Drepper <drepper@redhat.com>, 2008. | |
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/>. */ | |
f63abf58 UD |
19 | |
20 | #define TEST_MAIN | |
69f07e5f | 21 | #define TEST_NAME "memmem" |
f63abf58 UD |
22 | #define BUF1PAGES 20 |
23 | #define ITERATIONS 500 | |
24 | #include "test-string.h" | |
25 | ||
26 | typedef char *(*proto_t) (const void *, size_t, const void *, size_t); | |
27 | void *simple_memmem (const void *, size_t, const void *, size_t); | |
28 | ||
29 | IMPL (simple_memmem, 0) | |
30 | IMPL (memmem, 1) | |
31 | ||
32 | void * | |
33 | simple_memmem (const void *haystack, size_t haystack_len, const void *needle, | |
34 | size_t needle_len) | |
35 | { | |
36 | const char *begin; | |
37 | const char *const last_possible | |
38 | = (const char *) haystack + haystack_len - needle_len; | |
39 | ||
40 | if (needle_len == 0) | |
41 | /* The first occurrence of the empty string is deemed to occur at | |
42 | the beginning of the string. */ | |
43 | return (void *) haystack; | |
44 | ||
45 | /* Sanity check, otherwise the loop might search through the whole | |
46 | memory. */ | |
a1ffb40e | 47 | if (__glibc_unlikely (haystack_len < needle_len)) |
f63abf58 UD |
48 | return NULL; |
49 | ||
50 | for (begin = (const char *) haystack; begin <= last_possible; ++begin) | |
51 | if (begin[0] == ((const char *) needle)[0] && | |
52 | !memcmp ((const void *) &begin[1], | |
53 | (const void *) ((const char *) needle + 1), | |
54 | needle_len - 1)) | |
55 | return (void *) begin; | |
56 | ||
57 | return NULL; | |
58 | } | |
59 | ||
38c78296 L |
60 | static int |
61 | check_result (impl_t *impl, const void *haystack, size_t haystack_len, | |
f63abf58 UD |
62 | const void *needle, size_t needle_len, const void *expected) |
63 | { | |
64 | void *res; | |
65 | ||
66 | res = CALL (impl, haystack, haystack_len, needle, needle_len); | |
67 | if (res != expected) | |
68 | { | |
69 | error (0, 0, "Wrong result in function %s %p %p", impl->name, | |
70 | res, expected); | |
71 | ret = 1; | |
38c78296 | 72 | return -1; |
f63abf58 UD |
73 | } |
74 | ||
38c78296 L |
75 | return 0; |
76 | } | |
77 | ||
78 | static void | |
79 | do_one_test (impl_t *impl, const void *haystack, size_t haystack_len, | |
80 | const void *needle, size_t needle_len, const void *expected) | |
81 | { | |
82 | if (check_result (impl, haystack, haystack_len, needle, needle_len, | |
83 | expected) < 0) | |
84 | return; | |
f63abf58 UD |
85 | } |
86 | ||
87 | static void | |
88 | do_test (const char *str, size_t len, size_t idx) | |
89 | { | |
90 | char tmpbuf[len]; | |
91 | ||
92 | memcpy (tmpbuf, buf1 + idx, len); | |
93 | memcpy (buf1 + idx, str, len); | |
94 | ||
f63abf58 UD |
95 | FOR_EACH_IMPL (impl, 0) |
96 | do_one_test (impl, buf1, BUF1PAGES * page_size, str, len, buf1 + idx); | |
97 | ||
98 | memcpy (buf1 + idx, tmpbuf, len); | |
f63abf58 UD |
99 | } |
100 | ||
101 | static void | |
102 | do_random_tests (void) | |
103 | { | |
104 | for (size_t n = 0; n < ITERATIONS; ++n) | |
105 | { | |
106 | char tmpbuf[32]; | |
107 | ||
108 | size_t shift = random () % 11; | |
109 | size_t rel = random () % ((2 << (shift + 1)) * 64); | |
110 | size_t idx = MIN ((2 << shift) * 64 + rel, BUF1PAGES * page_size - 2); | |
111 | size_t len = random () % (sizeof (tmpbuf) - 1) + 1; | |
112 | len = MIN (len, BUF1PAGES * page_size - idx - 1); | |
113 | memcpy (tmpbuf, buf1 + idx, len); | |
114 | for (size_t i = random () % len / 2 + 1; i > 0; --i) | |
115 | { | |
116 | size_t off = random () % len; | |
117 | char ch = '0' + random () % 10; | |
118 | ||
119 | buf1[idx + off] = ch; | |
120 | } | |
121 | ||
f63abf58 UD |
122 | FOR_EACH_IMPL (impl, 0) |
123 | do_one_test (impl, buf1, BUF1PAGES * page_size, buf1 + idx, len, | |
124 | buf1 + idx); | |
125 | ||
f63abf58 UD |
126 | memcpy (buf1 + idx, tmpbuf, len); |
127 | } | |
128 | } | |
129 | ||
38c78296 L |
130 | static void |
131 | check1 (void) | |
132 | { | |
133 | ||
134 | const char search_buf_data[5] = { 0x56, 0x34, 0x12, 0x78, 0x78 }; | |
135 | const char pattern[2] = { 0x78, 0x56 }; | |
136 | void *search_buf = (void *) buf1 + page_size - sizeof search_buf_data; | |
137 | void *exp_result; | |
138 | ||
139 | memcpy (search_buf, search_buf_data, sizeof search_buf_data); | |
140 | exp_result = simple_memmem (search_buf, sizeof search_buf_data, | |
141 | pattern, sizeof pattern); | |
142 | FOR_EACH_IMPL (impl, 0) | |
143 | check_result (impl, search_buf, sizeof search_buf_data, | |
144 | pattern, sizeof pattern, exp_result); | |
145 | } | |
f63abf58 UD |
146 | |
147 | static const char *const strs[] = | |
148 | { | |
149 | "00000", "00112233", "0123456789", "0000111100001111", | |
150 | "00000111110000022222", "012345678901234567890", | |
151 | "abc0", "aaaa0", "abcabc0" | |
152 | }; | |
153 | ||
154 | ||
155 | int | |
156 | test_main (void) | |
157 | { | |
158 | size_t i; | |
159 | ||
160 | test_init (); | |
161 | ||
38c78296 L |
162 | check1 (); |
163 | ||
f63abf58 UD |
164 | printf ("%23s", ""); |
165 | FOR_EACH_IMPL (impl, 0) | |
166 | printf ("\t%s", impl->name); | |
167 | putchar ('\n'); | |
168 | ||
169 | for (i = 0; i < BUF1PAGES * page_size; ++i) | |
170 | buf1[i] = 60 + random () % 32; | |
171 | ||
172 | for (i = 0; i < sizeof (strs) / sizeof (strs[0]); ++i) | |
173 | for (size_t j = 0; j < 120; j += 7) | |
174 | { | |
175 | size_t len = strlen (strs[i]); | |
176 | ||
177 | do_test (strs[i], len, j); | |
178 | } | |
179 | ||
180 | do_random_tests (); | |
181 | return ret; | |
182 | } | |
183 | ||
fb82116f | 184 | #include <support/test-driver.c> |