Skip to content

Commit

Permalink
Use dynamic memory allocation for keys, values, and attributes (#18)
Browse files Browse the repository at this point in the history
* update workflow
  • Loading branch information
andy5995 authored Feb 21, 2024
1 parent 602841f commit 756fb30
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 59 deletions.
37 changes: 17 additions & 20 deletions .github/workflows/c-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,37 +22,34 @@ on:
- '**/c-cpp.yml'

jobs:
ubuntu-focal:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- run: sudo apt-get install -y meson
- run: |
meson _build
cd _build
ninja
meson test -v
ubuntu-jammy:
runs-on: ubuntu-22.04
linux:
strategy:
matrix:
cc: [gcc, clang]
runs-on: ubuntu-latest
env:
CC: 'gcc-12'
CC: ${{ matrix.cc }}
steps:
- uses: actions/checkout@v4
- run: sudo apt-get install -y meson $CC
- run: |
meson _build

- name: Install dependencies
run: sudo apt update && sudo apt-get install -y meson $CC

- name: Build
run: |
meson setup _build
cd _build
ninja
meson test -v
- name: Test
run: cd _build && meson test -v

macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- run: brew install meson
- run: |
meson _build
meson setup _build
cd _build
ninja
ninja test
meson test -v
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Canfigger ChangeLog

2024-02-21

* Use dynamic memory allocation for keys, values, and attributes.

2022-01-06

* implement support for multiple attributes (breaking change)
Expand Down
114 changes: 84 additions & 30 deletions canfigger.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This file is part of canfigger<https://github.com/andy5995/canfigger>
Copyright (C) 2021-2022 Andy Alt ([email protected])
Copyright (C) 2021-2024 Andy Alt ([email protected])
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -25,25 +25,40 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.

#include "canfigger.h"

static int err_strdup = 0;


static void
cleanup_1(char **line, FILE **fp)
{
free(*line);
fclose(*fp);
return;
}


void
canfigger_free(st_canfigger_node * node)
canfigger_free(st_canfigger_node *node)
{
if (node)
{
canfigger_free(node->next);
free(node->key);
free(node->value);
free(node);
}
return;
}


void
canfigger_free_attr(st_canfigger_attr_node * node)
canfigger_free_attr(st_canfigger_attr_node *node)
{
if (node)
{
canfigger_free_attr(node->next);
if (node->str)
free(node->str);
free(node);
}
return;
Expand Down Expand Up @@ -109,41 +124,62 @@ trim_whitespace(char *str)


static char *
grab_str_segment(char *a, char *dest, const int c)
grab_str_segment(char *a, char **dest, const int c)
{
free(*dest);
a = erase_lead_char(' ', a);

char *b = strchr(a, c);
if (!b)
{
strcpy(dest, a);
trim_whitespace(dest);
return NULL;
*dest = strdup(a);
if (!*dest)
err_strdup = -1;
return b; // NULL
}

char *dest_ptr = dest;
while (a != b)
*dest_ptr++ = *a++;

*dest_ptr = '\0';
trim_whitespace(dest);

*dest = strndup(a, b - a);
if (!*dest)
{
if (!*dest)
err_strdup = -1;
return NULL;
}
trim_whitespace(*dest);
return b + 1;
}


st_canfigger_list *
canfigger_parse_file(const char *file, const int delimiter)
{
err_strdup = 0;
static st_canfigger_node *root = NULL;
st_canfigger_list *list = NULL;

FILE *fp = fopen(file, "r");
if (!fp)
{
perror("canfigger:");
return NULL;
}

char *line = NULL;
size_t len = 0;
ssize_t read;

char line[__CFG_LEN_MAX_LINE];
while (fgets(line, sizeof line, fp) != NULL)
// getline() malloc's the memory needed for line
while ((read = getline(&line, &len, fp)) != -1)
{
static const char *empty_str = "";

if (!line)
{
fclose(fp);
return NULL;
}

// fprintf(stderr, "Retrieved line of length %zu:\n", read);
trim_whitespace(line);
char *a = line;

Expand All @@ -164,14 +200,27 @@ canfigger_parse_file(const char *file, const int delimiter)
st_canfigger_attr_node *attr_root = NULL;
st_canfigger_attr_node *attr_list = NULL;

*tmp_node->key = '\0';
*tmp_node->value = '\0';
tmp_node->key = strdup(empty_str);
if (!empty_str)
{
cleanup_1(&line, &fp);
return NULL;
}

char *b = grab_str_segment(a, &tmp_node->key, '=');
// fprintf(stderr, "key: '%s'\n", tmp_node->key);

tmp_node->value = strdup(empty_str);
if (!empty_str)
{
cleanup_1(&line, &fp);
return NULL;
}

char *b = grab_str_segment(a, tmp_node->key, '=');
if (b)
{
a = b;
b = grab_str_segment(a, tmp_node->value, delimiter);
b = grab_str_segment(a, &tmp_node->value, delimiter);
}
do
{
Expand All @@ -184,7 +233,8 @@ canfigger_parse_file(const char *file, const int delimiter)

if (root)
canfigger_free(root);
fclose(fp);

cleanup_1(&line, &fp);
return NULL;
}

Expand All @@ -193,12 +243,16 @@ canfigger_parse_file(const char *file, const int delimiter)
else
attr_root = cur_attr_node;

*cur_attr_node->str = '\0';

cur_attr_node->str = strdup(empty_str);
if (!empty_str)
{
cleanup_1(&line, &fp);
return NULL;
}
if (b)
{
a = b;
b = grab_str_segment(a, cur_attr_node->str, delimiter);
b = grab_str_segment(a, &cur_attr_node->str, delimiter);
}
attr_list = cur_attr_node;
cur_attr_node->next = NULL;
Expand All @@ -215,16 +269,16 @@ canfigger_parse_file(const char *file, const int delimiter)
if (root)
canfigger_free(root);

fclose(fp);
cleanup_1(&line, &fp);
return NULL;
}
}

int r = fclose(fp);
if (r != 0)
{
return NULL;
}
if (line)
free(line);

if (fclose(fp) != 0)
perror("canfigger:");

list = root;
return list;
Expand Down
12 changes: 4 additions & 8 deletions canfigger.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This file is part of canfigger<https://github.com/andy5995/canfigger>
Copyright (C) 2021-2022 Andy Alt ([email protected])
Copyright (C) 2021-2024 Andy Alt ([email protected])
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -23,16 +23,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define CANFIGGER_VERSION "0.2.0999"
#endif

// The max length of a line in a configuration file; a longer line will
// get truncated when fgets() is called to read the file.
#define __CFG_LEN_MAX_LINE (512 + 1)

// Member of st_canfigger_node
// @see canfigger_free_attr()
typedef struct st_canfigger_attr_node st_canfigger_attr_node;
struct st_canfigger_attr_node
{
char str[__CFG_LEN_MAX_LINE];
char *str;
st_canfigger_attr_node *next;
};

Expand All @@ -41,10 +37,10 @@ typedef struct st_canfigger_node st_canfigger_node;
struct st_canfigger_node
{
// Contains the string that precedes the '=' sign
char key[__CFG_LEN_MAX_LINE];
char *key;

// Contains the string between the '=' sign and the delimiter
char value[__CFG_LEN_MAX_LINE];
char *value;

// Linked list of attributes
st_canfigger_attr_node *attr_node;
Expand Down
2 changes: 1 addition & 1 deletion tests/test_parse_file2.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ main(void)
snprintf(test_config_file, sizeof test_config_file,
"%s/no_exist_test_canfigger.conf",
SOURCE_DIR) < sizeof test_config_file);
st_canfigger_list *list = canfigger_parse_file(test_config_file, ',');

st_canfigger_list *list = canfigger_parse_file(test_config_file, ',');
assert(list == NULL);
assert(errno);
perror(__func__);
Expand Down

0 comments on commit 756fb30

Please sign in to comment.