From 7a654466db3ca5b5f2867dcf91c8f5b95e5da381 Mon Sep 17 00:00:00 2001 From: randomuser Date: Thu, 10 Jun 2021 23:10:47 -0500 Subject: [PATCH] add timer application --- .gitignore | 1 + Makefile | 4 +- rndutils.1 => man/rndutils.1 | 0 progs/timer.c | 164 +++++++++++++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 1 deletion(-) rename rndutils.1 => man/rndutils.1 (100%) create mode 100644 progs/timer.c diff --git a/.gitignore b/.gitignore index 2d03a57..573e5d5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.swp *.tmp progs/scream +progs/timer diff --git a/Makefile b/Makefile index 73d2032..fc04124 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ install: man sh mkc c man: mkdir -p $(DESTDIR)$(PREFIX)/man1 - cp -f *.1 $(DESTDIR)$(PREFIX)/man1 + cp -f man/* $(DESTDIR)$(PREFIX)/man1 sh: mkdir -p $(DESTDIR)$(PREFIX)/bin cp -f scripts/paste $(DESTDIR)$(PREFIX)/bin @@ -26,7 +26,9 @@ sh: mkc: cc progs/scream.c -o progs/scream + cc progs/timer.c -o progs/timer c: cp -f progs/scream $(DESTDIR)$(PREFIX)/bin + cp -f progs/timer $(DESTDIR)$(PREFIX)/bin clean: rm progs/scream diff --git a/rndutils.1 b/man/rndutils.1 similarity index 100% rename from rndutils.1 rename to man/rndutils.1 diff --git a/progs/timer.c b/progs/timer.c new file mode 100644 index 0000000..9a6297b --- /dev/null +++ b/progs/timer.c @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include + +struct timer { + int m; + int s; + void (*u)(struct timer *t); + int (*c)(struct timer *t); +}; + +struct settings { + int e:1; /* use escape (v assumed) */ + int v:1; /* verbose */ + int d:1; /* count down/up (1/0) */ + int b:1; /* ascii bel when done */ + int f:1; /* display hours */ + int m; /* minutes */ + int s; /* seconds */ +} settings = { + .e = 0, + .v = 0, + .d = 0, + .b = 0, + .f = 0, + .m = 0, + .s = 0 +}; + +void timerdec(struct timer *t) { + if(t->s > 0) t->s--; + else if(t->s == 0) { + t->s = 59; + t->m--; + } +} + +void timerinc(struct timer *t) { + if(t->s < 59) t->s++; + else if(t->s == 59) { + t->s = 0; + t->m++; + } +} + +void timerupdate(struct timer *t) { + if(t->u != NULL) t->u(t); +} + +int timerstate(struct timer *t) { + if(t->c != NULL) { + if(t->c(t)) return 1; + else return 0; + } + return 0; +} + +int timerzero(struct timer *t) { + if(t->m == 0 && t->s == 0) return 1; + return 0; +} + +int timerissettings(struct timer *t) { + if(t->m == 0 && t->s == 0) return 0; + if(t->m == settings.m && + t->s == settings.s) return 1; + return 0; +} + +char *timerdisp(struct timer *t) { + char *str = malloc(20); + if(settings.f) snprintf(str, 20, "%02i:%02i:%02i", + (t->m / 60), (t->m % 60), t->s); + else snprintf(str, 20, "%02i:%02i", t->m, t->s); + return str; +} + +struct timer *timerinit(void) { + struct timer *t = malloc(sizeof t); + t->m = 0; + t->s = 0; + t->u = NULL; + t->c = NULL; + return t; +} + +void timerloop() { + struct timer *t = timerinit(); + if(settings.d) { + t->u = timerdec; + t->m = settings.m; + t->s = settings.s; + t->c = timerzero; + } else { + t->u = timerinc; + t->c = timerissettings; + } + char *c; + struct pollfd *p = malloc(sizeof p); + p->fd = STDIN_FILENO; + p->events = POLLIN; + for(;;) { + poll(p, 1, 60); + if(p->revents == POLLIN) { + /* TODO: make this nicer */ + getchar(); + if(settings.e) { + c = timerdisp(t); + printf("\r\e[1A* %s", c); + } + getchar(); + /* TODO: stop relying on hard assumptions */ + if(settings.e) printf("\r\e[1A \r", c); + } + c = timerdisp(t); + if(settings.e) { + printf("%s\r", c); + fflush(stdout); + } + else if(settings.v) printf("%s\n", c); + if(timerstate(t)) break; + timerupdate(t); + sleep(1); + } + if(settings.b) putchar('\a'); +} + +int main(int argc, char **argv) { + char c; + while((c = getopt (argc, argv, "evdbfm:s:")) != -1) { + switch(c) { + case 'e': + settings.e = 1; + break; + case 'v': + settings.v = 1; + break; + case 'd': + settings.d = 1; + break; + case 'b': + settings.b = 1; + break; + case 'f': + settings.f = 1; + break; + case 'm': + settings.m = atoi(optarg); + break; + case 's': + settings.s = atoi(optarg); + break; + case '?': + return 1; + default: + abort(); + break; + } + } + timerloop(); + return 0; +}