From: Fletcher T. Penney Date: Sun, 5 Mar 2017 21:57:10 +0000 (-0500) Subject: ADDED: Add and utility functions; fix memory leak X-Git-Tag: 0.4.2-b^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2ad5684b172cc5d53449ebfbe05d32fd6679f143;p=multimarkdown ADDED: Add and utility functions; fix memory leak --- diff --git a/Sources/libMultiMarkdown/include/libMultiMarkdown.h b/Sources/libMultiMarkdown/include/libMultiMarkdown.h index bc7248c..eefd7ea 100644 --- a/Sources/libMultiMarkdown/include/libMultiMarkdown.h +++ b/Sources/libMultiMarkdown/include/libMultiMarkdown.h @@ -64,6 +64,16 @@ #include "token.h" +// Convert MMD text to specified format, with specified extensions, and language +// Returned char * must be freed +char * mmd_convert_string(const char * source, unsigned long extensions, short format, short language); + + +// Convert MMD text to specified format, with specified extensions, and language +// Returned char * must be freed +char * mmd_convert_d_string(DString * source, unsigned long extensions, short format, short language); + + /// MMD Engine is used for storing configuration information for MMD parser typedef struct mmd_engine mmd_engine; diff --git a/Sources/libMultiMarkdown/mmd.c b/Sources/libMultiMarkdown/mmd.c index f87694a..2d8ea2d 100644 --- a/Sources/libMultiMarkdown/mmd.c +++ b/Sources/libMultiMarkdown/mmd.c @@ -227,8 +227,13 @@ void mmd_engine_free(mmd_engine * e, bool freeDString) { // Pointers to blocks that are freed elsewhere stack_free(e->definition_stack); stack_free(e->header_stack); - stack_free(e->abbreviation_stack); + + // Abbreviations need to be freed + while (e->abbreviation_stack->size) { + footnote_free(stack_pop(e->abbreviation_stack)); + } + stack_free(e->abbreviation_stack); // Citations need to be freed while (e->citation_stack->size) { @@ -1879,3 +1884,51 @@ char * metavalue_for_key(mmd_engine * e, const char * key) { return result; } + +// Convert MMD text to specified format, with specified extensions, and language +// Returned char * must be freed +char * mmd_convert_string(const char * source, unsigned long extensions, short format, short language) { + char * result; + + mmd_engine * e = mmd_engine_create_with_string(source, extensions); + + mmd_engine_set_language(e, language); + + mmd_engine_parse_string(e); + + DString * output = d_string_new(""); + + mmd_export_token_tree(output, e, format); + + result = output->str; + + mmd_engine_free(e, true); // The engine has a private copy of source that must be freed + d_string_free(output, false); + + return result; +} + + +// Convert MMD text to specified format, with specified extensions, and language +// Returned char * must be freed +char * mmd_convert_d_string(DString * source, unsigned long extensions, short format, short language) { + char * result; + + mmd_engine * e = mmd_engine_create_with_dstring(source, extensions); + + mmd_engine_set_language(e, language); + + mmd_engine_parse_string(e); + + DString * output = d_string_new(""); + + mmd_export_token_tree(output, e, format); + + result = output->str; + + mmd_engine_free(e, false); // The engine doesn't own the DString, so don't free it. + d_string_free(output, false); + + return result; +} + diff --git a/Sources/libMultiMarkdown/writer.c b/Sources/libMultiMarkdown/writer.c index d658e20..b78f8ba 100644 --- a/Sources/libMultiMarkdown/writer.c +++ b/Sources/libMultiMarkdown/writer.c @@ -243,7 +243,6 @@ void scratch_pad_free(scratch_pad * scratch) { HASH_DEL(scratch->footnote_hash, f); // Remove item from hash free(f); // Free the fn_holder } - stack_free(scratch->used_footnotes); while (scratch->inline_footnotes_to_free->size) { @@ -257,7 +256,6 @@ void scratch_pad_free(scratch_pad * scratch) { HASH_DEL(scratch->citation_hash, f); // Remove item from hash free(f); // Free the fn_holder } - stack_free(scratch->used_citations); while (scratch->inline_citations_to_free->size) { @@ -271,7 +269,6 @@ void scratch_pad_free(scratch_pad * scratch) { HASH_DEL(scratch->glossary_hash, f); // Remove item from hash free(f); // Free the fn_holder } - stack_free(scratch->used_glossaries); while (scratch->inline_glossaries_to_free->size) { @@ -285,7 +282,6 @@ void scratch_pad_free(scratch_pad * scratch) { HASH_DEL(scratch->abbreviation_hash, f); // Remove item from hash free(f); // Free the fn_holder } - stack_free(scratch->used_abbreviations); while (scratch->inline_abbreviations_to_free->size) { @@ -293,6 +289,7 @@ void scratch_pad_free(scratch_pad * scratch) { } stack_free(scratch->inline_abbreviations_to_free); + // Free metadata hash meta * m, * m_tmp; @@ -1230,10 +1227,10 @@ void process_definition_block(mmd_engine * e, token * block) { label = label->child; switch (block->type) { + case BLOCK_DEF_ABBREVIATION: case BLOCK_DEF_CITATION: case BLOCK_DEF_FOOTNOTE: case BLOCK_DEF_GLOSSARY: - case BLOCK_DEF_ABBREVIATION: switch (block->type) { case BLOCK_DEF_ABBREVIATION: // Strip leading '>'' from term diff --git a/Sources/multimarkdown/main.c b/Sources/multimarkdown/main.c index 285ef10..7e54825 100644 --- a/Sources/multimarkdown/main.c +++ b/Sources/multimarkdown/main.c @@ -154,28 +154,6 @@ char * filename_with_extension(const char * original, const char * new_extension } -char * mmd_process(DString * buffer, unsigned long extensions, short format, short language) { - char * result; - - mmd_engine * e = mmd_engine_create_with_dstring(buffer, extensions); - - mmd_engine_set_language(e, language); - - mmd_engine_parse_string(e); - - DString * output = d_string_new(""); - - mmd_export_token_tree(output, e, format); - - result = output->str; - - mmd_engine_free(e, false); - d_string_free(output, false); - - return result; -} - - int main(int argc, char** argv) { int exitcode = EXIT_SUCCESS; char * binname = "multimarkdown"; @@ -379,7 +357,7 @@ int main(int argc, char** argv) { if (FORMAT_MMD == format) { result = buffer->str; } else { - result = mmd_process(buffer, extensions, format, language); + result = mmd_convert_d_string(buffer, extensions, format, language); } if (!(output_stream = fopen(output_filename, "w"))) { @@ -437,7 +415,7 @@ int main(int argc, char** argv) { if (FORMAT_MMD == format) { result = buffer->str; } else { - result = mmd_process(buffer, extensions, format, language); + result = mmd_convert_d_string(buffer, extensions, format, language); } // Where does output go?