summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rwxr-xr-xsrc/array.c300
-rwxr-xr-xsrc/array.h147
-rw-r--r--src/autolink.c4
-rw-r--r--[-rwxr-xr-x]src/buffer.c362
-rw-r--r--[-rwxr-xr-x]src/buffer.h167
-rw-r--r--[-rwxr-xr-x]src/markdown.c213
-rw-r--r--[-rwxr-xr-x]src/markdown.h0
8 files changed, 382 insertions, 815 deletions
diff --git a/Makefile b/Makefile
index de38f2a..57346c2 100644
--- a/Makefile
+++ b/Makefile
@@ -32,12 +32,12 @@ all: libsundown.so sundown smartypants html_blocks
libsundown.so: libsundown.so.1
ln -f -s $^ $@
-libsundown.so.1: src/markdown.o src/array.o src/buffer.o src/autolink.o html/html.o html/html_smartypants.o
+libsundown.so.1: src/markdown.o src/stack.o src/buffer.o src/autolink.o html/html.o html/html_smartypants.o
$(CC) $(LDFLAGS) -shared -Wl $^ -o $@
# executables
-sundown: examples/sundown.o src/markdown.o src/array.o src/autolink.o src/buffer.o html/html.o html/html_smartypants.o
+sundown: examples/sundown.o src/markdown.o src/stack.o src/autolink.o src/buffer.o html/html.o html/html_smartypants.o
$(CC) $(LDFLAGS) $^ -o $@
smartypants: examples/smartypants.o src/buffer.o html/html_smartypants.o html/html.o src/autolink.o
diff --git a/src/array.c b/src/array.c
deleted file mode 100755
index be7a816..0000000
--- a/src/array.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/* array.c - automatic dynamic array for pointers */
-
-/*
- * Copyright (c) 2008, Natacha Porté
- *
- * 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.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * 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.
- */
-
-#include "array.h"
-
-#include <string.h>
-
-
-/***************************
- * STATIC HELPER FUNCTIONS *
- ***************************/
-
-/* arr_realloc • realloc memory of a struct array */
-static int
-arr_realloc(struct array* arr, int neosz) {
- void* neo;
- neo = realloc(arr->base, neosz * arr->unit);
- if (neo == 0) return 0;
- arr->base = neo;
- arr->asize = neosz;
- if (arr->size > neosz) arr->size = neosz;
- return 1; }
-
-
-/* parr_realloc • realloc memory of a struct parray */
-static int
-parr_realloc(struct parray* arr, int neosz) {
- void* neo;
- neo = realloc(arr->item, neosz * sizeof (void*));
- if (neo == 0) return 0;
- arr->item = neo;
- arr->asize = neosz;
- if (arr->size > neosz) arr->size = neosz;
- return 1; }
-
-
-
-/***************************
- * GENERIC ARRAY FUNCTIONS *
- ***************************/
-
-/* arr_adjust • shrink the allocated memory to fit exactly the needs */
-int
-arr_adjust(struct array *arr) {
- return arr_realloc(arr, arr->size); }
-
-
-/* arr_free • frees the structure contents (buf NOT the struct itself) */
-void
-arr_free(struct array *arr) {
- if (!arr) return;
- free(arr->base);
- arr->base = 0;
- arr->size = arr->asize = 0; }
-
-
-/* arr_grow • increases the array size to fit the given number of elements */
-int
-arr_grow(struct array *arr, int need) {
- if (arr->asize >= need) return 1;
- else return arr_realloc(arr, need); }
-
-
-/* arr_init • initialization of the contents of the struct */
-void
-arr_init(struct array *arr, size_t unit) {
- arr->base = 0;
- arr->size = arr->asize = 0;
- arr->unit = unit; }
-
-
-/* arr_insert • inserting nb elements before the nth one */
-int
-arr_insert(struct array *arr, int nb, int n) {
- char *src, *dst;
- size_t len;
- if (!arr || nb <= 0 || n < 0
- || !arr_grow(arr, arr->size + nb))
- return 0;
- if (n < arr->size) {
- src = arr->base;
- src += n * arr->unit;
- dst = src + nb * arr->unit;
- len = (arr->size - n) * arr->unit;
- memmove(dst, src, len); }
- arr->size += nb;
- return 1; }
-
-
-/* arr_item • returns a pointer to the n-th element */
-void *
-arr_item(struct array *arr, int no) {
- char *ptr;
- if (!arr || no < 0 || no >= arr->size) return 0;
- ptr = arr->base;
- ptr += no * arr->unit;
- return ptr; }
-
-
-/* arr_newitem • returns the index of a new element appended to the array */
-int
-arr_newitem(struct array *arr) {
- if (!arr_grow(arr, arr->size + 1)) return -1;
- arr->size += 1;
- return arr->size - 1; }
-
-
-/* arr_remove • removes the n-th elements of the array */
-void
-arr_remove(struct array *arr, int idx) {
- if (!arr || idx < 0 || idx >= arr->size) return;
- arr->size -= 1;
- if (idx < arr->size) {
- char *dst = arr->base;
- char *src;
- dst += idx * arr->unit;
- src = dst + arr->unit;
- memmove(dst, src, (arr->size - idx) * arr->unit); } }
-
-
-/* arr_sorted_find • O(log n) search in a sorted array, returning entry */
-void *
-arr_sorted_find(struct array *arr, void *key, array_cmp_fn cmp) {
- int mi, ma, cu, ret;
- char *ptr = arr->base;
- mi = -1;
- ma = arr->size;
- while (mi < ma - 1) {
- cu = mi + (ma - mi) / 2;
- ret = cmp(key, ptr + cu * arr->unit);
- if (ret == 0) return ptr + cu * arr->unit;
- else if (ret < 0) ma = cu;
- else /* if (ret > 0) */ mi = cu; }
- return 0; }
-
-
-/* arr_sorted_find_i • O(log n) search in a sorted array,
- * returning index of the smallest element larger than the key */
-int
-arr_sorted_find_i(struct array *arr, void *key, array_cmp_fn cmp) {
- int mi, ma, cu, ret;
- char *ptr = arr->base;
- mi = -1;
- ma = arr->size;
- while (mi < ma - 1) {
- cu = mi + (ma - mi) / 2;
- ret = cmp(key, ptr + cu * arr->unit);
- if (ret == 0) {
- while (cu < arr->size && ret == 0) {
- cu += 1;
- ret = cmp(key, ptr + cu * arr->unit); }
- return cu; }
- else if (ret < 0) ma = cu;
- else /* if (ret > 0) */ mi = cu; }
- return ma; }
-
-
-
-/***************************
- * POINTER ARRAY FUNCTIONS *
- ***************************/
-
-/* parr_adjust • shrinks the allocated memory to fit exactly the needs */
-int
-parr_adjust(struct parray* arr) {
- return parr_realloc (arr, arr->size); }
-
-
-/* parr_free • frees the structure contents (buf NOT the struct itself) */
-void
-parr_free(struct parray *arr) {
- if (!arr) return;
- free (arr->item);
- arr->item = 0;
- arr->size = 0;
- arr->asize = 0; }
-
-
-/* parr_grow • increases the array size to fit the given number of elements */
-int
-parr_grow(struct parray *arr, int need) {
- if (arr->asize >= need) return 1;
- else return parr_realloc (arr, need); }
-
-
-/* parr_init • initialization of the struct (which is equivalent to zero) */
-void
-parr_init(struct parray *arr) {
- arr->item = 0;
- arr->size = 0;
- arr->asize = 0; }
-
-
-/* parr_insert • inserting nb elements before the nth one */
-int
-parr_insert(struct parray *parr, int nb, int n) {
- char *src, *dst;
- size_t len, i;
- if (!parr || nb <= 0 || n < 0
- || !parr_grow(parr, parr->size + nb))
- return 0;
- if (n < parr->size) {
- src = (void *)parr->item;
- src += n * sizeof (void *);
- dst = src + nb * sizeof (void *);
- len = (parr->size - n) * sizeof (void *);
- memmove(dst, src, len);
- for (i = 0; i < (size_t)nb; ++i)
- parr->item[n + i] = 0; }
- parr->size += nb;
- return 1; }
-
-
-/* parr_pop • pops the last item of the array and returns it */
-void *
-parr_pop(struct parray *arr) {
- if (arr->size <= 0) return 0;
- arr->size -= 1;
- return arr->item[arr->size]; }
-
-
-/* parr_push • pushes a pointer at the end of the array (= append) */
-int
-parr_push(struct parray *arr, void *i) {
- if (!parr_grow(arr, arr->size + 1)) return 0;
- arr->item[arr->size] = i;
- arr->size += 1;
- return 1; }
-
-
-/* parr_remove • removes the n-th element of the array and returns it */
-void *
-parr_remove(struct parray *arr, int idx) {
- void* ret;
- int i;
- if (!arr || idx < 0 || idx >= arr->size) return 0;
- ret = arr->item[idx];
- for (i = idx+1; i < arr->size; ++i)
- arr->item[i - 1] = arr->item[i];
- arr->size -= 1;
- return ret; }
-
-
-/* parr_sorted_find • O(log n) search in a sorted array, returning entry */
-void *
-parr_sorted_find(struct parray *arr, void *key, array_cmp_fn cmp) {
- int mi, ma, cu, ret;
- mi = -1;
- ma = arr->size;
- while (mi < ma - 1) {
- cu = mi + (ma - mi) / 2;
- ret = cmp(key, arr->item[cu]);
- if (ret == 0) return arr->item[cu];
- else if (ret < 0) ma = cu;
- else /* if (ret > 0) */ mi = cu; }
- return 0; }
-
-
-/* parr_sorted_find_i • O(log n) search in a sorted array,
- * returning index of the smallest element larger than the key */
-int
-parr_sorted_find_i(struct parray *arr, void *key, array_cmp_fn cmp) {
- int mi, ma, cu, ret;
- mi = -1;
- ma = arr->size;
- while (mi < ma - 1) {
- cu = mi + (ma - mi) / 2;
- ret = cmp(key, arr->item[cu]);
- if (ret == 0) {
- while (cu < arr->size && ret == 0) {
- cu += 1;
- ret = cmp(key, arr->item[cu]); }
- return cu; }
- else if (ret < 0) ma = cu;
- else /* if (ret > 0) */ mi = cu; }
- return ma; }
-
-
-/* parr_top • returns the top the stack (i.e. the last element of the array) */
-void *
-parr_top(struct parray *arr) {
- if (arr == 0 || arr->size <= 0) return 0;
- else return arr->item[arr->size - 1]; }
-
-/* vim: set filetype=c: */
diff --git a/src/array.h b/src/array.h
deleted file mode 100755
index bb9a2a5..0000000
--- a/src/array.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/* array.h - automatic dynamic array for pointers */
-
-/*
- * Copyright (c) 2008, Natacha Porté
- *
- * 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.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * 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.
- */
-
-#ifndef LITHIUM_ARRAY_H
-#define LITHIUM_ARRAY_H
-
-#include <stdlib.h>
-
-/********************
- * TYPE DEFINITIONS *
- ********************/
-
-/* struct array • generic linear array */
-struct array {
- void* base;
- int size;
- int asize;
- size_t unit; };
-
-
-/* struct parray • array of pointers */
-struct parray {
- void ** item;
- int size;
- int asize; };
-
-
-/* array_cmp_fn • comparison functions for sorted arrays */
-typedef int (*array_cmp_fn)(void *key, void *array_entry);
-
-
-
-/***************************
- * GENERIC ARRAY FUNCTIONS *
- ***************************/
-
-/* arr_adjust • shrink the allocated memory to fit exactly the needs */
-int
-arr_adjust(struct array *);
-
-/* arr_free • frees the structure contents (buf NOT the struct itself) */
-void
-arr_free(struct array *);
-
-/* arr_grow • increases the array size to fit the given number of elements */
-int
-arr_grow(struct array *, int);
-
-/* arr_init • initialization of the contents of the struct */
-void
-arr_init(struct array *, size_t);
-
-/* arr_insert • inserting elements nb before the nth one */
-int
-arr_insert(struct array *, int nb, int n);
-
-/* arr_item • returns a pointer to the n-th element */
-void *
-arr_item(struct array *, int);
-
-/* arr_newitem • returns the index of a new element appended to the array */
-int
-arr_newitem(struct array *);
-
-/* arr_remove • removes the n-th elements of the array */
-void
-arr_remove(struct array *, int);
-
-/* arr_sorted_find • O(log n) search in a sorted array, returning entry */
-/* equivalent to bsearch(key, arr->base, arr->size, arr->unit, cmp) */
-void *
-arr_sorted_find(struct array *, void *key, array_cmp_fn cmp);
-
-/* arr_sorted_find_i • O(log n) search in a sorted array,
- * returning index of the smallest element larger than the key */
-int
-arr_sorted_find_i(struct array *, void *key, array_cmp_fn cmp);
-
-
-/***************************
- * POINTER ARRAY FUNCTIONS *
- ***************************/
-
-/* parr_adjust • shrinks the allocated memory to fit exactly the needs */
-int
-parr_adjust(struct parray *);
-
-/* parr_free • frees the structure contents (buf NOT the struct itself) */
-void
-parr_free(struct parray *);
-
-/* parr_grow • increases the array size to fit the given number of elements */
-int
-parr_grow(struct parray *, int);
-
-/* parr_init • initialization of the struct (which is equivalent to zero) */
-void
-parr_init(struct parray *);
-
-/* parr_insert • inserting nb elements before the nth one */
-int
-parr_insert(struct parray *, int nb, int n);
-
-/* parr_pop • pops the last item of the array and returns it */
-void *
-parr_pop(struct parray *);
-
-/* parr_push • pushes a pointer at the end of the array (= append) */
-int
-parr_push(struct parray *, void *);
-
-/* parr_remove • removes the n-th element of the array and returns it */
-void *
-parr_remove(struct parray *, int);
-
-/* parr_sorted_find • O(log n) search in a sorted array, returning entry */
-void *
-parr_sorted_find(struct parray *, void *key, array_cmp_fn cmp);
-
-/* parr_sorted_find_i • O(log n) search in a sorted array,
- * returning index of the smallest element larger than the key */
-int
-parr_sorted_find_i(struct parray *, void *key, array_cmp_fn cmp);
-
-/* parr_top • returns the top the stack (i.e. the last element of the array) */
-void *
-parr_top(struct parray *);
-
-
-#endif /* ndef LITHIUM_ARRAY_H */
-
-/* vim: set filetype=c: */
diff --git a/src/autolink.c b/src/autolink.c
index b31658a..02ea9cd 100644
--- a/src/autolink.c
+++ b/src/autolink.c
@@ -154,7 +154,7 @@ sd_autolink__www(size_t *rewind_p, struct buf *link, char *data, size_t offset,
if (offset > 0 && !ispunct(data[-1]) && !isspace(data[-1]))
return 0;
- if (size < 4 || memcmp(data, "www.", STRLEN("www.")) != 0)
+ if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0)
return 0;
link_end = check_domain(data, size);
@@ -238,7 +238,7 @@ sd_autolink__url(size_t *rewind_p, struct buf *link, char *data, size_t offset,
if (!sd_autolink_issafe(data - rewind, size + rewind))
return 0;
- link_end = STRLEN("://");
+ link_end = strlen("://");
domain_len = check_domain(data + link_end, size - link_end);
if (domain_len == 0)
diff --git a/src/buffer.c b/src/buffer.c
index 4b04a78..1098eaf 100755..100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1,7 +1,6 @@
-/* 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
@@ -16,13 +15,6 @@
* 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"
@@ -31,77 +23,64 @@
#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
+/* bufcmp: buffer comparison */
+int
+bufcmp(const struct buf *a, const struct buf *b)
+{
+ size_t i = 0;
+ size_t cmplen;
-/***************************
- * 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; }
-
+ if (a == b)
+ return 0;
+ if (!a)
+ return -1;
-/********************
- * BUFFER FUNCTIONS *
- ********************/
+ if (!b)
+ return 1;
-/* 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; } }
+ while (i < cmplen && a->data[i] == b->data[i])
+ ++i;
-/* 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; } }
-
+ if (i < b->size) return a->data[i] - b->data[i];
+ return 1;
+ } else {
+ if (i < b->size) return -1;
+ return 0;
+ }
+}
-/* bufcmps • case-sensitive comparison of a string to a buffer */
+/* bufcmps: comparison of a string to a buffer */
int
-bufcmps(const struct buf *a, const char *b) {
+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;
+
+ 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; }
+ else return 1;
+}
int
bufprefix(const struct buf *buf, const char *prefix)
@@ -120,199 +99,231 @@ bufprefix(const struct buf *buf, const char *prefix)
}
-/* bufdup • buffer duplication */
+/* bufdup: buffer duplication */
struct buf *
-bufdup(const struct buf *src, size_t dupunit) {
+bufdup(const struct buf *src, size_t dupunit)
+{
size_t blocks;
struct buf *ret;
- if (src == 0) return 0;
+ if (src == 0)
+ return 0;
+
ret = malloc(sizeof (struct buf));
- if (ret == 0) return 0;
+ 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; }
+ 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; }
+ 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; }
+ 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 buf->data;
+ if (buf->size + 1 <= buf->asize || bufgrow(buf, buf->size + 1) == 0) {
+ buf->data[buf->size] = 0;
+ return buf->data;
+ }
+
+ return NULL;
+}
-/* bufprintf • formatted printing to a buffer */
+/* 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;
+
+ memcpy(buf->data + buf->size, data, len);
+ buf->size += len;
+}
-/* bufputs • appends a NUL-terminated string to a buffer */
+/* 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 char 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, char 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 */
+ buf->data[buf->size] = c;
+ buf->size += 1;
+}
+
+/* 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
+bufrelease(struct buf *buf)
+{
+ if (!buf)
+ return;
+
+ if (--buf->ref == 0) {
free(buf->data);
- free(buf); } }
+ free(buf);
+ }
+}
-/* bufreset • frees internal data of the buffer */
+/* bufreset: frees internal data of the buffer */
void
-bufreset(struct buf *buf) {
- if (!buf) return;
-#ifdef BUFFER_STATS
- buffer_stat_alloc_bytes -= buf->asize;
-#endif
+bufreset(struct buf *buf)
+{
+ if (!buf)
+ return;
+
free(buf->data);
- buf->data = 0;
- buf->size = buf->asize = 0; }
+ buf->data = NULL;
+ buf->size = buf->asize = 0;
+}
-/* bufset • safely assigns a buffer to another */
+/* bufset: safely assigns a buffer to another */
void
-bufset(struct buf **dest, struct buf *src) {
+bufset(struct buf **dest, struct buf *src)
+{
if (src) {
if (!src->asize) src = bufdup(src, 1);
- else src->ref += 1; }
- bufrelease(*dest);
- *dest = src; }
+ else src->ref += 1;
+ }
+ bufrelease(*dest);
+ *dest = src;
+}
-/* 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; }
- buf->size -= len;
- memmove(buf->data, buf->data + len, buf->size); }
+ return;
+ }
+ buf->size -= len;
+ 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(buf->data + buf->size, buf->asize - buf->size, fmt, ap);
+
+ if (n < 0) {
+#ifdef _MSC_VER
+ n = _vscprintf(fmt, ap);
+#else
+ return;
+#endif
+ }
- 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 ((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(buf->data + buf->size, buf->asize - buf->size, fmt, ap);
}
- va_end(ap_save);
if (n < 0)
return;
@@ -320,4 +331,3 @@ vbufprintf(struct buf *buf, const char *fmt, va_list ap) {
buf->size += n;
}
-/* vim: set filetype=c: */
diff --git a/src/buffer.h b/src/buffer.h
index ea0ad65..6db4d78 100755..100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1,7 +1,6 @@
-/* buffer.h - 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
@@ -16,139 +15,89 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef LITHIUM_BUFFER_H
-#define LITHIUM_BUFFER_H
+#ifndef __GEN_BUFFER_H__
+#define __GEN_BUFFER_H__
#include <stddef.h>
+#include <stdarg.h>
#if defined(_MSC_VER)
#define __attribute__(x)
#define inline
-#define strncasecmp _strnicmp
-#define snprintf _snprintf
-#define va_copy(d,s) ((d) = (s))
#endif
-/********************
- * TYPE DEFINITIONS *
- ********************/
+typedef enum {
+ BUF_OK = 0,
+ BUF_ENOMEM = -1,
+} buferror_t;
-/* struct buf • character array buffer */
+/* struct buf: character array buffer */
struct buf {
- char * data; /* actual character data */
- size_t size; /* size of the string */
- size_t asize; /* allocated size (0 = volatile buffer) */
- size_t unit; /* reallocation unit size (0 = read-only buffer) */
- int ref; }; /* reference count */
-
-/**********
- * MACROS *
- **********/
-
-#define STRLEN(x) (sizeof(x) - 1)
-
-/* CONST_BUF • global buffer from a string litteral */
-#define CONST_BUF(name, string) \
- static struct buf name = { string, sizeof string -1, sizeof string }
-
-
-/* VOLATILE_BUF • macro for creating a volatile buffer on the stack */
-#define VOLATILE_BUF(name, strname) \
- struct buf name = { strname, strlen(strname) }
-
-
-/* BUFPUTSL • optimized bufputs of a string litteral */
+ char *data; /* actual character data */
+ size_t size; /* size of the string */
+ size_t asize; /* allocated size (0 = volatile buffer) */
+ size_t unit; /* reallocation unit size (0 = read-only buffer) */
+ int ref; /* reference count */
+};
+
+/* CONST_BUF: global buffer from a string litteral */
+#define BUF_STATIC(string) \
+ { string, sizeof string -1, sizeof string, 0, 0 }
+
+/* VOLATILE_BUF: macro for creating a volatile buffer on the stack */
+#define BUF_VOLATILE(strname) \
+ { strname, strlen(strname), 0, 0, 0 }
+
+/* BUFPUTSL: optimized bufputs of a string litteral */
#define BUFPUTSL(output, litteral) \
bufput(output, litteral, sizeof litteral - 1)
+/* bufcmp: case-sensitive buffer comparison */
+int bufcmp(const struct buf *, const struct buf *);
+/* bufcmps: case-sensitive comparison of a string to a buffer */
+int bufcmps(const struct buf *, const char *);
-/********************
- * BUFFER FUNCTIONS *
- ********************/
-
-/* bufcasecmp • case-insensitive buffer comparison */
-int
-bufcasecmp(const struct buf *, const struct buf *);
-
-/* bufcmp • case-sensitive buffer comparison */
-int
-bufcmp(const struct buf *, const struct buf *);
+/* bufprefix: compare the beginning of a buffer with a string */
+int bufprefix(const struct buf *buf, const char *prefix);
-/* bufcmps • case-sensitive comparison of a string to a buffer */
-int
-bufcmps(const struct buf *, const char *);
+/* bufdup: buffer duplication */
+struct buf *bufdup(const struct buf *, size_t) __attribute__ ((malloc));
-/* bufprefix * compare the beginning of a buffer with a string */
-int
-bufprefix(const struct buf *buf, const char *prefix);
+/* bufgrow: increasing the allocated size to the given value */
+int bufgrow(struct buf *, size_t);
-/* bufdup • buffer duplication */
-struct buf *
-bufdup(const struct buf *, size_t)
- __attribute__ ((malloc));
+/* bufnew: allocation of a new buffer */
+struct buf *bufnew(size_t) __attribute__ ((malloc));
-/* bufgrow • increasing the allocated size to the given value */
-int
-bufgrow(struct buf *, size_t);
+/* bufnullterm: NUL-termination of the string array (making a C-string) */
+const char *bufcstr(struct buf *);
-/* bufnew • allocation of a new buffer */
-struct buf *
-bufnew(size_t)
- __attribute__ ((malloc));
+/* bufprintf: formatted printing to a buffer */
+void bufprintf(struct buf *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
-/* bufnullterm • NUL-termination of the string array (making a C-string) */
-void
-bufnullterm(struct buf *);
+/* bufput: appends raw data to a buffer */
+void bufput(struct buf *, const void*, size_t);
-/* bufprintf • formatted printing to a buffer */
-void
-bufprintf(struct buf *, const char *, ...)
- __attribute__ ((format (printf, 2, 3)));
+/* bufputs: appends a NUL-terminated string to a buffer */
+void bufputs(struct buf *, const char*);
-/* bufput • appends raw data to a buffer */
-void
-bufput(struct buf *, const void*, size_t);
+/* bufputc: appends a single char to a buffer */
+void bufputc(struct buf *, char);
-/* bufputs • appends a NUL-terminated string to a buffer */
-void
-bufputs(struct buf *, const char*);
+/* bufrelease: decrease the reference count and free the buffer if needed */
+void bufrelease(struct buf *);
-/* bufputc • appends a single char to a buffer */
-void
-bufputc(struct buf *, char);
+/* bufreset: frees internal data of the buffer */
+void bufreset(struct buf *);
-/* bufrelease • decrease the reference count and free the buffer if needed */
-void
-bufrelease(struct buf *);
+/* bufset: safely assigns a buffer to another */
+void bufset(struct buf **, struct buf *);
-/* bufreset • frees internal data of the buffer */
-void
-bufreset(struct buf *);
+/* bufslurp: removes a given number of bytes from the head of the array */
+void bufslurp(struct buf *, size_t);
-/* bufset • safely assigns a buffer to another */
-void
-bufset(struct buf **, struct buf *);
+/* vbufprintf: stdarg variant of formatted printing into a buffer */
+void vbufprintf(struct buf *, const char*, va_list);
-/* bufslurp • removes a given number of bytes from the head of the array */
-void
-bufslurp(struct buf *, size_t);
-
-/* buftoi • converts the numbers at the beginning of the buf into an int */
-int
-buftoi(struct buf *, size_t, size_t *);
-
-
-
-#ifdef BUFFER_STDARG
-#include <stdarg.h>
-
-/* vbufprintf • stdarg variant of formatted printing into a buffer */
-void
-vbufprintf(struct buf *, const char*, va_list);
-
-#endif /* def BUFFER_STDARG */
-
-#endif /* ndef LITHIUM_BUFFER_H */
-
-/* vim: set filetype=c: */
+#endif
diff --git a/src/markdown.c b/src/markdown.c
index f769a8b..ee19009 100755..100644
--- a/src/markdown.c
+++ b/src/markdown.c
@@ -18,14 +18,15 @@
*/
#include "markdown.h"
-#include "array.h"
+#include "stack.h"
#include <assert.h>
#include <string.h>
-//#include <strings.h> /* for strncasecmp */
#include <ctype.h>
#include <stdio.h>
+#define REF_TABLE_SIZE 8
+
#define BUFFER_BLOCK 0
#define BUFFER_SPAN 1
@@ -40,14 +41,17 @@
* LOCAL TYPES *
***************/
-/* link_ref • reference to a link */
+/* link_ref: reference to a link */
struct link_ref {
- struct buf *id;
- struct buf *link;
- struct buf *title;
+ unsigned int id;
+
+ struct buf link;
+ struct buf title;
+
+ struct link_ref *next;
};
-/* char_trigger • function pointer to render active chars */
+/* char_trigger: function pointer to render active chars */
/* returns the number of chars taken care of */
/* data is the pointer of the beginning of the span */
/* offset is the number of valid chars before data */
@@ -102,9 +106,9 @@ struct render {
struct sd_callbacks cb;
void *opaque;
- struct array refs;
+ struct link_ref *refs[REF_TABLE_SIZE];
char active_char[256];
- struct parray work_bufs[2];
+ struct stack work_bufs[2];
unsigned int ext_flags;
size_t max_nesting;
};
@@ -118,14 +122,15 @@ rndr_newbuf(struct render *rndr, int type)
{
static const size_t buf_size[2] = {256, 64};
struct buf *work = NULL;
- struct parray *queue = &rndr->work_bufs[type];
+ struct stack *pool = &rndr->work_bufs[type];
- if (queue->size < queue->asize) {
- work = queue->item[queue->size++];
+ if (pool->size < pool->asize &&
+ pool->item[pool->size] != NULL) {
+ work = pool->item[pool->size++];
work->size = 0;
} else {
work = bufnew(buf_size[type]);
- parr_push(queue, work);
+ stack_push(pool, work);
}
return work;
@@ -157,21 +162,72 @@ unscape_text(struct buf *ob, struct buf *src)
}
}
-/* cmp_link_ref • comparison function for link_ref sorted arrays */
-static int
-cmp_link_ref(void *key, void *array_entry)
+static unsigned int
+hash_link_ref(char *link_ref, size_t length)
{
- struct link_ref *lr = array_entry;
- return bufcasecmp(key, lr->id);
+ size_t i;
+ unsigned int hash = 0;
+
+ for (i = 0; i < length; ++i)
+ hash = tolower(link_ref[i]) + (hash << 6) + (hash << 16) - hash;
+
+ return hash;
}
-/* cmp_link_ref_sort • comparison function for link_ref qsort */
-static int
-cmp_link_ref_sort(const void *a, const void *b)
+static void add_link_ref(
+ struct link_ref **references,
+ char *name, size_t name_size,
+ char *link, size_t link_size,
+ char *title, size_t title_size)
+{
+ struct link_ref *ref = calloc(1, sizeof(struct link_ref));
+
+ if (!ref)
+ return;
+
+ ref->id = hash_link_ref(name, name_size);
+ ref->next = references[ref->id % REF_TABLE_SIZE];
+
+ ref->link.data = link;
+ ref->link.size = link_size;
+
+ ref->title.data = title;
+ ref->title.size = title_size;
+
+ references[ref->id % REF_TABLE_SIZE] = ref;
+}
+
+static struct link_ref *
+find_link_ref(struct link_ref **references, char *name, size_t length)
{
- const struct link_ref *lra = a;
- const struct link_ref *lrb = b;
- return bufcasecmp(lra->id, lrb->id);
+ unsigned int hash = hash_link_ref(name, length);
+ struct link_ref *ref = NULL;
+
+ ref = references[hash % REF_TABLE_SIZE];
+
+ while (ref != NULL) {
+ if (ref->id == hash)
+ return ref;
+
+ ref = ref->next;
+ }
+
+ return NULL;
+}
+
+static void
+free_link_refs(struct link_ref **references)
+{
+ size_t i;
+
+ for (i = 0; i < REF_TABLE_SIZE; ++i) {
+ struct link_ref *r = references[i];
+ struct link_ref *next;
+
+ while (r) {
+ next = r->next; free(r); r = next;
+ }
+ }
}
/****************************
@@ -304,10 +360,10 @@ parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size)
end = markdown_char_ptrs[(int)action](ob, rndr, data + i, i, size - i);
if (!end) /* no action from the callback */
end = i + 1;
- else {
+ else {
i += end;
end = i;
- }
+ }
}
}
@@ -451,7 +507,7 @@ parse_emph2(struct buf *ob, struct render *rndr, char *data, size_t size, char c
if (!render_method)
return 0;
-
+
while (i < size) {
len = find_emph_char(data + i, size - i, c);
if (!len) return 0;
@@ -508,7 +564,7 @@ parse_emph3(struct buf *ob, struct render *rndr, char *data, size_t size, char c
else return len - 1;
}
}
- return 0;
+ return 0;
}
/* char_emphasis • single and double emphasis parsing */
@@ -541,7 +597,7 @@ char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, si
return ret + 3;
}
- return 0;
+ return 0;
}
@@ -894,12 +950,14 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
id.size = link_e - link_b;
}
- lr = arr_sorted_find(&rndr->refs, &id, cmp_link_ref);
- if (!lr) goto cleanup;
+ lr = find_link_ref(rndr->refs, id.data, id.size);
+ if (!lr)
+ goto cleanup;
/* keeping link and title from link_ref */
- link = lr->link;
- title = lr->title;
+ link = &lr->link;
+ if (lr->title.size)
+ title = &lr->title;
i++;
}
@@ -928,12 +986,14 @@ char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t
}
/* finding the link_ref */
- lr = arr_sorted_find(&rndr->refs, &id, cmp_link_ref);
- if (!lr) goto cleanup;
+ lr = find_link_ref(rndr->refs, id.data, id.size);
+ if (!lr)
+ goto cleanup;
/* keeping link and title from link_ref */
- link = lr->link;
- title = lr->title;
+ link = &lr->link;
+ if (lr->title.size)
+ title = &lr->title;
/* rewinding the whitespace */
i = txt_e + 1;
@@ -1527,7 +1587,7 @@ parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int
/* intermediate render of block li */
if (sublist && sublist < work->size) {
parse_block(inter, rndr, work->data, sublist);
- parse_block(inter, rndr, work->data + sublist, work->size - sublist);
+ parse_block(inter, rndr, work->data + sublist, work->size - sublist);
}
else
parse_block(inter, rndr, work->data, work->size);
@@ -1676,7 +1736,7 @@ parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, in
if (do_render && rndr->cb.blockhtml)
rndr->cb.blockhtml(ob, &work, rndr->opaque);
return work.size;
- }
+ }
}
/* HR, which is the only self-closing block tag considered */
@@ -1694,7 +1754,7 @@ parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, in
rndr->cb.blockhtml(ob, &work, rndr->opaque);
return work.size;
}
- }
+ }
}
/* no special case recognised */
@@ -1726,7 +1786,7 @@ parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, in
found = 1;
break;
}
- }
+ }
}
if (!found) return 0;
@@ -1979,7 +2039,7 @@ parse_block(struct buf *ob, struct render *rndr, char *data, size_t size)
/* is_ref • returns whether a line is a reference or not */
static int
-is_ref(char *data, size_t beg, size_t end, size_t *last, struct array *refs)
+is_ref(char *data, size_t beg, size_t end, size_t *last, struct link_ref **refs)
{
/* int n; */
size_t i = 0;
@@ -1987,8 +2047,6 @@ is_ref(char *data, size_t beg, size_t end, size_t *last, struct array *refs)
size_t link_offset, link_end;
size_t title_offset, title_end;
size_t line_end;
- struct link_ref *lr;
-/* struct buf id = { 0, 0, 0, 0, 0 }; / * volatile buf for id search */
/* up to 3 optional leading spaces */
if (beg + 3 >= end) return 0;
@@ -2062,22 +2120,33 @@ is_ref(char *data, size_t beg, size_t end, size_t *last, struct array *refs)
&& (data[i] == '\'' || data[i] == '"' || data[i] == ')')) {
line_end = title_end;
title_end = i; } }
- if (!line_end) return 0; /* garbage after the link */
+
+ if (!line_end)
+ return 0; /* garbage after the link */
/* a valid ref has been found, filling-in return structures */
- if (last) *last = line_end;
- if (!refs) return 1;
- lr = arr_item(refs, arr_newitem(refs));
- lr->id = bufnew(id_end - id_offset);
- bufput(lr->id, data + id_offset, id_end - id_offset);
- lr->link = bufnew(link_end - link_offset);
- bufput(lr->link, data + link_offset, link_end - link_offset);
- if (title_end > title_offset) {
- lr->title = bufnew(title_end - title_offset);
- bufput(lr->title, data + title_offset,
- title_end - title_offset); }
- else lr->title = 0;
- return 1;
+ if (last)
+ *last = line_end;
+
+ if (refs) {
+ char *title_str = NULL;
+ size_t title_size = 0;
+
+ if (title_end > title_offset) {
+ title_str = data + title_offset;
+ title_size = title_end - title_offset;
+ }
+
+ add_link_ref( refs,
+ data + id_offset, /* identifier */
+ id_end - id_offset,
+ data + link_offset, /* link url */
+ link_end - link_offset,
+ title_str, /* title (optional) */
+ title_size);
+ }
+
+ return 1;
}
static void expand_tabs(struct buf *ob, const char *line, size_t size)
@@ -2119,7 +2188,6 @@ sd_markdown(struct buf *ob,
static const float MARKDOWN_GROW_FACTOR = 1.4f;
- struct link_ref *lr;
struct buf *text;
size_t i, beg, end;
struct render rndr;
@@ -2136,12 +2204,10 @@ sd_markdown(struct buf *ob,
bufgrow(text, ib->size);
memcpy(&rndr.cb, callbacks, sizeof(struct sd_callbacks));
- arr_init(&rndr.refs, sizeof (struct link_ref));
- parr_init(&rndr.work_bufs[BUFFER_BLOCK]);
- parr_init(&rndr.work_bufs[BUFFER_SPAN]);
+ memset(&rndr.refs, 0x0, REF_TABLE_SIZE * sizeof(void *));
-/* for (i = 0; i < 256; i++)
- rndr.active_char[i] = 0; */
+ stack_init(&rndr.work_bufs[BUFFER_BLOCK], 4);
+ stack_init(&rndr.work_bufs[BUFFER_SPAN], 8);
memset(rndr.active_char, 0x0, 256);
@@ -2182,7 +2248,7 @@ sd_markdown(struct buf *ob,
/* first pass: looking for references, copying everything else */
beg = 0;
while (beg < ib->size) /* iterating over lines */
- if (is_ref(ib->data, beg, ib->size, &end, &rndr.refs))
+ if (is_ref(ib->data, beg, ib->size, &end, rndr.refs))
beg = end;
else { /* skipping to the next line */
end = beg;
@@ -2203,10 +2269,6 @@ sd_markdown(struct buf *ob,
beg = end;
}
- /* sorting the reference array */
- if (rndr.refs.size)
- qsort(rndr.refs.base, rndr.refs.size, rndr.refs.unit, cmp_link_ref_sort);
-
/* pre-grow the output buffer to minimize allocations */
bufgrow(ob, text->size * MARKDOWN_GROW_FACTOR);
@@ -2227,14 +2289,7 @@ sd_markdown(struct buf *ob,
/* clean-up */
bufrelease(text);
- lr = rndr.refs.base;
- for (i = 0; i < (size_t)rndr.refs.size; i++) {
- bufrelease(lr[i].id);
- bufrelease(lr[i].link);
- bufrelease(lr[i].title);
- }
-
- arr_free(&rndr.refs);
+ free_link_refs(rndr.refs);
assert(rndr.work_bufs[BUFFER_SPAN].size == 0);
assert(rndr.work_bufs[BUFFER_BLOCK].size == 0);
@@ -2245,8 +2300,8 @@ sd_markdown(struct buf *ob,
for (i = 0; i < (size_t)rndr.work_bufs[BUFFER_BLOCK].asize; ++i)
bufrelease(rndr.work_bufs[BUFFER_BLOCK].item[i]);
- parr_free(&rndr.work_bufs[BUFFER_SPAN]);
- parr_free(&rndr.work_bufs[BUFFER_BLOCK]);
+ stack_free(&rndr.work_bufs[BUFFER_SPAN]);
+ stack_free(&rndr.work_bufs[BUFFER_BLOCK]);
}
void
diff --git a/src/markdown.h b/src/markdown.h
index 2886cdf..2886cdf 100755..100644
--- a/src/markdown.h
+++ b/src/markdown.h