1 /*
2 * bitset_test.c
3 * Test for bitset.
4 *
5 * Copyright (C) 2001-2017 Cosmin Truta.
6 *
7 * This software is distributed under the zlib license.
8 * Please see the accompanying LICENSE file.
9 */
10
11 #include "bitset.h"
12
13 #include <errno.h>
14 #include <limits.h>
15 #include <stdio.h>
16
17
18 static int num_tests = 0;
19 static int num_errors = 0;
20
21 #define EMPTY OPNG_BITSET_EMPTY
22 #define FULL OPNG_BITSET_FULL
23 #define ELT_MIN OPNG_BITSET_ELT_MIN
24 #define ELT_MAX OPNG_BITSET_ELT_MAX
25
26 #define TEST_BOOL(expr) \
27 test_int_impl("!!(" #expr ")", !!(expr), 1)
28
29 #define TEST_INT(expr, expected) \
30 test_int_impl(#expr, expr, expected)
31
32 #define TEST_BITSET(expr, expected) \
33 test_bitset_impl(#expr, expr, expected)
34
35 static void
test_int_impl(const char * expr_str,int result,int expected)36 test_int_impl(const char *expr_str, int result, int expected)
37 {
38 ++num_tests;
39 if (result != expected)
40 {
41 ++num_errors;
42 printf("FAILED: %s, result: %d, expected: %d\n",
43 expr_str, result, expected);
44 }
45 }
46
47 static void
test_bitset_impl(const char * expr_str,opng_bitset_t result,opng_bitset_t expected)48 test_bitset_impl(const char *expr_str,
49 opng_bitset_t result, opng_bitset_t expected)
50 {
51 ++num_tests;
52 if (result != expected)
53 {
54 ++num_errors;
55 printf("FAILED: %s, result: 0x%lx, expected: 0x%lx\n",
56 expr_str, (unsigned long)result, (unsigned long)expected);
57 }
58 }
59
60 static void
test_bitset_const()61 test_bitset_const()
62 {
63 printf("Testing: bitset constants\n");
64
65 TEST_BITSET(EMPTY, 0);
66 TEST_BITSET(FULL, ~EMPTY);
67
68 TEST_INT(ELT_MIN, 0);
69 TEST_INT(ELT_MAX, (int)OPNG_BITSIZEOF(opng_bitset_t) - 1);
70 TEST_INT(ELT_MAX, (int)(sizeof(opng_bitset_t) * CHAR_BIT) - 1);
71 }
72
73 static void
test_bitset_obs()74 test_bitset_obs()
75 {
76 printf("Testing: bitset observers\n");
77
78 TEST_INT(opng_bitset_test(EMPTY, ELT_MIN), 0);
79 TEST_INT(opng_bitset_test(EMPTY, ELT_MAX), 0);
80 TEST_INT(opng_bitset_test(FULL, ELT_MIN), 1);
81 TEST_INT(opng_bitset_test(FULL, ELT_MAX), 1);
82 TEST_INT(opng_bitset_test(0x0002, ELT_MIN), 0);
83 TEST_INT(opng_bitset_test(0x0ff0, ELT_MAX), 0);
84 TEST_INT(opng_bitset_test(EMPTY, 1), 0);
85 TEST_INT(opng_bitset_test(FULL, 1), 1);
86 TEST_INT(opng_bitset_test(0x0002, 1), 1);
87 TEST_INT(opng_bitset_test(0x0ff0, 1), 0);
88
89 TEST_INT(opng_bitset_test_all_in_range(EMPTY, ELT_MIN, ELT_MAX), 0);
90 TEST_INT(opng_bitset_test_all_in_range(FULL, ELT_MIN, ELT_MAX), 1);
91 TEST_INT(opng_bitset_test_all_in_range(0x0002, ELT_MIN, ELT_MAX), 0);
92 TEST_INT(opng_bitset_test_all_in_range(0x0ff0, ELT_MIN, ELT_MAX), 0);
93 TEST_INT(opng_bitset_test_all_in_range(EMPTY, 1, 1), 0);
94 TEST_INT(opng_bitset_test_all_in_range(FULL, 1, 1), 1);
95 TEST_INT(opng_bitset_test_all_in_range(0x0002, 1, 1), 1);
96 TEST_INT(opng_bitset_test_all_in_range(0x0ff0, 1, 1), 0);
97
98 TEST_INT(opng_bitset_test_any_in_range(EMPTY, ELT_MIN, ELT_MAX), 0);
99 TEST_INT(opng_bitset_test_any_in_range(FULL, ELT_MIN, ELT_MAX), 1);
100 TEST_INT(opng_bitset_test_any_in_range(0x0002, ELT_MIN, ELT_MAX), 1);
101 TEST_INT(opng_bitset_test_any_in_range(0x0ff0, ELT_MIN, ELT_MAX), 1);
102 TEST_INT(opng_bitset_test_any_in_range(EMPTY, 1, 1), 0);
103 TEST_INT(opng_bitset_test_any_in_range(FULL, 1, 1), 1);
104 TEST_INT(opng_bitset_test_any_in_range(0x0002, 1, 1), 1);
105 TEST_INT(opng_bitset_test_any_in_range(0x0ff0, 1, 1), 0);
106
107 TEST_INT(opng_bitset_count(EMPTY), 0);
108 TEST_INT(opng_bitset_count(FULL), OPNG_BITSIZEOF(opng_bitset_t));
109 TEST_INT(opng_bitset_count(0x0002), 1);
110 TEST_INT(opng_bitset_count(0x0ff0), 8);
111 }
112
113 static void
test_bitset_mod()114 test_bitset_mod()
115 {
116 opng_bitset_t set;
117
118 printf("Testing: bitset modifiers\n");
119
120 set = 0x0002;
121 opng_bitset_set(&set, 1);
122 opng_bitset_set(&set, 2);
123 TEST_BITSET(set, 0x06);
124 opng_bitset_reset(&set, 2);
125 opng_bitset_reset(&set, 3);
126 TEST_BITSET(set, 0x0002);
127 opng_bitset_flip(&set, 3);
128 opng_bitset_flip(&set, 1);
129 TEST_BITSET(set, 0x08);
130
131 set = 0x0ff0;
132 opng_bitset_set_range(&set, 0, 7);
133 TEST_BITSET(set, 0x0fff);
134 opng_bitset_set_range(&set, ELT_MIN, ELT_MAX);
135 TEST_BITSET(set, FULL);
136 set = 0x0ff0;
137 opng_bitset_reset_range(&set, 0, 7);
138 TEST_BITSET(set, 0x0f00);
139 opng_bitset_reset_range(&set, ELT_MIN, ELT_MAX);
140 TEST_BITSET(set, EMPTY);
141 set = 0x0ff0;
142 opng_bitset_flip_range(&set, 0, 7);
143 TEST_BITSET(set, 0x0f0f);
144 opng_bitset_flip_range(&set, ELT_MIN, ELT_MAX);
145 TEST_BITSET(set, FULL ^ 0x0f0f);
146 }
147
148 static void
test_bitset_find_forward_impl(opng_bitset_t bitset)149 test_bitset_find_forward_impl(opng_bitset_t bitset)
150 {
151 opng_bitset_t check_bitset;
152 int check_count;
153 int elt, prev_elt;
154
155 check_bitset = EMPTY;
156 check_count = 0;
157 prev_elt = -1;
158 for (elt = opng_bitset_find_first(bitset);
159 elt >= 0;
160 elt = opng_bitset_find_next(bitset, elt))
161 {
162 if (elt < ELT_MIN || elt > ELT_MAX || elt <= prev_elt)
163 {
164 /* Fail. */
165 TEST_INT(check_count, -1);
166 return;
167 }
168 opng_bitset_set(&check_bitset, elt);
169 ++check_count;
170 prev_elt = elt;
171 }
172 TEST_BITSET(check_bitset, bitset);
173 TEST_INT(check_count, opng_bitset_count(bitset));
174 }
175
176 static void
test_bitset_find_reverse_impl(opng_bitset_t bitset)177 test_bitset_find_reverse_impl(opng_bitset_t bitset)
178 {
179 opng_bitset_t check_bitset;
180 int check_count;
181 int elt, prev_elt;
182
183 check_bitset = EMPTY;
184 check_count = 0;
185 prev_elt = INT_MAX;
186 for (elt = opng_bitset_find_last(bitset);
187 elt >= 0;
188 elt = opng_bitset_find_prev(bitset, elt))
189 {
190 if (elt < ELT_MIN || elt > ELT_MAX || elt >= prev_elt)
191 {
192 /* Fail. */
193 TEST_INT(check_count, -1);
194 return;
195 }
196 opng_bitset_set(&check_bitset, elt);
197 ++check_count;
198 prev_elt = elt;
199 }
200 TEST_BITSET(check_bitset, bitset);
201 TEST_INT(check_count, opng_bitset_count(bitset));
202 }
203
204 static void
test_bitset_iter()205 test_bitset_iter()
206 {
207 printf("Testing: bitset iterators\n");
208
209 TEST_INT(opng_bitset_find_first(EMPTY), -1);
210 TEST_INT(opng_bitset_find_first(FULL), ELT_MIN);
211 TEST_INT(opng_bitset_find_first(0x0002), 1);
212 TEST_INT(opng_bitset_find_first(0x0ff0), 4);
213
214 TEST_INT(opng_bitset_find_next(EMPTY, 0), -1);
215 TEST_INT(opng_bitset_find_next(FULL, 0), 1);
216 TEST_INT(opng_bitset_find_next(0x0002, 0), 1);
217 TEST_INT(opng_bitset_find_next(0x0ff0, 0), 4);
218 TEST_INT(opng_bitset_find_next(EMPTY, 1), -1);
219 TEST_INT(opng_bitset_find_next(FULL, 1), 2);
220 TEST_INT(opng_bitset_find_next(0x0002, 1), -1);
221 TEST_INT(opng_bitset_find_next(0x0ff0, 1), 4);
222 TEST_INT(opng_bitset_find_next(EMPTY, 2), -1);
223 TEST_INT(opng_bitset_find_next(FULL, 2), 3);
224 TEST_INT(opng_bitset_find_next(0x0002, 2), -1);
225 TEST_INT(opng_bitset_find_next(0x0ff0, 2), 4);
226 TEST_INT(opng_bitset_find_next(EMPTY, ELT_MAX), -1);
227 TEST_INT(opng_bitset_find_next(FULL, ELT_MAX), -1);
228 TEST_INT(opng_bitset_find_next(0x0002, ELT_MAX), -1);
229 TEST_INT(opng_bitset_find_next(0x0ff0, ELT_MAX), -1);
230
231 TEST_INT(opng_bitset_find_last(EMPTY), -1);
232 TEST_INT(opng_bitset_find_last(FULL), ELT_MAX);
233 TEST_INT(opng_bitset_find_last(0x0002), 1);
234 TEST_INT(opng_bitset_find_last(0x0ff0), 11);
235
236 TEST_INT(opng_bitset_find_prev(EMPTY, 0), -1);
237 TEST_INT(opng_bitset_find_prev(FULL, 0), -1);
238 TEST_INT(opng_bitset_find_prev(0x0002, 0), -1);
239 TEST_INT(opng_bitset_find_prev(0x0ff0, 0), -1);
240 TEST_INT(opng_bitset_find_prev(EMPTY, 1), -1);
241 TEST_INT(opng_bitset_find_prev(FULL, 1), 0);
242 TEST_INT(opng_bitset_find_prev(0x0002, 1), -1);
243 TEST_INT(opng_bitset_find_prev(0x0ff0, 1), -1);
244 TEST_INT(opng_bitset_find_prev(EMPTY, 2), -1);
245 TEST_INT(opng_bitset_find_prev(FULL, 2), 1);
246 TEST_INT(opng_bitset_find_prev(0x0002, 2), 1);
247 TEST_INT(opng_bitset_find_prev(0x0ff0, 2), -1);
248 TEST_INT(opng_bitset_find_prev(EMPTY, ELT_MAX), -1);
249 TEST_INT(opng_bitset_find_prev(FULL, ELT_MAX), ELT_MAX - 1);
250 TEST_INT(opng_bitset_find_prev(0x0002, ELT_MAX), 1);
251 TEST_INT(opng_bitset_find_prev(0x0ff0, ELT_MAX), 11);
252
253 test_bitset_find_forward_impl(EMPTY);
254 test_bitset_find_forward_impl(FULL);
255 test_bitset_find_forward_impl(0x0002);
256 test_bitset_find_forward_impl(0x0ff0);
257
258 test_bitset_find_reverse_impl(EMPTY);
259 test_bitset_find_reverse_impl(FULL);
260 test_bitset_find_reverse_impl(0x0002);
261 test_bitset_find_reverse_impl(0x0ff0);
262 }
263
264 static void
test_strparse_rangeset_impl(const char * rangeset,opng_bitset_t mask,opng_bitset_t expected_bitset,int expected_errno)265 test_strparse_rangeset_impl(const char *rangeset,
266 opng_bitset_t mask,
267 opng_bitset_t expected_bitset,
268 int expected_errno)
269 {
270 opng_bitset_t bitset;
271 int parse_result, expected_parse_result;
272
273 ++num_tests;
274 errno = 0;
275 expected_parse_result = (expected_errno == 0) ? 0 : -1;
276 parse_result = opng_strparse_rangeset_to_bitset(&bitset, rangeset, mask);
277 if (parse_result != expected_parse_result ||
278 bitset != expected_bitset ||
279 errno != expected_errno)
280 {
281 ++num_errors;
282 printf("FAILED: opng_strparse_rangeset_to_bitset(\"%s\", 0x%lx)\n",
283 rangeset, (unsigned long)mask);
284 printf(" bitset: 0x%lx, expected: 0x%lx\n",
285 (unsigned long)bitset, (unsigned long)expected_bitset);
286 printf(" result: %d, expected: %d\n",
287 parse_result, expected_parse_result);
288 printf(" errno: %d, expected: %d\n",
289 errno, expected_errno);
290 }
291 }
292
293 static void
test_rangeset_parse()294 test_rangeset_parse()
295 {
296 static const opng_bitset_t mask_full = FULL;
297 static const opng_bitset_t mask_byte = 0x00ff;
298 static const opng_bitset_t mask_pattern = 0x5555;
299 static const opng_bitset_t mask_empty = EMPTY;
300
301 printf("Testing: rangeset parser\n");
302
303 test_strparse_rangeset_impl("", mask_full, EMPTY, 0);
304 test_strparse_rangeset_impl(" ", mask_byte, EMPTY, 0);
305 test_strparse_rangeset_impl(" ", mask_pattern, EMPTY, 0);
306 test_strparse_rangeset_impl(" ,; ;, ", mask_empty, EMPTY, 0);
307 test_strparse_rangeset_impl("0", mask_full, 0x0001, 0);
308 test_strparse_rangeset_impl("0,", mask_byte, 0x0001, 0);
309 test_strparse_rangeset_impl(",0", mask_pattern, 0x0001, 0);
310 test_strparse_rangeset_impl(",0,", mask_empty, FULL, ERANGE);
311 test_strparse_rangeset_impl("0-", mask_full, FULL, 0);
312 test_strparse_rangeset_impl("0-;", mask_pattern, 0x5555, 0);
313 test_strparse_rangeset_impl(";0-", mask_byte, 0x00ff, 0);
314 test_strparse_rangeset_impl(";0-;", mask_empty, FULL, ERANGE);
315 test_strparse_rangeset_impl(" 01 ", mask_full, 0x0002, 0);
316 test_strparse_rangeset_impl(" 01,; ", mask_byte, 0x0002, 0);
317 test_strparse_rangeset_impl(" ,;01 ", mask_pattern, FULL, ERANGE);
318 test_strparse_rangeset_impl(" ,;01,; ", mask_empty, FULL, ERANGE);
319 test_strparse_rangeset_impl(" 012 , ;", mask_full, 0x1000, 0);
320 test_strparse_rangeset_impl(", ; 012 ", mask_byte, FULL, ERANGE);
321 test_strparse_rangeset_impl(",;012,;", mask_pattern, 0x1000, 0);
322 test_strparse_rangeset_impl("1, 1", mask_full, 0x0002, 0);
323 test_strparse_rangeset_impl("1- 1", mask_byte, 0x0002, 0);
324 test_strparse_rangeset_impl("1 ;2", mask_full, 0x0006, 0);
325 test_strparse_rangeset_impl("1 -2", mask_byte, 0x0006, 0);
326 test_strparse_rangeset_impl("1 - 2", mask_pattern, FULL, ERANGE);
327 test_strparse_rangeset_impl("2-1", mask_full, FULL, ERANGE);
328 test_strparse_rangeset_impl("2-1", mask_byte, FULL, ERANGE);
329 test_strparse_rangeset_impl("124", mask_full, FULL, ERANGE);
330 test_strparse_rangeset_impl("12-4", mask_full, FULL, ERANGE);
331 test_strparse_rangeset_impl("1-2,4", mask_full, 0x0016, 0);
332 test_strparse_rangeset_impl("1-2,4-", mask_byte, 0x00f6, 0);
333 test_strparse_rangeset_impl("1,2,4", mask_full, 0x0016, 0);
334 test_strparse_rangeset_impl("1,2,4-", mask_pattern, FULL, ERANGE);
335 test_strparse_rangeset_impl("1,2,4", mask_byte, 0x0016, 0);
336 test_strparse_rangeset_impl("1,2-4", mask_full, 0x001e, 0);
337 test_strparse_rangeset_impl("12,4", mask_full, 0x1010, 0);
338 test_strparse_rangeset_impl("12,4", mask_byte, FULL, ERANGE);
339 test_strparse_rangeset_impl("2-4,1", mask_full, 0x001e, 0);
340 test_strparse_rangeset_impl("4-2,1", mask_full, FULL, ERANGE);
341 test_strparse_rangeset_impl("4-,2-1", mask_byte, FULL, ERANGE);
342 test_strparse_rangeset_impl("4-,1-2", mask_full, FULL ^ 0x0009, 0);
343 test_strparse_rangeset_impl("9999999999", mask_full, FULL, ERANGE);
344 test_strparse_rangeset_impl("9999999999-", mask_byte, FULL, ERANGE);
345
346 test_strparse_rangeset_impl("-", mask_full, EMPTY, EINVAL);
347 test_strparse_rangeset_impl(" - ", mask_pattern, EMPTY, EINVAL);
348 test_strparse_rangeset_impl("--", mask_byte, EMPTY, EINVAL);
349 test_strparse_rangeset_impl("- -", mask_empty, EMPTY, EINVAL);
350 test_strparse_rangeset_impl("0--", mask_full, EMPTY, EINVAL);
351 test_strparse_rangeset_impl("0 -- ", mask_pattern, EMPTY, EINVAL);
352 test_strparse_rangeset_impl("0- -", mask_byte, EMPTY, EINVAL);
353 test_strparse_rangeset_impl("0 --- ", mask_empty, EMPTY, EINVAL);
354 test_strparse_rangeset_impl("-0", mask_full, EMPTY, EINVAL);
355 test_strparse_rangeset_impl("-0-", mask_pattern, EMPTY, EINVAL);
356 test_strparse_rangeset_impl("1k", mask_full, EMPTY, EINVAL);
357 test_strparse_rangeset_impl("1 k", mask_pattern, EMPTY, EINVAL);
358 test_strparse_rangeset_impl("A1", mask_full, EMPTY, EINVAL);
359 test_strparse_rangeset_impl("0xA1", mask_pattern, EMPTY, EINVAL);
360 test_strparse_rangeset_impl(".1", mask_full, EMPTY, EINVAL);
361 test_strparse_rangeset_impl("1.", mask_pattern, EMPTY, EINVAL);
362 test_strparse_rangeset_impl("1.2", mask_byte, EMPTY, EINVAL);
363 test_strparse_rangeset_impl("1 2", mask_full, EMPTY, EINVAL);
364 test_strparse_rangeset_impl("2 1", mask_pattern, EMPTY, EINVAL);
365 test_strparse_rangeset_impl("1--2", mask_full, EMPTY, EINVAL);
366 test_strparse_rangeset_impl("1--2-", mask_pattern, EMPTY, EINVAL);
367 test_strparse_rangeset_impl("1- -2", mask_byte, EMPTY, EINVAL);
368 test_strparse_rangeset_impl("1- -2-", mask_empty, EMPTY, EINVAL);
369 test_strparse_rangeset_impl("-1--2", mask_full, EMPTY, EINVAL);
370 test_strparse_rangeset_impl("-1--2-", mask_pattern, EMPTY, EINVAL);
371 test_strparse_rangeset_impl("-1- -2", mask_byte, EMPTY, EINVAL);
372 test_strparse_rangeset_impl("-1- -2-", mask_empty, EMPTY, EINVAL);
373 test_strparse_rangeset_impl("1-2-4", mask_full, EMPTY, EINVAL);
374 test_strparse_rangeset_impl("1-2-4-", mask_pattern, EMPTY, EINVAL);
375 test_strparse_rangeset_impl("1-2-4-", mask_byte, EMPTY, EINVAL);
376 test_strparse_rangeset_impl("-1-2-4", mask_empty, EMPTY, EINVAL);
377 test_strparse_rangeset_impl("1-4-2,", mask_full, EMPTY, EINVAL);
378 test_strparse_rangeset_impl("1-4-2-,", mask_pattern, EMPTY, EINVAL);
379 test_strparse_rangeset_impl("1-4-2-,", mask_byte, EMPTY, EINVAL);
380 test_strparse_rangeset_impl("-1-4-2,", mask_empty, EMPTY, EINVAL);
381 test_strparse_rangeset_impl(",4-2-1;", mask_full, EMPTY, EINVAL);
382 test_strparse_rangeset_impl(",4-2-1-;", mask_pattern, EMPTY, EINVAL);
383 test_strparse_rangeset_impl(",4-2-1-;", mask_byte, EMPTY, EINVAL);
384 test_strparse_rangeset_impl(",-4-2-1;", mask_empty, EMPTY, EINVAL);
385 test_strparse_rangeset_impl("-9999999999", mask_full, EMPTY, EINVAL);
386 }
387
388 static void
run_tests()389 run_tests()
390 {
391 test_bitset_const();
392 test_bitset_obs();
393 test_bitset_mod();
394 test_bitset_iter();
395 test_rangeset_parse();
396 }
397
398 int
main()399 main()
400 {
401 run_tests();
402 if (num_errors != 0)
403 {
404 printf("** %d/%d tests FAILED **\n", num_errors, num_tests);
405 return 1;
406 }
407 else
408 {
409 printf("** %d tests passed **\n", num_tests);
410 return 0;
411 }
412 }
413