Make iCal event import independent of property ordering
Refactoring of ical.c: properties DTSTART, DTEND, DURATION, RRULE and EXDATE are saved and only processed after encountering END:VEVENT. Adresses Github issue #323, follow-up question. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
This commit is contained in:
parent
1e243dba90
commit
d126696999
257
src/ical.c
257
src/ical.c
@ -1218,11 +1218,6 @@ ical_read_exdate(llist_t * exc, FILE * log, char *exstr, unsigned *noskipped,
|
|||||||
time_t t;
|
time_t t;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (type == UNDEFINED) {
|
|
||||||
ical_log(log, ICAL_VEVENT, itemline,
|
|
||||||
_("need DTSTART to determine event type."));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (type != ical_get_type(exstr)) {
|
if (type != ical_get_type(exstr)) {
|
||||||
ical_log(log, ICAL_VEVENT, itemline,
|
ical_log(log, ICAL_VEVENT, itemline,
|
||||||
_("invalid exception date value type."));
|
_("invalid exception date value type."));
|
||||||
@ -1346,8 +1341,9 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
|
|||||||
const int ITEMLINE = *lineno - !feof(fdi);
|
const int ITEMLINE = *lineno - !feof(fdi);
|
||||||
ical_vevent_e vevent_type;
|
ical_vevent_e vevent_type;
|
||||||
ical_property_e property;
|
ical_property_e property;
|
||||||
char *p, *note = NULL, *tmp, *tzid;
|
char *p, *note, *tzid;
|
||||||
struct string s;
|
char *dtstart, *dtend, *duration, *rrule;
|
||||||
|
struct string s, exdate;
|
||||||
struct {
|
struct {
|
||||||
llist_t exc;
|
llist_t exc;
|
||||||
struct rpt *rpt;
|
struct rpt *rpt;
|
||||||
@ -1357,12 +1353,13 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
|
|||||||
long dur;
|
long dur;
|
||||||
int has_alarm;
|
int has_alarm;
|
||||||
} vevent;
|
} vevent;
|
||||||
int skip_alarm, has_note, separator;
|
int skip_alarm, has_note, separator, has_exdate;
|
||||||
|
|
||||||
vevent_type = UNDEFINED;
|
vevent_type = UNDEFINED;
|
||||||
memset(&vevent, 0, sizeof vevent);
|
memset(&vevent, 0, sizeof vevent);
|
||||||
LLIST_INIT(&vevent.exc);
|
LLIST_INIT(&vevent.exc);
|
||||||
skip_alarm = has_note = separator = 0;
|
note = dtstart = dtend = duration = rrule = NULL;
|
||||||
|
skip_alarm = has_note = separator = has_exdate =0;
|
||||||
while (ical_readline(fdi, buf, lstore, lineno)) {
|
while (ical_readline(fdi, buf, lstore, lineno)) {
|
||||||
note = NULL;
|
note = NULL;
|
||||||
property = NO_PROPERTY;
|
property = NO_PROPERTY;
|
||||||
@ -1376,16 +1373,108 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (starts_with_ci(buf, "END:VEVENT")) {
|
if (starts_with_ci(buf, "END:VEVENT")) {
|
||||||
if (!vevent.mesg) {
|
/* DTSTART and related properties (picked up earlier). */
|
||||||
|
if (!dtstart) {
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
_("could not retrieve item summary."));
|
_("item start date not defined."));
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
if (vevent.start == 0) {
|
vevent_type = ical_get_type(dtstart);
|
||||||
|
if ((tzid = ical_get_tzid(dtstart)) &&
|
||||||
|
vevent_type == APPOINTMENT) {
|
||||||
|
if (vevent.imp) {
|
||||||
|
asprintf(&p, "%s, TZID=%s",
|
||||||
|
vevent.imp, tzid);
|
||||||
|
mem_free(vevent.imp);
|
||||||
|
vevent.imp = p;
|
||||||
|
} else
|
||||||
|
asprintf(&vevent.imp, "TZID=%s", tzid);
|
||||||
|
has_note = separator = 1;
|
||||||
|
}
|
||||||
|
p = ical_get_value(dtstart);
|
||||||
|
if (!p) {
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
_("item start date is not defined."));
|
_("malformed start time line."));
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
vevent.start = ical_datetime2time_t(p, tzid, vevent_type);
|
||||||
|
if (tzid)
|
||||||
|
mem_free(tzid);
|
||||||
|
if (!vevent.start) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("invalid or malformed event "
|
||||||
|
"start time."));
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
/* DTEND */
|
||||||
|
if (!dtend)
|
||||||
|
goto duration;
|
||||||
|
if (vevent_type != ical_get_type(dtend)) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("invalid end time value type."));
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
tzid = ical_get_tzid(dtend);
|
||||||
|
p = ical_get_value(dtend);
|
||||||
|
if (!p) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("malformed end time line."));
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
vevent.end = ical_datetime2time_t(p, tzid, vevent_type);
|
||||||
|
if (tzid)
|
||||||
|
mem_free(tzid);
|
||||||
|
if (!vevent.end) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("malformed event end time."));
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
if (vevent.end <= vevent.start) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("end must be later than start."));
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
duration:
|
||||||
|
if (!duration)
|
||||||
|
goto rrule;
|
||||||
|
if (vevent.end) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("either end or duration."));
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
p = ical_get_value(duration);
|
||||||
|
if (!p) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("malformed duration line."));
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
vevent.dur = ical_dur2long(p, vevent_type);
|
||||||
|
if (!vevent.dur) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("invalid duration."));
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
rrule:
|
||||||
|
if (!rrule)
|
||||||
|
goto exdate;
|
||||||
|
vevent.rpt = ical_read_rrule(log, rrule, noskipped,
|
||||||
|
ITEMLINE, vevent_type, vevent.start,
|
||||||
|
&vevent.count);
|
||||||
|
if (!vevent.rpt)
|
||||||
|
goto cleanup;
|
||||||
|
exdate:
|
||||||
|
if (!has_exdate)
|
||||||
|
goto duration_end;
|
||||||
|
if (!rrule) {
|
||||||
|
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
||||||
|
_("exception date, but no recurrence "
|
||||||
|
"rule."));
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
if (!ical_read_exdate(&vevent.exc, log, exdate.buf,
|
||||||
|
noskipped, ITEMLINE, vevent_type))
|
||||||
|
goto cleanup;
|
||||||
|
duration_end:
|
||||||
/* An APPOINTMENT must always have a duration. */
|
/* An APPOINTMENT must always have a duration. */
|
||||||
if (vevent_type == APPOINTMENT && !vevent.dur) {
|
if (vevent_type == APPOINTMENT && !vevent.dur) {
|
||||||
vevent.dur = vevent.end ?
|
vevent.dur = vevent.end ?
|
||||||
@ -1402,10 +1491,10 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
|
|||||||
char *md = _("multi-day event changed "
|
char *md = _("multi-day event changed "
|
||||||
"to one-day event");
|
"to one-day event");
|
||||||
if (vevent.imp) {
|
if (vevent.imp) {
|
||||||
asprintf(&tmp, "%s, %s",
|
asprintf(&p, "%s, %s",
|
||||||
vevent.imp, md);
|
vevent.imp, md);
|
||||||
mem_free(vevent.imp);
|
mem_free(vevent.imp);
|
||||||
vevent.imp = tmp;
|
vevent.imp = p;
|
||||||
} else
|
} else
|
||||||
asprintf(&vevent.imp, "%s", md);
|
asprintf(&vevent.imp, "%s", md);
|
||||||
has_note = separator = 1;
|
has_note = separator = 1;
|
||||||
@ -1494,115 +1583,28 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
|
|||||||
}
|
}
|
||||||
if (starts_with_ci(buf, "DTSTART")) {
|
if (starts_with_ci(buf, "DTSTART")) {
|
||||||
/*
|
/*
|
||||||
* DTSTART has a value type: either DATE-TIME (by
|
* DTSTART has a value type: either DATE-TIME or DATE.
|
||||||
* default) or DATE. Properties DTEND, DURATION and
|
|
||||||
* EXDATE and rrule part UNTIL must agree.
|
|
||||||
* Assume that DTSTART comes before the others even
|
|
||||||
* though RFC 5545 allows any order.
|
|
||||||
* In calcurse DATE-TIME implies an appointment, DATE an
|
* In calcurse DATE-TIME implies an appointment, DATE an
|
||||||
* event.
|
* event.
|
||||||
|
* Properties DTEND, DURATION and EXDATE and rrule part
|
||||||
|
* UNTIL must match the DTSTART value type.
|
||||||
*/
|
*/
|
||||||
vevent_type = ical_get_type(buf);
|
asprintf(&dtstart, "%s", buf);
|
||||||
if ((tzid = ical_get_tzid(buf)) &&
|
|
||||||
vevent_type == APPOINTMENT) {
|
|
||||||
/* Add note on TZID. */
|
|
||||||
if (vevent.imp) {
|
|
||||||
asprintf(&tmp, "%s, TZID=%s",
|
|
||||||
vevent.imp, tzid);
|
|
||||||
mem_free(vevent.imp);
|
|
||||||
vevent.imp = tmp;
|
|
||||||
} else
|
|
||||||
asprintf(&vevent.imp, "TZID=%s", tzid);
|
|
||||||
has_note = separator = 1;
|
|
||||||
}
|
|
||||||
p = ical_get_value(buf);
|
|
||||||
if (!p) {
|
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
|
||||||
_("malformed start time line."));
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
vevent.start = ical_datetime2time_t(p, tzid, vevent_type);
|
|
||||||
if (tzid)
|
|
||||||
mem_free(tzid);
|
|
||||||
if (!vevent.start) {
|
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
|
||||||
_("invalid or malformed event "
|
|
||||||
"start time."));
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
} else if (starts_with_ci(buf, "DTEND")) {
|
} else if (starts_with_ci(buf, "DTEND")) {
|
||||||
if (vevent.dur) {
|
asprintf(&dtend, "%s", buf);
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
|
||||||
_("either end or duration."));
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
if (vevent_type == UNDEFINED) {
|
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
|
||||||
_("need DTSTART to determine "
|
|
||||||
"event type."));
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
if (vevent_type != ical_get_type(buf)) {
|
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
|
||||||
_("invalid end time value type."));
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
tzid = ical_get_tzid(buf);
|
|
||||||
p = ical_get_value(buf);
|
|
||||||
if (!p) {
|
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
|
||||||
_("malformed end time line."));
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
vevent.end = ical_datetime2time_t(p, tzid, vevent_type);
|
|
||||||
if (tzid)
|
|
||||||
mem_free(tzid);
|
|
||||||
if (!vevent.end) {
|
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
|
||||||
_("malformed event end time."));
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
if (vevent.end <= vevent.start) {
|
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
|
||||||
_("end must be later than start."));
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
} else if (starts_with_ci(buf, "DURATION")) {
|
} else if (starts_with_ci(buf, "DURATION")) {
|
||||||
if (vevent.end) {
|
asprintf(&duration, "%s", buf);
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
|
||||||
_("either end or duration."));
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
if (vevent_type == UNDEFINED) {
|
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
|
||||||
_("need DTSTART to determine "
|
|
||||||
"event type."));
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
p = ical_get_value(buf);
|
|
||||||
if (!p) {
|
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
|
||||||
_("malformed duration line."));
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
vevent.dur = ical_dur2long(p, vevent_type);
|
|
||||||
if (!vevent.dur) {
|
|
||||||
ical_log(log, ICAL_VEVENT, ITEMLINE,
|
|
||||||
_("invalid duration."));
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
} else if (starts_with_ci(buf, "RRULE")) {
|
} else if (starts_with_ci(buf, "RRULE")) {
|
||||||
vevent.rpt = ical_read_rrule(log, buf, noskipped,
|
asprintf(&rrule, "%s", buf);
|
||||||
ITEMLINE, vevent_type, vevent.start,
|
|
||||||
&vevent.count);
|
|
||||||
if (!vevent.rpt)
|
|
||||||
goto cleanup;
|
|
||||||
} else if (starts_with_ci(buf, "EXDATE")) {
|
} else if (starts_with_ci(buf, "EXDATE")) {
|
||||||
if (!ical_read_exdate(&vevent.exc, log, buf, noskipped,
|
if (!has_exdate) {
|
||||||
ITEMLINE, vevent_type))
|
has_exdate = 1;
|
||||||
goto cleanup;
|
string_init(&exdate);
|
||||||
|
string_catf(&exdate, "%s", buf);
|
||||||
|
} else {
|
||||||
|
p = ical_get_value(buf);
|
||||||
|
string_catf(&exdate, ",%s", p);
|
||||||
|
}
|
||||||
} else if (starts_with_ci(buf, "SUMMARY")) {
|
} else if (starts_with_ci(buf, "SUMMARY")) {
|
||||||
vevent.mesg = ical_read_summary(buf, noskipped,
|
vevent.mesg = ical_read_summary(buf, noskipped,
|
||||||
ICAL_VEVENT, ITEMLINE, log);
|
ICAL_VEVENT, ITEMLINE, log);
|
||||||
@ -1646,10 +1648,10 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
|
|||||||
case COMMENT:
|
case COMMENT:
|
||||||
/* There may be more than one. */
|
/* There may be more than one. */
|
||||||
if (vevent.comm) {
|
if (vevent.comm) {
|
||||||
asprintf(&tmp, "%sComment: %s",
|
asprintf(&p, "%sComment: %s",
|
||||||
vevent.comm, note);
|
vevent.comm, note);
|
||||||
mem_free(vevent.comm);
|
mem_free(vevent.comm);
|
||||||
vevent.comm = tmp;
|
vevent.comm = p;
|
||||||
} else
|
} else
|
||||||
vevent.comm = note;
|
vevent.comm = note;
|
||||||
break;
|
break;
|
||||||
@ -1663,6 +1665,16 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
|
|||||||
skip:
|
skip:
|
||||||
(*noskipped)++;
|
(*noskipped)++;
|
||||||
cleanup:
|
cleanup:
|
||||||
|
if (dtstart)
|
||||||
|
mem_free(dtstart);
|
||||||
|
if (dtend)
|
||||||
|
mem_free(dtend);
|
||||||
|
if (duration)
|
||||||
|
mem_free(duration);
|
||||||
|
if (rrule)
|
||||||
|
mem_free(rrule);
|
||||||
|
if (has_exdate)
|
||||||
|
mem_free(exdate.buf);
|
||||||
if (note)
|
if (note)
|
||||||
mem_free(note);
|
mem_free(note);
|
||||||
if (vevent.desc)
|
if (vevent.desc)
|
||||||
@ -1686,7 +1698,7 @@ ical_read_todo(FILE * fdi, FILE * log, unsigned *notodos, unsigned *noskipped,
|
|||||||
{
|
{
|
||||||
const int ITEMLINE = *lineno - !feof(fdi);
|
const int ITEMLINE = *lineno - !feof(fdi);
|
||||||
ical_property_e property;
|
ical_property_e property;
|
||||||
char *note = NULL, *tmp;
|
char *p, *note;
|
||||||
struct string s;
|
struct string s;
|
||||||
struct {
|
struct {
|
||||||
char *mesg, *desc, *loc, *comm, *note;
|
char *mesg, *desc, *loc, *comm, *note;
|
||||||
@ -1696,6 +1708,7 @@ ical_read_todo(FILE * fdi, FILE * log, unsigned *notodos, unsigned *noskipped,
|
|||||||
int skip_alarm, has_note, separator;
|
int skip_alarm, has_note, separator;
|
||||||
|
|
||||||
memset(&vtodo, 0, sizeof vtodo);
|
memset(&vtodo, 0, sizeof vtodo);
|
||||||
|
note = NULL;
|
||||||
skip_alarm = has_note = separator = 0;
|
skip_alarm = has_note = separator = 0;
|
||||||
while (ical_readline(fdi, buf, lstore, lineno)) {
|
while (ical_readline(fdi, buf, lstore, lineno)) {
|
||||||
note = NULL;
|
note = NULL;
|
||||||
@ -1796,10 +1809,10 @@ ical_read_todo(FILE * fdi, FILE * log, unsigned *notodos, unsigned *noskipped,
|
|||||||
case COMMENT:
|
case COMMENT:
|
||||||
/* There may be more than one. */
|
/* There may be more than one. */
|
||||||
if (vtodo.comm) {
|
if (vtodo.comm) {
|
||||||
asprintf(&tmp, "%sComment: %s",
|
asprintf(&p, "%sComment: %s",
|
||||||
vtodo.comm, note);
|
vtodo.comm, note);
|
||||||
mem_free(vtodo.comm);
|
mem_free(vtodo.comm);
|
||||||
vtodo.comm = tmp;
|
vtodo.comm = p;
|
||||||
} else
|
} else
|
||||||
vtodo.comm = note;
|
vtodo.comm = note;
|
||||||
break;
|
break;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
BEGIN:VCALENDAR
|
BEGIN:VCALENDAR
|
||||||
VERSION:2.0
|
VERSION:2.0
|
||||||
BEGIN:VEVENT
|
BEGIN:VEVENT
|
||||||
DTSTART:20200318T084100
|
|
||||||
DURATION:PT1H30M0S
|
DURATION:PT1H30M0S
|
||||||
SUMMARY:A simple appointment
|
SUMMARY:A simple appointment
|
||||||
|
DTSTART:20200318T084100
|
||||||
END:VEVENT
|
END:VEVENT
|
||||||
BEGIN:VTODO
|
BEGIN:VTODO
|
||||||
PRIORITY:1
|
PRIORITY:1
|
||||||
@ -12,6 +12,10 @@ END:VTODO
|
|||||||
BEGIN:VEVENT
|
BEGIN:VEVENT
|
||||||
DTSTART:
|
DTSTART:
|
||||||
DURATION:PT1H30M0S
|
DURATION:PT1H30M0S
|
||||||
|
SUMMARY:invalid start time
|
||||||
|
END:VEVENT
|
||||||
|
BEGIN:VEVENT
|
||||||
|
DURATION:PT1H30M0S
|
||||||
SUMMARY:missing start time
|
SUMMARY:missing start time
|
||||||
END:VEVENT
|
END:VEVENT
|
||||||
BEGIN:VEVENT
|
BEGIN:VEVENT
|
||||||
@ -39,6 +43,12 @@ END:VEVENT
|
|||||||
BEGIN:VEVENT
|
BEGIN:VEVENT
|
||||||
DTSTART:20200318T084100
|
DTSTART:20200318T084100
|
||||||
DURATION:PT1H30M0S
|
DURATION:PT1H30M0S
|
||||||
|
EXDATE:20200324T084100
|
||||||
|
SUMMARY:exdate\, missing rrule
|
||||||
|
END:VEVENT
|
||||||
|
BEGIN:VEVENT
|
||||||
|
DTSTART:20200318T084100
|
||||||
|
DURATION:PT1H30M0S
|
||||||
SUMMARY:Summary with more than\none line
|
SUMMARY:Summary with more than\none line
|
||||||
END:VEVENT
|
END:VEVENT
|
||||||
BEGIN:VEVENT
|
BEGIN:VEVENT
|
||||||
|
@ -17,27 +17,29 @@ if [ "$1" = 'actual' ]; then
|
|||||||
rm -rf "$tmpdir" || exit 1
|
rm -rf "$tmpdir" || exit 1
|
||||||
elif [ "$1" = 'expected' ]; then
|
elif [ "$1" = 'expected' ]; then
|
||||||
cat <<EOD
|
cat <<EOD
|
||||||
Import process report: 0121 lines read
|
Import process report: 0131 lines read
|
||||||
2 apps / 0 events / 1 todo / 19 skipped
|
2 apps / 0 events / 1 todo / 21 skipped
|
||||||
VEVENT [12]: invalid or malformed event start time.
|
VEVENT [12]: invalid or malformed event start time.
|
||||||
VEVENT [17]: rrule frequency not supported.
|
VEVENT [17]: item start date not defined.
|
||||||
VEVENT [23]: malformed summary line.
|
VEVENT [21]: rrule frequency not supported.
|
||||||
VTODO [28]: item priority is invalid (must be between 0 and 9).
|
VEVENT [27]: malformed summary line.
|
||||||
VEVENT [32]: malformed exceptions line.
|
VTODO [32]: item priority is invalid (must be between 0 and 9).
|
||||||
VEVENT [39]: line break in summary.
|
VEVENT [36]: malformed exceptions line.
|
||||||
VEVENT [44]: malformed description line.
|
VEVENT [43]: exception date, but no recurrence rule.
|
||||||
VEVENT [50]: malformed description.
|
VEVENT [49]: line break in summary.
|
||||||
VTODO [62]: malformed summary.
|
VEVENT [54]: malformed description line.
|
||||||
VEVENT [66]: only one location allowed.
|
VEVENT [60]: malformed description.
|
||||||
VEVENT [73]: invalid duration.
|
VTODO [72]: malformed summary.
|
||||||
VEVENT [78]: invalid or malformed event start time.
|
VEVENT [76]: only one location allowed.
|
||||||
VEVENT [83]: invalid end time value type.
|
VEVENT [83]: invalid duration.
|
||||||
VEVENT [88]: invalid until format.
|
VEVENT [88]: invalid or malformed event start time.
|
||||||
VEVENT [94]: invalid exception date value type.
|
VEVENT [93]: invalid end time value type.
|
||||||
VEVENT [101]: invalid exception.
|
VEVENT [98]: invalid until format.
|
||||||
VEVENT [108]: either end or duration.
|
VEVENT [104]: invalid exception date value type.
|
||||||
VEVENT [114]: end must be later than start.
|
VEVENT [111]: invalid exception.
|
||||||
VTODO [119]: The ical file seems to be malformed. The end of item was not found.
|
VEVENT [118]: either end or duration.
|
||||||
|
VEVENT [124]: end must be later than start.
|
||||||
|
VTODO [129]: The ical file seems to be malformed. The end of item was not found.
|
||||||
101
|
101
|
||||||
EOD
|
EOD
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user