summaryrefslogtreecommitdiff
path: root/src/blocks.c
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2014-11-06 21:16:08 -0800
committerJohn MacFarlane <jgm@berkeley.edu>2014-11-06 21:16:24 -0800
commit27446657d2731d30190db9c240e326959bf43442 (patch)
tree8f0c29a57a17bf0cbbce35f1d6f7716acd5134a0 /src/blocks.c
parentcf6af2267fb0ab617d537d7d8403a67d45bf878c (diff)
Use non-recursive algorithm for process_inlines.
Closes #187.
Diffstat (limited to 'src/blocks.c')
-rw-r--r--src/blocks.c53
1 files changed, 40 insertions, 13 deletions
diff --git a/src/blocks.c b/src/blocks.c
index b30bae3..ccb84a7 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -276,25 +276,52 @@ void cmark_free_nodes(node_block *e)
}
}
+typedef struct BlockStack {
+ struct BlockStack *previous;
+ node_block *next_sibling;
+} block_stack;
+
// Walk through node_block and all children, recursively, parsing
// string content into inline content where appropriate.
void process_inlines(node_block* cur, reference_map *refmap)
{
- switch (cur->tag) {
- case BLOCK_PARAGRAPH:
- case BLOCK_ATX_HEADER:
- case BLOCK_SETEXT_HEADER:
- cur->inline_content = parse_inlines(&cur->string_content, refmap);
- break;
+ block_stack* stack = NULL;
+ block_stack* newstack = NULL;
+
+ while (cur != NULL) {
+ switch (cur->tag) {
+ case BLOCK_PARAGRAPH:
+ case BLOCK_ATX_HEADER:
+ case BLOCK_SETEXT_HEADER:
+ cur->inline_content = parse_inlines(&cur->string_content, refmap);
+ break;
- default:
- break;
- }
+ default:
+ break;
+ }
- node_block *child = cur->children;
- while (child != NULL) {
- process_inlines(child, refmap);
- child = child->next;
+ if (cur->children) {
+ newstack = (block_stack*)malloc(sizeof(block_stack));
+ if (newstack == NULL) return;
+ newstack->previous = stack;
+ stack = newstack;
+ stack->next_sibling = cur->next;
+ cur = cur->children;
+ } else {
+ cur = cur->next;
+ }
+
+ while (cur == NULL && stack != NULL) {
+ cur = stack->next_sibling;
+ newstack = stack->previous;
+ free(stack);
+ stack = newstack;
+ }
+ }
+ while (stack != NULL) {
+ newstack = stack->previous;
+ free(stack);
+ stack = newstack;
}
}