4 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
27 #include "config-parser.h"
29 #define MAX_SECTION 64
31 int config_parse(const char *file_name, int cb(struct parse_result *result,
32 void *user_data), void *user_data)
35 struct parse_result result;
36 /* use stack for parsing */
38 char section[MAX_SECTION];
39 char *start, *end, *name, *value;
40 int lineno = 0, ret = 0;
42 if (!file_name || !cb) {
48 f = fopen(file_name, "r");
50 _E("Failed to open file %s", file_name);
55 /* parsing line by line */
56 while (fgets(line, LINE_MAX, f) != NULL) {
61 start = strstrip(start);
63 if (*start == COMMENT) {
65 } else if (*start == '[') {
67 end = strchr(start, ']');
68 if (!end || *end != ']') {
74 strncpy(section, start + 1, sizeof(section)-1);
75 section[MAX_SECTION-1] = '\0';
77 /* parse name & value */
78 end = strchr(start, '=');
79 if (!end || *end != '=') {
84 name = strstrip(start);
85 value = strstrip(end + 1);
86 end = strchr(value, COMMENT);
87 if (end && *end == COMMENT) {
89 value = strstrip(value);
92 result.section = section;
95 /* callback with parse result */
96 ret = cb(&result, user_data);
103 _D("Success to load %s", file_name);
110 _E("Failed to read %s:%d!", file_name, lineno);
114 static int config_table_lookup(void *table,
117 ConfigParserCallback *func,
129 for (t = table; t->lvalue; t++) {
131 if (!streq(lvalue, t->lvalue))
134 if (!streq_ptr(section, t->section))
146 /* Run the user supplied parser for an assignment */
147 static int config_parse_table(const char *filename,
154 ConfigParserCallback cb = NULL;
164 r = config_table_lookup(table,
185 int config_parse_new(const char *filename, void *table)
187 _cleanup_fclose_ FILE *f = NULL;
188 char *sections[MAX_SECTION] = { 0 };
189 char *section = NULL, *n, *e, l[LINE_MAX];
191 int i, r, num_section = 0;
197 f = fopen(filename, "r");
199 _E("Failed to open file %s", filename);
204 _cleanup_free_ char *lvalue = NULL, *rvalue = NULL;
207 if (fgets(l, LINE_MAX, f) == NULL) {
211 _E("Failed to parse configuration file '%s': %m", filename);
219 if (strchr(COMMENTS NEWLINE, *l))
224 if (l[len-1] != ']') {
225 _E("Error: Invalid section header: %s", l);
230 n = strndup(l+1, len-2);
237 for (i = 0; i < num_section; i++) {
238 if (streq(n, sections[i])) {
239 section = sections[i];
250 sections[num_section] = n;
252 if (num_section > MAX_SECTION) {
253 _E("Error: max number of section reached: %d", num_section);
266 _D("Warning: config: no '=' character in line '%s'.", l);
270 lvalue = strndup(l, e-l);
287 r = config_parse_table(filename,
300 for (i = 0; i < num_section; i++)
307 int config_parse_dir(const char *dir, ConfigParseFunc fp, void *data)
309 _cleanup_closedir_ DIR *d = NULL;
314 _E("Failed to open dir: %s", dir);
318 for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) {
323 } else if (streq(de->d_name, ".") || streq(de->d_name, "..")) {
327 _cleanup_free_ char *path = NULL;
330 if (de->d_type != DT_REG)
333 r = asprintf(&path, "%s/%s", dir, de->d_name);
338 /* Do not just break loop until parse all file of
339 * dir. Just only put log */
341 _D("Failed to parse config: %s", de->d_name);
347 int config_parse_bool(const char *filename,
363 k = parse_boolean(rvalue);
365 _E("Failed to parse boolean value, ignoring: %s", rvalue);
374 #define DEFINE_PARSER(type, vartype, conv_func) \
375 int config_parse_##type( \
376 const char *filename, \
378 const char *section, \
379 const char *lvalue, \
381 const char *rvalue, \
391 *i = conv_func(rvalue); \
395 DEFINE_PARSER(int, int, atoi)
396 DEFINE_PARSER(float, float, atof)
397 DEFINE_PARSER(long, long, atol)
399 int config_parse_string(const char *filename,
414 if (is_empty(rvalue))
428 int config_parse_bytes(const char *filename,
444 if (is_empty(rvalue))
447 r = parse_bytes(rvalue, s);
455 int config_parse_strv(const char *filename,
464 char **o = NULL, **v = NULL, **vv = NULL;
472 if (is_empty(rvalue))
475 r = str_to_strv(rvalue, &v, WHITESPACE);
481 r = strv_attach(o, v, &vv, true);