libcommon: Add common library 32/250832/3
authorYunmi Ha <yunmi.ha@samsung.com>
Tue, 5 Jan 2021 04:45:21 +0000 (13:45 +0900)
committerYunmi Ha <yunmi.ha@samsung.com>
Wed, 6 Jan 2021 03:53:48 +0000 (12:53 +0900)
- list (glib)
- ini-parser

Change-Id: Ic13b47d5a1f26ed8b40007684da620a804775623
Signed-off-by: Yunmi Ha <yunmi.ha@samsung.com>
CMakeLists.txt
packaging/libsyscommon.spec
src/libcommon/ini-parser.c [new file with mode: 0644]
src/libcommon/ini-parser.h [new file with mode: 0644]
src/libcommon/list.h [new file with mode: 0644]

index 2a1522ffeaccf376b90abc0e28d8d9d1d97b0302..33bf5f4ba45f395fe2be326fe0d894da953a0aba 100644 (file)
@@ -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
index 4957b71485f619732d6ffb6cd0b60219110ccdf3..45a25cedb69655e85e3bdfcb6818bfcdd45c7770 100644 (file)
@@ -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 (file)
index 0000000..11093cc
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <errno.h>
+#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 (file)
index 0000000..b65c2b1
--- /dev/null
@@ -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 (file)
index 0000000..eed36c0
--- /dev/null
@@ -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 <glib.h>
+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
+