Refactorize memory management of MD_LINK_REF_DEF structures.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
diff --git a/md4c/md4c.c b/md4c/md4c.c
index c2410d0..aa13562 100644
--- a/md4c/md4c.c
+++ b/md4c/md4c.c
@@ -101,8 +101,10 @@ struct MD_CTX_tag {
CHAR* buffer;
unsigned alloc_buffer;
- MD_LINK_REF_DEF* link_ref_head;
- MD_LINK_REF_DEF* link_ref_tail;
+ /* Link reference definitions. */
+ MD_LINK_REF_DEF* link_ref_defs;
+ unsigned n_link_ref_defs;
+ unsigned alloc_link_ref_defs;
/* Stack of inline/span markers.
* This is only used for parsing a single block contents but by storing it
@@ -1188,8 +1190,6 @@ struct MD_LINK_REF_DEF_tag {
SZ title_size;
OFF dest_beg;
OFF dest_end;
-
- MD_LINK_REF_DEF* next;
};
typedef struct MD_LINK_ATTR_tag MD_LINK_ATTR;
@@ -1535,11 +1535,22 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
return FALSE;
/* Store the link reference definition. */
- def = (MD_LINK_REF_DEF*) malloc(sizeof(MD_LINK_REF_DEF));
- if(def == NULL) {
- MD_LOG("malloc() failed.");
- return -1;
+ if(ctx->n_link_ref_defs >= ctx->alloc_link_ref_defs) {
+ MD_LINK_REF_DEF* new_defs;
+
+ ctx->alloc_link_ref_defs = (ctx->alloc_link_ref_defs > 0 ? ctx->alloc_link_ref_defs * 2 : 16);
+ new_defs = (MD_LINK_REF_DEF*) realloc(ctx->link_ref_defs, ctx->alloc_link_ref_defs * sizeof(MD_LINK_REF_DEF));
+ if(new_defs == NULL) {
+ MD_LOG("realloc() failed.");
+ ret = -1;
+ goto abort;
+ }
+
+ ctx->link_ref_defs = new_defs;
}
+
+ 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) {
@@ -1571,13 +1582,6 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
def->title_needs_free = TRUE;
}
- if(ctx->link_ref_tail != NULL)
- ctx->link_ref_tail->next = def;
- else
- ctx->link_ref_head = def;
- ctx->link_ref_tail = def;
- def->next = NULL;
-
ret = line_index + 1;
abort:
@@ -1664,16 +1668,15 @@ md_link_label_eq(const CHAR* a_label, SZ a_size, const CHAR* b_label, SZ b_size)
static int
md_lookup_link_ref_def(MD_CTX* ctx, const CHAR* label, SZ label_size, MD_LINK_REF_DEF** p_def)
{
- MD_LINK_REF_DEF* def;
+ unsigned i;
+
+ for(i = 0; i < ctx->n_link_ref_defs; i++) {
+ MD_LINK_REF_DEF* def = &ctx->link_ref_defs[i];
- def = ctx->link_ref_head;
- while(def != NULL) {
if(md_link_label_eq(def->label, def->label_size, label, label_size)) {
*p_def = def;
return TRUE;
}
-
- def = def->next;
}
*p_def = NULL;
@@ -1822,20 +1825,18 @@ abort:
static void
md_free_link_ref_defs(MD_CTX* ctx)
{
- MD_LINK_REF_DEF* def = ctx->link_ref_head;
- MD_LINK_REF_DEF* def_next;
+ unsigned i;
- while(def != NULL) {
- def_next = def->next;
+ for(i = 0; i < ctx->n_link_ref_defs; i++) {
+ MD_LINK_REF_DEF* def = &ctx->link_ref_defs[i];
if(def->label_needs_free)
free(def->label);
if(def->title_needs_free)
free(def->title);
- free(def);
-
- def = def_next;
}
+
+ free(ctx->link_ref_defs);
}