#include #include #include #include "config.h" #define MAXCONFIGLEN 64 struct configitem { char setting[MAXCONFIGLEN]; char value[MAXCONFIGLEN]; struct configitem *next; }; static struct { const char *filename; struct configitem *head; } s_config; static void config_free(void) { struct configitem *prev; struct configitem *curr = s_config.head; s_config.head = NULL; while (curr != NULL) { prev = curr; curr = curr->next; free(prev); } } void config_set_string(const char *key, const char *value) { struct configitem *item; struct configitem **itemp = &s_config.head; while (*itemp != NULL) { if (strcasecmp((*itemp)->setting, key) == 0) { item = *itemp; if (value == NULL) { *itemp = item->next; free(item); } else { strncpy(item->value, value, sizeof item->value); } return; } itemp = &(*itemp)->next; } if (value == NULL) return; *itemp = malloc(sizeof *item); item = *itemp; strncpy(item->setting, key, sizeof item->setting); strncpy(item->value, value, sizeof item->value); item->next = NULL; } static void config_rehash(void) { FILE *f = fopen(s_config.filename, "r"); if (f == NULL) return; config_free(); while (!feof(f)) { char buf[256]; if (fgets(buf, sizeof buf, f) <= 0) break; /* Ignore comments */ if (*buf == '#') continue; char *n = strchr(buf, '='); if (n == NULL) continue; *n++ = '\0'; char *eol = strchr(n, '\n'); if (eol != NULL) *eol = '\0'; config_set_string(buf, n); } fclose(f); } static void config_write(void) { FILE *f = fopen(s_config.filename, "w"); if (f == NULL) return; struct configitem *curr; for (curr = s_config.head; curr != NULL; curr = curr->next) { fprintf(f, "%s=%s\n", curr->setting, curr->value); } fclose(f); } void config_init(const char *filename) { s_config.filename = filename; s_config.head = NULL; config_rehash(); } void config_deinit(void) { config_write(); config_free(); } void config_set_int(const char *setting, int value) { char c[MAXCONFIGLEN]; snprintf(c, sizeof c, "%d", value); config_set_string(setting, c); } void config_set_float(const char *setting, float value) { char c[MAXCONFIGLEN]; snprintf(c, sizeof c, "%f", value); config_set_string(setting, c); } int config_get_string(const char *setting, char **value) { struct configitem *curr; for (curr = s_config.head; curr != NULL; curr = curr->next) { if (strcasecmp(curr->setting, setting) == 0) { *value = curr->value; return 1; } } *value = NULL; return 0; } int config_get_int(const char *setting, int *value) { char *c, *endptr; int v; if (!config_get_string(setting, &c)) return 0; v = strtol(c, &endptr, 10); if (*endptr != '\0') return 0; *value = v; return 1; } int config_get_float(const char *setting, float *value) { char *c, *endptr; float v; if (!config_get_string(setting, &c)) return 0; v = strtof(c, &endptr); if (*endptr != '\0') return 0; *value = v; return 1; }