modfetch/config.c

104 lines
3 KiB
C

#include "config.h"
#include "util.h"
#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void parsing_error(size_t line) {
fprintf(stderr, "error: failed parsing config at line %zu", line);
exit(EXIT_FAILURE);
}
Config parse_config(FILE *config_file) {
size_t len = 0;
ssize_t read;
char *line = NULL;
size_t line_index = 0;
bool in_config = false;
char current_path[MAX_MODULE_NAME_LENGTH];
Module current_module = {
.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,
};
// TODO handle errors of all the function inside the while
errno = 0;
// TODO rewrite this to read the config char by char
while ((read = getline(&line, &len, config_file)) != -1) {
if (read <= 1)
continue;
// 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_path[read - 2] = '\0';
current_module.path = process_str(current_path);
current_module.config = malloc(INITIAL_CONFIG_SIZE * sizeof(char*));
continue;
}
// end of config for current module
if (line[read - 2u] == '}') {
if (!in_config) {
fclose(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[config.module_count] = current_module;
config.module_count += 1;
config_index = 0;
continue;
}
if (in_config) {
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 += 1;
continue;
}
// 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[config.module_count] = current_module;
config.module_count += 1;
free(line);
}
if (read == -1 && errno != 0)
free(line);
return config;
}