Mercurial > code
annotate parray.c @ 92:4d723e81b685
Same thing for parray
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 03 Jan 2012 17:54:35 +0100 |
parents | cff6869fbc94 |
children | 9ebea85c7765 |
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 * |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
4 * Copyright (c) 2011, David Demelier <markand@malikania.fr> |
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 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
27 static int parray_grow(struct parray *); |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
28 |
92 | 29 int |
30 parray_new(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 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
37 arr->size = LENGTH(arr->bsize); |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
38 |
92 | 39 if ((arr->datas = arr->malloc(arr->size)) == NULL) |
40 return -1; | |
41 | |
42 memset(arr->datas, 0, arr->bsize); | |
43 | |
44 return 0; | |
45 } | |
46 | |
47 /* | |
48 * Valid options that can be set for an array : | |
49 * l -> optional array block size of type int | |
50 * m -> malloc function that must matches void * (*malloc)(size_t) | |
51 * r -> realloc function that must matches void * (*realloc)(void *, size_t) | |
52 * t -> type of array of type enum array_type | |
53 */ | |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
54 |
92 | 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': | |
71 arr->realloc = va_arg(ap, void *(*)(void *, size_t)); | |
72 break; | |
73 case 't': | |
74 arr->type = va_arg(ap, enum parray_type); | |
75 default: | |
76 break; | |
77 } | |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
78 } |
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 * 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
|
82 * of object (about 100000). If you need to add a lot of data please consider |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
83 * using linked list instead. |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
84 */ |
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 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
89 if (parray_grow(arr) < 0) |
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 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
92 memmove(&arr->datas[1], &arr->datas[0], LENGTH(arr->length++)); |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
93 arr->datas[0] = data; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
94 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
95 return 0; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
96 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
97 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
98 /* |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
99 * Insert the data at the specified index. The function returns -1 on |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
100 * allocation failure or when the index is outof bounds otherwise 0 is returned. |
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 int |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
104 parray_insert(struct parray *arr, void *data, int index) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
105 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
106 if (index > arr->length - 1 || index < 0 || parray_grow(arr) < 0) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
107 return -1; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
108 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
109 memmove(&arr->datas[index + 1], &arr->datas[index], |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
110 LENGTH(arr->length++ - index)); |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
111 arr->datas[index] = data; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
112 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
113 return 0; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
114 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
115 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
116 /* |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
117 * Append the data to the end of array. |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
118 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
119 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
120 int |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
121 parray_append(struct parray *arr, void *data) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
122 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
123 if (parray_grow(arr) < 0) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
124 return -1; |
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 arr->datas[arr->length++] = data; |
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 return 0; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
129 } |
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 * Remove the array's head. |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
133 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
134 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
135 void |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
136 parray_pop(struct parray *arr) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
137 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
138 if (arr->length > 0) { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
139 memmove(&arr->datas[0], &arr->datas[1], LENGTH(--arr->length)); |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
140 arr->datas[arr->length] = NULL; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
141 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
142 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
143 |
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 * Remove the array's tail. |
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 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
148 void |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
149 parray_unqueue(struct parray *arr) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
150 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
151 if (arr->length > 0) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
152 arr->datas[--arr->length] = NULL; |
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 data at the specified index. Bounds are checked. |
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 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
159 void |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
160 parray_remove(struct parray *arr, int index) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
161 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
162 if (arr->length > 0 && index >= 0 && index < arr->length) { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
163 memmove(&arr->datas[index], &arr->datas[index + 1], |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
164 LENGTH(arr->length - index - 1)); |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
165 arr->datas[--arr->length] = NULL; |
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 } |
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 * 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
|
171 * don't know the index. |
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 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
174 void |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
175 parray_unref(struct parray *arr, const void *data) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
176 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
177 void *elm; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
178 int i; |
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 for (i = 0; i < arr->length; ++i) { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
181 elm = PARRAY_INDEX(arr, i); |
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 if (elm == data) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
184 parray_remove(arr, i); |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
185 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
186 } |
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 * 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
|
190 * 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
|
191 * otherwise 0 is returned. |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
192 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
193 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
194 int |
43
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
195 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
|
196 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
197 void *tmp; |
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 /* Out of bounds */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
200 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
|
201 return -1; |
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 tmp = arr->datas[i1]; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
204 arr->datas[i1] = arr->datas[i2]; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
205 arr->datas[i2] = tmp; |
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 return 0; |
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 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
210 /* |
43
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
211 * 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
|
212 * 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
|
213 * to find the indexes. |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
214 */ |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
215 |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
216 int |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
217 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
|
218 { |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
219 int found, i1, i2; |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
220 |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
221 for (i1 = found = 0; !found && i1 < arr->length; ++i1) |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
222 found = arr->datas[i1] == o1; |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
223 |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
224 if (!found) |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
225 return -1; |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
226 |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
227 for (i2 = found = 0; !found && i2 < arr->length; ++i2) |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
228 found = arr->datas[i2] == o2; |
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 if (!found) |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
231 return -1; |
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 return parray_iswap(arr, --i1, --i2); |
f1e184940197
Same last commit for array too
David Demelier <markand@malikania.fr>
parents:
40
diff
changeset
|
234 } |
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 /* |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
237 * 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
|
238 * argument to the function too. |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
239 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
240 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
241 void |
67
cff6869fbc94
Modified [p]array_find to return the index for a better usage
David Demelier <markand@malikania.fr>
parents:
50
diff
changeset
|
242 parray_map(const struct parray *arr, parray_map_fn fn, void *udata) |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
243 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
244 int i; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
245 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
246 for (i = 0; i < arr->length; ++i) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
247 fn(arr->datas[i], udata); |
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 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
250 /* |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
251 * 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
|
252 * 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
|
253 * 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
|
254 * function nevers returns 1, array_find returns -1. |
36
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 |
67
cff6869fbc94
Modified [p]array_find to return the index for a better usage
David Demelier <markand@malikania.fr>
parents:
50
diff
changeset
|
257 int |
cff6869fbc94
Modified [p]array_find to return the index for a better usage
David Demelier <markand@malikania.fr>
parents:
50
diff
changeset
|
258 parray_find(const struct parray *arr, parray_cmp_fn fn, void **ptr, void *u) |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
259 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
260 int st, i; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
261 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
262 for (i = st = 0; i < arr->length && st != 1; ++i) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
263 st = fn(arr->datas[i], u); |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
264 |
67
cff6869fbc94
Modified [p]array_find to return the index for a better usage
David Demelier <markand@malikania.fr>
parents:
50
diff
changeset
|
265 if (st) |
cff6869fbc94
Modified [p]array_find to return the index for a better usage
David Demelier <markand@malikania.fr>
parents:
50
diff
changeset
|
266 *ptr = arr->datas[--i]; |
cff6869fbc94
Modified [p]array_find to return the index for a better usage
David Demelier <markand@malikania.fr>
parents:
50
diff
changeset
|
267 else |
cff6869fbc94
Modified [p]array_find to return the index for a better usage
David Demelier <markand@malikania.fr>
parents:
50
diff
changeset
|
268 i = -1; |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
269 |
67
cff6869fbc94
Modified [p]array_find to return the index for a better usage
David Demelier <markand@malikania.fr>
parents:
50
diff
changeset
|
270 return i; |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
271 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
272 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
273 /* |
40
d741c948de89
Added a convenient macro PARRAY_FLUSH to free all objects
David Demelier <markand@malikania.fr>
parents:
37
diff
changeset
|
274 * 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
|
275 */ |
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 void |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
278 parray_clear(struct parray *arr) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
279 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
280 memset(arr->datas, 0, arr->size); |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
281 arr->length = 0; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
282 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
283 |
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 * 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
|
286 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
287 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
288 void |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
289 parray_free(struct parray *arr) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
290 { |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
291 parray_clear(arr); |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
292 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
293 if (arr->datas) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
294 free(arr->datas); |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
295 } |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
296 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
297 /* |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
298 * 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
|
299 * 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
|
300 * succeeded. |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
301 */ |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
302 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
303 static int |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
304 parray_grow(struct parray *arr) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
305 { |
37 | 306 if ((arr->size / sizeof (void *)) > (size_t) arr->length) |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
307 return 0; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
308 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
309 if (arr->type == PARRAY_AUTO) { |
92 | 310 if ((arr->datas = arr->realloc(arr->datas, arr->size + |
36
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
311 LENGTH(arr->bsize))) == NULL) |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
312 return -1; |
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 arr->size += LENGTH(arr->bsize); |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
315 } else |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
316 return -1; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
317 |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
318 return 0; |
fdc3736ff806
Added parray.c and parray.h:
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
319 } |