logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git
commit: e450d99b5382edf35a5e9e9e66fab0c8686e8cc6
parent 1a622d996f83e14a43b84c0cc572eaf7650961e6
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Thu, 26 Sep 2024 10:05:57 +0200

lib/strtodur: fix fractional + suffix

Diffstat:

Mlib/strtodur.c67+++++++++++++++++++++++++++++++++++--------------------------------
Mtest-lib/strtodur.c12+++++++++++-
2 files changed, 46 insertions(+), 33 deletions(-)

diff --git a/lib/strtodur.c b/lib/strtodur.c @@ -12,16 +12,17 @@ int strtodur(char *s, struct timespec *dur) { - if(s == 0 || s[0] == 0) return 0; + if(s == 0 || s[0] == '\0') return 0; assert(dur); - int parsed = 0; + float in = 0.0; + if(s[0] != '.' && s[0] != ',') { + int parsed = 0; assert(errno == 0); - int ret = sscanf(s, "%10ld%n", &dur->tv_sec, &parsed); - if(ret < 1) + if(sscanf(s, "%10f%n", &in, &parsed) < 1) { if(errno == 0) { @@ -36,17 +37,14 @@ strtodur(char *s, struct timespec *dur) } s += parsed; - - if(s[0] == 0) return 0; } - if(s[0] == '.' || s[0] == ',') + if((s[0] == '.' || s[0] == ',') && s[1] != '\0') { float fraction = 0.0; - if(s[1] == 0) return 0; if(s[0] == ',') s[0] = '.'; - parsed = 0; + int parsed = 0; assert(errno == 0); if(sscanf(s, "%10f%n", &fraction, &parsed) < 1) { @@ -62,35 +60,40 @@ strtodur(char *s, struct timespec *dur) return -1; } - dur->tv_nsec = fraction * 1000000000; + in += fraction; s += parsed; } - if(s[0] == 0) return 0; - - if(s[1] != 0) + if(s[0] != '\0' && s[0] != ',' && s[0] != '.') { - fprintf(stderr, "strtodur: error: suffix '%s' is too long, should be only one character\n", s); - return -1; - } + if(s[1] != '\0') + { + fprintf( + stderr, "strtodur: error: suffix '%s' is too long, should be only one character\n", s); + return -1; + } - switch(s[0]) - { - case 's': // seconds - break; - case 'm': // minutes - dur->tv_sec *= 60; - break; - case 'h': // hours - dur->tv_sec *= 60 * 60; - break; - case 'd': // days - dur->tv_sec *= 24 * 60 * 60; - break; - default: - fprintf(stderr, "strtodur: error: Unknown suffix %c\n", s[0]); - return -1; + switch(s[0]) + { + case 's': // seconds + break; + case 'm': // minutes + in *= 60; + break; + case 'h': // hours + in *= 60 * 60; + break; + case 'd': // days + in *= 24 * 60 * 60; + break; + default: + fprintf(stderr, "strtodur: error: Unknown suffix '%c'\n", s[0]); + return -1; + } } + dur->tv_sec = in; + dur->tv_nsec = (in - dur->tv_sec) * 1000000000; + return 0; } diff --git a/test-lib/strtodur.c b/test-lib/strtodur.c @@ -43,7 +43,7 @@ t_strtodur(char *str, time_t ex_sec, long ex_nsec) int main(void) { - int plan = 8; + int plan = 16; printf("1..%d\n", plan); // TODO: Capture errors, say with open_memstream(3) @@ -59,6 +59,16 @@ main(void) t_strtodur((char *)".1", 0, 1000000000 * 0.1); t_strtodur((char *)"0.1", 0, 1000000000 * 0.1); + t_strtodur((char *)"1s", 1, 0); + t_strtodur((char *)"1m", 60, 0); + t_strtodur((char *)"1h", 60 * 60, 0); + t_strtodur((char *)"1d", 60 * 60 * 24, 0); + + t_strtodur((char *)"1.5s", 1, 1000000000 * 0.5); + t_strtodur((char *)"1.5m", 1.5 * 60, 0); + t_strtodur((char *)"1.5h", 1.5 * 60 * 60, 0); + t_strtodur((char *)"1.5d", 1.5 * 60 * 60 * 24, 0); + assert(counter == plan); return err; }