Fix cexpl when compiled with latest GCC
[glibc.git] / string / tst-cmp.c
blob7ddbd0b24e3beedc9d97c31ecb0de40f9fb31654
1 /* Alignment/padding coverage test for string comparison.
2 Copyright (C) 2016-2017 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 <stdint.h>
27 #include <stdlib.h>
28 #include <string.h>
30 static int
31 signum (int val)
33 if (val < 0)
34 return -1;
35 if (val > 0)
36 return 1;
37 else
38 return 0;
41 static size_t
42 max_size_t (size_t left, size_t right)
44 if (left > right)
45 return left;
46 else
47 return right;
50 /* Wrappers for strncmp and strncasecmp which determine the maximum
51 string length in some, either based on the input string length, or
52 using fixed constants. */
54 static int
55 strncmp_no_terminator (const char *left, const char *right)
57 size_t left_len = strlen (left);
58 size_t right_len = strlen (right);
59 return strncmp (left, right, max_size_t (left_len, right_len));
62 static int
63 strncasecmp_no_terminator (const char *left, const char *right)
65 size_t left_len = strlen (left);
66 size_t right_len = strlen (right);
67 return strncasecmp (left, right, max_size_t (left_len, right_len));
70 static int
71 strncmp_terminator (const char *left, const char *right)
73 size_t left_len = strlen (left);
74 size_t right_len = strlen (right);
75 return strncmp (left, right, max_size_t (left_len, right_len));
78 static int
79 strncasecmp_terminator (const char *left, const char *right)
81 size_t left_len = strlen (left);
82 size_t right_len = strlen (right);
83 return strncasecmp (left, right, max_size_t (left_len, right_len));
86 static int
87 strncmp_64 (const char *left, const char *right)
89 return strncmp (left, right, 64);
92 static int
93 strncasecmp_64 (const char *left, const char *right)
95 return strncasecmp (left, right, 64);
98 static int
99 strncmp_max (const char *left, const char *right)
101 return strncmp (left, right, SIZE_MAX);
104 static int
105 strncasecmp_max (const char *left, const char *right)
107 return strncasecmp (left, right, SIZE_MAX);
111 do_test (void)
113 enum {
114 max_align = 64,
115 max_string_length = 33
117 size_t blob_size = max_align + max_string_length + 1;
118 char *left = memalign (max_align, blob_size);
119 char *right = memalign (max_align, blob_size);
120 if (left == NULL || right == NULL)
122 printf ("error: out of memory\n");
123 return 1;
126 const struct
128 const char *name;
129 int (*implementation) (const char *, const char *);
130 } functions[] =
132 { "strcmp", strcmp },
133 { "strcasecmp", strcasecmp },
134 { "strncmp (without NUL)", strncmp_no_terminator},
135 { "strncasecmp (without NUL)", strncasecmp_no_terminator},
136 { "strncmp (with NUL)", strncmp_terminator},
137 { "strncasecmp (with NUL)", strncasecmp_terminator},
138 { "strncmp (length 64)", strncmp_64},
139 { "strncasecmp (length 64)", strncasecmp_64},
140 { "strncmp (length SIZE_MAX)", strncmp_max},
141 { "strncasecmp (length SIZE_MAX)", strncasecmp_max},
142 { NULL, NULL }
144 const char *const strings[] =
147 "0",
148 "01",
149 "01234567",
150 "0123456789abcde",
151 "0123456789abcdef",
152 "0123456789abcdefg",
153 "1",
154 "10",
155 "123456789abcdef",
156 "123456789abcdefg",
157 "23456789abcdef",
158 "23456789abcdefg",
159 "abcdefghijklmnopqrstuvwxyzABCDEF",
160 NULL
162 const unsigned char pads[] =
163 { 0, 1, 32, 64, 128, '0', '1', 'e', 'f', 'g', 127, 192, 255 };
165 bool errors = false;
166 for (int left_idx = 0; strings[left_idx] != NULL; ++left_idx)
167 for (int left_align = 0; left_align < max_align; ++left_align)
168 for (unsigned pad_left = 0; pad_left < sizeof (pads); ++pad_left)
170 memset (left, pads[pad_left], blob_size);
171 strcpy (left + left_align, strings[left_idx]);
173 for (int right_idx = 0; strings[right_idx] != NULL; ++right_idx)
174 for (unsigned pad_right = 0; pad_right < sizeof (pads);
175 ++pad_right)
176 for (int right_align = 0; right_align < max_align;
177 ++right_align)
179 memset (right, pads[pad_right], blob_size);
180 strcpy (right + right_align, strings[right_idx]);
182 for (int func = 0; functions[func].name != NULL; ++func)
184 int expected = left_idx - right_idx;
185 int actual = functions[func].implementation
186 (left + left_align, right + right_align);
187 if (signum (actual) != signum (expected))
189 printf ("error: mismatch for %s: %d\n"
190 " left: \"%s\"\n"
191 " right: \"%s\"\n"
192 " pad_left = %u, pad_right = %u,\n"
193 " left_align = %d, right_align = %d\n",
194 functions[func].name, actual,
195 strings[left_idx], strings[right_idx],
196 pad_left, pad_right,
197 left_align, right_align);
198 errors = true;
203 free (right);
204 free (left);
205 return errors;
208 /* The nested loops need a long time to complete on slower
209 machines. */
210 #define TIMEOUT 600
212 #include <support/test-driver.c>