diff options
author | Guillaume Friloux <guillaume.friloux@gmail.com> | 2013-12-17 15:31:53 +0100 |
---|---|---|
committer | Guillaume Friloux <guillaume.friloux@gmail.com> | 2013-12-17 15:31:53 +0100 |
commit | 6b427971ed5c8c26786e77fb33140cca117737c1 (patch) | |
tree | 549e9005366b8312d5aba93759c7a22c8ef61c22 | |
parent | 208c0f4277dcd39db4a9c6a10bf12a7e29a114eb (diff) |
Rewrite of libconf to be clean. SMMAN BROKEN AT THIS COMMIT!
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/include/Conf.h | 72 | ||||
-rw-r--r-- | src/lib/Makefile.mk | 4 | ||||
-rw-r--r-- | src/lib/conf/conf_load.c | 133 | ||||
-rw-r--r-- | src/lib/conf/conf_main.c | 155 | ||||
-rw-r--r-- | src/lib/conf/conf_private.h | 38 |
6 files changed, 341 insertions, 63 deletions
diff --git a/configure.ac b/configure.ac index 688c0d6..e34fd21 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -47,7 +47,7 @@ doc/Makefile | |||
47 | ]) | 47 | ]) |
48 | 48 | ||
49 | build_libs= | 49 | build_libs= |
50 | LIBS_REQUIRES="eina ecore" | 50 | LIBS_REQUIRES="eina ecore eio" |
51 | PKG_CHECK_MODULES(LIBS, [$LIBS_REQUIRES], [build_libs=yes], [build_libs=no]) | 51 | PKG_CHECK_MODULES(LIBS, [$LIBS_REQUIRES], [build_libs=yes], [build_libs=no]) |
52 | 52 | ||
53 | build_smman= | 53 | build_smman= |
diff --git a/src/include/Conf.h b/src/include/Conf.h index d26a4a2..e6f68fe 100644 --- a/src/include/Conf.h +++ b/src/include/Conf.h | |||
@@ -1,66 +1,16 @@ | |||
1 | /* | 1 | #ifndef CONF_H |
2 | * Copyright © 2013 Guillaume Friloux <kuri@efl.so> | 2 | #define CONF_H |
3 | * | ||
4 | * This program is free software: you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation, either version 3 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | /** | ||
20 | * @file libconf.h | ||
21 | * @brief Contains structs and prototypes of libconf | ||
22 | * @author Guillaume Friloux <kuri@efl.so> | ||
23 | * @version 1.0 | ||
24 | * | ||
25 | * Contains structs and prototypes of libconf | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include <string.h> | ||
30 | #include <sys/types.h> | ||
31 | #include <sys/stat.h> | ||
32 | #include <fcntl.h> | ||
33 | #include <unistd.h> | ||
34 | #include <errno.h> | ||
35 | #include <Eina.h> | 3 | #include <Eina.h> |
4 | #include <Ecore.h> | ||
5 | #include <Eio.h> | ||
36 | 6 | ||
37 | #ifndef LIBCONFVARS | 7 | typedef struct _Conf Conf; |
38 | #define LIBCONFVARS | ||
39 | /** | ||
40 | * \struct libconfig | ||
41 | * \brief Main structure | ||
42 | */ | ||
43 | struct libconfig | ||
44 | { | ||
45 | char file[512]; /**< Name of config file */ | ||
46 | Eina_List *lconfig; /**< List of variables */ | ||
47 | }; | ||
48 | 8 | ||
49 | /** | 9 | typedef void (*Conf_Done_Cb)(void *data, Conf *conf); |
50 | * \struct libconfig_entry | 10 | typedef void (*Conf_Error_Cb)(void *data, Conf *conf, const char *errstr); |
51 | * \brief Structure containing information about one config entry | ||
52 | */ | ||
53 | struct libconfig_entry | ||
54 | { | ||
55 | char *var, /**< Variable name */ | ||
56 | *value; /**< Value for this variable */ | ||
57 | }; | ||
58 | 11 | ||
59 | int ligconfig_einadom; /**< Eina DOM to use for eina logs */ | 12 | Eina_Hash * conf_variables_get(Conf *conf); |
13 | Eina_Bool conf_load(char *file, Conf_Done_Cb done_cb, Conf_Error_Cb error_cb, const void *data); | ||
14 | int conf_init(void); | ||
15 | int conf_shutdown(void); | ||
60 | #endif | 16 | #endif |
61 | |||
62 | int libconfig_init(char *file, struct libconfig *myconf); | ||
63 | int libconfig_load(struct libconfig *myconf); | ||
64 | int libconfig_list(struct libconfig *myconf, int (*callback_function)(char *variable, char *value)); | ||
65 | int libconfig_free(struct libconfig *myconf); | ||
66 | void libconfig_version(char *version); | ||
diff --git a/src/lib/Makefile.mk b/src/lib/Makefile.mk index 88771bb..67784be 100644 --- a/src/lib/Makefile.mk +++ b/src/lib/Makefile.mk | |||
@@ -5,7 +5,9 @@ src/lib/libconf.la \ | |||
5 | src/lib/libspy.la | 5 | src/lib/libspy.la |
6 | 6 | ||
7 | src_lib_libconf_la_SOURCES = \ | 7 | src_lib_libconf_la_SOURCES = \ |
8 | src/lib/conf.c \ | 8 | src/lib/conf/conf_main.c \ |
9 | src/lib/conf/conf_load.c \ | ||
10 | src/lib/conf/conf_private.h \ | ||
9 | src/include/Conf.h | 11 | src/include/Conf.h |
10 | src_lib_libconf_la_CFLAGS = $(LIBS_CFLAGS) $(EXTRA_CPPFLAGS) | 12 | src_lib_libconf_la_CFLAGS = $(LIBS_CFLAGS) $(EXTRA_CPPFLAGS) |
11 | src_lib_libconf_la_LDFLAGS = $(LIBS_CFLAGS) | 13 | src_lib_libconf_la_LDFLAGS = $(LIBS_CFLAGS) |
diff --git a/src/lib/conf/conf_load.c b/src/lib/conf/conf_load.c new file mode 100644 index 0000000..f41c1e7 --- /dev/null +++ b/src/lib/conf/conf_load.c | |||
@@ -0,0 +1,133 @@ | |||
1 | #include "conf_private.h" | ||
2 | |||
3 | void | ||
4 | conf_load_line_free(void *data) | ||
5 | { | ||
6 | free(data); | ||
7 | } | ||
8 | |||
9 | void | ||
10 | conf_load_line_parse(Conf *conf, | ||
11 | char *line) | ||
12 | { | ||
13 | char **split, | ||
14 | *variable, | ||
15 | *value; | ||
16 | Eina_Strbuf *buf; | ||
17 | |||
18 | DBG("conf[%p] line[%s]", conf, line); | ||
19 | |||
20 | if (line[0] == '#') | ||
21 | return; | ||
22 | |||
23 | split = eina_str_split(line, "=", 2); | ||
24 | if (!split) | ||
25 | { | ||
26 | ERR("Failed to alloc 2D array"); | ||
27 | return; | ||
28 | } | ||
29 | |||
30 | if ((!split[0]) || (!split[1])) | ||
31 | { | ||
32 | ERR("Failed to split line correctly"); | ||
33 | return; | ||
34 | } | ||
35 | |||
36 | buf = eina_strbuf_new(); | ||
37 | if (!buf) | ||
38 | { | ||
39 | ERR("Failed to allocate string buffer"); | ||
40 | return; | ||
41 | } | ||
42 | |||
43 | eina_strbuf_append(buf, split[0]); | ||
44 | eina_strbuf_trim(buf); | ||
45 | variable = eina_strbuf_string_steal(buf); | ||
46 | |||
47 | eina_strbuf_append(buf, split[1]); | ||
48 | eina_strbuf_trim(buf); | ||
49 | value = eina_strbuf_string_steal(buf); | ||
50 | |||
51 | eina_hash_add(conf->variables, variable, strdup(value)); | ||
52 | |||
53 | free(variable); | ||
54 | free(value); | ||
55 | eina_strbuf_free(buf); | ||
56 | } | ||
57 | |||
58 | Eina_Bool | ||
59 | conf_load_map_filter(void *data, | ||
60 | Eio_File *handler EINA_UNUSED, | ||
61 | void *map, | ||
62 | size_t length) | ||
63 | { | ||
64 | Conf_Load *cl; | ||
65 | Conf *conf; | ||
66 | const char *s, | ||
67 | *p1; | ||
68 | char *line; | ||
69 | |||
70 | cl = data; | ||
71 | conf = cl->conf; | ||
72 | s = map; | ||
73 | |||
74 | while (1) | ||
75 | { | ||
76 | if ((size_t)(s-(const char *)map) == length) | ||
77 | break; | ||
78 | |||
79 | p1 = strchr(s, '\n'); | ||
80 | if (!p1) | ||
81 | goto end_loop; | ||
82 | |||
83 | if (p1 == s) | ||
84 | goto end_loop; | ||
85 | |||
86 | line = strndup(s, p1 -s); | ||
87 | if (line[p1-s-1] == '\r') | ||
88 | line[p1-s-1] = 0; | ||
89 | |||
90 | conf_load_line_parse(conf, line); | ||
91 | |||
92 | free((char *)line); | ||
93 | |||
94 | s = p1; | ||
95 | |||
96 | end_loop: | ||
97 | s++; | ||
98 | } | ||
99 | |||
100 | return EINA_TRUE; | ||
101 | } | ||
102 | |||
103 | void | ||
104 | conf_load_map_main(void *data, | ||
105 | Eio_File *handler EINA_UNUSED, | ||
106 | void *map EINA_UNUSED, | ||
107 | size_t length EINA_UNUSED) | ||
108 | { | ||
109 | Conf_Load *cl; | ||
110 | |||
111 | cl = data; | ||
112 | DBG("cl[%p]", cl); | ||
113 | |||
114 | cl->cb.done((void *)cl->cb.data, cl->conf); | ||
115 | conf_free(cl->conf); | ||
116 | free(cl); | ||
117 | } | ||
118 | |||
119 | void | ||
120 | conf_load_map_error(void *data, | ||
121 | Eio_File *handler EINA_UNUSED, | ||
122 | int error) | ||
123 | { | ||
124 | Conf_Load *cl; | ||
125 | |||
126 | cl = data; | ||
127 | ERR("Error while mmaping file %s : %s", cl->conf->file, strerror(error)); | ||
128 | |||
129 | cl->cb.error((void *)cl->cb.data, cl->conf, | ||
130 | "Error while mmaping file"); | ||
131 | conf_free(cl->conf); | ||
132 | free(cl); | ||
133 | } | ||
diff --git a/src/lib/conf/conf_main.c b/src/lib/conf/conf_main.c new file mode 100644 index 0000000..154995f --- /dev/null +++ b/src/lib/conf/conf_main.c | |||
@@ -0,0 +1,155 @@ | |||
1 | #include "conf_private.h" | ||
2 | |||
3 | static int _conf_init_count = 0; | ||
4 | int _conf_log_dom_global = -1; | ||
5 | |||
6 | Eina_Hash * | ||
7 | conf_variables_get(Conf *conf) | ||
8 | { | ||
9 | return conf->variables; | ||
10 | } | ||
11 | |||
12 | void | ||
13 | conf_free(Conf *conf) | ||
14 | { | ||
15 | EINA_SAFETY_ON_NULL_RETURN(conf); | ||
16 | |||
17 | if (conf->ef) | ||
18 | { | ||
19 | eina_file_close(conf->ef); | ||
20 | conf->ef = NULL; | ||
21 | } | ||
22 | |||
23 | if (conf->file) | ||
24 | { | ||
25 | free((char *)conf->file); | ||
26 | conf->file = NULL; | ||
27 | } | ||
28 | |||
29 | free(conf); | ||
30 | } | ||
31 | |||
32 | Eina_Bool | ||
33 | conf_load(char *file, | ||
34 | Conf_Done_Cb done_cb, | ||
35 | Conf_Error_Cb error_cb, | ||
36 | const void *data) | ||
37 | { | ||
38 | Conf *conf; | ||
39 | Conf_Load *cl; | ||
40 | |||
41 | conf = calloc(1, sizeof(Conf)); | ||
42 | if (!conf) | ||
43 | { | ||
44 | ERR("Failed to allocate Conf structure"); | ||
45 | return EINA_FALSE; | ||
46 | } | ||
47 | |||
48 | conf->ef = eina_file_open(file, EINA_FALSE); | ||
49 | if (!conf->ef) | ||
50 | { | ||
51 | ERR("Failed to open file %s : %s", file, strerror(errno)); | ||
52 | goto free_conf; | ||
53 | } | ||
54 | |||
55 | conf->file = strdup(file); | ||
56 | if (!conf->file) | ||
57 | { | ||
58 | ERR("Failed to allocate buffer"); | ||
59 | goto close_file; | ||
60 | } | ||
61 | |||
62 | cl = calloc(1, sizeof(Conf_Load)); | ||
63 | if (!cl) | ||
64 | { | ||
65 | ERR("Failed to allocate Conf_Load structure"); | ||
66 | goto free_file; | ||
67 | } | ||
68 | |||
69 | cl->cb.done = done_cb; | ||
70 | cl->cb.error = error_cb; | ||
71 | cl->cb.data = data; | ||
72 | cl->conf = conf; | ||
73 | |||
74 | conf->variables = eina_hash_string_superfast_new(conf_load_line_free); | ||
75 | |||
76 | eio_file_map_all(conf->ef, | ||
77 | EINA_FILE_SEQUENTIAL, | ||
78 | conf_load_map_filter, | ||
79 | conf_load_map_main, | ||
80 | conf_load_map_error, | ||
81 | cl); | ||
82 | |||
83 | return EINA_TRUE; | ||
84 | |||
85 | free_file: | ||
86 | free((char *)conf->file); | ||
87 | close_file: | ||
88 | eina_file_close(conf->ef); | ||
89 | conf->ef = NULL; | ||
90 | free_conf: | ||
91 | free(conf); | ||
92 | return EINA_FALSE; | ||
93 | } | ||
94 | |||
95 | int conf_init(void) | ||
96 | { | ||
97 | if (++_conf_init_count != 1) | ||
98 | return _conf_init_count; | ||
99 | |||
100 | if (!eina_init()) | ||
101 | { | ||
102 | fprintf(stderr, "Conf can not initialize Eina\n"); | ||
103 | return --_conf_init_count; | ||
104 | } | ||
105 | |||
106 | _conf_log_dom_global = eina_log_domain_register("conf", EINA_COLOR_RED); | ||
107 | if (_conf_log_dom_global < 0) | ||
108 | { | ||
109 | EINA_LOG_ERR("Conf can not create a general log domain"); | ||
110 | goto shutdown_eina; | ||
111 | } | ||
112 | |||
113 | if (!ecore_init()) | ||
114 | { | ||
115 | ERR("Can not initialize Ecore"); | ||
116 | goto unregister_log_domain; | ||
117 | } | ||
118 | |||
119 | if (!eio_init()) | ||
120 | { | ||
121 | ERR("Can not initialize Conf"); | ||
122 | goto shutdown_ecore; | ||
123 | } | ||
124 | |||
125 | eina_log_threads_enable(); | ||
126 | return _conf_init_count; | ||
127 | |||
128 | shutdown_ecore: | ||
129 | ecore_shutdown(); | ||
130 | unregister_log_domain: | ||
131 | eina_log_domain_unregister(_conf_log_dom_global); | ||
132 | _conf_log_dom_global = -1; | ||
133 | shutdown_eina: | ||
134 | eina_shutdown(); | ||
135 | return --_conf_init_count; | ||
136 | } | ||
137 | |||
138 | int | ||
139 | conf_shutdown(void) | ||
140 | { | ||
141 | if (_conf_init_count <= 0) | ||
142 | { | ||
143 | fprintf(stderr, "Conf init count not greater than 0 in shutdown."); | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | if (--_conf_init_count != 0) | ||
148 | return _conf_init_count; | ||
149 | |||
150 | ecore_shutdown(); | ||
151 | eina_log_domain_unregister(_conf_log_dom_global); | ||
152 | _conf_log_dom_global = -1; | ||
153 | eina_shutdown(); | ||
154 | return _conf_init_count; | ||
155 | } | ||
diff --git a/src/lib/conf/conf_private.h b/src/lib/conf/conf_private.h new file mode 100644 index 0000000..693f36e --- /dev/null +++ b/src/lib/conf/conf_private.h | |||
@@ -0,0 +1,38 @@ | |||
1 | #include <Conf.h> | ||
2 | |||
3 | extern int _conf_log_dom_global; | ||
4 | |||
5 | #define ERR(...) EINA_LOG_DOM_ERR(_conf_log_dom_global, __VA_ARGS__) | ||
6 | #define DBG(...) EINA_LOG_DOM_DBG(_conf_log_dom_global, __VA_ARGS__) | ||
7 | #define NFO(...) EINA_LOG_DOM_INFO(_conf_log_dom_global, __VA_ARGS__) | ||
8 | #define WRN(...) EINA_LOG_DOM_WARN(_conf_log_dom_global, __VA_ARGS__) | ||
9 | #define CRI(...) EINA_LOG_DOM_CRIT(_conf_log_dom_global, __VA_ARGS__) | ||
10 | |||
11 | struct _Conf | ||
12 | { | ||
13 | const char *file; | ||
14 | Eina_File *ef; | ||
15 | |||
16 | Eina_Hash *variables; | ||
17 | }; | ||
18 | |||
19 | |||
20 | typedef struct _Conf_Load | ||
21 | { | ||
22 | Conf *conf; | ||
23 | |||
24 | struct | ||
25 | { | ||
26 | Conf_Done_Cb done; | ||
27 | Conf_Error_Cb error; | ||
28 | const void *data; | ||
29 | } cb; | ||
30 | } Conf_Load; | ||
31 | |||
32 | void conf_free(Conf *conf); | ||
33 | |||
34 | Eina_Bool conf_load_map_filter(void *data, Eio_File *handler, void *map, size_t length); | ||
35 | void conf_load_map_main(void *data, Eio_File *handler, void *map, size_t length); | ||
36 | void conf_load_map_error(void *data, Eio_File *handler, int error); | ||
37 | |||
38 | void conf_load_line_free(void *data); | ||