Mercurial > code
annotate parray.c @ 176:ba62ab219fc4
add cstring for strerror
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 13 Sep 2013 13:35:32 +0200 |
parents | 970e491d93cb |
children |
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 |
163
66d317ba4b80
Added a new _qsort function for array and parray
David Demelier <markand@malikania.fr>
parents:
147
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 */ |
55 void | |
56 parray_set(struct parray *arr, const char *fmt, ...) | |
57 { | |
58 va_list ap; | |
59 const char *p; | |
60 | |
61 va_start(ap, fmt); | |
62 for (p = fmt; *p != '\0'; ++p) | |
63 switch (*p) { | |
64 case 'l': | |
65 arr->bsize = va_arg(ap, int); | |
66 break; | |
67 case 'm': | |
68 arr->malloc = va_arg(ap, void * (*)(size_t)); | |
69 break; | |
70 case 'r': | |
117
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
71 arr->realloc = va_arg(ap, void * (*)(void *, size_t)); |
92 | 72 break; |
136 | 73 case 'f': |
74 arr->flags = va_arg(ap, int); | |
99
d534fdcbb319
Remove #ifdef __cplusplus
David Demelier <markand@malikania.fr>
parents:
98
diff
changeset
|
75 break; |
92 | 76 default: |
77 break; | |
78 } | |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
79 } |
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 * 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
|
83 * 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
|
84 * 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
|
85 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
86 int |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
87 parray_push(struct parray *arr, void *data) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
88 { |
124
5917096facb9
Use enum and add #ifdef __cplusplus
David Demelier <markand@malikania.fr>
parents:
120
diff
changeset
|
89 if (grow(arr) < 0) |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
90 return -1; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
91 |
117
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
92 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
|
93 arr->data[0] = data; |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
94 |
136 | 95 if (arr->flags & PARRAY_NULLEND) |
96 arr->data[arr->length] = NULL; | |
97 | |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
98 return 0; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
99 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
100 |
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 * 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
|
103 * 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
|
104 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
105 int |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
106 parray_insert(struct parray *arr, void *data, int index) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
107 { |
147
535f12e0a5af
Add a flag to prevent insertions at out of bounds
David Demelier <markand@malikania.fr>
parents:
142
diff
changeset
|
108 if (arr->flags & PARRAY_INSERTSAFE) |
535f12e0a5af
Add a flag to prevent insertions at out of bounds
David Demelier <markand@malikania.fr>
parents:
142
diff
changeset
|
109 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
|
110 return -1; |
535f12e0a5af
Add a flag to prevent insertions at out of bounds
David Demelier <markand@malikania.fr>
parents:
142
diff
changeset
|
111 |
117
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
112 if (index < 0) |
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
113 return parray_push(arr, data); |
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
114 if (index >= arr->length) |
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
115 return parray_append(arr, data); |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
116 |
117
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
117 /* Good place */ |
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
118 memmove(&arr->data[index + 1], &arr->data[index], |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
119 LENGTH(arr->length++ - index)); |
117
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
120 arr->data[index] = data; |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
121 |
136 | 122 if (arr->flags & PARRAY_NULLEND) |
123 arr->data[arr->length] = NULL; | |
124 | |
142
e3cf5ac9a5aa
[p]array_insert now returns -1 or index of added element
David Demelier <markand@malikania.fr>
parents:
137
diff
changeset
|
125 return index; |
36
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 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
128 /* |
142
e3cf5ac9a5aa
[p]array_insert now returns -1 or index of added element
David Demelier <markand@malikania.fr>
parents:
137
diff
changeset
|
129 * 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
|
130 * of the added element. |
36
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 void |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
150 parray_pop(struct parray *arr) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
151 { |
136 | 152 parray_iremove(arr, 0); |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
153 } |
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 * Remove the array's tail. |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
157 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
158 void |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
159 parray_unqueue(struct parray *arr) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
160 { |
136 | 161 parray_iremove(arr, arr->length - 1); |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
162 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
163 |
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 * 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
|
166 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
167 void |
117
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
168 parray_iremove(struct parray *arr, int index) |
36
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 if (arr->length > 0 && index >= 0 && index < arr->length) { |
136 | 171 if (arr->flags & PARRAY_FASTREMOVE) |
172 arr->data[index] = arr->data[--arr->length]; | |
173 else | |
174 memmove(&arr->data[index], &arr->data[index + 1], | |
175 LENGTH(arr->length-- - index - 1)); | |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
176 } |
136 | 177 |
178 arr->data[arr->length] = NULL; | |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
179 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
180 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
181 /* |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
182 * 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
|
183 * don't know the index. |
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 void |
117
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
186 parray_premove(struct parray *arr, const void *data) |
36
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 void *elm; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
189 int i; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
190 |
117
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
191 PARRAY_FOREACH(arr, elm, i) { |
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
192 if (elm == data) { |
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
193 parray_iremove(arr, i); |
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
194 break; |
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
195 } |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
196 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
197 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
198 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
199 /* |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
200 * 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
|
201 * 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
|
202 * otherwise 0 is returned. |
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 int |
43
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
205 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
|
206 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
207 void *tmp; |
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 /* Out of bounds */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
210 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
|
211 return -1; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
212 |
117
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
213 tmp = arr->data[i1]; |
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
214 arr->data[i1] = arr->data[i2]; |
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
215 arr->data[i2] = tmp; |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
216 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
217 return 0; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
218 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
219 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
220 /* |
43
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
221 * 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
|
222 * 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
|
223 * to find the indexes. |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
224 */ |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
225 int |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
226 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
|
227 { |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
228 int found, i1, i2; |
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 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
|
231 found = arr->data[i1] == o1; |
43
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
232 |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
233 if (!found) |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
234 return -1; |
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 (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
|
237 found = arr->data[i2] == o2; |
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 return parray_iswap(arr, --i1, --i2); |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
243 } |
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 /* |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
246 * 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
|
247 * argument to the function too. |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
248 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
249 void |
142
e3cf5ac9a5aa
[p]array_insert now returns -1 or index of added element
David Demelier <markand@malikania.fr>
parents:
137
diff
changeset
|
250 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
|
251 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
252 int i; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
253 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
254 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
|
255 fn(arr->data[i], udata); |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
256 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
257 |
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 * 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
|
260 * 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
|
261 * 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
|
262 * function nevers returns 1, array_find returns -1. |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
263 */ |
67
cff6869fbc94
Modified [p]array_find to return the index for a better usage
David Demelier <markand@malikania.fr>
parents:
50
diff
changeset
|
264 int |
142
e3cf5ac9a5aa
[p]array_insert now returns -1 or index of added element
David Demelier <markand@malikania.fr>
parents:
137
diff
changeset
|
265 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
|
266 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
267 int st, i; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
268 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
269 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
|
270 st = fn(arr->data[i], u); |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
271 |
120 | 272 if (st && ptr) |
273 *(void **)ptr = arr->data[i - 1]; | |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
274 |
120 | 275 return (st) ? i - 1 : -1; |
36
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 |
136 | 278 void * |
279 parray_first(const struct parray *arr) | |
280 { | |
281 return arr->data[0]; | |
282 } | |
283 | |
284 void * | |
163
66d317ba4b80
Added a new _qsort function for array and parray
David Demelier <markand@malikania.fr>
parents:
147
diff
changeset
|
285 parray_get(const struct parray *arr, int idx) |
136 | 286 { |
287 if (idx < 0) | |
288 return parray_first(arr); | |
289 if (idx >= arr->length) | |
290 return parray_last(arr); | |
291 | |
292 return arr->data[idx]; | |
293 } | |
294 | |
163
66d317ba4b80
Added a new _qsort function for array and parray
David Demelier <markand@malikania.fr>
parents:
147
diff
changeset
|
295 void * |
66d317ba4b80
Added a new _qsort function for array and parray
David Demelier <markand@malikania.fr>
parents:
147
diff
changeset
|
296 parray_last(const struct parray *arr) |
66d317ba4b80
Added a new _qsort function for array and parray
David Demelier <markand@malikania.fr>
parents:
147
diff
changeset
|
297 { |
66d317ba4b80
Added a new _qsort function for array and parray
David Demelier <markand@malikania.fr>
parents:
147
diff
changeset
|
298 if (arr->length == 0) |
66d317ba4b80
Added a new _qsort function for array and parray
David Demelier <markand@malikania.fr>
parents:
147
diff
changeset
|
299 return parray_first(arr); |
66d317ba4b80
Added a new _qsort function for array and parray
David Demelier <markand@malikania.fr>
parents:
147
diff
changeset
|
300 |
66d317ba4b80
Added a new _qsort function for array and parray
David Demelier <markand@malikania.fr>
parents:
147
diff
changeset
|
301 return arr->data[arr->length - 1]; |
66d317ba4b80
Added a new _qsort function for array and parray
David Demelier <markand@malikania.fr>
parents:
147
diff
changeset
|
302 } |
66d317ba4b80
Added a new _qsort function for array and parray
David Demelier <markand@malikania.fr>
parents:
147
diff
changeset
|
303 |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
304 /* |
40
d741c948de89
Added a convenient macro PARRAY_FLUSH to free all objects
David Demelier <markand@malikania.fr>
parents:
37
diff
changeset
|
305 * 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
|
306 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
307 void |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
308 parray_clear(struct parray *arr) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
309 { |
136 | 310 arr->data[0] = NULL; |
311 arr->length = 0; | |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
312 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
313 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
314 /* |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
315 * 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
|
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_free(struct parray *arr) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
319 { |
136 | 320 parray_clear(arr); |
117
bbe86bdb55da
Update parray for a lot of things
David Demelier <markand@malikania.fr>
parents:
109
diff
changeset
|
321 free(arr->data); |
136 | 322 |
323 arr->data = NULL; | |
324 arr->size = 0; | |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
325 } |
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 /* |
165
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
328 * Trim down the array to the correct size. |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
329 */ |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
330 void * |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
331 parray_trim(struct parray *arr) |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
332 { |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
333 int count = arr->length; |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
334 |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
335 if (arr->flags & PARRAY_NULLEND) |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
336 ++ count; |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
337 |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
338 return arr->realloc(arr->data, count * sizeof (void *)); |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
339 } |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
340 |
970e491d93cb
Add _trim function to realloc to the needed size
David Demelier <markand@malikania.fr>
parents:
163
diff
changeset
|
341 /* |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
342 * 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
|
343 * 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
|
344 * succeeded. |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
345 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
346 static int |
124
5917096facb9
Use enum and add #ifdef __cplusplus
David Demelier <markand@malikania.fr>
parents:
120
diff
changeset
|
347 grow(struct parray *arr) |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
348 { |
163
66d317ba4b80
Added a new _qsort function for array and parray
David Demelier <markand@malikania.fr>
parents:
147
diff
changeset
|
349 unsigned int toadd = (arr->flags & PARRAY_NULLEND) ? 2 : 1; |
136 | 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 } |