summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Murchison <murch@andrew.cmu.edu>2017-09-25 03:21:39 -0400
committerKen Murchison <murch@andrew.cmu.edu>2017-09-25 03:21:39 -0400
commitb8fc31be68e0d8cb74548a78812003139eb58962 (patch)
tree74b26a61e8c62b1380f2c0e06f1f15e551ad1e75
parent2511737f0e529cdaf2accfad1dd0ebc2c7d525af (diff)
parentaa84c9822ed8e4c4505480a00d009e2c160cd2b7 (diff)
downloadlibical-git-b8fc31be68e0d8cb74548a78812003139eb58962.tar.gz
Merge branch 'vpatch' of github.com:libical/libical into vpatch
-rw-r--r--CMakeLists.txt15
-rwxr-xr-xscripts/buildtests.sh17
-rw-r--r--src/libical/icalcomponent.c204
-rw-r--r--src/libical/icalcomponent.h3
-rw-r--r--src/libical/icalproperty.c112
-rw-r--r--src/libical/icalproperty.h2
-rw-r--r--src/libical/icalrecur.c2
-rw-r--r--src/libical/icalvalue.c1
-rw-r--r--src/libicalvcal/vobject.c2
-rw-r--r--test-data/caltime.ics262
-rw-r--r--test-data/get_char_test.ics1961
-rw-r--r--uninstall.cmake.in21
12 files changed, 2600 insertions, 2 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f95acf03..1cfcf96a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -465,4 +465,19 @@ install(
FILE LibIcalTargets.cmake
)
+########## By popular demand, add an uninstall target ##########
+
+if(NOT TARGET uninstall)
+ configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/uninstall.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake"
+ IMMEDIATE
+ @ONLY
+ )
+
+ add_custom_target(uninstall
+ COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake"
+ )
+endif()
+
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/scripts/buildtests.sh b/scripts/buildtests.sh
index 20f879e8..128378fe 100755
--- a/scripts/buildtests.sh
+++ b/scripts/buildtests.sh
@@ -31,6 +31,16 @@ HELP() {
echo
}
+COMMAND_EXISTS () {
+ command -v $1 >/dev/null 2>&1
+ if ( test $? != 0 )
+ then
+ echo "$1 is not in your PATH. Either install this program or skip the assocatied test"
+ exit 1
+ fi
+}
+
+
#function SET_GCC
# setup compiling with gcc
SET_GCC() {
@@ -140,6 +150,7 @@ GCC_BUILD() {
echo "===== GCC BUILD TEST $1 DISABLED DUE TO COMMAND LINE OPTION ====="
return
fi
+ COMMAND_EXISTS "gcc"
echo "===== START GCC BUILD: $1 ======"
SET_GCC
BUILD "$name" "$2"
@@ -157,6 +168,7 @@ CLANG_BUILD() {
echo "===== CLANG BUILD TEST $1 DISABLED DUE TO COMMAND LINE OPTION ====="
return
fi
+ COMMAND_EXISTS "clang"
echo "===== START CLANG BUILD: $1 ======"
SET_CLANG
BUILD "$name" "$2"
@@ -191,6 +203,7 @@ CPPCHECK() {
echo "===== CPPCHECK TEST $1 DISABLED DUE TO COMMAND LINE OPTION ====="
return
fi
+ COMMAND_EXISTS "cppcheck"
echo "===== START SETUP FOR CPPCHECK: $1 ======"
#first build it
@@ -239,6 +252,7 @@ SPLINT() {
echo "===== SPLIT TEST $1 DISABLED DUE TO COMMAND LINE OPTION ====="
return
fi
+ COMMAND_EXISTS "splint"
echo "===== START SETUP FOR SPLINT: $1 ======"
#first build it
@@ -320,6 +334,7 @@ CLANGTIDY() {
echo "===== CLANG-TIDY TEST $1 DISABLED DUE TO COMMAND LINE OPTION ====="
return
fi
+ COMMAND_EXISTS "clang-tidy"
echo "===== START CLANG-TIDY: $1 ====="
cd $TOP
SET_CLANG
@@ -340,6 +355,7 @@ CLANGSCAN() {
echo "===== SCAN-BUILD TEST $1 DISABLED DUE TO COMMAND LINE OPTION ====="
return
fi
+ COMMAND_EXISTS "scan-build"
echo "===== START SCAN-BUILD: $1 ====="
cd $TOP
@@ -364,6 +380,7 @@ KRAZY() {
echo "===== KRAZY TEST DISABLED DUE TO COMMAND LINE OPTION ====="
return
fi
+ COMMAND_EXISTS "krazy2all"
echo "===== START KRAZY ====="
cd $TOP
krazy2all |& tee krazy.out
diff --git a/src/libical/icalcomponent.c b/src/libical/icalcomponent.c
index d5eab7df..341b39f5 100644
--- a/src/libical/icalcomponent.c
+++ b/src/libical/icalcomponent.c
@@ -885,12 +885,24 @@ void icalcomponent_foreach_recurrence(icalcomponent *comp,
dtstart = icalcomponent_get_dtstart(comp);
+ if (icaltime_is_null_time(dtstart) &&
+ icalcomponent_isa(comp) == ICAL_VTODO_COMPONENT) {
+ /* VTODO with no DTSTART - use DUE */
+ dtstart = icalcomponent_get_due(comp);
+ }
if (icaltime_is_null_time(dtstart))
return;
/* The end time could be specified as either a DTEND or a DURATION */
/* icalcomponent_get_dtend takes care of these cases. */
dtend = icalcomponent_get_dtend(comp);
+ if (icaltime_is_null_time(dtend) && icaltime_is_date(dtstart)) {
+ /* No DTEND or DURATION and DTSTART is DATE - duration is 1 day */
+ struct icaldurationtype dur = icaldurationtype_null_duration();
+
+ dur.days = 1;
+ dtend = icaltime_add(dtstart, dur);
+ }
/* Now set up the base span for this item, corresponding to the
base DTSTART and DTEND */
@@ -2532,3 +2544,195 @@ void icalcomponent_set_due(icalcomponent *comp, struct icaltimetype v)
icalproperty_set_parameter(due_prop, icalparameter_new_tzid(tzid));
}
}
+
+static int prop_compare(void *a, void *b)
+{
+ icalproperty *p1 = (icalproperty*) a;
+ icalproperty *p2 = (icalproperty*) b;
+ icalproperty_kind k1 = icalproperty_isa(p1);
+ icalproperty_kind k2 = icalproperty_isa(p2);
+ int r = k1 - k2;
+
+ if (r == 0) {
+ if (k1 == ICAL_X_PROPERTY) {
+ r = strcmp(icalproperty_get_x_name(p1),
+ icalproperty_get_x_name(p2));
+ }
+
+ if (r == 0) {
+ r = strcmp(icalproperty_get_value_as_string(p1),
+ icalproperty_get_value_as_string(p2));
+ }
+ }
+
+ return r;
+}
+
+static int comp_compare(void *a, void *b)
+{
+ icalcomponent *c1 = (icalcomponent*) a;
+ icalcomponent *c2 = (icalcomponent*) b;
+ icalcomponent_kind k1 = icalcomponent_isa(c1);
+ icalcomponent_kind k2 = icalcomponent_isa(c2);
+ int r = k1 - k2;
+
+ if (r == 0) {
+ if (k1 == ICAL_X_COMPONENT) {
+ r = strcmp(c1->x_name, c2->x_name);
+ }
+
+ if (r == 0) {
+ const char *u1 = icalcomponent_get_uid(c1);
+ const char *u2 = icalcomponent_get_uid(c2);
+
+ if (u1 && u2) {
+ r = strcmp(u1, u2);
+
+ if (r == 0) {
+ r = icaltime_compare(icalcomponent_get_recurrenceid(c1),
+ icalcomponent_get_recurrenceid(c2));
+ }
+ }
+ else {
+ icalproperty *p1, *p2;
+
+ switch (k1) {
+ case ICAL_VALARM_COMPONENT:
+ p1 = icalcomponent_get_first_property(c1,
+ ICAL_TRIGGER_PROPERTY);
+ p2 = icalcomponent_get_first_property(c2,
+ ICAL_TRIGGER_PROPERTY);
+ r = strcmp(icalproperty_get_value_as_string(p1),
+ icalproperty_get_value_as_string(p2));
+
+ if (r == 0) {
+ p1 = icalcomponent_get_first_property(c1,
+ ICAL_ACTION_PROPERTY);
+ p2 = icalcomponent_get_first_property(c2,
+ ICAL_ACTION_PROPERTY);
+ r = strcmp(icalproperty_get_value_as_string(p1),
+ icalproperty_get_value_as_string(p2));
+ }
+ break;
+
+ case ICAL_VTIMEZONE_COMPONENT:
+ p1 = icalcomponent_get_first_property(c1,
+ ICAL_TZID_PROPERTY);
+ p2 = icalcomponent_get_first_property(c2,
+ ICAL_TZID_PROPERTY);
+ r = strcmp(icalproperty_get_value_as_string(p1),
+ icalproperty_get_value_as_string(p2));
+ break;
+
+ case ICAL_XSTANDARD_COMPONENT:
+ case ICAL_XDAYLIGHT_COMPONENT:
+ p1 = icalcomponent_get_first_property(c1,
+ ICAL_DTSTART_PROPERTY);
+ p2 = icalcomponent_get_first_property(c2,
+ ICAL_DTSTART_PROPERTY);
+ r = strcmp(icalproperty_get_value_as_string(p1),
+ icalproperty_get_value_as_string(p2));
+ break;
+
+ case ICAL_VVOTER_COMPONENT:
+ p1 = icalcomponent_get_first_property(c1,
+ ICAL_VOTER_PROPERTY);
+ p2 = icalcomponent_get_first_property(c2,
+ ICAL_VOTER_PROPERTY);
+ r = strcmp(icalproperty_get_value_as_string(p1),
+ icalproperty_get_value_as_string(p2));
+ break;
+
+ case ICAL_XVOTE_COMPONENT:
+ p1 = icalcomponent_get_first_property(c1,
+ ICAL_POLLITEMID_PROPERTY);
+ p2 = icalcomponent_get_first_property(c2,
+ ICAL_POLLITEMID_PROPERTY);
+ r = strcmp(icalproperty_get_value_as_string(p1),
+ icalproperty_get_value_as_string(p2));
+ break;
+
+ default:
+ /* XXX Anything better? */
+ r = icaltime_compare(icalcomponent_get_dtstamp(c1),
+ icalcomponent_get_dtstamp(c2));
+ break;
+ }
+ }
+ }
+ }
+
+ return r;
+}
+
+void icalcomponent_normalize(icalcomponent *comp)
+{
+ pvl_list sorted_props = pvl_newlist();
+ icalproperty *prop;
+
+ while ((prop = pvl_pop(comp->properties)) != 0) {
+ int nparams = icalproperty_count_parameters(prop);
+
+ /* Skip unparameterized properties having default values */
+ switch (icalproperty_isa(prop)) {
+ case ICAL_CALSCALE_PROPERTY:
+ if ((nparams == 0) &&
+ (strcmp("GREGORIAN", icalproperty_get_calscale(prop)) == 0)) {
+ continue;
+ }
+ break;
+
+ case ICAL_CLASS_PROPERTY:
+ if ((nparams == 0) &&
+ (icalproperty_get_class(prop) == ICAL_CLASS_PUBLIC)) {
+ continue;
+ }
+ break;
+
+ case ICAL_PRIORITY_PROPERTY:
+ if ((nparams == 0) && (icalproperty_get_priority(prop) == 0)) {
+ continue;
+ }
+ break;
+
+ case ICAL_TRANSP_PROPERTY:
+ if ((nparams == 0) &&
+ (icalproperty_get_transp(prop) == ICAL_TRANSP_OPAQUE)) {
+ continue;
+ }
+ break;
+
+ case ICAL_REPEAT_PROPERTY:
+ if ((nparams == 0) && (icalproperty_get_repeat(prop) == 0)) {
+ continue;
+ }
+ break;
+
+ case ICAL_SEQUENCE_PROPERTY:
+ if ((nparams == 0) && (icalproperty_get_sequence(prop) == 0)) {
+ continue;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ icalproperty_normalize(prop);
+ pvl_insert_ordered(sorted_props, prop_compare, prop);
+ }
+
+ pvl_free(comp->properties);
+ comp->properties = sorted_props;
+
+ pvl_list sorted_comps = pvl_newlist();
+ icalcomponent *mycomp;
+
+ while ((mycomp = pvl_pop(comp->components)) != 0) {
+ icalcomponent_normalize(mycomp);
+ pvl_insert_ordered(sorted_comps, comp_compare, mycomp);
+ }
+
+ pvl_free(comp->components);
+ comp->components = sorted_comps;
+}
diff --git a/src/libical/icalcomponent.h b/src/libical/icalcomponent.h
index 84f4282e..3b1bec0f 100644
--- a/src/libical/icalcomponent.h
+++ b/src/libical/icalcomponent.h
@@ -273,6 +273,9 @@ LIBICAL_ICAL_EXPORT void icalcomponent_foreach_recurrence(icalcomponent *comp,
span, void *data),
void *callback_data);
+LIBICAL_ICAL_EXPORT void icalcomponent_normalize(icalcomponent *comp);
+
+
/*************** Type Specific routines ***************/
LIBICAL_ICAL_EXPORT icalcomponent *icalcomponent_new_vcalendar(void);
diff --git a/src/libical/icalproperty.c b/src/libical/icalproperty.c
index ac38259e..f76c0f07 100644
--- a/src/libical/icalproperty.c
+++ b/src/libical/icalproperty.c
@@ -937,3 +937,115 @@ icalcomponent *icalproperty_get_parent(const icalproperty *property)
return property->parent;
}
+
+static int param_compare(void *a, void *b)
+{
+ /* XXX Need to sort values for multi-valued parameters (e.g. MEMBER) */
+ return strcmp(icalparameter_as_ical_string((icalparameter *) a),
+ icalparameter_as_ical_string((icalparameter *) b));
+}
+
+void icalproperty_normalize(icalproperty *prop)
+{
+ icalproperty_kind prop_kind = icalproperty_isa(prop);
+ pvl_list sorted_params = pvl_newlist();
+ icalparameter *param;
+
+ while ((param = pvl_pop(prop->parameters)) != 0) {
+ /* Skip parameters having default values */
+ switch (icalparameter_isa(param)) {
+ case ICAL_VALUE_PARAMETER:
+ /* Skip VALUE parameters for default property value types */
+ switch (prop_kind) {
+ case ICAL_ATTACH_PROPERTY:
+ if (icalparameter_get_value(param) == ICAL_VALUE_URI) {
+ continue;
+ }
+ break;
+
+ case ICAL_DTEND_PROPERTY:
+ case ICAL_DUE_PROPERTY:
+ case ICAL_DTSTART_PROPERTY:
+ case ICAL_EXDATE_PROPERTY:
+ case ICAL_RDATE_PROPERTY:
+ case ICAL_RECURRENCEID_PROPERTY:
+ if (icalparameter_get_value(param) == ICAL_VALUE_DATETIME) {
+ continue;
+ }
+ break;
+
+ case ICAL_DURATION_PROPERTY:
+ if (icalparameter_get_value(param) == ICAL_VALUE_DURATION) {
+ continue;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case ICAL_CUTYPE_PARAMETER:
+ if (icalparameter_get_cutype(param) == ICAL_CUTYPE_INDIVIDUAL) {
+ continue;
+ }
+ break;
+
+ case ICAL_ENCODING_PARAMETER:
+ if (icalparameter_get_encoding(param) == ICAL_ENCODING_8BIT) {
+ continue;
+ }
+ break;
+
+ case ICAL_FBTYPE_PARAMETER:
+ if (icalparameter_get_fbtype(param) == ICAL_FBTYPE_BUSY) {
+ continue;
+ }
+ break;
+
+ case ICAL_PARTSTAT_PARAMETER:
+ if (icalparameter_get_partstat(param) == ICAL_PARTSTAT_NEEDSACTION) {
+ continue;
+ }
+ break;
+
+ case ICAL_RELATED_PARAMETER:
+ if (icalparameter_get_related(param) == ICAL_RELATED_START) {
+ continue;
+ }
+ break;
+
+ case ICAL_RELTYPE_PARAMETER:
+ if (icalparameter_get_reltype(param) == ICAL_RELTYPE_PARENT) {
+ continue;
+ }
+ break;
+
+ case ICAL_ROLE_PARAMETER:
+ if (icalparameter_get_role(param) == ICAL_ROLE_REQPARTICIPANT) {
+ continue;
+ }
+ break;
+
+ case ICAL_RSVP_PARAMETER:
+ if (icalparameter_get_rsvp(param) == ICAL_RSVP_FALSE) {
+ continue;
+ }
+ break;
+
+ case ICAL_SCHEDULEAGENT_PARAMETER:
+ if (icalparameter_get_scheduleagent(param) == ICAL_SCHEDULEAGENT_SERVER) {
+ continue;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ pvl_insert_ordered(sorted_params, param_compare, param);
+ }
+
+ pvl_free(prop->parameters);
+ prop->parameters = sorted_params;
+}
diff --git a/src/libical/icalproperty.h b/src/libical/icalproperty.h
index 6fad331f..84fd2e6e 100644
--- a/src/libical/icalproperty.h
+++ b/src/libical/icalproperty.h
@@ -124,4 +124,6 @@ LIBICAL_ICAL_EXPORT icalproperty_status icalproperty_string_to_status(const char
LIBICAL_ICAL_EXPORT int icalproperty_enum_belongs_to_property(icalproperty_kind kind, int e);
+LIBICAL_ICAL_EXPORT void icalproperty_normalize(icalproperty *prop);
+
#endif /*ICALPROPERTY_H */
diff --git a/src/libical/icalrecur.c b/src/libical/icalrecur.c
index 643be805..e8851621 100644
--- a/src/libical/icalrecur.c
+++ b/src/libical/icalrecur.c
@@ -1328,7 +1328,7 @@ static int initialize_iterator(icalrecur_iterator *impl)
struct icaltimetype dtstart = impl->dtstart;
char locale[ULOC_KEYWORD_AND_VALUES_CAPACITY] = "";
UErrorCode status = U_ZERO_ERROR;
- UChar *tzid = NULL;
+ UChar *tzid = (UChar *) UCAL_UNKNOWN_ZONE_ID;
short is_hebrew = 0;
if (dtstart.zone) {
diff --git a/src/libical/icalvalue.c b/src/libical/icalvalue.c
index 868d3261..d97c1014 100644
--- a/src/libical/icalvalue.c
+++ b/src/libical/icalvalue.c
@@ -628,6 +628,7 @@ static icalvalue *icalvalue_new_from_string_with_error(icalvalue_kind kind,
if (rt.freq != ICAL_NO_RECURRENCE) {
value = icalvalue_new_recur(rt);
}
+ free(rt.rscale);
break;
}
diff --git a/src/libicalvcal/vobject.c b/src/libicalvcal/vobject.c
index 47b8aa9b..10d0cf5a 100644
--- a/src/libicalvcal/vobject.c
+++ b/src/libicalvcal/vobject.c
@@ -199,7 +199,7 @@ const wchar_t* vObjectUStringZValue(VObject *o)
void setVObjectUStringZValue(VObject *o, const wchar_t *s)
{
- size_t size = (size_t)((uStrLen(s)+1)*2);
+ size_t size = (size_t)((uStrLen(s)+1)*sizeof(wchar_t));
USTRINGZ_VALUE_OF(o) = (wchar_t*) dupStr((char*)s,size);
VALUE_TYPE(o) = VCVT_USTRINGZ;
}
diff --git a/test-data/caltime.ics b/test-data/caltime.ics
new file mode 100644
index 00000000..a8d83057
--- /dev/null
+++ b/test-data/caltime.ics
@@ -0,0 +1,262 @@
+BEGIN:VTIMEZONE
+TZID:00
+BEGIN:VTIMEZONE
+TZID:00000
+BEGIN:STANDARD
+DTSTART;000000000000d00
+RDATE:00000020/00000005T000000Z
+0;0
+RDATE:00000020/00000005T000000Z
+RDATE:00000020/00000005T000000Z
+RDATE:TZID=:00;:000000
+00000000000:
+00
+000000000000000:
+0;
+0000;000000
+END;0YD000000000000:000
+0;
+00000;1
+0000000:
+0000000000:-1;
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+0;000000
+00
+00000020/00000005T000000Z
+RDATE:00000020/00000005T000000Z
+RDATE:00000020/Z
+DAY:000
+0;
+00000;1
+0000000:
+01000=000000;
+00000:00000000000
+RRULE:00000000000;
+0E00000000
+RRULE:0000
+0
+RRULE:000=000000;
+RRULE:FREQ=YEARLY;5Y000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;0;00000000:000000000000000:
+0;
+00000000000000000000:
+X;00000
+00
+00
+00000006000;00000000000000000000000
+X;TZID=:0000;TzID=0000000:000
+0;
+00000000000000000000:
+0000000:0
+00
+0;
+0000000000000000000000000000000000000000:
+0;0000000:
+X;TZID=:000000
+000:
+0;00
+X;00000INVITATION
+00000
+
+00000000000:
+0;
+0000000000:
+X;TZID=:0000000
+0;0000000000000000000000000
+X;TZID=0000000000000000EXDATE00000000000000000000
+X;TZID=0000000000000000:SAINTS
+ID=:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000?000000000000000000000000000000000000000000000
+00000000000000;?
+00000000000;0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E0;0
+00000000000000000000AEST
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000WEEKLY
+0000000000:0000?0
+
+
+
+
+
+
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;0;00000000:000000000000000000000
+000000000000000000000000@0:000000
+X;TZID=}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}:000000;
+00
+000000000000000:
+0;
+0 00;000000
+END;00000:000000
+X;:000000
+0000:000
+0;
+00000000000000000000:
+0000000:9
+00
+0;
+00000000
+0000000:
+0000000000:
+0;
+00000000000000000000:0000
+000
+00
+00
+000000000000000000000000000000000000000000
+X;00000:00000
+0000000
+X;00BYSETPOS
+00000000
+
+000H0000000000000000000000:
+X;TZID=:0000000
+0000000
+X;00000000000000000000000000000
+0000000:
+0000000000:
+0;
+00000000000000000000:0000
+0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+010000:0;
+0;
+0000000
+X;0000000000
+
+0000000000000000000000?000:
+X;TZID=:0000000
+0;00000000
+X;TZID=00000000000000000000000000000000000000000.0000:0000;00000000000000000000000000000000000000000000000000000000000000X0d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E0;0
+00000000000000000000AEST
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000I000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:0000?0
+
+
+
+
+
+
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+000000000000000000000000000000000000080000000000000000000000000000000000:0000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+X;TZID=:0000000
+0;00000000000000000000000000000?000000000000000000000;0;00??00:000000000000000000000
+000000000000000000000000@0:000000
+X;TZID=:000000;
+00
+000000000000000:
+0;
+0 00;000000
+END;00000:000000
+X;:000000
+0000000Q0000
+0;
+000:000
+X;0000000=:000000;0
+0000000:
+0000000000:
+0;
+00000000000000000000:
+X;00000
+00
+00
+00000006000;00000000000000000000000
+X;TZID=:0000;TzID=0000000:000
+0;
+00000000000000000000:
+0000000:0
+00(0;
+000000000000000000000000000000000000000000000000;
+0000000:
+0;0000000:
+X;TZID=:000000
+000:
+0;00
+X;00000INVITATION77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777
+00000
+
+00000000000:
+0;
+0000000000:
+X;TZID=:0000000
+0;0000000000000000000000000
+X;TZID=0000000000000000EXDATE00000000000000000000
+X;TZID=0000000000000000:SAINTS
+ID=:000
+X;TZID=0000000000000000:0000;T:000X;TZID=:256;00;00000000:000000000000000000000
+00000000000000;
+00000000000000000000
+X;TZID=:00;:000000
+00000000000:
+00
+000000000000000:
+0;
+0000;000000
+END;0YD000000000000:000
+0;
+00000;PUBLISH
+00:
+0000000000:-1;
+00000000000000000000:
+0;000000
+00
+0000000000
+00000
+0;0000000
+0;000000000000000
+0000000000000000:
+0;
+000
+000000000000000000000000000000;000000000000000000000000000000000000000MVT
+0000000:
+00
+000000000000000000000;00000:
+4411581995551233265899243;000%00000000000000:
+0000000000000000000:
diff --git a/test-data/get_char_test.ics b/test-data/get_char_test.ics
new file mode 100644
index 00000000..f726f448
--- /dev/null
+++ b/test-data/get_char_test.ics
@@ -0,0 +1,1961 @@
+BEGIN:000
+DURATION:0
+DURATION:0
+DURATION:-0
+DURATITIMEZONE
+TZID:000000000
+BEGIN:DAYLIGHT
+00000000000000000:0
+TZNAME:0
+DTSTART:10000000T000000
+DTSTART:0000000000
+END:000000000000000000
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0000
+'TSTART:10000000T000000
+DTSTART:10000003T000000
+END:0
+BEGINVTIMEZONE
+TZID:00000000000000000
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000000T000000
+DTSTART:0000000000
+END:000000000000000000
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0000
+DTSTART:10000000T000000
+DTSTART:10000003T000000
+END:0
+BEGIN:VTIMEZONE
+TZID:00000000000000000
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000000T000000
+DTSTART:0000000000
+END:000000000000000000
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0000
+DTSTART:10000000T000000
+
+DTSTART:10000003T000000
+END:0
+BEGIN:VTIMEZONE
+TZID:00000000000000000
+BEGIN:DAYLIGNIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN0000@
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATMON:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGI00
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+000000START:00:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+00E
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+00000000000
+PRODID:0
+VERSION:0
+BEGIN:VTIMEZONE
+TZID:0
+X-:0
+BEGIN:DAYLIGHT
+TZOFFSETTO:0
+TZNAME:0
+DTSTART:10000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:000
+DURATION:000
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:P00P
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+00:0
+DTSTART:00000001T000000
+DTSTART:10000000T000000
+END:0
+000:00000
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+:0000000000="
+00000000:000
+00000000000
+ORGANIZER:0
+:000000="
+00000000000000000000
+DURATION:P0P
+DURATION:00
+DURATION:PP0N0
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+00000000000000000000000000
+ORGANIZER:0
+:00000000000000="
+0000000000000000:000
+DURATION:P0P
+DURATION:0000000000
+DURATION:PPO00
+00
+DURATION:P0P
+00000000:000
+DURATION:PN000000
+000:000
+DURATION:P000P
+DURATION:P0P
+DURATION:P0d
+ORGANIZER:0
+"00000000000000="00000000000000000000:000
+END:
diff --git a/uninstall.cmake.in b/uninstall.cmake.in
new file mode 100644
index 00000000..662668c7
--- /dev/null
+++ b/uninstall.cmake.in
@@ -0,0 +1,21 @@
+if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+ message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+endif()
+
+file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
+string(REGEX REPLACE "\n" ";" files "${files}")
+foreach(file ${files})
+ message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
+ if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
+ exec_program(
+ "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
+ OUTPUT_VARIABLE rm_out
+ RETURN_VALUE rm_retval
+ )
+ if(NOT "${rm_retval}" STREQUAL 0)
+ message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
+ endif()
+ else()
+ message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
+ endif()
+endforeach()