strtodur.c (1795B)
- // utils-std: Collection of commonly available Unix tools
- // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _POSIX_C_SOURCE 200809L
- #include "strtodur.h"
- #include <assert.h>
- #include <errno.h> // errno
- #include <stdio.h> // fprintf, perror, sscanf
- int
- strtodur(char *s, struct timespec *dur)
- {
- if(s == 0 || s[0] == '\0') return 0;
- assert(dur);
- float in = 0.0;
- if(s[0] != '.' && s[0] != ',')
- {
- int parsed = 0;
- assert(errno == 0);
- if(sscanf(s, "%10f%n", &in, &parsed) < 1)
- {
- if(errno == 0)
- {
- fprintf(stderr, "strtodur: error: Not a number: %s\n", s);
- }
- else
- {
- perror("strtodur: error: sscanf");
- errno = 0;
- }
- return -1;
- }
- s += parsed;
- }
- if((s[0] == '.' || s[0] == ',') && s[1] != '\0')
- {
- float fraction = 0.0;
- if(s[0] == ',') s[0] = '.';
- int parsed = 0;
- assert(errno == 0);
- if(sscanf(s, "%10f%n", &fraction, &parsed) < 1)
- {
- if(errno == 0)
- {
- fprintf(stderr, "strtodur: error: Decimal part is not a number: %s\n", s);
- }
- else
- {
- perror("strtodur: error: sscanf");
- errno = 0;
- }
- return -1;
- }
- in += fraction;
- s += parsed;
- }
- if(s[0] != '\0' && s[0] != ',' && s[0] != '.')
- {
- 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
- 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;
- }