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; | |
+} |