]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/config.c
refactoring
[dragonblocks_alpha.git] / src / config.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdbool.h>
5 #include "config.h"
6
7 void config_read(char *path, ConfigEntry *entries, size_t num_entries)
8 {
9         FILE *f = fopen(path, "r");
10
11         if (!f)
12                 return;
13
14         printf("[info] reading config from %s\n", path);
15
16         while (!feof(f)) {
17                 char key[BUFSIZ];
18                 if (!fscanf(f, "%s", key))
19                         break;
20
21                 bool found = false;
22                 for (size_t i = 0; i < num_entries; i++) {
23                         ConfigEntry *entry = &entries[i];
24                         if (strcmp(key, entry->key) == 0) {
25                                 bool valid = false;
26
27                                 switch (entry->type) {
28                                         case CONFIG_STRING: {
29                                                 char value[BUFSIZ];
30
31                                                 if (!fscanf(f, "%s", value))
32                                                         break;
33
34                                                 valid = true;
35
36                                                 char **entry_value = entry->value;
37
38                                                 if (*entry_value)
39                                                         free(*entry_value);
40                                                 *entry_value = strdup(value);
41
42                                                 break;
43                                         }
44
45                                         case CONFIG_INT:
46                                                 if (fscanf(f, "%d", (int *) entry->value))
47                                                         valid = true;
48
49                                                 break;
50
51                                         case CONFIG_UINT:
52                                                 if (fscanf(f, "%u", (unsigned int *) entry->value))
53                                                         valid = true;
54
55                                                 break;
56
57                                         case CONFIG_FLOAT:
58                                                 if (fscanf(f, "%lf", (double *) entry->value))
59                                                         valid = true;
60
61                                                 break;
62
63                                         case CONFIG_BOOL: {
64                                                 char value[BUFSIZ];
65
66                                                 if (!fscanf(f, "%s", value))
67                                                         break;
68
69                                                 valid = true;
70
71                                                 if (strcmp(value, "on") == 0 || strcmp(value, "yes") == 0 || strcmp(value, "true") == 0)
72                                                         *(bool *) entry->value = true;
73                                                 else if (strcmp(value, "off") == 0 || strcmp(value, "no") == 0 || strcmp(value, "false") == 0)
74                                                         *(bool *) entry->value = false;
75                                                 else
76                                                         valid = false;
77
78                                                 break;
79                                         }
80                                 }
81
82                                 if (!valid)
83                                         fprintf(stderr, "[warning] invalid value for setting %s in %s\n", key, path);
84
85                                 found = true;
86                                 break;
87                         }
88                 }
89
90                 if (!found)
91                         fprintf(stderr, "[warning] unknown setting %s in %s\n", key, path);
92         }
93
94         fclose(f);
95 }
96
97 void config_free(ConfigEntry *entries, size_t num_entries)
98 {
99         for (size_t i = 0; i < num_entries; i++) {
100                 ConfigEntry *entry = &entries[i];
101
102                 if (entry->type == CONFIG_STRING) {
103                         char **entry_value = entry->value;
104
105                         if (*entry_value)
106                                 free(*entry_value);
107                 }
108         }
109 }