2 * Copyright 2001-2004 Brandon Long
5 * ClearSilver Templating System
7 * This code is made available under the terms of the ClearSilver License.
8 * http://www.clearsilver.net/license.hdf
12 #include "cs_config.h"
22 #define ULIST_DEFAULT_SIZE 10
24 static NEOERR
*check_resize (ULIST
*ul
, int size
)
34 new_size
= size
+ ul
->max
;
37 new_items
= (void **) realloc ((void *)(ul
->items
), new_size
* sizeof(void *));
38 if (new_items
== NULL
)
40 return nerr_raise(NERR_NOMEM
,
41 "Unable to resize ULIST to %d: Out of memory", new_size
);
43 ul
->items
= new_items
;
51 NEOERR
*uListInit(ULIST
**ul
, int size
, int flags
)
58 size
= ULIST_DEFAULT_SIZE
;
61 r_ul
= (ULIST
*) calloc (1, sizeof (ULIST
));
64 return nerr_raise(NERR_NOMEM
, "Unable to create ULIST: Out of memory");
66 r_ul
->items
= (void **) calloc (size
, sizeof(void *));
67 if (r_ul
->items
== NULL
)
70 return nerr_raise(NERR_NOMEM
, "Unable to create ULIST: Out of memory");
81 NEOERR
*uListvInit(ULIST
**ul
, ...)
87 err
= uListInit (ul
, 0, 0);
88 if (err
) return nerr_pass (err
);
92 it
= va_arg (ap
, void *);
96 err
= uListAppend (*ul
, it
);
100 return nerr_pass (err
);
102 it
= va_arg (ap
, void *);
107 NEOERR
*uListAppend (ULIST
*ul
, void *data
)
111 r
= check_resize (ul
, ul
->num
+ 1);
115 ul
->items
[ul
->num
] = data
;
121 NEOERR
*uListPop (ULIST
*ul
, void **data
)
124 return nerr_raise(NERR_OUTOFRANGE
, "uListPop: empty list");
126 *data
= ul
->items
[ul
->num
- 1];
132 NEOERR
*uListInsert (ULIST
*ul
, int x
, void *data
)
141 return nerr_raise(NERR_OUTOFRANGE
, "uListInsert: past end (%d > %d)",
144 r
= check_resize (ul
, ul
->num
+ 1);
148 start
= &(ul
->items
[x
]);
149 memmove (start
+ 1, start
, (ul
->num
- x
) * sizeof(void *));
156 NEOERR
*uListDelete (ULIST
*ul
, int x
, void **data
)
164 return nerr_raise(NERR_OUTOFRANGE
, "uListDelete: past end (%d > %d)",
168 *data
= ul
->items
[x
];
170 start
= &(ul
->items
[x
]);
171 memmove (start
, start
+1, (ul
->num
- x
- 1) * sizeof(void *));
177 NEOERR
*uListGet (ULIST
*ul
, int x
, void **data
)
183 return nerr_raise(NERR_OUTOFRANGE
, "uListGet: past end (%d > %d)",
187 return nerr_raise(NERR_OUTOFRANGE
, "uListGet: past beginning (%d < 0)", x
);
189 *data
= ul
->items
[x
];
194 NEOERR
*uListSet (ULIST
*ul
, int x
, void *data
)
197 return nerr_raise(NERR_OUTOFRANGE
, "uListSet: past end (%d > %d)",
205 NEOERR
*uListReverse (ULIST
*ul
)
209 for (i
= 0; i
< ul
->num
/2; ++i
) {
210 void *tmp
= ul
->items
[i
];
211 ul
->items
[i
] = ul
->items
[ul
->num
-1-i
];
212 ul
->items
[ul
->num
-1-i
] = tmp
;
218 NEOERR
*uListSort (ULIST
*ul
, int (*compareFunc
)(const void *, const void*)) {
219 qsort(ul
->items
, ul
->num
, sizeof(void *), compareFunc
);
223 void *uListSearch (ULIST
*ul
, const void *key
, int
224 (*compareFunc
)(const void *, const void*)) {
225 return bsearch(key
, ul
->items
, ul
->num
, sizeof(void *), compareFunc
);
228 void *uListIn (ULIST
*ul
, const void *key
, int (*compareFunc
)(const void *, const void*)) {
231 for (i
= 0; i
< ul
->num
; ++i
) {
232 if (!compareFunc(key
, &ul
->items
[i
])) {
233 return &ul
->items
[i
];
239 int uListIndex (ULIST
*ul
, const void *key
, int (*compareFunc
)(const void *, const void*)) {
240 void **p
= uListIn(ul
, key
, compareFunc
);
241 return p
? (p
- ul
->items
) : -1;
246 NEOERR
*uListDestroy (ULIST
**ul
, int flags
)
248 if (flags
& ULIST_FREE
)
250 return uListDestroyFunc(ul
, free
);
254 return uListDestroyFunc(ul
, NULL
);
258 NEOERR
*uListDestroyFunc (ULIST
**ul
, void (*destroyFunc
)(void *))
267 if (destroyFunc
!= NULL
)
270 for (x
= 0; x
< r_ul
->num
; x
++)
272 (*destroyFunc
)(r_ul
->items
[x
]);
282 int uListLength (ULIST
*ul
)
284 if (ul
== NULL
) return 0;