From 9fab24818a119aef08b9726f6c1cd31d5434ce34 Mon Sep 17 00:00:00 2001
From: Lukas Fleischer <calcurse@cryptocrack.de>
Date: Sat, 16 Apr 2011 15:20:42 +0200
Subject: Use generic lists for recurring apointments and events.

Use them instead of "recur_apoint_list" and "next" pointers in
"recur_event" type variables. Includes some code simplifications and
cleanups.

Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
---
 src/args.c     | 104 ++++++------
 src/calcurse.h |  11 +-
 src/day.c      |  96 +++++------
 src/io.c       | 125 +++++++-------
 src/recur.c    | 503 +++++++++++++++++++++++++--------------------------------
 5 files changed, 373 insertions(+), 466 deletions(-)

(limited to 'src')

diff --git a/src/args.c b/src/args.c
index 18a8887..374e872 100644
--- a/src/args.c
+++ b/src/args.c
@@ -352,8 +352,6 @@ app_arg (int add_line, struct date *day, long date, int print_note,
          struct conf *conf, regex_t *regex)
 {
   llist_item_t *i;
-  struct recur_event *re;
-  struct recur_apoint *ra;
   long today;
   unsigned print_date = 1;
   int app_found = 0;
@@ -370,31 +368,28 @@ app_arg (int add_line, struct date *day, long date, int print_note,
    * that date and it is the first one, and then print all the events for
    * that date.
    */
-  for (re = recur_elist; re != NULL; re = re->next)
+  LLIST_FIND_FOREACH (&recur_elist, today, recur_event_inday, i)
     {
-      if (recur_item_inday (re->day, re->exc, re->rpt->type, re->rpt->freq,
-                            re->rpt->until, today))
-        {
-          if (regex && regexec (regex, re->mesg, 0, 0, 0) != 0)
-            continue;
+      struct recur_event *re = LLIST_GET_DATA (i);
+      if (regex && regexec (regex, re->mesg, 0, 0, 0) != 0)
+        continue;
 
-          app_found = 1;
-          if (add_line)
-            {
-              fputs ("\n", stdout);
-              add_line = 0;
-            }
-          if (print_date)
-            {
-              arg_print_date (today, conf);
-              print_date = 0;
-            }
-          fputs (" * ", stdout);
-          fputs (re->mesg, stdout);
+      app_found = 1;
+      if (add_line)
+        {
           fputs ("\n", stdout);
-          if (print_note && re->note)
-            print_notefile (stdout, re->note, 2);
+          add_line = 0;
         }
+      if (print_date)
+        {
+          arg_print_date (today, conf);
+          print_date = 0;
+        }
+      fputs (" * ", stdout);
+      fputs (re->mesg, stdout);
+      fputs ("\n", stdout);
+      if (print_note && re->note)
+        print_notefile (stdout, re->note, 2);
     }
 
   LLIST_FIND_FOREACH (&eventlist, today, event_inday, i)
@@ -422,45 +417,42 @@ app_arg (int add_line, struct date *day, long date, int print_note,
     }
 
   /* Same process is performed but this time on the appointments. */
-  pthread_mutex_lock (&(recur_alist_p->mutex));
-  for (ra = recur_alist_p->root; ra != NULL; ra = ra->next)
+  LLIST_TS_LOCK (&recur_alist_p);
+  LLIST_TS_FIND_FOREACH (&recur_alist_p, today, recur_apoint_inday, i)
     {
-      if (recur_item_inday (ra->start, ra->exc, ra->rpt->type, ra->rpt->freq,
-                            ra->rpt->until, today))
-        {
-          struct apoint *apt;
+      struct recur_apoint *ra = LLIST_TS_GET_DATA (i);
+      struct apoint *apt;
 
-          if (regex && regexec (regex, ra->mesg, 0, 0, 0) != 0)
-            continue;
+      if (regex && regexec (regex, ra->mesg, 0, 0, 0) != 0)
+        continue;
 
-          app_found = 1;
-          if (add_line)
-            {
-              fputs ("\n", stdout);
-              add_line = 0;
-            }
-          if (print_date)
-            {
-              arg_print_date (today, conf);
-              print_date = 0;
-            }
-          apt = apoint_recur_s2apoint_s (ra);
-          apoint_sec2str (apt, RECUR_APPT, today, apoint_start_time,
-                          apoint_end_time);
-          mem_free (apt->mesg);
-          mem_free (apt);
-          fputs (" - ", stdout);
-          fputs (apoint_start_time, stdout);
-          fputs (" -> ", stdout);
-          fputs (apoint_end_time, stdout);
-          fputs ("\n\t", stdout);
-          fputs (ra->mesg, stdout);
+      app_found = 1;
+      if (add_line)
+        {
           fputs ("\n", stdout);
-          if (print_note && ra->note)
-            print_notefile (stdout, ra->note, 2);
+          add_line = 0;
         }
+      if (print_date)
+        {
+          arg_print_date (today, conf);
+          print_date = 0;
+        }
+      apt = apoint_recur_s2apoint_s (ra);
+      apoint_sec2str (apt, RECUR_APPT, today, apoint_start_time,
+                      apoint_end_time);
+      mem_free (apt->mesg);
+      mem_free (apt);
+      fputs (" - ", stdout);
+      fputs (apoint_start_time, stdout);
+      fputs (" -> ", stdout);
+      fputs (apoint_end_time, stdout);
+      fputs ("\n\t", stdout);
+      fputs (ra->mesg, stdout);
+      fputs ("\n", stdout);
+      if (print_note && ra->note)
+        print_notefile (stdout, ra->note, 2);
     }
-  pthread_mutex_unlock (&(recur_alist_p->mutex));
+  LLIST_TS_UNLOCK (&recur_alist_p);
 
   LLIST_TS_LOCK (&alist_p);
   LLIST_TS_FIND_FOREACH (&alist_p, today, apoint_inday, i)
diff --git a/src/calcurse.h b/src/calcurse.h
index 4981a59..a2b7bcc 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -334,15 +334,8 @@ struct recur_apoint {
   char                 *note;  /* note attached to appointment */
 };
 
-/* Recurrent appointments are stored in a linked-list. */
-struct recur_apoint_list {
-  struct recur_apoint  *root;
-  pthread_mutex_t       mutex;
-};
-
 /* Reccurent event definition. */
 struct recur_event {
-  struct recur_event  *next;
   struct rpt          *rpt;  /* information about repetition */
   struct days         *exc;  /* days when the item should not be repeated */
   int                  id;   /* event type */
@@ -768,8 +761,8 @@ int       notify_same_recur_item (struct recur_apoint *);
 void      notify_config_bar (void);
 
 /* recur.c */
-extern struct recur_apoint_list  *recur_alist_p;
-extern struct recur_event        *recur_elist;
+extern llist_ts_t recur_alist_p;
+extern llist_t recur_elist;
 void                  recur_event_free_bkp (enum eraseflg);
 void                  recur_apoint_free_bkp (enum eraseflg);
 void                  recur_apoint_llist_init (void);
diff --git a/src/day.c b/src/day.c
index f806b06..1bcbaef 100644
--- a/src/day.c
+++ b/src/day.c
@@ -168,17 +168,15 @@ day_store_events (long date)
 static int
 day_store_recur_events (long date)
 {
-  struct recur_event *j;
+  llist_item_t *i;
   int e_nb = 0;
 
-  for (j = recur_elist; j != NULL; j = j->next)
+  LLIST_FIND_FOREACH (&recur_elist, date, recur_event_inday, i)
     {
-      if (recur_item_inday (j->day, j->exc, j->rpt->type, j->rpt->freq,
-                            j->rpt->until, date))
-        {
-          e_nb++;
-          (void)day_add_event (RECUR_EVNT, j->mesg, j->note, j->day, j->id);
-        }
+      struct recur_event *rev = LLIST_TS_GET_DATA (i);
+      (void)day_add_event (RECUR_EVNT, rev->mesg, rev->note, rev->day,
+                           rev->id);
+      e_nb++;
     }
 
   return e_nb;
@@ -213,31 +211,26 @@ day_store_apoints (long date)
 /*
  * Store the recurrent apoints for the selected day in structure pointed
  * by day_items. This is done by copying the appointments
- * from the general structure pointed by recur_alist_p->root to the
+ * from the general structure pointed by recur_alist_p to the
  * structure dedicated to the selected day.
  * Returns the number of recurrent appointments for the selected day.
  */
 static int
 day_store_recur_apoints (long date)
 {
-  struct recur_apoint *j;
-  long real_start;
-  int a_nb = 0, n = 0;
+  llist_item_t *i;
+  int a_nb = 0;
 
-  pthread_mutex_lock (&(recur_alist_p->mutex));
-  for (j = recur_alist_p->root; j != NULL; j = j->next)
+  LLIST_TS_LOCK (&recur_alist_p);
+  LLIST_TS_FIND_FOREACH (&recur_alist_p, date, recur_apoint_inday, i)
     {
-      if ((real_start = recur_item_inday (j->start, j->exc,
-                                          j->rpt->type, j->rpt->freq,
-                                          j->rpt->until, date)))
-        {
-          a_nb++;
-          (void)day_add_apoint (RECUR_APPT, j->mesg, j->note,
-                                real_start, j->dur, j->state, n);
-          n++;
-        }
+      struct recur_apoint *rapt = LLIST_TS_GET_DATA (i);
+      int real_start = recur_apoint_inday (rapt, date);
+      (void)day_add_apoint (RECUR_APPT, rapt->mesg, rapt->note, real_start,
+                            rapt->dur, rapt->state, a_nb);
+      a_nb++;
     }
-  pthread_mutex_unlock (&(recur_alist_p->mutex));
+  LLIST_TS_UNLOCK (&recur_alist_p);
 
   return a_nb;
 }
@@ -467,24 +460,18 @@ day_popup_item (void)
 int
 day_check_if_item (struct date day)
 {
-  struct recur_event *re;
-  struct recur_apoint *ra;
   const long date = date2sec (day, 0, 0);
 
-  for (re = recur_elist; re != NULL; re = re->next)
-    if (recur_item_inday (re->day, re->exc, re->rpt->type,
-                          re->rpt->freq, re->rpt->until, date))
-      return (1);
+  if (LLIST_FIND_FIRST (&recur_elist, date, recur_event_inday))
+    return (1);
 
-  pthread_mutex_lock (&(recur_alist_p->mutex));
-  for (ra = recur_alist_p->root; ra != NULL; ra = ra->next)
-    if (recur_item_inday (ra->start, ra->exc, ra->rpt->type,
-                          ra->rpt->freq, ra->rpt->until, date))
-      {
-        pthread_mutex_unlock (&(recur_alist_p->mutex));
-        return (1);
-      }
-  pthread_mutex_unlock (&(recur_alist_p->mutex));
+  LLIST_TS_LOCK (&recur_alist_p);
+  if (LLIST_TS_FIND_FIRST (&recur_alist_p, date, recur_apoint_inday))
+    {
+      LLIST_TS_UNLOCK (&recur_alist_p);
+      return (1);
+    }
+  LLIST_TS_UNLOCK (&recur_alist_p);
 
   if (LLIST_FIND_FIRST (&eventlist, date, event_inday))
     return (1);
@@ -526,7 +513,6 @@ unsigned
 day_chk_busy_slices (struct date day, int slicesno, int *slices)
 {
   llist_item_t *i;
-  struct recur_apoint *ra;
   int slicelen;
   const long date = date2sec (day, 0, 0);
 
@@ -534,22 +520,20 @@ day_chk_busy_slices (struct date day, int slicesno, int *slices)
 
 #define  SLICENUM(tsec)  ((tsec) / slicelen % slicesno)
 
-  pthread_mutex_lock (&(recur_alist_p->mutex));
-  for (ra = recur_alist_p->root; ra != NULL; ra = ra->next)
-    if (recur_item_inday (ra->start, ra->exc, ra->rpt->type,
-                          ra->rpt->freq, ra->rpt->until, date))
-      {
-        long start, end;
-
-        start = get_item_time (ra->start);
-        end = get_item_time (ra->start + ra->dur);
-        if (!fill_slices (slices, slicesno, SLICENUM (start), SLICENUM (end)))
-          {
-            pthread_mutex_unlock (&(recur_alist_p->mutex));
-            return 0;
-          }
-      }
-  pthread_mutex_unlock (&(recur_alist_p->mutex));
+  LLIST_TS_LOCK (&recur_alist_p);
+  LLIST_TS_FIND_FOREACH (&recur_alist_p, date, recur_apoint_inday, i)
+    {
+      struct apoint *rapt = LLIST_TS_GET_DATA (i);
+      long start = get_item_time (rapt->start);
+      long end = get_item_time (rapt->start + rapt->dur);
+
+      if (!fill_slices (slices, slicesno, SLICENUM (start), SLICENUM (end)))
+        {
+          LLIST_TS_UNLOCK (&recur_alist_p);
+          return 0;
+        }
+    }
+  LLIST_TS_UNLOCK (&recur_alist_p);
 
   LLIST_TS_LOCK (&alist_p);
   LLIST_TS_FIND_FOREACH (&alist_p, date, apoint_inday, i)
diff --git a/src/io.c b/src/io.c
index d6f6565..9e1dcf6 100644
--- a/src/io.c
+++ b/src/io.c
@@ -342,31 +342,32 @@ pcal_export_footer (FILE *stream)
 static void
 ical_export_recur_events (FILE *stream)
 {
-  struct recur_event *i;
+  llist_item_t *i;
   struct days *day;
   char ical_date[BUFSIZ];
 
-  for (i = recur_elist; i != NULL; i = i->next)
+  LLIST_FOREACH (&recur_elist, i)
     {
-      date_sec2date_fmt (i->day, ICALDATEFMT, ical_date);
+      struct recur_event *rev = LLIST_GET_DATA (i);
+      date_sec2date_fmt (rev->day, ICALDATEFMT, ical_date);
       (void)fprintf (stream, "BEGIN:VEVENT\n");
       (void)fprintf (stream, "DTSTART:%s\n", ical_date);
       (void)fprintf (stream, "RRULE:FREQ=%s;INTERVAL=%d",
-                     ical_recur_type[i->rpt->type], i->rpt->freq);
+                     ical_recur_type[rev->rpt->type], rev->rpt->freq);
 
-      if (i->rpt->until != 0)
+      if (rev->rpt->until != 0)
         {
-          date_sec2date_fmt (i->rpt->until, ICALDATEFMT, ical_date);
+          date_sec2date_fmt (rev->rpt->until, ICALDATEFMT, ical_date);
           (void)fprintf (stream, ";UNTIL=%s\n", ical_date);
         }
       else
         (void)fprintf (stream, "\n");
 
-      if (i->exc != NULL)
+      if (rev->exc != NULL)
         {
-          date_sec2date_fmt (i->exc->st, ICALDATEFMT, ical_date);
+          date_sec2date_fmt (rev->exc->st, ICALDATEFMT, ical_date);
           (void)fprintf (stream, "EXDATE:%s", ical_date);
-          for (day = i->exc->next; day; day = day->next)
+          for (day = rev->exc->next; day; day = day->next)
             {
               date_sec2date_fmt (day->st, ICALDATEFMT, ical_date);
               (void)fprintf (stream, ",%s", ical_date);
@@ -374,7 +375,7 @@ ical_export_recur_events (FILE *stream)
           (void)fprintf (stream, "\n");
         }
 
-      (void)fprintf (stream, "SUMMARY:%s\n", i->mesg);
+      (void)fprintf (stream, "SUMMARY:%s\n", rev->mesg);
       (void)fprintf (stream, "END:VEVENT\n");
     }
 }
@@ -407,7 +408,7 @@ pcal_dump_apoint (FILE *stream, long apoint_date, long apoint_dur,
 static void
 pcal_export_recur_events (FILE *stream)
 {
-  struct recur_event *i;
+  llist_item_t *i;
   char pcal_date[BUFSIZ];
 
   (void)fprintf (stream, "\n# =============");
@@ -416,30 +417,32 @@ pcal_export_recur_events (FILE *stream)
   (void)fprintf (stream,
                  "# (pcal does not support from..until dates specification\n");
 
-  for (i = recur_elist; i != NULL; i = i->next)
+  LLIST_FOREACH (&recur_elist, i)
     {
-      if (i->rpt->until == 0 && i->rpt->freq == 1)
+      struct recur_event *rev = LLIST_GET_DATA (i);
+      if (rev->rpt->until == 0 && rev->rpt->freq == 1)
         {
-          switch (i->rpt->type)
+          switch (rev->rpt->type)
             {
             case RECUR_DAILY:
-              date_sec2date_fmt (i->day, "%b %d", pcal_date);
+              date_sec2date_fmt (rev->day, "%b %d", pcal_date);
               (void)fprintf (stream, "all day on_or_after %s  %s\n",
-                             pcal_date, i->mesg);
+                             pcal_date, rev->mesg);
               break;
             case RECUR_WEEKLY:
-              date_sec2date_fmt (i->day, "%a", pcal_date);
+              date_sec2date_fmt (rev->day, "%a", pcal_date);
               (void)fprintf (stream, "all %s on_or_after ", pcal_date);
-              date_sec2date_fmt (i->day, "%b %d", pcal_date);
-              (void)fprintf (stream, "%s  %s\n", pcal_date, i->mesg);
+              date_sec2date_fmt (rev->day, "%b %d", pcal_date);
+              (void)fprintf (stream, "%s  %s\n", pcal_date, rev->mesg);
               break;
             case RECUR_MONTHLY:
-              date_sec2date_fmt (i->day, "%d", pcal_date);
-              (void)fprintf (stream, "day on all %s  %s\n", pcal_date, i->mesg);
+              date_sec2date_fmt (rev->day, "%d", pcal_date);
+              (void)fprintf (stream, "day on all %s  %s\n", pcal_date,
+                             rev->mesg);
               break;
             case RECUR_YEARLY:
-              date_sec2date_fmt (i->day, "%b %d", pcal_date);
-              (void)fprintf (stream, "%s  %s\n", pcal_date, i->mesg);
+              date_sec2date_fmt (rev->day, "%b %d", pcal_date);
+              (void)fprintf (stream, "%s  %s\n", pcal_date, rev->mesg);
               break;
             default:
               EXIT (_("incoherent repetition type"));
@@ -450,9 +453,9 @@ pcal_export_recur_events (FILE *stream)
           const long YEAR_START = calendar_start_of_year ();
           const long YEAR_END = calendar_end_of_year ();
 
-          if (i->day < YEAR_END && i->day > YEAR_START)
-            foreach_date_dump (YEAR_END, i->rpt, i->exc, i->day, 0, i->mesg,
-                               (cb_dump_t) pcal_dump_event, stream);
+          if (rev->day < YEAR_END && rev->day > YEAR_START)
+            foreach_date_dump (YEAR_END, rev->rpt, rev->exc, rev->day, 0,
+                               rev->mesg, (cb_dump_t) pcal_dump_event, stream);
         }
     }
 }
@@ -493,34 +496,37 @@ pcal_export_events (FILE *stream)
 static void
 ical_export_recur_apoints (FILE *stream)
 {
-  struct recur_apoint *i;
+  llist_item_t *i;
   struct days *day;
   char ical_datetime[BUFSIZ];
   char ical_date[BUFSIZ];
 
-  pthread_mutex_lock (&(recur_alist_p->mutex));
-  for (i = recur_alist_p->root; i != NULL; i = i->next)
+  LLIST_TS_LOCK (&recur_alist_p);
+  LLIST_TS_FOREACH (&recur_alist_p, i)
     {
-      date_sec2date_fmt (i->start, ICALDATETIMEFMT, ical_datetime);
+      struct recur_apoint *rapt = LLIST_TS_GET_DATA (i);
+
+      date_sec2date_fmt (rapt->start, ICALDATETIMEFMT, ical_datetime);
       (void)fprintf (stream, "BEGIN:VEVENT\n");
       (void)fprintf (stream, "DTSTART:%s\n", ical_datetime);
-      (void)fprintf (stream, "DURATION:PT0H0M%ldS\n", i->dur);
+      (void)fprintf (stream, "DURATION:PT0H0M%ldS\n", rapt->dur);
       (void)fprintf (stream, "RRULE:FREQ=%s;INTERVAL=%d",
-                     ical_recur_type[i->rpt->type], i->rpt->freq);
+                     ical_recur_type[rapt->rpt->type], rapt->rpt->freq);
 
-      if (i->rpt->until != 0)
+      if (rapt->rpt->until != 0)
         {
-          date_sec2date_fmt (i->rpt->until + HOURINSEC, ICALDATEFMT, ical_date);
+          date_sec2date_fmt (rapt->rpt->until + HOURINSEC, ICALDATEFMT,
+                             ical_date);
           (void)fprintf (stream, ";UNTIL=%s\n", ical_date);
         }
       else
         (void)fprintf (stream, "\n");
 
-      if (i->exc != NULL)
+      if (rapt->exc != NULL)
         {
-          date_sec2date_fmt (i->exc->st, ICALDATEFMT, ical_date);
+          date_sec2date_fmt (rapt->exc->st, ICALDATEFMT, ical_date);
           (void)fprintf (stream, "EXDATE:%s", ical_date);
-          for (day = i->exc->next; day; day = day->next)
+          for (day = rapt->exc->next; day; day = day->next)
             {
               date_sec2date_fmt (day->st, ICALDATEFMT, ical_date);
               (void)fprintf (stream, ",%s", ical_date);
@@ -528,18 +534,18 @@ ical_export_recur_apoints (FILE *stream)
           (void)fprintf (stream, "\n");
         }
 
-      (void)fprintf (stream, "SUMMARY:%s\n", i->mesg);
-      if (i->state & APOINT_NOTIFY)
+      (void)fprintf (stream, "SUMMARY:%s\n", rapt->mesg);
+      if (rapt->state & APOINT_NOTIFY)
         ical_export_valarm (stream);
       (void)fprintf (stream, "END:VEVENT\n");
     }
-  pthread_mutex_unlock (&(recur_alist_p->mutex));
+  LLIST_TS_UNLOCK (&recur_alist_p);
 }
 
 static void
 pcal_export_recur_apoints (FILE *stream)
 {
-  struct recur_apoint *i;
+  llist_item_t *i;
   char pcal_date[BUFSIZ], pcal_beg[BUFSIZ], pcal_end[BUFSIZ];
 
   (void)fprintf (stream, "\n# ==============");
@@ -548,35 +554,37 @@ pcal_export_recur_apoints (FILE *stream)
   (void)fprintf (stream,
                  "# (pcal does not support from..until dates specification\n");
 
-  for (i = recur_alist_p->root; i != NULL; i = i->next)
+  LLIST_TS_FOREACH (&recur_alist_p, i)
     {
-      if (i->rpt->until == 0 && i->rpt->freq == 1)
+      struct recur_apoint *rapt = LLIST_TS_GET_DATA (i);
+
+      if (rapt->rpt->until == 0 && rapt->rpt->freq == 1)
         {
-          date_sec2date_fmt (i->start, "%R", pcal_beg);
-          date_sec2date_fmt (i->start + i->dur, "%R", pcal_end);
-          switch (i->rpt->type)
+          date_sec2date_fmt (rapt->start, "%R", pcal_beg);
+          date_sec2date_fmt (rapt->start + rapt->dur, "%R", pcal_end);
+          switch (rapt->rpt->type)
             {
             case RECUR_DAILY:
-              date_sec2date_fmt (i->start, "%b %d", pcal_date);
+              date_sec2date_fmt (rapt->start, "%b %d", pcal_date);
               (void)fprintf (stream, "all day on_or_after %s  (%s -> %s) %s\n",
-                             pcal_date, pcal_beg, pcal_end, i->mesg);
+                             pcal_date, pcal_beg, pcal_end, rapt->mesg);
               break;
             case RECUR_WEEKLY:
-              date_sec2date_fmt (i->start, "%a", pcal_date);
+              date_sec2date_fmt (rapt->start, "%a", pcal_date);
               (void)fprintf (stream, "all %s on_or_after ", pcal_date);
-              date_sec2date_fmt (i->start, "%b %d", pcal_date);
+              date_sec2date_fmt (rapt->start, "%b %d", pcal_date);
               (void)fprintf (stream, "%s  (%s -> %s) %s\n", pcal_date,
-                             pcal_beg, pcal_end, i->mesg);
+                             pcal_beg, pcal_end, rapt->mesg);
               break;
             case RECUR_MONTHLY:
-              date_sec2date_fmt (i->start, "%d", pcal_date);
+              date_sec2date_fmt (rapt->start, "%d", pcal_date);
               (void)fprintf (stream, "day on all %s  (%s -> %s) %s\n",
-                             pcal_date, pcal_beg, pcal_end, i->mesg);
+                             pcal_date, pcal_beg, pcal_end, rapt->mesg);
               break;
             case RECUR_YEARLY:
-              date_sec2date_fmt (i->start, "%b %d", pcal_date);
+              date_sec2date_fmt (rapt->start, "%b %d", pcal_date);
               (void)fprintf (stream, "%s  (%s -> %s) %s\n", pcal_date,
-                             pcal_beg, pcal_end, i->mesg);
+                             pcal_beg, pcal_end, rapt->mesg);
               break;
             default:
               EXIT (_("incoherent repetition type"));
@@ -587,9 +595,10 @@ pcal_export_recur_apoints (FILE *stream)
           const long YEAR_START = calendar_start_of_year ();
           const long YEAR_END = calendar_end_of_year ();
 
-          if (i->start < YEAR_END && i->start > YEAR_START)
-            foreach_date_dump (YEAR_END, i->rpt, i->exc, i->start, i->dur,
-                               i->mesg, (cb_dump_t)pcal_dump_apoint, stream);
+          if (rapt->start < YEAR_END && rapt->start > YEAR_START)
+            foreach_date_dump (YEAR_END, rapt->rpt, rapt->exc, rapt->start,
+                               rapt->dur, rapt->mesg,
+                               (cb_dump_t)pcal_dump_apoint, stream);
         }
     }
 }
diff --git a/src/recur.c b/src/recur.c
index c781c01..f037abf 100644
--- a/src/recur.c
+++ b/src/recur.c
@@ -42,10 +42,10 @@
 
 #include "calcurse.h"
 
-struct recur_apoint_list         *recur_alist_p;
-struct recur_event               *recur_elist;
-static struct recur_event         bkp_cut_recur_event;
-static struct recur_apoint        bkp_cut_recur_apoint;
+llist_ts_t                 recur_alist_p;
+llist_t                    recur_elist;
+static struct recur_event  bkp_cut_recur_event;
+static struct recur_apoint bkp_cut_recur_apoint;
 
 
 static void
@@ -179,58 +179,65 @@ recur_apoint_dup (struct recur_apoint *in, struct recur_apoint *bkp)
 void
 recur_apoint_llist_init (void)
 {
-  recur_alist_p = mem_malloc (sizeof (struct recur_apoint_list));
-  recur_alist_p->root = NULL;
-  pthread_mutex_init (&(recur_alist_p->mutex), NULL);
+  LLIST_TS_INIT (&recur_alist_p);
 }
 
-void
-recur_apoint_llist_free (void)
+static void
+recur_apoint_free (struct recur_apoint *rapt)
 {
-  struct recur_apoint *o, **i;
+  mem_free (rapt->mesg);
+  if (rapt->note)
+    mem_free (rapt->note);
+  if (rapt->rpt)
+    mem_free (rapt->rpt);
+  if (rapt->exc)
+    {
+      free_exc (rapt->exc);
+      rapt->exc = 0;
+    }
+  mem_free (rapt);
+}
 
-  i = &recur_alist_p->root;
-  while (*i)
+static void
+recur_event_free (struct recur_event *rev)
+{
+  mem_free (rev->mesg);
+  if (rev->note)
+    mem_free (rev->note);
+  if (rev->rpt)
+    mem_free (rev->rpt);
+  if (rev->exc)
     {
-      o = *i;
-      *i = o->next;
-      mem_free (o->mesg);
-      if (o->note)
-        mem_free (o->note);
-      if (o->rpt)
-        mem_free (o->rpt);
-      if (o->exc)
-        {
-          free_exc (o->exc);
-          o->exc = 0;
-        }
-      mem_free (o);
+      free_exc (rev->exc);
+      rev->exc = 0;
     }
-  mem_free (recur_alist_p);
+  mem_free (rev);
+}
+
+void
+recur_apoint_llist_free (void)
+{
+  LLIST_TS_FREE_INNER (&recur_alist_p, recur_apoint_free);
+  LLIST_TS_FREE (&recur_alist_p);
 }
 
 void
 recur_event_llist_free (void)
 {
-  struct recur_event *o, **i;
+  LLIST_FREE_INNER (&recur_elist, recur_event_free);
+  LLIST_FREE (&recur_elist);
+}
 
-  i = &recur_elist;
-  while (*i)
-    {
-      o = *i;
-      *i = o->next;
-      mem_free (o->mesg);
-      if (o->note)
-        mem_free (o->note);
-      if (o->rpt)
-        mem_free (o->rpt);
-      if (o->exc)
-        {
-          free_exc (o->exc);
-          o->exc = 0;
-        }
-      mem_free (o);
-    }
+static int
+recur_apoint_cmp_start (struct recur_apoint *a, struct recur_apoint *b)
+{
+  return (a->start < b->start ? -1 : (a->start == b->start ? 0 : 1));
+}
+
+static int
+recur_event_cmp_day (struct recur_event *a, struct recur_event *b)
+{
+  return (a->day < b->day ? -1 : (a->day == b->day ? 0 : 1));
 }
 
 /* Insert a new recursive appointment in the general linked list */
@@ -238,41 +245,30 @@ struct recur_apoint *
 recur_apoint_new (char *mesg, char *note, long start, long dur, char state,
                   int type, int freq, long until, struct days **except)
 {
-  struct recur_apoint *o, **i;
-
-  o = mem_malloc (sizeof (struct recur_apoint));
-  o->rpt = mem_malloc (sizeof (struct rpt));
-  o->mesg = mem_strdup (mesg);
-  o->note = (note != NULL) ? mem_strdup (note) : 0;
-  o->start = start;
-  o->state = state;
-  o->dur = dur;
-  o->rpt->type = type;
-  o->rpt->freq = freq;
-  o->rpt->until = until;
-  o->exc = 0;
+  struct recur_apoint *rapt = mem_malloc (sizeof (struct recur_apoint));
+
+  rapt->rpt = mem_malloc (sizeof (struct rpt));
+  rapt->mesg = mem_strdup (mesg);
+  rapt->note = (note != NULL) ? mem_strdup (note) : 0;
+  rapt->start = start;
+  rapt->state = state;
+  rapt->dur = dur;
+  rapt->rpt->type = type;
+  rapt->rpt->freq = freq;
+  rapt->rpt->until = until;
+  rapt->exc = 0;
   if (except && *except)
     {
-      exc_dup (&o->exc, *except);
+      exc_dup (&rapt->exc, *except);
       free_exc (*except);
       *except = 0;
     }
 
-  pthread_mutex_lock (&(recur_alist_p->mutex));
-  i = &recur_alist_p->root;
-  for (;;)
-    {
-      if (*i == NULL || (*i)->start > start)
-        {
-          o->next = *i;
-          *i = o;
-          break;
-        }
-      i = &(*i)->next;
-    }
-  pthread_mutex_unlock (&(recur_alist_p->mutex));
+  LLIST_TS_LOCK (&recur_alist_p);
+  LLIST_TS_ADD_SORTED (&recur_alist_p, rapt, recur_apoint_cmp_start);
+  LLIST_TS_UNLOCK (&recur_alist_p);
 
-  return (o);
+  return rapt;
 }
 
 /* Insert a new recursive event in the general linked list */
@@ -280,37 +276,27 @@ struct recur_event *
 recur_event_new (char *mesg, char *note, long day, int id, int type, int freq,
                  long until, struct days **except)
 {
-  struct recur_event *o, **i;
-
-  o = mem_malloc (sizeof (struct recur_event));
-  o->rpt = mem_malloc (sizeof (struct rpt));
-  o->mesg = mem_strdup (mesg);
-  o->note = (note != NULL) ? mem_strdup (note) : 0;
-  o->day = day;
-  o->id = id;
-  o->rpt->type = type;
-  o->rpt->freq = freq;
-  o->rpt->until = until;
-  o->exc = 0;
+  struct recur_event *rev = mem_malloc (sizeof (struct recur_event));
+
+  rev->rpt = mem_malloc (sizeof (struct rpt));
+  rev->mesg = mem_strdup (mesg);
+  rev->note = (note != NULL) ? mem_strdup (note) : 0;
+  rev->day = day;
+  rev->id = id;
+  rev->rpt->type = type;
+  rev->rpt->freq = freq;
+  rev->rpt->until = until;
+  rev->exc = 0;
   if (except && *except)
     {
-      exc_dup (&o->exc, *except);
+      exc_dup (&rev->exc, *except);
       free_exc (*except);
       *except = 0;
     }
 
-  i = &recur_elist;
-  for (;;)
-    {
-      if (*i == NULL || (*i)->day > day)
-        {
-          o->next = *i;
-          *i = o;
-          break;
-        }
-      i = &(*i)->next;
-    }
-  return (o);
+  LLIST_ADD_SORTED (&recur_elist, rev, recur_event_cmp_day);
+
+  return rev;
 }
 
 /*
@@ -566,16 +552,21 @@ recur_event_write (struct recur_event *o, FILE *f)
 void
 recur_save_data (FILE *f)
 {
-  struct recur_event *re;
-  struct recur_apoint *ra;
+  llist_item_t *i;
 
-  for (re = recur_elist; re != NULL; re = re->next)
-    recur_event_write (re, f);
+  LLIST_FOREACH (&recur_elist, i)
+    {
+      struct recur_event *rev = LLIST_GET_DATA (i);
+      recur_event_write (rev, f);
+    }
 
-  pthread_mutex_lock (&(recur_alist_p->mutex));
-  for (ra = recur_alist_p->root; ra != NULL; ra = ra->next)
-    recur_apoint_write (ra, f);
-  pthread_mutex_unlock (&(recur_alist_p->mutex));
+  LLIST_TS_LOCK (&recur_alist_p);
+  LLIST_TS_FOREACH (&recur_alist_p, i)
+    {
+      struct recur_apoint *rapt = LLIST_GET_DATA (i);
+      recur_apoint_write (rapt, f);
+    }
+  LLIST_TS_UNLOCK (&recur_alist_p);
 }
 
 
@@ -750,61 +741,47 @@ void
 recur_event_erase (long start, unsigned num, unsigned delete_whole,
                    enum eraseflg flag)
 {
-  unsigned n = 0;
-  struct recur_event *i, **iptr;
+  llist_item_t *i;
+ 
+  i = LLIST_FIND_NTH (&recur_elist, num, start, recur_event_inday);
+
+  if (!i)
+    EXIT (_("event not found"));
+  struct recur_event *rev = LLIST_GET_DATA (i);
 
-  iptr = &recur_elist;
-  for (i = recur_elist; i != NULL; i = i->next)
+  if (delete_whole)
     {
-      if (recur_item_inday (i->day, i->exc, i->rpt->type,
-                            i->rpt->freq, i->rpt->until, start))
+      switch (flag)
         {
-          if (n == num)
+        case ERASE_FORCE_ONLY_NOTE:
+          erase_note (&rev->note, flag);
+          break;
+        case ERASE_CUT:
+          recur_event_free_bkp (ERASE_FORCE);
+          recur_event_dup (rev, &bkp_cut_recur_event);
+          erase_note (&rev->note, ERASE_FORCE_KEEP_NOTE);
+          /* FALLTHROUGH */
+        default:
+          LLIST_REMOVE (&recur_elist, i);
+          mem_free (rev->mesg);
+          if (rev->rpt)
             {
-              if (delete_whole)
-                {
-                  switch (flag)
-                    {
-                    case ERASE_FORCE_ONLY_NOTE:
-                      erase_note (&i->note, flag);
-                      break;
-                    case ERASE_CUT:
-                      recur_event_free_bkp (ERASE_FORCE);
-                      recur_event_dup (i, &bkp_cut_recur_event);
-                      erase_note (&i->note, ERASE_FORCE_KEEP_NOTE);
-                      /* FALLTHROUGH */
-                    default:
-                      *iptr = i->next;
-                      mem_free (i->mesg);
-                      if (i->rpt)
-                        {
-                          mem_free (i->rpt);
-                          i->rpt = 0;
-                        }
-                      if (i->exc)
-                        {
-                          free_exc (i->exc);
-                          i->exc = 0;
-                        }
-                      if (flag != ERASE_FORCE_KEEP_NOTE && flag != ERASE_CUT)
-                        erase_note (&i->note, flag);
-                      mem_free (i);
-                      break;
-                    }
-                  return;
-                }
-              else
-                {
-                  recur_add_exc (&i->exc, start);
-                  return;
-                }
+              mem_free (rev->rpt);
+              rev->rpt = 0;
+            }
+          if (rev->exc)
+            {
+              free_exc (rev->exc);
+              rev->exc = 0;
             }
-          n++;
+          if (flag != ERASE_FORCE_KEEP_NOTE && flag != ERASE_CUT)
+            erase_note (&rev->note, flag);
+          mem_free (rev);
+          break;
         }
-      iptr = &i->next;
     }
-  EXIT (_("event not found"));
-  /* NOTREACHED */
+  else
+    recur_add_exc (&rev->exc, start);
 }
 
 /*
@@ -815,71 +792,58 @@ void
 recur_apoint_erase (long start, unsigned num, unsigned delete_whole,
                     enum eraseflg flag)
 {
-  unsigned n = 0;
-  struct recur_apoint *i, **iptr;
+  llist_item_t *i;
   int need_check_notify = 0;
+ 
+  i = LLIST_TS_FIND_NTH (&recur_alist_p, num, start, recur_apoint_inday);
 
-  pthread_mutex_lock (&(recur_alist_p->mutex));
-  iptr = &recur_alist_p->root;
-  for (i = recur_alist_p->root; i != NULL; i = i->next)
+  if (!i)
+    EXIT (_("appointment not found"));
+  struct recur_apoint *rapt = LLIST_GET_DATA (i);
+
+  LLIST_TS_LOCK (&recur_alist_p);
+  if (notify_bar () && flag != ERASE_FORCE_ONLY_NOTE)
+    need_check_notify = notify_same_recur_item (rapt);
+  if (delete_whole)
     {
-      if (recur_item_inday (i->start, i->exc, i->rpt->type,
-                            i->rpt->freq, i->rpt->until, start))
+      switch (flag)
         {
-          if (n == num)
+        case ERASE_FORCE_ONLY_NOTE:
+          erase_note (&rapt->note, flag);
+          break;
+        case ERASE_CUT:
+          recur_apoint_free_bkp (ERASE_FORCE);
+          recur_apoint_dup (rapt, &bkp_cut_recur_apoint);
+          erase_note (&rapt->note, ERASE_FORCE_KEEP_NOTE);
+          /* FALLTHROUGH */
+        default:
+          LLIST_TS_REMOVE (&recur_alist_p, i);
+          mem_free (rapt->mesg);
+          if (rapt->rpt)
             {
-              if (notify_bar () && flag != ERASE_FORCE_ONLY_NOTE)
-                need_check_notify = notify_same_recur_item (i);
-              if (delete_whole)
-                {
-                  switch (flag)
-                    {
-                    case ERASE_FORCE_ONLY_NOTE:
-                      erase_note (&i->note, flag);
-                      break;
-                    case ERASE_CUT:
-                      recur_apoint_free_bkp (ERASE_FORCE);
-                      recur_apoint_dup (i, &bkp_cut_recur_apoint);
-                      erase_note (&i->note, ERASE_FORCE_KEEP_NOTE);
-                      /* FALLTHROUGH */
-                    default:
-                      *iptr = i->next;
-                      mem_free (i->mesg);
-                      if (i->rpt)
-                        {
-                          mem_free (i->rpt);
-                          i->rpt = 0;
-                        }
-                      if (i->exc)
-                        {
-                          free_exc (i->exc);
-                          i->exc = 0;
-                        }
-                      if (flag != ERASE_FORCE_KEEP_NOTE && flag != ERASE_CUT)
-                        erase_note (&i->note, flag);
-                      mem_free (i);
-                      pthread_mutex_unlock (&(recur_alist_p->mutex));
-                      if (need_check_notify)
-                        notify_check_next_app ();
-                      break;
-                    }
-                  return;
-                }
-              else
-                {
-                  recur_add_exc (&i->exc, start);
-                  pthread_mutex_unlock (&(recur_alist_p->mutex));
-                  if (need_check_notify)
-                    notify_check_next_app ();
-                  return;
-                }
+              mem_free (rapt->rpt);
+              rapt->rpt = 0;
             }
-          n++;
+          if (rapt->exc)
+            {
+              free_exc (rapt->exc);
+              rapt->exc = 0;
+            }
+          if (flag != ERASE_FORCE_KEEP_NOTE && flag != ERASE_CUT)
+            erase_note (&rapt->note, flag);
+          mem_free (rapt);
+          if (need_check_notify)
+            notify_check_next_app ();
+          break;
         }
-      iptr = &i->next;
     }
-  EXIT (_("appointment not found"));
-  /* NOTREACHED */
+  else
+    {
+      recur_add_exc (&rapt->exc, start);
+      if (need_check_notify)
+        notify_check_next_app ();
+    }
+  LLIST_TS_UNLOCK (&recur_alist_p);
 }
 
 /*
@@ -1064,6 +1028,12 @@ recur_exc_scan (FILE *data_file)
   return exc_head;
 }
 
+static int
+recur_apoint_starts_after (struct recur_apoint *rapt, long time)
+{
+  return (rapt->start > time);
+}
+
 /*
  * Look in the appointment list if we have an item which starts before the item
  * stored in the notify_app structure (which is the next item to be notified).
@@ -1071,32 +1041,27 @@ recur_exc_scan (FILE *data_file)
 struct notify_app *
 recur_apoint_check_next (struct notify_app *app, long start, long day)
 {
-  struct recur_apoint *i;
+  llist_item_t *i;
   long real_recur_start_time;
 
-  pthread_mutex_lock (&(recur_alist_p->mutex));
-  for (i = recur_alist_p->root; i != NULL; i = i->next)
+  LLIST_TS_LOCK (&recur_alist_p);
+  i = LLIST_TS_FIND_FIRST (&recur_alist_p, start, recur_apoint_starts_after);
+
+  if (i)
     {
-      if (i->start > app->time)
-        {
-          pthread_mutex_unlock (&(recur_alist_p->mutex));
-          return (app);
-        }
-      else
+      struct recur_apoint *rapt = LLIST_TS_GET_DATA (i);
+
+      real_recur_start_time = recur_apoint_inday(rapt, day);
+      if (real_recur_start_time > start)
         {
-          real_recur_start_time =
-            recur_item_inday (i->start, i->exc, i->rpt->type, i->rpt->freq,
-                              i->rpt->until, day);
-          if (real_recur_start_time > start)
-            {
-              app->time = real_recur_start_time;
-              app->txt = mem_strdup (i->mesg);
-              app->state = i->state;
-              app->got_app = 1;
-            }
+          app->time = real_recur_start_time;
+          app->txt = mem_strdup (rapt->mesg);
+          app->state = rapt->state;
+          app->got_app = 1;
         }
     }
-  pthread_mutex_unlock (&(recur_alist_p->mutex));
+
+  LLIST_TS_UNLOCK (&recur_alist_p);
 
   return (app);
 }
@@ -1105,25 +1070,13 @@ recur_apoint_check_next (struct notify_app *app, long start, long day)
 struct recur_apoint *
 recur_get_apoint (long date, int num)
 {
-  struct recur_apoint *o;
-  int n = 0;
+  llist_item_t *i = LLIST_TS_FIND_NTH (&recur_alist_p, num, date,
+                                      recur_apoint_inday);
+
+  if (i)
+    return LLIST_TS_GET_DATA (i);
 
-  pthread_mutex_lock (&(recur_alist_p->mutex));
-  for (o = recur_alist_p->root; o != NULL; o = o->next)
-    {
-      if (recur_item_inday (o->start, o->exc, o->rpt->type,
-                            o->rpt->freq, o->rpt->until, date))
-        {
-          if (n == num)
-            {
-              pthread_mutex_unlock (&(recur_alist_p->mutex));
-              return (o);
-            }
-          n++;
-        }
-    }
   EXIT (_("item not found"));
-  return 0;
   /* NOTREACHED */
 }
 
@@ -1131,23 +1084,13 @@ recur_get_apoint (long date, int num)
 struct recur_event *
 recur_get_event (long date, int num)
 {
-  struct recur_event *o;
-  int n = 0;
+  llist_item_t *i = LLIST_FIND_NTH (&recur_elist, num, date,
+                                    recur_event_inday);
+
+  if (i)
+    return LLIST_GET_DATA (i);
 
-  for (o = recur_elist; o != NULL; o = o->next)
-    {
-      if (recur_item_inday (o->day, o->exc, o->rpt->type,
-                            o->rpt->freq, o->rpt->until, date))
-        {
-          if (n == num)
-            {
-              return (o);
-            }
-          n++;
-        }
-    }
   EXIT (_("item not found"));
-  return 0;
   /* NOTREACHED */
 }
 
@@ -1155,35 +1098,21 @@ recur_get_event (long date, int num)
 void
 recur_apoint_switch_notify (long date, int recur_nb)
 {
-  int n, need_chk_notify;
-  struct recur_apoint *o;
+  llist_item_t *i;
 
-  n = 0;
-  need_chk_notify = 0;
+  LLIST_TS_LOCK (&recur_alist_p);
+  i = LLIST_TS_FIND_NTH (&recur_alist_p, recur_nb, date, recur_apoint_inday);
 
-  pthread_mutex_lock (&(recur_alist_p->mutex));
-  for (o = recur_alist_p->root; o != NULL; o = o->next)
-    {
-      if (recur_item_inday (o->start, o->exc, o->rpt->type,
-                            o->rpt->freq, o->rpt->until, date))
-        {
-          if (n == recur_nb)
-            {
-              o->state ^= APOINT_NOTIFY;
+  if (!i)
+    EXIT (_("item not found"));
+  struct recur_apoint *rapt = LLIST_TS_GET_DATA (i);
 
-              if (notify_bar ())
-                notify_check_repeated (o);
+  rapt->state ^= APOINT_NOTIFY;
 
-              pthread_mutex_unlock (&(recur_alist_p->mutex));
-              if (need_chk_notify)
-                notify_check_next_app ();
-              return;
-            }
-          n++;
-        }
-    }
-  EXIT (_("item not found"));
-  /* NOTREACHED */
+  if (notify_bar ())
+    notify_check_repeated (rapt);
+
+  LLIST_TS_UNLOCK (&recur_alist_p);
 }
 
 void
-- 
cgit v1.2.3-70-g09d2