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}