Branch data Line data Source code
1 : : // Copyright 2011-2026 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 <stdbool.h>
10 : : #include <stdint.h>
11 : :
12 : : typedef bool (*ComparisonPredicate)(int);
13 : :
14 : : static bool
15 : 94 : less(const int cmp)
16 : : {
17 : 94 : return cmp == EXESS_ORDER_STRICTLY_LESS;
18 : : }
19 : :
20 : : static bool
21 : 29 : maybe_less(const int cmp)
22 : : {
23 : 29 : return cmp == EXESS_ORDER_MAYBE_LESS;
24 : : }
25 : :
26 : : static bool
27 : 106 : equal(const int cmp)
28 : : {
29 : 106 : return cmp == EXESS_ORDER_EQUAL;
30 : : }
31 : :
32 : : static bool
33 : 19 : maybe_greater(const int cmp)
34 : : {
35 : 19 : return cmp == EXESS_ORDER_MAYBE_GREATER;
36 : : }
37 : :
38 : : static bool
39 : 92 : greater(const int cmp)
40 : : {
41 : 92 : return cmp == EXESS_ORDER_STRICTLY_GREATER;
42 : : }
43 : :
44 : : static void
45 : 340 : check_cross_type_comparison(const ExessDatatype lhs_datatype,
46 : : const char* const lhs_string,
47 : : const ExessDatatype rhs_datatype,
48 : : const char* const rhs_string,
49 : : const ComparisonPredicate pred)
50 : : {
51 : : #define VALUE_SIZE 12U
52 : :
53 : 340 : EXESS_ALIGN uint8_t lhs[VALUE_SIZE] = {0};
54 : 340 : EXESS_ALIGN uint8_t rhs[VALUE_SIZE] = {0};
55 : :
56 : : const ExessVariableResult l =
57 : 340 : exess_read_value(lhs_datatype, lhs_string, sizeof(lhs), lhs);
58 : :
59 : : const ExessVariableResult r =
60 : 340 : exess_read_value(rhs_datatype, rhs_string, sizeof(rhs), rhs);
61 : :
62 [ + + - + ]: 340 : assert(lhs_datatype == EXESS_NOTHING || !l.status);
63 [ + + - + ]: 340 : assert(rhs_datatype == EXESS_NOTHING || !r.status);
64 : :
65 : 340 : const ExessOrder order = exess_compare_value(
66 : 340 : lhs_datatype, l.write_count, lhs, rhs_datatype, r.write_count, rhs);
67 : :
68 [ - + ]: 340 : assert(pred(order));
69 : :
70 : : // NOLINTNEXTLINE(readability-suspicious-call-argument)
71 : 340 : const ExessOrder inv_order = exess_compare_value(
72 : 340 : rhs_datatype, r.write_count, rhs, lhs_datatype, l.write_count, lhs);
73 : :
74 [ + + ]: 340 : if (order == EXESS_ORDER_STRICTLY_LESS) {
75 [ - + ]: 94 : assert(inv_order == EXESS_ORDER_STRICTLY_GREATER);
76 [ + + ]: 246 : } else if (order == EXESS_ORDER_MAYBE_LESS) {
77 [ - + ]: 29 : assert(inv_order == EXESS_ORDER_MAYBE_GREATER);
78 [ + + ]: 217 : } else if (order == EXESS_ORDER_EQUAL) {
79 [ - + ]: 106 : assert(inv_order == EXESS_ORDER_EQUAL);
80 [ + + ]: 111 : } else if (order == EXESS_ORDER_MAYBE_GREATER) {
81 [ - + ]: 19 : assert(inv_order == EXESS_ORDER_MAYBE_LESS);
82 [ + - ]: 92 : } else if (order == EXESS_ORDER_STRICTLY_GREATER) {
83 [ - + ]: 92 : assert(inv_order == EXESS_ORDER_STRICTLY_LESS);
84 : : }
85 : :
86 : : #undef VALUE_SIZE
87 : 340 : }
88 : :
89 : : static void
90 : 335 : check_comparison(const ExessDatatype datatype,
91 : : const char* const lhs_string,
92 : : const char* const rhs_string,
93 : : const ComparisonPredicate pred)
94 : : {
95 : 335 : check_cross_type_comparison(datatype, lhs_string, datatype, rhs_string, pred);
96 : 335 : }
97 : :
98 : : static void
99 : 5 : check_comparisons_partial(const ExessDatatype datatype,
100 : : const char* const low,
101 : : const char* const mid,
102 : : const char* const high)
103 : : {
104 : 5 : check_comparison(datatype, low, mid, maybe_less);
105 : 5 : check_comparison(datatype, mid, mid, equal);
106 : 5 : check_comparison(datatype, high, mid, maybe_greater);
107 : 5 : }
108 : :
109 : : static void
110 : 75 : check_comparisons(const ExessDatatype datatype,
111 : : const char* const low,
112 : : const char* const mid,
113 : : const char* const high)
114 : : {
115 : 75 : check_comparison(datatype, low, mid, less);
116 : 75 : check_comparison(datatype, mid, mid, equal);
117 : 75 : check_comparison(datatype, high, mid, greater);
118 : 75 : }
119 : :
120 : : static void
121 : 1 : test_compare(void)
122 : : {
123 : : // Cross-type and nothing
124 : 1 : check_cross_type_comparison(EXESS_NOTHING, "", EXESS_NOTHING, "", equal);
125 : 1 : check_cross_type_comparison(EXESS_NOTHING, "", EXESS_INT, "0", maybe_less);
126 : 1 : check_cross_type_comparison(EXESS_INT, "0", EXESS_NOTHING, "", maybe_greater);
127 : 1 : check_cross_type_comparison(
128 : : EXESS_BOOLEAN, "true", EXESS_INT, "0", maybe_less);
129 : 1 : check_cross_type_comparison(
130 : : EXESS_TIME, "12:00:00", EXESS_INT, "42", maybe_greater);
131 : :
132 : : // All boolean cases
133 : 1 : check_comparison(EXESS_BOOLEAN, "false", "true", less);
134 : 1 : check_comparison(EXESS_BOOLEAN, "false", "1", less);
135 : 1 : check_comparison(EXESS_BOOLEAN, "0", "true", less);
136 : 1 : check_comparison(EXESS_BOOLEAN, "0", "1", less);
137 : 1 : check_comparison(EXESS_BOOLEAN, "false", "false", equal);
138 : 1 : check_comparison(EXESS_BOOLEAN, "false", "0", equal);
139 : 1 : check_comparison(EXESS_BOOLEAN, "0", "0", equal);
140 : 1 : check_comparison(EXESS_BOOLEAN, "0", "false", equal);
141 : 1 : check_comparison(EXESS_BOOLEAN, "true", "true", equal);
142 : 1 : check_comparison(EXESS_BOOLEAN, "true", "1", equal);
143 : 1 : check_comparison(EXESS_BOOLEAN, "1", "1", equal);
144 : 1 : check_comparison(EXESS_BOOLEAN, "1", "true", equal);
145 : 1 : check_comparison(EXESS_BOOLEAN, "true", "false", greater);
146 : 1 : check_comparison(EXESS_BOOLEAN, "true", "0", greater);
147 : 1 : check_comparison(EXESS_BOOLEAN, "1", "0", greater);
148 : :
149 : : // Numbers
150 : 1 : check_comparison(EXESS_DECIMAL, "-0.0", "0.0", equal);
151 : 1 : check_comparisons(EXESS_DECIMAL, "-0.1", "-0.0", "0.1");
152 : 1 : check_comparisons(EXESS_DECIMAL, "-9.0", "0.0", "9.0");
153 : 1 : check_comparisons(EXESS_DECIMAL, "-100.0", "-10.0", "-1.0");
154 : 1 : check_comparisons(EXESS_DECIMAL, "1.0", "10.0", "100.0");
155 : 1 : check_comparisons(EXESS_DOUBLE, "1.0E-1", "1.0E0", "1.0E1");
156 : 1 : check_comparisons(EXESS_FLOAT, "-1.0E-1", "1.0E0", "1.0E1");
157 : 1 : check_comparisons(EXESS_INTEGER, "-9", "0", "9");
158 : 1 : check_comparisons(EXESS_NON_POSITIVE_INTEGER, "-9", "-5", "0");
159 : 1 : check_comparisons(EXESS_NEGATIVE_INTEGER, "-9", "-5", "-1");
160 : 1 : check_comparisons(EXESS_LONG, "-9", "0", "9");
161 : 1 : check_comparisons(EXESS_INT, "-9", "0", "9");
162 : 1 : check_comparisons(EXESS_SHORT, "-9", "0", "9");
163 : 1 : check_comparisons(EXESS_BYTE, "-9", "0", "9");
164 : 1 : check_comparisons(EXESS_NON_NEGATIVE_INTEGER, "0", "5", "9");
165 : 1 : check_comparisons(EXESS_ULONG, "0", "5", "9");
166 : 1 : check_comparisons(EXESS_UINT, "0", "5", "9");
167 : 1 : check_comparisons(EXESS_USHORT, "0", "5", "9");
168 : 1 : check_comparisons(EXESS_UBYTE, "0", "5", "9");
169 : 1 : check_comparisons(EXESS_POSITIVE_INTEGER, "1", "5", "9");
170 : :
171 : : // Duration
172 : :
173 : : // Trivially comparable
174 : 1 : check_comparisons(EXESS_DURATION, "-P9Y", "P0Y", "P9Y");
175 : 1 : check_comparisons(EXESS_DURATION, "-P9M", "P0M", "P9M");
176 : 1 : check_comparisons(EXESS_DURATION, "-P9D", "P0D", "P9D");
177 : 1 : check_comparisons(EXESS_DURATION, "-PT9H", "PT0H", "PT9H");
178 : 1 : check_comparisons(EXESS_DURATION, "-PT9M", "PT0M", "PT9M");
179 : 1 : check_comparisons(EXESS_DURATION, "-PT9S", "PT0S", "PT9S");
180 : 1 : check_comparisons(EXESS_DURATION, "-PT0.9S", "PT0.0S", "PT0.9S");
181 : :
182 : : // Months and years
183 : 1 : check_comparison(EXESS_DURATION, "P11M", "P1Y", less);
184 : 1 : check_comparison(EXESS_DURATION, "P12M", "P1Y", equal);
185 : 1 : check_comparison(EXESS_DURATION, "P13M", "P1Y", greater);
186 : :
187 : : // Months and days
188 : 1 : check_comparison(EXESS_DURATION, "P27D", "P1M", less);
189 : 1 : check_comparison(EXESS_DURATION, "P31D", "P1M", maybe_less);
190 : 1 : check_comparison(EXESS_DURATION, "P32D", "P1M", greater);
191 : 1 : check_comparison(EXESS_DURATION, "P1M", "P28D", maybe_greater);
192 : 1 : check_comparison(EXESS_DURATION, "P330D", "P6M", maybe_less);
193 : 1 : check_comparison(EXESS_DURATION, "P4M", "P4M28D", maybe_less);
194 : 1 : check_comparison(EXESS_DURATION, "P4M", "P4M31D", maybe_less);
195 : 1 : check_comparison(EXESS_DURATION, "P4M", "P4M32D", maybe_less);
196 : 1 : check_comparison(EXESS_DURATION, "P3M29D", "P4M", less);
197 : 1 : check_comparison(EXESS_DURATION, "P3M31D", "P4M", maybe_less);
198 : 1 : check_comparison(EXESS_DURATION, "P4M27D", "P4M", maybe_greater);
199 : :
200 : : // Months and seconds
201 : 1 : check_comparison(EXESS_DURATION, "P1MT0.000000001S", "P1M", greater);
202 : 1 : check_comparison(EXESS_DURATION, "P1M", "P1MT0.000000001S", less);
203 : :
204 : : // Days, seconds, and months
205 : 1 : check_comparison(EXESS_DURATION, "P3M30DT86400S", "P4M", maybe_less);
206 : 1 : check_comparison(EXESS_DURATION, "P3M30DT86400.1S", "P4M", greater);
207 : 1 : check_comparison(EXESS_DURATION, "P3M30DT86401S", "P4M", greater);
208 : 1 : check_comparison(EXESS_DURATION, "P3M31DT0.000000001S", "P4M", greater);
209 : 1 : check_comparison(EXESS_DURATION, "P3M32D", "P4M", greater);
210 : :
211 : : // Seconds and days
212 : 1 : check_comparison(EXESS_DURATION, "PT86399S", "P1D", less);
213 : 1 : check_comparison(EXESS_DURATION, "PT86400S", "P1D", equal);
214 : 1 : check_comparison(EXESS_DURATION, "PT86401S", "P1D", greater);
215 : :
216 : : // Seconds and months
217 : 1 : check_comparison(EXESS_DURATION, "PT2332800S", "P1M", less);
218 : 1 : check_comparison(EXESS_DURATION, "PT2678400S", "P1M", maybe_less);
219 : 1 : check_comparison(EXESS_DURATION, "PT2678401S", "P1M", greater);
220 : :
221 : : // Seconds and years
222 : 1 : check_comparison(EXESS_DURATION, "PT31535999S", "P1Y", less);
223 : 1 : check_comparison(EXESS_DURATION, "PT31536000S", "P1Y", maybe_less);
224 : 1 : check_comparison(EXESS_DURATION, "PT31622400S", "P1Y", maybe_less);
225 : 1 : check_comparison(EXESS_DURATION, "PT31622401S", "P1Y", greater);
226 : :
227 : : // DateTime
228 : :
229 : : // Equality
230 : 1 : check_comparison(
231 : : EXESS_DATE_TIME, "2001-02-03T12:13:14", "2001-02-03T12:13:14", equal);
232 : 1 : check_comparison(
233 : : EXESS_DATE_TIME, "2001-02-03T12:13:14Z", "2001-02-03T12:13:14Z", equal);
234 : :
235 : : // All local
236 : 1 : check_comparisons(EXESS_DATE_TIME,
237 : : "2001-02-03T12:13:14.15",
238 : : "2001-02-03T12:13:14.16",
239 : : "2001-02-03T12:13:14.17");
240 : 1 : check_comparisons(EXESS_DATE_TIME,
241 : : "2001-02-03T12:13:14",
242 : : "2001-02-03T12:13:15",
243 : : "2001-02-03T12:13:16");
244 : 1 : check_comparisons(EXESS_DATE_TIME,
245 : : "2001-02-03T12:13:14",
246 : : "2001-02-03T12:14:14",
247 : : "2001-02-03T12:15:14");
248 : 1 : check_comparisons(EXESS_DATE_TIME,
249 : : "2001-02-03T12:13:14",
250 : : "2001-02-03T13:13:14",
251 : : "2001-02-03T14:13:14");
252 : 1 : check_comparisons(EXESS_DATE_TIME,
253 : : "2001-02-03T12:13:14",
254 : : "2001-02-04T12:13:14",
255 : : "2001-02-05T12:13:14");
256 : 1 : check_comparisons(EXESS_DATE_TIME,
257 : : "2001-02-03T12:13:14",
258 : : "2001-03-03T12:13:14",
259 : : "2001-04-03T12:13:14");
260 : 1 : check_comparisons(EXESS_DATE_TIME,
261 : : "2001-02-03T12:13:14",
262 : : "2002-02-03T12:13:14",
263 : : "2003-02-03T12:13:14");
264 : :
265 : : // All UTC
266 : 1 : check_comparisons(EXESS_DATE_TIME,
267 : : "2001-02-03T12:13:14.15Z",
268 : : "2001-02-03T12:13:14.16Z",
269 : : "2001-02-03T12:13:14.17Z");
270 : 1 : check_comparisons(EXESS_DATE_TIME,
271 : : "2001-02-03T12:13:14Z",
272 : : "2001-02-03T12:13:15Z",
273 : : "2001-02-03T12:13:16Z");
274 : 1 : check_comparisons(EXESS_DATE_TIME,
275 : : "2001-02-03T12:13:14Z",
276 : : "2001-02-03T12:14:14Z",
277 : : "2001-02-03T12:15:14Z");
278 : 1 : check_comparisons(EXESS_DATE_TIME,
279 : : "2001-02-03T12:13:14Z",
280 : : "2001-02-03T13:13:14Z",
281 : : "2001-02-03T14:13:14Z");
282 : 1 : check_comparisons(EXESS_DATE_TIME,
283 : : "2001-02-03T12:13:14Z",
284 : : "2001-02-04T12:13:14Z",
285 : : "2001-02-05T12:13:14Z");
286 : 1 : check_comparisons(EXESS_DATE_TIME,
287 : : "2001-02-03T12:13:14Z",
288 : : "2001-03-03T12:13:14Z",
289 : : "2001-04-03T12:13:14Z");
290 : 1 : check_comparisons(EXESS_DATE_TIME,
291 : : "2001-02-03T12:13:14Z",
292 : : "2002-02-03T12:13:14Z",
293 : : "2003-02-03T12:13:14Z");
294 : :
295 : : // Local and UTC comparable
296 : 1 : check_comparisons(EXESS_DATE_TIME,
297 : : "2001-02-03T12:13:14Z",
298 : : "2001-02-04T02:13:15",
299 : : "2001-02-04T16:13:15.000000001Z");
300 : 1 : check_comparisons(EXESS_DATE_TIME,
301 : : "2001-02-03T12:13:14Z",
302 : : "2001-02-04T12:13:14",
303 : : "2001-02-05T12:13:14Z");
304 : 1 : check_comparisons(EXESS_DATE_TIME,
305 : : "2001-02-03T12:13:14",
306 : : "2001-02-04T02:13:15Z",
307 : : "2001-02-04T16:13:16");
308 : :
309 : : // Local and UTC incomparable, "same" time
310 : 1 : check_comparison(EXESS_DATE_TIME,
311 : : "2001-02-03T12:13:14Z",
312 : : "2001-02-03T12:13:14",
313 : : maybe_greater);
314 : :
315 : : // Local and UTC incomparable, exactly -14 hours apart
316 : 1 : check_comparison(EXESS_DATE_TIME,
317 : : "2001-02-04T16:13:15Z",
318 : : "2001-02-04T02:13:15",
319 : : maybe_greater);
320 : :
321 : : // Local and UTC incomparable, exactly +14 hours apart
322 : 1 : check_comparison(
323 : : EXESS_DATE_TIME, "2001-02-04T02:13:15", "2001-02-04T16:13:15Z", maybe_less);
324 : :
325 : : // Local and UTC comparable, just over +14 hours apart
326 : 1 : check_comparison(EXESS_DATE_TIME,
327 : : "2001-02-04T02:13:15",
328 : : "2001-02-04T16:13:15.000000001Z",
329 : : less);
330 : :
331 : : // Local and UTC comparable (example from spec)
332 : 1 : check_comparison(
333 : : EXESS_DATE_TIME, "2000-01-15T12:00:00", "2000-01-16T12:00:00Z", less);
334 : :
335 : : // Local and UTC incomparable (examples from spec, local is first here)
336 : 1 : check_comparison(
337 : : EXESS_DATE_TIME, "2000-01-01T12:00:00", "1999-12-31T23:00:00Z", maybe_less);
338 : 1 : check_comparison(
339 : : EXESS_DATE_TIME, "2000-01-16T12:00:00", "2000-01-16T12:00:00Z", maybe_less);
340 : 1 : check_comparison(
341 : : EXESS_DATE_TIME, "2000-01-16T00:00:00", "2000-01-16T12:00:00Z", maybe_less);
342 : :
343 : : // Time
344 : :
345 : : // Equality
346 : 1 : check_comparison(EXESS_TIME, "12:13:14", "12:13:14", equal);
347 : 1 : check_comparison(EXESS_TIME, "12:13:14Z", "12:13:14Z", equal);
348 : 1 : check_comparison(EXESS_TIME, "12:13:14", "12:13:14", equal);
349 : 1 : check_comparison(EXESS_TIME, "12:13:14+00:00", "12:13:14+00:00", equal);
350 : 1 : check_comparison(EXESS_TIME, "12:13:14", "12:13:14", equal);
351 : 1 : check_comparison(EXESS_TIME, "12:13:14-00:00", "12:13:14-00:00", equal);
352 : :
353 : : // All local
354 : 1 : check_comparisons(EXESS_TIME, "12:13:14.15", "12:13:14.16", "12:13:14.17");
355 : 1 : check_comparisons(EXESS_TIME, "12:13:14", "12:13:15", "12:13:16");
356 : 1 : check_comparisons(EXESS_TIME, "12:13:14", "12:14:14", "12:15:14");
357 : 1 : check_comparisons(EXESS_TIME, "12:13:14", "13:13:14", "14:13:14");
358 : :
359 : : // All UTC
360 : 1 : check_comparisons(EXESS_TIME, "12:13:14.15Z", "12:13:14.16Z", "12:13:14.17Z");
361 : 1 : check_comparisons(EXESS_TIME, "12:13:14Z", "12:13:15Z", "12:13:16Z");
362 : 1 : check_comparisons(EXESS_TIME, "12:13:14Z", "12:14:14Z", "12:15:14Z");
363 : 1 : check_comparisons(EXESS_TIME, "12:13:14Z", "13:13:14Z", "14:13:14Z");
364 : :
365 : : // Time zones
366 : 1 : check_comparisons(
367 : : EXESS_TIME, "12:13:14+03:00", "12:13:14+02:00", "12:13:14+01:00");
368 : 1 : check_comparisons(
369 : : EXESS_TIME, "12:13:14+03:00", "12:13:13+01:00", "12:13:13+00:00");
370 : :
371 : : // Local and UTC incomparable
372 : 1 : check_comparison(EXESS_TIME, "12:13:14", "02:13:15Z", maybe_less);
373 : 1 : check_comparison(EXESS_TIME, "02:13:15Z", "12:13:14", maybe_greater);
374 : :
375 : : // Local and UTC comparable
376 : 1 : check_comparison(EXESS_TIME, "01:00:00Z", "15:00:01", less);
377 : 1 : check_comparison(EXESS_TIME, "15:00:01", "01:00:00Z", greater);
378 : 1 : check_comparison(EXESS_TIME, "02:13:15Z", "16:13:16", less);
379 : 1 : check_comparison(EXESS_TIME, "16:13:16", "02:13:15Z", greater);
380 : :
381 : : // Local and UTC incomparable (local is first here)
382 : 1 : check_comparison(EXESS_TIME, "12:00:00", "12:00:00Z", maybe_less);
383 : 1 : check_comparison(EXESS_TIME, "00:00:00", "12:00:00Z", maybe_less);
384 : 1 : check_comparison(EXESS_TIME, "12:00:00Z", "12:00:00", maybe_greater);
385 : 1 : check_comparison(EXESS_TIME, "00:00:00Z", "12:00:00", maybe_greater);
386 : 1 : check_comparison(EXESS_TIME, "15:00:00Z", "01:00:00", maybe_greater);
387 : 1 : check_comparison(EXESS_TIME, "01:00:00", "15:00:00Z", maybe_less);
388 : :
389 : : // Date
390 : :
391 : : // Equality
392 : 1 : check_comparison(EXESS_DATE, "2001-02-03", "2001-02-03", equal);
393 : 1 : check_comparison(EXESS_DATE, "2001-02-03Z", "2001-02-03Z", equal);
394 : 1 : check_comparison(EXESS_DATE, "2001-02-03Z", "2001-02-03+00:00", equal);
395 : 1 : check_comparison(EXESS_DATE, "2001-02-03Z", "2001-02-03-00:00", equal);
396 : :
397 : : // All local
398 : 1 : check_comparisons(EXESS_DATE, "2001-02-03", "2001-02-04", "2001-02-05");
399 : 1 : check_comparisons(EXESS_DATE, "2001-02-03", "2001-03-03", "2001-04-03");
400 : 1 : check_comparisons(EXESS_DATE, "2001-02-03", "2002-02-03", "2003-02-03");
401 : :
402 : : // All UTC
403 : 1 : check_comparisons(EXESS_DATE, "2001-02-03Z", "2001-02-04Z", "2001-02-05");
404 : 1 : check_comparisons(EXESS_DATE, "2001-02-03Z", "2001-03-03Z", "2001-04-03");
405 : 1 : check_comparisons(EXESS_DATE, "2001-02-03Z", "2002-02-03Z", "2003-02-03");
406 : :
407 : : // Time zones
408 : 1 : check_comparisons(
409 : : EXESS_DATE, "2001-02-03+03:00", "2001-02-03+02:00", "2001-02-03+01:00");
410 : :
411 : : // Local and UTC
412 : 1 : check_comparison(EXESS_DATE, "2001-02-03Z", "2001-02-04", less);
413 : 1 : check_comparison(EXESS_DATE, "2001-02-04", "2001-02-04Z", maybe_less);
414 : 1 : check_comparison(EXESS_DATE, "2001-02-03Z", "2001-02-04", less);
415 : 1 : check_comparison(EXESS_DATE, "2001-02-04", "2001-02-05Z", less);
416 : 1 : check_comparison(EXESS_DATE, "2001-02-03Z", "2001-02-03", maybe_greater);
417 : 1 : check_comparison(EXESS_DATE, "2001-02-03", "2001-02-03Z", maybe_less);
418 : 1 : check_comparison(EXESS_DATE, "2001-02-03Z", "2001-02-03+01:00", greater);
419 : 1 : check_comparison(EXESS_DATE, "2001-02-03Z", "2001-02-03-01:00", less);
420 : 1 : check_comparison(EXESS_DATE, "2001-02-03Z", "2001-02-03+14:00", greater);
421 : :
422 : : // Gregorian calendar
423 : :
424 : : // YearMonth
425 : 1 : check_comparisons(EXESS_YEAR_MONTH, "2001-02", "2001-03", "2001-04");
426 : 1 : check_comparisons(EXESS_YEAR_MONTH, "2001-02Z", "2001-03Z", "2001-04");
427 : 1 : check_comparisons(
428 : : EXESS_YEAR_MONTH, "2001-02+03:00", "2001-02+02:00", "2001-02+01:00");
429 : :
430 : : // Year
431 : 1 : check_comparisons(EXESS_YEAR, "2001", "2002", "2003");
432 : 1 : check_comparisons(EXESS_YEAR, "2001Z", "2002Z", "2003");
433 : 1 : check_comparisons(EXESS_YEAR, "2001+03:00", "2001+02:00", "2001+01:00");
434 : :
435 : : // MonthDay
436 : 1 : check_comparisons(EXESS_MONTH_DAY, "--02-03", "--02-04", "--02-05");
437 : 1 : check_comparisons(EXESS_MONTH_DAY, "--02-03Z", "--03-03Z", "--03-04");
438 : 1 : check_comparisons(
439 : : EXESS_MONTH_DAY, "--01-02+03:00", "--01-02+02:00", "--01-02+01:00");
440 : :
441 : : // Day
442 : 1 : check_comparisons(EXESS_DAY, "---03", "---04", "---05");
443 : 1 : check_comparisons(EXESS_DAY, "---03Z", "---04Z", "---05");
444 : 1 : check_comparisons(EXESS_DAY, "---03+03:00", "---03+02:00", "---03+01:00");
445 : :
446 : : // Month
447 : 1 : check_comparisons(EXESS_MONTH, "--02", "--03", "--04");
448 : 1 : check_comparisons(EXESS_MONTH, "--02Z", "--03Z", "--04");
449 : 1 : check_comparisons(EXESS_MONTH, "--02+03:00", "--02+02:00", "--02+01:00");
450 : :
451 : : // Binary
452 : :
453 : 1 : check_comparisons_partial(EXESS_HEX, "010203", "010204", "010205");
454 : 1 : check_comparisons_partial(EXESS_HEX, "0102", "010204", "010205");
455 : 1 : check_comparisons_partial(EXESS_HEX, "0102", "010204", "0103");
456 : 1 : check_comparisons_partial(EXESS_HEX, "01", "0101", "010101");
457 : 1 : check_comparison(EXESS_HEX, "01", "01", equal);
458 : 1 : check_comparison(EXESS_HEX, "02", "01", maybe_greater);
459 : 1 : check_comparison(EXESS_HEX, "01", "02", maybe_less);
460 : 1 : check_comparison(EXESS_HEX, "09", "0102", maybe_greater);
461 : 1 : check_comparison(EXESS_HEX, "0102", "010304", maybe_less);
462 : 1 : check_comparison(EXESS_HEX, "0101", "01", maybe_greater);
463 : 1 : check_comparisons_partial(EXESS_BASE64, "Zg==", "Zm8=", "Zm9v");
464 : 1 : check_comparison(EXESS_BASE64, "Zm9v", "Zm9v", equal);
465 : 1 : }
466 : :
467 : : int
468 : 1 : main(void)
469 : : {
470 : 1 : test_compare();
471 : :
472 : 1 : return 0;
473 : : }
|