NeoMutt  2025-12-11-980-ge38c27
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
list.c File Reference

Singly-linked list type. More...

#include "config.h"
#include <stdbool.h>
#include "list.h"
#include "buffer.h"
#include "memory.h"
#include "queue.h"
#include "string2.h"
+ Include dependency graph for list.c:

Go to the source code of this file.

Functions

struct ListNodemutt_list_insert_head (struct ListHead *h, char *s)
 Insert a string at the beginning of a List.
 
struct ListNodemutt_list_insert_tail (struct ListHead *h, char *s)
 Append a string to the end of a List.
 
struct ListNodemutt_list_insert_after (struct ListHead *h, struct ListNode *n, char *s)
 Insert a string after a given ListNode.
 
struct ListNodemutt_list_find (const struct ListHead *h, const char *data)
 Find a string in a List.
 
void mutt_list_free (struct ListHead *h)
 Free a List AND its strings.
 
void mutt_list_free_type (struct ListHead *h, list_free_t fn)
 Free a List of type.
 
void mutt_list_clear (struct ListHead *h)
 Free a list, but NOT its strings.
 
bool mutt_list_match (const char *s, struct ListHead *h)
 Is the string in the list (see notes)
 
bool mutt_list_equal (const struct ListHead *ah, const struct ListHead *bh)
 Compare two string lists.
 
size_t mutt_list_str_split (struct ListHead *head, const char *src, char sep)
 Split a string into a list using a separator char.
 
void mutt_list_copy_tail (struct ListHead *dst, const struct ListHead *src)
 Copy a list into another list.
 
size_t mutt_list_write (const struct ListHead *h, struct Buffer *buf)
 Write a list to a buffer.
 
void add_to_stailq (struct ListHead *head, const char *str)
 Add a string to a list.
 
void remove_from_stailq (struct ListHead *head, const char *str)
 Remove an item, matching a string, from a List.
 

Detailed Description

Singly-linked list type.

Authors
  • Richard Russon
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file list.c.

Function Documentation

◆ mutt_list_insert_head()

struct ListNode * mutt_list_insert_head ( struct ListHead * h,
char * s )

Insert a string at the beginning of a List.

Parameters
hHead of the List
sString to insert
Return values
ptrNewly inserted ListNode containing the string
Note
The inserted string isn't strdup()d

Definition at line 46 of file list.c.

47{
48 if (!h)
49 return NULL;
50
51 struct ListNode *np = MUTT_MEM_CALLOC(1, struct ListNode);
52 np->data = s;
53 STAILQ_INSERT_HEAD(h, np, entries);
54 return np;
55}
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
#define STAILQ_INSERT_HEAD(head, elm, field)
Definition queue.h:421
A List node for strings.
Definition list.h:37
char * data
String.
Definition list.h:38
+ Here is the caller graph for this function:

◆ mutt_list_insert_tail()

struct ListNode * mutt_list_insert_tail ( struct ListHead * h,
char * s )

Append a string to the end of a List.

Parameters
hHead of the List
sString to insert
Return values
ptrNewly appended ListNode containing the string
Note
The inserted string isn't strdup()d

Definition at line 65 of file list.c.

66{
67 if (!h)
68 return NULL;
69
70 struct ListNode *np = MUTT_MEM_CALLOC(1, struct ListNode);
71 np->data = s;
72 STAILQ_INSERT_TAIL(h, np, entries);
73 return np;
74}
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition queue.h:427
+ Here is the caller graph for this function:

◆ mutt_list_insert_after()

struct ListNode * mutt_list_insert_after ( struct ListHead * h,
struct ListNode * n,
char * s )

Insert a string after a given ListNode.

Parameters
hHead of the List
nListNode after which the string will be inserted
sString to insert
Return values
ptrNewly created ListNode containing the string
Note
The inserted string isn't strdup()d

Definition at line 85 of file list.c.

86{
87 if (!h || !n)
88 return NULL;
89
90 struct ListNode *np = MUTT_MEM_CALLOC(1, struct ListNode);
91 np->data = s;
92 STAILQ_INSERT_AFTER(h, n, np, entries);
93 return np;
94}
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field)
Definition queue.h:415
+ Here is the caller graph for this function:

◆ mutt_list_find()

struct ListNode * mutt_list_find ( const struct ListHead * h,
const char * data )

Find a string in a List.

Parameters
hHead of the List
dataString to find
Return values
ptrListNode containing the string
NULLThe string isn't found

Definition at line 103 of file list.c.

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}
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:666
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_list_free()

void mutt_list_free ( struct ListHead * h)

Free a List AND its strings.

Parameters
hHead of the List

Definition at line 123 of file list.c.

124{
125 if (!h)
126 return;
127
128 struct ListNode *np = NULL;
129 struct ListNode *tmp = NULL;
130 STAILQ_FOREACH_SAFE(np, h, entries, tmp)
131 {
132 STAILQ_REMOVE(h, np, ListNode, entries);
133 FREE(&np->data);
134 FREE(&np);
135 }
136
137 STAILQ_INIT(h);
138}
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define STAILQ_REMOVE(head, elm, type, field)
Definition queue.h:441
#define STAILQ_INIT(head)
Definition queue.h:410
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition queue.h:400
+ Here is the caller graph for this function:

◆ mutt_list_free_type()

void mutt_list_free_type ( struct ListHead * h,
list_free_t fn )

Free a List of type.

Parameters
hHead of the List
fnFunction to free contents of ListNode

Definition at line 145 of file list.c.

146{
147 if (!h || !fn)
148 return;
149
150 struct ListNode *np = NULL;
151 struct ListNode *tmp = NULL;
152 STAILQ_FOREACH_SAFE(np, h, entries, tmp)
153 {
154 STAILQ_REMOVE(h, np, ListNode, entries);
155 fn((void **) &np->data);
156 FREE(&np);
157 }
158
159 STAILQ_INIT(h);
160}
+ Here is the caller graph for this function:

◆ mutt_list_clear()

void mutt_list_clear ( struct ListHead * h)

Free a list, but NOT its strings.

Parameters
hHead of the List

This can be used when the strings have a different lifetime to the List.

Definition at line 168 of file list.c.

169{
170 if (!h)
171 return;
172
173 struct ListNode *np = NULL;
174 struct ListNode *tmp = NULL;
175 STAILQ_FOREACH_SAFE(np, h, entries, tmp)
176 {
177 STAILQ_REMOVE(h, np, ListNode, entries);
178 FREE(&np);
179 }
180
181 STAILQ_INIT(h);
182}
+ Here is the caller graph for this function:

◆ mutt_list_match()

bool mutt_list_match ( const char * s,
struct ListHead * h )

Is the string in the list (see notes)

Parameters
sString to match
hHead of the List
Return values
trueString matches a List item (or List contains "*")

This is a very specific function. It searches a List of strings looking for a match. If the list contains a string "*", then it match any input string.

Note
The strings are compared to the length of the List item, e.g. List: "Red" matches Param: "Redwood", but not the other way around.
The case of the strings is ignored.

Definition at line 197 of file list.c.

198{
199 if (!h)
200 return false;
201
202 struct ListNode *np = NULL;
203 STAILQ_FOREACH(np, h, entries)
204 {
205 if ((*np->data == '*') || mutt_istr_startswith(s, np->data))
206 return true;
207 }
208 return false;
209}
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition string.c:246
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_list_equal()

bool mutt_list_equal ( const struct ListHead * ah,
const struct ListHead * bh )

Compare two string lists.

Parameters
ahFirst string list
bhSecond string list
Return values
trueLists are identical

To be identical, the lists must both be the same length and contain the same strings. Two empty lists are identical.

Definition at line 220 of file list.c.

221{
222 if (!ah || !bh)
223 return false;
224
225 struct ListNode *a = STAILQ_FIRST(ah);
226 struct ListNode *b = STAILQ_FIRST(bh);
227
228 while (a && b)
229 {
230 if (!mutt_str_equal(a->data, b->data))
231 return false;
232
233 a = STAILQ_NEXT(a, entries);
234 b = STAILQ_NEXT(b, entries);
235 }
236 if (a || b)
237 return false;
238
239 return true;
240}
#define STAILQ_FIRST(head)
Definition queue.h:388
#define STAILQ_NEXT(elm, field)
Definition queue.h:439
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_list_str_split()

size_t mutt_list_str_split ( struct ListHead * head,
const char * src,
char sep )

Split a string into a list using a separator char.

Parameters
headList to add to
srcString to split
sepWord separator
Return values
numNumber of items in list

Definition at line 249 of file list.c.

250{
251 if (!src || (*src == '\0'))
252 return 0;
253
254 size_t count = 0;
255 while (true)
256 {
257 const char *start = src;
258 while ((*src != '\0') && (*src != sep))
259 src++;
260
261 mutt_list_insert_tail(head, mutt_strn_dup(start, src - start));
262 count++;
263
264 if ((*src == '\0'))
265 break;
266
267 src++;
268 }
269
270 return count;
271}
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition list.c:65
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition string.c:384
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_list_copy_tail()

void mutt_list_copy_tail ( struct ListHead * dst,
const struct ListHead * src )

Copy a list into another list.

Parameters
dstDestination list
srcSource list

Definition at line 278 of file list.c.

279{
280 const struct ListNode *np = NULL;
281
282 STAILQ_FOREACH(np, src, entries)
283 {
285 }
286}
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_list_write()

size_t mutt_list_write ( const struct ListHead * h,
struct Buffer * buf )

Write a list to a buffer.

Parameters
hList to write
bufBuffer for the list

Elements separated by a space. References, and In-Reply-To, use this format.

Definition at line 296 of file list.c.

297{
298 if (!buf || !h)
299 return 0;
300
301 struct ListNode *np = NULL;
302 STAILQ_FOREACH(np, h, entries)
303 {
304 buf_addstr(buf, np->data);
305 if (STAILQ_NEXT(np, entries))
306 buf_addstr(buf, " ");
307 }
308
309 return buf_len(buf);
310}
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition buffer.c:497
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:233
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_to_stailq()

void add_to_stailq ( struct ListHead * head,
const char * str )

Add a string to a list.

Parameters
headString list
strString to add
Note
Duplicate or empty strings will not be added

Definition at line 319 of file list.c.

320{
321 /* don't add a NULL or empty string to the list */
322 if (!str || (*str == '\0'))
323 return;
324
325 /* check to make sure the item is not already on this list */
326 struct ListNode *np = NULL;
327 STAILQ_FOREACH(np, head, entries)
328 {
329 if (mutt_istr_equal(str, np->data))
330 {
331 return;
332 }
333 }
335}
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:678
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remove_from_stailq()

void remove_from_stailq ( struct ListHead * head,
const char * str )

Remove an item, matching a string, from a List.

Parameters
headHead of the List
strString to match
Note
The string comparison is case-insensitive

Definition at line 344 of file list.c.

345{
346 if (mutt_str_equal("*", str))
347 {
348 mutt_list_free(head); /* "unCMD *" means delete all current entries */
349 }
350 else
351 {
352 struct ListNode *np = NULL;
353 struct ListNode *tmp = NULL;
354 STAILQ_FOREACH_SAFE(np, head, entries, tmp)
355 {
356 if (mutt_istr_equal(str, np->data))
357 {
358 STAILQ_REMOVE(head, np, ListNode, entries);
359 FREE(&np->data);
360 FREE(&np);
361 break;
362 }
363 }
364 }
365}
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition list.c:123
+ Here is the call graph for this function:
+ Here is the caller graph for this function: