aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/calcurse.h6
-rw-r--r--src/notify.c9
-rw-r--r--src/pcal.c10
-rw-r--r--src/recur.c148
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(&notify_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(&notify_app.mutex);
if (notify_app.got_app && item_start == notify_app.time)
diff --git a/src/pcal.c b/src/pcal.c
index 36fdd8e..78da0bb 100644
--- a/src/pcal.c
+++ b/src/pcal.c
@@ -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);
lt.tm_hour = lt.tm_min = lt.tm_sec = 0;
lt.tm_isdst = -1;
date = mktime(&lt);
- 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, &lt_day); /* selected day */
- localtime_r(&item_start, &lt_item); /* first occurrence */
- lt_item_day = lt_item; /* recent occurrence */
+ localtime_r(&day_start, &lt_day); /* Given day. */
+ localtime_r(&start, &lt_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(&lt_item_day);
+ lt_occur.tm_isdst = -1;
+ occ = mktime(&lt_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, &lt_item_day);
- if (lt_item_day.tm_mday != lt_item.tm_mday)
+ if (rpt->type == RECUR_MONTHLY || rpt->type == RECUR_YEARLY) {
+ localtime_r(&occ, &lt_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. */