]> git.ipfire.org Git - thirdparty/kmod.git/blame - shared/array.c
Remove FSF mailing address
[thirdparty/kmod.git] / shared / array.c
CommitLineData
6670c633
LDM
1/*
2 * libkmod - interface to kernel module operations
3 *
e6b0e49b 4 * Copyright (C) 2011-2013 ProFUSION embedded systems
6670c633
LDM
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
dea2dfee 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6670c633
LDM
18 */
19
6670c633 20#include <assert.h>
c2e4286b 21#include <errno.h>
6670c633
LDM
22#include <stdlib.h>
23#include <string.h>
c2e4286b
LDM
24
25#include <shared/array.h>
26
27#include <libkmod.h>
6670c633
LDM
28
29/* basic pointer array growing in steps */
30
cacbcc42
LDM
31
32static int array_realloc(struct array *array, size_t new_total)
33{
34 void *tmp = realloc(array->array, sizeof(void *) * new_total);
35 if (tmp == NULL)
36 return -ENOMEM;
37 array->array = tmp;
38 array->total = new_total;
39 return 0;
40}
41
6670c633
LDM
42void array_init(struct array *array, size_t step)
43{
44 assert(step > 0);
45 array->array = NULL;
46 array->count = 0;
47 array->total = 0;
48 array->step = step;
49}
50
51int array_append(struct array *array, const void *element)
52{
53 size_t idx;
54
55 if (array->count + 1 >= array->total) {
cacbcc42
LDM
56 int r = array_realloc(array, array->total + array->step);
57 if (r < 0)
58 return r;
6670c633
LDM
59 }
60 idx = array->count;
61 array->array[idx] = (void *)element;
62 array->count++;
63 return idx;
64}
65
66int array_append_unique(struct array *array, const void *element)
67{
68 void **itr = array->array;
69 void **itr_end = itr + array->count;
70 for (; itr < itr_end; itr++)
71 if (*itr == element)
72 return -EEXIST;
73 return array_append(array, element);
74}
75
76void array_pop(struct array *array) {
77 array->count--;
78 if (array->count + array->step < array->total) {
cacbcc42
LDM
79 int r = array_realloc(array, array->total - array->step);
80 if (r < 0)
6670c633 81 return;
6670c633
LDM
82 }
83}
84
85void array_free_array(struct array *array) {
86 free(array->array);
87 array->count = 0;
88 array->total = 0;
89}
90
91
92void array_sort(struct array *array, int (*cmp)(const void *a, const void *b))
93{
94 qsort(array->array, array->count, sizeof(void *), cmp);
95}
79b656fa
GSB
96
97int array_remove_at(struct array *array, unsigned int pos)
98{
99 if (array->count <= pos)
100 return -ENOENT;
101
102 array->count--;
103 if (pos < array->count)
104 memmove(array->array + pos, array->array + pos + 1,
105 sizeof(void *) * (array->count - pos));
106
107 if (array->count + array->step < array->total) {
cacbcc42
LDM
108 int r = array_realloc(array, array->total - array->step);
109 /* ignore error */
110 if (r < 0)
79b656fa 111 return 0;
79b656fa
GSB
112 }
113
114 return 0;
115}