Rocco Rutte:
authorpdmef <pdmef@e385b8ad-14ed-0310-8656-cc95a2468c6d>
Mon, 21 Mar 2005 03:11:45 +0000 (03:11 +0000)
committerpdmef <pdmef@e385b8ad-14ed-0310-8656-cc95a2468c6d>
Mon, 21 Mar 2005 03:11:45 +0000 (03:11 +0000)
- add generalized list array-based list implementation
- handling of Incoming uses this list
- necessary update for sidebar + first cleanup

git-svn-id: svn://svn.berlios.de/mutt-ng/trunk@215 e385b8ad-14ed-0310-8656-cc95a2468c6d

browser.c
buffy.c
curs_main.c
flags.c
lib/Makefile.am
lib/list.c [new file with mode: 0644]
lib/list.h [new file with mode: 0644]
menu.c
pager.c
sidebar.c

index 587fb6b..1dbc644 100644 (file)
--- a/browser.c
+++ b/browser.c
@@ -30,6 +30,7 @@
 #include "lib/mem.h"
 #include "lib/intl.h"
 #include "lib/str.h"
+#include "lib/list.h"
 
 #include <stdlib.h>
 #include <dirent.h>
@@ -497,7 +498,7 @@ static int examine_directory (MUTTMENU * menu, struct browser_state *state,
     DIR *dp;
     struct dirent *de;
     char buffer[_POSIX_PATH_MAX + SHORT_STRING];
-    BUFFY *tmp;
+    int i = -1;
 
     while (stat (d, &s) == -1) {
       if (errno == ENOENT) {
@@ -545,14 +546,12 @@ static int examine_directory (MUTTMENU * menu, struct browser_state *state,
           (!S_ISLNK (s.st_mode)))
         continue;
 
-      tmp = Incoming;
-      while (tmp && mutt_strcmp (buffer, tmp->path))
-        tmp = tmp->next;
-      add_folder (menu, state, de->d_name, &s, NULL, (tmp) ? tmp->new : 0);
+      i = buffy_lookup (buffer);
+      add_folder (menu, state, de->d_name, &s, NULL, i >= 0 ? ((BUFFY*) Incoming->data[i])->new : 0);
     }
     closedir (dp);
   }
-  draw_sidebar (CurrentMenu);
+  sidebar_draw (CurrentMenu);
   browser_sort (state);
   return 0;
 }
@@ -585,7 +584,8 @@ static int examine_mailboxes (MUTTMENU * menu, struct browser_state *state)
   else
 #endif
   {
-    BUFFY *tmp = Incoming;
+    int i = 0;
+    BUFFY* tmp;
 
     if (!Incoming)
       return (-1);
@@ -593,7 +593,8 @@ static int examine_mailboxes (MUTTMENU * menu, struct browser_state *state)
 
     init_state (state, menu);
 
-    do {
+    for (i = 0; i < Incoming->length; i++) {
+      tmp = (BUFFY*) Incoming->data[i];
 #ifdef USE_IMAP
       if (mx_is_imap (tmp->path)) {
         add_folder (menu, state, tmp->path, NULL, NULL, tmp->new);
@@ -624,7 +625,6 @@ static int examine_mailboxes (MUTTMENU * menu, struct browser_state *state)
 
       add_folder (menu, state, buffer, &s, NULL, tmp->new);
     }
-    while ((tmp = tmp->next));
   }
   browser_sort (state);
   return 0;
diff --git a/buffy.c b/buffy.c
index 7d2f1bb..67800dd 100644 (file)
--- a/buffy.c
+++ b/buffy.c
@@ -165,12 +165,29 @@ void mutt_update_mailbox (BUFFY * b)
 }
 #endif
 
+/* func to free buffy for list_del() */
+static void buffy_free (void** p) {
+  FREE(&(*((BUFFY**) p))->path);
+  FREE(p);
+}
+
+int buffy_lookup (const char* path) {
+  int i = 0;
+  if (list_empty(Incoming) || !path || !*path)
+    return (-1);
+  for (i = 0; i < Incoming->length; i++) {
+    if (mutt_strcmp (((BUFFY*) Incoming->data[i])->path, path) == 0)
+      return (i);
+  }
+  return (-1);
+}
+
 int mutt_parse_mailboxes (BUFFER * path, BUFFER * s, unsigned long data,
                           BUFFER * err)
 {
-  BUFFY **tmp, *tmp1;
+  BUFFY* tmp;
   char buf[_POSIX_PATH_MAX];
-
+  int i = 0;
 #ifdef BUFFY_SIZE
   struct stat sb;
 #endif /* BUFFY_SIZE */
@@ -180,61 +197,49 @@ int mutt_parse_mailboxes (BUFFER * path, BUFFER * s, unsigned long data,
     strfcpy (buf, path->data, sizeof (buf));
 
     if (data == M_UNMAILBOXES && mutt_strcmp (buf, "*") == 0) {
-      for (tmp = &Incoming; *tmp;) {
-        FREE (&((*tmp)->path));
-        tmp1 = (*tmp)->next;
-        FREE (tmp);
-        *tmp = tmp1;
-      }
+      list_del (&Incoming, buffy_free);
       return 0;
     }
 
-    mutt_expand_path (buf, sizeof (buf));
-
     /* Skip empty tokens. */
     if (!*buf)
       continue;
 
-    /* simple check to avoid duplicates */
-    for (tmp = &Incoming; *tmp; tmp = &((*tmp)->next)) {
-      if (mutt_strcmp (buf, (*tmp)->path) == 0)
-        break;
-    }
+    mutt_expand_path (buf, sizeof (buf));
+    i = buffy_lookup (buf);
 
     if (data == M_UNMAILBOXES) {
-      if (*tmp) {
-        FREE (&((*tmp)->path));
-        tmp1 = (*tmp)->next;
-        FREE (tmp);
-        *tmp = tmp1;
+      if (i >= 0) {
+        tmp = (BUFFY*) list_pop_idx (Incoming, i);
+        buffy_free (&tmp);
       }
       continue;
     }
 
-    if (!*tmp) {
-      *tmp = (BUFFY *) safe_calloc (1, sizeof (BUFFY));
-      (*tmp)->path = safe_strdup (buf);
-      (*tmp)->next = NULL;
-      /* it is tempting to set magic right here */
-      (*tmp)->magic = 0;
-
-    }
+    if (i < 0) {
+      tmp = safe_calloc (1, sizeof (BUFFY));
+      tmp->path = safe_strdup (buf);
+      tmp->magic = 0;
+      list_push_back (&Incoming, tmp);
+      i = Incoming->length-1;
+    } else
+      tmp = (BUFFY*) Incoming->data[i];
 
-    (*tmp)->new = 0;
-    (*tmp)->notified = 1;
-    (*tmp)->newly_created = 0;
+    tmp->new = 0;
+    tmp->notified = 1;
+    tmp->newly_created = 0;
 
 #ifdef BUFFY_SIZE
     /* for buffy_size, it is important that if the folder is new (tested by
      * reading it), the size is set to 0 so that later when we check we see
      * that it increased .  without buffy_size we probably don't care.
      */
-    if (stat ((*tmp)->path, &sb) == 0 && !test_new_folder ((*tmp)->path)) {
+    if (stat (tmp->path, &sb) == 0 && !test_new_folder (tmp->path)) {
       /* some systems out there don't have an off_t type */
-      (*tmp)->size = (long) sb.st_size;
+      tmp->size = (long) sb.st_size;
     }
     else
-      (*tmp)->size = 0;
+      tmp->size = 0;
 #endif /* BUFFY_SIZE */
   }
   return 0;
@@ -264,7 +269,7 @@ int mutt_buffy_check (int force)
   struct stat contex_sb;
   time_t now, last1;
   CONTEXT *ctx;
-
+  int i = 0;
 #ifdef USE_IMAP
   time_t last2;
 
@@ -274,7 +279,7 @@ int mutt_buffy_check (int force)
 #endif
 
   /* fastest return if there are no mailboxes */
-  if (!Incoming)
+  if (list_empty(Incoming))
     return 0;
   now = time (NULL);
   if (force == 0 && (now - BuffyTime < BuffyTimeout)
@@ -312,7 +317,8 @@ int mutt_buffy_check (int force)
           contex_sb.st_ino = 0;
         }
 
-  for (tmp = Incoming; tmp; tmp = tmp->next) {
+  for (i = 0; i < Incoming->length; i++) {
+    tmp = (BUFFY*) Incoming->data[i];
 #ifdef USE_IMAP
     if (mx_is_imap (tmp->path))
       tmp->magic = M_IMAP;
@@ -535,7 +541,7 @@ int mutt_buffy_check (int force)
     tmp->has_new = tmp->new > 0;
   }
   if (BuffyCount > 0 && force != 2)
-    draw_sidebar (CurrentMenu);
+    sidebar_draw (CurrentMenu);
   return (BuffyCount);
 }
 
@@ -547,6 +553,7 @@ int mutt_buffy_list (void)
   int pos;
   int first;
   int have_unnotified = BuffyNotify;
+  int i = 0;
 
   if (option (OPTFORCEBUFFYCHECK))
     mutt_buffy_check (1);
@@ -555,35 +562,38 @@ int mutt_buffy_list (void)
   first = 1;
   buffylist[0] = 0;
   pos += mutt_strlen (strncat (buffylist, _("New mail in "), sizeof (buffylist) - 1 - pos)); /* __STRNCAT_CHECKED__ */
-  for (tmp = Incoming; tmp; tmp = tmp->next) {
-    /* Is there new mail in this mailbox? */
-    if (tmp->new <= 0 || (have_unnotified && tmp->notified))
-      continue;
+  if (Incoming) {
+    for (i = 0; i < Incoming->length; i++) {
+      tmp = (BUFFY*) Incoming->data[i];
+      /* Is there new mail in this mailbox? */
+      if (tmp->new <= 0 || (have_unnotified && tmp->notified))
+        continue;
 
-    strfcpy (path, tmp->path, sizeof (path));
-    mutt_pretty_mailbox (path);
+      strfcpy (path, tmp->path, sizeof (path));
+      mutt_pretty_mailbox (path);
 
-    if (!first && pos + mutt_strlen (path) >= COLS - 7)
-      break;
+      if (!first && pos + mutt_strlen (path) >= COLS - 7)
+        break;
 
-    if (!first)
-      pos += mutt_strlen (strncat (buffylist + pos, ", ", sizeof (buffylist) - 1 - pos));    /* __STRNCAT_CHECKED__ */
+      if (!first)
+        pos += mutt_strlen (strncat (buffylist + pos, ", ", sizeof (buffylist) - 1 - pos));    /* __STRNCAT_CHECKED__ */
 
-    /* Prepend an asterisk to mailboxes not already notified */
-    if (!tmp->notified) {
-      /* pos += mutt_strlen (strncat(buffylist + pos, "*", sizeof(buffylist)-1-pos));  __STRNCAT_CHECKED__ */
-      tmp->notified = 1;
-      BuffyNotify--;
+      /* Prepend an asterisk to mailboxes not already notified */
+      if (!tmp->notified) {
+        /* pos += mutt_strlen (strncat(buffylist + pos, "*", sizeof(buffylist)-1-pos));  __STRNCAT_CHECKED__ */
+        tmp->notified = 1;
+        BuffyNotify--;
+      }
+      pos += mutt_strlen (strncat (buffylist + pos, path, sizeof (buffylist) - 1 - pos));      /* __STRNCAT_CHECKED__ */
+      first = 0;
     }
-    pos += mutt_strlen (strncat (buffylist + pos, path, sizeof (buffylist) - 1 - pos));      /* __STRNCAT_CHECKED__ */
-    first = 0;
   }
   if (!first && tmp) {
     strncat (buffylist + pos, ", ...", sizeof (buffylist) - 1 - pos);   /* __STRNCAT_CHECKED__ */
   }
   if (!first) {
     /* on new mail: redraw sidebar */
-    draw_sidebar (CurrentMenu);
+    sidebar_draw (CurrentMenu);
     mutt_message ("%s", buffylist);
     return (1);
   }
@@ -610,50 +620,31 @@ int mutt_buffy_notify (void)
  */
 void mutt_buffy (char *s, size_t slen)
 {
-  int count;
-  BUFFY *tmp = Incoming;
+  int i = 0, c = 0;
 
-  mutt_expand_path (s, _POSIX_PATH_MAX);
-  switch (mutt_buffy_check (0)) {
-  case 0:
+  if (list_empty(Incoming))
+    return;
 
+  mutt_expand_path (s, _POSIX_PATH_MAX);
+  if (mutt_buffy_check (0) == 0) {
     *s = '\0';
-    break;
-
-  case 1:
-
-    while (tmp && tmp->new <= 0)
-      tmp = tmp->next;
-    if (!tmp) {
-      *s = '\0';
-      mutt_buffy_check (1);     /* buffy was wrong - resync things */
-      break;
-    }
-    strfcpy (s, tmp->path, slen);
-    mutt_pretty_mailbox (s);
-    break;
-
-  default:
+    return;
+  }
 
-    count = 0;
-    while (count < 3) {
-      if (mutt_strcmp (s, tmp->path) == 0)
-        count++;
-      else if (count && tmp->new > 0)
-        break;
-      tmp = tmp->next;
-      if (!tmp) {
-        tmp = Incoming;
-        count++;
-      }
-    }
-    if (count >= 3) {
-      *s = '\0';
-      mutt_buffy_check (1);     /* buffy was wrong - resync things */
-      break;
-    }
-    strfcpy (s, tmp->path, slen);
+  i = buffy_lookup (s);
+  c = i == Incoming->length-1 ? 0 : i+1;
+  while (((BUFFY*) Incoming->data[c])->new <= 0) {
+    c = (c+1) % Incoming->length;
+    if (c == i)
+      break;    /* tried all once */
+  }
+  if (c == i) {
+    *s = '\0';
+    /* something went wrong since we're here when mutt_buffy_check
+     * reported new mail */
+    mutt_buffy_check (0);
+  } else {
+    strfcpy (s, ((BUFFY*) Incoming->data[c])->path, slen);
     mutt_pretty_mailbox (s);
-    break;
   }
 }
index 73b22cf..f2b6cb2 100644 (file)
@@ -459,7 +459,7 @@ int mutt_index_menu (void)
     mutt_buffy_check (1);       /* force the buffy check after we enter the folder */
     /* record folder we open to place sidebar indicator properly */
     if (Context && Context->path)
-      set_curbuffy (Context->path);
+      sidebar_set_current (Context->path);
   }
 
   FOREVER {
@@ -514,7 +514,7 @@ int mutt_index_menu (void)
                       ("Mailbox was externally modified.  Flags may be wrong."));
         else if (check == M_NEW_MAIL) {
           /* on new mail: redraw sidebar */
-          draw_sidebar (CurrentMenu);
+          sidebar_draw (CurrentMenu);
           mutt_message (_("New mail in this mailbox."));
 
           if (option (OPTBEEPNEW))
@@ -556,10 +556,10 @@ int mutt_index_menu (void)
     if (op != -1)
       mutt_curs_set (0);
     if (menu->redraw & REDRAW_SIDEBAR)
-      draw_sidebar (menu->menu);
+      sidebar_draw (menu->menu);
     if (menu->redraw & REDRAW_FULL) {
       menu_redraw_full (menu);
-      draw_sidebar (menu->menu);
+      sidebar_draw (menu->menu);
       mutt_show_error ();
     }
 
@@ -585,7 +585,7 @@ int mutt_index_menu (void)
         SETCOLOR (MT_COLOR_STATUS);
         mutt_paddstr (COLS, buf);
         SETCOLOR (MT_COLOR_NORMAL);
-        set_buffystats (Context);
+        sidebar_set_buffystats (Context);
         menu->redraw &= ~REDRAW_STATUS;
         if (option (OPTXTERMSETTITLES)) {
           menu_status_line (buf, sizeof (buf), menu, NONULL (XtermTitle));
@@ -1223,9 +1223,7 @@ int mutt_index_menu (void)
       }
 
       if (op == OP_SIDEBAR_OPEN) {
-        if (!CurBuffy)
-          break;
-        strncpy (buf, CurBuffy->path, sizeof (buf));
+        strncpy (buf, NONULL(sidebar_get_current ()), sizeof (buf));
       }
       else if (mutt_enter_fname (cp, buf, sizeof (buf), &menu->redraw, 1) ==
                -1)
@@ -1243,7 +1241,7 @@ int mutt_index_menu (void)
       else
 #endif
         mutt_expand_path (buf, sizeof (buf));
-      set_curbuffy (buf);
+      sidebar_set_current (buf);
       if (mx_get_magic (buf) <= 0) {
         mutt_error (_("%s is not a mailbox."), buf);
         break;
@@ -2377,7 +2375,7 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE);
     case OP_SIDEBAR_PREV:
     case OP_SIDEBAR_NEXT_NEW:
     case OP_SIDEBAR_PREV_NEW:
-      scroll_sidebar (op, menu->menu);
+      sidebar_scroll (op, menu->menu);
       break;
     default:
       if (menu->menu == MENU_MAIN)
diff --git a/flags.c b/flags.c
index 16ae021..bc57bb9 100644 (file)
--- a/flags.c
+++ b/flags.c
@@ -304,7 +304,7 @@ void _mutt_set_flag (CONTEXT * ctx, HEADER * h, int flag, int bf, int upd_ctx)
       && (changed != h->changed || deleted != ctx->deleted
           || tagged != ctx->tagged))
     h->searched = 0;
-  draw_sidebar (0);
+  sidebar_draw (0);
 }
 
 void mutt_tag_set_flag (int flag, int bf)
index 0417af1..f26cca8 100644 (file)
@@ -7,7 +7,7 @@ AUTOMAKE_OPTIONS = foreign
 INCLUDES = -I$(top_srcdir) -I../intl
 
 noinst_LIBRARIES = libsane.a
-noinst_HEADERS = mem.h str.h exit.h intl.h
+noinst_HEADERS = mem.h str.h exit.h intl.h list.h
 
-libsane_a_SOURCES = mem.c exit.c \
-                   mem.h exit.h str.h intl.h
+libsane_a_SOURCES = mem.c exit.c list.c \
+                   mem.h exit.h str.h intl.h list.h
diff --git a/lib/list.c b/lib/list.c
new file mode 100644 (file)
index 0000000..0719d9f
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * written for mutt-ng by:
+ * Rocco Rutte <pdmef@cs.tu-berlin.de>
+ *
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+#include "list.h"
+
+#include "mem.h"
+
+list2_t* list_new (void) {
+  return (safe_calloc (sizeof (list2_t), 1));
+}
+
+void list_del (list2_t** l, void (*edel) (void**)) {
+  size_t i = 0;
+  if (!l || !*l)
+    return;
+  if (*edel)
+    for (i = 0; i < (*l)->length; i++)
+      edel (&(*l)->data[i]);
+  FREE(&(*l)->data);
+  FREE(l);
+}
+
+void list_push_back (list2_t** l, void* p) {
+  if (!*l)
+    *l = list_new ();
+  safe_realloc (&(*l)->data, (++(*l)->length)*sizeof(void*));
+  (*l)->data[(*l)->length-1] = p;
+}
+
+void list_push_front (list2_t** l, void* p) {
+  if (!*l)
+    *l = list_new ();
+  safe_realloc (&(*l)->data, (++(*l)->length)*sizeof(void*));
+  if ((*l)->length > 1)
+    memmove (&(*l)->data[1], &(*l)->data[0], ((*l)->length-1)*sizeof(void*));
+  (*l)->data[0] = p;
+}
+
+void* list_pop_back (list2_t* l) {
+  void* p = NULL;
+  if (list_empty(l))
+    return (NULL);
+  p = l->data[l->length-1];
+  safe_realloc (&l->data, --(l->length)*sizeof(void*));
+  return (p);
+}
+
+void* list_pop_front (list2_t* l) {
+  void* p = NULL;
+  if (list_empty(l))
+    return (NULL);
+  p = l->data[0];
+  memmove (&l->data[0], &l->data[1], (--(l->length))*sizeof(void*));
+  safe_realloc (&l->data, l->length*sizeof(void*));
+  return (p);
+}
+
+void* list_pop_idx (list2_t* l, int c) {
+  void* p = NULL;
+  if (list_empty(l) || c < 0 || c >= l->length)
+    return (NULL);
+  if (c == l->length-1)
+    return (list_pop_back (l));
+  p = l->data[c];
+  memmove (&l->data[c], &l->data[c+1], (l->length-c)*sizeof(void*));
+  safe_realloc (&l->data, (--(l->length))*sizeof(void*));
+  return (p);
+}
+
+list2_t* list_cpy (list2_t* l) {
+  list2_t* ret = NULL;
+  if (list_empty(l))
+    return (NULL);
+  ret = list_new ();
+  ret->length = l->length;
+  ret->data = safe_malloc (l->length*sizeof(void*));
+  memcpy (ret->data, l->data, l->length*sizeof(void*));
+  return (ret);
+}
+
+list2_t* list_dup (list2_t* l, void* (*dup) (void*)) {
+  list2_t* ret = NULL;
+  int i = 0;
+  if (list_empty(l) || !*dup)
+    return (NULL);
+  ret = list_new ();
+  ret->length = l->length;
+  ret->data = safe_malloc (l->length*sizeof(void*));
+  for (i = 0; i < l->length; i++)
+    ret->data[i] = dup (l->data[i]);
+  return (ret);
+}
+
+int _list_lookup (list2_t* l, int (*cmp) (const void*, const void*), const void* p) {
+  int i = 0;
+  if (list_empty(l) || !*cmp)
+    return (-1);
+  for (i = 0; i < l->length; i++)
+    if (cmp (l->data[i], p) == 0)
+      return (i);
+  return (-1);
+}
diff --git a/lib/list.h b/lib/list.h
new file mode 100644 (file)
index 0000000..9cb4bb3
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * written for mutt-ng by:
+ * Rocco Rutte <pdmef@cs.tu-berlin.de>
+ *
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
+
+/*
+ * this aims to provide a generic list 
+ * implementation using arrays only
+ * mostly untested
+ */
+
+#ifndef _LIB_LIST_H
+#define _LIB_LIST_H
+
+#include <sys/types.h>
+
+typedef struct list2_t {
+  void** data;
+  size_t length;
+} list2_t;
+
+/*
+ * basics
+ */
+
+list2_t* list_new (void);
+/* frees all memory used by list and optionally used edel func
+ * ptr to free items */
+void list_del (list2_t**, void (*edel) (void**));
+
+#define list_empty(l) (!l || l->length == 0 || !l->data)
+
+/*
+ * insertion, removal
+ * the list_push_* functions create a list if empty so far
+ * for convenience
+ */
+void list_push_back (list2_t**, void*);
+void list_push_front (list2_t**, void*);
+void* list_pop_back (list2_t*);
+void* list_pop_front (list2_t*);
+void* list_pop_idx (list2_t*, int);
+
+/*
+ * copying
+ */
+
+/* plain copy */
+list2_t* list_cpy (list2_t*);
+/* "hard copy" using callback to copy items */
+list2_t* list_dup (list2_t*, void* (*dup) (void*));
+
+/*
+ * misc
+ */
+
+/* looks up item in list using callback function and comparison item
+ * return:
+ *      -1 if not found
+ *      index in data array otherwise
+ * the callback must return 0 on equality
+ */
+int list_lookup (list2_t*, int (*cmp) (const void*, const void*), const void*);
+
+#endif /* !_LIB_LIST_H */
diff --git a/menu.c b/menu.c
index 8f64595..1406e17 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -203,7 +203,7 @@ void menu_redraw_index (MUTTMENU * menu)
   char buf[STRING];
   int i;
 
-  draw_sidebar (1);
+  sidebar_draw (1);
   for (i = menu->top; i < menu->top + menu->pagelen; i++) {
     if (i < menu->max) {
       menu_make_entry (buf, sizeof (buf), menu, i);
diff --git a/pager.c b/pager.c
index 8ed08a8..8f8b5fe 100644 (file)
--- a/pager.c
+++ b/pager.c
@@ -1645,13 +1645,13 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t * extra)
     }
 
     if (redraw & REDRAW_SIDEBAR)
-      draw_sidebar (MENU_PAGER);
+      sidebar_draw (MENU_PAGER);
 
     if ((redraw & REDRAW_INDEX) && index) {
       /* redraw the pager_index indicator, because the
        * flags for this message might have changed. */
       menu_redraw_current (index);
-      draw_sidebar (MENU_PAGER);
+      sidebar_draw (MENU_PAGER);
       /* print out the index status bar */
       menu_status_line (buffer, sizeof (buffer), index, NONULL (Status));
       move (indexoffset + (option (OPTSTATUSONTOP) ? 0 : (indexlen - 1)),
@@ -1663,7 +1663,7 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t * extra)
     }
     /* if we're not using the index, update every time */
     if (index == 0)
-      draw_sidebar (MENU_PAGER);
+      sidebar_draw (MENU_PAGER);
 
     redraw = 0;
 
@@ -2586,7 +2586,7 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t * extra)
     case OP_SIDEBAR_NEXT_NEW:
     case OP_SIDEBAR_PREV:
     case OP_SIDEBAR_PREV_NEW:
-      scroll_sidebar (ch, MENU_PAGER);
+      sidebar_scroll (ch, MENU_PAGER);
       break;
     default:
       ch = -1;
index 8c661f2..77c5510 100644 (file)
--- a/sidebar.c
+++ b/sidebar.c
 #include <libgen.h>
 #include <ctype.h>
 
-/*BUFFY *CurBuffy = 0;*/
-static BUFFY *TopBuffy = 0;
-static BUFFY *BottomBuffy = 0;
+static int TopBuffy = 0;
+static int CurBuffy = 0;
 static int known_lines = 0;
 static short initialized = 0;
 static int prev_show_value;
 static short saveSidebarWidth;
 static char *entry = 0;
 
-static int quick_log10 (int n)
-{
+/* computes how many digets a number has;
+ * FIXME move out to library?
+ */
+static int quick_log10 (int n) {
   int len = 0;
 
   for (; n > 9; len++, n /= 10);
   return (++len);
 }
 
-/* CurBuffy should contain a valid buffy 
- * mailbox before calling this function!!! */
+/* computes first entry to be shown */
 void calc_boundaries (int menu)
 {
-  BUFFY *tmp = Incoming;
-  int position;
-  int i, count, mailbox_position;
+  int lines = 0;
 
+  if (list_empty(Incoming))
+    return;
   /* correct known_lines if it has changed because of a window resize */
-  if (known_lines != LINES) {
+  if (known_lines != LINES)
     known_lines = LINES;
-  }
-  /* fix all the prev links on all the mailboxes
-   * FIXME move this over to buffy.c where it belongs */
-  for (; tmp->next != 0; tmp = tmp->next)
-    tmp->next->prev = tmp;
-
-  /* calculate the position of the current mailbox */
-  position = 1;
-  tmp = Incoming;
-  while (tmp != CurBuffy) {
-    position++;
-    tmp = tmp->next;
-  }
-  /* calculate the size of the screen we can use */
-  count = LINES - 2 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
-  /* calculate the position of the current mailbox on the screen */
-  mailbox_position = position % count;
-  if (mailbox_position == 0)
-    mailbox_position = count;
-  /* determine topbuffy */
-  TopBuffy = CurBuffy;
-  for (i = mailbox_position; i > 1; i--)
-    TopBuffy = TopBuffy->prev;
-  /* determine bottombuffy */
-  BottomBuffy = CurBuffy;
-  for (i = mailbox_position; i < count && BottomBuffy->next; i++)
-    BottomBuffy = BottomBuffy->next;
+  lines = LINES - 2 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
+  TopBuffy = CurBuffy - (CurBuffy % lines);
+  if (TopBuffy < 0)
+    TopBuffy = 0;
 }
 
+/* compresses hierarchy in folder names;
+ * FIXME move out to library?
+ */
 static char *shortened_hierarchy (char *box)
 {
   int dots = 0;
@@ -120,6 +100,9 @@ static char *shortened_hierarchy (char *box)
   return safe_strdup (box);
 }
 
+/* print single item
+ * FIXME this is completely fucked up right now
+ */
 char *make_sidebar_entry (char *box, int size, int new, int flagged)
 {
   int i = 0, dlen, max, shortened = 0;
@@ -197,49 +180,47 @@ char *make_sidebar_entry (char *box, int size, int new, int flagged)
   return entry;
 }
 
-void set_curbuffy (char buf[LONG_STRING])
-{
-  BUFFY *tmp = CurBuffy = Incoming;
-
-  if (!Incoming)
-    return;
-
-  while (1) {
-    if (!mutt_strcmp (tmp->path, buf)) {
-      CurBuffy = tmp;
-      break;
-    }
-
-    if (tmp->next)
-      tmp = tmp->next;
-    else
-      break;
-  }
+/* returns folder name of currently 
+ * selected folder for <sidebar-open>
+ */
+const char* sidebar_get_current (void) {
+  if (list_empty(Incoming))
+    return (NULL);
+  return ((char*) ((BUFFY*) Incoming->data[CurBuffy])->path);
 }
 
-void set_buffystats (CONTEXT * Context)
-{
-  BUFFY *tmp = Incoming;
+/* internally sets item to buf */
+void sidebar_set_current (const char* buf) {
+  int i = buffy_lookup (buf);
+  if (i >= 0)
+    CurBuffy = i;
+}
 
-  if (!Context)
+/* fix counters for a context
+ * FIXME since ctx must not be of our business, move it elsewhere
+ */
+void sidebar_set_buffystats (CONTEXT* Context) {
+  int i = 0;
+  BUFFY* tmp = NULL;
+  if (!Context || list_empty(Incoming) || (i = buffy_lookup (Context->path)) < 0)
     return;
-  while (tmp) {
-    if (mutt_strcmp (tmp->path, Context->path) == 0) {
-      tmp->new = Context->new;
-      tmp->msg_unread = Context->unread;
-      tmp->msgcount = Context->msgcount;
-      tmp->msg_flagged = Context->flagged;
-      break;
-    }
-    tmp = tmp->next;
-  }
+  tmp = (BUFFY*) Incoming->data[i];
+  tmp->new = Context->new;
+  tmp->msg_unread = Context->unread;
+  tmp->msgcount = Context->msgcount;
+  tmp->msg_flagged = Context->flagged;
 }
 
-int draw_sidebar (int menu)
+/* actually draws something
+ * FIXME this needs some clue when to do it
+ * FIXME this is completely fucked up right now
+ */
+int sidebar_draw (int menu)
 {
 
   int lines = option (OPTHELP) ? 1 : 0;
   BUFFY *tmp;
+  int i = 0;
   short delim_len = mutt_strlen (SidebarDelim);
 
   /* initialize first time */
@@ -277,7 +258,6 @@ int draw_sidebar (int menu)
     return 0;
 
   /* draw the divider */
-  /* SETCOLOR(MT_COLOR_STATUS); */
   SETCOLOR (MT_COLOR_SIDEBAR);
   for (lines = 1;
        lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
@@ -294,24 +274,17 @@ int draw_sidebar (int menu)
   }
   SETCOLOR (MT_COLOR_NORMAL);
 
-  if (Incoming == 0)
+  if (list_empty(Incoming))
     return 0;
-  lines = option (OPTHELP) ? 1 : 0;     /* go back to the top */
 
-  if (CurBuffy == 0)
-    CurBuffy = Incoming;
-#if 0
-  if (known_lines != LINES || TopBuffy == 0 || BottomBuffy == 0)
-#endif
-    calc_boundaries (menu);
+  lines = option (OPTHELP) ? 1 : 0;     /* go back to the top */
 
-  tmp = TopBuffy;
+  calc_boundaries (menu);
 
-  for (;
-       tmp && lines < LINES - 1 - (menu != MENU_PAGER
-                                   || option (OPTSTATUSONTOP));
-       tmp = tmp->next) {
-    if (tmp == CurBuffy)
+  for (i = TopBuffy; i < Incoming->length && lines < LINES - 1 - 
+       (menu != MENU_PAGER || option (OPTSTATUSONTOP)); i++) {
+    tmp = (BUFFY*) Incoming->data[i];
+    if (i == CurBuffy)
       SETCOLOR (MT_COLOR_INDICATOR);
     else if (tmp->msg_flagged > 0)
       SETCOLOR (MT_COLOR_FLAGGED);
@@ -370,97 +343,93 @@ int draw_sidebar (int menu)
   return 0;
 }
 
-BUFFY *exist_next_new ()
-{
-  BUFFY *tmp = CurBuffy;
-
-  if (tmp == NULL)
-    return NULL;
-  while (tmp->next != NULL) {
-    tmp = tmp->next;
-    if (tmp->msg_unread)
-      return tmp;
-  }
-  return NULL;
+/* returns index of new item with new mail or -1 */
+static int exist_next_new () {
+  int i = 0;
+  if (list_empty(Incoming))
+    return (-1);
+  i = CurBuffy;
+  while (i < Incoming->length)
+    if (((BUFFY*) Incoming->data[i++])->msg_unread)
+      return (i-1);
+  return (-1);
 }
 
-BUFFY *exist_prev_new ()
-{
-  BUFFY *tmp = CurBuffy;
-
-  if (tmp == NULL)
-    return NULL;
-  while (tmp->prev != NULL) {
-    tmp = tmp->prev;
-    if (tmp->msg_unread)
-      return tmp;
-  }
-  return NULL;
+/* returns index of prev item with new mail or -1 */
+static int exist_prev_new () {
+  int i = 0;
+  if (list_empty(Incoming))
+    return (-1);
+  i = CurBuffy;
+  while (i >= 0)
+    if (((BUFFY*) Incoming->data[i--])->msg_unread)
+      return (i+1);
+  return (-1);
 }
 
+void sidebar_scroll (int op, int menu) {
+  int i = 0;
 
-void scroll_sidebar (int op, int menu)
-{
-  BUFFY *tmp;
-
-  if (!SidebarWidth)
-    return;
-  if (!CurBuffy)
+  if (!SidebarWidth || list_empty(Incoming))
     return;
 
   switch (op) {
   case OP_SIDEBAR_NEXT:
     if (!option (OPTSIDEBARNEWMAILONLY)) {
-      if (CurBuffy->next == NULL) {
+      if (CurBuffy + 1 == Incoming->length) {
         mutt_error (_("You are on the last mailbox."));
         return;
       }
-      CurBuffy = CurBuffy->next;
+      CurBuffy++;
       break;
     }                           /* the fall-through is intentional */
   case OP_SIDEBAR_NEXT_NEW:
-    if ((tmp = exist_next_new ()) == NULL) {
+    if ((i = exist_next_new ()) < 0) {
       mutt_error (_("No next mailboxes with new mail."));
       return;
     }
     else
-      CurBuffy = tmp;
+      CurBuffy = i;
     break;
   case OP_SIDEBAR_PREV:
     if (!option (OPTSIDEBARNEWMAILONLY)) {
-      if (CurBuffy->prev == NULL) {
+      if (CurBuffy == 0) {
         mutt_error (_("You are on the first mailbox."));
         return;
       }
-      CurBuffy = CurBuffy->prev;
+      CurBuffy--;
       break;
     }                           /* the fall-through is intentional */
   case OP_SIDEBAR_PREV_NEW:
-    if ((tmp = exist_prev_new ()) == NULL) {
+    if ((i = exist_prev_new ()) < 0) {
       mutt_error (_("No previous mailbox with new mail."));
       return;
     }
     else
-      CurBuffy = tmp;
+      CurBuffy = i;
     break;
 
   case OP_SIDEBAR_SCROLL_UP:
-    CurBuffy = TopBuffy;
-    if (CurBuffy != Incoming) {
-      calc_boundaries (menu);
-      CurBuffy = CurBuffy->prev;
+    if (TopBuffy == 0) {
+      mutt_error (_("You are on the first mailbox."));
+      return;
     }
+    CurBuffy -= known_lines;
+    if (CurBuffy < 0)
+      CurBuffy = 0;
     break;
   case OP_SIDEBAR_SCROLL_DOWN:
-    CurBuffy = BottomBuffy;
-    if (CurBuffy->next) {
-      calc_boundaries (menu);
-      CurBuffy = CurBuffy->next;
+    if (TopBuffy + known_lines >= Incoming->length) {
+      mutt_error (_("You are on the last mailbox."));
+      return;
     }
+    CurBuffy += known_lines;
+    if (CurBuffy >= Incoming->length)
+      CurBuffy = Incoming->length;
     break;
   default:
     return;
   }
   calc_boundaries (menu);
-  draw_sidebar (menu);
+  sidebar_draw (menu);
 }