+static event_t *to_list(icalarray *array)
+{
+ event_t list = {};
+ event_t *tail = &list;
+ for (int i = 0; i < array->num_elements; i++) {
+ ical_inst *inst = icalarray_element_at(array, i);
+ tail->next = to_event(inst);
+ tail = tail->next;
+ }
+ return list.next;
+}
+
+static void print_list(event_t *start)
+{
+ for (event_t *cur = start; cur; cur = cur->next)
+ printf("%04d-%02d-%02d %02d:%02d - %s\n",
+ cur->start.year, cur->start.month, cur->start.day,
+ cur->start.hour, cur->start.min,
+ cur->name ?: cur->desc ?: "[no summary]");
+}
+
+static void add_events(icalarray *array, icalcomponent *comp,
+ icaltimetype start, icaltimetype end)
+{
+ icalcomponent_kind kind = icalcomponent_isa(comp);
+
+ if (kind == ICAL_VEVENT_COMPONENT ||
+ kind == ICAL_VTODO_COMPONENT) {
+ /* Get recurrence data */
+ struct icaltimetype cstart, cend; // Component times
+ struct icaltimetype istart, iend; // Instance times
+ struct icaldurationtype length; // Duration
+
+ icalproperty *rrule;
+ struct icalrecurrencetype recur;
+ icalrecur_iterator *iter;
+
+ cstart = icalcomponent_get_dtstart(comp);
+ cend = icalcomponent_get_dtend(comp);
+ length = icaltime_subtract(cend, cstart);
+
+ rrule = icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY);
+ recur = icalproperty_get_rrule(rrule);
+ iter = icalrecur_iterator_new(recur, cstart);
+
+ /* Add recurrences */
+ while (1) {
+ istart = icalrecur_iterator_next(iter);
+ if (icaltime_is_null_time(istart))
+ break; // no more instances
+ iend = icaltime_add(istart, length);
+ if (icaltime_compare(iend, start) <= 0)
+ continue; // instance ends before start time
+ if (icaltime_compare(istart, end) >= 0)
+ break; // instance begins after stop time
+ icalarray_append(array, &(ical_inst){
+ .comp = comp,
+ .start = istart,
+ .end = iend,
+ });
+ }
+ }
+
+ /* Add children */
+ icalcomponent_kind find = ICAL_ANY_COMPONENT;
+ icalcomponent *child = icalcomponent_get_first_component(comp, find);
+ while (child) {
+ add_events(array, child, start, end);
+ child = icalcomponent_get_next_component(comp, find);
+ }
+}
+