1 /* Unit tests for dl-hwcaps.c.
2    Copyright (C) 2020-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
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.
9 
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.
14 
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    <https://www.gnu.org/licenses/>.  */
18 
19 #include <array_length.h>
20 #include <dl-hwcaps.h>
21 #include <string.h>
22 #include <support/check.h>
23 
24 static void
check_split_masked(const char * input,int32_t bitmask,const char * mask,const char * expected[],size_t expected_length)25 check_split_masked (const char *input, int32_t bitmask, const char *mask,
26                     const char *expected[], size_t expected_length)
27 {
28   struct dl_hwcaps_split_masked split;
29   _dl_hwcaps_split_masked_init (&split, input, bitmask, mask);
30   size_t index = 0;
31   while (_dl_hwcaps_split_masked (&split))
32     {
33       TEST_VERIFY_EXIT (index < expected_length);
34       TEST_COMPARE_BLOB (expected[index], strlen (expected[index]),
35                          split.split.segment, split.split.length);
36       ++index;
37     }
38   TEST_COMPARE (index, expected_length);
39 }
40 
41 static void
check_split(const char * input,const char * expected[],size_t expected_length)42 check_split (const char *input,
43              const char *expected[], size_t expected_length)
44 {
45   struct dl_hwcaps_split split;
46   _dl_hwcaps_split_init (&split, input);
47   size_t index = 0;
48   while (_dl_hwcaps_split (&split))
49     {
50       TEST_VERIFY_EXIT (index < expected_length);
51       TEST_COMPARE_BLOB (expected[index], strlen (expected[index]),
52                          split.segment, split.length);
53       ++index;
54     }
55   TEST_COMPARE (index, expected_length);
56 
57   /* Reuse the test cases with masking that does not actually remove
58      anything.  */
59   check_split_masked (input, -1, NULL, expected, expected_length);
60   check_split_masked (input, -1, input, expected, expected_length);
61 }
62 
63 static int
do_test(void)64 do_test (void)
65 {
66   /* Splitting tests, without masking.  */
67   check_split (NULL, NULL, 0);
68   check_split ("", NULL, 0);
69   check_split (":", NULL, 0);
70   check_split ("::", NULL, 0);
71 
72   {
73     const char *expected[] = { "first" };
74     check_split ("first", expected, array_length (expected));
75     check_split (":first", expected, array_length (expected));
76     check_split ("first:", expected, array_length (expected));
77     check_split (":first:", expected, array_length (expected));
78   }
79 
80   {
81     const char *expected[] = { "first", "second" };
82     check_split ("first:second", expected, array_length (expected));
83     check_split ("first::second", expected, array_length (expected));
84     check_split (":first:second", expected, array_length (expected));
85     check_split ("first:second:", expected, array_length (expected));
86     check_split (":first:second:", expected, array_length (expected));
87   }
88 
89   /* Splitting tests with masking.  */
90   {
91     const char *expected[] = { "first" };
92     check_split_masked ("first", 3, "first:second",
93                         expected, array_length (expected));
94     check_split_masked ("first:second", 3, "first:",
95                         expected, array_length (expected));
96     check_split_masked ("first:second", 1, NULL,
97                         expected, array_length (expected));
98   }
99   {
100     const char *expected[] = { "second" };
101     check_split_masked ("first:second", 3, "second",
102                         expected, array_length (expected));
103     check_split_masked ("first:second:third", -1, "second:",
104                         expected, array_length (expected));
105     check_split_masked ("first:second", 2, NULL,
106                         expected, array_length (expected));
107     check_split_masked ("first:second:third", 2, "first:second",
108                         expected, array_length (expected));
109   }
110 
111   /* Tests for _dl_hwcaps_contains.  */
112   TEST_VERIFY (_dl_hwcaps_contains (NULL, "first", strlen ("first")));
113   TEST_VERIFY (_dl_hwcaps_contains (NULL, "", 0));
114   TEST_VERIFY (! _dl_hwcaps_contains ("", "first", strlen ("first")));
115   TEST_VERIFY (! _dl_hwcaps_contains ("firs", "first", strlen ("first")));
116   TEST_VERIFY (_dl_hwcaps_contains ("firs", "first", strlen ("first") - 1));
117   for (int i = 0; i < strlen ("first"); ++i)
118     TEST_VERIFY (! _dl_hwcaps_contains ("first", "first", i));
119   TEST_VERIFY (_dl_hwcaps_contains ("first", "first", strlen ("first")));
120   TEST_VERIFY (_dl_hwcaps_contains ("first:", "first", strlen ("first")));
121   TEST_VERIFY (_dl_hwcaps_contains ("first:second",
122                                     "first", strlen ("first")));
123   TEST_VERIFY (_dl_hwcaps_contains (":first:second", "first",
124                                     strlen ("first")));
125   TEST_VERIFY (_dl_hwcaps_contains ("first:second", "second",
126                                     strlen ("second")));
127   TEST_VERIFY (_dl_hwcaps_contains ("first:second:", "second",
128                                     strlen ("second")));
129   TEST_VERIFY (_dl_hwcaps_contains ("first::second:", "second",
130                                     strlen ("second")));
131   TEST_VERIFY (_dl_hwcaps_contains ("first:second::", "second",
132                                     strlen ("second")));
133   for (int i = 0; i < strlen ("second"); ++i)
134     {
135       TEST_VERIFY (!_dl_hwcaps_contains ("first:second", "second", i));
136       TEST_VERIFY (!_dl_hwcaps_contains ("first:second:", "second", i));
137       TEST_VERIFY (!_dl_hwcaps_contains ("first:second::", "second", i));
138       TEST_VERIFY (!_dl_hwcaps_contains ("first::second", "second", i));
139     }
140 
141   return 0;
142 }
143 
144 #include <support/test-driver.c>
145 
146 /* Rebuild the sources here because the object file is built for
147    inclusion into the dynamic loader.  */
148 #include "dl-hwcaps_split.c"
149