diff --git a/canfigger.c b/canfigger.c index 9994b8c..2cf7e71 100644 --- a/canfigger.c +++ b/canfigger.c @@ -40,7 +40,6 @@ SOFTWARE. #include "canfigger.h" static char *grab_str_segment(char *a, char **dest, const int c); -static void free_list(struct Canfigger **node); /** \cond */ struct line @@ -158,8 +157,8 @@ canfigger_free_current_key_node_advance(struct Canfigger **node) } -static void -free_list(struct Canfigger **node) +void +canfigger_free_list(struct Canfigger **node) { if (*node) { @@ -466,7 +465,7 @@ canfigger_parse_file(const char *file, const int delimiter) if (!node_complete) { - free_list(&root); + canfigger_free_list(&root); return NULL; } diff --git a/canfigger.h b/canfigger.h index 5bac10e..0e39719 100644 --- a/canfigger.h +++ b/canfigger.h @@ -101,6 +101,13 @@ void canfigger_free_current_key_node_advance(struct Canfigger **list); */ void canfigger_free_current_attr_str_advance(struct attributes *attributes, char **attr); +/** + * @brief Frees the remainder of list allocated by canfigger_parse_file(). + * + * @param list Double pointer to the current node in the linked list. + */ +void canfigger_free_list(struct Canfigger **node); + #ifdef __cplusplus } #endif diff --git a/tests/incomplete_parse_file.c b/tests/incomplete_parse_file.c new file mode 100644 index 0000000..474a24c --- /dev/null +++ b/tests/incomplete_parse_file.c @@ -0,0 +1,77 @@ +#include "test.h" + +// Note this test may only return the correct result +// when it and the library are built with sanitize enabled + +int +main(void) +{ + const struct expected + { + const char *key; + const char *value; + const char *attribute; + } data[] = { + {"foo", "bar", NULL}, + {"blue", "color", "shiny"}, + {"statement", "hello world", "obvious"}, + {"leadingSpace", "nullified", NULL}, + {"fookey", "bar-value", NULL}, + {"FeatureFooEnabled", NULL, NULL}, + }; + + char test_config_file[PATH_MAX]; + assert((size_t) + snprintf(test_config_file, sizeof test_config_file, + "%s/test_canfigger.conf", + SOURCE_DIR) < sizeof test_config_file); + + // call the primary library function to read your config file + struct Canfigger *list = canfigger_parse_file(test_config_file, ','); + assert(list); + + // Free the list without actually looking at any keys + canfigger_free_list(&list); + assert(!list); + + list = canfigger_parse_file(test_config_file, ','); + assert(list); + + int i = 0; + int incomplete_get = ARRAY_SIZE(data) / 2; + assert(incomplete_get == 3); + while (i < incomplete_get) + { + char *attr = NULL; + canfigger_free_current_attr_str_advance(list->attributes, &attr); + + fprintf(stderr, "\n\ +Key: %s | Expected: %s\n\ +Value: %s | Expected: %s\n\ +Attribute: %s | Expected: %s\n", + list->key, data[i].key, + list->value ? list->value : "NULL", data[i].value ? data[i].value : "NULL", + attr ? attr : "NULL", data[i].attribute ? data[i].attribute : "NULL"); + + assert(strcmp(data[i].key, list->key) == 0); + assert(strcmp + (data[i].value != NULL ? data[i].value : "NULL", + list->value != NULL ? list->value : "NULL") == 0); + fprintf(stderr, "attr: %s\n", attr != NULL ? attr : "NULL"); + assert(strcmp + (attr != NULL ? data[i].attribute : "NULL", + attr != NULL ? attr : "NULL") == 0); + i++; + + canfigger_free_current_key_node_advance(&list); + } + + assert (list); + canfigger_free_list(&list); + // 'list' should be NULL, not a dangling pointer + assert(list == NULL); + + assert(i == incomplete_get); + + return 0; +} diff --git a/tests/meson.build b/tests/meson.build index 65fbd3b..42354f6 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -2,6 +2,7 @@ test_cases = [ 'colons', 'file_open_err', 'german', + 'incomplete_parse_file', 'multiple_attributes', 'parse_file', 'skip_attributes',