get rid of non-ANSI function declarations missing (void)
[osmocom-bb.git] / src / vty / vector.c
1 /* Generic vector interface routine
2  * Copyright (C) 1997 Kunihiro Ishiguro
3  *
4  * This file is part of GNU Zebra.
5  *
6  * GNU Zebra is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; either version 2, or (at your option) any
9  * later version.
10  *
11  * GNU Zebra is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
18  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19  * 02111-1307, USA.
20  */
21
22 #include <stdlib.h>
23 #include <unistd.h>
24
25 #include <osmocom/vty/vector.h>
26 #include <osmocom/vty/vty.h>
27 #include <osmocom/core/talloc.h>
28 #include <memory.h>
29
30 void *tall_vty_vec_ctx;
31
32 /* Initialize vector : allocate memory and return vector. */
33 vector vector_init(unsigned int size)
34 {
35         vector v = talloc_zero(tall_vty_vec_ctx, struct _vector);
36         if (!v)
37                 return NULL;
38
39         /* allocate at least one slot */
40         if (size == 0)
41                 size = 1;
42
43         v->alloced = size;
44         v->active = 0;
45         v->index = _talloc_zero(tall_vty_vec_ctx, sizeof(void *) * size,
46                                 "vector_init:index");
47         if (!v->index) {
48                 talloc_free(v);
49                 return NULL;
50         }
51         return v;
52 }
53
54 void vector_only_wrapper_free(vector v)
55 {
56         talloc_free(v);
57 }
58
59 void vector_only_index_free(void *index)
60 {
61         talloc_free(index);
62 }
63
64 void vector_free(vector v)
65 {
66         talloc_free(v->index);
67         talloc_free(v);
68 }
69
70 vector vector_copy(vector v)
71 {
72         unsigned int size;
73         vector new = talloc_zero(tall_vty_vec_ctx, struct _vector);
74         if (!new)
75                 return NULL;
76
77         new->active = v->active;
78         new->alloced = v->alloced;
79
80         size = sizeof(void *) * (v->alloced);
81         new->index = _talloc_zero(tall_vty_vec_ctx, size, "vector_copy:index");
82         if (!new->index) {
83                 talloc_free(new);
84                 return NULL;
85         }
86         memcpy(new->index, v->index, size);
87
88         return new;
89 }
90
91 /* Check assigned index, and if it runs short double index pointer */
92 void vector_ensure(vector v, unsigned int num)
93 {
94         if (v->alloced > num)
95                 return;
96
97         v->index = talloc_realloc_size(tall_vty_vec_ctx, v->index,
98                                        sizeof(void *) * (v->alloced * 2));
99         memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
100         v->alloced *= 2;
101
102         if (v->alloced <= num)
103                 vector_ensure(v, num);
104 }
105
106 /* This function only returns next empty slot index.  It dose not mean
107    the slot's index memory is assigned, please call vector_ensure()
108    after calling this function. */
109 int vector_empty_slot(vector v)
110 {
111         unsigned int i;
112
113         if (v->active == 0)
114                 return 0;
115
116         for (i = 0; i < v->active; i++)
117                 if (v->index[i] == 0)
118                         return i;
119
120         return i;
121 }
122
123 /* Set value to the smallest empty slot. */
124 int vector_set(vector v, void *val)
125 {
126         unsigned int i;
127
128         i = vector_empty_slot(v);
129         vector_ensure(v, i);
130
131         v->index[i] = val;
132
133         if (v->active <= i)
134                 v->active = i + 1;
135
136         return i;
137 }
138
139 /* Set value to specified index slot. */
140 int vector_set_index(vector v, unsigned int i, void *val)
141 {
142         vector_ensure(v, i);
143
144         v->index[i] = val;
145
146         if (v->active <= i)
147                 v->active = i + 1;
148
149         return i;
150 }
151
152 /* Look up vector.  */
153 void *vector_lookup(vector v, unsigned int i)
154 {
155         if (i >= v->active)
156                 return NULL;
157         return v->index[i];
158 }
159
160 /* Lookup vector, ensure it. */
161 void *vector_lookup_ensure(vector v, unsigned int i)
162 {
163         vector_ensure(v, i);
164         return v->index[i];
165 }
166
167 /* Unset value at specified index slot. */
168 void vector_unset(vector v, unsigned int i)
169 {
170         if (i >= v->alloced)
171                 return;
172
173         v->index[i] = NULL;
174
175         if (i + 1 == v->active) {
176                 v->active--;
177                 while (i && v->index[--i] == NULL && v->active--) ;     /* Is this ugly ? */
178         }
179 }
180
181 /* Count the number of not emplty slot. */
182 unsigned int vector_count(vector v)
183 {
184         unsigned int i;
185         unsigned count = 0;
186
187         for (i = 0; i < v->active; i++)
188                 if (v->index[i] != NULL)
189                         count++;
190
191         return count;
192 }