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: */