From: Ben Harris Date: Sat, 3 Nov 2018 22:25:48 +0000 (+0000) Subject: Add an option to specify the current displayed time at startup. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~bjharris/git?a=commitdiff_plain;h=8b4058d4f93ed0908db81488623831a05f309342;p=clunk.git Add an option to specify the current displayed time at startup. --- diff --git a/clunk.c b/clunk.c index f7e7271..6e6e191 100644 --- a/clunk.c +++ b/clunk.c @@ -2,6 +2,7 @@ #include #include #include +#include static long const pulsewidth = 250000000; /* nanoseconds */ @@ -26,15 +27,16 @@ pulse() displayed.tm_min -= 60; } displayed.tm_hour %= 12; - printf(" (%02d:%02d:%02d)\n", + printf(" (%d:%02d:%02d)\n", displayed.tm_hour, displayed.tm_min, displayed.tm_sec); fflush(stdout); } static void -init() +init(int argc, char **argv) { struct timespec ts; + int opt; tzset(); if (clock_gettime(CLOCK_REALTIME, &ts) != 0) @@ -42,30 +44,76 @@ init() if (localtime_r(&ts.tv_sec, &displayed) == NULL) err(1, "localtime_r"); displayed.tm_sec = (displayed.tm_sec >= 30) ? 30 : 0; + while ((opt = getopt(argc, argv, "s:")) != -1) { + switch (opt) { + case 's': + if (sscanf(optarg, "%d:%d:%d", &displayed.tm_hour, + &displayed.tm_min, &displayed.tm_sec) != 3) + errx(1, "usage"); + break; + } + } +} + +enum need_adjust { STOP, TICK, ADVANCE }; + +static enum need_adjust +need_adjust(struct tm const *now) +{ + long diff; + + diff = now->tm_sec - displayed.tm_sec + + 60 * (now->tm_min - displayed.tm_min) + + 3600 * (now->tm_hour - displayed.tm_hour); + if (diff < 0) diff += 3600 * 12; + diff %= 3600 * 12; + printf("diff = %ld\n", diff); + if (diff < 30 || diff >= (10 * 3600)) return STOP; + if (diff < 60) return TICK; + if (diff < (10 * 3600)) return ADVANCE; +} + +static void +ts_advance(struct timespec *tp, long nsec) +{ + + tp->tv_nsec += nsec; + if (tp->tv_nsec >= 1000000000) tp->tv_sec++; } - static void run() { struct timespec ts; struct tm tm; + int tick; while (true) { if (clock_gettime(CLOCK_REALTIME, &ts) != 0) err(1, "clock_gettime"); + ts_advance(&ts, pulsewidth); if (localtime_r(&ts.tv_sec, &tm) == NULL) err(1, "localtime_r"); - /* Round down to the last 30 s. */ + tick = 30; + switch (need_adjust(&tm)) { + case ADVANCE: + tick = 2; + /* FALLTHROUGH */ + case TICK: + pulse(); + /* FALLTHROUGH */ + case STOP: + /* nothing */ ; + } + /* Round down to the last tick. */ ts.tv_nsec = 0; - ts.tv_sec -= tm.tm_sec % 30; + ts.tv_sec -= tm.tm_sec % tick; /* Choose when next tick will be. */ ts.tv_nsec = 1000000000 - pulsewidth; - ts.tv_sec += 29; + ts.tv_sec += tick - 1; if (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL) != 0) err(1, "clock_nanosleep"); - pulse(); } } @@ -73,7 +121,7 @@ int main(int argc, char **argv) { - init(); + init(argc, argv); run(); return 0; }