commit 921602b373bf7f7453cc0d2a0baad844c9ee9c92
parent aeaff18e871b13b3781267413eaea0cd3cdff108
Author: Martin Mitas <mity@morous.org>
Date: Thu, 4 May 2017 16:21:34 +0200
md_is_link_reference_definition: Do not store multiple link definitions with same label.
Diffstat:
| M | md4c/md4c.c | | | 48 | ++++++++++++++++++++++++++++++++---------------- |
1 file changed, 32 insertions(+), 16 deletions(-)
diff --git a/md4c/md4c.c b/md4c/md4c.c
@@ -1695,6 +1695,8 @@ md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg,
return FALSE;
}
+static int md_lookup_link_ref_def(MD_CTX* ctx, const CHAR* label, SZ label_size, MD_LINK_REF_DEF** p_def);
+
/* Returns 0 if it is not a link reference definition.
*
* Returns N > 0 if it is not a link reference definition (then N corresponds
@@ -1710,6 +1712,9 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
OFF label_contents_end;
int label_contents_line_index = -1;
int label_is_multiline;
+ CHAR* label;
+ SZ label_size;
+ int label_needs_free = FALSE;
OFF dest_contents_beg;
OFF dest_contents_end;
OFF title_contents_beg;
@@ -1720,7 +1725,7 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
int line_index = 0;
int tmp_line_index;
MD_LINK_REF_DEF* def;
- int ret = 0;
+ int ret;
/* Link label. */
if(!md_is_link_label(ctx, lines, n_lines, lines[0].beg,
@@ -1771,6 +1776,22 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
if(off < lines[line_index].end)
return FALSE;
+ /* Construct label. */
+ if(!label_is_multiline) {
+ label = (CHAR*) STR(label_contents_beg);
+ label_size = label_contents_end - label_contents_beg;
+ label_needs_free = FALSE;
+ } else {
+ MD_CHECK(md_merge_lines_alloc(ctx, label_contents_beg, label_contents_end,
+ lines + label_contents_line_index, n_lines - label_contents_line_index,
+ _T(' '), &label, &label_size));
+ label_needs_free = TRUE;
+ }
+
+ /* If such definition is already present, we do not store it. */
+ if(md_lookup_link_ref_def(ctx, label, label_size, &def))
+ return line_index + 1;
+
/* Store the link reference definition. */
if(ctx->n_link_ref_defs >= ctx->alloc_link_ref_defs) {
MD_LINK_REF_DEF* new_defs;
@@ -1787,21 +1808,11 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
}
def = &ctx->link_ref_defs[ctx->n_link_ref_defs];
- ctx->n_link_ref_defs++;
memset(def, 0, sizeof(MD_LINK_REF_DEF));
- if(!label_is_multiline) {
- def->label = (CHAR*) STR(label_contents_beg);
- def->label_size = label_contents_end - label_contents_beg;
- } else {
- SZ label_size;
-
- MD_CHECK(md_merge_lines_alloc(ctx, label_contents_beg, label_contents_end,
- lines + label_contents_line_index, n_lines - label_contents_line_index,
- _T(' '), &def->label, &label_size));
- def->label_size = label_size;
- def->label_needs_free = TRUE;
- }
+ def->label = label;
+ def->label_size = label_size;
+ def->label_needs_free = label_needs_free;
def->dest_beg = dest_contents_beg;
def->dest_end = dest_contents_end;
@@ -1819,10 +1830,15 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
def->title_needs_free = TRUE;
}
- ret = line_index + 1;
+ /* Success. */
+ ctx->n_link_ref_defs++;
+ return line_index + 1;
abort:
- return ret;
+ /* Failure. */
+ if(label_needs_free)
+ free(label);
+ return -1;
}
static OFF