diff options
Diffstat (limited to 'src/string.c')
-rw-r--r-- | src/string.c | 88 |
1 files changed, 55 insertions, 33 deletions
diff --git a/src/string.c b/src/string.c index ae19271..4abd694 100644 --- a/src/string.c +++ b/src/string.c @@ -9,7 +9,7 @@ */ #include <errno.h> #include <limits.h> -#include <math.h> +#include <math.h> /* nextafter */ #include <stdbool.h> #include <stddef.h> #include <stdint.h> @@ -476,7 +476,7 @@ EXPORT_SYMBOL char *HX_strrev(char *s) EXPORT_SYMBOL size_t HX_strrtrim(char *expr) { - int i = strlen(expr), s = 0; + size_t i = strlen(expr), s = 0; while (i-- && HX_isspace(expr[i])) ++s; expr[++i] = '\0'; @@ -1037,55 +1037,63 @@ EXPORT_SYMBOL unsigned long long HX_strtoull_unit(const char *s, #define SECONDS_PER_YEAR 31557600 #define SECONDS_PER_MONTH 2629800 +#define NSEC_PER_SECOND 1000000000ULL static const struct { const char name[8]; unsigned int len; - uint32_t mult; + uint32_t s_mult; + uint64_t ns_mult; } time_multiplier[] = { - {"seconds", 7, 1}, - {"second", 6, 1}, - {"sec", 3, 1}, - {"s", 1, 1}, - {"minutes", 7, 60}, - {"minute", 6, 60}, - {"min", 3, 60}, - {"hours", 5, 3600}, - {"hour", 4, 3600}, - {"h", 1, 3600}, - {"days", 4, 86400}, - {"day", 3, 86400}, - {"d", 1, 86400}, - {"weeks", 5, 604800}, - {"week", 4, 604800}, - {"months", 6, SECONDS_PER_MONTH}, - {"month", 5, SECONDS_PER_MONTH}, - {"years", 5, SECONDS_PER_YEAR}, - {"year", 4, SECONDS_PER_YEAR}, - {"y", 1, SECONDS_PER_YEAR}, + {"seconds", 7, 1, 1 * NSEC_PER_SECOND}, + {"second", 6, 1, 1 * NSEC_PER_SECOND}, + {"sec", 3, 1, 1 * NSEC_PER_SECOND}, + {"s", 1, 1, 1 * NSEC_PER_SECOND}, + {"minutes", 7, 60, 60 * NSEC_PER_SECOND}, + {"minute", 6, 60, 60 * NSEC_PER_SECOND}, + {"min", 3, 60, 60 * NSEC_PER_SECOND}, + {"hours", 5, 3600, 3600 * NSEC_PER_SECOND}, + {"hour", 4, 3600, 3600 * NSEC_PER_SECOND}, + {"h", 1, 3600, 3600 * NSEC_PER_SECOND}, + {"days", 4, 86400, 86400 * NSEC_PER_SECOND}, + {"day", 3, 86400, 86400 * NSEC_PER_SECOND}, + {"d", 1, 86400, 86400 * NSEC_PER_SECOND}, + {"weeks", 5, 604800, 604800 * NSEC_PER_SECOND}, + {"week", 4, 604800, 604800 * NSEC_PER_SECOND}, + {"months", 6, SECONDS_PER_MONTH, SECONDS_PER_MONTH * NSEC_PER_SECOND}, + {"month", 5, SECONDS_PER_MONTH, SECONDS_PER_MONTH * NSEC_PER_SECOND}, + {"years", 5, SECONDS_PER_YEAR, SECONDS_PER_YEAR * NSEC_PER_SECOND}, + {"year", 4, SECONDS_PER_YEAR, SECONDS_PER_YEAR * NSEC_PER_SECOND}, + {"y", 1, SECONDS_PER_YEAR, SECONDS_PER_YEAR * NSEC_PER_SECOND}, + {"msec", 4, 0, 1000000}, + {"ms", 2, 0, 1000000}, + {"µsec", 5, 0, 1000}, + {"µs", 3, 0, 1000}, + {"nsec", 4, 0, 1}, + {"ns", 2, 0, 1}, + {"", 0, 1, NSEC_PER_SECOND}, }; -EXPORT_SYMBOL unsigned long long HX_strtoull_sec(const char *s, char **out_end) +static unsigned long long HX_strtoull_time(const char *s, char **out_end, bool nsec) { - unsigned long long seconds = 0; + unsigned long long quant = 0; while (*s != '\0') { while (HX_isspace(*s)) ++s; - if (*s == '-') { + if (*s == '-') break; - } char *end = nullptr; unsigned long long num = strtoull(s, &end, 10); + double frac = 0; + bool have_frac = *end == '.'; + if (have_frac) + frac = strtod(s, &end); if (end == s) break; s = end; while (HX_isspace(*s)) ++s; - if (!HX_isalpha(*s)) { - seconds += num; - continue; - } unsigned int i; for (i = 0; i < ARRAY_SIZE(time_multiplier); ++i) if (strncmp(s, time_multiplier[i].name, @@ -1094,12 +1102,26 @@ EXPORT_SYMBOL unsigned long long HX_strtoull_sec(const char *s, char **out_end) break; if (i == ARRAY_SIZE(time_multiplier)) break; - seconds += num * time_multiplier[i].mult; + unsigned long long mult = nsec ? time_multiplier[i].ns_mult : time_multiplier[i].s_mult; + if (have_frac) + quant += frac * mult; + else + quant += num * mult; s += time_multiplier[i].len; } if (out_end != nullptr) *out_end = const_cast(char *, s); - return seconds; + return quant; +} + +EXPORT_SYMBOL unsigned long long HX_strtoull_sec(const char *s, char **out_end) +{ + return HX_strtoull_time(s, out_end, false); +} + +EXPORT_SYMBOL unsigned long long HX_strtoull_nsec(const char *s, char **out_end) +{ + return HX_strtoull_time(s, out_end, true); } EXPORT_SYMBOL char *HX_unit_seconds(char *out, size_t outsize, |