move rx.[hc].
[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 #include <lib-lib/str.h>
15
16 #include "list.h"
17
18
19 list2_t* list_new (void) {
20   return p_new(list2_t, 1);
21 }
22
23 void list_del (list2_t** l, list_del_t* del) {
24   ssize_t i = 0;
25   if (!l || !*l)
26     return;
27   if (del)
28     for (i = 0; i < (*l)->length; i++)
29       del (&(*l)->data[i]);
30   p_delete(&(*l)->data);
31   p_delete(l);
32 }
33
34 void list_push_back (list2_t** l, void* p) {
35   if (!*l)
36     *l = list_new ();
37   p_realloc(&(*l)->data, ++(*l)->length);
38   (*l)->data[(*l)->length-1] = p;
39 }
40
41 void list_push_front (list2_t** l, void* p) {
42   if (!*l)
43     *l = list_new ();
44   p_realloc(&(*l)->data, ++(*l)->length);
45   if ((*l)->length > 1)
46     memmove (&(*l)->data[1], &(*l)->data[0], ((*l)->length-1)*sizeof(void*));
47   (*l)->data[0] = p;
48 }
49
50 void* list_pop_back (list2_t* l) {
51   void* p = NULL;
52   if (list_empty(l))
53     return (NULL);
54   p = l->data[l->length-1];
55   p_realloc(&l->data, --(l->length));
56   return (p);
57 }
58
59 void* list_pop_front (list2_t* l) {
60   void* p = NULL;
61   if (list_empty(l))
62     return (NULL);
63   p = l->data[0];
64   memmove (&l->data[0], &l->data[1], (--(l->length))*sizeof(void*));
65   p_realloc(&l->data, l->length);
66   return (p);
67 }
68
69 void* list_pop_idx (list2_t* l, int c) {
70   void* p = NULL;
71   if (list_empty(l) || c < 0 || c >= l->length)
72     return (NULL);
73   if (c == l->length-1)
74     return (list_pop_back (l));
75   p = l->data[c];
76   memmove (&l->data[c], &l->data[c+1], (l->length-c)*sizeof(void*));
77   p_realloc(&l->data, --(l->length));
78   return (p);
79 }
80
81 list2_t *list_cpy(list2_t *l) {
82     list2_t* ret = NULL;
83     if (list_empty(l))
84         return NULL;
85     ret = list_new();
86     ret->length = l->length;
87     ret->data = p_dup(l->data, l->length);
88     return ret;
89 }
90
91 list2_t* list_dup (list2_t* l, void* (*dup_f) (void*)) {
92   list2_t* ret = NULL;
93   int i = 0;
94   if (list_empty(l) || !*dup_f)
95     return (NULL);
96   ret = list_new ();
97   ret->length = l->length;
98   ret->data = p_new(void*, l->length);
99   for (i = 0; i < l->length; i++)
100     ret->data[i] = dup_f (l->data[i]);
101   return (ret);
102 }
103
104 int list_lookup (list2_t* l, int (*cmp) (const void*, const void*), const void* p) {
105   int i = 0;
106   if (list_empty(l) || !*cmp)
107     return (-1);
108   for (i = 0; i < l->length; i++)
109     if (cmp (l->data[i], p) == 0)
110       return (i);
111   return (-1);
112 }
113
114 list2_t* list_from_str (const char* str, const char* delim) {
115   list2_t* ret = NULL;
116   char* tmp = NULL, *p = NULL;
117
118   if (!str || !*str || !delim || !*delim)
119     return (NULL);
120
121   tmp = m_strdup(str);
122   for (p = strtok (tmp, delim); p; p = strtok (NULL, delim)) {
123     list_push_back (&ret, m_strdup(p));
124   }
125   p_delete(&tmp);
126   return (ret);
127 }
128