multipathd: fix reservation_key check
[multipath-tools/.git] / libmultipath / vector.c
1 /*
2  * Part:        Vector structure manipulation.
3  *
4  * Version:     $Id: vector.c,v 1.0.3 2003/05/11 02:28:03 acassen Exp $
5  *
6  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
7  *
8  *              This program is distributed in the hope that it will be useful,
9  *              but WITHOUT ANY WARRANTY; without even the implied warranty of
10  *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *              See the GNU General Public License for more details.
12  *
13  *              This program is free software; you can redistribute it and/or
14  *              modify it under the terms of the GNU General Public License
15  *              as published by the Free Software Foundation; either version
16  *              2 of the License, or (at your option) any later version.
17  *
18  * Copyright (c) 2002, 2003, 2004 Alexandre Cassen
19  * Copyright (c) 2005 Christophe Varoqui
20  */
21
22 #include "memory.h"
23 #include <stdlib.h>
24 #include "vector.h"
25
26 /*
27  * Initialize vector struct.
28  * allocated 'size' slot elements then return vector.
29  */
30 vector
31 vector_alloc(void)
32 {
33         vector v = (vector) MALLOC(sizeof (struct _vector));
34         return v;
35 }
36
37 /* allocated one slot */
38 void *
39 vector_alloc_slot(vector v)
40 {
41         void *new_slot = NULL;
42
43         if (!v)
44                 return NULL;
45
46         v->allocated += VECTOR_DEFAULT_SIZE;
47         if (v->slot)
48                 new_slot = REALLOC(v->slot, sizeof (void *) * v->allocated);
49         else
50                 new_slot = (void *) MALLOC(sizeof (void *) * v->allocated);
51
52         if (!new_slot)
53                 v->allocated -= VECTOR_DEFAULT_SIZE;
54         else
55                 v->slot = new_slot;
56
57         return v->slot;
58 }
59
60 int
61 vector_move_up(vector v, int src, int dest)
62 {
63         void *value;
64         int i;
65         if (dest == src)
66                 return 0;
67         if (dest > src || src >= v->allocated)
68                 return -1;
69         value = v->slot[src];
70         for (i = src - 1; i >= dest; i--)
71                 v->slot[i + 1] = v->slot[i];
72         v->slot[dest] = value;
73         return 0;
74 }
75
76 void *
77 vector_insert_slot(vector v, int slot, void *value)
78 {
79         int i;
80
81         if (!vector_alloc_slot(v))
82                 return NULL;
83
84         for (i = VECTOR_SIZE(v) - 2; i >= slot; i--)
85                 v->slot[i + 1] = v->slot[i];
86
87         v->slot[slot] = value;
88
89         return v->slot[slot];
90 }
91
92 int
93 find_slot(vector v, void * addr)
94 {
95         int i;
96
97         if (!v)
98                 return -1;
99
100         for (i = 0; i < VECTOR_SIZE(v); i++)
101                 if (v->slot[i] == addr)
102                         return i;
103
104         return -1;
105 }
106
107 void
108 vector_del_slot(vector v, int slot)
109 {
110         int i;
111
112         if (!v || !v->allocated || slot < 0 || slot > VECTOR_SIZE(v))
113                 return;
114
115         for (i = slot + 1; i < VECTOR_SIZE(v); i++)
116                 v->slot[i-1] = v->slot[i];
117
118         v->allocated -= VECTOR_DEFAULT_SIZE;
119
120         if (v->allocated <= 0) {
121                 FREE(v->slot);
122                 v->slot = NULL;
123                 v->allocated = 0;
124         } else {
125                 void *new_slot;
126
127                 new_slot = REALLOC(v->slot, sizeof (void *) * v->allocated);
128                 if (!new_slot)
129                         v->allocated += VECTOR_DEFAULT_SIZE;
130                 else
131                         v->slot = new_slot;
132         }
133 }
134
135 void
136 vector_repack(vector v)
137 {
138         int i;
139
140         if (!v || !v->allocated)
141                 return;
142
143         for (i = 0; i < VECTOR_SIZE(v); i++)
144                 if (i > 0 && v->slot[i] == NULL)
145                         vector_del_slot(v, i--);
146 }
147
148 vector
149 vector_reset(vector v)
150 {
151         if (!v)
152                 return NULL;
153
154         if (v->slot)
155                 FREE(v->slot);
156
157         v->allocated = 0;
158         v->slot = NULL;
159         return v;
160 }
161
162 /* Free memory vector allocation */
163 void
164 vector_free(vector v)
165 {
166         if (!vector_reset(v))
167                 return;
168         FREE(v);
169 }
170
171 void
172 free_strvec(vector strvec)
173 {
174         int i;
175         char *str;
176
177         if (!strvec)
178                 return;
179
180         vector_foreach_slot (strvec, str, i)
181                 if (str)
182                         FREE(str);
183
184         vector_free(strvec);
185 }
186
187 /* Set a vector slot value */
188 void
189 vector_set_slot(vector v, void *value)
190 {
191         unsigned int i;
192
193         if (!v)
194                 return;
195
196         i = VECTOR_SIZE(v) - 1;
197         v->slot[i] = value;
198 }