drop mem_alloc and mem_free, use my own hand crafted optmized macros that
[apps/madmutt.git] / lib / list.c
1 /*
2  * written for mutt-ng by:
3  * Rocco Rutte <pdmef@cs.tu-berlin.de>
4  *
5  * This file is part of mutt-ng, see http://www.muttng.org/.
6  * It's licensed under the GNU General Public License,
7  * please see the file GPL in the top level source directory.
8  */
9
10 #include <stddef.h>
11 #include <string.h>
12
13 #include <lib-lib/mem.h>
14
15 #include "list.h"
16
17 #include "mem.h"
18 #include "str.h"
19
20 list2_t* list_new (void) {
21   return (mem_calloc (1, sizeof (list2_t)));
22 }
23
24 void list_del (list2_t** l, list_del_t* del) {
25   size_t i = 0;
26   if (!l || !*l)
27     return;
28   if (del)
29     for (i = 0; i < (*l)->length; i++)
30       del (&(*l)->data[i]);
31   p_delete(&(*l)->data);
32   p_delete(l);
33 }
34
35 void list_push_back (list2_t** l, void* p) {
36   if (!*l)
37     *l = list_new ();
38   mem_realloc (&(*l)->data, (++(*l)->length)*sizeof(void*));
39   (*l)->data[(*l)->length-1] = p;
40 }
41
42 void list_push_front (list2_t** l, void* p) {
43   if (!*l)
44     *l = list_new ();
45   mem_realloc (&(*l)->data, (++(*l)->length)*sizeof(void*));
46   if ((*l)->length > 1)
47     memmove (&(*l)->data[1], &(*l)->data[0], ((*l)->length-1)*sizeof(void*));
48   (*l)->data[0] = p;
49 }
50
51 void* list_pop_back (list2_t* l) {
52   void* p = NULL;
53   if (list_empty(l))
54     return (NULL);
55   p = l->data[l->length-1];
56   mem_realloc (&l->data, --(l->length)*sizeof(void*));
57   return (p);
58 }
59
60 void* list_pop_front (list2_t* l) {
61   void* p = NULL;
62   if (list_empty(l))
63     return (NULL);
64   p = l->data[0];
65   memmove (&l->data[0], &l->data[1], (--(l->length))*sizeof(void*));
66   mem_realloc (&l->data, l->length*sizeof(void*));
67   return (p);
68 }
69
70 void* list_pop_idx (list2_t* l, int c) {
71   void* p = NULL;
72   if (list_empty(l) || c < 0 || c >= l->length)
73     return (NULL);
74   if (c == l->length-1)
75     return (list_pop_back (l));
76   p = l->data[c];
77   memmove (&l->data[c], &l->data[c+1], (l->length-c)*sizeof(void*));
78   mem_realloc (&l->data, (--(l->length))*sizeof(void*));
79   return (p);
80 }
81
82 list2_t *list_cpy(list2_t *l) {
83     list2_t* ret = NULL;
84     if (list_empty(l))
85         return NULL;
86     ret = list_new();
87     ret->length = l->length;
88     ret->data = p_dup(l->data, l->length);
89     return ret;
90 }
91
92 list2_t* list_dup (list2_t* l, void* (*dup) (void*)) {
93   list2_t* ret = NULL;
94   int i = 0;
95   if (list_empty(l) || !*dup)
96     return (NULL);
97   ret = list_new ();
98   ret->length = l->length;
99   ret->data = p_new(void*, l->length);
100   for (i = 0; i < l->length; i++)
101     ret->data[i] = dup (l->data[i]);
102   return (ret);
103 }
104
105 int list_lookup (list2_t* l, int (*cmp) (const void*, const void*), const void* p) {
106   int i = 0;
107   if (list_empty(l) || !*cmp)
108     return (-1);
109   for (i = 0; i < l->length; i++)
110     if (cmp (l->data[i], p) == 0)
111       return (i);
112   return (-1);
113 }
114
115 list2_t* list_from_str (const char* str, const char* delim) {
116   list2_t* ret = NULL;
117   char* tmp = NULL, *p = NULL;
118
119   if (!str || !*str || !delim || !*delim)
120     return (NULL);
121
122   tmp = str_dup (str);
123   for (p = strtok (tmp, delim); p; p = strtok (NULL, delim)) {
124     list_push_back (&ret, str_dup (p));
125   }
126   p_delete(&tmp);
127   return (ret);
128 }
129