feat(config): added a simple user config
This commit is contained in:
parent
1e4677bcda
commit
a089bc43c3
2 changed files with 170 additions and 0 deletions
20
include/config.h
Normal file
20
include/config.h
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
#include "tomlc17.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
char *email;
|
||||||
|
} UserTable;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UserTable user;
|
||||||
|
} Config;
|
||||||
|
|
||||||
|
int load_config(Config*);
|
||||||
|
void free_config(Config*);
|
||||||
|
int validate_config(Config*);
|
||||||
|
|
||||||
|
#endif // CONFIG_H
|
||||||
150
src/config.c
Normal file
150
src/config.c
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
// Initialize config with defaults
|
||||||
|
static void init_default_config(Config* config) {
|
||||||
|
config->user.name = NULL;
|
||||||
|
config->user.email = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free config memory
|
||||||
|
void free_config(Config* config) {
|
||||||
|
if (!config) return;
|
||||||
|
|
||||||
|
free(config->user.name);
|
||||||
|
free(config->user.email);
|
||||||
|
|
||||||
|
memset(config, 0, sizeof(*config));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get XDG config directory
|
||||||
|
static char* get_xdg_config_dir() {
|
||||||
|
char *xdg_config = getenv("XDG_CONFIG_HOME");
|
||||||
|
if (xdg_config && strlen(xdg_config) > 0) {
|
||||||
|
return strdup(xdg_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *home = getenv("HOME");
|
||||||
|
if (!home) {
|
||||||
|
fprintf(stderr, "Error: HOME environment variable not set\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t len = strlen(home) + strlen("/.config") + 1;
|
||||||
|
char *config_dir = malloc(len);
|
||||||
|
if (!config_dir) {
|
||||||
|
perror("malloc");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(config_dir, len, "%s/.config", home);
|
||||||
|
return config_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get config file path
|
||||||
|
static char* get_config_path() {
|
||||||
|
char *config_dir = get_xdg_config_dir();
|
||||||
|
if (!config_dir) return NULL;
|
||||||
|
|
||||||
|
size_t len = strlen(config_dir) + strlen("/merk/config.toml") + 1;
|
||||||
|
char *config_path = malloc(len);
|
||||||
|
if (!config_path) {
|
||||||
|
free(config_dir);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(config_path, len, "%s/merk/config.toml", config_dir);
|
||||||
|
free(config_dir);
|
||||||
|
|
||||||
|
return config_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse TOML config into Config
|
||||||
|
static int parse_toml_config(toml_result_t result, Config* config) {
|
||||||
|
if (!result.ok) {
|
||||||
|
fprintf(stderr, "TOML parse error: %s\n", result.errmsg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t root = result.toptab;
|
||||||
|
if (root.type != TOML_TABLE) {
|
||||||
|
fprintf(stderr, "Root element is not a table\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t user_table = toml_get(root, "user");
|
||||||
|
if (user_table.type != TOML_TABLE) {
|
||||||
|
fprintf(stderr, "Warning: 'user' table not found or invalid\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t name = toml_get(user_table, "name");
|
||||||
|
if (name.type == TOML_STRING) {
|
||||||
|
config->user.name = strdup(name.u.s);
|
||||||
|
if (!config->user.name) {
|
||||||
|
perror("strdup");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t email = toml_get(user_table, "email");
|
||||||
|
if (email.type == TOML_STRING) {
|
||||||
|
config->user.email = strdup(email.u.s);
|
||||||
|
if (!config->user.email) {
|
||||||
|
perror("strdup");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load configuration from file
|
||||||
|
int load_config(Config* config) {
|
||||||
|
if (!config) return -1;
|
||||||
|
|
||||||
|
init_default_config(config);
|
||||||
|
|
||||||
|
char *config_path = get_config_path();
|
||||||
|
|
||||||
|
if (!config_path) {
|
||||||
|
fprintf(stderr, "Failed to get config path\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (access(config_path, F_OK) != 0) {
|
||||||
|
if (create_default_config_file(config_path) < 0) {
|
||||||
|
free(config_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_result_t result = toml_parse_file_ex(config_path);
|
||||||
|
free(config_path);
|
||||||
|
|
||||||
|
int ret = parse_toml_config(result, config);
|
||||||
|
toml_free(result);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate configuration
|
||||||
|
int validate_config(Config* config) {
|
||||||
|
if (!config) return -1;
|
||||||
|
|
||||||
|
if (!config->user.name || strlen(config->user.name) == 0) {
|
||||||
|
fprintf(stderr, "Error: User name is required\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config->user.email || strlen(config->user.email) == 0) {
|
||||||
|
fprintf(stderr, "Error: User email is required\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strchr(config->user.email, '@') || !strchr(config->user.email, '.')) {
|
||||||
|
fprintf(stderr, "Error: Invalid email format\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue