diff options
-rw-r--r-- | src/calcurse.h | 6 | ||||
-rw-r--r-- | src/notify.c | 9 | ||||
-rw-r--r-- | src/pcal.c | 10 | ||||
-rw-r--r-- | src/recur.c | 148 |
4 files changed, 78 insertions, 95 deletions
diff --git a/src/calcurse.h b/src/calcurse.h index d65d088..70a3923 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -1060,11 +1060,11 @@ char *recur_event_tostr(struct recur_event *); char *recur_event_hash(struct recur_event *); void recur_event_write(struct recur_event *, FILE *); void recur_save_data(FILE *); -unsigned recur_item_find_occurrence(time_t, long, llist_t *, int, - int, time_t, time_t, time_t *); +unsigned recur_item_find_occurrence(time_t, long, struct rpt *, llist_t *, + time_t, time_t *); unsigned recur_apoint_find_occurrence(struct recur_apoint *, time_t, time_t *); unsigned recur_event_find_occurrence(struct recur_event *, time_t, time_t *); -unsigned recur_item_inday(time_t, long, llist_t *, int, int, time_t, time_t); +unsigned recur_item_inday(time_t, long, struct rpt *, llist_t *, time_t); unsigned recur_apoint_inday(struct recur_apoint *, time_t *); unsigned recur_event_inday(struct recur_event *, time_t *); void recur_event_add_exc(struct recur_event *, time_t); diff --git a/src/notify.c b/src/notify.c index 3d19511..a24beb2 100644 --- a/src/notify.c +++ b/src/notify.c @@ -505,8 +505,7 @@ void notify_check_repeated(struct recur_apoint *i) current_time = time(NULL); pthread_mutex_lock(¬ify_app.mutex); if (recur_item_find_occurrence - (i->start, i->dur, &i->exc, i->rpt->type, i->rpt->freq, - i->rpt->until, get_today(), &real_app_time)) { + (i->start, i->dur, i->rpt, &i->exc, get_today(), &real_app_time)) { if (!notify_app.got_app) { if (real_app_time - current_time <= DAYINSEC) update_notify = 1; @@ -547,12 +546,10 @@ int notify_same_recur_item(struct recur_apoint *i) time_t item_start; /* Tomorrow? */ - recur_item_find_occurrence(i->start, i->dur, &i->exc, i->rpt->type, - i->rpt->freq, i->rpt->until, + recur_item_find_occurrence(i->start, i->dur, i->rpt, &i->exc, NEXTDAY(get_today()), &item_start); /* Today? */ - recur_item_find_occurrence(i->start, i->dur, &i->exc, i->rpt->type, - i->rpt->freq, i->rpt->until, + recur_item_find_occurrence(i->start, i->dur, i->rpt, &i->exc, get_today(), &item_start); pthread_mutex_lock(¬ify_app.mutex); if (notify_app.got_app && item_start == notify_app.time) @@ -56,24 +56,22 @@ typedef void (*cb_dump_t) (FILE *, long, long, char *); */ static void foreach_date_dump(const long date_end, struct rpt *rpt, llist_t * exc, - long item_first_date, long item_dur, char *item_mesg, + long item_start, long item_dur, char *item_mesg, cb_dump_t cb_dump, FILE * stream) { long date, item_time; struct tm lt; time_t t; - t = item_first_date; + t = item_start; localtime_r(&t, <); lt.tm_hour = lt.tm_min = lt.tm_sec = 0; lt.tm_isdst = -1; date = mktime(<); - item_time = item_first_date - date; + item_time = item_start - date; while (date <= date_end && date <= rpt->until) { - if (recur_item_inday - (item_first_date, item_dur, exc, rpt->type, rpt->freq, - rpt->until, date)) { + if (recur_item_inday(item_start, item_dur, rpt, exc, date)) { (*cb_dump) (stream, date + item_time, item_dur, item_mesg); } diff --git a/src/recur.c b/src/recur.c index 54c43ba..cad8345 100644 --- a/src/recur.c +++ b/src/recur.c @@ -746,108 +746,103 @@ static int exc_inday(struct excp *exc, time_t *day_start) } /* - * Check if the recurrent item belongs to the selected day, and if yes, store - * the start date of the occurrence that belongs to the day in a buffer. - * - * This function was improved thanks to Tony's patch. - * Thanks also to youshe for reporting daylight saving time related problems. - * And finally thanks to Lukas for providing a patch to correct the wrong - * calculation of recurrent dates after a turn of years. + * Return true if the recurrent item has an occurrence on the given day + * and, if so, store the start date of that occurrence in a buffer. */ unsigned -recur_item_find_occurrence(time_t item_start, long item_dur, - llist_t * item_exc, int rpt_type, int rpt_freq, - time_t rpt_until, time_t day_start, - time_t *occurrence) +recur_item_find_occurrence(time_t start, long dur, struct rpt *rpt, llist_t *exc, + time_t day_start, time_t *occurrence) { -/* - * Function-internal duration - * 1) To avoid an item ending on midnight (which belongs to the next day), - * duration is always diminished by 1 second. - * 2) An event has no explicit duration, but lasts for an entire day, which - * in turn depends on DST. - */ -#define ITEM_DUR(d) ((item_dur == -1 ? DAYLEN(d) : item_dur) - 1) + /* + * Duration fix. + * An item cannot end on midnight or else it is counted towards the next day. + * An event (dur == -1) has no explicit duration, but is considered to last for + * the entire day which depends on DST. + */ +#define DUR(d) (dur == -1 ? DAYLEN((d)) - 1 : dur - 1) long diff; - struct tm lt_day, lt_item, lt_item_day; - time_t occ, item_day_start; + struct tm lt_day, lt_item, lt_occur; + time_t occ; - item_day_start = update_time_in_date(item_start, 0, 0); - - if (day_start < item_day_start) + /* Is the given day before the day of the first occurence? */ + if (date_cmp_day(day_start, start) < 0) return 0; - - if (rpt_until && day_start >= - rpt_until + (item_start - item_day_start) + ITEM_DUR(rpt_until)) + /* + * - or after the day of the last occurrence (which may stretch beyond + * the until date)? Extraneous days are eliminated later. + */ + if (rpt->until && + date_cmp_day(NEXTDAY(rpt->until) + DUR(rpt->until), day_start) < 0) return 0; - localtime_r(&day_start, <_day); /* selected day */ - localtime_r(&item_start, <_item); /* first occurrence */ - lt_item_day = lt_item; /* recent occurrence */ + localtime_r(&day_start, <_day); /* Given day. */ + localtime_r(&start, <_item); /* Original item. */ + lt_occur = lt_item; /* First occurence. */ /* * Update to the most recent occurrence before or on the selected day. */ - switch (rpt_type) { + switch (rpt->type) { case RECUR_DAILY: - diff = diff_days(lt_item_day, lt_day) % rpt_freq; - lt_item_day.tm_mday = lt_day.tm_mday - diff; - lt_item_day.tm_mon = lt_day.tm_mon; - lt_item_day.tm_year = lt_day.tm_year; + /* Number of days since the most recent occurrence. */ + diff = diff_days(lt_occur, lt_day) % rpt->freq; + lt_occur.tm_mday = lt_day.tm_mday - diff; + lt_occur.tm_mon = lt_day.tm_mon; + lt_occur.tm_year = lt_day.tm_year; break; case RECUR_WEEKLY: - diff = diff_days(lt_item_day, lt_day) % - (rpt_freq * WEEKINDAYS); - lt_item_day.tm_mday = lt_day.tm_mday - diff; - lt_item_day.tm_mon = lt_day.tm_mon; - lt_item_day.tm_year = lt_day.tm_year; + diff = diff_days(lt_occur, lt_day) % + (rpt->freq * WEEKINDAYS); + lt_occur.tm_mday = lt_day.tm_mday - diff; + lt_occur.tm_mon = lt_day.tm_mon; + lt_occur.tm_year = lt_day.tm_year; break; case RECUR_MONTHLY: - diff = diff_months(lt_item_day, lt_day) % rpt_freq; - if (!diff && lt_day.tm_mday < lt_item_day.tm_mday) - diff += rpt_freq; - lt_item_day.tm_mon = lt_day.tm_mon - diff; - lt_item_day.tm_year = lt_day.tm_year; + diff = diff_months(lt_occur, lt_day) % rpt->freq; + if (!diff && lt_day.tm_mday < lt_occur.tm_mday) + diff += rpt->freq; + lt_occur.tm_mon = lt_day.tm_mon - diff; + lt_occur.tm_year = lt_day.tm_year; break; case RECUR_YEARLY: - diff = diff_years(lt_item_day, lt_day) % rpt_freq; + diff = diff_years(lt_occur, lt_day) % rpt->freq; if (!diff && - (lt_day.tm_mon < lt_item_day.tm_mon || - (lt_day.tm_mon == lt_item_day.tm_mon && - lt_day.tm_mday < lt_item_day.tm_mday))) - diff += rpt_freq; - lt_item_day.tm_year = lt_day.tm_year - diff; + (lt_day.tm_mon < lt_occur.tm_mon || + (lt_day.tm_mon == lt_occur.tm_mon && + lt_day.tm_mday < lt_occur.tm_mday))) + diff += rpt->freq; + lt_occur.tm_year = lt_day.tm_year - diff; break; default: EXIT(_("unknown item type")); } /* Switch to calendar (Unix) time. */ - lt_item_day.tm_isdst = -1; - occ = mktime(<_item_day); + lt_occur.tm_isdst = -1; + occ = mktime(<_occur); /* * Impossible dates must be ignored (according to RFC 5545). Changing * only the year or the month may lead to dates like 29 February in * non-leap years or 31 November. */ - if (rpt_type == RECUR_MONTHLY || rpt_type == RECUR_YEARLY) { - localtime_r(&occ, <_item_day); - if (lt_item_day.tm_mday != lt_item.tm_mday) + if (rpt->type == RECUR_MONTHLY || rpt->type == RECUR_YEARLY) { + localtime_r(&occ, <_occur); + if (lt_occur.tm_mday != lt_item.tm_mday) return 0; } /* Exception day? */ - if (LLIST_FIND_FIRST(item_exc, &occ, exc_inday)) + if (LLIST_FIND_FIRST(exc, &occ, exc_inday)) return 0; - /* After until day? */ - if (rpt_until && occ >= NEXTDAY(rpt_until)) + /* Extraneous day? */ + if (rpt->until && occ >= NEXTDAY(rpt->until)) return 0; - /* Does it span the selected day? */ - if (occ + ITEM_DUR(occ) < day_start) + /* Does it span the given day? */ + if (occ + DUR(occ) < day_start) return 0; if (occurrence) @@ -856,53 +851,46 @@ recur_item_find_occurrence(time_t item_start, long item_dur, return 1; #undef ITEM_DUR } +#undef DUR unsigned recur_apoint_find_occurrence(struct recur_apoint *rapt, time_t day_start, time_t *occurrence) { - return recur_item_find_occurrence(rapt->start, rapt->dur, - &rapt->exc, rapt->rpt->type, - rapt->rpt->freq, - rapt->rpt->until, day_start, - occurrence); + return recur_item_find_occurrence(rapt->start, rapt->dur, rapt->rpt, + &rapt->exc, day_start, occurrence); } unsigned recur_event_find_occurrence(struct recur_event *rev, time_t day_start, time_t *occurrence) { - return recur_item_find_occurrence(rev->day, -1, &rev->exc, - rev->rpt->type, rev->rpt->freq, - rev->rpt->until, day_start, - occurrence); + return recur_item_find_occurrence(rev->day, -1, rev->rpt, &rev->exc, + day_start, occurrence); } /* Check if a recurrent item belongs to the selected day. */ unsigned -recur_item_inday(time_t item_start, long item_dur, llist_t * item_exc, - int rpt_type, int rpt_freq, time_t rpt_until, +recur_item_inday(time_t start, long dur, + struct rpt *rpt, llist_t * exc, time_t day_start) { /* We do not need the (real) start time of the occurrence here, so just * ignore the buffer. */ - return recur_item_find_occurrence(item_start, item_dur, item_exc, - rpt_type, rpt_freq, rpt_until, + return recur_item_find_occurrence(start, dur, rpt, exc, day_start, NULL); } unsigned recur_apoint_inday(struct recur_apoint *rapt, time_t *day_start) { - return recur_item_inday(rapt->start, rapt->dur, &rapt->exc, - rapt->rpt->type, rapt->rpt->freq, - rapt->rpt->until, *day_start); + return recur_item_inday(rapt->start, rapt->dur, rapt->rpt, &rapt->exc, + *day_start); } unsigned recur_event_inday(struct recur_event *rev, time_t *day_start) { - return recur_item_inday(rev->day, -1, &rev->exc, - rev->rpt->type, rev->rpt->freq, - rev->rpt->until, *day_start); + return recur_item_inday(rev->day, -1, rev->rpt, &rev->exc, + *day_start); } /* Add an exception to a recurrent event. */ |