Sending translation for Portuguese
[platform/upstream/pulseaudio.git] / src / pulsecore / conf-parser.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2004-2006 Lennart Poettering
5
6   PulseAudio is free software; you can redistribute it and/or modify
7   it under the terms of the GNU Lesser General Public License as published
8   by the Free Software Foundation; either version 2.1 of the License,
9   or (at your option) any later version.
10
11   PulseAudio is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with PulseAudio; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27 #include <stdio.h>
28 #include <errno.h>
29
30 #include <pulse/xmalloc.h>
31
32 #include <pulsecore/core-error.h>
33 #include <pulsecore/log.h>
34 #include <pulsecore/core-util.h>
35 #include <pulsecore/macro.h>
36
37 #include "conf-parser.h"
38
39 #define WHITESPACE " \t\n"
40 #define COMMENTS "#;\n"
41
42 /* Run the user supplied parser for an assignment */
43 static int next_assignment(const char *filename, unsigned line, const char *section, const pa_config_item *t, const char *lvalue, const char *rvalue, void *userdata) {
44     pa_assert(filename);
45     pa_assert(t);
46     pa_assert(lvalue);
47     pa_assert(rvalue);
48
49     for (; t->parse; t++)
50         if (!t->lvalue ||
51             (pa_streq(lvalue, t->lvalue) &&
52              ((!section && !t->section) || pa_streq(section, t->section))))
53             return t->parse(filename, line, section, lvalue, rvalue, t->data, userdata);
54
55     pa_log("[%s:%u] Unknown lvalue '%s' in section '%s'.", filename, line, lvalue, pa_strnull(section));
56
57     return -1;
58 }
59
60 /* Returns non-zero when c is contained in s */
61 static int in_string(char c, const char *s) {
62     pa_assert(s);
63
64     for (; *s; s++)
65         if (*s == c)
66             return 1;
67
68     return 0;
69 }
70
71 /* Remove all whitepsapce from the beginning and the end of *s. *s may
72  * be modified. */
73 static char *strip(char *s) {
74     char *b = s+strspn(s, WHITESPACE);
75     char *e, *l = NULL;
76
77     for (e = b; *e; e++)
78         if (!in_string(*e, WHITESPACE))
79             l = e;
80
81     if (l)
82         *(l+1) = 0;
83
84     return b;
85 }
86
87 /* Parse a variable assignment line */
88 static int parse_line(const char *filename, unsigned line, char **section, const pa_config_item *t, char *l, void *userdata) {
89     char *e, *c, *b;
90
91     b = l+strspn(l, WHITESPACE);
92
93     if ((c = strpbrk(b, COMMENTS)))
94         *c = 0;
95
96     if (!*b)
97         return 0;
98
99     if (*b == '[') {
100         size_t k;
101
102         k = strlen(b);
103         pa_assert(k > 0);
104
105         if (b[k-1] != ']') {
106             pa_log("[%s:%u] Invalid section header.", filename, line);
107             return -1;
108         }
109
110         pa_xfree(*section);
111         *section = pa_xstrndup(b+1, k-2);
112         return 0;
113     }
114
115     if (!(e = strchr(b, '='))) {
116         pa_log("[%s:%u] Missing '='.", filename, line);
117         return -1;
118     }
119
120     *e = 0;
121     e++;
122
123     return next_assignment(filename, line, *section, t, strip(b), strip(e), userdata);
124 }
125
126 /* Go through the file and parse each line */
127 int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata) {
128     int r = -1;
129     unsigned line = 0;
130     pa_bool_t do_close = !f;
131     char *section = NULL;
132
133     pa_assert(filename);
134     pa_assert(t);
135
136     if (!f && !(f = fopen(filename, "r"))) {
137         if (errno == ENOENT) {
138             r = 0;
139             goto finish;
140         }
141
142         pa_log_warn("Failed to open configuration file '%s': %s", filename, pa_cstrerror(errno));
143         goto finish;
144     }
145
146     while (!feof(f)) {
147         char l[4096];
148
149         if (!fgets(l, sizeof(l), f)) {
150             if (feof(f))
151                 break;
152
153             pa_log_warn("Failed to read configuration file '%s': %s", filename, pa_cstrerror(errno));
154             goto finish;
155         }
156
157         if (parse_line(filename, ++line, &section, t, l, userdata) < 0)
158             goto finish;
159     }
160
161     r = 0;
162
163 finish:
164     pa_xfree(section);
165
166     if (do_close && f)
167         fclose(f);
168
169     return r;
170 }
171
172 int pa_config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
173     int *i = data;
174     int32_t k;
175
176     pa_assert(filename);
177     pa_assert(lvalue);
178     pa_assert(rvalue);
179     pa_assert(data);
180
181     if (pa_atoi(rvalue, &k) < 0) {
182         pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
183         return -1;
184     }
185
186     *i = (int) k;
187     return 0;
188 }
189
190 int pa_config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
191     unsigned *u = data;
192     uint32_t k;
193
194     pa_assert(filename);
195     pa_assert(lvalue);
196     pa_assert(rvalue);
197     pa_assert(data);
198
199     if (pa_atou(rvalue, &k) < 0) {
200         pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
201         return -1;
202     }
203
204     *u = (unsigned) k;
205     return 0;
206 }
207
208 int pa_config_parse_size(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
209     size_t *i = data;
210     uint32_t k;
211
212     pa_assert(filename);
213     pa_assert(lvalue);
214     pa_assert(rvalue);
215     pa_assert(data);
216
217     if (pa_atou(rvalue, &k) < 0) {
218         pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
219         return -1;
220     }
221
222     *i = (size_t) k;
223     return 0;
224 }
225
226 int pa_config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
227     int k;
228     pa_bool_t *b = data;
229
230     pa_assert(filename);
231     pa_assert(lvalue);
232     pa_assert(rvalue);
233     pa_assert(data);
234
235     if ((k = pa_parse_boolean(rvalue)) < 0) {
236         pa_log("[%s:%u] Failed to parse boolean value: %s", filename, line, rvalue);
237         return -1;
238     }
239
240     *b = !!k;
241
242     return 0;
243 }
244
245 int pa_config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
246     char **s = data;
247
248     pa_assert(filename);
249     pa_assert(lvalue);
250     pa_assert(rvalue);
251     pa_assert(data);
252
253     pa_xfree(*s);
254     *s = *rvalue ? pa_xstrdup(rvalue) : NULL;
255     return 0;
256 }