logo

cmd-timer

run command at a specific interval git clone https://anongit.hacktivis.me/git/cmd-timer.git
commit: c37db06adf826bafee8bd4d42de58a4334c8315b
parent 2e7604927c930e333d46a4b4c061db4601b8b672
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Wed, 18 Jun 2025 12:00:21 +0200

Add strtodur

Diffstat:

M.gitignore2++
MMakefile16++++++++++++----
Astrtodur.c65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest_strtodur.c60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtimer.c14+++-----------
Atimer.h4++++
6 files changed, 146 insertions(+), 15 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,4 +1,6 @@ # SPDX-FileCopyrightText: 2025 Haelwenn (lanodan) Monnier <contact+cmd-timer@hacktivis.me> # SPDX-License-Identifier: MIT +*.o /timer +/test_strtodur diff --git a/Makefile b/Makefile @@ -4,15 +4,23 @@ PREFIX ?= /usr/local BINDIR ?= ${PREFIX}/bin -timer: timer.c - ${CC} -std=c99 ${CFLAGS} -o $@ $< ${LDFLAGS} $[LDSTATIC} +TIMER_SRC_C = timer.c strtodur.o +timer: ${TIMER_SRC_C} timer.h + ${CC} -std=c99 ${CFLAGS} -o $@ ${TIMER_SRC_C} ${LDFLAGS} ${LDSTATIC} + +TEST_STRTODUR_SRC_C = test_strtodur.c strtodur.o +test_strtodur: ${TEST_STRTODUR_SRC_C} timer.h + ${CC} -std=c99 ${CFLAGS} -o $@ ${TEST_STRTODUR_SRC_C} ${LDFLAGS} ${LDSTATIC} + +check: test_strtodur + ./test_strtodur clean: - rm -f timer + rm -f timer test_strtodur strtodur.o .PHONY: format format: - clang-format -style=file -assume-filename=.clang-format -i timer.c + clang-format -style=file -assume-filename=.clang-format -i *.c *.h .PHONY: install install: diff --git a/strtodur.c b/strtodur.c @@ -0,0 +1,65 @@ +// SPDX-FileCopyrightText: 2025 Haelwenn (lanodan) Monnier <contact+cmd-timer@hacktivis.me> +// SPDX-License-Identifier: MIT + +#define _POSIX_C_SOURCE 200809L +#include "timer.h" + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +unsigned long +strtodur(char *s) +{ + if(s == 0 || s[0] == '\0') return 0; + + unsigned long dur = 0; + + while(*s != '\0') + { + char *end = NULL; + errno = 0; + unsigned long tmp = strtoul(s, &end, 0); + if(errno != 0) + { + fprintf(stderr, + "timer: error: Failed parsing argument '%s' as integer: %s\n", + s, + strerror(errno)); + return 1; + } + + if(end) + { + s = end; + + if(s[0] != '\0') + { + switch(s[0]) + { + case 's': // seconds + break; + case 'm': // minutes + tmp *= 60; + break; + case 'h': // hours + tmp *= 60 * 60; + break; + case 'd': // days + tmp *= 24 * 60 * 60; + break; + default: + fprintf(stderr, "timer: error: Unknown duration suffix '%c'\n", s[0]); + return -1; + } + + s++; + } + } + + dur += tmp; + } + + return dur; +} diff --git a/test_strtodur.c b/test_strtodur.c @@ -0,0 +1,60 @@ +// SPDX-FileCopyrightText: 2025 Haelwenn (lanodan) Monnier <contact+cmd-timer@hacktivis.me> +// SPDX-License-Identifier: MIT + +#define _POSIX_C_SOURCE 200809L +#include "timer.h" + +#include <assert.h> +#include <stdio.h> + +int counter = 0; +int err = 0; + +static void +t(char *str, unsigned long exp) +{ + int id = ++counter; + + unsigned long res = strtodur(str); + if(res == exp) + { + printf("ok %d - %s -> %ld\n", id, str, res); + return; + } + + err = 1; + printf("not ok %d - %s -> %ld\n", id, str, res); + printf("# Expected: %ld\n", exp); +} + +int +main() +{ + int plan = 13; + printf("1..%d\n", plan); + +#define T_MIN 60 +#define T_HOUR 60 * T_MIN +#define T_DAY 24 * T_HOUR + + t(NULL, 0); + t("", 0); + + t("5", 5); + t("5s", 5); + + t("5m", 5 * T_MIN); + t("5m5s", (5 * T_MIN) + 5); + + t("5h", 5 * T_HOUR); + t("5h5m", (5 * T_HOUR) + (5 * T_MIN)); + t("5h5m5s", (5 * T_HOUR) + (5 * T_MIN) + 5); + + t("5d", 5 * T_DAY); + t("5d5h", (5 * T_DAY) + (5 * T_HOUR)); + t("5d5h5m", (5 * T_DAY) + (5 * T_HOUR) + (5 * T_MIN)); + t("5d5h5m5s", (5 * T_DAY) + (5 * T_HOUR) + (5 * T_MIN) + 5); + + assert(counter == plan); + return err; +} diff --git a/timer.c b/timer.c @@ -2,6 +2,8 @@ // SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L +#include "timer.h" + #include <errno.h> #include <limits.h> // UINT_MAX #include <signal.h> // sigaction @@ -47,17 +49,7 @@ main(int argc, char *argv[]) bad_usage(); } - char *durend = NULL; - errno = 0; - unsigned long dur = strtoul(*argv, &durend, 0); - if(errno != 0) - { - fprintf(stderr, - "timer: error: Failed parsing argument '%s' as integer: %s\n", - *argv, - strerror(errno)); - return 1; - } + unsigned long dur = strtodur(*argv); if(dur == 0) { diff --git a/timer.h b/timer.h @@ -0,0 +1,4 @@ +// SPDX-FileCopyrightText: 2025 Haelwenn (lanodan) Monnier <contact+cmd-timer@hacktivis.me> +// SPDX-License-Identifier: MIT + +unsigned long strtodur(char *s);