diff options
author | Mattias Andrée <maandree@kth.se> | 2018-11-19 21:39:11 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2018-11-19 21:39:11 +0100 |
commit | e8a7e1c358caec60751460d337f634ff6957ff9d (patch) | |
tree | b0fe92173edbf210d2890ecd35141cc39decf8dc /difftimespec.c | |
parent | Add memelemscan (diff) | |
download | libsimple-e8a7e1c358caec60751460d337f634ff6957ff9d.tar.gz libsimple-e8a7e1c358caec60751460d337f634ff6957ff9d.tar.bz2 libsimple-e8a7e1c358caec60751460d337f634ff6957ff9d.tar.xz |
Add a bunch of function and macros
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'difftimespec.c')
-rw-r--r-- | difftimespec.c | 60 |
1 files changed, 24 insertions, 36 deletions
diff --git a/difftimespec.c b/difftimespec.c index 07f46c9..86d3441 100644 --- a/difftimespec.c +++ b/difftimespec.c @@ -6,48 +6,36 @@ int libsimple_difftimespec(struct timespec *diff, const struct timespec *minuend, const struct timespec *subtrahend) { - long int ns = minuend->tv_nsec - subtrahend->tv_nsec; time_t s; - int ret = 0; - - s = minuend->tv_sec - subtrahend->tv_sec; - if ((minuend->tv_sec <= 0) != (subtrahend->tv_sec <= 0)) { - if (minuend->tv_sec < 0 && minuend->tv_sec < TIME_MIN + subtrahend->tv_sec) { - s = TIME_MIN; - ns = 0; - errno = ERANGE; - ret = -1; - } else if (minuend->tv_sec >= 0 && minuend->tv_sec > TIME_MAX + subtrahend->tv_sec) { - s = TIME_MAX; - ns = 999999999L; - errno = ERANGE; - ret = -1; - } + + if (LIBSIMPLE_SSUB_OVERFLOW(minuend->tv_sec, subtrahend->tv_sec, &s, TIME_MIN, TIME_MAX)) { + if (subtrahend->tv_sec < 0) + goto too_large; + else + goto too_small; } - if (ns < 0) { - if (s == TIME_MIN) { - ns = 0L; - errno = ERANGE; - ret = -1; - } else { - s -= 1; - ns += 1000000000L; - } - } else if (ns >= 1000000000L) { - if (s == TIME_MAX) { - ns = 999999999L; - errno = ERANGE; - ret = -1; - } else { - s += 1; - ns -= 1000000000L; - } + diff->tv_nsec = minuend->tv_nsec - subtrahend->tv_nsec; + if (diff->tv_nsec < 0) { + if (LIBSIMPLE_SDECR_OVERFLOW(&s, TIME_MIN)) + goto too_small; + diff->tv_nsec += 1000000000L; } diff->tv_sec = s; - diff->tv_nsec = ns; - return ret; + return 0; + +too_large: + diff->tv_sec = TIME_MAX; + diff->tv_nsec = 999999999L; + errno = ERANGE; + return -1; + +too_small: + diff->tv_sec = TIME_MIN; + diff->tv_nsec = 0; + errno = ERANGE; + return -1; } |