From b34af68668c514b73102acc4c32e7bd6ac5a8301 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Wed, 21 Jan 2015 17:19:05 -0800 Subject: Avoid trying to free string_contents for inlines. This avoids an unnecessary free(0) -- and perhaps free(???). However, ltrace reveals that there is still a free(0) happening, with some other source. --- src/node.c | 138 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 70 insertions(+), 68 deletions(-) (limited to 'src/node.c') diff --git a/src/node.c b/src/node.c index 675eb19..9cdfbe9 100644 --- a/src/node.c +++ b/src/node.c @@ -7,6 +7,73 @@ static void S_node_unlink(cmark_node *node); +static inline bool +S_is_block(cmark_node *node) +{ + if (node == NULL) { + return false; + } + return node->type >= CMARK_NODE_FIRST_BLOCK + && node->type <= CMARK_NODE_LAST_BLOCK; +} + +static inline bool +S_is_inline(cmark_node *node) +{ + if (node == NULL) { + return false; + } + return node->type >= CMARK_NODE_FIRST_INLINE + && node->type <= CMARK_NODE_LAST_INLINE; +} + +static bool +S_can_contain(cmark_node *node, cmark_node *child) +{ + cmark_node *cur; + + if (node == NULL || child == NULL) { + return false; + } + + // Verify that child is not an ancestor of node or equal to node. + cur = node; + do { + if (cur == child) { + return false; + } + cur = cur->parent; + } while (cur != NULL); + + if (child->type == CMARK_NODE_DOCUMENT) { + return false; + } + + switch (node->type) { + case CMARK_NODE_DOCUMENT: + case CMARK_NODE_BLOCK_QUOTE: + case CMARK_NODE_ITEM: + return S_is_block(child) + && child->type != CMARK_NODE_ITEM; + + case CMARK_NODE_LIST: + return child->type == CMARK_NODE_ITEM; + + case CMARK_NODE_PARAGRAPH: + case CMARK_NODE_HEADER: + case CMARK_NODE_EMPH: + case CMARK_NODE_STRONG: + case CMARK_NODE_LINK: + case CMARK_NODE_IMAGE: + return S_is_inline(child); + + default: + break; + } + + return false; +} + cmark_node* cmark_node_new(cmark_node_type type) { @@ -39,7 +106,9 @@ void S_free_nodes(cmark_node *e) { cmark_node *next; while (e != NULL) { - cmark_strbuf_free(&e->string_content); + if (S_is_block(e)) { + cmark_strbuf_free(&e->string_content); + } switch (e->type) { case NODE_CODE_BLOCK: cmark_chunk_free(&e->as.code.info); @@ -568,73 +637,6 @@ cmark_node_get_end_column(cmark_node *node) return node->end_column; } -static inline bool -S_is_block(cmark_node *node) -{ - if (node == NULL) { - return false; - } - return node->type >= CMARK_NODE_FIRST_BLOCK - && node->type <= CMARK_NODE_LAST_BLOCK; -} - -static inline bool -S_is_inline(cmark_node *node) -{ - if (node == NULL) { - return false; - } - return node->type >= CMARK_NODE_FIRST_INLINE - && node->type <= CMARK_NODE_LAST_INLINE; -} - -static bool -S_can_contain(cmark_node *node, cmark_node *child) -{ - cmark_node *cur; - - if (node == NULL || child == NULL) { - return false; - } - - // Verify that child is not an ancestor of node or equal to node. - cur = node; - do { - if (cur == child) { - return false; - } - cur = cur->parent; - } while (cur != NULL); - - if (child->type == CMARK_NODE_DOCUMENT) { - return false; - } - - switch (node->type) { - case CMARK_NODE_DOCUMENT: - case CMARK_NODE_BLOCK_QUOTE: - case CMARK_NODE_ITEM: - return S_is_block(child) - && child->type != CMARK_NODE_ITEM; - - case CMARK_NODE_LIST: - return child->type == CMARK_NODE_ITEM; - - case CMARK_NODE_PARAGRAPH: - case CMARK_NODE_HEADER: - case CMARK_NODE_EMPH: - case CMARK_NODE_STRONG: - case CMARK_NODE_LINK: - case CMARK_NODE_IMAGE: - return S_is_inline(child); - - default: - break; - } - - return false; -} - // Unlink a node without adjusting its next, prev, and parent pointers. static void S_node_unlink(cmark_node *node) -- cgit v1.2.3