1 /*======================================================================
2  FILE: regression-recur.c
3  CREATOR: ebusboom 8jun00
4 
5  (C) COPYRIGHT 1999 Eric Busboom <eric@civicknowledge.com>
6 
7  DESCRIPTION:
8 
9  This library is free software; you can redistribute it and/or modify
10  it under the terms of either:
11 
12     The LGPL as published by the Free Software Foundation, version
13     2.1, available at: https://www.gnu.org/licenses/lgpl-2.1.html
14 
15  Or:
16 
17     The Mozilla Public License Version 2.0. You may obtain a copy of
18     the License at https://www.mozilla.org/MPL/
19 ======================================================================*/
20 
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 
25 #include "regression.h"
26 #include "libical/ical.h"
27 #include "libicalss/icalss.h"
28 
29 #include <stdlib.h>
30 
31 #if defined(HAVE_SIGNAL) && defined(HAVE_ALARM)
sig_alrm(int i)32 static void sig_alrm(int i)
33 {
34     _unused(i);
35     fprintf(stderr, "Could not get lock on file\n");
36     exit(1);
37 }
38 
39 #endif
40 
41 /* Get the expected result about the purpose of the property*/
42 
get_expected_numevents(icalcomponent * c)43 static int get_expected_numevents(icalcomponent *c)
44 {
45     icalproperty *p;
46     const char *note = 0;
47     int num_events = 0;
48 
49     if (c != 0) {
50         for (p = icalcomponent_get_first_property(c, ICAL_X_PROPERTY);
51              p != 0; p = icalcomponent_get_next_property(c, ICAL_X_PROPERTY)) {
52             if (strcmp(icalproperty_get_x_name(p), "X-EXPECT-NUMEVENTS") == 0) {
53                 note = icalproperty_get_x(p);
54             }
55         }
56     }
57 
58     if (note != 0) {
59         num_events = atoi(note);
60     }
61 
62     return num_events;
63 }
64 
recur_callback(icalcomponent * comp,struct icaltime_span * span,void * data)65 static void recur_callback(icalcomponent *comp, struct icaltime_span *span, void *data)
66 {
67     int *num_recurs = data;
68 
69     _unused(comp);
70 
71     if (VERBOSE) {
72         printf("recur: %s", ctime(&span->start));
73         printf("       %s", ctime(&span->end));
74     }
75     *num_recurs = *num_recurs + 1;
76 }
77 
test_recur_file()78 void test_recur_file()
79 {
80     icalset *cin = 0;
81     struct icaltimetype next;
82     icalcomponent *itr;
83     icalproperty *desc, *dtstart, *rrule;
84     struct icalrecurrencetype recur;
85     icalrecur_iterator *ritr;
86     time_t tt;
87     const char *file;
88     int num_recurs_found = 0;
89     icalfileset_options options = { O_RDONLY, 0644, 0, NULL };
90 
91     icalerror_set_error_state(ICAL_PARSE_ERROR, ICAL_ERROR_NONFATAL);
92 
93 #if defined(HAVE_SIGNAL) && defined(HAVE_ALARM)
94     (void)signal(SIGALRM, sig_alrm);
95 #endif
96     file = getenv("ICAL_RECUR_FILE");
97     if (!file)
98         file = TEST_DATADIR "/recur.txt";
99 
100 #if defined(HAVE_SIGNAL) && defined(HAVE_ALARM)
101     alarm(15);  /* to get file lock */
102 #endif
103     cin = icalset_new(ICAL_FILE_SET, file, &options);
104 #if defined(HAVE_SIGNAL) && defined(HAVE_ALARM)
105     alarm(0);
106 #endif
107 
108     ok("opening file with recurring events", (cin != NULL));
109     assert(cin != NULL);
110 
111     for (itr = icalfileset_get_first_component(cin);
112          itr != 0; itr = icalfileset_get_next_component(cin)) {
113         int expected_events = 0;
114         char msg[128];
115 
116         struct icaltimetype start;
117         struct icaltimetype startmin = icaltime_from_timet_with_zone(1, 0, NULL);
118         struct icaltimetype endmax = icaltime_null_time();
119         const char *desc_str = "malformed component";
120 
121         desc = icalcomponent_get_first_property(itr, ICAL_DESCRIPTION_PROPERTY);
122         dtstart = icalcomponent_get_first_property(itr, ICAL_DTSTART_PROPERTY);
123         rrule = icalcomponent_get_first_property(itr, ICAL_RRULE_PROPERTY);
124         if (desc) {
125             desc_str = icalproperty_get_description(desc);
126         }
127 
128         ok((char *)desc_str, !(desc == 0 || dtstart == 0 || rrule == 0));
129 
130         if (desc == 0 || dtstart == 0 || rrule == 0) {
131             if (VERBOSE) {
132                 printf("\n******** Error in input component ********\n");
133                 printf("The following component is malformed:\n %s\n", desc_str);
134             }
135             continue;
136         }
137         if (VERBOSE) {
138             printf("\n\n#### %s\n", desc_str);
139             printf("#### %s\n", icalvalue_as_ical_string(icalproperty_get_value(rrule)));
140         }
141 
142         recur = icalproperty_get_rrule(rrule);
143         start = icalproperty_get_dtstart(dtstart);
144 
145         ritr = icalrecur_iterator_new(recur, start);
146 
147         tt = icaltime_as_timet(start);
148 
149         if (VERBOSE)
150             printf("#### %s\n", ctime(&tt));
151 
152         icalrecur_iterator_free(ritr);
153 
154         ritr = icalrecur_iterator_new(recur, start);
155         for (next = icalrecur_iterator_next(ritr);
156              !icaltime_is_null_time(next);
157              next = icalrecur_iterator_next(ritr)) {
158             tt = icaltime_as_timet(next);
159             if (VERBOSE)
160                 printf("  %s", ctime(&tt));
161         }
162 
163         icalrecur_iterator_free(ritr);
164         num_recurs_found = 0;
165         expected_events = get_expected_numevents(itr);
166 
167         icalcomponent_foreach_recurrence(itr, startmin, endmax, recur_callback, &num_recurs_found);
168 
169         snprintf(msg, sizeof(msg), "   expecting total of %d events", expected_events);
170 #if ADD_TESTS_REQUIRING_INVESTIGATION
171         int_is(msg, num_recurs_found, expected_events);
172 #endif
173     }
174 
175     icalset_free(cin);
176 }
177