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 
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 anders@adamsgaard.dk
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 anders@adamsgaard.dk
diff --git a/timer.c b/timer.c
t@@ -0,0 +1,101 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "timeutil.h"
+
+char *argv0;
+
+void
+usage(void)
+{
+        errx(1, "usage: %s [-p prefix] [-P postfix] [-i interval] [-x] HH:MM:SS", argv0);
+}
+
+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, postfix);
+                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, postfix);
+                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;
+}