under the terms of the license (GNU LGPL) which comes with this package. */
#include "gras_private.h"
+#include <sys/types.h>
-GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(dynar,tbx);
+GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(dynar,gros,"Dynamic arrays");
struct gras_dynar_s {
size_t size;
#define __sanity_check_idx(idx) \
gras_assert1(idx >= 0, \
"dynar idx(=%d) < 0", \
- idx)
+ (int) (idx))
#define __check_inbound_idx(dynar, idx) \
gras_assert2(idx < dynar->used, \
- "dynar is not that long. You asked %d, but it's only %d long", \
- idx, dynar->used)
+ "dynar is not that long. You asked %d, but it's only %lu long", \
+ (int) (idx), (unsigned long) dynar->used)
#define __check_sloppy_inbound_idx(dynar, idx) \
gras_assert2(idx <= dynar->used, \
- "dynar is not that long. You asked %d, but it's only %d long", \
- idx, dynar->used)
+ "dynar is not that long. You asked %d, but it's only %lu long", \
+ (int) (idx), (unsigned long) dynar->used)
#define __check_populated_dynar(dynar) \
- gras_assert0(dynar->used, \
- "dynar contains nothing")
+ gras_assert1(dynar->used, \
+ "dynar %p contains nothing",(void*)dynar)
-
-static inline
-void
-_gras_clear_mem(void * const ptr,
- const size_t length) {
+static _GRAS_INLINE
+void _gras_clear_mem(void * const ptr,
+ const size_t length) {
memset(ptr, 0, length);
}
-static inline
+static _GRAS_INLINE
gras_error_t
_gras_dynar_expand(gras_dynar_t * const dynar,
const int nb) {
const size_t new_size = nb > (2*(old_size+1)) ? nb : (2*(old_size+1));
const size_t new_length = new_size*elmsize;
- char * const new_data = calloc(1, elmsize*new_size);
+ char * const new_data = gras_malloc0(elmsize*new_size);
- DEBUG3("expend %p from %d to %d elements", dynar, old_size, nb);
+ DEBUG3("expend %p from %lu to %d elements", (void*)dynar, (unsigned long)old_size, nb);
if (!new_data)
RAISE_MALLOC;
if (old_data) {
memcpy(new_data, old_data, used_length);
_gras_clear_mem(old_data, old_length);
- free(old_data);
+ gras_free(old_data);
}
_gras_clear_mem(new_data + used_length, new_length - used_length);
return errcode;
}
-static inline
+static _GRAS_INLINE
void *
_gras_dynar_elm(const gras_dynar_t * const dynar,
const size_t idx) {
return data + idx*elmsize;
}
-static inline
+static _GRAS_INLINE
void
_gras_dynar_get_elm(void * const dst,
const gras_dynar_t * const dynar,
memcpy(dst, elm, elmsize);
}
-static inline
+static _GRAS_INLINE
void
_gras_dynar_put_elm(const gras_dynar_t * const dynar,
const size_t idx,
gras_error_t errcode = no_error;
gras_dynar_t *dynar = NULL;
- if (!(dynar = calloc(1, sizeof(gras_dynar_t))))
+ if (!(dynar = gras_new0(gras_dynar_t,1)))
RAISE_MALLOC;
dynar->size = 0;
if (dynar->data) {
_gras_clear_mem(dynar->data, dynar->size);
- free(dynar->data);
+ gras_free(dynar->data);
}
_gras_clear_mem(dynar, sizeof(gras_dynar_t));
- free(dynar);
+ gras_free(dynar);
}
}
__sanity_check_dynar(dynar);
+ DEBUG1("Reset the dynar %p",(void*)dynar);
if (dynar->free) {
gras_dynar_map(dynar, dynar->free);
}
if (dynar->data) {
_gras_clear_mem(dynar->data, dynar->size);
- free(dynar->data);
+ gras_free(dynar->data);
}
dynar->size = 0;
*
* Returns the count of elements in a dynar
*/
-size_t
+unsigned long
gras_dynar_length(const gras_dynar_t * const dynar) {
- return (dynar ? dynar->used : (size_t)0);
+ return (dynar ? (unsigned long) dynar->used : (unsigned long)0);
}
/**
void * const dst) {
__sanity_check_dynar(dynar);
__check_populated_dynar(dynar);
+ DEBUG1("Pop %p",(void*)dynar);
gras_dynar_remove_at(dynar, dynar->used-1, dst);
}
int * const cursor) {
__sanity_check_dynar(dynar);
- DEBUG1("Set cursor on %p to the first position",dynar);
+ DEBUG1("Set cursor on %p to the first position",(void*)dynar);
*cursor = 0;
}
const int idx = *cursor;
if (idx >= dynar->used) {
- DEBUG1("Cursor on %p already on last elem",dynar);
+ DEBUG1("Cursor on %p already on last elem",(void*)dynar);
return FALSE;
}
- DEBUG2("Cash out cursor on %p at %d",dynar,idx);
+ DEBUG2("Cash out cursor on %p at %d",(void*)dynar,idx);
_gras_dynar_get_elm(dst, dynar, idx);
}
int * const cursor) {
void *dst;
- gras_dynar_remove_at(dynar,(*cursor)--,&dst);
- if (dynar->free)
- (dynar->free)(dst);
+ if (dynar->elmsize > sizeof(void*)) {
+ DEBUG0("Elements too big to fit into a pointer");
+ if (dynar->free) {
+ dst=gras_malloc(dynar->elmsize);
+ gras_dynar_remove_at(dynar,(*cursor)--,dst);
+ (dynar->free)(dst);
+ gras_free(dst);
+ } else {
+ DEBUG0("Ok, we dont care about the element when no free function");
+ gras_dynar_remove_at(dynar,(*cursor)--,NULL);
+ }
+
+ } else {
+ gras_dynar_remove_at(dynar,(*cursor)--,&dst);
+ if (dynar->free)
+ (dynar->free)(dst);
+ }
}