diff --git a/api_test/main.c b/api_test/main.c index f3fc9ffdf..0e8e7e242 100644 --- a/api_test/main.c +++ b/api_test/main.c @@ -340,7 +340,7 @@ static void iterator_delete(test_batch_runner *runner) { cmark_mem *allocator = cmark_get_default_mem_allocator(); - allocator->free(html); + allocator->free(allocator->ctx, html); cmark_iter_free(iter); cmark_node_free(doc); } diff --git a/src/blocks.c b/src/blocks.c index 292e563bb..6f8378f47 100644 --- a/src/blocks.c +++ b/src/blocks.c @@ -73,7 +73,7 @@ static cmark_node *make_block(cmark_mem *mem, cmark_node_type tag, int start_line, int start_column) { cmark_node *e; - e = (cmark_node *)mem->calloc(1, sizeof(*e)); + e = (cmark_node *)mem->calloc(mem->ctx, 1, sizeof(*e)); e->mem = mem; e->type = (uint16_t)tag; e->flags = CMARK_NODE__OPEN; @@ -91,7 +91,7 @@ static cmark_node *make_document(cmark_mem *mem) { } cmark_parser *cmark_parser_new_with_mem_into_root(int options, cmark_mem *mem, cmark_node *root) { - cmark_parser *parser = (cmark_parser *)mem->calloc(1, sizeof(cmark_parser)); + cmark_parser *parser = (cmark_parser *)mem->calloc(mem->ctx, 1, sizeof(cmark_parser)); parser->mem = mem; cmark_strbuf_init(mem, &parser->curline, 256); @@ -134,7 +134,7 @@ void cmark_parser_free(cmark_parser *parser) { cmark_strbuf_free(&parser->curline); cmark_strbuf_free(&parser->linebuf); cmark_reference_map_free(parser->refmap); - mem->free(parser); + mem->free(mem->ctx, parser); } static cmark_node *finalize(cmark_parser *parser, cmark_node *b); @@ -411,7 +411,7 @@ static void process_inlines(cmark_mem *mem, cmark_node *root, if (ev_type == CMARK_EVENT_ENTER) { if (contains_inlines(S_type(cur))) { cmark_parse_inlines(mem, cur, refmap, options); - mem->free(cur->data); + mem->free(mem->ctx, cur->data); cur->data = NULL; cur->len = 0; } @@ -452,7 +452,7 @@ static bufsize_t parse_list_marker(cmark_mem *mem, cmark_chunk *input, } } - data = (cmark_list *)mem->calloc(1, sizeof(*data)); + data = (cmark_list *)mem->calloc(mem->ctx, 1, sizeof(*data)); data->marker_offset = 0; // will be adjusted later data->list_type = CMARK_BULLET_LIST; data->bullet_char = c; @@ -492,7 +492,7 @@ static bufsize_t parse_list_marker(cmark_mem *mem, cmark_chunk *input, } } - data = (cmark_list *)mem->calloc(1, sizeof(*data)); + data = (cmark_list *)mem->calloc(mem->ctx, 1, sizeof(*data)); data->marker_offset = 0; // will be adjusted later data->list_type = CMARK_ORDERED_LIST; data->bullet_char = 0; @@ -1130,7 +1130,7 @@ static void open_new_blocks(cmark_parser *parser, cmark_node **container, parser->first_nonspace + 1); /* TODO: static */ memcpy(&((*container)->as.list), data, sizeof(*data)); - parser->mem->free(data); + parser->mem->free(parser->mem->ctx, data); } else if (indented && !maybe_lazy && !parser->blank) { S_advance_offset(parser, input, CODE_INDENT, true); *container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK, diff --git a/src/buffer.c b/src/buffer.c index f3159948c..097b429bf 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -53,7 +53,7 @@ void cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size) { new_size += 1; new_size = (new_size + 7) & ~7; - buf->ptr = (unsigned char *)buf->mem->realloc(buf->asize ? buf->ptr : NULL, + buf->ptr = (unsigned char *)buf->mem->realloc(buf->mem->ctx, buf->asize ? buf->ptr : NULL, new_size); buf->asize = new_size; } @@ -63,7 +63,7 @@ void cmark_strbuf_free(cmark_strbuf *buf) { return; if (buf->ptr != cmark_strbuf__initbuf) - buf->mem->free(buf->ptr); + buf->mem->free(buf->mem->ctx, buf->ptr); cmark_strbuf_init(buf->mem, buf, 0); } @@ -116,7 +116,7 @@ unsigned char *cmark_strbuf_detach(cmark_strbuf *buf) { if (buf->asize == 0) { /* return an empty string */ - return (unsigned char *)buf->mem->calloc(1, 1); + return (unsigned char *)buf->mem->calloc(buf->mem->ctx, 1, 1); } cmark_strbuf_init(buf->mem, buf, 0); diff --git a/src/cmark.c b/src/cmark.c index 60aedbc6f..c7def6a00 100644 --- a/src/cmark.c +++ b/src/cmark.c @@ -10,7 +10,8 @@ int cmark_version(void) { return CMARK_VERSION; } const char *cmark_version_string(void) { return CMARK_VERSION_STRING; } -static void *xcalloc(size_t nmem, size_t size) { +static void *xcalloc(void *ctx, size_t nmem, size_t size) { + (void)ctx; // explicitly discard void *ptr = calloc(nmem, size); if (!ptr) { fprintf(stderr, "[cmark] calloc returned null pointer, aborting\n"); @@ -19,7 +20,8 @@ static void *xcalloc(size_t nmem, size_t size) { return ptr; } -static void *xrealloc(void *ptr, size_t size) { +static void *xrealloc(void *ctx, void *ptr, size_t size) { + (void)ctx; // explicitly discard void *new_ptr = realloc(ptr, size); if (!new_ptr) { fprintf(stderr, "[cmark] realloc returned null pointer, aborting\n"); @@ -28,7 +30,12 @@ static void *xrealloc(void *ptr, size_t size) { return new_ptr; } -cmark_mem DEFAULT_MEM_ALLOCATOR = {xcalloc, xrealloc, free}; +static void xfree(void *ctx, void *ptr) { + (void)ctx; // explicitly discard + free(ptr); +} + +cmark_mem DEFAULT_MEM_ALLOCATOR = {NULL, xcalloc, xrealloc, xfree}; cmark_mem *cmark_get_default_mem_allocator(void) { return &DEFAULT_MEM_ALLOCATOR; diff --git a/src/cmark.h b/src/cmark.h index 6626b0627..9e6639fcf 100644 --- a/src/cmark.h +++ b/src/cmark.h @@ -96,9 +96,10 @@ typedef struct cmark_iter cmark_iter; * when parsing and allocating a document tree */ typedef struct cmark_mem { - void *(*calloc)(size_t, size_t); - void *(*realloc)(void *, size_t); - void (*free)(void *); + void *ctx; + void *(*calloc)(void*, size_t, size_t); + void *(*realloc)(void*, void *, size_t); + void (*free)(void*, void *); } cmark_mem; /** Returns a pointer to the default memory allocator. diff --git a/src/inlines.c b/src/inlines.c index ab82ca74e..f3843dd76 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -86,7 +86,7 @@ static bufsize_t subject_find_special_char(subject *subj, int options); // Create an inline with a literal string value. static inline cmark_node *make_literal(subject *subj, cmark_node_type t, int start_column, int end_column) { - cmark_node *e = (cmark_node *)subj->mem->calloc(1, sizeof(*e)); + cmark_node *e = (cmark_node *)subj->mem->calloc(subj->mem->ctx, 1, sizeof(*e)); e->mem = subj->mem; e->type = (uint16_t)t; e->start_line = e->end_line = subj->line; @@ -98,7 +98,7 @@ static inline cmark_node *make_literal(subject *subj, cmark_node_type t, // Create an inline with no value. static inline cmark_node *make_simple(cmark_mem *mem, cmark_node_type t) { - cmark_node *e = (cmark_node *)mem->calloc(1, sizeof(*e)); + cmark_node *e = (cmark_node *)mem->calloc(mem->ctx, 1, sizeof(*e)); e->mem = mem; e->type = t; return e; @@ -106,7 +106,7 @@ static inline cmark_node *make_simple(cmark_mem *mem, cmark_node_type t) { static cmark_node *make_str(subject *subj, int sc, int ec, cmark_chunk s) { cmark_node *e = make_literal(subj, CMARK_NODE_TEXT, sc, ec); - e->data = (unsigned char *)subj->mem->realloc(NULL, s.len + 1); + e->data = (unsigned char *)subj->mem->realloc(subj->mem->ctx, NULL, s.len + 1); if (s.data != NULL) { memcpy(e->data, s.data, s.len); } @@ -161,7 +161,7 @@ static unsigned char *cmark_strdup(cmark_mem *mem, unsigned char *src) { return NULL; } size_t len = strlen((char *)src); - unsigned char *data = (unsigned char *)mem->realloc(NULL, len + 1); + unsigned char *data = (unsigned char *)mem->realloc(mem->ctx, NULL, len + 1); memcpy(data, src, len + 1); return data; } @@ -516,7 +516,7 @@ static void remove_delimiter(subject *subj, delimiter *delim) { if (delim->previous != NULL) { delim->previous->next = delim->next; } - subj->mem->free(delim); + subj->mem->free(subj->mem->ctx, delim); } static void pop_bracket(subject *subj) { @@ -525,12 +525,12 @@ static void pop_bracket(subject *subj) { return; b = subj->last_bracket; subj->last_bracket = subj->last_bracket->previous; - subj->mem->free(b); + subj->mem->free(subj->mem->ctx, b); } static void push_delimiter(subject *subj, unsigned char c, bool can_open, bool can_close, cmark_node *inl_text) { - delimiter *delim = (delimiter *)subj->mem->calloc(1, sizeof(delimiter)); + delimiter *delim = (delimiter *)subj->mem->calloc(subj->mem->ctx, 1, sizeof(delimiter)); delim->delim_char = c; delim->can_open = can_open; delim->can_close = can_close; @@ -546,7 +546,7 @@ static void push_delimiter(subject *subj, unsigned char c, bool can_open, } static void push_bracket(subject *subj, bool image, cmark_node *inl_text) { - bracket *b = (bracket *)subj->mem->calloc(1, sizeof(bracket)); + bracket *b = (bracket *)subj->mem->calloc(subj->mem->ctx, 1, sizeof(bracket)); if (subj->last_bracket != NULL) { subj->last_bracket->bracket_after = true; } @@ -992,7 +992,7 @@ static cmark_node *handle_pointy_brace(subject *subj, int options) { subj->pos += matchlen; cmark_node *node = make_literal(subj, CMARK_NODE_HTML_INLINE, subj->pos - matchlen - 1, subj->pos - 1); - node->data = (unsigned char *)subj->mem->realloc(NULL, len + 1); + node->data = (unsigned char *)subj->mem->realloc(subj->mem->ctx, NULL, len + 1); memcpy(node->data, src, len); node->data[len] = 0; node->len = len; diff --git a/src/iterator.c b/src/iterator.c index cc428285e..8e95ff257 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -17,7 +17,7 @@ cmark_iter *cmark_iter_new(cmark_node *root) { return NULL; } cmark_mem *mem = root->mem; - cmark_iter *iter = (cmark_iter *)mem->calloc(1, sizeof(cmark_iter)); + cmark_iter *iter = (cmark_iter *)mem->calloc(mem->ctx, 1, sizeof(cmark_iter)); iter->mem = mem; iter->root = root; iter->cur.ev_type = CMARK_EVENT_NONE; @@ -27,7 +27,7 @@ cmark_iter *cmark_iter_new(cmark_node *root) { return iter; } -void cmark_iter_free(cmark_iter *iter) { iter->mem->free(iter); } +void cmark_iter_free(cmark_iter *iter) { iter->mem->free(iter->mem->ctx, iter); } static bool S_is_leaf(cmark_node *node) { return ((1 << node->type) & S_leaf_mask) != 0; @@ -111,7 +111,7 @@ void cmark_consolidate_text_nodes(cmark_node *root) { cmark_node_free(tmp); tmp = next; } - iter->mem->free(cur->data); + iter->mem->free(iter->mem->ctx, cur->data); cur->len = buf.size; cur->data = cmark_strbuf_detach(&buf); } diff --git a/src/main.c b/src/main.c index 9a43cceda..a5427cac6 100644 --- a/src/main.c +++ b/src/main.c @@ -70,7 +70,7 @@ static void print_document(cmark_node *document, writer_format writer, exit(1); } fwrite(result, strlen(result), 1, stdout); - document->mem->free(result); + document->mem->free(document->mem->ctx, result); } int main(int argc, char *argv[]) { diff --git a/src/man.c b/src/man.c index 02dfb7cb3..4f5b14e22 100644 --- a/src/man.c +++ b/src/man.c @@ -116,7 +116,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node, case CMARK_NODE_ITEM: if (entering) { - new_block_number = allocator->calloc(1, sizeof(struct block_number)); + new_block_number = allocator->calloc(allocator->ctx, 1, sizeof(struct block_number)); new_block_number->number = 0; new_block_number->parent = renderer->block_number_in_list_item; renderer->block_number_in_list_item = new_block_number; @@ -145,7 +145,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node, new_block_number = renderer->block_number_in_list_item; renderer->block_number_in_list_item = renderer->block_number_in_list_item->parent; - allocator->free(new_block_number); + allocator->free(allocator->ctx, new_block_number); } CR(); } diff --git a/src/node.c b/src/node.c index c1492545e..af68deaca 100644 --- a/src/node.c +++ b/src/node.c @@ -88,7 +88,7 @@ static bool S_can_contain(cmark_node *node, cmark_node *child) { } cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) { - cmark_node *node = (cmark_node *)mem->calloc(1, sizeof(*node)); + cmark_node *node = (cmark_node *)mem->calloc(mem->ctx, 1, sizeof(*node)); node->mem = mem; node->type = (uint16_t)type; @@ -124,24 +124,24 @@ static void S_free_nodes(cmark_node *e) { while (e != NULL) { switch (e->type) { case CMARK_NODE_CODE_BLOCK: - mem->free(e->data); - mem->free(e->as.code.info); + mem->free(mem->ctx, e->data); + mem->free(mem->ctx, e->as.code.info); break; case CMARK_NODE_TEXT: case CMARK_NODE_HTML_INLINE: case CMARK_NODE_CODE: case CMARK_NODE_HTML_BLOCK: - mem->free(e->data); + mem->free(mem->ctx, e->data); break; case CMARK_NODE_LINK: case CMARK_NODE_IMAGE: - mem->free(e->as.link.url); - mem->free(e->as.link.title); + mem->free(mem->ctx, e->as.link.url); + mem->free(mem->ctx, e->as.link.title); break; case CMARK_NODE_CUSTOM_BLOCK: case CMARK_NODE_CUSTOM_INLINE: - mem->free(e->as.custom.on_enter); - mem->free(e->as.custom.on_exit); + mem->free(mem->ctx, e->as.custom.on_enter); + mem->free(mem->ctx, e->as.custom.on_exit); break; default: break; @@ -152,7 +152,7 @@ static void S_free_nodes(cmark_node *e) { e->next = e->first_child; } next = e->next; - mem->free(e); + mem->free(mem->ctx, e); e = next; } } @@ -271,14 +271,14 @@ static bufsize_t cmark_set_cstr(cmark_mem *mem, unsigned char **dst, if (src && src[0]) { len = (bufsize_t)strlen(src); - *dst = (unsigned char *)mem->realloc(NULL, len + 1); + *dst = (unsigned char *)mem->realloc(mem->ctx, NULL, len + 1); memcpy(*dst, src, len + 1); } else { len = 0; *dst = NULL; } if (old) { - mem->free(old); + mem->free(mem->ctx, old); } return len; diff --git a/src/references.c b/src/references.c index 96d793b70..fe64515db 100644 --- a/src/references.c +++ b/src/references.c @@ -8,10 +8,10 @@ static void reference_free(cmark_reference_map *map, cmark_reference *ref) { cmark_mem *mem = map->mem; if (ref != NULL) { - mem->free(ref->label); - mem->free(ref->url); - mem->free(ref->title); - mem->free(ref); + mem->free(mem->ctx, ref->label); + mem->free(mem->ctx, ref->url); + mem->free(mem->ctx, ref->title); + mem->free(mem->ctx, ref); } } @@ -37,7 +37,7 @@ static unsigned char *normalize_reference(cmark_mem *mem, cmark_chunk *ref) { assert(result); if (result[0] == '\0') { - mem->free(result); + mem->free(mem->ctx, result); return NULL; } @@ -55,7 +55,7 @@ void cmark_reference_create(cmark_reference_map *map, cmark_chunk *label, assert(map->sorted == NULL); - ref = (cmark_reference *)map->mem->calloc(1, sizeof(*ref)); + ref = (cmark_reference *)map->mem->calloc(map->mem->ctx, 1, sizeof(*ref)); ref->label = reflabel; ref->url = cmark_clean_url(map->mem, url); ref->title = cmark_clean_title(map->mem, title); @@ -94,7 +94,7 @@ static void sort_references(cmark_reference_map *map) { unsigned int i = 0, last = 0, size = map->size; cmark_reference *r = map->refs, **sorted = NULL; - sorted = (cmark_reference **)map->mem->calloc(size, sizeof(cmark_reference *)); + sorted = (cmark_reference **)map->mem->calloc(map->mem->ctx, size, sizeof(cmark_reference *)); while (r) { sorted[i++] = r; r = r->next; @@ -133,7 +133,7 @@ cmark_reference *cmark_reference_lookup(cmark_reference_map *map, ref = (cmark_reference **)bsearch(norm, map->sorted, map->size, sizeof(cmark_reference *), refsearch); - map->mem->free(norm); + map->mem->free(map->mem->ctx, norm); if (ref != NULL) { r = ref[0]; @@ -159,13 +159,13 @@ void cmark_reference_map_free(cmark_reference_map *map) { ref = next; } - map->mem->free(map->sorted); - map->mem->free(map); + map->mem->free(map->mem->ctx, map->sorted); + map->mem->free(map->mem->ctx, map); } cmark_reference_map *cmark_reference_map_new(cmark_mem *mem) { cmark_reference_map *map = - (cmark_reference_map *)mem->calloc(1, sizeof(cmark_reference_map)); + (cmark_reference_map *)mem->calloc(mem->ctx, 1, sizeof(cmark_reference_map)); map->mem = mem; return map; } diff --git a/src/render.c b/src/render.c index 0404deba1..7fe212a7e 100644 --- a/src/render.c +++ b/src/render.c @@ -116,7 +116,7 @@ static void S_out(cmark_renderer *renderer, const char *source, bool wrap, bufsize_t remainder_len = renderer->buffer->size - renderer->last_breakable - 1; unsigned char *remainder = - (unsigned char *)renderer->mem->realloc(NULL, remainder_len); + (unsigned char *)renderer->mem->realloc(renderer->mem->ctx, NULL, remainder_len); memcpy(remainder, src, remainder_len); // truncate at last_breakable cmark_strbuf_truncate(renderer->buffer, renderer->last_breakable); @@ -126,7 +126,7 @@ static void S_out(cmark_renderer *renderer, const char *source, bool wrap, renderer->prefix->size); cmark_strbuf_put(renderer->buffer, remainder, remainder_len); renderer->column = renderer->prefix->size + remainder_len; - renderer->mem->free(remainder); + renderer->mem->free(renderer->mem->ctx, remainder); renderer->last_breakable = 0; renderer->begin_line = false; renderer->begin_content = false; diff --git a/test/cmark.py b/test/cmark.py index f9200f346..d5e42bbfd 100644 --- a/test/cmark.py +++ b/test/cmark.py @@ -7,9 +7,10 @@ import os class cmark_mem(Structure): - _fields_ = [("calloc", c_void_p), + _fields_ = [("ctx", c_void_p), + ("calloc", c_void_p), ("realloc", c_void_p), - ("free", CFUNCTYPE(None, c_void_p))] + ("free", CFUNCTYPE(None, c_void_p, c_void_p))] def pipe_through_prog(prog, text): p1 = Popen(prog.split(), stdout=PIPE, stdin=PIPE, stderr=PIPE) @@ -30,7 +31,7 @@ def to_html(lib, text): # 1 << 17 == CMARK_OPT_UNSAFE cstring = markdown(textbytes, textlen, 1 << 17) result = string_at(cstring).decode('utf-8') - free_func(cstring) + free_func(None, cstring) return [0, result, ''] @@ -55,7 +56,7 @@ def to_commonmark(lib, text): node = parse_document(textbytes, textlen, 0) cstring = render_commonmark(node, 0, 0) result = string_at(cstring).decode('utf-8') - free_func(cstring) + free_func(None, cstring) free_node(node) return [0, result, ''] @@ -85,4 +86,3 @@ def __init__(self, prog=None, library_dir=None): cmark = CDLL(libpath) self.to_html = lambda x: to_html(cmark, x) self.to_commonmark = lambda x: to_commonmark(cmark, x) -