all repos — mgba @ e3573d402f3bda8ccf383d765319fa882fd5e1fa

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