| tadd timer(1) - stopwatch - simple timer for console or x root window | |
| git clone git://src.adamsgaard.dk/stopwatch | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| commit 056f2e50e7795c50e3fd616034a39731ebc49d30 | |
| parent 4f6e38d9d743040a27ac5fdc0f49dbe5d53ec2af | |
| Author: Anders Damsgaard <[email protected]> | |
| Date: Thu, 5 Nov 2020 09:03:59 +0100 | |
| add timer(1) | |
| Diffstat: | |
| M Makefile | 7 +++---- | |
| M stopwatch.1 | 1 + | |
| A timer.1 | 48 +++++++++++++++++++++++++++++… | |
| A timer.c | 101 +++++++++++++++++++++++++++++… | |
| 4 files changed, 153 insertions(+), 4 deletions(-) | |
| --- | |
| diff --git a/Makefile b/Makefile | |
| t@@ -10,10 +10,9 @@ DOCPREFIX = ${PREFIX}/share/doc/${NAME} | |
| RANLIB = ranlib | |
| -BIN = ${NAME} | |
| -#BIN = \ | |
| -# stopwatch\ | |
| -# timer | |
| +BIN = \ | |
| + stopwatch\ | |
| + timer | |
| SRC = ${BIN:=.c} | |
| HDR = timeutil.h | |
| diff --git a/stopwatch.1 b/stopwatch.1 | |
| t@@ -40,6 +40,7 @@ exits with 0 on success, and >0 if a a runtime error occurs. | |
| .Sh SEE ALSO | |
| .Xr dwm 1 | |
| .Xr spoon 1 | |
| +.Xr timer 1 | |
| .Xr xsetroot 1 | |
| .Sh AUTHORS | |
| .An Anders Damsgaard Aq Mt [email protected] | |
| diff --git a/timer.1 b/timer.1 | |
| t@@ -0,0 +1,48 @@ | |
| +.Dd $Mdocdate$ | |
| +.Dt TIMER 1 | |
| +.Os | |
| +.Sh NAME | |
| +.Nm timer | |
| +.Nd reports elapsed time after launch. | |
| +.Sh SYNOPSIS | |
| +.Nm | |
| +.Op Fl p Ar prefix | |
| +.Op Fl P Ar postfix | |
| +.Op Fl i Ar interval | |
| +.Op Fl x | |
| +.Ar HH:MM:SS | |
| +.Sh DESCRIPTION | |
| +The | |
| +.Nm | |
| +counts down from for the specified duration in HH:MM:SS format, and | |
| +prints the remaining time to standard output by default. The time | |
| +is written in the format "%S s" for remaining time of less than one | |
| +minute long, "%M:%SS" for durations less than one hour, and | |
| +"%H:%MM:%SS" for all longer durations. | |
| +.Pp | |
| +The options are as follows: | |
| +.Bl -tag -width Ds | |
| +.It Fl p Ar prefix | |
| +Print the | |
| +.Ar prefix | |
| +string before the time stamp. | |
| +.It Fl P Ar postfix | |
| +Print the | |
| +.Ar postfix | |
| +string after the time stamp. | |
| +.It Fl i Ar interval | |
| +update the elapsed time with this interval in seconds. | |
| +.It Fl x | |
| +write the output to the X root window parameter, which | |
| +.Xr dwm 1 | |
| +uses as status line. | |
| +.Sh EXIT STATUS | |
| +.Nm | |
| +exits with 0 on success, and >0 if a a runtime error occurs. | |
| +.Sh SEE ALSO | |
| +.Xr dwm 1 | |
| +.Xr spoon 1 | |
| +.Xr stopwatch 1 | |
| +.Xr xsetroot 1 | |
| +.Sh AUTHORS | |
| +.An Anders Damsgaard Aq Mt [email protected] | |
| diff --git a/timer.c b/timer.c | |
| t@@ -0,0 +1,101 @@ | |
| +#include <stdio.h> | |
| +#include <stdlib.h> | |
| +#include <limits.h> | |
| +#include <unistd.h> | |
| +#include <time.h> | |
| +#include <string.h> | |
| +#include <err.h> | |
| +#include <X11/Xlib.h> | |
| + | |
| +#include "timeutil.h" | |
| + | |
| +char *argv0; | |
| + | |
| +void | |
| +usage(void) | |
| +{ | |
| + errx(1, "usage: %s [-p prefix] [-P postfix] [-i interval] [-x] HH:MM:S… | |
| +} | |
| + | |
| +void | |
| +print_loop(unsigned int interval, char *prefix, char *postfix, time_t duration) | |
| +{ | |
| + char buf[LINE_MAX]; | |
| + time_t t_start = time(NULL); | |
| + time_t t_elapsed = 0; | |
| + | |
| + while ((t_elapsed = time(NULL) - t_start) < duration) { | |
| + format_time(buf, sizeof(buf), duration - t_elapsed, prefix, po… | |
| + printf("\r%s ", buf); | |
| + fflush(stdout); | |
| + sleep(interval); | |
| + } | |
| +} | |
| + | |
| +void | |
| +xroot_loop(unsigned int interval, char *prefix, char *postfix, time_t duration) | |
| +{ | |
| + Display *dpy; | |
| + char buf[LINE_MAX]; | |
| + time_t t_start = time(NULL); | |
| + time_t t_elapsed = 0; | |
| + | |
| + dpy = XOpenDisplay(NULL); | |
| + if (dpy == NULL) | |
| + errx(1, "cannot open display"); | |
| + while ((t_elapsed = time(NULL) - t_start) < duration) { | |
| + format_time(buf, sizeof(buf), duration - t_elapsed, prefix, po… | |
| + XStoreName(dpy, DefaultRootWindow(dpy), buf); | |
| + XSync(dpy, False); | |
| + sleep(interval); | |
| + } | |
| +} | |
| + | |
| +int | |
| +main(int argc, char *argv[]) | |
| +{ | |
| + int h, m, s; | |
| + time_t duration; | |
| + int ch, xflag = 0; | |
| + unsigned int interval = 1; | |
| + char prefix[LINE_MAX] = "", postfix[LINE_MAX] = ""; | |
| + const char *errstr; | |
| + | |
| + argv0 = *argv; | |
| + | |
| + while ((ch = getopt(argc, argv, "p:P:i:x")) != -1) { | |
| + switch (ch) { | |
| + case 'p': | |
| + strlcpy(prefix, optarg, sizeof(prefix)); | |
| + break; | |
| + case 'P': | |
| + strlcpy(postfix, optarg, sizeof(postfix)); | |
| + break; | |
| + case 'i': | |
| + interval = strtonum(optarg, 1, UINT_MAX, &errstr); | |
| + if (errstr != NULL) | |
| + errx(1, "interval is %s: %s", errstr, optarg); | |
| + break; | |
| + case 'x': | |
| + xflag = 1; | |
| + break; | |
| + default: | |
| + usage(); | |
| + } | |
| + } | |
| + argc -= optind; | |
| + argv += optind; | |
| + if (argc != 1) | |
| + usage(); | |
| + | |
| + if (sscanf(argv[0], "%d:%d:%d", &h, &m, &s) != 3) | |
| + errx(2, "could not parse time in HH:MM:SS format"); | |
| + duration = h * 3600 + m * 60 + s; | |
| + | |
| + if (xflag) | |
| + xroot_loop(interval, prefix, postfix, duration); | |
| + else | |
| + print_loop(interval, prefix, postfix, duration); | |
| + | |
| + return 0; | |
| +} |