1 /*
2 * Copyright (c) 2011 ARM Ltd
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the company may not be used to endorse or promote
14 * products derived from this software without specific prior written
15 * permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
22 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <stdarg.h>
33
34 /* The macro LONG_TEST controls whether a short or a more comprehensive test
35 of strcmp should be performed. */
36 #ifdef LONG_TEST
37 #ifndef BUFF_SIZE
38 #define BUFF_SIZE 1024
39 #endif
40
41 #ifndef MAX_BLOCK_SIZE
42 #define MAX_BLOCK_SIZE 128
43 #endif
44
45 #ifndef MAX_OFFSET
46 #define MAX_OFFSET 3
47 #endif
48
49 #ifndef MAX_DIFF
50 #define MAX_DIFF 8
51 #endif
52
53 #ifndef MAX_LEN
54 #define MAX_LEN 8
55 #endif
56
57 #ifndef MAX_ZEROS
58 #define MAX_ZEROS 8
59 #endif
60 #else /* not defined LONG_TEST */
61 #ifndef BUFF_SIZE
62 #define BUFF_SIZE 1024
63 #endif
64
65 #ifndef MAX_BLOCK_SIZE
66 #define MAX_BLOCK_SIZE 64
67 #endif
68
69 #ifndef MAX_OFFSET
70 #define MAX_OFFSET 3
71 #endif
72
73 #ifndef MAX_DIFF
74 #define MAX_DIFF 4
75 #endif
76
77 #ifndef MAX_LEN
78 #define MAX_LEN 4
79 #endif
80
81 #ifndef MAX_ZEROS
82 #define MAX_ZEROS 4
83 #endif
84 #endif /* not defined LONG_TEST */
85
86 #if (MAX_OFFSET >= 26)
87 #error "MAX_OFFSET >= 26"
88 #endif
89 #if (MAX_OFFSET + MAX_BLOCK_SIZE + MAX_DIFF + MAX_LEN + MAX_ZEROS >= BUFF_SIZE)
90 #error "Buffer overrun: MAX_OFFSET + MAX_BLOCK_SIZE + MAX_DIFF + MAX_LEN + MAX_ZEROS >= BUFF_SIZE."
91 #endif
92
93
94 #define TOO_MANY_ERRORS 11
95 int errors = 0;
96
97 const char *testname = "strcmp";
98
99 static void
print_error(char const * msg,...)100 print_error (char const* msg, ...)
101 {
102 errors++;
103 if (errors == TOO_MANY_ERRORS)
104 {
105 fprintf (stderr, "Too many errors.\n");
106 }
107 else if (errors < TOO_MANY_ERRORS)
108 {
109 va_list ap;
110 va_start (ap, msg);
111 vfprintf (stderr, msg, ap);
112 va_end (ap);
113 }
114 else
115 {
116 /* Further errors omitted. */
117 }
118 }
119
120 #if 0
121 static void
122 printbuf (char *buf, char *name)
123 {
124 int i;
125 printf ("\n %s=", name);
126 for (i = 0; i < BUFF_SIZE; i++)
127 if (buf[i] != 0)
128 printf ("(%d,%c)", i, buf[i]);
129 else
130 printf ("(%d,%s)", i, "\\0");
131 printf ("\n");
132 }
133 #endif
134
135 int
main(void)136 main (void)
137 {
138 /* Allocate buffers to read and write from. */
139 char src[BUFF_SIZE], dest[BUFF_SIZE];
140
141 /* Fill the source buffer with non-null values, reproducable random data. */
142 srand (1539);
143 unsigned i, j, zeros;
144 unsigned sa;
145 unsigned da;
146 unsigned n, m, len;
147 char *p;
148 int ret;
149
150 /* Make calls to strcmp with block sizes ranging between 1 and
151 MAX_BLOCK_SIZE bytes, aligned and misaligned source and destination. */
152 for (sa = 0; sa <= MAX_OFFSET; sa++)
153 for (da = 0; da <= MAX_OFFSET; da++)
154 for (n = 1; n <= MAX_BLOCK_SIZE; n++)
155 {
156 for (m = 1; m < n + MAX_DIFF; m++)
157 for (len = 0; len < MAX_LEN; len++)
158 for (zeros = 1; zeros < MAX_ZEROS; zeros++)
159 {
160 if (n - m > MAX_DIFF)
161 continue;
162 /* Make a copy of the source. */
163 j = 'A';
164 for (i = 0; i < BUFF_SIZE; i++)
165 {
166 src[i] = j;
167 if (j++ == 'Z') j = 'A';
168 dest[i] = src[i];
169 }
170 memcpy (dest + da, src + sa, n);
171
172 /* Make src 0-terminated. */
173 p = src + sa + n - 1;
174 for (i = 0; i < zeros; i++)
175 {
176 *p++ = '\0';
177 }
178
179 /* Modify dest. */
180 p = dest + da + m - 1;
181 for (j = 0; j < len; j++)
182 *p++ = 'x';
183 /* Make dest 0-terminated. */
184 *p = '\0';
185
186 ret = strcmp (src + sa, dest + da);
187
188 /* Check return value. */
189 if (n == m)
190 {
191 if (len == 0)
192 {
193 if (ret != 0)
194 {
195 print_error ("\nFailed: after %s of %u bytes "
196 "with src_align %u and dst_align %u, "
197 "dest after %d bytes is modified for %d bytes, "
198 "return value is %d, expected 0.\n",
199 testname, n, sa, da, m, len, ret);
200 }
201 }
202 else
203 {
204 if (ret >= 0)
205 print_error ("\nFailed: after %s of %u bytes "
206 "with src_align %u and dst_align %u, "
207 "dest after %d bytes is modified for %d bytes, "
208 "return value is %d, expected negative.\n",
209 testname, n, sa, da, m, len, ret);
210 }
211 }
212 else if (m > n)
213 {
214 if (ret >= 0)
215 {
216 print_error ("\nFailed: after %s of %u bytes "
217 "with src_align %u and dst_align %u, "
218 "dest after %d bytes is modified for %d bytes, "
219 "return value is %d, expected negative.\n",
220 testname, n, sa, da, m, len, ret);
221 }
222 }
223 else /* m < n */
224 {
225 if (len == 0)
226 {
227 if (ret <= 0)
228 print_error ("\nFailed: after %s of %u bytes "
229 "with src_align %u and dst_align %u, "
230 "dest after %d bytes is modified for %d bytes, "
231 "return value is %d, expected positive.\n",
232 testname, n, sa, da, m, len, ret);
233 }
234 else
235 {
236 if (ret >= 0)
237 print_error ("\nFailed: after %s of %u bytes "
238 "with src_align %u and dst_align %u, "
239 "dest after %d bytes is modified for %d bytes, "
240 "return value is %d, expected negative.\n",
241 testname, n, sa, da, m, len, ret);
242 }
243 }
244 }
245 }
246
247 /* Check some corner cases. */
248 src[1] = 'A';
249 dest[1] = 'A';
250 src[2] = 'B';
251 dest[2] = 'B';
252 src[3] = 'C';
253 dest[3] = 'C';
254 src[4] = '\0';
255 dest[4] = '\0';
256
257 src[0] = 0xc1;
258 dest[0] = 0x41;
259 ret = strcmp (src, dest);
260 if (ret <= 0)
261 print_error ("\nFailed: expected positive, return %d\n", ret);
262
263 src[0] = 0x01;
264 dest[0] = 0x82;
265 ret = strcmp (src, dest);
266 if (ret >= 0)
267 print_error ("\nFailed: expected negative, return %d\n", ret);
268
269 dest[0] = src[0] = 'D';
270 src[3] = 0xc1;
271 dest[3] = 0x41;
272 ret = strcmp (src, dest);
273 if (ret <= 0)
274 print_error ("\nFailed: expected positive, return %d\n", ret);
275
276 src[3] = 0x01;
277 dest[3] = 0x82;
278 ret = strcmp (src, dest);
279 if (ret >= 0)
280 print_error ("\nFailed: expected negative, return %d\n", ret);
281
282 printf ("\n");
283 if (errors != 0)
284 {
285 printf ("ERROR. FAILED.\n");
286 abort ();
287 }
288 exit (0);
289 }
290