From 9c37e2803b356fb4192d77678f414a5726ec7785 Mon Sep 17 00:00:00 2001 From: katherine Date: Sat, 14 Dec 2019 00:14:09 -0700 Subject: implement entry --- src/entry.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/entry.c (limited to 'src/entry.c') diff --git a/src/entry.c b/src/entry.c new file mode 100644 index 0000000..64acdea --- /dev/null +++ b/src/entry.c @@ -0,0 +1,178 @@ +#include "entry.h" + +#include + +static int sub_inc_year(struct tm *t, int n) +{ + if (n == 0) + return 0; + + t->tm_year += n; + + if (mktime(t) == -1) + return -1; + + return 0; +} + +static int sub_inc_month(struct tm *t, int n) +{ + unsigned i; + + if (n == 0) + return 0; + + for (i = 0; i < n; i++) { + t->tm_mon++; + if (mktime(t) == -1) { + t->tm_mon = 0; + if (sub_inc_year(t, 1) == -1) + return -1; + } + } + + return 0; +} + +static int sub_inc_day(struct tm *t, int n) +{ + unsigned i; + + if (n == 0) + return 0; + + for (i = 0; i < n; i++) { + t->tm_mday++; + if (mktime(t) == -1) { + t->tm_mday = 1; + if (sub_inc_month(t, 1) == -1) + return -1; + } + } + + return 0; +} + +static int sub_inc_hour(struct tm *t, int n) +{ + unsigned i; + + if (n == 0) + return 0; + + for (i = 0; i < n; i++) { + t->tm_hour++; + if (mktime(t) == -1) { + t->tm_hour = 0; + if (sub_inc_day(t, 1) == -1) + return -1; + } + } + + return 0; +} + +static int sub_inc_minute(struct tm *t, int n) +{ + unsigned i; + + if (n == 0) + return 0; + + for (i = 0; i < n; i++) { + t->tm_min++; + if (mktime(t) == -1) { + t->tm_min = 0; + if (sub_inc_hour(t, 1) == -1) + return -1; + } + } + + return 0; +} + +static int sub_inc_second(struct tm *t, int n) +{ + time_t r; + struct tm *tmp; + + if (n == 0) + return 0; + + r = mktime(t); + + if (r + n <= r) + return -1; + r += n; + + tmp = localtime(&r); + *t = *tmp; + + return 0; +} + +/* super inefficient, but should best-possible avoid any weird leap + * years/seconds/dst-problems/other future changes */ +bool entry_is_active(struct entry_s *e, time_t now) +{ + struct tm t, *tmp; + time_t rtmp, now_plus_warn; + + assert(e != NULL); + + tmp = localtime(&now); + assert(tmp != NULL); + t = *tmp; + + if (sub_inc_year(&t, e->warn.year)) + return false; + if (sub_inc_month(&t, e->warn.month)) + return false; + if (sub_inc_day(&t, e->warn.day)) + return false; + if (sub_inc_hour(&t, e->warn.hour)) + return false; + if (sub_inc_minute(&t, e->warn.minute)) + return false; + if (sub_inc_second(&t, e->warn.second)) + return false; + + now_plus_warn = mktime(&t); + + if (e->type == ENTRY_TYPE_ON) { + if (e->start >= now && e->start <= now_plus_warn) + return true; + + return false; + } + + tmp = localtime(&(e->start)); + assert(tmp != NULL); + t = *tmp; + + if (e->has_end && now > e->end) + return false; + + for (rtmp = e->start;;) { + rtmp = mktime(&t); + + if (rtmp > now_plus_warn) + return false; + + if (rtmp >= now) + return true; + + if (sub_inc_year(&t, e->every.year)) + return false; + if (sub_inc_month(&t, e->every.month)) + return false; + if (sub_inc_day(&t, e->every.day)) + return false; + if (sub_inc_hour(&t, e->every.hour)) + return false; + if (sub_inc_minute(&t, e->every.minute)) + return false; + if (sub_inc_second(&t, e->every.second)) + return false; + } +} -- cgit v1.2.3