NeoMutt  2020-06-26-30-g76c339
Teaching an old dog new tricks
DOXYGEN
list.c File Reference

Singly-linked list type. More...

#include "config.h"
#include <stdbool.h>
#include "list.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. More...
 
struct ListNodemutt_list_insert_tail (struct ListHead *h, char *s)
 Append a string to the end of a List. More...
 
struct ListNodemutt_list_insert_after (struct ListHead *h, struct ListNode *n, char *s)
 Insert a string after a given ListNode. More...
 
struct ListNodemutt_list_find (const struct ListHead *h, const char *data)
 Find a string in a List. More...
 
void mutt_list_free (struct ListHead *h)
 Free a List AND its strings. More...
 
void mutt_list_free_type (struct ListHead *h, list_free_t fn)
 Free a List of type. More...
 
void mutt_list_clear (struct ListHead *h)
 Free a list, but NOT its strings. More...
 
bool mutt_list_match (const char *s, struct ListHead *h)
 Is the string in the list (see notes) More...
 
bool mutt_list_compare (const struct ListHead *ah, const struct ListHead *bh)
 Compare two string lists. More...
 
size_t mutt_list_str_split (struct ListHead *head, const char *src, char sep)
 Split a string into a list using a separator char. More...
 

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 45 of file list.c.

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 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define STAILQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:380
char * data
String.
Definition: list.h:36
A List node for strings.
Definition: list.h:34
+ Here is the call graph for this function:
+ 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 64 of file list.c.

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 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:386
char * data
String.
Definition: list.h:36
A List node for strings.
Definition: list.h:34
+ Here is the call graph for this function:
+ 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 84 of file list.c.

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 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
char * data
String.
Definition: list.h:36
A List node for strings.
Definition: list.h:34
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field)
Definition: queue.h:374
+ Here is the call graph for this function:
+ 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
NULLif the string isn't found

Definition at line 102 of file list.c.

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 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:879
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * data
String.
Definition: list.h:36
A List node for strings.
Definition: list.h:34
+ 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 122 of file list.c.

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 }
#define STAILQ_INIT(head)
Definition: queue.h:369
#define STAILQ_NEXT(elm, field)
Definition: queue.h:397
char * data
String.
Definition: list.h:36
#define FREE(x)
Definition: memory.h:40
A List node for strings.
Definition: list.h:34
#define STAILQ_FIRST(head)
Definition: queue.h:347
+ 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 144 of file list.c.

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 }
#define STAILQ_INIT(head)
Definition: queue.h:369
#define STAILQ_NEXT(elm, field)
Definition: queue.h:397
char * data
String.
Definition: list.h:36
#define FREE(x)
Definition: memory.h:40
A List node for strings.
Definition: list.h:34
#define STAILQ_FIRST(head)
Definition: queue.h:347
+ 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 167 of file list.c.

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 }
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:399
#define STAILQ_INIT(head)
Definition: queue.h:369
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:359
#define FREE(x)
Definition: memory.h:40
A List node for strings.
Definition: list.h:34
+ 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 195 of file list.c.

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 }
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:177
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * data
String.
Definition: list.h:36
A List node for strings.
Definition: list.h:34
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_list_compare()

bool mutt_list_compare ( 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 218 of file list.c.

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 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:879
#define STAILQ_NEXT(elm, field)
Definition: queue.h:397
char * data
String.
Definition: list.h:36
A List node for strings.
Definition: list.h:34
#define STAILQ_FIRST(head)
Definition: queue.h:347
+ 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 247 of file list.c.

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 }
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:551
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
+ Here is the call graph for this function:
+ Here is the caller graph for this function: