Skip to content

Commit e5a65e0

Browse files
committed
Add CMARK_NODE__LAST_LINE_CHECKED flag.
Use this to avoid unnecessary recursion in ends_with_blank_line. Closes commonmark#284.
1 parent b4138c5 commit e5a65e0

File tree

2 files changed

+18
-13
lines changed

2 files changed

+18
-13
lines changed

src/blocks.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ static bool S_last_line_blank(const cmark_node *node) {
3434
return (node->flags & CMARK_NODE__LAST_LINE_BLANK) != 0;
3535
}
3636

37+
static bool S_last_line_checked(const cmark_node *node) {
38+
return (node->flags & CMARK_NODE__LAST_LINE_CHECKED) != 0;
39+
}
40+
3741
static CMARK_INLINE cmark_node_type S_type(const cmark_node *node) {
3842
return (cmark_node_type)node->type;
3943
}
@@ -45,6 +49,10 @@ static void S_set_last_line_blank(cmark_node *node, bool is_blank) {
4549
node->flags &= ~CMARK_NODE__LAST_LINE_BLANK;
4650
}
4751

52+
static void S_set_last_line_checked(cmark_node *node) {
53+
node->flags |= CMARK_NODE__LAST_LINE_CHECKED;
54+
}
55+
4856
static CMARK_INLINE bool S_is_line_end_char(char c) {
4957
return (c == '\n' || c == '\r');
5058
}
@@ -208,20 +216,16 @@ static void remove_trailing_blank_lines(cmark_strbuf *ln) {
208216
// Check to see if a node ends with a blank line, descending
209217
// if needed into lists and sublists.
210218
static bool ends_with_blank_line(cmark_node *node) {
211-
cmark_node *cur = node;
212-
while (cur != NULL) {
213-
if (S_last_line_blank(cur)) {
214-
S_set_last_line_blank(node, true);
215-
return true;
216-
}
217-
if (S_type(cur) == CMARK_NODE_LIST || S_type(cur) == CMARK_NODE_ITEM) {
218-
cur = cur->last_child;
219-
} else {
220-
cur = NULL;
221-
}
219+
if (S_last_line_checked(node)) {
220+
return(S_last_line_blank(node));
221+
} else if ((S_type(node) == CMARK_NODE_LIST ||
222+
S_type(node) == CMARK_NODE_ITEM) && node->last_child) {
223+
S_set_last_line_checked(node);
224+
return(ends_with_blank_line(node->last_child));
225+
} else {
226+
S_set_last_line_checked(node);
227+
return (S_last_line_blank(node));
222228
}
223-
S_set_last_line_blank(node, false);
224-
return false;
225229
}
226230

227231
static cmark_node *finalize(cmark_parser *parser, cmark_node *b) {

src/node.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ typedef struct {
4949
enum cmark_node__internal_flags {
5050
CMARK_NODE__OPEN = (1 << 0),
5151
CMARK_NODE__LAST_LINE_BLANK = (1 << 1),
52+
CMARK_NODE__LAST_LINE_CHECKED = (1 << 2),
5253
};
5354

5455
struct cmark_node {

0 commit comments

Comments
 (0)