Mercurial > code
annotate array.c @ 147:535f12e0a5af
Add a flag to prevent insertions at out of bounds
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 11 May 2012 20:06:41 +0200 |
parents | e3cf5ac9a5aa |
children | 94847374833b |
rev | line source |
---|---|
62 | 1 /* |
2 * array.c -- manipulate dynamic arrays | |
3 * | |
98 | 4 * Copyright (c) 2011, 2012, David Demelier <markand@malikania.fr> |
62 | 5 * |
6 * Permission to use, copy, modify, and/or distribute this software for any | |
7 * purpose with or without fee is hereby granted, provided that the above | |
8 * copyright notice and this permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 */ | |
18 | |
19 #include <stdio.h> | |
20 #include <stdlib.h> | |
21 #include <string.h> | |
22 | |
23 #include "array.h" | |
24 | |
25 #define OFFSET(x) (arr->unit * (x)) | |
26 | |
124
5917096facb9
Use enum and add #ifdef __cplusplus
David Demelier <markand@malikania.fr>
parents:
123
diff
changeset
|
27 static int grow(struct array *); |
62 | 28 |
91
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
29 int |
93
9ebea85c7765
Use pointer instead of copying variable in ARRAY_FOREACH, then you can modify it
David Demelier <markand@malikania.fr>
parents:
92
diff
changeset
|
30 array_init(struct array *arr, size_t unit) |
62 | 31 { |
91
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
32 if (unit == 0) |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
33 return -1; |
62 | 34 |
35 arr->unit = unit; | |
36 arr->size = OFFSET(arr->bsize); | |
37 | |
92 | 38 /* Set defaults if needed */ |
39 arr->bsize = (arr->bsize <= 0) ? ARRAY_DEFAULT_BSIZE : arr->bsize; | |
91
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
40 arr->malloc = (arr->malloc == NULL) ? &malloc : arr->malloc; |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
41 arr->realloc = (arr->realloc == NULL) ? &realloc : arr->realloc; |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
42 |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
43 if ((arr->data = arr->malloc(arr->size)) == NULL) |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
44 return -1; |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
45 |
136 | 46 if (arr->flags & ARRAY_CLEARBITS) |
47 memset(arr->data, 0, arr->size); | |
48 | |
91
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
49 return 0; |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
50 } |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
51 |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
52 /* |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
53 * Valid options that can be set for an array : |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
54 * l -> optional array block size of type int |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
55 * m -> malloc function that must matches void * (*malloc)(size_t) |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
56 * r -> realloc function that must matches void * (*realloc)(void *, size_t) |
136 | 57 * f -> array flags of type int |
91
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
58 */ |
62 | 59 |
91
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
60 void |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
61 array_set(struct array *arr, const char *fmt, ...) |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
62 { |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
63 va_list ap; |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
64 const char *p; |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
65 |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
66 va_start(ap, fmt); |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
67 for (p = fmt; *p != '\0'; ++p) |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
68 switch (*p) { |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
69 case 'l': |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
70 arr->bsize = va_arg(ap, int); |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
71 break; |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
72 case 'm': |
93
9ebea85c7765
Use pointer instead of copying variable in ARRAY_FOREACH, then you can modify it
David Demelier <markand@malikania.fr>
parents:
92
diff
changeset
|
73 arr->malloc = va_arg(ap, void *(*)(size_t)); |
91
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
74 break; |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
75 case 'r': |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
76 arr->realloc = va_arg(ap, void *(*)(void *, size_t)); |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
77 break; |
136 | 78 case 'f': |
79 arr->flags = va_arg(ap, int); | |
99
d534fdcbb319
Remove #ifdef __cplusplus
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
80 break; |
91
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
81 default: |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
82 break; |
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
83 } |
62 | 84 } |
85 | |
86 /* | |
87 * Add to the head of array. NOTE: this may be very slow when adding a lot | |
88 * of object (about 100000). If you need to add a lot of data please consider | |
142
e3cf5ac9a5aa
[p]array_insert now returns -1 or index of added element
David Demelier <markand@malikania.fr>
parents:
136
diff
changeset
|
89 * using linked list instead. Returns -1 on failure or 0 on success. |
62 | 90 */ |
91 | |
92 int | |
93 array_push(struct array *arr, const void *data) | |
94 { | |
124
5917096facb9
Use enum and add #ifdef __cplusplus
David Demelier <markand@malikania.fr>
parents:
123
diff
changeset
|
95 if (grow(arr) < 0) |
62 | 96 return -1; |
97 | |
64
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
98 memmove((char *)arr->data + arr->unit, arr->data, OFFSET(arr->length++)); |
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
99 memcpy((char *)arr->data, data, arr->unit); |
62 | 100 |
101 return 0; | |
102 } | |
103 | |
104 /* | |
105 * Insert the data at the specified index. The function returns -1 on | |
142
e3cf5ac9a5aa
[p]array_insert now returns -1 or index of added element
David Demelier <markand@malikania.fr>
parents:
136
diff
changeset
|
106 * allocation failure or the position of the added element. |
62 | 107 */ |
108 | |
109 int | |
110 array_insert(struct array *arr, const void *data, int index) | |
111 { | |
147
535f12e0a5af
Add a flag to prevent insertions at out of bounds
David Demelier <markand@malikania.fr>
parents:
142
diff
changeset
|
112 if (arr->flags & ARRAY_INSERTSAFE) |
535f12e0a5af
Add a flag to prevent insertions at out of bounds
David Demelier <markand@malikania.fr>
parents:
142
diff
changeset
|
113 if (index < 0 || index > arr->length) |
535f12e0a5af
Add a flag to prevent insertions at out of bounds
David Demelier <markand@malikania.fr>
parents:
142
diff
changeset
|
114 return -1; |
535f12e0a5af
Add a flag to prevent insertions at out of bounds
David Demelier <markand@malikania.fr>
parents:
142
diff
changeset
|
115 |
118 | 116 if (index < 0) |
117 return array_push(arr, data); | |
118 if (index >= arr->length) | |
119 return array_append(arr, data); | |
62 | 120 |
118 | 121 /* Good place */ |
64
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
122 memmove((char *)arr->data + OFFSET(index + 1), |
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
123 (char *)arr->data + OFFSET(index), OFFSET(arr->length++ - index)); |
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
124 memcpy((char *)arr->data + OFFSET(index), data, arr->unit); |
62 | 125 |
142
e3cf5ac9a5aa
[p]array_insert now returns -1 or index of added element
David Demelier <markand@malikania.fr>
parents:
136
diff
changeset
|
126 return index; |
62 | 127 } |
128 | |
129 /* | |
142
e3cf5ac9a5aa
[p]array_insert now returns -1 or index of added element
David Demelier <markand@malikania.fr>
parents:
136
diff
changeset
|
130 * Append the data to the end of array. Returns -1 on failure or the position |
e3cf5ac9a5aa
[p]array_insert now returns -1 or index of added element
David Demelier <markand@malikania.fr>
parents:
136
diff
changeset
|
131 * of the added element. |
62 | 132 */ |
133 | |
134 int | |
135 array_append(struct array *arr, const void *data) | |
136 { | |
124
5917096facb9
Use enum and add #ifdef __cplusplus
David Demelier <markand@malikania.fr>
parents:
123
diff
changeset
|
137 if (grow(arr) < 0) |
62 | 138 return -1; |
139 | |
64
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
140 memcpy((char *)arr->data + OFFSET(arr->length++), data, arr->unit); |
62 | 141 |
142
e3cf5ac9a5aa
[p]array_insert now returns -1 or index of added element
David Demelier <markand@malikania.fr>
parents:
136
diff
changeset
|
142 return (arr->length - 1); |
62 | 143 } |
144 | |
145 /* | |
146 * Remove the array's head. | |
147 */ | |
148 | |
149 void | |
150 array_pop(struct array *arr) | |
151 { | |
136 | 152 array_iremove(arr, 0); |
62 | 153 } |
154 | |
155 /* | |
156 * Remove the array's tail. | |
157 */ | |
158 | |
159 void | |
160 array_unqueue(struct array *arr) | |
161 { | |
136 | 162 array_iremove(arr, arr->length - 1); |
62 | 163 } |
164 | |
165 /* | |
166 * Remove the data at the specified index. Bounds are checked. | |
167 */ | |
168 | |
169 void | |
119 | 170 array_iremove(struct array *arr, int index) |
62 | 171 { |
172 if (arr->length > 0 && index >= 0 && index < arr->length) { | |
136 | 173 if (arr->flags & ARRAY_FASTREMOVE) |
174 memmove((char *)arr->data + OFFSET(index), | |
175 (char *)arr->data + OFFSET(--arr->length), | |
176 arr->unit); | |
177 else | |
178 memmove((char *)arr->data + OFFSET(index), | |
179 (char *)arr->data + OFFSET(index + 1), | |
180 OFFSET(arr->length-- - index - 1)); | |
62 | 181 } |
136 | 182 |
183 if (arr->flags & ARRAY_CLEARBITS) | |
184 memset((char *)arr->data + OFFSET(arr->length), 0, arr->unit); | |
62 | 185 } |
186 | |
187 /* | |
188 * Remove the object referenced by the `data' argument. Useful when you | |
189 * don't know the index. | |
190 */ | |
191 | |
192 void | |
119 | 193 array_premove(struct array *arr, const void *data) |
62 | 194 { |
195 void *elm; | |
196 int i; | |
197 | |
198 for (i = 0; i < arr->length; ++i) { | |
64
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
199 elm = (char *)arr->data + OFFSET(i); |
62 | 200 |
136 | 201 if (memcmp(elm, data, arr->unit) == 0) { |
123 | 202 array_iremove(arr, i); |
136 | 203 break; |
204 } | |
62 | 205 } |
206 } | |
207 | |
208 /* | |
209 * Swap the two elements referenced by index `i1' and `i2'. This function needs | |
210 * to allocate data to swap elements thus if the functions fails it returns -1 | |
211 * otherwise 0 is returned. | |
212 */ | |
213 | |
214 int | |
215 array_iswap(struct array *arr, int i1, int i2) | |
216 { | |
217 void *tmp; | |
218 | |
219 /* Out of bounds */ | |
220 if (i1 >= arr->length || i1 < 0 || i2 >= arr->length || i2 < 0) | |
221 return -1; | |
222 | |
91
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
223 if ((tmp = arr->malloc(arr->unit)) == NULL) |
62 | 224 return -1; |
225 | |
64
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
226 memcpy((char *)tmp, (char *)arr->data + OFFSET(i1), arr->unit); |
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
227 memcpy((char *)arr->data + OFFSET(i1), (char *)arr->data + OFFSET(i2), |
62 | 228 arr->unit); |
64
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
229 memcpy((char *)arr->data + OFFSET(i2), (char *)tmp, arr->unit); |
62 | 230 |
231 /* | |
232 * Clear bytes for safety you probably don't want a password or | |
233 * secure data to be left somewhere in the memory. | |
234 */ | |
235 | |
136 | 236 if (arr->flags & ARRAY_CLEARBITS) |
237 memset(tmp, 0, arr->unit); | |
62 | 238 free(tmp); |
239 | |
240 return 0; | |
241 } | |
242 | |
243 /* | |
244 * Swap the two elements referenced by data `o1' and `o2'. This function | |
245 * may be slow on large arrays since it must travel all the object | |
246 * to find the indexes. | |
247 */ | |
248 | |
249 int | |
250 array_pswap(struct array *arr, const void *o1, const void *o2) | |
251 { | |
252 int found, i1, i2; | |
253 | |
254 for (i1 = found = 0; !found && i1 < arr->length; ++i1) | |
64
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
255 found = memcmp((char *)arr->data + OFFSET(i1), o1, arr->unit) == 0; |
62 | 256 |
257 if (!found) | |
258 return -1; | |
259 | |
260 for (i2 = found = 0; !found && i2 < arr->length; ++i2) | |
64
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
261 found = memcmp((char *)arr->data + OFFSET(i2), o2, arr->unit) == 0; |
62 | 262 |
263 if (!found) | |
264 return -1; | |
265 | |
266 return array_iswap(arr, --i1, --i2); | |
267 } | |
268 | |
269 /* | |
270 * Apply the function `fn' on each object and give the optional `udata' | |
271 * argument to the function too. | |
272 */ | |
273 | |
274 void | |
142
e3cf5ac9a5aa
[p]array_insert now returns -1 or index of added element
David Demelier <markand@malikania.fr>
parents:
136
diff
changeset
|
275 array_map(const struct array *arr, array_map_t fn, void *udata) |
62 | 276 { |
277 int i; | |
278 | |
279 for (i = 0; i < arr->length; ++i) | |
64
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
280 fn((char *)arr->data + OFFSET(i), udata); |
62 | 281 } |
282 | |
283 /* | |
284 * Compare each object with the user supplied function. If the `fn' function | |
106
06c968b92090
Use pointer to pointer in array_find, better to reuse
David Demelier <markand@malikania.fr>
parents:
99
diff
changeset
|
285 * returns 1, 1 is returned and dst points to the correct object, dst should |
06c968b92090
Use pointer to pointer in array_find, better to reuse
David Demelier <markand@malikania.fr>
parents:
99
diff
changeset
|
286 * be a pointer to a pointer of object, like (int **) for a array of int. |
62 | 287 */ |
288 | |
67
cff6869fbc94
Modified [p]array_find to return the index for a better usage
David Demelier <markand@malikania.fr>
parents:
64
diff
changeset
|
289 int |
142
e3cf5ac9a5aa
[p]array_insert now returns -1 or index of added element
David Demelier <markand@malikania.fr>
parents:
136
diff
changeset
|
290 array_find(const struct array *arr, array_cmp_t fn, void *dst, void *u) |
62 | 291 { |
292 int st, i; | |
293 | |
120 | 294 for (i = st = 0; i < arr->length && st != 1; ++i) |
64
9cc5d6d0563e
Add more cast for old gcc and other cc
David Demelier <markand@malikania.fr>
parents:
62
diff
changeset
|
295 st = fn((char *)arr->data + OFFSET(i), u); |
62 | 296 |
120 | 297 if (st && dst) |
298 *(char **)dst = (char *)arr->data + OFFSET(i - 1); | |
62 | 299 |
120 | 300 return (st) ? i - 1 : -1; |
62 | 301 } |
302 | |
136 | 303 void * |
304 array_first(const struct array *arr) | |
305 { | |
306 return arr->data; | |
307 } | |
308 | |
309 void * | |
310 array_last(const struct array *arr) | |
311 { | |
312 if (arr->length == 0) | |
313 return array_first(arr); | |
314 | |
315 return (char *)arr->data + OFFSET(arr->length - 1); | |
316 | |
317 } | |
318 | |
319 void * | |
320 array_index(const struct array *arr, int idx) | |
321 { | |
322 if (idx < 0) | |
323 return array_first(arr); | |
324 if (idx >= arr->length) | |
325 return array_last(arr); | |
326 | |
327 return (char *)arr->data + OFFSET(idx); | |
328 } | |
329 | |
62 | 330 /* |
331 * Erase every bytes and set the length to 0. | |
332 */ | |
333 | |
334 void | |
335 array_clear(struct array *arr) | |
336 { | |
136 | 337 if (arr->flags & ARRAY_CLEARBITS) |
338 memset(arr->data, 0, arr->size); | |
339 | |
62 | 340 arr->length = 0; |
341 } | |
342 | |
343 /* | |
344 * Same as array_clear except it also free the array object. | |
345 */ | |
346 | |
347 void | |
348 array_free(struct array *arr) | |
349 { | |
136 | 350 array_clear(arr); |
109
4efd3873a457
Remove useless bits in _free()
David Demelier <markand@malikania.fr>
parents:
106
diff
changeset
|
351 free(arr->data); |
136 | 352 |
353 arr->data = NULL; | |
354 arr->size = 0; | |
62 | 355 } |
356 | |
357 /* | |
358 * Increate the array storage when it is full. If the buffer is fixed size | |
359 * it returns -1 on full buffer otherwise 0 is returned if allocation | |
360 * succeeded. | |
361 */ | |
362 | |
363 static int | |
124
5917096facb9
Use enum and add #ifdef __cplusplus
David Demelier <markand@malikania.fr>
parents:
123
diff
changeset
|
364 grow(struct array *arr) |
62 | 365 { |
136 | 366 if ((arr->size / arr->unit) > (size_t)arr->length) |
62 | 367 return 0; |
368 | |
136 | 369 if (!(arr->flags & ARRAY_FIXED)) { |
91
b3ba5f5df3b9
New style for array.c and array.h, no pointer to these object thus
David Demelier <markand@malikania.fr>
parents:
67
diff
changeset
|
370 if ((arr->data = arr->realloc(arr->data, arr->size + |
136 | 371 OFFSET(arr->bsize))) == NULL) { |
372 arr->size = arr->length = 0; | |
62 | 373 return -1; |
136 | 374 } |
62 | 375 |
376 arr->size += OFFSET(arr->bsize); | |
377 } else | |
378 return -1; | |
379 | |
380 return 0; | |
381 } |