Commit | Line | Data |
---|---|---|
3719602c PC |
1 | /* Copyright (C) 2010-2020 The RetroArch team |
2 | * | |
3 | * --------------------------------------------------------------------------------------- | |
4 | * The following license statement only applies to this file (config_file.h). | |
5 | * --------------------------------------------------------------------------------------- | |
6 | * | |
7 | * Permission is hereby granted, free of charge, | |
8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), | |
9 | * to deal in the Software without restriction, including without limitation the rights to | |
10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, | |
11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | |
12 | * | |
13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | |
14 | * | |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |
16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
21 | */ | |
22 | ||
23 | #ifndef __LIBRETRO_SDK_CONFIG_FILE_H | |
24 | #define __LIBRETRO_SDK_CONFIG_FILE_H | |
25 | ||
26 | #include <retro_common_api.h> | |
27 | ||
28 | RETRO_BEGIN_DECLS | |
29 | ||
30 | #include <stdio.h> | |
31 | #include <stdint.h> | |
32 | #include <stddef.h> | |
33 | ||
34 | #include <boolean.h> | |
35 | ||
36 | #define CONFIG_GET_BOOL_BASE(conf, base, var, key) do { \ | |
37 | bool tmp = false; \ | |
38 | if (config_get_bool(conf, key, &tmp)) \ | |
39 | base->var = tmp; \ | |
40 | } while(0) | |
41 | ||
42 | #define CONFIG_GET_INT_BASE(conf, base, var, key) do { \ | |
43 | int tmp = 0; \ | |
44 | if (config_get_int(conf, key, &tmp)) \ | |
45 | base->var = tmp; \ | |
46 | } while(0) | |
47 | ||
48 | #define CONFIG_GET_FLOAT_BASE(conf, base, var, key) do { \ | |
49 | float tmp = 0.0f; \ | |
50 | if (config_get_float(conf, key, &tmp)) \ | |
51 | base->var = tmp; \ | |
52 | } while(0) | |
53 | ||
54 | struct config_file | |
55 | { | |
56 | char *path; | |
57 | struct config_entry_list **entries_map; | |
58 | struct config_entry_list *entries; | |
59 | struct config_entry_list *tail; | |
60 | struct config_entry_list *last; | |
61 | struct config_include_list *includes; | |
62 | struct path_linked_list *references; | |
63 | unsigned include_depth; | |
64 | bool guaranteed_no_duplicates; | |
65 | bool modified; | |
66 | }; | |
67 | ||
68 | typedef struct config_file config_file_t; | |
69 | ||
70 | struct config_file_cb | |
71 | { | |
72 | void (*config_file_new_entry_cb)(char*, char*); | |
73 | }; | |
74 | ||
75 | typedef struct config_file_cb config_file_cb_t ; | |
76 | ||
77 | /* Config file format | |
78 | * - # are treated as comments. Rest of the line is ignored. | |
79 | * - Format is: key = value. There can be as many spaces as you like in-between. | |
80 | * - Value can be wrapped inside "" for multiword strings. (foo = "hai u") | |
81 | * - #include includes a config file in-place. | |
82 | * | |
83 | * Path is relative to where config file was loaded unless an absolute path is chosen. | |
84 | * Key/value pairs from an #include are read-only, and cannot be modified. | |
85 | */ | |
86 | ||
87 | /** | |
88 | * config_file_new: | |
89 | * | |
90 | * Loads a config file. | |
91 | * If @path is NULL, will create an empty config file. | |
92 | * | |
93 | * @return Returns NULL if file doesn't exist. | |
94 | **/ | |
95 | config_file_t *config_file_new(const char *path); | |
96 | ||
97 | config_file_t *config_file_new_alloc(void); | |
98 | ||
99 | /** | |
100 | * config_file_initialize: | |
101 | * | |
102 | * Leaf function. | |
103 | **/ | |
104 | void config_file_initialize(struct config_file *conf); | |
105 | ||
106 | /** | |
107 | * config_file_new_with_callback: | |
108 | * | |
109 | * Loads a config file. | |
110 | * If @path is NULL, will create an empty config file. | |
111 | * Includes cb callbacks to run custom code during config file processing. | |
112 | * | |
113 | * @return Returns NULL if file doesn't exist. | |
114 | **/ | |
115 | config_file_t *config_file_new_with_callback( | |
116 | const char *path, config_file_cb_t *cb); | |
117 | ||
118 | /** | |
119 | * config_file_new_from_string: | |
120 | * | |
121 | * Load a config file from a string. | |
122 | * | |
123 | * NOTE: This will modify @from_string. | |
124 | * Pass a copy of source string if original | |
125 | * contents must be preserved | |
126 | **/ | |
127 | config_file_t *config_file_new_from_string(char *from_string, | |
128 | const char *path); | |
129 | ||
130 | config_file_t *config_file_new_from_path_to_string(const char *path); | |
131 | ||
132 | /** | |
133 | * config_file_free: | |
134 | * | |
135 | * Frees config file. | |
136 | **/ | |
137 | void config_file_free(config_file_t *conf); | |
138 | ||
139 | void config_file_add_reference(config_file_t *conf, char *path); | |
140 | ||
141 | bool config_file_deinitialize(config_file_t *conf); | |
142 | ||
143 | /** | |
144 | * config_append_file: | |
145 | * | |
146 | * Loads a new config, and appends its data to @conf. | |
147 | * The key-value pairs of the new config file takes priority over the old. | |
148 | **/ | |
149 | bool config_append_file(config_file_t *conf, const char *path); | |
150 | ||
151 | /* All extract functions return true when value is valid and exists. | |
152 | * Returns false otherwise. */ | |
153 | ||
154 | struct config_entry_list | |
155 | { | |
156 | char *key; | |
157 | char *value; | |
158 | struct config_entry_list *next; | |
159 | /* If we got this from an #include, | |
160 | * do not allow overwrite. */ | |
161 | bool readonly; | |
162 | }; | |
163 | ||
164 | struct config_file_entry | |
165 | { | |
166 | const char *key; | |
167 | const char *value; | |
168 | /* Used intentionally. Opaque here. */ | |
169 | const struct config_entry_list *next; | |
170 | }; | |
171 | ||
172 | struct config_entry_list *config_get_entry( | |
173 | const config_file_t *conf, const char *key); | |
174 | ||
175 | /** | |
176 | * config_get_entry_list_head: | |
177 | * | |
178 | * Leaf function. | |
179 | **/ | |
180 | bool config_get_entry_list_head(config_file_t *conf, | |
181 | struct config_file_entry *entry); | |
182 | ||
183 | /** | |
184 | * config_get_entry_list_next: | |
185 | * | |
186 | * Leaf function. | |
187 | **/ | |
188 | bool config_get_entry_list_next(struct config_file_entry *entry); | |
189 | ||
190 | /** | |
191 | * config_get_double: | |
192 | * | |
193 | * Extracts a double from config file. | |
194 | * | |
195 | * Hidden non-leaf function cost: | |
196 | * - Calls config_get_entry() | |
197 | * - Calls strtod | |
198 | * | |
199 | * @return True if double found, otherwise false. | |
200 | **/ | |
201 | bool config_get_double(config_file_t *conf, const char *entry, double *in); | |
202 | ||
203 | /** | |
204 | * config_get_float: | |
205 | * | |
206 | * Extracts a float from config file. | |
207 | * | |
208 | * Hidden non-leaf function cost: | |
209 | * - Calls config_get_entry() | |
210 | * - Calls strtod | |
211 | * | |
212 | * @return true if found, otherwise false. | |
213 | **/ | |
214 | bool config_get_float(config_file_t *conf, const char *entry, float *in); | |
215 | ||
216 | /* Extracts an int from config file. */ | |
217 | bool config_get_int(config_file_t *conf, const char *entry, int *in); | |
218 | ||
219 | /* Extracts an uint from config file. */ | |
220 | bool config_get_uint(config_file_t *conf, const char *entry, unsigned *in); | |
221 | ||
222 | /* Extracts an size_t from config file. */ | |
223 | bool config_get_size_t(config_file_t *conf, const char *key, size_t *in); | |
224 | ||
225 | #if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L | |
226 | /* Extracts an uint64 from config file. */ | |
227 | bool config_get_uint64(config_file_t *conf, const char *entry, uint64_t *in); | |
228 | #endif | |
229 | ||
230 | /* Extracts an unsigned int from config file treating input as hex. */ | |
231 | bool config_get_hex(config_file_t *conf, const char *entry, unsigned *in); | |
232 | ||
233 | /** | |
234 | * config_get_char: | |
235 | * | |
236 | * Extracts a single char from config file. | |
237 | * If value consists of several chars, this is an error. | |
238 | * | |
239 | * Hidden non-leaf function cost: | |
240 | * - Calls config_get_entry() | |
241 | * | |
242 | * @return true if found, otherwise false. | |
243 | **/ | |
244 | bool config_get_char(config_file_t *conf, const char *entry, char *in); | |
245 | ||
246 | /** | |
247 | * config_get_string: | |
248 | * | |
249 | * Extracts an allocated string in *in. This must be free()-d if | |
250 | * this function succeeds. | |
251 | * | |
252 | * Hidden non-leaf function cost: | |
253 | * - Calls config_get_entry() | |
254 | * - Calls strdup | |
255 | * | |
256 | * @return true if found, otherwise false. | |
257 | **/ | |
258 | bool config_get_string(config_file_t *conf, const char *entry, char **in); | |
259 | ||
260 | /* Extracts a string to a preallocated buffer. Avoid memory allocation. */ | |
261 | bool config_get_array(config_file_t *conf, const char *entry, char *s, size_t len); | |
262 | ||
263 | /** | |
264 | * config_get_config_path: | |
265 | * | |
266 | * Extracts a string to a preallocated buffer. | |
267 | * Avoid memory allocation. | |
268 | * | |
269 | * Hidden non-leaf function cost: | |
270 | * - Calls strlcpy | |
271 | **/ | |
272 | bool config_get_config_path(config_file_t *conf, char *s, size_t len); | |
273 | ||
274 | /* Extracts a string to a preallocated buffer. Avoid memory allocation. | |
275 | * Recognized magic like ~/. Similar to config_get_array() otherwise. */ | |
276 | bool config_get_path(config_file_t *conf, const char *entry, char *s, size_t len); | |
277 | ||
278 | /** | |
279 | * config_get_bool: | |
280 | * | |
281 | * Extracts a boolean from config. | |
282 | * Valid boolean true are "true" and "1". Valid false are "false" and "0". | |
283 | * Other values will be treated as an error. | |
284 | * | |
285 | * Hidden non-leaf function cost: | |
286 | * - Calls string_is_equal() x times | |
287 | * | |
288 | * @return true if preconditions are true, otherwise false. | |
289 | **/ | |
290 | bool config_get_bool(config_file_t *conf, const char *entry, bool *in); | |
291 | ||
292 | /* Setters. Similar to the getters. | |
293 | * Will not write to entry if the entry was obtained from an #include. */ | |
294 | void config_set_double(config_file_t *conf, const char *entry, double value); | |
295 | void config_set_float(config_file_t *conf, const char *entry, float value); | |
296 | void config_set_int(config_file_t *conf, const char *entry, int val); | |
297 | void config_set_hex(config_file_t *conf, const char *entry, unsigned val); | |
298 | void config_set_uint64(config_file_t *conf, const char *entry, uint64_t val); | |
299 | void config_set_char(config_file_t *conf, const char *entry, char val); | |
300 | void config_set_string(config_file_t *conf, const char *entry, const char *val); | |
301 | void config_unset(config_file_t *conf, const char *key); | |
302 | void config_set_path(config_file_t *conf, const char *entry, const char *val); | |
303 | ||
304 | /** | |
305 | * config_set_bool: | |
306 | ||
307 | * TODO/FIXME - could be turned into a trivial macro or removed | |
308 | **/ | |
309 | void config_set_bool(config_file_t *conf, const char *entry, bool val); | |
310 | ||
311 | void config_set_uint(config_file_t *conf, const char *key, unsigned int val); | |
312 | ||
313 | /** | |
314 | * config_file_write: | |
315 | * | |
316 | * Write the current config to a file. | |
317 | **/ | |
318 | bool config_file_write(config_file_t *conf, const char *path, bool val); | |
319 | ||
320 | /** | |
321 | * config_file_dump: | |
322 | * | |
323 | * Dump the current config to an already opened file. | |
324 | * Does not close the file. | |
325 | **/ | |
326 | void config_file_dump(config_file_t *conf, FILE *file, bool val); | |
327 | ||
328 | RETRO_END_DECLS | |
329 | ||
330 | #endif |