diff options
author | WaLyong Cho <walyong.cho@samsung.com> | 2016-10-17 14:21:53 +0900 |
---|---|---|
committer | WaLyong Cho <walyong.cho@samsung.com> | 2016-10-17 14:22:05 +0900 |
commit | bf6b02d15c986496b697131a68f3f99c6dcf1e70 (patch) | |
tree | e2f9fc203521135e04ccca966837ae4cad7585c7 /src/libsystem/config-parser.c | |
parent | 7928edd9b8dfd3501154bd70decdcefa1c275b43 (diff) | |
parent | 2836b189c0b82d8baacadadff7517d13ba03eacc (diff) | |
download | libsystem-bf6b02d15c986496b697131a68f3f99c6dcf1e70.tar.gz libsystem-bf6b02d15c986496b697131a68f3f99c6dcf1e70.tar.bz2 libsystem-bf6b02d15c986496b697131a68f3f99c6dcf1e70.zip |
release: 4.0-0
[Model] Common
[BinType] AP
[Customer] N/A
[Issue] N/A
[Request] N/A
[Occurrence Version] N/A
[Problem] release: 4.0-0
[Cause & Measure] N/A
[Checking Method] N/A
[Team] SystemFW
[Developer] WaLyong Cho
[Solution company] Samsung
[Change Type] N/A
* devel/systemfw/master:
release: 4.0-0
rpm: spec: modify rpm spec properly
test: add test-truncate_nl
make: add tests
gitignore: update git ignores
remove empty files
initial files upload
Change-Id: Iff40ea8c67918bc95e4c91be572299939477ea05
Signed-off-by: WaLyong Cho <walyong.cho@samsung.com>
Diffstat (limited to 'src/libsystem/config-parser.c')
-rw-r--r-- | src/libsystem/config-parser.c | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/src/libsystem/config-parser.c b/src/libsystem/config-parser.c new file mode 100644 index 0000000..3319056 --- /dev/null +++ b/src/libsystem/config-parser.c @@ -0,0 +1,347 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * libsystem + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <stdbool.h> +#include <limits.h> + +#include "libsystem.h" +#include "config-parser.h" + +#define MAX_SECTION 64 + +static int config_table_lookup( + void *table, + const char *section, + const char *lvalue, + ConfigParserCallback *func, + int *ltype, + void **data) { + + ConfigTableItem *t; + + assert(table); + assert(lvalue); + assert(func); + assert(ltype); + assert(data); + + for (t = table; t->lvalue; t++) { + + if (!streq(lvalue, t->lvalue)) + continue; + + if (!streq_ptr(section, t->section)) + continue; + + *func = t->cb; + *ltype = t->ltype; + *data = t->data; + return 1; + } + + return 0; +} + +/* Run the user supplied parser for an assignment */ +static int config_parse_table( + const char *filename, + unsigned line, + void *table, + const char *section, + const char *lvalue, + const char *rvalue) { + + ConfigParserCallback cb = NULL; + int ltype = 0; + void *data = NULL; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + + r = config_table_lookup(table, + section, + lvalue, + &cb, + <ype, + &data); + if (r <= 0) + return r; + + if (cb) + return cb(filename, + line, + section, + lvalue, + ltype, + rvalue, + data); + + return 0; +} + +int config_parse( + const char *filename, + void *table) { + + _cleanup_fclose_ FILE *f = NULL; + char *sections[MAX_SECTION] = { 0 }; + char *section = NULL, *n, *e, l[LINE_MAX]; + size_t len; + int i, r, num_section = 0; + bool already; + unsigned line = 0; + + assert(filename); + + f = fopen(filename, "r"); + if (!f) + return -errno; + + while (!feof(f)) { + _cleanup_free_ char *lvalue = NULL, *rvalue = NULL; + + if (fgets(l, LINE_MAX, f) == NULL) { + if (feof(f)) + break; + + r = -errno; + goto finish; + } + + line++; + truncate_nl(l); + + if (strchr(COMMENTS NEWLINE, *l)) + continue; + + if (*l == '[') { + len = strlen(l); + if (l[len-1] != ']') { + r = -EBADMSG; + goto finish; + } + + n = strndup(l+1, len-2); + if (!n) { + r = -ENOMEM; + goto finish; + } + + already = false; + for (i = 0; i < num_section; i++) { + if (streq(n, sections[i])) { + section = sections[i]; + already = true; + free(n); + break; + } + } + + if (already) + continue; + + section = n; + sections[num_section] = n; + num_section++; + if (num_section > MAX_SECTION) { + r = -EOVERFLOW; + goto finish; + } + + continue; + } + + if (!section) + continue; + + e = strchr(l, '='); + if (e == NULL) + continue; + + r = strndup_strip(l, e - l, &lvalue); + if (r < 0) + goto finish; + + r = strdup_strip(e + 1, &rvalue); + if (r < 0) + goto finish; + + r = config_parse_table(filename, + line, + table, + section, + lvalue, + rvalue); + if (r < 0) + goto finish; + } + + r = 0; + +finish: + for (i=0; i<num_section; i++) + if (sections[i]) + free(sections[i]); + + return r; +} + +int config_parse_dir(const char *dir, ConfigParseFunc fp, void *data) { + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; + + d = opendir(dir); + if (!d) + return errno; + + FOREACH_DIRENT(de, d, return -errno) { + _cleanup_free_ char *path = NULL; + int r; + + if (de->d_type != DT_REG) + continue; + + r = asprintf(&path, "%s/%s", dir, de->d_name); + if (r < 0) + return -ENOMEM; + + /* Do not just break loop until parse all file of + * dir. ignore return */ + (void) fp(path, data); + } + + return 0; +} + +int config_parse_int( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data) { + + int *i = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (!is_number(rvalue, strlen(rvalue))) + return -EINVAL; + + *i = atoi(rvalue); + + return 0; +} + +int config_parse_bool( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data) { + + int k; + bool *b = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + k = parse_boolean(rvalue); + if (k < 0) + return 0; + + *b = !!k; + return 0; +} + +int config_parse_string( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data) { + + char **s = data, *n; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (isempty(rvalue)) + n = NULL; + else { + n = strdup(rvalue); + if (!n) + return -ENOMEM; + } + + free(*s); + *s = n; + + return 0; +} + +int config_parse_bytes( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data) { + + size_t *ss = data, s = 0; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (isempty(rvalue)) + s = 0; + else { + r = parse_bytes(rvalue, &s); + if (r < 0) + return r; + } + + *ss = s; + + return 0; +} |