all repos — mgba @ 11bf4fdfdad16a2a3b8059d652f41c2c6b2e2581

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
 7static void _sectionDeinit(void* string) {
 8	free(string);
 9}
10
11static int _iniRead(void* configuration, const char* section, const char* key, const char* value) {
12	if (section && !section[0]) {
13		section = 0;
14	}
15	ConfigurationSetValue(configuration, section, key, value);
16	return 1;
17}
18
19static void _keyHandler(const char* key, void* value, void* user) {
20	dprintf((int) user, "%s=%s\n", key, value);
21}
22
23static void _sectionHandler(const char* key, void* section, void* user) {
24	dprintf((int) user, "[%s]\n", key);
25	HashTableEnumerate(section, _keyHandler, user);
26	dprintf((int) user, "\n");
27}
28
29void ConfigurationInit(struct Configuration* configuration) {
30	HashTableInit(&configuration->sections, 0, (void (*)(void *)) TableDeinit);
31	HashTableInit(&configuration->root, 0, _sectionDeinit);
32}
33
34void ConfigurationDeinit(struct Configuration* configuration) {
35	HashTableDeinit(&configuration->sections);
36	HashTableDeinit(&configuration->root);
37}
38
39void ConfigurationSetValue(struct Configuration* configuration, const char* section, const char* key, const char* value) {
40	struct Table* currentSection = &configuration->root;
41	if (section) {
42		currentSection = HashTableLookup(&configuration->sections, section);
43		if (!currentSection && value) {
44			currentSection = malloc(sizeof(*currentSection));
45			HashTableInit(currentSection, 0, _sectionDeinit);
46			HashTableInsert(&configuration->sections, section, currentSection);
47		}
48	}
49	if (value) {
50		HashTableInsert(currentSection, key, strdup(value));
51	} else {
52		HashTableRemove(currentSection, key);
53	}
54}
55
56const char* ConfigurationGetValue(const struct Configuration* configuration, const char* section, const char* key) {
57	const struct Table* currentSection = &configuration->root;
58	if (section) {
59		currentSection = HashTableLookup(&configuration->sections, section);
60		if (!currentSection) {
61			return 0;
62		}
63	}
64	return HashTableLookup(currentSection, key);
65}
66
67bool ConfigurationRead(struct Configuration* configuration, const char* path) {
68	HashTableClear(&configuration->root);
69	HashTableClear(&configuration->sections);
70	return ini_parse(path, _iniRead, configuration) == 0;
71}
72
73bool ConfigurationWrite(const struct Configuration* configuration, const char* path) {
74	int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
75	if (fd < 0) {
76		return false;
77	}
78	HashTableEnumerate(&configuration->root, _keyHandler, (void*) fd);
79	HashTableEnumerate(&configuration->sections, _sectionHandler, (void*) fd);
80	close(fd);
81	return true;
82}
83
84bool ConfigurationWriteSection(const struct Configuration* configuration, const char* path, const char* section) {
85	struct Table* currentSection = &configuration->root;
86	int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
87	if (fd < 0) {
88		return false;
89	}
90	if (section) {
91		currentSection = HashTableLookup(&configuration->sections, section);
92		dprintf(fd, "[%s]\n", section);
93	}
94	if (currentSection) {
95		HashTableEnumerate(currentSection, _sectionHandler, (void*) fd);
96	}
97	close(fd);
98	return true;
99}