]> granicus.if.org Git - neomutt/commitdiff
Convert mutt_addr_remove_from_list and mutt_addr_remove_xrefs API to AddressList
authorPietro Cerutti <gahr@gahr.ch>
Mon, 13 May 2019 13:14:57 +0000 (13:14 +0000)
committerRichard Russon <rich@flatcap.org>
Thu, 23 May 2019 10:57:09 +0000 (11:57 +0100)
address/address.c
address/address.h
address/group.c
address/group.h
send.c
test/address/mutt_addr_remove_from_list.c
test/address/mutt_addr_remove_xrefs.c
test/group/mutt_group_match.c
test/group/mutt_grouplist_add.c

index 93de1114602e45bf2161c92b9d349ae273aaaffe..8cdf10b5f3ecd982cc8c8399690574e457428092 100644 (file)
@@ -401,20 +401,20 @@ struct Address *mutt_addr_new(void)
 
 /**
  * mutt_addr_remove_from_list - Remove an Address from a list
- * @param[out] a       Address list
+ * @param[in, out] al AddressList
  * @param[in]  mailbox Email address to match
  * @retval  0 Success
  * @retval -1 Error, or email not found
  */
-int mutt_addr_remove_from_list(struct Address **a, const char *mailbox)
+int mutt_addr_remove_from_list(struct AddressList *al, const char *mailbox)
 {
-  if (!a)
+  if (!al)
     return -1;
+
   if (!mailbox)
     return 0;
 
   int rc = -1;
-  struct AddressList *al = mutt_addr_to_addresslist(*a);
   struct AddressNode *an, *tmp;
   TAILQ_FOREACH_SAFE(an, al, entries, tmp)
   {
@@ -425,9 +425,6 @@ int mutt_addr_remove_from_list(struct Address **a, const char *mailbox)
     }
   }
 
-  *a = mutt_addresslist_to_addr(al);
-  FREE(&al);
-
   return rc;
 }
 
@@ -451,16 +448,7 @@ void mutt_addresslist_free(struct AddressList **al)
 {
   if (!al)
     return;
-
-  struct AddressNode *np = TAILQ_FIRST(*al), *next = NULL;
-  while (np)
-  {
-    next = TAILQ_NEXT(np, entries);
-    free_address(&np->addr);
-    FREE(&np);
-    np = next;
-  }
-  TAILQ_INIT(*al);
+  mutt_addresslist_free_all(*al);
   FREE(al);
 }
 
@@ -1405,35 +1393,27 @@ struct Address *mutt_addrlist_dedupe(struct Address *addr)
  * mutt_addr_remove_xrefs - Remove cross-references
  * @param a Reference list of Addresses
  * @param b Address list to trim
- * @retval ptr Updated Address list
  *
  * Remove addresses from "b" which are contained in "a"
  */
-struct Address *mutt_addr_remove_xrefs(const struct Address *a, struct Address *b)
+void mutt_addr_remove_xrefs(const struct AddressList *a, struct AddressList *b)
 {
   if (!a || !b)
-    return NULL;
+    return;
 
-  struct AddressList *ala = mutt_addr_to_addresslist((struct Address *) a);
-  struct AddressList *alb = mutt_addr_to_addresslist(b);
   struct AddressNode *ana, *anb, *tmp;
 
-  TAILQ_FOREACH_SAFE(anb, alb, entries, tmp)
+  TAILQ_FOREACH_SAFE(anb, b, entries, tmp)
   {
-    TAILQ_FOREACH(ana, ala, entries)
+    TAILQ_FOREACH(ana, a, entries)
     {
       if (mutt_addr_cmp(ana->addr, anb->addr))
       {
-        mutt_addresslist_free_one(alb, anb);
+        mutt_addresslist_free_one(b, anb);
         break;
       }
     }
   }
-
-  b = mutt_addresslist_to_addr(alb);
-  FREE(&ala);
-  FREE(&alb);
-  return b;
 }
 
 /**
@@ -1515,3 +1495,38 @@ void mutt_addresslist_free_one(struct AddressList *al, struct AddressNode *an)
   free_address(&an->addr);
   FREE(&an);
 }
+
+/**
+ * mutt_addresslist_free_one - Unlinks all AddressNodes from an AddressList,
+ * frees the referenced Addresses and reinitialize the AddressList.
+ * @param al AddressList
+ */
+void mutt_addresslist_free_all(struct AddressList *al)
+{
+  struct AddressNode *np = TAILQ_FIRST(al), *next = NULL;
+  while (np)
+  {
+    next = TAILQ_NEXT(np, entries);
+    free_address(&np->addr);
+    FREE(&np);
+    np = next;
+  }
+  TAILQ_INIT(al);
+}
+
+/**
+ * mutt_addresslist_clear - Unlinks all AddressNodes from an AddressList
+ * and reinitialize the AddressList.
+ * @param al AddressList
+ */
+void mutt_addresslist_clear(struct AddressList *al)
+{
+  struct AddressNode *np = TAILQ_FIRST(al), *next = NULL;
+  while (np)
+  {
+    next = TAILQ_NEXT(np, entries);
+    FREE(&np);
+    np = next;
+  }
+  TAILQ_INIT(al);
+}
index 4801b2292c00ca1a0b7107c07b5bc9aa6eb27715..2428b1e3197c5dbef2dc4c43da19613646f34d5b 100644 (file)
@@ -82,8 +82,8 @@ struct Address *mutt_addr_new(void);
 struct Address *mutt_addr_parse_list(struct Address *top, const char *s);
 struct Address *mutt_addr_parse_list2(struct Address *p, const char *s);
 void            mutt_addr_qualify(struct Address *addr, const char *host);
-int             mutt_addr_remove_from_list(struct Address **a, const char *mailbox);
-struct Address *mutt_addr_remove_xrefs(const struct Address *a, struct Address *b);
+int             mutt_addr_remove_from_list(struct AddressList *a, const char *mailbox);
+void            mutt_addr_remove_xrefs(const struct AddressList *a, struct AddressList *b);
 bool            mutt_addr_search(struct Address *a, struct Address *lst);
 void            mutt_addr_set_intl(struct Address *a, char *intl_mailbox);
 void            mutt_addr_set_local(struct Address *a, char *local_mailbox);
@@ -96,10 +96,12 @@ int             mutt_addrlist_to_local(struct Address *a);
 
 struct AddressList *mutt_addr_to_addresslist(struct Address *a);
 struct AddressList *mutt_addresslist_new(void);
-struct Address     *mutt_addresslist_to_addr(struct AddressList *alist);
+struct Address     *mutt_addresslist_to_addr(struct AddressList *al);
 void                mutt_addresslist_append(struct AddressList *al, struct Address *a);
 struct AddressList *mutt_addresslist_copy(const struct AddressList *al, bool prune);
-void                mutt_addresslist_free(struct AddressList **alist);
-void                mutt_addresslist_free_one(struct AddressList *alist, struct AddressNode *anode);
+void                mutt_addresslist_clear(struct AddressList *al);
+void                mutt_addresslist_free(struct AddressList **al);
+void                mutt_addresslist_free_one(struct AddressList *al, struct AddressNode *anode);
+void                mutt_addresslist_free_all(struct AddressList *al);
 
 #endif /* MUTT_EMAIL_ADDRESS_H */
index ffbfa759a99e24de4a1a332aeffa807249a7ec3e..400f526ed999fec46627b14c67f010748eabeb5c 100644 (file)
@@ -88,7 +88,7 @@ static void group_remove(struct Group *g)
   if (!g)
     return;
   mutt_hash_delete(Groups, g->name, g);
-  mutt_addr_free(&g->as);
+  mutt_addresslist_free_all(&g->al);
   mutt_regexlist_free(&g->rs);
   FREE(&g->name);
   FREE(&g);
@@ -124,7 +124,7 @@ static bool empty_group(struct Group *g)
 {
   if (!g)
     return true;
-  return !g->as && STAILQ_EMPTY(&g->rs);
+  return TAILQ_EMPTY(&g->al) && STAILQ_EMPTY(&g->rs);
 }
 
 /**
@@ -170,23 +170,22 @@ void mutt_grouplist_destroy(struct GroupList *head)
 
 /**
  * group_add_addrlist - Add an Address List to a Group
- * @param g Group to add to
- * @param a Address List
+ * @param g  Group to add to
+ * @param al Address List
  */
-static void group_add_addrlist(struct Group *g, struct Address *a)
+static void group_add_addrlist(struct Group *g, const struct AddressList *al)
 {
-  if (!g || !a)
+  if (!g || !al)
     return;
 
-  struct Address **p = NULL;
-  struct Address *q = NULL;
-
-  for (p = &g->as; *p; p = &((*p)->next))
-    ;
-
-  q = mutt_addr_copy_list(a, false);
-  q = mutt_addr_remove_xrefs(g->as, q);
-  *p = q;
+  struct AddressList *new = mutt_addresslist_copy(al, false);
+  mutt_addr_remove_xrefs(&g->al, new);
+  struct AddressNode *np, *tmp;
+  TAILQ_FOREACH_SAFE(np, new, entries, tmp)
+  {
+    TAILQ_INSERT_TAIL(&g->al, np, entries);
+  }
+  FREE(&new);
 }
 
 /**
@@ -196,13 +195,14 @@ static void group_add_addrlist(struct Group *g, struct Address *a)
  * @retval  0 Success
  * @retval -1 Error
  */
-static int group_remove_addrlist(struct Group *g, struct Address *a)
+static int group_remove_addrlist(struct Group *g, struct AddressList *al)
 {
-  if (!g || !a)
+  if (!g || !al)
     return -1;
 
-  for (struct Address *p = a; p; p = p->next)
-    mutt_addr_remove_from_list(&g->as, p->mailbox);
+  struct AddressNode *np = NULL;
+  TAILQ_FOREACH(np, al, entries)
+  mutt_addr_remove_from_list(&g->al, np->addr->mailbox);
 
   return 0;
 }
@@ -243,11 +243,16 @@ void mutt_grouplist_add_addrlist(struct GroupList *head, struct Address *a)
   if (!head || !a)
     return;
 
+  struct AddressList *al = mutt_addr_to_addresslist(a);
+
   struct GroupNode *np = NULL;
   STAILQ_FOREACH(np, head, entries)
   {
-    group_add_addrlist(np->group, a);
+    group_add_addrlist(np->group, al);
   }
+
+  mutt_addresslist_to_addr(al);
+  FREE(&al);
 }
 
 /**
@@ -264,15 +269,19 @@ int mutt_grouplist_remove_addrlist(struct GroupList *head, struct Address *a)
 
   int rc = 0;
   struct GroupNode *np = NULL;
+  struct AddressList *al = mutt_addr_to_addresslist(a);
 
   STAILQ_FOREACH(np, head, entries)
   {
-    rc = group_remove_addrlist(np->group, a);
+    rc = group_remove_addrlist(np->group, al);
     if (empty_group(np->group))
       group_remove(np->group);
     if (rc)
-      return rc;
+      break;
   }
+
+  mutt_addresslist_clear(al);
+  FREE(&al);
   return rc;
 }
 
@@ -341,9 +350,12 @@ bool mutt_group_match(struct Group *g, const char *s)
 
   if (mutt_regexlist_match(&g->rs, s))
     return true;
-  for (struct Address *ap = g->as; ap; ap = ap->next)
-    if (ap->mailbox && (mutt_str_strcasecmp(s, ap->mailbox) == 0))
+  struct AddressNode *np = NULL;
+  TAILQ_FOREACH(np, &g->al, entries)
+  {
+    if (np->addr->mailbox && (mutt_str_strcasecmp(s, np->addr->mailbox) == 0))
       return true;
+  }
 
   return false;
 }
index ba007600b73b965f6ef4148a6e309c35c569ea4e..10a9053482ea40e99f4117044ebdf7742a137a2e 100644 (file)
@@ -37,7 +37,7 @@ struct Address;
  */
 struct Group
 {
-  struct Address *as;
+  struct AddressList al;
   struct RegexList rs;
   char *name;
 };
diff --git a/send.c b/send.c
index 03c8d2eb34a4f8afeef259b5a790a30e73d58517..5ec22a219397b4e32b15f658fae9deb335d99095 100644 (file)
--- a/send.c
+++ b/send.c
@@ -921,7 +921,14 @@ void mutt_fix_reply_recipients(struct Envelope *env)
   /* the CC field can get cluttered, especially with lists */
   env->to = mutt_addrlist_dedupe(env->to);
   env->cc = mutt_addrlist_dedupe(env->cc);
-  env->cc = mutt_addr_remove_xrefs(env->to, env->cc);
+  struct AddressList *toal = mutt_addr_to_addresslist(env->to);
+  struct AddressList *ccal = mutt_addr_to_addresslist(env->cc);
+  mutt_addr_remove_xrefs(toal, ccal);
+  env->cc = mutt_addresslist_to_addr(ccal);
+  mutt_addresslist_clear(toal);
+  FREE(&toal);
+  mutt_addresslist_clear(ccal);
+  FREE(&ccal);
 
   if (env->cc && !env->to)
   {
index 96d313afd91e05eacdb2d9b34d1852aab42af721..b21e2915e2920eb6d72e9df4be88987fca347965 100644 (file)
@@ -31,11 +31,13 @@ void test_mutt_addr_remove_from_list(void)
   // int mutt_addr_remove_from_list(struct Address **a, const char *mailbox);
 
   {
-    TEST_CHECK(mutt_addr_remove_from_list(NULL, "apple") == -1);
+    int rc = mutt_addr_remove_from_list(NULL, "apple");
+    TEST_CHECK(rc == -1);
   }
 
   {
-    struct Address *addr = NULL;
-    TEST_CHECK(mutt_addr_remove_from_list(&addr, NULL) == 0);
+    struct AddressList a;
+    int rc = mutt_addr_remove_from_list(&a, NULL);
+    TEST_CHECK(rc == 0);
   }
 }
index 1e282fcaf5b18a404700babf6551833147a41679..55ddcf33cb22e8cfe93b6bc8936d34730f63ede3 100644 (file)
 
 void test_mutt_addr_remove_xrefs(void)
 {
-  // struct Address *mutt_addr_remove_xrefs(struct Address *a, struct Address *b);
-
-  {
-    struct Address addr = { 0 };
-    TEST_CHECK(mutt_addr_remove_xrefs(NULL, &addr) == NULL);
-  }
-
-  {
-    struct Address addr = { 0 };
-    TEST_CHECK(mutt_addr_remove_xrefs(&addr, NULL) == NULL);
-  }
+  // TODO - check when either argument is NULL
 }
index af616bf6e10e6427c76815ffb6a921e6572a22ac..dd3e4eb3aa4617873f8f51c6cbe62ef4a335b729 100644 (file)
@@ -35,7 +35,7 @@ void test_mutt_group_match(void)
   }
 
   {
-    struct Group group = { 0 };
+    struct Group group;
     TEST_CHECK(!mutt_group_match(&group, NULL));
   }
 }
index b8b63208d1faa7a468252dd4a36d4e344b21aa5b..f844582611a258360e5fbbe48fef3ff19919e697 100644 (file)
@@ -31,7 +31,7 @@ void test_mutt_grouplist_add(void)
   // void mutt_grouplist_add(struct GroupList *head, struct Group *group);
 
   {
-    struct Group group = { 0 };
+    struct Group group;
     mutt_grouplist_add(NULL, &group);
     TEST_CHECK_(1, "mutt_grouplist_add(NULL, &group)");
   }