4 This file is part of PulseAudio.
6 Copyright 2004-2006 Lennart Poettering
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.
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.
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
33 #include <pulse/xmalloc.h>
35 #include <pulsecore/core-error.h>
36 #include <pulsecore/log.h>
37 #include <pulsecore/core-util.h>
39 #include "conf-parser.h"
41 #define WHITESPACE " \t\n"
42 #define COMMENTS "#;\n"
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);
49 if (!strcmp(lvalue, t->lvalue))
50 return t->parse(filename, line, lvalue, rvalue, t->data, userdata);
52 pa_log("[%s:%u] Unknown lvalue '%s'.", filename, line, lvalue);
57 /* Returns non-zero when c is contained in s */
58 static int in_string(char c, const char *s) {
68 /* Remove all whitepsapce from the beginning and the end of *s. *s may
70 static char *strip(char *s) {
71 char *b = s+strspn(s, WHITESPACE);
75 if (!in_string(*e, WHITESPACE))
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);
88 if ((c = strpbrk(b, COMMENTS)))
94 if (!(e = strchr(b, '='))) {
95 pa_log("[%s:%u] Missing '='.", filename, line);
102 return next_assignment(filename, line, t, strip(b), strip(e), userdata);
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) {
110 assert(filename && t);
112 if (!f && !(f = fopen(filename, "r"))) {
113 if (errno == ENOENT) {
118 pa_log_warn("WARNING: failed to open configuration file '%s': %s",
119 filename, pa_cstrerror(errno));
125 if (!fgets(l, sizeof(l), f)) {
129 pa_log_warn("WARNING: failed to read configuration file '%s': %s",
130 filename, pa_cstrerror(errno));
134 if (parse_line(filename, ++line, t, l, userdata) < 0)
148 int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
151 assert(filename && lvalue && rvalue && data);
153 if (pa_atoi(rvalue, &k) < 0) {
154 pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
162 int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
164 assert(filename && lvalue && rvalue && data);
166 if ((k = pa_parse_boolean(rvalue)) < 0) {
167 pa_log("[%s:%u] Failed to parse boolean value: %s", filename, line, rvalue);
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) {
178 assert(filename && lvalue && rvalue && data);
181 *s = *rvalue ? pa_xstrdup(rvalue) : NULL;