all repos — mgba @ 50d76d952891c2a981b17732160229d901c9fd0a

mGBA Game Boy Advance Emulator

src/util/configuration.c (view raw)

  1#include "configuration.h"
  2
  3#include "util/vfs.h"
  4
  5#include "third-party/inih/ini.h"
  6
  7#include <float.h>
  8
  9static void _sectionDeinit(void* string) {
 10	free(string);
 11}
 12
 13static int _iniRead(void* configuration, const char* section, const char* key, const char* value) {
 14	if (section && !section[0]) {
 15		section = 0;
 16	}
 17	ConfigurationSetValue(configuration, section, key, value);
 18	return 1;
 19}
 20
 21static void _keyHandler(const char* key, void* value, void* user) {
 22	dprintf((int) user, "%s=%s\n", key, value);
 23}
 24
 25static void _sectionHandler(const char* key, void* section, void* user) {
 26	dprintf((int) user, "[%s]\n", key);
 27	HashTableEnumerate(section, _keyHandler, user);
 28	dprintf((int) user, "\n");
 29}
 30
 31void ConfigurationInit(struct Configuration* configuration) {
 32	HashTableInit(&configuration->sections, 0, (void (*)(void *)) TableDeinit);
 33	HashTableInit(&configuration->root, 0, _sectionDeinit);
 34}
 35
 36void ConfigurationDeinit(struct Configuration* configuration) {
 37	HashTableDeinit(&configuration->sections);
 38	HashTableDeinit(&configuration->root);
 39}
 40
 41void ConfigurationSetValue(struct Configuration* configuration, const char* section, const char* key, const char* value) {
 42	struct Table* currentSection = &configuration->root;
 43	if (section) {
 44		currentSection = HashTableLookup(&configuration->sections, section);
 45		if (!currentSection && value) {
 46			currentSection = malloc(sizeof(*currentSection));
 47			HashTableInit(currentSection, 0, _sectionDeinit);
 48			HashTableInsert(&configuration->sections, section, currentSection);
 49		}
 50	}
 51	if (value) {
 52		HashTableInsert(currentSection, key, strdup(value));
 53	} else {
 54		HashTableRemove(currentSection, key);
 55	}
 56}
 57
 58void ConfigurationSetIntValue(struct Configuration* configuration, const char* section, const char* key, int value) {
 59	char charValue[12];
 60	sprintf(charValue, "%i", value);
 61	ConfigurationSetValue(configuration, section, key, charValue);
 62}
 63
 64void ConfigurationSetUIntValue(struct Configuration* configuration, const char* section, const char* key, unsigned value) {
 65	char charValue[12];
 66	sprintf(charValue, "%u", value);
 67	ConfigurationSetValue(configuration, section, key, charValue);
 68}
 69
 70void ConfigurationSetFloatValue(struct Configuration* configuration, const char* section, const char* key, float value) {
 71	char charValue[FLT_DIG + 7];
 72	sprintf(charValue, "%.*g", FLT_DIG, value);
 73	ConfigurationSetValue(configuration, section, key, charValue);
 74}
 75
 76const char* ConfigurationGetValue(const struct Configuration* configuration, const char* section, const char* key) {
 77	const struct Table* currentSection = &configuration->root;
 78	if (section) {
 79		currentSection = HashTableLookup(&configuration->sections, section);
 80		if (!currentSection) {
 81			return 0;
 82		}
 83	}
 84	return HashTableLookup(currentSection, key);
 85}
 86
 87bool ConfigurationRead(struct Configuration* configuration, const char* path) {
 88	HashTableClear(&configuration->root);
 89	HashTableClear(&configuration->sections);
 90	return ini_parse(path, _iniRead, configuration) == 0;
 91}
 92
 93bool ConfigurationWrite(const struct Configuration* configuration, const char* path) {
 94	int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
 95	if (fd < 0) {
 96		return false;
 97	}
 98	HashTableEnumerate(&configuration->root, _keyHandler, (void*) fd);
 99	HashTableEnumerate(&configuration->sections, _sectionHandler, (void*) fd);
100	close(fd);
101	return true;
102}
103
104bool ConfigurationWriteSection(const struct Configuration* configuration, const char* path, const char* section) {
105	struct Table* currentSection = &configuration->root;
106	int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
107	if (fd < 0) {
108		return false;
109	}
110	if (section) {
111		currentSection = HashTableLookup(&configuration->sections, section);
112		dprintf(fd, "[%s]\n", section);
113	}
114	if (currentSection) {
115		HashTableEnumerate(currentSection, _sectionHandler, (void*) fd);
116	}
117	close(fd);
118	return true;
119}