Use "struct rpt" to shorten argument lists

Also, prepare for extension of the structure, shorten names and
rearrange comments.

Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
This commit is contained in:
Lars Henriksen 2019-05-22 09:04:36 +02:00 committed by Lukas Fleischer
parent e9deb6fff3
commit 3f7bd331c8
4 changed files with 79 additions and 96 deletions

View File

@ -1060,11 +1060,11 @@ char *recur_event_tostr(struct recur_event *);
char *recur_event_hash(struct recur_event *); char *recur_event_hash(struct recur_event *);
void recur_event_write(struct recur_event *, FILE *); void recur_event_write(struct recur_event *, FILE *);
void recur_save_data(FILE *); void recur_save_data(FILE *);
unsigned recur_item_find_occurrence(time_t, long, llist_t *, int, unsigned recur_item_find_occurrence(time_t, long, struct rpt *, llist_t *,
int, time_t, time_t, time_t *); time_t, time_t *);
unsigned recur_apoint_find_occurrence(struct recur_apoint *, 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_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_apoint_inday(struct recur_apoint *, time_t *);
unsigned recur_event_inday(struct recur_event *, time_t *); unsigned recur_event_inday(struct recur_event *, time_t *);
void recur_event_add_exc(struct recur_event *, time_t); void recur_event_add_exc(struct recur_event *, time_t);

View File

@ -505,8 +505,7 @@ void notify_check_repeated(struct recur_apoint *i)
current_time = time(NULL); current_time = time(NULL);
pthread_mutex_lock(&notify_app.mutex); pthread_mutex_lock(&notify_app.mutex);
if (recur_item_find_occurrence if (recur_item_find_occurrence
(i->start, i->dur, &i->exc, i->rpt->type, i->rpt->freq, (i->start, i->dur, i->rpt, &i->exc, get_today(), &real_app_time)) {
i->rpt->until, get_today(), &real_app_time)) {
if (!notify_app.got_app) { if (!notify_app.got_app) {
if (real_app_time - current_time <= DAYINSEC) if (real_app_time - current_time <= DAYINSEC)
update_notify = 1; update_notify = 1;
@ -547,12 +546,10 @@ int notify_same_recur_item(struct recur_apoint *i)
time_t item_start; time_t item_start;
/* Tomorrow? */ /* Tomorrow? */
recur_item_find_occurrence(i->start, i->dur, &i->exc, i->rpt->type, recur_item_find_occurrence(i->start, i->dur, i->rpt, &i->exc,
i->rpt->freq, i->rpt->until,
NEXTDAY(get_today()), &item_start); NEXTDAY(get_today()), &item_start);
/* Today? */ /* Today? */
recur_item_find_occurrence(i->start, i->dur, &i->exc, i->rpt->type, recur_item_find_occurrence(i->start, i->dur, i->rpt, &i->exc,
i->rpt->freq, i->rpt->until,
get_today(), &item_start); get_today(), &item_start);
pthread_mutex_lock(&notify_app.mutex); pthread_mutex_lock(&notify_app.mutex);
if (notify_app.got_app && item_start == notify_app.time) if (notify_app.got_app && item_start == notify_app.time)

View File

@ -56,24 +56,22 @@ typedef void (*cb_dump_t) (FILE *, long, long, char *);
*/ */
static void static void
foreach_date_dump(const long date_end, struct rpt *rpt, llist_t * exc, 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) cb_dump_t cb_dump, FILE * stream)
{ {
long date, item_time; long date, item_time;
struct tm lt; struct tm lt;
time_t t; time_t t;
t = item_first_date; t = item_start;
localtime_r(&t, &lt); localtime_r(&t, &lt);
lt.tm_hour = lt.tm_min = lt.tm_sec = 0; lt.tm_hour = lt.tm_min = lt.tm_sec = 0;
lt.tm_isdst = -1; lt.tm_isdst = -1;
date = mktime(&lt); date = mktime(&lt);
item_time = item_first_date - date; item_time = item_start - date;
while (date <= date_end && date <= rpt->until) { while (date <= date_end && date <= rpt->until) {
if (recur_item_inday if (recur_item_inday(item_start, item_dur, rpt, exc, date)) {
(item_first_date, item_dur, exc, rpt->type, rpt->freq,
rpt->until, date)) {
(*cb_dump) (stream, date + item_time, item_dur, (*cb_dump) (stream, date + item_time, item_dur,
item_mesg); item_mesg);
} }

View File

@ -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 * Return true if the recurrent item has an occurrence on the given day
* the start date of the occurrence that belongs to the day in a buffer. * and, if so, store the start date of that occurrence 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.
*/ */
unsigned unsigned
recur_item_find_occurrence(time_t item_start, long item_dur, recur_item_find_occurrence(time_t start, long dur, struct rpt *rpt, llist_t *exc,
llist_t * item_exc, int rpt_type, int rpt_freq, time_t day_start, time_t *occurrence)
time_t rpt_until, time_t day_start,
time_t *occurrence)
{ {
/* /*
* Function-internal duration * Duration fix.
* 1) To avoid an item ending on midnight (which belongs to the next day), * An item cannot end on midnight or else it is counted towards the next day.
* duration is always diminished by 1 second. * An event (dur == -1) has no explicit duration, but is considered to last for
* 2) An event has no explicit duration, but lasts for an entire day, which * the entire day which depends on DST.
* in turn depends on DST. */
*/ #define DUR(d) (dur == -1 ? DAYLEN((d)) - 1 : dur - 1)
#define ITEM_DUR(d) ((item_dur == -1 ? DAYLEN(d) : item_dur) - 1)
long diff; long diff;
struct tm lt_day, lt_item, lt_item_day; struct tm lt_day, lt_item, lt_occur;
time_t occ, item_day_start; time_t occ;
item_day_start = update_time_in_date(item_start, 0, 0); /* Is the given day before the day of the first occurence? */
if (date_cmp_day(day_start, start) < 0)
if (day_start < item_day_start) return 0;
/*
* - 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; return 0;
if (rpt_until && day_start >= localtime_r(&day_start, &lt_day); /* Given day. */
rpt_until + (item_start - item_day_start) + ITEM_DUR(rpt_until)) localtime_r(&start, &lt_item); /* Original item. */
return 0; lt_occur = lt_item; /* First occurence. */
localtime_r(&day_start, &lt_day); /* selected day */
localtime_r(&item_start, &lt_item); /* first occurrence */
lt_item_day = lt_item; /* recent occurrence */
/* /*
* Update to the most recent occurrence before or on the selected day. * Update to the most recent occurrence before or on the selected day.
*/ */
switch (rpt_type) { switch (rpt->type) {
case RECUR_DAILY: case RECUR_DAILY:
diff = diff_days(lt_item_day, lt_day) % rpt_freq; /* Number of days since the most recent occurrence. */
lt_item_day.tm_mday = lt_day.tm_mday - diff; diff = diff_days(lt_occur, lt_day) % rpt->freq;
lt_item_day.tm_mon = lt_day.tm_mon; lt_occur.tm_mday = lt_day.tm_mday - diff;
lt_item_day.tm_year = lt_day.tm_year; lt_occur.tm_mon = lt_day.tm_mon;
lt_occur.tm_year = lt_day.tm_year;
break; break;
case RECUR_WEEKLY: case RECUR_WEEKLY:
diff = diff_days(lt_item_day, lt_day) % diff = diff_days(lt_occur, lt_day) %
(rpt_freq * WEEKINDAYS); (rpt->freq * WEEKINDAYS);
lt_item_day.tm_mday = lt_day.tm_mday - diff; lt_occur.tm_mday = lt_day.tm_mday - diff;
lt_item_day.tm_mon = lt_day.tm_mon; lt_occur.tm_mon = lt_day.tm_mon;
lt_item_day.tm_year = lt_day.tm_year; lt_occur.tm_year = lt_day.tm_year;
break; break;
case RECUR_MONTHLY: case RECUR_MONTHLY:
diff = diff_months(lt_item_day, lt_day) % rpt_freq; diff = diff_months(lt_occur, lt_day) % rpt->freq;
if (!diff && lt_day.tm_mday < lt_item_day.tm_mday) if (!diff && lt_day.tm_mday < lt_occur.tm_mday)
diff += rpt_freq; diff += rpt->freq;
lt_item_day.tm_mon = lt_day.tm_mon - diff; lt_occur.tm_mon = lt_day.tm_mon - diff;
lt_item_day.tm_year = lt_day.tm_year; lt_occur.tm_year = lt_day.tm_year;
break; break;
case RECUR_YEARLY: case RECUR_YEARLY:
diff = diff_years(lt_item_day, lt_day) % rpt_freq; diff = diff_years(lt_occur, lt_day) % rpt->freq;
if (!diff && if (!diff &&
(lt_day.tm_mon < lt_item_day.tm_mon || (lt_day.tm_mon < lt_occur.tm_mon ||
(lt_day.tm_mon == lt_item_day.tm_mon && (lt_day.tm_mon == lt_occur.tm_mon &&
lt_day.tm_mday < lt_item_day.tm_mday))) lt_day.tm_mday < lt_occur.tm_mday)))
diff += rpt_freq; diff += rpt->freq;
lt_item_day.tm_year = lt_day.tm_year - diff; lt_occur.tm_year = lt_day.tm_year - diff;
break; break;
default: default:
EXIT(_("unknown item type")); EXIT(_("unknown item type"));
} }
/* Switch to calendar (Unix) time. */ /* Switch to calendar (Unix) time. */
lt_item_day.tm_isdst = -1; lt_occur.tm_isdst = -1;
occ = mktime(&lt_item_day); occ = mktime(&lt_occur);
/* /*
* Impossible dates must be ignored (according to RFC 5545). Changing * Impossible dates must be ignored (according to RFC 5545). Changing
* only the year or the month may lead to dates like 29 February in * only the year or the month may lead to dates like 29 February in
* non-leap years or 31 November. * non-leap years or 31 November.
*/ */
if (rpt_type == RECUR_MONTHLY || rpt_type == RECUR_YEARLY) { if (rpt->type == RECUR_MONTHLY || rpt->type == RECUR_YEARLY) {
localtime_r(&occ, &lt_item_day); localtime_r(&occ, &lt_occur);
if (lt_item_day.tm_mday != lt_item.tm_mday) if (lt_occur.tm_mday != lt_item.tm_mday)
return 0; return 0;
} }
/* Exception day? */ /* Exception day? */
if (LLIST_FIND_FIRST(item_exc, &occ, exc_inday)) if (LLIST_FIND_FIRST(exc, &occ, exc_inday))
return 0; return 0;
/* After until day? */ /* Extraneous day? */
if (rpt_until && occ >= NEXTDAY(rpt_until)) if (rpt->until && occ >= NEXTDAY(rpt->until))
return 0; return 0;
/* Does it span the selected day? */ /* Does it span the given day? */
if (occ + ITEM_DUR(occ) < day_start) if (occ + DUR(occ) < day_start)
return 0; return 0;
if (occurrence) if (occurrence)
@ -856,53 +851,46 @@ recur_item_find_occurrence(time_t item_start, long item_dur,
return 1; return 1;
#undef ITEM_DUR #undef ITEM_DUR
} }
#undef DUR
unsigned unsigned
recur_apoint_find_occurrence(struct recur_apoint *rapt, time_t day_start, recur_apoint_find_occurrence(struct recur_apoint *rapt, time_t day_start,
time_t *occurrence) time_t *occurrence)
{ {
return recur_item_find_occurrence(rapt->start, rapt->dur, return recur_item_find_occurrence(rapt->start, rapt->dur, rapt->rpt,
&rapt->exc, rapt->rpt->type, &rapt->exc, day_start, occurrence);
rapt->rpt->freq,
rapt->rpt->until, day_start,
occurrence);
} }
unsigned unsigned
recur_event_find_occurrence(struct recur_event *rev, time_t day_start, recur_event_find_occurrence(struct recur_event *rev, time_t day_start,
time_t *occurrence) time_t *occurrence)
{ {
return recur_item_find_occurrence(rev->day, -1, &rev->exc, return recur_item_find_occurrence(rev->day, -1, rev->rpt, &rev->exc,
rev->rpt->type, rev->rpt->freq, day_start, occurrence);
rev->rpt->until, day_start,
occurrence);
} }
/* Check if a recurrent item belongs to the selected day. */ /* Check if a recurrent item belongs to the selected day. */
unsigned unsigned
recur_item_inday(time_t item_start, long item_dur, llist_t * item_exc, recur_item_inday(time_t start, long dur,
int rpt_type, int rpt_freq, time_t rpt_until, struct rpt *rpt, llist_t * exc,
time_t day_start) time_t day_start)
{ {
/* We do not need the (real) start time of the occurrence here, so just /* We do not need the (real) start time of the occurrence here, so just
* ignore the buffer. */ * ignore the buffer. */
return recur_item_find_occurrence(item_start, item_dur, item_exc, return recur_item_find_occurrence(start, dur, rpt, exc,
rpt_type, rpt_freq, rpt_until,
day_start, NULL); day_start, NULL);
} }
unsigned recur_apoint_inday(struct recur_apoint *rapt, time_t *day_start) unsigned recur_apoint_inday(struct recur_apoint *rapt, time_t *day_start)
{ {
return recur_item_inday(rapt->start, rapt->dur, &rapt->exc, return recur_item_inday(rapt->start, rapt->dur, rapt->rpt, &rapt->exc,
rapt->rpt->type, rapt->rpt->freq, *day_start);
rapt->rpt->until, *day_start);
} }
unsigned recur_event_inday(struct recur_event *rev, time_t *day_start) unsigned recur_event_inday(struct recur_event *rev, time_t *day_start)
{ {
return recur_item_inday(rev->day, -1, &rev->exc, return recur_item_inday(rev->day, -1, rev->rpt, &rev->exc,
rev->rpt->type, rev->rpt->freq, *day_start);
rev->rpt->until, *day_start);
} }
/* Add an exception to a recurrent event. */ /* Add an exception to a recurrent event. */