Branch data Line data Source code
1 : : // Copyright 2011-2025 David Robillard <d@drobilla.net>
2 : : // SPDX-License-Identifier: ISC
3 : :
4 : : #undef NDEBUG
5 : :
6 : : #include <exess/exess.h>
7 : :
8 : : #include <assert.h>
9 : : #include <stdint.h>
10 : : #include <string.h>
11 : :
12 : : static void
13 : 27 : check_read(const char* const string,
14 : : const ExessStatus expected_status,
15 : : const uint64_t expected_value,
16 : : const size_t expected_count)
17 : : {
18 : 27 : uint64_t value = 0;
19 : 27 : const ExessResult r = exess_read_ulong(string, &value);
20 : :
21 [ - + ]: 27 : assert(r.status == expected_status);
22 [ - + ]: 27 : assert(r.count == expected_count);
23 [ - + ]: 27 : assert(value == expected_value);
24 : 27 : }
25 : :
26 : : static void
27 : 1 : test_read_ulong(void)
28 : : {
29 : : // No input
30 : 1 : check_read("", EXESS_EXPECTED_DIGIT, 0, 0);
31 : 1 : check_read("\t\n\r ", EXESS_EXPECTED_DIGIT, 0, 4);
32 : :
33 : : // Canonical form
34 : 1 : check_read("0", EXESS_SUCCESS, 0, 1);
35 : 1 : check_read("1234", EXESS_SUCCESS, 1234, 4);
36 : :
37 : : // Non-canonical form
38 : 1 : check_read("\t\n\r 1234 ", EXESS_SUCCESS, 1234, 8);
39 : 1 : check_read("\t\n\r +1234 ", EXESS_SUCCESS, 1234, 9);
40 : 1 : check_read("\t\n\r 01234 ", EXESS_SUCCESS, 1234, 9);
41 : 1 : check_read("+1234", EXESS_SUCCESS, 1234, 5);
42 : 1 : check_read("01234", EXESS_SUCCESS, 1234, 5);
43 : 1 : check_read("00", EXESS_SUCCESS, 0, 2);
44 : 1 : check_read("+0", EXESS_SUCCESS, 0, 2);
45 : 1 : check_read("-0", EXESS_SUCCESS, 0, 2);
46 : :
47 : : // Limits
48 : 1 : check_read("0", EXESS_SUCCESS, 0, 1);
49 : 1 : check_read(
50 : : "18446744073709551615", EXESS_SUCCESS, UINT64_MAX, EXESS_MAX_ULONG_LENGTH);
51 : :
52 : : // Out of range
53 : 1 : check_read("18446744073709551616", EXESS_OUT_OF_RANGE, 0, 19);
54 : :
55 : : // Trailing garbage
56 : 1 : check_read("1234extra", EXESS_SUCCESS, 1234, 4);
57 : 1 : check_read("-0x", EXESS_SUCCESS, 0, 2);
58 : 1 : check_read("-01", EXESS_SUCCESS, 0, 2);
59 : :
60 : : // Garbage
61 : 1 : check_read("+", EXESS_EXPECTED_DIGIT, 0, 1);
62 : 1 : check_read("-", EXESS_EXPECTED_ZERO, 0, 1);
63 : 1 : check_read("-1", EXESS_EXPECTED_ZERO, 0, 1);
64 : 1 : check_read("true", EXESS_EXPECTED_DIGIT, 0, 0);
65 : 1 : check_read("false", EXESS_EXPECTED_DIGIT, 0, 0);
66 : 1 : check_read("zero", EXESS_EXPECTED_DIGIT, 0, 0);
67 : 1 : check_read("NaN", EXESS_EXPECTED_DIGIT, 0, 0);
68 : 1 : check_read("INF", EXESS_EXPECTED_DIGIT, 0, 0);
69 : 1 : check_read("-INF", EXESS_EXPECTED_ZERO, 0, 1);
70 : 1 : }
71 : :
72 : : static void
73 : 4 : check_write(const uint64_t value,
74 : : const ExessStatus expected_status,
75 : : const size_t buf_size,
76 : : const char* const expected_string)
77 : : {
78 : 4 : char buf[EXESS_MAX_ULONG_LENGTH + 1] = {
79 : : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
80 : :
81 [ - + ]: 4 : assert(buf_size <= sizeof(buf));
82 : :
83 : 4 : const ExessResult r = exess_write_ulong(value, buf_size, buf);
84 : :
85 [ - + ]: 4 : assert(r.status == expected_status);
86 [ + + ]: 4 : if (!r.status) {
87 [ - + ]: 3 : assert(!strcmp(buf, expected_string));
88 [ - + ]: 3 : assert(r.count == strlen(buf));
89 [ - + ]: 3 : assert(exess_write_ulong(value, 0, NULL).count == r.count);
90 : : }
91 : 4 : }
92 : :
93 : : static void
94 : 1 : test_write_ulong(void)
95 : : {
96 : 1 : check_write(0U, EXESS_SUCCESS, 2, "0");
97 : 1 : check_write(1U, EXESS_SUCCESS, 2, "1");
98 : 1 : check_write(UINT64_MAX, EXESS_SUCCESS, 21, "18446744073709551615");
99 : :
100 : 1 : check_write(1234U, EXESS_NO_SPACE, 4, "");
101 : :
102 : : // Check that nothing is written when there isn't enough space
103 : 1 : char c = 42;
104 : 1 : const ExessResult r = exess_write_ulong(1234U, 0, &c);
105 [ - + ]: 1 : assert(c == 42);
106 [ - + ]: 1 : assert(r.status == EXESS_NO_SPACE);
107 [ - + ]: 1 : assert(r.count == 4);
108 : 1 : }
109 : :
110 : : int
111 : 1 : main(void)
112 : : {
113 : 1 : test_read_ulong();
114 : 1 : test_write_ulong();
115 : 1 : return 0;
116 : : }
|