From 2245a35be602ae03e0c8e548c48d261741f13524 Mon Sep 17 00:00:00 2001
From: Frederic Culot <calcurse@culot.org>
Date: Mon, 29 Sep 2008 06:27:53 +0000
Subject: 2.3_beta released

---
 src/io.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 73 insertions(+), 14 deletions(-)

(limited to 'src')

diff --git a/src/io.c b/src/io.c
index ed7bbf0..243128d 100755
--- a/src/io.c
+++ b/src/io.c
@@ -1,4 +1,4 @@
-/*	$calcurse: io.c,v 1.39 2008/09/24 19:06:02 culot Exp $	*/
+/*	$calcurse: io.c,v 1.40 2008/09/29 06:27:53 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -1722,6 +1722,42 @@ ical_dur2long (char *durstr)
   return durlong;
 }
 
+/*
+ * Compute the vevent repetition end date from the repetition count.
+ *
+ * Extract from RFC2445:
+ * The COUNT rule part defines the number of occurrences at which to
+ * range-bound the recurrence. The "DTSTART" property value, if specified,
+ * counts as the first occurrence.
+ */
+static long
+ical_compute_rpt_until (long start, ical_rpt_t *rpt)
+{
+  long until;
+
+  switch (rpt->type)
+    {
+    case RECUR_DAILY:
+      until = date_sec_change (start, 0,  rpt->freq * (rpt->count - 1));
+      break;
+    case RECUR_WEEKLY:
+      until = date_sec_change (start, 0,
+                               rpt->freq * WEEKINDAYS * (rpt->count - 1));
+      break;
+    case RECUR_MONTHLY:
+      until = date_sec_change (start, rpt->freq * (rpt->count - 1), 0);
+      break;
+    case RECUR_YEARLY:
+      until = date_sec_change (start, rpt->freq * 12 * (rpt->count - 1), 0);
+      break;
+    default:
+      until = 0;
+      break;
+      /* NOTREACHED */
+    }
+  return until;
+}
+
 /*
  * Read a recurrence rule from an iCalendar RRULE string.
  *
@@ -1767,9 +1803,11 @@ ical_read_rrule (FILE *log, char *rrulestr, unsigned *noskipped,
   const string_t weekly = STRING_BUILD ("WEEKLY");
   const string_t monthly = STRING_BUILD ("MONTHLY");
   const string_t yearly = STRING_BUILD ("YEARLY");
+  const string_t count = STRING_BUILD ("COUNT=");
+  const string_t interv = STRING_BUILD ("INTERVAL=");
   unsigned interval;
   ical_rpt_t *rpt;
-  char *p, *q;
+  char *p;
 
   rpt = NULL;
   if ((p = strchr (rrulestr, ':')) != NULL)
@@ -1778,6 +1816,7 @@ ical_read_rrule (FILE *log, char *rrulestr, unsigned *noskipped,
                   
       p++;
       rpt = malloc (sizeof (ical_rpt_t));
+      bzero (rpt, sizeof (ical_rpt_t));
       if (sscanf (p, "FREQ=%s", freqstr) != 1)
         {
           ical_log (log, ICAL_VEVENT, itemline,
@@ -1815,35 +1854,51 @@ ical_read_rrule (FILE *log, char *rrulestr, unsigned *noskipped,
         range-bound the recurrence.  The "DTSTART" property value, if
         specified, counts as the first occurrence.
       */
-      if ((q = strstr (p, "UNTIL")) != NULL)
+      if ((p = strstr (rrulestr, "UNTIL")) != NULL)
         {
           char *untilstr;
 
-          untilstr = strchr (q, '=');
+          untilstr = strchr (p, '=');
           rpt->until = ical_datetime2long (++untilstr, NULL);
         }
       else
         {
-          unsigned count;
+          unsigned cnt;
+          char *countstr;
 
-          if (sscanf (p, "COUNT=%u", &count) != 1)
+          if ((countstr = strstr (rrulestr, count.str)) != NULL)
             {
-              rpt->until = 0;
-              /* endless repetition */
+              countstr += count.len;
+              if (sscanf (countstr, "%u", &cnt) != 1)
+                {
+                  rpt->until = 0;
+                  /* endless repetition */
+                }
+              else
+                {
+                  rpt->count = cnt;
+                }
             }
           else
-            {
-              rpt->count = count;
-            }
+            rpt->until = 0;
         }
-      if (sscanf (p, "INTERVAL=%u", &interval) == 1)
+
+      if ((p = strstr (rrulestr, interv.str)) != NULL)
         {
-          rpt->freq = interval;
+          p += interv.len;
+          if (sscanf (p, "%u", &interval) != 1)
+            {
+              rpt->freq = 1;
+              /* default frequence if none specified */
+            }
+          else
+            {
+              rpt->freq = interval;
+            }
         }
       else
         {
           rpt->freq = 1;
-          /* default frequence if none specified */
         }
     }
   else
@@ -2024,6 +2079,10 @@ ical_read_event (FILE *fdi, FILE *log, unsigned *noevents, unsigned *noapoints,
         {
           if (vevent.mesg)
             {
+              if (vevent.rpt && vevent.rpt->count)
+                vevent.rpt->until = ical_compute_rpt_until (vevent.start,
+                                                            vevent.rpt);
+              
               switch (vevent_type)
                 {
                 case APPOINTMENT:
-- 
cgit v1.2.3-70-g09d2