NeoMutt  2022-04-29-249-gaae397
Teaching an old dog new tricks
DOXYGEN
list.c
Go to the documentation of this file.
1
30#include "config.h"
31#include <stdbool.h>
32#include "list.h"
33#include "memory.h"
34#include "queue.h"
35#include "string2.h"
36
45struct ListNode *mutt_list_insert_head(struct ListHead *h, char *s)
46{
47 if (!h)
48 return NULL;
49
50 struct ListNode *np = mutt_mem_calloc(1, sizeof(struct ListNode));
51 np->data = s;
52 STAILQ_INSERT_HEAD(h, np, entries);
53 return np;
54}
55
64struct ListNode *mutt_list_insert_tail(struct ListHead *h, char *s)
65{
66 if (!h)
67 return NULL;
68
69 struct ListNode *np = mutt_mem_calloc(1, sizeof(struct ListNode));
70 np->data = s;
71 STAILQ_INSERT_TAIL(h, np, entries);
72 return np;
73}
74
84struct ListNode *mutt_list_insert_after(struct ListHead *h, struct ListNode *n, char *s)
85{
86 if (!h || !n)
87 return NULL;
88
89 struct ListNode *np = mutt_mem_calloc(1, sizeof(struct ListNode));
90 np->data = s;
91 STAILQ_INSERT_AFTER(h, n, np, entries);
92 return np;
93}
94
102struct ListNode *mutt_list_find(const struct ListHead *h, const char *data)
103{
104 if (!h)
105 return NULL;
106
107 struct ListNode *np = NULL;
108 STAILQ_FOREACH(np, h, entries)
109 {
110 if (mutt_str_equal(np->data, data))
111 {
112 return np;
113 }
114 }
115 return NULL;
116}
117
122void mutt_list_free(struct ListHead *h)
123{
124 if (!h)
125 return;
126
127 struct ListNode *np = STAILQ_FIRST(h);
128 struct ListNode *next = NULL;
129 while (np)
130 {
131 next = STAILQ_NEXT(np, entries);
132 FREE(&np->data);
133 FREE(&np);
134 np = next;
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 = STAILQ_FIRST(h);
150 struct ListNode *next = NULL;
151 while (np)
152 {
153 next = STAILQ_NEXT(np, entries);
154 fn((void **) &np->data);
155 FREE(&np);
156 np = next;
157 }
158 STAILQ_INIT(h);
159}
160
167void mutt_list_clear(struct ListHead *h)
168{
169 if (!h)
170 return;
171
172 struct ListNode *np = NULL, *tmp = NULL;
173 STAILQ_FOREACH_SAFE(np, h, entries, tmp)
174 {
175 STAILQ_REMOVE(h, np, ListNode, entries);
176 FREE(&np);
177 }
178
179 STAILQ_INIT(h);
180}
181
195bool mutt_list_match(const char *s, struct ListHead *h)
196{
197 if (!h)
198 return false;
199
200 struct ListNode *np = NULL;
201 STAILQ_FOREACH(np, h, entries)
202 {
203 if ((*np->data == '*') || mutt_istr_startswith(s, np->data))
204 return true;
205 }
206 return false;
207}
208
218bool mutt_list_compare(const struct ListHead *ah, const struct ListHead *bh)
219{
220 if (!ah || !bh)
221 return false;
222
223 struct ListNode *a = STAILQ_FIRST(ah);
224 struct ListNode *b = STAILQ_FIRST(bh);
225
226 while (a && b)
227 {
228 if (!mutt_str_equal(a->data, b->data))
229 return false;
230
231 a = STAILQ_NEXT(a, entries);
232 b = STAILQ_NEXT(b, entries);
233 }
234 if (a || b)
235 return false;
236
237 return true;
238}
239
247size_t mutt_list_str_split(struct ListHead *head, const char *src, char sep)
248{
249 if (!src || (*src == '\0'))
250 return 0;
251
252 size_t count = 0;
253 while (true)
254 {
255 const char *start = src;
256 while ((*src != '\0') && (*src != sep))
257 src++;
258
259 mutt_list_insert_tail(head, mutt_strn_dup(start, src - start));
260 count++;
261
262 if ((*src == '\0'))
263 break;
264
265 src++;
266 }
267
268 return count;
269}
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition: list.c:102
struct ListNode * mutt_list_insert_head(struct ListHead *h, char *s)
Insert a string at the beginning of a List.
Definition: list.c:45
bool mutt_list_compare(const struct ListHead *ah, const struct ListHead *bh)
Compare two string lists.
Definition: list.c:218
void mutt_list_clear(struct ListHead *h)
Free a list, but NOT its strings.
Definition: list.c:167
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:247
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
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:195
struct ListNode * mutt_list_insert_after(struct ListHead *h, struct ListNode *n, char *s)
Insert a string after a given ListNode.
Definition: list.c:84
Singly-linked list type.
void(* list_free_t)(void **ptr)
Definition: list.h:48
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
Memory management wrappers.
#define FREE(x)
Definition: memory.h:43
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:451
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:239
#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.
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36