summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2020-01-19 13:46:10 +0100
committerJohn MacFarlane <jgm@berkeley.edu>2020-01-23 08:25:54 -0800
commitf3f50b29d615d2678d8047dc277b108cc5143167 (patch)
treeca3f01f6352d2cc2dd7cfc9c96508b800b8cc510
parent3ef0718f9f4c9dea5014a8a0e9a67e2366b9374f (diff)
Rearrange struct cmark_node
Introduce multi-purpose data/len members in struct cmark_node. This is mainly used to store literal text for inlines, code and HTML blocks. Move the content strbuf for blocks from cmark_node to cmark_parser. When finalizing nodes that allow inlines (paragraphs and headings), detach the strbuf and store the block content in the node's data/len members. Free the block content after processing inlines. Reduces size of struct cmark_node by 8 bytes.
-rw-r--r--src/blocks.c53
-rw-r--r--src/chunk.h65
-rw-r--r--src/commonmark.c2
-rw-r--r--src/html.c15
-rw-r--r--src/inlines.c62
-rw-r--r--src/iterator.c12
-rw-r--r--src/latex.c6
-rw-r--r--src/main.c2
-rw-r--r--src/node.c42
-rw-r--r--src/node.h16
-rw-r--r--src/parser.h1
-rw-r--r--src/render.c2
-rw-r--r--src/xml.c7
13 files changed, 111 insertions, 174 deletions
diff --git a/src/blocks.c b/src/blocks.c
index 9970cc9..df19752 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -72,7 +72,7 @@ static cmark_node *make_block(cmark_mem *mem, cmark_node_type tag,
cmark_node *e;
e = (cmark_node *)mem->calloc(1, sizeof(*e));
- cmark_strbuf_init(mem, &e->content, 32);
+ e->mem = mem;
e->type = (uint16_t)tag;
e->flags = CMARK_NODE__OPEN;
e->start_line = start_line;
@@ -96,6 +96,7 @@ cmark_parser *cmark_parser_new_with_mem(int options, cmark_mem *mem) {
cmark_strbuf_init(mem, &parser->curline, 256);
cmark_strbuf_init(mem, &parser->linebuf, 0);
+ cmark_strbuf_init(mem, &parser->content, 0);
parser->refmap = cmark_reference_map_new(mem);
parser->root = document;
@@ -171,19 +172,18 @@ static CMARK_INLINE bool contains_inlines(cmark_node_type block_type) {
block_type == CMARK_NODE_HEADING);
}
-static void add_line(cmark_node *node, cmark_chunk *ch, cmark_parser *parser) {
+static void add_line(cmark_chunk *ch, cmark_parser *parser) {
int chars_to_tab;
int i;
- assert(node->flags & CMARK_NODE__OPEN);
if (parser->partially_consumed_tab) {
parser->offset += 1; // skip over tab
// add space characters:
chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);
for (i = 0; i < chars_to_tab; i++) {
- cmark_strbuf_putc(&node->content, ' ');
+ cmark_strbuf_putc(&parser->content, ' ');
}
}
- cmark_strbuf_put(&node->content, ch->data + parser->offset,
+ cmark_strbuf_put(&parser->content, ch->data + parser->offset,
ch->len - parser->offset);
}
@@ -230,12 +230,10 @@ static bool S_ends_with_blank_line(cmark_node *node) {
}
// returns true if content remains after link defs are resolved.
-static bool resolve_reference_link_definitions(
- cmark_parser *parser,
- cmark_node *b) {
+static bool resolve_reference_link_definitions(cmark_parser *parser) {
bufsize_t pos;
- cmark_strbuf *node_content = &b->content;
- cmark_chunk chunk = {node_content->ptr, node_content->size, 0};
+ cmark_strbuf *node_content = &parser->content;
+ cmark_chunk chunk = {node_content->ptr, node_content->size};
while (chunk.len && chunk.data[0] == '[' &&
(pos = cmark_parse_reference_inline(parser->mem, &chunk,
parser->refmap))) {
@@ -244,7 +242,7 @@ static bool resolve_reference_link_definitions(
chunk.len -= pos;
}
cmark_strbuf_drop(node_content, (node_content->size - chunk.len));
- return !is_blank(&b->content, 0);
+ return !is_blank(node_content, 0);
}
static cmark_node *finalize(cmark_parser *parser, cmark_node *b) {
@@ -277,15 +275,18 @@ static cmark_node *finalize(cmark_parser *parser, cmark_node *b) {
b->end_column = parser->last_line_length;
}
- cmark_strbuf *node_content = &b->content;
+ cmark_strbuf *node_content = &parser->content;
switch (S_type(b)) {
case CMARK_NODE_PARAGRAPH:
{
- has_content = resolve_reference_link_definitions(parser, b);
+ has_content = resolve_reference_link_definitions(parser);
if (!has_content) {
// remove blank node (former reference def)
cmark_node_free(b);
+ } else {
+ b->len = node_content->size;
+ b->data = cmark_strbuf_detach(node_content);
}
break;
}
@@ -318,12 +319,14 @@ static cmark_node *finalize(cmark_parser *parser, cmark_node *b) {
pos += 1;
cmark_strbuf_drop(node_content, pos);
}
- b->as.code.literal = cmark_strbuf_detach(node_content);
+ b->len = node_content->size;
+ b->data = cmark_strbuf_detach(node_content);
break;
+ case CMARK_NODE_HEADING:
case CMARK_NODE_HTML_BLOCK:
- b->as.literal.len = node_content->size;
- b->as.literal.data = cmark_strbuf_detach(node_content);
+ b->len = node_content->size;
+ b->data = cmark_strbuf_detach(node_content);
break;
case CMARK_NODE_LIST: // determine tight/loose status
@@ -401,6 +404,9 @@ static void process_inlines(cmark_mem *mem, cmark_node *root,
if (ev_type == CMARK_EVENT_ENTER) {
if (contains_inlines(S_type(cur))) {
cmark_parse_inlines(mem, cur, refmap, options);
+ mem->free(cur->data);
+ cur->data = NULL;
+ cur->len = 0;
}
}
}
@@ -513,6 +519,8 @@ static cmark_node *finalize_document(cmark_parser *parser) {
finalize(parser, parser->root);
process_inlines(parser->mem, parser->root, parser->refmap, parser->options);
+ cmark_strbuf_free(&parser->content);
+
return parser->root;
}
@@ -996,7 +1004,7 @@ static void open_new_blocks(cmark_parser *parser, cmark_node **container,
(lev =
scan_setext_heading_line(input, parser->first_nonspace))) {
// finalize paragraph, resolving reference links
- has_content = resolve_reference_link_definitions(parser, *container);
+ has_content = resolve_reference_link_definitions(parser);
if (has_content) {
@@ -1136,7 +1144,7 @@ static void add_text_to_container(cmark_parser *parser, cmark_node *container,
if (parser->current != last_matched_container &&
container == last_matched_container && !parser->blank &&
S_type(parser->current) == CMARK_NODE_PARAGRAPH) {
- add_line(parser->current, input, parser);
+ add_line(input, parser);
} else { // not a lazy continuation
// Finalize any blocks that were not matched and set cur to container:
while (parser->current != last_matched_container) {
@@ -1145,9 +1153,9 @@ static void add_text_to_container(cmark_parser *parser, cmark_node *container,
}
if (S_type(container) == CMARK_NODE_CODE_BLOCK) {
- add_line(container, input, parser);
+ add_line(input, parser);
} else if (S_type(container) == CMARK_NODE_HTML_BLOCK) {
- add_line(container, input, parser);
+ add_line(input, parser);
int matches_end_condition;
switch (container->as.html_block_type) {
@@ -1194,14 +1202,14 @@ static void add_text_to_container(cmark_parser *parser, cmark_node *container,
}
S_advance_offset(parser, input, parser->first_nonspace - parser->offset,
false);
- add_line(container, input, parser);
+ add_line(input, parser);
} else {
// create paragraph container for line
container = add_child(parser, container, CMARK_NODE_PARAGRAPH,
parser->first_nonspace + 1);
S_advance_offset(parser, input, parser->first_nonspace - parser->offset,
false);
- add_line(container, input, parser);
+ add_line(input, parser);
}
parser->current = container;
@@ -1238,7 +1246,6 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
input.data = parser->curline.ptr;
input.len = parser->curline.size;
- input.alloc = 0;
parser->line_number++;
diff --git a/src/chunk.h b/src/chunk.h
index 6d1601d..1e93f66 100644
--- a/src/chunk.h
+++ b/src/chunk.h
@@ -9,26 +9,19 @@
#include "cmark_ctype.h"
#define CMARK_CHUNK_EMPTY \
- { NULL, 0, 0 }
+ { NULL, 0 }
typedef struct {
- unsigned char *data;
+ const unsigned char *data;
bufsize_t len;
- bufsize_t alloc; // also implies a NULL-terminated string
} cmark_chunk;
-static CMARK_INLINE void cmark_chunk_free(cmark_mem *mem, cmark_chunk *c) {
- if (c->alloc)
- mem->free(c->data);
-
+static CMARK_INLINE void cmark_chunk_free(cmark_chunk *c) {
c->data = NULL;
- c->alloc = 0;
c->len = 0;
}
static CMARK_INLINE void cmark_chunk_ltrim(cmark_chunk *c) {
- assert(!c->alloc);
-
while (c->len && cmark_isspace(c->data[0])) {
c->data++;
c->len--;
@@ -36,8 +29,6 @@ static CMARK_INLINE void cmark_chunk_ltrim(cmark_chunk *c) {
}
static CMARK_INLINE void cmark_chunk_rtrim(cmark_chunk *c) {
- assert(!c->alloc);
-
while (c->len > 0) {
if (!cmark_isspace(c->data[c->len - 1]))
break;
@@ -58,61 +49,15 @@ static CMARK_INLINE bufsize_t cmark_chunk_strchr(cmark_chunk *ch, int c,
return p ? (bufsize_t)(p - ch->data) : ch->len;
}
-static CMARK_INLINE const char *cmark_chunk_to_cstr(cmark_mem *mem,
- cmark_chunk *c) {
- unsigned char *str;
-
- if (c->alloc) {
- return (char *)c->data;
- }
- str = (unsigned char *)mem->calloc(c->len + 1, 1);
- if (c->len > 0) {
- memcpy(str, c->data, c->len);
- }
- str[c->len] = 0;
- c->data = str;
- c->alloc = 1;
-
- return (char *)str;
-}
-
-static CMARK_INLINE void cmark_chunk_set_cstr(cmark_mem *mem, cmark_chunk *c,
- const char *str) {
- unsigned char *old = c->alloc ? c->data : NULL;
- if (str == NULL) {
- c->len = 0;
- c->data = NULL;
- c->alloc = 0;
- } else {
- c->len = (bufsize_t)strlen(str);
- c->data = (unsigned char *)mem->calloc(c->len + 1, 1);
- c->alloc = 1;
- memcpy(c->data, str, c->len + 1);
- }
- if (old != NULL) {
- mem->free(old);
- }
-}
-
static CMARK_INLINE cmark_chunk cmark_chunk_literal(const char *data) {
bufsize_t len = data ? (bufsize_t)strlen(data) : 0;
- cmark_chunk c = {(unsigned char *)data, len, 0};
+ cmark_chunk c = {(unsigned char *)data, len};
return c;
}
static CMARK_INLINE cmark_chunk cmark_chunk_dup(const cmark_chunk *ch,
bufsize_t pos, bufsize_t len) {
- cmark_chunk c = {ch->data + pos, len, 0};
- return c;
-}
-
-static CMARK_INLINE cmark_chunk cmark_chunk_buf_detach(cmark_strbuf *buf) {
- cmark_chunk c;
-
- c.len = buf->size;
- c.data = cmark_strbuf_detach(buf);
- c.alloc = 1;
-
+ cmark_chunk c = {ch->data + pos, len};
return c;
}
diff --git a/src/commonmark.c b/src/commonmark.c
index 41bfa52..cc12bb4 100644
--- a/src/commonmark.c
+++ b/src/commonmark.c
@@ -146,7 +146,7 @@ static bool is_autolink(cmark_node *node) {
if (strcmp((const char *)url, "mailto:") == 0) {
url += 7;
}
- return strcmp((const char *)url, (char *)link_text->as.literal.data) == 0;
+ return strcmp((const char *)url, (char *)link_text->data) == 0;
}
// if node is a block node, returns node.
diff --git a/src/html.c b/src/html.c
index f3f4cd1..c69ffb6 100644
--- a/src/html.c
+++ b/src/html.c
@@ -61,7 +61,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
case CMARK_NODE_TEXT:
case CMARK_NODE_CODE:
case CMARK_NODE_HTML_INLINE:
- escape_html(html, node->as.literal.data, node->as.literal.len);
+ escape_html(html, node->data, node->len);
break;
case CMARK_NODE_LINEBREAK:
@@ -164,8 +164,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
cmark_strbuf_puts(html, "\">");
}
- escape_html(html, node->as.code.literal,
- strlen((char *)node->as.code.literal));
+ escape_html(html, node->data, node->len);
cmark_strbuf_puts(html, "</code></pre>\n");
break;
@@ -174,7 +173,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
if (!(options & CMARK_OPT_UNSAFE)) {
cmark_strbuf_puts(html, "<!-- raw HTML omitted -->");
} else {
- cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);
+ cmark_strbuf_put(html, node->data, node->len);
}
cr(html);
break;
@@ -218,7 +217,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
break;
case CMARK_NODE_TEXT:
- escape_html(html, node->as.literal.data, node->as.literal.len);
+ escape_html(html, node->data, node->len);
break;
case CMARK_NODE_LINEBREAK:
@@ -237,7 +236,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
case CMARK_NODE_CODE:
cmark_strbuf_puts(html, "<code>");
- escape_html(html, node->as.literal.data, node->as.literal.len);
+ escape_html(html, node->data, node->len);
cmark_strbuf_puts(html, "</code>");
break;
@@ -245,7 +244,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
if (!(options & CMARK_OPT_UNSAFE)) {
cmark_strbuf_puts(html, "<!-- raw HTML omitted -->");
} else {
- cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);
+ cmark_strbuf_put(html, node->data, node->len);
}
break;
@@ -325,7 +324,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
char *cmark_render_html(cmark_node *root, int options) {
char *result;
- cmark_strbuf html = CMARK_BUF_INIT(cmark_node_mem(root));
+ cmark_strbuf html = CMARK_BUF_INIT(root->mem);
cmark_event_type ev_type;
cmark_node *cur;
struct render_state state = {&html, NULL};
diff --git a/src/inlines.c b/src/inlines.c
index 2c13546..15290a0 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -80,7 +80,7 @@ static bufsize_t subject_find_special_char(subject *subj, int options);
static CMARK_INLINE cmark_node *make_literal(subject *subj, cmark_node_type t,
int start_column, int end_column) {
cmark_node *e = (cmark_node *)subj->mem->calloc(1, sizeof(*e));
- cmark_strbuf_init(subj->mem, &e->content, 0);
+ e->mem = subj->mem;
e->type = (uint16_t)t;
e->start_line = e->end_line = subj->line;
// columns are 1 based.
@@ -92,25 +92,25 @@ static CMARK_INLINE cmark_node *make_literal(subject *subj, cmark_node_type t,
// Create an inline with no value.
static CMARK_INLINE cmark_node *make_simple(cmark_mem *mem, cmark_node_type t) {
cmark_node *e = (cmark_node *)mem->calloc(1, sizeof(*e));
- cmark_strbuf_init(mem, &e->content, 0);
+ e->mem = mem;
e->type = t;
return e;
}
static cmark_node *make_str(subject *subj, int sc, int ec, cmark_chunk s) {
cmark_node *e = make_literal(subj, CMARK_NODE_TEXT, sc, ec);
- e->as.literal.data = (unsigned char *)subj->mem->realloc(NULL, s.len + 1);
- memcpy(e->as.literal.data, s.data, s.len);
- e->as.literal.data[s.len] = 0;
- e->as.literal.len = s.len;
+ e->data = (unsigned char *)subj->mem->realloc(NULL, s.len + 1);
+ memcpy(e->data, s.data, s.len);
+ e->data[s.len] = 0;
+ e->len = s.len;
return e;
}
static cmark_node *make_str_from_buf(subject *subj, int sc, int ec,
cmark_strbuf *buf) {
cmark_node *e = make_literal(subj, CMARK_NODE_TEXT, sc, ec);
- e->as.literal.len = buf->size;
- e->as.literal.data = cmark_strbuf_detach(buf);
+ e->len = buf->size;
+ e->data = cmark_strbuf_detach(buf);
return e;
}
@@ -382,8 +382,8 @@ static cmark_node *handle_backticks(subject *subj, int options) {
cmark_node *node = make_literal(subj, CMARK_NODE_CODE, startpos,
endpos - openticks.len - 1);
- node->as.literal.len = buf.size;
- node->as.literal.data = cmark_strbuf_detach(&buf);
+ node->len = buf.size;
+ node->data = cmark_strbuf_detach(&buf);
adjust_subj_node_newlines(subj, node, endpos - startpos, openticks.len, options);
return node;
}
@@ -503,7 +503,7 @@ static void push_delimiter(subject *subj, unsigned char c, bool can_open,
delim->can_open = can_open;
delim->can_close = can_close;
delim->inl_text = inl_text;
- delim->length = inl_text->as.literal.len;
+ delim->length = inl_text->len;
delim->previous = subj->last_delim;
delim->next = NULL;
if (delim->previous != NULL) {
@@ -709,8 +709,8 @@ static delimiter *S_insert_emph(subject *subj, delimiter *opener,
bufsize_t use_delims;
cmark_node *opener_inl = opener->inl_text;
cmark_node *closer_inl = closer->inl_text;
- bufsize_t opener_num_chars = opener_inl->as.literal.len;
- bufsize_t closer_num_chars = closer_inl->as.literal.len;
+ bufsize_t opener_num_chars = opener_inl->len;
+ bufsize_t closer_num_chars = closer_inl->len;
cmark_node *tmp, *tmpnext, *emph;
// calculate the actual number of characters used from this closer
@@ -719,10 +719,10 @@ static delimiter *S_insert_emph(subject *subj, delimiter *opener,
// remove used characters from associated inlines.
opener_num_chars -= use_delims;
closer_num_chars -= use_delims;
- opener_inl->as.literal.len = opener_num_chars;
- opener_inl->as.literal.data[opener_num_chars] = 0;
- closer_inl->as.literal.len = closer_num_chars;
- closer_inl->as.literal.data[closer_num_chars] = 0;
+ opener_inl->len = opener_num_chars;
+ opener_inl->data[opener_num_chars] = 0;
+ closer_inl->len = closer_num_chars;
+ closer_inl->data[closer_num_chars] = 0;
// free delimiters between opener and closer
delim = closer->previous;
@@ -866,15 +866,15 @@ static cmark_node *handle_pointy_brace(subject *subj, int options) {
// finally, try to match an html tag
matchlen = scan_html_tag(&subj->input, subj->pos);
if (matchlen > 0) {
- unsigned char *src = subj->input.data + subj->pos - 1;
+ const unsigned char *src = subj->input.data + subj->pos - 1;
bufsize_t len = matchlen + 1;
subj->pos += matchlen;
cmark_node *node = make_literal(subj, CMARK_NODE_HTML_INLINE,
subj->pos - matchlen - 1, subj->pos - 1);
- node->as.literal.data = (unsigned char *)subj->mem->realloc(NULL, len + 1);
- memcpy(node->as.literal.data, src, len);
- node->as.literal.data[len] = 0;
- node->as.literal.len = len;
+ node->data = (unsigned char *)subj->mem->realloc(NULL, len + 1);
+ memcpy(node->data, src, len);
+ node->data[len] = 0;
+ node->len = len;
adjust_subj_node_newlines(subj, node, matchlen, 1, options);
return node;
}
@@ -963,7 +963,7 @@ static bufsize_t manual_scan_link_url_2(cmark_chunk *input, bufsize_t offset,
return -1;
{
- cmark_chunk result = {input->data + offset, i - offset, 0};
+ cmark_chunk result = {input->data + offset, i - offset};
*output = result;
}
return i - offset;
@@ -994,7 +994,7 @@ static bufsize_t manual_scan_link_url(cmark_chunk *input, bufsize_t offset,
return -1;
{
- cmark_chunk result = {input->data + offset + 1, i - 2 - offset, 0};
+ cmark_chunk result = {input->data + offset + 1, i - 2 - offset};
*output = result;
}
return i - offset;
@@ -1061,8 +1061,8 @@ static cmark_node *handle_close_bracket(subject *subj) {
cmark_chunk_dup(&subj->input, starttitle, endtitle - starttitle);
url = cmark_clean_url(subj->mem, &url_chunk);
title = cmark_clean_title(subj->mem, &title_chunk);
- cmark_chunk_free(subj->mem, &url_chunk);
- cmark_chunk_free(subj->mem, &title_chunk);
+ cmark_chunk_free(&url_chunk);
+ cmark_chunk_free(&title_chunk);
goto match;
} else {
@@ -1082,7 +1082,7 @@ static cmark_node *handle_close_bracket(subject *subj) {
}
if ((!found_label || raw_label.len == 0) && !opener->bracket_after) {
- cmark_chunk_free(subj->mem, &raw_label);
+ cmark_chunk_free(&raw_label);
raw_label = cmark_chunk_dup(&subj->input, opener->position,
initial_pos - opener->position - 1);
found_label = true;
@@ -1090,7 +1090,7 @@ static cmark_node *handle_close_bracket(subject *subj) {
if (found_label) {
ref = cmark_reference_lookup(subj->refmap, &raw_label);
- cmark_chunk_free(subj->mem, &raw_label);
+ cmark_chunk_free(&raw_label);
}
if (ref != NULL) { // found
@@ -1294,10 +1294,10 @@ static int parse_inline(subject *subj, cmark_node *parent, int options) {
}
// Parse inlines from parent's string_content, adding as children of parent.
-extern void cmark_parse_inlines(cmark_mem *mem, cmark_node *parent,
- cmark_reference_map *refmap, int options) {
+void cmark_parse_inlines(cmark_mem *mem, cmark_node *parent,
+ cmark_reference_map *refmap, int options) {
subject subj;
- cmark_chunk content = {parent->content.ptr, parent->content.size, 0};
+ cmark_chunk content = {parent->data, parent->len};
subject_from_buf(mem, parent->start_line, parent->start_column - 1 + parent->internal_offset, &subj, &content, refmap);
cmark_chunk_rtrim(&subj.input);
diff --git a/src/iterator.c b/src/iterator.c
index cd7db8e..63cbf9e 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -16,7 +16,7 @@ cmark_iter *cmark_iter_new(cmark_node *root) {
if (root == NULL) {
return NULL;
}
- cmark_mem *mem = root->content.mem;
+ cmark_mem *mem = root->mem;
cmark_iter *iter = (cmark_iter *)mem->calloc(1, sizeof(cmark_iter));
iter->mem = mem;
iter->root = root;
@@ -101,19 +101,19 @@ void cmark_consolidate_text_nodes(cmark_node *root) {
if (ev_type == CMARK_EVENT_ENTER && cur->type == CMARK_NODE_TEXT &&
cur->next && cur->next->type == CMARK_NODE_TEXT) {
cmark_strbuf_clear(&buf);
- cmark_strbuf_put(&buf, cur->as.literal.data, cur->as.literal.len);
+ cmark_strbuf_put(&buf, cur->data, cur->len);
tmp = cur->next;
while (tmp && tmp->type == CMARK_NODE_TEXT) {
cmark_iter_next(iter); // advance pointer
- cmark_strbuf_put(&buf, tmp->as.literal.data, tmp->as.literal.len);
+ cmark_strbuf_put(&buf, tmp->data, tmp->len);
cur->end_column = tmp->end_column;
next = tmp->next;
cmark_node_free(tmp);
tmp = next;
}
- iter->mem->free(cur->as.literal.data);
- cur->as.literal.len = buf.size;
- cur->as.literal.data = cmark_strbuf_detach(&buf);
+ iter->mem->free(cur->data);
+ cur->len = buf.size;
+ cur->data = cmark_strbuf_detach(&buf);
}
}
diff --git a/src/latex.c b/src/latex.c
index 0d9517d..1d4d7bc 100644
--- a/src/latex.c
+++ b/src/latex.c
@@ -190,9 +190,9 @@ static link_type get_link_type(cmark_node *node) {
realurllen -= 7;
isemail = true;
}
- if (realurllen == link_text->as.literal.len &&
- strncmp(realurl, (char *)link_text->as.literal.data,
- link_text->as.literal.len) == 0) {
+ if (realurllen == link_text->len &&
+ strncmp(realurl, (char *)link_text->data,
+ link_text->len) == 0) {
if (isemail) {
return EMAIL_AUTOLINK;
} else {
diff --git a/src/main.c b/src/main.c
index 8454c79..6162704 100644
--- a/src/main.c
+++ b/src/main.c
@@ -69,7 +69,7 @@ static void print_document(cmark_node *document, writer_format writer,
exit(1);
}
printf("%s", result);
- cmark_node_mem(document)->free(result);
+ document->mem->free(result);
}
int main(int argc, char *argv[]) {
diff --git a/src/node.c b/src/node.c
index fd6526c..ea09c30 100644
--- a/src/node.c
+++ b/src/node.c
@@ -6,8 +6,6 @@
static void S_node_unlink(cmark_node *node);
-#define NODE_MEM(node) cmark_node_mem(node)
-
static CMARK_INLINE bool S_is_block(cmark_node *node) {
if (node == NULL) {
return false;
@@ -74,7 +72,7 @@ static bool S_can_contain(cmark_node *node, cmark_node *child) {
cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) {
cmark_node *node = (cmark_node *)mem->calloc(1, sizeof(*node));
- cmark_strbuf_init(mem, &node->content, 0);
+ node->mem = mem;
node->type = (uint16_t)type;
switch (node->type) {
@@ -104,29 +102,29 @@ cmark_node *cmark_node_new(cmark_node_type type) {
// Free a cmark_node list and any children.
static void S_free_nodes(cmark_node *e) {
+ cmark_mem *mem = e->mem;
cmark_node *next;
while (e != NULL) {
- cmark_strbuf_free(&e->content);
switch (e->type) {
case CMARK_NODE_CODE_BLOCK:
- NODE_MEM(e)->free(e->as.code.info);
- NODE_MEM(e)->free(e->as.code.literal);
+ mem->free(e->data);
+ mem->free(e->as.code.info);
break;
case CMARK_NODE_TEXT:
case CMARK_NODE_HTML_INLINE:
case CMARK_NODE_CODE:
case CMARK_NODE_HTML_BLOCK:
- NODE_MEM(e)->free(e->as.literal.data);
+ mem->free(e->data);
break;
case CMARK_NODE_LINK:
case CMARK_NODE_IMAGE:
- NODE_MEM(e)->free(e->as.link.url);
- NODE_MEM(e)->free(e->as.link.title);
+ mem->free(e->as.link.url);
+ mem->free(e->as.link.title);
break;
case CMARK_NODE_CUSTOM_BLOCK:
case CMARK_NODE_CUSTOM_INLINE:
- NODE_MEM(e)->free(e->as.custom.on_enter);
- NODE_MEM(e)->free(e->as.custom.on_exit);
+ mem->free(e->as.custom.on_enter);
+ mem->free(e->as.custom.on_exit);
break;
default:
break;
@@ -137,7 +135,7 @@ static void S_free_nodes(cmark_node *e) {
e->next = e->first_child;
}
next = e->next;
- NODE_MEM(e)->free(e);
+ mem->free(e);
e = next;
}
}
@@ -295,10 +293,8 @@ const char *cmark_node_get_literal(cmark_node *node) {
case CMARK_NODE_TEXT:
case CMARK_NODE_HTML_INLINE:
case CMARK_NODE_CODE:
- return node->as.literal.data ? (char *)node->as.literal.data : "";
-
case CMARK_NODE_CODE_BLOCK:
- return (char *)node->as.code.literal;
+ return node->data ? (char *)node->data : "";
default:
break;
@@ -317,12 +313,8 @@ int cmark_node_set_literal(cmark_node *node, const char *content) {
case CMARK_NODE_TEXT:
case CMARK_NODE_HTML_INLINE:
case CMARK_NODE_CODE:
- node->as.literal.len = cmark_set_cstr(NODE_MEM(node),
- &node->as.literal.data, content);
- return 1;
-
case CMARK_NODE_CODE_BLOCK:
- cmark_set_cstr(NODE_MEM(node), &node->as.code.literal, content);
+ node->len = cmark_set_cstr(node->mem, &node->data, content);
return 1;
default:
@@ -491,7 +483,7 @@ int cmark_node_set_fence_info(cmark_node *node, const char *info) {
}
if (node->type == CMARK_NODE_CODE_BLOCK) {
- cmark_set_cstr(NODE_MEM(node), &node->as.code.info, info);
+ cmark_set_cstr(node->mem, &node->as.code.info, info);
return 1;
} else {
return 0;
@@ -522,7 +514,7 @@ int cmark_node_set_url(cmark_node *node, const char *url) {
switch (node->type) {
case CMARK_NODE_LINK:
case CMARK_NODE_IMAGE:
- cmark_set_cstr(NODE_MEM(node), &node->as.link.url, url);
+ cmark_set_cstr(node->mem, &node->as.link.url, url);
return 1;
default:
break;
@@ -555,7 +547,7 @@ int cmark_node_set_title(cmark_node *node, const char *title) {
switch (node->type) {
case CMARK_NODE_LINK:
case CMARK_NODE_IMAGE:
- cmark_set_cstr(NODE_MEM(node), &node->as.link.title, title);
+ cmark_set_cstr(node->mem, &node->as.link.title, title);
return 1;
default:
break;
@@ -588,7 +580,7 @@ int cmark_node_set_on_enter(cmark_node *node, const char *on_enter) {
switch (node->type) {
case CMARK_NODE_CUSTOM_INLINE:
case CMARK_NODE_CUSTOM_BLOCK:
- cmark_set_cstr(NODE_MEM(node), &node->as.custom.on_enter, on_enter);
+ cmark_set_cstr(node->mem, &node->as.custom.on_enter, on_enter);
return 1;
default:
break;
@@ -621,7 +613,7 @@ int cmark_node_set_on_exit(cmark_node *node, const char *on_exit) {
switch (node->type) {
case CMARK_NODE_CUSTOM_INLINE:
case CMARK_NODE_CUSTOM_BLOCK:
- cmark_set_cstr(NODE_MEM(node), &node->as.custom.on_exit, on_exit);
+ cmark_set_cstr(node->mem, &node->as.custom.on_exit, on_exit);
return 1;
default:
break;
diff --git a/src/node.h b/src/node.h
index ee0ff41..6bf6677 100644
--- a/src/node.h
+++ b/src/node.h
@@ -8,15 +8,11 @@ extern "C" {
#include <stdio.h>
#include <stdint.h>
+#include "config.h"
#include "cmark.h"
#include "buffer.h"
typedef struct {
- unsigned char *data;
- bufsize_t len;
-} cmark_literal;
-
-typedef struct {
int marker_offset;
int padding;
int start;
@@ -28,7 +24,6 @@ typedef struct {
typedef struct {
unsigned char *info;
- unsigned char *literal;
uint8_t fence_length;
uint8_t fence_offset;
unsigned char fence_char;
@@ -57,7 +52,7 @@ enum cmark_node__internal_flags {
};
struct cmark_node {
- cmark_strbuf content;
+ cmark_mem *mem;
struct cmark_node *next;
struct cmark_node *prev;
@@ -67,6 +62,9 @@ struct cmark_node {
void *user_data;
+ unsigned char *data;
+ bufsize_t len;
+
int start_line;
int start_column;
int end_line;
@@ -76,7 +74,6 @@ struct cmark_node {
uint16_t flags;
union {
- cmark_literal literal;
cmark_list list;
cmark_code code;
cmark_heading heading;
@@ -86,9 +83,6 @@ struct cmark_node {
} as;
};
-static CMARK_INLINE cmark_mem *cmark_node_mem(cmark_node *node) {
- return node->content.mem;
-}
CMARK_EXPORT int cmark_node_check(cmark_node *node, FILE *out);
#ifdef __cplusplus
diff --git a/src/parser.h b/src/parser.h
index f41f099..8f6c694 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -29,6 +29,7 @@ struct cmark_parser {
cmark_strbuf curline;
bufsize_t last_line_length;
cmark_strbuf linebuf;
+ cmark_strbuf content;
int options;
bool last_buffer_ended_with_cr;
};
diff --git a/src/render.c b/src/render.c
index c076e17..dfdd855 100644
--- a/src/render.c
+++ b/src/render.c
@@ -154,7 +154,7 @@ char *cmark_render(cmark_node *root, int options, int width,
int (*render_node)(cmark_renderer *renderer,
cmark_node *node,
cmark_event_type ev_type, int options)) {
- cmark_mem *mem = cmark_node_mem(root);
+ cmark_mem *mem = root->mem;
cmark_strbuf pref = CMARK_BUF_INIT(mem);
cmark_strbuf buf = CMARK_BUF_INIT(mem);
cmark_node *cur;
diff --git a/src/xml.c b/src/xml.c
index 48b4e91..9306141 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -61,7 +61,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
case CMARK_NODE_HTML_BLOCK:
case CMARK_NODE_HTML_INLINE:
cmark_strbuf_puts(xml, " xml:space=\"preserve\">");
- escape_xml(xml, node->as.literal.data, node->as.literal.len);
+ escape_xml(xml, node->data, node->len);
cmark_strbuf_puts(xml, "</");
cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
literal = true;
@@ -101,8 +101,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
cmark_strbuf_putc(xml, '"');
}
cmark_strbuf_puts(xml, " xml:space=\"preserve\">");
- escape_xml(xml, node->as.code.literal,
- strlen((char *)node->as.code.literal));
+ escape_xml(xml, node->data, node->len);
cmark_strbuf_puts(xml, "</");
cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
literal = true;
@@ -153,7 +152,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
char *cmark_render_xml(cmark_node *root, int options) {
char *result;
- cmark_strbuf xml = CMARK_BUF_INIT(cmark_node_mem(root));
+ cmark_strbuf xml = CMARK_BUF_INIT(root->mem);
cmark_event_type ev_type;
cmark_node *cur;
struct render_state state = {&xml, 0};