|
1 #include "cfg.h" |
|
2 |
|
3 #include "../iniparser/iniparser.h" |
|
4 #include "../iniparser/dictionary.h" |
|
5 #include "../ini/inihelper.h" |
|
6 #include "../logging.h" |
|
7 |
|
8 #include <stdio.h> |
|
9 |
|
10 static void freeCfgMeta(flib_cfg_meta *cfg) { |
|
11 if(cfg) { |
|
12 if(cfg->settings) { |
|
13 for(int i=0; i<cfg->settingCount; i++) { |
|
14 free(cfg->settings[i].iniName); |
|
15 free(cfg->settings[i].title); |
|
16 free(cfg->settings[i].engineCommand); |
|
17 free(cfg->settings[i].image); |
|
18 } |
|
19 free(cfg->settings); |
|
20 } |
|
21 if(cfg->mods) { |
|
22 for(int i=0; i<cfg->modCount; i++) { |
|
23 free(cfg->mods[i].iniName); |
|
24 } |
|
25 free(cfg->mods); |
|
26 } |
|
27 free(cfg); |
|
28 } |
|
29 } |
|
30 |
|
31 flib_cfg_meta *flib_cfg_meta_from_ini(const char *settingpath, const char *modpath) { |
|
32 if(!settingpath || !modpath) { |
|
33 return NULL; |
|
34 } |
|
35 flib_cfg_meta *result = calloc(1, sizeof(flib_cfg_meta)); |
|
36 dictionary *settingfile = iniparser_load(settingpath); |
|
37 dictionary *modfile = iniparser_load(modpath); |
|
38 |
|
39 if(!result || !settingfile || !modfile) { |
|
40 goto handleError; |
|
41 } |
|
42 |
|
43 result->settingCount = iniparser_getnsec(settingfile); |
|
44 result->modCount = iniparser_getnsec(modfile); |
|
45 result->settings = calloc(result->settingCount, sizeof(flib_cfg_setting_meta)); |
|
46 result->mods = calloc(result->modCount, sizeof(flib_cfg_mod_meta)); |
|
47 |
|
48 if(!result->settings || !result->mods) { |
|
49 goto handleError; |
|
50 } |
|
51 |
|
52 for(int i=0; i<result->settingCount; i++) { |
|
53 char *sectionName = iniparser_getsecname(settingfile, i); |
|
54 if(!sectionName) { |
|
55 goto handleError; |
|
56 } |
|
57 |
|
58 bool error = false; |
|
59 result->settings[i].iniName = inihelper_strdupnull(sectionName); |
|
60 result->settings[i].title = inihelper_getstringdup(settingfile, &error, sectionName, "title"); |
|
61 result->settings[i].engineCommand = inihelper_getstringdup(settingfile, &error, sectionName, "command"); |
|
62 result->settings[i].image = inihelper_getstringdup(settingfile, &error, sectionName, "image"); |
|
63 result->settings[i].checkOverMax = inihelper_getbool(settingfile, &error, sectionName, "checkOverMax"); |
|
64 result->settings[i].times1000 = inihelper_getbool(settingfile, &error, sectionName, "times1000"); |
|
65 result->settings[i].min = inihelper_getint(settingfile, &error, sectionName, "min"); |
|
66 result->settings[i].max = inihelper_getint(settingfile, &error, sectionName, "max"); |
|
67 result->settings[i].def = inihelper_getint(settingfile, &error, sectionName, "default"); |
|
68 if(error) { |
|
69 flib_log_e("Missing or malformed ini parameter in file %s, section %s", settingpath, sectionName); |
|
70 goto handleError; |
|
71 } |
|
72 } |
|
73 |
|
74 for(int i=0; i<result->modCount; i++) { |
|
75 char *sectionName = iniparser_getsecname(modfile, i); |
|
76 if(!sectionName) { |
|
77 goto handleError; |
|
78 } |
|
79 |
|
80 bool error = false; |
|
81 result->mods[i].iniName = inihelper_strdupnull(sectionName); |
|
82 result->mods[i].bitmaskIndex = inihelper_getint(modfile, &error, sectionName, "bitmaskIndex"); |
|
83 if(error) { |
|
84 flib_log_e("Missing or malformed ini parameter in file %s, section %s", modpath, sectionName); |
|
85 goto handleError; |
|
86 } |
|
87 } |
|
88 |
|
89 iniparser_freedict(settingfile); |
|
90 iniparser_freedict(modfile); |
|
91 return result; |
|
92 |
|
93 handleError: |
|
94 freeCfgMeta(result); |
|
95 iniparser_freedict(settingfile); |
|
96 iniparser_freedict(modfile); |
|
97 return NULL; |
|
98 } |
|
99 |
|
100 void flib_cfg_meta_destroy(flib_cfg_meta *metainfo) { |
|
101 freeCfgMeta(metainfo); |
|
102 } |
|
103 |
|
104 flib_cfg *flib_cfg_create(const flib_cfg_meta *meta, const char *schemeName) { |
|
105 flib_cfg *result = calloc(1, sizeof(flib_cfg)); |
|
106 if(!meta || !result || !schemeName) { |
|
107 return NULL; |
|
108 } |
|
109 |
|
110 result->modCount = meta->modCount; |
|
111 result->settingCount = meta->settingCount; |
|
112 result->schemeName = inihelper_strdupnull(schemeName); |
|
113 result->mods = calloc(meta->modCount, sizeof(*result->mods)); |
|
114 result->settings = calloc(meta->settingCount, sizeof(*result->settings)); |
|
115 |
|
116 if(!result->mods || !result->settings || !result->schemeName) { |
|
117 flib_cfg_destroy(result); |
|
118 return NULL; |
|
119 } |
|
120 |
|
121 for(int i=0; i<meta->settingCount; i++) { |
|
122 result->settings[i] = meta->settings[i].def; |
|
123 } |
|
124 return result; |
|
125 } |
|
126 |
|
127 flib_cfg *flib_cfg_from_ini_handleError(flib_cfg *result, dictionary *settingfile) { |
|
128 iniparser_freedict(settingfile); |
|
129 flib_cfg_destroy(result); |
|
130 return NULL; |
|
131 } |
|
132 |
|
133 flib_cfg *flib_cfg_from_ini(const flib_cfg_meta *meta, const char *filename) { |
|
134 if(!meta || !filename) { |
|
135 return NULL; |
|
136 } |
|
137 dictionary *settingfile = iniparser_load(filename); |
|
138 if(!settingfile) { |
|
139 return NULL; |
|
140 } |
|
141 |
|
142 bool error = false; |
|
143 char *schemename = inihelper_getstring(settingfile, &error, "Scheme", "name"); |
|
144 if(!schemename) { |
|
145 return flib_cfg_from_ini_handleError(NULL, settingfile); |
|
146 } |
|
147 |
|
148 flib_cfg *result = flib_cfg_create(meta, schemename); |
|
149 |
|
150 for(int i=0; i<meta->settingCount; i++) { |
|
151 char *key = inihelper_createDictKey("BasicSettings", meta->settings[i].iniName); |
|
152 if(!key) { |
|
153 return flib_cfg_from_ini_handleError(result, settingfile); |
|
154 } |
|
155 result->settings[i] = iniparser_getint(settingfile, key, meta->settings[i].def); |
|
156 free(key); |
|
157 } |
|
158 for(int i=0; i<meta->modCount; i++) { |
|
159 char *key = inihelper_createDictKey("GameMods", meta->mods[i].iniName); |
|
160 if(!key) { |
|
161 return flib_cfg_from_ini_handleError(result, settingfile); |
|
162 } |
|
163 result->mods[i] = iniparser_getboolean(settingfile, key, false); |
|
164 free(key); |
|
165 } |
|
166 iniparser_freedict(settingfile); |
|
167 return result; |
|
168 } |
|
169 |
|
170 int flib_cfg_to_ini(const flib_cfg_meta *meta, const char *filename, const flib_cfg *config) { |
|
171 int result = -1; |
|
172 if(meta && filename && config && config->modCount==meta->modCount && config->settingCount==meta->settingCount) { |
|
173 dictionary *dict = dictionary_new(0); |
|
174 if(dict) { |
|
175 bool error = false; |
|
176 // Add the sections |
|
177 error |= iniparser_set(dict, "Scheme", NULL); |
|
178 error |= iniparser_set(dict, "BasicSettings", NULL); |
|
179 error |= iniparser_set(dict, "GameMods", NULL); |
|
180 |
|
181 // Add the values |
|
182 error |= inihelper_setstr(dict, "Scheme", "name", config->schemeName); |
|
183 for(int i=0; i<config->settingCount; i++) { |
|
184 error |= inihelper_setint(dict, "BasicSettings", meta->settings[i].iniName, config->settings[i]); |
|
185 } |
|
186 for(int i=0; i<config->modCount; i++) { |
|
187 error |= inihelper_setbool(dict, "GameMods", meta->mods[i].iniName, config->mods[i]); |
|
188 } |
|
189 if(!error) { |
|
190 FILE *inifile = fopen(filename, "wb"); |
|
191 if(inifile) { |
|
192 iniparser_dump_ini(dict, inifile); |
|
193 fclose(inifile); |
|
194 result = 0; |
|
195 } |
|
196 } |
|
197 dictionary_del(dict); |
|
198 } |
|
199 } |
|
200 return result; |
|
201 } |
|
202 |
|
203 void flib_cfg_destroy(flib_cfg* cfg) { |
|
204 if(cfg) { |
|
205 free(cfg->mods); |
|
206 free(cfg->settings); |
|
207 free(cfg->schemeName); |
|
208 free(cfg); |
|
209 } |
|
210 } |