diff options
-rw-r--r-- | libsimple/time.h | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/libsimple/time.h b/libsimple/time.h index 7304030..e0f7603 100644 --- a/libsimple/time.h +++ b/libsimple/time.h @@ -1,23 +1,70 @@ /* See LICENSE file for copyright and license details. */ + +/** + * Calculates the sum of two `struct timespec`s + * + * @param sum Output parameter for the result + * @param augend One of the terms + * @param addend The other term + * @return 0 on success, -1 on failure + * @throws ERANGE The result is too large or too small to be store; the result + * will be `{.tv_sec = TIME_MAX, .tv_nsec = 999999999L}` if the + * result too large and `{.tv_sec = TIME_MIN, .tv_nsec = 0L}` + * if the result too small + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) int libsimple_sumtimespec(struct timespec *, const struct timespec *, const struct timespec *); #ifndef sumtimespec # define sumtimespec libsimple_sumtimespec #endif + +/** + * Calculates the difference of two `struct timespec`s + * + * @param diff Output parameter for the result + * @param minuend The left-hand term + * @param subtrahend The right-hand term + * @return 0 on success, -1 on failure + * @throws ERANGE The result is too large or too small to be store; the result + * will be `{.tv_sec = TIME_MAX, .tv_nsec = 999999999L}` if the + * result too large and `{.tv_sec = TIME_MIN, .tv_nsec = 0L}` + * if the result too small + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) int libsimple_difftimespec(struct timespec *, const struct timespec *, const struct timespec *); #ifndef difftimespec # define difftimespec libsimple_difftimespec #endif + +/** + * Calculates the product of a `struct timespec` and an integer + * + * @param prod Output parameter for the result + * @param multiplicand One of the factors + * @param multiplier The other factor + * @return 0 on success, -1 on failure + * @throws ERANGE The result is too large or too small to be store; the result + * will be `{.tv_sec = TIME_MAX, .tv_nsec = 999999999L}` if the + * result too large and `{.tv_sec = TIME_MIN, .tv_nsec = 0L}` + * if the result too small + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) int libsimple_multimespec(struct timespec *, const struct timespec *, int); #ifndef multimespec # define multimespec libsimple_multimespec #endif + +/** + * Compares two `struct timespec`s + * + * @param a One of the `struct timespec`s + * @param b The other `struct timespec` + * @return -1 if `a` < `b`, 0 if `a` = `b`, and +1 if `a` > `b` + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__))) static inline int libsimple_cmptimespec(const struct timespec *__a, const struct timespec *__b) @@ -31,24 +78,70 @@ libsimple_cmptimespec(const struct timespec *__a, const struct timespec *__b) #endif +/** + * Calculates the sum of two `struct timeval`s + * + * @param sum Output parameter for the result + * @param augend One of the terms + * @param addend The other term + * @return 0 on success, -1 on failure + * @throws ERANGE The result is too large or too small to be store; the result + * will be `{.tv_sec = TIME_MAX, .tv_usec = 999999L}` if the + * result too large and `{.tv_sec = TIME_MIN, .tv_usec = 0L}` + * if the result too small + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) int libsimple_sumtimeval(struct timeval *, const struct timeval *, const struct timeval *); #ifndef sumtimeval # define sumtimeval libsimple_sumtimeval #endif + +/** + * Calculates the difference of two `struct timeval`s + * + * @param diff Output parameter for the result + * @param minuend The left-hand term + * @param subtrahend The right-hand term + * @return 0 on success, -1 on failure + * @throws ERANGE The result is too large or too small to be store; the result + * will be `{.tv_sec = TIME_MAX, .tv_usec = 999999L}` if the + * result too large and `{.tv_sec = TIME_MIN, .tv_usec = 0L}` + * if the result too small + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) int libsimple_difftimeval(struct timeval *, const struct timeval *, const struct timeval *); #ifndef difftimeval # define difftimeval libsimple_difftimeval #endif + +/** + * Calculates the product of a `struct timeval` and an integer + * + * @param prod Output parameter for the result + * @param multiplicand One of the factors + * @param multiplier The other factor + * @return 0 on success, -1 on failure + * @throws ERANGE The result is too large or too small to be store; the result + * will be `{.tv_sec = TIME_MAX, .tv_usec = 999999L}` if the + * result too large and `{.tv_sec = TIME_MIN, .tv_usec = 0L}` + * if the result too small + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) int libsimple_multimeval(struct timeval *, const struct timeval *, int); #ifndef multimeval # define multimeval libsimple_multimeval #endif + +/** + * Compares two `struct timeval`s + * + * @param a One of the `struct timeval`s + * @param b The other `struct timeval` + * @return -1 if `a` < `b`, 0 if `a` = `b`, and +1 if `a` > `b` + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__))) static inline int libsimple_cmptimeval(const struct timeval *__a, const struct timeval *__b) @@ -62,6 +155,12 @@ libsimple_cmptimeval(const struct timeval *__a, const struct timeval *__b) #endif +/** + * Converts a `struct timeval` to a `struct timespec` + * + * @param ts Output parameter for the result + * @param tv The value to convert + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) static inline void libsimple_timeval2timespec(struct timespec *restrict __ts, const struct timeval *restrict __tv) @@ -74,36 +173,117 @@ libsimple_timeval2timespec(struct timespec *restrict __ts, const struct timeval # define timeval2timespec libsimple_timeval2timespec #endif + +/** + * Converts a `struct timespec` to a `struct timeval` + * + * @param tv The value to convert + * @param ts Output parameter for the result + * @return 0 on success, -1 on error + * @throws EOVERFLOW The value is too large to be convert, the value will be + * truncated to `{.tv_sec = TIME_MAX, .tv_usec = 999999L}` + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) int libsimple_timespec2timeval(struct timeval *restrict, const struct timespec *restrict); #ifndef timespec2timeval # define timespec2timeval libsimple_timespec2timeval #endif + +/** + * Converts a string to `struct timespec` + * + * Repeating decimal are supported ith the repetend inside + * round brackets or after an additional point, for example + * "0.1(6)" or "0.1.6" for one sixth + * + * @param ts Output parameter for the result + * @param s The string to parse + * @param end Output parameter for where the parsing stopped; + * will only be set on success or on ERANGE error + * @return 0 on success, -1 on error + * @throws EINVAL The input string is invalid (`*end` is not set) + * @throws ERANGE The result is too large or too small to be store; the result + * will be `{.tv_sec = TIME_MAX, .tv_nsec = 999999999L}` if the + * result too large and `{.tv_sec = TIME_MIN, .tv_nsec = 0L}` + * if the result too small (`*end` is set) + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1, 2)))) int libsimple_strtotimespec(struct timespec *restrict, const char *restrict, char **restrict); #ifndef strtotimespec # define strtotimespec libsimple_strtotimespec #endif + +/** + * Converts a string to `struct timeval` + * + * Repeating decimal are supported ith the repetend inside + * round brackets or after an additional point, for example + * "0.1(6)" or "0.1.6" for one sixth + * + * @param tv Output parameter for the result + * @param s The string to parse + * @param end Output parameter for where the parsing stopped; + * will only be set on success or on ERANGE error + * @return 0 on success, -1 on error + * @throws EINVAL The input string is invalid (`*end` is not set) + * @throws ERANGE The result is too large or too small to be store; the result + * will be `{.tv_sec = TIME_MAX, .tv_usec = 999999L}` if the + * result too large and `{.tv_sec = TIME_MIN, .tv_usec = 0L}` + * if the result too small (`*end` is set) + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1, 2)))) int libsimple_strtotimeval(struct timeval *restrict, const char *restrict, char **restrict); #ifndef strtotimeval # define strtotimeval libsimple_strtotimeval #endif + +/** + * Converts a `struct timespec` to string + * + * The output will always have a sign ("+" or "-") and 9 decimals. + * + * @param buf Output buffer to use, if `NULL` a new buffer will be allocated + * @param ts The value to convert + * @return The result (same pointer as `buf` unless `buf == NULL`), + * `NULL` on failure + * @throws ENOMEM Output buffer could not be allocated (only if `buf == NULL`) + * @throws EINVAL `ts->tv_nsec` is negative or greater than 999999999 + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2)))) char *libsimple_timespectostr(char *restrict, const struct timespec *restrict); #ifndef timespectostr # define timespectostr libsimple_timespectostr #endif + +/** + * Converts a `struct timeval` to string + * + * The output will always have a sign ("+" or "-") and 6 decimals. + * + * @param buf Output buffer to use, if `NULL` a new buffer will be allocated + * @param tv The value to convert + * @return The result (same pointer as `buf` unless `buf == NULL`), + * `NULL` on failure + * @throws ENOMEM Output buffer could not be allocated (only if `buf == NULL`) + * @throws EINVAL `ts->tv_usec` is negative or greater than 999999 + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2)))) char *libsimple_timevaltostr(char *restrict, const struct timeval *restrict); #ifndef timevaltostr # define timevaltostr libsimple_timevaltostr #endif + +/** + * Converts a `struct timespec` to `double` + * + * @param ts The value to convert + * @return The result + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) static inline double libsimple_timespectodouble(const struct timespec *__ts) @@ -117,6 +297,13 @@ libsimple_timespectodouble(const struct timespec *__ts) # define timespectodouble libsimple_timespectodouble #endif + +/** + * Converts a `struct timeval` to `double` + * + * @param tv The value to convert + * @return The result + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) static inline double libsimple_timevaltodouble(const struct timeval *__tv) @@ -130,18 +317,45 @@ libsimple_timevaltodouble(const struct timeval *__tv) # define timevaltodouble libsimple_timevaltodouble #endif + +/** + * Converts a double to `struct timespec` + * + * No overflow check is made + * + * @param ts Output parameter for the result + * @param d The value to convert + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) void libsimple_doubletotimespec(struct timespec *, double); #ifndef doubletotimespec # define doubletotimespec libsimple_doubletotimespec #endif + +/** + * Converts a double to `struct timeval` + * + * No overflow check is made + * + * @param tv Output parameter for the result + * @param d The value to convert + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) void libsimple_doubletotimeval(struct timeval *, double); #ifndef doubletotimeval # define doubletotimeval libsimple_doubletotimeval #endif + +/** + * Minimises a numerical string + * + * This function does not support repeating decimals + * + * @param s The string to minimise + * @return `s` + */ _LIBSIMPLE_GCC_ONLY(__attribute__((__returns_nonnull__, __nonnull__))) char *libsimple_minimise_number_string(char *); #ifndef minimise_number_string |