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