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 }