ext/redcarpet/buffer.c in redcarpet-2.0.0b3 vs ext/redcarpet/buffer.c in redcarpet-2.0.0b4

- old
+ new

@@ -1,9 +1,8 @@ -/* buffer.c - automatic buffer structure */ - /* * Copyright (c) 2008, Natacha Porté + * Copyright (c) 2011, Vicent Martí * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * @@ -14,98 +13,26 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* - * COMPILE TIME OPTIONS - * - * BUFFER_STATS • if defined, stats are kept about memory usage - */ - -#define BUFFER_STDARG #define BUFFER_MAX_ALLOC_SIZE (1024 * 1024 * 16) //16mb #include "buffer.h" #include <stdio.h> #include <stdlib.h> #include <string.h> - -/******************** - * GLOBAL VARIABLES * - ********************/ - -#ifdef BUFFER_STATS -long buffer_stat_nb = 0; -size_t buffer_stat_alloc_bytes = 0; +/* MSVC compat */ +#if defined(_MSC_VER) +# define _buf_vsnprintf _vsnprintf +#else +# define _buf_vsnprintf vsnprintf #endif - -/*************************** - * STATIC HELPER FUNCTIONS * - ***************************/ - -/* lower • retruns the lower-case variant of the input char */ -static char -lower(char c) { - return (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; } - - - -/******************** - * BUFFER FUNCTIONS * - ********************/ - -/* bufcasecmp • case-insensitive buffer comparison */ int -bufcasecmp(const struct buf *a, const struct buf *b) { - size_t i = 0; - size_t cmplen; - if (a == b) return 0; - if (!a) return -1; else if (!b) return 1; - cmplen = (a->size < b->size) ? a->size : b->size; - while (i < cmplen && lower(a->data[i]) == lower(b->data[i])) ++i; - if (i < a->size) { - if (i < b->size) return lower(a->data[i]) - lower(b->data[i]); - else return 1; } - else { if (i < b->size) return -1; - else return 0; } } - - -/* bufcmp • case-sensitive buffer comparison */ -int -bufcmp(const struct buf *a, const struct buf *b) { - size_t i = 0; - size_t cmplen; - if (a == b) return 0; - if (!a) return -1; else if (!b) return 1; - cmplen = (a->size < b->size) ? a->size : b->size; - while (i < cmplen && a->data[i] == b->data[i]) ++i; - if (i < a->size) { - if (i < b->size) return a->data[i] - b->data[i]; - else return 1; } - else { if (i < b->size) return -1; - else return 0; } } - - -/* bufcmps • case-sensitive comparison of a string to a buffer */ -int -bufcmps(const struct buf *a, const char *b) { - const size_t len = strlen(b); - size_t cmplen = len; - int r; - if (!a || !a->size) return b ? 0 : -1; - if (len < a->size) cmplen = a->size; - r = strncmp(a->data, b, cmplen); - if (r) return r; - else if (a->size == len) return 0; - else if (a->size < len) return -1; - else return 1; } - -int bufprefix(const struct buf *buf, const char *prefix) { size_t i; for (i = 0; i < buf->size; ++i) { @@ -117,207 +44,185 @@ } return 0; } - -/* bufdup • buffer duplication */ -struct buf * -bufdup(const struct buf *src, size_t dupunit) { - size_t blocks; - struct buf *ret; - if (src == 0) return 0; - ret = malloc(sizeof (struct buf)); - if (ret == 0) return 0; - ret->unit = dupunit; - ret->size = src->size; - ret->ref = 1; - if (!src->size) { - ret->asize = 0; - ret->data = 0; - return ret; } - blocks = (src->size + dupunit - 1) / dupunit; - ret->asize = blocks * dupunit; - ret->data = malloc(ret->asize); - if (ret->data == 0) { - free(ret); - return 0; } - memcpy(ret->data, src->data, src->size); -#ifdef BUFFER_STATS - buffer_stat_nb += 1; - buffer_stat_alloc_bytes += ret->asize; -#endif - return ret; } - -/* bufgrow • increasing the allocated size to the given value */ +/* bufgrow: increasing the allocated size to the given value */ int -bufgrow(struct buf *buf, size_t neosz) { +bufgrow(struct buf *buf, size_t neosz) +{ size_t neoasz; void *neodata; - if (!buf || !buf->unit || neosz > BUFFER_MAX_ALLOC_SIZE) return 0; - if (buf->asize >= neosz) return 1; + if (!buf || !buf->unit || neosz > BUFFER_MAX_ALLOC_SIZE) + return BUF_ENOMEM; + + if (buf->asize >= neosz) + return BUF_OK; + neoasz = buf->asize + buf->unit; - while (neoasz < neosz) neoasz += buf->unit; + while (neoasz < neosz) + neoasz += buf->unit; + neodata = realloc(buf->data, neoasz); - if (!neodata) return 0; -#ifdef BUFFER_STATS - buffer_stat_alloc_bytes += (neoasz - buf->asize); -#endif + if (!neodata) + return BUF_ENOMEM; + buf->data = neodata; buf->asize = neoasz; - return 1; } + return BUF_OK; +} -/* bufnew • allocation of a new buffer */ +/* bufnew: allocation of a new buffer */ struct buf * -bufnew(size_t unit) { +bufnew(size_t unit) +{ struct buf *ret; ret = malloc(sizeof (struct buf)); + if (ret) { -#ifdef BUFFER_STATS - buffer_stat_nb += 1; -#endif ret->data = 0; ret->size = ret->asize = 0; - ret->ref = 1; - ret->unit = unit; } - return ret; } + ret->unit = unit; + } + return ret; +} +/* bufnullterm: NULL-termination of the string array */ +const char * +bufcstr(struct buf *buf) +{ + if (!buf || !buf->unit) + return NULL; -/* bufnullterm • NUL-termination of the string array (making a C-string) */ -void -bufnullterm(struct buf *buf) { - if (!buf || !buf->unit) return; - if (buf->size < buf->asize && buf->data[buf->size] == 0) return; - if (buf->size + 1 <= buf->asize || bufgrow(buf, buf->size + 1)) - buf->data[buf->size] = 0; } + if (buf->size < buf->asize && buf->data[buf->size] == 0) + return (char *)buf->data; + if (buf->size + 1 <= buf->asize || bufgrow(buf, buf->size + 1) == 0) { + buf->data[buf->size] = 0; + return (char *)buf->data; + } -/* bufprintf • formatted printing to a buffer */ + return NULL; +} + +/* bufprintf: formatted printing to a buffer */ void -bufprintf(struct buf *buf, const char *fmt, ...) { +bufprintf(struct buf *buf, const char *fmt, ...) +{ va_list ap; - if (!buf || !buf->unit) return; + if (!buf || !buf->unit) + return; + va_start(ap, fmt); vbufprintf(buf, fmt, ap); - va_end(ap); } + va_end(ap); +} - -/* bufput • appends raw data to a buffer */ +/* bufput: appends raw data to a buffer */ void -bufput(struct buf *buf, const void *data, size_t len) { - if (!buf) return; - if (buf->size + len > buf->asize && !bufgrow(buf, buf->size + len)) +bufput(struct buf *buf, const void *data, size_t len) +{ + if (!buf) return; - memcpy(buf->data + buf->size, data, len); - buf->size += len; } + if (buf->size + len > buf->asize && bufgrow(buf, buf->size + len) < 0) + return; -/* bufputs • appends a NUL-terminated string to a buffer */ + memcpy(buf->data + buf->size, data, len); + buf->size += len; +} + +/* bufputs: appends a NUL-terminated string to a buffer */ void -bufputs(struct buf *buf, const char *str) { - bufput(buf, str, strlen (str)); } +bufputs(struct buf *buf, const char *str) +{ + bufput(buf, str, strlen(str)); +} -/* bufputc • appends a single char to a buffer */ +/* bufputc: appends a single uint8_t to a buffer */ void -bufputc(struct buf *buf, char c) { - if (!buf) return; - if (buf->size + 1 > buf->asize && !bufgrow(buf, buf->size + 1)) +bufputc(struct buf *buf, int c) +{ + if (!buf) return; - buf->data[buf->size] = c; - buf->size += 1; } + if (buf->size + 1 > buf->asize && bufgrow(buf, buf->size + 1) < 0) + return; -/* bufrelease • decrease the reference count and free the buffer if needed */ -void -bufrelease(struct buf *buf) { - if (!buf) return; - buf->ref -= 1; - if (buf->ref == 0) { -#ifdef BUFFER_STATS - buffer_stat_nb -= 1; - buffer_stat_alloc_bytes -= buf->asize; -#endif - free(buf->data); - free(buf); } } + buf->data[buf->size] = c; + buf->size += 1; +} - -/* bufreset • frees internal data of the buffer */ +/* bufrelease: decrease the reference count and free the buffer if needed */ void -bufreset(struct buf *buf) { - if (!buf) return; -#ifdef BUFFER_STATS - buffer_stat_alloc_bytes -= buf->asize; -#endif +bufrelease(struct buf *buf) +{ + if (!buf) + return; + free(buf->data); - buf->data = 0; - buf->size = buf->asize = 0; } + free(buf); +} -/* bufset • safely assigns a buffer to another */ +/* bufreset: frees internal data of the buffer */ void -bufset(struct buf **dest, struct buf *src) { - if (src) { - if (!src->asize) src = bufdup(src, 1); - else src->ref += 1; } - bufrelease(*dest); - *dest = src; } +bufreset(struct buf *buf) +{ + if (!buf) + return; + free(buf->data); + buf->data = NULL; + buf->size = buf->asize = 0; +} -/* bufslurp • removes a given number of bytes from the head of the array */ +/* bufslurp: removes a given number of bytes from the head of the array */ void -bufslurp(struct buf *buf, size_t len) { - if (!buf || !buf->unit || len <= 0) return; +bufslurp(struct buf *buf, size_t len) +{ + if (!buf || !buf->unit || len <= 0) + return; + if (len >= buf->size) { buf->size = 0; - return; } + return; + } + buf->size -= len; - memmove(buf->data, buf->data + len, buf->size); } + memmove(buf->data, buf->data + len, buf->size); +} - -/* buftoi • converts the numbers at the beginning of the buf into an int */ -int -buftoi(struct buf *buf, size_t offset_i, size_t *offset_o) { - int r = 0, neg = 0; - size_t i = offset_i; - if (!buf || !buf->size) return 0; - if (buf->data[i] == '+') i += 1; - else if (buf->data[i] == '-') { - neg = 1; - i += 1; } - while (i < buf->size && buf->data[i] >= '0' && buf->data[i] <= '9') { - r = (r * 10) + buf->data[i] - '0'; - i += 1; } - if (offset_o) *offset_o = i; - return neg ? -r : r; } - - - -/* vbufprintf • stdarg variant of formatted printing into a buffer */ +/* vbufprintf: stdarg variant of formatted printing into a buffer */ void -vbufprintf(struct buf *buf, const char *fmt, va_list ap) { +vbufprintf(struct buf *buf, const char *fmt, va_list ap) +{ int n; - va_list ap_save; - if (buf == 0 - || (buf->size >= buf->asize && !bufgrow (buf, buf->size + 1))) + + if (buf == 0 || (buf->size >= buf->asize && bufgrow(buf, buf->size + 1)) < 0) return; - va_copy(ap_save, ap); - n = vsnprintf(buf->data + buf->size, buf->asize - buf->size, fmt, ap); + n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap); - if (n < 0 || (size_t)n >= buf->asize - buf->size) { - size_t new_size = (n > 0) ? n : buf->size; - if (!bufgrow (buf, buf->size + new_size + 1)) + if (n < 0) { +#ifdef _MSC_VER + n = _vscprintf(fmt, ap); +#else + return; +#endif + } + + if ((size_t)n >= buf->asize - buf->size) { + if (bufgrow(buf, buf->size + n + 1) < 0) return; - n = vsnprintf(buf->data + buf->size, buf->asize - buf->size, fmt, ap_save); + n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap); } - va_end(ap_save); if (n < 0) return; buf->size += n; } -/* vim: set filetype=c: */