153a5a1b3Sopenharmony_ci/*** 253a5a1b3Sopenharmony_ci This file is part of PulseAudio. 353a5a1b3Sopenharmony_ci 453a5a1b3Sopenharmony_ci Copyright 2004-2006 Lennart Poettering 553a5a1b3Sopenharmony_ci 653a5a1b3Sopenharmony_ci PulseAudio is free software; you can redistribute it and/or modify 753a5a1b3Sopenharmony_ci it under the terms of the GNU Lesser General Public License as published 853a5a1b3Sopenharmony_ci by the Free Software Foundation; either version 2.1 of the License, 953a5a1b3Sopenharmony_ci or (at your option) any later version. 1053a5a1b3Sopenharmony_ci 1153a5a1b3Sopenharmony_ci PulseAudio is distributed in the hope that it will be useful, but 1253a5a1b3Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 1353a5a1b3Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1453a5a1b3Sopenharmony_ci General Public License for more details. 1553a5a1b3Sopenharmony_ci 1653a5a1b3Sopenharmony_ci You should have received a copy of the GNU Lesser General Public License 1753a5a1b3Sopenharmony_ci along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 1853a5a1b3Sopenharmony_ci***/ 1953a5a1b3Sopenharmony_ci 2053a5a1b3Sopenharmony_ci#ifdef HAVE_CONFIG_H 2153a5a1b3Sopenharmony_ci#include <config.h> 2253a5a1b3Sopenharmony_ci#endif 2353a5a1b3Sopenharmony_ci 2453a5a1b3Sopenharmony_ci#include <dirent.h> 2553a5a1b3Sopenharmony_ci#include <string.h> 2653a5a1b3Sopenharmony_ci#include <stdio.h> 2753a5a1b3Sopenharmony_ci#include <errno.h> 2853a5a1b3Sopenharmony_ci 2953a5a1b3Sopenharmony_ci#include <pulse/xmalloc.h> 3053a5a1b3Sopenharmony_ci 3153a5a1b3Sopenharmony_ci#include <pulsecore/core-error.h> 3253a5a1b3Sopenharmony_ci#include <pulsecore/log.h> 3353a5a1b3Sopenharmony_ci#include <pulsecore/core-util.h> 3453a5a1b3Sopenharmony_ci#include <pulsecore/macro.h> 3553a5a1b3Sopenharmony_ci 3653a5a1b3Sopenharmony_ci#include "conf-parser.h" 3753a5a1b3Sopenharmony_ci 3853a5a1b3Sopenharmony_ci#define WHITESPACE " \t\n" 3953a5a1b3Sopenharmony_ci#define COMMENTS "#;\n" 4053a5a1b3Sopenharmony_ci 4153a5a1b3Sopenharmony_ci/* Run the user supplied parser for an assignment */ 4253a5a1b3Sopenharmony_cistatic int normal_assignment(pa_config_parser_state *state) { 4353a5a1b3Sopenharmony_ci const pa_config_item *item; 4453a5a1b3Sopenharmony_ci 4553a5a1b3Sopenharmony_ci pa_assert(state); 4653a5a1b3Sopenharmony_ci 4753a5a1b3Sopenharmony_ci for (item = state->item_table; item->parse; item++) { 4853a5a1b3Sopenharmony_ci 4953a5a1b3Sopenharmony_ci if (item->lvalue && !pa_streq(state->lvalue, item->lvalue)) 5053a5a1b3Sopenharmony_ci continue; 5153a5a1b3Sopenharmony_ci 5253a5a1b3Sopenharmony_ci if (item->section && !state->section) 5353a5a1b3Sopenharmony_ci continue; 5453a5a1b3Sopenharmony_ci 5553a5a1b3Sopenharmony_ci if (item->section && !pa_streq(state->section, item->section)) 5653a5a1b3Sopenharmony_ci continue; 5753a5a1b3Sopenharmony_ci 5853a5a1b3Sopenharmony_ci state->data = item->data; 5953a5a1b3Sopenharmony_ci 6053a5a1b3Sopenharmony_ci return item->parse(state); 6153a5a1b3Sopenharmony_ci } 6253a5a1b3Sopenharmony_ci 6353a5a1b3Sopenharmony_ci pa_log("[%s:%u] Unknown lvalue '%s' in section '%s'.", state->filename, state->lineno, state->lvalue, pa_strna(state->section)); 6453a5a1b3Sopenharmony_ci 6553a5a1b3Sopenharmony_ci return -1; 6653a5a1b3Sopenharmony_ci} 6753a5a1b3Sopenharmony_ci 6853a5a1b3Sopenharmony_ci/* Parse a proplist entry. */ 6953a5a1b3Sopenharmony_cistatic int proplist_assignment(pa_config_parser_state *state) { 7053a5a1b3Sopenharmony_ci pa_assert(state); 7153a5a1b3Sopenharmony_ci pa_assert(state->proplist); 7253a5a1b3Sopenharmony_ci 7353a5a1b3Sopenharmony_ci if (pa_proplist_sets(state->proplist, state->lvalue, state->rvalue) < 0) { 7453a5a1b3Sopenharmony_ci pa_log("[%s:%u] Failed to parse a proplist entry: %s = %s", state->filename, state->lineno, state->lvalue, state->rvalue); 7553a5a1b3Sopenharmony_ci return -1; 7653a5a1b3Sopenharmony_ci } 7753a5a1b3Sopenharmony_ci 7853a5a1b3Sopenharmony_ci return 0; 7953a5a1b3Sopenharmony_ci} 8053a5a1b3Sopenharmony_ci 8153a5a1b3Sopenharmony_ci/* Parse a variable assignment line */ 8253a5a1b3Sopenharmony_cistatic int parse_line(pa_config_parser_state *state) { 8353a5a1b3Sopenharmony_ci char *c; 8453a5a1b3Sopenharmony_ci 8553a5a1b3Sopenharmony_ci state->lvalue = state->buf + strspn(state->buf, WHITESPACE); 8653a5a1b3Sopenharmony_ci 8753a5a1b3Sopenharmony_ci if ((c = strpbrk(state->lvalue, COMMENTS))) 8853a5a1b3Sopenharmony_ci *c = 0; 8953a5a1b3Sopenharmony_ci 9053a5a1b3Sopenharmony_ci if (!*state->lvalue) 9153a5a1b3Sopenharmony_ci return 0; 9253a5a1b3Sopenharmony_ci 9353a5a1b3Sopenharmony_ci if (pa_startswith(state->lvalue, ".include ")) { 9453a5a1b3Sopenharmony_ci char *path = NULL, *fn; 9553a5a1b3Sopenharmony_ci int r; 9653a5a1b3Sopenharmony_ci 9753a5a1b3Sopenharmony_ci fn = pa_strip(state->lvalue + 9); 9853a5a1b3Sopenharmony_ci if (!pa_is_path_absolute(fn)) { 9953a5a1b3Sopenharmony_ci const char *k; 10053a5a1b3Sopenharmony_ci if ((k = strrchr(state->filename, '/'))) { 10153a5a1b3Sopenharmony_ci char *dir = pa_xstrndup(state->filename, k - state->filename); 10253a5a1b3Sopenharmony_ci fn = path = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", dir, fn); 10353a5a1b3Sopenharmony_ci pa_xfree(dir); 10453a5a1b3Sopenharmony_ci } 10553a5a1b3Sopenharmony_ci } 10653a5a1b3Sopenharmony_ci 10753a5a1b3Sopenharmony_ci r = pa_config_parse(fn, NULL, state->item_table, state->proplist, false, state->userdata); 10853a5a1b3Sopenharmony_ci pa_xfree(path); 10953a5a1b3Sopenharmony_ci return r; 11053a5a1b3Sopenharmony_ci } 11153a5a1b3Sopenharmony_ci 11253a5a1b3Sopenharmony_ci if (*state->lvalue == '[') { 11353a5a1b3Sopenharmony_ci size_t k; 11453a5a1b3Sopenharmony_ci 11553a5a1b3Sopenharmony_ci k = strlen(state->lvalue); 11653a5a1b3Sopenharmony_ci pa_assert(k > 0); 11753a5a1b3Sopenharmony_ci 11853a5a1b3Sopenharmony_ci if (state->lvalue[k-1] != ']') { 11953a5a1b3Sopenharmony_ci pa_log("[%s:%u] Invalid section header.", state->filename, state->lineno); 12053a5a1b3Sopenharmony_ci return -1; 12153a5a1b3Sopenharmony_ci } 12253a5a1b3Sopenharmony_ci 12353a5a1b3Sopenharmony_ci pa_xfree(state->section); 12453a5a1b3Sopenharmony_ci state->section = pa_xstrndup(state->lvalue + 1, k-2); 12553a5a1b3Sopenharmony_ci 12653a5a1b3Sopenharmony_ci if (pa_streq(state->section, "Properties")) { 12753a5a1b3Sopenharmony_ci if (!state->proplist) { 12853a5a1b3Sopenharmony_ci pa_log("[%s:%u] \"Properties\" section is not allowed in this file.", state->filename, state->lineno); 12953a5a1b3Sopenharmony_ci return -1; 13053a5a1b3Sopenharmony_ci } 13153a5a1b3Sopenharmony_ci 13253a5a1b3Sopenharmony_ci state->in_proplist = true; 13353a5a1b3Sopenharmony_ci } else 13453a5a1b3Sopenharmony_ci state->in_proplist = false; 13553a5a1b3Sopenharmony_ci 13653a5a1b3Sopenharmony_ci return 0; 13753a5a1b3Sopenharmony_ci } 13853a5a1b3Sopenharmony_ci 13953a5a1b3Sopenharmony_ci if (!(state->rvalue = strchr(state->lvalue, '='))) { 14053a5a1b3Sopenharmony_ci pa_log("[%s:%u] Missing '='.", state->filename, state->lineno); 14153a5a1b3Sopenharmony_ci return -1; 14253a5a1b3Sopenharmony_ci } 14353a5a1b3Sopenharmony_ci 14453a5a1b3Sopenharmony_ci *state->rvalue = 0; 14553a5a1b3Sopenharmony_ci state->rvalue++; 14653a5a1b3Sopenharmony_ci 14753a5a1b3Sopenharmony_ci state->lvalue = pa_strip(state->lvalue); 14853a5a1b3Sopenharmony_ci state->rvalue = pa_strip(state->rvalue); 14953a5a1b3Sopenharmony_ci 15053a5a1b3Sopenharmony_ci if (state->in_proplist) 15153a5a1b3Sopenharmony_ci return proplist_assignment(state); 15253a5a1b3Sopenharmony_ci else 15353a5a1b3Sopenharmony_ci return normal_assignment(state); 15453a5a1b3Sopenharmony_ci} 15553a5a1b3Sopenharmony_ci 15653a5a1b3Sopenharmony_ci#ifndef OS_IS_WIN32 15753a5a1b3Sopenharmony_cistatic int conf_filter(const struct dirent *entry) { 15853a5a1b3Sopenharmony_ci return pa_endswith(entry->d_name, ".conf"); 15953a5a1b3Sopenharmony_ci} 16053a5a1b3Sopenharmony_ci#endif 16153a5a1b3Sopenharmony_ci 16253a5a1b3Sopenharmony_ci/* Go through the file and parse each line */ 16353a5a1b3Sopenharmony_ciint pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, pa_proplist *proplist, bool use_dot_d, 16453a5a1b3Sopenharmony_ci void *userdata) { 16553a5a1b3Sopenharmony_ci int r = -1; 16653a5a1b3Sopenharmony_ci bool do_close = !f; 16753a5a1b3Sopenharmony_ci pa_config_parser_state state; 16853a5a1b3Sopenharmony_ci 16953a5a1b3Sopenharmony_ci pa_assert(filename); 17053a5a1b3Sopenharmony_ci pa_assert(t); 17153a5a1b3Sopenharmony_ci 17253a5a1b3Sopenharmony_ci pa_zero(state); 17353a5a1b3Sopenharmony_ci 17453a5a1b3Sopenharmony_ci if (!f && !(f = pa_fopen_cloexec(filename, "r"))) { 17553a5a1b3Sopenharmony_ci if (errno == ENOENT) { 17653a5a1b3Sopenharmony_ci pa_log_debug("Failed to open configuration file '%s': %s", filename, pa_cstrerror(errno)); 17753a5a1b3Sopenharmony_ci r = 0; 17853a5a1b3Sopenharmony_ci goto finish; 17953a5a1b3Sopenharmony_ci } 18053a5a1b3Sopenharmony_ci 18153a5a1b3Sopenharmony_ci pa_log_warn("Failed to open configuration file '%s': %s", filename, pa_cstrerror(errno)); 18253a5a1b3Sopenharmony_ci goto finish; 18353a5a1b3Sopenharmony_ci } 18453a5a1b3Sopenharmony_ci pa_log_debug("Parsing configuration file '%s'", filename); 18553a5a1b3Sopenharmony_ci 18653a5a1b3Sopenharmony_ci state.filename = filename; 18753a5a1b3Sopenharmony_ci state.item_table = t; 18853a5a1b3Sopenharmony_ci state.userdata = userdata; 18953a5a1b3Sopenharmony_ci 19053a5a1b3Sopenharmony_ci if (proplist) 19153a5a1b3Sopenharmony_ci state.proplist = pa_proplist_new(); 19253a5a1b3Sopenharmony_ci 19353a5a1b3Sopenharmony_ci while (!feof(f)) { 19453a5a1b3Sopenharmony_ci if (!fgets(state.buf, sizeof(state.buf), f)) { 19553a5a1b3Sopenharmony_ci if (feof(f)) 19653a5a1b3Sopenharmony_ci break; 19753a5a1b3Sopenharmony_ci 19853a5a1b3Sopenharmony_ci pa_log_warn("Failed to read configuration file '%s': %s", filename, pa_cstrerror(errno)); 19953a5a1b3Sopenharmony_ci goto finish; 20053a5a1b3Sopenharmony_ci } 20153a5a1b3Sopenharmony_ci 20253a5a1b3Sopenharmony_ci state.lineno++; 20353a5a1b3Sopenharmony_ci 20453a5a1b3Sopenharmony_ci if (parse_line(&state) < 0) 20553a5a1b3Sopenharmony_ci goto finish; 20653a5a1b3Sopenharmony_ci } 20753a5a1b3Sopenharmony_ci 20853a5a1b3Sopenharmony_ci if (proplist) 20953a5a1b3Sopenharmony_ci pa_proplist_update(proplist, PA_UPDATE_REPLACE, state.proplist); 21053a5a1b3Sopenharmony_ci 21153a5a1b3Sopenharmony_ci r = 0; 21253a5a1b3Sopenharmony_ci 21353a5a1b3Sopenharmony_cifinish: 21453a5a1b3Sopenharmony_ci if (state.proplist) 21553a5a1b3Sopenharmony_ci pa_proplist_free(state.proplist); 21653a5a1b3Sopenharmony_ci 21753a5a1b3Sopenharmony_ci pa_xfree(state.section); 21853a5a1b3Sopenharmony_ci 21953a5a1b3Sopenharmony_ci if (do_close && f) 22053a5a1b3Sopenharmony_ci fclose(f); 22153a5a1b3Sopenharmony_ci 22253a5a1b3Sopenharmony_ci if (use_dot_d) { 22353a5a1b3Sopenharmony_ci#ifdef OS_IS_WIN32 22453a5a1b3Sopenharmony_ci char *dir_name = pa_sprintf_malloc("%s.d", filename); 22553a5a1b3Sopenharmony_ci char *pattern = pa_sprintf_malloc("%s\\*.conf", dir_name); 22653a5a1b3Sopenharmony_ci HANDLE fh; 22753a5a1b3Sopenharmony_ci WIN32_FIND_DATA wfd; 22853a5a1b3Sopenharmony_ci 22953a5a1b3Sopenharmony_ci fh = FindFirstFile(pattern, &wfd); 23053a5a1b3Sopenharmony_ci if (fh != INVALID_HANDLE_VALUE) { 23153a5a1b3Sopenharmony_ci do { 23253a5a1b3Sopenharmony_ci if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { 23353a5a1b3Sopenharmony_ci char *filename2 = pa_sprintf_malloc("%s\\%s", dir_name, wfd.cFileName); 23453a5a1b3Sopenharmony_ci pa_config_parse(filename2, NULL, t, proplist, false, userdata); 23553a5a1b3Sopenharmony_ci pa_xfree(filename2); 23653a5a1b3Sopenharmony_ci } 23753a5a1b3Sopenharmony_ci } while (FindNextFile(fh, &wfd)); 23853a5a1b3Sopenharmony_ci FindClose(fh); 23953a5a1b3Sopenharmony_ci } else { 24053a5a1b3Sopenharmony_ci DWORD err = GetLastError(); 24153a5a1b3Sopenharmony_ci 24253a5a1b3Sopenharmony_ci if (err == ERROR_PATH_NOT_FOUND) { 24353a5a1b3Sopenharmony_ci pa_log_debug("Pattern %s did not match any files, ignoring.", pattern); 24453a5a1b3Sopenharmony_ci } else { 24553a5a1b3Sopenharmony_ci LPVOID msgbuf; 24653a5a1b3Sopenharmony_ci DWORD fret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 24753a5a1b3Sopenharmony_ci NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msgbuf, 0, NULL); 24853a5a1b3Sopenharmony_ci 24953a5a1b3Sopenharmony_ci if (fret != 0) { 25053a5a1b3Sopenharmony_ci pa_log_warn("FindFirstFile(%s) failed with error %ld (%s), ignoring.", pattern, err, (char*)msgbuf); 25153a5a1b3Sopenharmony_ci LocalFree(msgbuf); 25253a5a1b3Sopenharmony_ci } else { 25353a5a1b3Sopenharmony_ci pa_log_warn("FindFirstFile(%s) failed with error %ld, ignoring.", pattern, err); 25453a5a1b3Sopenharmony_ci pa_log_warn("FormatMessage failed with error %lu", GetLastError()); 25553a5a1b3Sopenharmony_ci } 25653a5a1b3Sopenharmony_ci } 25753a5a1b3Sopenharmony_ci } 25853a5a1b3Sopenharmony_ci 25953a5a1b3Sopenharmony_ci pa_xfree(pattern); 26053a5a1b3Sopenharmony_ci pa_xfree(dir_name); 26153a5a1b3Sopenharmony_ci#else 26253a5a1b3Sopenharmony_ci char *dir_name; 26353a5a1b3Sopenharmony_ci int n; 26453a5a1b3Sopenharmony_ci struct dirent **entries = NULL; 26553a5a1b3Sopenharmony_ci 26653a5a1b3Sopenharmony_ci dir_name = pa_sprintf_malloc("%s.d", filename); 26753a5a1b3Sopenharmony_ci 26853a5a1b3Sopenharmony_ci n = scandir(dir_name, &entries, conf_filter, alphasort); 26953a5a1b3Sopenharmony_ci if (n >= 0) { 27053a5a1b3Sopenharmony_ci int i; 27153a5a1b3Sopenharmony_ci 27253a5a1b3Sopenharmony_ci for (i = 0; i < n; i++) { 27353a5a1b3Sopenharmony_ci char *filename2; 27453a5a1b3Sopenharmony_ci 27553a5a1b3Sopenharmony_ci filename2 = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", dir_name, entries[i]->d_name); 27653a5a1b3Sopenharmony_ci pa_config_parse(filename2, NULL, t, proplist, false, userdata); 27753a5a1b3Sopenharmony_ci pa_xfree(filename2); 27853a5a1b3Sopenharmony_ci 27953a5a1b3Sopenharmony_ci free(entries[i]); 28053a5a1b3Sopenharmony_ci } 28153a5a1b3Sopenharmony_ci 28253a5a1b3Sopenharmony_ci free(entries); 28353a5a1b3Sopenharmony_ci } else { 28453a5a1b3Sopenharmony_ci if (errno == ENOENT) 28553a5a1b3Sopenharmony_ci pa_log_debug("%s does not exist, ignoring.", dir_name); 28653a5a1b3Sopenharmony_ci else 28753a5a1b3Sopenharmony_ci pa_log_warn("scandir(\"%s\") failed: %s", dir_name, pa_cstrerror(errno)); 28853a5a1b3Sopenharmony_ci } 28953a5a1b3Sopenharmony_ci 29053a5a1b3Sopenharmony_ci pa_xfree(dir_name); 29153a5a1b3Sopenharmony_ci#endif 29253a5a1b3Sopenharmony_ci } 29353a5a1b3Sopenharmony_ci 29453a5a1b3Sopenharmony_ci return r; 29553a5a1b3Sopenharmony_ci} 29653a5a1b3Sopenharmony_ci 29753a5a1b3Sopenharmony_ciint pa_config_parse_int(pa_config_parser_state *state) { 29853a5a1b3Sopenharmony_ci int *i; 29953a5a1b3Sopenharmony_ci int32_t k; 30053a5a1b3Sopenharmony_ci 30153a5a1b3Sopenharmony_ci pa_assert(state); 30253a5a1b3Sopenharmony_ci 30353a5a1b3Sopenharmony_ci i = state->data; 30453a5a1b3Sopenharmony_ci 30553a5a1b3Sopenharmony_ci if (pa_atoi(state->rvalue, &k) < 0) { 30653a5a1b3Sopenharmony_ci pa_log("[%s:%u] Failed to parse numeric value: %s", state->filename, state->lineno, state->rvalue); 30753a5a1b3Sopenharmony_ci return -1; 30853a5a1b3Sopenharmony_ci } 30953a5a1b3Sopenharmony_ci 31053a5a1b3Sopenharmony_ci *i = (int) k; 31153a5a1b3Sopenharmony_ci return 0; 31253a5a1b3Sopenharmony_ci} 31353a5a1b3Sopenharmony_ci 31453a5a1b3Sopenharmony_ciint pa_config_parse_unsigned(pa_config_parser_state *state) { 31553a5a1b3Sopenharmony_ci unsigned *u; 31653a5a1b3Sopenharmony_ci uint32_t k; 31753a5a1b3Sopenharmony_ci 31853a5a1b3Sopenharmony_ci pa_assert(state); 31953a5a1b3Sopenharmony_ci 32053a5a1b3Sopenharmony_ci u = state->data; 32153a5a1b3Sopenharmony_ci 32253a5a1b3Sopenharmony_ci if (pa_atou(state->rvalue, &k) < 0) { 32353a5a1b3Sopenharmony_ci pa_log("[%s:%u] Failed to parse numeric value: %s", state->filename, state->lineno, state->rvalue); 32453a5a1b3Sopenharmony_ci return -1; 32553a5a1b3Sopenharmony_ci } 32653a5a1b3Sopenharmony_ci 32753a5a1b3Sopenharmony_ci *u = (unsigned) k; 32853a5a1b3Sopenharmony_ci return 0; 32953a5a1b3Sopenharmony_ci} 33053a5a1b3Sopenharmony_ci 33153a5a1b3Sopenharmony_ciint pa_config_parse_size(pa_config_parser_state *state) { 33253a5a1b3Sopenharmony_ci size_t *i; 33353a5a1b3Sopenharmony_ci uint32_t k; 33453a5a1b3Sopenharmony_ci 33553a5a1b3Sopenharmony_ci pa_assert(state); 33653a5a1b3Sopenharmony_ci 33753a5a1b3Sopenharmony_ci i = state->data; 33853a5a1b3Sopenharmony_ci 33953a5a1b3Sopenharmony_ci if (pa_atou(state->rvalue, &k) < 0) { 34053a5a1b3Sopenharmony_ci pa_log("[%s:%u] Failed to parse numeric value: %s", state->filename, state->lineno, state->rvalue); 34153a5a1b3Sopenharmony_ci return -1; 34253a5a1b3Sopenharmony_ci } 34353a5a1b3Sopenharmony_ci 34453a5a1b3Sopenharmony_ci *i = (size_t) k; 34553a5a1b3Sopenharmony_ci return 0; 34653a5a1b3Sopenharmony_ci} 34753a5a1b3Sopenharmony_ci 34853a5a1b3Sopenharmony_ciint pa_config_parse_bool(pa_config_parser_state *state) { 34953a5a1b3Sopenharmony_ci int k; 35053a5a1b3Sopenharmony_ci bool *b; 35153a5a1b3Sopenharmony_ci 35253a5a1b3Sopenharmony_ci pa_assert(state); 35353a5a1b3Sopenharmony_ci 35453a5a1b3Sopenharmony_ci b = state->data; 35553a5a1b3Sopenharmony_ci 35653a5a1b3Sopenharmony_ci if ((k = pa_parse_boolean(state->rvalue)) < 0) { 35753a5a1b3Sopenharmony_ci pa_log("[%s:%u] Failed to parse boolean value: %s", state->filename, state->lineno, state->rvalue); 35853a5a1b3Sopenharmony_ci return -1; 35953a5a1b3Sopenharmony_ci } 36053a5a1b3Sopenharmony_ci 36153a5a1b3Sopenharmony_ci *b = !!k; 36253a5a1b3Sopenharmony_ci 36353a5a1b3Sopenharmony_ci return 0; 36453a5a1b3Sopenharmony_ci} 36553a5a1b3Sopenharmony_ci 36653a5a1b3Sopenharmony_ciint pa_config_parse_not_bool(pa_config_parser_state *state) { 36753a5a1b3Sopenharmony_ci int k; 36853a5a1b3Sopenharmony_ci bool *b; 36953a5a1b3Sopenharmony_ci 37053a5a1b3Sopenharmony_ci pa_assert(state); 37153a5a1b3Sopenharmony_ci 37253a5a1b3Sopenharmony_ci b = state->data; 37353a5a1b3Sopenharmony_ci 37453a5a1b3Sopenharmony_ci if ((k = pa_parse_boolean(state->rvalue)) < 0) { 37553a5a1b3Sopenharmony_ci pa_log("[%s:%u] Failed to parse boolean value: %s", state->filename, state->lineno, state->rvalue); 37653a5a1b3Sopenharmony_ci return -1; 37753a5a1b3Sopenharmony_ci } 37853a5a1b3Sopenharmony_ci 37953a5a1b3Sopenharmony_ci *b = !k; 38053a5a1b3Sopenharmony_ci 38153a5a1b3Sopenharmony_ci return 0; 38253a5a1b3Sopenharmony_ci} 38353a5a1b3Sopenharmony_ci 38453a5a1b3Sopenharmony_ciint pa_config_parse_string(pa_config_parser_state *state) { 38553a5a1b3Sopenharmony_ci char **s; 38653a5a1b3Sopenharmony_ci 38753a5a1b3Sopenharmony_ci pa_assert(state); 38853a5a1b3Sopenharmony_ci 38953a5a1b3Sopenharmony_ci s = state->data; 39053a5a1b3Sopenharmony_ci 39153a5a1b3Sopenharmony_ci pa_xfree(*s); 39253a5a1b3Sopenharmony_ci *s = *state->rvalue ? pa_xstrdup(state->rvalue) : NULL; 39353a5a1b3Sopenharmony_ci return 0; 39453a5a1b3Sopenharmony_ci} 395