Mercurial > ~dholland > hg > ag > index.cgi
comparison help2html/array.c @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children | 60b08b68c750 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:13d2b8934445 |
---|---|
1 #include <stdlib.h> | |
2 #include "must.h" | |
3 #include "array.h" | |
4 | |
5 //////////////////////////////////////////////////////////// | |
6 | |
7 void array_init(struct array *a) { | |
8 a->v = NULL; | |
9 a->num = a->max = 0; | |
10 } | |
11 | |
12 struct array *array_create(void) { | |
13 struct array *a; | |
14 a = must_malloc(sizeof(*a)); | |
15 array_init(a); | |
16 return a; | |
17 } | |
18 | |
19 void array_cleanup(struct array *a) { | |
20 free(a->v); | |
21 a->v = NULL; | |
22 a->num = a->max = 0; | |
23 } | |
24 | |
25 void array_destroy(struct array *a) { | |
26 array_cleanup(a); | |
27 free(a); | |
28 } | |
29 | |
30 //////////////////////////////////////////////////////////// | |
31 | |
32 /* | |
33 * I wish there were a way to check that these were the same as the | |
34 * inline versions, but apparently allowing such things to diverge is | |
35 * a feature of C99. Bleh. | |
36 */ | |
37 | |
38 unsigned array_num(const struct array *a) { | |
39 return a->num; | |
40 } | |
41 | |
42 void *array_get(const struct array *a, unsigned ix) { | |
43 assert(ix < a->num); | |
44 return a->v[ix]; | |
45 } | |
46 | |
47 void array_set(struct array *a, unsigned ix, void *ptr) { | |
48 assert(ix < a->num); | |
49 a->v[ix] = ptr; | |
50 } | |
51 | |
52 //////////////////////////////////////////////////////////// | |
53 | |
54 unsigned array_add(struct array *a, void *ptr) { | |
55 unsigned ix; | |
56 | |
57 ix = a->num; | |
58 array_setsize(a, a->num+1); | |
59 a->v[ix] = ptr; | |
60 return ix; | |
61 } | |
62 | |
63 void array_setsize(struct array *a, unsigned newnum) { | |
64 unsigned newmax; | |
65 void **newptr; | |
66 | |
67 if (newnum > a->max) { | |
68 newmax = a->max; | |
69 if (newmax == 0) { | |
70 newmax = 4; | |
71 } | |
72 while (newmax < newnum) { | |
73 newmax *= 2; | |
74 } | |
75 newptr = must_realloc(a->v, newmax*sizeof(void *)); | |
76 a->v = newptr; | |
77 a->max = newmax; | |
78 } | |
79 | |
80 a->num = newnum; | |
81 | |
82 /* Note: it's the user's responsibility to initialize the new space */ | |
83 } | |
84 | |
85 void array_nonulls(struct array *a) { | |
86 unsigned i, j; | |
87 | |
88 for (i=j=0; i<a->num; i++) { | |
89 if (a->v[i] != NULL) { | |
90 if (i != j) { | |
91 a->v[j] = a->v[i]; | |
92 } | |
93 j++; | |
94 } | |
95 } | |
96 | |
97 a->num = j; | |
98 } | |
99 | |
100 static int (*array_usersort)(void *a, void *b); | |
101 | |
102 static int array_sortthunk(const void *av, const void *bv) { | |
103 /* av and bv point to elements of the array */ | |
104 void *a = *(void *const *)av; | |
105 void *b = *(void *const *)bv; | |
106 return array_usersort(a, b); | |
107 } | |
108 | |
109 void array_sort(struct array *a, int (*f)(void *a, void *b)) { | |
110 array_usersort = f; | |
111 qsort(a->v, a->num, sizeof(void *), array_sortthunk); | |
112 } |