ical.c: Reduce nesting depth
Refactor the iCal parser to reduce nesting depth. Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
This commit is contained in:
parent
52779d2ec6
commit
329ef1c22a
587
src/ical.c
587
src/ical.c
@ -569,45 +569,39 @@ static long ical_durtime2long(char *timestr)
|
|||||||
*/
|
*/
|
||||||
static long ical_dur2long(char *durstr)
|
static long ical_dur2long(char *durstr)
|
||||||
{
|
{
|
||||||
const int NOTFOUND = -1;
|
|
||||||
long durlong;
|
|
||||||
char *p;
|
char *p;
|
||||||
struct {
|
struct {
|
||||||
unsigned week, day;
|
unsigned week, day;
|
||||||
} date;
|
} date;
|
||||||
|
|
||||||
memset(&date, 0, sizeof date);
|
memset(&date, 0, sizeof date);
|
||||||
if ((p = strchr(durstr, 'P')) == NULL) {
|
|
||||||
durlong = NOTFOUND;
|
|
||||||
} else {
|
|
||||||
p++;
|
|
||||||
if (*p == '-')
|
|
||||||
return NOTFOUND;
|
|
||||||
else if (*p == '+')
|
|
||||||
p++;
|
|
||||||
|
|
||||||
if (*p == 'T') { /* dur-time */
|
p = strchr(durstr, 'P');
|
||||||
durlong = ical_durtime2long(p);
|
if (!p)
|
||||||
} else if (strchr(p, 'W')) { /* dur-week */
|
return -1;
|
||||||
if (sscanf(p, "%u", &date.week) == 1)
|
p++;
|
||||||
durlong =
|
|
||||||
date.week * WEEKINDAYS * DAYINSEC;
|
if (*p == '-')
|
||||||
else
|
return -1;
|
||||||
durlong = NOTFOUND;
|
if (*p == '+')
|
||||||
} else {
|
p++;
|
||||||
if (strchr(p, 'D')) { /* dur-date */
|
|
||||||
if (sscanf(p, "%uD", &date.day) == 1) {
|
if (*p == 'T') {
|
||||||
durlong = date.day * DAYINSEC;
|
/* dur-time */
|
||||||
durlong += ical_durtime2long(p);
|
return ical_durtime2long(p);
|
||||||
} else {
|
} else if (strchr(p, 'W')) {
|
||||||
durlong = NOTFOUND;
|
/* dur-week */
|
||||||
}
|
if (sscanf(p, "%u", &date.week) == 1)
|
||||||
} else {
|
return date.week * WEEKINDAYS * DAYINSEC;
|
||||||
durlong = NOTFOUND;
|
} else if (strchr(p, 'D')) {
|
||||||
}
|
/* dur-date */
|
||||||
|
if (sscanf(p, "%uD", &date.day) == 1) {
|
||||||
|
return date.day * DAYINSEC +
|
||||||
|
ical_durtime2long(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return durlong;
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -620,35 +614,20 @@ static long ical_dur2long(char *durstr)
|
|||||||
*/
|
*/
|
||||||
static long ical_compute_rpt_until(long start, ical_rpt_t * rpt)
|
static long ical_compute_rpt_until(long start, ical_rpt_t * rpt)
|
||||||
{
|
{
|
||||||
long until;
|
|
||||||
|
|
||||||
switch (rpt->type) {
|
switch (rpt->type) {
|
||||||
case RECUR_DAILY:
|
case RECUR_DAILY:
|
||||||
until =
|
return date_sec_change(start, 0, rpt->freq * (rpt->count - 1));
|
||||||
date_sec_change(start, 0,
|
|
||||||
rpt->freq * (rpt->count - 1));
|
|
||||||
break;
|
|
||||||
case RECUR_WEEKLY:
|
case RECUR_WEEKLY:
|
||||||
until = date_sec_change(start, 0,
|
return date_sec_change(start, 0,
|
||||||
rpt->freq * WEEKINDAYS *
|
rpt->freq * WEEKINDAYS * (rpt->count - 1));
|
||||||
(rpt->count - 1));
|
|
||||||
break;
|
|
||||||
case RECUR_MONTHLY:
|
case RECUR_MONTHLY:
|
||||||
until =
|
return date_sec_change(start, rpt->freq * (rpt->count - 1), 0);
|
||||||
date_sec_change(start, rpt->freq * (rpt->count - 1),
|
|
||||||
0);
|
|
||||||
break;
|
|
||||||
case RECUR_YEARLY:
|
case RECUR_YEARLY:
|
||||||
until =
|
return date_sec_change(start,
|
||||||
date_sec_change(start,
|
|
||||||
rpt->freq * 12 * (rpt->count - 1), 0);
|
rpt->freq * 12 * (rpt->count - 1), 0);
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
until = 0;
|
return 0;
|
||||||
break;
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
}
|
||||||
return until;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -693,99 +672,89 @@ static ical_rpt_t *ical_read_rrule(FILE * log, char *rrulestr,
|
|||||||
{
|
{
|
||||||
const char count[] = "COUNT=";
|
const char count[] = "COUNT=";
|
||||||
const char interv[] = "INTERVAL=";
|
const char interv[] = "INTERVAL=";
|
||||||
|
char freqstr[BUFSIZ];
|
||||||
unsigned interval;
|
unsigned interval;
|
||||||
ical_rpt_t *rpt;
|
ical_rpt_t *rpt;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
rpt = NULL;
|
p = strchr(rrulestr, ':');
|
||||||
if ((p = strchr(rrulestr, ':')) != NULL) {
|
if (!p) {
|
||||||
char freqstr[BUFSIZ];
|
|
||||||
|
|
||||||
p++;
|
|
||||||
rpt = mem_malloc(sizeof(ical_rpt_t));
|
|
||||||
memset(rpt, 0, sizeof(ical_rpt_t));
|
|
||||||
if (sscanf(p, "FREQ=%s", freqstr) != 1) {
|
|
||||||
ical_log(log, ICAL_VEVENT, itemline,
|
|
||||||
_("recurrence frequence not found."));
|
|
||||||
(*noskipped)++;
|
|
||||||
mem_free(rpt);
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
if (starts_with(freqstr, "DAILY")) {
|
|
||||||
rpt->type = RECUR_DAILY;
|
|
||||||
} else if (starts_with(freqstr, "WEEKLY")) {
|
|
||||||
rpt->type = RECUR_WEEKLY;
|
|
||||||
} else if (starts_with(freqstr, "MONTHLY")) {
|
|
||||||
rpt->type = RECUR_MONTHLY;
|
|
||||||
} else if (starts_with(freqstr, "YEARLY")) {
|
|
||||||
rpt->type = RECUR_YEARLY;
|
|
||||||
} else {
|
|
||||||
ical_log(log, ICAL_VEVENT, itemline,
|
|
||||||
_("recurrence frequence not recognized."));
|
|
||||||
(*noskipped)++;
|
|
||||||
mem_free(rpt);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
The UNTIL rule part defines a date-time value which bounds the
|
|
||||||
recurrence rule in an inclusive manner. If not present, and the
|
|
||||||
COUNT rule part is also not present, the RRULE is considered to
|
|
||||||
repeat forever.
|
|
||||||
|
|
||||||
The COUNT rule part defines the number of occurrences at which to
|
|
||||||
range-bound the recurrence. The "DTSTART" property value, if
|
|
||||||
specified, counts as the first occurrence.
|
|
||||||
*/
|
|
||||||
if ((p = strstr(rrulestr, "UNTIL")) != NULL) {
|
|
||||||
char *untilstr;
|
|
||||||
|
|
||||||
untilstr = strchr(p, '=');
|
|
||||||
rpt->until = ical_datetime2long(++untilstr, NULL);
|
|
||||||
} else {
|
|
||||||
unsigned cnt;
|
|
||||||
char *countstr;
|
|
||||||
|
|
||||||
if ((countstr = strstr(rrulestr, count)) != NULL) {
|
|
||||||
countstr += sizeof(count) - 1;
|
|
||||||
if (sscanf(countstr, "%u", &cnt) != 1) {
|
|
||||||
rpt->until = 0;
|
|
||||||
/* endless repetition */
|
|
||||||
} else {
|
|
||||||
rpt->count = cnt;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rpt->until = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((p = strstr(rrulestr, interv)) != NULL) {
|
|
||||||
p += sizeof(interv) - 1;
|
|
||||||
if (sscanf(p, "%u", &interval) != 1) {
|
|
||||||
rpt->freq = 1;
|
|
||||||
/* default frequence if none specified */
|
|
||||||
} else {
|
|
||||||
rpt->freq = interval;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rpt->freq = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ical_log(log, ICAL_VEVENT, itemline,
|
ical_log(log, ICAL_VEVENT, itemline,
|
||||||
_("recurrence rule malformed."));
|
_("recurrence rule malformed."));
|
||||||
(*noskipped)++;
|
(*noskipped)++;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
p++;
|
||||||
|
|
||||||
|
rpt = mem_malloc(sizeof(ical_rpt_t));
|
||||||
|
memset(rpt, 0, sizeof(ical_rpt_t));
|
||||||
|
if (sscanf(p, "FREQ=%s", freqstr) != 1) {
|
||||||
|
ical_log(log, ICAL_VEVENT, itemline,
|
||||||
|
_("recurrence frequence not found."));
|
||||||
|
(*noskipped)++;
|
||||||
|
mem_free(rpt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (starts_with(freqstr, "DAILY")) {
|
||||||
|
rpt->type = RECUR_DAILY;
|
||||||
|
} else if (starts_with(freqstr, "WEEKLY")) {
|
||||||
|
rpt->type = RECUR_WEEKLY;
|
||||||
|
} else if (starts_with(freqstr, "MONTHLY")) {
|
||||||
|
rpt->type = RECUR_MONTHLY;
|
||||||
|
} else if (starts_with(freqstr, "YEARLY")) {
|
||||||
|
rpt->type = RECUR_YEARLY;
|
||||||
|
} else {
|
||||||
|
ical_log(log, ICAL_VEVENT, itemline,
|
||||||
|
_("recurrence frequence not recognized."));
|
||||||
|
(*noskipped)++;
|
||||||
|
mem_free(rpt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The UNTIL rule part defines a date-time value which bounds the
|
||||||
|
* recurrence rule in an inclusive manner. If not present, and the
|
||||||
|
* COUNT rule part is also not present, the RRULE is considered to
|
||||||
|
* repeat forever.
|
||||||
|
|
||||||
|
* The COUNT rule part defines the number of occurrences at which to
|
||||||
|
* range-bound the recurrence. The "DTSTART" property value, if
|
||||||
|
* specified, counts as the first occurrence.
|
||||||
|
*/
|
||||||
|
if ((p = strstr(rrulestr, "UNTIL")) != NULL) {
|
||||||
|
rpt->until = ical_datetime2long(strchr(p, '=') + 1, NULL);
|
||||||
|
} else {
|
||||||
|
unsigned cnt;
|
||||||
|
char *countstr;
|
||||||
|
|
||||||
|
rpt->until = 0;
|
||||||
|
if ((countstr = strstr(rrulestr, count))) {
|
||||||
|
countstr += sizeof(count) - 1;
|
||||||
|
if (sscanf(countstr, "%u", &cnt) == 1)
|
||||||
|
rpt->count = cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rpt->freq = 1;
|
||||||
|
if ((p = strstr(rrulestr, interv))) {
|
||||||
|
p += sizeof(interv) - 1;
|
||||||
|
if (sscanf(p, "%u", &interval) == 1)
|
||||||
|
rpt->freq = interval;
|
||||||
|
}
|
||||||
|
|
||||||
return rpt;
|
return rpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ical_add_exc(llist_t * exc_head, long date)
|
static void ical_add_exc(llist_t * exc_head, long date)
|
||||||
{
|
{
|
||||||
if (date != 0) {
|
if (date == 0)
|
||||||
struct excp *exc = mem_malloc(sizeof(struct excp));
|
return;
|
||||||
exc->st = date;
|
|
||||||
|
|
||||||
LLIST_ADD(exc_head, exc);
|
struct excp *exc = mem_malloc(sizeof(struct excp));
|
||||||
}
|
exc->st = date;
|
||||||
|
|
||||||
|
LLIST_ADD(exc_head, exc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -799,25 +768,27 @@ ical_read_exdate(llist_t * exc, FILE * log, char *exstr,
|
|||||||
char *p, *q;
|
char *p, *q;
|
||||||
long date;
|
long date;
|
||||||
|
|
||||||
if ((p = strchr(exstr, ':')) != NULL) {
|
p = strchr(exstr, ':');
|
||||||
p++;
|
if (!p) {
|
||||||
while ((q = strchr(p, ',')) != NULL) {
|
|
||||||
char buf[BUFSIZ];
|
|
||||||
const int buflen = q - p;
|
|
||||||
|
|
||||||
strncpy(buf, p, buflen);
|
|
||||||
buf[buflen] = '\0';
|
|
||||||
date = ical_datetime2long(buf, NULL);
|
|
||||||
ical_add_exc(exc, date);
|
|
||||||
p = ++q;
|
|
||||||
}
|
|
||||||
date = ical_datetime2long(p, NULL);
|
|
||||||
ical_add_exc(exc, date);
|
|
||||||
} else {
|
|
||||||
ical_log(log, ICAL_VEVENT, itemline,
|
ical_log(log, ICAL_VEVENT, itemline,
|
||||||
_("recurrence exception dates malformed."));
|
_("recurrence exception dates malformed."));
|
||||||
(*noskipped)++;
|
(*noskipped)++;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
p++;
|
||||||
|
|
||||||
|
while ((q = strchr(p, ',')) != NULL) {
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
const int buflen = q - p;
|
||||||
|
|
||||||
|
strncpy(buf, p, buflen);
|
||||||
|
buf[buflen] = '\0';
|
||||||
|
date = ical_datetime2long(buf, NULL);
|
||||||
|
ical_add_exc(exc, date);
|
||||||
|
p = ++q;
|
||||||
|
}
|
||||||
|
date = ical_datetime2long(p, NULL);
|
||||||
|
ical_add_exc(exc, date);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return an allocated string containing the name of the newly created note. */
|
/* Return an allocated string containing the name of the newly created note. */
|
||||||
@ -827,28 +798,29 @@ static char *ical_read_note(char *line, unsigned *noskipped,
|
|||||||
{
|
{
|
||||||
char *p, *notestr, *note;
|
char *p, *notestr, *note;
|
||||||
|
|
||||||
if ((p = strchr(line, ':')) != NULL) {
|
p = strchr(line, ':');
|
||||||
p++;
|
if (!p) {
|
||||||
notestr = ical_unformat_line(p);
|
|
||||||
if (notestr == NULL) {
|
|
||||||
ical_log(log, item_type, itemline,
|
|
||||||
_("could not get entire item description."));
|
|
||||||
(*noskipped)++;
|
|
||||||
return NULL;
|
|
||||||
} else if (strlen(notestr) == 0) {
|
|
||||||
mem_free(notestr);
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
note = generate_note(notestr);
|
|
||||||
mem_free(notestr);
|
|
||||||
return note;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ical_log(log, item_type, itemline,
|
ical_log(log, item_type, itemline,
|
||||||
_("description malformed."));
|
_("description malformed."));
|
||||||
(*noskipped)++;
|
(*noskipped)++;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
p++;
|
||||||
|
|
||||||
|
notestr = ical_unformat_line(p);
|
||||||
|
if (notestr == NULL) {
|
||||||
|
ical_log(log, item_type, itemline,
|
||||||
|
_("could not get entire item description."));
|
||||||
|
(*noskipped)++;
|
||||||
|
return NULL;
|
||||||
|
} else if (strlen(notestr) == 0) {
|
||||||
|
mem_free(notestr);
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
note = generate_note(notestr);
|
||||||
|
mem_free(notestr);
|
||||||
|
return note;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns an allocated string containing the ical item summary. */
|
/* Returns an allocated string containing the ical item summary. */
|
||||||
@ -902,147 +874,119 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
|
|||||||
skip_alarm = 0;
|
skip_alarm = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (starts_with_ci(buf, "END:VEVENT")) {
|
|
||||||
if (vevent.mesg) {
|
|
||||||
if (vevent.rpt && vevent.rpt->count)
|
|
||||||
vevent.rpt->until =
|
|
||||||
ical_compute_rpt_until(vevent.
|
|
||||||
start,
|
|
||||||
vevent.
|
|
||||||
rpt);
|
|
||||||
|
|
||||||
switch (vevent_type) {
|
if (starts_with_ci(buf, "END:VEVENT")) {
|
||||||
case APPOINTMENT:
|
if (!vevent.mesg) {
|
||||||
if (vevent.start == 0) {
|
|
||||||
ical_log(log, ICAL_VEVENT,
|
|
||||||
ITEMLINE,
|
|
||||||
_("appointment has no start time."));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (vevent.dur == 0) {
|
|
||||||
if (vevent.end == 0) {
|
|
||||||
ical_log(log,
|
|
||||||
ICAL_VEVENT,
|
|
||||||
ITEMLINE,
|
|
||||||
_("could not compute duration "
|
|
||||||
"(no end time)."));
|
|
||||||
goto cleanup;
|
|
||||||
} else if (vevent.start ==
|
|
||||||
vevent.end) {
|
|
||||||
vevent_type =
|
|
||||||
EVENT;
|
|
||||||
vevent.end = 0L;
|
|
||||||
ical_store_event
|
|
||||||
(vevent.mesg,
|
|
||||||
vevent.note,
|
|
||||||
vevent.start,
|
|
||||||
vevent.end,
|
|
||||||
vevent.rpt,
|
|
||||||
&vevent.exc);
|
|
||||||
(*noevents)++;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
vevent.dur =
|
|
||||||
vevent.end -
|
|
||||||
vevent.start;
|
|
||||||
if (vevent.dur < 0) {
|
|
||||||
ical_log
|
|
||||||
(log,
|
|
||||||
ICAL_VEVENT,
|
|
||||||
ITEMLINE,
|
|
||||||
_("item has a negative duration."));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ical_store_apoint(vevent.mesg,
|
|
||||||
vevent.note,
|
|
||||||
vevent.start,
|
|
||||||
vevent.dur,
|
|
||||||
vevent.rpt,
|
|
||||||
&vevent.exc,
|
|
||||||
vevent.
|
|
||||||
has_alarm);
|
|
||||||
(*noapoints)++;
|
|
||||||
break;
|
|
||||||
case EVENT:
|
|
||||||
if (vevent.start == 0) {
|
|
||||||
ical_log(log, ICAL_VEVENT,
|
|
||||||
ITEMLINE,
|
|
||||||
_("event date is not defined."));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
ical_store_event(vevent.mesg,
|
|
||||||
vevent.note,
|
|
||||||
vevent.start,
|
|
||||||
vevent.end,
|
|
||||||
vevent.rpt,
|
|
||||||
&vevent.exc);
|
|
||||||
(*noevents)++;
|
|
||||||
break;
|
|
||||||
case UNDEFINED:
|
|
||||||
ical_log(log, ICAL_VEVENT,
|
|
||||||
ITEMLINE,
|
|
||||||
_("item could not be identified."));
|
|
||||||
goto cleanup;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
_("could not retrieve item summary."));
|
_("could not retrieve item summary."));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
return;
|
if (vevent.start == 0) {
|
||||||
} else {
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
if (starts_with_ci(buf, "DTSTART")) {
|
_("item start date is not defined."));
|
||||||
if ((p = strchr(buf, ':')) != NULL)
|
goto cleanup;
|
||||||
vevent.start =
|
|
||||||
ical_datetime2long(++p,
|
|
||||||
&vevent_type);
|
|
||||||
if (!vevent.start) {
|
|
||||||
ical_log(log, ICAL_VEVENT,
|
|
||||||
ITEMLINE,
|
|
||||||
_("could not retrieve event start time."));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
} else if (starts_with_ci(buf, "DTEND")) {
|
|
||||||
if ((p = strchr(buf, ':')) != NULL)
|
|
||||||
vevent.end =
|
|
||||||
ical_datetime2long(++p,
|
|
||||||
&vevent_type);
|
|
||||||
if (!vevent.end) {
|
|
||||||
ical_log(log, ICAL_VEVENT,
|
|
||||||
ITEMLINE,
|
|
||||||
_("could not retrieve event end time."));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
} else if (starts_with_ci(buf, "DURATION")) {
|
|
||||||
if ((vevent.dur = ical_dur2long(buf)) <= 0) {
|
|
||||||
ical_log(log, ICAL_VEVENT,
|
|
||||||
ITEMLINE,
|
|
||||||
_("item duration malformed."));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
} else if (starts_with_ci(buf, "RRULE")) {
|
|
||||||
vevent.rpt =
|
|
||||||
ical_read_rrule(log, buf, noskipped,
|
|
||||||
ITEMLINE);
|
|
||||||
} else if (starts_with_ci(buf, "EXDATE")) {
|
|
||||||
ical_read_exdate(&vevent.exc, log, buf,
|
|
||||||
noskipped, ITEMLINE);
|
|
||||||
} else if (starts_with_ci(buf, "SUMMARY")) {
|
|
||||||
vevent.mesg = ical_read_summary(buf);
|
|
||||||
} else if (starts_with_ci(buf, "BEGIN:VALARM")) {
|
|
||||||
skip_alarm = 1;
|
|
||||||
vevent.has_alarm = 1;
|
|
||||||
} else if (starts_with_ci(buf, "DESCRIPTION")) {
|
|
||||||
vevent.note =
|
|
||||||
ical_read_note(buf, noskipped,
|
|
||||||
ICAL_VEVENT, ITEMLINE,
|
|
||||||
log);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vevent_type == APPOINTMENT && vevent.dur == 0) {
|
||||||
|
if (vevent.end == 0) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("could not compute duration "
|
||||||
|
"(no end time)."));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
vevent.dur = vevent.end - vevent.start;
|
||||||
|
if (vevent.dur == 0) {
|
||||||
|
vevent_type = EVENT;
|
||||||
|
vevent.end = 0L;
|
||||||
|
} else if (vevent.dur < 0) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("item has a negative duration."));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vevent.rpt && vevent.rpt->count) {
|
||||||
|
vevent.rpt->until =
|
||||||
|
ical_compute_rpt_until(vevent.start,
|
||||||
|
vevent.rpt);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (vevent_type) {
|
||||||
|
case APPOINTMENT:
|
||||||
|
ical_store_apoint(vevent.mesg, vevent.note,
|
||||||
|
vevent.start, vevent.dur,
|
||||||
|
vevent.rpt, &vevent.exc,
|
||||||
|
vevent.has_alarm);
|
||||||
|
(*noapoints)++;
|
||||||
|
break;
|
||||||
|
case EVENT:
|
||||||
|
ical_store_event(vevent.mesg, vevent.note,
|
||||||
|
vevent.start, vevent.end,
|
||||||
|
vevent.rpt, &vevent.exc);
|
||||||
|
(*noevents)++;
|
||||||
|
break;
|
||||||
|
case UNDEFINED:
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("item could not be identified."));
|
||||||
|
goto cleanup;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (starts_with_ci(buf, "DTSTART")) {
|
||||||
|
p = strchr(buf, ':');
|
||||||
|
if (!p) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("event start time malformed."));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
vevent.start = ical_datetime2long(++p, &vevent_type);
|
||||||
|
if (!vevent.start) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("could not retrieve event start time."));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
} else if (starts_with_ci(buf, "DTEND")) {
|
||||||
|
p = strchr(buf, ':');
|
||||||
|
if (!p) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("event end time malformed."));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
vevent.end = ical_datetime2long(++p, &vevent_type);
|
||||||
|
if (!vevent.end) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("could not retrieve event end time."));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
} else if (starts_with_ci(buf, "DURATION")) {
|
||||||
|
vevent.dur = ical_dur2long(buf);
|
||||||
|
if (vevent.dur <= 0) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("item duration malformed."));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
} else if (starts_with_ci(buf, "RRULE")) {
|
||||||
|
vevent.rpt = ical_read_rrule(log, buf, noskipped,
|
||||||
|
ITEMLINE);
|
||||||
|
} else if (starts_with_ci(buf, "EXDATE")) {
|
||||||
|
ical_read_exdate(&vevent.exc, log, buf, noskipped,
|
||||||
|
ITEMLINE);
|
||||||
|
} else if (starts_with_ci(buf, "SUMMARY")) {
|
||||||
|
vevent.mesg = ical_read_summary(buf);
|
||||||
|
} else if (starts_with_ci(buf, "BEGIN:VALARM")) {
|
||||||
|
skip_alarm = vevent.has_alarm = 1;
|
||||||
|
} else if (starts_with_ci(buf, "DESCRIPTION")) {
|
||||||
|
vevent.note = ical_read_note(buf, noskipped,
|
||||||
|
ICAL_VEVENT, ITEMLINE, log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
_("The ical file seems to be malformed. "
|
_("The ical file seems to be malformed. "
|
||||||
"The end of item was not found."));
|
"The end of item was not found."));
|
||||||
@ -1084,51 +1028,46 @@ ical_read_todo(FILE * fdi, FILE * log, unsigned *notodos,
|
|||||||
skip_alarm = 0;
|
skip_alarm = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (starts_with_ci(buf, "END:VTODO")) {
|
if (starts_with_ci(buf, "END:VTODO")) {
|
||||||
if (!vtodo.has_priority)
|
if (!vtodo.has_priority)
|
||||||
vtodo.priority = LOWEST;
|
vtodo.priority = LOWEST;
|
||||||
if (vtodo.mesg) {
|
if (!vtodo.mesg) {
|
||||||
ical_store_todo(vtodo.priority, vtodo.mesg,
|
|
||||||
vtodo.note);
|
|
||||||
(*notodos)++;
|
|
||||||
} else {
|
|
||||||
ical_log(log, ICAL_VTODO, ITEMLINE,
|
ical_log(log, ICAL_VTODO, ITEMLINE,
|
||||||
_("could not retrieve item summary."));
|
_("could not retrieve item summary."));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
int tmpint;
|
|
||||||
|
|
||||||
if (starts_with_ci(buf, "PRIORITY:")) {
|
ical_store_todo(vtodo.priority, vtodo.mesg,
|
||||||
sscanf(buf, "%d", &tmpint);
|
vtodo.note);
|
||||||
if (tmpint <= 9 && tmpint >= 1) {
|
(*notodos)++;
|
||||||
vtodo.priority = tmpint;
|
return;
|
||||||
vtodo.has_priority = 1;
|
}
|
||||||
} else {
|
|
||||||
ical_log(log, ICAL_VTODO, ITEMLINE,
|
if (starts_with_ci(buf, "PRIORITY:")) {
|
||||||
_("item priority is not acceptable "
|
sscanf(buf, "%d", &vtodo.priority);
|
||||||
"(must be between 1 and 9)."));
|
if (vtodo.priority >= 1 && vtodo.priority <= 9) {
|
||||||
vtodo.priority = LOWEST;
|
vtodo.has_priority = 1;
|
||||||
}
|
} else {
|
||||||
} else if (starts_with_ci(buf, "SUMMARY")) {
|
ical_log(log, ICAL_VTODO, ITEMLINE,
|
||||||
vtodo.mesg = ical_read_summary(buf);
|
_("item priority is not acceptable "
|
||||||
} else if (starts_with_ci(buf, "BEGIN:VALARM")) {
|
"(must be between 1 and 9)."));
|
||||||
skip_alarm = 1;
|
|
||||||
} else if (starts_with_ci(buf, "DESCRIPTION")) {
|
|
||||||
vtodo.note =
|
|
||||||
ical_read_note(buf, noskipped,
|
|
||||||
ICAL_VTODO, ITEMLINE,
|
|
||||||
log);
|
|
||||||
}
|
}
|
||||||
|
} else if (starts_with_ci(buf, "SUMMARY")) {
|
||||||
|
vtodo.mesg = ical_read_summary(buf);
|
||||||
|
} else if (starts_with_ci(buf, "BEGIN:VALARM")) {
|
||||||
|
skip_alarm = 1;
|
||||||
|
} else if (starts_with_ci(buf, "DESCRIPTION")) {
|
||||||
|
vtodo.note = ical_read_note(buf, noskipped, ICAL_VTODO,
|
||||||
|
ITEMLINE, log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ical_log(log, ICAL_VTODO, ITEMLINE,
|
ical_log(log, ICAL_VTODO, ITEMLINE,
|
||||||
_("The ical file seems to be malformed. "
|
_("The ical file seems to be malformed. "
|
||||||
"The end of item was not found."));
|
"The end of item was not found."));
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
||||||
if (vtodo.note)
|
if (vtodo.note)
|
||||||
mem_free(vtodo.note);
|
mem_free(vtodo.note);
|
||||||
if (vtodo.mesg)
|
if (vtodo.mesg)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user