NeoMutt  2024-04-25-76-g20fe7b
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
list.c
Go to the documentation of this file.
1
30#include "config.h"
31#include <stdbool.h>
32#include "list.h"
33#include "buffer.h"
34#include "memory.h"
35#include "queue.h"
36#include "string2.h"
37
46struct ListNode *mutt_list_insert_head(struct ListHead *h, char *s)
47{
48 if (!h)
49 return NULL;
50
51 struct ListNode *np = mutt_mem_calloc(1, sizeof(struct ListNode));
52 np->data = s;
53 STAILQ_INSERT_HEAD(h, np, entries);
54 return np;
55}
56
65struct ListNode *mutt_list_insert_tail(struct ListHead *h, char *s)
66{
67 if (!h)
68 return NULL;
69
70 struct ListNode *np = mutt_mem_calloc(1, sizeof(struct ListNode));
71 np->data = s;
72 STAILQ_INSERT_TAIL(h, np, entries);
73 return np;
74}
75
85struct ListNode *mutt_list_insert_after(struct ListHead *h, struct ListNode *n, char *s)
86{
87 if (!h || !n)
88 return NULL;
89
90 struct ListNode *np = mutt_mem_calloc(1, sizeof(struct ListNode));
91 np->data = s;
92 STAILQ_INSERT_AFTER(h, n, np, entries);
93 return np;
94}
95
103struct ListNode *mutt_list_find(const struct ListHead *h, const char *data)
104{
105 if (!h)
106 return NULL;
107
108 struct ListNode *np = NULL;
109 STAILQ_FOREACH(np, h, entries)
110 {
111 if (mutt_str_equal(np->data, data))
112 {
113 return np;
114 }
115 }
116 return NULL;
117}
118
123void mutt_list_free(struct ListHead *h)
124{
125 if (!h)
126 return;
127
128 struct ListNode *np = NULL, *tmp = NULL;
129 STAILQ_FOREACH_SAFE(np, h, entries, tmp)
130 {
131 STAILQ_REMOVE(h, np, ListNode, entries);
132 FREE(&np->data);
133 FREE(&np);
134 }
135
136 STAILQ_INIT(h);
137}
138
144void mutt_list_free_type(struct ListHead *h, list_free_t fn)
145{
146 if (!h || !fn)
147 return;
148
149 struct ListNode *np = NULL, *tmp = NULL;
150 STAILQ_FOREACH_SAFE(np, h, entries, tmp)
151 {
152 STAILQ_REMOVE(h, np, ListNode, entries);
153 fn((void **) &np->data);
154 FREE(&np);
155 }
156
157 STAILQ_INIT(h);
158}
159
166void mutt_list_clear(struct ListHead *h)
167{
168 if (!h)
169 return;
170
171 struct ListNode *np = NULL, *tmp = NULL;
172 STAILQ_FOREACH_SAFE(np, h, entries, tmp)
173 {
174 STAILQ_REMOVE(h, np, ListNode, entries);
175 FREE(&np);
176 }
177
178 STAILQ_INIT(h);
179}
180
194bool mutt_list_match(const char *s, struct ListHead *h)
195{
196 if (!h)
197 return false;
198
199 struct ListNode *np = NULL;
200 STAILQ_FOREACH(np, h, entries)
201 {
202 if ((*np->data == '*') || mutt_istr_startswith(s, np->data))
203 return true;
204 }
205 return false;
206}
207
217bool mutt_list_equal(const struct ListHead *ah, const struct ListHead *bh)
218{
219 if (!ah || !bh)
220 return false;
221
222 struct ListNode *a = STAILQ_FIRST(ah);
223 struct ListNode *b = STAILQ_FIRST(bh);
224
225 while (a && b)
226 {
227 if (!mutt_str_equal(a->data, b->data))
228 return false;
229
230 a = STAILQ_NEXT(a, entries);
231 b = STAILQ_NEXT(b, entries);
232 }
233 if (a || b)
234 return false;
235
236 return true;
237}
238
246size_t mutt_list_str_split(struct ListHead *head, const char *src, char sep)
247{
248 if (!src || (*src == '\0'))
249 return 0;
250
251 size_t count = 0;
252 while (true)
253 {
254 const char *start = src;
255 while ((*src != '\0') && (*src != sep))
256 src++;
257
258 mutt_list_insert_tail(head, mutt_strn_dup(start, src - start));
259 count++;
260
261 if ((*src == '\0'))
262 break;
263
264 src++;
265 }
266
267 return count;
268}
269
275void mutt_list_copy_tail(struct ListHead *dst, const struct ListHead *src)
276{
277 const struct ListNode *np = NULL;
278
279 STAILQ_FOREACH(np, src, entries)
280 {
282 }
283}
284
293size_t mutt_list_write(const struct ListHead *h, struct Buffer *buf)
294{
295 if (!buf || !h)
296 return 0;
297
298 struct ListNode *np = NULL;
299 STAILQ_FOREACH(np, h, entries)
300 {
301 buf_addstr(buf, np->data);
302 if (STAILQ_NEXT(np, entries))
303 buf_addstr(buf, " ");
304 }
305
306 return buf_len(buf);
307}
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:491
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:226
General purpose object for storing and parsing strings.
void mutt_list_copy_tail(struct ListHead *dst, const struct ListHead *src)
Copy a list into another list.
Definition: list.c:275
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:65
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition: list.c:103
struct ListNode * mutt_list_insert_head(struct ListHead *h, char *s)
Insert a string at the beginning of a List.
Definition: list.c:46
size_t mutt_list_write(const struct ListHead *h, struct Buffer *buf)
Write a list to a buffer.
Definition: list.c:293
void mutt_list_clear(struct ListHead *h)
Free a list, but NOT its strings.
Definition: list.c:166
size_t mutt_list_str_split(struct ListHead *head, const char *src, char sep)
Split a string into a list using a separator char.
Definition: list.c:246
bool mutt_list_equal(const struct ListHead *ah, const struct ListHead *bh)
Compare two string lists.
Definition: list.c:217
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:123
void mutt_list_free_type(struct ListHead *h, list_free_t fn)
Free a List of type.
Definition: list.c:144
bool mutt_list_match(const char *s, struct ListHead *h)
Is the string in the list (see notes)
Definition: list.c:194
struct ListNode * mutt_list_insert_after(struct ListHead *h, struct ListNode *n, char *s)
Insert a string after a given ListNode.
Definition: list.c:85
Singly-linked list type.
void(* list_free_t)(void **ptr)
Definition: list.h:49
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
Memory management wrappers.
#define FREE(x)
Definition: memory.h:45
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:380
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:253
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:660
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:242
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:402
#define STAILQ_INIT(head)
Definition: queue.h:372
#define STAILQ_FIRST(head)
Definition: queue.h:350
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:389
#define STAILQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:383
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
#define STAILQ_NEXT(elm, field)
Definition: queue.h:400
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field)
Definition: queue.h:377
String manipulation functions.
String manipulation buffer.
Definition: buffer.h:36
A List node for strings.
Definition: list.h:36
char * data
String.
Definition: list.h:37