diff options
-rw-r--r-- | include/rin/time.h | 12 | ||||
-rw-r--r-- | meson.build | 30 | ||||
-rw-r--r-- | src/time/time.c | 104 | ||||
-rw-r--r-- | src/time/time_private.h | 1 | ||||
-rw-r--r-- | test/time.c | 231 | ||||
-rw-r--r-- | test/time_test_private.h | 10 |
6 files changed, 367 insertions, 21 deletions
diff --git a/include/rin/time.h b/include/rin/time.h index 523103f..9c8200f 100644 --- a/include/rin/time.h +++ b/include/rin/time.h @@ -21,17 +21,27 @@ #ifndef LIBRIN_TIME_INCLUDED #define LIBRIN_TIME_INCLUDED -#include <time.h> +#include <sys/time.h> struct timespec rin_time_add(const struct timespec * const a, const struct timespec * const b); struct timespec rin_time_sub(const struct timespec * const a, const struct timespec * const b); struct timespec rin_time_normalize(const struct timespec * const t); +struct timeval rin_timeval_add(const struct timeval * const a, const struct timeval * const b); +struct timeval rin_timeval_sub(const struct timeval * const a, const struct timeval * const b); +struct timeval rin_timeval_normalize(const struct timeval * const t); long int rin_time_cmp(const struct timespec * const a, const struct timespec * const b); +long int rin_timeval_cmp(const struct timeval * const a, const struct timeval * const b); unsigned int rin_time_cmp_less(const struct timespec * const a, const struct timespec * const b); unsigned int rin_time_cmp_more(const struct timespec * const a, const struct timespec * const b); unsigned int rin_time_cmp_lessequal(const struct timespec * const a, const struct timespec * const b); unsigned int rin_time_cmp_moreequal(const struct timespec * const a, const struct timespec * const b); unsigned int rin_time_cmp_equal(const struct timespec * const a, const struct timespec * const b); unsigned int rin_time_cmp_nonequal(const struct timespec * const a, const struct timespec * const b); +unsigned int rin_timeval_cmp_less(const struct timeval * const a, const struct timeval * const b); +unsigned int rin_timeval_cmp_more(const struct timeval * const a, const struct timeval * const b); +unsigned int rin_timeval_cmp_lessequal(const struct timeval * const a, const struct timeval * const b); +unsigned int rin_timeval_cmp_moreequal(const struct timeval * const a, const struct timeval * const b); +unsigned int rin_timeval_cmp_equal(const struct timeval * const a, const struct timeval * const b); +unsigned int rin_timeval_cmp_nonequal(const struct timeval * const a, const struct timeval * const b); #endif /* LIBRIN_TIME_INCLUDED */ diff --git a/meson.build b/meson.build index 4aee09d..9a925bd 100644 --- a/meson.build +++ b/meson.build @@ -34,15 +34,25 @@ if get_option('tests') test('compare floats', test_e, args : ['float', 'comparefloat']) test('compare doubles', test_e, args : ['float', 'comparedouble']) test('diagnostic', test_e, args : ['diagnostic', 'none']) - test('time add', test_e, args : ['time', 'add']) - test('time subtract', test_e, args : ['time', 'sub']) - test('time normalize', test_e, args : ['time', 'normalize']) - test('time compare', test_e, args : ['time', 'cmp']) - test('time compare less', test_e, args : ['time', 'cmpless']) - test('time compare more', test_e, args : ['time', 'cmpmore']) - test('time compare less or equal', test_e, args : ['time', 'cmplessequal']) - test('time compare more or equal', test_e, args : ['time', 'cmpmoreequal']) - test('time compare equal', test_e, args : ['time', 'cmpequal']) - test('time compare nonequal', test_e, args : ['time', 'cmpnonequal']) + test('timespec add', test_e, args : ['time', 'timespec add']) + test('timespec subtract', test_e, args : ['time', 'timespec sub']) + test('timespec normalize', test_e, args : ['time', 'timespec normalize']) + test('timespec compare', test_e, args : ['time', 'timespec cmp']) + test('timespec compare less', test_e, args : ['time', 'timespec cmpless']) + test('timespec compare more', test_e, args : ['time', 'timespec cmpmore']) + test('timespec compare less or equal', test_e, args : ['time', 'timespec cmplessequal']) + test('timespec compare more or equal', test_e, args : ['time', 'timespec cmpmoreequal']) + test('timespec compare equal', test_e, args : ['time', 'timespec cmpequal']) + test('timespec compare nonequal', test_e, args : ['time', 'timespec cmpnonequal']) + test('timeval add', test_e, args : ['time', 'timeval add']) + test('timeval subtract', test_e, args : ['time', 'timeval sub']) + test('timeval normalize', test_e, args : ['time', 'timeval normalize']) + test('timeval compare', test_e, args : ['time', 'timeval cmp']) + test('timeval compare less', test_e, args : ['time', 'timeval cmpless']) + test('timeval compare more', test_e, args : ['time', 'timeval cmpmore']) + test('timeval compare less or equal', test_e, args : ['time', 'timeval cmplessequal']) + test('timeval compare more or equal', test_e, args : ['time', 'timeval cmpmoreequal']) + test('timeval compare equal', test_e, args : ['time', 'timeval cmpequal']) + test('timeval compare nonequal', test_e, args : ['time', 'timeval cmpnonequal']) test('uuid print fromat macros', test_e, args : ['uuid', 'formatmacro']) endif diff --git a/src/time/time.c b/src/time/time.c index d9f00b7..489196d 100644 --- a/src/time/time.c +++ b/src/time/time.c @@ -62,6 +62,47 @@ struct timespec rin_time_normalize(const struct timespec * const t) return ret; } +struct timeval rin_timeval_add(const struct timeval * const a, const struct timeval * const b) +{ + struct timeval ret; + + ret.tv_sec = a->tv_sec + b->tv_sec; + ret.tv_usec = a->tv_usec + b->tv_usec; + + return rin_timeval_normalize(&ret); +} + +struct timeval rin_timeval_sub(const struct timeval * const a, const struct timeval * const b) +{ + struct timeval ret; + + ret.tv_sec = a->tv_sec - b->tv_sec; + ret.tv_usec = a->tv_usec - b->tv_usec; + + return rin_timeval_normalize(&ret); +} + +struct timeval rin_timeval_normalize(const struct timeval * const t) +{ + struct timeval ret; + + ret = *t; + + if (ret.tv_usec >= 0 && ret.tv_usec <= tv_usec_max) { + return ret; + } + + if (ret.tv_usec > 0) { + ret.tv_sec += ret.tv_usec / (tv_usec_max + 1); + ret.tv_usec = ret.tv_usec % (tv_usec_max + 1); + } else { + ret.tv_sec += ret.tv_usec / (tv_usec_max + 1) - 1; + ret.tv_usec = (tv_usec_max + 1) - (-ret.tv_usec) % (tv_usec_max + 1); + } + + return ret; +} + long int rin_time_cmp(const struct timespec * const a, const struct timespec * const b) { if (a->tv_sec != b->tv_sec) { @@ -71,6 +112,15 @@ long int rin_time_cmp(const struct timespec * const a, const struct timespec * c } } +long int rin_timeval_cmp(const struct timeval * const a, const struct timeval * const b) +{ + if (a->tv_sec != b->tv_sec) { + return a->tv_sec - b->tv_sec; + } else { + return a->tv_usec - b->tv_usec; + } +} + unsigned int rin_time_cmp_less(const struct timespec * const a, const struct timespec * const b) { if (a->tv_sec > b->tv_sec) { @@ -124,3 +174,57 @@ unsigned int rin_time_cmp_nonequal(const struct timespec * const a, const struct { return a->tv_sec != b->tv_sec || a->tv_nsec != b->tv_nsec; } + +unsigned int rin_timeval_cmp_less(const struct timeval * const a, const struct timeval * const b) +{ + if (a->tv_sec > b->tv_sec) { + return 0; + } else if (a->tv_sec < b->tv_sec) { + return 1; + } else { + return a->tv_usec < b->tv_usec; + } +} + +unsigned int rin_timeval_cmp_more(const struct timeval * const a, const struct timeval * const b) +{ + if (a->tv_sec < b->tv_sec) { + return 0; + } else if (a->tv_sec > b->tv_sec) { + return 1; + } else { + return a->tv_usec > b->tv_usec; + } +} + +unsigned int rin_timeval_cmp_lessequal(const struct timeval * const a, const struct timeval * const b) +{ + if (a->tv_sec > b->tv_sec) { + return 0; + } else if (a->tv_sec < b->tv_sec) { + return 1; + } else { + return a->tv_usec <= b->tv_usec; + } +} + +unsigned int rin_timeval_cmp_moreequal(const struct timeval * const a, const struct timeval * const b) +{ + if (a->tv_sec < b->tv_sec) { + return 0; + } else if (a->tv_sec > b->tv_sec) { + return 1; + } else { + return a->tv_usec >= b->tv_usec; + } +} + +unsigned int rin_timeval_cmp_equal(const struct timeval * const a, const struct timeval * const b) +{ + return a->tv_sec == b->tv_sec && a->tv_usec == b->tv_usec; +} + +unsigned int rin_timeval_cmp_nonequal(const struct timeval * const a, const struct timeval * const b) +{ + return a->tv_sec != b->tv_sec || a->tv_usec != b->tv_usec; +} diff --git a/src/time/time_private.h b/src/time/time_private.h index 4bb6099..097a987 100644 --- a/src/time/time_private.h +++ b/src/time/time_private.h @@ -22,5 +22,6 @@ #define LIBRIN_TIME_PRIVATE_INCLUDED static const long tv_nsec_max = 999999999l; +static const long tv_usec_max = 999999l; #endif /* LIBRIN_TIME_PRIVATE_INCLUDED */ diff --git a/test/time.c b/test/time.c index 017597b..f0ad5a2 100644 --- a/test/time.c +++ b/test/time.c @@ -24,16 +24,26 @@ int time_test(char *testname) { static const struct test tests[] = { - {"add", rin_time_add_test}, - {"sub", rin_time_sub_test}, - {"normalize", rin_time_normalize_test}, - {"cmp", rin_time_cmp_test}, - {"cmpless", rin_time_cmpless_test}, - {"cmpmore", rin_time_cmpmore_test}, - {"cmplessequal", rin_time_cmplessequal_test}, - {"cmpmoreequal", rin_time_cmpmoreequal_test}, - {"cmpequal",rin_time_cmpequal_test}, - {"cmpnonequal", rin_time_cmpnonequal_test} }; + {"timespec add", rin_time_add_test}, + {"timespec sub", rin_time_sub_test}, + {"timespec normalize", rin_time_normalize_test}, + {"timespec cmp", rin_time_cmp_test}, + {"timespec cmpless", rin_time_cmpless_test}, + {"timespec cmpmore", rin_time_cmpmore_test}, + {"timespec cmplessequal", rin_time_cmplessequal_test}, + {"timespec cmpmoreequal", rin_time_cmpmoreequal_test}, + {"timespec cmpequal",rin_time_cmpequal_test}, + {"timespec cmpnonequal", rin_time_cmpnonequal_test}, + {"timeval add", rin_timeval_add_test}, + {"timeval sub", rin_timeval_sub_test}, + {"timeval normalize", rin_timeval_normalize_test}, + {"timeval cmp", rin_timeval_cmp_test}, + {"timeval cmpless", rin_timeval_cmpless_test}, + {"timeval cmpmore", rin_timeval_cmpmore_test}, + {"timeval cmplessequal", rin_timeval_cmplessequal_test}, + {"timeval cmpmoreequal", rin_timeval_cmpmoreequal_test}, + {"timeval cmpequal",rin_timeval_cmpequal_test}, + {"timeval cmpnonequal", rin_timeval_cmpnonequal_test} }; size_t i; for (i = 0; i < arrlen(tests); ++i) { @@ -44,6 +54,7 @@ int time_test(char *testname) return EXIT_FAILURE; } + static int rin_time_add_test(void) { int ret; @@ -245,3 +256,203 @@ static int rin_time_cmpnonequal_test(void) return ret; } +static int rin_timeval_add_test(void) +{ + int ret; + size_t i; + static const struct timeval in_a[] = { {187, 12289}, {0, 999999}, {0, 999998}, {0, 0} }; + static const struct timeval in_b[] = { {23, 17711}, {0, 21}, {999999, 2}, {0, 0} }; + static const struct timeval expected[] = { {210, 30000}, {1, 20}, {1000000, 0}, {0, 0} }; + struct timeval tmp; + + for (i = 0; i < arrlen(expected); ++i) { + tmp = rin_timeval_add(in_a + i, in_b + i); + ret = ok(tmp.tv_sec != expected[i].tv_sec || tmp.tv_usec != expected[i].tv_usec, + "%s: expected: %li %li, got: %li %li", + __func__, + expected[i].tv_sec, + expected[i].tv_usec, + tmp.tv_sec, + tmp.tv_usec); + } + + return ret; +} + +static int rin_timeval_sub_test(void) +{ + int ret; + size_t i; + static const struct timeval in_a[] = { {187, 17289}, {0, 999999}, {0, 99}, {0, 0} }; + static const struct timeval in_b[] = { {27, 12711}, {0, 1}, {999999, 999999}, {0, 0} }; + static const struct timeval expected[] = { {160, 4578}, {0, 999998}, {-1000000, 100}, {0, 0} }; + struct timeval tmp; + + for (i = 0; i < arrlen(expected); ++i) { + tmp = rin_timeval_sub(in_a + i, in_b + i); + ret = ok(tmp.tv_sec != expected[i].tv_sec || tmp.tv_usec != expected[i].tv_usec, + "%s: expected: %li %li, got: %li %li", + __func__, + expected[i].tv_sec, + expected[i].tv_usec, + tmp.tv_sec, + tmp.tv_usec); + } + + return ret; +} + +static int rin_timeval_normalize_test(void) +{ + int ret; + size_t i; + static const struct timeval in[] = { {187, -100}, {0, 1999999}, {2, 99000000}, {10, 10}, {0, 1000000}, {0, 0} }; + static const struct timeval expected[] = { {186, 999900}, {1, 999999}, {101, 0}, {10, 10}, {1, 0}, {0, 0} }; + struct timeval tmp; + + for (i = 0; i < arrlen(expected); ++i) { + tmp = rin_timeval_normalize(in + i); + ret = ok(tmp.tv_sec != expected[i].tv_sec || tmp.tv_usec != expected[i].tv_usec, + "%s: expected: %li %li, got: %li %li", + __func__, + expected[i].tv_sec, + expected[i].tv_usec, + tmp.tv_sec, + tmp.tv_usec); + } + + return ret; +} + +static int rin_timeval_cmp_test(void) +{ + int ret; + size_t i; + static const struct timeval in_a[] = { {187, 100}, {1, 100}, {1, 200}, {1, 100}, {9, 10}, {3, 100}, {4, 101}, {0, 0} }; + static const struct timeval in_b[] = { {187, 100}, {0, 100}, {1, 200}, {1, 200}, {10, 10}, {4, 101}, {3, 100}, {0, 0} }; + static const long int expected[] = {0, 1, 0, -100, -1, -1, 1, 0}; + + for (i = 0; i < arrlen(expected); ++i) { + ret = ok(rin_timeval_cmp(in_a + i, in_b + i) != expected[i], + "%s: expected: %li, got: %li", + __func__, + expected[i], + rin_timeval_cmp(in_a + i, in_b + i)); + } + + return ret; +} + +static int rin_timeval_cmpless_test(void) +{ + int ret; + size_t i; + static const struct timeval in_a[] = { {187, 100}, {1, 100}, {1, 200}, {1, 100}, {9, 10}, {3, 100}, {4, 101}, {0, 0} }; + static const struct timeval in_b[] = { {187, 100}, {0, 100}, {1, 200}, {1, 200}, {10, 10}, {4, 101}, {3, 100}, {0, 0} }; + static const unsigned int expected[] = {0, 0, 0, 1, 1, 1, 0, 0}; + + for (i = 0; i < arrlen(expected); ++i) { + ret = ok(rin_timeval_cmp_less(in_a + i, in_b + i) != expected[i], + "%s: expected: %u, got: %u", + __func__, + expected[i], + rin_timeval_cmp_less(in_a + i, in_b + i)); + } + + return ret; +} + +static int rin_timeval_cmpmore_test(void) +{ + int ret; + size_t i; + static const struct timeval in_a[] = { {187, 100}, {1, 100}, {1, 200}, {1, 100}, {9, 10}, {3, 100}, {4, 101}, {0, 0} }; + static const struct timeval in_b[] = { {187, 100}, {0, 100}, {1, 200}, {1, 200}, {10, 10}, {4, 101}, {3, 100}, {0, 0} }; + static const unsigned int expected[] = {0, 1, 0, 0, 0, 0, 1, 0}; + + for (i = 0; i < arrlen(expected); ++i) { + ret = ok(rin_timeval_cmp_more(in_a + i, in_b + i) != expected[i], + "%s: expected: %u, got: %u", + __func__, + expected[i], + rin_timeval_cmp_more(in_a + i, in_b + i)); + } + + return ret; +} + +static int rin_timeval_cmplessequal_test(void) +{ + int ret; + size_t i; + static const struct timeval in_a[] = { {187, 100}, {1, 100}, {1, 200}, {1, 100}, {9, 10}, {3, 100}, {4, 101}, {0, 0} }; + static const struct timeval in_b[] = { {187, 100}, {0, 100}, {1, 200}, {1, 200}, {10, 10}, {4, 101}, {3, 100}, {0, 0} }; + static const unsigned int expected[] = {1, 0, 1, 1, 1, 1, 0, 1}; + + for (i = 0; i < arrlen(expected); ++i) { + ret = ok(rin_timeval_cmp_lessequal(in_a + i, in_b + i) != expected[i], + "%s: expected: %u, got: %u", + __func__, + expected[i], + rin_timeval_cmp_lessequal(in_a + i, in_b + i)); + } + + return ret; +} + +static int rin_timeval_cmpmoreequal_test(void) +{ + int ret; + size_t i; + static const struct timeval in_a[] = { {187, 100}, {1, 100}, {1, 200}, {1, 100}, {9, 10}, {3, 100}, {4, 101}, {0, 0} }; + static const struct timeval in_b[] = { {187, 100}, {0, 100}, {1, 200}, {1, 200}, {10, 10}, {4, 101}, {3, 100}, {0, 0} }; + static const unsigned int expected[] = {1, 1, 1, 0, 0, 0, 1, 1}; + + for (i = 0; i < arrlen(expected); ++i) { + ret = ok(rin_timeval_cmp_moreequal(in_a + i, in_b + i) != expected[i], + "%s: expected: %u, got: %u", + __func__, + expected[i], + rin_timeval_cmp_moreequal(in_a + i, in_b + i)); + } + + return ret; +} + +static int rin_timeval_cmpequal_test(void) +{ + int ret; + size_t i; + static const struct timeval in_a[] = { {187, 100}, {1, 100}, {1, 200}, {1, 100}, {9, 10}, {3, 100}, {4, 101}, {0, 0} }; + static const struct timeval in_b[] = { {187, 100}, {0, 100}, {1, 200}, {1, 200}, {10, 10}, {4, 101}, {3, 100}, {0, 0} }; + static const unsigned int expected[] = {1, 0, 1, 0, 0, 0, 0, 1}; + + for (i = 0; i < arrlen(expected); ++i) { + ret = ok(rin_timeval_cmp_equal(in_a + i, in_b + i) != expected[i], + "%s: expected: %u, got: %u", + __func__, + expected[i], + rin_timeval_cmp_equal(in_a + i, in_b + i)); + } + + return ret; +} + +static int rin_timeval_cmpnonequal_test(void) +{ + int ret; + size_t i; + static const struct timeval in_a[] = { {187, 100}, {1, 100}, {1, 200}, {1, 100}, {9, 10}, {3, 100}, {4, 101}, {0, 0} }; + static const struct timeval in_b[] = { {187, 100}, {0, 100}, {1, 200}, {1, 200}, {10, 10}, {4, 101}, {3, 100}, {0, 0} }; + static const unsigned int expected[] = {0, 1, 0, 1, 1, 1, 1, 0}; + + for (i = 0; i < arrlen(expected); ++i) { + ret = ok(rin_timeval_cmp_nonequal(in_a + i, in_b + i) != expected[i], + "%s: expected: %u, got: %u", + __func__, + expected[i], + rin_timeval_cmp_nonequal(in_a + i, in_b + i)); + } + + return ret; +} diff --git a/test/time_test_private.h b/test/time_test_private.h index c7d505c..8283e25 100644 --- a/test/time_test_private.h +++ b/test/time_test_private.h @@ -33,5 +33,15 @@ static int rin_time_cmplessequal_test(void); static int rin_time_cmpmoreequal_test(void); static int rin_time_cmpequal_test(void); static int rin_time_cmpnonequal_test(void); +static int rin_timeval_add_test(void); +static int rin_timeval_sub_test(void); +static int rin_timeval_normalize_test(void); +static int rin_timeval_cmp_test(void); +static int rin_timeval_cmpless_test(void); +static int rin_timeval_cmpmore_test(void); +static int rin_timeval_cmplessequal_test(void); +static int rin_timeval_cmpmoreequal_test(void); +static int rin_timeval_cmpequal_test(void); +static int rin_timeval_cmpnonequal_test(void); #endif /* LIBRIN_TIME_TEST_PRIVATE_INCLUDED */ |