Skip to content

Commit

Permalink
Merge pull request #38 from andy5995/add_public_free_list_func
Browse files Browse the repository at this point in the history
Add public function for freeing  list when the entire struct hasn't been parsed
  • Loading branch information
andy5995 authored Jan 11, 2025
2 parents 9ee75bd + a3a4454 commit c948456
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 4 deletions.
7 changes: 3 additions & 4 deletions canfigger.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
}

Expand Down
7 changes: 7 additions & 0 deletions canfigger.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
77 changes: 77 additions & 0 deletions tests/incomplete_parse_file.c
Original file line number Diff line number Diff line change
@@ -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;
}
1 change: 1 addition & 0 deletions tests/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ test_cases = [
'colons',
'file_open_err',
'german',
'incomplete_parse_file',
'multiple_attributes',
'parse_file',
'skip_attributes',
Expand Down

0 comments on commit c948456

Please sign in to comment.