cmark

My personal build of CMark ✏️

Commit
27446657d2731d30190db9c240e326959bf43442
Parent
cf6af2267fb0ab617d537d7d8403a67d45bf878c
Author
John MacFarlane <jgm@berkeley.edu>
Date

Use non-recursive algorithm for process_inlines.

Closes #187.

Diffstat

1 file changed, 40 insertions, 13 deletions

Status File Name N° Changes Insertions Deletions
Modified src/blocks.c 53 40 13
diff --git 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;
 	}
 }