return 0;
}
-char *months[] = {
- "January", "February", "March", "April", "May", "June", "July",
- "August", "September", "October", "November", "December"
-};
+static int month_to_number(const char *month)
+{
+ static char *months[] = {
+ "January", "February", "March", "April", "May", "June", "July",
+ "August", "September", "October", "November", "December"
+ };
+ int monthnr;
+ for (monthnr = 0; monthnr < 12; monthnr++) {
+ if (!strcmp(month, months[monthnr]))
+ return monthnr + 1;
+ }
+
+ fprintf(stderr, "Unrecognised month name '%s'\n", month);
+ return 0;
+}
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+static const char *weekday_to_ical(const char *weekday)
+{
+ static struct {
+ const char *exch;
+ const char *ical;
+ } table[] = {
+ { "Sunday", "SO" },
+ { "Monday", "MO" },
+ { "Tuesday", "TU" },
+ { "Wednesday", "WE" },
+ { "Thursday", "TH" },
+ { "Friday", "FR" },
+ { "Day", "SU,MO,TU,WE,TH,FR,SA" },
+ { "Weekday", "MO,TU,WE,TH,FR" },
+ { "WeekendDay", "SA,SU" },
+ };
+ int i;
+
+ for (i=0 ; i < ARRAY_SIZE(table); i++) {
+ if (!strcmp(weekday, table[i].exch))
+ return table[i].ical;
+ }
+ fprintf(stderr, "Unrecognised DaysOfWeek '%s'\n", weekday);
+ return NULL;
+}
+
+static int weekindex_to_ical(const char *week)
+{
+ static struct {
+ char *exch;
+ int week;
+ } table[] = {
+ { "First", 1 },
+ { "Second", 2 },
+ { "Third", 3 },
+ { "Fourth", 4 },
+ { "Last", -1 }
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(table); i++) {
+ if (!strcmp(week, table[i].exch))
+ return table[i].week;
+ }
+ fprintf(stderr, "Unrecognised DayOfWeekIndex '%s'\n", week);
+ return 0;
+}
+
int process_recurrence(xmlNode *xml_node)
{
xmlNode *xml_node2;
const char *weekly_interval = NULL;
const char *weekday = NULL;
const char *daily_interval = NULL;
+ const char *monthly_interval = NULL;
const char *day_of_month = NULL;
const char *month = NULL;
+ const char *week_index = NULL;
const char *end_date = NULL;
const char *nr_recurrences = NULL;
month = (char *)xmlNodeGetContent(xml_node2);
}
} else if (!strcmp((char *)xml_node->name, "RelativeYearlyRecurrence")) {
- fprintf(stderr, "Cannot yet handle %s\n", xml_node->name);
+ for (xml_node2 = xml_node->children; xml_node2;
+ xml_node2 = xml_node2->next) {
+ if (xml_node2->type != XML_ELEMENT_NODE)
+ continue;
+ if (!strcmp((char *)xml_node2->name, "DaysOfWeek"))
+ weekday = (char *)xmlNodeGetContent(xml_node2);
+ else if (!strcmp((char *)xml_node2->name, "Interval"))
+ monthly_interval = (char *)xmlNodeGetContent(xml_node2);
+ else if (!strcmp((char *)xml_node2->name, "DayOfWeekIndex"))
+ week_index = (char *)xmlNodeGetContent(xml_node2);
+ }
} else if (!strcmp((char *)xml_node->name, "AbsoluteMonthlyRecurrence")) {
- fprintf(stderr, "Cannot yet handle %s\n", xml_node->name);
+ for (xml_node2 = xml_node->children; xml_node2;
+ xml_node2 = xml_node2->next) {
+ if (xml_node2->type != XML_ELEMENT_NODE)
+ continue;
+ if (!strcmp((char *)xml_node2->name, "DayOfMonth"))
+ day_of_month = (char *)xmlNodeGetContent(xml_node2);
+ else if (!strcmp((char *)xml_node2->name, "DayOfWeekIndex"))
+ week_index = (char *)xmlNodeGetContent(xml_node2);
+ else if (!strcmp((char *)xml_node2->name, "Month"))
+ month = (char *)xmlNodeGetContent(xml_node2);
+ }
} else if (!strcmp((char *)xml_node->name, "RelativeMonthlyRecurrence")) {
- fprintf(stderr, "Cannot yet handle %s\n", xml_node->name);
+ for (xml_node2 = xml_node->children; xml_node2;
+ xml_node2 = xml_node2->next) {
+ if (xml_node2->type != XML_ELEMENT_NODE)
+ continue;
+ if (!strcmp((char *)xml_node2->name, "DaysOfWeek"))
+ weekday = (char *)xmlNodeGetContent(xml_node2);
+ else if (!strcmp((char *)xml_node2->name, "Interval"))
+ monthly_interval = (char *)xmlNodeGetContent(xml_node2);
+ else if (!strcmp((char *)xml_node2->name, "DayOfWeekIndex"))
+ week_index = (char *)xmlNodeGetContent(xml_node2);
+ }
} else if (!strcmp((char *)xml_node->name, "EndDateRecurrence")) {
for (xml_node2 = xml_node->children; xml_node2;
xml_node2 = xml_node2->next) {
}
if (daily_interval) {
fprintf(calfile, "RRULE:FREQ=DAILY;INTERVAL=%s", daily_interval);
+ } else if (weekday && month && week_index) {
+ int monthnr = month_to_number(month);
+ int week = weekindex_to_ical(week_index);
+ const char *weekday_ical = weekday_to_ical(weekday);
+ if (!monthnr || !week || !weekday_ical)
+ return -1;
+
+ fprintf(calfile, "RRULE:FREQ=YEARLY;MONTH=%d;BYDAY=%d%s",
+ monthnr, week, weekday_ical);
+ /* Relative Yearly */
+ } else if (monthly_interval && weekday && week_index) {
+ int week = weekindex_to_ical(week_index);
+ const char *weekday_ical = weekday_to_ical(weekday);
+ if (!week || !weekday_ical)
+ return -1;
+ fprintf(calfile, "RRULE:FREQ=MONTHLY;INTERVAL=%s;BYDAY=%d%s",
+ monthly_interval, week, weekday_ical);
} else if (day_of_month && month) {
- int monthnr;
- for (monthnr = 0; monthnr < 12; monthnr++)
- if (!strcmp(month, months[monthnr]))
- break;
- if (monthnr == 12) {
- fprintf(stderr, "Unrecognised month name '%s'\n", month);
+ int monthnr = month_to_number(month);
+ if (!monthnr)
return -1;
- }
fprintf(calfile, "RRULE:FREQ=YEARLY;BYMONTH=%d;BYMONTHDAY=%s",
- monthnr+1, day_of_month);
+ monthnr, day_of_month);
+ } else if (monthly_interval && day_of_month) {
+ fprintf(calfile, "RRULE:FREQ=MONTHLY;INTERVAL=%s;BYMONTHDAY=%s",
+ monthly_interval, day_of_month);
} else if (weekly_interval && weekday) {
char day[3];
day[0] = toupper(weekday[0]);