mgba/src/util/configuration.c

151 lines
4.6 KiB
C
Raw Normal View History

/* Copyright (c) 2013-2014 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
2014-11-01 10:02:40 +00:00
#include "configuration.h"
#include "util/formatting.h"
#include "util/string.h"
2014-11-01 10:02:40 +00:00
#include "util/vfs.h"
#include "third-party/inih/ini.h"
2014-11-01 10:02:40 +00:00
#include <float.h>
2014-11-05 10:45:00 +00:00
static void _tableDeinit(void* table) {
TableDeinit(table);
free(table);
}
2014-11-01 10:02:40 +00:00
static void _sectionDeinit(void* string) {
free(string);
}
static int _iniRead(void* configuration, const char* section, const char* key, const char* value) {
if (section && !section[0]) {
section = 0;
}
ConfigurationSetValue(configuration, section, key, value);
return 1;
}
static void _keyHandler(const char* key, void* value, void* user) {
fprintf(user, "%s=%s\n", key, (const char*) value);
2014-11-01 10:02:40 +00:00
}
static void _sectionHandler(const char* key, void* section, void* user) {
fprintf(user, "[%s]\n", key);
2014-11-01 10:02:40 +00:00
HashTableEnumerate(section, _keyHandler, user);
fprintf(user, "\n");
2014-11-01 10:02:40 +00:00
}
void ConfigurationInit(struct Configuration* configuration) {
2014-11-05 10:45:00 +00:00
HashTableInit(&configuration->sections, 0, _tableDeinit);
2014-11-01 10:02:40 +00:00
HashTableInit(&configuration->root, 0, _sectionDeinit);
}
void ConfigurationDeinit(struct Configuration* configuration) {
HashTableDeinit(&configuration->sections);
HashTableDeinit(&configuration->root);
}
void ConfigurationSetValue(struct Configuration* configuration, const char* section, const char* key, const char* value) {
struct Table* currentSection = &configuration->root;
if (section) {
currentSection = HashTableLookup(&configuration->sections, section);
if (!currentSection) {
if (value) {
currentSection = malloc(sizeof(*currentSection));
HashTableInit(currentSection, 0, _sectionDeinit);
HashTableInsert(&configuration->sections, section, currentSection);
} else {
return;
}
2014-11-01 10:02:40 +00:00
}
}
if (value) {
HashTableInsert(currentSection, key, strdup(value));
} else {
HashTableRemove(currentSection, key);
}
2014-11-01 10:02:40 +00:00
}
void ConfigurationSetIntValue(struct Configuration* configuration, const char* section, const char* key, int value) {
char charValue[12];
sprintf(charValue, "%i", value);
ConfigurationSetValue(configuration, section, key, charValue);
}
void ConfigurationSetUIntValue(struct Configuration* configuration, const char* section, const char* key, unsigned value) {
char charValue[12];
sprintf(charValue, "%u", value);
ConfigurationSetValue(configuration, section, key, charValue);
}
void ConfigurationSetFloatValue(struct Configuration* configuration, const char* section, const char* key, float value) {
char charValue[16];
ftostr_u(charValue, sizeof(charValue), value);
ConfigurationSetValue(configuration, section, key, charValue);
}
2015-01-18 09:19:28 +00:00
void ConfigurationClearValue(struct Configuration* configuration, const char* section, const char* key) {
struct Table* currentSection = &configuration->root;
if (section) {
currentSection = HashTableLookup(&configuration->sections, section);
if (!currentSection) {
return;
}
}
HashTableRemove(currentSection, key);
}
bool ConfigurationHasSection(const struct Configuration* configuration, const char* section) {
return HashTableLookup(&configuration->sections, section);
}
2014-11-01 10:02:40 +00:00
const char* ConfigurationGetValue(const struct Configuration* configuration, const char* section, const char* key) {
const struct Table* currentSection = &configuration->root;
if (section) {
currentSection = HashTableLookup(&configuration->sections, section);
if (!currentSection) {
return 0;
}
}
return HashTableLookup(currentSection, key);
}
bool ConfigurationRead(struct Configuration* configuration, const char* path) {
HashTableClear(&configuration->root);
HashTableClear(&configuration->sections);
return ini_parse(path, _iniRead, configuration) == 0;
}
bool ConfigurationWrite(const struct Configuration* configuration, const char* path) {
FILE* file = fopen(path, "w");
if (!file) {
2014-11-01 10:02:40 +00:00
return false;
}
HashTableEnumerate(&configuration->root, _keyHandler, file);
HashTableEnumerate(&configuration->sections, _sectionHandler, file);
fclose(file);
2014-11-01 10:02:40 +00:00
return true;
}
bool ConfigurationWriteSection(const struct Configuration* configuration, const char* path, const char* section) {
2014-11-05 10:34:51 +00:00
const struct Table* currentSection = &configuration->root;
FILE* file = fopen(path, "w");
if (!file) {
2014-11-01 10:02:40 +00:00
return false;
}
if (section) {
currentSection = HashTableLookup(&configuration->sections, section);
fprintf(file, "[%s]\n", section);
2014-11-01 10:02:40 +00:00
}
if (currentSection) {
HashTableEnumerate(currentSection, _sectionHandler, file);
2014-11-01 10:02:40 +00:00
}
fclose(file);
2014-11-01 10:02:40 +00:00
return true;
}