diff options
Diffstat (limited to 'src/recur.c')
-rw-r--r-- | src/recur.c | 79 |
1 files changed, 47 insertions, 32 deletions
diff --git a/src/recur.c b/src/recur.c index 3a16d1e..10523ad 100644 --- a/src/recur.c +++ b/src/recur.c @@ -1,7 +1,7 @@ /* * Calcurse - text-based organizer * - * Copyright (c) 2004-2020 calcurse Development Team <misc@calcurse.org> + * Copyright (c) 2004-2023 calcurse Development Team <misc@calcurse.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -253,8 +253,13 @@ void recur_apoint_free(struct recur_apoint *rapt) mem_free(rapt->mesg); if (rapt->note) mem_free(rapt->note); - if (rapt->rpt) + if (rapt->rpt) { + recur_free_exc_list(&rapt->rpt->exc); + recur_free_int_list(&rapt->rpt->bywday); + recur_free_int_list(&rapt->rpt->bymonth); + recur_free_int_list(&rapt->rpt->bymonthday); mem_free(rapt->rpt); + } recur_free_exc_list(&rapt->exc); mem_free(rapt); } @@ -264,8 +269,13 @@ void recur_event_free(struct recur_event *rev) mem_free(rev->mesg); if (rev->note) mem_free(rev->note); - if (rev->rpt) + if (rev->rpt) { + recur_free_exc_list(&rev->rpt->exc); + recur_free_int_list(&rev->rpt->bywday); + recur_free_int_list(&rev->rpt->bymonth); + recur_free_int_list(&rev->rpt->bymonthday); mem_free(rev->rpt); + } recur_free_exc_list(&rev->exc); mem_free(rev); } @@ -517,8 +527,7 @@ char *recur_apoint_scan(FILE *f, struct tm start, struct tm end, /* Does it occur on the start day? */ if (!recur_item_find_occurrence(tstart, tend - tstart, rpt, NULL, - update_time_in_date(tstart, 0, 0), - NULL)) { + DAY(tstart), NULL)) { char *fmt = _("recurrence error: not on start day (%s)"); return day_ins(&fmt, tstart); } @@ -590,8 +599,7 @@ char *recur_event_scan(FILE * f, struct tm start, int id, /* Does it occur on the start day? */ if (!recur_item_find_occurrence(tstart, -1, rpt, NULL, - update_time_in_date(tstart, 0, 0), - NULL)) { + DAY(tstart), NULL)) { char *fmt = _("recurrence error: not on start day (%s)"); return day_ins(&fmt, tstart); } @@ -1005,14 +1013,20 @@ static int find_occurrence(time_t start, long dur, struct rpt *rpt, llist_t *exc if (rpt->until && t >= NEXTDAY(rpt->until)) return 0; - /* Does it span the given day? */ - if (t + DUR(t) < day) + /* Does it span the given day? + * + * NOTE: An appointment ending at 00:00 is not considered to span the + * given day, unless the appointment is an appointment without + * specified end time, which is internally treated as appointment with + * duration 0. + */ + if (t + DUR(t) >= day || (t == day && dur == 0)) { + if (occurrence) + *occurrence = t; + return 1; + } else { return 0; - - if (occurrence) - *occurrence = t; - - return 1; + } } #undef DUR @@ -1209,7 +1223,7 @@ static int expand_monthly(time_t start, long dur, struct rpt *rpt, llist_t *exc, -WEEKINDAYS ); r.until = date_sec_change( - update_time_in_date(nstart, 0, 0), + DAY(nstart), 0, r.freq * WEEKINDAYS ); @@ -1243,7 +1257,7 @@ static int expand_monthly(time_t start, long dur, struct rpt *rpt, llist_t *exc, -WEEKINDAYS ); r.until = date_sec_change( - update_time_in_date(nstart, 0, 0), + DAY(nstart), 0, r.freq * WEEKINDAYS ); @@ -1349,7 +1363,7 @@ static int expand_yearly(time_t start, long dur, struct rpt *rpt, llist_t *exc, -WEEKINDAYS ); r.until = date_sec_change( - update_time_in_date(nstart, 0, 0), + DAY(nstart), 0, r.freq * WEEKINDAYS ); @@ -1394,7 +1408,7 @@ static int expand_yearly(time_t start, long dur, struct rpt *rpt, llist_t *exc, -WEEKINDAYS ); r.until = date_sec_change( - update_time_in_date(nstart, 0, 0), + DAY(nstart), 0, r.freq * WEEKINDAYS ); @@ -1840,7 +1854,7 @@ int recur_nth_occurrence(time_t s, long d, struct rpt *r, llist_t *e, int n, return 0; for (n--, *nth = s; n > 0; n--) { - day = update_time_in_date(*nth, 0, 0); + day = DAY(*nth); if (!recur_next_occurrence(s, d, r, e, day, nth)) break; } @@ -1854,19 +1868,20 @@ int recur_nth_occurrence(time_t s, long d, struct rpt *r, llist_t *e, int n, int recur_prev_occurrence(time_t s, long d, struct rpt *r, llist_t *e, time_t day, time_t *prev) { - time_t prev_day, next; + int ret = 0; - if (day <= update_time_in_date(s, 0, 0)) - return 0; - next = *prev = s; - while (update_time_in_date(next, 0, 0) < day) { - /* Set new previous and next. */ - *prev = next; - prev_day = update_time_in_date(*prev, 0, 0); - recur_next_occurrence(s, d, r, e, prev_day, &next); - /* Multi-day appointment */ - if (next == *prev) - next = NEXTDAY(*prev); + if (day <= DAY(s)) + return ret; + + while (DAY(s) < day) { + day = PREVDAY(day); + if (recur_item_find_occurrence(s, d, r, e, day, prev)) { + /* Multi-day appointment. */ + if (d != -1 && *prev < day && day < *prev + d) + continue; + ret = 1; + break; + } } - return 1; + return ret; } |