]> granicus.if.org Git - neomutt/commitdiff
Convert List to STailQ in imap code
authorPietro Cerutti <gahr@gahr.ch>
Tue, 25 Jul 2017 18:13:55 +0000 (18:13 +0000)
committerRichard Russon <rich@flatcap.org>
Sat, 5 Aug 2017 17:53:06 +0000 (18:53 +0100)
Issue #374

imap/imap.c
imap/imap_private.h
imap/message.c
imap/message.h
imap/util.c
list.h

index 4d2f8d0965ae7f2f2450ee76f79b006963175be8..1f54845a2b34ea849216e10bd7ed1c4b00a44896 100644 (file)
@@ -65,7 +65,7 @@
 #endif
 
 /* imap forward declarations */
-static char *imap_get_flags(struct List **hflags, char *s);
+static char *imap_get_flags(struct STailQHead *hflags, char *s);
 static int imap_check_capabilities(struct ImapData *idata);
 static void imap_set_flag(struct ImapData *idata, int aclbit, int flag,
                           const char *str, char *flags, size_t flsize);
@@ -547,9 +547,8 @@ void imap_close_connection(struct ImapData *idata)
  *
  * return stream following FLAGS response
  */
-static char *imap_get_flags(struct List **hflags, char *s)
+static char *imap_get_flags(struct STailQHead *hflags, char *s)
 {
-  struct List *flags = NULL;
   char *flag_word = NULL;
   char ctmp;
 
@@ -567,10 +566,7 @@ static char *imap_get_flags(struct List **hflags, char *s)
     return NULL;
   }
 
-  /* create list, update caller's flags handle */
-  flags = mutt_new_list();
-  *hflags = flags;
-
+  /* update caller's flags handle */
   while (*s && *s != ')')
   {
     s++;
@@ -581,7 +577,7 @@ static char *imap_get_flags(struct List **hflags, char *s)
     ctmp = *s;
     *s = '\0';
     if (*flag_word)
-      mutt_add_list(flags, flag_word);
+      mutt_stailq_insert_tail(hflags, safe_strdup(flag_word));
     *s = ctmp;
   }
 
@@ -589,7 +585,7 @@ static char *imap_get_flags(struct List **hflags, char *s)
   if (*s != ')')
   {
     mutt_debug(1, "imap_get_flags: Unterminated FLAGS response: %s\n", s);
-    mutt_free_list(hflags);
+    mutt_stailq_free(hflags);
 
     return NULL;
   }
@@ -696,10 +692,10 @@ static int imap_open_mailbox(struct Context *ctx)
     if (mutt_strncasecmp("FLAGS", pc, 5) == 0)
     {
       /* don't override PERMANENTFLAGS */
-      if (!idata->flags)
+      if (STAILQ_EMPTY(&idata->flags))
       {
         mutt_debug(3, "Getting mailbox FLAGS\n");
-        if ((pc = imap_get_flags(&(idata->flags), pc)) == NULL)
+        if ((pc = imap_get_flags(&idata->flags, pc)) == NULL)
           goto fail;
       }
     }
@@ -708,7 +704,7 @@ static int imap_open_mailbox(struct Context *ctx)
     {
       mutt_debug(3, "Getting mailbox PERMANENTFLAGS\n");
       /* safe to call on NULL */
-      mutt_free_list(&(idata->flags));
+      mutt_stailq_free(&idata->flags);
       /* skip "OK [PERMANENT" so syntax is the same as FLAGS */
       pc += 13;
       if ((pc = imap_get_flags(&(idata->flags), pc)) == NULL)
@@ -767,19 +763,15 @@ static int imap_open_mailbox(struct Context *ctx)
   /* dump the mailbox flags we've found */
   if (debuglevel > 2)
   {
-    if (!idata->flags)
+    if (STAILQ_EMPTY(&idata->flags))
       mutt_debug(3, "No folder flags found\n");
     else
     {
-      struct List *t = idata->flags;
-
       mutt_debug(3, "Mailbox flags: ");
-
-      t = t->next;
-      while (t)
+      struct STailQNode *np;
+      STAILQ_FOREACH(np, &idata->flags, entries)
       {
-        mutt_debug(3, "[%s] ", t->data);
-        t = t->next;
+        mutt_debug(3, "[%s] ", np->data);
       }
       mutt_debug(3, "\n");
     }
@@ -901,7 +893,7 @@ static void imap_set_flag(struct ImapData *idata, int aclbit, int flag,
                           const char *str, char *flags, size_t flsize)
 {
   if (mutt_bit_isset(idata->ctx->rights, aclbit))
-    if (flag && imap_has_flag(idata->flags, str))
+    if (flag && imap_has_flag(&idata->flags, str))
       safe_strcat(flags, flsize, str);
 }
 
@@ -912,21 +904,19 @@ static void imap_set_flag(struct ImapData *idata, int aclbit, int flag,
  * Do a caseless comparison of the flag against a flag list, return true if
  * found or flag list has '\*'.
  */
-bool imap_has_flag(struct List *flag_list, const char *flag)
+bool imap_has_flag(struct STailQHead *flag_list, const char *flag)
 {
-  if (!flag_list)
+  if (STAILQ_EMPTY(flag_list))
     return false;
 
-  flag_list = flag_list->next;
-  while (flag_list)
+  struct STailQNode *np;
+  STAILQ_FOREACH(np, flag_list, entries)
   {
-    if (mutt_strncasecmp(flag_list->data, flag, strlen(flag_list->data)) == 0)
+    if (mutt_strncasecmp(np->data, flag, strlen(np->data)) == 0)
       return true;
 
-    if (mutt_strncmp(flag_list->data, "\\*", strlen(flag_list->data)) == 0)
+    if (mutt_strncmp(np->data, "\\*", strlen(np->data)) == 0)
       return true;
-
-    flag_list = flag_list->next;
   }
 
   return false;
@@ -1154,7 +1144,7 @@ int imap_sync_message(struct ImapData *idata, struct Header *hdr,
 
   /* now make sure we don't lose custom tags */
   if (mutt_bit_isset(idata->ctx->rights, MUTT_ACL_WRITE))
-    imap_add_keywords(flags, hdr, idata->flags, sizeof(flags));
+    imap_add_keywords(flags, hdr, &idata->flags, sizeof(flags));
 
   mutt_remove_trailing_ws(flags);
 
@@ -1209,7 +1199,7 @@ static int sync_helper(struct ImapData *idata, int right, int flag, const char *
   if (!mutt_bit_isset(idata->ctx->rights, right))
     return 0;
 
-  if (right == MUTT_ACL_WRITE && !imap_has_flag(idata->flags, name))
+  if (right == MUTT_ACL_WRITE && !imap_has_flag(&idata->flags, name))
     return 0;
 
   snprintf(buf, sizeof(buf), "+FLAGS.SILENT (%s)", name);
@@ -1459,7 +1449,7 @@ int imap_close_mailbox(struct Context *ctx)
 
     idata->reopen &= IMAP_REOPEN_ALLOW;
     FREE(&(idata->mailbox));
-    mutt_free_list(&idata->flags);
+    mutt_stailq_free(&idata->flags);
     idata->ctx = NULL;
 
     hash_destroy(&idata->uid_hash, NULL);
@@ -1748,18 +1738,17 @@ int imap_status(char *path, int queue)
  */
 struct ImapStatus *imap_mboxcache_get(struct ImapData *idata, const char *mbox, int create)
 {
-  struct List *cur = NULL;
   struct ImapStatus *status = NULL;
-  struct ImapStatus scache;
 #ifdef USE_HCACHE
   header_cache_t *hc = NULL;
   void *uidvalidity = NULL;
   void *uidnext = NULL;
 #endif
 
-  for (cur = idata->mboxcache; cur; cur = cur->next)
+  struct STailQNode *np;
+  STAILQ_FOREACH(np, &idata->mboxcache, entries)
   {
-    status = (struct ImapStatus *) cur->data;
+    status = (struct ImapStatus *) np->data;
 
     if (imap_mxcmp(mbox, status->name) == 0)
       return status;
@@ -1769,9 +1758,9 @@ struct ImapStatus *imap_mboxcache_get(struct ImapData *idata, const char *mbox,
   /* lame */
   if (create)
   {
-    memset(&scache, 0, sizeof(scache));
-    scache.name = (char *) mbox;
-    idata->mboxcache = mutt_add_list_n(idata->mboxcache, &scache, sizeof(scache));
+    struct ImapStatus *scache = safe_calloc(1, sizeof(struct ImapStatus));
+    scache->name = (char *) mbox;
+    mutt_stailq_insert_tail(&idata->mboxcache, (char *)scache);
     status = imap_mboxcache_get(idata, mbox, 0);
     status->name = safe_strdup(mbox);
   }
@@ -1807,17 +1796,16 @@ struct ImapStatus *imap_mboxcache_get(struct ImapData *idata, const char *mbox,
 
 void imap_mboxcache_free(struct ImapData *idata)
 {
-  struct List *cur = NULL;
   struct ImapStatus *status = NULL;
 
-  for (cur = idata->mboxcache; cur; cur = cur->next)
+  struct STailQNode *np;
+  STAILQ_FOREACH(np, &idata->mboxcache, entries)
   {
-    status = (struct ImapStatus *) cur->data;
-
+    status = (struct ImapStatus *) np->data;
     FREE(&status->name);
   }
 
-  mutt_free_list(&idata->mboxcache);
+  mutt_stailq_free(&idata->mboxcache);
 }
 
 /**
index 89d588f881b4605a3ace2f99d0dd3d3152ee13a2..0fb3b50f446ca7bdb1a0ec9ed42b51c6b163c01e 100644 (file)
@@ -30,6 +30,7 @@
 #ifdef USE_HCACHE
 #include "hcache/hcache.h"
 #endif
+#include "list.h"
 
 struct Account;
 struct Buffer;
@@ -37,7 +38,6 @@ struct Context;
 struct Header;
 struct ImapHeaderData;
 struct ImapMbox;
-struct List;
 struct Message;
 struct Progress;
 
@@ -238,7 +238,7 @@ struct ImapData
   struct Buffer *cmdbuf;
 
   /* cache ImapStatus of visited mailboxes */
-  struct List *mboxcache;
+  struct STailQHead mboxcache;
 
   /* The following data is all specific to the currently SELECTED mbox */
   char delim;
@@ -257,7 +257,7 @@ struct ImapData
   struct BodyCache *bcache;
 
   /* all folder flags - system flags AND keywords */
-  struct List *flags;
+  struct STailQHead flags;
 #ifdef USE_HCACHE
   header_cache_t *hcache;
 #endif
@@ -280,7 +280,7 @@ int imap_read_literal(FILE *fp, struct ImapData *idata, long bytes, struct Progr
 void imap_expunge_mailbox(struct ImapData *idata);
 void imap_logout(struct ImapData **idata);
 int imap_sync_message(struct ImapData *idata, struct Header *hdr, struct Buffer *cmd, int *err_continue);
-bool imap_has_flag(struct List *flag_list, const char *flag);
+bool imap_has_flag(struct STailQHead *flag_list, const char *flag);
 
 /* auth.c */
 int imap_authenticate(struct ImapData *idata);
@@ -295,7 +295,7 @@ int imap_exec(struct ImapData *idata, const char *cmd, int flags);
 int imap_cmd_idle(struct ImapData *idata);
 
 /* message.c */
-void imap_add_keywords(char *s, struct Header *keywords, struct List *mailbox_flags, size_t slen);
+void imap_add_keywords(char *s, struct Header *keywords, struct STailQHead *mailbox_flags, size_t slen);
 void imap_free_header_data(struct ImapHeaderData **data);
 int imap_read_headers(struct ImapData *idata, unsigned int msn_begin, unsigned int msn_end);
 char *imap_set_flags(struct ImapData *idata, struct Header *h, char *s);
index f888c05b4e39551a3cd9ed327b57b3f2c6ab96f6..4441fc7132877cd8bcac96f30d526e4a8b613b78 100644 (file)
 #include "hcache/hcache.h"
 #endif
 
+static struct ImapHeaderData* imap_new_header_data(void)
+{
+    struct ImapHeaderData *d = safe_calloc(1, sizeof(struct ImapHeaderData));
+    STAILQ_INIT(&d->keywords);
+    return d;
+}
+
 static void imap_update_context(struct ImapData *idata, int oldmsgcount)
 {
   struct Context *ctx = NULL;
@@ -155,7 +162,7 @@ static char *msg_parse_flags(struct ImapHeader *h, char *s)
   }
   s++;
 
-  mutt_free_list(&hd->keywords);
+  mutt_stailq_free(&hd->keywords);
   hd->deleted = hd->flagged = hd->replied = hd->read = hd->old = false;
 
   /* start parsing */
@@ -194,14 +201,11 @@ static char *msg_parse_flags(struct ImapHeader *h, char *s)
       char ctmp;
       char *flag_word = s;
 
-      if (!hd->keywords)
-        hd->keywords = mutt_new_list();
-
       while (*s && !ISSPACE(*s) && *s != ')')
         s++;
       ctmp = *s;
       *s = '\0';
-      mutt_add_list(hd->keywords, flag_word);
+      mutt_stailq_insert_tail(&hd->keywords, safe_strdup(flag_word));
       *s = ctmp;
     }
     SKIPWS(s);
@@ -570,7 +574,7 @@ int imap_read_headers(struct ImapData *idata, unsigned int msn_begin, unsigned i
       mutt_progress_update(&progress, msgno, -1);
 
       memset(&h, 0, sizeof(h));
-      h.data = safe_calloc(1, sizeof(struct ImapHeaderData));
+      h.data = imap_new_header_data();
       do
       {
         rc = imap_cmd_step(idata);
@@ -681,7 +685,7 @@ int imap_read_headers(struct ImapData *idata, unsigned int msn_begin, unsigned i
 
       rewind(fp);
       memset(&h, 0, sizeof(h));
-      h.data = safe_calloc(1, sizeof(struct ImapHeaderData));
+      h.data = imap_new_header_data();
 
       /* this DO loop does two things:
        * 1. handles untagged messages, so we can try again on the same msg
@@ -1393,23 +1397,21 @@ int imap_cache_clean(struct ImapData *idata)
  *
  * If the tags appear in the folder flags list. Why wouldn't they?
  */
-void imap_add_keywords(char *s, struct Header *h, struct List *mailbox_flags, size_t slen)
+void imap_add_keywords(char *s, struct Header *h, struct STailQHead *mailbox_flags, size_t slen)
 {
-  struct List *keywords = NULL;
+  struct STailQHead *keywords = &HEADER_DATA(h)->keywords;
 
-  if (!mailbox_flags || !HEADER_DATA(h) || !HEADER_DATA(h)->keywords)
+  if (STAILQ_EMPTY(mailbox_flags) || !HEADER_DATA(h) || STAILQ_EMPTY(keywords))
     return;
 
-  keywords = HEADER_DATA(h)->keywords->next;
-
-  while (keywords)
+  struct STailQNode *np;
+  STAILQ_FOREACH(np, keywords, entries)
   {
-    if (imap_has_flag(mailbox_flags, keywords->data))
+    if (imap_has_flag(mailbox_flags, np->data))
     {
-      safe_strcat(s, slen, keywords->data);
+      safe_strcat(s, slen, np->data);
       safe_strcat(s, slen, " ");
     }
-    keywords = keywords->next;
   }
 }
 
@@ -1421,7 +1423,7 @@ void imap_free_header_data(struct ImapHeaderData **data)
   if (*data)
   {
     /* this should be safe even if the list wasn't used */
-    mutt_free_list(&((*data)->keywords));
+    mutt_stailq_free(&(*data)->keywords);
     FREE(data);
   }
 }
index 6f05eed4556bcd8887cb32d8e667551c851190f8..03ab7023cb44ae06d54670dc3e55fe8bb2b11e12 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <stdbool.h>
 #include <time.h>
+#include "list.h"
 
 /**
  * struct ImapHeaderData - IMAP-specific header data
@@ -46,7 +47,7 @@ struct ImapHeaderData
 
   unsigned int uid; /**< 32-bit Message UID */
   unsigned int msn; /**< Message Sequence Number */
-  struct List *keywords;
+  struct STailQHead keywords;
 };
 
 /**
index e7183226ee87817f1203b72a17f870b9a7eac17b..55f2ac7a61788acfbcdb151665f10ab9c739880b 100644 (file)
@@ -517,6 +517,9 @@ struct ImapData *imap_new_idata(void)
     FREE(&idata);
   }
 
+  STAILQ_INIT(&idata->flags);
+  STAILQ_INIT(&idata->mboxcache);
+
   return idata;
 }
 
@@ -529,7 +532,7 @@ void imap_free_idata(struct ImapData **idata)
     return;
 
   FREE(&(*idata)->capstr);
-  mutt_free_list(&(*idata)->flags);
+  mutt_stailq_free(&(*idata)->flags);
   imap_mboxcache_free(*idata);
   mutt_buffer_free(&(*idata)->cmdbuf);
   FREE(&(*idata)->buf);
diff --git a/list.h b/list.h
index a83c81be2d944aa3ddb883d9f2e3d79d5842e700..887853e7de88df21456473b8cb7e70a48f60b4e5 100644 (file)
--- a/list.h
+++ b/list.h
@@ -24,6 +24,7 @@
 #define _MUTT_LIST_H
 
 #include <string.h>
+#include "lib/lib.h"
 
 /**
  * struct List - Singly-linked List type
@@ -94,10 +95,6 @@ static inline void mutt_stailq_free(struct STailQHead *h)
   STAILQ_INIT(h);
 }
 
-/**
- * mutt_stailq_match - Is the string in the list
- * @return true if the header contained in "s" is in list "h"
- */
 static inline bool mutt_stailq_match(const char *s, struct STailQHead *h)
 {
   struct STailQNode *np;