/**
* 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)
{
}
}
- *a = mutt_addresslist_to_addr(al);
- FREE(&al);
-
return rc;
}
{
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);
}
* 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;
}
/**
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);
+}
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);
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 */
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);
{
if (!g)
return true;
- return !g->as && STAILQ_EMPTY(&g->rs);
+ return TAILQ_EMPTY(&g->al) && STAILQ_EMPTY(&g->rs);
}
/**
/**
* 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);
}
/**
* @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;
}
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);
}
/**
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;
}
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;
}
*/
struct Group
{
- struct Address *as;
+ struct AddressList al;
struct RegexList rs;
char *name;
};
/* 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)
{
// 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);
}
}
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
}
}
{
- struct Group group = { 0 };
+ struct Group group;
TEST_CHECK(!mutt_group_match(&group, NULL));
}
}
// 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)");
}