From 90c48e849440e50b3fef21f0cd6c38b998490073 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Wed, 5 Nov 2014 09:49:05 -0800 Subject: free_inlines: use non-recursive algorithm. This will help avoid stack overflows in deeply nested structures. Partially addresses #187 (still need to do renderers). --- src/inlines.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'src/inlines.c') diff --git a/src/inlines.c b/src/inlines.c index 2fe0caa..1ab1b29 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -121,10 +121,29 @@ inline static node_inl* make_simple(int t) #define make_emph(contents) make_inlines(INL_EMPH, contents) #define make_strong(contents) make_inlines(INL_STRONG, contents) -// Free an inline list. +// Utility function used by free_inlines +void splice_into_list(node_inl* e, node_inl* children) { + node_inl * tmp; + tmp = children; + if (!tmp) { + return ; + } + // Find last child + while (tmp->next) { + tmp = tmp->next; + } + // Splice children into list + tmp->next = e->next; + e->next = children; + return ; +} + +// Free an inline list. Avoid recursion to prevent stack overflows +// on deeply nested structures. extern void free_inlines(node_inl* e) { node_inl * next; + while (e != NULL) { switch (e->tag){ case INL_STRING: @@ -139,11 +158,11 @@ extern void free_inlines(node_inl* e) case INL_IMAGE: free(e->content.linkable.url); free(e->content.linkable.title); - free_inlines(e->content.linkable.label); + splice_into_list(e, e->content.linkable.label); break; case INL_EMPH: case INL_STRONG: - free_inlines(e->content.inlines); + splice_into_list(e, e->content.inlines); break; default: break; -- cgit v1.2.3