Add copyright notices to all relevant files. (based on svn log)
[profile/ivi/pulseaudio.git] / src / pulsecore / conf-parser.c
1 /* $Id$ */
2
3 /***
4   This file is part of PulseAudio.
5
6   Copyright 2004-2006 Lennart Poettering
7
8   PulseAudio is free software; you can redistribute it and/or modify
9   it under the terms of the GNU Lesser General Public License as published
10   by the Free Software Foundation; either version 2 of the License,
11   or (at your option) any later version.
12
13   PulseAudio is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with PulseAudio; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21   USA.
22 ***/
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <assert.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <errno.h>
32
33 #include <pulse/xmalloc.h>
34
35 #include <pulsecore/core-error.h>
36 #include <pulsecore/log.h>
37 #include <pulsecore/core-util.h>
38
39 #include "conf-parser.h"
40
41 #define WHITESPACE " \t\n"
42 #define COMMENTS "#;\n"
43
44 /* Run the user supplied parser for an assignment */
45 static int next_assignment(const char *filename, unsigned line, const pa_config_item *t, const char *lvalue, const char *rvalue, void *userdata) {
46     assert(filename && t && lvalue && rvalue);
47
48     for (; t->parse; t++)
49         if (!strcmp(lvalue, t->lvalue))
50             return t->parse(filename, line, lvalue, rvalue, t->data, userdata);
51
52     pa_log("[%s:%u] Unknown lvalue '%s'.", filename, line, lvalue);
53
54     return -1;
55 }
56
57 /* Returns non-zero when c is contained in s */
58 static int in_string(char c, const char *s) {
59     assert(s);
60
61     for (; *s; s++)
62         if (*s == c)
63             return 1;
64
65     return 0;
66 }
67
68 /* Remove all whitepsapce from the beginning and the end of *s. *s may
69  * be modified. */
70 static char *strip(char *s) {
71     char *b = s+strspn(s, WHITESPACE);
72     char *e, *l = NULL;
73
74     for (e = b; *e; e++)
75         if (!in_string(*e, WHITESPACE))
76             l = e;
77
78     if (l)
79         *(l+1) = 0;
80
81     return b;
82 }
83
84 /* Parse a variable assignment line */
85 static int parse_line(const char *filename, unsigned line, const pa_config_item *t, char *l, void *userdata) {
86     char *e, *c, *b = l+strspn(l, WHITESPACE);
87
88     if ((c = strpbrk(b, COMMENTS)))
89         *c = 0;
90
91     if (!*b)
92         return 0;
93
94     if (!(e = strchr(b, '='))) {
95         pa_log("[%s:%u] Missing '='.", filename, line);
96         return -1;
97     }
98
99     *e = 0;
100     e++;
101
102     return next_assignment(filename, line, t, strip(b), strip(e), userdata);
103 }
104
105 /* Go through the file and parse each line */
106 int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata) {
107     int r = -1;
108     unsigned line = 0;
109     int do_close = !f;
110     assert(filename && t);
111
112     if (!f && !(f = fopen(filename, "r"))) {
113         if (errno == ENOENT) {
114             r = 0;
115             goto finish;
116         }
117
118         pa_log_warn("WARNING: failed to open configuration file '%s': %s",
119             filename, pa_cstrerror(errno));
120         goto finish;
121     }
122
123     while (!feof(f)) {
124         char l[256];
125         if (!fgets(l, sizeof(l), f)) {
126             if (feof(f))
127                 break;
128
129             pa_log_warn("WARNING: failed to read configuration file '%s': %s",
130                 filename, pa_cstrerror(errno));
131             goto finish;
132         }
133
134         if (parse_line(filename, ++line, t,  l, userdata) < 0)
135             goto finish;
136     }
137
138     r = 0;
139
140 finish:
141
142     if (do_close && f)
143         fclose(f);
144
145     return r;
146 }
147
148 int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
149     int *i = data;
150     int32_t k;
151     assert(filename && lvalue && rvalue && data);
152
153     if (pa_atoi(rvalue, &k) < 0) {
154         pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
155         return -1;
156     }
157
158     *i = (int) k;
159     return 0;
160 }
161
162 int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
163     int *b = data, k;
164     assert(filename && lvalue && rvalue && data);
165
166     if ((k = pa_parse_boolean(rvalue)) < 0) {
167         pa_log("[%s:%u] Failed to parse boolean value: %s", filename, line, rvalue);
168         return -1;
169     }
170
171     *b = k;
172
173     return 0;
174 }
175
176 int pa_config_parse_string(const char *filename, PA_GCC_UNUSED unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
177     char **s = data;
178     assert(filename && lvalue && rvalue && data);
179
180     pa_xfree(*s);
181     *s = *rvalue ? pa_xstrdup(rvalue) : NULL;
182     return 0;
183 }