aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2015-01-21 17:19:05 -0800
committerJohn MacFarlane <jgm@berkeley.edu>2015-01-21 17:19:05 -0800
commitb34af68668c514b73102acc4c32e7bd6ac5a8301 (patch)
tree64ca2a6e7bced68354ccc9924eb74615ba703993
parentc737934e286710a2b8094c6255eee98102eed57a (diff)
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.
-rw-r--r--src/node.c138
1 files changed, 70 insertions, 68 deletions
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)