lfsdash/config.c

183 lines
3.0 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}