From 21aefd281a88849b30067c7d2471ff09b317e8fd Mon Sep 17 00:00:00 2001 From: jacekpoz Date: Fri, 9 Feb 2024 15:10:13 +0100 Subject: [PATCH] general memory and readability improvements --- modfetch.c | 79 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/modfetch.c b/modfetch.c index 121dcad..fdcccaa 100644 --- a/modfetch.c +++ b/modfetch.c @@ -16,7 +16,10 @@ static const uint8_t VERSION_PATCH = 0; static const uint8_t MAX_MODULE_NAME_LENGTH = 128; static const uint8_t MAX_MODULES = 128; -static const uint8_t MAX_MODULE_VARS = 128; + +static const uint8_t INITIAL_CONFIG_SIZE = 8; + +static const uint16_t MAX_PATH_LENGTH = 4096; static const char *version_str(void) { char *ver; @@ -44,7 +47,7 @@ void parsing_error(size_t line) { } char *remove_whitespaces(const char *str) { - char *tmp = malloc(strlen(str) * sizeof(char)); + char tmp[strlen(str)]; size_t i = 0; size_t j = 0; while (str[i] != '\0') { @@ -60,17 +63,17 @@ char *remove_whitespaces(const char *str) { char *ret = malloc(j * sizeof(char)); strncpy(ret, tmp, j); - free(tmp); return ret; } char *resolve_env_vars(const char *str) { size_t len = strlen(str); - char *ret = malloc(4096 * sizeof(char)); + char *ret = malloc(MAX_PATH_LENGTH * sizeof(char)); size_t ret_offset = 0; bool in_env_var = false; - char *env_var = malloc(4096 * sizeof(char)); + char env_var[MAX_PATH_LENGTH]; + memset(env_var, 0, sizeof(env_var)); size_t env_var_offset = 0; for (size_t i = 0; i < len; ++i) { @@ -86,14 +89,14 @@ char *resolve_env_vars(const char *str) { continue; } + // end of current env var if (in_env_var && !(isalpha(str[i]) || isdigit(str[i]) || str[i] == '_')) { in_env_var = false; char *env = getenv(env_var); strcat(ret, env); ret_offset += strlen(env); - free(env_var); - env_var = malloc(4096 * sizeof(char)); + memset(env_var, 0, sizeof(env_var)); env_var_offset = 0; } @@ -107,8 +110,13 @@ char *resolve_env_vars(const char *str) { ++ret_offset; } - free(env_var); + return ret; +} +char *process_str(const char *str) { + char *whitespaceless = remove_whitespaces(str); + char *ret = resolve_env_vars(whitespaceless); + free(whitespaceless); return ret; } @@ -119,33 +127,36 @@ Config parse_config(FILE *config_file) { size_t line_index = 0; bool in_config = false; - char *current_path = malloc(MAX_MODULE_NAME_LENGTH * sizeof(char)); + char current_path[MAX_MODULE_NAME_LENGTH]; Module current_module = { - .path = malloc(4096 * sizeof(char)), - .config = malloc(MAX_MODULE_VARS * sizeof(char)), + .path = NULL, + .config = NULL, }; size_t config_index = 0; + size_t config_multiplier = 1; Config config = { .modules = malloc(MAX_MODULES * sizeof(Module)), .module_count = 0, }; - size_t module_index = 0; + // TODO rewrite this to read the config char by char while ((read = getline(&line, &len, config_file)) != -1) { - if (read == 1) + if (read <= 1) continue; - // if config is passed + + // if config is passed to this module if (line[read - 2u] == '{') { if (in_config) { fclose(config_file); parsing_error(line_index); } in_config = true; + // get rid of the '{' strncpy(current_path, line, (size_t)read - 2); - current_module.path = resolve_env_vars(remove_whitespaces(current_path)); - free(current_path); - current_path = malloc(MAX_MODULE_NAME_LENGTH); + + current_module.path = process_str(current_path); + current_module.config = malloc(INITIAL_CONFIG_SIZE * sizeof(char*)); continue; } @@ -156,31 +167,39 @@ Config parse_config(FILE *config_file) { parsing_error(line_index); } in_config = false; + + if (config_index >= INITIAL_CONFIG_SIZE * config_multiplier) { + config_multiplier *= 2; + current_module.config = realloc(current_module.config, INITIAL_CONFIG_SIZE * config_multiplier); + } current_module.config[config_index] = NULL; - config.modules[module_index] = current_module; - ++module_index; - current_module.path = malloc(4096 * sizeof(char)); - current_module.config = malloc(MAX_MODULE_VARS * sizeof(char)); + config.modules[config.module_count] = current_module; + ++config.module_count; + config_index = 0; continue; } if (in_config) { - current_module.config[config_index] = remove_whitespaces(line); + if (config_index >= INITIAL_CONFIG_SIZE * config_multiplier) { + config_multiplier *= 2; + current_module.config = realloc(current_module.config, INITIAL_CONFIG_SIZE * config_multiplier); + } + current_module.config[config_index] = process_str(line); ++config_index; continue; } - current_module.path = resolve_env_vars(remove_whitespaces(line)); - free(current_module.config); + // no config passed to this module + current_module.path = process_str(line); + current_module.config = malloc(sizeof(void*)); current_module.config[0] = NULL; - config.modules[module_index] = current_module; - ++module_index; - current_module.path = malloc(4096 * sizeof(char)); - current_module.config = malloc(MAX_MODULE_VARS * sizeof(char)); - } - config.module_count = module_index; + config.modules[config.module_count] = current_module; + ++config.module_count; + + free(line); + } return config; }