1*2e9d4914SAndroid Build Coastguard Worker /* ----------------------------------------------------------------------------
2*2e9d4914SAndroid Build Coastguard Worker libconfig - A library for processing structured configuration files
3*2e9d4914SAndroid Build Coastguard Worker Copyright (C) 2005-2020 Mark A Lindner
4*2e9d4914SAndroid Build Coastguard Worker
5*2e9d4914SAndroid Build Coastguard Worker This file is part of libconfig.
6*2e9d4914SAndroid Build Coastguard Worker
7*2e9d4914SAndroid Build Coastguard Worker This library is free software; you can redistribute it and/or
8*2e9d4914SAndroid Build Coastguard Worker modify it under the terms of the GNU Lesser General Public License
9*2e9d4914SAndroid Build Coastguard Worker as published by the Free Software Foundation; either version 2.1 of
10*2e9d4914SAndroid Build Coastguard Worker the License, or (at your option) any later version.
11*2e9d4914SAndroid Build Coastguard Worker
12*2e9d4914SAndroid Build Coastguard Worker This library is distributed in the hope that it will be useful, but
13*2e9d4914SAndroid Build Coastguard Worker WITHOUT ANY WARRANTY; without even the implied warranty of
14*2e9d4914SAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15*2e9d4914SAndroid Build Coastguard Worker Lesser General Public License for more details.
16*2e9d4914SAndroid Build Coastguard Worker
17*2e9d4914SAndroid Build Coastguard Worker You should have received a copy of the GNU Library General Public
18*2e9d4914SAndroid Build Coastguard Worker License along with this library; if not, see
19*2e9d4914SAndroid Build Coastguard Worker <http://www.gnu.org/licenses/>.
20*2e9d4914SAndroid Build Coastguard Worker ----------------------------------------------------------------------------
21*2e9d4914SAndroid Build Coastguard Worker */
22*2e9d4914SAndroid Build Coastguard Worker
23*2e9d4914SAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
24*2e9d4914SAndroid Build Coastguard Worker #include "ac_config.h"
25*2e9d4914SAndroid Build Coastguard Worker #endif
26*2e9d4914SAndroid Build Coastguard Worker
27*2e9d4914SAndroid Build Coastguard Worker #include <locale.h>
28*2e9d4914SAndroid Build Coastguard Worker
29*2e9d4914SAndroid Build Coastguard Worker #if defined(HAVE_XLOCALE_H) || defined(__APPLE__)
30*2e9d4914SAndroid Build Coastguard Worker #include <xlocale.h>
31*2e9d4914SAndroid Build Coastguard Worker #endif
32*2e9d4914SAndroid Build Coastguard Worker
33*2e9d4914SAndroid Build Coastguard Worker #include <ctype.h>
34*2e9d4914SAndroid Build Coastguard Worker #include <float.h>
35*2e9d4914SAndroid Build Coastguard Worker #include <stdio.h>
36*2e9d4914SAndroid Build Coastguard Worker #include <stdlib.h>
37*2e9d4914SAndroid Build Coastguard Worker #include <string.h>
38*2e9d4914SAndroid Build Coastguard Worker #include <sys/stat.h>
39*2e9d4914SAndroid Build Coastguard Worker #include <sys/types.h>
40*2e9d4914SAndroid Build Coastguard Worker
41*2e9d4914SAndroid Build Coastguard Worker #include "libconfig.h"
42*2e9d4914SAndroid Build Coastguard Worker #include "parsectx.h"
43*2e9d4914SAndroid Build Coastguard Worker #include "scanctx.h"
44*2e9d4914SAndroid Build Coastguard Worker #include "strvec.h"
45*2e9d4914SAndroid Build Coastguard Worker #include "wincompat.h"
46*2e9d4914SAndroid Build Coastguard Worker #include "grammar.h"
47*2e9d4914SAndroid Build Coastguard Worker #include "scanner.h"
48*2e9d4914SAndroid Build Coastguard Worker #include "util.h"
49*2e9d4914SAndroid Build Coastguard Worker
50*2e9d4914SAndroid Build Coastguard Worker #define PATH_TOKENS ":./"
51*2e9d4914SAndroid Build Coastguard Worker #define CHUNK_SIZE 16
52*2e9d4914SAndroid Build Coastguard Worker #define DEFAULT_TAB_WIDTH 2
53*2e9d4914SAndroid Build Coastguard Worker #define DEFAULT_FLOAT_PRECISION 6
54*2e9d4914SAndroid Build Coastguard Worker
55*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
56*2e9d4914SAndroid Build Coastguard Worker
57*2e9d4914SAndroid Build Coastguard Worker #ifndef LIBCONFIG_STATIC
58*2e9d4914SAndroid Build Coastguard Worker #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \
59*2e9d4914SAndroid Build Coastguard Worker || defined(WIN64) || defined(_WIN64) || defined(__WIN64__))
60*2e9d4914SAndroid Build Coastguard Worker
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)61*2e9d4914SAndroid Build Coastguard Worker BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
62*2e9d4914SAndroid Build Coastguard Worker {
63*2e9d4914SAndroid Build Coastguard Worker return(TRUE);
64*2e9d4914SAndroid Build Coastguard Worker }
65*2e9d4914SAndroid Build Coastguard Worker
66*2e9d4914SAndroid Build Coastguard Worker #endif /* WIN32 || WIN64 */
67*2e9d4914SAndroid Build Coastguard Worker #endif /* LIBCONFIG_STATIC */
68*2e9d4914SAndroid Build Coastguard Worker
69*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
70*2e9d4914SAndroid Build Coastguard Worker
71*2e9d4914SAndroid Build Coastguard Worker static const char *__io_error = "file I/O error";
72*2e9d4914SAndroid Build Coastguard Worker
73*2e9d4914SAndroid Build Coastguard Worker static void __config_list_destroy(config_list_t *list);
74*2e9d4914SAndroid Build Coastguard Worker static void __config_write_setting(const config_t *config,
75*2e9d4914SAndroid Build Coastguard Worker const config_setting_t *setting,
76*2e9d4914SAndroid Build Coastguard Worker FILE *stream, int depth);
77*2e9d4914SAndroid Build Coastguard Worker
78*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
79*2e9d4914SAndroid Build Coastguard Worker
__config_locale_override(void)80*2e9d4914SAndroid Build Coastguard Worker static void __config_locale_override(void)
81*2e9d4914SAndroid Build Coastguard Worker {
82*2e9d4914SAndroid Build Coastguard Worker #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \
83*2e9d4914SAndroid Build Coastguard Worker && ! defined(__MINGW32__)
84*2e9d4914SAndroid Build Coastguard Worker
85*2e9d4914SAndroid Build Coastguard Worker _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
86*2e9d4914SAndroid Build Coastguard Worker setlocale(LC_NUMERIC, "C");
87*2e9d4914SAndroid Build Coastguard Worker
88*2e9d4914SAndroid Build Coastguard Worker #elif defined(__APPLE__)
89*2e9d4914SAndroid Build Coastguard Worker
90*2e9d4914SAndroid Build Coastguard Worker locale_t loc = newlocale(LC_NUMERIC_MASK, "C", NULL);
91*2e9d4914SAndroid Build Coastguard Worker uselocale(loc);
92*2e9d4914SAndroid Build Coastguard Worker
93*2e9d4914SAndroid Build Coastguard Worker #elif ((defined HAVE_NEWLOCALE) && (defined HAVE_USELOCALE))
94*2e9d4914SAndroid Build Coastguard Worker
95*2e9d4914SAndroid Build Coastguard Worker locale_t loc = newlocale(LC_NUMERIC, "C", NULL);
96*2e9d4914SAndroid Build Coastguard Worker uselocale(loc);
97*2e9d4914SAndroid Build Coastguard Worker
98*2e9d4914SAndroid Build Coastguard Worker #else
99*2e9d4914SAndroid Build Coastguard Worker
100*2e9d4914SAndroid Build Coastguard Worker #warning "No way to modify calling thread's locale!"
101*2e9d4914SAndroid Build Coastguard Worker
102*2e9d4914SAndroid Build Coastguard Worker #endif
103*2e9d4914SAndroid Build Coastguard Worker }
104*2e9d4914SAndroid Build Coastguard Worker
105*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
106*2e9d4914SAndroid Build Coastguard Worker
__config_locale_restore(void)107*2e9d4914SAndroid Build Coastguard Worker static void __config_locale_restore(void)
108*2e9d4914SAndroid Build Coastguard Worker {
109*2e9d4914SAndroid Build Coastguard Worker #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \
110*2e9d4914SAndroid Build Coastguard Worker && ! defined(__MINGW32__)
111*2e9d4914SAndroid Build Coastguard Worker
112*2e9d4914SAndroid Build Coastguard Worker _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
113*2e9d4914SAndroid Build Coastguard Worker
114*2e9d4914SAndroid Build Coastguard Worker #elif ((defined HAVE_USELOCALE) && (defined HAVE_FREELOCALE))
115*2e9d4914SAndroid Build Coastguard Worker
116*2e9d4914SAndroid Build Coastguard Worker locale_t loc = uselocale(LC_GLOBAL_LOCALE);
117*2e9d4914SAndroid Build Coastguard Worker freelocale(loc);
118*2e9d4914SAndroid Build Coastguard Worker
119*2e9d4914SAndroid Build Coastguard Worker #else
120*2e9d4914SAndroid Build Coastguard Worker
121*2e9d4914SAndroid Build Coastguard Worker #warning "No way to modify calling thread's locale!"
122*2e9d4914SAndroid Build Coastguard Worker
123*2e9d4914SAndroid Build Coastguard Worker #endif
124*2e9d4914SAndroid Build Coastguard Worker }
125*2e9d4914SAndroid Build Coastguard Worker
126*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
127*2e9d4914SAndroid Build Coastguard Worker
__config_name_compare(const char * a,const char * b)128*2e9d4914SAndroid Build Coastguard Worker static int __config_name_compare(const char *a, const char *b)
129*2e9d4914SAndroid Build Coastguard Worker {
130*2e9d4914SAndroid Build Coastguard Worker const char *p, *q;
131*2e9d4914SAndroid Build Coastguard Worker
132*2e9d4914SAndroid Build Coastguard Worker for(p = a, q = b; ; p++, q++)
133*2e9d4914SAndroid Build Coastguard Worker {
134*2e9d4914SAndroid Build Coastguard Worker int pd = ((! *p) || strchr(PATH_TOKENS, *p));
135*2e9d4914SAndroid Build Coastguard Worker int qd = ((! *q) || strchr(PATH_TOKENS, *q));
136*2e9d4914SAndroid Build Coastguard Worker
137*2e9d4914SAndroid Build Coastguard Worker if(pd && qd)
138*2e9d4914SAndroid Build Coastguard Worker break;
139*2e9d4914SAndroid Build Coastguard Worker else if(pd)
140*2e9d4914SAndroid Build Coastguard Worker return(-1);
141*2e9d4914SAndroid Build Coastguard Worker else if(qd)
142*2e9d4914SAndroid Build Coastguard Worker return(1);
143*2e9d4914SAndroid Build Coastguard Worker else if(*p < *q)
144*2e9d4914SAndroid Build Coastguard Worker return(-1);
145*2e9d4914SAndroid Build Coastguard Worker else if(*p > *q)
146*2e9d4914SAndroid Build Coastguard Worker return(1);
147*2e9d4914SAndroid Build Coastguard Worker }
148*2e9d4914SAndroid Build Coastguard Worker
149*2e9d4914SAndroid Build Coastguard Worker return(0);
150*2e9d4914SAndroid Build Coastguard Worker }
151*2e9d4914SAndroid Build Coastguard Worker
152*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
153*2e9d4914SAndroid Build Coastguard Worker
__config_indent(FILE * stream,int depth,unsigned short w)154*2e9d4914SAndroid Build Coastguard Worker static void __config_indent(FILE *stream, int depth, unsigned short w)
155*2e9d4914SAndroid Build Coastguard Worker {
156*2e9d4914SAndroid Build Coastguard Worker if(w)
157*2e9d4914SAndroid Build Coastguard Worker fprintf(stream, "%*s", (depth - 1) * w, " ");
158*2e9d4914SAndroid Build Coastguard Worker else
159*2e9d4914SAndroid Build Coastguard Worker {
160*2e9d4914SAndroid Build Coastguard Worker int i;
161*2e9d4914SAndroid Build Coastguard Worker for(i = 0; i < (depth - 1); ++i)
162*2e9d4914SAndroid Build Coastguard Worker fputc('\t', stream);
163*2e9d4914SAndroid Build Coastguard Worker }
164*2e9d4914SAndroid Build Coastguard Worker }
165*2e9d4914SAndroid Build Coastguard Worker
166*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
167*2e9d4914SAndroid Build Coastguard Worker
__config_write_value(const config_t * config,const config_value_t * value,int type,int format,int depth,FILE * stream)168*2e9d4914SAndroid Build Coastguard Worker static void __config_write_value(const config_t *config,
169*2e9d4914SAndroid Build Coastguard Worker const config_value_t *value, int type,
170*2e9d4914SAndroid Build Coastguard Worker int format, int depth, FILE *stream)
171*2e9d4914SAndroid Build Coastguard Worker {
172*2e9d4914SAndroid Build Coastguard Worker char fbuf[64];
173*2e9d4914SAndroid Build Coastguard Worker
174*2e9d4914SAndroid Build Coastguard Worker switch(type)
175*2e9d4914SAndroid Build Coastguard Worker {
176*2e9d4914SAndroid Build Coastguard Worker /* boolean */
177*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_BOOL:
178*2e9d4914SAndroid Build Coastguard Worker fputs(value->ival ? "true" : "false", stream);
179*2e9d4914SAndroid Build Coastguard Worker break;
180*2e9d4914SAndroid Build Coastguard Worker
181*2e9d4914SAndroid Build Coastguard Worker /* int */
182*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT:
183*2e9d4914SAndroid Build Coastguard Worker switch(format)
184*2e9d4914SAndroid Build Coastguard Worker {
185*2e9d4914SAndroid Build Coastguard Worker case CONFIG_FORMAT_HEX:
186*2e9d4914SAndroid Build Coastguard Worker fprintf(stream, "0x%X", value->ival);
187*2e9d4914SAndroid Build Coastguard Worker break;
188*2e9d4914SAndroid Build Coastguard Worker
189*2e9d4914SAndroid Build Coastguard Worker case CONFIG_FORMAT_DEFAULT:
190*2e9d4914SAndroid Build Coastguard Worker default:
191*2e9d4914SAndroid Build Coastguard Worker fprintf(stream, "%d", value->ival);
192*2e9d4914SAndroid Build Coastguard Worker break;
193*2e9d4914SAndroid Build Coastguard Worker }
194*2e9d4914SAndroid Build Coastguard Worker break;
195*2e9d4914SAndroid Build Coastguard Worker
196*2e9d4914SAndroid Build Coastguard Worker /* 64-bit int */
197*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT64:
198*2e9d4914SAndroid Build Coastguard Worker switch(format)
199*2e9d4914SAndroid Build Coastguard Worker {
200*2e9d4914SAndroid Build Coastguard Worker case CONFIG_FORMAT_HEX:
201*2e9d4914SAndroid Build Coastguard Worker fprintf(stream, "0x" INT64_HEX_FMT "L", value->llval);
202*2e9d4914SAndroid Build Coastguard Worker break;
203*2e9d4914SAndroid Build Coastguard Worker
204*2e9d4914SAndroid Build Coastguard Worker case CONFIG_FORMAT_DEFAULT:
205*2e9d4914SAndroid Build Coastguard Worker default:
206*2e9d4914SAndroid Build Coastguard Worker fprintf(stream, INT64_FMT "L", value->llval);
207*2e9d4914SAndroid Build Coastguard Worker break;
208*2e9d4914SAndroid Build Coastguard Worker }
209*2e9d4914SAndroid Build Coastguard Worker break;
210*2e9d4914SAndroid Build Coastguard Worker
211*2e9d4914SAndroid Build Coastguard Worker /* float */
212*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_FLOAT:
213*2e9d4914SAndroid Build Coastguard Worker {
214*2e9d4914SAndroid Build Coastguard Worker const int sci_ok = config_get_option(
215*2e9d4914SAndroid Build Coastguard Worker config, CONFIG_OPTION_ALLOW_SCIENTIFIC_NOTATION);
216*2e9d4914SAndroid Build Coastguard Worker libconfig_format_double(value->fval, config->float_precision, sci_ok,
217*2e9d4914SAndroid Build Coastguard Worker fbuf, sizeof(fbuf));
218*2e9d4914SAndroid Build Coastguard Worker fputs(fbuf, stream);
219*2e9d4914SAndroid Build Coastguard Worker break;
220*2e9d4914SAndroid Build Coastguard Worker }
221*2e9d4914SAndroid Build Coastguard Worker
222*2e9d4914SAndroid Build Coastguard Worker /* string */
223*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_STRING:
224*2e9d4914SAndroid Build Coastguard Worker {
225*2e9d4914SAndroid Build Coastguard Worker char *p;
226*2e9d4914SAndroid Build Coastguard Worker
227*2e9d4914SAndroid Build Coastguard Worker fputc('\"', stream);
228*2e9d4914SAndroid Build Coastguard Worker
229*2e9d4914SAndroid Build Coastguard Worker if(value->sval)
230*2e9d4914SAndroid Build Coastguard Worker {
231*2e9d4914SAndroid Build Coastguard Worker for(p = value->sval; *p; p++)
232*2e9d4914SAndroid Build Coastguard Worker {
233*2e9d4914SAndroid Build Coastguard Worker int c = (int)*p & 0xFF;
234*2e9d4914SAndroid Build Coastguard Worker switch(c)
235*2e9d4914SAndroid Build Coastguard Worker {
236*2e9d4914SAndroid Build Coastguard Worker case '\"':
237*2e9d4914SAndroid Build Coastguard Worker case '\\':
238*2e9d4914SAndroid Build Coastguard Worker fputc('\\', stream);
239*2e9d4914SAndroid Build Coastguard Worker fputc(c, stream);
240*2e9d4914SAndroid Build Coastguard Worker break;
241*2e9d4914SAndroid Build Coastguard Worker
242*2e9d4914SAndroid Build Coastguard Worker case '\n':
243*2e9d4914SAndroid Build Coastguard Worker fputs("\\n", stream);
244*2e9d4914SAndroid Build Coastguard Worker break;
245*2e9d4914SAndroid Build Coastguard Worker
246*2e9d4914SAndroid Build Coastguard Worker case '\r':
247*2e9d4914SAndroid Build Coastguard Worker fputs("\\r", stream);
248*2e9d4914SAndroid Build Coastguard Worker break;
249*2e9d4914SAndroid Build Coastguard Worker
250*2e9d4914SAndroid Build Coastguard Worker case '\f':
251*2e9d4914SAndroid Build Coastguard Worker fputs("\\f", stream);
252*2e9d4914SAndroid Build Coastguard Worker break;
253*2e9d4914SAndroid Build Coastguard Worker
254*2e9d4914SAndroid Build Coastguard Worker case '\t':
255*2e9d4914SAndroid Build Coastguard Worker fputs("\\t", stream);
256*2e9d4914SAndroid Build Coastguard Worker break;
257*2e9d4914SAndroid Build Coastguard Worker
258*2e9d4914SAndroid Build Coastguard Worker default:
259*2e9d4914SAndroid Build Coastguard Worker if(c >= ' ')
260*2e9d4914SAndroid Build Coastguard Worker fputc(c, stream);
261*2e9d4914SAndroid Build Coastguard Worker else
262*2e9d4914SAndroid Build Coastguard Worker fprintf(stream, "\\x%02X", c);
263*2e9d4914SAndroid Build Coastguard Worker }
264*2e9d4914SAndroid Build Coastguard Worker }
265*2e9d4914SAndroid Build Coastguard Worker }
266*2e9d4914SAndroid Build Coastguard Worker fputc('\"', stream);
267*2e9d4914SAndroid Build Coastguard Worker break;
268*2e9d4914SAndroid Build Coastguard Worker }
269*2e9d4914SAndroid Build Coastguard Worker
270*2e9d4914SAndroid Build Coastguard Worker /* list */
271*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_LIST:
272*2e9d4914SAndroid Build Coastguard Worker {
273*2e9d4914SAndroid Build Coastguard Worker config_list_t *list = value->list;
274*2e9d4914SAndroid Build Coastguard Worker
275*2e9d4914SAndroid Build Coastguard Worker fputs("( ", stream);
276*2e9d4914SAndroid Build Coastguard Worker
277*2e9d4914SAndroid Build Coastguard Worker if(list)
278*2e9d4914SAndroid Build Coastguard Worker {
279*2e9d4914SAndroid Build Coastguard Worker int len = list->length;
280*2e9d4914SAndroid Build Coastguard Worker config_setting_t **s;
281*2e9d4914SAndroid Build Coastguard Worker
282*2e9d4914SAndroid Build Coastguard Worker for(s = list->elements; len--; s++)
283*2e9d4914SAndroid Build Coastguard Worker {
284*2e9d4914SAndroid Build Coastguard Worker __config_write_value(config, &((*s)->value), (*s)->type,
285*2e9d4914SAndroid Build Coastguard Worker config_setting_get_format(*s), depth + 1,
286*2e9d4914SAndroid Build Coastguard Worker stream);
287*2e9d4914SAndroid Build Coastguard Worker
288*2e9d4914SAndroid Build Coastguard Worker if(len)
289*2e9d4914SAndroid Build Coastguard Worker fputc(',', stream);
290*2e9d4914SAndroid Build Coastguard Worker
291*2e9d4914SAndroid Build Coastguard Worker fputc(' ', stream);
292*2e9d4914SAndroid Build Coastguard Worker }
293*2e9d4914SAndroid Build Coastguard Worker }
294*2e9d4914SAndroid Build Coastguard Worker
295*2e9d4914SAndroid Build Coastguard Worker fputc(')', stream);
296*2e9d4914SAndroid Build Coastguard Worker break;
297*2e9d4914SAndroid Build Coastguard Worker }
298*2e9d4914SAndroid Build Coastguard Worker
299*2e9d4914SAndroid Build Coastguard Worker /* array */
300*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_ARRAY:
301*2e9d4914SAndroid Build Coastguard Worker {
302*2e9d4914SAndroid Build Coastguard Worker config_list_t *list = value->list;
303*2e9d4914SAndroid Build Coastguard Worker
304*2e9d4914SAndroid Build Coastguard Worker fputs("[ ", stream);
305*2e9d4914SAndroid Build Coastguard Worker
306*2e9d4914SAndroid Build Coastguard Worker if(list)
307*2e9d4914SAndroid Build Coastguard Worker {
308*2e9d4914SAndroid Build Coastguard Worker int len = list->length;
309*2e9d4914SAndroid Build Coastguard Worker config_setting_t **s;
310*2e9d4914SAndroid Build Coastguard Worker
311*2e9d4914SAndroid Build Coastguard Worker for(s = list->elements; len--; s++)
312*2e9d4914SAndroid Build Coastguard Worker {
313*2e9d4914SAndroid Build Coastguard Worker __config_write_value(config, &((*s)->value), (*s)->type,
314*2e9d4914SAndroid Build Coastguard Worker config_setting_get_format(*s), depth + 1,
315*2e9d4914SAndroid Build Coastguard Worker stream);
316*2e9d4914SAndroid Build Coastguard Worker
317*2e9d4914SAndroid Build Coastguard Worker if(len)
318*2e9d4914SAndroid Build Coastguard Worker fputc(',', stream);
319*2e9d4914SAndroid Build Coastguard Worker
320*2e9d4914SAndroid Build Coastguard Worker fputc(' ', stream);
321*2e9d4914SAndroid Build Coastguard Worker }
322*2e9d4914SAndroid Build Coastguard Worker }
323*2e9d4914SAndroid Build Coastguard Worker
324*2e9d4914SAndroid Build Coastguard Worker fputc(']', stream);
325*2e9d4914SAndroid Build Coastguard Worker break;
326*2e9d4914SAndroid Build Coastguard Worker }
327*2e9d4914SAndroid Build Coastguard Worker
328*2e9d4914SAndroid Build Coastguard Worker /* group */
329*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_GROUP:
330*2e9d4914SAndroid Build Coastguard Worker {
331*2e9d4914SAndroid Build Coastguard Worker config_list_t *list = value->list;
332*2e9d4914SAndroid Build Coastguard Worker
333*2e9d4914SAndroid Build Coastguard Worker if(depth > 0)
334*2e9d4914SAndroid Build Coastguard Worker {
335*2e9d4914SAndroid Build Coastguard Worker if(config_get_option(config, CONFIG_OPTION_OPEN_BRACE_ON_SEPARATE_LINE))
336*2e9d4914SAndroid Build Coastguard Worker {
337*2e9d4914SAndroid Build Coastguard Worker fputc('\n', stream);
338*2e9d4914SAndroid Build Coastguard Worker
339*2e9d4914SAndroid Build Coastguard Worker if(depth > 1)
340*2e9d4914SAndroid Build Coastguard Worker __config_indent(stream, depth, config->tab_width);
341*2e9d4914SAndroid Build Coastguard Worker }
342*2e9d4914SAndroid Build Coastguard Worker
343*2e9d4914SAndroid Build Coastguard Worker fputs("{\n", stream);
344*2e9d4914SAndroid Build Coastguard Worker }
345*2e9d4914SAndroid Build Coastguard Worker
346*2e9d4914SAndroid Build Coastguard Worker if(list)
347*2e9d4914SAndroid Build Coastguard Worker {
348*2e9d4914SAndroid Build Coastguard Worker int len = list->length;
349*2e9d4914SAndroid Build Coastguard Worker config_setting_t **s;
350*2e9d4914SAndroid Build Coastguard Worker
351*2e9d4914SAndroid Build Coastguard Worker for(s = list->elements; len--; s++)
352*2e9d4914SAndroid Build Coastguard Worker __config_write_setting(config, *s, stream, depth + 1);
353*2e9d4914SAndroid Build Coastguard Worker }
354*2e9d4914SAndroid Build Coastguard Worker
355*2e9d4914SAndroid Build Coastguard Worker if(depth > 1)
356*2e9d4914SAndroid Build Coastguard Worker __config_indent(stream, depth, config->tab_width);
357*2e9d4914SAndroid Build Coastguard Worker
358*2e9d4914SAndroid Build Coastguard Worker if(depth > 0)
359*2e9d4914SAndroid Build Coastguard Worker fputc('}', stream);
360*2e9d4914SAndroid Build Coastguard Worker
361*2e9d4914SAndroid Build Coastguard Worker break;
362*2e9d4914SAndroid Build Coastguard Worker }
363*2e9d4914SAndroid Build Coastguard Worker
364*2e9d4914SAndroid Build Coastguard Worker default:
365*2e9d4914SAndroid Build Coastguard Worker /* this shouldn't happen, but handle it gracefully... */
366*2e9d4914SAndroid Build Coastguard Worker fputs("???", stream);
367*2e9d4914SAndroid Build Coastguard Worker break;
368*2e9d4914SAndroid Build Coastguard Worker }
369*2e9d4914SAndroid Build Coastguard Worker }
370*2e9d4914SAndroid Build Coastguard Worker
371*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
372*2e9d4914SAndroid Build Coastguard Worker
__config_list_add(config_list_t * list,config_setting_t * setting)373*2e9d4914SAndroid Build Coastguard Worker static void __config_list_add(config_list_t *list, config_setting_t *setting)
374*2e9d4914SAndroid Build Coastguard Worker {
375*2e9d4914SAndroid Build Coastguard Worker if((list->length % CHUNK_SIZE) == 0)
376*2e9d4914SAndroid Build Coastguard Worker {
377*2e9d4914SAndroid Build Coastguard Worker list->elements = (config_setting_t **)realloc(
378*2e9d4914SAndroid Build Coastguard Worker list->elements,
379*2e9d4914SAndroid Build Coastguard Worker (list->length + CHUNK_SIZE) * sizeof(config_setting_t *));
380*2e9d4914SAndroid Build Coastguard Worker }
381*2e9d4914SAndroid Build Coastguard Worker
382*2e9d4914SAndroid Build Coastguard Worker list->elements[list->length] = setting;
383*2e9d4914SAndroid Build Coastguard Worker list->length++;
384*2e9d4914SAndroid Build Coastguard Worker }
385*2e9d4914SAndroid Build Coastguard Worker
386*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
387*2e9d4914SAndroid Build Coastguard Worker
__config_list_search(config_list_t * list,const char * name,unsigned int * idx)388*2e9d4914SAndroid Build Coastguard Worker static config_setting_t *__config_list_search(config_list_t *list,
389*2e9d4914SAndroid Build Coastguard Worker const char *name,
390*2e9d4914SAndroid Build Coastguard Worker unsigned int *idx)
391*2e9d4914SAndroid Build Coastguard Worker {
392*2e9d4914SAndroid Build Coastguard Worker config_setting_t **found = NULL;
393*2e9d4914SAndroid Build Coastguard Worker unsigned int i;
394*2e9d4914SAndroid Build Coastguard Worker
395*2e9d4914SAndroid Build Coastguard Worker if(! list)
396*2e9d4914SAndroid Build Coastguard Worker return(NULL);
397*2e9d4914SAndroid Build Coastguard Worker
398*2e9d4914SAndroid Build Coastguard Worker for(i = 0, found = list->elements; i < list->length; i++, found++)
399*2e9d4914SAndroid Build Coastguard Worker {
400*2e9d4914SAndroid Build Coastguard Worker if(! (*found)->name)
401*2e9d4914SAndroid Build Coastguard Worker continue;
402*2e9d4914SAndroid Build Coastguard Worker
403*2e9d4914SAndroid Build Coastguard Worker if(! __config_name_compare(name, (*found)->name))
404*2e9d4914SAndroid Build Coastguard Worker {
405*2e9d4914SAndroid Build Coastguard Worker if(idx)
406*2e9d4914SAndroid Build Coastguard Worker *idx = i;
407*2e9d4914SAndroid Build Coastguard Worker
408*2e9d4914SAndroid Build Coastguard Worker return(*found);
409*2e9d4914SAndroid Build Coastguard Worker }
410*2e9d4914SAndroid Build Coastguard Worker }
411*2e9d4914SAndroid Build Coastguard Worker
412*2e9d4914SAndroid Build Coastguard Worker return(NULL);
413*2e9d4914SAndroid Build Coastguard Worker }
414*2e9d4914SAndroid Build Coastguard Worker
415*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
416*2e9d4914SAndroid Build Coastguard Worker
__config_list_remove(config_list_t * list,int idx)417*2e9d4914SAndroid Build Coastguard Worker static config_setting_t *__config_list_remove(config_list_t *list, int idx)
418*2e9d4914SAndroid Build Coastguard Worker {
419*2e9d4914SAndroid Build Coastguard Worker config_setting_t *removed = *(list->elements + idx);
420*2e9d4914SAndroid Build Coastguard Worker int offset = (idx * sizeof(config_setting_t *));
421*2e9d4914SAndroid Build Coastguard Worker int len = list->length - 1 - idx;
422*2e9d4914SAndroid Build Coastguard Worker char *base = (char *)list->elements + offset;
423*2e9d4914SAndroid Build Coastguard Worker
424*2e9d4914SAndroid Build Coastguard Worker memmove(base, base + sizeof(config_setting_t *),
425*2e9d4914SAndroid Build Coastguard Worker len * sizeof(config_setting_t *));
426*2e9d4914SAndroid Build Coastguard Worker
427*2e9d4914SAndroid Build Coastguard Worker list->length--;
428*2e9d4914SAndroid Build Coastguard Worker
429*2e9d4914SAndroid Build Coastguard Worker /* possibly realloc smaller? */
430*2e9d4914SAndroid Build Coastguard Worker
431*2e9d4914SAndroid Build Coastguard Worker return(removed);
432*2e9d4914SAndroid Build Coastguard Worker }
433*2e9d4914SAndroid Build Coastguard Worker
434*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
435*2e9d4914SAndroid Build Coastguard Worker
__config_setting_destroy(config_setting_t * setting)436*2e9d4914SAndroid Build Coastguard Worker static void __config_setting_destroy(config_setting_t *setting)
437*2e9d4914SAndroid Build Coastguard Worker {
438*2e9d4914SAndroid Build Coastguard Worker if(setting)
439*2e9d4914SAndroid Build Coastguard Worker {
440*2e9d4914SAndroid Build Coastguard Worker if(setting->name)
441*2e9d4914SAndroid Build Coastguard Worker __delete(setting->name);
442*2e9d4914SAndroid Build Coastguard Worker
443*2e9d4914SAndroid Build Coastguard Worker if(setting->type == CONFIG_TYPE_STRING)
444*2e9d4914SAndroid Build Coastguard Worker __delete(setting->value.sval);
445*2e9d4914SAndroid Build Coastguard Worker
446*2e9d4914SAndroid Build Coastguard Worker else if(config_setting_is_aggregate(setting))
447*2e9d4914SAndroid Build Coastguard Worker {
448*2e9d4914SAndroid Build Coastguard Worker if(setting->value.list)
449*2e9d4914SAndroid Build Coastguard Worker __config_list_destroy(setting->value.list);
450*2e9d4914SAndroid Build Coastguard Worker }
451*2e9d4914SAndroid Build Coastguard Worker
452*2e9d4914SAndroid Build Coastguard Worker if(setting->hook && setting->config->destructor)
453*2e9d4914SAndroid Build Coastguard Worker setting->config->destructor(setting->hook);
454*2e9d4914SAndroid Build Coastguard Worker
455*2e9d4914SAndroid Build Coastguard Worker __delete(setting);
456*2e9d4914SAndroid Build Coastguard Worker }
457*2e9d4914SAndroid Build Coastguard Worker }
458*2e9d4914SAndroid Build Coastguard Worker
459*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
460*2e9d4914SAndroid Build Coastguard Worker
__config_list_destroy(config_list_t * list)461*2e9d4914SAndroid Build Coastguard Worker static void __config_list_destroy(config_list_t *list)
462*2e9d4914SAndroid Build Coastguard Worker {
463*2e9d4914SAndroid Build Coastguard Worker config_setting_t **p;
464*2e9d4914SAndroid Build Coastguard Worker unsigned int i;
465*2e9d4914SAndroid Build Coastguard Worker
466*2e9d4914SAndroid Build Coastguard Worker if(! list)
467*2e9d4914SAndroid Build Coastguard Worker return;
468*2e9d4914SAndroid Build Coastguard Worker
469*2e9d4914SAndroid Build Coastguard Worker if(list->elements)
470*2e9d4914SAndroid Build Coastguard Worker {
471*2e9d4914SAndroid Build Coastguard Worker for(p = list->elements, i = 0; i < list->length; p++, i++)
472*2e9d4914SAndroid Build Coastguard Worker __config_setting_destroy(*p);
473*2e9d4914SAndroid Build Coastguard Worker
474*2e9d4914SAndroid Build Coastguard Worker __delete(list->elements);
475*2e9d4914SAndroid Build Coastguard Worker }
476*2e9d4914SAndroid Build Coastguard Worker
477*2e9d4914SAndroid Build Coastguard Worker __delete(list);
478*2e9d4914SAndroid Build Coastguard Worker }
479*2e9d4914SAndroid Build Coastguard Worker
480*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
481*2e9d4914SAndroid Build Coastguard Worker
__config_list_checktype(const config_setting_t * setting,int type)482*2e9d4914SAndroid Build Coastguard Worker static int __config_list_checktype(const config_setting_t *setting, int type)
483*2e9d4914SAndroid Build Coastguard Worker {
484*2e9d4914SAndroid Build Coastguard Worker /* if the array is empty, then it has no type yet */
485*2e9d4914SAndroid Build Coastguard Worker
486*2e9d4914SAndroid Build Coastguard Worker if(! setting->value.list)
487*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
488*2e9d4914SAndroid Build Coastguard Worker
489*2e9d4914SAndroid Build Coastguard Worker if(setting->value.list->length == 0)
490*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
491*2e9d4914SAndroid Build Coastguard Worker
492*2e9d4914SAndroid Build Coastguard Worker /* if it's a list, any type is allowed */
493*2e9d4914SAndroid Build Coastguard Worker
494*2e9d4914SAndroid Build Coastguard Worker if(setting->type == CONFIG_TYPE_LIST)
495*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
496*2e9d4914SAndroid Build Coastguard Worker
497*2e9d4914SAndroid Build Coastguard Worker /* otherwise the first element added determines the type of the array */
498*2e9d4914SAndroid Build Coastguard Worker
499*2e9d4914SAndroid Build Coastguard Worker return((setting->value.list->elements[0]->type == type)
500*2e9d4914SAndroid Build Coastguard Worker ? CONFIG_TRUE : CONFIG_FALSE);
501*2e9d4914SAndroid Build Coastguard Worker }
502*2e9d4914SAndroid Build Coastguard Worker
503*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
504*2e9d4914SAndroid Build Coastguard Worker
__config_type_is_scalar(int type)505*2e9d4914SAndroid Build Coastguard Worker static int __config_type_is_scalar(int type)
506*2e9d4914SAndroid Build Coastguard Worker {
507*2e9d4914SAndroid Build Coastguard Worker return((type >= CONFIG_TYPE_INT) && (type <= CONFIG_TYPE_BOOL));
508*2e9d4914SAndroid Build Coastguard Worker }
509*2e9d4914SAndroid Build Coastguard Worker
510*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
511*2e9d4914SAndroid Build Coastguard Worker
__config_validate_name(const char * name)512*2e9d4914SAndroid Build Coastguard Worker static int __config_validate_name(const char *name)
513*2e9d4914SAndroid Build Coastguard Worker {
514*2e9d4914SAndroid Build Coastguard Worker const char *p = name;
515*2e9d4914SAndroid Build Coastguard Worker
516*2e9d4914SAndroid Build Coastguard Worker if(*p == '\0')
517*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
518*2e9d4914SAndroid Build Coastguard Worker
519*2e9d4914SAndroid Build Coastguard Worker if(! isalpha((int)*p) && (*p != '*'))
520*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
521*2e9d4914SAndroid Build Coastguard Worker
522*2e9d4914SAndroid Build Coastguard Worker for(++p; *p; ++p)
523*2e9d4914SAndroid Build Coastguard Worker {
524*2e9d4914SAndroid Build Coastguard Worker if(! (isalpha((int)*p) || isdigit((int)*p) || strchr("*_-", (int)*p)))
525*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
526*2e9d4914SAndroid Build Coastguard Worker }
527*2e9d4914SAndroid Build Coastguard Worker
528*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
529*2e9d4914SAndroid Build Coastguard Worker }
530*2e9d4914SAndroid Build Coastguard Worker
531*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
532*2e9d4914SAndroid Build Coastguard Worker
__config_read(config_t * config,FILE * stream,const char * filename,const char * str)533*2e9d4914SAndroid Build Coastguard Worker static int __config_read(config_t *config, FILE *stream, const char *filename,
534*2e9d4914SAndroid Build Coastguard Worker const char *str)
535*2e9d4914SAndroid Build Coastguard Worker {
536*2e9d4914SAndroid Build Coastguard Worker yyscan_t scanner;
537*2e9d4914SAndroid Build Coastguard Worker struct scan_context scan_ctx;
538*2e9d4914SAndroid Build Coastguard Worker struct parse_context parse_ctx;
539*2e9d4914SAndroid Build Coastguard Worker int r;
540*2e9d4914SAndroid Build Coastguard Worker
541*2e9d4914SAndroid Build Coastguard Worker config_clear(config);
542*2e9d4914SAndroid Build Coastguard Worker
543*2e9d4914SAndroid Build Coastguard Worker libconfig_parsectx_init(&parse_ctx);
544*2e9d4914SAndroid Build Coastguard Worker parse_ctx.config = config;
545*2e9d4914SAndroid Build Coastguard Worker parse_ctx.parent = config->root;
546*2e9d4914SAndroid Build Coastguard Worker parse_ctx.setting = config->root;
547*2e9d4914SAndroid Build Coastguard Worker
548*2e9d4914SAndroid Build Coastguard Worker __config_locale_override();
549*2e9d4914SAndroid Build Coastguard Worker
550*2e9d4914SAndroid Build Coastguard Worker libconfig_scanctx_init(&scan_ctx, filename);
551*2e9d4914SAndroid Build Coastguard Worker config->root->file = libconfig_scanctx_current_filename(&scan_ctx);
552*2e9d4914SAndroid Build Coastguard Worker scan_ctx.config = config;
553*2e9d4914SAndroid Build Coastguard Worker libconfig_yylex_init_extra(&scan_ctx, &scanner);
554*2e9d4914SAndroid Build Coastguard Worker
555*2e9d4914SAndroid Build Coastguard Worker if(stream)
556*2e9d4914SAndroid Build Coastguard Worker libconfig_yyrestart(stream, scanner);
557*2e9d4914SAndroid Build Coastguard Worker else /* read from string */
558*2e9d4914SAndroid Build Coastguard Worker (void)libconfig_yy_scan_string(str, scanner);
559*2e9d4914SAndroid Build Coastguard Worker
560*2e9d4914SAndroid Build Coastguard Worker libconfig_yyset_lineno(1, scanner);
561*2e9d4914SAndroid Build Coastguard Worker r = libconfig_yyparse(scanner, &parse_ctx, &scan_ctx);
562*2e9d4914SAndroid Build Coastguard Worker
563*2e9d4914SAndroid Build Coastguard Worker if(r != 0)
564*2e9d4914SAndroid Build Coastguard Worker {
565*2e9d4914SAndroid Build Coastguard Worker YY_BUFFER_STATE buf;
566*2e9d4914SAndroid Build Coastguard Worker
567*2e9d4914SAndroid Build Coastguard Worker config->error_file = libconfig_scanctx_current_filename(&scan_ctx);
568*2e9d4914SAndroid Build Coastguard Worker config->error_type = CONFIG_ERR_PARSE;
569*2e9d4914SAndroid Build Coastguard Worker
570*2e9d4914SAndroid Build Coastguard Worker /* Unwind the include stack, freeing the buffers and closing the files. */
571*2e9d4914SAndroid Build Coastguard Worker while((buf = (YY_BUFFER_STATE)libconfig_scanctx_pop_include(&scan_ctx))
572*2e9d4914SAndroid Build Coastguard Worker != NULL)
573*2e9d4914SAndroid Build Coastguard Worker libconfig_yy_delete_buffer(buf, scanner);
574*2e9d4914SAndroid Build Coastguard Worker }
575*2e9d4914SAndroid Build Coastguard Worker
576*2e9d4914SAndroid Build Coastguard Worker libconfig_yylex_destroy(scanner);
577*2e9d4914SAndroid Build Coastguard Worker config->filenames = libconfig_scanctx_cleanup(&scan_ctx);
578*2e9d4914SAndroid Build Coastguard Worker libconfig_parsectx_cleanup(&parse_ctx);
579*2e9d4914SAndroid Build Coastguard Worker
580*2e9d4914SAndroid Build Coastguard Worker __config_locale_restore();
581*2e9d4914SAndroid Build Coastguard Worker
582*2e9d4914SAndroid Build Coastguard Worker return(r == 0 ? CONFIG_TRUE : CONFIG_FALSE);
583*2e9d4914SAndroid Build Coastguard Worker }
584*2e9d4914SAndroid Build Coastguard Worker
585*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
586*2e9d4914SAndroid Build Coastguard Worker
config_read(config_t * config,FILE * stream)587*2e9d4914SAndroid Build Coastguard Worker int config_read(config_t *config, FILE *stream)
588*2e9d4914SAndroid Build Coastguard Worker {
589*2e9d4914SAndroid Build Coastguard Worker return(__config_read(config, stream, NULL, NULL));
590*2e9d4914SAndroid Build Coastguard Worker }
591*2e9d4914SAndroid Build Coastguard Worker
592*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
593*2e9d4914SAndroid Build Coastguard Worker
config_read_string(config_t * config,const char * str)594*2e9d4914SAndroid Build Coastguard Worker int config_read_string(config_t *config, const char *str)
595*2e9d4914SAndroid Build Coastguard Worker {
596*2e9d4914SAndroid Build Coastguard Worker return(__config_read(config, NULL, NULL, str));
597*2e9d4914SAndroid Build Coastguard Worker }
598*2e9d4914SAndroid Build Coastguard Worker
599*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
600*2e9d4914SAndroid Build Coastguard Worker
__config_write_setting(const config_t * config,const config_setting_t * setting,FILE * stream,int depth)601*2e9d4914SAndroid Build Coastguard Worker static void __config_write_setting(const config_t *config,
602*2e9d4914SAndroid Build Coastguard Worker const config_setting_t *setting,
603*2e9d4914SAndroid Build Coastguard Worker FILE *stream, int depth)
604*2e9d4914SAndroid Build Coastguard Worker {
605*2e9d4914SAndroid Build Coastguard Worker char group_assign_char = config_get_option(
606*2e9d4914SAndroid Build Coastguard Worker config, CONFIG_OPTION_COLON_ASSIGNMENT_FOR_GROUPS) ? ':' : '=';
607*2e9d4914SAndroid Build Coastguard Worker
608*2e9d4914SAndroid Build Coastguard Worker char nongroup_assign_char = config_get_option(
609*2e9d4914SAndroid Build Coastguard Worker config, CONFIG_OPTION_COLON_ASSIGNMENT_FOR_NON_GROUPS) ? ':' : '=';
610*2e9d4914SAndroid Build Coastguard Worker
611*2e9d4914SAndroid Build Coastguard Worker if(depth > 1)
612*2e9d4914SAndroid Build Coastguard Worker __config_indent(stream, depth, config->tab_width);
613*2e9d4914SAndroid Build Coastguard Worker
614*2e9d4914SAndroid Build Coastguard Worker
615*2e9d4914SAndroid Build Coastguard Worker if(setting->name)
616*2e9d4914SAndroid Build Coastguard Worker {
617*2e9d4914SAndroid Build Coastguard Worker fputs(setting->name, stream);
618*2e9d4914SAndroid Build Coastguard Worker fprintf(stream, " %c ", ((setting->type == CONFIG_TYPE_GROUP)
619*2e9d4914SAndroid Build Coastguard Worker ? group_assign_char
620*2e9d4914SAndroid Build Coastguard Worker : nongroup_assign_char));
621*2e9d4914SAndroid Build Coastguard Worker }
622*2e9d4914SAndroid Build Coastguard Worker
623*2e9d4914SAndroid Build Coastguard Worker __config_write_value(config, &(setting->value), setting->type,
624*2e9d4914SAndroid Build Coastguard Worker config_setting_get_format(setting), depth, stream);
625*2e9d4914SAndroid Build Coastguard Worker
626*2e9d4914SAndroid Build Coastguard Worker if(depth > 0)
627*2e9d4914SAndroid Build Coastguard Worker {
628*2e9d4914SAndroid Build Coastguard Worker if(config_get_option(config, CONFIG_OPTION_SEMICOLON_SEPARATORS))
629*2e9d4914SAndroid Build Coastguard Worker fputc(';', stream);
630*2e9d4914SAndroid Build Coastguard Worker
631*2e9d4914SAndroid Build Coastguard Worker fputc('\n', stream);
632*2e9d4914SAndroid Build Coastguard Worker }
633*2e9d4914SAndroid Build Coastguard Worker }
634*2e9d4914SAndroid Build Coastguard Worker
635*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
636*2e9d4914SAndroid Build Coastguard Worker
config_write(const config_t * config,FILE * stream)637*2e9d4914SAndroid Build Coastguard Worker void config_write(const config_t *config, FILE *stream)
638*2e9d4914SAndroid Build Coastguard Worker {
639*2e9d4914SAndroid Build Coastguard Worker __config_locale_override();
640*2e9d4914SAndroid Build Coastguard Worker
641*2e9d4914SAndroid Build Coastguard Worker __config_write_setting(config, config->root, stream, 0);
642*2e9d4914SAndroid Build Coastguard Worker
643*2e9d4914SAndroid Build Coastguard Worker __config_locale_restore();
644*2e9d4914SAndroid Build Coastguard Worker }
645*2e9d4914SAndroid Build Coastguard Worker
646*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
647*2e9d4914SAndroid Build Coastguard Worker
config_read_file(config_t * config,const char * filename)648*2e9d4914SAndroid Build Coastguard Worker int config_read_file(config_t *config, const char *filename)
649*2e9d4914SAndroid Build Coastguard Worker {
650*2e9d4914SAndroid Build Coastguard Worker int ret, ok = 0;
651*2e9d4914SAndroid Build Coastguard Worker
652*2e9d4914SAndroid Build Coastguard Worker FILE *stream = fopen(filename, "rt");
653*2e9d4914SAndroid Build Coastguard Worker if(stream != NULL)
654*2e9d4914SAndroid Build Coastguard Worker {
655*2e9d4914SAndroid Build Coastguard Worker // On some operating systems, fopen() succeeds on a directory.
656*2e9d4914SAndroid Build Coastguard Worker int fd = fileno(stream);
657*2e9d4914SAndroid Build Coastguard Worker struct stat statbuf;
658*2e9d4914SAndroid Build Coastguard Worker
659*2e9d4914SAndroid Build Coastguard Worker if(fstat(fd, &statbuf) == 0)
660*2e9d4914SAndroid Build Coastguard Worker {
661*2e9d4914SAndroid Build Coastguard Worker // Only proceed if this is not a directory.
662*2e9d4914SAndroid Build Coastguard Worker if(!S_ISDIR(statbuf.st_mode))
663*2e9d4914SAndroid Build Coastguard Worker ok = 1;
664*2e9d4914SAndroid Build Coastguard Worker }
665*2e9d4914SAndroid Build Coastguard Worker }
666*2e9d4914SAndroid Build Coastguard Worker
667*2e9d4914SAndroid Build Coastguard Worker if(!ok)
668*2e9d4914SAndroid Build Coastguard Worker {
669*2e9d4914SAndroid Build Coastguard Worker if(stream != NULL)
670*2e9d4914SAndroid Build Coastguard Worker fclose(stream);
671*2e9d4914SAndroid Build Coastguard Worker
672*2e9d4914SAndroid Build Coastguard Worker config->error_text = __io_error;
673*2e9d4914SAndroid Build Coastguard Worker config->error_type = CONFIG_ERR_FILE_IO;
674*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
675*2e9d4914SAndroid Build Coastguard Worker }
676*2e9d4914SAndroid Build Coastguard Worker
677*2e9d4914SAndroid Build Coastguard Worker ret = __config_read(config, stream, filename, NULL);
678*2e9d4914SAndroid Build Coastguard Worker fclose(stream);
679*2e9d4914SAndroid Build Coastguard Worker
680*2e9d4914SAndroid Build Coastguard Worker return(ret);
681*2e9d4914SAndroid Build Coastguard Worker }
682*2e9d4914SAndroid Build Coastguard Worker
683*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
684*2e9d4914SAndroid Build Coastguard Worker
config_write_file(config_t * config,const char * filename)685*2e9d4914SAndroid Build Coastguard Worker int config_write_file(config_t *config, const char *filename)
686*2e9d4914SAndroid Build Coastguard Worker {
687*2e9d4914SAndroid Build Coastguard Worker FILE *stream = fopen(filename, "wt");
688*2e9d4914SAndroid Build Coastguard Worker if(stream == NULL)
689*2e9d4914SAndroid Build Coastguard Worker {
690*2e9d4914SAndroid Build Coastguard Worker config->error_text = __io_error;
691*2e9d4914SAndroid Build Coastguard Worker config->error_type = CONFIG_ERR_FILE_IO;
692*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
693*2e9d4914SAndroid Build Coastguard Worker }
694*2e9d4914SAndroid Build Coastguard Worker
695*2e9d4914SAndroid Build Coastguard Worker config_write(config, stream);
696*2e9d4914SAndroid Build Coastguard Worker
697*2e9d4914SAndroid Build Coastguard Worker if(config_get_option(config, CONFIG_OPTION_FSYNC))
698*2e9d4914SAndroid Build Coastguard Worker {
699*2e9d4914SAndroid Build Coastguard Worker int fd = fileno(stream);
700*2e9d4914SAndroid Build Coastguard Worker
701*2e9d4914SAndroid Build Coastguard Worker if(fd >= 0)
702*2e9d4914SAndroid Build Coastguard Worker {
703*2e9d4914SAndroid Build Coastguard Worker if(fsync(fd) != 0)
704*2e9d4914SAndroid Build Coastguard Worker {
705*2e9d4914SAndroid Build Coastguard Worker fclose(stream);
706*2e9d4914SAndroid Build Coastguard Worker config->error_text = __io_error;
707*2e9d4914SAndroid Build Coastguard Worker config->error_type = CONFIG_ERR_FILE_IO;
708*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
709*2e9d4914SAndroid Build Coastguard Worker }
710*2e9d4914SAndroid Build Coastguard Worker }
711*2e9d4914SAndroid Build Coastguard Worker }
712*2e9d4914SAndroid Build Coastguard Worker
713*2e9d4914SAndroid Build Coastguard Worker fclose(stream);
714*2e9d4914SAndroid Build Coastguard Worker config->error_type = CONFIG_ERR_NONE;
715*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
716*2e9d4914SAndroid Build Coastguard Worker }
717*2e9d4914SAndroid Build Coastguard Worker
718*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
719*2e9d4914SAndroid Build Coastguard Worker
config_destroy(config_t * config)720*2e9d4914SAndroid Build Coastguard Worker void config_destroy(config_t *config)
721*2e9d4914SAndroid Build Coastguard Worker {
722*2e9d4914SAndroid Build Coastguard Worker __config_setting_destroy(config->root);
723*2e9d4914SAndroid Build Coastguard Worker libconfig_strvec_delete(config->filenames);
724*2e9d4914SAndroid Build Coastguard Worker __delete(config->include_dir);
725*2e9d4914SAndroid Build Coastguard Worker __zero(config);
726*2e9d4914SAndroid Build Coastguard Worker }
727*2e9d4914SAndroid Build Coastguard Worker
728*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
729*2e9d4914SAndroid Build Coastguard Worker
config_clear(config_t * config)730*2e9d4914SAndroid Build Coastguard Worker void config_clear(config_t *config)
731*2e9d4914SAndroid Build Coastguard Worker {
732*2e9d4914SAndroid Build Coastguard Worker /* Destroy the root setting (recursively) and then create a new one. */
733*2e9d4914SAndroid Build Coastguard Worker __config_setting_destroy(config->root);
734*2e9d4914SAndroid Build Coastguard Worker
735*2e9d4914SAndroid Build Coastguard Worker libconfig_strvec_delete(config->filenames);
736*2e9d4914SAndroid Build Coastguard Worker config->filenames = NULL;
737*2e9d4914SAndroid Build Coastguard Worker
738*2e9d4914SAndroid Build Coastguard Worker config->root = __new(config_setting_t);
739*2e9d4914SAndroid Build Coastguard Worker config->root->type = CONFIG_TYPE_GROUP;
740*2e9d4914SAndroid Build Coastguard Worker config->root->config = config;
741*2e9d4914SAndroid Build Coastguard Worker }
742*2e9d4914SAndroid Build Coastguard Worker
743*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
744*2e9d4914SAndroid Build Coastguard Worker
config_set_tab_width(config_t * config,unsigned short width)745*2e9d4914SAndroid Build Coastguard Worker void config_set_tab_width(config_t *config, unsigned short width)
746*2e9d4914SAndroid Build Coastguard Worker {
747*2e9d4914SAndroid Build Coastguard Worker /* As per documentation: valid range is 0 - 15. */
748*2e9d4914SAndroid Build Coastguard Worker config->tab_width = (width <= 15) ? width : 15;
749*2e9d4914SAndroid Build Coastguard Worker }
750*2e9d4914SAndroid Build Coastguard Worker
751*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
752*2e9d4914SAndroid Build Coastguard Worker
config_get_tab_width(const config_t * config)753*2e9d4914SAndroid Build Coastguard Worker unsigned short config_get_tab_width(const config_t *config)
754*2e9d4914SAndroid Build Coastguard Worker {
755*2e9d4914SAndroid Build Coastguard Worker return config->tab_width;
756*2e9d4914SAndroid Build Coastguard Worker }
757*2e9d4914SAndroid Build Coastguard Worker
758*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
759*2e9d4914SAndroid Build Coastguard Worker
config_set_float_precision(config_t * config,unsigned short digits)760*2e9d4914SAndroid Build Coastguard Worker void config_set_float_precision(config_t *config, unsigned short digits)
761*2e9d4914SAndroid Build Coastguard Worker {
762*2e9d4914SAndroid Build Coastguard Worker config->float_precision = digits;
763*2e9d4914SAndroid Build Coastguard Worker }
764*2e9d4914SAndroid Build Coastguard Worker
765*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
766*2e9d4914SAndroid Build Coastguard Worker
config_get_float_precision(const config_t * config)767*2e9d4914SAndroid Build Coastguard Worker unsigned short config_get_float_precision(const config_t *config)
768*2e9d4914SAndroid Build Coastguard Worker {
769*2e9d4914SAndroid Build Coastguard Worker return config->float_precision;
770*2e9d4914SAndroid Build Coastguard Worker }
771*2e9d4914SAndroid Build Coastguard Worker
772*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
773*2e9d4914SAndroid Build Coastguard Worker
config_init(config_t * config)774*2e9d4914SAndroid Build Coastguard Worker void config_init(config_t *config)
775*2e9d4914SAndroid Build Coastguard Worker {
776*2e9d4914SAndroid Build Coastguard Worker __zero(config);
777*2e9d4914SAndroid Build Coastguard Worker config_clear(config);
778*2e9d4914SAndroid Build Coastguard Worker
779*2e9d4914SAndroid Build Coastguard Worker /* Set default options. */
780*2e9d4914SAndroid Build Coastguard Worker config->options = (CONFIG_OPTION_SEMICOLON_SEPARATORS
781*2e9d4914SAndroid Build Coastguard Worker | CONFIG_OPTION_COLON_ASSIGNMENT_FOR_GROUPS
782*2e9d4914SAndroid Build Coastguard Worker | CONFIG_OPTION_OPEN_BRACE_ON_SEPARATE_LINE);
783*2e9d4914SAndroid Build Coastguard Worker config->tab_width = DEFAULT_TAB_WIDTH;
784*2e9d4914SAndroid Build Coastguard Worker config->float_precision = DEFAULT_FLOAT_PRECISION;
785*2e9d4914SAndroid Build Coastguard Worker config->include_fn = config_default_include_func;
786*2e9d4914SAndroid Build Coastguard Worker }
787*2e9d4914SAndroid Build Coastguard Worker
788*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
789*2e9d4914SAndroid Build Coastguard Worker
config_set_options(config_t * config,int options)790*2e9d4914SAndroid Build Coastguard Worker void config_set_options(config_t *config, int options)
791*2e9d4914SAndroid Build Coastguard Worker {
792*2e9d4914SAndroid Build Coastguard Worker config->options = options;
793*2e9d4914SAndroid Build Coastguard Worker }
794*2e9d4914SAndroid Build Coastguard Worker
795*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
796*2e9d4914SAndroid Build Coastguard Worker
config_get_options(const config_t * config)797*2e9d4914SAndroid Build Coastguard Worker int config_get_options(const config_t *config)
798*2e9d4914SAndroid Build Coastguard Worker {
799*2e9d4914SAndroid Build Coastguard Worker return(config->options);
800*2e9d4914SAndroid Build Coastguard Worker }
801*2e9d4914SAndroid Build Coastguard Worker
802*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
803*2e9d4914SAndroid Build Coastguard Worker
config_set_option(config_t * config,int option,int flag)804*2e9d4914SAndroid Build Coastguard Worker void config_set_option(config_t *config, int option, int flag)
805*2e9d4914SAndroid Build Coastguard Worker {
806*2e9d4914SAndroid Build Coastguard Worker if(flag)
807*2e9d4914SAndroid Build Coastguard Worker config->options |= option;
808*2e9d4914SAndroid Build Coastguard Worker else
809*2e9d4914SAndroid Build Coastguard Worker config->options &= ~option;
810*2e9d4914SAndroid Build Coastguard Worker }
811*2e9d4914SAndroid Build Coastguard Worker
812*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
813*2e9d4914SAndroid Build Coastguard Worker
config_get_option(const config_t * config,int option)814*2e9d4914SAndroid Build Coastguard Worker int config_get_option(const config_t *config, int option)
815*2e9d4914SAndroid Build Coastguard Worker {
816*2e9d4914SAndroid Build Coastguard Worker return((config->options & option) == option);
817*2e9d4914SAndroid Build Coastguard Worker }
818*2e9d4914SAndroid Build Coastguard Worker
819*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
820*2e9d4914SAndroid Build Coastguard Worker
config_set_hook(config_t * config,void * hook)821*2e9d4914SAndroid Build Coastguard Worker void config_set_hook(config_t *config, void *hook)
822*2e9d4914SAndroid Build Coastguard Worker {
823*2e9d4914SAndroid Build Coastguard Worker config->hook = hook;
824*2e9d4914SAndroid Build Coastguard Worker }
825*2e9d4914SAndroid Build Coastguard Worker
826*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
827*2e9d4914SAndroid Build Coastguard Worker
config_setting_create(config_setting_t * parent,const char * name,int type)828*2e9d4914SAndroid Build Coastguard Worker static config_setting_t *config_setting_create(config_setting_t *parent,
829*2e9d4914SAndroid Build Coastguard Worker const char *name, int type)
830*2e9d4914SAndroid Build Coastguard Worker {
831*2e9d4914SAndroid Build Coastguard Worker config_setting_t *setting;
832*2e9d4914SAndroid Build Coastguard Worker config_list_t *list;
833*2e9d4914SAndroid Build Coastguard Worker
834*2e9d4914SAndroid Build Coastguard Worker if(!config_setting_is_aggregate(parent))
835*2e9d4914SAndroid Build Coastguard Worker return(NULL);
836*2e9d4914SAndroid Build Coastguard Worker
837*2e9d4914SAndroid Build Coastguard Worker setting = __new(config_setting_t);
838*2e9d4914SAndroid Build Coastguard Worker setting->parent = parent;
839*2e9d4914SAndroid Build Coastguard Worker setting->name = (name == NULL) ? NULL : strdup(name);
840*2e9d4914SAndroid Build Coastguard Worker setting->type = type;
841*2e9d4914SAndroid Build Coastguard Worker setting->config = parent->config;
842*2e9d4914SAndroid Build Coastguard Worker setting->hook = NULL;
843*2e9d4914SAndroid Build Coastguard Worker setting->line = 0;
844*2e9d4914SAndroid Build Coastguard Worker
845*2e9d4914SAndroid Build Coastguard Worker list = parent->value.list;
846*2e9d4914SAndroid Build Coastguard Worker
847*2e9d4914SAndroid Build Coastguard Worker if(! list)
848*2e9d4914SAndroid Build Coastguard Worker list = parent->value.list = __new(config_list_t);
849*2e9d4914SAndroid Build Coastguard Worker
850*2e9d4914SAndroid Build Coastguard Worker __config_list_add(list, setting);
851*2e9d4914SAndroid Build Coastguard Worker
852*2e9d4914SAndroid Build Coastguard Worker return(setting);
853*2e9d4914SAndroid Build Coastguard Worker }
854*2e9d4914SAndroid Build Coastguard Worker
855*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
856*2e9d4914SAndroid Build Coastguard Worker
__config_setting_get_int(const config_setting_t * setting,int * value)857*2e9d4914SAndroid Build Coastguard Worker static int __config_setting_get_int(const config_setting_t *setting,
858*2e9d4914SAndroid Build Coastguard Worker int *value)
859*2e9d4914SAndroid Build Coastguard Worker {
860*2e9d4914SAndroid Build Coastguard Worker switch(setting->type)
861*2e9d4914SAndroid Build Coastguard Worker {
862*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT:
863*2e9d4914SAndroid Build Coastguard Worker *value = setting->value.ival;
864*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
865*2e9d4914SAndroid Build Coastguard Worker
866*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT64:
867*2e9d4914SAndroid Build Coastguard Worker if((setting->value.llval >= INT_MIN)
868*2e9d4914SAndroid Build Coastguard Worker && (setting->value.llval <= INT_MAX))
869*2e9d4914SAndroid Build Coastguard Worker {
870*2e9d4914SAndroid Build Coastguard Worker *value = (int)(setting->value.llval);
871*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
872*2e9d4914SAndroid Build Coastguard Worker }
873*2e9d4914SAndroid Build Coastguard Worker else
874*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
875*2e9d4914SAndroid Build Coastguard Worker
876*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_FLOAT:
877*2e9d4914SAndroid Build Coastguard Worker if(config_get_option(setting->config, CONFIG_OPTION_AUTOCONVERT))
878*2e9d4914SAndroid Build Coastguard Worker {
879*2e9d4914SAndroid Build Coastguard Worker *value = (int)(setting->value.fval);
880*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
881*2e9d4914SAndroid Build Coastguard Worker }
882*2e9d4914SAndroid Build Coastguard Worker else
883*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
884*2e9d4914SAndroid Build Coastguard Worker
885*2e9d4914SAndroid Build Coastguard Worker default:
886*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
887*2e9d4914SAndroid Build Coastguard Worker }
888*2e9d4914SAndroid Build Coastguard Worker }
889*2e9d4914SAndroid Build Coastguard Worker
890*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
891*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_int(const config_setting_t * setting)892*2e9d4914SAndroid Build Coastguard Worker int config_setting_get_int(const config_setting_t *setting)
893*2e9d4914SAndroid Build Coastguard Worker {
894*2e9d4914SAndroid Build Coastguard Worker int value = 0;
895*2e9d4914SAndroid Build Coastguard Worker __config_setting_get_int(setting, &value);
896*2e9d4914SAndroid Build Coastguard Worker return(value);
897*2e9d4914SAndroid Build Coastguard Worker }
898*2e9d4914SAndroid Build Coastguard Worker
899*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
900*2e9d4914SAndroid Build Coastguard Worker
__config_setting_get_int64(const config_setting_t * setting,long long * value)901*2e9d4914SAndroid Build Coastguard Worker static int __config_setting_get_int64(const config_setting_t *setting,
902*2e9d4914SAndroid Build Coastguard Worker long long *value)
903*2e9d4914SAndroid Build Coastguard Worker {
904*2e9d4914SAndroid Build Coastguard Worker switch(setting->type)
905*2e9d4914SAndroid Build Coastguard Worker {
906*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT64:
907*2e9d4914SAndroid Build Coastguard Worker *value = setting->value.llval;
908*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
909*2e9d4914SAndroid Build Coastguard Worker
910*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT:
911*2e9d4914SAndroid Build Coastguard Worker *value = (long long)(setting->value.ival);
912*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
913*2e9d4914SAndroid Build Coastguard Worker
914*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_FLOAT:
915*2e9d4914SAndroid Build Coastguard Worker if(config_get_option(setting->config, CONFIG_OPTION_AUTOCONVERT))
916*2e9d4914SAndroid Build Coastguard Worker {
917*2e9d4914SAndroid Build Coastguard Worker *value = (long long)(setting->value.fval);
918*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
919*2e9d4914SAndroid Build Coastguard Worker }
920*2e9d4914SAndroid Build Coastguard Worker else
921*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
922*2e9d4914SAndroid Build Coastguard Worker
923*2e9d4914SAndroid Build Coastguard Worker default:
924*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
925*2e9d4914SAndroid Build Coastguard Worker }
926*2e9d4914SAndroid Build Coastguard Worker }
927*2e9d4914SAndroid Build Coastguard Worker
928*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
929*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_int64(const config_setting_t * setting)930*2e9d4914SAndroid Build Coastguard Worker long long config_setting_get_int64(const config_setting_t *setting)
931*2e9d4914SAndroid Build Coastguard Worker {
932*2e9d4914SAndroid Build Coastguard Worker long long value = 0;
933*2e9d4914SAndroid Build Coastguard Worker __config_setting_get_int64(setting, &value);
934*2e9d4914SAndroid Build Coastguard Worker return(value);
935*2e9d4914SAndroid Build Coastguard Worker }
936*2e9d4914SAndroid Build Coastguard Worker
937*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
938*2e9d4914SAndroid Build Coastguard Worker
config_setting_lookup_int(const config_setting_t * setting,const char * name,int * value)939*2e9d4914SAndroid Build Coastguard Worker int config_setting_lookup_int(const config_setting_t *setting,
940*2e9d4914SAndroid Build Coastguard Worker const char *name, int *value)
941*2e9d4914SAndroid Build Coastguard Worker {
942*2e9d4914SAndroid Build Coastguard Worker config_setting_t *member = config_setting_get_member(setting, name);
943*2e9d4914SAndroid Build Coastguard Worker if(! member)
944*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
945*2e9d4914SAndroid Build Coastguard Worker
946*2e9d4914SAndroid Build Coastguard Worker return(__config_setting_get_int(member, value));
947*2e9d4914SAndroid Build Coastguard Worker }
948*2e9d4914SAndroid Build Coastguard Worker
949*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
950*2e9d4914SAndroid Build Coastguard Worker
config_setting_lookup_int64(const config_setting_t * setting,const char * name,long long * value)951*2e9d4914SAndroid Build Coastguard Worker int config_setting_lookup_int64(const config_setting_t *setting,
952*2e9d4914SAndroid Build Coastguard Worker const char *name, long long *value)
953*2e9d4914SAndroid Build Coastguard Worker {
954*2e9d4914SAndroid Build Coastguard Worker config_setting_t *member = config_setting_get_member(setting, name);
955*2e9d4914SAndroid Build Coastguard Worker if(! member)
956*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
957*2e9d4914SAndroid Build Coastguard Worker
958*2e9d4914SAndroid Build Coastguard Worker return(__config_setting_get_int64(member, value));
959*2e9d4914SAndroid Build Coastguard Worker }
960*2e9d4914SAndroid Build Coastguard Worker
961*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
962*2e9d4914SAndroid Build Coastguard Worker
__config_setting_get_float(const config_setting_t * setting,double * value)963*2e9d4914SAndroid Build Coastguard Worker static int __config_setting_get_float(const config_setting_t *setting,
964*2e9d4914SAndroid Build Coastguard Worker double *value)
965*2e9d4914SAndroid Build Coastguard Worker {
966*2e9d4914SAndroid Build Coastguard Worker switch(setting->type)
967*2e9d4914SAndroid Build Coastguard Worker {
968*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_FLOAT:
969*2e9d4914SAndroid Build Coastguard Worker *value = setting->value.fval;
970*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
971*2e9d4914SAndroid Build Coastguard Worker
972*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT:
973*2e9d4914SAndroid Build Coastguard Worker if(config_get_auto_convert(setting->config))
974*2e9d4914SAndroid Build Coastguard Worker {
975*2e9d4914SAndroid Build Coastguard Worker *value = (double)(setting->value.ival);
976*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
977*2e9d4914SAndroid Build Coastguard Worker }
978*2e9d4914SAndroid Build Coastguard Worker else
979*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
980*2e9d4914SAndroid Build Coastguard Worker
981*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT64:
982*2e9d4914SAndroid Build Coastguard Worker if(config_get_auto_convert(setting->config))
983*2e9d4914SAndroid Build Coastguard Worker {
984*2e9d4914SAndroid Build Coastguard Worker *value = (double)(setting->value.llval);
985*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
986*2e9d4914SAndroid Build Coastguard Worker }
987*2e9d4914SAndroid Build Coastguard Worker else
988*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
989*2e9d4914SAndroid Build Coastguard Worker
990*2e9d4914SAndroid Build Coastguard Worker default:
991*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
992*2e9d4914SAndroid Build Coastguard Worker }
993*2e9d4914SAndroid Build Coastguard Worker }
994*2e9d4914SAndroid Build Coastguard Worker
995*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
996*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_float(const config_setting_t * setting)997*2e9d4914SAndroid Build Coastguard Worker double config_setting_get_float(const config_setting_t *setting)
998*2e9d4914SAndroid Build Coastguard Worker {
999*2e9d4914SAndroid Build Coastguard Worker double value = 0.0;
1000*2e9d4914SAndroid Build Coastguard Worker __config_setting_get_float(setting, &value);
1001*2e9d4914SAndroid Build Coastguard Worker return(value);
1002*2e9d4914SAndroid Build Coastguard Worker }
1003*2e9d4914SAndroid Build Coastguard Worker
1004*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1005*2e9d4914SAndroid Build Coastguard Worker
config_setting_lookup_float(const config_setting_t * setting,const char * name,double * value)1006*2e9d4914SAndroid Build Coastguard Worker int config_setting_lookup_float(const config_setting_t *setting,
1007*2e9d4914SAndroid Build Coastguard Worker const char *name, double *value)
1008*2e9d4914SAndroid Build Coastguard Worker {
1009*2e9d4914SAndroid Build Coastguard Worker config_setting_t *member = config_setting_get_member(setting, name);
1010*2e9d4914SAndroid Build Coastguard Worker if(! member)
1011*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1012*2e9d4914SAndroid Build Coastguard Worker
1013*2e9d4914SAndroid Build Coastguard Worker return(__config_setting_get_float(member, value));
1014*2e9d4914SAndroid Build Coastguard Worker }
1015*2e9d4914SAndroid Build Coastguard Worker
1016*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1017*2e9d4914SAndroid Build Coastguard Worker
config_setting_lookup_string(const config_setting_t * setting,const char * name,const char ** value)1018*2e9d4914SAndroid Build Coastguard Worker int config_setting_lookup_string(const config_setting_t *setting,
1019*2e9d4914SAndroid Build Coastguard Worker const char *name, const char **value)
1020*2e9d4914SAndroid Build Coastguard Worker {
1021*2e9d4914SAndroid Build Coastguard Worker config_setting_t *member = config_setting_get_member(setting, name);
1022*2e9d4914SAndroid Build Coastguard Worker if(! member)
1023*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1024*2e9d4914SAndroid Build Coastguard Worker
1025*2e9d4914SAndroid Build Coastguard Worker if(config_setting_type(member) != CONFIG_TYPE_STRING)
1026*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1027*2e9d4914SAndroid Build Coastguard Worker
1028*2e9d4914SAndroid Build Coastguard Worker *value = config_setting_get_string(member);
1029*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1030*2e9d4914SAndroid Build Coastguard Worker }
1031*2e9d4914SAndroid Build Coastguard Worker
1032*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1033*2e9d4914SAndroid Build Coastguard Worker
config_setting_lookup_bool(const config_setting_t * setting,const char * name,int * value)1034*2e9d4914SAndroid Build Coastguard Worker int config_setting_lookup_bool(const config_setting_t *setting,
1035*2e9d4914SAndroid Build Coastguard Worker const char *name, int *value)
1036*2e9d4914SAndroid Build Coastguard Worker {
1037*2e9d4914SAndroid Build Coastguard Worker config_setting_t *member = config_setting_get_member(setting, name);
1038*2e9d4914SAndroid Build Coastguard Worker if(! member)
1039*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1040*2e9d4914SAndroid Build Coastguard Worker
1041*2e9d4914SAndroid Build Coastguard Worker if(config_setting_type(member) != CONFIG_TYPE_BOOL)
1042*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1043*2e9d4914SAndroid Build Coastguard Worker
1044*2e9d4914SAndroid Build Coastguard Worker *value = config_setting_get_bool(member);
1045*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1046*2e9d4914SAndroid Build Coastguard Worker }
1047*2e9d4914SAndroid Build Coastguard Worker
1048*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1049*2e9d4914SAndroid Build Coastguard Worker
config_setting_set_int(config_setting_t * setting,int value)1050*2e9d4914SAndroid Build Coastguard Worker int config_setting_set_int(config_setting_t *setting, int value)
1051*2e9d4914SAndroid Build Coastguard Worker {
1052*2e9d4914SAndroid Build Coastguard Worker switch(setting->type)
1053*2e9d4914SAndroid Build Coastguard Worker {
1054*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_NONE:
1055*2e9d4914SAndroid Build Coastguard Worker setting->type = CONFIG_TYPE_INT;
1056*2e9d4914SAndroid Build Coastguard Worker /* fall through */
1057*2e9d4914SAndroid Build Coastguard Worker
1058*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT:
1059*2e9d4914SAndroid Build Coastguard Worker setting->value.ival = value;
1060*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1061*2e9d4914SAndroid Build Coastguard Worker
1062*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_FLOAT:
1063*2e9d4914SAndroid Build Coastguard Worker if(config_get_auto_convert(setting->config))
1064*2e9d4914SAndroid Build Coastguard Worker {
1065*2e9d4914SAndroid Build Coastguard Worker setting->value.fval = (float)value;
1066*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1067*2e9d4914SAndroid Build Coastguard Worker }
1068*2e9d4914SAndroid Build Coastguard Worker else
1069*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1070*2e9d4914SAndroid Build Coastguard Worker
1071*2e9d4914SAndroid Build Coastguard Worker default:
1072*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1073*2e9d4914SAndroid Build Coastguard Worker }
1074*2e9d4914SAndroid Build Coastguard Worker }
1075*2e9d4914SAndroid Build Coastguard Worker
1076*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1077*2e9d4914SAndroid Build Coastguard Worker
config_setting_set_int64(config_setting_t * setting,long long value)1078*2e9d4914SAndroid Build Coastguard Worker int config_setting_set_int64(config_setting_t *setting, long long value)
1079*2e9d4914SAndroid Build Coastguard Worker {
1080*2e9d4914SAndroid Build Coastguard Worker switch(setting->type)
1081*2e9d4914SAndroid Build Coastguard Worker {
1082*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_NONE:
1083*2e9d4914SAndroid Build Coastguard Worker setting->type = CONFIG_TYPE_INT64;
1084*2e9d4914SAndroid Build Coastguard Worker /* fall through */
1085*2e9d4914SAndroid Build Coastguard Worker
1086*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT64:
1087*2e9d4914SAndroid Build Coastguard Worker setting->value.llval = value;
1088*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1089*2e9d4914SAndroid Build Coastguard Worker
1090*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT:
1091*2e9d4914SAndroid Build Coastguard Worker if((value >= INT_MIN) && (value <= INT_MAX))
1092*2e9d4914SAndroid Build Coastguard Worker {
1093*2e9d4914SAndroid Build Coastguard Worker setting->value.ival = (int)value;
1094*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1095*2e9d4914SAndroid Build Coastguard Worker }
1096*2e9d4914SAndroid Build Coastguard Worker else
1097*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1098*2e9d4914SAndroid Build Coastguard Worker
1099*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_FLOAT:
1100*2e9d4914SAndroid Build Coastguard Worker if(config_get_auto_convert(setting->config))
1101*2e9d4914SAndroid Build Coastguard Worker {
1102*2e9d4914SAndroid Build Coastguard Worker setting->value.fval = (float)value;
1103*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1104*2e9d4914SAndroid Build Coastguard Worker }
1105*2e9d4914SAndroid Build Coastguard Worker else
1106*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1107*2e9d4914SAndroid Build Coastguard Worker
1108*2e9d4914SAndroid Build Coastguard Worker default:
1109*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1110*2e9d4914SAndroid Build Coastguard Worker }
1111*2e9d4914SAndroid Build Coastguard Worker }
1112*2e9d4914SAndroid Build Coastguard Worker
1113*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1114*2e9d4914SAndroid Build Coastguard Worker
config_setting_set_float(config_setting_t * setting,double value)1115*2e9d4914SAndroid Build Coastguard Worker int config_setting_set_float(config_setting_t *setting, double value)
1116*2e9d4914SAndroid Build Coastguard Worker {
1117*2e9d4914SAndroid Build Coastguard Worker switch(setting->type)
1118*2e9d4914SAndroid Build Coastguard Worker {
1119*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_NONE:
1120*2e9d4914SAndroid Build Coastguard Worker setting->type = CONFIG_TYPE_FLOAT;
1121*2e9d4914SAndroid Build Coastguard Worker /* fall through */
1122*2e9d4914SAndroid Build Coastguard Worker
1123*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_FLOAT:
1124*2e9d4914SAndroid Build Coastguard Worker setting->value.fval = value;
1125*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1126*2e9d4914SAndroid Build Coastguard Worker
1127*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT:
1128*2e9d4914SAndroid Build Coastguard Worker if(config_get_option(setting->config, CONFIG_OPTION_AUTOCONVERT))
1129*2e9d4914SAndroid Build Coastguard Worker {
1130*2e9d4914SAndroid Build Coastguard Worker setting->value.ival = (int)value;
1131*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1132*2e9d4914SAndroid Build Coastguard Worker }
1133*2e9d4914SAndroid Build Coastguard Worker else
1134*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1135*2e9d4914SAndroid Build Coastguard Worker
1136*2e9d4914SAndroid Build Coastguard Worker case CONFIG_TYPE_INT64:
1137*2e9d4914SAndroid Build Coastguard Worker if(config_get_option(setting->config, CONFIG_OPTION_AUTOCONVERT))
1138*2e9d4914SAndroid Build Coastguard Worker {
1139*2e9d4914SAndroid Build Coastguard Worker setting->value.llval = (long long)value;
1140*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1141*2e9d4914SAndroid Build Coastguard Worker }
1142*2e9d4914SAndroid Build Coastguard Worker else
1143*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1144*2e9d4914SAndroid Build Coastguard Worker
1145*2e9d4914SAndroid Build Coastguard Worker default:
1146*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1147*2e9d4914SAndroid Build Coastguard Worker }
1148*2e9d4914SAndroid Build Coastguard Worker }
1149*2e9d4914SAndroid Build Coastguard Worker
1150*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1151*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_bool(const config_setting_t * setting)1152*2e9d4914SAndroid Build Coastguard Worker int config_setting_get_bool(const config_setting_t *setting)
1153*2e9d4914SAndroid Build Coastguard Worker {
1154*2e9d4914SAndroid Build Coastguard Worker return((setting->type == CONFIG_TYPE_BOOL) ? setting->value.ival : 0);
1155*2e9d4914SAndroid Build Coastguard Worker }
1156*2e9d4914SAndroid Build Coastguard Worker
1157*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1158*2e9d4914SAndroid Build Coastguard Worker
config_setting_set_bool(config_setting_t * setting,int value)1159*2e9d4914SAndroid Build Coastguard Worker int config_setting_set_bool(config_setting_t *setting, int value)
1160*2e9d4914SAndroid Build Coastguard Worker {
1161*2e9d4914SAndroid Build Coastguard Worker if(setting->type == CONFIG_TYPE_NONE)
1162*2e9d4914SAndroid Build Coastguard Worker setting->type = CONFIG_TYPE_BOOL;
1163*2e9d4914SAndroid Build Coastguard Worker else if(setting->type != CONFIG_TYPE_BOOL)
1164*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1165*2e9d4914SAndroid Build Coastguard Worker
1166*2e9d4914SAndroid Build Coastguard Worker setting->value.ival = value;
1167*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1168*2e9d4914SAndroid Build Coastguard Worker }
1169*2e9d4914SAndroid Build Coastguard Worker
1170*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1171*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_string(const config_setting_t * setting)1172*2e9d4914SAndroid Build Coastguard Worker const char *config_setting_get_string(const config_setting_t *setting)
1173*2e9d4914SAndroid Build Coastguard Worker {
1174*2e9d4914SAndroid Build Coastguard Worker return((setting->type == CONFIG_TYPE_STRING) ? setting->value.sval : NULL);
1175*2e9d4914SAndroid Build Coastguard Worker }
1176*2e9d4914SAndroid Build Coastguard Worker
1177*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1178*2e9d4914SAndroid Build Coastguard Worker
config_setting_set_string(config_setting_t * setting,const char * value)1179*2e9d4914SAndroid Build Coastguard Worker int config_setting_set_string(config_setting_t *setting, const char *value)
1180*2e9d4914SAndroid Build Coastguard Worker {
1181*2e9d4914SAndroid Build Coastguard Worker if(setting->type == CONFIG_TYPE_NONE)
1182*2e9d4914SAndroid Build Coastguard Worker setting->type = CONFIG_TYPE_STRING;
1183*2e9d4914SAndroid Build Coastguard Worker else if(setting->type != CONFIG_TYPE_STRING)
1184*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1185*2e9d4914SAndroid Build Coastguard Worker
1186*2e9d4914SAndroid Build Coastguard Worker if(setting->value.sval)
1187*2e9d4914SAndroid Build Coastguard Worker __delete(setting->value.sval);
1188*2e9d4914SAndroid Build Coastguard Worker
1189*2e9d4914SAndroid Build Coastguard Worker setting->value.sval = (value == NULL) ? NULL : strdup(value);
1190*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1191*2e9d4914SAndroid Build Coastguard Worker }
1192*2e9d4914SAndroid Build Coastguard Worker
1193*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1194*2e9d4914SAndroid Build Coastguard Worker
config_setting_set_format(config_setting_t * setting,short format)1195*2e9d4914SAndroid Build Coastguard Worker int config_setting_set_format(config_setting_t *setting, short format)
1196*2e9d4914SAndroid Build Coastguard Worker {
1197*2e9d4914SAndroid Build Coastguard Worker if(((setting->type != CONFIG_TYPE_INT)
1198*2e9d4914SAndroid Build Coastguard Worker && (setting->type != CONFIG_TYPE_INT64))
1199*2e9d4914SAndroid Build Coastguard Worker || ((format != CONFIG_FORMAT_DEFAULT) && (format != CONFIG_FORMAT_HEX)))
1200*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1201*2e9d4914SAndroid Build Coastguard Worker
1202*2e9d4914SAndroid Build Coastguard Worker setting->format = format;
1203*2e9d4914SAndroid Build Coastguard Worker
1204*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1205*2e9d4914SAndroid Build Coastguard Worker }
1206*2e9d4914SAndroid Build Coastguard Worker
1207*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1208*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_format(const config_setting_t * setting)1209*2e9d4914SAndroid Build Coastguard Worker short config_setting_get_format(const config_setting_t *setting)
1210*2e9d4914SAndroid Build Coastguard Worker {
1211*2e9d4914SAndroid Build Coastguard Worker return(setting->format != 0 ? setting->format
1212*2e9d4914SAndroid Build Coastguard Worker : setting->config->default_format);
1213*2e9d4914SAndroid Build Coastguard Worker }
1214*2e9d4914SAndroid Build Coastguard Worker
1215*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1216*2e9d4914SAndroid Build Coastguard Worker
config_setting_lookup(config_setting_t * setting,const char * path)1217*2e9d4914SAndroid Build Coastguard Worker config_setting_t *config_setting_lookup(config_setting_t *setting,
1218*2e9d4914SAndroid Build Coastguard Worker const char *path)
1219*2e9d4914SAndroid Build Coastguard Worker {
1220*2e9d4914SAndroid Build Coastguard Worker const char *p = path;
1221*2e9d4914SAndroid Build Coastguard Worker config_setting_t *found = setting;
1222*2e9d4914SAndroid Build Coastguard Worker
1223*2e9d4914SAndroid Build Coastguard Worker for(;;)
1224*2e9d4914SAndroid Build Coastguard Worker {
1225*2e9d4914SAndroid Build Coastguard Worker while(*p && strchr(PATH_TOKENS, *p))
1226*2e9d4914SAndroid Build Coastguard Worker p++;
1227*2e9d4914SAndroid Build Coastguard Worker
1228*2e9d4914SAndroid Build Coastguard Worker if(! *p)
1229*2e9d4914SAndroid Build Coastguard Worker break;
1230*2e9d4914SAndroid Build Coastguard Worker
1231*2e9d4914SAndroid Build Coastguard Worker if(*p == '[')
1232*2e9d4914SAndroid Build Coastguard Worker found = config_setting_get_elem(found, atoi(++p));
1233*2e9d4914SAndroid Build Coastguard Worker else
1234*2e9d4914SAndroid Build Coastguard Worker found = config_setting_get_member(found, p);
1235*2e9d4914SAndroid Build Coastguard Worker
1236*2e9d4914SAndroid Build Coastguard Worker if(! found)
1237*2e9d4914SAndroid Build Coastguard Worker break;
1238*2e9d4914SAndroid Build Coastguard Worker
1239*2e9d4914SAndroid Build Coastguard Worker while(! strchr(PATH_TOKENS, *p))
1240*2e9d4914SAndroid Build Coastguard Worker p++;
1241*2e9d4914SAndroid Build Coastguard Worker }
1242*2e9d4914SAndroid Build Coastguard Worker
1243*2e9d4914SAndroid Build Coastguard Worker return(*p || (found == setting) ? NULL : found);
1244*2e9d4914SAndroid Build Coastguard Worker }
1245*2e9d4914SAndroid Build Coastguard Worker
1246*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1247*2e9d4914SAndroid Build Coastguard Worker
config_lookup(const config_t * config,const char * path)1248*2e9d4914SAndroid Build Coastguard Worker config_setting_t *config_lookup(const config_t *config, const char *path)
1249*2e9d4914SAndroid Build Coastguard Worker {
1250*2e9d4914SAndroid Build Coastguard Worker return(config_setting_lookup(config->root, path));
1251*2e9d4914SAndroid Build Coastguard Worker }
1252*2e9d4914SAndroid Build Coastguard Worker
1253*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1254*2e9d4914SAndroid Build Coastguard Worker
config_lookup_string(const config_t * config,const char * path,const char ** value)1255*2e9d4914SAndroid Build Coastguard Worker int config_lookup_string(const config_t *config, const char *path,
1256*2e9d4914SAndroid Build Coastguard Worker const char **value)
1257*2e9d4914SAndroid Build Coastguard Worker {
1258*2e9d4914SAndroid Build Coastguard Worker const config_setting_t *s = config_lookup(config, path);
1259*2e9d4914SAndroid Build Coastguard Worker if(! s)
1260*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1261*2e9d4914SAndroid Build Coastguard Worker
1262*2e9d4914SAndroid Build Coastguard Worker if(config_setting_type(s) != CONFIG_TYPE_STRING)
1263*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1264*2e9d4914SAndroid Build Coastguard Worker
1265*2e9d4914SAndroid Build Coastguard Worker *value = config_setting_get_string(s);
1266*2e9d4914SAndroid Build Coastguard Worker
1267*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1268*2e9d4914SAndroid Build Coastguard Worker }
1269*2e9d4914SAndroid Build Coastguard Worker
1270*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1271*2e9d4914SAndroid Build Coastguard Worker
config_lookup_int(const config_t * config,const char * path,int * value)1272*2e9d4914SAndroid Build Coastguard Worker int config_lookup_int(const config_t *config, const char *path,
1273*2e9d4914SAndroid Build Coastguard Worker int *value)
1274*2e9d4914SAndroid Build Coastguard Worker {
1275*2e9d4914SAndroid Build Coastguard Worker const config_setting_t *s = config_lookup(config, path);
1276*2e9d4914SAndroid Build Coastguard Worker if(! s)
1277*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1278*2e9d4914SAndroid Build Coastguard Worker
1279*2e9d4914SAndroid Build Coastguard Worker return(__config_setting_get_int(s, value));
1280*2e9d4914SAndroid Build Coastguard Worker }
1281*2e9d4914SAndroid Build Coastguard Worker
1282*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1283*2e9d4914SAndroid Build Coastguard Worker
config_lookup_int64(const config_t * config,const char * path,long long * value)1284*2e9d4914SAndroid Build Coastguard Worker int config_lookup_int64(const config_t *config, const char *path,
1285*2e9d4914SAndroid Build Coastguard Worker long long *value)
1286*2e9d4914SAndroid Build Coastguard Worker {
1287*2e9d4914SAndroid Build Coastguard Worker const config_setting_t *s = config_lookup(config, path);
1288*2e9d4914SAndroid Build Coastguard Worker if(! s)
1289*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1290*2e9d4914SAndroid Build Coastguard Worker
1291*2e9d4914SAndroid Build Coastguard Worker return(__config_setting_get_int64(s, value));
1292*2e9d4914SAndroid Build Coastguard Worker }
1293*2e9d4914SAndroid Build Coastguard Worker
1294*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1295*2e9d4914SAndroid Build Coastguard Worker
config_lookup_float(const config_t * config,const char * path,double * value)1296*2e9d4914SAndroid Build Coastguard Worker int config_lookup_float(const config_t *config, const char *path,
1297*2e9d4914SAndroid Build Coastguard Worker double *value)
1298*2e9d4914SAndroid Build Coastguard Worker {
1299*2e9d4914SAndroid Build Coastguard Worker const config_setting_t *s = config_lookup(config, path);
1300*2e9d4914SAndroid Build Coastguard Worker if(! s)
1301*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1302*2e9d4914SAndroid Build Coastguard Worker
1303*2e9d4914SAndroid Build Coastguard Worker return(__config_setting_get_float(s, value));
1304*2e9d4914SAndroid Build Coastguard Worker }
1305*2e9d4914SAndroid Build Coastguard Worker
1306*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1307*2e9d4914SAndroid Build Coastguard Worker
config_lookup_bool(const config_t * config,const char * path,int * value)1308*2e9d4914SAndroid Build Coastguard Worker int config_lookup_bool(const config_t *config, const char *path, int *value)
1309*2e9d4914SAndroid Build Coastguard Worker {
1310*2e9d4914SAndroid Build Coastguard Worker const config_setting_t *s = config_lookup(config, path);
1311*2e9d4914SAndroid Build Coastguard Worker if(! s)
1312*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1313*2e9d4914SAndroid Build Coastguard Worker
1314*2e9d4914SAndroid Build Coastguard Worker if(config_setting_type(s) != CONFIG_TYPE_BOOL)
1315*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1316*2e9d4914SAndroid Build Coastguard Worker
1317*2e9d4914SAndroid Build Coastguard Worker *value = config_setting_get_bool(s);
1318*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1319*2e9d4914SAndroid Build Coastguard Worker }
1320*2e9d4914SAndroid Build Coastguard Worker
1321*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1322*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_int_elem(const config_setting_t * setting,int idx)1323*2e9d4914SAndroid Build Coastguard Worker int config_setting_get_int_elem(const config_setting_t *setting, int idx)
1324*2e9d4914SAndroid Build Coastguard Worker {
1325*2e9d4914SAndroid Build Coastguard Worker const config_setting_t *element = config_setting_get_elem(setting, idx);
1326*2e9d4914SAndroid Build Coastguard Worker
1327*2e9d4914SAndroid Build Coastguard Worker return(element ? config_setting_get_int(element) : 0);
1328*2e9d4914SAndroid Build Coastguard Worker }
1329*2e9d4914SAndroid Build Coastguard Worker
1330*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1331*2e9d4914SAndroid Build Coastguard Worker
config_setting_set_int_elem(config_setting_t * setting,int idx,int value)1332*2e9d4914SAndroid Build Coastguard Worker config_setting_t *config_setting_set_int_elem(config_setting_t *setting,
1333*2e9d4914SAndroid Build Coastguard Worker int idx, int value)
1334*2e9d4914SAndroid Build Coastguard Worker {
1335*2e9d4914SAndroid Build Coastguard Worker config_setting_t *element = NULL;
1336*2e9d4914SAndroid Build Coastguard Worker
1337*2e9d4914SAndroid Build Coastguard Worker if((setting->type != CONFIG_TYPE_ARRAY)
1338*2e9d4914SAndroid Build Coastguard Worker && (setting->type != CONFIG_TYPE_LIST))
1339*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1340*2e9d4914SAndroid Build Coastguard Worker
1341*2e9d4914SAndroid Build Coastguard Worker if(idx < 0)
1342*2e9d4914SAndroid Build Coastguard Worker {
1343*2e9d4914SAndroid Build Coastguard Worker if(! __config_list_checktype(setting, CONFIG_TYPE_INT))
1344*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1345*2e9d4914SAndroid Build Coastguard Worker
1346*2e9d4914SAndroid Build Coastguard Worker element = config_setting_create(setting, NULL, CONFIG_TYPE_INT);
1347*2e9d4914SAndroid Build Coastguard Worker }
1348*2e9d4914SAndroid Build Coastguard Worker else
1349*2e9d4914SAndroid Build Coastguard Worker {
1350*2e9d4914SAndroid Build Coastguard Worker element = config_setting_get_elem(setting, idx);
1351*2e9d4914SAndroid Build Coastguard Worker
1352*2e9d4914SAndroid Build Coastguard Worker if(! element)
1353*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1354*2e9d4914SAndroid Build Coastguard Worker }
1355*2e9d4914SAndroid Build Coastguard Worker
1356*2e9d4914SAndroid Build Coastguard Worker if(! config_setting_set_int(element, value))
1357*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1358*2e9d4914SAndroid Build Coastguard Worker
1359*2e9d4914SAndroid Build Coastguard Worker return(element);
1360*2e9d4914SAndroid Build Coastguard Worker }
1361*2e9d4914SAndroid Build Coastguard Worker
1362*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1363*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_int64_elem(const config_setting_t * setting,int idx)1364*2e9d4914SAndroid Build Coastguard Worker long long config_setting_get_int64_elem(const config_setting_t *setting,
1365*2e9d4914SAndroid Build Coastguard Worker int idx)
1366*2e9d4914SAndroid Build Coastguard Worker {
1367*2e9d4914SAndroid Build Coastguard Worker const config_setting_t *element = config_setting_get_elem(setting, idx);
1368*2e9d4914SAndroid Build Coastguard Worker
1369*2e9d4914SAndroid Build Coastguard Worker return(element ? config_setting_get_int64(element) : 0);
1370*2e9d4914SAndroid Build Coastguard Worker }
1371*2e9d4914SAndroid Build Coastguard Worker
1372*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1373*2e9d4914SAndroid Build Coastguard Worker
config_setting_set_int64_elem(config_setting_t * setting,int idx,long long value)1374*2e9d4914SAndroid Build Coastguard Worker config_setting_t *config_setting_set_int64_elem(config_setting_t *setting,
1375*2e9d4914SAndroid Build Coastguard Worker int idx, long long value)
1376*2e9d4914SAndroid Build Coastguard Worker {
1377*2e9d4914SAndroid Build Coastguard Worker config_setting_t *element = NULL;
1378*2e9d4914SAndroid Build Coastguard Worker
1379*2e9d4914SAndroid Build Coastguard Worker if((setting->type != CONFIG_TYPE_ARRAY)
1380*2e9d4914SAndroid Build Coastguard Worker && (setting->type != CONFIG_TYPE_LIST))
1381*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1382*2e9d4914SAndroid Build Coastguard Worker
1383*2e9d4914SAndroid Build Coastguard Worker if(idx < 0)
1384*2e9d4914SAndroid Build Coastguard Worker {
1385*2e9d4914SAndroid Build Coastguard Worker if(! __config_list_checktype(setting, CONFIG_TYPE_INT64))
1386*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1387*2e9d4914SAndroid Build Coastguard Worker
1388*2e9d4914SAndroid Build Coastguard Worker element = config_setting_create(setting, NULL, CONFIG_TYPE_INT64);
1389*2e9d4914SAndroid Build Coastguard Worker }
1390*2e9d4914SAndroid Build Coastguard Worker else
1391*2e9d4914SAndroid Build Coastguard Worker {
1392*2e9d4914SAndroid Build Coastguard Worker element = config_setting_get_elem(setting, idx);
1393*2e9d4914SAndroid Build Coastguard Worker
1394*2e9d4914SAndroid Build Coastguard Worker if(! element)
1395*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1396*2e9d4914SAndroid Build Coastguard Worker }
1397*2e9d4914SAndroid Build Coastguard Worker
1398*2e9d4914SAndroid Build Coastguard Worker if(! config_setting_set_int64(element, value))
1399*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1400*2e9d4914SAndroid Build Coastguard Worker
1401*2e9d4914SAndroid Build Coastguard Worker return(element);
1402*2e9d4914SAndroid Build Coastguard Worker }
1403*2e9d4914SAndroid Build Coastguard Worker
1404*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1405*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_float_elem(const config_setting_t * setting,int idx)1406*2e9d4914SAndroid Build Coastguard Worker double config_setting_get_float_elem(const config_setting_t *setting, int idx)
1407*2e9d4914SAndroid Build Coastguard Worker {
1408*2e9d4914SAndroid Build Coastguard Worker config_setting_t *element = config_setting_get_elem(setting, idx);
1409*2e9d4914SAndroid Build Coastguard Worker
1410*2e9d4914SAndroid Build Coastguard Worker return(element ? config_setting_get_float(element) : 0.0);
1411*2e9d4914SAndroid Build Coastguard Worker }
1412*2e9d4914SAndroid Build Coastguard Worker
1413*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1414*2e9d4914SAndroid Build Coastguard Worker
config_setting_set_float_elem(config_setting_t * setting,int idx,double value)1415*2e9d4914SAndroid Build Coastguard Worker config_setting_t *config_setting_set_float_elem(config_setting_t *setting,
1416*2e9d4914SAndroid Build Coastguard Worker int idx, double value)
1417*2e9d4914SAndroid Build Coastguard Worker {
1418*2e9d4914SAndroid Build Coastguard Worker config_setting_t *element = NULL;
1419*2e9d4914SAndroid Build Coastguard Worker
1420*2e9d4914SAndroid Build Coastguard Worker if((setting->type != CONFIG_TYPE_ARRAY)
1421*2e9d4914SAndroid Build Coastguard Worker && (setting->type != CONFIG_TYPE_LIST))
1422*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1423*2e9d4914SAndroid Build Coastguard Worker
1424*2e9d4914SAndroid Build Coastguard Worker if(idx < 0)
1425*2e9d4914SAndroid Build Coastguard Worker {
1426*2e9d4914SAndroid Build Coastguard Worker if(! __config_list_checktype(setting, CONFIG_TYPE_FLOAT))
1427*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1428*2e9d4914SAndroid Build Coastguard Worker
1429*2e9d4914SAndroid Build Coastguard Worker element = config_setting_create(setting, NULL, CONFIG_TYPE_FLOAT);
1430*2e9d4914SAndroid Build Coastguard Worker }
1431*2e9d4914SAndroid Build Coastguard Worker else
1432*2e9d4914SAndroid Build Coastguard Worker element = config_setting_get_elem(setting, idx);
1433*2e9d4914SAndroid Build Coastguard Worker
1434*2e9d4914SAndroid Build Coastguard Worker if(! element)
1435*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1436*2e9d4914SAndroid Build Coastguard Worker
1437*2e9d4914SAndroid Build Coastguard Worker if(! config_setting_set_float(element, value))
1438*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1439*2e9d4914SAndroid Build Coastguard Worker
1440*2e9d4914SAndroid Build Coastguard Worker return(element);
1441*2e9d4914SAndroid Build Coastguard Worker }
1442*2e9d4914SAndroid Build Coastguard Worker
1443*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1444*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_bool_elem(const config_setting_t * setting,int idx)1445*2e9d4914SAndroid Build Coastguard Worker int config_setting_get_bool_elem(const config_setting_t *setting, int idx)
1446*2e9d4914SAndroid Build Coastguard Worker {
1447*2e9d4914SAndroid Build Coastguard Worker config_setting_t *element = config_setting_get_elem(setting, idx);
1448*2e9d4914SAndroid Build Coastguard Worker
1449*2e9d4914SAndroid Build Coastguard Worker if(! element)
1450*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1451*2e9d4914SAndroid Build Coastguard Worker
1452*2e9d4914SAndroid Build Coastguard Worker if(element->type != CONFIG_TYPE_BOOL)
1453*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1454*2e9d4914SAndroid Build Coastguard Worker
1455*2e9d4914SAndroid Build Coastguard Worker return(element->value.ival);
1456*2e9d4914SAndroid Build Coastguard Worker }
1457*2e9d4914SAndroid Build Coastguard Worker
1458*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1459*2e9d4914SAndroid Build Coastguard Worker
config_setting_set_bool_elem(config_setting_t * setting,int idx,int value)1460*2e9d4914SAndroid Build Coastguard Worker config_setting_t *config_setting_set_bool_elem(config_setting_t *setting,
1461*2e9d4914SAndroid Build Coastguard Worker int idx, int value)
1462*2e9d4914SAndroid Build Coastguard Worker {
1463*2e9d4914SAndroid Build Coastguard Worker config_setting_t *element = NULL;
1464*2e9d4914SAndroid Build Coastguard Worker
1465*2e9d4914SAndroid Build Coastguard Worker if((setting->type != CONFIG_TYPE_ARRAY)
1466*2e9d4914SAndroid Build Coastguard Worker && (setting->type != CONFIG_TYPE_LIST))
1467*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1468*2e9d4914SAndroid Build Coastguard Worker
1469*2e9d4914SAndroid Build Coastguard Worker if(idx < 0)
1470*2e9d4914SAndroid Build Coastguard Worker {
1471*2e9d4914SAndroid Build Coastguard Worker if(! __config_list_checktype(setting, CONFIG_TYPE_BOOL))
1472*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1473*2e9d4914SAndroid Build Coastguard Worker
1474*2e9d4914SAndroid Build Coastguard Worker element = config_setting_create(setting, NULL, CONFIG_TYPE_BOOL);
1475*2e9d4914SAndroid Build Coastguard Worker }
1476*2e9d4914SAndroid Build Coastguard Worker else
1477*2e9d4914SAndroid Build Coastguard Worker element = config_setting_get_elem(setting, idx);
1478*2e9d4914SAndroid Build Coastguard Worker
1479*2e9d4914SAndroid Build Coastguard Worker if(! element)
1480*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1481*2e9d4914SAndroid Build Coastguard Worker
1482*2e9d4914SAndroid Build Coastguard Worker if(! config_setting_set_bool(element, value))
1483*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1484*2e9d4914SAndroid Build Coastguard Worker
1485*2e9d4914SAndroid Build Coastguard Worker return(element);
1486*2e9d4914SAndroid Build Coastguard Worker }
1487*2e9d4914SAndroid Build Coastguard Worker
1488*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1489*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_string_elem(const config_setting_t * setting,int idx)1490*2e9d4914SAndroid Build Coastguard Worker const char *config_setting_get_string_elem(const config_setting_t *setting,
1491*2e9d4914SAndroid Build Coastguard Worker int idx)
1492*2e9d4914SAndroid Build Coastguard Worker {
1493*2e9d4914SAndroid Build Coastguard Worker config_setting_t *element = config_setting_get_elem(setting, idx);
1494*2e9d4914SAndroid Build Coastguard Worker
1495*2e9d4914SAndroid Build Coastguard Worker if(! element)
1496*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1497*2e9d4914SAndroid Build Coastguard Worker
1498*2e9d4914SAndroid Build Coastguard Worker if(element->type != CONFIG_TYPE_STRING)
1499*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1500*2e9d4914SAndroid Build Coastguard Worker
1501*2e9d4914SAndroid Build Coastguard Worker return(element->value.sval);
1502*2e9d4914SAndroid Build Coastguard Worker }
1503*2e9d4914SAndroid Build Coastguard Worker
1504*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1505*2e9d4914SAndroid Build Coastguard Worker
config_setting_set_string_elem(config_setting_t * setting,int idx,const char * value)1506*2e9d4914SAndroid Build Coastguard Worker config_setting_t *config_setting_set_string_elem(config_setting_t *setting,
1507*2e9d4914SAndroid Build Coastguard Worker int idx, const char *value)
1508*2e9d4914SAndroid Build Coastguard Worker {
1509*2e9d4914SAndroid Build Coastguard Worker config_setting_t *element = NULL;
1510*2e9d4914SAndroid Build Coastguard Worker
1511*2e9d4914SAndroid Build Coastguard Worker if((setting->type != CONFIG_TYPE_ARRAY)
1512*2e9d4914SAndroid Build Coastguard Worker && (setting->type != CONFIG_TYPE_LIST))
1513*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1514*2e9d4914SAndroid Build Coastguard Worker
1515*2e9d4914SAndroid Build Coastguard Worker if(idx < 0)
1516*2e9d4914SAndroid Build Coastguard Worker {
1517*2e9d4914SAndroid Build Coastguard Worker if(! __config_list_checktype(setting, CONFIG_TYPE_STRING))
1518*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1519*2e9d4914SAndroid Build Coastguard Worker
1520*2e9d4914SAndroid Build Coastguard Worker element = config_setting_create(setting, NULL, CONFIG_TYPE_STRING);
1521*2e9d4914SAndroid Build Coastguard Worker }
1522*2e9d4914SAndroid Build Coastguard Worker else
1523*2e9d4914SAndroid Build Coastguard Worker element = config_setting_get_elem(setting, idx);
1524*2e9d4914SAndroid Build Coastguard Worker
1525*2e9d4914SAndroid Build Coastguard Worker if(! element)
1526*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1527*2e9d4914SAndroid Build Coastguard Worker
1528*2e9d4914SAndroid Build Coastguard Worker if(! config_setting_set_string(element, value))
1529*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1530*2e9d4914SAndroid Build Coastguard Worker
1531*2e9d4914SAndroid Build Coastguard Worker return(element);
1532*2e9d4914SAndroid Build Coastguard Worker }
1533*2e9d4914SAndroid Build Coastguard Worker
1534*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1535*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_elem(const config_setting_t * setting,unsigned int idx)1536*2e9d4914SAndroid Build Coastguard Worker config_setting_t *config_setting_get_elem(const config_setting_t *setting,
1537*2e9d4914SAndroid Build Coastguard Worker unsigned int idx)
1538*2e9d4914SAndroid Build Coastguard Worker {
1539*2e9d4914SAndroid Build Coastguard Worker config_list_t *list;
1540*2e9d4914SAndroid Build Coastguard Worker
1541*2e9d4914SAndroid Build Coastguard Worker if(! config_setting_is_aggregate(setting))
1542*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1543*2e9d4914SAndroid Build Coastguard Worker
1544*2e9d4914SAndroid Build Coastguard Worker list = setting->value.list;
1545*2e9d4914SAndroid Build Coastguard Worker if(! list)
1546*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1547*2e9d4914SAndroid Build Coastguard Worker
1548*2e9d4914SAndroid Build Coastguard Worker if(idx >= list->length)
1549*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1550*2e9d4914SAndroid Build Coastguard Worker
1551*2e9d4914SAndroid Build Coastguard Worker return(list->elements[idx]);
1552*2e9d4914SAndroid Build Coastguard Worker }
1553*2e9d4914SAndroid Build Coastguard Worker
1554*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1555*2e9d4914SAndroid Build Coastguard Worker
config_setting_get_member(const config_setting_t * setting,const char * name)1556*2e9d4914SAndroid Build Coastguard Worker config_setting_t *config_setting_get_member(const config_setting_t *setting,
1557*2e9d4914SAndroid Build Coastguard Worker const char *name)
1558*2e9d4914SAndroid Build Coastguard Worker {
1559*2e9d4914SAndroid Build Coastguard Worker if(setting->type != CONFIG_TYPE_GROUP)
1560*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1561*2e9d4914SAndroid Build Coastguard Worker
1562*2e9d4914SAndroid Build Coastguard Worker return(__config_list_search(setting->value.list, name, NULL));
1563*2e9d4914SAndroid Build Coastguard Worker }
1564*2e9d4914SAndroid Build Coastguard Worker
1565*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1566*2e9d4914SAndroid Build Coastguard Worker
config_set_destructor(config_t * config,void (* destructor)(void *))1567*2e9d4914SAndroid Build Coastguard Worker void config_set_destructor(config_t *config, void (*destructor)(void *))
1568*2e9d4914SAndroid Build Coastguard Worker {
1569*2e9d4914SAndroid Build Coastguard Worker config->destructor = destructor;
1570*2e9d4914SAndroid Build Coastguard Worker }
1571*2e9d4914SAndroid Build Coastguard Worker
1572*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1573*2e9d4914SAndroid Build Coastguard Worker
config_set_include_dir(config_t * config,const char * include_dir)1574*2e9d4914SAndroid Build Coastguard Worker void config_set_include_dir(config_t *config, const char *include_dir)
1575*2e9d4914SAndroid Build Coastguard Worker {
1576*2e9d4914SAndroid Build Coastguard Worker __delete(config->include_dir);
1577*2e9d4914SAndroid Build Coastguard Worker config->include_dir = strdup(include_dir);
1578*2e9d4914SAndroid Build Coastguard Worker }
1579*2e9d4914SAndroid Build Coastguard Worker
1580*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1581*2e9d4914SAndroid Build Coastguard Worker
config_set_include_func(config_t * config,config_include_fn_t func)1582*2e9d4914SAndroid Build Coastguard Worker void config_set_include_func(config_t *config, config_include_fn_t func)
1583*2e9d4914SAndroid Build Coastguard Worker {
1584*2e9d4914SAndroid Build Coastguard Worker config->include_fn = func ? func : config_default_include_func;
1585*2e9d4914SAndroid Build Coastguard Worker }
1586*2e9d4914SAndroid Build Coastguard Worker
1587*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1588*2e9d4914SAndroid Build Coastguard Worker
config_setting_length(const config_setting_t * setting)1589*2e9d4914SAndroid Build Coastguard Worker int config_setting_length(const config_setting_t *setting)
1590*2e9d4914SAndroid Build Coastguard Worker {
1591*2e9d4914SAndroid Build Coastguard Worker if(! config_setting_is_aggregate(setting))
1592*2e9d4914SAndroid Build Coastguard Worker return(0);
1593*2e9d4914SAndroid Build Coastguard Worker
1594*2e9d4914SAndroid Build Coastguard Worker if(! setting->value.list)
1595*2e9d4914SAndroid Build Coastguard Worker return(0);
1596*2e9d4914SAndroid Build Coastguard Worker
1597*2e9d4914SAndroid Build Coastguard Worker return(setting->value.list->length);
1598*2e9d4914SAndroid Build Coastguard Worker }
1599*2e9d4914SAndroid Build Coastguard Worker
1600*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1601*2e9d4914SAndroid Build Coastguard Worker
config_setting_set_hook(config_setting_t * setting,void * hook)1602*2e9d4914SAndroid Build Coastguard Worker void config_setting_set_hook(config_setting_t *setting, void *hook)
1603*2e9d4914SAndroid Build Coastguard Worker {
1604*2e9d4914SAndroid Build Coastguard Worker setting->hook = hook;
1605*2e9d4914SAndroid Build Coastguard Worker }
1606*2e9d4914SAndroid Build Coastguard Worker
1607*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1608*2e9d4914SAndroid Build Coastguard Worker
config_setting_add(config_setting_t * parent,const char * name,int type)1609*2e9d4914SAndroid Build Coastguard Worker config_setting_t *config_setting_add(config_setting_t *parent,
1610*2e9d4914SAndroid Build Coastguard Worker const char *name, int type)
1611*2e9d4914SAndroid Build Coastguard Worker {
1612*2e9d4914SAndroid Build Coastguard Worker if((type < CONFIG_TYPE_NONE) || (type > CONFIG_TYPE_LIST))
1613*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1614*2e9d4914SAndroid Build Coastguard Worker
1615*2e9d4914SAndroid Build Coastguard Worker if(! parent)
1616*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1617*2e9d4914SAndroid Build Coastguard Worker
1618*2e9d4914SAndroid Build Coastguard Worker if((parent->type == CONFIG_TYPE_ARRAY) && !__config_type_is_scalar(type))
1619*2e9d4914SAndroid Build Coastguard Worker return(NULL); /* only scalars can be added to arrays */
1620*2e9d4914SAndroid Build Coastguard Worker
1621*2e9d4914SAndroid Build Coastguard Worker if((parent->type == CONFIG_TYPE_ARRAY) || (parent->type == CONFIG_TYPE_LIST))
1622*2e9d4914SAndroid Build Coastguard Worker name = NULL;
1623*2e9d4914SAndroid Build Coastguard Worker
1624*2e9d4914SAndroid Build Coastguard Worker if(name)
1625*2e9d4914SAndroid Build Coastguard Worker {
1626*2e9d4914SAndroid Build Coastguard Worker if(! __config_validate_name(name))
1627*2e9d4914SAndroid Build Coastguard Worker return(NULL);
1628*2e9d4914SAndroid Build Coastguard Worker }
1629*2e9d4914SAndroid Build Coastguard Worker
1630*2e9d4914SAndroid Build Coastguard Worker if(config_setting_get_member(parent, name) != NULL)
1631*2e9d4914SAndroid Build Coastguard Worker {
1632*2e9d4914SAndroid Build Coastguard Worker if(config_get_option(parent->config, CONFIG_OPTION_ALLOW_OVERRIDES))
1633*2e9d4914SAndroid Build Coastguard Worker config_setting_remove(parent, name);
1634*2e9d4914SAndroid Build Coastguard Worker else
1635*2e9d4914SAndroid Build Coastguard Worker return(NULL); /* already exists */
1636*2e9d4914SAndroid Build Coastguard Worker }
1637*2e9d4914SAndroid Build Coastguard Worker
1638*2e9d4914SAndroid Build Coastguard Worker return(config_setting_create(parent, name, type));
1639*2e9d4914SAndroid Build Coastguard Worker }
1640*2e9d4914SAndroid Build Coastguard Worker
1641*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1642*2e9d4914SAndroid Build Coastguard Worker
config_setting_remove(config_setting_t * parent,const char * name)1643*2e9d4914SAndroid Build Coastguard Worker int config_setting_remove(config_setting_t *parent, const char *name)
1644*2e9d4914SAndroid Build Coastguard Worker {
1645*2e9d4914SAndroid Build Coastguard Worker unsigned int idx;
1646*2e9d4914SAndroid Build Coastguard Worker config_setting_t *setting;
1647*2e9d4914SAndroid Build Coastguard Worker const char *settingName;
1648*2e9d4914SAndroid Build Coastguard Worker const char *lastFound;
1649*2e9d4914SAndroid Build Coastguard Worker
1650*2e9d4914SAndroid Build Coastguard Worker if(! parent)
1651*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1652*2e9d4914SAndroid Build Coastguard Worker
1653*2e9d4914SAndroid Build Coastguard Worker if(parent->type != CONFIG_TYPE_GROUP)
1654*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1655*2e9d4914SAndroid Build Coastguard Worker
1656*2e9d4914SAndroid Build Coastguard Worker setting = config_setting_lookup(parent, name);
1657*2e9d4914SAndroid Build Coastguard Worker if(! setting)
1658*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1659*2e9d4914SAndroid Build Coastguard Worker
1660*2e9d4914SAndroid Build Coastguard Worker settingName = name;
1661*2e9d4914SAndroid Build Coastguard Worker do
1662*2e9d4914SAndroid Build Coastguard Worker {
1663*2e9d4914SAndroid Build Coastguard Worker lastFound = settingName;
1664*2e9d4914SAndroid Build Coastguard Worker while(settingName && !strchr(PATH_TOKENS, *settingName))
1665*2e9d4914SAndroid Build Coastguard Worker ++settingName;
1666*2e9d4914SAndroid Build Coastguard Worker
1667*2e9d4914SAndroid Build Coastguard Worker if(*settingName == '\0')
1668*2e9d4914SAndroid Build Coastguard Worker {
1669*2e9d4914SAndroid Build Coastguard Worker settingName = lastFound;
1670*2e9d4914SAndroid Build Coastguard Worker break;
1671*2e9d4914SAndroid Build Coastguard Worker }
1672*2e9d4914SAndroid Build Coastguard Worker
1673*2e9d4914SAndroid Build Coastguard Worker }while(*++settingName);
1674*2e9d4914SAndroid Build Coastguard Worker
1675*2e9d4914SAndroid Build Coastguard Worker if(!(setting = __config_list_search(setting->parent->value.list, settingName, &idx)))
1676*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1677*2e9d4914SAndroid Build Coastguard Worker
1678*2e9d4914SAndroid Build Coastguard Worker __config_list_remove(setting->parent->value.list, idx);
1679*2e9d4914SAndroid Build Coastguard Worker __config_setting_destroy(setting);
1680*2e9d4914SAndroid Build Coastguard Worker
1681*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1682*2e9d4914SAndroid Build Coastguard Worker }
1683*2e9d4914SAndroid Build Coastguard Worker
1684*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1685*2e9d4914SAndroid Build Coastguard Worker
config_setting_remove_elem(config_setting_t * parent,unsigned int idx)1686*2e9d4914SAndroid Build Coastguard Worker int config_setting_remove_elem(config_setting_t *parent, unsigned int idx)
1687*2e9d4914SAndroid Build Coastguard Worker {
1688*2e9d4914SAndroid Build Coastguard Worker config_list_t *list;
1689*2e9d4914SAndroid Build Coastguard Worker config_setting_t *removed = NULL;
1690*2e9d4914SAndroid Build Coastguard Worker
1691*2e9d4914SAndroid Build Coastguard Worker if(! parent)
1692*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1693*2e9d4914SAndroid Build Coastguard Worker
1694*2e9d4914SAndroid Build Coastguard Worker if(! config_setting_is_aggregate(parent))
1695*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1696*2e9d4914SAndroid Build Coastguard Worker
1697*2e9d4914SAndroid Build Coastguard Worker list = parent->value.list;
1698*2e9d4914SAndroid Build Coastguard Worker if(! list)
1699*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1700*2e9d4914SAndroid Build Coastguard Worker
1701*2e9d4914SAndroid Build Coastguard Worker if(idx >= list->length)
1702*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_FALSE);
1703*2e9d4914SAndroid Build Coastguard Worker
1704*2e9d4914SAndroid Build Coastguard Worker removed = __config_list_remove(list, idx);
1705*2e9d4914SAndroid Build Coastguard Worker __config_setting_destroy(removed);
1706*2e9d4914SAndroid Build Coastguard Worker
1707*2e9d4914SAndroid Build Coastguard Worker return(CONFIG_TRUE);
1708*2e9d4914SAndroid Build Coastguard Worker }
1709*2e9d4914SAndroid Build Coastguard Worker
1710*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1711*2e9d4914SAndroid Build Coastguard Worker
config_setting_index(const config_setting_t * setting)1712*2e9d4914SAndroid Build Coastguard Worker int config_setting_index(const config_setting_t *setting)
1713*2e9d4914SAndroid Build Coastguard Worker {
1714*2e9d4914SAndroid Build Coastguard Worker config_setting_t **found = NULL;
1715*2e9d4914SAndroid Build Coastguard Worker config_list_t *list;
1716*2e9d4914SAndroid Build Coastguard Worker int i;
1717*2e9d4914SAndroid Build Coastguard Worker
1718*2e9d4914SAndroid Build Coastguard Worker if(! setting->parent)
1719*2e9d4914SAndroid Build Coastguard Worker return(-1);
1720*2e9d4914SAndroid Build Coastguard Worker
1721*2e9d4914SAndroid Build Coastguard Worker list = setting->parent->value.list;
1722*2e9d4914SAndroid Build Coastguard Worker
1723*2e9d4914SAndroid Build Coastguard Worker for(i = 0, found = list->elements; i < (int)list->length; ++i, ++found)
1724*2e9d4914SAndroid Build Coastguard Worker {
1725*2e9d4914SAndroid Build Coastguard Worker if(*found == setting)
1726*2e9d4914SAndroid Build Coastguard Worker return(i);
1727*2e9d4914SAndroid Build Coastguard Worker }
1728*2e9d4914SAndroid Build Coastguard Worker
1729*2e9d4914SAndroid Build Coastguard Worker return(-1);
1730*2e9d4914SAndroid Build Coastguard Worker }
1731*2e9d4914SAndroid Build Coastguard Worker
1732*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1733*2e9d4914SAndroid Build Coastguard Worker
config_default_include_func(config_t * config,const char * include_dir,const char * path,const char ** error)1734*2e9d4914SAndroid Build Coastguard Worker const char **config_default_include_func(config_t *config,
1735*2e9d4914SAndroid Build Coastguard Worker const char *include_dir,
1736*2e9d4914SAndroid Build Coastguard Worker const char *path,
1737*2e9d4914SAndroid Build Coastguard Worker const char **error)
1738*2e9d4914SAndroid Build Coastguard Worker {
1739*2e9d4914SAndroid Build Coastguard Worker char *file;
1740*2e9d4914SAndroid Build Coastguard Worker const char **files;
1741*2e9d4914SAndroid Build Coastguard Worker
1742*2e9d4914SAndroid Build Coastguard Worker if(include_dir && IS_RELATIVE_PATH(path))
1743*2e9d4914SAndroid Build Coastguard Worker {
1744*2e9d4914SAndroid Build Coastguard Worker file = (char *)malloc(strlen(include_dir) + strlen(path) + 2);
1745*2e9d4914SAndroid Build Coastguard Worker strcpy(file, include_dir);
1746*2e9d4914SAndroid Build Coastguard Worker strcat(file, FILE_SEPARATOR);
1747*2e9d4914SAndroid Build Coastguard Worker strcat(file, path);
1748*2e9d4914SAndroid Build Coastguard Worker }
1749*2e9d4914SAndroid Build Coastguard Worker else
1750*2e9d4914SAndroid Build Coastguard Worker file = strdup(path);
1751*2e9d4914SAndroid Build Coastguard Worker
1752*2e9d4914SAndroid Build Coastguard Worker *error = NULL;
1753*2e9d4914SAndroid Build Coastguard Worker
1754*2e9d4914SAndroid Build Coastguard Worker files = (const char **)malloc(sizeof(char **) * 2);
1755*2e9d4914SAndroid Build Coastguard Worker files[0] = file;
1756*2e9d4914SAndroid Build Coastguard Worker files[1] = NULL;
1757*2e9d4914SAndroid Build Coastguard Worker
1758*2e9d4914SAndroid Build Coastguard Worker return(files);
1759*2e9d4914SAndroid Build Coastguard Worker }
1760*2e9d4914SAndroid Build Coastguard Worker
1761*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1762*2e9d4914SAndroid Build Coastguard Worker
config_setting_is_scalar(const config_setting_t * setting)1763*2e9d4914SAndroid Build Coastguard Worker int config_setting_is_scalar(const config_setting_t *setting)
1764*2e9d4914SAndroid Build Coastguard Worker {
1765*2e9d4914SAndroid Build Coastguard Worker return(__config_type_is_scalar(setting->type));
1766*2e9d4914SAndroid Build Coastguard Worker }
1767*2e9d4914SAndroid Build Coastguard Worker
1768*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1769*2e9d4914SAndroid Build Coastguard Worker
config_setting_is_aggregate(const config_setting_t * setting)1770*2e9d4914SAndroid Build Coastguard Worker int config_setting_is_aggregate(const config_setting_t *setting)
1771*2e9d4914SAndroid Build Coastguard Worker {
1772*2e9d4914SAndroid Build Coastguard Worker return((setting->type == CONFIG_TYPE_ARRAY)
1773*2e9d4914SAndroid Build Coastguard Worker || (setting->type == CONFIG_TYPE_LIST)
1774*2e9d4914SAndroid Build Coastguard Worker || (setting->type == CONFIG_TYPE_GROUP));
1775*2e9d4914SAndroid Build Coastguard Worker }
1776*2e9d4914SAndroid Build Coastguard Worker
1777*2e9d4914SAndroid Build Coastguard Worker /* ------------------------------------------------------------------------- */
1778