diff options
Diffstat (limited to 'src/list.c')
-rw-r--r-- | src/list.c | 177 |
1 files changed, 85 insertions, 92 deletions
@@ -23,139 +23,132 @@ | |||
23 | #include <string.h> | 23 | #include <string.h> |
24 | 24 | ||
25 | struct grecs_list * | 25 | struct grecs_list * |
26 | grecs_list_create () | 26 | grecs_list_create() |
27 | { | 27 | { |
28 | struct grecs_list *lp = grecs_malloc (sizeof (*lp)); | 28 | struct grecs_list *lp = grecs_malloc(sizeof(*lp)); |
29 | memset (lp, 0, sizeof (*lp)); | 29 | memset(lp, 0, sizeof(*lp)); |
30 | return lp; | 30 | return lp; |
31 | } | 31 | } |
32 | 32 | ||
33 | size_t | 33 | size_t |
34 | grecs_list_size (struct grecs_list *lp) | 34 | grecs_list_size(struct grecs_list *lp) |
35 | { | 35 | { |
36 | return lp ? lp->count : 0; | 36 | return lp ? lp->count : 0; |
37 | } | 37 | } |
38 | 38 | ||
39 | void | 39 | void |
40 | grecs_list_append (struct grecs_list *lp, void *val) | 40 | grecs_list_append(struct grecs_list *lp, void *val) |
41 | { | 41 | { |
42 | struct grecs_list_entry *ep = grecs_malloc (sizeof (*ep)); | 42 | struct grecs_list_entry *ep = grecs_malloc(sizeof(*ep)); |
43 | ep->data = val; | 43 | ep->data = val; |
44 | ep->next = NULL; | 44 | ep->next = NULL; |
45 | if (lp->tail) | 45 | if (lp->tail) |
46 | lp->tail->next = ep; | 46 | lp->tail->next = ep; |
47 | else | 47 | else |
48 | lp->head = ep; | 48 | lp->head = ep; |
49 | lp->tail = ep; | 49 | lp->tail = ep; |
50 | lp->count++; | 50 | lp->count++; |
51 | } | 51 | } |
52 | 52 | ||
53 | void | 53 | void |
54 | grecs_list_push (struct grecs_list *lp, void *val) | 54 | grecs_list_push(struct grecs_list *lp, void *val) |
55 | { | 55 | { |
56 | struct grecs_list_entry *ep = grecs_malloc (sizeof (*ep)); | 56 | struct grecs_list_entry *ep = grecs_malloc(sizeof(*ep)); |
57 | ep->data = val; | 57 | ep->data = val; |
58 | ep->next = lp->head; | 58 | ep->next = lp->head; |
59 | lp->head = ep; | 59 | lp->head = ep; |
60 | lp->count++; | 60 | lp->count++; |
61 | } | 61 | } |
62 | 62 | ||
63 | void * | 63 | void * |
64 | grecs_list_pop (struct grecs_list *lp) | 64 | grecs_list_pop(struct grecs_list *lp) |
65 | { | 65 | { |
66 | void *data; | 66 | void *data; |
67 | struct grecs_list_entry *ep = lp->head; | 67 | struct grecs_list_entry *ep = lp->head; |
68 | if (ep) | 68 | if (ep) { |
69 | { | 69 | data = ep->data; |
70 | data = ep->data; | 70 | lp->head = ep->next; |
71 | lp->head = ep->next; | 71 | if (!lp->head) |
72 | if (!lp->head) | 72 | lp->tail = NULL; |
73 | lp->tail = NULL; | 73 | lp->count--; |
74 | lp->count--; | 74 | free (ep); |
75 | free (ep); | 75 | } else |
76 | } | 76 | data = NULL; |
77 | else | 77 | return data; |
78 | data = NULL; | ||
79 | return data; | ||
80 | } | 78 | } |
81 | 79 | ||
82 | void | 80 | void |
83 | grecs_list_clear (struct grecs_list *lp) | 81 | grecs_list_clear(struct grecs_list *lp) |
84 | { | 82 | { |
85 | struct grecs_list_entry *ep = lp->head; | 83 | struct grecs_list_entry *ep = lp->head; |
86 | 84 | ||
87 | while (ep) | 85 | while (ep) { |
88 | { | 86 | struct grecs_list_entry *next = ep->next; |
89 | struct grecs_list_entry *next = ep->next; | 87 | if (lp->free_entry) |
90 | if (lp->free_entry) | 88 | lp->free_entry(ep->data); |
91 | lp->free_entry (ep->data); | 89 | free(ep); |
92 | free (ep); | 90 | ep = next; |
93 | ep = next; | 91 | } |
94 | } | 92 | lp->head = lp->tail = NULL; |
95 | lp->head = lp->tail = NULL; | 93 | lp->count = 0; |
96 | lp->count = 0; | ||
97 | } | 94 | } |
98 | 95 | ||
99 | void | 96 | void |
100 | grecs_list_free (struct grecs_list *lp) | 97 | grecs_list_free(struct grecs_list *lp) |
101 | { | 98 | { |
102 | grecs_list_clear (lp); | 99 | grecs_list_clear(lp); |
103 | free (lp); | 100 | free(lp); |
104 | } | 101 | } |
105 | 102 | ||
106 | static int | 103 | static int |
107 | _ptrcmp (const void *a, const void *b) | 104 | _ptrcmp(const void *a, const void *b) |
108 | { | 105 | { |
109 | return a != b; | 106 | return a != b; |
110 | } | 107 | } |
111 | 108 | ||
112 | void * | 109 | void * |
113 | grecs_list_locate (struct grecs_list *lp, void *data) | 110 | grecs_list_locate(struct grecs_list *lp, void *data) |
114 | { | 111 | { |
115 | struct grecs_list_entry *ep; | 112 | struct grecs_list_entry *ep; |
116 | int (*cmp)(const void *, const void *) = lp->cmp ? lp->cmp : _ptrcmp; | 113 | int (*cmp)(const void *, const void *) = lp->cmp ? lp->cmp : _ptrcmp; |
117 | 114 | ||
118 | for (ep = lp->head; ep; ep = ep->next) | 115 | for (ep = lp->head; ep; ep = ep->next) { |
119 | { | 116 | if (cmp(ep->data, data) == 0) |
120 | if (cmp (ep->data, data) == 0) | 117 | return ep->data; |
121 | return ep->data; | 118 | } |
122 | } | 119 | return NULL; |
123 | return NULL; | ||
124 | } | 120 | } |
125 | 121 | ||
126 | void * | 122 | void * |
127 | grecs_list_index (struct grecs_list *lp, size_t idx) | 123 | grecs_list_index(struct grecs_list *lp, size_t idx) |
128 | { | 124 | { |
129 | struct grecs_list_entry *ep; | 125 | struct grecs_list_entry *ep; |
130 | 126 | ||
131 | for (ep = lp->head; ep && idx; ep = ep->next, idx--) | 127 | for (ep = lp->head; ep && idx; ep = ep->next, idx--) |
132 | ; | 128 | ; |
133 | return ep ? ep->data : NULL; | 129 | return ep ? ep->data : NULL; |
134 | } | 130 | } |
135 | 131 | ||
136 | void * | 132 | void * |
137 | grecs_list_remove_tail (struct grecs_list *lp) | 133 | grecs_list_remove_tail(struct grecs_list *lp) |
138 | { | 134 | { |
139 | void *data; | 135 | void *data; |
140 | 136 | ||
141 | if (!lp->head) | 137 | if (!lp->head) |
142 | return NULL; | 138 | return NULL; |
143 | data = lp->tail; | 139 | data = lp->tail; |
144 | if (lp->head == lp->tail) | 140 | if (lp->head == lp->tail) { |
145 | { | 141 | free(lp->tail); |
146 | free (lp->tail); | 142 | lp->head = lp->tail = NULL; |
147 | lp->head = lp->tail = NULL; | 143 | lp->count = 0; |
148 | lp->count = 0; | 144 | } else { |
149 | } | 145 | struct grecs_list_entry *ep; |
150 | else | ||
151 | { | ||
152 | struct grecs_list_entry *ep; | ||
153 | 146 | ||
154 | for (ep = lp->head; ep->next != lp->tail; ep = ep->next) | 147 | for (ep = lp->head; ep->next != lp->tail; ep = ep->next) |
155 | ; | 148 | ; |
156 | free (lp->tail); | 149 | free(lp->tail); |
157 | ep->next = NULL; | 150 | ep->next = NULL; |
158 | lp->tail = ep; | 151 | lp->tail = ep; |
159 | } | 152 | } |
160 | return data; | 153 | return data; |
161 | } | 154 | } |