Adiciona comando para salvar declaração.
[cascardo/declara.git] / list.c
1 /*
2  *  Copyright (C) 2012-2015  Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include "list.h"
20 #include <stdlib.h>
21 #include <string.h>
22
23 struct item {
24         void *val;
25 };
26
27 struct list {
28         size_t alen;
29         size_t len;
30         struct item items[];
31 };
32
33 struct list * list_new(void)
34 {
35         struct list *list;
36         size_t alen = 128;
37         list = malloc(sizeof(*list) + alen * sizeof(struct item));
38         if (!list)
39                 return NULL;
40         list->alen = alen;
41         list->len = 0;
42         memset(list->items, 0, alen * sizeof(struct item));
43         return list;
44 }
45
46 int list_add(struct list **list, void *val)
47 {
48         unsigned int i;
49         struct list *l = *list;
50         l->items[l->len].val = val;
51         l->len++;
52         if (l->len == l->alen) {
53                 struct list *nlist;
54                 size_t len = l->alen * sizeof(struct item);
55                 size_t nlen = len * 2;
56                 nlist = realloc(l, sizeof(*nlist) + nlen);
57                 if (!nlist)
58                         goto out;
59                 *list = l = nlist;
60                 memset(&l->items[l->len], 0, len);
61                 l->alen = l->alen * 2;
62         }
63         return 0;
64 out:
65         l->items[l->len].val = NULL;
66         return -1;
67 }
68
69 void * list_get(struct list *list, int pos)
70 {
71         unsigned int i;
72         if (pos >= list->len)
73                 return NULL;
74         return list->items[pos].val;
75 }
76
77 void list_free(struct list *list, free_function_t *ifree)
78 {
79         int i;
80         for (i = 0; i < list->len; i++)
81                 ifree(list->items[i].val);
82         free(list);
83 }