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 : 38 : check_read(const char* const string,
14 : : const ExessStatus expected_status,
15 : : const int64_t expected_value,
16 : : const size_t expected_count)
17 : : {
18 : 38 : int64_t value = 0;
19 : :
20 : 38 : const ExessResult r = exess_read_long(string, &value);
21 [ - + ]: 38 : assert(r.status == expected_status);
22 [ - + ]: 38 : assert(r.count == expected_count);
23 [ - + ]: 38 : assert(value == expected_value);
24 : 38 : }
25 : :
26 : : static void
27 : 1 : test_read_long(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("-1", EXESS_SUCCESS, -1, 2);
35 : 1 : check_read("0", EXESS_SUCCESS, 0, 1);
36 : 1 : check_read("1", EXESS_SUCCESS, 1, 1);
37 : 1 : check_read("1234", EXESS_SUCCESS, 1234, 4);
38 : 1 : check_read("-1234", EXESS_SUCCESS, -1234, 5);
39 : :
40 : : // Non-canonical form
41 : 1 : check_read("\t\n\r 1234 ", EXESS_SUCCESS, 1234, 8);
42 : 1 : check_read("\t\n\r -1234 ", EXESS_SUCCESS, -1234, 9);
43 : 1 : check_read("\t\n\r +1234 ", EXESS_SUCCESS, 1234, 9);
44 : 1 : check_read("\t\n\r 01234 ", EXESS_SUCCESS, 1234, 9);
45 : 1 : check_read("\t\n\r -01234 ", EXESS_SUCCESS, -1234, 10);
46 : 1 : check_read("-01", EXESS_SUCCESS, -1, 3);
47 : 1 : check_read("-0", EXESS_SUCCESS, 0, 2);
48 : 1 : check_read("-00", EXESS_SUCCESS, 0, 3);
49 : 1 : check_read("00", EXESS_SUCCESS, 0, 2);
50 : 1 : check_read("+0", EXESS_SUCCESS, 0, 2);
51 : 1 : check_read("+00", EXESS_SUCCESS, 0, 3);
52 : 1 : check_read("+1", EXESS_SUCCESS, 1, 2);
53 : 1 : check_read("+01", EXESS_SUCCESS, 1, 3);
54 : 1 : check_read("+1234", EXESS_SUCCESS, 1234, 5);
55 : 1 : check_read("01234", EXESS_SUCCESS, 1234, 5);
56 : 1 : check_read("-01234", EXESS_SUCCESS, -1234, 6);
57 : :
58 : : // Limits
59 : 1 : check_read(
60 : : "-9223372036854775808", EXESS_SUCCESS, INT64_MIN, EXESS_MAX_LONG_LENGTH);
61 : 1 : check_read("9223372036854775807", EXESS_SUCCESS, INT64_MAX, 19);
62 : :
63 : : // Out of range
64 : 1 : check_read("-9223372036854775809", EXESS_OUT_OF_RANGE, 0, 20);
65 : 1 : check_read("9223372036854775808", EXESS_OUT_OF_RANGE, 0, 19);
66 : 1 : check_read("12345678901234567890", EXESS_OUT_OF_RANGE, 0, 20);
67 : :
68 : : // Trailing garbage
69 : 1 : check_read("1234extra", EXESS_SUCCESS, 1234, 4);
70 : 1 : check_read("-0x", EXESS_SUCCESS, 0, 2);
71 : :
72 : : // Garbage
73 : 1 : check_read("+", EXESS_EXPECTED_DIGIT, 0, 1);
74 : 1 : check_read("-", EXESS_EXPECTED_DIGIT, 0, 1);
75 : 1 : check_read("true", EXESS_EXPECTED_DIGIT, 0, 0);
76 : 1 : check_read("false", EXESS_EXPECTED_DIGIT, 0, 0);
77 : 1 : check_read("zero", EXESS_EXPECTED_DIGIT, 0, 0);
78 : 1 : check_read("NaN", EXESS_EXPECTED_DIGIT, 0, 0);
79 : 1 : check_read("INF", EXESS_EXPECTED_DIGIT, 0, 0);
80 : 1 : check_read("-INF", EXESS_EXPECTED_DIGIT, 0, 1);
81 : 1 : }
82 : :
83 : : static void
84 : 9 : check_write(const int64_t value,
85 : : const ExessStatus expected_status,
86 : : const size_t buf_size,
87 : : const char* const expected_string)
88 : : {
89 : 9 : char buf[EXESS_MAX_LONG_LENGTH + 1] = {
90 : : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
91 : :
92 [ - + ]: 9 : assert(buf_size <= sizeof(buf));
93 : :
94 : 9 : const ExessResult r = exess_write_long(value, buf_size, buf);
95 [ - + ]: 9 : assert(r.status == expected_status);
96 [ + + ]: 9 : if (!r.status) {
97 [ - + ]: 5 : assert(!strcmp(buf, expected_string));
98 [ - + ]: 5 : assert(r.count == strlen(buf));
99 [ - + ]: 5 : assert(exess_write_long(value, 0, NULL).count == r.count);
100 : : }
101 : 9 : }
102 : :
103 : : static void
104 : 1 : test_write_long(void)
105 : : {
106 : 1 : check_write(-1, EXESS_SUCCESS, 3, "-1");
107 : 1 : check_write(0, EXESS_SUCCESS, 2, "0");
108 : 1 : check_write(1, EXESS_SUCCESS, 2, "1");
109 : 1 : check_write(INT64_MIN, EXESS_SUCCESS, 21, "-9223372036854775808");
110 : 1 : check_write(INT64_MAX, EXESS_SUCCESS, 20, "9223372036854775807");
111 : :
112 : 1 : check_write(INT64_MIN, EXESS_NO_SPACE, 20, "");
113 : 1 : check_write(INT64_MAX, EXESS_NO_SPACE, 19, "");
114 : 1 : check_write(1234, EXESS_NO_SPACE, 4, "");
115 : 1 : check_write(-1234, EXESS_NO_SPACE, 5, "");
116 : :
117 : : // Check that nothing is written when there isn't enough space
118 : 1 : char c = 42;
119 : 1 : const ExessResult r = exess_write_long(1234, 0, &c);
120 [ - + ]: 1 : assert(c == 42);
121 [ - + ]: 1 : assert(r.status == EXESS_NO_SPACE);
122 [ - + ]: 1 : assert(r.count == 4);
123 : 1 : }
124 : :
125 : : int
126 : 1 : main(void)
127 : : {
128 : 1 : test_read_long();
129 : 1 : test_write_long();
130 : 1 : return 0;
131 : : }
|