From e811d404a1722f42a7654160faf351325a01c208 Mon Sep 17 00:00:00 2001 From: klemek Date: Thu, 18 Sep 2025 19:32:19 +0200 Subject: [PATCH] working config file --- Makefile.am | 4 +-- src/args.c | 20 ++------------ src/config_file.c | 70 +++++++++++++++++++++++++++++++++++++++++------ src/file.c | 4 +-- src/string.c | 64 +++++++++++++++++++++++++++++++++++++++++++ src/string.h | 12 ++++++++ src/strings.c | 15 ---------- src/strings.h | 6 ---- src/types.h | 4 +-- 9 files changed, 145 insertions(+), 54 deletions(-) create mode 100644 src/string.c create mode 100644 src/string.h delete mode 100644 src/strings.c delete mode 100644 src/strings.h diff --git a/Makefile.am b/Makefile.am index edb35cf..ed0c658 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign subdir-objects -Wall bin_PROGRAMS = forge -forge_SOURCES = src/main.c src/args.c src/forge.c src/file.c src/window.c src/shaders.c src/timer.c src/strings.c src/config_file.c $(top_srcdir)/include/glad/gl.h $(top_srcdir)/hashmap.c/hashmap.c +forge_SOURCES = src/main.c src/args.c src/forge.c src/file.c src/window.c src/shaders.c src/timer.c src/string.c src/config_file.c $(top_srcdir)/include/glad/gl.h $(top_srcdir)/hashmap.c/hashmap.c forge_CFLAGS = -Ofast -march=native -flto -funroll-loops -fprefetch-loop-arrays -fno-exceptions -fopenmp -I$(top_srcdir)/include -DGLFW_INCLUDE_NONE forge_LDADD = -lm -lGL -lglfw -include_HEADERS = src/main.h src/args.h src/config.h src/types.h src/forge.h src/file.h src/constants.h src/window.h src/shaders.h src/logs.h src/timer.h src/strings.h src/config_file.h $(top_srcdir)/include/glad/gl.h $(top_srcdir)/include/linmath.h $(top_srcdir)/include/hashmap.h \ No newline at end of file +include_HEADERS = src/main.h src/args.h src/config.h src/types.h src/forge.h src/file.h src/constants.h src/window.h src/shaders.h src/logs.h src/timer.h src/string.h src/config_file.h $(top_srcdir)/include/glad/gl.h $(top_srcdir)/include/linmath.h $(top_srcdir)/include/hashmap.h \ No newline at end of file diff --git a/src/args.c b/src/args.c index 6d5eda3..f2dcbd7 100644 --- a/src/args.c +++ b/src/args.c @@ -6,6 +6,7 @@ #include "args.h" #include "config.h" #include "logs.h" +#include "string.h" #include "types.h" static void print_help(int status_code) { @@ -45,25 +46,8 @@ static char *split_arg_value(char *arg) { return strtok(NULL, "="); } -static bool is_digit(char c) { return c >= '0' && c <= '9'; } - -static bool is_number(char *value) { - unsigned long value_len; - unsigned int i; - if (value == NULL) { - return false; - } - value_len = strlen(value); - for (i = 0; i < value_len; i++) { - if (!is_digit(value[i])) { - return false; - } - } - return true; -} - static unsigned char parse_uchar(char *arg, char *value) { - if (!is_number(value)) { + if (!string_is_number(value)) { invalid_value(arg, value); } unsigned long long tmp_value = (unsigned long long)atoll(value); diff --git a/src/config_file.c b/src/config_file.c index 58f0c2f..f0934cf 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -1,8 +1,11 @@ #include #include +#include #include "config_file.h" #include "file.h" +#include "logs.h" +#include "string.h" #include "types.h" static int item_compare(const void *a, const void *b, @@ -24,31 +27,75 @@ static uint64_t item_hash(const void *item, uint64_t seed0, uint64_t seed1) { return hashmap_sip(c_item->key, strlen(c_item->key), seed0, seed1); } +static void parse_config_file_line(ConfigFile config, char *line) { + unsigned int size; + char *equal_pos; + unsigned int key_size; + unsigned int value_size; + ConfigFileItem item; + + size = string_trim(line); + + if (size == 0 || line[0] == '#') { + return; + } + + equal_pos = strchr(line, '='); + + if (equal_pos == NULL) { + log_warn("Invalid config line '%s'", line); + return; + } + + key_size = equal_pos - line; + value_size = size - key_size - 1; + + strncpy(item.key, line, key_size); + item.key[key_size] = '\0'; + + if (value_size > 0) { + strncpy(item.value, line + key_size + 1, value_size); + item.value[value_size] = '\0'; + } + + hashmap_set(config.map, &item); +} + ConfigFile config_file_read(char *path, bool free_path) { File file; - ConfigFile output; + ConfigFile config; + char *line; + + config.map = hashmap_new(sizeof(ConfigFileItem), 0, 0, 0, item_hash, + item_compare, NULL, NULL); file = file_read(path); - output.map = hashmap_new(sizeof(ConfigFileItem), 0, 0, 0, item_hash, - item_compare, NULL, NULL); + if (file.error) { + return config; + } - // TODO + line = strtok(file.content, "\n"); + + while (line != NULL) { + parse_config_file_line(config, line); + line = strtok(NULL, "\n"); + } file_free(&file, free_path); - return output; + return config; } char *config_file_get_str(ConfigFile config, char *key, char *default_value) { ConfigFileItem c_key; ConfigFileItem *item; - c_key.key = key; + strcpy(c_key.key, key); item = (ConfigFileItem *)hashmap_get(config.map, &c_key); - if (item == NULL) { + if (item == NULL || strlen(item->value) == 0) { return default_value; } @@ -59,11 +106,16 @@ int config_file_get_int(ConfigFile config, char *key, int default_value) { ConfigFileItem c_key; ConfigFileItem *item; - c_key.key = key; + strcpy(c_key.key, key); item = (ConfigFileItem *)hashmap_get(config.map, &c_key); - if (item == NULL) { + if (item == NULL || strlen(item->value) == 0) { + return default_value; + } + + if (!string_is_number(item->value)) { + log_warn("Invalid number for %s: '%s'", item->key, item->value); return default_value; } diff --git a/src/file.c b/src/file.c index 600d014..0f74c64 100644 --- a/src/file.c +++ b/src/file.c @@ -8,7 +8,7 @@ #include "file.h" #include "logs.h" -#include "strings.h" +#include "string.h" #include "types.h" static time_t get_file_time(File file) { @@ -81,7 +81,7 @@ void file_prepend(File *src, File extra) { char *old_src_content; old_src_content = src->content; - src->content = strings_concat(extra.content, src->content); + src->content = string_concat(extra.content, src->content); free(old_src_content); } diff --git a/src/string.c b/src/string.c new file mode 100644 index 0000000..1f93662 --- /dev/null +++ b/src/string.c @@ -0,0 +1,64 @@ +#include +#include +#include + +#include "string.h" + +char *string_concat(const char *s1, const char *s2) { + char *result; + + result = malloc(strlen(s1) + strlen(s2) + 1); // +1 for the null-terminator + + strcpy(result, s1); + strcat(result, s2); + + return result; +} + +unsigned int string_trim(char *str) { + // https://www.delftstack.com/howto/c/trim-string-in-c/ + unsigned int start; + unsigned int end; + + start = 0; + end = strlen(str) - 1; + + if (end == 0) { + return 0; + } + + // Remove leading whitespace + while (str[start] == ' ') { + start++; + } + + // Remove trailing whitespace + while (end > start && str[end] == ' ') { + end--; + } + + // If the string was trimmed, adjust the null terminator + if (start > 0 || end < (strlen(str) - 1)) { + memmove(str, str + start, end - start + 1); + str[end - start + 1] = '\0'; + } + + return end - start + 1; +} + +static bool is_digit(char c) { return c >= '0' && c <= '9'; } + +bool string_is_number(char *value) { + unsigned long value_len; + unsigned int i; + if (value == NULL) { + return false; + } + value_len = strlen(value); + for (i = 0; i < value_len; i++) { + if (!is_digit(value[i])) { + return false; + } + } + return true; +} \ No newline at end of file diff --git a/src/string.h b/src/string.h new file mode 100644 index 0000000..07c96ae --- /dev/null +++ b/src/string.h @@ -0,0 +1,12 @@ +#include + +#ifndef STRINGS_H +#define STRINGS_H + +char *string_concat(const char *s1, const char *s2); + +unsigned int string_trim(char *str); + +bool string_is_number(char *value); + +#endif /* STRINGS_H */ \ No newline at end of file diff --git a/src/strings.c b/src/strings.c deleted file mode 100644 index 45e264e..0000000 --- a/src/strings.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include - -#include "strings.h" - -char *strings_concat(const char *s1, const char *s2) { - char *result; - - result = malloc(strlen(s1) + strlen(s2) + 1); // +1 for the null-terminator - - strcpy(result, s1); - strcat(result, s2); - - return result; -} \ No newline at end of file diff --git a/src/strings.h b/src/strings.h deleted file mode 100644 index e9f9432..0000000 --- a/src/strings.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef STRINGS_H -#define STRINGS_H - -char *strings_concat(const char *s1, const char *s2); - -#endif /* STRINGS_H */ \ No newline at end of file diff --git a/src/types.h b/src/types.h index 59f0906..62ae677 100644 --- a/src/types.h +++ b/src/types.h @@ -83,8 +83,8 @@ typedef struct ConfigFile { } ConfigFile; typedef struct ConfigFileItem { - char *key; - char *value; + char key[256]; + char value[2048]; } ConfigFileItem; #endif /* TYPES_H */ \ No newline at end of file