• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2014 Red Hat, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include <config.h>
25 
26 #include <check.h>
27 
28 #include <valgrind/valgrind.h>
29 
30 #include "util-list.h"
31 #include "util-strings.h"
32 #include "util-time.h"
33 #include "util-prop-parsers.h"
34 #include "util-macros.h"
35 #include "util-bits.h"
36 #include "util-ratelimit.h"
37 #include "util-matrix.h"
38 
39 #define  TEST_VERSIONSORT
40 #include "libinput-versionsort.h"
41 
42 #include "check-double-macros.h"
43 
START_TEST(bitfield_helpers)44 START_TEST(bitfield_helpers)
45 {
46 	/* This value has a bit set on all of the word boundaries we want to
47 	 * test: 0, 1, 7, 8, 31, 32, and 33
48 	 */
49 	unsigned char read_bitfield[] = { 0x83, 0x1, 0x0, 0x80, 0x3 };
50 	unsigned char write_bitfield[ARRAY_LENGTH(read_bitfield)] = {0};
51 	size_t i;
52 
53 	/* Now check that the bitfield we wrote to came out to be the same as
54 	 * the bitfield we were writing from */
55 	for (i = 0; i < ARRAY_LENGTH(read_bitfield) * 8; i++) {
56 		switch (i) {
57 		case 0:
58 		case 1:
59 		case 7:
60 		case 8:
61 		case 31:
62 		case 32:
63 		case 33:
64 			ck_assert(bit_is_set(read_bitfield, i));
65 			set_bit(write_bitfield, i);
66 			break;
67 		default:
68 			ck_assert(!bit_is_set(read_bitfield, i));
69 			clear_bit(write_bitfield, i);
70 			break;
71 		}
72 	}
73 
74 	ck_assert_int_eq(memcmp(read_bitfield,
75 				write_bitfield,
76 				sizeof(read_bitfield)),
77 			 0);
78 }
79 END_TEST
80 
START_TEST(matrix_helpers)81 START_TEST(matrix_helpers)
82 {
83 	struct matrix m1, m2, m3;
84 	float f[6] = { 1, 2, 3, 4, 5, 6 };
85 	int x, y;
86 	int row, col;
87 
88 	matrix_init_identity(&m1);
89 
90 	for (row = 0; row < 3; row++) {
91 		for (col = 0; col < 3; col++) {
92 			ck_assert_int_eq(m1.val[row][col],
93 					 (row == col) ? 1 : 0);
94 		}
95 	}
96 	ck_assert(matrix_is_identity(&m1));
97 
98 	matrix_from_farray6(&m2, f);
99 	ck_assert_int_eq(m2.val[0][0], 1);
100 	ck_assert_int_eq(m2.val[0][1], 2);
101 	ck_assert_int_eq(m2.val[0][2], 3);
102 	ck_assert_int_eq(m2.val[1][0], 4);
103 	ck_assert_int_eq(m2.val[1][1], 5);
104 	ck_assert_int_eq(m2.val[1][2], 6);
105 	ck_assert_int_eq(m2.val[2][0], 0);
106 	ck_assert_int_eq(m2.val[2][1], 0);
107 	ck_assert_int_eq(m2.val[2][2], 1);
108 
109 	x = 100;
110 	y = 5;
111 	matrix_mult_vec(&m1, &x, &y);
112 	ck_assert_int_eq(x, 100);
113 	ck_assert_int_eq(y, 5);
114 
115 	matrix_mult(&m3, &m1, &m1);
116 	ck_assert(matrix_is_identity(&m3));
117 
118 	matrix_init_scale(&m2, 2, 4);
119 	ck_assert_int_eq(m2.val[0][0], 2);
120 	ck_assert_int_eq(m2.val[0][1], 0);
121 	ck_assert_int_eq(m2.val[0][2], 0);
122 	ck_assert_int_eq(m2.val[1][0], 0);
123 	ck_assert_int_eq(m2.val[1][1], 4);
124 	ck_assert_int_eq(m2.val[1][2], 0);
125 	ck_assert_int_eq(m2.val[2][0], 0);
126 	ck_assert_int_eq(m2.val[2][1], 0);
127 	ck_assert_int_eq(m2.val[2][2], 1);
128 
129 	matrix_mult_vec(&m2, &x, &y);
130 	ck_assert_int_eq(x, 200);
131 	ck_assert_int_eq(y, 20);
132 
133 	matrix_init_translate(&m2, 10, 100);
134 	ck_assert_int_eq(m2.val[0][0], 1);
135 	ck_assert_int_eq(m2.val[0][1], 0);
136 	ck_assert_int_eq(m2.val[0][2], 10);
137 	ck_assert_int_eq(m2.val[1][0], 0);
138 	ck_assert_int_eq(m2.val[1][1], 1);
139 	ck_assert_int_eq(m2.val[1][2], 100);
140 	ck_assert_int_eq(m2.val[2][0], 0);
141 	ck_assert_int_eq(m2.val[2][1], 0);
142 	ck_assert_int_eq(m2.val[2][2], 1);
143 
144 	matrix_mult_vec(&m2, &x, &y);
145 	ck_assert_int_eq(x, 210);
146 	ck_assert_int_eq(y, 120);
147 
148 	matrix_to_farray6(&m2, f);
149 	ck_assert_int_eq(f[0], 1);
150 	ck_assert_int_eq(f[1], 0);
151 	ck_assert_int_eq(f[2], 10);
152 	ck_assert_int_eq(f[3], 0);
153 	ck_assert_int_eq(f[4], 1);
154 	ck_assert_int_eq(f[5], 100);
155 }
156 END_TEST
157 
START_TEST(ratelimit_helpers)158 START_TEST(ratelimit_helpers)
159 {
160 	struct ratelimit rl;
161 	unsigned int i, j;
162 
163 	/* 10 attempts every 1000ms */
164 	ratelimit_init(&rl, ms2us(1000), 10);
165 
166 	for (j = 0; j < 3; ++j) {
167 		/* a burst of 9 attempts must succeed */
168 		for (i = 0; i < 9; ++i) {
169 			ck_assert_int_eq(ratelimit_test(&rl),
170 					 RATELIMIT_PASS);
171 		}
172 
173 		/* the 10th attempt reaches the threshold */
174 		ck_assert_int_eq(ratelimit_test(&rl), RATELIMIT_THRESHOLD);
175 
176 		/* ..then further attempts must fail.. */
177 		ck_assert_int_eq(ratelimit_test(&rl), RATELIMIT_EXCEEDED);
178 
179 		/* ..regardless of how often we try. */
180 		for (i = 0; i < 100; ++i) {
181 			ck_assert_int_eq(ratelimit_test(&rl),
182 					 RATELIMIT_EXCEEDED);
183 		}
184 
185 		/* ..even after waiting 20ms */
186 		msleep(100);
187 		for (i = 0; i < 100; ++i) {
188 			ck_assert_int_eq(ratelimit_test(&rl),
189 					 RATELIMIT_EXCEEDED);
190 		}
191 
192 		/* but after 1000ms the counter is reset */
193 		msleep(950); /* +50ms to account for time drifts */
194 	}
195 }
196 END_TEST
197 
198 struct parser_test {
199 	char *tag;
200 	int expected_value;
201 };
202 
START_TEST(dpi_parser)203 START_TEST(dpi_parser)
204 {
205 	struct parser_test tests[] = {
206 		{ "450 *1800 3200", 1800 },
207 		{ "*450 1800 3200", 450 },
208 		{ "450 1800 *3200", 3200 },
209 		{ "450 1800 3200", 3200 },
210 		{ "450 1800 failboat", 0 },
211 		{ "450 1800 *failboat", 0 },
212 		{ "0 450 1800 *3200", 0 },
213 		{ "450@37 1800@12 *3200@6", 3200 },
214 		{ "450@125 1800@125   *3200@125  ", 3200 },
215 		{ "450@125 *1800@125  3200@125", 1800 },
216 		{ "*this @string fails", 0 },
217 		{ "12@34 *45@", 0 },
218 		{ "12@a *45@", 0 },
219 		{ "12@a *45@25", 0 },
220 		{ "                                      * 12, 450, 800", 0 },
221 		{ "                                      *12, 450, 800", 12 },
222 		{ "*12, *450, 800", 12 },
223 		{ "*-23412, 450, 800", 0 },
224 		{ "112@125, 450@125, 800@125, 900@-125", 0 },
225 		{ "", 0 },
226 		{ "   ", 0 },
227 		{ "* ", 0 },
228 		{ NULL, 0 }
229 	};
230 	int i, dpi;
231 
232 	for (i = 0; tests[i].tag != NULL; i++) {
233 		dpi = parse_mouse_dpi_property(tests[i].tag);
234 		ck_assert_int_eq(dpi, tests[i].expected_value);
235 	}
236 
237 	dpi = parse_mouse_dpi_property(NULL);
238 	ck_assert_int_eq(dpi, 0);
239 }
240 END_TEST
241 
START_TEST(wheel_click_parser)242 START_TEST(wheel_click_parser)
243 {
244 	struct parser_test tests[] = {
245 		{ "1", 1 },
246 		{ "10", 10 },
247 		{ "-12", -12 },
248 		{ "360", 360 },
249 
250 		{ "0", 0 },
251 		{ "-0", 0 },
252 		{ "a", 0 },
253 		{ "10a", 0 },
254 		{ "10-", 0 },
255 		{ "sadfasfd", 0 },
256 		{ "361", 0 },
257 		{ NULL, 0 }
258 	};
259 
260 	int i, angle;
261 
262 	for (i = 0; tests[i].tag != NULL; i++) {
263 		angle = parse_mouse_wheel_click_angle_property(tests[i].tag);
264 		ck_assert_int_eq(angle, tests[i].expected_value);
265 	}
266 }
267 END_TEST
268 
START_TEST(wheel_click_count_parser)269 START_TEST(wheel_click_count_parser)
270 {
271 	struct parser_test tests[] = {
272 		{ "1", 1 },
273 		{ "10", 10 },
274 		{ "-12", -12 },
275 		{ "360", 360 },
276 
277 		{ "0", 0 },
278 		{ "-0", 0 },
279 		{ "a", 0 },
280 		{ "10a", 0 },
281 		{ "10-", 0 },
282 		{ "sadfasfd", 0 },
283 		{ "361", 0 },
284 		{ NULL, 0 }
285 	};
286 
287 	int i, angle;
288 
289 	for (i = 0; tests[i].tag != NULL; i++) {
290 		angle = parse_mouse_wheel_click_count_property(tests[i].tag);
291 		ck_assert_int_eq(angle, tests[i].expected_value);
292 	}
293 
294 	angle = parse_mouse_wheel_click_count_property(NULL);
295 	ck_assert_int_eq(angle, 0);
296 }
297 END_TEST
298 
START_TEST(dimension_prop_parser)299 START_TEST(dimension_prop_parser)
300 {
301 	struct parser_test_dimension {
302 		char *tag;
303 		bool success;
304 		int x, y;
305 	} tests[] = {
306 		{ "10x10", true, 10, 10 },
307 		{ "1x20", true, 1, 20 },
308 		{ "1x8000", true, 1, 8000 },
309 		{ "238492x428210", true, 238492, 428210 },
310 		{ "0x0", false, 0, 0 },
311 		{ "-10x10", false, 0, 0 },
312 		{ "-1", false, 0, 0 },
313 		{ "1x-99", false, 0, 0 },
314 		{ "0", false, 0, 0 },
315 		{ "100", false, 0, 0 },
316 		{ "", false, 0, 0 },
317 		{ "abd", false, 0, 0 },
318 		{ "xabd", false, 0, 0 },
319 		{ "0xaf", false, 0, 0 },
320 		{ "0x0x", false, 0, 0 },
321 		{ "x10", false, 0, 0 },
322 		{ NULL, false, 0, 0 }
323 	};
324 	int i;
325 	size_t x, y;
326 	bool success;
327 
328 	for (i = 0; tests[i].tag != NULL; i++) {
329 		x = y = 0xad;
330 		success = parse_dimension_property(tests[i].tag, &x, &y);
331 		ck_assert(success == tests[i].success);
332 		if (success) {
333 			ck_assert_int_eq(x, tests[i].x);
334 			ck_assert_int_eq(y, tests[i].y);
335 		} else {
336 			ck_assert_int_eq(x, 0xad);
337 			ck_assert_int_eq(y, 0xad);
338 		}
339 	}
340 
341 	success = parse_dimension_property(NULL, &x, &y);
342 	ck_assert(success == false);
343 }
344 END_TEST
345 
START_TEST(reliability_prop_parser)346 START_TEST(reliability_prop_parser)
347 {
348 	struct parser_test_reliability {
349 		char *tag;
350 		bool success;
351 		enum switch_reliability reliability;
352 	} tests[] = {
353 		{ "reliable", true, RELIABILITY_RELIABLE },
354 		{ "unreliable", false, 0 },
355 		{ "", false, 0 },
356 		{ "0", false, 0 },
357 		{ "1", false, 0 },
358 		{ NULL, false, 0, }
359 	};
360 	enum switch_reliability r;
361 	bool success;
362 	int i;
363 
364 	for (i = 0; tests[i].tag != NULL; i++) {
365 		r = 0xaf;
366 		success = parse_switch_reliability_property(tests[i].tag, &r);
367 		ck_assert(success == tests[i].success);
368 		if (success)
369 			ck_assert_int_eq(r, tests[i].reliability);
370 		else
371 			ck_assert_int_eq(r, 0xaf);
372 	}
373 
374 	success = parse_switch_reliability_property(NULL, &r);
375 	ck_assert(success == true);
376 	ck_assert_int_eq(r, RELIABILITY_UNKNOWN);
377 
378 	success = parse_switch_reliability_property("foo", NULL);
379 	ck_assert(success == false);
380 }
381 END_TEST
382 
START_TEST(calibration_prop_parser)383 START_TEST(calibration_prop_parser)
384 {
385 #define DEFAULT_VALUES { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 }
386 	const float untouched[6] = DEFAULT_VALUES;
387 	struct parser_test_calibration {
388 		char *prop;
389 		bool success;
390 		float values[6];
391 	} tests[] = {
392 		{ "", false, DEFAULT_VALUES },
393 		{ "banana", false, DEFAULT_VALUES },
394 		{ "1 2 3 a 5 6", false, DEFAULT_VALUES },
395 		{ "2", false, DEFAULT_VALUES },
396 		{ "2 3 4 5 6", false, DEFAULT_VALUES },
397 		{ "1 2 3 4 5 6", true, DEFAULT_VALUES },
398 		{ "6.00012 3.244 4.238 5.2421 6.0134 8.860", true,
399 			{ 6.00012, 3.244, 4.238, 5.2421, 6.0134, 8.860 }},
400 		{ "0xff 2 3 4 5 6", false, DEFAULT_VALUES },
401 		{ NULL, false, DEFAULT_VALUES }
402 	};
403 	bool success;
404 	float calibration[6];
405 	int rc;
406 	int i;
407 
408 	for (i = 0; tests[i].prop != NULL; i++) {
409 		memcpy(calibration, untouched, sizeof(calibration));
410 
411 		success = parse_calibration_property(tests[i].prop,
412 						     calibration);
413 		ck_assert_int_eq(success, tests[i].success);
414 		if (success)
415 			rc = memcmp(tests[i].values,
416 				    calibration,
417 				    sizeof(calibration));
418 		else
419 			rc = memcmp(untouched,
420 				    calibration,
421 				    sizeof(calibration));
422 		ck_assert_int_eq(rc, 0);
423 	}
424 
425 	memcpy(calibration, untouched, sizeof(calibration));
426 
427 	success = parse_calibration_property(NULL, calibration);
428 	ck_assert(success == false);
429 	rc = memcmp(untouched, calibration, sizeof(calibration));
430 	ck_assert_int_eq(rc, 0);
431 }
432 END_TEST
433 
START_TEST(range_prop_parser)434 START_TEST(range_prop_parser)
435 {
436 	struct parser_test_range {
437 		char *tag;
438 		bool success;
439 		int hi, lo;
440 	} tests[] = {
441 		{ "10:8", true, 10, 8 },
442 		{ "100:-1", true, 100, -1 },
443 		{ "-203813:-502023", true, -203813, -502023 },
444 		{ "238492:28210", true, 238492, 28210 },
445 		{ "none", true, 0, 0 },
446 		{ "0:0", false, 0, 0 },
447 		{ "", false, 0, 0 },
448 		{ "abcd", false, 0, 0 },
449 		{ "10:30:10", false, 0, 0 },
450 		{ NULL, false, 0, 0 }
451 	};
452 	int i;
453 	int hi, lo;
454 	bool success;
455 
456 	for (i = 0; tests[i].tag != NULL; i++) {
457 		hi = lo = 0xad;
458 		success = parse_range_property(tests[i].tag, &hi, &lo);
459 		ck_assert(success == tests[i].success);
460 		if (success) {
461 			ck_assert_int_eq(hi, tests[i].hi);
462 			ck_assert_int_eq(lo, tests[i].lo);
463 		} else {
464 			ck_assert_int_eq(hi, 0xad);
465 			ck_assert_int_eq(lo, 0xad);
466 		}
467 	}
468 
469 	success = parse_range_property(NULL, NULL, NULL);
470 	ck_assert(success == false);
471 }
472 END_TEST
473 
START_TEST(evcode_prop_parser)474 START_TEST(evcode_prop_parser)
475 {
476 	struct parser_test_tuple {
477 		const char *prop;
478 		bool success;
479 		size_t ntuples;
480 		int tuples[20];
481 	} tests[] = {
482 		{ "EV_KEY", true, 1, {EV_KEY, 0xffff} },
483 		{ "EV_ABS;", true, 1, {EV_ABS, 0xffff} },
484 		{ "ABS_X;", true, 1, {EV_ABS, ABS_X} },
485 		{ "SW_TABLET_MODE;", true, 1, {EV_SW, SW_TABLET_MODE} },
486 		{ "EV_SW", true, 1, {EV_SW, 0xffff} },
487 		{ "ABS_Y", true, 1, {EV_ABS, ABS_Y} },
488 		{ "EV_ABS:0x00", true, 1, {EV_ABS, ABS_X} },
489 		{ "EV_ABS:01", true, 1, {EV_ABS, ABS_Y} },
490 		{ "ABS_TILT_X;ABS_TILT_Y;", true, 2,
491 			{ EV_ABS, ABS_TILT_X,
492 			  EV_ABS, ABS_TILT_Y} },
493 		{ "BTN_TOOL_DOUBLETAP;EV_KEY;KEY_A", true, 3,
494 			{ EV_KEY, BTN_TOOL_DOUBLETAP,
495 			  EV_KEY, 0xffff,
496 			  EV_KEY, KEY_A } },
497 		{ "REL_Y;ABS_Z;BTN_STYLUS", true, 3,
498 			{ EV_REL, REL_Y,
499 			  EV_ABS, ABS_Z,
500 			  EV_KEY, BTN_STYLUS } },
501 		{ "REL_Y;EV_KEY:0x123;BTN_STYLUS", true, 3,
502 			{ EV_REL, REL_Y,
503 			  EV_KEY, 0x123,
504 			  EV_KEY, BTN_STYLUS } },
505 		{ .prop = "", .success = false },
506 		{ .prop = "EV_FOO", .success = false },
507 		{ .prop = "EV_KEY;EV_FOO", .success = false },
508 		{ .prop = "BTN_STYLUS;EV_FOO", .success = false },
509 		{ .prop = "BTN_UNKNOWN", .success = false },
510 		{ .prop = "BTN_UNKNOWN;EV_KEY", .success = false },
511 		{ .prop = "PR_UNKNOWN", .success = false },
512 		{ .prop = "BTN_STYLUS;PR_UNKNOWN;ABS_X", .success = false },
513 		{ .prop = "EV_REL:0xffff", .success = false },
514 		{ .prop = "EV_REL:0x123.", .success = false },
515 		{ .prop = "EV_REL:ffff", .success = false },
516 		{ .prop = "EV_REL:blah", .success = false },
517 		{ .prop = "KEY_A:0x11", .success = false },
518 		{ .prop = "EV_KEY:0x11 ", .success = false },
519 		{ .prop = "EV_KEY:0x11not", .success = false },
520 		{ .prop = "none", .success = false },
521 		{ .prop = NULL },
522 	};
523 	struct parser_test_tuple *t;
524 
525 	for (int i = 0; tests[i].prop; i++) {
526 		bool success;
527 		struct input_event events[32];
528 		size_t nevents = ARRAY_LENGTH(events);
529 
530 		t = &tests[i];
531 		success = parse_evcode_property(t->prop, events, &nevents);
532 		ck_assert(success == t->success);
533 		if (!success)
534 			continue;
535 
536 		ck_assert_int_eq(nevents, t->ntuples);
537 		for (size_t j = 0; j < nevents; j++) {
538 			int type, code;
539 
540 			type = events[j].type;
541 			code = events[j].code;
542 			ck_assert_int_eq(t->tuples[j * 2], type);
543 			ck_assert_int_eq(t->tuples[j * 2 + 1], code);
544 		}
545 	}
546 }
547 END_TEST
548 
START_TEST(evdev_abs_parser)549 START_TEST(evdev_abs_parser)
550 {
551 	struct test {
552 		uint32_t which;
553 		const char *prop;
554 		int min, max, res, fuzz, flat;
555 
556 	} tests[] = {
557 		{ .which = (ABS_MASK_MIN|ABS_MASK_MAX),
558 		  .prop = "1:2",
559 		  .min = 1, .max = 2 },
560 		{ .which = (ABS_MASK_MIN|ABS_MASK_MAX),
561 		  .prop = "1:2:",
562 		  .min = 1, .max = 2 },
563 		{ .which = (ABS_MASK_MIN|ABS_MASK_MAX|ABS_MASK_RES),
564 		  .prop = "10:20:30",
565 		  .min = 10, .max = 20, .res = 30 },
566 		{ .which = (ABS_MASK_RES),
567 		  .prop = "::100",
568 		  .res = 100 },
569 		{ .which = (ABS_MASK_MIN),
570 		  .prop = "10:",
571 		  .min = 10 },
572 		{ .which = (ABS_MASK_MAX|ABS_MASK_RES),
573 		  .prop = ":10:1001",
574 		  .max = 10, .res = 1001 },
575 		{ .which = (ABS_MASK_MIN|ABS_MASK_MAX|ABS_MASK_RES|ABS_MASK_FUZZ),
576 		  .prop = "1:2:3:4",
577 		  .min = 1, .max = 2, .res = 3, .fuzz = 4},
578 		{ .which = (ABS_MASK_MIN|ABS_MASK_MAX|ABS_MASK_RES|ABS_MASK_FUZZ|ABS_MASK_FLAT),
579 		  .prop = "1:2:3:4:5",
580 		  .min = 1, .max = 2, .res = 3, .fuzz = 4, .flat = 5},
581 		{ .which = (ABS_MASK_MIN|ABS_MASK_RES|ABS_MASK_FUZZ|ABS_MASK_FLAT),
582 		  .prop = "1::3:4:50",
583 		  .min = 1, .res = 3, .fuzz = 4, .flat = 50},
584 		{ .which = ABS_MASK_FUZZ|ABS_MASK_FLAT,
585 		  .prop = ":::5:60",
586 		  .fuzz = 5, .flat = 60},
587 		{ .which = ABS_MASK_FUZZ,
588 		  .prop = ":::5:",
589 		  .fuzz = 5 },
590 		{ .which = ABS_MASK_RES, .prop = "::12::",
591 		  .res = 12 },
592 		/* Malformed property but parsing this one makes us more
593 		 * future proof */
594 		{ .which = (ABS_MASK_RES|ABS_MASK_FUZZ|ABS_MASK_FLAT),
595 		  .prop = "::12:1:2:3:4:5:6",
596 		  .res = 12, .fuzz = 1, .flat = 2 },
597 		{ .which = 0, .prop = ":::::" },
598 		{ .which = 0, .prop = ":" },
599 		{ .which = 0, .prop = "" },
600 		{ .which = 0, .prop = ":asb::::" },
601 		{ .which = 0, .prop = "foo" },
602 	};
603 	struct test *t;
604 
605 	ARRAY_FOR_EACH(tests, t) {
606 		struct input_absinfo abs;
607 		uint32_t mask;
608 
609 		mask = parse_evdev_abs_prop(t->prop, &abs);
610 		ck_assert_int_eq(mask, t->which);
611 
612 		if (t->which & ABS_MASK_MIN)
613 			ck_assert_int_eq(abs.minimum, t->min);
614 		if (t->which & ABS_MASK_MAX)
615 			ck_assert_int_eq(abs.maximum, t->max);
616 		if (t->which & ABS_MASK_RES)
617 			ck_assert_int_eq(abs.resolution, t->res);
618 		if (t->which & ABS_MASK_FUZZ)
619 			ck_assert_int_eq(abs.fuzz, t->fuzz);
620 		if (t->which & ABS_MASK_FLAT)
621 			ck_assert_int_eq(abs.flat, t->flat);
622 	}
623 }
624 END_TEST
625 
START_TEST(time_conversion)626 START_TEST(time_conversion)
627 {
628 	ck_assert_int_eq(us(10), 10);
629 	ck_assert_int_eq(ns2us(10000), 10);
630 	ck_assert_int_eq(ms2us(10), 10000);
631 	ck_assert_int_eq(s2us(1), 1000000);
632 	ck_assert_int_eq(us2ms(10000), 10);
633 }
634 END_TEST
635 
START_TEST(human_time)636 START_TEST(human_time)
637 {
638 	struct ht_tests {
639 		uint64_t interval;
640 		unsigned int value;
641 		const char *unit;
642 	} tests[] = {
643 		{ 0, 0, "us" },
644 		{ 123, 123, "us" },
645 		{ ms2us(5), 5, "ms" },
646 		{ ms2us(100), 100, "ms" },
647 		{ s2us(5), 5, "s" },
648 		{ s2us(100), 100, "s" },
649 		{ s2us(120), 2, "min" },
650 		{ 5 * s2us(60), 5, "min" },
651 		{ 120 * s2us(60), 2, "h" },
652 		{ 5 * 60 * s2us(60), 5, "h" },
653 		{ 48 * 60 * s2us(60), 2, "d" },
654 		{ 1000 * 24 * 60 * s2us(60), 1000, "d" },
655 		{ 0, 0, NULL },
656 	};
657 	for (int i = 0; tests[i].unit != NULL; i++) {
658 		struct human_time ht;
659 
660 		ht = to_human_time(tests[i].interval);
661 		ck_assert_int_eq(ht.value, tests[i].value);
662 		ck_assert_str_eq(ht.unit, tests[i].unit);
663 	}
664 }
665 END_TEST
666 
667 struct atoi_test {
668 	char *str;
669 	bool success;
670 	int val;
671 };
672 
START_TEST(safe_atoi_test)673 START_TEST(safe_atoi_test)
674 {
675 	struct atoi_test tests[] = {
676 		{ "10", true, 10 },
677 		{ "20", true, 20 },
678 		{ "-1", true, -1 },
679 		{ "2147483647", true, 2147483647 },
680 		{ "-2147483648", true, -2147483648 },
681 		{ "4294967295", false, 0 },
682 		{ "0x0", false, 0 },
683 		{ "-10x10", false, 0 },
684 		{ "1x-99", false, 0 },
685 		{ "", false, 0 },
686 		{ "abd", false, 0 },
687 		{ "xabd", false, 0 },
688 		{ "0xaf", false, 0 },
689 		{ "0x0x", false, 0 },
690 		{ "x10", false, 0 },
691 		{ NULL, false, 0 }
692 	};
693 	int v;
694 	bool success;
695 
696 	for (int i = 0; tests[i].str != NULL; i++) {
697 		v = 0xad;
698 		success = safe_atoi(tests[i].str, &v);
699 		ck_assert(success == tests[i].success);
700 		if (success)
701 			ck_assert_int_eq(v, tests[i].val);
702 		else
703 			ck_assert_int_eq(v, 0xad);
704 	}
705 }
706 END_TEST
707 
START_TEST(safe_atoi_base_16_test)708 START_TEST(safe_atoi_base_16_test)
709 {
710 	struct atoi_test tests[] = {
711 		{ "10", true, 0x10 },
712 		{ "20", true, 0x20 },
713 		{ "-1", true, -1 },
714 		{ "0x10", true, 0x10 },
715 		{ "0xff", true, 0xff },
716 		{ "abc", true, 0xabc },
717 		{ "-10", true, -0x10 },
718 		{ "0x0", true, 0 },
719 		{ "0", true, 0 },
720 		{ "0x-99", false, 0 },
721 		{ "0xak", false, 0 },
722 		{ "0x", false, 0 },
723 		{ "x10", false, 0 },
724 		{ NULL, false, 0 }
725 	};
726 
727 	int v;
728 	bool success;
729 
730 	for (int i = 0; tests[i].str != NULL; i++) {
731 		v = 0xad;
732 		success = safe_atoi_base(tests[i].str, &v, 16);
733 		ck_assert(success == tests[i].success);
734 		if (success)
735 			ck_assert_int_eq(v, tests[i].val);
736 		else
737 			ck_assert_int_eq(v, 0xad);
738 	}
739 }
740 END_TEST
741 
START_TEST(safe_atoi_base_8_test)742 START_TEST(safe_atoi_base_8_test)
743 {
744 	struct atoi_test tests[] = {
745 		{ "7", true, 07 },
746 		{ "10", true, 010 },
747 		{ "20", true, 020 },
748 		{ "-1", true, -1 },
749 		{ "010", true, 010 },
750 		{ "0ff", false, 0 },
751 		{ "abc", false, 0},
752 		{ "0xabc", false, 0},
753 		{ "-10", true, -010 },
754 		{ "0", true, 0 },
755 		{ "00", true, 0 },
756 		{ "0x0", false, 0 },
757 		{ "0x-99", false, 0 },
758 		{ "0xak", false, 0 },
759 		{ "0x", false, 0 },
760 		{ "x10", false, 0 },
761 		{ NULL, false, 0 }
762 	};
763 
764 	int v;
765 	bool success;
766 
767 	for (int i = 0; tests[i].str != NULL; i++) {
768 		v = 0xad;
769 		success = safe_atoi_base(tests[i].str, &v, 8);
770 		ck_assert(success == tests[i].success);
771 		if (success)
772 			ck_assert_int_eq(v, tests[i].val);
773 		else
774 			ck_assert_int_eq(v, 0xad);
775 	}
776 }
777 END_TEST
778 
779 struct atou_test {
780 	char *str;
781 	bool success;
782 	unsigned int val;
783 };
784 
START_TEST(safe_atou_test)785 START_TEST(safe_atou_test)
786 {
787 	struct atou_test tests[] = {
788 		{ "10", true, 10 },
789 		{ "20", true, 20 },
790 		{ "-1", false, 0 },
791 		{ "2147483647", true, 2147483647 },
792 		{ "-2147483648", false, 0},
793 		{ "0x0", false, 0 },
794 		{ "-10x10", false, 0 },
795 		{ "1x-99", false, 0 },
796 		{ "", false, 0 },
797 		{ "abd", false, 0 },
798 		{ "xabd", false, 0 },
799 		{ "0xaf", false, 0 },
800 		{ "0x0x", false, 0 },
801 		{ "x10", false, 0 },
802 		{ NULL, false, 0 }
803 	};
804 	unsigned int v;
805 	bool success;
806 
807 	for (int i = 0; tests[i].str != NULL; i++) {
808 		v = 0xad;
809 		success = safe_atou(tests[i].str, &v);
810 		ck_assert(success == tests[i].success);
811 		if (success)
812 			ck_assert_int_eq(v, tests[i].val);
813 		else
814 			ck_assert_int_eq(v, 0xad);
815 	}
816 }
817 END_TEST
818 
START_TEST(safe_atou_base_16_test)819 START_TEST(safe_atou_base_16_test)
820 {
821 	struct atou_test tests[] = {
822 		{ "10", true, 0x10 },
823 		{ "20", true, 0x20 },
824 		{ "-1", false, 0 },
825 		{ "0x10", true, 0x10 },
826 		{ "0xff", true, 0xff },
827 		{ "abc", true, 0xabc },
828 		{ "-10", false, 0 },
829 		{ "0x0", true, 0 },
830 		{ "0", true, 0 },
831 		{ "0x-99", false, 0 },
832 		{ "0xak", false, 0 },
833 		{ "0x", false, 0 },
834 		{ "x10", false, 0 },
835 		{ NULL, false, 0 }
836 	};
837 
838 	unsigned int v;
839 	bool success;
840 
841 	for (int i = 0; tests[i].str != NULL; i++) {
842 		v = 0xad;
843 		success = safe_atou_base(tests[i].str, &v, 16);
844 		ck_assert(success == tests[i].success);
845 		if (success)
846 			ck_assert_int_eq(v, tests[i].val);
847 		else
848 			ck_assert_int_eq(v, 0xad);
849 	}
850 }
851 END_TEST
852 
START_TEST(safe_atou_base_8_test)853 START_TEST(safe_atou_base_8_test)
854 {
855 	struct atou_test tests[] = {
856 		{ "7", true, 07 },
857 		{ "10", true, 010 },
858 		{ "20", true, 020 },
859 		{ "-1", false, 0 },
860 		{ "010", true, 010 },
861 		{ "0ff", false, 0 },
862 		{ "abc", false, 0},
863 		{ "0xabc", false, 0},
864 		{ "-10", false, 0 },
865 		{ "0", true, 0 },
866 		{ "00", true, 0 },
867 		{ "0x0", false, 0 },
868 		{ "0x-99", false, 0 },
869 		{ "0xak", false, 0 },
870 		{ "0x", false, 0 },
871 		{ "x10", false, 0 },
872 		{ NULL, false, 0 }
873 	};
874 
875 	unsigned int v;
876 	bool success;
877 
878 	for (int i = 0; tests[i].str != NULL; i++) {
879 		v = 0xad;
880 		success = safe_atou_base(tests[i].str, &v, 8);
881 		ck_assert(success == tests[i].success);
882 		if (success)
883 			ck_assert_int_eq(v, tests[i].val);
884 		else
885 			ck_assert_int_eq(v, 0xad);
886 	}
887 }
888 END_TEST
889 
START_TEST(safe_atod_test)890 START_TEST(safe_atod_test)
891 {
892 	struct atod_test {
893 		char *str;
894 		bool success;
895 		double val;
896 	} tests[] = {
897 		{ "10", true, 10 },
898 		{ "20", true, 20 },
899 		{ "-1", true, -1 },
900 		{ "2147483647", true, 2147483647 },
901 		{ "-2147483648", true, -2147483648 },
902 		{ "4294967295", true, 4294967295 },
903 		{ "0x0", false, 0 },
904 		{ "0x10", false, 0 },
905 		{ "0xaf", false, 0 },
906 		{ "x80", false, 0 },
907 		{ "0.0", true, 0.0 },
908 		{ "0.1", true, 0.1 },
909 		{ "1.2", true, 1.2 },
910 		{ "-324.9", true, -324.9 },
911 		{ "9324.9", true, 9324.9 },
912 		{ "NAN", false, 0 },
913 		{ "INFINITY", false, 0 },
914 		{ "-10x10", false, 0 },
915 		{ "1x-99", false, 0 },
916 		{ "", false, 0 },
917 		{ "abd", false, 0 },
918 		{ "xabd", false, 0 },
919 		{ "0x0x", false, 0 },
920 		{ NULL, false, 0 }
921 	};
922 	double v;
923 	bool success;
924 
925 	for (int i = 0; tests[i].str != NULL; i++) {
926 		v = 0xad;
927 		success = safe_atod(tests[i].str, &v);
928 		ck_assert(success == tests[i].success);
929 		if (success)
930 			ck_assert_int_eq(v, tests[i].val);
931 		else
932 			ck_assert_int_eq(v, 0xad);
933 	}
934 }
935 END_TEST
936 
START_TEST(strsplit_test)937 START_TEST(strsplit_test)
938 {
939 	struct strsplit_test {
940 		const char *string;
941 		const char *delim;
942 		const char *results[10];
943 	} tests[] = {
944 		{ "one two three", " ", { "one", "two", "three", NULL } },
945 		{ "one", " ", { "one", NULL } },
946 		{ "one two ", " ", { "one", "two", NULL } },
947 		{ "one  two", " ", { "one", "two", NULL } },
948 		{ " one two", " ", { "one", "two", NULL } },
949 		{ "one", "\t \r", { "one", NULL } },
950 		{ "one two three", " t", { "one", "wo", "hree", NULL } },
951 		{ " one two three", "te", { " on", " ", "wo ", "hr", NULL } },
952 		{ "one", "ne", { "o", NULL } },
953 		{ "onene", "ne", { "o", NULL } },
954 		{ NULL, NULL, { NULL }}
955 	};
956 	struct strsplit_test *t = tests;
957 
958 	while (t->string) {
959 		char **strv;
960 		int idx = 0;
961 		strv = strv_from_string(t->string, t->delim);
962 		while (t->results[idx]) {
963 			ck_assert_str_eq(t->results[idx], strv[idx]);
964 			idx++;
965 		}
966 		ck_assert_ptr_eq(strv[idx], NULL);
967 		strv_free(strv);
968 		t++;
969 	}
970 
971 	/* Special cases */
972 	ck_assert_ptr_eq(strv_from_string("", " "), NULL);
973 	ck_assert_ptr_eq(strv_from_string(" ", " "), NULL);
974 	ck_assert_ptr_eq(strv_from_string("     ", " "), NULL);
975 	ck_assert_ptr_eq(strv_from_string("oneoneone", "one"), NULL);
976 }
977 END_TEST
978 
START_TEST(kvsplit_double_test)979 START_TEST(kvsplit_double_test)
980 {
981 	struct kvsplit_dbl_test {
982 		const char *string;
983 		const char *psep;
984 		const char *kvsep;
985 		ssize_t nresults;
986 		struct {
987 			double a;
988 			double b;
989 		} results[32];
990 	} tests[] = {
991 		{ "1:2;3:4;5:6", ";", ":", 3, { {1, 2}, {3, 4}, {5, 6}}},
992 		{ "1.0x2.3 -3.2x4.5 8.090909x-6.00", " ", "x", 3, { {1.0, 2.3}, {-3.2, 4.5}, {8.090909, -6}}},
993 
994 		{ "1:2", "x", ":", 1, {{1, 2}}},
995 		{ "1:2", ":", "x", -1, {}},
996 		{ "1:2", NULL, "x", -1, {}},
997 		{ "1:2", "", "x", -1, {}},
998 		{ "1:2", "x", NULL, -1, {}},
999 		{ "1:2", "x", "", -1, {}},
1000 		{ "a:b", "x", ":", -1, {}},
1001 		{ "", " ", "x", -1, {}},
1002 		{ "1.2.3.4.5", ".", "", -1, {}},
1003 		{ NULL }
1004 	};
1005 	struct kvsplit_dbl_test *t = tests;
1006 
1007 	while (t->string) {
1008 		struct key_value_double *result = NULL;
1009 		ssize_t npairs;
1010 
1011 		npairs = kv_double_from_string(t->string,
1012 					       t->psep,
1013 					       t->kvsep,
1014 					       &result);
1015 		ck_assert_int_eq(npairs, t->nresults);
1016 
1017 		for (ssize_t i = 0; i < npairs; i++) {
1018 			ck_assert_double_eq(t->results[i].a, result[i].key);
1019 			ck_assert_double_eq(t->results[i].b, result[i].value);
1020 		}
1021 
1022 
1023 		free(result);
1024 		t++;
1025 	}
1026 }
1027 END_TEST
1028 
START_TEST(strjoin_test)1029 START_TEST(strjoin_test)
1030 {
1031 	struct strjoin_test {
1032 		char *strv[10];
1033 		const char *joiner;
1034 		const char *result;
1035 	} tests[] = {
1036 		{ { "one", "two", "three", NULL }, " ", "one two three" },
1037 		{ { "one", NULL }, "x", "one" },
1038 		{ { "one", "two", NULL }, "x", "onextwo" },
1039 		{ { "one", "two", NULL }, ",", "one,two" },
1040 		{ { "one", "two", NULL }, ", ", "one, two" },
1041 		{ { "one", "two", NULL }, "one", "oneonetwo" },
1042 		{ { "one", "two", NULL }, NULL, NULL },
1043 		{ { "", "", "", NULL }, " ", "  " },
1044 		{ { "a", "b", "c", NULL }, "", "abc" },
1045 		{ { "", "b", "c", NULL }, "x", "xbxc" },
1046 		{ { "", "", "", NULL }, "", "" },
1047 		{ { NULL }, NULL, NULL }
1048 	};
1049 	struct strjoin_test *t = tests;
1050 	struct strjoin_test nulltest = { {NULL}, "x", NULL };
1051 
1052 	while (t->strv[0]) {
1053 		char *str;
1054 		str = strv_join(t->strv, t->joiner);
1055 		if (t->result == NULL)
1056 			ck_assert(str == NULL);
1057 		else
1058 			ck_assert_str_eq(str, t->result);
1059 		free(str);
1060 		t++;
1061 	}
1062 
1063 	ck_assert(strv_join(nulltest.strv, "x") == NULL);
1064 }
1065 END_TEST
1066 
START_TEST(strstrip_test)1067 START_TEST(strstrip_test)
1068 {
1069 	struct strstrip_test {
1070 		const char *string;
1071 		const char *expected;
1072 		const char *what;
1073 	} tests[] = {
1074 		{ "foo",		"foo",		"1234" },
1075 		{ "\"bar\"",		"bar",		"\"" },
1076 		{ "'bar'",		"bar",		"'" },
1077 		{ "\"bar\"",		"\"bar\"",	"'" },
1078 		{ "'bar'",		"'bar'",	"\"" },
1079 		{ "\"bar\"",		"bar",		"\"" },
1080 		{ "\"\"",		"",		"\"" },
1081 		{ "\"foo\"bar\"",	"foo\"bar",	"\"" },
1082 		{ "\"'foo\"bar\"",	"foo\"bar",	"\"'" },
1083 		{ "abcfooabcbarbca",	"fooabcbar",	"abc" },
1084 		{ "xxxxfoo",		"foo",		"x" },
1085 		{ "fooyyyy",		"foo",		"y" },
1086 		{ "xxxxfooyyyy",	"foo",		"xy" },
1087 		{ "x xfooy y",		" xfooy ",	"xy" },
1088 		{ " foo\n",		"foo",		" \n" },
1089 		{ "",			"",		"abc" },
1090 		{ "",			"",		"" },
1091 		{ NULL , NULL, NULL }
1092 	};
1093 	struct strstrip_test *t = tests;
1094 
1095 	while (t->string) {
1096 		char *str;
1097 		str = strstrip(t->string, t->what);
1098 		ck_assert_str_eq(str, t->expected);
1099 		free(str);
1100 		t++;
1101 	}
1102 }
1103 END_TEST
1104 
START_TEST(strendswith_test)1105 START_TEST(strendswith_test)
1106 {
1107 	struct strendswith_test {
1108 		const char *string;
1109 		const char *suffix;
1110 		bool expected;
1111 	} tests[] = {
1112 		{ "foobar", "bar", true },
1113 		{ "foobar", "foo", false },
1114 		{ "foobar", "foobar", true },
1115 		{ "foo", "foobar", false },
1116 		{ "foobar", "", false },
1117 		{ "", "", false },
1118 		{ "", "foo", false },
1119 		{ NULL, NULL, false },
1120 	};
1121 
1122 	for (struct strendswith_test *t = tests; t->string; t++) {
1123 		ck_assert_int_eq(strendswith(t->string, t->suffix),
1124 				 t->expected);
1125 	}
1126 }
1127 END_TEST
1128 
START_TEST(strstartswith_test)1129 START_TEST(strstartswith_test)
1130 {
1131 	struct strstartswith_test {
1132 		const char *string;
1133 		const char *suffix;
1134 		bool expected;
1135 	} tests[] = {
1136 		{ "foobar", "foo", true },
1137 		{ "foobar", "bar", false },
1138 		{ "foobar", "foobar", true },
1139 		{ "foo", "foobar", false },
1140 		{ "foo", "", false },
1141 		{ "", "", false },
1142 		{ "foo", "", false },
1143 		{ NULL, NULL, false },
1144 	};
1145 
1146 	for (struct strstartswith_test *t = tests; t->string; t++) {
1147 		ck_assert_int_eq(strstartswith(t->string, t->suffix),
1148 				 t->expected);
1149 	}
1150 }
1151 END_TEST
1152 
START_TEST(list_test_insert)1153 START_TEST(list_test_insert)
1154 {
1155 	struct list_test {
1156 		int val;
1157 		struct list node;
1158 	} tests[] = {
1159 		{ .val  = 1 },
1160 		{ .val  = 2 },
1161 		{ .val  = 3 },
1162 		{ .val  = 4 },
1163 	};
1164 	struct list_test *t;
1165 	struct list head;
1166 	int val;
1167 
1168 	list_init(&head);
1169 
1170 	ARRAY_FOR_EACH(tests, t) {
1171 		list_insert(&head, &t->node);
1172 	}
1173 
1174 	val = 4;
1175 	list_for_each(t, &head, node) {
1176 		ck_assert_int_eq(t->val, val);
1177 		val--;
1178 	}
1179 
1180 	ck_assert_int_eq(val, 0);
1181 }
1182 END_TEST
1183 
START_TEST(list_test_append)1184 START_TEST(list_test_append)
1185 {
1186 	struct list_test {
1187 		int val;
1188 		struct list node;
1189 	} tests[] = {
1190 		{ .val  = 1 },
1191 		{ .val  = 2 },
1192 		{ .val  = 3 },
1193 		{ .val  = 4 },
1194 	};
1195 	struct list_test *t;
1196 	struct list head;
1197 	int val;
1198 
1199 	list_init(&head);
1200 
1201 	ARRAY_FOR_EACH(tests, t) {
1202 		list_append(&head, &t->node);
1203 	}
1204 
1205 	val = 1;
1206 	list_for_each(t, &head, node) {
1207 		ck_assert_int_eq(t->val, val);
1208 		val++;
1209 	}
1210 	ck_assert_int_eq(val, 5);
1211 }
1212 END_TEST
1213 
START_TEST(strverscmp_test)1214 START_TEST(strverscmp_test)
1215 {
1216 	ck_assert_int_eq(libinput_strverscmp("", ""), 0);
1217 	ck_assert_int_gt(libinput_strverscmp("0.0.1", ""), 0);
1218 	ck_assert_int_lt(libinput_strverscmp("", "0.0.1"), 0);
1219 	ck_assert_int_eq(libinput_strverscmp("0.0.1", "0.0.1"), 0);
1220 	ck_assert_int_eq(libinput_strverscmp("0.0.1", "0.0.2"), -1);
1221 	ck_assert_int_eq(libinput_strverscmp("0.0.2", "0.0.1"), 1);
1222 	ck_assert_int_eq(libinput_strverscmp("0.0.1", "0.1.0"), -1);
1223 	ck_assert_int_eq(libinput_strverscmp("0.1.0", "0.0.1"), 1);
1224 }
1225 END_TEST
1226 
1227 static Suite *
litest_utils_suite(void)1228 litest_utils_suite(void)
1229 {
1230 	TCase *tc;
1231 	Suite *s;
1232 
1233 	s = suite_create("litest:utils");
1234 	tc = tcase_create("utils");
1235 
1236 	tcase_add_test(tc, bitfield_helpers);
1237 	tcase_add_test(tc, matrix_helpers);
1238 	tcase_add_test(tc, ratelimit_helpers);
1239 	tcase_add_test(tc, dpi_parser);
1240 	tcase_add_test(tc, wheel_click_parser);
1241 	tcase_add_test(tc, wheel_click_count_parser);
1242 	tcase_add_test(tc, dimension_prop_parser);
1243 	tcase_add_test(tc, reliability_prop_parser);
1244 	tcase_add_test(tc, calibration_prop_parser);
1245 	tcase_add_test(tc, range_prop_parser);
1246 	tcase_add_test(tc, evcode_prop_parser);
1247 	tcase_add_test(tc, evdev_abs_parser);
1248 	tcase_add_test(tc, safe_atoi_test);
1249 	tcase_add_test(tc, safe_atoi_base_16_test);
1250 	tcase_add_test(tc, safe_atoi_base_8_test);
1251 	tcase_add_test(tc, safe_atou_test);
1252 	tcase_add_test(tc, safe_atou_base_16_test);
1253 	tcase_add_test(tc, safe_atou_base_8_test);
1254 	tcase_add_test(tc, safe_atod_test);
1255 	tcase_add_test(tc, strsplit_test);
1256 	tcase_add_test(tc, kvsplit_double_test);
1257 	tcase_add_test(tc, strjoin_test);
1258 	tcase_add_test(tc, strstrip_test);
1259 	tcase_add_test(tc, strendswith_test);
1260 	tcase_add_test(tc, strstartswith_test);
1261 	tcase_add_test(tc, time_conversion);
1262 	tcase_add_test(tc, human_time);
1263 
1264 	tcase_add_test(tc, list_test_insert);
1265 	tcase_add_test(tc, list_test_append);
1266 	tcase_add_test(tc, strverscmp_test);
1267 
1268 	suite_add_tcase(s, tc);
1269 
1270 	return s;
1271 }
1272 
main(int argc,char ** argv)1273 int main(int argc, char **argv)
1274 {
1275 	int nfailed;
1276 	Suite *s;
1277 	SRunner *sr;
1278 
1279 	s = litest_utils_suite();
1280 	sr = srunner_create(s);
1281 
1282 	srunner_run_all(sr, CK_ENV);
1283 	nfailed = srunner_ntests_failed(sr);
1284 	srunner_free(sr);
1285 
1286 	return (nfailed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1287 }
1288