28 #include <stdlib.h> |
28 #include <stdlib.h> |
29 #include <limits.h> |
29 #include <limits.h> |
30 #include <string.h> |
30 #include <string.h> |
31 |
31 |
32 static char *makePrefixedName(int schemeIndex, const char *settingName) { |
32 static char *makePrefixedName(int schemeIndex, const char *settingName) { |
33 return flib_asprintf("%i\\%s", schemeIndex, settingName); |
33 return flib_asprintf("%i\\%s", schemeIndex, settingName); |
34 } |
34 } |
35 |
35 |
36 static int readSettingsFromIni(flib_ini *ini, flib_scheme *scheme, int index) { |
36 static int readSettingsFromIni(flib_ini *ini, flib_scheme *scheme, int index) { |
37 bool error = false; |
37 bool error = false; |
38 for(int i=0; i<flib_meta.settingCount && !error; i++) { |
38 for(int i=0; i<flib_meta.settingCount && !error; i++) { |
39 char *key = makePrefixedName(index, flib_meta.settings[i].name); |
39 char *key = makePrefixedName(index, flib_meta.settings[i].name); |
40 if(!key) { |
40 if(!key) { |
41 error = true; |
41 error = true; |
42 } else if(flib_ini_get_int_opt(ini, &scheme->settings[i], key, flib_meta.settings[i].def)) { |
42 } else if(flib_ini_get_int_opt(ini, &scheme->settings[i], key, flib_meta.settings[i].def)) { |
43 flib_log_e("Error reading setting %s in schemes file.", key); |
43 flib_log_e("Error reading setting %s in schemes file.", key); |
44 error = true; |
44 error = true; |
45 } |
45 } |
46 free(key); |
46 free(key); |
47 } |
47 } |
48 return error; |
48 return error; |
49 } |
49 } |
50 |
50 |
51 static int readModsFromIni(flib_ini *ini, flib_scheme *scheme, int index) { |
51 static int readModsFromIni(flib_ini *ini, flib_scheme *scheme, int index) { |
52 bool error = false; |
52 bool error = false; |
53 for(int i=0; i<flib_meta.modCount && !error; i++) { |
53 for(int i=0; i<flib_meta.modCount && !error; i++) { |
54 char *key = makePrefixedName(index, flib_meta.mods[i].name); |
54 char *key = makePrefixedName(index, flib_meta.mods[i].name); |
55 if(!key) { |
55 if(!key) { |
56 error = true; |
56 error = true; |
57 } else if(flib_ini_get_bool_opt(ini, &scheme->mods[i], key, false)) { |
57 } else if(flib_ini_get_bool_opt(ini, &scheme->mods[i], key, false)) { |
58 flib_log_e("Error reading mod %s in schemes file.", key); |
58 flib_log_e("Error reading mod %s in schemes file.", key); |
59 error = true; |
59 error = true; |
60 } |
60 } |
61 free(key); |
61 free(key); |
62 } |
62 } |
63 return error; |
63 return error; |
64 } |
64 } |
65 |
65 |
66 static flib_scheme *readSchemeFromIni(flib_ini *ini, int index) { |
66 static flib_scheme *readSchemeFromIni(flib_ini *ini, int index) { |
67 flib_scheme *result = NULL; |
67 flib_scheme *result = NULL; |
68 char *schemeNameKey = makePrefixedName(index+1, "name"); |
68 char *schemeNameKey = makePrefixedName(index+1, "name"); |
69 if(schemeNameKey) { |
69 if(schemeNameKey) { |
70 char *schemeName = NULL; |
70 char *schemeName = NULL; |
71 if(!flib_ini_get_str_opt(ini, &schemeName, schemeNameKey, "Unnamed")) { |
71 if(!flib_ini_get_str_opt(ini, &schemeName, schemeNameKey, "Unnamed")) { |
72 flib_scheme *tmpScheme = flib_scheme_create(schemeName); |
72 flib_scheme *tmpScheme = flib_scheme_create(schemeName); |
73 if(tmpScheme) { |
73 if(tmpScheme) { |
74 if(!readSettingsFromIni(ini, tmpScheme, index) && !readModsFromIni(ini, tmpScheme, index)) { |
74 if(!readSettingsFromIni(ini, tmpScheme, index) && !readModsFromIni(ini, tmpScheme, index)) { |
75 result = tmpScheme; |
75 result = tmpScheme; |
76 tmpScheme = NULL; |
76 tmpScheme = NULL; |
77 } |
77 } |
78 } |
78 } |
79 flib_scheme_destroy(tmpScheme); |
79 flib_scheme_destroy(tmpScheme); |
80 } |
80 } |
81 free(schemeName); |
81 free(schemeName); |
82 } |
82 } |
83 free(schemeNameKey); |
83 free(schemeNameKey); |
84 return result; |
84 return result; |
85 } |
85 } |
86 |
86 |
87 static flib_schemelist *fromIniHandleError(flib_schemelist *result, flib_ini *ini) { |
87 static flib_schemelist *fromIniHandleError(flib_schemelist *result, flib_ini *ini) { |
88 flib_ini_destroy(ini); |
88 flib_ini_destroy(ini); |
89 flib_schemelist_destroy(result); |
89 flib_schemelist_destroy(result); |
90 return NULL; |
90 return NULL; |
91 } |
91 } |
92 |
92 |
93 flib_schemelist *flib_schemelist_from_ini(const char *filename) { |
93 flib_schemelist *flib_schemelist_from_ini(const char *filename) { |
94 if(log_badargs_if(filename==NULL)) { |
94 if(log_badargs_if(filename==NULL)) { |
95 return NULL; |
95 return NULL; |
96 } |
96 } |
97 |
97 |
98 flib_schemelist *list = NULL; |
98 flib_schemelist *list = NULL; |
99 flib_ini *ini = flib_ini_load(filename); |
99 flib_ini *ini = flib_ini_load(filename); |
100 if(!ini || flib_ini_enter_section(ini, "schemes")) { |
100 if(!ini || flib_ini_enter_section(ini, "schemes")) { |
101 flib_log_e("Missing file or missing section \"schemes\" in file %s.", filename); |
101 flib_log_e("Missing file or missing section \"schemes\" in file %s.", filename); |
102 return fromIniHandleError(list, ini); |
102 return fromIniHandleError(list, ini); |
103 } |
103 } |
104 |
104 |
105 list = flib_schemelist_create(); |
105 list = flib_schemelist_create(); |
106 if(!list) { |
106 if(!list) { |
107 return fromIniHandleError(list, ini); |
107 return fromIniHandleError(list, ini); |
108 } |
108 } |
109 |
109 |
110 int schemeCount = 0; |
110 int schemeCount = 0; |
111 if(flib_ini_get_int(ini, &schemeCount, "size")) { |
111 if(flib_ini_get_int(ini, &schemeCount, "size")) { |
112 flib_log_e("Missing or malformed scheme count in config file %s.", filename); |
112 flib_log_e("Missing or malformed scheme count in config file %s.", filename); |
113 return fromIniHandleError(list, ini); |
113 return fromIniHandleError(list, ini); |
114 } |
114 } |
115 |
115 |
116 for(int i=0; i<schemeCount; i++) { |
116 for(int i=0; i<schemeCount; i++) { |
117 flib_scheme *scheme = readSchemeFromIni(ini, i); |
117 flib_scheme *scheme = readSchemeFromIni(ini, i); |
118 if(!scheme || flib_schemelist_insert(list, scheme, i)) { |
118 if(!scheme || flib_schemelist_insert(list, scheme, i)) { |
119 flib_scheme_destroy(scheme); |
119 flib_scheme_destroy(scheme); |
120 flib_log_e("Error reading scheme %i from config file %s.", i, filename); |
120 flib_log_e("Error reading scheme %i from config file %s.", i, filename); |
121 return fromIniHandleError(list, ini); |
121 return fromIniHandleError(list, ini); |
122 } |
122 } |
123 } |
123 } |
124 |
124 |
125 |
125 |
126 flib_ini_destroy(ini); |
126 flib_ini_destroy(ini); |
127 return list; |
127 return list; |
128 } |
128 } |
129 |
129 |
130 static int writeSchemeToIni(const flib_scheme *scheme, flib_ini *ini, int index) { |
130 static int writeSchemeToIni(const flib_scheme *scheme, flib_ini *ini, int index) { |
131 bool error = false; |
131 bool error = false; |
132 |
132 |
133 char *key = makePrefixedName(index+1, "name"); |
133 char *key = makePrefixedName(index+1, "name"); |
134 error |= !key || flib_ini_set_str(ini, key, scheme->name); |
134 error |= !key || flib_ini_set_str(ini, key, scheme->name); |
135 free(key); |
135 free(key); |
136 |
136 |
137 for(int i=0; i<flib_meta.modCount && !error; i++) { |
137 for(int i=0; i<flib_meta.modCount && !error; i++) { |
138 char *key = makePrefixedName(index+1, flib_meta.mods[i].name); |
138 char *key = makePrefixedName(index+1, flib_meta.mods[i].name); |
139 error |= !key || flib_ini_set_bool(ini, key, scheme->mods[i]); |
139 error |= !key || flib_ini_set_bool(ini, key, scheme->mods[i]); |
140 free(key); |
140 free(key); |
141 } |
141 } |
142 |
142 |
143 for(int i=0; i<flib_meta.settingCount && !error; i++) { |
143 for(int i=0; i<flib_meta.settingCount && !error; i++) { |
144 char *key = makePrefixedName(index+1, flib_meta.settings[i].name); |
144 char *key = makePrefixedName(index+1, flib_meta.settings[i].name); |
145 error |= !key || flib_ini_set_int(ini, key, scheme->settings[i]); |
145 error |= !key || flib_ini_set_int(ini, key, scheme->settings[i]); |
146 free(key); |
146 free(key); |
147 } |
147 } |
148 return error; |
148 return error; |
149 } |
149 } |
150 |
150 |
151 int flib_schemelist_to_ini(const char *filename, const flib_schemelist *schemes) { |
151 int flib_schemelist_to_ini(const char *filename, const flib_schemelist *schemes) { |
152 int result = -1; |
152 int result = -1; |
153 if(!log_badargs_if2(filename==NULL, schemes==NULL)) { |
153 if(!log_badargs_if2(filename==NULL, schemes==NULL)) { |
154 flib_ini *ini = flib_ini_create(NULL); |
154 flib_ini *ini = flib_ini_create(NULL); |
155 if(ini && !flib_ini_create_section(ini, "schemes")) { |
155 if(ini && !flib_ini_create_section(ini, "schemes")) { |
156 bool error = false; |
156 bool error = false; |
157 error |= flib_ini_set_int(ini, "size", schemes->schemeCount); |
157 error |= flib_ini_set_int(ini, "size", schemes->schemeCount); |
158 for(int i=0; i<schemes->schemeCount && !error; i++) { |
158 for(int i=0; i<schemes->schemeCount && !error; i++) { |
159 error |= writeSchemeToIni(schemes->schemes[i], ini, i); |
159 error |= writeSchemeToIni(schemes->schemes[i], ini, i); |
160 } |
160 } |
161 |
161 |
162 if(!error) { |
162 if(!error) { |
163 result = flib_ini_save(ini, filename); |
163 result = flib_ini_save(ini, filename); |
164 } |
164 } |
165 } |
165 } |
166 flib_ini_destroy(ini); |
166 flib_ini_destroy(ini); |
167 } |
167 } |
168 return result; |
168 return result; |
169 } |
169 } |
170 |
170 |
171 flib_schemelist *flib_schemelist_create() { |
171 flib_schemelist *flib_schemelist_create() { |
172 return flib_calloc(1, sizeof(flib_schemelist)); |
172 return flib_calloc(1, sizeof(flib_schemelist)); |
173 } |
173 } |
174 |
174 |
175 void flib_schemelist_destroy(flib_schemelist *list) { |
175 void flib_schemelist_destroy(flib_schemelist *list) { |
176 if(list) { |
176 if(list) { |
177 for(int i=0; i<list->schemeCount; i++) { |
177 for(int i=0; i<list->schemeCount; i++) { |
178 flib_scheme_destroy(list->schemes[i]); |
178 flib_scheme_destroy(list->schemes[i]); |
179 } |
179 } |
180 free(list->schemes); |
180 free(list->schemes); |
181 free(list); |
181 free(list); |
182 } |
182 } |
183 } |
183 } |
184 |
184 |
185 flib_scheme *flib_schemelist_find(flib_schemelist *list, const char *name) { |
185 flib_scheme *flib_schemelist_find(flib_schemelist *list, const char *name) { |
186 if(!log_badargs_if2(list==NULL, name==NULL)) { |
186 if(!log_badargs_if2(list==NULL, name==NULL)) { |
187 for(int i=0; i<list->schemeCount; i++) { |
187 for(int i=0; i<list->schemeCount; i++) { |
188 if(!strcmp(name, list->schemes[i]->name)) { |
188 if(!strcmp(name, list->schemes[i]->name)) { |
189 return list->schemes[i]; |
189 return list->schemes[i]; |
190 } |
190 } |
191 } |
191 } |
192 } |
192 } |
193 return NULL; |
193 return NULL; |
194 } |
194 } |
195 |
195 |
196 GENERATE_STATIC_LIST_INSERT(insertScheme, flib_scheme*) |
196 GENERATE_STATIC_LIST_INSERT(insertScheme, flib_scheme*) |
197 GENERATE_STATIC_LIST_DELETE(deleteScheme, flib_scheme*) |
197 GENERATE_STATIC_LIST_DELETE(deleteScheme, flib_scheme*) |
198 |
198 |
199 int flib_schemelist_insert(flib_schemelist *list, flib_scheme *cfg, int pos) { |
199 int flib_schemelist_insert(flib_schemelist *list, flib_scheme *cfg, int pos) { |
200 if(!log_badargs_if2(list==NULL, cfg==NULL) |
200 if(!log_badargs_if2(list==NULL, cfg==NULL) |
201 && !insertScheme(&list->schemes, &list->schemeCount, cfg, pos)) { |
201 && !insertScheme(&list->schemes, &list->schemeCount, cfg, pos)) { |
202 return 0; |
202 return 0; |
203 } |
203 } |
204 return -1; |
204 return -1; |
205 } |
205 } |
206 |
206 |
207 int flib_schemelist_delete(flib_schemelist *list, int pos) { |
207 int flib_schemelist_delete(flib_schemelist *list, int pos) { |
208 if(!log_badargs_if(list==NULL)) { |
208 if(!log_badargs_if(list==NULL)) { |
209 flib_scheme *elem = list->schemes[pos]; |
209 flib_scheme *elem = list->schemes[pos]; |
210 if(!deleteScheme(&list->schemes, &list->schemeCount, pos)) { |
210 if(!deleteScheme(&list->schemes, &list->schemeCount, pos)) { |
211 flib_scheme_destroy(elem); |
211 flib_scheme_destroy(elem); |
212 return 0; |
212 return 0; |
213 } |
213 } |
214 } |
214 } |
215 return -1; |
215 return -1; |
216 } |
216 } |