NeoMutt  2024-04-25-34-g585158
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
group.c
Go to the documentation of this file.
1
32#include "config.h"
33#include <assert.h>
34#include <stdbool.h>
35#include <stdlib.h>
36#include "group.h"
37#include "address.h"
38
44static struct HashTable *Groups = NULL;
45
50static void group_free(struct Group **ptr)
51{
52 if (!ptr || !*ptr)
53 return;
54
55 struct Group *g = *ptr;
56
59 FREE(&g->name);
60
61 FREE(ptr);
62}
63
71static struct Group *group_new(const char *pat)
72{
73 struct Group *g = mutt_mem_calloc(1, sizeof(struct Group));
74
75 g->name = mutt_str_dup(pat);
76 STAILQ_INIT(&g->rs);
77 TAILQ_INIT(&g->al);
78
79 return g;
80}
81
85static void group_hash_free(int type, void *obj, intptr_t data)
86{
87 struct Group *g = obj;
88 group_free(&g);
89}
90
97{
99
101}
102
109{
111}
112
118struct Group *mutt_pattern_group(const char *pat)
119{
120 if (!pat)
121 return NULL;
122
123 struct Group *g = mutt_hash_find(Groups, pat);
124 if (!g)
125 {
126 mutt_debug(LL_DEBUG2, "Creating group %s\n", pat);
127 g = group_new(pat);
129 }
130
131 return g;
132}
133
138static void group_remove(struct Group *g)
139{
140 if (!g)
141 return;
143}
144
149void mutt_grouplist_clear(struct GroupList *gl)
150{
151 if (!gl)
152 return;
153
154 struct GroupNode *np = STAILQ_FIRST(gl);
155 struct GroupNode *next = NULL;
156 while (np)
157 {
158 group_remove(np->group);
159 next = STAILQ_NEXT(np, entries);
160 FREE(&np);
161 np = next;
162 }
163 STAILQ_INIT(gl);
164}
165
171static bool empty_group(struct Group *g)
172{
173 if (!g)
174 return true;
175 return TAILQ_EMPTY(&g->al) && STAILQ_EMPTY(&g->rs);
176}
177
183void mutt_grouplist_add(struct GroupList *gl, struct Group *group)
184{
185 if (!gl || !group)
186 return;
187
188 struct GroupNode *np = NULL;
189 STAILQ_FOREACH(np, gl, entries)
190 {
191 if (np->group == group)
192 return;
193 }
194 np = mutt_mem_calloc(1, sizeof(struct GroupNode));
195 np->group = group;
196 STAILQ_INSERT_TAIL(gl, np, entries);
197}
198
203void mutt_grouplist_destroy(struct GroupList *gl)
204{
205 if (!gl)
206 return;
207
208 struct GroupNode *np = STAILQ_FIRST(gl);
209 struct GroupNode *next = NULL;
210 while (np)
211 {
212 next = STAILQ_NEXT(np, entries);
213 FREE(&np);
214 np = next;
215 }
216 STAILQ_INIT(gl);
217}
218
224static void group_add_addrlist(struct Group *g, const struct AddressList *al)
225{
226 if (!g || !al)
227 return;
228
229 struct AddressList al_new = TAILQ_HEAD_INITIALIZER(al_new);
230 mutt_addrlist_copy(&al_new, al, false);
231 mutt_addrlist_remove_xrefs(&g->al, &al_new);
232 struct Address *a = NULL, *tmp = NULL;
233 TAILQ_FOREACH_SAFE(a, &al_new, entries, tmp)
234 {
235 TAILQ_REMOVE(&al_new, a, entries);
236 mutt_addrlist_append(&g->al, a);
237 }
238 assert(TAILQ_EMPTY(&al_new));
239}
240
250static int group_add_regex(struct Group *g, const char *s, uint16_t flags, struct Buffer *err)
251{
252 return mutt_regexlist_add(&g->rs, s, flags, err);
253}
254
262static int group_remove_regex(struct Group *g, const char *s)
263{
264 return mutt_regexlist_remove(&g->rs, s);
265}
266
272void mutt_grouplist_add_addrlist(struct GroupList *gl, struct AddressList *al)
273{
274 if (!gl || !al)
275 return;
276
277 struct GroupNode *np = NULL;
278 STAILQ_FOREACH(np, gl, entries)
279 {
280 group_add_addrlist(np->group, al);
281 }
282}
283
291int mutt_grouplist_remove_addrlist(struct GroupList *gl, struct AddressList *al)
292{
293 if (!gl || !al)
294 return -1;
295
296 struct GroupNode *gnp = NULL;
297 STAILQ_FOREACH(gnp, gl, entries)
298 {
299 struct Address *a = NULL;
300 TAILQ_FOREACH(a, al, entries)
301 {
303 }
304 if (empty_group(gnp->group))
305 {
306 group_remove(gnp->group);
307 }
308 }
309
310 return 0;
311}
312
322int mutt_grouplist_add_regex(struct GroupList *gl, const char *s,
323 uint16_t flags, struct Buffer *err)
324{
325 if (!gl || !s)
326 return -1;
327
328 int rc = 0;
329
330 struct GroupNode *np = NULL;
331 STAILQ_FOREACH(np, gl, entries)
332 {
333 rc = group_add_regex(np->group, s, flags, err);
334 if (rc)
335 return rc;
336 }
337 return rc;
338}
339
347int mutt_grouplist_remove_regex(struct GroupList *gl, const char *s)
348{
349 if (!gl || !s)
350 return -1;
351
352 int rc = 0;
353 struct GroupNode *np = NULL;
354 STAILQ_FOREACH(np, gl, entries)
355 {
356 rc = group_remove_regex(np->group, s);
357 if (empty_group(np->group))
358 group_remove(np->group);
359 if (rc)
360 return rc;
361 }
362 return rc;
363}
364
371bool mutt_group_match(struct Group *g, const char *s)
372{
373 if (!g || !s)
374 return false;
375
376 if (mutt_regexlist_match(&g->rs, s))
377 return true;
378 struct Address *a = NULL;
379 TAILQ_FOREACH(a, &g->al, entries)
380 {
381 if (a->mailbox && mutt_istr_equal(s, buf_string(a->mailbox)))
382 return true;
383 }
384
385 return false;
386}
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:765
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1460
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1480
void mutt_addrlist_remove_xrefs(const struct AddressList *a, struct AddressList *b)
Remove cross-references.
Definition: address.c:1433
int mutt_addrlist_remove(struct AddressList *al, const char *mailbox)
Remove an Address from a list.
Definition: address.c:435
Representation of an email address.
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
static bool empty_group(struct Group *g)
Is a Group empty?
Definition: group.c:171
static int group_add_regex(struct Group *g, const char *s, uint16_t flags, struct Buffer *err)
Add a Regex to a Group.
Definition: group.c:250
int mutt_grouplist_remove_addrlist(struct GroupList *gl, struct AddressList *al)
Remove an AddressList from a GroupList.
Definition: group.c:291
void mutt_grouplist_add(struct GroupList *gl, struct Group *group)
Add a Group to a GroupList.
Definition: group.c:183
static void group_remove(struct Group *g)
Remove a Group from the Hash Table.
Definition: group.c:138
static void group_add_addrlist(struct Group *g, const struct AddressList *al)
Add an Address List to a Group.
Definition: group.c:224
static struct HashTable * Groups
Hash Table: "group-name" -> Group.
Definition: group.c:44
static void group_free(struct Group **ptr)
Free an Address Group.
Definition: group.c:50
bool mutt_group_match(struct Group *g, const char *s)
Does a string match an entry in a Group?
Definition: group.c:371
int mutt_grouplist_add_regex(struct GroupList *gl, const char *s, uint16_t flags, struct Buffer *err)
Add matching Addresses to a GroupList.
Definition: group.c:322
static struct Group * group_new(const char *pat)
Create a new Address Group.
Definition: group.c:71
static int group_remove_regex(struct Group *g, const char *s)
Remove a Regex from a Group.
Definition: group.c:262
struct Group * mutt_pattern_group(const char *pat)
Match a pattern to a Group.
Definition: group.c:118
int mutt_grouplist_remove_regex(struct GroupList *gl, const char *s)
Remove matching addresses from a GroupList.
Definition: group.c:347
void mutt_grouplist_init(void)
Initialize the GroupList singleton.
Definition: group.c:96
void mutt_grouplist_destroy(struct GroupList *gl)
Free a GroupList.
Definition: group.c:203
void mutt_grouplist_clear(struct GroupList *gl)
Clear a GroupList.
Definition: group.c:149
void mutt_grouplist_add_addrlist(struct GroupList *gl, struct AddressList *al)
Add Address list to a GroupList.
Definition: group.c:272
void mutt_grouplist_cleanup(void)
Free GroupList singleton resource.
Definition: group.c:108
Handling for email address groups.
static void group_hash_free(int type, void *obj, intptr_t data)
Free our hash table data - Implements hash_hdata_free_t -.
Definition: group.c:85
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:335
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:427
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:362
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:259
void mutt_hash_set_destructor(struct HashTable *table, hash_hdata_free_t fn, intptr_t fn_data)
Set the destructor for a Hash Table.
Definition: hash.c:301
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
#define MUTT_HASH_NO_FLAGS
No flags are set.
Definition: hash.h:109
@ LL_DEBUG2
Log at debug level 2.
Definition: logging2.h:44
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:52
#define FREE(x)
Definition: memory.h:45
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition: regex.c:179
int mutt_regexlist_add(struct RegexList *rl, const char *str, uint16_t flags, struct Buffer *err)
Compile a regex string and add it to a list.
Definition: regex.c:140
int mutt_regexlist_remove(struct RegexList *rl, const char *str)
Remove a Regex from a list.
Definition: regex.c:235
bool mutt_regexlist_match(struct RegexList *rl, const char *str)
Does a string match any Regex in the list?
Definition: regex.c:200
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:673
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:254
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:735
#define STAILQ_INIT(head)
Definition: queue.h:372
#define STAILQ_FIRST(head)
Definition: queue.h:350
#define TAILQ_INIT(head)
Definition: queue.h:765
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:389
#define STAILQ_EMPTY(head)
Definition: queue.h:348
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:841
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
#define TAILQ_EMPTY(head)
Definition: queue.h:721
#define STAILQ_NEXT(elm, field)
Definition: queue.h:400
An email address.
Definition: address.h:36
struct Buffer * mailbox
Mailbox and host address.
Definition: address.h:38
String manipulation buffer.
Definition: buffer.h:36
An element in a GroupList.
Definition: group.h:49
struct Group * group
Address Group.
Definition: group.h:50
A set of email addresses.
Definition: group.h:39
char * name
Name of Group.
Definition: group.h:42
struct AddressList al
List of Addresses.
Definition: group.h:40
struct RegexList rs
Group Regex patterns.
Definition: group.h:41
A Hash Table.
Definition: hash.h:97