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