NeoMutt  2018-07-16 +2481-68dcde
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 <string.h>
33 #include "list.h"
34 #include "memory.h"
35 #include "queue.h"
36 #include "string2.h"
37 
46 struct 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 
65 struct 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 
85 struct 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 
103 struct 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 ((np->data == data) || (mutt_str_strcmp(np->data, data) == 0))
112  {
113  return np;
114  }
115  }
116  return NULL;
117 }
118 
123 void mutt_list_free(struct ListHead *h)
124 {
125  if (!h)
126  return;
127 
128  struct ListNode *np = STAILQ_FIRST(h);
129  struct ListNode *next = NULL;
130  while (np)
131  {
132  next = STAILQ_NEXT(np, entries);
133  FREE(&np->data);
134  FREE(&np);
135  np = next;
136  }
137  STAILQ_INIT(h);
138 }
139 
145 void mutt_list_free_type(struct ListHead *h, list_free_t fn)
146 {
147  if (!h || !fn)
148  return;
149 
150  struct ListNode *np = STAILQ_FIRST(h);
151  struct ListNode *next = NULL;
152  while (np)
153  {
154  next = STAILQ_NEXT(np, entries);
155  fn((void **) &np->data);
156  FREE(&np);
157  np = next;
158  }
159  STAILQ_INIT(h);
160 }
161 
168 void mutt_list_clear(struct ListHead *h)
169 {
170  if (!h)
171  return;
172 
173  struct ListNode *np = NULL, *tmp = NULL;
174  STAILQ_FOREACH_SAFE(np, h, entries, tmp)
175  {
176  STAILQ_REMOVE(h, np, ListNode, entries);
177  FREE(&np);
178  }
179 
180  STAILQ_INIT(h);
181 }
182 
196 bool mutt_list_match(const char *s, struct ListHead *h)
197 {
198  if (!h)
199  return false;
200 
201  struct ListNode *np = NULL;
202  STAILQ_FOREACH(np, h, entries)
203  {
204  if ((*np->data == '*') || mutt_str_startswith(s, np->data, CASE_IGNORE))
205  return true;
206  }
207  return false;
208 }
209 
219 bool mutt_list_compare(const struct ListHead *ah, const struct ListHead *bh)
220 {
221  if (!ah || !bh)
222  return false;
223 
224  struct ListNode *a = STAILQ_FIRST(ah);
225  struct ListNode *b = STAILQ_FIRST(bh);
226 
227  while (a && b)
228  {
229  if (mutt_str_strcmp(a->data, b->data) != 0)
230  return false;
231 
232  a = STAILQ_NEXT(a, entries);
233  b = STAILQ_NEXT(b, entries);
234  }
235  if (a || b)
236  return false;
237 
238  return true;
239 }
240 
246 struct ListHead mutt_list_str_split(const char *src, char sep)
247 {
248  struct ListHead head = STAILQ_HEAD_INITIALIZER(head);
249 
250  if (!src || !*src)
251  return head;
252 
253  while (true)
254  {
255  const char *start = src;
256  while (*src && (*src != sep))
257  src++;
258 
259  mutt_list_insert_tail(&head, mutt_str_substr_dup(start, src));
260 
261  if (!*src)
262  break;
263 
264  src++;
265  }
266 
267  return head;
268 }
struct ListHead mutt_list_str_split(const char *src, char sep)
Split a string into a list using a separator char.
Definition: list.c:246
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:400
Memory management wrappers.
bool mutt_list_match(const char *s, struct ListHead *h)
Is the string in the list (see notes)
Definition: list.c:196
void mutt_list_free_type(struct ListHead *h, list_free_t fn)
Free a List of type.
Definition: list.c:145
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:387
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:123
String manipulation functions.
#define STAILQ_INIT(head)
Definition: queue.h:370
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition: list.c:103
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:360
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:65
Singly-linked list type.
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
#define STAILQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:381
Ignore case when comparing strings.
Definition: string2.h:68
struct ListNode * mutt_list_insert_head(struct ListHead *h, char *s)
Insert a string at the beginning of a List.
Definition: list.c:46
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
#define STAILQ_NEXT(elm, field)
Definition: queue.h:398
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
char * data
String.
Definition: list.h:35
#define FREE(x)
Definition: memory.h:40
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:322
bool mutt_list_compare(const struct ListHead *ah, const struct ListHead *bh)
Compare two string lists.
Definition: list.c:219
void mutt_list_clear(struct ListHead *h)
Free a list, but NOT its strings.
Definition: list.c:168
A List node for strings.
Definition: list.h:33
char * mutt_str_substr_dup(const char *begin, const char *end)
Duplicate a sub-string.
Definition: string.c:579
#define STAILQ_FIRST(head)
Definition: queue.h:348
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field)
Definition: queue.h:375
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
void(* list_free_t)(void **ptr)
typedef list_free_t - Prototype for a function to free List data
Definition: list.h:44