From 77ef3fe76e4ce4c9a990e8a5904ad2d83420ca02 Mon Sep 17 00:00:00 2001
From: Lukas Fleischer <calcurse@cryptocrack.de>
Date: Tue, 12 Apr 2011 19:40:53 +0200
Subject: Use generic lists for appointments.

Use the new generic list implementation instead of "apoint_list"
everywhere. Simplify stuff and drop unused variables as well.

Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
---
 src/apoint.c   | 232 +++++++++++++++++++++++----------------------------------
 src/args.c     |  54 +++++++-------
 src/calcurse.h |  10 +--
 src/day.c      |  65 ++++++++--------
 src/io.c       |  43 ++++++-----
 5 files changed, 177 insertions(+), 227 deletions(-)

diff --git a/src/apoint.c b/src/apoint.c
index bb8f00f..fac37c2 100644
--- a/src/apoint.c
+++ b/src/apoint.c
@@ -41,7 +41,7 @@
 
 #include "calcurse.h"
 
-struct apoint_list   *alist_p;
+llist_ts_t            alist_p;
 static struct apoint  bkp_cut_apoint;
 static int            hilt;
 
@@ -56,6 +56,14 @@ apoint_free_bkp (enum eraseflg flag)
   erase_note (&bkp_cut_apoint.note, flag);
 }
 
+static void
+apoint_free (struct apoint *apt)
+{
+  mem_free (apt->mesg);
+  erase_note (&apt->note, ERASE_FORCE_KEEP_NOTE);
+  mem_free (apt);
+}
+
 static void
 apoint_dup (struct apoint *in, struct apoint *bkp)
 {
@@ -72,9 +80,7 @@ apoint_dup (struct apoint *in, struct apoint *bkp)
 void
 apoint_llist_init (void)
 {
-  alist_p = mem_malloc (sizeof (struct apoint_list));
-  alist_p->root = NULL;
-  pthread_mutex_init (&(alist_p->mutex), NULL);
+  LLIST_TS_INIT (&alist_p);
 }
 
 /*
@@ -85,18 +91,8 @@ apoint_llist_init (void)
 void
 apoint_llist_free (void)
 {
-  struct apoint *o, **i;
-
-  i = &alist_p->root;
-  while (*i)
-    {
-      o = *i;
-      *i = o->next;
-      mem_free (o->mesg);
-      erase_note (&o->note, ERASE_FORCE_KEEP_NOTE);
-      mem_free (o);
-    }
-  mem_free (alist_p);
+  LLIST_TS_FREE_INNER (&alist_p, apoint_free);
+  LLIST_TS_FREE (&alist_p);
 }
 
 /* Sets which appointment is highlighted. */
@@ -125,33 +121,29 @@ apoint_hilt (void)
   return (hilt);
 }
 
+static int
+apoint_cmp_start (struct apoint *a, struct apoint *b)
+{
+  return (a->start < b->start ? -1 : (a->start == b->start ? 0 : 1));
+}
+
 struct apoint *
 apoint_new (char *mesg, char *note, long start, long dur, char state)
 {
-  struct apoint *o, **i;
-
-  o = mem_malloc (sizeof (struct apoint));
-  o->mesg = mem_strdup (mesg);
-  o->note = (note != NULL) ? mem_strdup (note) : NULL;
-  o->state = state;
-  o->start = start;
-  o->dur = dur;
-
-  pthread_mutex_lock (&(alist_p->mutex));
-  i = &alist_p->root;
-  for (;;)
-    {
-      if (*i == NULL || (*i)->start > start)
-        {
-          o->next = *i;
-          *i = o;
-          break;
-        }
-      i = &(*i)->next;
-    }
-  pthread_mutex_unlock (&(alist_p->mutex));
+  struct apoint *apt;
+
+  apt = mem_malloc (sizeof (struct apoint));
+  apt->mesg = mem_strdup (mesg);
+  apt->note = (note != NULL) ? mem_strdup (note) : NULL;
+  apt->state = state;
+  apt->start = start;
+  apt->dur = dur;
 
-  return (o);
+  LLIST_TS_LOCK (&alist_p);
+  LLIST_TS_ADD_SORTED (&alist_p, apt, apoint_cmp_start);
+  LLIST_TS_UNLOCK (&alist_p);
+
+  return apt;
 }
 
 /*
@@ -483,74 +475,52 @@ apoint_scan (FILE *f, struct tm start, struct tm end, char state, char *note)
 struct apoint *
 apoint_get (long day, int pos)
 {
-  struct apoint *o;
-  int n;
+  llist_item_t *i = LLIST_TS_FIND_NTH (&alist_p, pos, day, apoint_inday);
+
+  if (i)
+    return LLIST_TS_GET_DATA (i);
 
-  n = 0;
-  for (o = alist_p->root; o; o = o->next)
-    {
-      if (apoint_inday (o, day))
-        {
-          if (n == pos)
-            return (o);
-          n++;
-        }
-    }
   EXIT (_("item not found"));
-  return 0;
   /* NOTREACHED */
 }
 
 void
 apoint_delete_bynum (long start, unsigned num, enum eraseflg flag)
 {
-  unsigned n;
+  llist_item_t *i;
   int need_check_notify = 0;
-  struct apoint *i, **iptr;
 
-  n = 0;
-  pthread_mutex_lock (&(alist_p->mutex));
-  iptr = &alist_p->root;
-  for (i = alist_p->root; i != NULL; i = i->next)
+  LLIST_TS_LOCK (&alist_p);
+  i = LLIST_TS_FIND_NTH (&alist_p, num, start, apoint_inday);
+
+  if (!i)
+    EXIT (_("no such appointment"));
+  struct apoint *apt = LLIST_TS_GET_DATA (i);
+
+  switch (flag)
     {
-      if (apoint_inday (i, start))
-        {
-          if (n == num)
-            {
-              switch (flag)
-                {
-                case ERASE_FORCE_ONLY_NOTE:
-                  erase_note (&i->note, flag);
-                  pthread_mutex_unlock (&(alist_p->mutex));
-                  break;
-                case ERASE_CUT:
-                  apoint_free_bkp (ERASE_FORCE);
-                  apoint_dup (i, &bkp_cut_apoint);
-                  erase_note (&i->note, ERASE_FORCE_KEEP_NOTE);
-                  /* FALLTHROUGH */
-                default:
-                  if (notify_bar ())
-                    need_check_notify = notify_same_item (i->start);
-                  *iptr = i->next;
-                  mem_free (i->mesg);
-                  if (flag != ERASE_FORCE_KEEP_NOTE && flag != ERASE_CUT)
-                    erase_note (&i->note, flag);
-                  mem_free (i);
-                  pthread_mutex_unlock (&(alist_p->mutex));
-                  if (need_check_notify)
-                    notify_check_next_app ();
-                  break;
-                }
-              return;
-            }
-          n++;
-        }
-      iptr = &i->next;
+    case ERASE_FORCE_ONLY_NOTE:
+      erase_note (&apt->note, flag);
+      break;
+    case ERASE_CUT:
+      apoint_free_bkp (ERASE_FORCE);
+      apoint_dup (apt, &bkp_cut_apoint);
+      erase_note (&apt->note, ERASE_FORCE_KEEP_NOTE);
+      /* FALLTHROUGH */
+    default:
+      if (notify_bar ())
+        need_check_notify = notify_same_item (apt->start);
+      LLIST_TS_REMOVE (&alist_p, i);
+      mem_free (apt->mesg);
+      if (flag != ERASE_FORCE_KEEP_NOTE && flag != ERASE_CUT)
+        erase_note (&apt->note, flag);
+      mem_free (apt);
+      if (need_check_notify)
+        notify_check_next_app ();
+      break;
     }
 
-  pthread_mutex_unlock (&(alist_p->mutex));
-  EXIT (_("no such appointment"));
-  /* NOTREACHED */
+  LLIST_TS_UNLOCK (&alist_p);
 }
 
 /*
@@ -608,6 +578,12 @@ apoint_scroll_pad_up (int nb_events_inday)
     apad.first_onscreen = item_first_line;
 }
 
+static int
+apoint_starts_after (struct apoint *apt, long time)
+{
+  return (apt->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).
@@ -615,28 +591,25 @@ apoint_scroll_pad_up (int nb_events_inday)
 struct notify_app *
 apoint_check_next (struct notify_app *app, long start)
 {
-  struct apoint *i;
+  llist_item_t *i;
+
+  LLIST_TS_LOCK (&alist_p);
+  i = LLIST_TS_FIND_FIRST (&alist_p, start, apoint_starts_after);
 
-  pthread_mutex_lock (&(alist_p->mutex));
-  for (i = alist_p->root; i != NULL; i = i->next)
+  if (i)
     {
-      if (i->start > app->time)
-        {
-          pthread_mutex_unlock (&(alist_p->mutex));
-          return (app);
-        }
-      else
+      struct apoint *apt = LLIST_TS_GET_DATA (i);
+
+      if (apt->start <= app->time)
         {
-          if (i->start > start)
-            {
-              app->time = i->start;
-              app->txt = mem_strdup (i->mesg);
-              app->state = i->state;
-              app->got_app = 1;
-            }
+          app->time = apt->start;
+          app->txt = mem_strdup (apt->mesg);
+          app->state = apt->state;
+          app->got_app = 1;
         }
     }
-  pthread_mutex_unlock (&(alist_p->mutex));
+
+  LLIST_TS_UNLOCK (&alist_p);
 
   return (app);
 }
@@ -663,10 +636,9 @@ apoint_recur_s2apoint_s (struct recur_apoint *p)
 void
 apoint_switch_notify (void)
 {
-  struct apoint *apoint;
   struct day_item *p;
   long date;
-  int apoint_nb = 0, n, need_chk_notify;
+  int apoint_nb = 0, need_chk_notify;
 
   p = day_get_item (hilt);
   if (p->type != APPT && p->type != RECUR_APPT)
@@ -682,34 +654,18 @@ apoint_switch_notify (void)
   else if (p->type == APPT)
     apoint_nb = day_item_nb (date, hilt, APPT);
 
-  n = 0;
   need_chk_notify = 0;
-  pthread_mutex_lock (&(alist_p->mutex));
+  LLIST_TS_LOCK (&alist_p);
 
-  for (apoint = alist_p->root; apoint != NULL; apoint = apoint->next)
-    {
-      if (apoint_inday (apoint, date))
-        {
-          if (n == apoint_nb)
-            {
-              apoint->state ^= APOINT_NOTIFY;
-              if (notify_bar ())
-                {
-                  notify_check_added (apoint->mesg, apoint->start,
-                                      apoint->state);
-                }
-              pthread_mutex_unlock (&(alist_p->mutex));
-              if (need_chk_notify)
-                notify_check_next_app ();
-              return;
-            }
-          n++;
-        }
-    }
+  struct apoint *apt = apoint_get (apoint_nb, date);
 
-  pthread_mutex_unlock (&(alist_p->mutex));
-  EXIT (_("no such appointment"));
-  /* NOTREACHED */
+  apt->state ^= APOINT_NOTIFY;
+  if (notify_bar ())
+    notify_check_added (apt->mesg, apt->start, apt->state);
+  if (need_chk_notify)
+    notify_check_next_app ();
+
+  LLIST_TS_UNLOCK (&alist_p);
 }
 
 /* Updates the Appointment panel */
diff --git a/src/args.c b/src/args.c
index cd2c5d5..af1dae2 100644
--- a/src/args.c
+++ b/src/args.c
@@ -350,10 +350,10 @@ static int
 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 event *j;
   struct recur_apoint *ra;
-  struct apoint *i;
   long today;
   unsigned print_date = 1;
   int app_found = 0;
@@ -464,38 +464,36 @@ app_arg (int add_line, struct date *day, long date, int print_note,
     }
   pthread_mutex_unlock (&(recur_alist_p->mutex));
 
-  pthread_mutex_lock (&(alist_p->mutex));
-  for (i = alist_p->root; i != NULL; i = i->next)
+  LLIST_TS_LOCK (&alist_p);
+  LLIST_TS_FIND_FOREACH (&alist_p, today, apoint_inday, i)
     {
-      if (apoint_inday (i, today))
-        {
-          if (regex && regexec (regex, i->mesg, 0, 0, 0) != 0)
-            continue;
+      struct apoint *apt = LLIST_TS_GET_DATA (i);
+      if (regex && regexec (regex, apt->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;
-            }
-          apoint_sec2str (i, APPT, today, apoint_start_time, apoint_end_time);
-          fputs (" - ", stdout);
-          fputs (apoint_start_time, stdout);
-          fputs (" -> ", stdout);
-          fputs (apoint_end_time, stdout);
-          fputs ("\n\t", stdout);
-          fputs (i->mesg, stdout);
+      app_found = 1;
+      if (add_line)
+        {
           fputs ("\n", stdout);
-          if (print_note && i->note)
-            print_notefile (stdout, i->note, 2);
+          add_line = 0;
+        }
+      if (print_date)
+        {
+          arg_print_date (today, conf);
+          print_date = 0;
         }
+      apoint_sec2str (apt, APPT, today, apoint_start_time, apoint_end_time);
+      fputs (" - ", stdout);
+      fputs (apoint_start_time, stdout);
+      fputs (" -> ", stdout);
+      fputs (apoint_end_time, stdout);
+      fputs ("\n\t", stdout);
+      fputs (apt->mesg, stdout);
+      fputs ("\n", stdout);
+      if (print_note && apt->note)
+        print_notefile (stdout, apt->note, 2);
     }
-  pthread_mutex_unlock (&(alist_p->mutex));
+  LLIST_TS_UNLOCK (&alist_p);
 
   return (app_found);
 }
diff --git a/src/calcurse.h b/src/calcurse.h
index f6f5898..31a2933 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -269,13 +269,6 @@ struct apoint
   char          *note;
 };
 
-/* Appointments are stored in a linked-list. */
-struct apoint_list
-{
-  struct apoint   *root;
-  pthread_mutex_t  mutex;
-};
-
 /* Event definition. */
 struct event {
   struct event *next;
@@ -564,8 +557,9 @@ enum save_display {
 };
 
 /* apoint.c */
-extern struct apoint_list  *alist_p;
+extern llist_ts_t alist_p;
 void               apoint_free_bkp (enum eraseflg);
+void               apoint_free (struct apoint *);
 void               apoint_llist_init (void);
 void               apoint_llist_free (void);
 void               apoint_hilt_set (int);
diff --git a/src/day.c b/src/day.c
index 50f025b..9c95ae0 100644
--- a/src/day.c
+++ b/src/day.c
@@ -194,27 +194,25 @@ day_store_recur_events (long date)
 /*
  * Store the apoints for the selected day in structure pointed
  * by day_items_ptr. This is done by copying the appointments
- * from the general structure pointed by alist_p->root to the
+ * from the general structure pointed by alist_p to the
  * structure dedicated to the selected day.
  * Returns the number of appointments for the selected day.
  */
 static int
 day_store_apoints (long date)
 {
-  struct apoint *j;
+  llist_item_t *i;
   int a_nb = 0;
 
-  pthread_mutex_lock (&(alist_p->mutex));
-  for (j = alist_p->root; j != NULL; j = j->next)
+  LLIST_TS_LOCK (&alist_p);
+  LLIST_TS_FIND_FOREACH (&alist_p, date, apoint_inday, i)
     {
-      if (apoint_inday (j, date))
-        {
-          a_nb++;
-          (void)day_add_apoint (APPT, j->mesg, j->note, j->start,
-                                j->dur, j->state, 0);
-        }
+      struct apoint *apt = LLIST_TS_GET_DATA (i);
+      (void)day_add_apoint (APPT, apt->mesg, apt->note, apt->start, apt->dur,
+                            apt->state, 0);
+      a_nb++;
     }
-  pthread_mutex_unlock (&(alist_p->mutex));
+  LLIST_TS_UNLOCK (&alist_p);
 
   return a_nb;
 }
@@ -478,7 +476,6 @@ day_check_if_item (struct date day)
   struct recur_event *re;
   struct recur_apoint *ra;
   struct event *e;
-  struct apoint *a;
   const long date = date2sec (day, 0, 0);
 
   for (re = recur_elist; re != NULL; re = re->next)
@@ -500,14 +497,13 @@ day_check_if_item (struct date day)
     if (event_inday (e, date))
       return (1);
 
-  pthread_mutex_lock (&(alist_p->mutex));
-  for (a = alist_p->root; a != NULL; a = a->next)
-    if (apoint_inday (a, date))
-      {
-        pthread_mutex_unlock (&(alist_p->mutex));
-        return (1);
-      }
-  pthread_mutex_unlock (&(alist_p->mutex));
+  LLIST_TS_LOCK (&alist_p);
+  if (LLIST_TS_FIND_FIRST (&alist_p, date, apoint_inday))
+    {
+      LLIST_TS_UNLOCK (&alist_p);
+      return (1);
+    }
+  LLIST_TS_UNLOCK (&alist_p);
 
   return (0);
 }
@@ -537,8 +533,8 @@ fill_slices (int *slices, int slicesno, int first, int last)
 unsigned
 day_chk_busy_slices (struct date day, int slicesno, int *slices)
 {
+  llist_item_t *i;
   struct recur_apoint *ra;
-  struct apoint *a;
   int slicelen;
   const long date = date2sec (day, 0, 0);
 
@@ -563,21 +559,20 @@ day_chk_busy_slices (struct date day, int slicesno, int *slices)
       }
   pthread_mutex_unlock (&(recur_alist_p->mutex));
 
-  pthread_mutex_lock (&(alist_p->mutex));
-  for (a = alist_p->root; a != NULL; a = a->next)
-    if (apoint_inday (a, date))
-      {
-        long start, end;
+  LLIST_TS_LOCK (&alist_p);
+  LLIST_TS_FIND_FOREACH (&alist_p, date, apoint_inday, i)
+    {
+      struct apoint *apt = LLIST_TS_GET_DATA (i);
+      long start = get_item_time (apt->start);
+      long end = get_item_time (apt->start + apt->dur);
 
-        start = get_item_time (a->start);
-        end = get_item_time (a->start + a->dur);
-        if (!fill_slices (slices, slicesno, SLICENUM (start), SLICENUM (end)))
-          {
-            pthread_mutex_unlock (&(alist_p->mutex));
-            return 0;
-          }
-      }
-  pthread_mutex_unlock (&(alist_p->mutex));
+      if (!fill_slices (slices, slicesno, SLICENUM (start), SLICENUM (end)))
+        {
+          LLIST_TS_UNLOCK (&alist_p);
+          return 0;
+        }
+    }
+  LLIST_TS_UNLOCK (&alist_p);
 
 #undef SLICENUM
   return 1;
diff --git a/src/io.c b/src/io.c
index 8cb9804..c46b281 100644
--- a/src/io.c
+++ b/src/io.c
@@ -594,34 +594,38 @@ pcal_export_recur_apoints (FILE *stream)
 static void
 ical_export_apoints (FILE *stream)
 {
-  struct apoint *i;
+  llist_item_t *i;
   char ical_datetime[BUFSIZ];
 
-  pthread_mutex_lock (&(alist_p->mutex));
-  for (i = alist_p->root; i != NULL; i = i->next)
+  LLIST_TS_LOCK (&alist_p);
+  LLIST_TS_FOREACH (&alist_p, i)
     {
-      date_sec2date_fmt (i->start, ICALDATETIMEFMT, ical_datetime);
+      struct apoint *apt = LLIST_TS_GET_DATA (i);
+      date_sec2date_fmt (apt->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, "SUMMARY:%s\n", i->mesg);
-      if (i->state & APOINT_NOTIFY)
+      (void)fprintf (stream, "DURATION:PT0H0M%ldS\n", apt->dur);
+      (void)fprintf (stream, "SUMMARY:%s\n", apt->mesg);
+      if (apt->state & APOINT_NOTIFY)
         ical_export_valarm (stream);
       (void)fprintf (stream, "END:VEVENT\n");
     }
-  pthread_mutex_unlock (&(alist_p->mutex));
+  LLIST_TS_UNLOCK (&alist_p);
 }
 
 static void
 pcal_export_apoints (FILE *stream)
 {
-  struct apoint *i;
+  llist_item_t *i;
 
   (void)fprintf (stream, "\n# ============\n# Appointments\n# ============\n");
-  pthread_mutex_lock (&(alist_p->mutex));
-  for (i = alist_p->root; i != NULL; i = i->next)
-      pcal_dump_apoint (stream, i->start, i->dur, i->mesg);
-  pthread_mutex_unlock (&(alist_p->mutex));
+  LLIST_TS_LOCK (&alist_p);
+  LLIST_TS_FOREACH (&alist_p, i)
+    {
+      struct apoint *apt = LLIST_TS_GET_DATA (i);
+      pcal_dump_apoint (stream, apt->start, apt->dur, apt->mesg);
+    }
+  LLIST_TS_UNLOCK (&alist_p);
   (void)fprintf (stream, "\n");
 }
 
@@ -959,7 +963,7 @@ io_save_conf (struct conf *conf)
 unsigned
 io_save_apts (void)
 {
-  struct apoint *a;
+  llist_item_t *i;
   struct event *e;
   FILE *fp;
 
@@ -969,11 +973,14 @@ io_save_apts (void)
   recur_save_data (fp);
 
   if (ui_mode == UI_CURSES)
-    pthread_mutex_lock (&(alist_p->mutex));
-  for (a = alist_p->root; a != NULL; a = a->next)
-    apoint_write (a, fp);
+    LLIST_TS_LOCK (&alist_p);
+  LLIST_TS_FOREACH (&alist_p, i)
+    {
+      struct apoint *apt = LLIST_TS_GET_DATA (i);
+      apoint_write (apt, fp);
+    }
   if (ui_mode == UI_CURSES)
-    pthread_mutex_unlock (&(alist_p->mutex));
+    LLIST_TS_UNLOCK (&alist_p);
 
   for (e = eventlist; e != NULL; e = e->next)
     event_write (e, fp);
-- 
cgit v1.2.3-70-g09d2