all repos — mgba @ 67e31c9666531c99aa7625c2ef009b39ae4bb49e

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) {
44			currentSection = malloc(sizeof(*currentSection));
45			HashTableInit(currentSection, 0, _sectionDeinit);
46			HashTableInsert(&configuration->sections, section, currentSection);
47		}
48	}
49	HashTableInsert(currentSection, key, strdup(value));
50}
51
52const char* ConfigurationGetValue(const struct Configuration* configuration, const char* section, const char* key) {
53	const struct Table* currentSection = &configuration->root;
54	if (section) {
55		currentSection = HashTableLookup(&configuration->sections, section);
56		if (!currentSection) {
57			return 0;
58		}
59	}
60	return HashTableLookup(currentSection, key);
61}
62
63bool ConfigurationRead(struct Configuration* configuration, const char* path) {
64	HashTableClear(&configuration->root);
65	HashTableClear(&configuration->sections);
66	return ini_parse(path, _iniRead, configuration) == 0;
67}
68
69bool ConfigurationWrite(const struct Configuration* configuration, const char* path) {
70	int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
71	if (fd < 0) {
72		return false;
73	}
74	HashTableEnumerate(&configuration->root, _keyHandler, (void*) fd);
75	HashTableEnumerate(&configuration->sections, _sectionHandler, (void*) fd);
76	close(fd);
77	return true;
78}
79
80bool ConfigurationWriteSection(const struct Configuration* configuration, const char* path, const char* section) {
81	struct Table* currentSection = &configuration->root;
82	int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
83	if (fd < 0) {
84		return false;
85	}
86	if (section) {
87		currentSection = HashTableLookup(&configuration->sections, section);
88		dprintf(fd, "[%s]\n", section);
89	}
90	if (currentSection) {
91		HashTableEnumerate(currentSection, _sectionHandler, (void*) fd);
92	}
93	close(fd);
94	return true;
95}