From: Yunmi Ha Date: Tue, 5 Jan 2021 04:45:21 +0000 (+0900) Subject: libcommon: Add common library X-Git-Tag: submit/tizen/20210108.041937~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3e6fe8f363bd28f83bdffde38f3be5aed1819b2e;p=platform%2Fcore%2Fsystem%2Flibsyscommon.git libcommon: Add common library - list (glib) - ini-parser Change-Id: Ic13b47d5a1f26ed8b40007684da620a804775623 Signed-off-by: Yunmi Ha --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a1522f..33bf5f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,12 +15,15 @@ SET(libsyscommon_SRCS src/libgdbus/dbus-system.c src/libgdbus/dbus-systemd.c src/libsystemd/systemd-state.c + src/libcommon/ini-parser.c ) SET(HEADERS src/libgdbus/dbus-system.h src/libgdbus/dbus-system-iface.h src/libgdbus/dbus-systemd.h src/libsystemd/systemd-state.h + src/libcommon/list.h + src/libcommon/ini-parser.h ) # CHECK PKG diff --git a/packaging/libsyscommon.spec b/packaging/libsyscommon.spec index 4957b71..45a25ce 100644 --- a/packaging/libsyscommon.spec +++ b/packaging/libsyscommon.spec @@ -70,8 +70,5 @@ touch debugsources.list %endif %license LICENSE.Apache-2.0 %{_libdir}/libsyscommon.so -%{_includedir}/libsyscommon/dbus-system.h -%{_includedir}/libsyscommon/dbus-system-iface.h -%{_includedir}/libsyscommon/dbus-systemd.h -%{_includedir}/libsyscommon/systemd-state.h +%{_includedir}/libsyscommon/*.h %{_libdir}/pkgconfig/libsyscommon.pc diff --git a/src/libcommon/ini-parser.c b/src/libcommon/ini-parser.c new file mode 100644 index 0000000..11093cc --- /dev/null +++ b/src/libcommon/ini-parser.c @@ -0,0 +1,128 @@ +/* + * libsyscommon + * + * Copyright (c) 2021 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 +#include +#include +#include "ini-parser.h" + +#include "shared/log.h" + +#define MAX_LINE 512 +#define MAX_SECTION 64 +#define WHITESPACE " \t" +#define NEWLINE "\n\r" +#define COMMENT '#' + +static inline char *trim_str(char *s) +{ + char *t; + /* left trim */ + s += strspn(s, WHITESPACE); + + /* right trim */ + for (t = strchr(s, 0); t > s; t--) + if (!strchr(WHITESPACE, t[-1])) + break; + *t = 0; + return s; +} + +int config_parse(const char *file_name, int cb(struct parse_result *result, + void *user_data), void *user_data) +{ + FILE *f = NULL; + struct parse_result result; + /* use stack for parsing */ + char line[MAX_LINE]; + char section[MAX_SECTION]; + char *start, *end, *name, *value; + int lineno = 0, ret = 0; + + if (!file_name || !cb) { + ret = -EINVAL; + goto error; + } + + /* open conf file */ + f = fopen(file_name, "r"); + if (!f) { + _E("Failed to open file '%s'.", file_name); + ret = -EIO; + goto error; + } + + /* parsing line by line */ + while (fgets(line, MAX_LINE, f) != NULL) { + lineno++; + + start = line; + start[strcspn(start, NEWLINE)] = '\0'; + start = trim_str(start); + + if (*start == COMMENT) { + continue; + } else if (*start == '[') { + /* parse section */ + end = strchr(start, ']'); + if (!end || *end != ']') { + ret = -EBADMSG; + goto error; + } + + *end = '\0'; + strncpy(section, start + 1, sizeof(section)-1); + section[MAX_SECTION-1] = '\0'; + } else if (*start) { + /* parse name & value */ + end = strchr(start, '='); + if (!end || *end != '=') { + ret = -EBADMSG; + goto error; + } + *end = '\0'; + name = trim_str(start); + value = trim_str(end + 1); + end = strchr(value, COMMENT); + if (end && *end == COMMENT) { + *end = '\0'; + value = trim_str(value); + } + + result.section = section; + result.name = name; + result.value = value; + /* callback with parse result */ + ret = cb(&result, user_data); + if (ret < 0) { + ret = -EBADMSG; + goto error; + } + } + } + _D("Success to load '%s'.", file_name); + fclose(f); + return 0; + +error: + if (f) + fclose(f); + _E("Failed to read '%s': %d", file_name, lineno); + return ret; +} + diff --git a/src/libcommon/ini-parser.h b/src/libcommon/ini-parser.h new file mode 100644 index 0000000..b65c2b1 --- /dev/null +++ b/src/libcommon/ini-parser.h @@ -0,0 +1,42 @@ +/* + * libsyscommon + * + * Copyright (c) 2021 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. + */ + + +#ifndef __INI_PARSER_H__ +#define __INI_PARSER_H__ + +#define MATCH(a, b) (!strncmp(a, b, strlen(a))) +#define SET_CONF(a, b) (a = (b > 0.0 ? b : a)) + +struct parse_result { + char *section; + char *name; + char *value; +}; + +/** + * @brief Parse config file and call callback\n + * @param[in] file_name conf file. + * @param[in] cb cb is called when conf file is parsed line by line. + * @param[in] user_data user data is passed to cb. + * @return 0 on success, negative if failed + */ +int config_parse(const char *file_name, int cb(struct parse_result *result, + void *user_data), void *user_data); + +#endif diff --git a/src/libcommon/list.h b/src/libcommon/list.h new file mode 100644 index 0000000..eed36c0 --- /dev/null +++ b/src/libcommon/list.h @@ -0,0 +1,61 @@ +/* + * libsyscommon + * + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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. + */ + +#ifndef __LIST_H__ +#define __LIST_H__ + +#include +typedef GList list; + +#define LIST_PREPEND(a, b) \ + a = g_list_prepend(a, (gpointer)b) +#define LIST_APPEND(a, b) \ + a = g_list_append(a, (gpointer)b) +#define LIST_REMOVE(a, b) \ + a = g_list_remove(a, (gpointer)b) +#define LIST_REMOVE_LIST(a, b) \ + a = g_list_delete_link(a, b) +#define LIST_LENGTH(a) \ + g_list_length(a) +#define LIST_NTH(a, b) \ + g_list_nth_data(a, b) +#define LIST_FIND(a, b) \ + g_list_find(a, (gpointer)b) +#define LIST_FREE_LIST(a) \ + g_list_free(a) +#define LIST_FOREACH(head, elem, node) \ + for (elem = head, node = NULL; \ + elem && ((node = elem->data) != NULL); \ + elem = elem->next, node = NULL) +#define LIST_FOREACH_SAFE(head, elem, elem_next, node) \ + for (elem = head, elem_next = g_list_next(elem), node = NULL; \ + elem && ((node = elem->data) != NULL); \ + elem = elem_next, elem_next = g_list_next(elem), node = NULL) +#define LIST_REVERSE_FOREACH(head, elem, node) \ + for (elem = g_list_last(head), node = NULL; \ + elem && ((node = elem->data) != NULL); \ + elem = g_list_previous(elem), node = NULL) +#define LIST_REVERSE_FOREACH_SAFE(head, elem, elem_next, node) \ + for (elem = g_list_last(head), elem_next = g_list_previous(elem), node = NULL; \ + elem && ((node = elem->data) != NULL); \ + elem = elem_next, elem_next = g_list_previous(elem), node = NULL) +#define LIST_NEXT(a) \ + g_list_next(a) + +#endif +