slw2gmi

Конвертор из slweb-а у Џемини
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 1cee24c2cfa9b8a9ea98dc5a1cb9746819677d6c
родитељ 42ef2d1df0c14cd0d37c26429cee6cd7f61eb9d6
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Sun, 28 Mar 2021 20:44:37 +0200

Fixed actual leaks

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
MTODO | 6+++---
Mslw2gmi.c | 273++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
измењених датотека: 2, додавања: 170(+), брисања: 109(-)

diff --git a/TODO b/TODO @@ -2,7 +2,7 @@ TODO ==== - [ ] Fix leaks - [ ] Fix leaks in slw2gmi - [ ] Propagate the fixes to slweb + [x] Fix leaks + [x] Fix leaks in slw2gmi + [x] Propagate the fixes to slweb diff --git a/slw2gmi.c b/slw2gmi.c @@ -146,6 +146,9 @@ free_keyvalue(KeyValue** list, size_t list_count) } int +slweb_cleanup(); + +int slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links); char* @@ -185,6 +188,8 @@ startswith(const char* s, const char* what) uint8_t* get_value(KeyValue* list, size_t list_count, uint8_t* key, BOOL* seen) { + if (!list) + return NULL; KeyValue* plist = list; while (plist < list + list_count) { @@ -881,31 +886,27 @@ process_include(uint8_t* token, FILE* output, BOOL read_yaml_macros_and_links) read_file_into_buffer(&buffer, &buffer_size, input_filename, &input_dirname, &input); + free_keyvalue(&links, links_count); free(links); - CALLOC(links, KeyValue, 1) - links->key = NULL; - links->value = NULL; - links->value_size = 0; + links = NULL; links_count = 0; + free_keyvalue(&paralinks, paralinks_count); free(paralinks); - CALLOC(paralinks, KeyValue, 1) - paralinks->key = NULL; - paralinks->value = NULL; - paralinks->value_size = 0; + paralinks = NULL; paralinks_count = 0; + free_keyvalue(&footnotes, footnote_count); free(footnotes); - CALLOC(footnotes, KeyValue, 1) - footnotes->key = NULL; - footnotes->value = NULL; - footnotes->value_size = 0; + footnotes = NULL; footnote_count = 0; current_footnote = 0; - free(inline_footnotes); - CALLOC(inline_footnotes, uint8_t*, 1) - *inline_footnotes = NULL; + while (inline_footnote_count--) + free(inline_footnotes[inline_footnote_count]); + if (inline_footnotes) + free(inline_footnotes); + inline_footnotes = NULL; inline_footnote_count = 0; current_inline_footnote = 0; @@ -921,7 +922,7 @@ process_include(uint8_t* token, FILE* output, BOOL read_yaml_macros_and_links) if (result) { - free(input_filename); + slweb_cleanup(); free(buffer); return result; } @@ -938,7 +939,7 @@ process_include(uint8_t* token, FILE* output, BOOL read_yaml_macros_and_links) output_firstcol = saved_output_firstcol; skip_para_end = saved_skip_para_end; - free(input_filename); + slweb_cleanup(); free(buffer); exit(result); } @@ -1107,31 +1108,27 @@ process_incdir_subdir(const char* subdirname, const uint8_t* link_prefix, read_file_into_buffer(&buffer, &buffer_size, input_filename, &input_dirname, &input); + free_keyvalue(&links, links_count); free(links); - CALLOC(links, KeyValue, 1) - links->key = NULL; - links->value = NULL; - links->value_size = 0; + links = NULL; links_count = 0; + free_keyvalue(&paralinks, paralinks_count); free(paralinks); - CALLOC(paralinks, KeyValue, 1) - paralinks->key = NULL; - paralinks->value = NULL; - paralinks->value_size = 0; + paralinks = 0; paralinks_count = 0; + free_keyvalue(&footnotes, footnote_count); free(footnotes); - CALLOC(footnotes, KeyValue, 1) - footnotes->key = NULL; - footnotes->value = NULL; - footnotes->value_size = 0; + footnotes = 0; footnote_count = 0; current_footnote = 0; - free(inline_footnotes); - CALLOC(inline_footnotes, uint8_t*, 1) - *inline_footnotes = NULL; + while (inline_footnote_count--) + free(inline_footnotes[inline_footnote_count]); + if (inline_footnotes) + free(inline_footnotes); + inline_footnotes = NULL; inline_footnote_count = 0; current_inline_footnote = 0; @@ -1147,6 +1144,7 @@ process_incdir_subdir(const char* subdirname, const uint8_t* link_prefix, if (result) { + slweb_cleanup(); free(buffer); free(link); free(basename); @@ -1168,6 +1166,7 @@ process_incdir_subdir(const char* subdirname, const uint8_t* link_prefix, skip_para_end = saved_skip_para_end; fflush(output); + slweb_cleanup(); free(buffer); free(link); free(basename); @@ -1208,9 +1207,8 @@ process_incdir(uint8_t* token, const uint8_t* link_prefix, FILE* output, long num = 5; uint8_t* macro_body = NULL; int names_total = 0; + int current_name = 0; struct dirent** namelist; - struct dirent** pnamelist; - long names_output; BOOL details_open = TRUE; @@ -1273,16 +1271,16 @@ process_incdir(uint8_t* token, const uint8_t* link_prefix, FILE* output, exit(error(errno, (uint8_t*)"incdir: scandir '%s' error", incdir)); } - pnamelist = namelist; - names_output = 0; + current_name = 0; print_output(output, "\n"); - while (names_output < num && pnamelist && *pnamelist) + if (names_total < num) + num = names_total; + while (current_name < num)// && pnamelist && *pnamelist) { - process_incdir_subdir((*pnamelist)->d_name, link_prefix, output, - details_open, macro_body); + process_incdir_subdir(namelist[current_name]->d_name, link_prefix, + output, details_open, macro_body); details_open = FALSE; - pnamelist++; - names_output++; + current_name++; } print_output(output, "\n"); output_firstcol = TRUE; @@ -1408,7 +1406,12 @@ process_macro(uint8_t* token, FILE* output, BOOL read_yaml_macros_and_links, { macros_count++; - if (macros_count > 1) + if (!macros) + { + CALLOC(macros, KeyValue, macros_count) + pmacros = macros; + } + else { REALLOC(macros, KeyValue, macros_count * sizeof(KeyValue)) pmacros = macros + macros_count - 1; @@ -1711,10 +1714,7 @@ process_paralinks(const uint8_t* link_prefix, FILE* output) free_keyvalue(&paralinks, paralinks_count); free(paralinks); - CALLOC(paralinks, KeyValue, 1) - paralinks->key = NULL; - paralinks->value = NULL; - paralinks->value_size = 0; + paralinks = NULL; paralinks_count = 0; pparalinks = paralinks; @@ -1826,7 +1826,12 @@ process_inline_footnote(uint8_t* token, BOOL read_yaml_macros_and_links, inline_footnote_count++; if (inline_footnote_count == 1 && footnote_count > 0) warning(1, (uint8_t*)"Both inline and regular footnotes present"); - else if (inline_footnote_count > 1) + else if (!inline_footnotes) + { + inline_footnote_count = 1; + CALLOC(inline_footnotes, uint8_t*, inline_footnote_count) + } + else REALLOC(inline_footnotes, uint8_t*, sizeof(uint8_t*) * inline_footnote_count) CALLOC(inline_footnotes[inline_footnote_count-1], uint8_t, token_len+1) @@ -1853,9 +1858,14 @@ process_footnote(uint8_t* token, BOOL footnote_definition, BOOL footnote_output, footnote_count++; if (footnote_count == 1 && inline_footnote_count > 0) warning(1, (uint8_t*)"Both inline and regular footnotes present"); - else if (footnote_count > 1) + else if (!footnotes) { - REALLOC(footnotes, KeyValue, footnote_count * sizeof(KeyValue)) + CALLOC(footnotes, KeyValue, footnote_count) + pfootnotes = footnotes; + } + else + { + REALLOCARRAY(footnotes, KeyValue, footnote_count) pfootnotes = footnotes + footnote_count - 1; } CALLOC(pfootnotes->key, uint8_t, KEYSIZE) @@ -2012,15 +2022,6 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) if (!buffer) exit(error(1, (uint8_t*)"Empty buffer")); - if (!vars) - exit(error(EINVAL, (uint8_t*)"Invalid argument (vars)")); - - if (!links) - exit(error(EINVAL, (uint8_t*)"Invalid argument (links)")); - - if (!macros) - exit(error(EINVAL, (uint8_t*)"Invalid argument (macros)")); - title = get_value(vars, vars_count, (uint8_t*)"title", NULL); title_heading_level = get_value(vars, vars_count, (uint8_t*)"title-heading-level", NULL); @@ -2168,7 +2169,12 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) vars_count++; - if (vars_count > 1) + if (!vars) + { + CALLOC(vars, KeyValue, vars_count) + pvars = vars; + } + else { REALLOCARRAY(vars, KeyValue, vars_count) pvars = vars + vars_count - 1; @@ -2628,6 +2634,12 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) skip_eol = TRUE; if (read_yaml_macros_and_links) { + if (!macros) + { + macros_count = 1; + CALLOC(macros, KeyValue, macros_count) + pmacros = macros; + } if (pmacros->value) { size_t value_len = u8_strlen(pmacros->value); @@ -3118,7 +3130,12 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) if (!read_yaml_macros_and_links) { paralinks_count++; - if (paralinks_count > 1) + if (!paralinks) + { + CALLOC(paralinks, KeyValue, paralinks_count) + pparalinks = paralinks; + } + else { REALLOCARRAY(paralinks, KeyValue, paralinks_count) pparalinks = paralinks + paralinks_count - 1; @@ -3218,7 +3235,12 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) { uint8_t* url = get_value(links, links_count, token, NULL); paralinks_count++; - if (paralinks_count > 1) + if (!paralinks) + { + CALLOC(paralinks, KeyValue, paralinks_count) + pparalinks = paralinks; + } + else { REALLOCARRAY(paralinks, KeyValue, paralinks_count) pparalinks = paralinks + paralinks_count - 1; @@ -3254,7 +3276,12 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) { uint8_t* url = get_value(links, links_count, token, NULL); paralinks_count++; - if (paralinks_count > 1) + if (!paralinks) + { + CALLOC(paralinks, KeyValue, paralinks_count) + pparalinks = paralinks; + } + else { REALLOCARRAY(paralinks, KeyValue, paralinks_count) pparalinks = paralinks + paralinks_count - 1; @@ -3290,7 +3317,12 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) case ':': links_count++; - if (links_count > 1) + if (!links) + { + CALLOC(links, KeyValue, links_count) + plinks = links; + } + else { REALLOCARRAY(links, KeyValue, links_count) plinks = links + links_count - 1; @@ -3583,6 +3615,12 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) && (state & ST_YAML_VAL)) { *ptoken = 0; + if (!vars) + { + vars_count = 1; + CALLOC(vars, KeyValue, vars_count) + pvars = vars; + } pvars->value_size = u8_strlen(token)+1; CALLOC(pvars->value, uint8_t, pvars->value_size) u8_strncpy(pvars->value, token, pvars->value_size-1); @@ -3614,6 +3652,12 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) skip_eol = TRUE; if (read_yaml_macros_and_links) { + if (!macros) + { + macros_count = 1; + CALLOC(macros, KeyValue, macros_count) + pmacros = macros; + } if (pmacros->value) { size_t value_len = u8_strlen(pmacros->value); @@ -3643,6 +3687,12 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) skip_eol = TRUE; if (read_yaml_macros_and_links) { + if (!footnotes) + { + footnote_count = 1; + CALLOC(footnotes, KeyValue, footnote_count) + pfootnotes = footnotes; + } if (pfootnotes->value) { size_t value_len = u8_strlen(pfootnotes->value); @@ -3671,6 +3721,12 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) { if (read_yaml_macros_and_links) { + if (!links) + { + links_count = 1; + CALLOC(links, KeyValue, links_count) + plinks = links; + } plinks->value_size = u8_strlen(token)+1; CALLOC(plinks->value, uint8_t, plinks->value_size) u8_strncpy(plinks->value, token, plinks->value_size-1); @@ -3743,6 +3799,12 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) skip_eol = TRUE; if (read_yaml_macros_and_links) { + if (!footnotes) + { + footnote_count = 1; + CALLOC(footnotes, KeyValue, footnote_count) + pfootnotes = footnotes; + } if (pfootnotes->value) { size_t value_len = u8_strlen(pfootnotes->value); @@ -3855,6 +3917,34 @@ slweb_parse(uint8_t* buffer, FILE* output, BOOL read_yaml_macros_and_links) } int +slweb_cleanup() +{ + free(basedir); + free(input_dirname); + while (inline_footnote_count--) + free(inline_footnotes[inline_footnote_count]); + if (inline_footnotes) + free(inline_footnotes); + free_keyvalue(&footnotes, footnote_count); + free_keyvalue(&paralinks, paralinks_count); + free_keyvalue(&links, links_count); + free_keyvalue(&macros, macros_count); + free_keyvalue(&vars, vars_count); + if (footnotes) + free(footnotes); + if (paralinks) + free(paralinks); + if (links) + free(links); + if (macros) + free(macros); + if (vars) + free(vars); + + return 0; +} + +int main(int argc, char** argv) { char* arg; @@ -3991,33 +4081,18 @@ main(int argc, char** argv) free(bufline); } - CALLOC(vars, KeyValue, 1) - vars->key = NULL; - vars->value = NULL; - vars->value_size = 0; - - CALLOC(macros, KeyValue, 1) - macros->key = NULL; - macros->value = NULL; - macros->value_size = 0; - - CALLOC(links, KeyValue, 1) - links->key = NULL; - links->value = NULL; - links->value_size = 0; - - CALLOC(paralinks, KeyValue, 1) - paralinks->key = NULL; - paralinks->value = NULL; - paralinks->value_size = 0; - - CALLOC(footnotes, KeyValue, 1) - footnotes->key = NULL; - footnotes->value = NULL; - footnotes->value_size = 0; - - CALLOC(inline_footnotes, uint8_t*, 1) - *inline_footnotes = NULL; + vars = NULL; + vars_count = 0; + macros = NULL; + macros_count = 0; + links = NULL; + links_count = 0; + paralinks = NULL; + paralinks_count = 0; + footnotes = NULL; + footnote_count = 0; + + inline_footnotes = NULL; inline_footnote_count = 0; /* First pass: read YAML, macros and links */ @@ -4025,6 +4100,7 @@ main(int argc, char** argv) if (result) { + slweb_cleanup(); free(buffer); return result; } @@ -4036,22 +4112,7 @@ main(int argc, char** argv) /* Second pass: parse and output */ result = slweb_parse(buffer, output, FALSE); - if (basedir) - free(basedir); - if (input_dirname) - free(input_dirname); - if (inline_footnotes) - free(inline_footnotes); - free_keyvalue(&footnotes, footnote_count); - free_keyvalue(&paralinks, paralinks_count); - free_keyvalue(&links, links_count); - free_keyvalue(&macros, macros_count); - free_keyvalue(&vars, vars_count); - free(footnotes); - free(paralinks); - free(links); - free(macros); - free(vars); + slweb_cleanup(); free(buffer); return result;