From f3f50b29d615d2678d8047dc277b108cc5143167 Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Sun, 19 Jan 2020 13:46:10 +0100 Subject: 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. --- src/blocks.c | 53 +++++++++++++++++++++++++-------------------- src/chunk.h | 65 +++++--------------------------------------------------- src/commonmark.c | 2 +- src/html.c | 15 ++++++------- src/inlines.c | 62 ++++++++++++++++++++++++++--------------------------- src/iterator.c | 12 +++++------ src/latex.c | 6 +++--- src/main.c | 2 +- src/node.c | 42 +++++++++++++++--------------------- src/node.h | 16 +++++--------- src/parser.h | 1 + src/render.c | 2 +- src/xml.c | 7 +++--- 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, "\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, ""); } 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, ""); - escape_html(html, node->as.literal.data, node->as.literal.len); + escape_html(html, node->data, node->len); cmark_strbuf_puts(html, ""); 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, ""); } 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,14 +8,10 @@ extern "C" { #include #include +#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; @@ -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, ""); - escape_xml(xml, node->as.code.literal, - strlen((char *)node->as.code.literal)); + escape_xml(xml, node->data, node->len); cmark_strbuf_puts(xml, "mem); cmark_event_type ev_type; cmark_node *cur; struct render_state state = {&xml, 0}; -- cgit v1.2.3