Mercurial > audlegacy
comparison libaudacious/configfile.c @ 0:cb178e5ad177 trunk
[svn] Import audacious source.
author | nenolod |
---|---|
date | Mon, 24 Oct 2005 03:06:47 -0700 |
parents | |
children | dc9aaf5eba90 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:cb178e5ad177 |
---|---|
1 /* XMMS - Cross-platform multimedia player | |
2 * Copyright (C) 1998-2002 Peter Alm, Mikael Alm, Olle Hallnas, | |
3 * Thomas Nilsson and 4Front Technologies | |
4 * Copyright (C) 1999-2002 Haavard Kvaalen | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
19 */ | |
20 | |
21 #if defined(HAVE_CONFIG_H) | |
22 #include "../config.h" | |
23 #endif | |
24 | |
25 #include "configfile.h" | |
26 | |
27 #include <stdio.h> | |
28 #include <string.h> | |
29 #include <stdlib.h> | |
30 #include <locale.h> | |
31 | |
32 #include <unistd.h> | |
33 #include <sys/stat.h> | |
34 | |
35 | |
36 typedef gboolean(*XmmsCfgValueReadFunc) (ConfigFile * config_file, | |
37 const gchar * section, | |
38 const gchar * key, | |
39 gpointer * value); | |
40 | |
41 typedef void (*XmmsCfgValueWriteFunc) (ConfigFile * config_file, | |
42 const gchar * section, | |
43 const gchar * key, | |
44 gpointer * value); | |
45 | |
46 struct _XmmsCfgValueTypeInfo { | |
47 XmmsCfgValueReadFunc read; | |
48 XmmsCfgValueWriteFunc write; | |
49 }; | |
50 | |
51 typedef struct _XmmsCfgValueTypeInfo XmmsCfgValueTypeInfo; | |
52 | |
53 | |
54 static XmmsCfgValueTypeInfo xmms_cfg_value_type_func[] = { | |
55 {(XmmsCfgValueReadFunc) xmms_cfg_read_int, | |
56 (XmmsCfgValueWriteFunc) xmms_cfg_write_int}, | |
57 {(XmmsCfgValueReadFunc) xmms_cfg_read_float, | |
58 (XmmsCfgValueWriteFunc) xmms_cfg_write_float}, | |
59 {(XmmsCfgValueReadFunc) xmms_cfg_read_boolean, | |
60 (XmmsCfgValueWriteFunc) xmms_cfg_write_boolean}, | |
61 {(XmmsCfgValueReadFunc) xmms_cfg_read_string, | |
62 (XmmsCfgValueWriteFunc) xmms_cfg_write_string} | |
63 }; | |
64 | |
65 | |
66 static ConfigSection *xmms_cfg_create_section(ConfigFile * cfg, | |
67 const gchar * name); | |
68 static ConfigLine *xmms_cfg_create_string(ConfigSection * section, | |
69 const gchar * key, | |
70 const gchar * value); | |
71 static ConfigSection *xmms_cfg_find_section(ConfigFile * cfg, | |
72 const gchar * name); | |
73 static ConfigLine *xmms_cfg_find_string(ConfigSection * section, | |
74 const gchar * key); | |
75 | |
76 | |
77 ConfigFile *xmms_cfg_new(void) | |
78 { | |
79 return g_new0(ConfigFile, 1); | |
80 } | |
81 | |
82 gboolean xmms_cfg_read_value(ConfigFile * config_file, | |
83 const gchar * section, const gchar * key, | |
84 XmmsCfgValueType value_type, gpointer * value) | |
85 { | |
86 return xmms_cfg_value_type_func[value_type].read(config_file, | |
87 section, key, value); | |
88 } | |
89 | |
90 void xmms_cfg_write_value(ConfigFile * config_file, | |
91 const gchar * section, const gchar * key, | |
92 XmmsCfgValueType value_type, gpointer * value) | |
93 { | |
94 xmms_cfg_value_type_func[value_type].read(config_file, | |
95 section, key, value); | |
96 } | |
97 | |
98 ConfigFile *xmms_cfg_open_file(const gchar * filename) | |
99 { | |
100 ConfigFile *cfg; | |
101 | |
102 gchar *buffer, **lines, *tmp; | |
103 gint i; | |
104 ConfigSection *section = NULL; | |
105 | |
106 g_return_val_if_fail(filename != NULL, FALSE); | |
107 | |
108 if (!g_file_get_contents(filename, &buffer, NULL, NULL)) | |
109 return NULL; | |
110 | |
111 cfg = g_malloc0(sizeof(ConfigFile)); | |
112 lines = g_strsplit(buffer, "\n", 0); | |
113 g_free(buffer); | |
114 i = 0; | |
115 while (lines[i]) { | |
116 if (lines[i][0] == '[') { | |
117 if ((tmp = strchr(lines[i], ']'))) { | |
118 *tmp = '\0'; | |
119 section = xmms_cfg_create_section(cfg, &lines[i][1]); | |
120 } | |
121 } else if (lines[i][0] != '#' && section) { | |
122 if ((tmp = strchr(lines[i], '='))) { | |
123 *tmp = '\0'; | |
124 tmp++; | |
125 xmms_cfg_create_string(section, lines[i], tmp); | |
126 } | |
127 } | |
128 i++; | |
129 } | |
130 g_strfreev(lines); | |
131 return cfg; | |
132 } | |
133 | |
134 gchar *xmms_cfg_get_default_filename(void) | |
135 { | |
136 static gchar *filename = NULL; | |
137 if (!filename) | |
138 filename = | |
139 g_strconcat(g_get_home_dir(), "/", BMP_RCPATH, "/config", | |
140 NULL); | |
141 return filename; | |
142 } | |
143 | |
144 ConfigFile *xmms_cfg_open_default_file(void) | |
145 { | |
146 ConfigFile *ret; | |
147 | |
148 ret = xmms_cfg_open_file(xmms_cfg_get_default_filename()); | |
149 if (!ret) | |
150 ret = xmms_cfg_new(); | |
151 return ret; | |
152 } | |
153 | |
154 gboolean xmms_cfg_write_file(ConfigFile * cfg, const gchar * filename) | |
155 { | |
156 FILE *file; | |
157 GList *section_list, *line_list; | |
158 ConfigSection *section; | |
159 ConfigLine *line; | |
160 | |
161 g_return_val_if_fail(cfg != NULL, FALSE); | |
162 g_return_val_if_fail(filename != NULL, FALSE); | |
163 | |
164 if (!(file = fopen(filename, "w"))) | |
165 return FALSE; | |
166 | |
167 section_list = cfg->sections; | |
168 while (section_list) { | |
169 section = (ConfigSection *) section_list->data; | |
170 if (section->lines) { | |
171 fprintf(file, "[%s]\n", section->name); | |
172 line_list = section->lines; | |
173 while (line_list) { | |
174 line = (ConfigLine *) line_list->data; | |
175 fprintf(file, "%s=%s\n", line->key, line->value); | |
176 line_list = g_list_next(line_list); | |
177 } | |
178 fprintf(file, "\n"); | |
179 } | |
180 section_list = g_list_next(section_list); | |
181 } | |
182 fclose(file); | |
183 return TRUE; | |
184 } | |
185 | |
186 gboolean xmms_cfg_write_default_file(ConfigFile * cfg) | |
187 { | |
188 return xmms_cfg_write_file(cfg, xmms_cfg_get_default_filename()); | |
189 } | |
190 | |
191 gboolean xmms_cfg_read_string(ConfigFile * cfg, const gchar * section, | |
192 const gchar * key, gchar ** value) | |
193 { | |
194 ConfigSection *sect; | |
195 ConfigLine *line; | |
196 | |
197 g_return_val_if_fail(cfg != NULL, FALSE); | |
198 g_return_val_if_fail(section != NULL, FALSE); | |
199 g_return_val_if_fail(key != NULL, FALSE); | |
200 g_return_val_if_fail(value != NULL, FALSE); | |
201 | |
202 if (!(sect = xmms_cfg_find_section(cfg, section))) | |
203 return FALSE; | |
204 if (!(line = xmms_cfg_find_string(sect, key))) | |
205 return FALSE; | |
206 *value = g_strdup(line->value); | |
207 return TRUE; | |
208 } | |
209 | |
210 gboolean xmms_cfg_read_int(ConfigFile * cfg, const gchar * section, | |
211 const gchar * key, gint * value) | |
212 { | |
213 gchar *str; | |
214 | |
215 g_return_val_if_fail(cfg != NULL, FALSE); | |
216 g_return_val_if_fail(section != NULL, FALSE); | |
217 g_return_val_if_fail(key != NULL, FALSE); | |
218 g_return_val_if_fail(value != NULL, FALSE); | |
219 | |
220 if (!xmms_cfg_read_string(cfg, section, key, &str)) | |
221 return FALSE; | |
222 *value = atoi(str); | |
223 g_free(str); | |
224 | |
225 return TRUE; | |
226 } | |
227 | |
228 gboolean xmms_cfg_read_boolean(ConfigFile * cfg, | |
229 const gchar * section, const gchar * key, | |
230 gboolean * value) | |
231 { | |
232 gchar *str; | |
233 | |
234 g_return_val_if_fail(cfg != NULL, FALSE); | |
235 g_return_val_if_fail(section != NULL, FALSE); | |
236 g_return_val_if_fail(key != NULL, FALSE); | |
237 g_return_val_if_fail(value != NULL, FALSE); | |
238 | |
239 if (!xmms_cfg_read_string(cfg, section, key, &str)) | |
240 return FALSE; | |
241 if (!strcasecmp(str, "TRUE")) | |
242 *value = TRUE; | |
243 else | |
244 *value = FALSE; | |
245 g_free(str); | |
246 return TRUE; | |
247 } | |
248 | |
249 gboolean xmms_cfg_read_float(ConfigFile * cfg, | |
250 const gchar * section, const gchar * key, | |
251 gfloat * value) | |
252 { | |
253 gchar *str, *locale; | |
254 | |
255 g_return_val_if_fail(cfg != NULL, FALSE); | |
256 g_return_val_if_fail(section != NULL, FALSE); | |
257 g_return_val_if_fail(key != NULL, FALSE); | |
258 g_return_val_if_fail(value != NULL, FALSE); | |
259 | |
260 if (!xmms_cfg_read_string(cfg, section, key, &str)) | |
261 return FALSE; | |
262 | |
263 locale = g_strdup(setlocale(LC_NUMERIC, NULL)); | |
264 setlocale(LC_NUMERIC, "C"); | |
265 *value = strtod(str, NULL); | |
266 setlocale(LC_NUMERIC, locale); | |
267 g_free(locale); | |
268 g_free(str); | |
269 | |
270 return TRUE; | |
271 } | |
272 | |
273 gboolean xmms_cfg_read_double(ConfigFile * cfg, | |
274 const gchar * section, const gchar * key, | |
275 gdouble * value) | |
276 { | |
277 gchar *str, *locale; | |
278 | |
279 g_return_val_if_fail(cfg != NULL, FALSE); | |
280 g_return_val_if_fail(section != NULL, FALSE); | |
281 g_return_val_if_fail(key != NULL, FALSE); | |
282 g_return_val_if_fail(value != NULL, FALSE); | |
283 | |
284 if (!xmms_cfg_read_string(cfg, section, key, &str)) | |
285 return FALSE; | |
286 | |
287 locale = g_strdup(setlocale(LC_NUMERIC, NULL)); | |
288 setlocale(LC_NUMERIC, "C"); | |
289 *value = strtod(str, NULL); | |
290 setlocale(LC_NUMERIC, locale); | |
291 g_free(locale); | |
292 g_free(str); | |
293 | |
294 return TRUE; | |
295 } | |
296 | |
297 void xmms_cfg_write_string(ConfigFile * cfg, | |
298 const gchar * section, const gchar * key, | |
299 gchar * value) | |
300 { | |
301 ConfigSection *sect; | |
302 ConfigLine *line; | |
303 | |
304 g_return_if_fail(cfg != NULL); | |
305 g_return_if_fail(section != NULL); | |
306 g_return_if_fail(key != NULL); | |
307 g_return_if_fail(value != NULL); | |
308 | |
309 sect = xmms_cfg_find_section(cfg, section); | |
310 if (!sect) | |
311 sect = xmms_cfg_create_section(cfg, section); | |
312 if ((line = xmms_cfg_find_string(sect, key))) { | |
313 g_free(line->value); | |
314 line->value = g_strstrip(g_strdup(value)); | |
315 } else | |
316 xmms_cfg_create_string(sect, key, value); | |
317 } | |
318 | |
319 void xmms_cfg_write_int(ConfigFile * cfg, | |
320 const gchar * section, const gchar * key, | |
321 gint value) | |
322 { | |
323 gchar *strvalue; | |
324 | |
325 g_return_if_fail(cfg != NULL); | |
326 g_return_if_fail(section != NULL); | |
327 g_return_if_fail(key != NULL); | |
328 | |
329 strvalue = g_strdup_printf("%d", value); | |
330 xmms_cfg_write_string(cfg, section, key, strvalue); | |
331 g_free(strvalue); | |
332 } | |
333 | |
334 void xmms_cfg_write_boolean(ConfigFile * cfg, | |
335 const gchar * section, const gchar * key, | |
336 gboolean value) | |
337 { | |
338 g_return_if_fail(cfg != NULL); | |
339 g_return_if_fail(section != NULL); | |
340 g_return_if_fail(key != NULL); | |
341 | |
342 if (value) | |
343 xmms_cfg_write_string(cfg, section, key, "TRUE"); | |
344 else | |
345 xmms_cfg_write_string(cfg, section, key, "FALSE"); | |
346 } | |
347 | |
348 void xmms_cfg_write_float(ConfigFile * cfg, | |
349 const gchar * section, const gchar * key, | |
350 gfloat value) | |
351 { | |
352 gchar *strvalue, *locale; | |
353 | |
354 g_return_if_fail(cfg != NULL); | |
355 g_return_if_fail(section != NULL); | |
356 g_return_if_fail(key != NULL); | |
357 | |
358 locale = g_strdup(setlocale(LC_NUMERIC, NULL)); | |
359 setlocale(LC_NUMERIC, "C"); | |
360 strvalue = g_strdup_printf("%g", value); | |
361 setlocale(LC_NUMERIC, locale); | |
362 xmms_cfg_write_string(cfg, section, key, strvalue); | |
363 g_free(locale); | |
364 g_free(strvalue); | |
365 } | |
366 | |
367 void xmms_cfg_write_double(ConfigFile * cfg, | |
368 const gchar * section, const gchar * key, | |
369 gdouble value) | |
370 { | |
371 gchar *strvalue, *locale; | |
372 | |
373 g_return_if_fail(cfg != NULL); | |
374 g_return_if_fail(section != NULL); | |
375 g_return_if_fail(key != NULL); | |
376 | |
377 locale = g_strdup(setlocale(LC_NUMERIC, NULL)); | |
378 setlocale(LC_NUMERIC, "C"); | |
379 strvalue = g_strdup_printf("%g", value); | |
380 setlocale(LC_NUMERIC, locale); | |
381 xmms_cfg_write_string(cfg, section, key, strvalue); | |
382 g_free(locale); | |
383 g_free(strvalue); | |
384 } | |
385 | |
386 void xmms_cfg_remove_key(ConfigFile * cfg, | |
387 const gchar * section, const gchar * key) | |
388 { | |
389 ConfigSection *sect; | |
390 ConfigLine *line; | |
391 | |
392 g_return_if_fail(cfg != NULL); | |
393 g_return_if_fail(section != NULL); | |
394 g_return_if_fail(key != NULL); | |
395 | |
396 if ((sect = xmms_cfg_find_section(cfg, section)) != NULL) { | |
397 if ((line = xmms_cfg_find_string(sect, key)) != NULL) { | |
398 g_free(line->key); | |
399 g_free(line->value); | |
400 g_free(line); | |
401 sect->lines = g_list_remove(sect->lines, line); | |
402 } | |
403 } | |
404 } | |
405 | |
406 void xmms_cfg_free(ConfigFile * cfg) | |
407 { | |
408 ConfigSection *section; | |
409 ConfigLine *line; | |
410 GList *section_list, *line_list; | |
411 | |
412 if (cfg == NULL) | |
413 return; | |
414 | |
415 section_list = cfg->sections; | |
416 while (section_list) { | |
417 section = (ConfigSection *) section_list->data; | |
418 g_free(section->name); | |
419 | |
420 line_list = section->lines; | |
421 while (line_list) { | |
422 line = (ConfigLine *) line_list->data; | |
423 g_free(line->key); | |
424 g_free(line->value); | |
425 g_free(line); | |
426 line_list = g_list_next(line_list); | |
427 } | |
428 g_list_free(section->lines); | |
429 g_free(section); | |
430 | |
431 section_list = g_list_next(section_list); | |
432 } | |
433 g_list_free(cfg->sections); | |
434 g_free(cfg); | |
435 } | |
436 | |
437 static ConfigSection *xmms_cfg_create_section(ConfigFile * cfg, | |
438 const gchar * name) | |
439 { | |
440 ConfigSection *section; | |
441 | |
442 section = g_new0(ConfigSection, 1); | |
443 section->name = g_strdup(name); | |
444 cfg->sections = g_list_append(cfg->sections, section); | |
445 | |
446 return section; | |
447 } | |
448 | |
449 static ConfigLine *xmms_cfg_create_string(ConfigSection * section, | |
450 const gchar * key, | |
451 const gchar * value) | |
452 { | |
453 ConfigLine *line; | |
454 | |
455 line = g_new0(ConfigLine, 1); | |
456 line->key = g_strstrip(g_strdup(key)); | |
457 line->value = g_strstrip(g_strdup(value)); | |
458 section->lines = g_list_append(section->lines, line); | |
459 | |
460 return line; | |
461 } | |
462 | |
463 static ConfigSection *xmms_cfg_find_section(ConfigFile * cfg, | |
464 const gchar * name) | |
465 { | |
466 ConfigSection *section; | |
467 GList *list; | |
468 | |
469 list = cfg->sections; | |
470 while (list) { | |
471 section = (ConfigSection *) list->data; | |
472 if (!strcasecmp(section->name, name)) | |
473 return section; | |
474 list = g_list_next(list); | |
475 } | |
476 return NULL; | |
477 } | |
478 | |
479 static ConfigLine *xmms_cfg_find_string(ConfigSection * section, | |
480 const gchar * key) | |
481 { | |
482 ConfigLine *line; | |
483 GList *list; | |
484 | |
485 list = section->lines; | |
486 while (list) { | |
487 line = (ConfigLine *) list->data; | |
488 if (!strcasecmp(line->key, key)) | |
489 return line; | |
490 list = g_list_next(list); | |
491 } | |
492 return NULL; | |
493 } |