# HG changeset patch # User David Demelier # Date 1326622326 -3600 # Node ID 37eef6776cc6fe1f199b7e1a0164947b6065ce9c # Parent 85ddc81848bda46a5a6d3e6201504b903b54ebd5 Update buffer like array and parray diff -r 85ddc81848bd -r 37eef6776cc6 buffer.c --- a/buffer.c Sat Jan 14 16:47:51 2012 +0100 +++ b/buffer.c Sun Jan 15 11:12:06 2012 +0100 @@ -26,30 +26,60 @@ static int buffer_grow(struct buffer *, size_t); /* - * Create a new buffer with initial size `length'. If type is set to BUFFER_AUTO - * the buffer will grow automatically increasing the size by `length' bytes. On - * BUFFER_FIXED type the buffer won't grow. + * Initialize a new buffer. */ -struct buffer * -buffer_new(enum buffer_type type, int length) +int +buffer_init(struct buffer *buf) { - struct buffer *buf; - - if ((buf = malloc(sizeof (struct buffer))) == NULL) - return NULL; + /* Set defaults if needed */ + buf->bsize = (buf->length == 0) ? BUFFER_DEFAULT_BSIZE : buf->length; + buf->size = buf->bsize + 1; + buf->malloc = (buf->malloc == NULL) ? &malloc : buf->malloc; + buf->realloc = (buf->realloc == NULL) ? &realloc : buf->realloc; - memset(buf, 0, sizeof (struct buffer)); - buf->bsize = (length == 0) ? BUFFER_DEFAULT_BSIZE : length; - buf->size = buf->bsize + 1; - buf->type = type; - - if ((buf->text = calloc(buf->size, 1)) == NULL) { + if ((buf->text = buf->malloc(buf->size)) == NULL) { free(buf); - return NULL; + return -1; } - return buf; + memset(buf->text, 0, buf->size); + + return 0; +} + +/* + * Valid options that can be set for a buffer : + * l -> optional buffer block size of type int + * m -> malloc function that must matches void * (*malloc)(size_t) + * r -> realloc function that must matches void * (*realloc)(void *, size_t) + * t -> type of array of type enum array_type + */ + +void +buffer_set(struct buffer *buf, const char *fmt, ...) +{ + va_list ap; + const char *p; + + va_start(ap, fmt); + for (p = fmt; *p != '\0'; ++p) + switch (*p) { + case 'l': + buf->bsize = va_arg(ap, int); + break; + case 'm': + buf->malloc = va_arg(ap, void *(*)(size_t)); + break; + case 'r': + buf->realloc = va_arg(ap, void *(*)(void *, size_t)); + break; + case 't': + buf->type = va_arg(ap, int); + break; + default: + break; + } } /* @@ -176,7 +206,7 @@ int buffer_shrink(struct buffer *buf) { - if ((buf->text = realloc(buf->text, buf->length + 1)) == NULL) { + if ((buf->text = buf->realloc(buf->text, buf->length + 1)) == NULL) { buf->size = 0; return -1; } @@ -243,7 +273,7 @@ while (newlen - buf->length - 1 <= needed) newlen += buf->bsize; - if ((buf->text = realloc(buf->text, newlen)) == NULL) { + if ((buf->text = buf->realloc(buf->text, newlen)) == NULL) { buf->size = 0; return -1; } diff -r 85ddc81848bd -r 37eef6776cc6 buffer.h --- a/buffer.h Sat Jan 14 16:47:51 2012 +0100 +++ b/buffer.h Sun Jan 15 11:12:06 2012 +0100 @@ -34,17 +34,22 @@ size_t length; /* string's real length */ size_t size; /* current allocated size */ int bsize; /* initial length */ + + /* Own allocation functions */ + void * (*malloc)(size_t); + void * (*realloc)(void *, size_t); }; -struct buffer *buffer_new(enum buffer_type, int); -int buffer_strcat(struct buffer *, const char *); -int buffer_putc(struct buffer *buf, char); -int buffer_bcat(struct buffer *, const void *, size_t); -int buffer_vprintf(struct buffer *, const char *, va_list); -int buffer_printf(struct buffer *, const char *, ...); -int buffer_shrink(struct buffer *); -char *buffer_end(struct buffer *); -void buffer_clear(struct buffer *); -void buffer_free(struct buffer *); +int buffer_init(struct buffer *); +void buffer_set(struct buffer *, const char *, ...); +int buffer_strcat(struct buffer *, const char *); +int buffer_putc(struct buffer *buf, char); +int buffer_bcat(struct buffer *, const void *, size_t); +int buffer_vprintf(struct buffer *, const char *, va_list); +int buffer_printf(struct buffer *, const char *, ...); +int buffer_shrink(struct buffer *); +char *buffer_end(struct buffer *); +void buffer_clear(struct buffer *); +void buffer_free(struct buffer *); #endif /* _BUFFER_H_ */