#include "config.h" #include #include #include #include char *klist_config_key_to_string(KLIST_CONFIG_KEY key) { switch (key) { case CONFIG_DATABASE_NAME: return "database"; case _CONFIG_KEY_COUNT: return ""; } return ""; } KLIST_CONFIG_KEY klist_config_string_to_key(char *key) { if (!strcmp(key, klist_config_key_to_string(CONFIG_DATABASE_NAME))) return CONFIG_DATABASE_NAME; return _CONFIG_KEY_COUNT; } char *klist_config_name(char *name) { char *config_home = getenv("XDG_CONFIG_HOME"); bool config_home_a = false; if (!config_home) { config_home_a = true; char *home = getenv("HOME"); const char *config_home_format = "%s/.config"; int config_home_len = snprintf(name, 0, config_home_format, home); config_home = malloc(++config_home_len * sizeof(char)); snprintf(config_home, config_home_len, config_home_format, home, name); } int config_dir_len = snprintf(NULL, 0, "%s/%s", config_home, name); char *config_dir = malloc(++config_dir_len * sizeof(char)); snprintf(config_dir, config_dir_len, "%s/%s", config_home, name); struct stat st; if (stat(config_dir, &st) == -1) mkdir(config_dir, 0755); int config_file_len = snprintf(NULL, 0, "%s/%s/config", config_home, name); char *config_file_name = malloc(++config_file_len * sizeof(char)); snprintf(config_file_name, config_file_len, "%s/%s/config", config_home, name); if (config_home_a) free(config_home); free(config_dir); return config_file_name; } void klist_config_parse(klist_config *ctx, FILE *config) { fseek(config, 0, SEEK_END); int c; char *key = NULL, *val = NULL; bool found_key = false, ignore_line = false; while ((c = fgetc(config)) != EOF) { switch (c) { case '\n': ignore_line = true; if (!key) continue; if (!val) { fprintf(stderr, "ignoring key '%s'", key); } if (!strcmp(key, "database")) { ctx->db_file = malloc(strlen(val)); strcpy(ctx->db_file, val); } else { fprintf(stderr, "ignoring unknown key '%s'", key); } free(key); free(val); key = NULL; val = NULL; break; case '=': if (!found_key) found_key = true; else { printf("config file is screwed, please review\n"); exit(1); } break; default: if (!key && !val && c == '#') ignore_line = true; if (ignore_line) continue; if (found_key) { char *_val = val ? realloc(val, (strlen(val) + 2) * sizeof(char)) : malloc(2 * sizeof(char)); if (_val) { val = _val; val[strlen(val) - 2] = (char)c; val[strlen(val) - 1] = '\0'; } } else { char *_key = key ? realloc(key, (strlen(key) + 2) * sizeof(char)) : malloc(2 * sizeof(char)); if (_key) { key = _key; key[strlen(key) - 2] = (char)c; key[strlen(key) - 1] = '\0'; } } } } } void klist_config_setup(char *name, FILE *config) { char *data_home = getenv("XDG_DATA_HOME"); bool data_home_a = false; if (!data_home) { data_home_a = true; char *home = getenv("HOME"); const char *data_home_format = "%s/.local/state"; int data_home_len = snprintf(name, 0, data_home_format, home); data_home = malloc(++data_home_len * sizeof(char)); snprintf(data_home, data_home_len, data_home_format, home, name); } int db_file_len = snprintf(NULL, 0, "%s/%s", data_home, name); char *db_file = malloc(++db_file_len * sizeof(char)); snprintf(db_file, db_file_len, "%s/%s", data_home, name); struct stat st; if (stat(db_file, &st) == -1) mkdir(db_file, 0755); if (data_home_a) free(data_home); // fseek(config, 0, SEEK_END); fprintf(config, "%s=%s/tasks.db\n", klist_config_key_to_string(CONFIG_DATABASE_NAME), db_file); fclose(config); if (db_file) free(db_file); }