Update comments for some functions in s_sin.c
[glibc.git] / string / tst-cmp.c
bloba3584770072f7b8c8ad02f9024d690613dfd297c
1 /* Alignment/padding coverage test for string comparison.
2 Copyright (C) 2016 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 /* This performs test comparisons with various (mis)alignments and
20 characters in the padding. It is partly a regression test for bug
21 20327. */
23 #include <limits.h>
24 #include <malloc.h>
25 #include <stdbool.h>
26 #include <stdlib.h>
27 #include <string.h>
29 static int
30 signum (int val)
32 if (val < 0)
33 return -1;
34 if (val > 0)
35 return 1;
36 else
37 return 0;
40 static size_t
41 max_size_t (size_t left, size_t right)
43 if (left > right)
44 return left;
45 else
46 return right;
49 /* Wrappers for strncmp and strncasecmp which determine the maximum
50 string length in some, either based on the input string length, or
51 using fixed constants. */
53 static int
54 strncmp_no_terminator (const char *left, const char *right)
56 size_t left_len = strlen (left);
57 size_t right_len = strlen (right);
58 return strncmp (left, right, max_size_t (left_len, right_len));
61 static int
62 strncasecmp_no_terminator (const char *left, const char *right)
64 size_t left_len = strlen (left);
65 size_t right_len = strlen (right);
66 return strncasecmp (left, right, max_size_t (left_len, right_len));
69 static int
70 strncmp_terminator (const char *left, const char *right)
72 size_t left_len = strlen (left);
73 size_t right_len = strlen (right);
74 return strncmp (left, right, max_size_t (left_len, right_len));
77 static int
78 strncasecmp_terminator (const char *left, const char *right)
80 size_t left_len = strlen (left);
81 size_t right_len = strlen (right);
82 return strncasecmp (left, right, max_size_t (left_len, right_len));
85 static int
86 strncmp_64 (const char *left, const char *right)
88 return strncmp (left, right, 64);
91 static int
92 strncasecmp_64 (const char *left, const char *right)
94 return strncasecmp (left, right, 64);
97 static int
98 strncmp_max (const char *left, const char *right)
100 return strncmp (left, right, SIZE_MAX);
103 static int
104 strncasecmp_max (const char *left, const char *right)
106 return strncasecmp (left, right, SIZE_MAX);
109 static int
110 do_test (void)
112 enum {
113 max_align = 64,
114 max_string_length = 33
116 size_t blob_size = max_align + max_string_length + 1;
117 char *left = memalign (max_align, blob_size);
118 char *right = memalign (max_align, blob_size);
119 if (left == NULL || right == NULL)
121 printf ("error: out of memory\n");
122 return 1;
125 const struct
127 const char *name;
128 int (*implementation) (const char *, const char *);
129 } functions[] =
131 { "strcmp", strcmp },
132 { "strcasecmp", strcasecmp },
133 { "strncmp (without NUL)", strncmp_no_terminator},
134 { "strncasecmp (without NUL)", strncasecmp_no_terminator},
135 { "strncmp (with NUL)", strncmp_terminator},
136 { "strncasecmp (with NUL)", strncasecmp_terminator},
137 { "strncmp (length 64)", strncmp_64},
138 { "strncasecmp (length 64)", strncasecmp_64},
139 { "strncmp (length SIZE_MAX)", strncmp_max},
140 { "strncasecmp (length SIZE_MAX)", strncasecmp_max},
141 { NULL, NULL }
143 const char *const strings[] =
146 "0",
147 "01",
148 "01234567",
149 "0123456789abcde",
150 "0123456789abcdef",
151 "0123456789abcdefg",
152 "1",
153 "10",
154 "123456789abcdef",
155 "123456789abcdefg",
156 "23456789abcdef",
157 "23456789abcdefg",
158 "abcdefghijklmnopqrstuvwxyzABCDEF",
159 NULL
161 const unsigned char pads[] =
162 { 0, 1, 32, 64, 128, '0', '1', 'e', 'f', 'g', 127, 192, 255 };
164 bool errors = false;
165 for (int left_idx = 0; strings[left_idx] != NULL; ++left_idx)
166 for (int left_align = 0; left_align < max_align; ++left_align)
167 for (unsigned pad_left = 0; pad_left < sizeof (pads); ++pad_left)
169 memset (left, pads[pad_left], blob_size);
170 strcpy (left + left_align, strings[left_idx]);
172 for (int right_idx = 0; strings[right_idx] != NULL; ++right_idx)
173 for (unsigned pad_right = 0; pad_right < sizeof (pads);
174 ++pad_right)
175 for (int right_align = 0; right_align < max_align;
176 ++right_align)
178 memset (right, pads[pad_right], blob_size);
179 strcpy (right + right_align, strings[right_idx]);
181 for (int func = 0; functions[func].name != NULL; ++func)
183 int expected = left_idx - right_idx;
184 int actual = functions[func].implementation
185 (left + left_align, right + right_align);
186 if (signum (actual) != signum (expected))
188 printf ("error: mismatch for %s: %d\n"
189 " left: \"%s\"\n"
190 " right: \"%s\"\n"
191 " pad_left = %u, pad_right = %u,\n"
192 " left_align = %d, right_align = %d\n",
193 functions[func].name, actual,
194 strings[left_idx], strings[right_idx],
195 pad_left, pad_right,
196 left_align, right_align);
197 errors = true;
202 free (right);
203 free (left);
204 return errors;
207 /* The nested loops need a long time to complete on slower
208 machines. */
209 #define TIMEOUT 300
211 #define TEST_FUNCTION do_test ()
212 #include "../test-skeleton.c"