diff options
author | Pierre Ossman <ossman@cendio.se> | 2006-02-16 19:19:58 +0000 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2006-02-16 19:19:58 +0000 |
commit | e205b25d65ccb380fa158711e24d55b6de5d9bc1 (patch) | |
tree | 470b4ced153c9ff18b8e35deb05c7a95efc838fc /src/polypcore/conf-parser.c | |
parent | 5b881e62282f26b353635120935d114e0c7c3f3c (diff) |
Reorganised the source tree. We now have src/ with a couple of subdirs:
* daemon/ - Contains the files specific to the polypaudio daemon.
* modules/ - All loadable modules.
* polyp/ - Files that are part of the public, application interface or
are only used in libpolyp.
* polypcore/ - All other shared files.
* tests/ - Test programs.
* utils/ - Utility programs.
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@487 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src/polypcore/conf-parser.c')
-rw-r--r-- | src/polypcore/conf-parser.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/src/polypcore/conf-parser.c b/src/polypcore/conf-parser.c new file mode 100644 index 00000000..507f2bf1 --- /dev/null +++ b/src/polypcore/conf-parser.c @@ -0,0 +1,176 @@ +/* $Id$ */ + +/*** + This file is part of polypaudio. + + polypaudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + polypaudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with polypaudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> + +#include "conf-parser.h" +#include "log.h" +#include "util.h" +#include "xmalloc.h" + +#define WHITESPACE " \t\n" +#define COMMENTS "#;\n" + +/* Run the user supplied parser for an assignment */ +static int next_assignment(const char *filename, unsigned line, const pa_config_item *t, const char *lvalue, const char *rvalue, void *userdata) { + assert(filename && t && lvalue && rvalue); + + for (; t->parse; t++) + if (!strcmp(lvalue, t->lvalue)) + return t->parse(filename, line, lvalue, rvalue, t->data, userdata); + + pa_log(__FILE__": [%s:%u] Unknown lvalue '%s'.\n", filename, line, lvalue); + + return -1; +} + +/* Returns non-zero when c is contained in s */ +static int in_string(char c, const char *s) { + assert(s); + + for (; *s; s++) + if (*s == c) + return 1; + + return 0; +} + +/* Remove all whitepsapce from the beginning and the end of *s. *s may + * be modified. */ +static char *strip(char *s) { + char *b = s+strspn(s, WHITESPACE); + char *e, *l = NULL; + + for (e = b; *e; e++) + if (!in_string(*e, WHITESPACE)) + l = e; + + if (l) + *(l+1) = 0; + + return b; +} + +/* Parse a variable assignment line */ +static int parse_line(const char *filename, unsigned line, const pa_config_item *t, char *l, void *userdata) { + char *e, *c, *b = l+strspn(l, WHITESPACE); + + if ((c = strpbrk(b, COMMENTS))) + *c = 0; + + if (!*b) + return 0; + + if (!(e = strchr(b, '='))) { + pa_log(__FILE__": [%s:%u] Missing '='.\n", filename, line); + return -1; + } + + *e = 0; + e++; + + return next_assignment(filename, line, t, strip(b), strip(e), userdata); +} + +/* Go through the file and parse each line */ +int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata) { + int r = -1; + unsigned line = 0; + int do_close = !f; + assert(filename && t); + + if (!f && !(f = fopen(filename, "r"))) { + if (errno == ENOENT) { + r = 0; + goto finish; + } + + pa_log(__FILE__": WARNING: failed to open configuration file '%s': %s\n", filename, strerror(errno)); + goto finish; + } + + while (!feof(f)) { + char l[256]; + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + pa_log(__FILE__": WARNING: failed to read configuration file '%s': %s\n", filename, strerror(errno)); + goto finish; + } + + if (parse_line(filename, ++line, t, l, userdata) < 0) + goto finish; + } + + r = 0; + +finish: + + if (do_close && f) + fclose(f); + + return r; +} + +int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { + int *i = data; + int32_t k; + assert(filename && lvalue && rvalue && data); + + if (pa_atoi(rvalue, &k) < 0) { + pa_log(__FILE__": [%s:%u] Failed to parse numeric value: %s\n", filename, line, rvalue); + return -1; + } + + *i = (int) k; + return 0; +} + +int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { + int *b = data, k; + assert(filename && lvalue && rvalue && data); + + if ((k = pa_parse_boolean(rvalue)) < 0) { + pa_log(__FILE__": [%s:%u] Failed to parse boolean value: %s\n", filename, line, rvalue); + return -1; + } + + *b = k; + + return 0; +} + +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) { + char **s = data; + assert(filename && lvalue && rvalue && data); + + pa_xfree(*s); + *s = *rvalue ? pa_xstrdup(rvalue) : NULL; + return 0; +} |