diff options
author | David Walter Seikel | 2013-01-13 17:29:19 +1000 |
---|---|---|
committer | David Walter Seikel | 2013-01-13 17:29:19 +1000 |
commit | 07274513e984f0b5544586c74508ccd16e7dcafa (patch) | |
tree | b32ff2a9136fbc1a4a6a0ed1e4d79cde0f5f16d9 /libraries/eina/src/lib | |
parent | Added Irrlicht 1.8, but without all the Windows binaries. (diff) | |
download | SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.zip SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.gz SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.bz2 SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.xz |
Remove EFL, since it's been released now.
Diffstat (limited to '')
52 files changed, 0 insertions, 38742 deletions
diff --git a/libraries/eina/src/lib/Makefile.am b/libraries/eina/src/lib/Makefile.am deleted file mode 100644 index 5de2848..0000000 --- a/libraries/eina/src/lib/Makefile.am +++ /dev/null | |||
@@ -1,178 +0,0 @@ | |||
1 | MAINTAINERCLEANFILES = Makefile.in | ||
2 | |||
3 | AM_CPPFLAGS = \ | ||
4 | -I$(top_srcdir)/src/include \ | ||
5 | -I$(top_builddir)/src/include \ | ||
6 | -DPACKAGE_BIN_DIR=\"$(bindir)\" \ | ||
7 | -DPACKAGE_LIB_DIR=\"$(libdir)\" \ | ||
8 | -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ | ||
9 | @EFL_EINA_BUILD@ \ | ||
10 | @VALGRIND_CFLAGS@ | ||
11 | |||
12 | base_sources = \ | ||
13 | eina_accessor.c \ | ||
14 | eina_array.c \ | ||
15 | eina_benchmark.c \ | ||
16 | eina_binbuf.c \ | ||
17 | eina_binshare.c \ | ||
18 | eina_convert.c \ | ||
19 | eina_counter.c \ | ||
20 | eina_cpu.c \ | ||
21 | eina_error.c \ | ||
22 | eina_fp.c \ | ||
23 | eina_hamster.c \ | ||
24 | eina_hash.c \ | ||
25 | eina_inarray.c \ | ||
26 | eina_inlist.c \ | ||
27 | eina_iterator.c \ | ||
28 | eina_lalloc.c \ | ||
29 | eina_list.c \ | ||
30 | eina_log.c \ | ||
31 | eina_magic.c \ | ||
32 | eina_main.c \ | ||
33 | eina_matrixsparse.c \ | ||
34 | eina_mempool.c \ | ||
35 | eina_mmap.c \ | ||
36 | eina_model.c \ | ||
37 | eina_module.c \ | ||
38 | eina_prefix.c \ | ||
39 | eina_quadtree.c \ | ||
40 | eina_rbtree.c \ | ||
41 | eina_rectangle.c \ | ||
42 | eina_safety_checks.c \ | ||
43 | eina_sched.c \ | ||
44 | eina_share_common.c \ | ||
45 | eina_simple_xml_parser.c \ | ||
46 | eina_str.c \ | ||
47 | eina_strbuf.c \ | ||
48 | eina_strbuf_common.c \ | ||
49 | eina_stringshare.c \ | ||
50 | eina_tiler.c \ | ||
51 | eina_unicode.c \ | ||
52 | eina_ustrbuf.c \ | ||
53 | eina_ustringshare.c \ | ||
54 | eina_value.c \ | ||
55 | eina_xattr.c | ||
56 | |||
57 | # Will be back for developper after 1.1 | ||
58 | # eina_object.c | ||
59 | |||
60 | if EINA_HAVE_WIN32 | ||
61 | base_sources += eina_file_win32.c | ||
62 | else | ||
63 | base_sources += eina_file.c | ||
64 | endif | ||
65 | |||
66 | EXTRA_DIST = \ | ||
67 | eina_share_common.h \ | ||
68 | eina_private.h \ | ||
69 | eina_strbuf_common.h \ | ||
70 | eina_strbuf_template_c.x \ | ||
71 | eina_binbuf_template_c.x | ||
72 | |||
73 | |||
74 | |||
75 | if EINA_STATIC_BUILD_BUDDY | ||
76 | base_sources += $(top_srcdir)/src/modules/mp/buddy/eina_buddy.c | ||
77 | endif | ||
78 | |||
79 | if EINA_STATIC_BUILD_CHAINED_POOL | ||
80 | base_sources += $(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c | ||
81 | endif | ||
82 | |||
83 | if EINA_STATIC_BUILD_EMEMOA_FIXED | ||
84 | base_sources += $(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c | ||
85 | endif | ||
86 | |||
87 | if EINA_STATIC_BUILD_EMEMOA_UNKNOWN | ||
88 | base_sources += $(top_srcdir)/src/modules/mp/ememoa_unknown/eina_ememoa_unknown.c | ||
89 | endif | ||
90 | |||
91 | if EINA_STATIC_BUILD_FIXED_BITMAP | ||
92 | base_sources += $(top_srcdir)/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c | ||
93 | endif | ||
94 | |||
95 | if EINA_STATIC_BUILD_ONE_BIG | ||
96 | base_sources += $(top_srcdir)/src/modules/mp/one_big/eina_one_big.c | ||
97 | endif | ||
98 | |||
99 | if EINA_STATIC_BUILD_PASS_THROUGH | ||
100 | base_sources += $(top_srcdir)/src/modules/mp/pass_through/eina_pass_through.c | ||
101 | endif | ||
102 | |||
103 | lib_LTLIBRARIES = libeina.la | ||
104 | |||
105 | if EINA_AMALGAMATION | ||
106 | nodist_libeina_la_SOURCES = eina_amalgamation.c | ||
107 | |||
108 | eina_amalgamation.c: $(base_sources) Makefile | ||
109 | -rm -f eina_amalgamation.c | ||
110 | |||
111 | @echo "#ifdef HAVE_CONFIG_H" >> eina_amalgamation.c | ||
112 | @echo "#include \"config.h\"" >> eina_amalgamation.c | ||
113 | @echo "#endif" >> eina_amalgamation.c | ||
114 | |||
115 | @echo "#ifdef HAVE_ALLOCA_H" >> eina_amalgamation.c | ||
116 | @echo "# include <alloca.h>" >> eina_amalgamation.c | ||
117 | @echo "#elif defined __GNUC__" >> eina_amalgamation.c | ||
118 | @echo "# define alloca __builtin_alloca" >> eina_amalgamation.c | ||
119 | @echo "#elif defined _AIX" >> eina_amalgamation.c | ||
120 | @echo "# define alloca __alloca" >> eina_amalgamation.c | ||
121 | @echo "#elif defined _MSC_VER" >> eina_amalgamation.c | ||
122 | @echo "# include <malloc.h>" >> eina_amalgamation.c | ||
123 | @echo "# define alloca _alloca" >> eina_amalgamation.c | ||
124 | @echo "#else" >> eina_amalgamation.c | ||
125 | @echo "# include <stddef.h>" >> eina_amalgamation.c | ||
126 | @echo "# ifdef __cplusplus" >> eina_amalgamation.c | ||
127 | @echo "#extern \"C\"" >> eina_amalgamation.c | ||
128 | @echo "# endif" >> eina_amalgamation.c | ||
129 | @echo "#void *alloca (size_t);" >> eina_amalgamation.c | ||
130 | @echo "#endif" >> eina_amalgamation.c | ||
131 | |||
132 | @echo "#include <stdio.h>" >> eina_amalgamation.c | ||
133 | @echo "#include <stdlib.h>" >> eina_amalgamation.c | ||
134 | @echo "#include <string.h>" >> eina_amalgamation.c | ||
135 | @echo "#ifdef HAVE_DLOPEN" >> eina_amalgamation.c | ||
136 | @echo "# include <dlfcn.h>" >> eina_amalgamation.c | ||
137 | @echo "#endif" >> eina_amalgamation.c | ||
138 | @echo "#include <sys/types.h>" >> eina_amalgamation.c | ||
139 | @echo "#ifdef HAVE_DIRENT_H" >> eina_amalgamation.c | ||
140 | @echo "# include <dirent.h>" >> eina_amalgamation.c | ||
141 | @echo "#endif" >> eina_amalgamation.c | ||
142 | @echo "#include <assert.h>" >> eina_amalgamation.c | ||
143 | @echo "#include <errno.h>" >> eina_amalgamation.c | ||
144 | @echo "#include <fnmatch.h>" >> eina_amalgamation.c | ||
145 | @echo "#include <fcntl.h>" >> eina_amalgamation.c | ||
146 | |||
147 | @echo "#ifdef HAVE_EVIL" >> eina_amalgamation.c | ||
148 | @echo "# include <Evil.h>" >> eina_amalgamation.c | ||
149 | @echo "#endif" >> eina_amalgamation.c | ||
150 | |||
151 | @echo "#include \"eina_config.h\"" >> eina_amalgamation.c | ||
152 | @echo "#include \"eina_private.h\"" >> eina_amalgamation.c | ||
153 | @echo "#include \"eina_safety_checks.h\"" >> eina_amalgamation.c | ||
154 | @echo "#include \"Eina.h\"" >> eina_amalgamation.c | ||
155 | @echo "#include \"eina_strbuf_common.h\"" >> eina_amalgamation.c | ||
156 | @echo "#include \"eina_share_common.h\"" >> eina_amalgamation.c | ||
157 | |||
158 | @for f in $(base_sources); do \ | ||
159 | if [ `echo $$f | sed -e 's/^...\(.\).*/\1/'` != '/' ]; then \ | ||
160 | file="$(srcdir)/$$f" ; \ | ||
161 | else \ | ||
162 | file="$$f" ; \ | ||
163 | fi ; \ | ||
164 | echo "/* file: $$file */" >> eina_amalgamation.c; \ | ||
165 | grep -v -e '^# *include \+.\(config\|eina_[a-z_]\+\|Evil\|stdio\|stdlib\|string\|dlfcn\|dirent\|assert\|errno\|fnmatch\)[.]h.*' $$file >> eina_amalgamation.c; \ | ||
166 | done | ||
167 | @echo "eina_amalgamation.c generated" | ||
168 | |||
169 | else | ||
170 | libeina_la_SOURCES = $(base_sources) | ||
171 | endif | ||
172 | |||
173 | libeina_la_LIBADD = @iconv_libs@ @rt_libs@ @EINA_LIBS@ @dlopen_libs@ | ||
174 | libeina_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ @EFL_PTHREAD_LIBS@ | ||
175 | libeina_la_CFLAGS = @EINA_CFLAGS@ @EFL_PTHREAD_CFLAGS@ | ||
176 | |||
177 | clean-local: | ||
178 | rm -rf *.gcno eina_amalgamation.c | ||
diff --git a/libraries/eina/src/lib/Makefile.in b/libraries/eina/src/lib/Makefile.in deleted file mode 100644 index f15bb00..0000000 --- a/libraries/eina/src/lib/Makefile.in +++ /dev/null | |||
@@ -1,1260 +0,0 @@ | |||
1 | # Makefile.in generated by automake 1.11.1 from Makefile.am. | ||
2 | # @configure_input@ | ||
3 | |||
4 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, | ||
5 | # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, | ||
6 | # Inc. | ||
7 | # This Makefile.in is free software; the Free Software Foundation | ||
8 | # gives unlimited permission to copy and/or distribute it, | ||
9 | # with or without modifications, as long as this notice is preserved. | ||
10 | |||
11 | # This program is distributed in the hope that it will be useful, | ||
12 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without | ||
13 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
14 | # PARTICULAR PURPOSE. | ||
15 | |||
16 | @SET_MAKE@ | ||
17 | |||
18 | VPATH = @srcdir@ | ||
19 | pkgdatadir = $(datadir)/@PACKAGE@ | ||
20 | pkgincludedir = $(includedir)/@PACKAGE@ | ||
21 | pkglibdir = $(libdir)/@PACKAGE@ | ||
22 | pkglibexecdir = $(libexecdir)/@PACKAGE@ | ||
23 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd | ||
24 | install_sh_DATA = $(install_sh) -c -m 644 | ||
25 | install_sh_PROGRAM = $(install_sh) -c | ||
26 | install_sh_SCRIPT = $(install_sh) -c | ||
27 | INSTALL_HEADER = $(INSTALL_DATA) | ||
28 | transform = $(program_transform_name) | ||
29 | NORMAL_INSTALL = : | ||
30 | PRE_INSTALL = : | ||
31 | POST_INSTALL = : | ||
32 | NORMAL_UNINSTALL = : | ||
33 | PRE_UNINSTALL = : | ||
34 | POST_UNINSTALL = : | ||
35 | build_triplet = @build@ | ||
36 | host_triplet = @host@ | ||
37 | |||
38 | # Will be back for developper after 1.1 | ||
39 | # eina_object.c | ||
40 | @EINA_HAVE_WIN32_TRUE@am__append_1 = eina_file_win32.c | ||
41 | @EINA_HAVE_WIN32_FALSE@am__append_2 = eina_file.c | ||
42 | @EINA_STATIC_BUILD_BUDDY_TRUE@am__append_3 = $(top_srcdir)/src/modules/mp/buddy/eina_buddy.c | ||
43 | @EINA_STATIC_BUILD_CHAINED_POOL_TRUE@am__append_4 = $(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c | ||
44 | @EINA_STATIC_BUILD_EMEMOA_FIXED_TRUE@am__append_5 = $(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c | ||
45 | @EINA_STATIC_BUILD_EMEMOA_UNKNOWN_TRUE@am__append_6 = $(top_srcdir)/src/modules/mp/ememoa_unknown/eina_ememoa_unknown.c | ||
46 | @EINA_STATIC_BUILD_FIXED_BITMAP_TRUE@am__append_7 = $(top_srcdir)/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c | ||
47 | @EINA_STATIC_BUILD_ONE_BIG_TRUE@am__append_8 = $(top_srcdir)/src/modules/mp/one_big/eina_one_big.c | ||
48 | @EINA_STATIC_BUILD_PASS_THROUGH_TRUE@am__append_9 = $(top_srcdir)/src/modules/mp/pass_through/eina_pass_through.c | ||
49 | subdir = src/lib | ||
50 | DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in | ||
51 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | ||
52 | am__aclocal_m4_deps = $(top_srcdir)/m4/eina/eina_bench.m4 \ | ||
53 | $(top_srcdir)/m4/eina/eina_check.m4 \ | ||
54 | $(top_srcdir)/m4/common/efl_attribute.m4 \ | ||
55 | $(top_srcdir)/m4/common/efl_benchmark.m4 \ | ||
56 | $(top_srcdir)/m4/common/efl_compiler_flag.m4 \ | ||
57 | $(top_srcdir)/m4/common/efl_coverage.m4 \ | ||
58 | $(top_srcdir)/m4/common/efl_cpu.m4 \ | ||
59 | $(top_srcdir)/m4/common/efl_doxygen.m4 \ | ||
60 | $(top_srcdir)/m4/common/efl_examples.m4 \ | ||
61 | $(top_srcdir)/m4/common/efl_fnmatch.m4 \ | ||
62 | $(top_srcdir)/m4/common/efl_path_max.m4 \ | ||
63 | $(top_srcdir)/m4/common/efl_tests.m4 \ | ||
64 | $(top_srcdir)/m4/common/efl_threads.m4 \ | ||
65 | $(top_srcdir)/m4/common/efl_voltron.m4 \ | ||
66 | $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ | ||
67 | $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ | ||
68 | $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \ | ||
69 | $(top_srcdir)/configure.ac | ||
70 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ | ||
71 | $(ACLOCAL_M4) | ||
72 | mkinstalldirs = $(install_sh) -d | ||
73 | CONFIG_HEADER = $(top_builddir)/config.h | ||
74 | CONFIG_CLEAN_FILES = | ||
75 | CONFIG_CLEAN_VPATH_FILES = | ||
76 | am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; | ||
77 | am__vpath_adj = case $$p in \ | ||
78 | $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ | ||
79 | *) f=$$p;; \ | ||
80 | esac; | ||
81 | am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; | ||
82 | am__install_max = 40 | ||
83 | am__nobase_strip_setup = \ | ||
84 | srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` | ||
85 | am__nobase_strip = \ | ||
86 | for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" | ||
87 | am__nobase_list = $(am__nobase_strip_setup); \ | ||
88 | for p in $$list; do echo "$$p $$p"; done | \ | ||
89 | sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ | ||
90 | $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ | ||
91 | if (++n[$$2] == $(am__install_max)) \ | ||
92 | { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ | ||
93 | END { for (dir in files) print dir, files[dir] }' | ||
94 | am__base_list = \ | ||
95 | sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ | ||
96 | sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | ||
97 | am__installdirs = "$(DESTDIR)$(libdir)" | ||
98 | LTLIBRARIES = $(lib_LTLIBRARIES) | ||
99 | libeina_la_DEPENDENCIES = | ||
100 | am__libeina_la_SOURCES_DIST = eina_accessor.c eina_array.c \ | ||
101 | eina_benchmark.c eina_binbuf.c eina_binshare.c eina_convert.c \ | ||
102 | eina_counter.c eina_cpu.c eina_error.c eina_fp.c \ | ||
103 | eina_hamster.c eina_hash.c eina_inarray.c eina_inlist.c \ | ||
104 | eina_iterator.c eina_lalloc.c eina_list.c eina_log.c \ | ||
105 | eina_magic.c eina_main.c eina_matrixsparse.c eina_mempool.c \ | ||
106 | eina_mmap.c eina_model.c eina_module.c eina_prefix.c \ | ||
107 | eina_quadtree.c eina_rbtree.c eina_rectangle.c \ | ||
108 | eina_safety_checks.c eina_sched.c eina_share_common.c \ | ||
109 | eina_simple_xml_parser.c eina_str.c eina_strbuf.c \ | ||
110 | eina_strbuf_common.c eina_stringshare.c eina_tiler.c \ | ||
111 | eina_unicode.c eina_ustrbuf.c eina_ustringshare.c eina_value.c \ | ||
112 | eina_xattr.c eina_file_win32.c eina_file.c \ | ||
113 | $(top_srcdir)/src/modules/mp/buddy/eina_buddy.c \ | ||
114 | $(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c \ | ||
115 | $(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c \ | ||
116 | $(top_srcdir)/src/modules/mp/ememoa_unknown/eina_ememoa_unknown.c \ | ||
117 | $(top_srcdir)/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c \ | ||
118 | $(top_srcdir)/src/modules/mp/one_big/eina_one_big.c \ | ||
119 | $(top_srcdir)/src/modules/mp/pass_through/eina_pass_through.c | ||
120 | @EINA_HAVE_WIN32_TRUE@am__objects_1 = libeina_la-eina_file_win32.lo | ||
121 | @EINA_HAVE_WIN32_FALSE@am__objects_2 = libeina_la-eina_file.lo | ||
122 | @EINA_STATIC_BUILD_BUDDY_TRUE@am__objects_3 = \ | ||
123 | @EINA_STATIC_BUILD_BUDDY_TRUE@ libeina_la-eina_buddy.lo | ||
124 | @EINA_STATIC_BUILD_CHAINED_POOL_TRUE@am__objects_4 = libeina_la-eina_chained_mempool.lo | ||
125 | @EINA_STATIC_BUILD_EMEMOA_FIXED_TRUE@am__objects_5 = libeina_la-eina_ememoa_fixed.lo | ||
126 | @EINA_STATIC_BUILD_EMEMOA_UNKNOWN_TRUE@am__objects_6 = libeina_la-eina_ememoa_unknown.lo | ||
127 | @EINA_STATIC_BUILD_FIXED_BITMAP_TRUE@am__objects_7 = libeina_la-eina_fixed_bitmap.lo | ||
128 | @EINA_STATIC_BUILD_ONE_BIG_TRUE@am__objects_8 = \ | ||
129 | @EINA_STATIC_BUILD_ONE_BIG_TRUE@ libeina_la-eina_one_big.lo | ||
130 | @EINA_STATIC_BUILD_PASS_THROUGH_TRUE@am__objects_9 = libeina_la-eina_pass_through.lo | ||
131 | am__objects_10 = libeina_la-eina_accessor.lo libeina_la-eina_array.lo \ | ||
132 | libeina_la-eina_benchmark.lo libeina_la-eina_binbuf.lo \ | ||
133 | libeina_la-eina_binshare.lo libeina_la-eina_convert.lo \ | ||
134 | libeina_la-eina_counter.lo libeina_la-eina_cpu.lo \ | ||
135 | libeina_la-eina_error.lo libeina_la-eina_fp.lo \ | ||
136 | libeina_la-eina_hamster.lo libeina_la-eina_hash.lo \ | ||
137 | libeina_la-eina_inarray.lo libeina_la-eina_inlist.lo \ | ||
138 | libeina_la-eina_iterator.lo libeina_la-eina_lalloc.lo \ | ||
139 | libeina_la-eina_list.lo libeina_la-eina_log.lo \ | ||
140 | libeina_la-eina_magic.lo libeina_la-eina_main.lo \ | ||
141 | libeina_la-eina_matrixsparse.lo libeina_la-eina_mempool.lo \ | ||
142 | libeina_la-eina_mmap.lo libeina_la-eina_model.lo \ | ||
143 | libeina_la-eina_module.lo libeina_la-eina_prefix.lo \ | ||
144 | libeina_la-eina_quadtree.lo libeina_la-eina_rbtree.lo \ | ||
145 | libeina_la-eina_rectangle.lo libeina_la-eina_safety_checks.lo \ | ||
146 | libeina_la-eina_sched.lo libeina_la-eina_share_common.lo \ | ||
147 | libeina_la-eina_simple_xml_parser.lo libeina_la-eina_str.lo \ | ||
148 | libeina_la-eina_strbuf.lo libeina_la-eina_strbuf_common.lo \ | ||
149 | libeina_la-eina_stringshare.lo libeina_la-eina_tiler.lo \ | ||
150 | libeina_la-eina_unicode.lo libeina_la-eina_ustrbuf.lo \ | ||
151 | libeina_la-eina_ustringshare.lo libeina_la-eina_value.lo \ | ||
152 | libeina_la-eina_xattr.lo $(am__objects_1) $(am__objects_2) \ | ||
153 | $(am__objects_3) $(am__objects_4) $(am__objects_5) \ | ||
154 | $(am__objects_6) $(am__objects_7) $(am__objects_8) \ | ||
155 | $(am__objects_9) | ||
156 | @EINA_AMALGAMATION_FALSE@am_libeina_la_OBJECTS = $(am__objects_10) | ||
157 | @EINA_AMALGAMATION_TRUE@nodist_libeina_la_OBJECTS = \ | ||
158 | @EINA_AMALGAMATION_TRUE@ libeina_la-eina_amalgamation.lo | ||
159 | libeina_la_OBJECTS = $(am_libeina_la_OBJECTS) \ | ||
160 | $(nodist_libeina_la_OBJECTS) | ||
161 | AM_V_lt = $(am__v_lt_$(V)) | ||
162 | am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) | ||
163 | am__v_lt_0 = --silent | ||
164 | libeina_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ | ||
165 | $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libeina_la_CFLAGS) \ | ||
166 | $(CFLAGS) $(libeina_la_LDFLAGS) $(LDFLAGS) -o $@ | ||
167 | DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) | ||
168 | depcomp = $(SHELL) $(top_srcdir)/depcomp | ||
169 | am__depfiles_maybe = depfiles | ||
170 | am__mv = mv -f | ||
171 | COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ | ||
172 | $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||
173 | LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ | ||
174 | $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ | ||
175 | $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ | ||
176 | $(AM_CFLAGS) $(CFLAGS) | ||
177 | AM_V_CC = $(am__v_CC_$(V)) | ||
178 | am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) | ||
179 | am__v_CC_0 = @echo " CC " $@; | ||
180 | AM_V_at = $(am__v_at_$(V)) | ||
181 | am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) | ||
182 | am__v_at_0 = @ | ||
183 | CCLD = $(CC) | ||
184 | LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ | ||
185 | $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ | ||
186 | $(AM_LDFLAGS) $(LDFLAGS) -o $@ | ||
187 | AM_V_CCLD = $(am__v_CCLD_$(V)) | ||
188 | am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) | ||
189 | am__v_CCLD_0 = @echo " CCLD " $@; | ||
190 | AM_V_GEN = $(am__v_GEN_$(V)) | ||
191 | am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) | ||
192 | am__v_GEN_0 = @echo " GEN " $@; | ||
193 | SOURCES = $(libeina_la_SOURCES) $(nodist_libeina_la_SOURCES) | ||
194 | DIST_SOURCES = $(am__libeina_la_SOURCES_DIST) | ||
195 | ETAGS = etags | ||
196 | CTAGS = ctags | ||
197 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) | ||
198 | ACLOCAL = @ACLOCAL@ | ||
199 | ALLOCA = @ALLOCA@ | ||
200 | AMTAR = @AMTAR@ | ||
201 | AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ | ||
202 | AR = @AR@ | ||
203 | AS = @AS@ | ||
204 | AUTOCONF = @AUTOCONF@ | ||
205 | AUTOHEADER = @AUTOHEADER@ | ||
206 | AUTOMAKE = @AUTOMAKE@ | ||
207 | AWK = @AWK@ | ||
208 | CC = @CC@ | ||
209 | CCDEPMODE = @CCDEPMODE@ | ||
210 | CFLAGS = @CFLAGS@ | ||
211 | CHECK_CFLAGS = @CHECK_CFLAGS@ | ||
212 | CHECK_LIBS = @CHECK_LIBS@ | ||
213 | CPP = @CPP@ | ||
214 | CPPFLAGS = @CPPFLAGS@ | ||
215 | CXX = @CXX@ | ||
216 | CXXCPP = @CXXCPP@ | ||
217 | CXXDEPMODE = @CXXDEPMODE@ | ||
218 | CXXFLAGS = @CXXFLAGS@ | ||
219 | CYGPATH_W = @CYGPATH_W@ | ||
220 | DEFS = @DEFS@ | ||
221 | DEPDIR = @DEPDIR@ | ||
222 | DLLTOOL = @DLLTOOL@ | ||
223 | DSYMUTIL = @DSYMUTIL@ | ||
224 | DUMPBIN = @DUMPBIN@ | ||
225 | ECHO_C = @ECHO_C@ | ||
226 | ECHO_N = @ECHO_N@ | ||
227 | ECHO_T = @ECHO_T@ | ||
228 | ECORE_EVAS_CFLAGS = @ECORE_EVAS_CFLAGS@ | ||
229 | ECORE_EVAS_LIBS = @ECORE_EVAS_LIBS@ | ||
230 | EFL_COVERAGE_CFLAGS = @EFL_COVERAGE_CFLAGS@ | ||
231 | EFL_COVERAGE_LIBS = @EFL_COVERAGE_LIBS@ | ||
232 | EFL_EINA_BUILD = @EFL_EINA_BUILD@ | ||
233 | EFL_FNMATCH_LIBS = @EFL_FNMATCH_LIBS@ | ||
234 | EFL_PTHREAD_CFLAGS = @EFL_PTHREAD_CFLAGS@ | ||
235 | EFL_PTHREAD_LIBS = @EFL_PTHREAD_LIBS@ | ||
236 | EFL_SIMD_FLAGS = @EFL_SIMD_FLAGS@ | ||
237 | EGREP = @EGREP@ | ||
238 | EINA_CFLAGS = @EINA_CFLAGS@ | ||
239 | EINA_CONFIGURE_DEFAULT_MEMPOOL = @EINA_CONFIGURE_DEFAULT_MEMPOOL@ | ||
240 | EINA_CONFIGURE_ENABLE_LOG = @EINA_CONFIGURE_ENABLE_LOG@ | ||
241 | EINA_CONFIGURE_HAVE_DEBUG_THREADS = @EINA_CONFIGURE_HAVE_DEBUG_THREADS@ | ||
242 | EINA_CONFIGURE_HAVE_DIRENT_H = @EINA_CONFIGURE_HAVE_DIRENT_H@ | ||
243 | EINA_CONFIGURE_HAVE_EXOTIC = @EINA_CONFIGURE_HAVE_EXOTIC@ | ||
244 | EINA_CONFIGURE_HAVE_INTTYPES_H = @EINA_CONFIGURE_HAVE_INTTYPES_H@ | ||
245 | EINA_CONFIGURE_HAVE_ON_OFF_THREADS = @EINA_CONFIGURE_HAVE_ON_OFF_THREADS@ | ||
246 | EINA_CONFIGURE_HAVE_STDINT_H = @EINA_CONFIGURE_HAVE_STDINT_H@ | ||
247 | EINA_CONFIGURE_HAVE_THREADS = @EINA_CONFIGURE_HAVE_THREADS@ | ||
248 | EINA_CONFIGURE_MAGIC_DEBUG = @EINA_CONFIGURE_MAGIC_DEBUG@ | ||
249 | EINA_CONFIGURE_SAFETY_CHECKS = @EINA_CONFIGURE_SAFETY_CHECKS@ | ||
250 | EINA_LIBS = @EINA_LIBS@ | ||
251 | EINA_SIZEOF_WCHAR_T = @EINA_SIZEOF_WCHAR_T@ | ||
252 | EMEMOA_CFLAGS = @EMEMOA_CFLAGS@ | ||
253 | EMEMOA_LIBS = @EMEMOA_LIBS@ | ||
254 | ESCAPE_CFLAGS = @ESCAPE_CFLAGS@ | ||
255 | ESCAPE_LIBS = @ESCAPE_LIBS@ | ||
256 | EVIL_CFLAGS = @EVIL_CFLAGS@ | ||
257 | EVIL_LIBS = @EVIL_LIBS@ | ||
258 | EXEEXT = @EXEEXT@ | ||
259 | EXOTIC_CFLAGS = @EXOTIC_CFLAGS@ | ||
260 | EXOTIC_LIBS = @EXOTIC_LIBS@ | ||
261 | FGREP = @FGREP@ | ||
262 | GLIB_CFLAGS = @GLIB_CFLAGS@ | ||
263 | GLIB_LIBS = @GLIB_LIBS@ | ||
264 | GREP = @GREP@ | ||
265 | INSTALL = @INSTALL@ | ||
266 | INSTALL_DATA = @INSTALL_DATA@ | ||
267 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ | ||
268 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ | ||
269 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ | ||
270 | LD = @LD@ | ||
271 | LDFLAGS = @LDFLAGS@ | ||
272 | LIBOBJS = @LIBOBJS@ | ||
273 | LIBS = @LIBS@ | ||
274 | LIBTOOL = @LIBTOOL@ | ||
275 | LIPO = @LIPO@ | ||
276 | LN_S = @LN_S@ | ||
277 | LTLIBOBJS = @LTLIBOBJS@ | ||
278 | MAKEINFO = @MAKEINFO@ | ||
279 | MKDIR_P = @MKDIR_P@ | ||
280 | MODULE_ARCH = @MODULE_ARCH@ | ||
281 | NM = @NM@ | ||
282 | NMEDIT = @NMEDIT@ | ||
283 | OBJDUMP = @OBJDUMP@ | ||
284 | OBJEXT = @OBJEXT@ | ||
285 | OTOOL = @OTOOL@ | ||
286 | OTOOL64 = @OTOOL64@ | ||
287 | PACKAGE = @PACKAGE@ | ||
288 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ | ||
289 | PACKAGE_NAME = @PACKAGE_NAME@ | ||
290 | PACKAGE_STRING = @PACKAGE_STRING@ | ||
291 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ | ||
292 | PACKAGE_URL = @PACKAGE_URL@ | ||
293 | PACKAGE_VERSION = @PACKAGE_VERSION@ | ||
294 | PATH_SEPARATOR = @PATH_SEPARATOR@ | ||
295 | PKG_CONFIG = @PKG_CONFIG@ | ||
296 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ | ||
297 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ | ||
298 | RANLIB = @RANLIB@ | ||
299 | SED = @SED@ | ||
300 | SET_MAKE = @SET_MAKE@ | ||
301 | SHELL = @SHELL@ | ||
302 | STRIP = @STRIP@ | ||
303 | VALGRIND_CFLAGS = @VALGRIND_CFLAGS@ | ||
304 | VALGRIND_LIBS = @VALGRIND_LIBS@ | ||
305 | VERSION = @VERSION@ | ||
306 | VMAJ = @VMAJ@ | ||
307 | abs_builddir = @abs_builddir@ | ||
308 | abs_srcdir = @abs_srcdir@ | ||
309 | abs_top_builddir = @abs_top_builddir@ | ||
310 | abs_top_srcdir = @abs_top_srcdir@ | ||
311 | ac_ct_CC = @ac_ct_CC@ | ||
312 | ac_ct_CXX = @ac_ct_CXX@ | ||
313 | ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ | ||
314 | am__include = @am__include@ | ||
315 | am__leading_dot = @am__leading_dot@ | ||
316 | am__quote = @am__quote@ | ||
317 | am__tar = @am__tar@ | ||
318 | am__untar = @am__untar@ | ||
319 | bindir = @bindir@ | ||
320 | build = @build@ | ||
321 | build_alias = @build_alias@ | ||
322 | build_cpu = @build_cpu@ | ||
323 | build_os = @build_os@ | ||
324 | build_vendor = @build_vendor@ | ||
325 | builddir = @builddir@ | ||
326 | datadir = @datadir@ | ||
327 | datarootdir = @datarootdir@ | ||
328 | dlopen_libs = @dlopen_libs@ | ||
329 | docdir = @docdir@ | ||
330 | dvidir = @dvidir@ | ||
331 | efl_doxygen = @efl_doxygen@ | ||
332 | efl_have_doxygen = @efl_have_doxygen@ | ||
333 | exec_prefix = @exec_prefix@ | ||
334 | have_lcov = @have_lcov@ | ||
335 | host = @host@ | ||
336 | host_alias = @host_alias@ | ||
337 | host_cpu = @host_cpu@ | ||
338 | host_os = @host_os@ | ||
339 | host_vendor = @host_vendor@ | ||
340 | htmldir = @htmldir@ | ||
341 | iconv_libs = @iconv_libs@ | ||
342 | includedir = @includedir@ | ||
343 | infodir = @infodir@ | ||
344 | install_sh = @install_sh@ | ||
345 | libdir = @libdir@ | ||
346 | libexecdir = @libexecdir@ | ||
347 | localedir = @localedir@ | ||
348 | localstatedir = @localstatedir@ | ||
349 | lt_ECHO = @lt_ECHO@ | ||
350 | lt_enable_auto_import = @lt_enable_auto_import@ | ||
351 | mandir = @mandir@ | ||
352 | mkdir_p = @mkdir_p@ | ||
353 | oldincludedir = @oldincludedir@ | ||
354 | pdfdir = @pdfdir@ | ||
355 | pkgconfig_requires_private = @pkgconfig_requires_private@ | ||
356 | prefix = @prefix@ | ||
357 | program_transform_name = @program_transform_name@ | ||
358 | psdir = @psdir@ | ||
359 | release_info = @release_info@ | ||
360 | requirement_eina = @requirement_eina@ | ||
361 | rt_libs = @rt_libs@ | ||
362 | sbindir = @sbindir@ | ||
363 | sharedstatedir = @sharedstatedir@ | ||
364 | srcdir = @srcdir@ | ||
365 | sysconfdir = @sysconfdir@ | ||
366 | target_alias = @target_alias@ | ||
367 | top_build_prefix = @top_build_prefix@ | ||
368 | top_builddir = @top_builddir@ | ||
369 | top_srcdir = @top_srcdir@ | ||
370 | version_info = @version_info@ | ||
371 | MAINTAINERCLEANFILES = Makefile.in | ||
372 | AM_CPPFLAGS = \ | ||
373 | -I$(top_srcdir)/src/include \ | ||
374 | -I$(top_builddir)/src/include \ | ||
375 | -DPACKAGE_BIN_DIR=\"$(bindir)\" \ | ||
376 | -DPACKAGE_LIB_DIR=\"$(libdir)\" \ | ||
377 | -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ | ||
378 | @EFL_EINA_BUILD@ \ | ||
379 | @VALGRIND_CFLAGS@ | ||
380 | |||
381 | base_sources = eina_accessor.c eina_array.c eina_benchmark.c \ | ||
382 | eina_binbuf.c eina_binshare.c eina_convert.c eina_counter.c \ | ||
383 | eina_cpu.c eina_error.c eina_fp.c eina_hamster.c eina_hash.c \ | ||
384 | eina_inarray.c eina_inlist.c eina_iterator.c eina_lalloc.c \ | ||
385 | eina_list.c eina_log.c eina_magic.c eina_main.c \ | ||
386 | eina_matrixsparse.c eina_mempool.c eina_mmap.c eina_model.c \ | ||
387 | eina_module.c eina_prefix.c eina_quadtree.c eina_rbtree.c \ | ||
388 | eina_rectangle.c eina_safety_checks.c eina_sched.c \ | ||
389 | eina_share_common.c eina_simple_xml_parser.c eina_str.c \ | ||
390 | eina_strbuf.c eina_strbuf_common.c eina_stringshare.c \ | ||
391 | eina_tiler.c eina_unicode.c eina_ustrbuf.c eina_ustringshare.c \ | ||
392 | eina_value.c eina_xattr.c $(am__append_1) $(am__append_2) \ | ||
393 | $(am__append_3) $(am__append_4) $(am__append_5) \ | ||
394 | $(am__append_6) $(am__append_7) $(am__append_8) \ | ||
395 | $(am__append_9) | ||
396 | EXTRA_DIST = \ | ||
397 | eina_share_common.h \ | ||
398 | eina_private.h \ | ||
399 | eina_strbuf_common.h \ | ||
400 | eina_strbuf_template_c.x \ | ||
401 | eina_binbuf_template_c.x | ||
402 | |||
403 | lib_LTLIBRARIES = libeina.la | ||
404 | @EINA_AMALGAMATION_TRUE@nodist_libeina_la_SOURCES = eina_amalgamation.c | ||
405 | @EINA_AMALGAMATION_FALSE@libeina_la_SOURCES = $(base_sources) | ||
406 | libeina_la_LIBADD = @iconv_libs@ @rt_libs@ @EINA_LIBS@ @dlopen_libs@ | ||
407 | libeina_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ @EFL_PTHREAD_LIBS@ | ||
408 | libeina_la_CFLAGS = @EINA_CFLAGS@ @EFL_PTHREAD_CFLAGS@ | ||
409 | all: all-am | ||
410 | |||
411 | .SUFFIXES: | ||
412 | .SUFFIXES: .c .lo .o .obj | ||
413 | $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) | ||
414 | @for dep in $?; do \ | ||
415 | case '$(am__configure_deps)' in \ | ||
416 | *$$dep*) \ | ||
417 | ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ | ||
418 | && { if test -f $@; then exit 0; else break; fi; }; \ | ||
419 | exit 1;; \ | ||
420 | esac; \ | ||
421 | done; \ | ||
422 | echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/lib/Makefile'; \ | ||
423 | $(am__cd) $(top_srcdir) && \ | ||
424 | $(AUTOMAKE) --gnu src/lib/Makefile | ||
425 | .PRECIOUS: Makefile | ||
426 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status | ||
427 | @case '$?' in \ | ||
428 | *config.status*) \ | ||
429 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ | ||
430 | *) \ | ||
431 | echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ | ||
432 | cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ | ||
433 | esac; | ||
434 | |||
435 | $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) | ||
436 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
437 | |||
438 | $(top_srcdir)/configure: $(am__configure_deps) | ||
439 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
440 | $(ACLOCAL_M4): $(am__aclocal_m4_deps) | ||
441 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
442 | $(am__aclocal_m4_deps): | ||
443 | install-libLTLIBRARIES: $(lib_LTLIBRARIES) | ||
444 | @$(NORMAL_INSTALL) | ||
445 | test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" | ||
446 | @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ | ||
447 | list2=; for p in $$list; do \ | ||
448 | if test -f $$p; then \ | ||
449 | list2="$$list2 $$p"; \ | ||
450 | else :; fi; \ | ||
451 | done; \ | ||
452 | test -z "$$list2" || { \ | ||
453 | echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ | ||
454 | $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ | ||
455 | } | ||
456 | |||
457 | uninstall-libLTLIBRARIES: | ||
458 | @$(NORMAL_UNINSTALL) | ||
459 | @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ | ||
460 | for p in $$list; do \ | ||
461 | $(am__strip_dir) \ | ||
462 | echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ | ||
463 | $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ | ||
464 | done | ||
465 | |||
466 | clean-libLTLIBRARIES: | ||
467 | -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) | ||
468 | @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ | ||
469 | dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ | ||
470 | test "$$dir" != "$$p" || dir=.; \ | ||
471 | echo "rm -f \"$${dir}/so_locations\""; \ | ||
472 | rm -f "$${dir}/so_locations"; \ | ||
473 | done | ||
474 | libeina.la: $(libeina_la_OBJECTS) $(libeina_la_DEPENDENCIES) | ||
475 | $(AM_V_CCLD)$(libeina_la_LINK) -rpath $(libdir) $(libeina_la_OBJECTS) $(libeina_la_LIBADD) $(LIBS) | ||
476 | |||
477 | mostlyclean-compile: | ||
478 | -rm -f *.$(OBJEXT) | ||
479 | |||
480 | distclean-compile: | ||
481 | -rm -f *.tab.c | ||
482 | |||
483 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_accessor.Plo@am__quote@ | ||
484 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_amalgamation.Plo@am__quote@ | ||
485 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_array.Plo@am__quote@ | ||
486 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_benchmark.Plo@am__quote@ | ||
487 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_binbuf.Plo@am__quote@ | ||
488 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_binshare.Plo@am__quote@ | ||
489 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_buddy.Plo@am__quote@ | ||
490 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_chained_mempool.Plo@am__quote@ | ||
491 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_convert.Plo@am__quote@ | ||
492 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_counter.Plo@am__quote@ | ||
493 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_cpu.Plo@am__quote@ | ||
494 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_ememoa_fixed.Plo@am__quote@ | ||
495 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_ememoa_unknown.Plo@am__quote@ | ||
496 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_error.Plo@am__quote@ | ||
497 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_file.Plo@am__quote@ | ||
498 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_file_win32.Plo@am__quote@ | ||
499 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_fixed_bitmap.Plo@am__quote@ | ||
500 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_fp.Plo@am__quote@ | ||
501 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_hamster.Plo@am__quote@ | ||
502 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_hash.Plo@am__quote@ | ||
503 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_inarray.Plo@am__quote@ | ||
504 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_inlist.Plo@am__quote@ | ||
505 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_iterator.Plo@am__quote@ | ||
506 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_lalloc.Plo@am__quote@ | ||
507 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_list.Plo@am__quote@ | ||
508 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_log.Plo@am__quote@ | ||
509 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_magic.Plo@am__quote@ | ||
510 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_main.Plo@am__quote@ | ||
511 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_matrixsparse.Plo@am__quote@ | ||
512 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_mempool.Plo@am__quote@ | ||
513 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_mmap.Plo@am__quote@ | ||
514 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_model.Plo@am__quote@ | ||
515 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_module.Plo@am__quote@ | ||
516 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_one_big.Plo@am__quote@ | ||
517 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_pass_through.Plo@am__quote@ | ||
518 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_prefix.Plo@am__quote@ | ||
519 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_quadtree.Plo@am__quote@ | ||
520 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_rbtree.Plo@am__quote@ | ||
521 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_rectangle.Plo@am__quote@ | ||
522 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_safety_checks.Plo@am__quote@ | ||
523 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_sched.Plo@am__quote@ | ||
524 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_share_common.Plo@am__quote@ | ||
525 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_simple_xml_parser.Plo@am__quote@ | ||
526 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_str.Plo@am__quote@ | ||
527 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_strbuf.Plo@am__quote@ | ||
528 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_strbuf_common.Plo@am__quote@ | ||
529 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_stringshare.Plo@am__quote@ | ||
530 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_tiler.Plo@am__quote@ | ||
531 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_unicode.Plo@am__quote@ | ||
532 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_ustrbuf.Plo@am__quote@ | ||
533 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_ustringshare.Plo@am__quote@ | ||
534 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_value.Plo@am__quote@ | ||
535 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_xattr.Plo@am__quote@ | ||
536 | |||
537 | .c.o: | ||
538 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< | ||
539 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po | ||
540 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
541 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ | ||
542 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
543 | @am__fastdepCC_FALSE@ $(COMPILE) -c $< | ||
544 | |||
545 | .c.obj: | ||
546 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` | ||
547 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po | ||
548 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
549 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ | ||
550 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
551 | @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` | ||
552 | |||
553 | .c.lo: | ||
554 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< | ||
555 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo | ||
556 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
557 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ | ||
558 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
559 | @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< | ||
560 | |||
561 | libeina_la-eina_accessor.lo: eina_accessor.c | ||
562 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_accessor.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_accessor.Tpo -c -o libeina_la-eina_accessor.lo `test -f 'eina_accessor.c' || echo '$(srcdir)/'`eina_accessor.c | ||
563 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_accessor.Tpo $(DEPDIR)/libeina_la-eina_accessor.Plo | ||
564 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
565 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_accessor.c' object='libeina_la-eina_accessor.lo' libtool=yes @AMDEPBACKSLASH@ | ||
566 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
567 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_accessor.lo `test -f 'eina_accessor.c' || echo '$(srcdir)/'`eina_accessor.c | ||
568 | |||
569 | libeina_la-eina_array.lo: eina_array.c | ||
570 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_array.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_array.Tpo -c -o libeina_la-eina_array.lo `test -f 'eina_array.c' || echo '$(srcdir)/'`eina_array.c | ||
571 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_array.Tpo $(DEPDIR)/libeina_la-eina_array.Plo | ||
572 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
573 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_array.c' object='libeina_la-eina_array.lo' libtool=yes @AMDEPBACKSLASH@ | ||
574 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
575 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_array.lo `test -f 'eina_array.c' || echo '$(srcdir)/'`eina_array.c | ||
576 | |||
577 | libeina_la-eina_benchmark.lo: eina_benchmark.c | ||
578 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_benchmark.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_benchmark.Tpo -c -o libeina_la-eina_benchmark.lo `test -f 'eina_benchmark.c' || echo '$(srcdir)/'`eina_benchmark.c | ||
579 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_benchmark.Tpo $(DEPDIR)/libeina_la-eina_benchmark.Plo | ||
580 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
581 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_benchmark.c' object='libeina_la-eina_benchmark.lo' libtool=yes @AMDEPBACKSLASH@ | ||
582 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
583 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_benchmark.lo `test -f 'eina_benchmark.c' || echo '$(srcdir)/'`eina_benchmark.c | ||
584 | |||
585 | libeina_la-eina_binbuf.lo: eina_binbuf.c | ||
586 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_binbuf.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_binbuf.Tpo -c -o libeina_la-eina_binbuf.lo `test -f 'eina_binbuf.c' || echo '$(srcdir)/'`eina_binbuf.c | ||
587 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_binbuf.Tpo $(DEPDIR)/libeina_la-eina_binbuf.Plo | ||
588 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
589 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_binbuf.c' object='libeina_la-eina_binbuf.lo' libtool=yes @AMDEPBACKSLASH@ | ||
590 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
591 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_binbuf.lo `test -f 'eina_binbuf.c' || echo '$(srcdir)/'`eina_binbuf.c | ||
592 | |||
593 | libeina_la-eina_binshare.lo: eina_binshare.c | ||
594 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_binshare.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_binshare.Tpo -c -o libeina_la-eina_binshare.lo `test -f 'eina_binshare.c' || echo '$(srcdir)/'`eina_binshare.c | ||
595 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_binshare.Tpo $(DEPDIR)/libeina_la-eina_binshare.Plo | ||
596 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
597 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_binshare.c' object='libeina_la-eina_binshare.lo' libtool=yes @AMDEPBACKSLASH@ | ||
598 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
599 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_binshare.lo `test -f 'eina_binshare.c' || echo '$(srcdir)/'`eina_binshare.c | ||
600 | |||
601 | libeina_la-eina_convert.lo: eina_convert.c | ||
602 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_convert.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_convert.Tpo -c -o libeina_la-eina_convert.lo `test -f 'eina_convert.c' || echo '$(srcdir)/'`eina_convert.c | ||
603 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_convert.Tpo $(DEPDIR)/libeina_la-eina_convert.Plo | ||
604 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
605 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_convert.c' object='libeina_la-eina_convert.lo' libtool=yes @AMDEPBACKSLASH@ | ||
606 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
607 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_convert.lo `test -f 'eina_convert.c' || echo '$(srcdir)/'`eina_convert.c | ||
608 | |||
609 | libeina_la-eina_counter.lo: eina_counter.c | ||
610 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_counter.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_counter.Tpo -c -o libeina_la-eina_counter.lo `test -f 'eina_counter.c' || echo '$(srcdir)/'`eina_counter.c | ||
611 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_counter.Tpo $(DEPDIR)/libeina_la-eina_counter.Plo | ||
612 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
613 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_counter.c' object='libeina_la-eina_counter.lo' libtool=yes @AMDEPBACKSLASH@ | ||
614 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
615 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_counter.lo `test -f 'eina_counter.c' || echo '$(srcdir)/'`eina_counter.c | ||
616 | |||
617 | libeina_la-eina_cpu.lo: eina_cpu.c | ||
618 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_cpu.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_cpu.Tpo -c -o libeina_la-eina_cpu.lo `test -f 'eina_cpu.c' || echo '$(srcdir)/'`eina_cpu.c | ||
619 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_cpu.Tpo $(DEPDIR)/libeina_la-eina_cpu.Plo | ||
620 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
621 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_cpu.c' object='libeina_la-eina_cpu.lo' libtool=yes @AMDEPBACKSLASH@ | ||
622 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
623 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_cpu.lo `test -f 'eina_cpu.c' || echo '$(srcdir)/'`eina_cpu.c | ||
624 | |||
625 | libeina_la-eina_error.lo: eina_error.c | ||
626 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_error.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_error.Tpo -c -o libeina_la-eina_error.lo `test -f 'eina_error.c' || echo '$(srcdir)/'`eina_error.c | ||
627 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_error.Tpo $(DEPDIR)/libeina_la-eina_error.Plo | ||
628 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
629 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_error.c' object='libeina_la-eina_error.lo' libtool=yes @AMDEPBACKSLASH@ | ||
630 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
631 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_error.lo `test -f 'eina_error.c' || echo '$(srcdir)/'`eina_error.c | ||
632 | |||
633 | libeina_la-eina_fp.lo: eina_fp.c | ||
634 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_fp.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_fp.Tpo -c -o libeina_la-eina_fp.lo `test -f 'eina_fp.c' || echo '$(srcdir)/'`eina_fp.c | ||
635 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_fp.Tpo $(DEPDIR)/libeina_la-eina_fp.Plo | ||
636 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
637 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_fp.c' object='libeina_la-eina_fp.lo' libtool=yes @AMDEPBACKSLASH@ | ||
638 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
639 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_fp.lo `test -f 'eina_fp.c' || echo '$(srcdir)/'`eina_fp.c | ||
640 | |||
641 | libeina_la-eina_hamster.lo: eina_hamster.c | ||
642 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_hamster.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_hamster.Tpo -c -o libeina_la-eina_hamster.lo `test -f 'eina_hamster.c' || echo '$(srcdir)/'`eina_hamster.c | ||
643 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_hamster.Tpo $(DEPDIR)/libeina_la-eina_hamster.Plo | ||
644 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
645 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_hamster.c' object='libeina_la-eina_hamster.lo' libtool=yes @AMDEPBACKSLASH@ | ||
646 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
647 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_hamster.lo `test -f 'eina_hamster.c' || echo '$(srcdir)/'`eina_hamster.c | ||
648 | |||
649 | libeina_la-eina_hash.lo: eina_hash.c | ||
650 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_hash.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_hash.Tpo -c -o libeina_la-eina_hash.lo `test -f 'eina_hash.c' || echo '$(srcdir)/'`eina_hash.c | ||
651 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_hash.Tpo $(DEPDIR)/libeina_la-eina_hash.Plo | ||
652 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
653 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_hash.c' object='libeina_la-eina_hash.lo' libtool=yes @AMDEPBACKSLASH@ | ||
654 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
655 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_hash.lo `test -f 'eina_hash.c' || echo '$(srcdir)/'`eina_hash.c | ||
656 | |||
657 | libeina_la-eina_inarray.lo: eina_inarray.c | ||
658 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_inarray.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_inarray.Tpo -c -o libeina_la-eina_inarray.lo `test -f 'eina_inarray.c' || echo '$(srcdir)/'`eina_inarray.c | ||
659 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_inarray.Tpo $(DEPDIR)/libeina_la-eina_inarray.Plo | ||
660 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
661 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_inarray.c' object='libeina_la-eina_inarray.lo' libtool=yes @AMDEPBACKSLASH@ | ||
662 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
663 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_inarray.lo `test -f 'eina_inarray.c' || echo '$(srcdir)/'`eina_inarray.c | ||
664 | |||
665 | libeina_la-eina_inlist.lo: eina_inlist.c | ||
666 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_inlist.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_inlist.Tpo -c -o libeina_la-eina_inlist.lo `test -f 'eina_inlist.c' || echo '$(srcdir)/'`eina_inlist.c | ||
667 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_inlist.Tpo $(DEPDIR)/libeina_la-eina_inlist.Plo | ||
668 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
669 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_inlist.c' object='libeina_la-eina_inlist.lo' libtool=yes @AMDEPBACKSLASH@ | ||
670 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
671 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_inlist.lo `test -f 'eina_inlist.c' || echo '$(srcdir)/'`eina_inlist.c | ||
672 | |||
673 | libeina_la-eina_iterator.lo: eina_iterator.c | ||
674 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_iterator.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_iterator.Tpo -c -o libeina_la-eina_iterator.lo `test -f 'eina_iterator.c' || echo '$(srcdir)/'`eina_iterator.c | ||
675 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_iterator.Tpo $(DEPDIR)/libeina_la-eina_iterator.Plo | ||
676 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
677 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_iterator.c' object='libeina_la-eina_iterator.lo' libtool=yes @AMDEPBACKSLASH@ | ||
678 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
679 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_iterator.lo `test -f 'eina_iterator.c' || echo '$(srcdir)/'`eina_iterator.c | ||
680 | |||
681 | libeina_la-eina_lalloc.lo: eina_lalloc.c | ||
682 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_lalloc.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_lalloc.Tpo -c -o libeina_la-eina_lalloc.lo `test -f 'eina_lalloc.c' || echo '$(srcdir)/'`eina_lalloc.c | ||
683 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_lalloc.Tpo $(DEPDIR)/libeina_la-eina_lalloc.Plo | ||
684 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
685 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_lalloc.c' object='libeina_la-eina_lalloc.lo' libtool=yes @AMDEPBACKSLASH@ | ||
686 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
687 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_lalloc.lo `test -f 'eina_lalloc.c' || echo '$(srcdir)/'`eina_lalloc.c | ||
688 | |||
689 | libeina_la-eina_list.lo: eina_list.c | ||
690 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_list.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_list.Tpo -c -o libeina_la-eina_list.lo `test -f 'eina_list.c' || echo '$(srcdir)/'`eina_list.c | ||
691 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_list.Tpo $(DEPDIR)/libeina_la-eina_list.Plo | ||
692 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
693 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_list.c' object='libeina_la-eina_list.lo' libtool=yes @AMDEPBACKSLASH@ | ||
694 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
695 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_list.lo `test -f 'eina_list.c' || echo '$(srcdir)/'`eina_list.c | ||
696 | |||
697 | libeina_la-eina_log.lo: eina_log.c | ||
698 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_log.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_log.Tpo -c -o libeina_la-eina_log.lo `test -f 'eina_log.c' || echo '$(srcdir)/'`eina_log.c | ||
699 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_log.Tpo $(DEPDIR)/libeina_la-eina_log.Plo | ||
700 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
701 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_log.c' object='libeina_la-eina_log.lo' libtool=yes @AMDEPBACKSLASH@ | ||
702 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
703 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_log.lo `test -f 'eina_log.c' || echo '$(srcdir)/'`eina_log.c | ||
704 | |||
705 | libeina_la-eina_magic.lo: eina_magic.c | ||
706 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_magic.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_magic.Tpo -c -o libeina_la-eina_magic.lo `test -f 'eina_magic.c' || echo '$(srcdir)/'`eina_magic.c | ||
707 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_magic.Tpo $(DEPDIR)/libeina_la-eina_magic.Plo | ||
708 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
709 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_magic.c' object='libeina_la-eina_magic.lo' libtool=yes @AMDEPBACKSLASH@ | ||
710 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
711 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_magic.lo `test -f 'eina_magic.c' || echo '$(srcdir)/'`eina_magic.c | ||
712 | |||
713 | libeina_la-eina_main.lo: eina_main.c | ||
714 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_main.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_main.Tpo -c -o libeina_la-eina_main.lo `test -f 'eina_main.c' || echo '$(srcdir)/'`eina_main.c | ||
715 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_main.Tpo $(DEPDIR)/libeina_la-eina_main.Plo | ||
716 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
717 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_main.c' object='libeina_la-eina_main.lo' libtool=yes @AMDEPBACKSLASH@ | ||
718 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
719 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_main.lo `test -f 'eina_main.c' || echo '$(srcdir)/'`eina_main.c | ||
720 | |||
721 | libeina_la-eina_matrixsparse.lo: eina_matrixsparse.c | ||
722 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_matrixsparse.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_matrixsparse.Tpo -c -o libeina_la-eina_matrixsparse.lo `test -f 'eina_matrixsparse.c' || echo '$(srcdir)/'`eina_matrixsparse.c | ||
723 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_matrixsparse.Tpo $(DEPDIR)/libeina_la-eina_matrixsparse.Plo | ||
724 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
725 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_matrixsparse.c' object='libeina_la-eina_matrixsparse.lo' libtool=yes @AMDEPBACKSLASH@ | ||
726 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
727 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_matrixsparse.lo `test -f 'eina_matrixsparse.c' || echo '$(srcdir)/'`eina_matrixsparse.c | ||
728 | |||
729 | libeina_la-eina_mempool.lo: eina_mempool.c | ||
730 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_mempool.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_mempool.Tpo -c -o libeina_la-eina_mempool.lo `test -f 'eina_mempool.c' || echo '$(srcdir)/'`eina_mempool.c | ||
731 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_mempool.Tpo $(DEPDIR)/libeina_la-eina_mempool.Plo | ||
732 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
733 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_mempool.c' object='libeina_la-eina_mempool.lo' libtool=yes @AMDEPBACKSLASH@ | ||
734 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
735 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_mempool.lo `test -f 'eina_mempool.c' || echo '$(srcdir)/'`eina_mempool.c | ||
736 | |||
737 | libeina_la-eina_mmap.lo: eina_mmap.c | ||
738 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_mmap.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_mmap.Tpo -c -o libeina_la-eina_mmap.lo `test -f 'eina_mmap.c' || echo '$(srcdir)/'`eina_mmap.c | ||
739 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_mmap.Tpo $(DEPDIR)/libeina_la-eina_mmap.Plo | ||
740 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
741 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_mmap.c' object='libeina_la-eina_mmap.lo' libtool=yes @AMDEPBACKSLASH@ | ||
742 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
743 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_mmap.lo `test -f 'eina_mmap.c' || echo '$(srcdir)/'`eina_mmap.c | ||
744 | |||
745 | libeina_la-eina_model.lo: eina_model.c | ||
746 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_model.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_model.Tpo -c -o libeina_la-eina_model.lo `test -f 'eina_model.c' || echo '$(srcdir)/'`eina_model.c | ||
747 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_model.Tpo $(DEPDIR)/libeina_la-eina_model.Plo | ||
748 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
749 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_model.c' object='libeina_la-eina_model.lo' libtool=yes @AMDEPBACKSLASH@ | ||
750 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
751 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_model.lo `test -f 'eina_model.c' || echo '$(srcdir)/'`eina_model.c | ||
752 | |||
753 | libeina_la-eina_module.lo: eina_module.c | ||
754 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_module.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_module.Tpo -c -o libeina_la-eina_module.lo `test -f 'eina_module.c' || echo '$(srcdir)/'`eina_module.c | ||
755 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_module.Tpo $(DEPDIR)/libeina_la-eina_module.Plo | ||
756 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
757 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_module.c' object='libeina_la-eina_module.lo' libtool=yes @AMDEPBACKSLASH@ | ||
758 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
759 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_module.lo `test -f 'eina_module.c' || echo '$(srcdir)/'`eina_module.c | ||
760 | |||
761 | libeina_la-eina_prefix.lo: eina_prefix.c | ||
762 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_prefix.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_prefix.Tpo -c -o libeina_la-eina_prefix.lo `test -f 'eina_prefix.c' || echo '$(srcdir)/'`eina_prefix.c | ||
763 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_prefix.Tpo $(DEPDIR)/libeina_la-eina_prefix.Plo | ||
764 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
765 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_prefix.c' object='libeina_la-eina_prefix.lo' libtool=yes @AMDEPBACKSLASH@ | ||
766 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
767 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_prefix.lo `test -f 'eina_prefix.c' || echo '$(srcdir)/'`eina_prefix.c | ||
768 | |||
769 | libeina_la-eina_quadtree.lo: eina_quadtree.c | ||
770 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_quadtree.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_quadtree.Tpo -c -o libeina_la-eina_quadtree.lo `test -f 'eina_quadtree.c' || echo '$(srcdir)/'`eina_quadtree.c | ||
771 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_quadtree.Tpo $(DEPDIR)/libeina_la-eina_quadtree.Plo | ||
772 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
773 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_quadtree.c' object='libeina_la-eina_quadtree.lo' libtool=yes @AMDEPBACKSLASH@ | ||
774 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
775 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_quadtree.lo `test -f 'eina_quadtree.c' || echo '$(srcdir)/'`eina_quadtree.c | ||
776 | |||
777 | libeina_la-eina_rbtree.lo: eina_rbtree.c | ||
778 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_rbtree.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_rbtree.Tpo -c -o libeina_la-eina_rbtree.lo `test -f 'eina_rbtree.c' || echo '$(srcdir)/'`eina_rbtree.c | ||
779 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_rbtree.Tpo $(DEPDIR)/libeina_la-eina_rbtree.Plo | ||
780 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
781 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_rbtree.c' object='libeina_la-eina_rbtree.lo' libtool=yes @AMDEPBACKSLASH@ | ||
782 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
783 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_rbtree.lo `test -f 'eina_rbtree.c' || echo '$(srcdir)/'`eina_rbtree.c | ||
784 | |||
785 | libeina_la-eina_rectangle.lo: eina_rectangle.c | ||
786 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_rectangle.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_rectangle.Tpo -c -o libeina_la-eina_rectangle.lo `test -f 'eina_rectangle.c' || echo '$(srcdir)/'`eina_rectangle.c | ||
787 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_rectangle.Tpo $(DEPDIR)/libeina_la-eina_rectangle.Plo | ||
788 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
789 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_rectangle.c' object='libeina_la-eina_rectangle.lo' libtool=yes @AMDEPBACKSLASH@ | ||
790 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
791 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_rectangle.lo `test -f 'eina_rectangle.c' || echo '$(srcdir)/'`eina_rectangle.c | ||
792 | |||
793 | libeina_la-eina_safety_checks.lo: eina_safety_checks.c | ||
794 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_safety_checks.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_safety_checks.Tpo -c -o libeina_la-eina_safety_checks.lo `test -f 'eina_safety_checks.c' || echo '$(srcdir)/'`eina_safety_checks.c | ||
795 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_safety_checks.Tpo $(DEPDIR)/libeina_la-eina_safety_checks.Plo | ||
796 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
797 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_safety_checks.c' object='libeina_la-eina_safety_checks.lo' libtool=yes @AMDEPBACKSLASH@ | ||
798 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
799 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_safety_checks.lo `test -f 'eina_safety_checks.c' || echo '$(srcdir)/'`eina_safety_checks.c | ||
800 | |||
801 | libeina_la-eina_sched.lo: eina_sched.c | ||
802 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_sched.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_sched.Tpo -c -o libeina_la-eina_sched.lo `test -f 'eina_sched.c' || echo '$(srcdir)/'`eina_sched.c | ||
803 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_sched.Tpo $(DEPDIR)/libeina_la-eina_sched.Plo | ||
804 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
805 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_sched.c' object='libeina_la-eina_sched.lo' libtool=yes @AMDEPBACKSLASH@ | ||
806 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
807 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_sched.lo `test -f 'eina_sched.c' || echo '$(srcdir)/'`eina_sched.c | ||
808 | |||
809 | libeina_la-eina_share_common.lo: eina_share_common.c | ||
810 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_share_common.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_share_common.Tpo -c -o libeina_la-eina_share_common.lo `test -f 'eina_share_common.c' || echo '$(srcdir)/'`eina_share_common.c | ||
811 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_share_common.Tpo $(DEPDIR)/libeina_la-eina_share_common.Plo | ||
812 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
813 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_share_common.c' object='libeina_la-eina_share_common.lo' libtool=yes @AMDEPBACKSLASH@ | ||
814 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
815 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_share_common.lo `test -f 'eina_share_common.c' || echo '$(srcdir)/'`eina_share_common.c | ||
816 | |||
817 | libeina_la-eina_simple_xml_parser.lo: eina_simple_xml_parser.c | ||
818 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_simple_xml_parser.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_simple_xml_parser.Tpo -c -o libeina_la-eina_simple_xml_parser.lo `test -f 'eina_simple_xml_parser.c' || echo '$(srcdir)/'`eina_simple_xml_parser.c | ||
819 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_simple_xml_parser.Tpo $(DEPDIR)/libeina_la-eina_simple_xml_parser.Plo | ||
820 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
821 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_simple_xml_parser.c' object='libeina_la-eina_simple_xml_parser.lo' libtool=yes @AMDEPBACKSLASH@ | ||
822 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
823 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_simple_xml_parser.lo `test -f 'eina_simple_xml_parser.c' || echo '$(srcdir)/'`eina_simple_xml_parser.c | ||
824 | |||
825 | libeina_la-eina_str.lo: eina_str.c | ||
826 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_str.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_str.Tpo -c -o libeina_la-eina_str.lo `test -f 'eina_str.c' || echo '$(srcdir)/'`eina_str.c | ||
827 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_str.Tpo $(DEPDIR)/libeina_la-eina_str.Plo | ||
828 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
829 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_str.c' object='libeina_la-eina_str.lo' libtool=yes @AMDEPBACKSLASH@ | ||
830 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
831 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_str.lo `test -f 'eina_str.c' || echo '$(srcdir)/'`eina_str.c | ||
832 | |||
833 | libeina_la-eina_strbuf.lo: eina_strbuf.c | ||
834 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_strbuf.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_strbuf.Tpo -c -o libeina_la-eina_strbuf.lo `test -f 'eina_strbuf.c' || echo '$(srcdir)/'`eina_strbuf.c | ||
835 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_strbuf.Tpo $(DEPDIR)/libeina_la-eina_strbuf.Plo | ||
836 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
837 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_strbuf.c' object='libeina_la-eina_strbuf.lo' libtool=yes @AMDEPBACKSLASH@ | ||
838 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
839 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_strbuf.lo `test -f 'eina_strbuf.c' || echo '$(srcdir)/'`eina_strbuf.c | ||
840 | |||
841 | libeina_la-eina_strbuf_common.lo: eina_strbuf_common.c | ||
842 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_strbuf_common.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_strbuf_common.Tpo -c -o libeina_la-eina_strbuf_common.lo `test -f 'eina_strbuf_common.c' || echo '$(srcdir)/'`eina_strbuf_common.c | ||
843 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_strbuf_common.Tpo $(DEPDIR)/libeina_la-eina_strbuf_common.Plo | ||
844 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
845 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_strbuf_common.c' object='libeina_la-eina_strbuf_common.lo' libtool=yes @AMDEPBACKSLASH@ | ||
846 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
847 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_strbuf_common.lo `test -f 'eina_strbuf_common.c' || echo '$(srcdir)/'`eina_strbuf_common.c | ||
848 | |||
849 | libeina_la-eina_stringshare.lo: eina_stringshare.c | ||
850 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_stringshare.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_stringshare.Tpo -c -o libeina_la-eina_stringshare.lo `test -f 'eina_stringshare.c' || echo '$(srcdir)/'`eina_stringshare.c | ||
851 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_stringshare.Tpo $(DEPDIR)/libeina_la-eina_stringshare.Plo | ||
852 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
853 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_stringshare.c' object='libeina_la-eina_stringshare.lo' libtool=yes @AMDEPBACKSLASH@ | ||
854 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
855 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_stringshare.lo `test -f 'eina_stringshare.c' || echo '$(srcdir)/'`eina_stringshare.c | ||
856 | |||
857 | libeina_la-eina_tiler.lo: eina_tiler.c | ||
858 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_tiler.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_tiler.Tpo -c -o libeina_la-eina_tiler.lo `test -f 'eina_tiler.c' || echo '$(srcdir)/'`eina_tiler.c | ||
859 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_tiler.Tpo $(DEPDIR)/libeina_la-eina_tiler.Plo | ||
860 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
861 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_tiler.c' object='libeina_la-eina_tiler.lo' libtool=yes @AMDEPBACKSLASH@ | ||
862 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
863 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_tiler.lo `test -f 'eina_tiler.c' || echo '$(srcdir)/'`eina_tiler.c | ||
864 | |||
865 | libeina_la-eina_unicode.lo: eina_unicode.c | ||
866 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_unicode.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_unicode.Tpo -c -o libeina_la-eina_unicode.lo `test -f 'eina_unicode.c' || echo '$(srcdir)/'`eina_unicode.c | ||
867 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_unicode.Tpo $(DEPDIR)/libeina_la-eina_unicode.Plo | ||
868 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
869 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_unicode.c' object='libeina_la-eina_unicode.lo' libtool=yes @AMDEPBACKSLASH@ | ||
870 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
871 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_unicode.lo `test -f 'eina_unicode.c' || echo '$(srcdir)/'`eina_unicode.c | ||
872 | |||
873 | libeina_la-eina_ustrbuf.lo: eina_ustrbuf.c | ||
874 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_ustrbuf.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_ustrbuf.Tpo -c -o libeina_la-eina_ustrbuf.lo `test -f 'eina_ustrbuf.c' || echo '$(srcdir)/'`eina_ustrbuf.c | ||
875 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_ustrbuf.Tpo $(DEPDIR)/libeina_la-eina_ustrbuf.Plo | ||
876 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
877 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_ustrbuf.c' object='libeina_la-eina_ustrbuf.lo' libtool=yes @AMDEPBACKSLASH@ | ||
878 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
879 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_ustrbuf.lo `test -f 'eina_ustrbuf.c' || echo '$(srcdir)/'`eina_ustrbuf.c | ||
880 | |||
881 | libeina_la-eina_ustringshare.lo: eina_ustringshare.c | ||
882 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_ustringshare.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_ustringshare.Tpo -c -o libeina_la-eina_ustringshare.lo `test -f 'eina_ustringshare.c' || echo '$(srcdir)/'`eina_ustringshare.c | ||
883 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_ustringshare.Tpo $(DEPDIR)/libeina_la-eina_ustringshare.Plo | ||
884 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
885 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_ustringshare.c' object='libeina_la-eina_ustringshare.lo' libtool=yes @AMDEPBACKSLASH@ | ||
886 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
887 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_ustringshare.lo `test -f 'eina_ustringshare.c' || echo '$(srcdir)/'`eina_ustringshare.c | ||
888 | |||
889 | libeina_la-eina_value.lo: eina_value.c | ||
890 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_value.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_value.Tpo -c -o libeina_la-eina_value.lo `test -f 'eina_value.c' || echo '$(srcdir)/'`eina_value.c | ||
891 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_value.Tpo $(DEPDIR)/libeina_la-eina_value.Plo | ||
892 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
893 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_value.c' object='libeina_la-eina_value.lo' libtool=yes @AMDEPBACKSLASH@ | ||
894 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
895 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_value.lo `test -f 'eina_value.c' || echo '$(srcdir)/'`eina_value.c | ||
896 | |||
897 | libeina_la-eina_xattr.lo: eina_xattr.c | ||
898 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_xattr.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_xattr.Tpo -c -o libeina_la-eina_xattr.lo `test -f 'eina_xattr.c' || echo '$(srcdir)/'`eina_xattr.c | ||
899 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_xattr.Tpo $(DEPDIR)/libeina_la-eina_xattr.Plo | ||
900 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
901 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_xattr.c' object='libeina_la-eina_xattr.lo' libtool=yes @AMDEPBACKSLASH@ | ||
902 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
903 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_xattr.lo `test -f 'eina_xattr.c' || echo '$(srcdir)/'`eina_xattr.c | ||
904 | |||
905 | libeina_la-eina_file_win32.lo: eina_file_win32.c | ||
906 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_file_win32.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_file_win32.Tpo -c -o libeina_la-eina_file_win32.lo `test -f 'eina_file_win32.c' || echo '$(srcdir)/'`eina_file_win32.c | ||
907 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_file_win32.Tpo $(DEPDIR)/libeina_la-eina_file_win32.Plo | ||
908 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
909 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_file_win32.c' object='libeina_la-eina_file_win32.lo' libtool=yes @AMDEPBACKSLASH@ | ||
910 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
911 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_file_win32.lo `test -f 'eina_file_win32.c' || echo '$(srcdir)/'`eina_file_win32.c | ||
912 | |||
913 | libeina_la-eina_file.lo: eina_file.c | ||
914 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_file.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_file.Tpo -c -o libeina_la-eina_file.lo `test -f 'eina_file.c' || echo '$(srcdir)/'`eina_file.c | ||
915 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_file.Tpo $(DEPDIR)/libeina_la-eina_file.Plo | ||
916 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
917 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_file.c' object='libeina_la-eina_file.lo' libtool=yes @AMDEPBACKSLASH@ | ||
918 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
919 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_file.lo `test -f 'eina_file.c' || echo '$(srcdir)/'`eina_file.c | ||
920 | |||
921 | libeina_la-eina_buddy.lo: $(top_srcdir)/src/modules/mp/buddy/eina_buddy.c | ||
922 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_buddy.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_buddy.Tpo -c -o libeina_la-eina_buddy.lo `test -f '$(top_srcdir)/src/modules/mp/buddy/eina_buddy.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/buddy/eina_buddy.c | ||
923 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_buddy.Tpo $(DEPDIR)/libeina_la-eina_buddy.Plo | ||
924 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
925 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/modules/mp/buddy/eina_buddy.c' object='libeina_la-eina_buddy.lo' libtool=yes @AMDEPBACKSLASH@ | ||
926 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
927 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_buddy.lo `test -f '$(top_srcdir)/src/modules/mp/buddy/eina_buddy.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/buddy/eina_buddy.c | ||
928 | |||
929 | libeina_la-eina_chained_mempool.lo: $(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c | ||
930 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_chained_mempool.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_chained_mempool.Tpo -c -o libeina_la-eina_chained_mempool.lo `test -f '$(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c | ||
931 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_chained_mempool.Tpo $(DEPDIR)/libeina_la-eina_chained_mempool.Plo | ||
932 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
933 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c' object='libeina_la-eina_chained_mempool.lo' libtool=yes @AMDEPBACKSLASH@ | ||
934 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
935 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_chained_mempool.lo `test -f '$(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c | ||
936 | |||
937 | libeina_la-eina_ememoa_fixed.lo: $(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c | ||
938 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_ememoa_fixed.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_ememoa_fixed.Tpo -c -o libeina_la-eina_ememoa_fixed.lo `test -f '$(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c | ||
939 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_ememoa_fixed.Tpo $(DEPDIR)/libeina_la-eina_ememoa_fixed.Plo | ||
940 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
941 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c' object='libeina_la-eina_ememoa_fixed.lo' libtool=yes @AMDEPBACKSLASH@ | ||
942 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
943 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_ememoa_fixed.lo `test -f '$(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c | ||
944 | |||
945 | libeina_la-eina_ememoa_unknown.lo: $(top_srcdir)/src/modules/mp/ememoa_unknown/eina_ememoa_unknown.c | ||
946 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_ememoa_unknown.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_ememoa_unknown.Tpo -c -o libeina_la-eina_ememoa_unknown.lo `test -f '$(top_srcdir)/src/modules/mp/ememoa_unknown/eina_ememoa_unknown.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/ememoa_unknown/eina_ememoa_unknown.c | ||
947 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_ememoa_unknown.Tpo $(DEPDIR)/libeina_la-eina_ememoa_unknown.Plo | ||
948 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
949 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/modules/mp/ememoa_unknown/eina_ememoa_unknown.c' object='libeina_la-eina_ememoa_unknown.lo' libtool=yes @AMDEPBACKSLASH@ | ||
950 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
951 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_ememoa_unknown.lo `test -f '$(top_srcdir)/src/modules/mp/ememoa_unknown/eina_ememoa_unknown.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/ememoa_unknown/eina_ememoa_unknown.c | ||
952 | |||
953 | libeina_la-eina_fixed_bitmap.lo: $(top_srcdir)/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c | ||
954 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_fixed_bitmap.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_fixed_bitmap.Tpo -c -o libeina_la-eina_fixed_bitmap.lo `test -f '$(top_srcdir)/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c | ||
955 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_fixed_bitmap.Tpo $(DEPDIR)/libeina_la-eina_fixed_bitmap.Plo | ||
956 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
957 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c' object='libeina_la-eina_fixed_bitmap.lo' libtool=yes @AMDEPBACKSLASH@ | ||
958 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
959 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_fixed_bitmap.lo `test -f '$(top_srcdir)/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c | ||
960 | |||
961 | libeina_la-eina_one_big.lo: $(top_srcdir)/src/modules/mp/one_big/eina_one_big.c | ||
962 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_one_big.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_one_big.Tpo -c -o libeina_la-eina_one_big.lo `test -f '$(top_srcdir)/src/modules/mp/one_big/eina_one_big.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/one_big/eina_one_big.c | ||
963 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_one_big.Tpo $(DEPDIR)/libeina_la-eina_one_big.Plo | ||
964 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
965 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/modules/mp/one_big/eina_one_big.c' object='libeina_la-eina_one_big.lo' libtool=yes @AMDEPBACKSLASH@ | ||
966 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
967 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_one_big.lo `test -f '$(top_srcdir)/src/modules/mp/one_big/eina_one_big.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/one_big/eina_one_big.c | ||
968 | |||
969 | libeina_la-eina_pass_through.lo: $(top_srcdir)/src/modules/mp/pass_through/eina_pass_through.c | ||
970 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_pass_through.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_pass_through.Tpo -c -o libeina_la-eina_pass_through.lo `test -f '$(top_srcdir)/src/modules/mp/pass_through/eina_pass_through.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/pass_through/eina_pass_through.c | ||
971 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_pass_through.Tpo $(DEPDIR)/libeina_la-eina_pass_through.Plo | ||
972 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
973 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/src/modules/mp/pass_through/eina_pass_through.c' object='libeina_la-eina_pass_through.lo' libtool=yes @AMDEPBACKSLASH@ | ||
974 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
975 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_pass_through.lo `test -f '$(top_srcdir)/src/modules/mp/pass_through/eina_pass_through.c' || echo '$(srcdir)/'`$(top_srcdir)/src/modules/mp/pass_through/eina_pass_through.c | ||
976 | |||
977 | libeina_la-eina_amalgamation.lo: eina_amalgamation.c | ||
978 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_amalgamation.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_amalgamation.Tpo -c -o libeina_la-eina_amalgamation.lo `test -f 'eina_amalgamation.c' || echo '$(srcdir)/'`eina_amalgamation.c | ||
979 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_amalgamation.Tpo $(DEPDIR)/libeina_la-eina_amalgamation.Plo | ||
980 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
981 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_amalgamation.c' object='libeina_la-eina_amalgamation.lo' libtool=yes @AMDEPBACKSLASH@ | ||
982 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
983 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_amalgamation.lo `test -f 'eina_amalgamation.c' || echo '$(srcdir)/'`eina_amalgamation.c | ||
984 | |||
985 | mostlyclean-libtool: | ||
986 | -rm -f *.lo | ||
987 | |||
988 | clean-libtool: | ||
989 | -rm -rf .libs _libs | ||
990 | |||
991 | ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) | ||
992 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
993 | unique=`for i in $$list; do \ | ||
994 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
995 | done | \ | ||
996 | $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ | ||
997 | END { if (nonempty) { for (i in files) print i; }; }'`; \ | ||
998 | mkid -fID $$unique | ||
999 | tags: TAGS | ||
1000 | |||
1001 | TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ | ||
1002 | $(TAGS_FILES) $(LISP) | ||
1003 | set x; \ | ||
1004 | here=`pwd`; \ | ||
1005 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
1006 | unique=`for i in $$list; do \ | ||
1007 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
1008 | done | \ | ||
1009 | $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ | ||
1010 | END { if (nonempty) { for (i in files) print i; }; }'`; \ | ||
1011 | shift; \ | ||
1012 | if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ | ||
1013 | test -n "$$unique" || unique=$$empty_fix; \ | ||
1014 | if test $$# -gt 0; then \ | ||
1015 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ | ||
1016 | "$$@" $$unique; \ | ||
1017 | else \ | ||
1018 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ | ||
1019 | $$unique; \ | ||
1020 | fi; \ | ||
1021 | fi | ||
1022 | ctags: CTAGS | ||
1023 | CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ | ||
1024 | $(TAGS_FILES) $(LISP) | ||
1025 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
1026 | unique=`for i in $$list; do \ | ||
1027 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
1028 | done | \ | ||
1029 | $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ | ||
1030 | END { if (nonempty) { for (i in files) print i; }; }'`; \ | ||
1031 | test -z "$(CTAGS_ARGS)$$unique" \ | ||
1032 | || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ | ||
1033 | $$unique | ||
1034 | |||
1035 | GTAGS: | ||
1036 | here=`$(am__cd) $(top_builddir) && pwd` \ | ||
1037 | && $(am__cd) $(top_srcdir) \ | ||
1038 | && gtags -i $(GTAGS_ARGS) "$$here" | ||
1039 | |||
1040 | distclean-tags: | ||
1041 | -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags | ||
1042 | |||
1043 | distdir: $(DISTFILES) | ||
1044 | @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ | ||
1045 | topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ | ||
1046 | list='$(DISTFILES)'; \ | ||
1047 | dist_files=`for file in $$list; do echo $$file; done | \ | ||
1048 | sed -e "s|^$$srcdirstrip/||;t" \ | ||
1049 | -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ | ||
1050 | case $$dist_files in \ | ||
1051 | */*) $(MKDIR_P) `echo "$$dist_files" | \ | ||
1052 | sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ | ||
1053 | sort -u` ;; \ | ||
1054 | esac; \ | ||
1055 | for file in $$dist_files; do \ | ||
1056 | if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ | ||
1057 | if test -d $$d/$$file; then \ | ||
1058 | dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ | ||
1059 | if test -d "$(distdir)/$$file"; then \ | ||
1060 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ | ||
1061 | fi; \ | ||
1062 | if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ | ||
1063 | cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ | ||
1064 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ | ||
1065 | fi; \ | ||
1066 | cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ | ||
1067 | else \ | ||
1068 | test -f "$(distdir)/$$file" \ | ||
1069 | || cp -p $$d/$$file "$(distdir)/$$file" \ | ||
1070 | || exit 1; \ | ||
1071 | fi; \ | ||
1072 | done | ||
1073 | check-am: all-am | ||
1074 | check: check-am | ||
1075 | all-am: Makefile $(LTLIBRARIES) | ||
1076 | installdirs: | ||
1077 | for dir in "$(DESTDIR)$(libdir)"; do \ | ||
1078 | test -z "$$dir" || $(MKDIR_P) "$$dir"; \ | ||
1079 | done | ||
1080 | install: install-am | ||
1081 | install-exec: install-exec-am | ||
1082 | install-data: install-data-am | ||
1083 | uninstall: uninstall-am | ||
1084 | |||
1085 | install-am: all-am | ||
1086 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | ||
1087 | |||
1088 | installcheck: installcheck-am | ||
1089 | install-strip: | ||
1090 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ | ||
1091 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ | ||
1092 | `test -z '$(STRIP)' || \ | ||
1093 | echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install | ||
1094 | mostlyclean-generic: | ||
1095 | |||
1096 | clean-generic: | ||
1097 | |||
1098 | distclean-generic: | ||
1099 | -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) | ||
1100 | -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) | ||
1101 | |||
1102 | maintainer-clean-generic: | ||
1103 | @echo "This command is intended for maintainers to use" | ||
1104 | @echo "it deletes files that may require special tools to rebuild." | ||
1105 | -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) | ||
1106 | clean: clean-am | ||
1107 | |||
1108 | clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ | ||
1109 | mostlyclean-am | ||
1110 | |||
1111 | distclean: distclean-am | ||
1112 | -rm -rf ./$(DEPDIR) | ||
1113 | -rm -f Makefile | ||
1114 | distclean-am: clean-am distclean-compile distclean-generic \ | ||
1115 | distclean-tags | ||
1116 | |||
1117 | dvi: dvi-am | ||
1118 | |||
1119 | dvi-am: | ||
1120 | |||
1121 | html: html-am | ||
1122 | |||
1123 | html-am: | ||
1124 | |||
1125 | info: info-am | ||
1126 | |||
1127 | info-am: | ||
1128 | |||
1129 | install-data-am: | ||
1130 | |||
1131 | install-dvi: install-dvi-am | ||
1132 | |||
1133 | install-dvi-am: | ||
1134 | |||
1135 | install-exec-am: install-libLTLIBRARIES | ||
1136 | |||
1137 | install-html: install-html-am | ||
1138 | |||
1139 | install-html-am: | ||
1140 | |||
1141 | install-info: install-info-am | ||
1142 | |||
1143 | install-info-am: | ||
1144 | |||
1145 | install-man: | ||
1146 | |||
1147 | install-pdf: install-pdf-am | ||
1148 | |||
1149 | install-pdf-am: | ||
1150 | |||
1151 | install-ps: install-ps-am | ||
1152 | |||
1153 | install-ps-am: | ||
1154 | |||
1155 | installcheck-am: | ||
1156 | |||
1157 | maintainer-clean: maintainer-clean-am | ||
1158 | -rm -rf ./$(DEPDIR) | ||
1159 | -rm -f Makefile | ||
1160 | maintainer-clean-am: distclean-am maintainer-clean-generic | ||
1161 | |||
1162 | mostlyclean: mostlyclean-am | ||
1163 | |||
1164 | mostlyclean-am: mostlyclean-compile mostlyclean-generic \ | ||
1165 | mostlyclean-libtool | ||
1166 | |||
1167 | pdf: pdf-am | ||
1168 | |||
1169 | pdf-am: | ||
1170 | |||
1171 | ps: ps-am | ||
1172 | |||
1173 | ps-am: | ||
1174 | |||
1175 | uninstall-am: uninstall-libLTLIBRARIES | ||
1176 | |||
1177 | .MAKE: install-am install-strip | ||
1178 | |||
1179 | .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ | ||
1180 | clean-libLTLIBRARIES clean-libtool clean-local ctags distclean \ | ||
1181 | distclean-compile distclean-generic distclean-libtool \ | ||
1182 | distclean-tags distdir dvi dvi-am html html-am info info-am \ | ||
1183 | install install-am install-data install-data-am install-dvi \ | ||
1184 | install-dvi-am install-exec install-exec-am install-html \ | ||
1185 | install-html-am install-info install-info-am \ | ||
1186 | install-libLTLIBRARIES install-man install-pdf install-pdf-am \ | ||
1187 | install-ps install-ps-am install-strip installcheck \ | ||
1188 | installcheck-am installdirs maintainer-clean \ | ||
1189 | maintainer-clean-generic mostlyclean mostlyclean-compile \ | ||
1190 | mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ | ||
1191 | tags uninstall uninstall-am uninstall-libLTLIBRARIES | ||
1192 | |||
1193 | |||
1194 | @EINA_AMALGAMATION_TRUE@eina_amalgamation.c: $(base_sources) Makefile | ||
1195 | @EINA_AMALGAMATION_TRUE@ -rm -f eina_amalgamation.c | ||
1196 | |||
1197 | @EINA_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_CONFIG_H" >> eina_amalgamation.c | ||
1198 | @EINA_AMALGAMATION_TRUE@ @echo "#include \"config.h\"" >> eina_amalgamation.c | ||
1199 | @EINA_AMALGAMATION_TRUE@ @echo "#endif" >> eina_amalgamation.c | ||
1200 | |||
1201 | @EINA_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_ALLOCA_H" >> eina_amalgamation.c | ||
1202 | @EINA_AMALGAMATION_TRUE@ @echo "# include <alloca.h>" >> eina_amalgamation.c | ||
1203 | @EINA_AMALGAMATION_TRUE@ @echo "#elif defined __GNUC__" >> eina_amalgamation.c | ||
1204 | @EINA_AMALGAMATION_TRUE@ @echo "# define alloca __builtin_alloca" >> eina_amalgamation.c | ||
1205 | @EINA_AMALGAMATION_TRUE@ @echo "#elif defined _AIX" >> eina_amalgamation.c | ||
1206 | @EINA_AMALGAMATION_TRUE@ @echo "# define alloca __alloca" >> eina_amalgamation.c | ||
1207 | @EINA_AMALGAMATION_TRUE@ @echo "#elif defined _MSC_VER" >> eina_amalgamation.c | ||
1208 | @EINA_AMALGAMATION_TRUE@ @echo "# include <malloc.h>" >> eina_amalgamation.c | ||
1209 | @EINA_AMALGAMATION_TRUE@ @echo "# define alloca _alloca" >> eina_amalgamation.c | ||
1210 | @EINA_AMALGAMATION_TRUE@ @echo "#else" >> eina_amalgamation.c | ||
1211 | @EINA_AMALGAMATION_TRUE@ @echo "# include <stddef.h>" >> eina_amalgamation.c | ||
1212 | @EINA_AMALGAMATION_TRUE@ @echo "# ifdef __cplusplus" >> eina_amalgamation.c | ||
1213 | @EINA_AMALGAMATION_TRUE@ @echo "#extern \"C\"" >> eina_amalgamation.c | ||
1214 | @EINA_AMALGAMATION_TRUE@ @echo "# endif" >> eina_amalgamation.c | ||
1215 | @EINA_AMALGAMATION_TRUE@ @echo "#void *alloca (size_t);" >> eina_amalgamation.c | ||
1216 | @EINA_AMALGAMATION_TRUE@ @echo "#endif" >> eina_amalgamation.c | ||
1217 | |||
1218 | @EINA_AMALGAMATION_TRUE@ @echo "#include <stdio.h>" >> eina_amalgamation.c | ||
1219 | @EINA_AMALGAMATION_TRUE@ @echo "#include <stdlib.h>" >> eina_amalgamation.c | ||
1220 | @EINA_AMALGAMATION_TRUE@ @echo "#include <string.h>" >> eina_amalgamation.c | ||
1221 | @EINA_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_DLOPEN" >> eina_amalgamation.c | ||
1222 | @EINA_AMALGAMATION_TRUE@ @echo "# include <dlfcn.h>" >> eina_amalgamation.c | ||
1223 | @EINA_AMALGAMATION_TRUE@ @echo "#endif" >> eina_amalgamation.c | ||
1224 | @EINA_AMALGAMATION_TRUE@ @echo "#include <sys/types.h>" >> eina_amalgamation.c | ||
1225 | @EINA_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_DIRENT_H" >> eina_amalgamation.c | ||
1226 | @EINA_AMALGAMATION_TRUE@ @echo "# include <dirent.h>" >> eina_amalgamation.c | ||
1227 | @EINA_AMALGAMATION_TRUE@ @echo "#endif" >> eina_amalgamation.c | ||
1228 | @EINA_AMALGAMATION_TRUE@ @echo "#include <assert.h>" >> eina_amalgamation.c | ||
1229 | @EINA_AMALGAMATION_TRUE@ @echo "#include <errno.h>" >> eina_amalgamation.c | ||
1230 | @EINA_AMALGAMATION_TRUE@ @echo "#include <fnmatch.h>" >> eina_amalgamation.c | ||
1231 | @EINA_AMALGAMATION_TRUE@ @echo "#include <fcntl.h>" >> eina_amalgamation.c | ||
1232 | |||
1233 | @EINA_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_EVIL" >> eina_amalgamation.c | ||
1234 | @EINA_AMALGAMATION_TRUE@ @echo "# include <Evil.h>" >> eina_amalgamation.c | ||
1235 | @EINA_AMALGAMATION_TRUE@ @echo "#endif" >> eina_amalgamation.c | ||
1236 | |||
1237 | @EINA_AMALGAMATION_TRUE@ @echo "#include \"eina_config.h\"" >> eina_amalgamation.c | ||
1238 | @EINA_AMALGAMATION_TRUE@ @echo "#include \"eina_private.h\"" >> eina_amalgamation.c | ||
1239 | @EINA_AMALGAMATION_TRUE@ @echo "#include \"eina_safety_checks.h\"" >> eina_amalgamation.c | ||
1240 | @EINA_AMALGAMATION_TRUE@ @echo "#include \"Eina.h\"" >> eina_amalgamation.c | ||
1241 | @EINA_AMALGAMATION_TRUE@ @echo "#include \"eina_strbuf_common.h\"" >> eina_amalgamation.c | ||
1242 | @EINA_AMALGAMATION_TRUE@ @echo "#include \"eina_share_common.h\"" >> eina_amalgamation.c | ||
1243 | |||
1244 | @EINA_AMALGAMATION_TRUE@ @for f in $(base_sources); do \ | ||
1245 | @EINA_AMALGAMATION_TRUE@ if [ `echo $$f | sed -e 's/^...\(.\).*/\1/'` != '/' ]; then \ | ||
1246 | @EINA_AMALGAMATION_TRUE@ file="$(srcdir)/$$f" ; \ | ||
1247 | @EINA_AMALGAMATION_TRUE@ else \ | ||
1248 | @EINA_AMALGAMATION_TRUE@ file="$$f" ; \ | ||
1249 | @EINA_AMALGAMATION_TRUE@ fi ; \ | ||
1250 | @EINA_AMALGAMATION_TRUE@ echo "/* file: $$file */" >> eina_amalgamation.c; \ | ||
1251 | @EINA_AMALGAMATION_TRUE@ grep -v -e '^# *include \+.\(config\|eina_[a-z_]\+\|Evil\|stdio\|stdlib\|string\|dlfcn\|dirent\|assert\|errno\|fnmatch\)[.]h.*' $$file >> eina_amalgamation.c; \ | ||
1252 | @EINA_AMALGAMATION_TRUE@ done | ||
1253 | @EINA_AMALGAMATION_TRUE@ @echo "eina_amalgamation.c generated" | ||
1254 | |||
1255 | clean-local: | ||
1256 | rm -rf *.gcno eina_amalgamation.c | ||
1257 | |||
1258 | # Tell versions [3.59,3.63) of GNU make to not export all variables. | ||
1259 | # Otherwise a system limit (for SysV at least) may be exceeded. | ||
1260 | .NOEXPORT: | ||
diff --git a/libraries/eina/src/lib/eina_accessor.c b/libraries/eina/src/lib/eina_accessor.c deleted file mode 100644 index aec44ef..0000000 --- a/libraries/eina/src/lib/eina_accessor.c +++ /dev/null | |||
@@ -1,176 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2002-2008 Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdlib.h> | ||
24 | |||
25 | #include "eina_config.h" | ||
26 | #include "eina_private.h" | ||
27 | |||
28 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
29 | #include "eina_safety_checks.h" | ||
30 | #include "eina_accessor.h" | ||
31 | |||
32 | /*============================================================================* | ||
33 | * Local * | ||
34 | *============================================================================*/ | ||
35 | |||
36 | /** | ||
37 | * @cond LOCAL | ||
38 | */ | ||
39 | |||
40 | static const char EINA_MAGIC_ACCESSOR_STR[] = "Eina Accessor"; | ||
41 | |||
42 | #define EINA_MAGIC_CHECK_ACCESSOR(d) \ | ||
43 | do { \ | ||
44 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ACCESSOR)) { \ | ||
45 | EINA_MAGIC_FAIL(d, EINA_MAGIC_ACCESSOR); } \ | ||
46 | } while(0) | ||
47 | |||
48 | /** | ||
49 | * @endcond | ||
50 | */ | ||
51 | |||
52 | /*============================================================================* | ||
53 | * Global * | ||
54 | *============================================================================*/ | ||
55 | |||
56 | /** | ||
57 | * @internal | ||
58 | * @brief Initialize the accessor module. | ||
59 | * | ||
60 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
61 | * | ||
62 | * This function sets up the accessor module of Eina. It is called by | ||
63 | * eina_init(). | ||
64 | * | ||
65 | * @see eina_init() | ||
66 | */ | ||
67 | Eina_Bool | ||
68 | eina_accessor_init(void) | ||
69 | { | ||
70 | return eina_magic_string_set(EINA_MAGIC_ACCESSOR, EINA_MAGIC_ACCESSOR_STR); | ||
71 | } | ||
72 | |||
73 | /** | ||
74 | * @internal | ||
75 | * @brief Shut down the accessor module. | ||
76 | * | ||
77 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
78 | * | ||
79 | * This function shuts down the accessor module set up by | ||
80 | * eina_accessor_init(). It is called by eina_shutdown(). | ||
81 | * | ||
82 | * @see eina_shutdown() | ||
83 | */ | ||
84 | Eina_Bool | ||
85 | eina_accessor_shutdown(void) | ||
86 | { | ||
87 | return EINA_TRUE; | ||
88 | } | ||
89 | |||
90 | /*============================================================================* | ||
91 | * API * | ||
92 | *============================================================================*/ | ||
93 | |||
94 | |||
95 | EAPI void | ||
96 | eina_accessor_free(Eina_Accessor *accessor) | ||
97 | { | ||
98 | EINA_MAGIC_CHECK_ACCESSOR(accessor); | ||
99 | EINA_SAFETY_ON_NULL_RETURN(accessor); | ||
100 | EINA_SAFETY_ON_NULL_RETURN(accessor->free); | ||
101 | accessor->free(accessor); | ||
102 | } | ||
103 | |||
104 | EAPI void * | ||
105 | eina_accessor_container_get(Eina_Accessor *accessor) | ||
106 | { | ||
107 | EINA_MAGIC_CHECK_ACCESSOR(accessor); | ||
108 | EINA_SAFETY_ON_NULL_RETURN_VAL(accessor, NULL); | ||
109 | EINA_SAFETY_ON_NULL_RETURN_VAL(accessor->get_container, NULL); | ||
110 | return accessor->get_container(accessor); | ||
111 | } | ||
112 | |||
113 | EAPI Eina_Bool | ||
114 | eina_accessor_data_get(Eina_Accessor *accessor, | ||
115 | unsigned int position, | ||
116 | void **data) | ||
117 | { | ||
118 | EINA_MAGIC_CHECK_ACCESSOR(accessor); | ||
119 | EINA_SAFETY_ON_NULL_RETURN_VAL(accessor, EINA_FALSE); | ||
120 | EINA_SAFETY_ON_NULL_RETURN_VAL(accessor->get_at, EINA_FALSE); | ||
121 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); | ||
122 | return accessor->get_at(accessor, position, data); | ||
123 | } | ||
124 | |||
125 | EAPI void | ||
126 | eina_accessor_over(Eina_Accessor *accessor, | ||
127 | Eina_Each_Cb cb, | ||
128 | unsigned int start, | ||
129 | unsigned int end, | ||
130 | const void *fdata) | ||
131 | { | ||
132 | const void *container; | ||
133 | void *data; | ||
134 | unsigned int i; | ||
135 | |||
136 | EINA_MAGIC_CHECK_ACCESSOR(accessor); | ||
137 | EINA_SAFETY_ON_NULL_RETURN(accessor); | ||
138 | EINA_SAFETY_ON_NULL_RETURN(accessor->get_container); | ||
139 | EINA_SAFETY_ON_NULL_RETURN(accessor->get_at); | ||
140 | EINA_SAFETY_ON_NULL_RETURN(cb); | ||
141 | EINA_SAFETY_ON_FALSE_RETURN(start < end); | ||
142 | |||
143 | if (!eina_accessor_lock(accessor)) | ||
144 | return ; | ||
145 | |||
146 | container = accessor->get_container(accessor); | ||
147 | for (i = start; i < end && accessor->get_at(accessor, i, &data) == EINA_TRUE; | ||
148 | ++i) | ||
149 | if (cb(container, data, (void *)fdata) != EINA_TRUE) | ||
150 | goto on_exit; | ||
151 | |||
152 | on_exit: | ||
153 | (void) eina_accessor_unlock(accessor); | ||
154 | } | ||
155 | |||
156 | EAPI Eina_Bool | ||
157 | eina_accessor_lock(Eina_Accessor *accessor) | ||
158 | { | ||
159 | EINA_MAGIC_CHECK_ACCESSOR(accessor); | ||
160 | EINA_SAFETY_ON_NULL_RETURN_VAL(accessor, EINA_FALSE); | ||
161 | |||
162 | if (accessor->lock) | ||
163 | return accessor->lock(accessor); | ||
164 | return EINA_TRUE; | ||
165 | } | ||
166 | |||
167 | EAPI Eina_Bool | ||
168 | eina_accessor_unlock(Eina_Accessor *accessor) | ||
169 | { | ||
170 | EINA_MAGIC_CHECK_ACCESSOR(accessor); | ||
171 | EINA_SAFETY_ON_NULL_RETURN_VAL(accessor, EINA_FALSE); | ||
172 | |||
173 | if (accessor->unlock) | ||
174 | return accessor->unlock(accessor); | ||
175 | return EINA_TRUE; | ||
176 | } | ||
diff --git a/libraries/eina/src/lib/eina_array.c b/libraries/eina/src/lib/eina_array.c deleted file mode 100644 index 4bcab61..0000000 --- a/libraries/eina/src/lib/eina_array.c +++ /dev/null | |||
@@ -1,491 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | |||
20 | #ifdef HAVE_CONFIG_H | ||
21 | # include "config.h" | ||
22 | #endif | ||
23 | |||
24 | #include <assert.h> | ||
25 | #include <stdlib.h> | ||
26 | #include <string.h> | ||
27 | #include <stdio.h> | ||
28 | |||
29 | #include "eina_config.h" | ||
30 | #include "eina_private.h" | ||
31 | #include "eina_error.h" | ||
32 | #include "eina_log.h" | ||
33 | |||
34 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
35 | #include "eina_safety_checks.h" | ||
36 | #include "eina_array.h" | ||
37 | |||
38 | /*============================================================================* | ||
39 | * Local * | ||
40 | *============================================================================*/ | ||
41 | |||
42 | /** | ||
43 | * @cond LOCAL | ||
44 | */ | ||
45 | |||
46 | static const char EINA_MAGIC_ARRAY_STR[] = "Eina Array"; | ||
47 | static const char EINA_MAGIC_ARRAY_ITERATOR_STR[] = "Eina Array Iterator"; | ||
48 | static const char EINA_MAGIC_ARRAY_ACCESSOR_STR[] = "Eina Array Accessor"; | ||
49 | |||
50 | #define EINA_MAGIC_CHECK_ARRAY(d) \ | ||
51 | do { \ | ||
52 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ARRAY)) { \ | ||
53 | EINA_MAGIC_FAIL(d, EINA_MAGIC_ARRAY); } \ | ||
54 | } while (0) | ||
55 | |||
56 | #define EINA_MAGIC_CHECK_ARRAY_ITERATOR(d, ...) \ | ||
57 | do { \ | ||
58 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ARRAY_ITERATOR)) \ | ||
59 | { \ | ||
60 | EINA_MAGIC_FAIL(d, EINA_MAGIC_ARRAY_ITERATOR); \ | ||
61 | return __VA_ARGS__; \ | ||
62 | } \ | ||
63 | } while (0) | ||
64 | |||
65 | #define EINA_MAGIC_CHECK_ARRAY_ACCESSOR(d, ...) \ | ||
66 | do { \ | ||
67 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ARRAY_ACCESSOR)) \ | ||
68 | { \ | ||
69 | EINA_MAGIC_FAIL(d, EINA_MAGIC_ACCESSOR); \ | ||
70 | return __VA_ARGS__; \ | ||
71 | } \ | ||
72 | } while (0) | ||
73 | |||
74 | |||
75 | typedef struct _Eina_Iterator_Array Eina_Iterator_Array; | ||
76 | struct _Eina_Iterator_Array | ||
77 | { | ||
78 | Eina_Iterator iterator; | ||
79 | |||
80 | const Eina_Array *array; | ||
81 | unsigned int index; | ||
82 | |||
83 | EINA_MAGIC | ||
84 | }; | ||
85 | |||
86 | typedef struct _Eina_Accessor_Array Eina_Accessor_Array; | ||
87 | struct _Eina_Accessor_Array | ||
88 | { | ||
89 | Eina_Accessor accessor; | ||
90 | const Eina_Array *array; | ||
91 | EINA_MAGIC | ||
92 | }; | ||
93 | |||
94 | static int _eina_array_log_dom = -1; | ||
95 | |||
96 | #ifdef ERR | ||
97 | #undef ERR | ||
98 | #endif | ||
99 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_array_log_dom, __VA_ARGS__) | ||
100 | |||
101 | #ifdef DBG | ||
102 | #undef DBG | ||
103 | #endif | ||
104 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_array_log_dom, __VA_ARGS__) | ||
105 | |||
106 | static void eina_array_iterator_free(Eina_Iterator_Array *it) EINA_ARG_NONNULL(1); | ||
107 | static Eina_Array *eina_array_iterator_get_container(Eina_Iterator_Array *it) EINA_ARG_NONNULL(1); | ||
108 | static Eina_Bool eina_array_iterator_next(Eina_Iterator_Array *it, | ||
109 | void **data) EINA_ARG_NONNULL(1); | ||
110 | |||
111 | static Eina_Bool eina_array_accessor_get_at(Eina_Accessor_Array *it, | ||
112 | unsigned int idx, | ||
113 | void **data) EINA_ARG_NONNULL(1); | ||
114 | static Eina_Array *eina_array_accessor_get_container(Eina_Accessor_Array *it) EINA_ARG_NONNULL(1); | ||
115 | static void eina_array_accessor_free(Eina_Accessor_Array *it) EINA_ARG_NONNULL(1); | ||
116 | |||
117 | static Eina_Bool | ||
118 | eina_array_iterator_next(Eina_Iterator_Array *it, void **data) | ||
119 | { | ||
120 | EINA_MAGIC_CHECK_ARRAY_ITERATOR(it, EINA_FALSE); | ||
121 | |||
122 | if (!(it->index < eina_array_count(it->array))) | ||
123 | return EINA_FALSE; | ||
124 | |||
125 | if (data) | ||
126 | *data = eina_array_data_get(it->array, it->index); | ||
127 | |||
128 | it->index++; | ||
129 | return EINA_TRUE; | ||
130 | } | ||
131 | |||
132 | static Eina_Array * | ||
133 | eina_array_iterator_get_container(Eina_Iterator_Array *it) | ||
134 | { | ||
135 | EINA_MAGIC_CHECK_ARRAY_ITERATOR(it, NULL); | ||
136 | return (Eina_Array *)it->array; | ||
137 | } | ||
138 | |||
139 | static void | ||
140 | eina_array_iterator_free(Eina_Iterator_Array *it) | ||
141 | { | ||
142 | EINA_MAGIC_CHECK_ARRAY_ITERATOR(it); | ||
143 | MAGIC_FREE(it); | ||
144 | } | ||
145 | |||
146 | static Eina_Bool | ||
147 | eina_array_accessor_get_at(Eina_Accessor_Array *it, | ||
148 | unsigned int idx, | ||
149 | void **data) | ||
150 | { | ||
151 | EINA_MAGIC_CHECK_ARRAY_ACCESSOR(it, EINA_FALSE); | ||
152 | |||
153 | if (!(idx < eina_array_count(it->array))) | ||
154 | return EINA_FALSE; | ||
155 | |||
156 | if (data) | ||
157 | *data = eina_array_data_get(it->array, idx); | ||
158 | |||
159 | return EINA_TRUE; | ||
160 | } | ||
161 | |||
162 | static Eina_Array * | ||
163 | eina_array_accessor_get_container(Eina_Accessor_Array *it) | ||
164 | { | ||
165 | EINA_MAGIC_CHECK_ARRAY_ACCESSOR(it, NULL); | ||
166 | return (Eina_Array *)it->array; | ||
167 | } | ||
168 | |||
169 | static void | ||
170 | eina_array_accessor_free(Eina_Accessor_Array *it) | ||
171 | { | ||
172 | EINA_MAGIC_CHECK_ARRAY_ACCESSOR(it); | ||
173 | MAGIC_FREE(it); | ||
174 | } | ||
175 | |||
176 | /* used from eina_inline_array.x, thus a needed symbol */ | ||
177 | EAPI Eina_Bool | ||
178 | eina_array_grow(Eina_Array *array) | ||
179 | { | ||
180 | void **tmp; | ||
181 | unsigned int total; | ||
182 | |||
183 | EINA_SAFETY_ON_NULL_RETURN_VAL(array, EINA_FALSE); | ||
184 | |||
185 | EINA_MAGIC_CHECK_ARRAY(array); | ||
186 | |||
187 | total = array->total + array->step; | ||
188 | eina_error_set(0); | ||
189 | tmp = realloc(array->data, sizeof (void *) * total); | ||
190 | if (EINA_UNLIKELY(!tmp)) | ||
191 | { | ||
192 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | array->total = total; | ||
197 | array->data = tmp; | ||
198 | |||
199 | return 1; | ||
200 | } | ||
201 | |||
202 | /** | ||
203 | * @endcond | ||
204 | */ | ||
205 | |||
206 | |||
207 | /*============================================================================* | ||
208 | * Global * | ||
209 | *============================================================================*/ | ||
210 | |||
211 | /** | ||
212 | * @internal | ||
213 | * @brief Initialize the array module. | ||
214 | * | ||
215 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
216 | * | ||
217 | * This function sets up the error and magic modules or Eina. It is | ||
218 | * called by eina_init(). | ||
219 | * | ||
220 | * @see eina_init() | ||
221 | */ | ||
222 | Eina_Bool | ||
223 | eina_array_init(void) | ||
224 | { | ||
225 | _eina_array_log_dom = eina_log_domain_register("eina_array", | ||
226 | EINA_LOG_COLOR_DEFAULT); | ||
227 | if (_eina_array_log_dom < 0) | ||
228 | { | ||
229 | EINA_LOG_ERR("Could not register log domain: eina_array"); | ||
230 | return EINA_FALSE; | ||
231 | } | ||
232 | |||
233 | #define EMS(n) eina_magic_string_static_set(n, n ## _STR) | ||
234 | EMS(EINA_MAGIC_ARRAY); | ||
235 | EMS(EINA_MAGIC_ARRAY_ITERATOR); | ||
236 | EMS(EINA_MAGIC_ARRAY_ACCESSOR); | ||
237 | #undef EMS | ||
238 | return EINA_TRUE; | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * @internal | ||
243 | * @brief Shut down the array module. | ||
244 | * | ||
245 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
246 | * | ||
247 | * This function shuts down the array module set up by | ||
248 | * eina_array_init(). It is called by eina_shutdown(). | ||
249 | * | ||
250 | * @see eina_shutdown() | ||
251 | */ | ||
252 | Eina_Bool | ||
253 | eina_array_shutdown(void) | ||
254 | { | ||
255 | eina_log_domain_unregister(_eina_array_log_dom); | ||
256 | _eina_array_log_dom = -1; | ||
257 | return EINA_TRUE; | ||
258 | } | ||
259 | |||
260 | /*============================================================================* | ||
261 | * API * | ||
262 | *============================================================================*/ | ||
263 | |||
264 | EAPI Eina_Array * | ||
265 | eina_array_new(unsigned int step) | ||
266 | { | ||
267 | Eina_Array *array; | ||
268 | |||
269 | eina_error_set(0); | ||
270 | array = malloc(sizeof (Eina_Array)); | ||
271 | if (!array) | ||
272 | { | ||
273 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
274 | return NULL; | ||
275 | } | ||
276 | |||
277 | EINA_MAGIC_SET(array, EINA_MAGIC_ARRAY); | ||
278 | |||
279 | array->version = EINA_ARRAY_VERSION; | ||
280 | array->data = NULL; | ||
281 | array->total = 0; | ||
282 | array->count = 0; | ||
283 | array->step = step; | ||
284 | |||
285 | return array; | ||
286 | } | ||
287 | |||
288 | EAPI void | ||
289 | eina_array_free(Eina_Array *array) | ||
290 | { | ||
291 | eina_array_flush(array); | ||
292 | |||
293 | EINA_SAFETY_ON_NULL_RETURN(array); | ||
294 | EINA_MAGIC_CHECK_ARRAY(array); | ||
295 | MAGIC_FREE(array); | ||
296 | } | ||
297 | |||
298 | EAPI void | ||
299 | eina_array_step_set(Eina_Array *array, | ||
300 | unsigned int sizeof_eina_array, | ||
301 | unsigned int step) | ||
302 | { | ||
303 | EINA_SAFETY_ON_NULL_RETURN(array); | ||
304 | |||
305 | if (sizeof (Eina_Array) != sizeof_eina_array) | ||
306 | { | ||
307 | ERR("Unknow Eina_Array size ! Got %i, expected %i !\n", | ||
308 | sizeof_eina_array, | ||
309 | (int) sizeof (Eina_Array)); | ||
310 | /* Force memory to zero to provide a small layer of security */ | ||
311 | memset(array, 0, sizeof_eina_array); | ||
312 | return ; | ||
313 | } | ||
314 | |||
315 | array->version = EINA_ARRAY_VERSION; | ||
316 | array->data = NULL; | ||
317 | array->total = 0; | ||
318 | array->count = 0; | ||
319 | array->step = step; | ||
320 | EINA_MAGIC_SET(array, EINA_MAGIC_ARRAY); | ||
321 | } | ||
322 | |||
323 | EAPI void | ||
324 | eina_array_flush(Eina_Array *array) | ||
325 | { | ||
326 | EINA_SAFETY_ON_NULL_RETURN(array); | ||
327 | EINA_MAGIC_CHECK_ARRAY(array); | ||
328 | |||
329 | array->count = 0; | ||
330 | array->total = 0; | ||
331 | |||
332 | if (!array->data) | ||
333 | return; | ||
334 | |||
335 | free(array->data); | ||
336 | array->data = NULL; | ||
337 | } | ||
338 | |||
339 | EAPI Eina_Bool | ||
340 | eina_array_remove(Eina_Array *array, Eina_Bool (*keep)(void *data, | ||
341 | void *gdata), | ||
342 | void *gdata) | ||
343 | { | ||
344 | void **tmp; | ||
345 | /* WARNING: | ||
346 | The algorithm does exit before using unitialized data. So compiler is | ||
347 | giving you a false positiv here too. | ||
348 | */ | ||
349 | void *data = NULL; | ||
350 | unsigned int total = 0; | ||
351 | unsigned int limit; | ||
352 | unsigned int i; | ||
353 | |||
354 | EINA_SAFETY_ON_NULL_RETURN_VAL(array, EINA_FALSE); | ||
355 | EINA_SAFETY_ON_NULL_RETURN_VAL(keep, EINA_FALSE); | ||
356 | EINA_MAGIC_CHECK_ARRAY(array); | ||
357 | |||
358 | if (array->total == 0) | ||
359 | return EINA_TRUE; | ||
360 | |||
361 | for (i = 0; i < array->count; ++i) | ||
362 | { | ||
363 | data = eina_array_data_get(array, i); | ||
364 | |||
365 | if (keep(data, gdata) == EINA_FALSE) | ||
366 | break; | ||
367 | } | ||
368 | limit = i; | ||
369 | if (i < array->count) | ||
370 | ++i; | ||
371 | |||
372 | for (; i < array->count; ++i) | ||
373 | { | ||
374 | data = eina_array_data_get(array, i); | ||
375 | |||
376 | if (keep(data, gdata) == EINA_TRUE) | ||
377 | break; | ||
378 | } | ||
379 | /* Special case all objects that need to stay are at the beginning of the array. */ | ||
380 | if (i == array->count) | ||
381 | { | ||
382 | array->count = limit; | ||
383 | if (array->count == 0) | ||
384 | { | ||
385 | free(array->data); | ||
386 | array->total = 0; | ||
387 | array->data = NULL; | ||
388 | } | ||
389 | |||
390 | return EINA_TRUE; | ||
391 | } | ||
392 | |||
393 | eina_error_set(0); | ||
394 | tmp = malloc(sizeof (void *) * array->total); | ||
395 | if (!tmp) | ||
396 | { | ||
397 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
398 | return EINA_FALSE; | ||
399 | } | ||
400 | |||
401 | memcpy(tmp, array->data, limit * sizeof(void *)); | ||
402 | total = limit; | ||
403 | |||
404 | if (i < array->count) | ||
405 | { | ||
406 | tmp[total] = data; | ||
407 | total++; | ||
408 | ++i; | ||
409 | } | ||
410 | |||
411 | for (; i < array->count; ++i) | ||
412 | { | ||
413 | data = eina_array_data_get(array, i); | ||
414 | |||
415 | if (keep(data, gdata)) | ||
416 | { | ||
417 | tmp[total] = data; | ||
418 | total++; | ||
419 | } | ||
420 | } | ||
421 | |||
422 | free(array->data); | ||
423 | |||
424 | /* If we do not keep any object in the array, we should have exited | ||
425 | earlier in test (i == array->count). */ | ||
426 | assert(total != 0); | ||
427 | |||
428 | array->data = tmp; | ||
429 | array->count = total; | ||
430 | return EINA_TRUE; | ||
431 | } | ||
432 | |||
433 | EAPI Eina_Iterator * | ||
434 | eina_array_iterator_new(const Eina_Array *array) | ||
435 | { | ||
436 | Eina_Iterator_Array *it; | ||
437 | |||
438 | EINA_SAFETY_ON_NULL_RETURN_VAL(array, NULL); | ||
439 | EINA_MAGIC_CHECK_ARRAY(array); | ||
440 | |||
441 | eina_error_set(0); | ||
442 | it = calloc(1, sizeof (Eina_Iterator_Array)); | ||
443 | if (!it) | ||
444 | { | ||
445 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
446 | return NULL; | ||
447 | } | ||
448 | |||
449 | EINA_MAGIC_SET(it, EINA_MAGIC_ARRAY_ITERATOR); | ||
450 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
451 | |||
452 | it->array = array; | ||
453 | |||
454 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
455 | it->iterator.next = FUNC_ITERATOR_NEXT(eina_array_iterator_next); | ||
456 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
457 | eina_array_iterator_get_container); | ||
458 | it->iterator.free = FUNC_ITERATOR_FREE(eina_array_iterator_free); | ||
459 | |||
460 | return &it->iterator; | ||
461 | } | ||
462 | |||
463 | EAPI Eina_Accessor * | ||
464 | eina_array_accessor_new(const Eina_Array *array) | ||
465 | { | ||
466 | Eina_Accessor_Array *ac; | ||
467 | |||
468 | EINA_SAFETY_ON_NULL_RETURN_VAL(array, NULL); | ||
469 | EINA_MAGIC_CHECK_ARRAY(array); | ||
470 | |||
471 | eina_error_set(0); | ||
472 | ac = calloc(1, sizeof (Eina_Accessor_Array)); | ||
473 | if (!ac) | ||
474 | { | ||
475 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
476 | return NULL; | ||
477 | } | ||
478 | |||
479 | EINA_MAGIC_SET(ac, EINA_MAGIC_ARRAY_ACCESSOR); | ||
480 | EINA_MAGIC_SET(&ac->accessor, EINA_MAGIC_ACCESSOR); | ||
481 | |||
482 | ac->array = array; | ||
483 | |||
484 | ac->accessor.version = EINA_ACCESSOR_VERSION; | ||
485 | ac->accessor.get_at = FUNC_ACCESSOR_GET_AT(eina_array_accessor_get_at); | ||
486 | ac->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER( | ||
487 | eina_array_accessor_get_container); | ||
488 | ac->accessor.free = FUNC_ACCESSOR_FREE(eina_array_accessor_free); | ||
489 | |||
490 | return &ac->accessor; | ||
491 | } | ||
diff --git a/libraries/eina/src/lib/eina_benchmark.c b/libraries/eina/src/lib/eina_benchmark.c deleted file mode 100644 index 1ba2a00..0000000 --- a/libraries/eina/src/lib/eina_benchmark.c +++ /dev/null | |||
@@ -1,372 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #ifdef HAVE_ALLOCA_H | ||
24 | # include <alloca.h> | ||
25 | #elif defined __GNUC__ | ||
26 | # define alloca __builtin_alloca | ||
27 | #elif defined _AIX | ||
28 | # define alloca __alloca | ||
29 | #elif defined _MSC_VER | ||
30 | # include <malloc.h> | ||
31 | # define alloca _alloca | ||
32 | #else | ||
33 | # include <stddef.h> | ||
34 | # ifdef __cplusplus | ||
35 | extern "C" | ||
36 | # endif | ||
37 | void *alloca (size_t); | ||
38 | #endif | ||
39 | |||
40 | #include <stdlib.h> | ||
41 | #include <stdio.h> | ||
42 | #include <string.h> | ||
43 | |||
44 | #ifdef HAVE_EVIL | ||
45 | # include <Evil.h> | ||
46 | #endif | ||
47 | |||
48 | #include "eina_config.h" | ||
49 | #include "eina_private.h" | ||
50 | #include "eina_log.h" | ||
51 | #include "eina_benchmark.h" | ||
52 | #include "eina_inlist.h" | ||
53 | #include "eina_list.h" | ||
54 | #include "eina_counter.h" | ||
55 | |||
56 | /*============================================================================* | ||
57 | * Local * | ||
58 | *============================================================================*/ | ||
59 | |||
60 | /** | ||
61 | * @cond LOCAL | ||
62 | */ | ||
63 | |||
64 | #define EINA_BENCHMARK_FILENAME_MASK "bench_%s_%s.gnuplot" | ||
65 | #define EINA_BENCHMARK_DATA_MASK "bench_%s_%s.%s.data" | ||
66 | |||
67 | typedef struct _Eina_Run Eina_Run; | ||
68 | struct _Eina_Run | ||
69 | { | ||
70 | EINA_INLIST; | ||
71 | |||
72 | Eina_Benchmark_Specimens cb; | ||
73 | const char *name; | ||
74 | int start; | ||
75 | int end; | ||
76 | int step; | ||
77 | }; | ||
78 | |||
79 | struct _Eina_Benchmark | ||
80 | { | ||
81 | const char *name; | ||
82 | const char *run; | ||
83 | |||
84 | Eina_Inlist *runs; | ||
85 | Eina_List *names; | ||
86 | }; | ||
87 | |||
88 | static int _eina_benchmark_log_dom = -1; | ||
89 | |||
90 | #ifdef ERR | ||
91 | #undef ERR | ||
92 | #endif | ||
93 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_benchmark_log_dom, __VA_ARGS__) | ||
94 | |||
95 | #ifdef DBG | ||
96 | #undef DBG | ||
97 | #endif | ||
98 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_benchmark_log_dom, __VA_ARGS__) | ||
99 | |||
100 | /** | ||
101 | * @endcond | ||
102 | */ | ||
103 | |||
104 | /*============================================================================* | ||
105 | * Global * | ||
106 | *============================================================================*/ | ||
107 | |||
108 | /** | ||
109 | * @internal | ||
110 | * @brief Initialize the benchmark module. | ||
111 | * | ||
112 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
113 | * | ||
114 | * This function sets up the benchmark module of Eina. It is called by | ||
115 | * eina_init(). | ||
116 | * | ||
117 | * @see eina_init() | ||
118 | */ | ||
119 | Eina_Bool | ||
120 | eina_benchmark_init(void) | ||
121 | { | ||
122 | _eina_benchmark_log_dom = eina_log_domain_register("eina_benchmark", | ||
123 | EINA_LOG_COLOR_DEFAULT); | ||
124 | if (_eina_benchmark_log_dom < 0) | ||
125 | { | ||
126 | EINA_LOG_ERR("Could not register log domain: eina_benchmark"); | ||
127 | return EINA_FALSE; | ||
128 | } | ||
129 | |||
130 | return EINA_TRUE; | ||
131 | } | ||
132 | |||
133 | /** | ||
134 | * @internal | ||
135 | * @brief Shut down the benchmark module. | ||
136 | * | ||
137 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
138 | * | ||
139 | * This function shuts down the benchmark module set up by | ||
140 | * eina_benchmark_init(). It is called by eina_shutdown(). | ||
141 | * | ||
142 | * @see eina_shutdown() | ||
143 | */ | ||
144 | Eina_Bool | ||
145 | eina_benchmark_shutdown(void) | ||
146 | { | ||
147 | eina_log_domain_unregister(_eina_benchmark_log_dom); | ||
148 | _eina_benchmark_log_dom = -1; | ||
149 | return EINA_TRUE; | ||
150 | } | ||
151 | |||
152 | /*============================================================================* | ||
153 | * API * | ||
154 | *============================================================================*/ | ||
155 | |||
156 | EAPI Eina_Benchmark * | ||
157 | eina_benchmark_new(const char *name, const char *run) | ||
158 | { | ||
159 | Eina_Benchmark *new; | ||
160 | |||
161 | eina_error_set(0); | ||
162 | new = calloc(1, sizeof (Eina_Benchmark)); | ||
163 | if (!new) | ||
164 | { | ||
165 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
166 | return NULL; | ||
167 | } | ||
168 | |||
169 | new->name = name; | ||
170 | new->run = run; | ||
171 | |||
172 | return new; | ||
173 | } | ||
174 | |||
175 | EAPI void | ||
176 | eina_benchmark_free(Eina_Benchmark *bench) | ||
177 | { | ||
178 | Eina_Array *names; | ||
179 | |||
180 | if (!bench) | ||
181 | return; | ||
182 | |||
183 | while (bench->runs) | ||
184 | { | ||
185 | Eina_Run *run = (Eina_Run *)bench->runs; | ||
186 | |||
187 | bench->runs = eina_inlist_remove(bench->runs, bench->runs); | ||
188 | free(run); | ||
189 | } | ||
190 | |||
191 | EINA_LIST_FREE(bench->names, names) | ||
192 | { | ||
193 | Eina_Array_Iterator it; | ||
194 | char *tmp; | ||
195 | unsigned int i; | ||
196 | |||
197 | EINA_ARRAY_ITER_NEXT(names, i, tmp, it) | ||
198 | free(tmp); | ||
199 | |||
200 | eina_array_free(names); | ||
201 | } | ||
202 | |||
203 | free(bench); | ||
204 | } | ||
205 | |||
206 | EAPI Eina_Bool | ||
207 | eina_benchmark_register(Eina_Benchmark *bench, | ||
208 | const char *name, | ||
209 | Eina_Benchmark_Specimens bench_cb, | ||
210 | int count_start, | ||
211 | int count_end, | ||
212 | int count_step) | ||
213 | { | ||
214 | Eina_Run *run; | ||
215 | |||
216 | if (!bench) | ||
217 | return EINA_FALSE; | ||
218 | |||
219 | if (count_step == 0) | ||
220 | return EINA_FALSE; | ||
221 | |||
222 | eina_error_set(0); | ||
223 | run = calloc(1, sizeof (Eina_Run)); | ||
224 | if (!run) | ||
225 | { | ||
226 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
227 | return EINA_FALSE; | ||
228 | } | ||
229 | |||
230 | run->cb = bench_cb; | ||
231 | run->name = name; | ||
232 | run->start = count_start; | ||
233 | run->end = count_end; | ||
234 | run->step = count_step; | ||
235 | |||
236 | bench->runs = eina_inlist_append(bench->runs, EINA_INLIST_GET(run)); | ||
237 | |||
238 | return EINA_TRUE; | ||
239 | } | ||
240 | |||
241 | EAPI Eina_Array * | ||
242 | eina_benchmark_run(Eina_Benchmark *bench) | ||
243 | { | ||
244 | FILE *main_script; | ||
245 | FILE *current_data; | ||
246 | Eina_Array *ea; | ||
247 | Eina_Run *run; | ||
248 | char *buffer; | ||
249 | Eina_Bool first = EINA_FALSE; | ||
250 | size_t length; | ||
251 | |||
252 | if (!bench) | ||
253 | return NULL; | ||
254 | |||
255 | length = strlen(EINA_BENCHMARK_FILENAME_MASK) + strlen(bench->name) + strlen( | ||
256 | bench->run); | ||
257 | |||
258 | buffer = alloca(sizeof (char) * length); | ||
259 | if (!buffer) | ||
260 | return NULL; | ||
261 | |||
262 | snprintf(buffer, | ||
263 | length, | ||
264 | EINA_BENCHMARK_FILENAME_MASK, | ||
265 | bench->name, | ||
266 | bench->run); | ||
267 | |||
268 | main_script = fopen(buffer, "w"); | ||
269 | if (!main_script) | ||
270 | return NULL; | ||
271 | |||
272 | ea = eina_array_new(16); | ||
273 | if (!ea) | ||
274 | { | ||
275 | fclose(main_script); | ||
276 | return NULL; | ||
277 | } | ||
278 | |||
279 | eina_array_push(ea, strdup(buffer)); | ||
280 | |||
281 | fprintf( | ||
282 | main_script, | ||
283 | "set autoscale # scale axes automatically\n" | ||
284 | "unset log # remove any log-scaling\n" | ||
285 | "unset label # remove any previous labels\n" | ||
286 | "set xtic auto # set xtics automatically\n" | ||
287 | "set ytic auto # set ytics automatically\n" | ||
288 | /* "set logscale y\n" */ | ||
289 | "set terminal png size 1024,768\n" | ||
290 | "set output \"output_%s_%s.png\"\n" | ||
291 | "set title \"%s %s\n" | ||
292 | "set xlabel \"tests\"\n" | ||
293 | "set ylabel \"time\"\n" | ||
294 | "plot ", | ||
295 | bench->name, | ||
296 | bench->run, | ||
297 | bench->name, | ||
298 | bench->run); | ||
299 | |||
300 | EINA_INLIST_FOREACH(bench->runs, run) | ||
301 | { | ||
302 | Eina_Counter *counter; | ||
303 | char *result; | ||
304 | size_t tmp; | ||
305 | int i; | ||
306 | |||
307 | tmp = strlen(EINA_BENCHMARK_DATA_MASK) + strlen(bench->name) + strlen( | ||
308 | bench->run) + strlen(run->name); | ||
309 | if (tmp > length) | ||
310 | { | ||
311 | buffer = alloca(sizeof (char) * tmp); | ||
312 | length = tmp; | ||
313 | } | ||
314 | |||
315 | snprintf(buffer, | ||
316 | length, | ||
317 | EINA_BENCHMARK_DATA_MASK, | ||
318 | bench->name, | ||
319 | bench->run, | ||
320 | run->name); | ||
321 | |||
322 | current_data = fopen(buffer, "w"); | ||
323 | if (!current_data) | ||
324 | continue; | ||
325 | |||
326 | eina_array_push(ea, strdup(buffer)); | ||
327 | |||
328 | counter = eina_counter_new(run->name); | ||
329 | |||
330 | for (i = run->start; i < run->end; i += run->step) | ||
331 | { | ||
332 | fprintf(stderr, "Run %s: %i\n", run->name, i); | ||
333 | eina_counter_start(counter); | ||
334 | |||
335 | run->cb(i); | ||
336 | |||
337 | eina_counter_stop(counter, i); | ||
338 | } | ||
339 | |||
340 | result = eina_counter_dump(counter); | ||
341 | if (result) | ||
342 | { | ||
343 | fprintf(current_data, "%s", result); | ||
344 | free(result); | ||
345 | } | ||
346 | |||
347 | eina_counter_free(counter); | ||
348 | |||
349 | fclose(current_data); | ||
350 | |||
351 | if (first == EINA_FALSE) | ||
352 | first = EINA_TRUE; | ||
353 | else | ||
354 | fprintf(main_script, ", \\\n"); | ||
355 | |||
356 | fprintf(main_script, | ||
357 | "\"%s\" using 1:2 title \'%s\' with line", | ||
358 | buffer, run->name); | ||
359 | } | ||
360 | |||
361 | fprintf(main_script, "\n"); | ||
362 | |||
363 | fclose(main_script); | ||
364 | |||
365 | bench->names = eina_list_append(bench->names, ea); | ||
366 | |||
367 | return ea; | ||
368 | } | ||
369 | |||
370 | /** | ||
371 | * @} | ||
372 | */ | ||
diff --git a/libraries/eina/src/lib/eina_binbuf.c b/libraries/eina/src/lib/eina_binbuf.c deleted file mode 100644 index 3cbebd1..0000000 --- a/libraries/eina/src/lib/eina_binbuf.c +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include "config.h" | ||
3 | #endif | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <string.h> | ||
7 | |||
8 | #ifdef HAVE_EVIL | ||
9 | # include <Evil.h> | ||
10 | #endif | ||
11 | |||
12 | #include "eina_private.h" | ||
13 | #include "eina_strbuf_common.h" | ||
14 | #include "eina_binbuf.h" | ||
15 | |||
16 | /*============================================================================* | ||
17 | * Local * | ||
18 | *============================================================================*/ | ||
19 | |||
20 | /** | ||
21 | * @cond LOCAL | ||
22 | */ | ||
23 | |||
24 | #ifdef _STRBUF_DATA_TYPE | ||
25 | # undef _STRBUF_DATA_TYPE | ||
26 | #endif | ||
27 | |||
28 | #ifdef _STRBUF_CSIZE | ||
29 | # undef _STRBUF_CSIZE | ||
30 | #endif | ||
31 | |||
32 | #ifdef _STRBUF_STRUCT_NAME | ||
33 | # undef _STRBUF_STRUCT_NAME | ||
34 | #endif | ||
35 | |||
36 | #ifdef _STRBUF_MAGIC | ||
37 | # undef _STRBUF_MAGIC | ||
38 | #endif | ||
39 | |||
40 | #ifdef _STRBUF_MAGIC_STR | ||
41 | # undef _STRBUF_MAGIC_STR | ||
42 | #endif | ||
43 | |||
44 | #ifdef _FUNC_EXPAND | ||
45 | # undef _FUNC_EXPAND | ||
46 | #endif | ||
47 | |||
48 | |||
49 | #define _STRBUF_DATA_TYPE unsigned char | ||
50 | #define _STRBUF_CSIZE sizeof(_STRBUF_DATA_TYPE) | ||
51 | #define _STRBUF_STRUCT_NAME Eina_Binbuf | ||
52 | #define _STRBUF_MAGIC EINA_MAGIC_BINBUF | ||
53 | #define _STRBUF_MAGIC_STR __BINBUF_MAGIC_STR | ||
54 | static const char __BINBUF_MAGIC_STR[] = "Eina Binbuf"; | ||
55 | |||
56 | #define _FUNC_EXPAND(y) eina_binbuf_ ## y | ||
57 | |||
58 | #include "eina_binbuf_template_c.x" | ||
59 | |||
60 | /** | ||
61 | * @endcond | ||
62 | */ | ||
diff --git a/libraries/eina/src/lib/eina_binbuf_template_c.x b/libraries/eina/src/lib/eina_binbuf_template_c.x deleted file mode 100644 index 7e0c539..0000000 --- a/libraries/eina/src/lib/eina_binbuf_template_c.x +++ /dev/null | |||
@@ -1,153 +0,0 @@ | |||
1 | /* | ||
2 | * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 | ||
3 | */ | ||
4 | |||
5 | /* This file should be included from files implementing binbuf. | ||
6 | * The including file should define the following macros: | ||
7 | * _STRBUF_DATA_TYPE | ||
8 | * _STRBUF_CSIZE | ||
9 | * _STRBUF_STRUCT_NAME | ||
10 | * _STRBUF_MAGIC | ||
11 | * _STRBUF_MAGIC_STR | ||
12 | * _FUNC_EXPAND | ||
13 | * See how it's done in eina_ustrbuf.c and eina_strbuf.c. This just makes things | ||
14 | * a lot easier since those are essentially the same just with different sizes. | ||
15 | */ | ||
16 | |||
17 | /*============================================================================* | ||
18 | * Global * | ||
19 | *============================================================================*/ | ||
20 | |||
21 | /** | ||
22 | * @internal | ||
23 | * @brief Initialize the strbuf module. | ||
24 | * | ||
25 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
26 | * | ||
27 | * This function sets up the strbuf module of Eina. It is called by | ||
28 | * eina_init(). | ||
29 | * | ||
30 | * @see eina_init() | ||
31 | */ | ||
32 | Eina_Bool | ||
33 | _FUNC_EXPAND(init)(void) | ||
34 | { | ||
35 | eina_magic_string_static_set(_STRBUF_MAGIC, _STRBUF_MAGIC_STR); | ||
36 | return eina_strbuf_common_init(); | ||
37 | } | ||
38 | |||
39 | /** | ||
40 | * @internal | ||
41 | * @brief Shut down the strbuf module. | ||
42 | * | ||
43 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
44 | * | ||
45 | * This function shuts down the strbuf module set up by | ||
46 | * eina_ustrbuf_init(). It is called by eina_shutdown(). | ||
47 | * | ||
48 | * @see eina_shutdown() | ||
49 | */ | ||
50 | Eina_Bool | ||
51 | _FUNC_EXPAND(shutdown)(void) | ||
52 | { | ||
53 | return eina_strbuf_common_shutdown(); | ||
54 | } | ||
55 | |||
56 | /*============================================================================* | ||
57 | * API * | ||
58 | *============================================================================*/ | ||
59 | |||
60 | EAPI _STRBUF_STRUCT_NAME * | ||
61 | _FUNC_EXPAND(new)(void) | ||
62 | { | ||
63 | _STRBUF_STRUCT_NAME *buf = eina_strbuf_common_new(_STRBUF_CSIZE); | ||
64 | EINA_MAGIC_SET(buf, _STRBUF_MAGIC); | ||
65 | return buf; | ||
66 | } | ||
67 | |||
68 | EAPI _STRBUF_STRUCT_NAME * | ||
69 | _FUNC_EXPAND(manage_new_length)(_STRBUF_DATA_TYPE *str, size_t length) | ||
70 | { | ||
71 | _STRBUF_STRUCT_NAME *buf = | ||
72 | eina_strbuf_common_manage_new(_STRBUF_CSIZE, (void *) str, length); | ||
73 | EINA_MAGIC_SET(buf, _STRBUF_MAGIC); | ||
74 | return buf; | ||
75 | } | ||
76 | |||
77 | EAPI void | ||
78 | _FUNC_EXPAND(free)(_STRBUF_STRUCT_NAME *buf) | ||
79 | { | ||
80 | EINA_MAGIC_CHECK_STRBUF(buf); | ||
81 | EINA_MAGIC_SET(buf, EINA_MAGIC_NONE); | ||
82 | eina_strbuf_common_free(buf); | ||
83 | } | ||
84 | |||
85 | EAPI void | ||
86 | _FUNC_EXPAND(reset)(_STRBUF_STRUCT_NAME *buf) | ||
87 | { | ||
88 | EINA_MAGIC_CHECK_STRBUF(buf); | ||
89 | eina_strbuf_common_reset(_STRBUF_CSIZE, buf); | ||
90 | } | ||
91 | |||
92 | EAPI Eina_Bool | ||
93 | _FUNC_EXPAND(append_length)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t length) | ||
94 | { | ||
95 | EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); | ||
96 | return eina_strbuf_common_append_length(_STRBUF_CSIZE, buf, (const void *) str, length); | ||
97 | } | ||
98 | |||
99 | EAPI Eina_Bool | ||
100 | _FUNC_EXPAND(insert_length)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t length, size_t pos) | ||
101 | { | ||
102 | EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); | ||
103 | return eina_strbuf_common_insert_length(_STRBUF_CSIZE, buf, (const void *) str, length, pos); | ||
104 | } | ||
105 | |||
106 | EAPI Eina_Bool | ||
107 | _FUNC_EXPAND(append_char)(_STRBUF_STRUCT_NAME *buf, _STRBUF_DATA_TYPE c) | ||
108 | { | ||
109 | EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); | ||
110 | return eina_strbuf_common_append_char(_STRBUF_CSIZE, buf, (const void *) &c); | ||
111 | } | ||
112 | |||
113 | EAPI Eina_Bool | ||
114 | _FUNC_EXPAND(insert_char)(_STRBUF_STRUCT_NAME *buf, _STRBUF_DATA_TYPE c, size_t pos) | ||
115 | { | ||
116 | EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); | ||
117 | return eina_strbuf_common_insert_char(_STRBUF_CSIZE, buf, (const void *) &c, pos); | ||
118 | } | ||
119 | |||
120 | EAPI Eina_Bool | ||
121 | _FUNC_EXPAND(remove)(_STRBUF_STRUCT_NAME *buf, size_t start, size_t end) | ||
122 | { | ||
123 | EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); | ||
124 | return eina_strbuf_common_remove(_STRBUF_CSIZE, buf, start, end); | ||
125 | } | ||
126 | |||
127 | EAPI const _STRBUF_DATA_TYPE * | ||
128 | _FUNC_EXPAND(string_get)(const _STRBUF_STRUCT_NAME *buf) | ||
129 | { | ||
130 | EINA_MAGIC_CHECK_STRBUF(buf, NULL); | ||
131 | return (const _STRBUF_DATA_TYPE *) eina_strbuf_common_string_get(buf); | ||
132 | } | ||
133 | |||
134 | EAPI _STRBUF_DATA_TYPE * | ||
135 | _FUNC_EXPAND(string_steal)(_STRBUF_STRUCT_NAME *buf) | ||
136 | { | ||
137 | EINA_MAGIC_CHECK_STRBUF(buf, NULL); | ||
138 | return (_STRBUF_DATA_TYPE *) eina_strbuf_common_string_steal(_STRBUF_CSIZE, buf); | ||
139 | } | ||
140 | |||
141 | EAPI void | ||
142 | _FUNC_EXPAND(string_free)(_STRBUF_STRUCT_NAME *buf) | ||
143 | { | ||
144 | EINA_MAGIC_CHECK_STRBUF(buf); | ||
145 | eina_strbuf_common_string_free(_STRBUF_CSIZE, buf); | ||
146 | } | ||
147 | |||
148 | EAPI size_t | ||
149 | _FUNC_EXPAND(length_get)(const _STRBUF_STRUCT_NAME *buf) | ||
150 | { | ||
151 | EINA_MAGIC_CHECK_STRBUF(buf, 0); | ||
152 | return eina_strbuf_common_length_get(buf); | ||
153 | } | ||
diff --git a/libraries/eina/src/lib/eina_binshare.c b/libraries/eina/src/lib/eina_binshare.c deleted file mode 100644 index 01e8046..0000000 --- a/libraries/eina/src/lib/eina_binshare.c +++ /dev/null | |||
@@ -1,182 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2002-2008 Carsten Haitzler, | ||
3 | * Jorge Luis Zapata Muga, | ||
4 | * Cedric Bail, | ||
5 | * Gustavo Sverzut Barbieri | ||
6 | * Tom Hacohen | ||
7 | * | ||
8 | * This library is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU Lesser General Public | ||
10 | * License as published by the Free Software Foundation; either | ||
11 | * version 2.1 of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * This library is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * Lesser General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU Lesser General Public | ||
19 | * License along with this library; | ||
20 | * if not, see <http://www.gnu.org/licenses/>. | ||
21 | |||
22 | */ | ||
23 | |||
24 | #ifdef HAVE_CONFIG_H | ||
25 | # include "config.h" | ||
26 | #endif | ||
27 | |||
28 | #include "eina_config.h" | ||
29 | #include "eina_private.h" | ||
30 | #include "eina_unicode.h" | ||
31 | #include "eina_log.h" | ||
32 | #include "eina_share_common.h" | ||
33 | |||
34 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
35 | #include "eina_safety_checks.h" | ||
36 | #include "eina_binshare.h" | ||
37 | |||
38 | /*============================================================================* | ||
39 | * Local * | ||
40 | *============================================================================*/ | ||
41 | |||
42 | /** | ||
43 | * @cond LOCAL | ||
44 | */ | ||
45 | |||
46 | #ifdef CRITICAL | ||
47 | #undef CRITICAL | ||
48 | #endif | ||
49 | #define CRITICAL(...) EINA_LOG_DOM_CRIT(_eina_share_binshare_log_dom, __VA_ARGS__) | ||
50 | |||
51 | #ifdef ERR | ||
52 | #undef ERR | ||
53 | #endif | ||
54 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_share_binshare_log_dom, __VA_ARGS__) | ||
55 | |||
56 | #ifdef DBG | ||
57 | #undef DBG | ||
58 | #endif | ||
59 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_share_binshare_log_dom, __VA_ARGS__) | ||
60 | |||
61 | static int _eina_share_binshare_log_dom = -1; | ||
62 | |||
63 | /* The actual share */ | ||
64 | static Eina_Share *binshare_share; | ||
65 | static const char EINA_MAGIC_BINSHARE_NODE_STR[] = "Eina Binshare Node"; | ||
66 | |||
67 | /** | ||
68 | * @endcond | ||
69 | */ | ||
70 | |||
71 | /*============================================================================* | ||
72 | * Global * | ||
73 | *============================================================================*/ | ||
74 | |||
75 | /** | ||
76 | * @internal | ||
77 | * @brief Initialize the share_common module. | ||
78 | * | ||
79 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
80 | * | ||
81 | * This function sets up the share_common module of Eina. It is called by | ||
82 | * eina_init(). | ||
83 | * | ||
84 | * @see eina_init() | ||
85 | */ | ||
86 | EAPI Eina_Bool | ||
87 | eina_binshare_init(void) | ||
88 | { | ||
89 | Eina_Bool ret; | ||
90 | |||
91 | if (_eina_share_binshare_log_dom < 0) | ||
92 | { | ||
93 | _eina_share_binshare_log_dom = eina_log_domain_register | ||
94 | ("eina_binshare", EINA_LOG_COLOR_DEFAULT); | ||
95 | |||
96 | if (_eina_share_binshare_log_dom < 0) | ||
97 | { | ||
98 | EINA_LOG_ERR("Could not register log domain: eina_binshare"); | ||
99 | return EINA_FALSE; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | ret = eina_share_common_init(&binshare_share, | ||
104 | EINA_MAGIC_BINSHARE_NODE, | ||
105 | EINA_MAGIC_BINSHARE_NODE_STR); | ||
106 | |||
107 | if (!ret) | ||
108 | { | ||
109 | eina_log_domain_unregister(_eina_share_binshare_log_dom); | ||
110 | _eina_share_binshare_log_dom = -1; | ||
111 | } | ||
112 | |||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * @internal | ||
118 | * @brief Shut down the share_common module. | ||
119 | * | ||
120 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
121 | * | ||
122 | * This function shuts down the share_common module set up by | ||
123 | * eina_share_common_init(). It is called by eina_shutdown(). | ||
124 | * | ||
125 | * @see eina_shutdown() | ||
126 | */ | ||
127 | EAPI Eina_Bool | ||
128 | eina_binshare_shutdown(void) | ||
129 | { | ||
130 | Eina_Bool ret; | ||
131 | ret = eina_share_common_shutdown(&binshare_share); | ||
132 | |||
133 | if (_eina_share_binshare_log_dom > 0) | ||
134 | { | ||
135 | eina_log_domain_unregister(_eina_share_binshare_log_dom); | ||
136 | _eina_share_binshare_log_dom = -1; | ||
137 | } | ||
138 | |||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | |||
143 | /*============================================================================* | ||
144 | * API * | ||
145 | *============================================================================*/ | ||
146 | |||
147 | EAPI void | ||
148 | eina_binshare_del(const void *obj) | ||
149 | { | ||
150 | if (!obj) | ||
151 | return; | ||
152 | |||
153 | if (!eina_share_common_del(binshare_share, obj)) | ||
154 | CRITICAL("EEEK trying to del non-shared binshare %p", obj); | ||
155 | } | ||
156 | |||
157 | EAPI const void * | ||
158 | eina_binshare_add_length(const void *obj, unsigned int olen) | ||
159 | { | ||
160 | return eina_share_common_add_length(binshare_share, | ||
161 | obj, | ||
162 | (olen) * sizeof(char), | ||
163 | 0); | ||
164 | } | ||
165 | |||
166 | EAPI const void * | ||
167 | eina_binshare_ref(const void *obj) | ||
168 | { | ||
169 | return eina_share_common_ref(binshare_share, obj); | ||
170 | } | ||
171 | |||
172 | EAPI int | ||
173 | eina_binshare_length(const void *obj) | ||
174 | { | ||
175 | return eina_share_common_length(binshare_share, obj); | ||
176 | } | ||
177 | |||
178 | EAPI void | ||
179 | eina_binshare_dump(void) | ||
180 | { | ||
181 | eina_share_common_dump(binshare_share, NULL, 0); | ||
182 | } | ||
diff --git a/libraries/eina/src/lib/eina_convert.c b/libraries/eina/src/lib/eina_convert.c deleted file mode 100644 index 63b6654..0000000 --- a/libraries/eina/src/lib/eina_convert.c +++ /dev/null | |||
@@ -1,483 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Cedric BAIL, Vincent Torri | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <math.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <string.h> | ||
26 | #include <stdio.h> | ||
27 | |||
28 | #ifdef HAVE_EVIL | ||
29 | # include <Evil.h> | ||
30 | #endif | ||
31 | |||
32 | #include "eina_config.h" | ||
33 | #include "eina_private.h" | ||
34 | #include "eina_log.h" | ||
35 | |||
36 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
37 | #include "eina_safety_checks.h" | ||
38 | #include "eina_convert.h" | ||
39 | #include "eina_fp.h" | ||
40 | |||
41 | /*============================================================================* | ||
42 | * Local * | ||
43 | *============================================================================*/ | ||
44 | |||
45 | /** | ||
46 | * @cond LOCAL | ||
47 | */ | ||
48 | |||
49 | static const char look_up_table[] = {'0', '1', '2', '3', '4', | ||
50 | '5', '6', '7', '8', '9', | ||
51 | 'a', 'b', 'c', 'd', 'e', 'f'}; | ||
52 | static int _eina_convert_log_dom = -1; | ||
53 | |||
54 | #ifdef ERR | ||
55 | #undef ERR | ||
56 | #endif | ||
57 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_convert_log_dom, __VA_ARGS__) | ||
58 | |||
59 | #ifdef DBG | ||
60 | #undef DBG | ||
61 | #endif | ||
62 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_convert_log_dom, __VA_ARGS__) | ||
63 | |||
64 | #define HEXA_TO_INT(Hexa) (Hexa >= 'a') ? Hexa - 'a' + 10 : Hexa - '0' | ||
65 | |||
66 | static inline void reverse(char s[], int length) | ||
67 | { | ||
68 | int i, j; | ||
69 | char c; | ||
70 | |||
71 | for (i = 0, j = length - 1; i < j; i++, j--) | ||
72 | { | ||
73 | c = s[i]; | ||
74 | s[i] = s[j]; | ||
75 | s[j] = c; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | /** | ||
80 | * @endcond | ||
81 | */ | ||
82 | |||
83 | /*============================================================================* | ||
84 | * Global * | ||
85 | *============================================================================*/ | ||
86 | |||
87 | /** | ||
88 | * @cond LOCAL | ||
89 | */ | ||
90 | |||
91 | EAPI Eina_Error EINA_ERROR_CONVERT_P_NOT_FOUND = 0; | ||
92 | EAPI Eina_Error EINA_ERROR_CONVERT_0X_NOT_FOUND = 0; | ||
93 | EAPI Eina_Error EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH = 0; | ||
94 | |||
95 | static const char EINA_ERROR_CONVERT_0X_NOT_FOUND_STR[] = | ||
96 | "Error during string conversion to float, First '0x' was not found."; | ||
97 | static const char EINA_ERROR_CONVERT_P_NOT_FOUND_STR[] = | ||
98 | "Error during string conversion to float, First 'p' was not found."; | ||
99 | static const char EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH_STR[] = | ||
100 | "Error outrun string limit during conversion string conversion to float."; | ||
101 | |||
102 | /** | ||
103 | * @endcond | ||
104 | */ | ||
105 | |||
106 | /** | ||
107 | * @internal | ||
108 | * @brief Initialize the convert module. | ||
109 | * | ||
110 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
111 | * | ||
112 | * This function sets up the convert module of Eina. It is called by | ||
113 | * eina_init(). | ||
114 | * | ||
115 | * This function sets up the error module of Eina and registers the | ||
116 | * errors #EINA_ERROR_CONVERT_0X_NOT_FOUND, | ||
117 | * #EINA_ERROR_CONVERT_P_NOT_FOUND and | ||
118 | * #EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH. | ||
119 | * | ||
120 | * @see eina_init() | ||
121 | */ | ||
122 | Eina_Bool | ||
123 | eina_convert_init(void) | ||
124 | { | ||
125 | _eina_convert_log_dom = eina_log_domain_register("eina_convert", | ||
126 | EINA_LOG_COLOR_DEFAULT); | ||
127 | if (_eina_convert_log_dom < 0) | ||
128 | { | ||
129 | EINA_LOG_ERR("Could not register log domain: eina_convert"); | ||
130 | return EINA_FALSE; | ||
131 | } | ||
132 | |||
133 | #define EEMR(n) n = eina_error_msg_static_register(n ## _STR) | ||
134 | EEMR(EINA_ERROR_CONVERT_0X_NOT_FOUND); | ||
135 | EEMR(EINA_ERROR_CONVERT_P_NOT_FOUND); | ||
136 | EEMR(EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH); | ||
137 | #undef EEMR | ||
138 | |||
139 | return EINA_TRUE; | ||
140 | } | ||
141 | |||
142 | /** | ||
143 | * @internal | ||
144 | * @brief Shut down the convert module. | ||
145 | * | ||
146 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
147 | * | ||
148 | * This function shuts down the convert module set up by | ||
149 | * eina_convert_init(). It is called by eina_shutdown(). | ||
150 | * | ||
151 | * @see eina_shutdown() | ||
152 | */ | ||
153 | Eina_Bool | ||
154 | eina_convert_shutdown(void) | ||
155 | { | ||
156 | eina_log_domain_unregister(_eina_convert_log_dom); | ||
157 | _eina_convert_log_dom = -1; | ||
158 | return EINA_TRUE; | ||
159 | } | ||
160 | |||
161 | /*============================================================================* | ||
162 | * API * | ||
163 | *============================================================================*/ | ||
164 | |||
165 | /* | ||
166 | * Come from the second edition of The C Programming Language ("K&R2") on page 64 | ||
167 | */ | ||
168 | |||
169 | EAPI int | ||
170 | eina_convert_itoa(int n, char *s) | ||
171 | { | ||
172 | int i = 0; | ||
173 | int r = 0; | ||
174 | |||
175 | EINA_SAFETY_ON_NULL_RETURN_VAL(s, 0); | ||
176 | |||
177 | if (n < 0) | ||
178 | { | ||
179 | n = -n; | ||
180 | *s++ = '-'; | ||
181 | r = 1; | ||
182 | } | ||
183 | |||
184 | do { | ||
185 | s[i++] = n % 10 + '0'; | ||
186 | } while ((n /= 10) > 0); | ||
187 | |||
188 | s[i] = '\0'; | ||
189 | |||
190 | reverse(s, i); | ||
191 | |||
192 | return i + r; | ||
193 | } | ||
194 | |||
195 | EAPI int | ||
196 | eina_convert_xtoa(unsigned int n, char *s) | ||
197 | { | ||
198 | int i; | ||
199 | |||
200 | EINA_SAFETY_ON_NULL_RETURN_VAL(s, 0); | ||
201 | |||
202 | i = 0; | ||
203 | do { | ||
204 | s[i++] = look_up_table[n & 0xF]; | ||
205 | } while ((n >>= 4) > 0); | ||
206 | |||
207 | s[i] = '\0'; | ||
208 | |||
209 | reverse(s, i); | ||
210 | |||
211 | return i; | ||
212 | } | ||
213 | |||
214 | EAPI Eina_Bool | ||
215 | eina_convert_atod(const char *src, int length, long long *m, long *e) | ||
216 | { | ||
217 | const char *str = src; | ||
218 | long long mantisse; | ||
219 | long exponent; | ||
220 | int nbr_decimals = 0; | ||
221 | int sign = 1; | ||
222 | |||
223 | EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); | ||
224 | EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); | ||
225 | EINA_SAFETY_ON_NULL_RETURN_VAL(e, EINA_FALSE); | ||
226 | |||
227 | if (length <= 0) | ||
228 | goto on_length_error; | ||
229 | |||
230 | /* Compute the mantisse. */ | ||
231 | if (*str == '-') | ||
232 | { | ||
233 | sign = -1; | ||
234 | str++; | ||
235 | length--; | ||
236 | } | ||
237 | |||
238 | if (length <= 2) | ||
239 | goto on_length_error; | ||
240 | |||
241 | if (strncmp(str, "0x", 2)) | ||
242 | { | ||
243 | eina_error_set(EINA_ERROR_CONVERT_0X_NOT_FOUND); | ||
244 | DBG("'0x' not found in '%s'", src); | ||
245 | return EINA_FALSE; | ||
246 | } | ||
247 | |||
248 | str += 2; | ||
249 | length -= 2; | ||
250 | |||
251 | mantisse = HEXA_TO_INT(*str); | ||
252 | |||
253 | str++; | ||
254 | length--; if (length <= 0) | ||
255 | goto on_length_error; | ||
256 | |||
257 | if (*str == '.') | ||
258 | for (str++, length--; | ||
259 | length > 0 && *str != 'p'; | ||
260 | ++str, --length, ++nbr_decimals) | ||
261 | { | ||
262 | mantisse <<= 4; | ||
263 | mantisse += HEXA_TO_INT(*str); | ||
264 | } | ||
265 | |||
266 | if (sign < 0) | ||
267 | mantisse = -mantisse; | ||
268 | |||
269 | /* Compute the exponent. */ | ||
270 | if (*str != 'p') | ||
271 | { | ||
272 | eina_error_set(EINA_ERROR_CONVERT_P_NOT_FOUND); | ||
273 | DBG("'p' not found in '%s'", src); | ||
274 | return EINA_FALSE; | ||
275 | } | ||
276 | |||
277 | sign = +1; | ||
278 | |||
279 | str++; | ||
280 | length--; if (length <= 0) | ||
281 | goto on_length_error; | ||
282 | |||
283 | if (strchr("-+", *str)) | ||
284 | { | ||
285 | sign = (*str == '-') ? -1 : +1; | ||
286 | |||
287 | str++; length--; | ||
288 | } | ||
289 | |||
290 | for (exponent = 0; length > 0 && *str != '\0'; ++str, --length) | ||
291 | { | ||
292 | exponent *= 10; | ||
293 | exponent += *str - '0'; | ||
294 | } | ||
295 | |||
296 | if (length < 0) | ||
297 | goto on_length_error; | ||
298 | |||
299 | if (sign < 0) | ||
300 | exponent = -exponent; | ||
301 | |||
302 | *m = mantisse; | ||
303 | *e = exponent - (nbr_decimals << 2); | ||
304 | |||
305 | return EINA_TRUE; | ||
306 | |||
307 | on_length_error: | ||
308 | eina_error_set(EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH); | ||
309 | return EINA_FALSE; | ||
310 | } | ||
311 | |||
312 | EAPI int | ||
313 | eina_convert_dtoa(double d, char *des) | ||
314 | { | ||
315 | int length = 0; | ||
316 | int p; | ||
317 | int i; | ||
318 | |||
319 | EINA_SAFETY_ON_NULL_RETURN_VAL(des, EINA_FALSE); | ||
320 | |||
321 | if (d < 0.0) | ||
322 | { | ||
323 | *(des++) = '-'; | ||
324 | d = -d; | ||
325 | length++; | ||
326 | } | ||
327 | |||
328 | d = frexp(d, &p); | ||
329 | |||
330 | if (p) | ||
331 | { | ||
332 | d *= 2; | ||
333 | p -= 1; | ||
334 | } | ||
335 | |||
336 | *(des++) = '0'; | ||
337 | *(des++) = 'x'; | ||
338 | *(des++) = look_up_table[(size_t)d]; | ||
339 | *(des++) = '.'; | ||
340 | length += 4; | ||
341 | |||
342 | for (i = 0; i < 16; i++, length++) | ||
343 | { | ||
344 | d -= floor(d); | ||
345 | d *= 16; | ||
346 | *(des++) = look_up_table[(size_t)d]; | ||
347 | } | ||
348 | |||
349 | while (*(des - 1) == '0') | ||
350 | { | ||
351 | des--; | ||
352 | length--; | ||
353 | } | ||
354 | |||
355 | if (*(des - 1) == '.') | ||
356 | { | ||
357 | des--; | ||
358 | length--; | ||
359 | } | ||
360 | |||
361 | *(des++) = 'p'; | ||
362 | if (p < 0) | ||
363 | { | ||
364 | *(des++) = '-'; | ||
365 | p = -p; | ||
366 | } | ||
367 | else | ||
368 | *(des++) = '+'; | ||
369 | |||
370 | length += 2; | ||
371 | |||
372 | return length + eina_convert_itoa(p, des); | ||
373 | } | ||
374 | |||
375 | EAPI int | ||
376 | eina_convert_fptoa(Eina_F32p32 fp, char *des) | ||
377 | { | ||
378 | int length = 0; | ||
379 | int p = 0; | ||
380 | int i; | ||
381 | |||
382 | EINA_SAFETY_ON_NULL_RETURN_VAL(des, EINA_FALSE); | ||
383 | |||
384 | if (fp == 0) | ||
385 | { | ||
386 | memcpy(des, "0x0p+0", 7); | ||
387 | return 7; | ||
388 | } | ||
389 | |||
390 | if (fp < 0) | ||
391 | { | ||
392 | *(des++) = '-'; | ||
393 | fp = -fp; | ||
394 | length++; | ||
395 | } | ||
396 | |||
397 | /* fp >= 1 */ | ||
398 | if (fp >= 0x0000000100000000LL) | ||
399 | while (fp >= 0x0000000100000000LL) | ||
400 | { | ||
401 | p++; | ||
402 | /* fp /= 2 */ | ||
403 | fp >>= 1; | ||
404 | } /* fp < 0.5 */ | ||
405 | else if (fp < 0x80000000) | ||
406 | while (fp < 0x80000000) | ||
407 | { | ||
408 | p--; | ||
409 | /* fp *= 2 */ | ||
410 | fp <<= 1; | ||
411 | } | ||
412 | |||
413 | if (p) | ||
414 | { | ||
415 | p--; | ||
416 | /* fp *= 2 */ | ||
417 | fp <<= 1; | ||
418 | } | ||
419 | |||
420 | *(des++) = '0'; | ||
421 | *(des++) = 'x'; | ||
422 | *(des++) = look_up_table[fp >> 32]; | ||
423 | *(des++) = '.'; | ||
424 | length += 4; | ||
425 | |||
426 | for (i = 0; i < 16; i++, length++) | ||
427 | { | ||
428 | fp &= 0x00000000ffffffffLL; | ||
429 | fp <<= 4; /* fp *= 16 */ | ||
430 | *(des++) = look_up_table[fp >> 32]; | ||
431 | } | ||
432 | |||
433 | while (*(des - 1) == '0') | ||
434 | { | ||
435 | des--; | ||
436 | length--; | ||
437 | } | ||
438 | |||
439 | if (*(des - 1) == '.') | ||
440 | { | ||
441 | des--; | ||
442 | length--; | ||
443 | } | ||
444 | |||
445 | *(des++) = 'p'; | ||
446 | if (p < 0) | ||
447 | { | ||
448 | *(des++) = '-'; | ||
449 | p = -p; | ||
450 | } | ||
451 | else | ||
452 | *(des++) = '+'; | ||
453 | |||
454 | length += 2; | ||
455 | |||
456 | return length + eina_convert_itoa(p, des); | ||
457 | } | ||
458 | |||
459 | EAPI Eina_Bool | ||
460 | eina_convert_atofp(const char *src, int length, Eina_F32p32 *fp) | ||
461 | { | ||
462 | long long m; | ||
463 | long e; | ||
464 | |||
465 | if (!eina_convert_atod(src, length, &m, &e)) | ||
466 | return EINA_FALSE; | ||
467 | |||
468 | if (!fp) | ||
469 | return EINA_TRUE; | ||
470 | |||
471 | e += 32; | ||
472 | |||
473 | if (e > 0) | ||
474 | *fp = m << e; | ||
475 | else | ||
476 | *fp = m >> -e; | ||
477 | |||
478 | return EINA_TRUE; | ||
479 | } | ||
480 | |||
481 | /** | ||
482 | * @} | ||
483 | */ | ||
diff --git a/libraries/eina/src/lib/eina_counter.c b/libraries/eina/src/lib/eina_counter.c deleted file mode 100644 index 6ca9417..0000000 --- a/libraries/eina/src/lib/eina_counter.c +++ /dev/null | |||
@@ -1,362 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Cedric Bail, Vincent Torri | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <string.h> | ||
26 | #include <stdarg.h> | ||
27 | #ifndef _WIN32 | ||
28 | # include <time.h> | ||
29 | # include <sys/time.h> | ||
30 | #else | ||
31 | # define WIN32_LEAN_AND_MEAN | ||
32 | # include <windows.h> | ||
33 | # undef WIN32_LEAN_AND_MEAN | ||
34 | #endif /* _WIN2 */ | ||
35 | |||
36 | #include "eina_config.h" | ||
37 | #include "eina_private.h" | ||
38 | #include "eina_inlist.h" | ||
39 | #include "eina_error.h" | ||
40 | |||
41 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
42 | #include "eina_safety_checks.h" | ||
43 | #include "eina_counter.h" | ||
44 | |||
45 | #ifdef HAVE_ESCAPE | ||
46 | # include <Escape.h> | ||
47 | #endif | ||
48 | |||
49 | /*============================================================================* | ||
50 | * Local * | ||
51 | *============================================================================*/ | ||
52 | |||
53 | /** | ||
54 | * @cond LOCAL | ||
55 | */ | ||
56 | |||
57 | #ifndef _WIN32 | ||
58 | typedef struct timespec Eina_Nano_Time; | ||
59 | #else | ||
60 | typedef LARGE_INTEGER Eina_Nano_Time; | ||
61 | #endif | ||
62 | |||
63 | typedef struct _Eina_Clock Eina_Clock; | ||
64 | |||
65 | struct _Eina_Counter | ||
66 | { | ||
67 | EINA_INLIST; | ||
68 | |||
69 | Eina_Inlist *clocks; | ||
70 | const char *name; | ||
71 | }; | ||
72 | |||
73 | struct _Eina_Clock | ||
74 | { | ||
75 | EINA_INLIST; | ||
76 | |||
77 | Eina_Nano_Time start; | ||
78 | Eina_Nano_Time end; | ||
79 | int specimen; | ||
80 | |||
81 | Eina_Bool valid; | ||
82 | }; | ||
83 | |||
84 | #ifndef _WIN32 | ||
85 | static inline int | ||
86 | _eina_counter_time_get(Eina_Nano_Time *tp) | ||
87 | { | ||
88 | # if defined(CLOCK_PROCESS_CPUTIME_ID) | ||
89 | return clock_gettime(CLOCK_PROCESS_CPUTIME_ID, tp); | ||
90 | # elif defined(CLOCK_PROF) | ||
91 | return clock_gettime(CLOCK_PROF, tp); | ||
92 | # elif defined(CLOCK_REALTIME) | ||
93 | return clock_gettime(CLOCK_REALTIME, tp); | ||
94 | # else | ||
95 | struct timeval tv; | ||
96 | |||
97 | if (gettimeofday(&tv, NULL)) | ||
98 | return -1; | ||
99 | |||
100 | tp->tv_sec = tv.tv_sec; | ||
101 | tp->tv_nsec = tv.tv_usec * 1000L; | ||
102 | |||
103 | return 0; | ||
104 | # endif | ||
105 | } | ||
106 | #else | ||
107 | static const char EINA_ERROR_COUNTER_WINDOWS_STR[] = | ||
108 | "Change your OS, you moron !"; | ||
109 | static int EINA_ERROR_COUNTER_WINDOWS = 0; | ||
110 | static LARGE_INTEGER _eina_counter_frequency; | ||
111 | |||
112 | static inline int | ||
113 | _eina_counter_time_get(Eina_Nano_Time *tp) | ||
114 | { | ||
115 | return QueryPerformanceCounter(tp); | ||
116 | } | ||
117 | #endif /* _WIN2 */ | ||
118 | |||
119 | static char * | ||
120 | _eina_counter_asiprintf(char *base, int *position, const char *format, ...) | ||
121 | { | ||
122 | char *tmp, *result; | ||
123 | int size = 32; | ||
124 | int n; | ||
125 | va_list ap; | ||
126 | |||
127 | tmp = realloc(base, sizeof (char) * (*position + size)); | ||
128 | if (!tmp) | ||
129 | return base; | ||
130 | |||
131 | result = tmp; | ||
132 | |||
133 | while (1) | ||
134 | { | ||
135 | va_start(ap, format); | ||
136 | n = vsnprintf(result + *position, size, format, ap); | ||
137 | va_end(ap); | ||
138 | |||
139 | if (n > -1 && n < size) | ||
140 | { | ||
141 | /* If we always have glibc > 2.2, we could just return *position += n. */ | ||
142 | *position += strlen(result + *position); | ||
143 | return result; | ||
144 | } | ||
145 | |||
146 | if (n > -1) | ||
147 | size = n + 1; | ||
148 | else | ||
149 | size <<= 1; | ||
150 | |||
151 | tmp = realloc(result, sizeof (char) * (*position + size)); | ||
152 | if (!tmp) | ||
153 | return result; | ||
154 | |||
155 | result = tmp; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | /** | ||
160 | * @endcond | ||
161 | */ | ||
162 | |||
163 | /*============================================================================* | ||
164 | * Global * | ||
165 | *============================================================================*/ | ||
166 | |||
167 | /** | ||
168 | * @internal | ||
169 | * @brief Initialize the eina counter internal structure. | ||
170 | * | ||
171 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
172 | * | ||
173 | * This function shuts down the counter module set up by | ||
174 | * eina_counter_init(). It is called by eina_init(). | ||
175 | * | ||
176 | * This function sets up the error module of Eina and only on Windows, | ||
177 | * it initializes the high precision timer. It also registers, only on | ||
178 | * Windows, the error #EINA_ERROR_COUNTER_WINDOWS. It is also called | ||
179 | * by eina_init(). It returns 0 on failure, otherwise it returns the | ||
180 | * number of times it has already been called. | ||
181 | * | ||
182 | * @see eina_init() | ||
183 | */ | ||
184 | Eina_Bool | ||
185 | eina_counter_init(void) | ||
186 | { | ||
187 | #ifdef _WIN32 | ||
188 | EINA_ERROR_COUNTER_WINDOWS = eina_error_msg_static_register( | ||
189 | EINA_ERROR_COUNTER_WINDOWS_STR); | ||
190 | if (!QueryPerformanceFrequency(&_eina_counter_frequency)) | ||
191 | { | ||
192 | eina_error_set(EINA_ERROR_COUNTER_WINDOWS); | ||
193 | return EINA_FALSE; | ||
194 | } | ||
195 | |||
196 | #endif /* _WIN2 */ | ||
197 | return EINA_TRUE; | ||
198 | } | ||
199 | |||
200 | /** | ||
201 | * @internal | ||
202 | * @brief Shut down the counter module. | ||
203 | * | ||
204 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
205 | * | ||
206 | * This function shuts down the counter module set up by | ||
207 | * eina_counter_init(). It is called by eina_shutdown(). | ||
208 | * | ||
209 | * @see eina_shutdown() | ||
210 | */ | ||
211 | Eina_Bool | ||
212 | eina_counter_shutdown(void) | ||
213 | { | ||
214 | return EINA_TRUE; | ||
215 | } | ||
216 | |||
217 | /*============================================================================* | ||
218 | * API * | ||
219 | *============================================================================*/ | ||
220 | |||
221 | EAPI Eina_Counter * | ||
222 | eina_counter_new(const char *name) | ||
223 | { | ||
224 | Eina_Counter *counter; | ||
225 | size_t length; | ||
226 | |||
227 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); | ||
228 | |||
229 | length = strlen(name) + 1; | ||
230 | |||
231 | eina_error_set(0); | ||
232 | counter = calloc(1, sizeof (Eina_Counter) + length); | ||
233 | if (!counter) | ||
234 | { | ||
235 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
236 | return NULL; | ||
237 | } | ||
238 | |||
239 | counter->name = (char *)(counter + 1); | ||
240 | memcpy((char *)counter->name, name, length); | ||
241 | |||
242 | return counter; | ||
243 | } | ||
244 | |||
245 | EAPI void | ||
246 | eina_counter_free(Eina_Counter *counter) | ||
247 | { | ||
248 | EINA_SAFETY_ON_NULL_RETURN(counter); | ||
249 | |||
250 | while (counter->clocks) | ||
251 | { | ||
252 | Eina_Clock *clk = (Eina_Clock *)counter->clocks; | ||
253 | |||
254 | counter->clocks = eina_inlist_remove(counter->clocks, counter->clocks); | ||
255 | free(clk); | ||
256 | } | ||
257 | |||
258 | free(counter); | ||
259 | } | ||
260 | |||
261 | EAPI void | ||
262 | eina_counter_start(Eina_Counter *counter) | ||
263 | { | ||
264 | Eina_Clock *clk; | ||
265 | Eina_Nano_Time tp; | ||
266 | |||
267 | EINA_SAFETY_ON_NULL_RETURN(counter); | ||
268 | if (_eina_counter_time_get(&tp) != 0) | ||
269 | return; | ||
270 | |||
271 | eina_error_set(0); | ||
272 | clk = calloc(1, sizeof (Eina_Clock)); | ||
273 | if (!clk) | ||
274 | { | ||
275 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
276 | return; | ||
277 | } | ||
278 | |||
279 | counter->clocks = eina_inlist_prepend(counter->clocks, EINA_INLIST_GET(clk)); | ||
280 | |||
281 | clk->valid = EINA_FALSE; | ||
282 | clk->start = tp; | ||
283 | } | ||
284 | |||
285 | EAPI void | ||
286 | eina_counter_stop(Eina_Counter *counter, int specimen) | ||
287 | { | ||
288 | Eina_Clock *clk; | ||
289 | Eina_Nano_Time tp; | ||
290 | |||
291 | EINA_SAFETY_ON_NULL_RETURN(counter); | ||
292 | if (_eina_counter_time_get(&tp) != 0) | ||
293 | return; | ||
294 | |||
295 | clk = (Eina_Clock *)counter->clocks; | ||
296 | |||
297 | if (!clk || clk->valid == EINA_TRUE) | ||
298 | return; | ||
299 | |||
300 | clk->end = tp; | ||
301 | clk->specimen = specimen; | ||
302 | clk->valid = EINA_TRUE; | ||
303 | } | ||
304 | |||
305 | EAPI char * | ||
306 | eina_counter_dump(Eina_Counter *counter) | ||
307 | { | ||
308 | Eina_Clock *clk; | ||
309 | char *result = NULL; | ||
310 | int position = 0; | ||
311 | |||
312 | EINA_SAFETY_ON_NULL_RETURN_VAL(counter, NULL); | ||
313 | |||
314 | result = _eina_counter_asiprintf( | ||
315 | result, | ||
316 | &position, | ||
317 | "# specimen\texperiment time\tstarting time\tending time\n"); | ||
318 | if (!result) | ||
319 | return NULL; | ||
320 | |||
321 | EINA_INLIST_REVERSE_FOREACH(counter->clocks, clk) | ||
322 | { | ||
323 | long int start; | ||
324 | long int end; | ||
325 | long int diff; | ||
326 | |||
327 | if (clk->valid == EINA_FALSE) | ||
328 | continue; | ||
329 | |||
330 | #ifndef _WIN32 | ||
331 | start = clk->start.tv_sec * 1000000000 + clk->start.tv_nsec; | ||
332 | end = clk->end.tv_sec * 1000000000 + clk->end.tv_nsec; | ||
333 | diff = | ||
334 | (clk->end.tv_sec - | ||
335 | clk->start.tv_sec) * 1000000000 + clk->end.tv_nsec - | ||
336 | clk->start.tv_nsec; | ||
337 | #else | ||
338 | start = | ||
339 | (long int)(((long long int)clk->start.QuadPart * | ||
340 | 1000000000ll) / | ||
341 | (long long int)_eina_counter_frequency.QuadPart); | ||
342 | end = | ||
343 | (long int)(((long long int)clk->end.QuadPart * | ||
344 | 1000000000LL) / | ||
345 | (long long int)_eina_counter_frequency.QuadPart); | ||
346 | diff = | ||
347 | (long int)(((long long int)(clk->end.QuadPart - | ||
348 | clk->start.QuadPart) * | ||
349 | 1000000000LL) / | ||
350 | (long long int)_eina_counter_frequency.QuadPart); | ||
351 | #endif /* _WIN2 */ | ||
352 | |||
353 | result = _eina_counter_asiprintf(result, &position, | ||
354 | "%i\t%li\t%li\t%li\n", | ||
355 | clk->specimen, | ||
356 | diff, | ||
357 | start, | ||
358 | end); | ||
359 | } | ||
360 | |||
361 | return result; | ||
362 | } | ||
diff --git a/libraries/eina/src/lib/eina_cpu.c b/libraries/eina/src/lib/eina_cpu.c deleted file mode 100644 index 5b190e4..0000000 --- a/libraries/eina/src/lib/eina_cpu.c +++ /dev/null | |||
@@ -1,207 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2007-2008 Jorge Luis Zapata Muga | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #ifdef EFL_HAVE_THREADS | ||
24 | # ifdef _WIN32 | ||
25 | # define WIN32_LEAN_AND_MEAN | ||
26 | # include <windows.h> | ||
27 | # elif defined (__sun) || defined(__GNU__) | ||
28 | # include <unistd.h> | ||
29 | # elif defined (__FreeBSD__) || defined (__OpenBSD__) || \ | ||
30 | defined (__NetBSD__) || defined (__DragonFly__) || defined (__MacOSX__) || \ | ||
31 | (defined (__MACH__) && defined (__APPLE__)) | ||
32 | # include <unistd.h> | ||
33 | # include <sys/param.h> | ||
34 | # include <sys/sysctl.h> | ||
35 | # elif defined (__linux__) || defined(__GLIBC__) | ||
36 | # include <sched.h> | ||
37 | # endif | ||
38 | # ifdef EFL_HAVE_POSIX_THREADS | ||
39 | # include <pthread.h> | ||
40 | # endif | ||
41 | |||
42 | # define TH_MAX 8 | ||
43 | #endif | ||
44 | |||
45 | #include <stdio.h> | ||
46 | #include <string.h> | ||
47 | #include <errno.h> | ||
48 | |||
49 | #include "eina_cpu.h" | ||
50 | |||
51 | /*============================================================================* | ||
52 | * Local * | ||
53 | *============================================================================*/ | ||
54 | |||
55 | /* FIXME this ifdefs should be replaced */ | ||
56 | #if defined(__i386__) || defined(__x86_64__) | ||
57 | /* We save ebx and restore it to be PIC compatible */ | ||
58 | static inline void _x86_cpuid(int op, int *a, int *b, int *c, int *d) | ||
59 | { | ||
60 | asm volatile ( | ||
61 | #if defined(__x86_64__) | ||
62 | "pushq %%rbx \n\t" /* save %ebx */ | ||
63 | #else | ||
64 | "pushl %%ebx \n\t" /* save %ebx */ | ||
65 | #endif | ||
66 | "cpuid \n\t" | ||
67 | "movl %%ebx, %1 \n\t" /* save what cpuid just put in %ebx */ | ||
68 | #if defined(__x86_64__) | ||
69 | "popq %%rbx \n\t" /* restore the old %ebx */ | ||
70 | #else | ||
71 | "popl %%ebx \n\t" /* restore the old %ebx */ | ||
72 | #endif | ||
73 | : "=a" (*a), "=r" (*b), "=c" (*c), "=d" (*d) | ||
74 | : "a" (op) | ||
75 | : "cc"); | ||
76 | } | ||
77 | |||
78 | static | ||
79 | void _x86_simd(Eina_Cpu_Features *features) | ||
80 | { | ||
81 | int a, b, c, d; | ||
82 | |||
83 | _x86_cpuid(1, &a, &b, &c, &d); | ||
84 | /* | ||
85 | * edx | ||
86 | * 18 = PN (Processor Number) | ||
87 | * 19 = CLFlush (Cache Line Flush) | ||
88 | * 23 = MMX | ||
89 | * 25 = SSE | ||
90 | * 26 = SSE2 | ||
91 | * 28 = HTT (Hyper Threading) | ||
92 | * ecx | ||
93 | * 0 = SSE3 | ||
94 | */ | ||
95 | if ((d >> 23) & 1) | ||
96 | *features |= EINA_CPU_MMX; | ||
97 | |||
98 | if ((d >> 25) & 1) | ||
99 | *features |= EINA_CPU_SSE; | ||
100 | |||
101 | if ((d >> 26) & 1) | ||
102 | *features |= EINA_CPU_SSE2; | ||
103 | |||
104 | if (c & 1) | ||
105 | *features |= EINA_CPU_SSE3; | ||
106 | } | ||
107 | #endif | ||
108 | |||
109 | /*============================================================================* | ||
110 | * Global * | ||
111 | *============================================================================*/ | ||
112 | |||
113 | /*============================================================================* | ||
114 | * API * | ||
115 | *============================================================================*/ | ||
116 | |||
117 | /* FIXME the features checks should be called when this function is called? | ||
118 | * or make it static by doing eina_cpu_init() and return a local var | ||
119 | */ | ||
120 | /** | ||
121 | * | ||
122 | * @return | ||
123 | */ | ||
124 | EAPI Eina_Cpu_Features eina_cpu_features_get(void) | ||
125 | { | ||
126 | Eina_Cpu_Features ecf = 0; | ||
127 | #if defined(__i386__) || defined(__x86_64__) | ||
128 | _x86_simd(&ecf); | ||
129 | #endif | ||
130 | return ecf; | ||
131 | } | ||
132 | |||
133 | EAPI int eina_cpu_count(void) | ||
134 | { | ||
135 | #ifdef EFL_HAVE_THREADS | ||
136 | |||
137 | # if defined (_WIN32) | ||
138 | SYSTEM_INFO sysinfo; | ||
139 | |||
140 | GetSystemInfo(&sysinfo); | ||
141 | return sysinfo.dwNumberOfProcessors; | ||
142 | |||
143 | # elif defined (__sun) || defined(__GNU__) | ||
144 | /* | ||
145 | * _SC_NPROCESSORS_ONLN: number of processors that are online, that | ||
146 | is available when sysconf is called. The number | ||
147 | of cpu can change by admins. | ||
148 | * _SC_NPROCESSORS_CONF: maximum number of processors that are available | ||
149 | to the current OS instance. That number can be | ||
150 | change after a reboot. | ||
151 | * _SC_NPROCESSORS_MAX : maximum number of processors that are on the | ||
152 | motherboard. | ||
153 | */ | ||
154 | return sysconf(_SC_NPROCESSORS_ONLN); | ||
155 | |||
156 | # elif defined (__FreeBSD__) || defined (__OpenBSD__) || \ | ||
157 | defined (__NetBSD__) || defined (__DragonFly__) || defined (__MacOSX__) || \ | ||
158 | (defined (__MACH__) && defined (__APPLE__)) | ||
159 | |||
160 | int mib[4]; | ||
161 | int cpus; | ||
162 | size_t len = sizeof(cpus); | ||
163 | |||
164 | mib[0] = CTL_HW; | ||
165 | #ifdef HW_AVAILCPU | ||
166 | mib[1] = HW_AVAILCPU; | ||
167 | #else | ||
168 | mib[1] = HW_NCPU; | ||
169 | #endif | ||
170 | sysctl(mib, 2, &cpus, &len, NULL, 0); | ||
171 | if (cpus < 1) | ||
172 | cpus = 1; | ||
173 | |||
174 | return cpus; | ||
175 | |||
176 | # elif defined (__linux__) || defined(__GLIBC__) | ||
177 | cpu_set_t cpu; | ||
178 | int i; | ||
179 | static int cpus = 0; | ||
180 | |||
181 | if (cpus != 0) | ||
182 | return cpus; | ||
183 | |||
184 | CPU_ZERO(&cpu); | ||
185 | if (sched_getaffinity(0, sizeof(cpu), &cpu) != 0) | ||
186 | { | ||
187 | fprintf(stderr, "[Eina] could not get cpu affinity: %s\n", | ||
188 | strerror(errno)); | ||
189 | return 1; | ||
190 | } | ||
191 | |||
192 | for (i = 0; i < TH_MAX; i++) | ||
193 | { | ||
194 | if (CPU_ISSET(i, &cpu)) | ||
195 | cpus = i + 1; | ||
196 | else | ||
197 | break; | ||
198 | } | ||
199 | return cpus; | ||
200 | |||
201 | # else | ||
202 | # error "eina_cpu_count() error: Platform not supported" | ||
203 | # endif | ||
204 | #else | ||
205 | return 1; | ||
206 | #endif | ||
207 | } | ||
diff --git a/libraries/eina/src/lib/eina_error.c b/libraries/eina/src/lib/eina_error.c deleted file mode 100644 index 428c414..0000000 --- a/libraries/eina/src/lib/eina_error.c +++ /dev/null | |||
@@ -1,279 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2007-2008 Jorge Luis Zapata Muga, Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <string.h> | ||
25 | #include <stdlib.h> | ||
26 | |||
27 | #ifdef HAVE_EVIL | ||
28 | # include <Evil.h> | ||
29 | #endif | ||
30 | |||
31 | #include "eina_config.h" | ||
32 | #include "eina_private.h" | ||
33 | |||
34 | |||
35 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
36 | #include "eina_safety_checks.h" | ||
37 | #include "eina_error.h" | ||
38 | #include "eina_stringshare.h" | ||
39 | |||
40 | /* TODO | ||
41 | * + add a wrapper for assert? | ||
42 | * + add common error numbers, messages | ||
43 | * + add a calltrace of errors, not only store the last error but a list of them | ||
44 | * and also store the function that set it | ||
45 | */ | ||
46 | |||
47 | /*============================================================================* | ||
48 | * Local * | ||
49 | *============================================================================*/ | ||
50 | |||
51 | /** | ||
52 | * @cond LOCAL | ||
53 | */ | ||
54 | |||
55 | typedef struct _Eina_Error_Message Eina_Error_Message; | ||
56 | struct _Eina_Error_Message | ||
57 | { | ||
58 | Eina_Bool string_allocated; | ||
59 | const char *string; | ||
60 | }; | ||
61 | |||
62 | static Eina_Error_Message *_eina_errors = NULL; | ||
63 | static size_t _eina_errors_count = 0; | ||
64 | static size_t _eina_errors_allocated = 0; | ||
65 | static Eina_Error _eina_last_error; | ||
66 | |||
67 | static Eina_Error_Message * | ||
68 | _eina_error_msg_alloc(void) | ||
69 | { | ||
70 | size_t idx; | ||
71 | |||
72 | if (_eina_errors_count == _eina_errors_allocated) | ||
73 | { | ||
74 | void *tmp; | ||
75 | size_t size; | ||
76 | |||
77 | if (EINA_UNLIKELY(_eina_errors_allocated == 0)) | ||
78 | size = 24; | ||
79 | else | ||
80 | size = _eina_errors_allocated + 8; | ||
81 | |||
82 | tmp = realloc(_eina_errors, sizeof(Eina_Error_Message) * size); | ||
83 | if (!tmp) | ||
84 | return NULL; | ||
85 | |||
86 | _eina_errors = tmp; | ||
87 | _eina_errors_allocated = size; | ||
88 | } | ||
89 | |||
90 | idx = _eina_errors_count; | ||
91 | _eina_errors_count++; | ||
92 | return _eina_errors + idx; | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * @endcond | ||
97 | */ | ||
98 | |||
99 | |||
100 | /*============================================================================* | ||
101 | * Global * | ||
102 | *============================================================================*/ | ||
103 | |||
104 | /** | ||
105 | * @cond LOCAL | ||
106 | */ | ||
107 | |||
108 | EAPI Eina_Error EINA_ERROR_OUT_OF_MEMORY = 0; | ||
109 | |||
110 | static const char EINA_ERROR_OUT_OF_MEMORY_STR[] = "Out of memory"; | ||
111 | |||
112 | /** | ||
113 | * @endcond | ||
114 | */ | ||
115 | |||
116 | /** | ||
117 | * @internal | ||
118 | * @brief Initialize the error module. | ||
119 | * | ||
120 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
121 | * | ||
122 | * This function sets up the error module of Eina. It is called by | ||
123 | * eina_init(). | ||
124 | * | ||
125 | * This function registers the error #EINA_ERROR_OUT_OF_MEMORY. | ||
126 | * | ||
127 | * @see eina_init() | ||
128 | */ | ||
129 | Eina_Bool | ||
130 | eina_error_init(void) | ||
131 | { | ||
132 | /* TODO register the eina's basic errors */ | ||
133 | EINA_ERROR_OUT_OF_MEMORY = eina_error_msg_static_register( | ||
134 | EINA_ERROR_OUT_OF_MEMORY_STR); | ||
135 | return EINA_TRUE; | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * @internal | ||
140 | * @brief Shut down the error module. | ||
141 | * | ||
142 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
143 | * | ||
144 | * This function shuts down the error module set up by | ||
145 | * eina_error_init(). It is called by eina_shutdown(). | ||
146 | * | ||
147 | * @see eina_shutdown() | ||
148 | */ | ||
149 | Eina_Bool | ||
150 | eina_error_shutdown(void) | ||
151 | { | ||
152 | Eina_Error_Message *eem, *eem_end; | ||
153 | |||
154 | eem = _eina_errors; | ||
155 | eem_end = eem + _eina_errors_count; | ||
156 | |||
157 | for (; eem < eem_end; eem++) | ||
158 | if (eem->string_allocated) | ||
159 | eina_stringshare_del(eem->string); | ||
160 | |||
161 | free(_eina_errors); | ||
162 | _eina_errors = NULL; | ||
163 | _eina_errors_count = 0; | ||
164 | _eina_errors_allocated = 0; | ||
165 | |||
166 | return EINA_TRUE; | ||
167 | } | ||
168 | |||
169 | /*============================================================================* | ||
170 | * API * | ||
171 | *============================================================================*/ | ||
172 | |||
173 | EAPI Eina_Error | ||
174 | eina_error_msg_register(const char *msg) | ||
175 | { | ||
176 | Eina_Error_Message *eem; | ||
177 | |||
178 | EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0); | ||
179 | |||
180 | eem = _eina_error_msg_alloc(); | ||
181 | if (!eem) | ||
182 | return 0; | ||
183 | |||
184 | eem->string_allocated = EINA_TRUE; | ||
185 | eem->string = eina_stringshare_add(msg); | ||
186 | if (!eem->string) | ||
187 | { | ||
188 | _eina_errors_count--; | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | return _eina_errors_count; /* identifier = index + 1 (== _count). */ | ||
193 | } | ||
194 | |||
195 | EAPI Eina_Error | ||
196 | eina_error_msg_static_register(const char *msg) | ||
197 | { | ||
198 | Eina_Error_Message *eem; | ||
199 | |||
200 | EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0); | ||
201 | |||
202 | eem = _eina_error_msg_alloc(); | ||
203 | if (!eem) | ||
204 | return 0; | ||
205 | |||
206 | eem->string_allocated = EINA_FALSE; | ||
207 | eem->string = msg; | ||
208 | return _eina_errors_count; /* identifier = index + 1 (== _count). */ | ||
209 | } | ||
210 | |||
211 | EAPI Eina_Bool | ||
212 | eina_error_msg_modify(Eina_Error error, const char *msg) | ||
213 | { | ||
214 | EINA_SAFETY_ON_NULL_RETURN_VAL(msg, EINA_FALSE); | ||
215 | if (error < 1) | ||
216 | return EINA_FALSE; | ||
217 | |||
218 | if ((size_t)error > _eina_errors_count) | ||
219 | return EINA_FALSE; | ||
220 | |||
221 | if (_eina_errors[error - 1].string_allocated) | ||
222 | { | ||
223 | const char *tmp; | ||
224 | |||
225 | if (!(tmp = eina_stringshare_add(msg))) | ||
226 | return EINA_FALSE; | ||
227 | |||
228 | eina_stringshare_del(_eina_errors[error - 1].string); | ||
229 | _eina_errors[error - 1].string = tmp; | ||
230 | return EINA_TRUE; | ||
231 | } | ||
232 | |||
233 | _eina_errors[error - 1].string = msg; | ||
234 | return EINA_TRUE; | ||
235 | } | ||
236 | |||
237 | EAPI const char * | ||
238 | eina_error_msg_get(Eina_Error error) | ||
239 | { | ||
240 | if (error < 1) | ||
241 | return NULL; | ||
242 | |||
243 | if ((size_t)error > _eina_errors_count) | ||
244 | return NULL; | ||
245 | |||
246 | return _eina_errors[error - 1].string; | ||
247 | } | ||
248 | |||
249 | EAPI Eina_Error | ||
250 | eina_error_get(void) | ||
251 | { | ||
252 | return _eina_last_error; | ||
253 | } | ||
254 | |||
255 | EAPI void | ||
256 | eina_error_set(Eina_Error err) | ||
257 | { | ||
258 | _eina_last_error = err; | ||
259 | } | ||
260 | |||
261 | EAPI Eina_Error | ||
262 | eina_error_find(const char *msg) | ||
263 | { | ||
264 | size_t i; | ||
265 | |||
266 | EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0); | ||
267 | |||
268 | for (i = 0; i < _eina_errors_count; i++) | ||
269 | { | ||
270 | if (_eina_errors[i].string_allocated) | ||
271 | { | ||
272 | if (_eina_errors[i].string == msg) | ||
273 | return i + 1; | ||
274 | } | ||
275 | if (!strcmp(_eina_errors[i].string, msg)) | ||
276 | return i + 1; | ||
277 | } | ||
278 | return 0; | ||
279 | } | ||
diff --git a/libraries/eina/src/lib/eina_file.c b/libraries/eina/src/lib/eina_file.c deleted file mode 100644 index c465301..0000000 --- a/libraries/eina/src/lib/eina_file.c +++ /dev/null | |||
@@ -1,1359 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2007-2008 Jorge Luis Zapata Muga, Vincent Torri | ||
3 | * Copyright (C) 2010-2011 Cedric Bail | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Lesser General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2.1 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This library is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * Lesser General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Lesser General Public | ||
16 | * License along with this library; | ||
17 | * if not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #ifdef HAVE_CONFIG_H | ||
21 | # include "config.h" | ||
22 | #endif | ||
23 | |||
24 | #ifdef HAVE_ALLOCA_H | ||
25 | # include <alloca.h> | ||
26 | #elif defined __GNUC__ | ||
27 | # define alloca __builtin_alloca | ||
28 | #elif defined _AIX | ||
29 | # define alloca __alloca | ||
30 | #elif defined _MSC_VER | ||
31 | # include <malloc.h> | ||
32 | # define alloca _alloca | ||
33 | #else | ||
34 | # include <stddef.h> | ||
35 | # ifdef __cplusplus | ||
36 | extern "C" | ||
37 | # endif | ||
38 | void *alloca (size_t); | ||
39 | #endif | ||
40 | |||
41 | #include <stdlib.h> | ||
42 | #include <string.h> | ||
43 | #include <stddef.h> | ||
44 | #ifdef HAVE_DIRENT_H | ||
45 | # include <dirent.h> | ||
46 | #endif | ||
47 | #include <sys/types.h> | ||
48 | #include <sys/stat.h> | ||
49 | #include <unistd.h> | ||
50 | #ifdef HAVE_SYS_MMAN_H | ||
51 | # include <sys/mman.h> | ||
52 | #endif | ||
53 | #include <fcntl.h> | ||
54 | |||
55 | #define PATH_DELIM '/' | ||
56 | |||
57 | #include "eina_config.h" | ||
58 | #include "eina_private.h" | ||
59 | |||
60 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
61 | #include "eina_safety_checks.h" | ||
62 | #include "eina_file.h" | ||
63 | #include "eina_stringshare.h" | ||
64 | #include "eina_hash.h" | ||
65 | #include "eina_list.h" | ||
66 | #include "eina_lock.h" | ||
67 | #include "eina_mmap.h" | ||
68 | #include "eina_log.h" | ||
69 | #include "eina_xattr.h" | ||
70 | |||
71 | #ifdef HAVE_ESCAPE_H | ||
72 | # include <Escape.h> | ||
73 | #endif | ||
74 | |||
75 | /*============================================================================* | ||
76 | * Local * | ||
77 | *============================================================================*/ | ||
78 | |||
79 | /** | ||
80 | * @cond LOCAL | ||
81 | */ | ||
82 | |||
83 | #ifndef EINA_LOG_COLOR_DEFAULT | ||
84 | #define EINA_LOG_COLOR_DEFAULT EINA_COLOR_CYAN | ||
85 | #endif | ||
86 | |||
87 | #ifdef ERR | ||
88 | #undef ERR | ||
89 | #endif | ||
90 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_file_log_dom, __VA_ARGS__) | ||
91 | |||
92 | #ifdef WRN | ||
93 | #undef WRN | ||
94 | #endif | ||
95 | #define WRN(...) EINA_LOG_DOM_WARN(_eina_file_log_dom, __VA_ARGS__) | ||
96 | |||
97 | #ifdef DBG | ||
98 | #undef DBG | ||
99 | #endif | ||
100 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_file_log_dom, __VA_ARGS__) | ||
101 | |||
102 | #define EINA_SMALL_PAGE 4096 | ||
103 | # define EINA_HUGE_PAGE 16 * 1024 * 1024 | ||
104 | |||
105 | #ifdef HAVE_DIRENT_H | ||
106 | typedef struct _Eina_File_Iterator Eina_File_Iterator; | ||
107 | struct _Eina_File_Iterator | ||
108 | { | ||
109 | Eina_Iterator iterator; | ||
110 | |||
111 | DIR *dirp; | ||
112 | int length; | ||
113 | |||
114 | char dir[1]; | ||
115 | }; | ||
116 | #endif | ||
117 | |||
118 | struct _Eina_File | ||
119 | { | ||
120 | const char *filename; | ||
121 | |||
122 | Eina_Hash *map; | ||
123 | Eina_Hash *rmap; | ||
124 | void *global_map; | ||
125 | |||
126 | Eina_Lock lock; | ||
127 | |||
128 | unsigned long long length; | ||
129 | time_t mtime; | ||
130 | ino_t inode; | ||
131 | #ifdef _STAT_VER_LINUX | ||
132 | unsigned long int mtime_nsec; | ||
133 | #endif | ||
134 | |||
135 | int refcount; | ||
136 | int global_refcount; | ||
137 | |||
138 | int fd; | ||
139 | |||
140 | Eina_Bool shared : 1; | ||
141 | Eina_Bool delete_me : 1; | ||
142 | Eina_Bool global_faulty : 1; | ||
143 | }; | ||
144 | |||
145 | typedef struct _Eina_File_Map Eina_File_Map; | ||
146 | struct _Eina_File_Map | ||
147 | { | ||
148 | void *map; | ||
149 | |||
150 | unsigned long int offset; | ||
151 | unsigned long int length; | ||
152 | |||
153 | int refcount; | ||
154 | |||
155 | Eina_Bool hugetlb : 1; | ||
156 | Eina_Bool faulty : 1; | ||
157 | }; | ||
158 | |||
159 | static Eina_Hash *_eina_file_cache = NULL; | ||
160 | static Eina_Lock _eina_file_lock_cache; | ||
161 | |||
162 | static int _eina_file_log_dom = -1; | ||
163 | |||
164 | /* | ||
165 | * This complex piece of code is needed due to possible race condition. | ||
166 | * The code and description of the issue can be found at : | ||
167 | * http://womble.decadent.org.uk/readdir_r-advisory.html | ||
168 | */ | ||
169 | #ifdef HAVE_DIRENT_H | ||
170 | static long | ||
171 | _eina_name_max(DIR *dirp) | ||
172 | { | ||
173 | long name_max; | ||
174 | |||
175 | #if defined(HAVE_FPATHCONF) && defined(HAVE_DIRFD) && defined(_PC_NAME_MAX) | ||
176 | name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX); | ||
177 | |||
178 | if (name_max == -1) | ||
179 | { | ||
180 | # if defined(NAME_MAX) | ||
181 | name_max = (NAME_MAX > 255) ? NAME_MAX : 255; | ||
182 | # else | ||
183 | name_max = PATH_MAX; | ||
184 | # endif | ||
185 | } | ||
186 | #else | ||
187 | # if defined(NAME_MAX) | ||
188 | name_max = (NAME_MAX > 255) ? NAME_MAX : 255; | ||
189 | # else | ||
190 | # ifdef _PC_NAME_MAX | ||
191 | # warning "buffer size for readdir_r cannot be determined safely, best effort, but racy" | ||
192 | name_max = pathconf(dirp, _PC_NAME_MAX); | ||
193 | # else | ||
194 | # error "buffer size for readdir_r cannot be determined safely" | ||
195 | # endif | ||
196 | # endif | ||
197 | #endif | ||
198 | |||
199 | return name_max; | ||
200 | } | ||
201 | |||
202 | static size_t | ||
203 | _eina_dirent_buffer_size(DIR *dirp) | ||
204 | { | ||
205 | long name_max = _eina_name_max(dirp); | ||
206 | size_t name_end; | ||
207 | |||
208 | name_end = (size_t) offsetof(struct dirent, d_name) + name_max + 1; | ||
209 | |||
210 | return (name_end > sizeof (struct dirent) ? name_end : sizeof (struct dirent)); | ||
211 | } | ||
212 | |||
213 | static Eina_Bool | ||
214 | _eina_file_ls_iterator_next(Eina_File_Iterator *it, void **data) | ||
215 | { | ||
216 | struct dirent *dp; | ||
217 | char *name; | ||
218 | size_t length; | ||
219 | |||
220 | dp = alloca(_eina_dirent_buffer_size(it->dirp)); | ||
221 | |||
222 | do | ||
223 | { | ||
224 | if (readdir_r(it->dirp, dp, &dp)) | ||
225 | return EINA_FALSE; | ||
226 | if (dp == NULL) | ||
227 | return EINA_FALSE; | ||
228 | } | ||
229 | while ((dp->d_name[0] == '.') && | ||
230 | ((dp->d_name[1] == '\0') || | ||
231 | ((dp->d_name[1] == '.') && (dp->d_name[2] == '\0')))); | ||
232 | |||
233 | #ifdef _DIRENT_HAVE_D_NAMLEN | ||
234 | length = dp->d_namlen; | ||
235 | #else | ||
236 | length = strlen(dp->d_name); | ||
237 | #endif | ||
238 | name = alloca(length + 2 + it->length); | ||
239 | |||
240 | memcpy(name, it->dir, it->length); | ||
241 | memcpy(name + it->length, "/", 1); | ||
242 | memcpy(name + it->length + 1, dp->d_name, length + 1); | ||
243 | |||
244 | *data = (char *)eina_stringshare_add(name); | ||
245 | return EINA_TRUE; | ||
246 | } | ||
247 | |||
248 | static DIR * | ||
249 | _eina_file_ls_iterator_container(Eina_File_Iterator *it) | ||
250 | { | ||
251 | return it->dirp; | ||
252 | } | ||
253 | |||
254 | static void | ||
255 | _eina_file_ls_iterator_free(Eina_File_Iterator *it) | ||
256 | { | ||
257 | closedir(it->dirp); | ||
258 | |||
259 | EINA_MAGIC_SET(&it->iterator, 0); | ||
260 | free(it); | ||
261 | } | ||
262 | |||
263 | typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator; | ||
264 | struct _Eina_File_Direct_Iterator | ||
265 | { | ||
266 | Eina_Iterator iterator; | ||
267 | |||
268 | DIR *dirp; | ||
269 | int length; | ||
270 | |||
271 | Eina_File_Direct_Info info; | ||
272 | |||
273 | char dir[1]; | ||
274 | }; | ||
275 | |||
276 | static Eina_Bool | ||
277 | _eina_file_direct_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data) | ||
278 | { | ||
279 | struct dirent *dp; | ||
280 | size_t length; | ||
281 | |||
282 | dp = alloca(_eina_dirent_buffer_size(it->dirp)); | ||
283 | |||
284 | do | ||
285 | { | ||
286 | if (readdir_r(it->dirp, dp, &dp)) | ||
287 | return EINA_FALSE; | ||
288 | if (!dp) | ||
289 | return EINA_FALSE; | ||
290 | |||
291 | #ifdef _DIRENT_HAVE_D_NAMLEN | ||
292 | length = dp->d_namlen; | ||
293 | #else | ||
294 | length = strlen(dp->d_name); | ||
295 | #endif | ||
296 | if (it->info.name_start + length + 1 >= EINA_PATH_MAX) | ||
297 | continue; | ||
298 | } | ||
299 | while ((dp->d_name[0] == '.') && | ||
300 | ((dp->d_name[1] == '\0') || | ||
301 | ((dp->d_name[1] == '.') && (dp->d_name[2] == '\0')))); | ||
302 | |||
303 | memcpy(it->info.path + it->info.name_start, dp->d_name, length); | ||
304 | it->info.name_length = length; | ||
305 | it->info.path_length = it->info.name_start + length; | ||
306 | it->info.path[it->info.path_length] = '\0'; | ||
307 | |||
308 | #ifdef _DIRENT_HAVE_D_TYPE | ||
309 | switch (dp->d_type) | ||
310 | { | ||
311 | case DT_FIFO: | ||
312 | it->info.type = EINA_FILE_FIFO; | ||
313 | break; | ||
314 | case DT_CHR: | ||
315 | it->info.type = EINA_FILE_CHR; | ||
316 | break; | ||
317 | case DT_DIR: | ||
318 | it->info.type = EINA_FILE_DIR; | ||
319 | break; | ||
320 | case DT_BLK: | ||
321 | it->info.type = EINA_FILE_BLK; | ||
322 | break; | ||
323 | case DT_REG: | ||
324 | it->info.type = EINA_FILE_REG; | ||
325 | break; | ||
326 | case DT_LNK: | ||
327 | it->info.type = EINA_FILE_LNK; | ||
328 | break; | ||
329 | case DT_SOCK: | ||
330 | it->info.type = EINA_FILE_SOCK; | ||
331 | break; | ||
332 | case DT_WHT: | ||
333 | it->info.type = EINA_FILE_WHT; | ||
334 | break; | ||
335 | default: | ||
336 | it->info.type = EINA_FILE_UNKNOWN; | ||
337 | break; | ||
338 | } | ||
339 | #else | ||
340 | it->info.type = EINA_FILE_UNKNOWN; | ||
341 | #endif | ||
342 | |||
343 | *data = &it->info; | ||
344 | return EINA_TRUE; | ||
345 | } | ||
346 | |||
347 | static DIR * | ||
348 | _eina_file_direct_ls_iterator_container(Eina_File_Direct_Iterator *it) | ||
349 | { | ||
350 | return it->dirp; | ||
351 | } | ||
352 | |||
353 | static void | ||
354 | _eina_file_direct_ls_iterator_free(Eina_File_Direct_Iterator *it) | ||
355 | { | ||
356 | closedir(it->dirp); | ||
357 | |||
358 | EINA_MAGIC_SET(&it->iterator, 0); | ||
359 | free(it); | ||
360 | } | ||
361 | |||
362 | static Eina_Bool | ||
363 | _eina_file_stat_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data) | ||
364 | { | ||
365 | Eina_Stat st; | ||
366 | |||
367 | if (!_eina_file_direct_ls_iterator_next(it, data)) | ||
368 | return EINA_FALSE; | ||
369 | |||
370 | if (it->info.type == EINA_FILE_UNKNOWN) | ||
371 | { | ||
372 | if (eina_file_statat(it->dirp, &it->info, &st) != 0) | ||
373 | it->info.type = EINA_FILE_UNKNOWN; | ||
374 | } | ||
375 | |||
376 | return EINA_TRUE; | ||
377 | } | ||
378 | #endif | ||
379 | |||
380 | static void | ||
381 | _eina_file_real_close(Eina_File *file) | ||
382 | { | ||
383 | if (file->refcount != 0) return; | ||
384 | |||
385 | eina_hash_free(file->rmap); | ||
386 | eina_hash_free(file->map); | ||
387 | |||
388 | if (file->global_map != MAP_FAILED) | ||
389 | munmap(file->global_map, file->length); | ||
390 | |||
391 | close(file->fd); | ||
392 | |||
393 | free(file); | ||
394 | } | ||
395 | |||
396 | static void | ||
397 | _eina_file_map_close(Eina_File_Map *map) | ||
398 | { | ||
399 | munmap(map->map, map->length); | ||
400 | free(map); | ||
401 | } | ||
402 | |||
403 | static unsigned int | ||
404 | _eina_file_map_key_length(const void *key __UNUSED__) | ||
405 | { | ||
406 | return sizeof (unsigned long int) * 2; | ||
407 | } | ||
408 | |||
409 | static int | ||
410 | _eina_file_map_key_cmp(const unsigned long int *key1, int key1_length __UNUSED__, | ||
411 | const unsigned long int *key2, int key2_length __UNUSED__) | ||
412 | { | ||
413 | if (key1[0] - key2[0] == 0) return key1[1] - key2[1]; | ||
414 | return key1[0] - key2[0]; | ||
415 | } | ||
416 | |||
417 | static int | ||
418 | _eina_file_map_key_hash(const unsigned long int *key, int key_length __UNUSED__) | ||
419 | { | ||
420 | return eina_hash_int64(&key[0], sizeof (unsigned long int)) | ||
421 | ^ eina_hash_int64(&key[1], sizeof (unsigned long int)); | ||
422 | } | ||
423 | |||
424 | #ifndef MAP_POPULATE | ||
425 | static unsigned int | ||
426 | _eina_file_map_populate(char *map, unsigned int size, Eina_Bool hugetlb) | ||
427 | { | ||
428 | unsigned int r = 0xDEADBEEF; | ||
429 | unsigned int i; | ||
430 | unsigned int s; | ||
431 | |||
432 | s = hugetlb ? EINA_HUGE_PAGE : EINA_SMALL_PAGE; | ||
433 | |||
434 | for (i = 0; i < size; i += s) | ||
435 | r ^= map[i]; | ||
436 | |||
437 | r ^= map[size]; | ||
438 | |||
439 | return r; | ||
440 | } | ||
441 | #endif | ||
442 | |||
443 | static int | ||
444 | _eina_file_map_rule_apply(Eina_File_Populate rule, void *addr, unsigned long int size, Eina_Bool hugetlb) | ||
445 | { | ||
446 | int tmp = 42; | ||
447 | int flag = MADV_RANDOM; | ||
448 | |||
449 | switch (rule) | ||
450 | { | ||
451 | case EINA_FILE_RANDOM: flag = MADV_RANDOM; break; | ||
452 | case EINA_FILE_SEQUENTIAL: flag = MADV_SEQUENTIAL; break; | ||
453 | case EINA_FILE_POPULATE: flag = MADV_WILLNEED; break; | ||
454 | case EINA_FILE_WILLNEED: flag = MADV_WILLNEED; break; | ||
455 | } | ||
456 | |||
457 | madvise(addr, size, flag); | ||
458 | |||
459 | #ifndef MAP_POPULATE | ||
460 | if (rule == EINA_FILE_POPULATE) | ||
461 | tmp ^= _eina_file_map_populate(addr, size, hugetlb); | ||
462 | #else | ||
463 | (void) hugetlb; | ||
464 | #endif | ||
465 | |||
466 | return tmp; | ||
467 | } | ||
468 | |||
469 | static Eina_Bool | ||
470 | _eina_file_timestamp_compare(Eina_File *f, struct stat *st) | ||
471 | { | ||
472 | if (f->mtime != st->st_mtime) return EINA_FALSE; | ||
473 | if (f->length != (unsigned long long) st->st_size) return EINA_FALSE; | ||
474 | if (f->inode != st->st_ino) return EINA_FALSE; | ||
475 | #ifdef _STAT_VER_LINUX | ||
476 | # if (defined __USE_MISC && defined st_mtime) | ||
477 | if (f->mtime_nsec != (unsigned long int)st->st_mtim.tv_nsec) | ||
478 | return EINA_FALSE; | ||
479 | # else | ||
480 | if (f->mtime_nsec != (unsigned long int)st->st_mtimensec) | ||
481 | return EINA_FALSE; | ||
482 | # endif | ||
483 | #endif | ||
484 | return EINA_TRUE; | ||
485 | } | ||
486 | |||
487 | static void | ||
488 | slprintf(char *str, size_t size, const char *format, ...) | ||
489 | { | ||
490 | va_list ap; | ||
491 | |||
492 | va_start(ap, format); | ||
493 | |||
494 | vsnprintf(str, size, format, ap); | ||
495 | str[size - 1] = 0; | ||
496 | |||
497 | va_end(ap); | ||
498 | } | ||
499 | |||
500 | static char * | ||
501 | _eina_file_escape(const char *path, int *length) | ||
502 | { | ||
503 | char *result = strdup(path ? path : ""); | ||
504 | char *p = result; | ||
505 | char *q = result; | ||
506 | int len; | ||
507 | |||
508 | if (!result) | ||
509 | return NULL; | ||
510 | |||
511 | if (length) len = *length; | ||
512 | else len = strlen(result); | ||
513 | |||
514 | while ((p = strchr(p, '/'))) | ||
515 | { | ||
516 | // remove double `/' | ||
517 | if (p[1] == '/') | ||
518 | { | ||
519 | memmove(p, p + 1, --len - (p - result)); | ||
520 | result[len] = '\0'; | ||
521 | } | ||
522 | else | ||
523 | if (p[1] == '.' | ||
524 | && p[2] == '.') | ||
525 | { | ||
526 | // remove `/../' | ||
527 | if (p[3] == '/') | ||
528 | { | ||
529 | char tmp; | ||
530 | |||
531 | len -= p + 3 - q; | ||
532 | memmove(q, p + 3, len - (q - result)); | ||
533 | result[len] = '\0'; | ||
534 | p = q; | ||
535 | |||
536 | /* Update q correctly. */ | ||
537 | tmp = *p; | ||
538 | *p = '\0'; | ||
539 | q = strrchr(result, '/'); | ||
540 | if (!q) q = result; | ||
541 | *p = tmp; | ||
542 | } | ||
543 | else | ||
544 | // remove '/..$' | ||
545 | if (p[3] == '\0') | ||
546 | { | ||
547 | len -= p + 2 - q; | ||
548 | result[len] = '\0'; | ||
549 | q = p; | ||
550 | ++p; | ||
551 | } | ||
552 | else | ||
553 | { | ||
554 | q = p; | ||
555 | ++p; | ||
556 | } | ||
557 | } | ||
558 | else | ||
559 | { | ||
560 | q = p; | ||
561 | ++p; | ||
562 | } | ||
563 | } | ||
564 | |||
565 | if (length) | ||
566 | *length = len; | ||
567 | return result; | ||
568 | } | ||
569 | |||
570 | /** | ||
571 | * @endcond | ||
572 | */ | ||
573 | |||
574 | /*============================================================================* | ||
575 | * Global * | ||
576 | *============================================================================*/ | ||
577 | |||
578 | Eina_Bool | ||
579 | eina_file_init(void) | ||
580 | { | ||
581 | _eina_file_log_dom = eina_log_domain_register("eina_file", | ||
582 | EINA_LOG_COLOR_DEFAULT); | ||
583 | if (_eina_file_log_dom < 0) | ||
584 | { | ||
585 | EINA_LOG_ERR("Could not register log domain: eina_file"); | ||
586 | return EINA_FALSE; | ||
587 | } | ||
588 | |||
589 | _eina_file_cache = eina_hash_string_djb2_new(NULL); | ||
590 | if (!_eina_file_cache) | ||
591 | { | ||
592 | ERR("Could not create cache."); | ||
593 | eina_log_domain_unregister(_eina_file_log_dom); | ||
594 | _eina_file_log_dom = -1; | ||
595 | return EINA_FALSE; | ||
596 | } | ||
597 | |||
598 | eina_lock_new(&_eina_file_lock_cache); | ||
599 | |||
600 | return EINA_TRUE; | ||
601 | } | ||
602 | |||
603 | Eina_Bool | ||
604 | eina_file_shutdown(void) | ||
605 | { | ||
606 | if (eina_hash_population(_eina_file_cache) > 0) | ||
607 | { | ||
608 | Eina_Iterator *it; | ||
609 | const char *key; | ||
610 | |||
611 | it = eina_hash_iterator_key_new(_eina_file_cache); | ||
612 | EINA_ITERATOR_FOREACH(it, key) | ||
613 | ERR("File [%s] still open !", key); | ||
614 | eina_iterator_free(it); | ||
615 | } | ||
616 | |||
617 | eina_hash_free(_eina_file_cache); | ||
618 | |||
619 | eina_lock_free(&_eina_file_lock_cache); | ||
620 | |||
621 | eina_log_domain_unregister(_eina_file_log_dom); | ||
622 | _eina_file_log_dom = -1; | ||
623 | return EINA_TRUE; | ||
624 | } | ||
625 | |||
626 | void | ||
627 | eina_file_mmap_faulty(void *addr, long page_size) | ||
628 | { | ||
629 | Eina_File_Map *m; | ||
630 | Eina_File *f; | ||
631 | Eina_Iterator *itf; | ||
632 | Eina_Iterator *itm; | ||
633 | |||
634 | /* NOTE: I actually don't know if other thread are running, I will try to take the lock. | ||
635 | It may be possible that if other thread are not running and they were in the middle of | ||
636 | accessing an Eina_File this lock are still taken and we will result as a deadlock. */ | ||
637 | eina_lock_take(&_eina_file_lock_cache); | ||
638 | |||
639 | itf = eina_hash_iterator_data_new(_eina_file_cache); | ||
640 | EINA_ITERATOR_FOREACH(itf, f) | ||
641 | { | ||
642 | Eina_Bool faulty = EINA_FALSE; | ||
643 | |||
644 | eina_lock_take(&f->lock); | ||
645 | |||
646 | if (f->global_map) | ||
647 | { | ||
648 | if ((unsigned char *) addr < (((unsigned char *)f->global_map) + f->length) && | ||
649 | (((unsigned char *) addr) + page_size) >= (unsigned char *) f->global_map) | ||
650 | { | ||
651 | f->global_faulty = EINA_TRUE; | ||
652 | faulty = EINA_TRUE; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | if (!faulty) | ||
657 | { | ||
658 | itm = eina_hash_iterator_data_new(f->map); | ||
659 | EINA_ITERATOR_FOREACH(itm, m) | ||
660 | { | ||
661 | if ((unsigned char *) addr < (((unsigned char *)m->map) + m->length) && | ||
662 | (((unsigned char *) addr) + page_size) >= (unsigned char *) m->map) | ||
663 | { | ||
664 | m->faulty = EINA_TRUE; | ||
665 | faulty = EINA_TRUE; | ||
666 | break; | ||
667 | } | ||
668 | } | ||
669 | eina_iterator_free(itm); | ||
670 | } | ||
671 | |||
672 | eina_lock_release(&f->lock); | ||
673 | |||
674 | if (faulty) break; | ||
675 | } | ||
676 | eina_iterator_free(itf); | ||
677 | |||
678 | eina_lock_release(&_eina_file_lock_cache); | ||
679 | } | ||
680 | |||
681 | /*============================================================================* | ||
682 | * API * | ||
683 | *============================================================================*/ | ||
684 | |||
685 | EAPI char * | ||
686 | eina_file_path_sanitize(const char *path) | ||
687 | { | ||
688 | char *result = NULL; | ||
689 | int len; | ||
690 | |||
691 | if (!path) return NULL; | ||
692 | |||
693 | len = strlen(path); | ||
694 | |||
695 | if (*path != '/') | ||
696 | { | ||
697 | char cwd[PATH_MAX]; | ||
698 | char *tmp = NULL; | ||
699 | |||
700 | tmp = getcwd(cwd, PATH_MAX); | ||
701 | if (!tmp) return NULL; | ||
702 | |||
703 | len += strlen(cwd) + 2; | ||
704 | tmp = alloca(sizeof (char) * len); | ||
705 | |||
706 | slprintf(tmp, len, "%s/%s", cwd, path); | ||
707 | |||
708 | result = tmp; | ||
709 | } | ||
710 | |||
711 | return _eina_file_escape(result ? result : path, &len); | ||
712 | } | ||
713 | |||
714 | EAPI Eina_Bool | ||
715 | eina_file_dir_list(const char *dir, | ||
716 | Eina_Bool recursive, | ||
717 | Eina_File_Dir_List_Cb cb, | ||
718 | void *data) | ||
719 | { | ||
720 | Eina_File_Direct_Info *info; | ||
721 | Eina_Iterator *it; | ||
722 | |||
723 | EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE); | ||
724 | EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE); | ||
725 | EINA_SAFETY_ON_TRUE_RETURN_VAL(dir[0] == '\0', EINA_FALSE); | ||
726 | |||
727 | it = eina_file_stat_ls(dir); | ||
728 | if (!it) | ||
729 | return EINA_FALSE; | ||
730 | |||
731 | EINA_ITERATOR_FOREACH(it, info) | ||
732 | { | ||
733 | cb(info->path + info->name_start, dir, data); | ||
734 | |||
735 | if (recursive == EINA_TRUE && info->type == EINA_FILE_DIR) | ||
736 | { | ||
737 | eina_file_dir_list(info->path, recursive, cb, data); | ||
738 | } | ||
739 | } | ||
740 | |||
741 | eina_iterator_free(it); | ||
742 | |||
743 | return EINA_TRUE; | ||
744 | } | ||
745 | |||
746 | EAPI Eina_Array * | ||
747 | eina_file_split(char *path) | ||
748 | { | ||
749 | Eina_Array *ea; | ||
750 | char *current; | ||
751 | size_t length; | ||
752 | |||
753 | EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); | ||
754 | |||
755 | ea = eina_array_new(16); | ||
756 | |||
757 | if (!ea) | ||
758 | return NULL; | ||
759 | |||
760 | for (current = strchr(path, PATH_DELIM); | ||
761 | current; | ||
762 | path = current + 1, current = strchr(path, PATH_DELIM)) | ||
763 | { | ||
764 | length = current - path; | ||
765 | |||
766 | if (length <= 0) | ||
767 | continue; | ||
768 | |||
769 | eina_array_push(ea, path); | ||
770 | *current = '\0'; | ||
771 | } | ||
772 | |||
773 | if (*path != '\0') | ||
774 | eina_array_push(ea, path); | ||
775 | |||
776 | return ea; | ||
777 | } | ||
778 | |||
779 | EAPI Eina_Iterator * | ||
780 | eina_file_ls(const char *dir) | ||
781 | { | ||
782 | #ifdef HAVE_DIRENT_H | ||
783 | Eina_File_Iterator *it; | ||
784 | size_t length; | ||
785 | |||
786 | EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); | ||
787 | |||
788 | length = strlen(dir); | ||
789 | if (length < 1) | ||
790 | return NULL; | ||
791 | |||
792 | it = calloc(1, sizeof (Eina_File_Iterator) + length); | ||
793 | if (!it) | ||
794 | return NULL; | ||
795 | |||
796 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
797 | |||
798 | it->dirp = opendir(dir); | ||
799 | if (!it->dirp) | ||
800 | { | ||
801 | free(it); | ||
802 | return NULL; | ||
803 | } | ||
804 | |||
805 | memcpy(it->dir, dir, length + 1); | ||
806 | if (dir[length - 1] != '/') | ||
807 | it->length = length; | ||
808 | else | ||
809 | it->length = length - 1; | ||
810 | |||
811 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
812 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_ls_iterator_next); | ||
813 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
814 | _eina_file_ls_iterator_container); | ||
815 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_ls_iterator_free); | ||
816 | |||
817 | return &it->iterator; | ||
818 | #else | ||
819 | (void) dir; | ||
820 | return NULL; | ||
821 | #endif | ||
822 | } | ||
823 | |||
824 | EAPI Eina_Iterator * | ||
825 | eina_file_direct_ls(const char *dir) | ||
826 | { | ||
827 | #ifdef HAVE_DIRENT_H | ||
828 | Eina_File_Direct_Iterator *it; | ||
829 | size_t length; | ||
830 | |||
831 | EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); | ||
832 | |||
833 | length = strlen(dir); | ||
834 | if (length < 1) | ||
835 | return NULL; | ||
836 | |||
837 | it = calloc(1, sizeof(Eina_File_Direct_Iterator) + length); | ||
838 | if (!it) | ||
839 | return NULL; | ||
840 | |||
841 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
842 | |||
843 | it->dirp = opendir(dir); | ||
844 | if (!it->dirp) | ||
845 | { | ||
846 | free(it); | ||
847 | return NULL; | ||
848 | } | ||
849 | |||
850 | if (length + _eina_name_max(it->dirp) + 2 >= EINA_PATH_MAX) | ||
851 | { | ||
852 | _eina_file_direct_ls_iterator_free(it); | ||
853 | return NULL; | ||
854 | } | ||
855 | |||
856 | memcpy(it->dir, dir, length + 1); | ||
857 | it->length = length; | ||
858 | |||
859 | memcpy(it->info.path, dir, length); | ||
860 | if (dir[length - 1] == '/') | ||
861 | it->info.name_start = length; | ||
862 | else | ||
863 | { | ||
864 | it->info.path[length] = '/'; | ||
865 | it->info.name_start = length + 1; | ||
866 | } | ||
867 | |||
868 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
869 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_direct_ls_iterator_next); | ||
870 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
871 | _eina_file_direct_ls_iterator_container); | ||
872 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_direct_ls_iterator_free); | ||
873 | |||
874 | return &it->iterator; | ||
875 | #else | ||
876 | (void) dir; | ||
877 | return NULL; | ||
878 | #endif | ||
879 | } | ||
880 | |||
881 | EAPI Eina_Iterator * | ||
882 | eina_file_stat_ls(const char *dir) | ||
883 | { | ||
884 | #ifdef HAVE_DIRENT_H | ||
885 | Eina_File_Direct_Iterator *it; | ||
886 | size_t length; | ||
887 | |||
888 | EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); | ||
889 | |||
890 | length = strlen(dir); | ||
891 | if (length < 1) | ||
892 | return NULL; | ||
893 | |||
894 | it = calloc(1, sizeof(Eina_File_Direct_Iterator) + length); | ||
895 | if (!it) | ||
896 | return NULL; | ||
897 | |||
898 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
899 | |||
900 | it->dirp = opendir(dir); | ||
901 | if (!it->dirp) | ||
902 | { | ||
903 | free(it); | ||
904 | return NULL; | ||
905 | } | ||
906 | |||
907 | if (length + _eina_name_max(it->dirp) + 2 >= EINA_PATH_MAX) | ||
908 | { | ||
909 | _eina_file_direct_ls_iterator_free(it); | ||
910 | return NULL; | ||
911 | } | ||
912 | |||
913 | memcpy(it->dir, dir, length + 1); | ||
914 | it->length = length; | ||
915 | |||
916 | memcpy(it->info.path, dir, length); | ||
917 | if (dir[length - 1] == '/') | ||
918 | it->info.name_start = length; | ||
919 | else | ||
920 | { | ||
921 | it->info.path[length] = '/'; | ||
922 | it->info.name_start = length + 1; | ||
923 | } | ||
924 | |||
925 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
926 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_stat_ls_iterator_next); | ||
927 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
928 | _eina_file_direct_ls_iterator_container); | ||
929 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_direct_ls_iterator_free); | ||
930 | |||
931 | return &it->iterator; | ||
932 | #else | ||
933 | (void) dir; | ||
934 | return NULL; | ||
935 | #endif | ||
936 | } | ||
937 | |||
938 | EAPI Eina_File * | ||
939 | eina_file_open(const char *path, Eina_Bool shared) | ||
940 | { | ||
941 | Eina_File *file; | ||
942 | Eina_File *n; | ||
943 | char *filename; | ||
944 | struct stat file_stat; | ||
945 | int fd = -1; | ||
946 | #ifdef HAVE_EXECVP | ||
947 | int flags; | ||
948 | #endif | ||
949 | |||
950 | EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); | ||
951 | |||
952 | filename = eina_file_path_sanitize(path); | ||
953 | if (!filename) return NULL; | ||
954 | |||
955 | if (shared) | ||
956 | #ifdef HAVE_SHMOPEN | ||
957 | fd = shm_open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO); | ||
958 | #else | ||
959 | goto on_error; | ||
960 | #endif | ||
961 | else | ||
962 | fd = open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO); | ||
963 | |||
964 | if (fd < 0) goto on_error; | ||
965 | |||
966 | #ifdef HAVE_EXECVP | ||
967 | flags = fcntl(fd, F_GETFD); | ||
968 | if (flags == -1) | ||
969 | goto on_error; | ||
970 | |||
971 | flags |= FD_CLOEXEC; | ||
972 | if (fcntl(fd, F_SETFD, flags) == -1) | ||
973 | goto on_error; | ||
974 | #endif | ||
975 | |||
976 | if (fstat(fd, &file_stat)) | ||
977 | goto on_error; | ||
978 | |||
979 | eina_lock_take(&_eina_file_lock_cache); | ||
980 | |||
981 | file = eina_hash_find(_eina_file_cache, filename); | ||
982 | if ((file) && !_eina_file_timestamp_compare(file, &file_stat)) | ||
983 | { | ||
984 | file->delete_me = EINA_TRUE; | ||
985 | eina_hash_del(_eina_file_cache, file->filename, file); | ||
986 | _eina_file_real_close(file); | ||
987 | file = NULL; | ||
988 | } | ||
989 | |||
990 | if (!file) | ||
991 | { | ||
992 | n = malloc(sizeof (Eina_File) + strlen(filename) + 1); | ||
993 | if (!n) | ||
994 | { | ||
995 | eina_lock_release(&_eina_file_lock_cache); | ||
996 | goto on_error; | ||
997 | } | ||
998 | |||
999 | n->filename = (char*) (n + 1); | ||
1000 | strcpy((char*) n->filename, filename); | ||
1001 | n->map = eina_hash_new(EINA_KEY_LENGTH(_eina_file_map_key_length), | ||
1002 | EINA_KEY_CMP(_eina_file_map_key_cmp), | ||
1003 | EINA_KEY_HASH(_eina_file_map_key_hash), | ||
1004 | EINA_FREE_CB(_eina_file_map_close), | ||
1005 | 3); | ||
1006 | n->rmap = eina_hash_pointer_new(NULL); | ||
1007 | n->global_map = MAP_FAILED; | ||
1008 | n->global_refcount = 0; | ||
1009 | n->length = file_stat.st_size; | ||
1010 | n->mtime = file_stat.st_mtime; | ||
1011 | #ifdef _STAT_VER_LINUX | ||
1012 | # if (defined __USE_MISC && defined st_mtime) | ||
1013 | n->mtime_nsec = (unsigned long int)file_stat.st_mtim.tv_nsec; | ||
1014 | # else | ||
1015 | n->mtime_nsec = (unsigned long int)file_stat.st_mtimensec; | ||
1016 | # endif | ||
1017 | #endif | ||
1018 | n->inode = file_stat.st_ino; | ||
1019 | n->refcount = 0; | ||
1020 | n->fd = fd; | ||
1021 | n->shared = shared; | ||
1022 | n->delete_me = EINA_FALSE; | ||
1023 | eina_lock_new(&n->lock); | ||
1024 | eina_hash_direct_add(_eina_file_cache, n->filename, n); | ||
1025 | } | ||
1026 | else | ||
1027 | { | ||
1028 | close(fd); | ||
1029 | n = file; | ||
1030 | } | ||
1031 | eina_lock_take(&n->lock); | ||
1032 | n->refcount++; | ||
1033 | eina_lock_release(&n->lock); | ||
1034 | |||
1035 | eina_lock_release(&_eina_file_lock_cache); | ||
1036 | |||
1037 | free(filename); | ||
1038 | |||
1039 | return n; | ||
1040 | |||
1041 | on_error: | ||
1042 | free(filename); | ||
1043 | if (fd >= 0) close(fd); | ||
1044 | return NULL; | ||
1045 | } | ||
1046 | |||
1047 | EAPI void | ||
1048 | eina_file_close(Eina_File *file) | ||
1049 | { | ||
1050 | EINA_SAFETY_ON_NULL_RETURN(file); | ||
1051 | |||
1052 | eina_lock_take(&file->lock); | ||
1053 | file->refcount--; | ||
1054 | eina_lock_release(&file->lock); | ||
1055 | |||
1056 | if (file->refcount != 0) return; | ||
1057 | eina_lock_take(&_eina_file_lock_cache); | ||
1058 | |||
1059 | eina_hash_del(_eina_file_cache, file->filename, file); | ||
1060 | _eina_file_real_close(file); | ||
1061 | |||
1062 | eina_lock_release(&_eina_file_lock_cache); | ||
1063 | } | ||
1064 | |||
1065 | EAPI size_t | ||
1066 | eina_file_size_get(Eina_File *file) | ||
1067 | { | ||
1068 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0); | ||
1069 | return file->length; | ||
1070 | } | ||
1071 | |||
1072 | EAPI time_t | ||
1073 | eina_file_mtime_get(Eina_File *file) | ||
1074 | { | ||
1075 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0); | ||
1076 | return file->mtime; | ||
1077 | } | ||
1078 | |||
1079 | EAPI const char * | ||
1080 | eina_file_filename_get(Eina_File *file) | ||
1081 | { | ||
1082 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
1083 | return file->filename; | ||
1084 | } | ||
1085 | |||
1086 | EAPI void * | ||
1087 | eina_file_map_all(Eina_File *file, Eina_File_Populate rule) | ||
1088 | { | ||
1089 | int flags = MAP_SHARED; | ||
1090 | void *ret = NULL; | ||
1091 | |||
1092 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
1093 | |||
1094 | // bsd people will lack this feature | ||
1095 | #ifdef MAP_POPULATE | ||
1096 | if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE; | ||
1097 | #endif | ||
1098 | #ifdef MAP_HUGETLB | ||
1099 | if (file->length > EINA_HUGE_PAGE) flags |= MAP_HUGETLB; | ||
1100 | #endif | ||
1101 | |||
1102 | eina_mmap_safety_enabled_set(EINA_TRUE); | ||
1103 | eina_lock_take(&file->lock); | ||
1104 | if (file->global_map == MAP_FAILED) | ||
1105 | file->global_map = mmap(NULL, file->length, PROT_READ, flags, file->fd, 0); | ||
1106 | #ifdef MAP_HUGETLB | ||
1107 | if ((file->global_map == MAP_FAILED) && (flags & MAP_HUGETLB)) | ||
1108 | { | ||
1109 | flags &= ~MAP_HUGETLB; | ||
1110 | file->global_map = mmap(NULL, file->length, PROT_READ, flags, file->fd, 0); | ||
1111 | } | ||
1112 | #endif | ||
1113 | |||
1114 | if (file->global_map != MAP_FAILED) | ||
1115 | { | ||
1116 | Eina_Bool hugetlb = EINA_FALSE; | ||
1117 | |||
1118 | #ifdef MAP_HUGETLB | ||
1119 | hugetlb = !!(flags & MAP_HUGETLB); | ||
1120 | #endif | ||
1121 | _eina_file_map_rule_apply(rule, file->global_map, file->length, hugetlb); | ||
1122 | file->global_refcount++; | ||
1123 | ret = file->global_map; | ||
1124 | } | ||
1125 | |||
1126 | eina_lock_release(&file->lock); | ||
1127 | return ret; | ||
1128 | } | ||
1129 | |||
1130 | EAPI void * | ||
1131 | eina_file_map_new(Eina_File *file, Eina_File_Populate rule, | ||
1132 | unsigned long int offset, unsigned long int length) | ||
1133 | { | ||
1134 | Eina_File_Map *map; | ||
1135 | unsigned long int key[2]; | ||
1136 | |||
1137 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
1138 | |||
1139 | if (offset > file->length) | ||
1140 | return NULL; | ||
1141 | if (offset + length > file->length) | ||
1142 | return NULL; | ||
1143 | |||
1144 | if (offset == 0 && length == file->length) | ||
1145 | return eina_file_map_all(file, rule); | ||
1146 | |||
1147 | key[0] = offset; | ||
1148 | key[1] = length; | ||
1149 | |||
1150 | eina_mmap_safety_enabled_set(EINA_TRUE); | ||
1151 | eina_lock_take(&file->lock); | ||
1152 | |||
1153 | map = eina_hash_find(file->map, &key); | ||
1154 | if (!map) | ||
1155 | { | ||
1156 | int flags = MAP_SHARED; | ||
1157 | |||
1158 | // bsd people will lack this feature | ||
1159 | #ifdef MAP_POPULATE | ||
1160 | if (rule == EINA_FILE_POPULATE) flags |= MAP_POPULATE; | ||
1161 | #endif | ||
1162 | #ifdef MAP_HUGETLB | ||
1163 | if (length > EINA_HUGE_PAGE) flags |= MAP_HUGETLB; | ||
1164 | #endif | ||
1165 | |||
1166 | map = malloc(sizeof (Eina_File_Map)); | ||
1167 | if (!map) goto on_error; | ||
1168 | |||
1169 | map->map = mmap(NULL, length, PROT_READ, flags, file->fd, offset); | ||
1170 | #ifdef MAP_HUGETLB | ||
1171 | if (map->map == MAP_FAILED && (flags & MAP_HUGETLB)) | ||
1172 | { | ||
1173 | flags &= ~MAP_HUGETLB; | ||
1174 | map->map = mmap(NULL, length, PROT_READ, flags, file->fd, offset); | ||
1175 | } | ||
1176 | |||
1177 | map->hugetlb = !!(flags & MAP_HUGETLB); | ||
1178 | #else | ||
1179 | map->hugetlb = EINA_FALSE; | ||
1180 | #endif | ||
1181 | map->offset = offset; | ||
1182 | map->length = length; | ||
1183 | map->refcount = 0; | ||
1184 | |||
1185 | if (map->map == MAP_FAILED) goto on_error; | ||
1186 | |||
1187 | eina_hash_add(file->map, &key, map); | ||
1188 | eina_hash_direct_add(file->rmap, map->map, map); | ||
1189 | } | ||
1190 | |||
1191 | map->refcount++; | ||
1192 | |||
1193 | _eina_file_map_rule_apply(rule, map->map, length, map->hugetlb); | ||
1194 | |||
1195 | eina_lock_release(&file->lock); | ||
1196 | |||
1197 | return map->map; | ||
1198 | |||
1199 | on_error: | ||
1200 | free(map); | ||
1201 | eina_lock_release(&file->lock); | ||
1202 | |||
1203 | return NULL; | ||
1204 | } | ||
1205 | |||
1206 | EAPI void | ||
1207 | eina_file_map_free(Eina_File *file, void *map) | ||
1208 | { | ||
1209 | EINA_SAFETY_ON_NULL_RETURN(file); | ||
1210 | |||
1211 | eina_lock_take(&file->lock); | ||
1212 | |||
1213 | if (file->global_map == map) | ||
1214 | { | ||
1215 | file->global_refcount--; | ||
1216 | |||
1217 | if (file->global_refcount > 0) goto on_exit; | ||
1218 | |||
1219 | munmap(file->global_map, file->length); | ||
1220 | file->global_map = MAP_FAILED; | ||
1221 | } | ||
1222 | else | ||
1223 | { | ||
1224 | Eina_File_Map *em; | ||
1225 | unsigned long int key[2]; | ||
1226 | |||
1227 | em = eina_hash_find(file->rmap, &map); | ||
1228 | if (!em) goto on_exit; | ||
1229 | |||
1230 | em->refcount--; | ||
1231 | |||
1232 | if (em->refcount > 0) goto on_exit; | ||
1233 | |||
1234 | key[0] = em->offset; | ||
1235 | key[1] = em->length; | ||
1236 | |||
1237 | eina_hash_del(file->rmap, &map, em); | ||
1238 | eina_hash_del(file->map, &key, em); | ||
1239 | } | ||
1240 | |||
1241 | on_exit: | ||
1242 | eina_lock_release(&file->lock); | ||
1243 | } | ||
1244 | |||
1245 | EAPI Eina_Bool | ||
1246 | eina_file_map_faulted(Eina_File *file, void *map) | ||
1247 | { | ||
1248 | Eina_File_Map *em; | ||
1249 | Eina_Bool r = EINA_FALSE; | ||
1250 | |||
1251 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE); | ||
1252 | |||
1253 | eina_lock_take(&file->lock); | ||
1254 | |||
1255 | if (file->global_map == map) | ||
1256 | { | ||
1257 | r = file->global_faulty; | ||
1258 | } | ||
1259 | else | ||
1260 | { | ||
1261 | em = eina_hash_find(file->rmap, &map); | ||
1262 | if (em) r = em->faulty; | ||
1263 | } | ||
1264 | |||
1265 | eina_lock_release(&file->lock); | ||
1266 | |||
1267 | return r; | ||
1268 | } | ||
1269 | |||
1270 | EAPI Eina_Iterator * | ||
1271 | eina_file_xattr_get(Eina_File *file) | ||
1272 | { | ||
1273 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
1274 | |||
1275 | return eina_xattr_fd_ls(file->fd); | ||
1276 | } | ||
1277 | |||
1278 | EAPI Eina_Iterator * | ||
1279 | eina_file_xattr_value_get(Eina_File *file) | ||
1280 | { | ||
1281 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
1282 | |||
1283 | return eina_xattr_value_fd_ls(file->fd); | ||
1284 | } | ||
1285 | |||
1286 | EAPI int | ||
1287 | eina_file_statat(void *container, Eina_File_Direct_Info *info, Eina_Stat *st) | ||
1288 | { | ||
1289 | struct stat buf; | ||
1290 | #ifdef HAVE_FSTATAT | ||
1291 | int fd; | ||
1292 | #endif | ||
1293 | |||
1294 | EINA_SAFETY_ON_NULL_RETURN_VAL(info, -1); | ||
1295 | EINA_SAFETY_ON_NULL_RETURN_VAL(st, -1); | ||
1296 | |||
1297 | #ifdef HAVE_FSTATAT | ||
1298 | fd = dirfd((DIR*) container); | ||
1299 | if (fstatat(fd, info->path + info->name_start, &buf, 0)) | ||
1300 | #else | ||
1301 | (void)container; | ||
1302 | if (stat(info->path, &buf)) | ||
1303 | #endif | ||
1304 | { | ||
1305 | if (info->type != EINA_FILE_LNK) | ||
1306 | info->type = EINA_FILE_UNKNOWN; | ||
1307 | return -1; | ||
1308 | } | ||
1309 | |||
1310 | if (info->type == EINA_FILE_UNKNOWN) | ||
1311 | { | ||
1312 | if (S_ISREG(buf.st_mode)) | ||
1313 | info->type = EINA_FILE_REG; | ||
1314 | else if (S_ISDIR(buf.st_mode)) | ||
1315 | info->type = EINA_FILE_DIR; | ||
1316 | else if (S_ISCHR(buf.st_mode)) | ||
1317 | info->type = EINA_FILE_CHR; | ||
1318 | else if (S_ISBLK(buf.st_mode)) | ||
1319 | info->type = EINA_FILE_BLK; | ||
1320 | else if (S_ISFIFO(buf.st_mode)) | ||
1321 | info->type = EINA_FILE_FIFO; | ||
1322 | else if (S_ISLNK(buf.st_mode)) | ||
1323 | info->type = EINA_FILE_LNK; | ||
1324 | else if (S_ISSOCK(buf.st_mode)) | ||
1325 | info->type = EINA_FILE_SOCK; | ||
1326 | else | ||
1327 | info->type = EINA_FILE_UNKNOWN; | ||
1328 | } | ||
1329 | |||
1330 | st->dev = buf.st_dev; | ||
1331 | st->ino = buf.st_ino; | ||
1332 | st->mode = buf.st_mode; | ||
1333 | st->nlink = buf.st_nlink; | ||
1334 | st->uid = buf.st_uid; | ||
1335 | st->gid = buf.st_gid; | ||
1336 | st->rdev = buf.st_rdev; | ||
1337 | st->size = buf.st_size; | ||
1338 | st->blksize = buf.st_blksize; | ||
1339 | st->blocks = buf.st_blocks; | ||
1340 | st->atime = buf.st_atime; | ||
1341 | st->mtime = buf.st_mtime; | ||
1342 | st->ctime = buf.st_ctime; | ||
1343 | #ifdef _STAT_VER_LINUX | ||
1344 | # if (defined __USE_MISC && defined st_mtime) | ||
1345 | st->atimensec = buf.st_atim.tv_nsec; | ||
1346 | st->mtimensec = buf.st_mtim.tv_nsec; | ||
1347 | st->ctimensec = buf.st_ctim.tv_nsec; | ||
1348 | # else | ||
1349 | st->atimensec = buf.st_atimensec; | ||
1350 | st->mtimensec = buf.st_mtimensec; | ||
1351 | st->ctimensec = buf.st_ctimensec; | ||
1352 | # endif | ||
1353 | #else | ||
1354 | st->atimensec = 0; | ||
1355 | st->mtimensec = 0; | ||
1356 | st->ctimensec = 0; | ||
1357 | #endif | ||
1358 | return 0; | ||
1359 | } | ||
diff --git a/libraries/eina/src/lib/eina_file_win32.c b/libraries/eina/src/lib/eina_file_win32.c deleted file mode 100644 index 5c20fdd..0000000 --- a/libraries/eina/src/lib/eina_file_win32.c +++ /dev/null | |||
@@ -1,1214 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2010 Vincent Torri | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #ifdef HAVE_ALLOCA_H | ||
24 | # include <alloca.h> | ||
25 | #elif defined __GNUC__ | ||
26 | # define alloca __builtin_alloca | ||
27 | #elif defined _AIX | ||
28 | # define alloca __alloca | ||
29 | #elif defined _MSC_VER | ||
30 | # include <malloc.h> | ||
31 | # define alloca _alloca | ||
32 | #else | ||
33 | # include <stddef.h> | ||
34 | # ifdef __cplusplus | ||
35 | extern "C" | ||
36 | # endif | ||
37 | void *alloca (size_t); | ||
38 | #endif | ||
39 | |||
40 | #include <sys/types.h> | ||
41 | #include <sys/stat.h> | ||
42 | |||
43 | #define WIN32_LEAN_AND_MEAN | ||
44 | #include <windows.h> | ||
45 | #undef WIN32_LEAN_AND_MEAN | ||
46 | |||
47 | #include <Evil.h> | ||
48 | |||
49 | #include "eina_config.h" | ||
50 | #include "eina_private.h" | ||
51 | |||
52 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
53 | #include "eina_safety_checks.h" | ||
54 | #include "eina_file.h" | ||
55 | #include "eina_stringshare.h" | ||
56 | #include "eina_hash.h" | ||
57 | #include "eina_list.h" | ||
58 | #include "eina_lock.h" | ||
59 | #include "eina_log.h" | ||
60 | |||
61 | /*============================================================================* | ||
62 | * Local * | ||
63 | *============================================================================*/ | ||
64 | |||
65 | /** | ||
66 | * @cond LOCAL | ||
67 | */ | ||
68 | |||
69 | #ifndef EINA_LOG_COLOR_DEFAULT | ||
70 | #define EINA_LOG_COLOR_DEFAULT EINA_COLOR_CYAN | ||
71 | #endif | ||
72 | |||
73 | #ifdef ERR | ||
74 | #undef ERR | ||
75 | #endif | ||
76 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_file_log_dom, __VA_ARGS__) | ||
77 | |||
78 | #ifdef WRN | ||
79 | #undef WRN | ||
80 | #endif | ||
81 | #define WRN(...) EINA_LOG_DOM_WARN(_eina_file_log_dom, __VA_ARGS__) | ||
82 | |||
83 | #ifdef DBG | ||
84 | #undef DBG | ||
85 | #endif | ||
86 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_file_log_dom, __VA_ARGS__) | ||
87 | |||
88 | #ifdef MAP_FAILED | ||
89 | # undef MAP_FAILED | ||
90 | #endif | ||
91 | #define MAP_FAILED ((void *)-1) | ||
92 | |||
93 | typedef struct _Eina_File_Iterator Eina_File_Iterator; | ||
94 | typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator; | ||
95 | typedef struct _Eina_File_Map Eina_File_Map; | ||
96 | |||
97 | struct _Eina_File_Iterator | ||
98 | { | ||
99 | Eina_Iterator iterator; | ||
100 | |||
101 | WIN32_FIND_DATA data; | ||
102 | HANDLE handle; | ||
103 | size_t length; | ||
104 | Eina_Bool is_last : 1; | ||
105 | |||
106 | char dir[1]; | ||
107 | }; | ||
108 | |||
109 | struct _Eina_File_Direct_Iterator | ||
110 | { | ||
111 | Eina_Iterator iterator; | ||
112 | |||
113 | WIN32_FIND_DATA data; | ||
114 | HANDLE handle; | ||
115 | size_t length; | ||
116 | Eina_Bool is_last : 1; | ||
117 | |||
118 | Eina_File_Direct_Info info; | ||
119 | |||
120 | char dir[1]; | ||
121 | }; | ||
122 | |||
123 | struct _Eina_File | ||
124 | { | ||
125 | const char *filename; | ||
126 | |||
127 | Eina_Hash *map; | ||
128 | Eina_Hash *rmap; | ||
129 | void *global_map; | ||
130 | |||
131 | Eina_Lock lock; | ||
132 | |||
133 | ULONGLONG length; | ||
134 | ULONGLONG mtime; | ||
135 | |||
136 | int refcount; | ||
137 | int global_refcount; | ||
138 | |||
139 | HANDLE handle; | ||
140 | HANDLE fm; | ||
141 | |||
142 | Eina_Bool shared : 1; | ||
143 | Eina_Bool delete_me : 1; | ||
144 | }; | ||
145 | |||
146 | struct _Eina_File_Map | ||
147 | { | ||
148 | void *map; | ||
149 | |||
150 | unsigned long int offset; | ||
151 | unsigned long int length; | ||
152 | |||
153 | int refcount; | ||
154 | }; | ||
155 | |||
156 | static Eina_Hash *_eina_file_cache = NULL; | ||
157 | static Eina_Lock _eina_file_lock_cache; | ||
158 | |||
159 | static int _eina_file_log_dom = -1; | ||
160 | |||
161 | static void | ||
162 | _eina_file_win32_backslash_change(char *dir) | ||
163 | { | ||
164 | char *tmp; | ||
165 | |||
166 | tmp = dir; | ||
167 | while (*tmp) | ||
168 | { | ||
169 | if (*tmp == '/') *tmp = '\\'; | ||
170 | tmp++; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | static Eina_Bool | ||
175 | _eina_file_win32_is_dir(const char *dir) | ||
176 | { | ||
177 | #ifdef UNICODE | ||
178 | wchar_t *wdir = NULL; | ||
179 | #endif | ||
180 | DWORD attr; | ||
181 | |||
182 | /* check if it's a directory */ | ||
183 | #ifdef UNICODE | ||
184 | wdir = evil_char_to_wchar(dir); | ||
185 | if (!wdir) | ||
186 | return EINA_FALSE; | ||
187 | |||
188 | attr = GetFileAttributes(wdir); | ||
189 | free(wdir); | ||
190 | #else | ||
191 | attr = GetFileAttributes(dir); | ||
192 | #endif | ||
193 | |||
194 | if (attr == 0xFFFFFFFF) | ||
195 | return EINA_FALSE; | ||
196 | |||
197 | if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) | ||
198 | return EINA_FALSE; | ||
199 | |||
200 | return EINA_TRUE; | ||
201 | } | ||
202 | |||
203 | static char * | ||
204 | _eina_file_win32_dir_new(const char *dir) | ||
205 | { | ||
206 | char *new_dir; | ||
207 | size_t length; | ||
208 | |||
209 | length = strlen(dir); | ||
210 | |||
211 | new_dir = (char *)malloc(sizeof(char) * length + 5); | ||
212 | if (!new_dir) | ||
213 | return NULL; | ||
214 | |||
215 | memcpy(new_dir, dir, length); | ||
216 | memcpy(new_dir + length, "\\*.*", 5); | ||
217 | _eina_file_win32_backslash_change(new_dir); | ||
218 | |||
219 | return new_dir; | ||
220 | } | ||
221 | |||
222 | static HANDLE | ||
223 | _eina_file_win32_first_file(const char *dir, WIN32_FIND_DATA *fd) | ||
224 | { | ||
225 | HANDLE h; | ||
226 | #ifdef UNICODE | ||
227 | wchar_t *wdir = NULL; | ||
228 | |||
229 | wdir = evil_char_to_wchar(dir); | ||
230 | if (!wdir) | ||
231 | return NULL; | ||
232 | |||
233 | h = FindFirstFile(wdir, fd); | ||
234 | free(wdir); | ||
235 | #else | ||
236 | h = FindFirstFile(dir, fd); | ||
237 | #endif | ||
238 | |||
239 | if (!h) | ||
240 | return NULL; | ||
241 | |||
242 | while ((fd->cFileName[0] == '.') && | ||
243 | ((fd->cFileName[1] == '\0') || | ||
244 | ((fd->cFileName[1] == '.') && (fd->cFileName[2] == '\0')))) | ||
245 | { | ||
246 | if (!FindNextFile(h, fd)) | ||
247 | return NULL; | ||
248 | } | ||
249 | |||
250 | return h; | ||
251 | } | ||
252 | |||
253 | static Eina_Bool | ||
254 | _eina_file_win32_ls_iterator_next(Eina_File_Iterator *it, void **data) | ||
255 | { | ||
256 | #ifdef UNICODE | ||
257 | wchar_t *old_name; | ||
258 | #else | ||
259 | char *old_name; | ||
260 | #endif | ||
261 | char *name; | ||
262 | char *cname; | ||
263 | size_t length; | ||
264 | Eina_Bool is_last; | ||
265 | Eina_Bool res = EINA_TRUE; | ||
266 | |||
267 | if (it->handle == INVALID_HANDLE_VALUE) | ||
268 | return EINA_FALSE; | ||
269 | |||
270 | is_last = it->is_last; | ||
271 | #ifdef UNICODE | ||
272 | old_name = _wcsdup(it->data.cFileName); | ||
273 | #else | ||
274 | old_name = _strdup(it->data.cFileName); | ||
275 | #endif | ||
276 | if (!old_name) | ||
277 | return EINA_FALSE; | ||
278 | |||
279 | do { | ||
280 | if (!FindNextFile(it->handle, &it->data)) | ||
281 | { | ||
282 | if (GetLastError() == ERROR_NO_MORE_FILES) | ||
283 | it->is_last = EINA_TRUE; | ||
284 | else | ||
285 | res = EINA_FALSE; | ||
286 | } | ||
287 | } while ((it->data.cFileName[0] == '.') && | ||
288 | ((it->data.cFileName[1] == '\0') || | ||
289 | ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */ | ||
290 | |||
291 | #ifdef UNICODE | ||
292 | cname = evil_wchar_to_char(old_name); | ||
293 | if (!cname) | ||
294 | return EINA_FALSE; | ||
295 | #else | ||
296 | cname = old_name; | ||
297 | #endif | ||
298 | |||
299 | length = strlen(cname); | ||
300 | name = alloca(length + 2 + it->length); | ||
301 | |||
302 | memcpy(name, it->dir, it->length); | ||
303 | memcpy(name + it->length, "\\", 1); | ||
304 | memcpy(name + it->length + 1, cname, length + 1); | ||
305 | |||
306 | *data = (char *)eina_stringshare_add(name); | ||
307 | |||
308 | #ifdef UNICODE | ||
309 | free(cname); | ||
310 | #endif | ||
311 | free(old_name); | ||
312 | |||
313 | if (is_last) | ||
314 | res = EINA_FALSE; | ||
315 | |||
316 | return res; | ||
317 | } | ||
318 | |||
319 | static HANDLE | ||
320 | _eina_file_win32_ls_iterator_container(Eina_File_Iterator *it) | ||
321 | { | ||
322 | return it->handle; | ||
323 | } | ||
324 | |||
325 | static void | ||
326 | _eina_file_win32_ls_iterator_free(Eina_File_Iterator *it) | ||
327 | { | ||
328 | if (it->handle != INVALID_HANDLE_VALUE) | ||
329 | FindClose(it->handle); | ||
330 | |||
331 | EINA_MAGIC_SET(&it->iterator, 0); | ||
332 | free(it); | ||
333 | } | ||
334 | |||
335 | static Eina_Bool | ||
336 | _eina_file_win32_direct_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data) | ||
337 | { | ||
338 | #ifdef UNICODE | ||
339 | wchar_t *old_name; | ||
340 | #else | ||
341 | char *old_name; | ||
342 | #endif | ||
343 | char *cname; | ||
344 | size_t length; | ||
345 | DWORD attr; | ||
346 | Eina_Bool is_last; | ||
347 | Eina_Bool res = EINA_TRUE; | ||
348 | |||
349 | if (it->handle == INVALID_HANDLE_VALUE) | ||
350 | return EINA_FALSE; | ||
351 | |||
352 | attr = it->data.dwFileAttributes; | ||
353 | is_last = it->is_last; | ||
354 | #ifdef UNICODE | ||
355 | old_name = _wcsdup(it->data.cFileName); | ||
356 | #else | ||
357 | old_name = _strdup(it->data.cFileName); | ||
358 | #endif | ||
359 | if (!old_name) | ||
360 | return EINA_FALSE; | ||
361 | |||
362 | do { | ||
363 | if (!FindNextFile(it->handle, &it->data)) | ||
364 | { | ||
365 | if (GetLastError() == ERROR_NO_MORE_FILES) | ||
366 | it->is_last = EINA_TRUE; | ||
367 | else | ||
368 | res = EINA_FALSE; | ||
369 | } | ||
370 | |||
371 | #ifdef UNICODE | ||
372 | length = wcslen(old_name); | ||
373 | #else | ||
374 | length = strlen(old_name); | ||
375 | #endif | ||
376 | if (it->info.name_start + length + 1 >= PATH_MAX) | ||
377 | { | ||
378 | free(old_name); | ||
379 | #ifdef UNICODE | ||
380 | old_name = _wcsdup(it->data.cFileName); | ||
381 | #else | ||
382 | old_name = _strdup(it->data.cFileName); | ||
383 | #endif | ||
384 | continue; | ||
385 | } | ||
386 | |||
387 | } while ((it->data.cFileName[0] == '.') && | ||
388 | ((it->data.cFileName[1] == '\0') || | ||
389 | ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */ | ||
390 | |||
391 | #ifdef UNICODE | ||
392 | cname = evil_wchar_to_char(old_name); | ||
393 | if (!cname) | ||
394 | return EINA_FALSE; | ||
395 | #else | ||
396 | cname = old_name; | ||
397 | #endif | ||
398 | |||
399 | memcpy(it->info.path + it->info.name_start, cname, length); | ||
400 | it->info.name_length = length; | ||
401 | it->info.path_length = it->info.name_start + length; | ||
402 | it->info.path[it->info.path_length] = '\0'; | ||
403 | |||
404 | if (attr & FILE_ATTRIBUTE_DIRECTORY) | ||
405 | it->info.type = EINA_FILE_DIR; | ||
406 | else if (attr & FILE_ATTRIBUTE_REPARSE_POINT) | ||
407 | it->info.type = EINA_FILE_LNK; | ||
408 | else if (attr & (FILE_ATTRIBUTE_ARCHIVE | | ||
409 | FILE_ATTRIBUTE_COMPRESSED | | ||
410 | FILE_ATTRIBUTE_COMPRESSED | | ||
411 | FILE_ATTRIBUTE_HIDDEN | | ||
412 | FILE_ATTRIBUTE_NORMAL | | ||
413 | FILE_ATTRIBUTE_SPARSE_FILE | | ||
414 | FILE_ATTRIBUTE_TEMPORARY)) | ||
415 | it->info.type = EINA_FILE_REG; | ||
416 | else | ||
417 | it->info.type = EINA_FILE_UNKNOWN; | ||
418 | |||
419 | *data = &it->info; | ||
420 | |||
421 | #ifdef UNICODE | ||
422 | free(cname); | ||
423 | #endif | ||
424 | |||
425 | free(old_name); | ||
426 | |||
427 | if (is_last) | ||
428 | res = EINA_FALSE; | ||
429 | |||
430 | return res; | ||
431 | } | ||
432 | |||
433 | static HANDLE | ||
434 | _eina_file_win32_direct_ls_iterator_container(Eina_File_Direct_Iterator *it) | ||
435 | { | ||
436 | return it->handle; | ||
437 | } | ||
438 | |||
439 | static void | ||
440 | _eina_file_win32_direct_ls_iterator_free(Eina_File_Direct_Iterator *it) | ||
441 | { | ||
442 | if (it->handle != INVALID_HANDLE_VALUE) | ||
443 | FindClose(it->handle); | ||
444 | |||
445 | EINA_MAGIC_SET(&it->iterator, 0); | ||
446 | free(it); | ||
447 | } | ||
448 | |||
449 | static void | ||
450 | _eina_file_real_close(Eina_File *file) | ||
451 | { | ||
452 | eina_hash_free(file->rmap); | ||
453 | eina_hash_free(file->map); | ||
454 | |||
455 | if (file->global_map != MAP_FAILED) | ||
456 | UnmapViewOfFile(file->global_map); | ||
457 | |||
458 | CloseHandle(file->fm); | ||
459 | CloseHandle(file->handle); | ||
460 | |||
461 | free(file); | ||
462 | } | ||
463 | |||
464 | static void | ||
465 | _eina_file_map_close(Eina_File_Map *map) | ||
466 | { | ||
467 | if (map->map != MAP_FAILED) | ||
468 | UnmapViewOfFile(map->map); | ||
469 | free(map); | ||
470 | } | ||
471 | |||
472 | static unsigned int | ||
473 | _eina_file_map_key_length(const void *key __UNUSED__) | ||
474 | { | ||
475 | return sizeof (unsigned long int) * 2; | ||
476 | } | ||
477 | |||
478 | static int | ||
479 | _eina_file_map_key_cmp(const unsigned long int *key1, int key1_length __UNUSED__, | ||
480 | const unsigned long int *key2, int key2_length __UNUSED__) | ||
481 | { | ||
482 | if (key1[0] - key2[0] == 0) return key1[1] - key2[1]; | ||
483 | return key1[0] - key2[0]; | ||
484 | } | ||
485 | |||
486 | static int | ||
487 | _eina_file_map_key_hash(const unsigned long int *key, int key_length __UNUSED__) | ||
488 | { | ||
489 | return eina_hash_int64(&key[0], sizeof (unsigned long int)) | ||
490 | ^ eina_hash_int64(&key[1], sizeof (unsigned long int)); | ||
491 | } | ||
492 | |||
493 | static char * | ||
494 | _eina_file_win32_escape(const char *path, size_t *length) | ||
495 | { | ||
496 | char *result = strdup(path ? path : ""); | ||
497 | char *p = result; | ||
498 | char *q = result; | ||
499 | size_t len; | ||
500 | |||
501 | if (!result) | ||
502 | return NULL; | ||
503 | |||
504 | if (length) len = *length; | ||
505 | else len = strlen(result); | ||
506 | |||
507 | while ((p = strchr(p, '/'))) | ||
508 | { | ||
509 | // remove double `/' | ||
510 | if (p[1] == '/') | ||
511 | { | ||
512 | memmove(p, p + 1, --len - (p - result)); | ||
513 | result[len] = '\0'; | ||
514 | } | ||
515 | else | ||
516 | if (p[1] == '.' | ||
517 | && p[2] == '.') | ||
518 | { | ||
519 | // remove `/../' | ||
520 | if (p[3] == '/') | ||
521 | { | ||
522 | char tmp; | ||
523 | |||
524 | len -= p + 3 - q; | ||
525 | memmove(q, p + 3, len - (q - result)); | ||
526 | result[len] = '\0'; | ||
527 | p = q; | ||
528 | |||
529 | /* Update q correctly. */ | ||
530 | tmp = *p; | ||
531 | *p = '\0'; | ||
532 | q = strrchr(result, '/'); | ||
533 | if (!q) q = result; | ||
534 | *p = tmp; | ||
535 | } | ||
536 | else | ||
537 | // remove '/..$' | ||
538 | if (p[3] == '\0') | ||
539 | { | ||
540 | len -= p + 2 - q; | ||
541 | result[len] = '\0'; | ||
542 | q = p; | ||
543 | ++p; | ||
544 | } | ||
545 | else | ||
546 | { | ||
547 | q = p; | ||
548 | ++p; | ||
549 | } | ||
550 | } | ||
551 | else | ||
552 | { | ||
553 | q = p; | ||
554 | ++p; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | if (length) | ||
559 | *length = len; | ||
560 | |||
561 | return result; | ||
562 | } | ||
563 | |||
564 | |||
565 | /** | ||
566 | * @endcond | ||
567 | */ | ||
568 | |||
569 | /*============================================================================* | ||
570 | * Global * | ||
571 | *============================================================================*/ | ||
572 | |||
573 | Eina_Bool | ||
574 | eina_file_init(void) | ||
575 | { | ||
576 | _eina_file_log_dom = eina_log_domain_register("eina_file", | ||
577 | EINA_LOG_COLOR_DEFAULT); | ||
578 | if (_eina_file_log_dom < 0) | ||
579 | { | ||
580 | EINA_LOG_ERR("Could not register log domain: eina_file"); | ||
581 | return EINA_FALSE; | ||
582 | } | ||
583 | |||
584 | _eina_file_cache = eina_hash_string_djb2_new(NULL); | ||
585 | if (!_eina_file_cache) | ||
586 | { | ||
587 | ERR("Could not create cache."); | ||
588 | eina_log_domain_unregister(_eina_file_log_dom); | ||
589 | _eina_file_log_dom = -1; | ||
590 | return EINA_FALSE; | ||
591 | } | ||
592 | |||
593 | eina_lock_new(&_eina_file_lock_cache); | ||
594 | |||
595 | return EINA_TRUE; | ||
596 | } | ||
597 | |||
598 | Eina_Bool | ||
599 | eina_file_shutdown(void) | ||
600 | { | ||
601 | if (eina_hash_population(_eina_file_cache) > 0) | ||
602 | { | ||
603 | Eina_Iterator *it; | ||
604 | const char *key; | ||
605 | |||
606 | it = eina_hash_iterator_key_new(_eina_file_cache); | ||
607 | EINA_ITERATOR_FOREACH(it, key) | ||
608 | ERR("File [%s] still open !", key); | ||
609 | eina_iterator_free(it); | ||
610 | } | ||
611 | |||
612 | eina_hash_free(_eina_file_cache); | ||
613 | |||
614 | eina_lock_free(&_eina_file_lock_cache); | ||
615 | |||
616 | eina_log_domain_unregister(_eina_file_log_dom); | ||
617 | _eina_file_log_dom = -1; | ||
618 | return EINA_TRUE; | ||
619 | } | ||
620 | |||
621 | /*============================================================================* | ||
622 | * API * | ||
623 | *============================================================================*/ | ||
624 | |||
625 | |||
626 | EAPI char * | ||
627 | eina_file_path_sanitize(const char *path) | ||
628 | { | ||
629 | char *result = NULL; | ||
630 | size_t len; | ||
631 | |||
632 | if (!path) return NULL; | ||
633 | |||
634 | len = strlen(path); | ||
635 | if (len < 3) return NULL; | ||
636 | |||
637 | if (!evil_path_is_absolute(path)) | ||
638 | { | ||
639 | DWORD l; | ||
640 | |||
641 | l = GetCurrentDirectory(0, NULL); | ||
642 | if (l > 0) | ||
643 | { | ||
644 | char *cwd; | ||
645 | DWORD l2; | ||
646 | |||
647 | cwd = alloca(sizeof(char) * (l + 1)); | ||
648 | l2 = GetCurrentDirectory(l + 1, cwd); | ||
649 | if (l2 == l) | ||
650 | { | ||
651 | char *tmp; | ||
652 | |||
653 | len += l + 2; | ||
654 | tmp = alloca(sizeof (char) * len); | ||
655 | snprintf(tmp, len, "%s/%s", cwd, path); | ||
656 | tmp[len - 1] = '\0'; | ||
657 | result = tmp; | ||
658 | } | ||
659 | } | ||
660 | } | ||
661 | |||
662 | return _eina_file_win32_escape(result ? result : path, &len); | ||
663 | } | ||
664 | |||
665 | EAPI Eina_Bool | ||
666 | eina_file_dir_list(const char *dir, | ||
667 | Eina_Bool recursive, | ||
668 | Eina_File_Dir_List_Cb cb, | ||
669 | void *data) | ||
670 | { | ||
671 | WIN32_FIND_DATA file; | ||
672 | HANDLE h; | ||
673 | char *new_dir; | ||
674 | |||
675 | EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE); | ||
676 | EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE); | ||
677 | EINA_SAFETY_ON_TRUE_RETURN_VAL(dir[0] == '\0', EINA_FALSE); | ||
678 | |||
679 | if (!_eina_file_win32_is_dir(dir)) | ||
680 | return EINA_FALSE; | ||
681 | |||
682 | new_dir = _eina_file_win32_dir_new(dir); | ||
683 | if (!new_dir) | ||
684 | return EINA_FALSE; | ||
685 | |||
686 | h = _eina_file_win32_first_file(new_dir, &file); | ||
687 | |||
688 | if (h == INVALID_HANDLE_VALUE) | ||
689 | return EINA_FALSE; | ||
690 | |||
691 | do | ||
692 | { | ||
693 | char *filename; | ||
694 | |||
695 | # ifdef UNICODE | ||
696 | filename = evil_wchar_to_char(file.cFileName); | ||
697 | # else | ||
698 | filename = file.cFileName; | ||
699 | # endif /* ! UNICODE */ | ||
700 | if (!strcmp(filename, ".") || !strcmp(filename, "..")) | ||
701 | continue; | ||
702 | |||
703 | cb(filename, dir, data); | ||
704 | |||
705 | if (recursive == EINA_TRUE) | ||
706 | { | ||
707 | char *path; | ||
708 | |||
709 | path = alloca(strlen(dir) + strlen(filename) + 2); | ||
710 | strcpy(path, dir); | ||
711 | strcat(path, "/"); | ||
712 | strcat(path, filename); | ||
713 | |||
714 | if (!(file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) | ||
715 | continue; | ||
716 | |||
717 | eina_file_dir_list(path, recursive, cb, data); | ||
718 | } | ||
719 | |||
720 | # ifdef UNICODE | ||
721 | free(filename); | ||
722 | # endif /* UNICODE */ | ||
723 | |||
724 | } while (FindNextFile(h, &file)); | ||
725 | FindClose(h); | ||
726 | |||
727 | return EINA_TRUE; | ||
728 | } | ||
729 | |||
730 | EAPI Eina_Array * | ||
731 | eina_file_split(char *path) | ||
732 | { | ||
733 | Eina_Array *ea; | ||
734 | char *current; | ||
735 | size_t length; | ||
736 | |||
737 | EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); | ||
738 | |||
739 | ea = eina_array_new(16); | ||
740 | |||
741 | if (!ea) | ||
742 | return NULL; | ||
743 | |||
744 | for (current = strchr(path, '\\'); | ||
745 | current; | ||
746 | path = current + 1, current = strchr(path, '\\')) | ||
747 | { | ||
748 | length = current - path; | ||
749 | |||
750 | if (length <= 0) | ||
751 | continue; | ||
752 | |||
753 | eina_array_push(ea, path); | ||
754 | *current = '\0'; | ||
755 | } | ||
756 | |||
757 | if (*path != '\0') | ||
758 | eina_array_push(ea, path); | ||
759 | |||
760 | return ea; | ||
761 | } | ||
762 | |||
763 | EAPI Eina_Iterator * | ||
764 | eina_file_ls(const char *dir) | ||
765 | { | ||
766 | Eina_File_Iterator *it; | ||
767 | char *new_dir; | ||
768 | size_t length; | ||
769 | |||
770 | EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); | ||
771 | |||
772 | if (!dir || !*dir) | ||
773 | return NULL; | ||
774 | |||
775 | if (!_eina_file_win32_is_dir(dir)) | ||
776 | return NULL; | ||
777 | |||
778 | length = strlen(dir); | ||
779 | |||
780 | it = calloc(1, sizeof (Eina_File_Iterator) + length); | ||
781 | if (!it) | ||
782 | return NULL; | ||
783 | |||
784 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
785 | |||
786 | new_dir = _eina_file_win32_dir_new(dir); | ||
787 | if (!new_dir) | ||
788 | goto free_it; | ||
789 | |||
790 | it->handle = _eina_file_win32_first_file(new_dir, &it->data); | ||
791 | free(new_dir); | ||
792 | if (it->handle == INVALID_HANDLE_VALUE) | ||
793 | goto free_it; | ||
794 | |||
795 | memcpy(it->dir, dir, length + 1); | ||
796 | if (dir[length - 1] != '\\') | ||
797 | it->length = length; | ||
798 | else | ||
799 | it->length = length - 1; | ||
800 | _eina_file_win32_backslash_change(it->dir); | ||
801 | |||
802 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
803 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_ls_iterator_next); | ||
804 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_ls_iterator_container); | ||
805 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_ls_iterator_free); | ||
806 | |||
807 | return &it->iterator; | ||
808 | |||
809 | free_it: | ||
810 | free(it); | ||
811 | |||
812 | return NULL; | ||
813 | } | ||
814 | |||
815 | EAPI Eina_Iterator * | ||
816 | eina_file_direct_ls(const char *dir) | ||
817 | { | ||
818 | Eina_File_Direct_Iterator *it; | ||
819 | char *new_dir; | ||
820 | size_t length; | ||
821 | |||
822 | EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); | ||
823 | |||
824 | if (!dir || !*dir) | ||
825 | return NULL; | ||
826 | |||
827 | length = strlen(dir); | ||
828 | |||
829 | if (length + 12 + 2 >= MAX_PATH) | ||
830 | return NULL; | ||
831 | |||
832 | it = calloc(1, sizeof(Eina_File_Direct_Iterator) + length); | ||
833 | if (!it) | ||
834 | return NULL; | ||
835 | |||
836 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
837 | |||
838 | new_dir = _eina_file_win32_dir_new(dir); | ||
839 | if (!new_dir) | ||
840 | goto free_it; | ||
841 | |||
842 | it->handle = _eina_file_win32_first_file(new_dir, &it->data); | ||
843 | free(new_dir); | ||
844 | if (it->handle == INVALID_HANDLE_VALUE) | ||
845 | goto free_it; | ||
846 | |||
847 | memcpy(it->dir, dir, length + 1); | ||
848 | it->length = length; | ||
849 | _eina_file_win32_backslash_change(it->dir); | ||
850 | |||
851 | memcpy(it->info.path, dir, length); | ||
852 | if (dir[length - 1] == '\\') | ||
853 | it->info.name_start = length; | ||
854 | else | ||
855 | { | ||
856 | it->info.path[length] = '\\'; | ||
857 | it->info.name_start = length + 1; | ||
858 | } | ||
859 | _eina_file_win32_backslash_change(it->info.path); | ||
860 | |||
861 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
862 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_direct_ls_iterator_next); | ||
863 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_direct_ls_iterator_container); | ||
864 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_direct_ls_iterator_free); | ||
865 | |||
866 | return &it->iterator; | ||
867 | |||
868 | free_it: | ||
869 | free(it); | ||
870 | |||
871 | return NULL; | ||
872 | } | ||
873 | |||
874 | EAPI Eina_Iterator * | ||
875 | eina_file_stat_ls(const char *dir) | ||
876 | { | ||
877 | return eina_file_direct_ls(dir); | ||
878 | } | ||
879 | |||
880 | EAPI Eina_File * | ||
881 | eina_file_open(const char *path, Eina_Bool shared) | ||
882 | { | ||
883 | Eina_File *file; | ||
884 | Eina_File *n; | ||
885 | char *filename; | ||
886 | HANDLE handle; | ||
887 | HANDLE fm; | ||
888 | WIN32_FILE_ATTRIBUTE_DATA fad; | ||
889 | ULARGE_INTEGER length; | ||
890 | ULARGE_INTEGER mtime; | ||
891 | |||
892 | EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); | ||
893 | |||
894 | filename = eina_file_path_sanitize(path); | ||
895 | if (!filename) return NULL; | ||
896 | |||
897 | /* FIXME: how to emulate shm_open ? Just OpenFileMapping ? */ | ||
898 | #if 0 | ||
899 | if (shared) | ||
900 | handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, | ||
901 | NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, | ||
902 | NULL); | ||
903 | else | ||
904 | #endif | ||
905 | handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, | ||
906 | NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, | ||
907 | NULL); | ||
908 | |||
909 | if (handle == INVALID_HANDLE_VALUE) | ||
910 | return NULL; | ||
911 | |||
912 | fm = CreateFileMapping(handle, NULL, PAGE_READONLY, 0, 0, NULL); | ||
913 | if (!fm) | ||
914 | goto close_handle; | ||
915 | |||
916 | if (!GetFileAttributesEx(filename, GetFileExInfoStandard, &fad)) | ||
917 | goto close_fm; | ||
918 | |||
919 | length.u.LowPart = fad.nFileSizeLow; | ||
920 | length.u.HighPart = fad.nFileSizeHigh; | ||
921 | mtime.u.LowPart = fad.ftLastWriteTime.dwLowDateTime; | ||
922 | mtime.u.HighPart = fad.ftLastWriteTime.dwHighDateTime; | ||
923 | |||
924 | eina_lock_take(&_eina_file_lock_cache); | ||
925 | |||
926 | file = eina_hash_find(_eina_file_cache, filename); | ||
927 | if (file && | ||
928 | (file->mtime != mtime.QuadPart || file->length != length.QuadPart)) | ||
929 | { | ||
930 | file->delete_me = EINA_TRUE; | ||
931 | eina_hash_del(_eina_file_cache, file->filename, file); | ||
932 | _eina_file_real_close(file); | ||
933 | file = NULL; | ||
934 | } | ||
935 | |||
936 | if (!file) | ||
937 | { | ||
938 | n = malloc(sizeof (Eina_File) + strlen(filename) + 1); | ||
939 | if (!n) | ||
940 | { | ||
941 | eina_lock_release(&_eina_file_lock_cache); | ||
942 | goto close_fm; | ||
943 | } | ||
944 | |||
945 | n->filename = (char*) (n + 1); | ||
946 | strcpy((char*) n->filename, filename); | ||
947 | n->map = eina_hash_new(EINA_KEY_LENGTH(_eina_file_map_key_length), | ||
948 | EINA_KEY_CMP(_eina_file_map_key_cmp), | ||
949 | EINA_KEY_HASH(_eina_file_map_key_hash), | ||
950 | EINA_FREE_CB(_eina_file_map_close), | ||
951 | 3); | ||
952 | n->rmap = eina_hash_pointer_new(NULL); | ||
953 | n->global_map = MAP_FAILED; | ||
954 | n->global_refcount = 0; | ||
955 | n->length = length.QuadPart; | ||
956 | n->mtime = mtime.QuadPart; | ||
957 | n->refcount = 0; | ||
958 | n->handle = handle; | ||
959 | n->fm = fm; | ||
960 | n->shared = shared; | ||
961 | n->delete_me = EINA_FALSE; | ||
962 | eina_lock_new(&n->lock); | ||
963 | eina_hash_direct_add(_eina_file_cache, n->filename, n); | ||
964 | } | ||
965 | else | ||
966 | { | ||
967 | CloseHandle(fm); | ||
968 | CloseHandle(handle); | ||
969 | |||
970 | n = file; | ||
971 | } | ||
972 | eina_lock_take(&n->lock); | ||
973 | n->refcount++; | ||
974 | eina_lock_release(&n->lock); | ||
975 | |||
976 | eina_lock_release(&_eina_file_lock_cache); | ||
977 | |||
978 | free(filename); | ||
979 | |||
980 | return n; | ||
981 | |||
982 | close_fm: | ||
983 | CloseHandle(fm); | ||
984 | close_handle: | ||
985 | CloseHandle(handle); | ||
986 | |||
987 | return NULL; | ||
988 | } | ||
989 | |||
990 | EAPI void | ||
991 | eina_file_close(Eina_File *file) | ||
992 | { | ||
993 | EINA_SAFETY_ON_NULL_RETURN(file); | ||
994 | |||
995 | eina_lock_take(&file->lock); | ||
996 | file->refcount--; | ||
997 | eina_lock_release(&file->lock); | ||
998 | |||
999 | if (file->refcount != 0) return ; | ||
1000 | eina_lock_take(&_eina_file_lock_cache); | ||
1001 | |||
1002 | eina_hash_del(_eina_file_cache, file->filename, file); | ||
1003 | _eina_file_real_close(file); | ||
1004 | |||
1005 | eina_lock_release(&_eina_file_lock_cache); | ||
1006 | } | ||
1007 | |||
1008 | EAPI size_t | ||
1009 | eina_file_size_get(Eina_File *file) | ||
1010 | { | ||
1011 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0); | ||
1012 | return file->length; | ||
1013 | } | ||
1014 | |||
1015 | EAPI time_t | ||
1016 | eina_file_mtime_get(Eina_File *file) | ||
1017 | { | ||
1018 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0); | ||
1019 | return file->mtime; | ||
1020 | } | ||
1021 | |||
1022 | EAPI const char * | ||
1023 | eina_file_filename_get(Eina_File *file) | ||
1024 | { | ||
1025 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
1026 | return file->filename; | ||
1027 | } | ||
1028 | |||
1029 | EAPI Eina_Iterator *eina_file_xattr_get(Eina_File *file __UNUSED__) | ||
1030 | { | ||
1031 | return NULL; | ||
1032 | } | ||
1033 | |||
1034 | EAPI Eina_Iterator *eina_file_xattr_value_get(Eina_File *file __UNUSED__) | ||
1035 | { | ||
1036 | return NULL; | ||
1037 | } | ||
1038 | |||
1039 | EAPI void * | ||
1040 | eina_file_map_all(Eina_File *file, Eina_File_Populate rule __UNUSED__) | ||
1041 | { | ||
1042 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
1043 | |||
1044 | eina_lock_take(&file->lock); | ||
1045 | if (file->global_map == MAP_FAILED) | ||
1046 | { | ||
1047 | void *data; | ||
1048 | |||
1049 | data = MapViewOfFile(file->fm, FILE_MAP_READ, | ||
1050 | 0, 0, file->length); | ||
1051 | if (!data) | ||
1052 | file->global_map = MAP_FAILED; | ||
1053 | else | ||
1054 | file->global_map = data; | ||
1055 | } | ||
1056 | |||
1057 | if (file->global_map != MAP_FAILED) | ||
1058 | { | ||
1059 | file->global_refcount++; | ||
1060 | return file->global_map; | ||
1061 | } | ||
1062 | |||
1063 | eina_lock_release(&file->lock); | ||
1064 | return NULL; | ||
1065 | } | ||
1066 | |||
1067 | EAPI void * | ||
1068 | eina_file_map_new(Eina_File *file, Eina_File_Populate rule, | ||
1069 | unsigned long int offset, unsigned long int length) | ||
1070 | { | ||
1071 | Eina_File_Map *map; | ||
1072 | unsigned long int key[2]; | ||
1073 | |||
1074 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
1075 | |||
1076 | if (offset > file->length) | ||
1077 | return NULL; | ||
1078 | if (offset + length > file->length) | ||
1079 | return NULL; | ||
1080 | |||
1081 | if (offset == 0 && length == file->length) | ||
1082 | return eina_file_map_all(file, rule); | ||
1083 | |||
1084 | key[0] = offset; | ||
1085 | key[1] = length; | ||
1086 | |||
1087 | eina_lock_take(&file->lock); | ||
1088 | |||
1089 | map = eina_hash_find(file->map, &key); | ||
1090 | if (!map) | ||
1091 | { | ||
1092 | void *data; | ||
1093 | |||
1094 | map = malloc(sizeof (Eina_File_Map)); | ||
1095 | if (!map) | ||
1096 | { | ||
1097 | eina_lock_release(&file->lock); | ||
1098 | return NULL; | ||
1099 | } | ||
1100 | |||
1101 | data = MapViewOfFile(file->fm, FILE_MAP_READ, | ||
1102 | offset & 0xffff0000, | ||
1103 | offset & 0x0000ffff, | ||
1104 | length); | ||
1105 | if (!data) | ||
1106 | map->map = MAP_FAILED; | ||
1107 | else | ||
1108 | map->map = data; | ||
1109 | |||
1110 | map->offset = offset; | ||
1111 | map->length = length; | ||
1112 | map->refcount = 0; | ||
1113 | |||
1114 | if (map->map == MAP_FAILED) | ||
1115 | { | ||
1116 | free(map); | ||
1117 | eina_lock_release(&file->lock); | ||
1118 | return NULL; | ||
1119 | } | ||
1120 | |||
1121 | eina_hash_add(file->map, &key, map); | ||
1122 | eina_hash_direct_add(file->rmap, map->map, map); | ||
1123 | } | ||
1124 | |||
1125 | map->refcount++; | ||
1126 | |||
1127 | eina_lock_release(&file->lock); | ||
1128 | |||
1129 | return map->map; | ||
1130 | } | ||
1131 | |||
1132 | EAPI void | ||
1133 | eina_file_map_free(Eina_File *file, void *map) | ||
1134 | { | ||
1135 | EINA_SAFETY_ON_NULL_RETURN(file); | ||
1136 | |||
1137 | eina_lock_take(&file->lock); | ||
1138 | |||
1139 | if (file->global_map == map) | ||
1140 | { | ||
1141 | file->global_refcount--; | ||
1142 | |||
1143 | if (file->global_refcount > 0) goto on_exit; | ||
1144 | |||
1145 | UnmapViewOfFile(file->global_map); | ||
1146 | file->global_map = MAP_FAILED; | ||
1147 | } | ||
1148 | else | ||
1149 | { | ||
1150 | Eina_File_Map *em; | ||
1151 | unsigned long int key[2]; | ||
1152 | |||
1153 | em = eina_hash_find(file->rmap, &map); | ||
1154 | if (!em) goto on_exit; | ||
1155 | |||
1156 | em->refcount--; | ||
1157 | |||
1158 | if (em->refcount > 0) goto on_exit; | ||
1159 | |||
1160 | key[0] = em->offset; | ||
1161 | key[1] = em->length; | ||
1162 | |||
1163 | eina_hash_del(file->rmap, &map, em); | ||
1164 | eina_hash_del(file->map, &key, em); | ||
1165 | } | ||
1166 | |||
1167 | on_exit: | ||
1168 | eina_lock_release(&file->lock); | ||
1169 | } | ||
1170 | |||
1171 | EAPI int | ||
1172 | eina_file_statat(void *container __UNUSED__, Eina_File_Direct_Info *info, Eina_Stat *st) | ||
1173 | { | ||
1174 | struct __stat64 buf; | ||
1175 | |||
1176 | EINA_SAFETY_ON_NULL_RETURN_VAL(info, -1); | ||
1177 | EINA_SAFETY_ON_NULL_RETURN_VAL(st, -1); | ||
1178 | |||
1179 | if (stat64(info->path, &buf)) | ||
1180 | { | ||
1181 | if (info->type != EINA_FILE_LNK) | ||
1182 | info->type = EINA_FILE_UNKNOWN; | ||
1183 | return -1; | ||
1184 | } | ||
1185 | |||
1186 | if (info->type == EINA_FILE_UNKNOWN) | ||
1187 | { | ||
1188 | if (S_ISREG(buf.st_mode)) | ||
1189 | info->type = EINA_FILE_REG; | ||
1190 | else if (S_ISDIR(buf.st_mode)) | ||
1191 | info->type = EINA_FILE_DIR; | ||
1192 | else | ||
1193 | info->type = EINA_FILE_UNKNOWN; | ||
1194 | } | ||
1195 | |||
1196 | st->dev = buf.st_dev; | ||
1197 | st->ino = buf.st_ino; | ||
1198 | st->mode = buf.st_mode; | ||
1199 | st->nlink = buf.st_nlink; | ||
1200 | st->uid = buf.st_uid; | ||
1201 | st->gid = buf.st_gid; | ||
1202 | st->rdev = buf.st_rdev; | ||
1203 | st->size = buf.st_size; | ||
1204 | st->blksize = 0; | ||
1205 | st->blocks = 0; | ||
1206 | st->atime = buf.st_atime; | ||
1207 | st->mtime = buf.st_mtime; | ||
1208 | st->ctime = buf.st_ctime; | ||
1209 | st->atimensec = 0; | ||
1210 | st->mtimensec = 0; | ||
1211 | st->ctimensec = 0; | ||
1212 | |||
1213 | return 0; | ||
1214 | } | ||
diff --git a/libraries/eina/src/lib/eina_fp.c b/libraries/eina/src/lib/eina_fp.c deleted file mode 100644 index 8984b49..0000000 --- a/libraries/eina/src/lib/eina_fp.c +++ /dev/null | |||
@@ -1,532 +0,0 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include "config.h" | ||
3 | #endif | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <math.h> | ||
7 | |||
8 | #include "eina_types.h" | ||
9 | #include "eina_fp.h" | ||
10 | |||
11 | #define MAX_PREC 1025 | ||
12 | static const Eina_F32p32 eina_trigo[MAX_PREC] = | ||
13 | { | ||
14 | 0x0000000100000000, 0x00000000ffffec43, 0x00000000ffffb10b, | ||
15 | 0x00000000ffff4e5a, 0x00000000fffec42e, 0x00000000fffe1287, | ||
16 | 0x00000000fffd3967, 0x00000000fffc38cd, 0x00000000fffb10b9, | ||
17 | 0x00000000fff9c12c, | ||
18 | 0x00000000fff84a25, 0x00000000fff6aba5, 0x00000000fff4e5ac, | ||
19 | 0x00000000fff2f83b, 0x00000000fff0e351, 0x00000000ffeea6ef, | ||
20 | 0x00000000ffec4316, 0x00000000ffe9b7c5, 0x00000000ffe704fe, | ||
21 | 0x00000000ffe42ac0, | ||
22 | 0x00000000ffe1290b, 0x00000000ffddffe2, 0x00000000ffdaaf43, | ||
23 | 0x00000000ffd7372f, 0x00000000ffd397a8, 0x00000000ffcfd0ad, | ||
24 | 0x00000000ffcbe23f, 0x00000000ffc7cc5f, 0x00000000ffc38f0d, | ||
25 | 0x00000000ffbf2a4b, | ||
26 | 0x00000000ffba9e17, 0x00000000ffb5ea75, 0x00000000ffb10f63, | ||
27 | 0x00000000ffac0ce3, 0x00000000ffa6e2f6, 0x00000000ffa1919c, | ||
28 | 0x00000000ff9c18d6, 0x00000000ff9678a6, 0x00000000ff90b10b, | ||
29 | 0x00000000ff8ac208, | ||
30 | 0x00000000ff84ab9c, 0x00000000ff7e6dc8, 0x00000000ff78088f, | ||
31 | 0x00000000ff717bf0, 0x00000000ff6ac7ec, 0x00000000ff63ec85, | ||
32 | 0x00000000ff5ce9bc, 0x00000000ff55bf92, 0x00000000ff4e6e08, | ||
33 | 0x00000000ff46f51f, | ||
34 | 0x00000000ff3f54d8, 0x00000000ff378d34, 0x00000000ff2f9e35, | ||
35 | 0x00000000ff2787dc, 0x00000000ff1f4a2a, 0x00000000ff16e520, | ||
36 | 0x00000000ff0e58c0, 0x00000000ff05a50a, 0x00000000fefcca01, | ||
37 | 0x00000000fef3c7a6, | ||
38 | 0x00000000feea9df9, 0x00000000fee14cfe, 0x00000000fed7d4b3, | ||
39 | 0x00000000fece351d, 0x00000000fec46e3b, 0x00000000feba800f, | ||
40 | 0x00000000feb06a9c, 0x00000000fea62de1, 0x00000000fe9bc9e2, | ||
41 | 0x00000000fe913e9f, | ||
42 | 0x00000000fe868c1b, 0x00000000fe7bb256, 0x00000000fe70b153, | ||
43 | 0x00000000fe658913, 0x00000000fe5a3998, 0x00000000fe4ec2e4, | ||
44 | 0x00000000fe4324f9, 0x00000000fe375fd7, 0x00000000fe2b7382, | ||
45 | 0x00000000fe1f5ffa, | ||
46 | 0x00000000fe132543, 0x00000000fe06c35d, 0x00000000fdfa3a4b, | ||
47 | 0x00000000fded8a0e, 0x00000000fde0b2a8, 0x00000000fdd3b41c, | ||
48 | 0x00000000fdc68e6c, 0x00000000fdb94199, 0x00000000fdabcda5, | ||
49 | 0x00000000fd9e3294, | ||
50 | 0x00000000fd907065, 0x00000000fd82871d, 0x00000000fd7476bd, | ||
51 | 0x00000000fd663f46, 0x00000000fd57e0bd, 0x00000000fd495b21, | ||
52 | 0x00000000fd3aae77, 0x00000000fd2bdabf, 0x00000000fd1cdffd, | ||
53 | 0x00000000fd0dbe32, | ||
54 | 0x00000000fcfe7562, 0x00000000fcef058e, 0x00000000fcdf6eb8, | ||
55 | 0x00000000fccfb0e4, 0x00000000fcbfcc13, 0x00000000fcafc048, | ||
56 | 0x00000000fc9f8d86, 0x00000000fc8f33ce, 0x00000000fc7eb325, | ||
57 | 0x00000000fc6e0b8b, | ||
58 | 0x00000000fc5d3d03, 0x00000000fc4c4791, 0x00000000fc3b2b37, | ||
59 | 0x00000000fc29e7f7, 0x00000000fc187dd5, 0x00000000fc06ecd2, | ||
60 | 0x00000000fbf534f2, 0x00000000fbe35637, 0x00000000fbd150a3, | ||
61 | 0x00000000fbbf243b, | ||
62 | 0x00000000fbacd100, 0x00000000fb9a56f6, 0x00000000fb87b61f, | ||
63 | 0x00000000fb74ee7e, 0x00000000fb620016, 0x00000000fb4eeaea, | ||
64 | 0x00000000fb3baefd, 0x00000000fb284c52, 0x00000000fb14c2eb, | ||
65 | 0x00000000fb0112cd, | ||
66 | 0x00000000faed3bf9, 0x00000000fad93e73, 0x00000000fac51a3f, | ||
67 | 0x00000000fab0cf5e, 0x00000000fa9c5dd5, 0x00000000fa87c5a6, | ||
68 | 0x00000000fa7306d5, 0x00000000fa5e2164, 0x00000000fa491558, | ||
69 | 0x00000000fa33e2b3, | ||
70 | 0x00000000fa1e8978, 0x00000000fa0909ab, 0x00000000f9f36350, | ||
71 | 0x00000000f9dd9668, 0x00000000f9c7a2f9, 0x00000000f9b18905, | ||
72 | 0x00000000f99b488f, 0x00000000f984e19c, 0x00000000f96e542e, | ||
73 | 0x00000000f957a049, | ||
74 | 0x00000000f940c5f1, 0x00000000f929c528, 0x00000000f9129df3, | ||
75 | 0x00000000f8fb5056, 0x00000000f8e3dc53, 0x00000000f8cc41ee, | ||
76 | 0x00000000f8b4812b, 0x00000000f89c9a0e, 0x00000000f8848c9b, | ||
77 | 0x00000000f86c58d4, | ||
78 | 0x00000000f853febe, 0x00000000f83b7e5d, 0x00000000f822d7b4, | ||
79 | 0x00000000f80a0ac7, 0x00000000f7f1179a, 0x00000000f7d7fe31, | ||
80 | 0x00000000f7bebe90, 0x00000000f7a558ba, 0x00000000f78bccb3, | ||
81 | 0x00000000f7721a80, | ||
82 | 0x00000000f7584225, 0x00000000f73e43a5, 0x00000000f7241f04, | ||
83 | 0x00000000f709d446, 0x00000000f6ef6370, 0x00000000f6d4cc85, | ||
84 | 0x00000000f6ba0f8a, 0x00000000f69f2c83, 0x00000000f6842374, | ||
85 | 0x00000000f668f461, | ||
86 | 0x00000000f64d9f4e, 0x00000000f632243f, 0x00000000f616833a, | ||
87 | 0x00000000f5fabc41, 0x00000000f5decf59, 0x00000000f5c2bc87, | ||
88 | 0x00000000f5a683cf, 0x00000000f58a2535, 0x00000000f56da0be, | ||
89 | 0x00000000f550f66e, | ||
90 | 0x00000000f5342649, 0x00000000f5173054, 0x00000000f4fa1494, | ||
91 | 0x00000000f4dcd30c, 0x00000000f4bf6bc2, 0x00000000f4a1deb9, | ||
92 | 0x00000000f4842bf7, 0x00000000f4665380, 0x00000000f4485559, | ||
93 | 0x00000000f42a3186, | ||
94 | 0x00000000f40be80c, 0x00000000f3ed78ef, 0x00000000f3cee434, | ||
95 | 0x00000000f3b029e1, 0x00000000f39149f9, 0x00000000f3724482, | ||
96 | 0x00000000f3531980, 0x00000000f333c8f8, 0x00000000f31452ef, | ||
97 | 0x00000000f2f4b76a, | ||
98 | 0x00000000f2d4f66d, 0x00000000f2b50ffe, 0x00000000f2950421, | ||
99 | 0x00000000f274d2dc, 0x00000000f2547c33, 0x00000000f234002b, | ||
100 | 0x00000000f2135eca, 0x00000000f1f29814, 0x00000000f1d1ac0e, | ||
101 | 0x00000000f1b09abe, | ||
102 | 0x00000000f18f6429, 0x00000000f16e0853, 0x00000000f14c8742, | ||
103 | 0x00000000f12ae0fb, 0x00000000f1091583, 0x00000000f0e724e0, | ||
104 | 0x00000000f0c50f17, 0x00000000f0a2d42c, 0x00000000f0807426, | ||
105 | 0x00000000f05def09, | ||
106 | 0x00000000f03b44db, 0x00000000f01875a1, 0x00000000eff58161, | ||
107 | 0x00000000efd2681f, 0x00000000efaf29e2, 0x00000000ef8bc6af, | ||
108 | 0x00000000ef683e8b, 0x00000000ef44917b, 0x00000000ef20bf86, | ||
109 | 0x00000000eefcc8b1, | ||
110 | 0x00000000eed8ad01, 0x00000000eeb46c7b, 0x00000000ee900727, | ||
111 | 0x00000000ee6b7d08, 0x00000000ee46ce25, 0x00000000ee21fa83, | ||
112 | 0x00000000edfd0228, 0x00000000edd7e51a, 0x00000000edb2a35f, | ||
113 | 0x00000000ed8d3cfc, | ||
114 | 0x00000000ed67b1f6, 0x00000000ed420255, 0x00000000ed1c2e1d, | ||
115 | 0x00000000ecf63554, 0x00000000ecd01801, 0x00000000eca9d628, | ||
116 | 0x00000000ec836fd1, 0x00000000ec5ce501, 0x00000000ec3635bd, | ||
117 | 0x00000000ec0f620d, | ||
118 | 0x00000000ebe869f5, 0x00000000ebc14d7d, 0x00000000eb9a0ca9, | ||
119 | 0x00000000eb72a780, 0x00000000eb4b1e08, 0x00000000eb237047, | ||
120 | 0x00000000eafb9e43, 0x00000000ead3a803, 0x00000000eaab8d8d, | ||
121 | 0x00000000ea834ee6, | ||
122 | 0x00000000ea5aec15, 0x00000000ea326520, 0x00000000ea09ba0d, | ||
123 | 0x00000000e9e0eae4, 0x00000000e9b7f7a9, 0x00000000e98ee063, | ||
124 | 0x00000000e965a51a, 0x00000000e93c45d2, 0x00000000e912c292, | ||
125 | 0x00000000e8e91b61, | ||
126 | 0x00000000e8bf5046, 0x00000000e8956146, 0x00000000e86b4e68, | ||
127 | 0x00000000e84117b3, 0x00000000e816bd2d, 0x00000000e7ec3edc, | ||
128 | 0x00000000e7c19cc8, 0x00000000e796d6f6, 0x00000000e76bed6e, | ||
129 | 0x00000000e740e036, | ||
130 | 0x00000000e715af54, 0x00000000e6ea5ad0, 0x00000000e6bee2af, | ||
131 | 0x00000000e69346f9, 0x00000000e66787b5, 0x00000000e63ba4e9, | ||
132 | 0x00000000e60f9e9b, 0x00000000e5e374d4, 0x00000000e5b72798, | ||
133 | 0x00000000e58ab6f1, | ||
134 | 0x00000000e55e22e3, 0x00000000e5316b76, 0x00000000e50490b1, | ||
135 | 0x00000000e4d7929c, 0x00000000e4aa713c, 0x00000000e47d2c98, | ||
136 | 0x00000000e44fc4b9, 0x00000000e42239a4, 0x00000000e3f48b61, | ||
137 | 0x00000000e3c6b9f7, | ||
138 | 0x00000000e398c56c, 0x00000000e36aadc9, 0x00000000e33c7314, | ||
139 | 0x00000000e30e1554, 0x00000000e2df9490, 0x00000000e2b0f0d0, | ||
140 | 0x00000000e2822a1a, 0x00000000e2534077, 0x00000000e22433ec, | ||
141 | 0x00000000e1f50482, | ||
142 | 0x00000000e1c5b240, 0x00000000e1963d2d, 0x00000000e166a550, | ||
143 | 0x00000000e136eab0, 0x00000000e1070d56, 0x00000000e0d70d48, | ||
144 | 0x00000000e0a6ea8e, 0x00000000e076a52f, 0x00000000e0463d33, | ||
145 | 0x00000000e015b2a1, | ||
146 | 0x00000000dfe50580, 0x00000000dfb435d9, 0x00000000df8343b2, | ||
147 | 0x00000000df522f13, 0x00000000df20f804, 0x00000000deef9e8d, | ||
148 | 0x00000000debe22b5, 0x00000000de8c8483, 0x00000000de5ac3ff, | ||
149 | 0x00000000de28e131, | ||
150 | 0x00000000ddf6dc21, 0x00000000ddc4b4d6, 0x00000000dd926b59, | ||
151 | 0x00000000dd5fffb0, 0x00000000dd2d71e3, 0x00000000dcfac1fb, | ||
152 | 0x00000000dcc7f000, 0x00000000dc94fbf8, 0x00000000dc61e5ec, | ||
153 | 0x00000000dc2eade4, | ||
154 | 0x00000000dbfb53e8, 0x00000000dbc7d7ff, 0x00000000db943a31, | ||
155 | 0x00000000db607a88, 0x00000000db2c9909, 0x00000000daf895bf, | ||
156 | 0x00000000dac470af, 0x00000000da9029e3, 0x00000000da5bc163, | ||
157 | 0x00000000da273737, | ||
158 | 0x00000000d9f28b66, 0x00000000d9bdbdf9, 0x00000000d988cef8, | ||
159 | 0x00000000d953be6b, 0x00000000d91e8c5b, 0x00000000d8e938d0, | ||
160 | 0x00000000d8b3c3d1, 0x00000000d87e2d67, 0x00000000d848759b, | ||
161 | 0x00000000d8129c74, | ||
162 | 0x00000000d7dca1fb, 0x00000000d7a68638, 0x00000000d7704934, | ||
163 | 0x00000000d739eaf7, 0x00000000d7036b89, 0x00000000d6cccaf3, | ||
164 | 0x00000000d696093d, 0x00000000d65f266f, 0x00000000d6282293, | ||
165 | 0x00000000d5f0fdb0, | ||
166 | 0x00000000d5b9b7d0, 0x00000000d58250fa, 0x00000000d54ac937, | ||
167 | 0x00000000d513208f, 0x00000000d4db570c, 0x00000000d4a36cb6, | ||
168 | 0x00000000d46b6195, 0x00000000d43335b3, 0x00000000d3fae917, | ||
169 | 0x00000000d3c27bcb, | ||
170 | 0x00000000d389edd7, 0x00000000d3513f43, 0x00000000d318701a, | ||
171 | 0x00000000d2df8063, 0x00000000d2a67027, 0x00000000d26d3f6f, | ||
172 | 0x00000000d233ee43, 0x00000000d1fa7cae, 0x00000000d1c0eab7, | ||
173 | 0x00000000d1873867, | ||
174 | 0x00000000d14d65c8, 0x00000000d11372e1, 0x00000000d0d95fbd, | ||
175 | 0x00000000d09f2c64, 0x00000000d064d8df, 0x00000000d02a6537, | ||
176 | 0x00000000cfefd176, 0x00000000cfb51da3, 0x00000000cf7a49c8, | ||
177 | 0x00000000cf3f55ef, | ||
178 | 0x00000000cf044220, 0x00000000cec90e64, 0x00000000ce8dbac5, | ||
179 | 0x00000000ce52474c, 0x00000000ce16b401, 0x00000000cddb00ef, | ||
180 | 0x00000000cd9f2e1e, 0x00000000cd633b97, 0x00000000cd272964, | ||
181 | 0x00000000cceaf78e, | ||
182 | 0x00000000ccaea61e, 0x00000000cc72351e, 0x00000000cc35a497, | ||
183 | 0x00000000cbf8f492, 0x00000000cbbc2519, 0x00000000cb7f3634, | ||
184 | 0x00000000cb4227ee, 0x00000000cb04fa50, 0x00000000cac7ad63, | ||
185 | 0x00000000ca8a4131, | ||
186 | 0x00000000ca4cb5c3, 0x00000000ca0f0b22, 0x00000000c9d14159, | ||
187 | 0x00000000c9935870, 0x00000000c9555072, 0x00000000c9172967, | ||
188 | 0x00000000c8d8e35a, 0x00000000c89a7e53, 0x00000000c85bfa5e, | ||
189 | 0x00000000c81d5782, | ||
190 | 0x00000000c7de95cb, 0x00000000c79fb541, 0x00000000c760b5ee, | ||
191 | 0x00000000c72197dc, 0x00000000c6e25b15, 0x00000000c6a2ffa3, | ||
192 | 0x00000000c663858f, 0x00000000c623ece2, 0x00000000c5e435a8, | ||
193 | 0x00000000c5a45fe9, | ||
194 | 0x00000000c5646bb0, 0x00000000c5245906, 0x00000000c4e427f6, | ||
195 | 0x00000000c4a3d888, 0x00000000c4636ac8, 0x00000000c422debf, | ||
196 | 0x00000000c3e23476, 0x00000000c3a16bf9, 0x00000000c3608550, | ||
197 | 0x00000000c31f8087, | ||
198 | 0x00000000c2de5da6, 0x00000000c29d1cb8, 0x00000000c25bbdc8, | ||
199 | 0x00000000c21a40de, 0x00000000c1d8a606, 0x00000000c196ed49, | ||
200 | 0x00000000c15516b2, 0x00000000c113224a, 0x00000000c0d1101d, | ||
201 | 0x00000000c08ee033, | ||
202 | 0x00000000c04c9297, 0x00000000c00a2754, 0x00000000bfc79e73, | ||
203 | 0x00000000bf84f800, 0x00000000bf423404, 0x00000000beff5289, | ||
204 | 0x00000000bebc539a, 0x00000000be793741, 0x00000000be35fd89, | ||
205 | 0x00000000bdf2a67b, | ||
206 | 0x00000000bdaf3223, 0x00000000bd6ba08b, 0x00000000bd27f1bc, | ||
207 | 0x00000000bce425c2, 0x00000000bca03ca7, 0x00000000bc5c3676, | ||
208 | 0x00000000bc181338, 0x00000000bbd3d2f9, 0x00000000bb8f75c3, | ||
209 | 0x00000000bb4afba1, | ||
210 | 0x00000000bb06649c, 0x00000000bac1b0c0, 0x00000000ba7ce018, | ||
211 | 0x00000000ba37f2ad, 0x00000000b9f2e88b, 0x00000000b9adc1bc, | ||
212 | 0x00000000b9687e4a, 0x00000000b9231e41, 0x00000000b8dda1ac, | ||
213 | 0x00000000b8980894, | ||
214 | 0x00000000b8525305, 0x00000000b80c8109, 0x00000000b7c692ac, | ||
215 | 0x00000000b78087f7, 0x00000000b73a60f6, 0x00000000b6f41db4, | ||
216 | 0x00000000b6adbe3a, 0x00000000b6674296, 0x00000000b620aad0, | ||
217 | 0x00000000b5d9f6f4, | ||
218 | 0x00000000b593270e, 0x00000000b54c3b27, 0x00000000b505334a, | ||
219 | 0x00000000b4be0f84, 0x00000000b476cfde, 0x00000000b42f7464, | ||
220 | 0x00000000b3e7fd20, 0x00000000b3a06a1e, 0x00000000b358bb69, | ||
221 | 0x00000000b310f10c, | ||
222 | 0x00000000b2c90b11, 0x00000000b2810985, 0x00000000b238ec71, | ||
223 | 0x00000000b1f0b3e2, 0x00000000b1a85fe2, 0x00000000b15ff07c, | ||
224 | 0x00000000b11765bc, 0x00000000b0cebfad, 0x00000000b085fe5a, | ||
225 | 0x00000000b03d21ce, | ||
226 | 0x00000000aff42a15, 0x00000000afab1739, 0x00000000af61e946, | ||
227 | 0x00000000af18a048, 0x00000000aecf3c49, 0x00000000ae85bd55, | ||
228 | 0x00000000ae3c2377, 0x00000000adf26ebb, 0x00000000ada89f2c, | ||
229 | 0x00000000ad5eb4d5, | ||
230 | 0x00000000ad14afc2, 0x00000000acca8ffd, 0x00000000ac805594, | ||
231 | 0x00000000ac360090, 0x00000000abeb90fe, 0x00000000aba106e9, | ||
232 | 0x00000000ab56625d, 0x00000000ab0ba364, 0x00000000aac0ca0b, | ||
233 | 0x00000000aa75d65d, | ||
234 | 0x00000000aa2ac865, 0x00000000a9dfa030, 0x00000000a9945dc9, | ||
235 | 0x00000000a949013a, 0x00000000a8fd8a91, 0x00000000a8b1f9d8, | ||
236 | 0x00000000a8664f1c, 0x00000000a81a8a68, 0x00000000a7ceabc7, | ||
237 | 0x00000000a782b345, | ||
238 | 0x00000000a736a0ef, 0x00000000a6ea74cf, 0x00000000a69e2ef2, | ||
239 | 0x00000000a651cf63, 0x00000000a605562f, 0x00000000a5b8c360, | ||
240 | 0x00000000a56c1702, 0x00000000a51f5123, 0x00000000a4d271cc, | ||
241 | 0x00000000a485790b, | ||
242 | 0x00000000a43866eb, 0x00000000a3eb3b77, 0x00000000a39df6bd, | ||
243 | 0x00000000a35098c7, 0x00000000a30321a2, 0x00000000a2b5915a, | ||
244 | 0x00000000a267e7fa, 0x00000000a21a258e, 0x00000000a1cc4a24, | ||
245 | 0x00000000a17e55c5, | ||
246 | 0x00000000a1304880, 0x00000000a0e2225f, 0x00000000a093e36f, | ||
247 | 0x00000000a0458bbb, 0x000000009ff71b50, 0x000000009fa8923a, | ||
248 | 0x000000009f59f086, 0x000000009f0b363e, 0x000000009ebc6370, | ||
249 | 0x000000009e6d7827, | ||
250 | 0x000000009e1e746f, 0x000000009dcf5856, 0x000000009d8023e6, | ||
251 | 0x000000009d30d72d, 0x000000009ce17236, 0x000000009c91f50e, | ||
252 | 0x000000009c425fc1, 0x000000009bf2b25b, 0x000000009ba2ece8, | ||
253 | 0x000000009b530f76, | ||
254 | 0x000000009b031a0f, 0x000000009ab30cc1, 0x000000009a62e797, | ||
255 | 0x000000009a12aa9f, 0x0000000099c255e5, 0x000000009971e974, | ||
256 | 0x000000009921655a, 0x0000000098d0c9a2, 0x0000000098801659, | ||
257 | 0x00000000982f4b8d, | ||
258 | 0x0000000097de6948, 0x00000000978d6f97, 0x00000000973c5e88, | ||
259 | 0x0000000096eb3626, 0x000000009699f67f, 0x0000000096489f9e, | ||
260 | 0x0000000095f73190, 0x0000000095a5ac61, 0x000000009554101f, | ||
261 | 0x0000000095025cd6, | ||
262 | 0x0000000094b09292, 0x00000000945eb161, 0x00000000940cb94e, | ||
263 | 0x0000000093baaa66, 0x00000000936884b6, 0x000000009316484b, | ||
264 | 0x0000000092c3f531, 0x0000000092718b75, 0x00000000921f0b24, | ||
265 | 0x0000000091cc744b, | ||
266 | 0x000000009179c6f5, 0x0000000091270331, 0x0000000090d4290a, | ||
267 | 0x000000009081388e, 0x00000000902e31c8, 0x000000008fdb14c7, | ||
268 | 0x000000008f87e197, 0x000000008f349845, 0x000000008ee138dd, | ||
269 | 0x000000008e8dc36c, | ||
270 | 0x000000008e3a3800, 0x000000008de696a5, 0x000000008d92df68, | ||
271 | 0x000000008d3f1256, 0x000000008ceb2f7c, 0x000000008c9736e7, | ||
272 | 0x000000008c4328a3, 0x000000008bef04bf, 0x000000008b9acb46, | ||
273 | 0x000000008b467c45, | ||
274 | 0x000000008af217cb, 0x000000008a9d9de3, 0x000000008a490e9b, | ||
275 | 0x0000000089f469ff, 0x00000000899fb01e, 0x00000000894ae103, | ||
276 | 0x0000000088f5fcbc, 0x0000000088a10357, 0x00000000884bf4df, | ||
277 | 0x0000000087f6d163, | ||
278 | 0x0000000087a198f0, 0x00000000874c4b92, 0x0000000086f6e956, | ||
279 | 0x0000000086a1724b, 0x00000000864be67c, 0x0000000085f645f8, | ||
280 | 0x0000000085a090cc, 0x00000000854ac704, 0x0000000084f4e8ad, | ||
281 | 0x00000000849ef5d7, | ||
282 | 0x000000008448ee8c, 0x0000000083f2d2db, 0x00000000839ca2d1, | ||
283 | 0x0000000083465e7c, 0x0000000082f005e8, 0x0000000082999922, | ||
284 | 0x0000000082431839, 0x0000000081ec833a, 0x000000008195da31, | ||
285 | 0x00000000813f1d2d, | ||
286 | 0x0000000080e84c3a, 0x0000000080916766, 0x00000000803a6ebf, | ||
287 | 0x000000007fe36251, 0x000000007f8c422b, 0x000000007f350e59, | ||
288 | 0x000000007eddc6ea, 0x000000007e866bea, 0x000000007e2efd67, | ||
289 | 0x000000007dd77b6f, | ||
290 | 0x000000007d7fe60f, 0x000000007d283d54, 0x000000007cd0814c, | ||
291 | 0x000000007c78b205, 0x000000007c20cf8c, 0x000000007bc8d9ef, | ||
292 | 0x000000007b70d13b, 0x000000007b18b57e, 0x000000007ac086c5, | ||
293 | 0x000000007a68451f, | ||
294 | 0x000000007a0ff098, 0x0000000079b7893e, 0x00000000795f0f1f, | ||
295 | 0x0000000079068248, 0x0000000078ade2c8, 0x00000000785530ab, | ||
296 | 0x0000000077fc6c01, 0x0000000077a394d5, 0x00000000774aab36, | ||
297 | 0x0000000076f1af32, | ||
298 | 0x000000007698a0d6, 0x00000000763f8030, 0x0000000075e64d4e, | ||
299 | 0x00000000758d083e, 0x000000007533b10d, 0x0000000074da47c9, | ||
300 | 0x000000007480cc80, 0x0000000074273f3f, 0x0000000073cda016, | ||
301 | 0x000000007373ef10, | ||
302 | 0x00000000731a2c3d, 0x0000000072c057aa, 0x0000000072667164, | ||
303 | 0x00000000720c797a, 0x0000000071b26ffa, 0x00000000715854f2, | ||
304 | 0x0000000070fe286e, 0x0000000070a3ea7e, 0x0000000070499b30, | ||
305 | 0x000000006fef3a90, | ||
306 | 0x000000006f94c8ae, 0x000000006f3a4596, 0x000000006edfb157, | ||
307 | 0x000000006e850c00, 0x000000006e2a559d, 0x000000006dcf8e3d, | ||
308 | 0x000000006d74b5ee, 0x000000006d19ccbe, 0x000000006cbed2bb, | ||
309 | 0x000000006c63c7f3, | ||
310 | 0x000000006c08ac74, 0x000000006bad804c, 0x000000006b524389, | ||
311 | 0x000000006af6f639, 0x000000006a9b986b, 0x000000006a402a2c, | ||
312 | 0x0000000069e4ab8a, 0x0000000069891c94, 0x00000000692d7d57, | ||
313 | 0x0000000068d1cde3, | ||
314 | 0x0000000068760e44, 0x00000000681a3e89, 0x0000000067be5ec1, | ||
315 | 0x0000000067626ef9, 0x0000000067066f40, 0x0000000066aa5fa3, | ||
316 | 0x00000000664e4032, 0x0000000065f210f9, 0x000000006595d209, | ||
317 | 0x000000006539836d, | ||
318 | 0x0000000064dd2536, 0x000000006480b770, 0x0000000064243a2b, | ||
319 | 0x0000000063c7ad75, 0x00000000636b115c, 0x00000000630e65ed, | ||
320 | 0x0000000062b1ab39, 0x000000006254e14c, 0x0000000061f80835, | ||
321 | 0x00000000619b2002, | ||
322 | 0x00000000613e28c2, 0x0000000060e12283, 0x0000000060840d54, | ||
323 | 0x000000006026e943, 0x000000005fc9b65d, 0x000000005f6c74b2, | ||
324 | 0x000000005f0f2450, 0x000000005eb1c545, 0x000000005e5457a0, | ||
325 | 0x000000005df6db6f, | ||
326 | 0x000000005d9950c0, 0x000000005d3bb7a3, 0x000000005cde1024, | ||
327 | 0x000000005c805a54, 0x000000005c22963f, 0x000000005bc4c3f6, | ||
328 | 0x000000005b66e385, 0x000000005b08f4fd, 0x000000005aaaf86a, | ||
329 | 0x000000005a4ceddc, | ||
330 | 0x0000000059eed561, 0x000000005990af08, 0x0000000059327adf, | ||
331 | 0x0000000058d438f4, 0x000000005875e957, 0x0000000058178c16, | ||
332 | 0x0000000057b9213f, 0x00000000575aa8e0, 0x0000000056fc230a, | ||
333 | 0x00000000569d8fc9, | ||
334 | 0x00000000563eef2d, 0x0000000055e04144, 0x000000005581861d, | ||
335 | 0x000000005522bdc6, 0x0000000054c3e84e, 0x00000000546505c4, | ||
336 | 0x0000000054061636, 0x0000000053a719b3, 0x000000005348104a, | ||
337 | 0x0000000052e8fa09, | ||
338 | 0x000000005289d6ff, 0x00000000522aa73a, 0x0000000051cb6aca, | ||
339 | 0x00000000516c21bc, 0x00000000510ccc20, 0x0000000050ad6a05, | ||
340 | 0x00000000504dfb78, 0x000000004fee808a, 0x000000004f8ef947, | ||
341 | 0x000000004f2f65c0, | ||
342 | 0x000000004ecfc603, 0x000000004e701a1f, 0x000000004e106222, | ||
343 | 0x000000004db09e1b, 0x000000004d50ce19, 0x000000004cf0f22b, | ||
344 | 0x000000004c910a5f, 0x000000004c3116c5, 0x000000004bd1176b, | ||
345 | 0x000000004b710c5f, | ||
346 | 0x000000004b10f5b2, 0x000000004ab0d371, 0x000000004a50a5ab, | ||
347 | 0x0000000049f06c70, 0x00000000499027cd, 0x00000000492fd7d3, | ||
348 | 0x0000000048cf7c8f, 0x00000000486f1611, 0x00000000480ea467, | ||
349 | 0x0000000047ae27a1, | ||
350 | 0x00000000474d9fcd, 0x0000000046ed0cfa, 0x00000000468c6f37, | ||
351 | 0x00000000462bc693, 0x0000000045cb131c, 0x00000000456a54e3, | ||
352 | 0x0000000045098bf5, 0x0000000044a8b861, 0x000000004447da37, | ||
353 | 0x0000000043e6f186, | ||
354 | 0x000000004385fe5c, 0x00000000432500c8, 0x0000000042c3f8d9, | ||
355 | 0x000000004262e69f, 0x000000004201ca28, 0x0000000041a0a383, | ||
356 | 0x00000000413f72bf, 0x0000000040de37eb, 0x00000000407cf317, | ||
357 | 0x00000000401ba450, | ||
358 | 0x000000003fba4ba7, 0x000000003f58e92a, 0x000000003ef77ce8, | ||
359 | 0x000000003e9606f1, 0x000000003e348752, 0x000000003dd2fe1c, | ||
360 | 0x000000003d716b5e, 0x000000003d0fcf25, 0x000000003cae2982, | ||
361 | 0x000000003c4c7a83, | ||
362 | 0x000000003beac238, 0x000000003b8900b0, 0x000000003b2735f9, | ||
363 | 0x000000003ac56223, 0x000000003a63853d, 0x000000003a019f56, | ||
364 | 0x00000000399fb07d, 0x00000000393db8c1, 0x0000000038dbb831, | ||
365 | 0x000000003879aedd, | ||
366 | 0x0000000038179cd3, 0x0000000037b58222, 0x0000000037535edb, | ||
367 | 0x0000000036f1330b, 0x00000000368efec2, 0x00000000362cc20f, | ||
368 | 0x0000000035ca7d02, 0x0000000035682fa9, 0x000000003505da14, | ||
369 | 0x0000000034a37c51, | ||
370 | 0x0000000034411671, 0x0000000033dea881, 0x00000000337c3292, | ||
371 | 0x000000003319b4b3, 0x0000000032b72ef2, 0x000000003254a15e, | ||
372 | 0x0000000031f20c08, 0x00000000318f6efe, 0x00000000312cca50, | ||
373 | 0x0000000030ca1e0c, | ||
374 | 0x0000000030676a43, 0x000000003004af02, 0x000000002fa1ec5a, | ||
375 | 0x000000002f3f2259, 0x000000002edc510f, 0x000000002e79788b, | ||
376 | 0x000000002e1698dc, 0x000000002db3b212, 0x000000002d50c43c, | ||
377 | 0x000000002cedcf68, | ||
378 | 0x000000002c8ad3a7, 0x000000002c27d108, 0x000000002bc4c799, | ||
379 | 0x000000002b61b76b, 0x000000002afea08c, 0x000000002a9b830b, | ||
380 | 0x000000002a385ef9, 0x0000000029d53464, 0x000000002972035b, | ||
381 | 0x00000000290ecbee, | ||
382 | 0x0000000028ab8e2c, 0x0000000028484a25, 0x0000000027e4ffe7, | ||
383 | 0x000000002781af83, 0x00000000271e5906, 0x0000000026bafc82, | ||
384 | 0x0000000026579a04, 0x0000000025f4319d, 0x000000002590c35c, | ||
385 | 0x00000000252d4f4f, | ||
386 | 0x0000000024c9d587, 0x0000000024665613, 0x000000002402d101, | ||
387 | 0x00000000239f4662, 0x00000000233bb644, 0x0000000022d820b8, | ||
388 | 0x00000000227485cc, 0x000000002210e590, 0x0000000021ad4013, | ||
389 | 0x0000000021499565, | ||
390 | 0x0000000020e5e594, 0x00000000208230b1, 0x00000000201e76ca, | ||
391 | 0x000000001fbab7ef, 0x000000001f56f430, 0x000000001ef32b9b, | ||
392 | 0x000000001e8f5e41, 0x000000001e2b8c30, 0x000000001dc7b578, | ||
393 | 0x000000001d63da29, | ||
394 | 0x000000001cfffa51, 0x000000001c9c1600, 0x000000001c382d46, | ||
395 | 0x000000001bd44032, 0x000000001b704ed3, 0x000000001b0c5939, | ||
396 | 0x000000001aa85f74, 0x000000001a446191, 0x0000000019e05fa2, | ||
397 | 0x00000000197c59b5, | ||
398 | 0x0000000019184fdb, 0x0000000018b44221, 0x0000000018503098, | ||
399 | 0x0000000017ec1b50, 0x0000000017880257, 0x000000001723e5bd, | ||
400 | 0x0000000016bfc591, 0x00000000165ba1e4, 0x0000000015f77ac3, | ||
401 | 0x0000000015935040, | ||
402 | 0x00000000152f2269, 0x0000000014caf14d, 0x000000001466bcfd, | ||
403 | 0x0000000014028587, 0x00000000139e4afb, 0x00000000133a0d69, | ||
404 | 0x0000000012d5cce0, 0x000000001271896f, 0x00000000120d4326, | ||
405 | 0x0000000011a8fa15, | ||
406 | 0x000000001144ae4a, 0x0000000010e05fd6, 0x00000000107c0ec7, | ||
407 | 0x000000001017bb2d, 0x000000000fb36519, 0x000000000f4f0c98, | ||
408 | 0x000000000eeab1bb, 0x000000000e865491, 0x000000000e21f52a, | ||
409 | 0x000000000dbd9395, | ||
410 | 0x000000000d592fe1, 0x000000000cf4ca1f, 0x000000000c90625c, | ||
411 | 0x000000000c2bf8aa, 0x000000000bc78d18, 0x000000000b631fb4, | ||
412 | 0x000000000afeb08f, 0x000000000a9a3fb8, 0x000000000a35cd3e, | ||
413 | 0x0000000009d15931, | ||
414 | 0x00000000096ce3a1, 0x0000000009086c9c, 0x0000000008a3f433, | ||
415 | 0x00000000083f7a75, 0x0000000007daff71, 0x0000000007768337, | ||
416 | 0x00000000071205d6, 0x0000000006ad875f, 0x00000000064907df, | ||
417 | 0x0000000005e48768, | ||
418 | 0x0000000005800608, 0x00000000051b83cf, 0x0000000004b700cc, | ||
419 | 0x0000000004527d0f, 0x0000000003edf8a7, 0x00000000038973a4, | ||
420 | 0x000000000324ee16, 0x0000000002c0680b, 0x00000000025be194, | ||
421 | 0x0000000001f75ac0, | ||
422 | 0x000000000192d39e, 0x00000000012e4c3e, 0x0000000000c9c4af, | ||
423 | 0x0000000000653d02, 0x0000000000000000 | ||
424 | }; | ||
425 | |||
426 | EAPI Eina_F32p32 | ||
427 | eina_f32p32_cos(Eina_F32p32 a) | ||
428 | { | ||
429 | Eina_F32p32 F32P32_2PI; | ||
430 | Eina_F32p32 F32P32_PI2; | ||
431 | Eina_F32p32 F32P32_3PI2; | ||
432 | Eina_F32p32 remainder_2PI; | ||
433 | Eina_F32p32 remainder_PI; | ||
434 | Eina_F32p32 interpol; | ||
435 | Eina_F32p32 result; | ||
436 | int idx; | ||
437 | int index2; | ||
438 | |||
439 | F32P32_2PI = EINA_F32P32_PI << 1; | ||
440 | F32P32_PI2 = EINA_F32P32_PI >> 1; | ||
441 | F32P32_3PI2 = EINA_F32P32_PI + F32P32_PI2; | ||
442 | |||
443 | /* Take advantage of cosinus symetrie. */ | ||
444 | a = eina_fp32p32_llabs(a); | ||
445 | |||
446 | /* Find table entry in 0 to PI / 2 */ | ||
447 | remainder_PI = a - (a / EINA_F32P32_PI) * EINA_F32P32_PI; | ||
448 | |||
449 | /* Find which case from 0 to 2 * PI */ | ||
450 | remainder_2PI = a - (a / F32P32_2PI) * F32P32_2PI; | ||
451 | |||
452 | interpol = eina_f32p32_div(eina_f32p32_scale(remainder_PI, MAX_PREC * 2), | ||
453 | EINA_F32P32_PI); | ||
454 | idx = eina_f32p32_int_to(interpol); | ||
455 | if (idx >= MAX_PREC) | ||
456 | idx = 2 * MAX_PREC - (idx + 1); | ||
457 | |||
458 | index2 = idx + 1; | ||
459 | if (index2 == MAX_PREC) | ||
460 | index2 = idx - 1; | ||
461 | |||
462 | result = eina_f32p32_add(eina_trigo[idx], | ||
463 | eina_f32p32_mul(eina_f32p32_sub(eina_trigo[idx], | ||
464 | eina_trigo[index2]), | ||
465 | (Eina_F32p32)eina_f32p32_fracc_get( | ||
466 | interpol))); | ||
467 | |||
468 | if (0 <= remainder_2PI && remainder_2PI < F32P32_PI2) | ||
469 | return result; | ||
470 | else if (F32P32_PI2 <= remainder_2PI && remainder_2PI < EINA_F32P32_PI) | ||
471 | return -result; | ||
472 | else if (EINA_F32P32_PI <= remainder_2PI && remainder_2PI < F32P32_3PI2) | ||
473 | return -result; | ||
474 | else /* if (F32P32_3PI2 <= remainder_2PI) */ | ||
475 | return result; | ||
476 | } | ||
477 | |||
478 | EAPI Eina_F32p32 | ||
479 | eina_f32p32_sin(Eina_F32p32 a) | ||
480 | { | ||
481 | Eina_F32p32 F32P32_2PI; | ||
482 | Eina_F32p32 F32P32_PI2; | ||
483 | Eina_F32p32 F32P32_3PI2; | ||
484 | Eina_F32p32 remainder_2PI; | ||
485 | Eina_F32p32 remainder_PI; | ||
486 | Eina_F32p32 interpol; | ||
487 | Eina_F32p32 result; | ||
488 | int idx; | ||
489 | int index2; | ||
490 | |||
491 | F32P32_2PI = EINA_F32P32_PI << 1; | ||
492 | F32P32_PI2 = EINA_F32P32_PI >> 1; | ||
493 | F32P32_3PI2 = EINA_F32P32_PI + F32P32_PI2; | ||
494 | |||
495 | /* We only have a table for cosinus, but sin(a) = cos(pi / 2 - a) */ | ||
496 | a = eina_f32p32_sub(F32P32_PI2, a); | ||
497 | |||
498 | /* Take advantage of cosinus symetrie. */ | ||
499 | a = eina_fp32p32_llabs(a); | ||
500 | |||
501 | /* Find table entry in 0 to PI / 2 */ | ||
502 | remainder_PI = a - (a / EINA_F32P32_PI) * EINA_F32P32_PI; | ||
503 | |||
504 | /* Find which case from 0 to 2 * PI */ | ||
505 | remainder_2PI = a - (a / F32P32_2PI) * F32P32_2PI; | ||
506 | |||
507 | interpol = eina_f32p32_div(eina_f32p32_scale(remainder_PI, MAX_PREC * 2), | ||
508 | EINA_F32P32_PI); | ||
509 | idx = eina_f32p32_int_to(interpol); | ||
510 | if (idx >= MAX_PREC) | ||
511 | idx = 2 * MAX_PREC - (idx + 1); | ||
512 | |||
513 | index2 = idx + 1; | ||
514 | if (index2 == MAX_PREC) | ||
515 | index2 = idx - 1; | ||
516 | |||
517 | result = eina_f32p32_add(eina_trigo[idx], | ||
518 | eina_f32p32_mul(eina_f32p32_sub(eina_trigo[idx], | ||
519 | eina_trigo[index2]), | ||
520 | (Eina_F32p32)eina_f32p32_fracc_get( | ||
521 | interpol))); | ||
522 | |||
523 | if (0 <= remainder_2PI && remainder_2PI < F32P32_PI2) | ||
524 | return result; | ||
525 | else if (F32P32_PI2 <= remainder_2PI && remainder_2PI < EINA_F32P32_PI) | ||
526 | return -result; | ||
527 | else if (EINA_F32P32_PI <= remainder_2PI && remainder_2PI < F32P32_3PI2) | ||
528 | return -result; | ||
529 | else /* if (F32P32_3PI2 <= remainder_2PI) */ | ||
530 | return result; | ||
531 | } | ||
532 | |||
diff --git a/libraries/eina/src/lib/eina_hamster.c b/libraries/eina/src/lib/eina_hamster.c deleted file mode 100644 index cebc10b..0000000 --- a/libraries/eina/src/lib/eina_hamster.c +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <string.h> | ||
25 | |||
26 | #include "eina_config.h" | ||
27 | #include "eina_types.h" | ||
28 | #include "eina_hamster.h" | ||
29 | |||
30 | /*============================================================================* | ||
31 | * Local * | ||
32 | *============================================================================*/ | ||
33 | |||
34 | /** | ||
35 | * @cond LOCAL | ||
36 | */ | ||
37 | |||
38 | const char *_eina_hamster_time = __TIME__; | ||
39 | const char *_eina_hamster_date = __DATE__; | ||
40 | static int _eina_hamsters = -1; | ||
41 | |||
42 | /** | ||
43 | * @endcond | ||
44 | */ | ||
45 | |||
46 | /*============================================================================* | ||
47 | * Global * | ||
48 | *============================================================================*/ | ||
49 | |||
50 | /*============================================================================* | ||
51 | * API * | ||
52 | *============================================================================*/ | ||
53 | |||
54 | EAPI int | ||
55 | eina_hamster_count(void) | ||
56 | { | ||
57 | if (_eina_hamsters < 0) | ||
58 | { | ||
59 | int hrs = 0, min = 0, sec = 0; | ||
60 | char mon[8] = ""; | ||
61 | int monnum = 0, day = 0, year = 0; | ||
62 | int fields; | ||
63 | |||
64 | fields = sscanf(_eina_hamster_time, "%02d:%02d:%02d", &hrs, &min, &sec); | ||
65 | if (fields == 3) | ||
66 | { | ||
67 | _eina_hamsters = (hrs * 60) + min; | ||
68 | fields = sscanf(_eina_hamster_date, "%s %d %d", mon, &day, &year); | ||
69 | if (fields == 3) | ||
70 | { | ||
71 | int i; | ||
72 | const char *mons[] = | ||
73 | { | ||
74 | "Jan", | ||
75 | "Feb", | ||
76 | "Mar", | ||
77 | "Apr", | ||
78 | "May", | ||
79 | "Jun", | ||
80 | "Jul", | ||
81 | "Aug", | ||
82 | "Sep", | ||
83 | "Oct", | ||
84 | "Nov", | ||
85 | "Dec" | ||
86 | }; | ||
87 | |||
88 | for (i = 0; i < 12; i++) | ||
89 | { | ||
90 | if (!strcmp(mon, mons[i])) | ||
91 | { | ||
92 | monnum = i + 1; | ||
93 | break; | ||
94 | } | ||
95 | } | ||
96 | // alloc 60 for mins, 24 for hrs | ||
97 | // alloc 1-31 (32) for days, 1-12 (13) for months | ||
98 | // use year as-is, for 31 bits (signed) this gives us up to | ||
99 | // 3584 years, which is good enough imho. - 1500 years from | ||
100 | // now or so. :) | ||
101 | _eina_hamsters += | ||
102 | (day + (monnum * 32) + (13 * 32 * year)) * (24 * 60); | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | |||
107 | // format: [rest - year][0-12 - month][0-31 - day][0-23 - hrs][0-59 - sec] | ||
108 | return _eina_hamsters; | ||
109 | } | ||
110 | |||
111 | /** | ||
112 | * @} | ||
113 | */ | ||
diff --git a/libraries/eina/src/lib/eina_hash.c b/libraries/eina/src/lib/eina_hash.c deleted file mode 100644 index 5196894..0000000 --- a/libraries/eina/src/lib/eina_hash.c +++ /dev/null | |||
@@ -1,1377 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2002-2008 Carsten Haitzler, Gustavo Sverzut Barbieri, | ||
3 | * Vincent Torri, Jorge Luis Zapata Muga, Cedric Bail | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Lesser General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2.1 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This library is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * Lesser General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Lesser General Public | ||
16 | * License along with this library; | ||
17 | * if not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #ifdef HAVE_CONFIG_H | ||
21 | # include "config.h" | ||
22 | #endif | ||
23 | |||
24 | #include <stdio.h> | ||
25 | #include <stdlib.h> | ||
26 | #include <string.h> | ||
27 | |||
28 | #ifdef HAVE_STDINT_H | ||
29 | # include <stdint.h> | ||
30 | #endif | ||
31 | |||
32 | #ifdef _MSC_VER | ||
33 | # include <Evil.h> | ||
34 | #endif | ||
35 | |||
36 | #include "eina_config.h" | ||
37 | #include "eina_private.h" | ||
38 | #include "eina_rbtree.h" | ||
39 | #include "eina_error.h" | ||
40 | |||
41 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
42 | #include "eina_safety_checks.h" | ||
43 | #include "eina_hash.h" | ||
44 | |||
45 | /*============================================================================* | ||
46 | * Local * | ||
47 | *============================================================================*/ | ||
48 | |||
49 | /** | ||
50 | * @cond LOCAL | ||
51 | */ | ||
52 | |||
53 | #define EINA_MAGIC_CHECK_HASH(d) \ | ||
54 | do { \ | ||
55 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_HASH)) { \ | ||
56 | EINA_MAGIC_FAIL(d, EINA_MAGIC_HASH); } \ | ||
57 | } while(0) | ||
58 | |||
59 | #define EINA_MAGIC_CHECK_HASH_ITERATOR(d, ...) \ | ||
60 | do { \ | ||
61 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_HASH_ITERATOR)) \ | ||
62 | { \ | ||
63 | EINA_MAGIC_FAIL(d, EINA_MAGIC_HASH_ITERATOR); \ | ||
64 | return __VA_ARGS__; \ | ||
65 | } \ | ||
66 | } while(0) | ||
67 | |||
68 | #define EINA_HASH_BUCKET_SIZE 8 | ||
69 | #define EINA_HASH_SMALL_BUCKET_SIZE 5 | ||
70 | |||
71 | #define EINA_HASH_RBTREE_MASK 0xFFF | ||
72 | |||
73 | typedef struct _Eina_Hash_Head Eina_Hash_Head; | ||
74 | typedef struct _Eina_Hash_Element Eina_Hash_Element; | ||
75 | typedef struct _Eina_Hash_Foreach_Data Eina_Hash_Foreach_Data; | ||
76 | typedef struct _Eina_Iterator_Hash Eina_Iterator_Hash; | ||
77 | typedef struct _Eina_Hash_Each Eina_Hash_Each; | ||
78 | |||
79 | struct _Eina_Hash | ||
80 | { | ||
81 | Eina_Key_Length key_length_cb; | ||
82 | Eina_Key_Cmp key_cmp_cb; | ||
83 | Eina_Key_Hash key_hash_cb; | ||
84 | Eina_Free_Cb data_free_cb; | ||
85 | |||
86 | Eina_Rbtree **buckets; | ||
87 | int size; | ||
88 | int mask; | ||
89 | |||
90 | int population; | ||
91 | |||
92 | EINA_MAGIC | ||
93 | }; | ||
94 | |||
95 | struct _Eina_Hash_Head | ||
96 | { | ||
97 | EINA_RBTREE; | ||
98 | int hash; | ||
99 | |||
100 | Eina_Rbtree *head; | ||
101 | }; | ||
102 | |||
103 | struct _Eina_Hash_Element | ||
104 | { | ||
105 | EINA_RBTREE; | ||
106 | Eina_Hash_Tuple tuple; | ||
107 | Eina_Bool begin : 1; | ||
108 | }; | ||
109 | |||
110 | struct _Eina_Hash_Foreach_Data | ||
111 | { | ||
112 | Eina_Hash_Foreach cb; | ||
113 | const void *fdata; | ||
114 | }; | ||
115 | |||
116 | typedef void *(*Eina_Iterator_Get_Content_Callback)(Eina_Iterator_Hash *it); | ||
117 | #define FUNC_ITERATOR_GET_CONTENT(Function) \ | ||
118 | ((Eina_Iterator_Get_Content_Callback)Function) | ||
119 | |||
120 | struct _Eina_Iterator_Hash | ||
121 | { | ||
122 | Eina_Iterator iterator; | ||
123 | |||
124 | Eina_Iterator_Get_Content_Callback get_content; | ||
125 | const Eina_Hash *hash; | ||
126 | |||
127 | Eina_Iterator *current; | ||
128 | Eina_Iterator *list; | ||
129 | Eina_Hash_Head *hash_head; | ||
130 | Eina_Hash_Element *hash_element; | ||
131 | int bucket; | ||
132 | |||
133 | int index; | ||
134 | |||
135 | EINA_MAGIC | ||
136 | }; | ||
137 | |||
138 | struct _Eina_Hash_Each | ||
139 | { | ||
140 | Eina_Hash_Head *hash_head; | ||
141 | const Eina_Hash_Element *hash_element; | ||
142 | const void *data; | ||
143 | }; | ||
144 | |||
145 | #undef get16bits | ||
146 | #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ | ||
147 | || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) | ||
148 | # define get16bits(d) (*((const uint16_t *)(d))) | ||
149 | #endif | ||
150 | |||
151 | #if !defined (get16bits) | ||
152 | # define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ | ||
153 | + (uint32_t)(((const uint8_t *)(d))[0])) | ||
154 | #endif | ||
155 | |||
156 | static inline int | ||
157 | _eina_hash_hash_rbtree_cmp_hash(const Eina_Hash_Head *hash_head, | ||
158 | const int *hash, | ||
159 | __UNUSED__ int key_length, | ||
160 | __UNUSED__ void *data) | ||
161 | { | ||
162 | return hash_head->hash - *hash; | ||
163 | } | ||
164 | |||
165 | static Eina_Rbtree_Direction | ||
166 | _eina_hash_hash_rbtree_cmp_node(const Eina_Hash_Head *left, | ||
167 | const Eina_Hash_Head *right, | ||
168 | __UNUSED__ void *data) | ||
169 | { | ||
170 | if (left->hash - right->hash < 0) | ||
171 | return EINA_RBTREE_LEFT; | ||
172 | |||
173 | return EINA_RBTREE_RIGHT; | ||
174 | } | ||
175 | |||
176 | static inline int | ||
177 | _eina_hash_key_rbtree_cmp_key_data(const Eina_Hash_Element *hash_element, | ||
178 | const Eina_Hash_Tuple *tuple, | ||
179 | __UNUSED__ unsigned int key_length, | ||
180 | Eina_Key_Cmp cmp) | ||
181 | { | ||
182 | int result; | ||
183 | |||
184 | result = cmp(hash_element->tuple.key, | ||
185 | hash_element->tuple.key_length, | ||
186 | tuple->key, | ||
187 | tuple->key_length); | ||
188 | |||
189 | if (result == 0 && tuple->data && tuple->data != hash_element->tuple.data) | ||
190 | return 1; | ||
191 | |||
192 | return result; | ||
193 | } | ||
194 | |||
195 | static Eina_Rbtree_Direction | ||
196 | _eina_hash_key_rbtree_cmp_node(const Eina_Hash_Element *left, | ||
197 | const Eina_Hash_Element *right, | ||
198 | Eina_Key_Cmp cmp) | ||
199 | { | ||
200 | int result; | ||
201 | |||
202 | result = cmp(left->tuple.key, left->tuple.key_length, | ||
203 | right->tuple.key, right->tuple.key_length); | ||
204 | |||
205 | if (result < 0) | ||
206 | return EINA_RBTREE_LEFT; | ||
207 | |||
208 | return EINA_RBTREE_RIGHT; | ||
209 | } | ||
210 | |||
211 | static inline Eina_Bool | ||
212 | eina_hash_add_alloc_by_hash(Eina_Hash *hash, | ||
213 | const void *key, int key_length, int alloc_length, | ||
214 | int key_hash, | ||
215 | const void *data) | ||
216 | { | ||
217 | Eina_Hash_Element *new_hash_element = NULL; | ||
218 | Eina_Hash_Head *hash_head; | ||
219 | Eina_Error error = 0; | ||
220 | int hash_num; | ||
221 | |||
222 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); | ||
223 | EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); | ||
224 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); | ||
225 | EINA_MAGIC_CHECK_HASH(hash); | ||
226 | |||
227 | error = EINA_ERROR_OUT_OF_MEMORY; | ||
228 | |||
229 | /* Apply eina mask to hash. */ | ||
230 | hash_num = key_hash & hash->mask; | ||
231 | key_hash &= EINA_HASH_RBTREE_MASK; | ||
232 | |||
233 | if (!hash->buckets) | ||
234 | { | ||
235 | hash->buckets = calloc(sizeof (Eina_Rbtree *), hash->size); | ||
236 | if (!hash->buckets) goto on_error; | ||
237 | |||
238 | hash_head = NULL; | ||
239 | } | ||
240 | else | ||
241 | /* Look up for head node. */ | ||
242 | hash_head = (Eina_Hash_Head *) | ||
243 | eina_rbtree_inline_lookup(hash->buckets[hash_num], | ||
244 | &key_hash, 0, | ||
245 | EINA_RBTREE_CMP_KEY_CB( | ||
246 | _eina_hash_hash_rbtree_cmp_hash), | ||
247 | NULL); | ||
248 | |||
249 | if (!hash_head) | ||
250 | { | ||
251 | /* If not found allocate it and an element. */ | ||
252 | hash_head = malloc(sizeof(Eina_Hash_Head) + sizeof(Eina_Hash_Element) | ||
253 | + alloc_length); | ||
254 | if (!hash_head) | ||
255 | goto on_error; | ||
256 | |||
257 | hash_head->hash = key_hash; | ||
258 | hash_head->head = NULL; | ||
259 | |||
260 | hash->buckets[hash_num] = | ||
261 | eina_rbtree_inline_insert(hash->buckets[hash_num], | ||
262 | EINA_RBTREE_GET(hash_head), | ||
263 | EINA_RBTREE_CMP_NODE_CB( | ||
264 | _eina_hash_hash_rbtree_cmp_node), | ||
265 | NULL); | ||
266 | |||
267 | new_hash_element = (Eina_Hash_Element *)(hash_head + 1); | ||
268 | new_hash_element->begin = EINA_TRUE; | ||
269 | } | ||
270 | |||
271 | if (!new_hash_element) | ||
272 | { | ||
273 | /* | ||
274 | Alloc a new element | ||
275 | (No more lookup as we expect to support more than one item for one key). | ||
276 | */ | ||
277 | new_hash_element = malloc(sizeof (Eina_Hash_Element) + alloc_length); | ||
278 | if (!new_hash_element) | ||
279 | goto on_error; | ||
280 | |||
281 | new_hash_element->begin = EINA_FALSE; | ||
282 | } | ||
283 | |||
284 | /* Setup the element */ | ||
285 | new_hash_element->tuple.key_length = key_length; | ||
286 | new_hash_element->tuple.data = (void *)data; | ||
287 | if (alloc_length > 0) | ||
288 | { | ||
289 | new_hash_element->tuple.key = (char *)(new_hash_element + 1); | ||
290 | memcpy((char *)new_hash_element->tuple.key, key, alloc_length); | ||
291 | } | ||
292 | else | ||
293 | new_hash_element->tuple.key = key; | ||
294 | |||
295 | /* add the new element to the hash. */ | ||
296 | hash_head->head = eina_rbtree_inline_insert(hash_head->head, | ||
297 | EINA_RBTREE_GET(new_hash_element), | ||
298 | EINA_RBTREE_CMP_NODE_CB( | ||
299 | _eina_hash_key_rbtree_cmp_node), | ||
300 | (const void *)hash->key_cmp_cb); | ||
301 | hash->population++; | ||
302 | return EINA_TRUE; | ||
303 | |||
304 | on_error: | ||
305 | eina_error_set(error); | ||
306 | return EINA_FALSE; | ||
307 | } | ||
308 | |||
309 | static Eina_Bool | ||
310 | _eina_hash_rbtree_each(__UNUSED__ const Eina_Rbtree *container, | ||
311 | const Eina_Hash_Head *hash_head, | ||
312 | Eina_Hash_Each *data) | ||
313 | { | ||
314 | Eina_Iterator *it; | ||
315 | Eina_Hash_Element *hash_element; | ||
316 | Eina_Bool found = EINA_TRUE; | ||
317 | |||
318 | it = eina_rbtree_iterator_prefix(hash_head->head); | ||
319 | EINA_ITERATOR_FOREACH(it, hash_element) | ||
320 | { | ||
321 | if (hash_element->tuple.data == data->data) | ||
322 | { | ||
323 | data->hash_element = hash_element; | ||
324 | data->hash_head = (Eina_Hash_Head *)hash_head; | ||
325 | found = EINA_FALSE; | ||
326 | break; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | eina_iterator_free(it); | ||
331 | return found; | ||
332 | } | ||
333 | |||
334 | static inline Eina_Hash_Element * | ||
335 | _eina_hash_find_by_hash(const Eina_Hash *hash, | ||
336 | Eina_Hash_Tuple *tuple, | ||
337 | int key_hash, | ||
338 | Eina_Hash_Head **hash_head) | ||
339 | { | ||
340 | Eina_Hash_Element *hash_element; | ||
341 | int rb_hash = key_hash & EINA_HASH_RBTREE_MASK; | ||
342 | |||
343 | key_hash &= hash->mask; | ||
344 | |||
345 | if (!hash->buckets) | ||
346 | return NULL; | ||
347 | |||
348 | *hash_head = (Eina_Hash_Head *) | ||
349 | eina_rbtree_inline_lookup(hash->buckets[key_hash], | ||
350 | &rb_hash, 0, | ||
351 | EINA_RBTREE_CMP_KEY_CB( | ||
352 | _eina_hash_hash_rbtree_cmp_hash), | ||
353 | NULL); | ||
354 | if (!*hash_head) | ||
355 | return NULL; | ||
356 | |||
357 | hash_element = (Eina_Hash_Element *) | ||
358 | eina_rbtree_inline_lookup((*hash_head)->head, | ||
359 | tuple, 0, | ||
360 | EINA_RBTREE_CMP_KEY_CB( | ||
361 | _eina_hash_key_rbtree_cmp_key_data), | ||
362 | (const void *)hash->key_cmp_cb); | ||
363 | |||
364 | return hash_element; | ||
365 | } | ||
366 | |||
367 | static inline Eina_Hash_Element * | ||
368 | _eina_hash_find_by_data(const Eina_Hash *hash, | ||
369 | const void *data, | ||
370 | int *key_hash, | ||
371 | Eina_Hash_Head **hash_head) | ||
372 | { | ||
373 | Eina_Hash_Each each; | ||
374 | Eina_Iterator *it; | ||
375 | int hash_num; | ||
376 | |||
377 | if (!hash->buckets) | ||
378 | return NULL; | ||
379 | |||
380 | each.hash_element = NULL; | ||
381 | each.data = data; | ||
382 | |||
383 | for (hash_num = 0; hash_num < hash->size; hash_num++) | ||
384 | { | ||
385 | if (!hash->buckets[hash_num]) | ||
386 | continue; | ||
387 | |||
388 | it = eina_rbtree_iterator_prefix(hash->buckets[hash_num]); | ||
389 | eina_iterator_foreach(it, EINA_EACH_CB(_eina_hash_rbtree_each), &each); | ||
390 | eina_iterator_free(it); | ||
391 | |||
392 | if (each.hash_element) | ||
393 | { | ||
394 | *key_hash = hash_num; | ||
395 | *hash_head = each.hash_head; | ||
396 | return (Eina_Hash_Element *)each.hash_element; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | return NULL; | ||
401 | } | ||
402 | |||
403 | static void | ||
404 | _eina_hash_el_free(Eina_Hash_Element *hash_element, Eina_Hash *hash) | ||
405 | { | ||
406 | if (hash->data_free_cb) | ||
407 | hash->data_free_cb(hash_element->tuple.data); | ||
408 | |||
409 | if (hash_element->begin == EINA_FALSE) | ||
410 | free(hash_element); | ||
411 | } | ||
412 | |||
413 | static void | ||
414 | _eina_hash_head_free(Eina_Hash_Head *hash_head, Eina_Hash *hash) | ||
415 | { | ||
416 | eina_rbtree_delete(hash_head->head, EINA_RBTREE_FREE_CB(_eina_hash_el_free), hash); | ||
417 | free(hash_head); | ||
418 | } | ||
419 | |||
420 | static Eina_Bool | ||
421 | _eina_hash_del_by_hash_el(Eina_Hash *hash, | ||
422 | Eina_Hash_Element *hash_element, | ||
423 | Eina_Hash_Head *hash_head, | ||
424 | int key_hash) | ||
425 | { | ||
426 | hash_head->head = eina_rbtree_inline_remove(hash_head->head, EINA_RBTREE_GET( | ||
427 | hash_element), EINA_RBTREE_CMP_NODE_CB( | ||
428 | _eina_hash_key_rbtree_cmp_node), | ||
429 | (const void *)hash->key_cmp_cb); | ||
430 | _eina_hash_el_free(hash_element, hash); | ||
431 | |||
432 | if (!hash_head->head) | ||
433 | { | ||
434 | key_hash &= hash->mask; | ||
435 | |||
436 | hash->buckets[key_hash] = | ||
437 | eina_rbtree_inline_remove(hash->buckets[key_hash], EINA_RBTREE_GET( | ||
438 | hash_head), | ||
439 | EINA_RBTREE_CMP_NODE_CB( | ||
440 | _eina_hash_hash_rbtree_cmp_node), NULL); | ||
441 | free(hash_head); | ||
442 | } | ||
443 | |||
444 | hash->population--; | ||
445 | if (hash->population == 0) | ||
446 | { | ||
447 | free(hash->buckets); | ||
448 | hash->buckets = NULL; | ||
449 | } | ||
450 | |||
451 | return EINA_TRUE; | ||
452 | } | ||
453 | |||
454 | static Eina_Bool | ||
455 | _eina_hash_del_by_key_hash(Eina_Hash *hash, | ||
456 | const void *key, | ||
457 | int key_length, | ||
458 | int key_hash, | ||
459 | const void *data) | ||
460 | { | ||
461 | Eina_Hash_Element *hash_element; | ||
462 | Eina_Hash_Head *hash_head; | ||
463 | Eina_Hash_Tuple tuple; | ||
464 | |||
465 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); | ||
466 | EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); | ||
467 | EINA_MAGIC_CHECK_HASH(hash); | ||
468 | |||
469 | if (!hash->buckets) | ||
470 | return EINA_FALSE; | ||
471 | |||
472 | tuple.key = (void *)key; | ||
473 | tuple.key_length = key_length; | ||
474 | tuple.data = (void *)data; | ||
475 | |||
476 | hash_element = _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head); | ||
477 | if (!hash_element) | ||
478 | return EINA_FALSE; | ||
479 | |||
480 | return _eina_hash_del_by_hash_el(hash, hash_element, hash_head, key_hash); | ||
481 | } | ||
482 | |||
483 | static Eina_Bool | ||
484 | _eina_hash_del_by_key(Eina_Hash *hash, const void *key, const void *data) | ||
485 | { | ||
486 | int key_length, key_hash; | ||
487 | |||
488 | EINA_MAGIC_CHECK_HASH(hash); | ||
489 | if (!hash) | ||
490 | return EINA_FALSE; | ||
491 | |||
492 | if (!key) | ||
493 | return EINA_FALSE; | ||
494 | |||
495 | if (!hash->buckets) | ||
496 | return EINA_FALSE; | ||
497 | |||
498 | key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0; | ||
499 | key_hash = hash->key_hash_cb(key, key_length); | ||
500 | return _eina_hash_del_by_key_hash(hash, key, key_length, key_hash, data); | ||
501 | } | ||
502 | |||
503 | static unsigned int | ||
504 | _eina_string_key_length(const char *key) | ||
505 | { | ||
506 | if (!key) | ||
507 | return 0; | ||
508 | |||
509 | return (int)strlen(key) + 1; | ||
510 | } | ||
511 | |||
512 | static int | ||
513 | _eina_string_key_cmp(const char *key1, __UNUSED__ int key1_length, | ||
514 | const char *key2, __UNUSED__ int key2_length) | ||
515 | { | ||
516 | return strcmp(key1, key2); | ||
517 | } | ||
518 | |||
519 | static int | ||
520 | _eina_stringshared_key_cmp(const char *key1, __UNUSED__ int key1_length, | ||
521 | const char *key2, __UNUSED__ int key2_length) | ||
522 | { | ||
523 | return key1 - key2; | ||
524 | } | ||
525 | |||
526 | static unsigned int | ||
527 | _eina_int32_key_length(__UNUSED__ const uint32_t *key) | ||
528 | { | ||
529 | return 4; | ||
530 | } | ||
531 | |||
532 | static int | ||
533 | _eina_int32_key_cmp(const uint32_t *key1, __UNUSED__ int key1_length, | ||
534 | const uint32_t *key2, __UNUSED__ int key2_length) | ||
535 | { | ||
536 | return *key1 - *key2; | ||
537 | } | ||
538 | |||
539 | static unsigned int | ||
540 | _eina_int64_key_length(__UNUSED__ const uint32_t *key) | ||
541 | { | ||
542 | return 8; | ||
543 | } | ||
544 | |||
545 | static int | ||
546 | _eina_int64_key_cmp(const uint64_t *key1, __UNUSED__ int key1_length, | ||
547 | const uint64_t *key2, __UNUSED__ int key2_length) | ||
548 | { | ||
549 | return *key1 - *key2; | ||
550 | } | ||
551 | |||
552 | static Eina_Bool | ||
553 | _eina_foreach_cb(const Eina_Hash *hash, | ||
554 | Eina_Hash_Tuple *data, | ||
555 | Eina_Hash_Foreach_Data *fdata) | ||
556 | { | ||
557 | return fdata->cb((Eina_Hash *)hash, | ||
558 | data->key, | ||
559 | data->data, | ||
560 | (void *)fdata->fdata); | ||
561 | } | ||
562 | |||
563 | static void * | ||
564 | _eina_hash_iterator_data_get_content(Eina_Iterator_Hash *it) | ||
565 | { | ||
566 | Eina_Hash_Element *stuff; | ||
567 | |||
568 | EINA_MAGIC_CHECK_HASH_ITERATOR(it, NULL); | ||
569 | |||
570 | stuff = it->hash_element; | ||
571 | |||
572 | if (!stuff) | ||
573 | return NULL; | ||
574 | |||
575 | return stuff->tuple.data; | ||
576 | } | ||
577 | |||
578 | static void * | ||
579 | _eina_hash_iterator_key_get_content(Eina_Iterator_Hash *it) | ||
580 | { | ||
581 | Eina_Hash_Element *stuff; | ||
582 | |||
583 | EINA_MAGIC_CHECK_HASH_ITERATOR(it, NULL); | ||
584 | |||
585 | stuff = it->hash_element; | ||
586 | |||
587 | if (!stuff) | ||
588 | return NULL; | ||
589 | |||
590 | return (void *)stuff->tuple.key; | ||
591 | } | ||
592 | |||
593 | static Eina_Hash_Tuple * | ||
594 | _eina_hash_iterator_tuple_get_content(Eina_Iterator_Hash *it) | ||
595 | { | ||
596 | Eina_Hash_Element *stuff; | ||
597 | |||
598 | EINA_MAGIC_CHECK_HASH_ITERATOR(it, NULL); | ||
599 | |||
600 | stuff = it->hash_element; | ||
601 | |||
602 | if (!stuff) | ||
603 | return NULL; | ||
604 | |||
605 | return &stuff->tuple; | ||
606 | } | ||
607 | |||
608 | static Eina_Bool | ||
609 | _eina_hash_iterator_next(Eina_Iterator_Hash *it, void **data) | ||
610 | { | ||
611 | Eina_Bool ok; | ||
612 | int bucket; | ||
613 | |||
614 | if (!(it->index < it->hash->population)) | ||
615 | return EINA_FALSE; | ||
616 | |||
617 | if (!it->current) | ||
618 | { | ||
619 | ok = EINA_FALSE; | ||
620 | bucket = 0; | ||
621 | it->index = -1; | ||
622 | } | ||
623 | else | ||
624 | { | ||
625 | ok = eina_iterator_next(it->list, (void **)(void*)&it->hash_element); | ||
626 | if (!ok) | ||
627 | { | ||
628 | eina_iterator_free(it->list); | ||
629 | it->list = NULL; | ||
630 | |||
631 | ok = eina_iterator_next(it->current, (void **)(void*)&it->hash_head); | ||
632 | if (!ok) | ||
633 | { | ||
634 | eina_iterator_free(it->current); | ||
635 | it->current = NULL; | ||
636 | it->bucket++; | ||
637 | } | ||
638 | else | ||
639 | { | ||
640 | it->list = eina_rbtree_iterator_prefix(it->hash_head->head); | ||
641 | ok = eina_iterator_next(it->list, (void **)(void*)&it->hash_element); | ||
642 | } | ||
643 | } | ||
644 | |||
645 | bucket = it->bucket; | ||
646 | } | ||
647 | |||
648 | if (ok == EINA_FALSE) | ||
649 | { | ||
650 | while (bucket < it->hash->size) | ||
651 | { | ||
652 | if (it->hash->buckets[bucket]) | ||
653 | { | ||
654 | it->current = | ||
655 | eina_rbtree_iterator_prefix(it->hash->buckets[bucket]); | ||
656 | ok = eina_iterator_next(it->current, (void **)(void*)&it->hash_head); | ||
657 | if (ok) | ||
658 | break; | ||
659 | |||
660 | eina_iterator_free(it->current); | ||
661 | it->current = NULL; | ||
662 | } | ||
663 | |||
664 | ++bucket; | ||
665 | } | ||
666 | if (it->list) | ||
667 | eina_iterator_free(it->list); | ||
668 | |||
669 | it->list = eina_rbtree_iterator_prefix(it->hash_head->head); | ||
670 | ok = eina_iterator_next(it->list, (void **)(void*)&it->hash_element); | ||
671 | if (bucket == it->hash->size) | ||
672 | ok = EINA_FALSE; | ||
673 | } | ||
674 | |||
675 | it->index++; | ||
676 | it->bucket = bucket; | ||
677 | |||
678 | if (ok) | ||
679 | *data = it->get_content(it); | ||
680 | |||
681 | return ok; | ||
682 | } | ||
683 | |||
684 | static void * | ||
685 | _eina_hash_iterator_get_container(Eina_Iterator_Hash *it) | ||
686 | { | ||
687 | EINA_MAGIC_CHECK_HASH_ITERATOR(it, NULL); | ||
688 | return (void *)it->hash; | ||
689 | } | ||
690 | |||
691 | static void | ||
692 | _eina_hash_iterator_free(Eina_Iterator_Hash *it) | ||
693 | { | ||
694 | EINA_MAGIC_CHECK_HASH_ITERATOR(it); | ||
695 | if (it->current) | ||
696 | eina_iterator_free(it->current); | ||
697 | |||
698 | if (it->list) | ||
699 | eina_iterator_free(it->list); | ||
700 | |||
701 | free(it); | ||
702 | } | ||
703 | |||
704 | /** | ||
705 | * @endcond | ||
706 | */ | ||
707 | |||
708 | /*============================================================================* | ||
709 | * Global * | ||
710 | *============================================================================*/ | ||
711 | |||
712 | /*============================================================================* | ||
713 | * API * | ||
714 | *============================================================================*/ | ||
715 | |||
716 | EAPI void | ||
717 | eina_hash_free_cb_set(Eina_Hash *hash, Eina_Free_Cb data_free_cb) | ||
718 | { | ||
719 | EINA_MAGIC_CHECK_HASH(hash); | ||
720 | EINA_SAFETY_ON_NULL_RETURN(hash); | ||
721 | |||
722 | hash->data_free_cb = data_free_cb; | ||
723 | } | ||
724 | |||
725 | EAPI Eina_Hash * | ||
726 | eina_hash_new(Eina_Key_Length key_length_cb, | ||
727 | Eina_Key_Cmp key_cmp_cb, | ||
728 | Eina_Key_Hash key_hash_cb, | ||
729 | Eina_Free_Cb data_free_cb, | ||
730 | int buckets_power_size) | ||
731 | { | ||
732 | /* FIXME: Use mempool. */ | ||
733 | Eina_Hash *new; | ||
734 | |||
735 | eina_error_set(0); | ||
736 | EINA_SAFETY_ON_NULL_RETURN_VAL(key_cmp_cb, NULL); | ||
737 | EINA_SAFETY_ON_NULL_RETURN_VAL(key_hash_cb, NULL); | ||
738 | EINA_SAFETY_ON_TRUE_RETURN_VAL(buckets_power_size <= 2, NULL); | ||
739 | EINA_SAFETY_ON_TRUE_RETURN_VAL(buckets_power_size >= 17, NULL); | ||
740 | |||
741 | new = malloc(sizeof (Eina_Hash)); | ||
742 | if (!new) | ||
743 | goto on_error; | ||
744 | |||
745 | EINA_MAGIC_SET(new, EINA_MAGIC_HASH); | ||
746 | |||
747 | new->key_length_cb = key_length_cb; | ||
748 | new->key_cmp_cb = key_cmp_cb; | ||
749 | new->key_hash_cb = key_hash_cb; | ||
750 | new->data_free_cb = data_free_cb; | ||
751 | new->buckets = NULL; | ||
752 | new->population = 0; | ||
753 | |||
754 | new->size = 1 << buckets_power_size; | ||
755 | new->mask = new->size - 1; | ||
756 | |||
757 | return new; | ||
758 | |||
759 | on_error: | ||
760 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
761 | return NULL; | ||
762 | } | ||
763 | |||
764 | EAPI Eina_Hash * | ||
765 | eina_hash_string_djb2_new(Eina_Free_Cb data_free_cb) | ||
766 | { | ||
767 | return eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length), | ||
768 | EINA_KEY_CMP(_eina_string_key_cmp), | ||
769 | EINA_KEY_HASH(eina_hash_djb2), | ||
770 | data_free_cb, | ||
771 | EINA_HASH_BUCKET_SIZE); | ||
772 | } | ||
773 | |||
774 | EAPI Eina_Hash * | ||
775 | eina_hash_string_superfast_new(Eina_Free_Cb data_free_cb) | ||
776 | { | ||
777 | return eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length), | ||
778 | EINA_KEY_CMP(_eina_string_key_cmp), | ||
779 | EINA_KEY_HASH(eina_hash_superfast), | ||
780 | data_free_cb, | ||
781 | EINA_HASH_BUCKET_SIZE); | ||
782 | } | ||
783 | |||
784 | EAPI Eina_Hash * | ||
785 | eina_hash_string_small_new(Eina_Free_Cb data_free_cb) | ||
786 | { | ||
787 | return eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length), | ||
788 | EINA_KEY_CMP(_eina_string_key_cmp), | ||
789 | EINA_KEY_HASH(eina_hash_superfast), | ||
790 | data_free_cb, | ||
791 | EINA_HASH_SMALL_BUCKET_SIZE); | ||
792 | } | ||
793 | |||
794 | EAPI Eina_Hash * | ||
795 | eina_hash_int32_new(Eina_Free_Cb data_free_cb) | ||
796 | { | ||
797 | return eina_hash_new(EINA_KEY_LENGTH(_eina_int32_key_length), | ||
798 | EINA_KEY_CMP(_eina_int32_key_cmp), | ||
799 | EINA_KEY_HASH(eina_hash_int32), | ||
800 | data_free_cb, | ||
801 | EINA_HASH_BUCKET_SIZE); | ||
802 | } | ||
803 | |||
804 | EAPI Eina_Hash * | ||
805 | eina_hash_int64_new(Eina_Free_Cb data_free_cb) | ||
806 | { | ||
807 | return eina_hash_new(EINA_KEY_LENGTH(_eina_int64_key_length), | ||
808 | EINA_KEY_CMP(_eina_int64_key_cmp), | ||
809 | EINA_KEY_HASH(eina_hash_int64), | ||
810 | data_free_cb, | ||
811 | EINA_HASH_BUCKET_SIZE); | ||
812 | } | ||
813 | |||
814 | EAPI Eina_Hash * | ||
815 | eina_hash_pointer_new(Eina_Free_Cb data_free_cb) | ||
816 | { | ||
817 | #ifdef __LP64__ | ||
818 | return eina_hash_new(EINA_KEY_LENGTH(_eina_int64_key_length), | ||
819 | EINA_KEY_CMP(_eina_int64_key_cmp), | ||
820 | EINA_KEY_HASH(eina_hash_int64), | ||
821 | data_free_cb, | ||
822 | EINA_HASH_BUCKET_SIZE); | ||
823 | #else | ||
824 | return eina_hash_new(EINA_KEY_LENGTH(_eina_int32_key_length), | ||
825 | EINA_KEY_CMP(_eina_int32_key_cmp), | ||
826 | EINA_KEY_HASH(eina_hash_int32), | ||
827 | data_free_cb, | ||
828 | EINA_HASH_BUCKET_SIZE); | ||
829 | #endif | ||
830 | } | ||
831 | |||
832 | EAPI Eina_Hash * | ||
833 | eina_hash_stringshared_new(Eina_Free_Cb data_free_cb) | ||
834 | { | ||
835 | return eina_hash_new(NULL, | ||
836 | EINA_KEY_CMP(_eina_stringshared_key_cmp), | ||
837 | EINA_KEY_HASH(eina_hash_superfast), | ||
838 | data_free_cb, | ||
839 | EINA_HASH_BUCKET_SIZE); | ||
840 | } | ||
841 | |||
842 | EAPI int | ||
843 | eina_hash_population(const Eina_Hash *hash) | ||
844 | { | ||
845 | if (!hash) | ||
846 | return 0; | ||
847 | |||
848 | EINA_MAGIC_CHECK_HASH(hash); | ||
849 | return hash->population; | ||
850 | } | ||
851 | |||
852 | EAPI void | ||
853 | eina_hash_free(Eina_Hash *hash) | ||
854 | { | ||
855 | int i; | ||
856 | |||
857 | if (!hash) return ; | ||
858 | |||
859 | EINA_MAGIC_CHECK_HASH(hash); | ||
860 | |||
861 | if (hash->buckets) | ||
862 | { | ||
863 | for (i = 0; i < hash->size; i++) | ||
864 | eina_rbtree_delete(hash->buckets[i], EINA_RBTREE_FREE_CB(_eina_hash_head_free), hash); | ||
865 | free(hash->buckets); | ||
866 | } | ||
867 | free(hash); | ||
868 | } | ||
869 | |||
870 | EAPI void | ||
871 | eina_hash_free_buckets(Eina_Hash *hash) | ||
872 | { | ||
873 | int i; | ||
874 | |||
875 | if (!hash) return ; | ||
876 | |||
877 | EINA_MAGIC_CHECK_HASH(hash); | ||
878 | |||
879 | if (hash->buckets) | ||
880 | { | ||
881 | for (i = 0; i < hash->size; i++) | ||
882 | eina_rbtree_delete(hash->buckets[i], | ||
883 | EINA_RBTREE_FREE_CB(_eina_hash_head_free), hash); | ||
884 | free(hash->buckets); | ||
885 | hash->buckets = NULL; | ||
886 | hash->population = 0; | ||
887 | } | ||
888 | } | ||
889 | |||
890 | EAPI Eina_Bool | ||
891 | eina_hash_add_by_hash(Eina_Hash *hash, | ||
892 | const void *key, | ||
893 | int key_length, | ||
894 | int key_hash, | ||
895 | const void *data) | ||
896 | { | ||
897 | return eina_hash_add_alloc_by_hash(hash, | ||
898 | key, | ||
899 | key_length, | ||
900 | key_length, | ||
901 | key_hash, | ||
902 | data); | ||
903 | } | ||
904 | |||
905 | EAPI Eina_Bool | ||
906 | eina_hash_direct_add_by_hash(Eina_Hash *hash, | ||
907 | const void *key, | ||
908 | int key_length, | ||
909 | int key_hash, | ||
910 | const void *data) | ||
911 | { | ||
912 | return eina_hash_add_alloc_by_hash(hash, key, key_length, 0, key_hash, data); | ||
913 | } | ||
914 | |||
915 | EAPI Eina_Bool | ||
916 | eina_hash_add(Eina_Hash *hash, const void *key, const void *data) | ||
917 | { | ||
918 | unsigned int key_length; | ||
919 | int key_hash; | ||
920 | |||
921 | EINA_MAGIC_CHECK_HASH(hash); | ||
922 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); | ||
923 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, EINA_FALSE); | ||
924 | EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); | ||
925 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); | ||
926 | |||
927 | key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0; | ||
928 | key_hash = hash->key_hash_cb(key, key_length); | ||
929 | |||
930 | return eina_hash_add_alloc_by_hash(hash, key, key_length, key_length, key_hash, data); | ||
931 | } | ||
932 | |||
933 | EAPI Eina_Bool | ||
934 | eina_hash_direct_add(Eina_Hash *hash, const void *key, const void *data) | ||
935 | { | ||
936 | int key_length; | ||
937 | int key_hash; | ||
938 | |||
939 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); | ||
940 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, EINA_FALSE); | ||
941 | EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); | ||
942 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); | ||
943 | EINA_MAGIC_CHECK_HASH(hash); | ||
944 | |||
945 | key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0; | ||
946 | key_hash = hash->key_hash_cb(key, key_length); | ||
947 | |||
948 | return eina_hash_add_alloc_by_hash(hash, key, key_length, 0, key_hash, data); | ||
949 | } | ||
950 | |||
951 | EAPI Eina_Bool | ||
952 | eina_hash_del_by_key_hash(Eina_Hash *hash, | ||
953 | const void *key, | ||
954 | int key_length, | ||
955 | int key_hash) | ||
956 | { | ||
957 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); | ||
958 | EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); | ||
959 | |||
960 | return _eina_hash_del_by_key_hash(hash, key, key_length, key_hash, NULL); | ||
961 | } | ||
962 | |||
963 | EAPI Eina_Bool | ||
964 | eina_hash_del_by_key(Eina_Hash *hash, const void *key) | ||
965 | { | ||
966 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); | ||
967 | EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); | ||
968 | |||
969 | return _eina_hash_del_by_key(hash, key, NULL); | ||
970 | } | ||
971 | |||
972 | EAPI Eina_Bool | ||
973 | eina_hash_del_by_data(Eina_Hash *hash, const void *data) | ||
974 | { | ||
975 | Eina_Hash_Element *hash_element; | ||
976 | Eina_Hash_Head *hash_head; | ||
977 | int key_hash; | ||
978 | |||
979 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); | ||
980 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); | ||
981 | EINA_MAGIC_CHECK_HASH(hash); | ||
982 | |||
983 | hash_element = _eina_hash_find_by_data(hash, data, &key_hash, &hash_head); | ||
984 | if (!hash_element) | ||
985 | goto error; | ||
986 | |||
987 | if (hash_element->tuple.data != data) | ||
988 | goto error; | ||
989 | |||
990 | return _eina_hash_del_by_hash_el(hash, hash_element, hash_head, key_hash); | ||
991 | |||
992 | error: | ||
993 | return EINA_FALSE; | ||
994 | } | ||
995 | |||
996 | EAPI Eina_Bool | ||
997 | eina_hash_del_by_hash(Eina_Hash *hash, | ||
998 | const void *key, | ||
999 | int key_length, | ||
1000 | int key_hash, | ||
1001 | const void *data) | ||
1002 | { | ||
1003 | Eina_Bool ret; | ||
1004 | |||
1005 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); | ||
1006 | EINA_MAGIC_CHECK_HASH(hash); | ||
1007 | |||
1008 | if (key) | ||
1009 | ret = _eina_hash_del_by_key_hash(hash, key, key_length, key_hash, data); | ||
1010 | else | ||
1011 | ret = eina_hash_del_by_data(hash, data); | ||
1012 | |||
1013 | return ret; | ||
1014 | } | ||
1015 | |||
1016 | EAPI Eina_Bool | ||
1017 | eina_hash_del(Eina_Hash *hash, const void *key, const void *data) | ||
1018 | { | ||
1019 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); | ||
1020 | EINA_MAGIC_CHECK_HASH(hash); | ||
1021 | |||
1022 | if (!key) | ||
1023 | return eina_hash_del_by_data(hash, data); | ||
1024 | |||
1025 | return _eina_hash_del_by_key(hash, key, data); | ||
1026 | } | ||
1027 | |||
1028 | EAPI void * | ||
1029 | eina_hash_find_by_hash(const Eina_Hash *hash, | ||
1030 | const void *key, | ||
1031 | int key_length, | ||
1032 | int key_hash) | ||
1033 | { | ||
1034 | Eina_Hash_Head *hash_head; | ||
1035 | Eina_Hash_Element *hash_element; | ||
1036 | Eina_Hash_Tuple tuple; | ||
1037 | |||
1038 | if (!hash) | ||
1039 | return NULL; | ||
1040 | |||
1041 | EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL); | ||
1042 | EINA_MAGIC_CHECK_HASH(hash); | ||
1043 | |||
1044 | tuple.key = key; | ||
1045 | tuple.key_length = key_length; | ||
1046 | tuple.data = NULL; | ||
1047 | |||
1048 | hash_element = _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head); | ||
1049 | if (hash_element) | ||
1050 | return hash_element->tuple.data; | ||
1051 | |||
1052 | return NULL; | ||
1053 | } | ||
1054 | |||
1055 | EAPI void * | ||
1056 | eina_hash_find(const Eina_Hash *hash, const void *key) | ||
1057 | { | ||
1058 | int key_length; | ||
1059 | int hash_num; | ||
1060 | |||
1061 | if (!hash) | ||
1062 | return NULL; | ||
1063 | |||
1064 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, NULL); | ||
1065 | EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL); | ||
1066 | EINA_MAGIC_CHECK_HASH(hash); | ||
1067 | |||
1068 | key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0; | ||
1069 | hash_num = hash->key_hash_cb(key, key_length); | ||
1070 | |||
1071 | return eina_hash_find_by_hash(hash, key, key_length, hash_num); | ||
1072 | } | ||
1073 | |||
1074 | EAPI void * | ||
1075 | eina_hash_modify_by_hash(Eina_Hash *hash, | ||
1076 | const void *key, | ||
1077 | int key_length, | ||
1078 | int key_hash, | ||
1079 | const void *data) | ||
1080 | { | ||
1081 | Eina_Hash_Head *hash_head; | ||
1082 | Eina_Hash_Element *hash_element; | ||
1083 | void *old_data = NULL; | ||
1084 | Eina_Hash_Tuple tuple; | ||
1085 | |||
1086 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, NULL); | ||
1087 | EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL); | ||
1088 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL); | ||
1089 | EINA_MAGIC_CHECK_HASH(hash); | ||
1090 | |||
1091 | tuple.key = key; | ||
1092 | tuple.key_length = key_length; | ||
1093 | tuple.data = NULL; | ||
1094 | |||
1095 | hash_element = _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head); | ||
1096 | if (hash_element) | ||
1097 | { | ||
1098 | old_data = hash_element->tuple.data; | ||
1099 | hash_element->tuple.data = (void *)data; | ||
1100 | } | ||
1101 | |||
1102 | return old_data; | ||
1103 | } | ||
1104 | |||
1105 | EAPI void * | ||
1106 | eina_hash_set(Eina_Hash *hash, const void *key, const void *data) | ||
1107 | { | ||
1108 | Eina_Hash_Tuple tuple; | ||
1109 | Eina_Hash_Head *hash_head; | ||
1110 | Eina_Hash_Element *hash_element; | ||
1111 | int key_length; | ||
1112 | int key_hash; | ||
1113 | |||
1114 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, NULL); | ||
1115 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, NULL); | ||
1116 | EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL); | ||
1117 | EINA_MAGIC_CHECK_HASH(hash); | ||
1118 | |||
1119 | key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0; | ||
1120 | key_hash = hash->key_hash_cb(key, key_length); | ||
1121 | |||
1122 | tuple.key = key; | ||
1123 | tuple.key_length = key_length; | ||
1124 | tuple.data = NULL; | ||
1125 | |||
1126 | hash_element = _eina_hash_find_by_hash(hash, &tuple, key_hash, &hash_head); | ||
1127 | if (hash_element) | ||
1128 | { | ||
1129 | void *old_data = NULL; | ||
1130 | |||
1131 | old_data = hash_element->tuple.data; | ||
1132 | |||
1133 | if (data) | ||
1134 | { | ||
1135 | hash_element->tuple.data = (void *)data; | ||
1136 | } | ||
1137 | else | ||
1138 | { | ||
1139 | _eina_hash_del_by_hash_el(hash, hash_element, hash_head, key_hash); | ||
1140 | } | ||
1141 | |||
1142 | return old_data; | ||
1143 | } | ||
1144 | |||
1145 | if (!data) return NULL; | ||
1146 | |||
1147 | eina_hash_add_alloc_by_hash(hash, | ||
1148 | key, | ||
1149 | key_length, | ||
1150 | key_length, | ||
1151 | key_hash, | ||
1152 | data); | ||
1153 | return NULL; | ||
1154 | } | ||
1155 | EAPI void * | ||
1156 | eina_hash_modify(Eina_Hash *hash, const void *key, const void *data) | ||
1157 | { | ||
1158 | int key_length; | ||
1159 | int hash_num; | ||
1160 | |||
1161 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, NULL); | ||
1162 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, NULL); | ||
1163 | EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL); | ||
1164 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL); | ||
1165 | EINA_MAGIC_CHECK_HASH(hash); | ||
1166 | |||
1167 | key_length = hash->key_length_cb ? hash->key_length_cb(key) : 0; | ||
1168 | hash_num = hash->key_hash_cb(key, key_length); | ||
1169 | |||
1170 | return eina_hash_modify_by_hash(hash, key, key_length, hash_num, data); | ||
1171 | } | ||
1172 | |||
1173 | EAPI Eina_Bool | ||
1174 | eina_hash_move(Eina_Hash *hash, const void *old_key, const void *new_key) | ||
1175 | { | ||
1176 | Eina_Free_Cb hash_free_cb; | ||
1177 | const void *data; | ||
1178 | Eina_Bool result = EINA_FALSE; | ||
1179 | |||
1180 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, EINA_FALSE); | ||
1181 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash->key_hash_cb, EINA_FALSE); | ||
1182 | EINA_SAFETY_ON_NULL_RETURN_VAL(old_key, EINA_FALSE); | ||
1183 | EINA_SAFETY_ON_NULL_RETURN_VAL(new_key, EINA_FALSE); | ||
1184 | EINA_MAGIC_CHECK_HASH(hash); | ||
1185 | |||
1186 | data = eina_hash_find(hash, old_key); | ||
1187 | if (!data) goto error; | ||
1188 | |||
1189 | hash_free_cb = hash->data_free_cb; | ||
1190 | hash->data_free_cb = NULL; | ||
1191 | |||
1192 | eina_hash_del(hash, old_key, data); | ||
1193 | result = eina_hash_add(hash, new_key, data); | ||
1194 | |||
1195 | hash->data_free_cb = hash_free_cb; | ||
1196 | |||
1197 | error: | ||
1198 | return result; | ||
1199 | } | ||
1200 | |||
1201 | /*============================================================================* | ||
1202 | * Iterator * | ||
1203 | *============================================================================*/ | ||
1204 | |||
1205 | EAPI void | ||
1206 | eina_hash_foreach(const Eina_Hash *hash, | ||
1207 | Eina_Hash_Foreach func, | ||
1208 | const void *fdata) | ||
1209 | { | ||
1210 | Eina_Iterator *it; | ||
1211 | Eina_Hash_Foreach_Data foreach; | ||
1212 | |||
1213 | EINA_MAGIC_CHECK_HASH(hash); | ||
1214 | EINA_SAFETY_ON_NULL_RETURN(hash); | ||
1215 | EINA_SAFETY_ON_NULL_RETURN(func); | ||
1216 | |||
1217 | foreach.cb = func; | ||
1218 | foreach.fdata = fdata; | ||
1219 | |||
1220 | it = eina_hash_iterator_tuple_new(hash); | ||
1221 | if (!it) | ||
1222 | return; | ||
1223 | eina_iterator_foreach(it, EINA_EACH_CB(_eina_foreach_cb), &foreach); | ||
1224 | |||
1225 | eina_iterator_free(it); | ||
1226 | } | ||
1227 | |||
1228 | EAPI Eina_Iterator * | ||
1229 | eina_hash_iterator_data_new(const Eina_Hash *hash) | ||
1230 | { | ||
1231 | Eina_Iterator_Hash *it; | ||
1232 | |||
1233 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, NULL); | ||
1234 | EINA_MAGIC_CHECK_HASH(hash); | ||
1235 | |||
1236 | eina_error_set(0); | ||
1237 | it = calloc(1, sizeof (Eina_Iterator_Hash)); | ||
1238 | if (!it) | ||
1239 | { | ||
1240 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
1241 | return NULL; | ||
1242 | } | ||
1243 | |||
1244 | it->hash = hash; | ||
1245 | it->get_content = FUNC_ITERATOR_GET_CONTENT(_eina_hash_iterator_data_get_content); | ||
1246 | |||
1247 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
1248 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next); | ||
1249 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
1250 | _eina_hash_iterator_get_container); | ||
1251 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_hash_iterator_free); | ||
1252 | |||
1253 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
1254 | EINA_MAGIC_SET(it, EINA_MAGIC_HASH_ITERATOR); | ||
1255 | |||
1256 | return &it->iterator; | ||
1257 | } | ||
1258 | |||
1259 | EAPI Eina_Iterator * | ||
1260 | eina_hash_iterator_key_new(const Eina_Hash *hash) | ||
1261 | { | ||
1262 | Eina_Iterator_Hash *it; | ||
1263 | |||
1264 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, NULL); | ||
1265 | EINA_MAGIC_CHECK_HASH(hash); | ||
1266 | |||
1267 | eina_error_set(0); | ||
1268 | it = calloc(1, sizeof (Eina_Iterator_Hash)); | ||
1269 | if (!it) | ||
1270 | { | ||
1271 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
1272 | return NULL; | ||
1273 | } | ||
1274 | |||
1275 | it->hash = hash; | ||
1276 | it->get_content = FUNC_ITERATOR_GET_CONTENT( | ||
1277 | _eina_hash_iterator_key_get_content); | ||
1278 | |||
1279 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
1280 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next); | ||
1281 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
1282 | _eina_hash_iterator_get_container); | ||
1283 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_hash_iterator_free); | ||
1284 | |||
1285 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
1286 | EINA_MAGIC_SET(it, EINA_MAGIC_HASH_ITERATOR); | ||
1287 | |||
1288 | return &it->iterator; | ||
1289 | } | ||
1290 | |||
1291 | EAPI Eina_Iterator * | ||
1292 | eina_hash_iterator_tuple_new(const Eina_Hash *hash) | ||
1293 | { | ||
1294 | Eina_Iterator_Hash *it; | ||
1295 | |||
1296 | EINA_SAFETY_ON_NULL_RETURN_VAL(hash, NULL); | ||
1297 | EINA_MAGIC_CHECK_HASH(hash); | ||
1298 | |||
1299 | eina_error_set(0); | ||
1300 | it = calloc(1, sizeof (Eina_Iterator_Hash)); | ||
1301 | if (!it) | ||
1302 | { | ||
1303 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
1304 | return NULL; | ||
1305 | } | ||
1306 | |||
1307 | it->hash = hash; | ||
1308 | it->get_content = FUNC_ITERATOR_GET_CONTENT( | ||
1309 | _eina_hash_iterator_tuple_get_content); | ||
1310 | |||
1311 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
1312 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_hash_iterator_next); | ||
1313 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
1314 | _eina_hash_iterator_get_container); | ||
1315 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_hash_iterator_free); | ||
1316 | |||
1317 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
1318 | EINA_MAGIC_SET(it, EINA_MAGIC_HASH_ITERATOR); | ||
1319 | |||
1320 | return &it->iterator; | ||
1321 | } | ||
1322 | |||
1323 | /* Common hash functions */ | ||
1324 | |||
1325 | /* Paul Hsieh (http://www.azillionmonkeys.com/qed/hash.html) | ||
1326 | used by WebCore (http://webkit.org/blog/8/hashtables-part-2/) */ | ||
1327 | EAPI int | ||
1328 | eina_hash_superfast(const char *key, int len) | ||
1329 | { | ||
1330 | int hash = len, tmp; | ||
1331 | int rem; | ||
1332 | |||
1333 | rem = len & 3; | ||
1334 | len >>= 2; | ||
1335 | |||
1336 | /* Main loop */ | ||
1337 | for (; len > 0; len--) | ||
1338 | { | ||
1339 | hash += get16bits(key); | ||
1340 | tmp = (get16bits(key + 2) << 11) ^ hash; | ||
1341 | hash = (hash << 16) ^ tmp; | ||
1342 | key += 2 * sizeof (uint16_t); | ||
1343 | hash += hash >> 11; | ||
1344 | } | ||
1345 | |||
1346 | /* Handle end cases */ | ||
1347 | switch (rem) | ||
1348 | { | ||
1349 | case 3: | ||
1350 | hash += get16bits(key); | ||
1351 | hash ^= hash << 16; | ||
1352 | hash ^= key[sizeof (uint16_t)] << 18; | ||
1353 | hash += hash >> 11; | ||
1354 | break; | ||
1355 | |||
1356 | case 2: | ||
1357 | hash += get16bits(key); | ||
1358 | hash ^= hash << 11; | ||
1359 | hash += hash >> 17; | ||
1360 | break; | ||
1361 | |||
1362 | case 1: | ||
1363 | hash += *key; | ||
1364 | hash ^= hash << 10; | ||
1365 | hash += hash >> 1; | ||
1366 | } | ||
1367 | |||
1368 | /* Force "avalanching" of final 127 bits */ | ||
1369 | hash ^= hash << 3; | ||
1370 | hash += hash >> 5; | ||
1371 | hash ^= hash << 4; | ||
1372 | hash += hash >> 17; | ||
1373 | hash ^= hash << 25; | ||
1374 | hash += hash >> 6; | ||
1375 | |||
1376 | return hash; | ||
1377 | } | ||
diff --git a/libraries/eina/src/lib/eina_inarray.c b/libraries/eina/src/lib/eina_inarray.c deleted file mode 100644 index dc95bc6..0000000 --- a/libraries/eina/src/lib/eina_inarray.c +++ /dev/null | |||
@@ -1,777 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2012 - ProFUSION embedded systems | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdlib.h> | ||
24 | #include <string.h> | ||
25 | |||
26 | #include "eina_config.h" | ||
27 | #include "eina_private.h" | ||
28 | #include "eina_error.h" | ||
29 | #include "eina_log.h" | ||
30 | |||
31 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
32 | #include "eina_safety_checks.h" | ||
33 | #include "eina_inarray.h" | ||
34 | |||
35 | /*============================================================================* | ||
36 | * Local * | ||
37 | *============================================================================*/ | ||
38 | |||
39 | /** | ||
40 | * @cond LOCAL | ||
41 | */ | ||
42 | |||
43 | static const char EINA_MAGIC_INARRAY_STR[] = "Eina Inline Array"; | ||
44 | static const char EINA_MAGIC_INARRAY_ITERATOR_STR[] = "Eina Inline Array Iterator"; | ||
45 | static const char EINA_MAGIC_INARRAY_ACCESSOR_STR[] = "Eina Inline Array Accessor"; | ||
46 | |||
47 | typedef struct _Eina_Iterator_Inarray Eina_Iterator_Inarray; | ||
48 | typedef struct _Eina_Accessor_Inarray Eina_Accessor_Inarray; | ||
49 | |||
50 | struct _Eina_Iterator_Inarray | ||
51 | { | ||
52 | Eina_Iterator iterator; | ||
53 | const Eina_Inarray *array; | ||
54 | unsigned int pos; | ||
55 | EINA_MAGIC | ||
56 | }; | ||
57 | |||
58 | struct _Eina_Accessor_Inarray | ||
59 | { | ||
60 | Eina_Accessor accessor; | ||
61 | const Eina_Inarray *array; | ||
62 | EINA_MAGIC | ||
63 | }; | ||
64 | |||
65 | static int _eina_inarray_log_dom = -1; | ||
66 | |||
67 | #ifdef ERR | ||
68 | #undef ERR | ||
69 | #endif | ||
70 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_inarray_log_dom, __VA_ARGS__) | ||
71 | |||
72 | #ifdef DBG | ||
73 | #undef DBG | ||
74 | #endif | ||
75 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_inarray_log_dom, __VA_ARGS__) | ||
76 | |||
77 | #define EINA_MAGIC_CHECK_INARRAY(d, ...) \ | ||
78 | do \ | ||
79 | { \ | ||
80 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_INARRAY)) \ | ||
81 | { \ | ||
82 | EINA_MAGIC_FAIL(d, EINA_MAGIC_INARRAY); \ | ||
83 | return __VA_ARGS__; \ | ||
84 | } \ | ||
85 | eina_error_set(0); \ | ||
86 | } \ | ||
87 | while(0) | ||
88 | |||
89 | #define EINA_MAGIC_CHECK_INARRAY_ITERATOR(d, ...) \ | ||
90 | do \ | ||
91 | { \ | ||
92 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_INARRAY_ITERATOR)) \ | ||
93 | { \ | ||
94 | EINA_MAGIC_FAIL(d, EINA_MAGIC_INARRAY_ITERATOR); \ | ||
95 | return __VA_ARGS__; \ | ||
96 | } \ | ||
97 | eina_error_set(0); \ | ||
98 | } \ | ||
99 | while(0) | ||
100 | |||
101 | #define EINA_MAGIC_CHECK_INARRAY_ACCESSOR(d, ...) \ | ||
102 | do \ | ||
103 | { \ | ||
104 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_INARRAY_ACCESSOR)) \ | ||
105 | { \ | ||
106 | EINA_MAGIC_FAIL(d, EINA_MAGIC_INARRAY_ACCESSOR); \ | ||
107 | return __VA_ARGS__; \ | ||
108 | } \ | ||
109 | eina_error_set(0); \ | ||
110 | } \ | ||
111 | while(0) | ||
112 | |||
113 | static void | ||
114 | _eina_inarray_setup(Eina_Inarray *array, unsigned int member_size, unsigned int step) | ||
115 | { | ||
116 | EINA_MAGIC_SET(array, EINA_MAGIC_INARRAY); | ||
117 | array->member_size = member_size; | ||
118 | array->len = 0; | ||
119 | array->max = 0; | ||
120 | array->step = (step > 0) ? step : 32; | ||
121 | array->members = NULL; | ||
122 | } | ||
123 | |||
124 | static Eina_Bool | ||
125 | _eina_inarray_resize(Eina_Inarray *array, unsigned int new_size) | ||
126 | { | ||
127 | unsigned int new_max; | ||
128 | void *tmp; | ||
129 | |||
130 | if (new_size < array->max) | ||
131 | return EINA_TRUE; | ||
132 | |||
133 | if (new_size % array->step == 0) | ||
134 | new_max = new_size; | ||
135 | else | ||
136 | new_max = ((new_size / array->step) + 1) * array->step; | ||
137 | |||
138 | tmp = realloc(array->members, new_max * array->member_size); | ||
139 | if ((!tmp) && (new_max > 0)) | ||
140 | { | ||
141 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
142 | return EINA_FALSE; | ||
143 | } | ||
144 | |||
145 | array->members = tmp; | ||
146 | array->max = new_max; | ||
147 | return EINA_TRUE; | ||
148 | } | ||
149 | |||
150 | static inline void * | ||
151 | _eina_inarray_get(const Eina_Inarray *array, unsigned int position) | ||
152 | { | ||
153 | unsigned int offset = position * array->member_size; | ||
154 | return (unsigned char *)array->members + offset; | ||
155 | } | ||
156 | |||
157 | static int | ||
158 | _eina_inarray_search(const Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) | ||
159 | { | ||
160 | const unsigned char *start, *found; | ||
161 | start = array->members; | ||
162 | found = bsearch(data, start, array->len, array->member_size, compare); | ||
163 | if (!found) | ||
164 | return -1; | ||
165 | return (found - start) / array->member_size; | ||
166 | } | ||
167 | |||
168 | static unsigned int | ||
169 | _eina_inarray_search_sorted_near(const Eina_Inarray *array, const void *data, Eina_Compare_Cb compare, int *cmp) | ||
170 | { | ||
171 | unsigned int start, last, middle; | ||
172 | |||
173 | if (array->len == 0) | ||
174 | { | ||
175 | *cmp = -1; | ||
176 | return 0; | ||
177 | } | ||
178 | else if (array->len == 1) | ||
179 | { | ||
180 | *cmp = compare(data, array->members); | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | start = 0; | ||
185 | last = array->len - 1; /* inclusive */ | ||
186 | do | ||
187 | { | ||
188 | void *p; | ||
189 | middle = start + (last - start) / 2; /* avoid overflow */ | ||
190 | p = _eina_inarray_get(array, middle); | ||
191 | *cmp = compare(data, p); | ||
192 | if (*cmp == 0) | ||
193 | return middle; | ||
194 | else if (*cmp > 0) | ||
195 | start = middle + 1; | ||
196 | else if (middle > 0) | ||
197 | last = middle - 1; | ||
198 | else | ||
199 | break; | ||
200 | } | ||
201 | while (start <= last); | ||
202 | return middle; | ||
203 | } | ||
204 | |||
205 | |||
206 | static Eina_Bool | ||
207 | _eina_inarray_iterator_next(Eina_Iterator_Inarray *it, void **data) | ||
208 | { | ||
209 | EINA_MAGIC_CHECK_INARRAY_ITERATOR(it, EINA_FALSE); | ||
210 | |||
211 | if (it->pos >= it->array->len) | ||
212 | return EINA_FALSE; | ||
213 | |||
214 | *data = _eina_inarray_get(it->array, it->pos); | ||
215 | it->pos++; | ||
216 | |||
217 | return EINA_TRUE; | ||
218 | } | ||
219 | |||
220 | static Eina_Bool | ||
221 | _eina_inarray_iterator_prev(Eina_Iterator_Inarray *it, void **data) | ||
222 | { | ||
223 | EINA_MAGIC_CHECK_INARRAY_ITERATOR(it, EINA_FALSE); | ||
224 | |||
225 | if (it->pos == 0) | ||
226 | return EINA_FALSE; | ||
227 | |||
228 | it->pos--; | ||
229 | *data = _eina_inarray_get(it->array, it->pos); | ||
230 | |||
231 | return EINA_TRUE; | ||
232 | } | ||
233 | |||
234 | static Eina_Inarray * | ||
235 | _eina_inarray_iterator_get_container(Eina_Iterator_Inarray *it) | ||
236 | { | ||
237 | EINA_MAGIC_CHECK_INARRAY_ITERATOR(it, NULL); | ||
238 | return (Eina_Inarray *)it->array; | ||
239 | } | ||
240 | |||
241 | static void | ||
242 | _eina_inarray_iterator_free(Eina_Iterator_Inarray *it) | ||
243 | { | ||
244 | EINA_MAGIC_CHECK_INARRAY_ITERATOR(it); | ||
245 | MAGIC_FREE(it); | ||
246 | } | ||
247 | |||
248 | static Eina_Bool | ||
249 | _eina_inarray_accessor_get_at(Eina_Accessor_Inarray *it, unsigned int pos, void **data) | ||
250 | { | ||
251 | EINA_MAGIC_CHECK_INARRAY_ACCESSOR(it, EINA_FALSE); | ||
252 | |||
253 | if (pos >= it->array->len) | ||
254 | return EINA_FALSE; | ||
255 | |||
256 | *data = _eina_inarray_get(it->array, pos); | ||
257 | return EINA_TRUE; | ||
258 | } | ||
259 | |||
260 | static Eina_Inarray * | ||
261 | _eina_inarray_accessor_get_container(Eina_Accessor_Inarray *it) | ||
262 | { | ||
263 | EINA_MAGIC_CHECK_INARRAY_ACCESSOR(it, NULL); | ||
264 | return (Eina_Inarray *)it->array; | ||
265 | } | ||
266 | |||
267 | static void | ||
268 | _eina_inarray_accessor_free(Eina_Accessor_Inarray *it) | ||
269 | { | ||
270 | EINA_MAGIC_CHECK_INARRAY_ACCESSOR(it); | ||
271 | MAGIC_FREE(it); | ||
272 | } | ||
273 | |||
274 | /** | ||
275 | * @endcond | ||
276 | */ | ||
277 | |||
278 | |||
279 | /*============================================================================* | ||
280 | * Global * | ||
281 | *============================================================================*/ | ||
282 | |||
283 | /** | ||
284 | * @internal | ||
285 | * @brief Initialize the inline array module. | ||
286 | * | ||
287 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
288 | * | ||
289 | * This function sets up the inline array module of Eina. It is called | ||
290 | * by eina_init(). | ||
291 | * | ||
292 | * @see eina_init() | ||
293 | */ | ||
294 | Eina_Bool | ||
295 | eina_inarray_init(void) | ||
296 | { | ||
297 | _eina_inarray_log_dom = eina_log_domain_register("eina_inarray", | ||
298 | EINA_LOG_COLOR_DEFAULT); | ||
299 | if (_eina_inarray_log_dom < 0) | ||
300 | { | ||
301 | EINA_LOG_ERR("Could not register log domain: eina_inarray"); | ||
302 | return EINA_FALSE; | ||
303 | } | ||
304 | |||
305 | #define EMS(n) eina_magic_string_static_set(n, n ## _STR) | ||
306 | EMS(EINA_MAGIC_INARRAY); | ||
307 | EMS(EINA_MAGIC_INARRAY_ITERATOR); | ||
308 | EMS(EINA_MAGIC_INARRAY_ACCESSOR); | ||
309 | #undef EMS | ||
310 | |||
311 | return EINA_TRUE; | ||
312 | } | ||
313 | |||
314 | /** | ||
315 | * @internal | ||
316 | * @brief Shut down the inline array module. | ||
317 | * | ||
318 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
319 | * | ||
320 | * This function shuts down the inline array module set up by | ||
321 | * eina_inarray_init(). It is called by eina_shutdown(). | ||
322 | * | ||
323 | * @see eina_shutdown() | ||
324 | */ | ||
325 | Eina_Bool | ||
326 | eina_inarray_shutdown(void) | ||
327 | { | ||
328 | eina_log_domain_unregister(_eina_inarray_log_dom); | ||
329 | _eina_inarray_log_dom = -1; | ||
330 | return EINA_TRUE; | ||
331 | } | ||
332 | |||
333 | /*============================================================================* | ||
334 | * API * | ||
335 | *============================================================================*/ | ||
336 | EAPI Eina_Inarray * | ||
337 | eina_inarray_new(unsigned int member_size, unsigned int step) | ||
338 | { | ||
339 | Eina_Inarray *ret; | ||
340 | |||
341 | EINA_SAFETY_ON_TRUE_RETURN_VAL(member_size == 0, NULL); | ||
342 | |||
343 | ret = malloc(sizeof(*ret)); | ||
344 | if (!ret) | ||
345 | { | ||
346 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
347 | return NULL; | ||
348 | } | ||
349 | eina_error_set(0); | ||
350 | _eina_inarray_setup(ret, member_size, step); | ||
351 | return ret; | ||
352 | } | ||
353 | |||
354 | EAPI void | ||
355 | eina_inarray_free(Eina_Inarray *array) | ||
356 | { | ||
357 | EINA_MAGIC_CHECK_INARRAY(array); | ||
358 | free(array->members); | ||
359 | free(array); | ||
360 | } | ||
361 | |||
362 | EAPI void | ||
363 | eina_inarray_setup(Eina_Inarray *array, unsigned int member_size, unsigned int step) | ||
364 | { | ||
365 | EINA_SAFETY_ON_NULL_RETURN(array); | ||
366 | EINA_SAFETY_ON_TRUE_RETURN(member_size == 0); | ||
367 | _eina_inarray_setup(array, member_size, step); | ||
368 | } | ||
369 | |||
370 | EAPI void | ||
371 | eina_inarray_flush(Eina_Inarray *array) | ||
372 | { | ||
373 | EINA_MAGIC_CHECK_INARRAY(array); | ||
374 | free(array->members); | ||
375 | array->len = 0; | ||
376 | array->max = 0; | ||
377 | array->members = NULL; | ||
378 | } | ||
379 | |||
380 | EAPI int | ||
381 | eina_inarray_append(Eina_Inarray *array, const void *data) | ||
382 | { | ||
383 | void *p; | ||
384 | |||
385 | EINA_MAGIC_CHECK_INARRAY(array, -1); | ||
386 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); | ||
387 | |||
388 | if (!_eina_inarray_resize(array, array->len + 1)) | ||
389 | return -1; | ||
390 | |||
391 | p = _eina_inarray_get(array, array->len); | ||
392 | memcpy(p, data, array->member_size); | ||
393 | |||
394 | array->len++; | ||
395 | return array->len - 1; | ||
396 | } | ||
397 | |||
398 | EAPI int | ||
399 | eina_inarray_insert(Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) | ||
400 | { | ||
401 | const unsigned char *itr, *itr_end; | ||
402 | unsigned int sz; | ||
403 | |||
404 | EINA_MAGIC_CHECK_INARRAY(array, -1); | ||
405 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); | ||
406 | EINA_SAFETY_ON_NULL_RETURN_VAL(compare, -1); | ||
407 | |||
408 | sz = array->member_size; | ||
409 | itr = array->members; | ||
410 | itr_end = itr + array->len * sz; | ||
411 | for (; itr < itr_end; itr += sz) | ||
412 | { | ||
413 | unsigned int offset, position; | ||
414 | int cmp = compare(itr, data); | ||
415 | if (cmp <= 0) | ||
416 | continue; | ||
417 | |||
418 | offset = itr - (unsigned char *)array->members; | ||
419 | position = offset / sz; | ||
420 | if (!eina_inarray_insert_at(array, position, data)) | ||
421 | return -1; | ||
422 | return position; | ||
423 | } | ||
424 | return eina_inarray_append(array, data); | ||
425 | } | ||
426 | |||
427 | EAPI int | ||
428 | eina_inarray_insert_sorted(Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) | ||
429 | { | ||
430 | unsigned int pos; | ||
431 | int cmp; | ||
432 | |||
433 | EINA_MAGIC_CHECK_INARRAY(array, -1); | ||
434 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); | ||
435 | EINA_SAFETY_ON_NULL_RETURN_VAL(compare, -1); | ||
436 | |||
437 | pos = _eina_inarray_search_sorted_near(array, data, compare, &cmp); | ||
438 | if (cmp > 0) | ||
439 | pos++; | ||
440 | |||
441 | if (!eina_inarray_insert_at(array, pos, data)) | ||
442 | return -1; | ||
443 | return pos; | ||
444 | } | ||
445 | |||
446 | EAPI int | ||
447 | eina_inarray_remove(Eina_Inarray *array, const void *data) | ||
448 | { | ||
449 | const unsigned char *itr, *itr_end; | ||
450 | unsigned int position, sz; | ||
451 | |||
452 | EINA_MAGIC_CHECK_INARRAY(array, -1); | ||
453 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); | ||
454 | |||
455 | sz = array->member_size; | ||
456 | if ((data >= array->members) && | ||
457 | (data < _eina_inarray_get(array, array->len))) | ||
458 | { | ||
459 | unsigned int offset = ((unsigned char *)data - | ||
460 | (unsigned char *)array->members); | ||
461 | position = offset / sz; | ||
462 | goto found; | ||
463 | } | ||
464 | |||
465 | itr = array->members; | ||
466 | itr_end = itr + array->len * sz; | ||
467 | for (; itr < itr_end; itr += sz) | ||
468 | { | ||
469 | if (memcmp(data, itr, sz) == 0) | ||
470 | { | ||
471 | unsigned int offset = itr - (unsigned char *)array->members; | ||
472 | position = offset / sz; | ||
473 | goto found; | ||
474 | } | ||
475 | } | ||
476 | return -1; | ||
477 | |||
478 | found: | ||
479 | if (!eina_inarray_remove_at(array, position)) | ||
480 | return -1; | ||
481 | return position; | ||
482 | } | ||
483 | |||
484 | EAPI int | ||
485 | eina_inarray_pop(Eina_Inarray *array) | ||
486 | { | ||
487 | EINA_MAGIC_CHECK_INARRAY(array, -1); | ||
488 | EINA_SAFETY_ON_TRUE_RETURN_VAL(array->len == 0, -1); | ||
489 | if (!_eina_inarray_resize(array, array->len - 1)) | ||
490 | return -1; | ||
491 | array->len--; | ||
492 | return array->len + 1; | ||
493 | } | ||
494 | |||
495 | EAPI void * | ||
496 | eina_inarray_nth(const Eina_Inarray *array, unsigned int position) | ||
497 | { | ||
498 | EINA_MAGIC_CHECK_INARRAY(array, NULL); | ||
499 | EINA_SAFETY_ON_TRUE_RETURN_VAL(position >= array->len, NULL); | ||
500 | return _eina_inarray_get(array, position); | ||
501 | } | ||
502 | |||
503 | EAPI Eina_Bool | ||
504 | eina_inarray_insert_at(Eina_Inarray *array, unsigned int position, const void *data) | ||
505 | { | ||
506 | unsigned int sz; | ||
507 | unsigned char *p; | ||
508 | |||
509 | EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); | ||
510 | EINA_SAFETY_ON_TRUE_RETURN_VAL(position > array->len, EINA_FALSE); | ||
511 | |||
512 | if (!_eina_inarray_resize(array, array->len + 1)) | ||
513 | return EINA_FALSE; | ||
514 | |||
515 | p = _eina_inarray_get(array, position); | ||
516 | sz = array->member_size; | ||
517 | if (array->len > position) | ||
518 | memmove(p + sz, p, (array->len - position) * sz); | ||
519 | memcpy(p, data, sz); | ||
520 | |||
521 | array->len++; | ||
522 | return EINA_TRUE; | ||
523 | } | ||
524 | |||
525 | EAPI void * | ||
526 | eina_inarray_alloc_at(Eina_Inarray *array, unsigned int position, unsigned int member_count) | ||
527 | { | ||
528 | unsigned int sz; | ||
529 | unsigned char *p; | ||
530 | |||
531 | EINA_MAGIC_CHECK_INARRAY(array, NULL); | ||
532 | EINA_SAFETY_ON_TRUE_RETURN_VAL(position > array->len, NULL); | ||
533 | EINA_SAFETY_ON_TRUE_RETURN_VAL(member_count == 0, NULL); | ||
534 | |||
535 | if (!_eina_inarray_resize(array, array->len + member_count)) | ||
536 | return NULL; | ||
537 | |||
538 | p = _eina_inarray_get(array, position); | ||
539 | sz = array->member_size; | ||
540 | if (array->len > position) | ||
541 | memmove(p + member_count * sz, p, (array->len - position) * sz); | ||
542 | |||
543 | array->len += member_count; | ||
544 | return p; | ||
545 | } | ||
546 | |||
547 | EAPI Eina_Bool | ||
548 | eina_inarray_replace_at(Eina_Inarray *array, unsigned int position, const void *data) | ||
549 | { | ||
550 | unsigned char *p; | ||
551 | |||
552 | EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); | ||
553 | EINA_SAFETY_ON_TRUE_RETURN_VAL(position >= array->len, EINA_FALSE); | ||
554 | |||
555 | p = _eina_inarray_get(array, position); | ||
556 | memcpy(p, data, array->member_size); | ||
557 | |||
558 | return EINA_TRUE; | ||
559 | } | ||
560 | |||
561 | EAPI Eina_Bool | ||
562 | eina_inarray_remove_at(Eina_Inarray *array, unsigned int position) | ||
563 | { | ||
564 | EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); | ||
565 | EINA_SAFETY_ON_TRUE_RETURN_VAL(position >= array->len, EINA_FALSE); | ||
566 | |||
567 | if (position + 1 < array->len) | ||
568 | { | ||
569 | unsigned int sz = array->member_size; | ||
570 | unsigned char *p = _eina_inarray_get(array, position); | ||
571 | memmove(p, p + sz, (array->len - position - 1) * sz); | ||
572 | } | ||
573 | |||
574 | _eina_inarray_resize(array, array->len - 1); | ||
575 | array->len--; | ||
576 | return EINA_TRUE; | ||
577 | } | ||
578 | |||
579 | EAPI void | ||
580 | eina_inarray_reverse(Eina_Inarray *array) | ||
581 | { | ||
582 | size_t sz; | ||
583 | unsigned char *fwd, *rev, *fwd_end; | ||
584 | void *tmp; | ||
585 | |||
586 | EINA_MAGIC_CHECK_INARRAY(array); | ||
587 | |||
588 | if (array->len < 2) | ||
589 | return; | ||
590 | |||
591 | sz = array->member_size; | ||
592 | |||
593 | tmp = alloca(sz); | ||
594 | EINA_SAFETY_ON_NULL_RETURN(tmp); | ||
595 | |||
596 | fwd = array->members; | ||
597 | fwd_end = fwd + (array->len / 2) * sz; | ||
598 | |||
599 | rev = fwd + (array->len - 1) * sz; | ||
600 | |||
601 | for (; fwd < fwd_end; fwd += sz, rev -= sz) | ||
602 | { | ||
603 | memcpy(tmp, fwd, sz); | ||
604 | memcpy(fwd, rev, sz); | ||
605 | memcpy(rev, tmp, sz); | ||
606 | } | ||
607 | } | ||
608 | |||
609 | EAPI void | ||
610 | eina_inarray_sort(Eina_Inarray *array, Eina_Compare_Cb compare) | ||
611 | { | ||
612 | EINA_MAGIC_CHECK_INARRAY(array); | ||
613 | EINA_SAFETY_ON_NULL_RETURN(compare); | ||
614 | qsort(array->members, array->len, array->member_size, compare); | ||
615 | } | ||
616 | |||
617 | EAPI int | ||
618 | eina_inarray_search(const Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) | ||
619 | { | ||
620 | EINA_MAGIC_CHECK_INARRAY(array, -1); | ||
621 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); | ||
622 | EINA_SAFETY_ON_NULL_RETURN_VAL(compare, -1); | ||
623 | return _eina_inarray_search(array, data, compare); | ||
624 | } | ||
625 | |||
626 | EAPI int | ||
627 | eina_inarray_search_sorted(const Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) | ||
628 | { | ||
629 | unsigned int pos; | ||
630 | int cmp; | ||
631 | |||
632 | EINA_MAGIC_CHECK_INARRAY(array, -1); | ||
633 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); | ||
634 | EINA_SAFETY_ON_NULL_RETURN_VAL(compare, -1); | ||
635 | |||
636 | pos = _eina_inarray_search_sorted_near(array, data, compare, &cmp); | ||
637 | if (cmp == 0) | ||
638 | return pos; | ||
639 | return -1; | ||
640 | } | ||
641 | |||
642 | EAPI Eina_Bool | ||
643 | eina_inarray_foreach(const Eina_Inarray *array, Eina_Each_Cb function, const void *user_data) | ||
644 | { | ||
645 | unsigned char *itr, *itr_end; | ||
646 | unsigned int sz; | ||
647 | Eina_Bool ret = EINA_TRUE; | ||
648 | |||
649 | EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); | ||
650 | EINA_SAFETY_ON_NULL_RETURN_VAL(function, EINA_FALSE); | ||
651 | |||
652 | sz = array->member_size; | ||
653 | itr = array->members; | ||
654 | itr_end = itr + array->len * sz; | ||
655 | for (; (itr < itr_end) && (ret); itr += sz) | ||
656 | ret = function(array, itr, (void *)user_data); | ||
657 | return ret; | ||
658 | } | ||
659 | |||
660 | EAPI int | ||
661 | eina_inarray_foreach_remove(Eina_Inarray *array, Eina_Each_Cb match, const void *user_data) | ||
662 | { | ||
663 | unsigned int i = 0, count = 0; | ||
664 | |||
665 | EINA_MAGIC_CHECK_INARRAY(array, -1); | ||
666 | EINA_SAFETY_ON_NULL_RETURN_VAL(match, -1); | ||
667 | |||
668 | while (i < array->len) | ||
669 | { | ||
670 | void *p = _eina_inarray_get(array, i); | ||
671 | if (match(array, p, (void *)user_data) == EINA_FALSE) | ||
672 | { | ||
673 | i++; | ||
674 | continue; | ||
675 | } | ||
676 | |||
677 | eina_inarray_remove_at(array, i); | ||
678 | count++; | ||
679 | } | ||
680 | |||
681 | return count; | ||
682 | } | ||
683 | |||
684 | EAPI unsigned int | ||
685 | eina_inarray_count(const Eina_Inarray *array) | ||
686 | { | ||
687 | EINA_MAGIC_CHECK_INARRAY(array, 0); | ||
688 | return array->len; | ||
689 | } | ||
690 | |||
691 | EAPI Eina_Iterator * | ||
692 | eina_inarray_iterator_new(const Eina_Inarray *array) | ||
693 | { | ||
694 | Eina_Iterator_Inarray *it; | ||
695 | |||
696 | EINA_MAGIC_CHECK_INARRAY(array, NULL); | ||
697 | |||
698 | eina_error_set(0); | ||
699 | it = calloc(1, sizeof(Eina_Iterator_Inarray)); | ||
700 | if (!it) | ||
701 | { | ||
702 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
703 | return NULL; | ||
704 | } | ||
705 | |||
706 | EINA_MAGIC_SET(it, EINA_MAGIC_INARRAY_ITERATOR); | ||
707 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
708 | |||
709 | it->array = array; | ||
710 | |||
711 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
712 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_inarray_iterator_next); | ||
713 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER | ||
714 | (_eina_inarray_iterator_get_container); | ||
715 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_inarray_iterator_free); | ||
716 | |||
717 | return &it->iterator; | ||
718 | } | ||
719 | |||
720 | EAPI Eina_Iterator * | ||
721 | eina_inarray_iterator_reversed_new(const Eina_Inarray *array) | ||
722 | { | ||
723 | Eina_Iterator_Inarray *it; | ||
724 | |||
725 | EINA_MAGIC_CHECK_INARRAY(array, NULL); | ||
726 | |||
727 | eina_error_set(0); | ||
728 | it = calloc(1, sizeof(Eina_Iterator_Inarray)); | ||
729 | if (!it) | ||
730 | { | ||
731 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
732 | return NULL; | ||
733 | } | ||
734 | |||
735 | EINA_MAGIC_SET(it, EINA_MAGIC_INARRAY_ITERATOR); | ||
736 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
737 | |||
738 | it->array = array; | ||
739 | it->pos = array->len; | ||
740 | |||
741 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
742 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_inarray_iterator_prev); | ||
743 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER | ||
744 | (_eina_inarray_iterator_get_container); | ||
745 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_inarray_iterator_free); | ||
746 | |||
747 | return &it->iterator; | ||
748 | } | ||
749 | |||
750 | EAPI Eina_Accessor * | ||
751 | eina_inarray_accessor_new(const Eina_Inarray *array) | ||
752 | { | ||
753 | Eina_Accessor_Inarray *ac; | ||
754 | |||
755 | EINA_MAGIC_CHECK_INARRAY(array, NULL); | ||
756 | |||
757 | eina_error_set(0); | ||
758 | ac = calloc(1, sizeof(Eina_Accessor_Inarray)); | ||
759 | if (!ac) | ||
760 | { | ||
761 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
762 | return NULL; | ||
763 | } | ||
764 | |||
765 | EINA_MAGIC_SET(ac, EINA_MAGIC_INARRAY_ACCESSOR); | ||
766 | EINA_MAGIC_SET(&ac->accessor, EINA_MAGIC_ACCESSOR); | ||
767 | |||
768 | ac->array = array; | ||
769 | |||
770 | ac->accessor.version = EINA_ACCESSOR_VERSION; | ||
771 | ac->accessor.get_at = FUNC_ACCESSOR_GET_AT(_eina_inarray_accessor_get_at); | ||
772 | ac->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER | ||
773 | (_eina_inarray_accessor_get_container); | ||
774 | ac->accessor.free = FUNC_ACCESSOR_FREE(_eina_inarray_accessor_free); | ||
775 | |||
776 | return &ac->accessor; | ||
777 | } | ||
diff --git a/libraries/eina/src/lib/eina_inlist.c b/libraries/eina/src/lib/eina_inlist.c deleted file mode 100644 index c80f87b..0000000 --- a/libraries/eina/src/lib/eina_inlist.c +++ /dev/null | |||
@@ -1,914 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2002-2008 Carsten Haitzler, Vincent Torri | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdlib.h> | ||
24 | #include <assert.h> | ||
25 | |||
26 | #include <stdio.h> | ||
27 | |||
28 | #include "eina_config.h" | ||
29 | #include "eina_private.h" | ||
30 | #include "eina_error.h" | ||
31 | #include "eina_log.h" | ||
32 | |||
33 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
34 | #include "eina_safety_checks.h" | ||
35 | #include "eina_inlist.h" | ||
36 | |||
37 | /* FIXME: TODO please, refactor this :) */ | ||
38 | |||
39 | /*============================================================================* | ||
40 | * Local * | ||
41 | *============================================================================*/ | ||
42 | |||
43 | /** | ||
44 | * @cond LOCAL | ||
45 | */ | ||
46 | |||
47 | #define EINA_INLIST_SORT_STACK_SIZE 32 | ||
48 | |||
49 | typedef struct _Eina_Iterator_Inlist Eina_Iterator_Inlist; | ||
50 | typedef struct _Eina_Accessor_Inlist Eina_Accessor_Inlist; | ||
51 | |||
52 | struct _Eina_Iterator_Inlist | ||
53 | { | ||
54 | Eina_Iterator iterator; | ||
55 | const Eina_Inlist *head; | ||
56 | const Eina_Inlist *current; | ||
57 | }; | ||
58 | |||
59 | struct _Eina_Accessor_Inlist | ||
60 | { | ||
61 | Eina_Accessor accessor; | ||
62 | |||
63 | const Eina_Inlist *head; | ||
64 | const Eina_Inlist *current; | ||
65 | |||
66 | unsigned int index; | ||
67 | }; | ||
68 | |||
69 | struct _Eina_Inlist_Sorted_State | ||
70 | { | ||
71 | Eina_Inlist *jump_table[EINA_INLIST_JUMP_SIZE]; | ||
72 | |||
73 | unsigned short jump_limit; | ||
74 | int jump_div; | ||
75 | |||
76 | int inserted; | ||
77 | }; | ||
78 | |||
79 | static Eina_Bool | ||
80 | eina_inlist_iterator_next(Eina_Iterator_Inlist *it, void **data) { | ||
81 | if (!it->current) | ||
82 | return EINA_FALSE; | ||
83 | |||
84 | if (data) | ||
85 | *data = (void *)it->current; | ||
86 | |||
87 | it->current = it->current->next; | ||
88 | |||
89 | return EINA_TRUE; | ||
90 | } | ||
91 | |||
92 | static Eina_Inlist * | ||
93 | eina_inlist_iterator_get_container(Eina_Iterator_Inlist *it) { | ||
94 | return (Eina_Inlist *)it->head; | ||
95 | } | ||
96 | |||
97 | static void | ||
98 | eina_inlist_iterator_free(Eina_Iterator_Inlist *it) { | ||
99 | free(it); | ||
100 | } | ||
101 | |||
102 | static Eina_Bool | ||
103 | eina_inlist_accessor_get_at(Eina_Accessor_Inlist *it, | ||
104 | unsigned int idx, | ||
105 | void **data) { | ||
106 | const Eina_Inlist *over; | ||
107 | unsigned int middle; | ||
108 | unsigned int i; | ||
109 | |||
110 | if (it->index == idx) | ||
111 | over = it->current; | ||
112 | else if (idx > it->index) | ||
113 | /* Looking after current. */ | ||
114 | for (i = it->index, over = it->current; | ||
115 | i < idx && over; | ||
116 | ++i, over = over->next) | ||
117 | ; | ||
118 | else | ||
119 | { | ||
120 | middle = it->index >> 1; | ||
121 | |||
122 | if (idx > middle) | ||
123 | /* Looking backward from current. */ | ||
124 | for (i = it->index, over = it->current; | ||
125 | i > idx && over; | ||
126 | --i, over = over->prev) | ||
127 | ; | ||
128 | else | ||
129 | /* Looking from the start. */ | ||
130 | for (i = 0, over = it->head; | ||
131 | i < idx && over; | ||
132 | ++i, over = over->next) | ||
133 | ; | ||
134 | } | ||
135 | |||
136 | if (!over) | ||
137 | return EINA_FALSE; | ||
138 | |||
139 | it->current = over; | ||
140 | it->index = idx; | ||
141 | |||
142 | if (data) | ||
143 | *data = (void *)over; | ||
144 | |||
145 | return EINA_TRUE; | ||
146 | } | ||
147 | |||
148 | static Eina_Inlist * | ||
149 | eina_inlist_accessor_get_container(Eina_Accessor_Inlist *it) { | ||
150 | return (Eina_Inlist *)it->head; | ||
151 | } | ||
152 | |||
153 | static void | ||
154 | eina_inlist_accessor_free(Eina_Accessor_Inlist *it) { | ||
155 | free(it); | ||
156 | } | ||
157 | |||
158 | static Eina_Inlist * | ||
159 | eina_inlist_sort_merge(Eina_Inlist *a, Eina_Inlist *b, Eina_Compare_Cb func) | ||
160 | { | ||
161 | Eina_Inlist *first, *last; | ||
162 | |||
163 | if (func(a, b) < 0) | ||
164 | a = (last = first = a)->next; | ||
165 | else | ||
166 | b = (last = first = b)->next; | ||
167 | |||
168 | while (a && b) | ||
169 | if (func(a, b) < 0) | ||
170 | a = (last = last->next = a)->next; | ||
171 | else | ||
172 | b = (last = last->next = b)->next; | ||
173 | |||
174 | last->next = a ? a : b; | ||
175 | |||
176 | return first; | ||
177 | } | ||
178 | |||
179 | static Eina_Inlist * | ||
180 | eina_inlist_sort_rebuild_prev(Eina_Inlist *list) | ||
181 | { | ||
182 | Eina_Inlist *prev = NULL; | ||
183 | |||
184 | for (; list; list = list->next) | ||
185 | { | ||
186 | list->prev = prev; | ||
187 | prev = list; | ||
188 | } | ||
189 | |||
190 | return prev; | ||
191 | } | ||
192 | |||
193 | static void | ||
194 | _eina_inlist_sorted_state_compact(Eina_Inlist_Sorted_State *state) | ||
195 | { | ||
196 | unsigned short i, j; | ||
197 | |||
198 | /* compress the jump table */ | ||
199 | state->jump_div *= 2; | ||
200 | state->jump_limit /= 2; | ||
201 | |||
202 | for (i = 2, j = 1; | ||
203 | i < EINA_INLIST_JUMP_SIZE; | ||
204 | i += 2, j++) | ||
205 | state->jump_table[j] = state->jump_table[i]; | ||
206 | } | ||
207 | |||
208 | /** | ||
209 | * @endcond | ||
210 | */ | ||
211 | |||
212 | |||
213 | /*============================================================================* | ||
214 | * Global * | ||
215 | *============================================================================*/ | ||
216 | |||
217 | /*============================================================================* | ||
218 | * API * | ||
219 | *============================================================================*/ | ||
220 | |||
221 | EAPI Eina_Inlist * | ||
222 | eina_inlist_append(Eina_Inlist *list, Eina_Inlist *new_l) | ||
223 | { | ||
224 | Eina_Inlist *l; | ||
225 | |||
226 | EINA_SAFETY_ON_NULL_RETURN_VAL(new_l, list); | ||
227 | |||
228 | new_l->next = NULL; | ||
229 | if (!list) | ||
230 | { | ||
231 | new_l->prev = NULL; | ||
232 | new_l->last = new_l; | ||
233 | return new_l; | ||
234 | } | ||
235 | |||
236 | if (list->last) | ||
237 | l = list->last; | ||
238 | else | ||
239 | for (l = list; (l) && (l->next); l = l->next) | ||
240 | ; | ||
241 | |||
242 | l->next = new_l; | ||
243 | new_l->prev = l; | ||
244 | list->last = new_l; | ||
245 | return list; | ||
246 | } | ||
247 | |||
248 | EAPI Eina_Inlist * | ||
249 | eina_inlist_prepend(Eina_Inlist *list, Eina_Inlist *new_l) | ||
250 | { | ||
251 | EINA_SAFETY_ON_NULL_RETURN_VAL(new_l, list); | ||
252 | |||
253 | new_l->prev = NULL; | ||
254 | if (!list) | ||
255 | { | ||
256 | new_l->next = NULL; | ||
257 | new_l->last = new_l; | ||
258 | return new_l; | ||
259 | } | ||
260 | |||
261 | new_l->next = list; | ||
262 | list->prev = new_l; | ||
263 | new_l->last = list->last; | ||
264 | list->last = NULL; | ||
265 | return new_l; | ||
266 | } | ||
267 | |||
268 | EAPI Eina_Inlist * | ||
269 | eina_inlist_append_relative(Eina_Inlist *list, | ||
270 | Eina_Inlist *new_l, | ||
271 | Eina_Inlist *relative) | ||
272 | { | ||
273 | EINA_SAFETY_ON_NULL_RETURN_VAL(new_l, list); | ||
274 | |||
275 | if (relative) | ||
276 | { | ||
277 | if (relative->next) | ||
278 | { | ||
279 | new_l->next = relative->next; | ||
280 | relative->next->prev = new_l; | ||
281 | } | ||
282 | else | ||
283 | new_l->next = NULL; | ||
284 | |||
285 | relative->next = new_l; | ||
286 | new_l->prev = relative; | ||
287 | if (!new_l->next) | ||
288 | list->last = new_l; | ||
289 | |||
290 | return list; | ||
291 | } | ||
292 | |||
293 | return eina_inlist_append(list, new_l); | ||
294 | } | ||
295 | |||
296 | EAPI Eina_Inlist * | ||
297 | eina_inlist_prepend_relative(Eina_Inlist *list, | ||
298 | Eina_Inlist *new_l, | ||
299 | Eina_Inlist *relative) | ||
300 | { | ||
301 | EINA_SAFETY_ON_NULL_RETURN_VAL(new_l, list); | ||
302 | |||
303 | if (relative) | ||
304 | { | ||
305 | new_l->prev = relative->prev; | ||
306 | new_l->next = relative; | ||
307 | relative->prev = new_l; | ||
308 | if (new_l->prev) | ||
309 | { | ||
310 | new_l->prev->next = new_l; | ||
311 | /* new_l->next could not be NULL, as it was set to 'relative' */ | ||
312 | assert(new_l->next); | ||
313 | return list; | ||
314 | } | ||
315 | else | ||
316 | { | ||
317 | /* new_l->next could not be NULL, as it was set to 'relative' */ | ||
318 | assert(new_l->next); | ||
319 | |||
320 | new_l->last = list->last; | ||
321 | list->last = NULL; | ||
322 | return new_l; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | return eina_inlist_prepend(list, new_l); | ||
327 | } | ||
328 | |||
329 | EAPI Eina_Inlist * | ||
330 | eina_inlist_remove(Eina_Inlist *list, Eina_Inlist *item) | ||
331 | { | ||
332 | Eina_Inlist *return_l; | ||
333 | |||
334 | /* checkme */ | ||
335 | EINA_SAFETY_ON_NULL_RETURN_VAL(list, NULL); | ||
336 | EINA_SAFETY_ON_NULL_RETURN_VAL(item, list); | ||
337 | if (EINA_UNLIKELY((item != list) && (!item->prev) && (!item->next))) | ||
338 | { | ||
339 | eina_error_set(EINA_ERROR_SAFETY_FAILED); | ||
340 | EINA_LOG_ERR("safety check failed: item %p does not appear to be part of an inlist!", item); | ||
341 | return list; | ||
342 | } | ||
343 | |||
344 | if (item->next) | ||
345 | item->next->prev = item->prev; | ||
346 | |||
347 | if (item->prev) | ||
348 | { | ||
349 | item->prev->next = item->next; | ||
350 | return_l = list; | ||
351 | } | ||
352 | else | ||
353 | { | ||
354 | return_l = item->next; | ||
355 | if (return_l) | ||
356 | return_l->last = list->last; | ||
357 | } | ||
358 | |||
359 | if (item == list->last) | ||
360 | list->last = item->prev; | ||
361 | |||
362 | item->next = NULL; | ||
363 | item->prev = NULL; | ||
364 | return return_l; | ||
365 | } | ||
366 | |||
367 | EAPI Eina_Inlist * | ||
368 | eina_inlist_promote(Eina_Inlist *list, Eina_Inlist *item) | ||
369 | { | ||
370 | EINA_SAFETY_ON_NULL_RETURN_VAL(list, NULL); | ||
371 | EINA_SAFETY_ON_NULL_RETURN_VAL(item, list); | ||
372 | |||
373 | if (item == list) | ||
374 | return list; | ||
375 | |||
376 | if (item->next) | ||
377 | item->next->prev = item->prev; | ||
378 | |||
379 | item->prev->next = item->next; | ||
380 | |||
381 | if (list->last == item) | ||
382 | list->last = item->prev; | ||
383 | |||
384 | item->next = list; | ||
385 | item->prev = NULL; | ||
386 | item->last = list->last; | ||
387 | |||
388 | list->prev = item; | ||
389 | list->last = NULL; | ||
390 | |||
391 | return item; | ||
392 | } | ||
393 | |||
394 | EAPI Eina_Inlist * | ||
395 | eina_inlist_demote(Eina_Inlist *list, Eina_Inlist *item) | ||
396 | { | ||
397 | Eina_Inlist *l; | ||
398 | |||
399 | EINA_SAFETY_ON_NULL_RETURN_VAL(list, NULL); | ||
400 | EINA_SAFETY_ON_NULL_RETURN_VAL(item, list); | ||
401 | |||
402 | if (list->last == item) | ||
403 | return list; | ||
404 | |||
405 | if (!list->last) | ||
406 | { | ||
407 | for (l = list; l->next; l = l->next) | ||
408 | ; | ||
409 | list->last = l; | ||
410 | } | ||
411 | |||
412 | l = list; | ||
413 | if (item->prev) | ||
414 | item->prev->next = item->next; | ||
415 | else | ||
416 | l = item->next; | ||
417 | |||
418 | item->next->prev = item->prev; | ||
419 | |||
420 | list->last->next = item; | ||
421 | item->prev = list->last; | ||
422 | item->next = NULL; | ||
423 | |||
424 | l->last = item; | ||
425 | return l; | ||
426 | } | ||
427 | |||
428 | EAPI Eina_Inlist * | ||
429 | eina_inlist_find(Eina_Inlist *list, Eina_Inlist *item) | ||
430 | { | ||
431 | Eina_Inlist *l; | ||
432 | |||
433 | EINA_SAFETY_ON_NULL_RETURN_VAL(item, NULL); | ||
434 | |||
435 | for (l = list; l; l = l->next) { | ||
436 | if (l == item) | ||
437 | return item; | ||
438 | } | ||
439 | return NULL; | ||
440 | } | ||
441 | |||
442 | EAPI unsigned int | ||
443 | eina_inlist_count(const Eina_Inlist *list) | ||
444 | { | ||
445 | const Eina_Inlist *l; | ||
446 | unsigned int i = 0; | ||
447 | |||
448 | for (l = list; l; l = l->next) | ||
449 | i++; | ||
450 | |||
451 | return i; | ||
452 | } | ||
453 | |||
454 | EAPI int | ||
455 | eina_inlist_sorted_state_init(Eina_Inlist_Sorted_State *state, Eina_Inlist *list) | ||
456 | { | ||
457 | Eina_Inlist *ct = NULL; | ||
458 | int count = 0; | ||
459 | int jump_count = 1; | ||
460 | |||
461 | /* | ||
462 | * prepare a jump table to avoid doing unnecessary rewalk | ||
463 | * of the inlist as much as possible. | ||
464 | */ | ||
465 | for (ct = list; ct; ct = ct->next, jump_count++, count++) | ||
466 | { | ||
467 | if (jump_count == state->jump_div) | ||
468 | { | ||
469 | if (state->jump_limit == EINA_INLIST_JUMP_SIZE) | ||
470 | { | ||
471 | _eina_inlist_sorted_state_compact(state); | ||
472 | } | ||
473 | |||
474 | state->jump_table[state->jump_limit] = ct; | ||
475 | state->jump_limit++; | ||
476 | jump_count = 0; | ||
477 | } | ||
478 | } | ||
479 | |||
480 | state->inserted = count; | ||
481 | return count; | ||
482 | } | ||
483 | |||
484 | EAPI Eina_Inlist_Sorted_State * | ||
485 | eina_inlist_sorted_state_new(void) | ||
486 | { | ||
487 | Eina_Inlist_Sorted_State *r; | ||
488 | |||
489 | r = calloc(1, sizeof (Eina_Inlist_Sorted_State)); | ||
490 | if (!r) return NULL; | ||
491 | |||
492 | r->jump_div = 1; | ||
493 | |||
494 | return r; | ||
495 | } | ||
496 | |||
497 | EAPI void | ||
498 | eina_inlist_sorted_state_free(Eina_Inlist_Sorted_State *state) | ||
499 | { | ||
500 | free(state); | ||
501 | } | ||
502 | |||
503 | static void | ||
504 | _eina_inlist_sorted_state_insert(Eina_Inlist_Sorted_State *state, | ||
505 | unsigned short idx, | ||
506 | int offset) | ||
507 | { | ||
508 | Eina_Inlist *last; | ||
509 | int jump_count; | ||
510 | int start; | ||
511 | |||
512 | state->inserted++; | ||
513 | |||
514 | if (offset != 0) idx++; | ||
515 | for (; idx < state->jump_limit; idx++) | ||
516 | { | ||
517 | state->jump_table[idx] = state->jump_table[idx]->prev; | ||
518 | } | ||
519 | |||
520 | start = state->jump_limit - 3; | ||
521 | if (start < 0) | ||
522 | start = 0; | ||
523 | |||
524 | last = state->jump_table[start]; | ||
525 | start++; | ||
526 | |||
527 | /* Correctly rebuild end of list */ | ||
528 | for (jump_count = 0; last->next != NULL; last = last->next, jump_count++) | ||
529 | { | ||
530 | if (jump_count == state->jump_div) | ||
531 | { | ||
532 | if (state->jump_limit == start) | ||
533 | { | ||
534 | if (state->jump_limit == EINA_INLIST_JUMP_SIZE) | ||
535 | { | ||
536 | _eina_inlist_sorted_state_compact(state); | ||
537 | start = state->jump_limit - 1; | ||
538 | continue ; | ||
539 | } | ||
540 | else | ||
541 | { | ||
542 | state->jump_limit++; | ||
543 | } | ||
544 | } | ||
545 | |||
546 | state->jump_table[start++] = last; | ||
547 | jump_count = 0; | ||
548 | } | ||
549 | } | ||
550 | } | ||
551 | |||
552 | EAPI Eina_Inlist * | ||
553 | eina_inlist_sorted_insert(Eina_Inlist *list, | ||
554 | Eina_Inlist *item, | ||
555 | Eina_Compare_Cb func) | ||
556 | { | ||
557 | Eina_Inlist *ct = NULL; | ||
558 | Eina_Inlist_Sorted_State state; | ||
559 | int cmp = 0; | ||
560 | int inf, sup; | ||
561 | int cur = 0; | ||
562 | int count; | ||
563 | |||
564 | EINA_SAFETY_ON_NULL_RETURN_VAL(item, list); | ||
565 | EINA_SAFETY_ON_NULL_RETURN_VAL(func, list); | ||
566 | |||
567 | if (!list) return eina_inlist_append(NULL, item); | ||
568 | |||
569 | if (!list->next) | ||
570 | { | ||
571 | cmp = func(list, item); | ||
572 | |||
573 | if (cmp < 0) | ||
574 | return eina_inlist_append(list, item); | ||
575 | return eina_inlist_prepend(list, item); | ||
576 | } | ||
577 | |||
578 | state.jump_div = 1; | ||
579 | state.jump_limit = 0; | ||
580 | count = eina_inlist_sorted_state_init(&state, list); | ||
581 | |||
582 | /* | ||
583 | * now do a dychotomic search directly inside the jump_table. | ||
584 | */ | ||
585 | inf = 0; | ||
586 | sup = state.jump_limit - 1; | ||
587 | cur = 0; | ||
588 | ct = state.jump_table[cur]; | ||
589 | cmp = func(ct, item); | ||
590 | |||
591 | while (inf <= sup) | ||
592 | { | ||
593 | cur = inf + ((sup - inf) >> 1); | ||
594 | ct = state.jump_table[cur]; | ||
595 | |||
596 | cmp = func(ct, item); | ||
597 | if (cmp == 0) | ||
598 | break ; | ||
599 | else if (cmp < 0) | ||
600 | inf = cur + 1; | ||
601 | else if (cmp > 0) | ||
602 | { | ||
603 | if (cur > 0) | ||
604 | sup = cur - 1; | ||
605 | else | ||
606 | break; | ||
607 | } | ||
608 | else | ||
609 | break; | ||
610 | } | ||
611 | |||
612 | /* If at the beginning of the table and cmp < 0, | ||
613 | * insert just after the head */ | ||
614 | if (cur == 0 && cmp > 0) | ||
615 | return eina_inlist_prepend_relative(list, item, ct); | ||
616 | |||
617 | /* If at the end of the table and cmp >= 0, | ||
618 | * just append the item to the list */ | ||
619 | if (cmp < 0 && ct == list->last) | ||
620 | return eina_inlist_append(list, item); | ||
621 | |||
622 | /* | ||
623 | * Now do a dychotomic search between two entries inside the jump_table | ||
624 | */ | ||
625 | cur *= state.jump_div; | ||
626 | inf = cur - state.jump_div - 1; | ||
627 | sup = cur + state.jump_div + 1; | ||
628 | |||
629 | if (sup > count - 1) sup = count - 1; | ||
630 | if (inf < 0) inf = 0; | ||
631 | |||
632 | while (inf <= sup) | ||
633 | { | ||
634 | int tmp = cur; | ||
635 | |||
636 | cur = inf + ((sup - inf) >> 1); | ||
637 | if (tmp < cur) | ||
638 | for (; tmp != cur; tmp++, ct = ct->next); | ||
639 | else if (tmp > cur) | ||
640 | for (; tmp != cur; tmp--, ct = ct->prev); | ||
641 | |||
642 | cmp = func(ct, item); | ||
643 | if (cmp == 0) | ||
644 | break ; | ||
645 | else if (cmp < 0) | ||
646 | inf = cur + 1; | ||
647 | else if (cmp > 0) | ||
648 | { | ||
649 | if (cur > 0) | ||
650 | sup = cur - 1; | ||
651 | else | ||
652 | break; | ||
653 | } | ||
654 | else | ||
655 | break; | ||
656 | } | ||
657 | |||
658 | if (cmp <= 0) | ||
659 | return eina_inlist_append_relative(list, item, ct); | ||
660 | return eina_inlist_prepend_relative(list, item, ct); | ||
661 | } | ||
662 | |||
663 | EAPI Eina_Inlist * | ||
664 | eina_inlist_sorted_state_insert(Eina_Inlist *list, | ||
665 | Eina_Inlist *item, | ||
666 | Eina_Compare_Cb func, | ||
667 | Eina_Inlist_Sorted_State *state) | ||
668 | { | ||
669 | Eina_Inlist *ct = NULL; | ||
670 | int cmp = 0; | ||
671 | int inf, sup; | ||
672 | int cur = 0; | ||
673 | int count; | ||
674 | unsigned short head; | ||
675 | unsigned int offset; | ||
676 | |||
677 | if (!list) | ||
678 | { | ||
679 | state->inserted = 1; | ||
680 | state->jump_limit = 1; | ||
681 | state->jump_table[0] = item; | ||
682 | return eina_inlist_append(NULL, item); | ||
683 | } | ||
684 | |||
685 | if (!list->next) | ||
686 | { | ||
687 | cmp = func(list, item); | ||
688 | |||
689 | state->jump_limit = 2; | ||
690 | state->inserted = 2; | ||
691 | |||
692 | if (cmp < 0) | ||
693 | { | ||
694 | state->jump_table[1] = item; | ||
695 | return eina_inlist_append(list, item); | ||
696 | } | ||
697 | state->jump_table[1] = state->jump_table[0]; | ||
698 | state->jump_table[0] = item; | ||
699 | return eina_inlist_prepend(list, item); | ||
700 | } | ||
701 | |||
702 | count = state->inserted; | ||
703 | |||
704 | /* | ||
705 | * now do a dychotomic search directly inside the jump_table. | ||
706 | */ | ||
707 | inf = 0; | ||
708 | sup = state->jump_limit - 1; | ||
709 | cur = 0; | ||
710 | ct = state->jump_table[cur]; | ||
711 | cmp = func(ct, item); | ||
712 | |||
713 | while (inf <= sup) | ||
714 | { | ||
715 | cur = inf + ((sup - inf) >> 1); | ||
716 | ct = state->jump_table[cur]; | ||
717 | |||
718 | cmp = func(ct, item); | ||
719 | if (cmp == 0) | ||
720 | break ; | ||
721 | else if (cmp < 0) | ||
722 | inf = cur + 1; | ||
723 | else if (cmp > 0) | ||
724 | { | ||
725 | if (cur > 0) | ||
726 | sup = cur - 1; | ||
727 | else | ||
728 | break; | ||
729 | } | ||
730 | else | ||
731 | break; | ||
732 | } | ||
733 | |||
734 | /* If at the beginning of the table and cmp < 0, | ||
735 | * insert just after the head */ | ||
736 | if (cur == 0 && cmp > 0) | ||
737 | { | ||
738 | ct = eina_inlist_prepend_relative(list, item, ct); | ||
739 | _eina_inlist_sorted_state_insert(state, 0, 0); | ||
740 | return ct; | ||
741 | } | ||
742 | |||
743 | /* If at the end of the table and cmp >= 0, | ||
744 | * just append the item to the list */ | ||
745 | if (cmp < 0 && ct == list->last) | ||
746 | { | ||
747 | ct = eina_inlist_append(list, item); | ||
748 | _eina_inlist_sorted_state_insert(state, state->jump_limit - 1, 1); | ||
749 | return ct; | ||
750 | } | ||
751 | |||
752 | /* | ||
753 | * Now do a dychotomic search between two entries inside the jump_table | ||
754 | */ | ||
755 | cur *= state->jump_div; | ||
756 | inf = cur - state->jump_div - 1; | ||
757 | sup = cur + state->jump_div + 1; | ||
758 | |||
759 | if (sup > count - 1) sup = count - 1; | ||
760 | if (inf < 0) inf = 0; | ||
761 | |||
762 | while (inf <= sup) | ||
763 | { | ||
764 | int tmp = cur; | ||
765 | |||
766 | cur = inf + ((sup - inf) >> 1); | ||
767 | if (tmp < cur) | ||
768 | for (; tmp != cur; tmp++, ct = ct->next); | ||
769 | else if (tmp > cur) | ||
770 | for (; tmp != cur; tmp--, ct = ct->prev); | ||
771 | |||
772 | cmp = func(ct, item); | ||
773 | if (cmp == 0) | ||
774 | break ; | ||
775 | else if (cmp < 0) | ||
776 | inf = cur + 1; | ||
777 | else if (cmp > 0) | ||
778 | { | ||
779 | if (cur > 0) | ||
780 | sup = cur - 1; | ||
781 | else | ||
782 | break; | ||
783 | } | ||
784 | else | ||
785 | break; | ||
786 | } | ||
787 | |||
788 | if (cmp <= 0) | ||
789 | { | ||
790 | cur++; | ||
791 | |||
792 | ct = eina_inlist_append_relative(list, item, ct); | ||
793 | } | ||
794 | else | ||
795 | { | ||
796 | ct = eina_inlist_prepend_relative(list, item, ct); | ||
797 | } | ||
798 | |||
799 | head = cur / state->jump_div; | ||
800 | offset = cur % state->jump_div; | ||
801 | |||
802 | _eina_inlist_sorted_state_insert(state, head, offset); | ||
803 | return ct; | ||
804 | } | ||
805 | |||
806 | EAPI Eina_Inlist * | ||
807 | eina_inlist_sort(Eina_Inlist *head, Eina_Compare_Cb func) | ||
808 | { | ||
809 | unsigned int i = 0; | ||
810 | unsigned int n = 0; | ||
811 | Eina_Inlist *tail = head; | ||
812 | Eina_Inlist *unsort = NULL; | ||
813 | Eina_Inlist *stack[EINA_INLIST_SORT_STACK_SIZE]; | ||
814 | |||
815 | EINA_SAFETY_ON_NULL_RETURN_VAL(head, NULL); | ||
816 | EINA_SAFETY_ON_NULL_RETURN_VAL(func, head); | ||
817 | |||
818 | while (tail) | ||
819 | { | ||
820 | unsigned int idx, tmp; | ||
821 | |||
822 | Eina_Inlist *a = tail; | ||
823 | Eina_Inlist *b = tail->next; | ||
824 | |||
825 | if (!b) | ||
826 | { | ||
827 | stack[i++] = a; | ||
828 | break; | ||
829 | } | ||
830 | |||
831 | tail = b->next; | ||
832 | |||
833 | if (func(a, b) < 0) | ||
834 | ((stack[i++] = a)->next = b)->next = 0; | ||
835 | else | ||
836 | ((stack[i++] = b)->next = a)->next = 0; | ||
837 | |||
838 | tmp = n++; | ||
839 | for (idx = n ^ tmp; idx &= idx - 1; i--) | ||
840 | stack[i - 2] = eina_inlist_sort_merge(stack[i - 2], stack[i - 1], func); | ||
841 | } | ||
842 | |||
843 | while (i-- > 1) | ||
844 | stack[i - 1] = eina_inlist_sort_merge(stack[i - 1], stack[i], func); | ||
845 | |||
846 | head = stack[0]; | ||
847 | tail = eina_inlist_sort_rebuild_prev(head); | ||
848 | |||
849 | if (unsort) | ||
850 | { | ||
851 | tail->next = unsort; | ||
852 | unsort->prev = tail; | ||
853 | } | ||
854 | |||
855 | head->last = tail; | ||
856 | |||
857 | return head; | ||
858 | |||
859 | } | ||
860 | |||
861 | EAPI Eina_Iterator * | ||
862 | eina_inlist_iterator_new(const Eina_Inlist *list) | ||
863 | { | ||
864 | Eina_Iterator_Inlist *it; | ||
865 | |||
866 | eina_error_set(0); | ||
867 | it = calloc(1, sizeof (Eina_Iterator_Inlist)); | ||
868 | if (!it) | ||
869 | { | ||
870 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
871 | return NULL; | ||
872 | } | ||
873 | |||
874 | it->head = list; | ||
875 | it->current = list; | ||
876 | |||
877 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
878 | it->iterator.next = FUNC_ITERATOR_NEXT(eina_inlist_iterator_next); | ||
879 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
880 | eina_inlist_iterator_get_container); | ||
881 | it->iterator.free = FUNC_ITERATOR_FREE(eina_inlist_iterator_free); | ||
882 | |||
883 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
884 | |||
885 | return &it->iterator; | ||
886 | } | ||
887 | |||
888 | EAPI Eina_Accessor * | ||
889 | eina_inlist_accessor_new(const Eina_Inlist *list) | ||
890 | { | ||
891 | Eina_Accessor_Inlist *ac; | ||
892 | |||
893 | eina_error_set(0); | ||
894 | ac = calloc(1, sizeof (Eina_Accessor_Inlist)); | ||
895 | if (!ac) | ||
896 | { | ||
897 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
898 | return NULL; | ||
899 | } | ||
900 | |||
901 | ac->head = list; | ||
902 | ac->current = list; | ||
903 | ac->index = 0; | ||
904 | |||
905 | ac->accessor.version = EINA_ACCESSOR_VERSION; | ||
906 | ac->accessor.get_at = FUNC_ACCESSOR_GET_AT(eina_inlist_accessor_get_at); | ||
907 | ac->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER( | ||
908 | eina_inlist_accessor_get_container); | ||
909 | ac->accessor.free = FUNC_ACCESSOR_FREE(eina_inlist_accessor_free); | ||
910 | |||
911 | EINA_MAGIC_SET(&ac->accessor, EINA_MAGIC_ACCESSOR); | ||
912 | |||
913 | return &ac->accessor; | ||
914 | } | ||
diff --git a/libraries/eina/src/lib/eina_iterator.c b/libraries/eina/src/lib/eina_iterator.c deleted file mode 100644 index 0721066..0000000 --- a/libraries/eina/src/lib/eina_iterator.c +++ /dev/null | |||
@@ -1,172 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2002-2008 Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdlib.h> | ||
24 | |||
25 | #include "eina_config.h" | ||
26 | #include "eina_private.h" | ||
27 | |||
28 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
29 | #include "eina_safety_checks.h" | ||
30 | #include "eina_iterator.h" | ||
31 | |||
32 | /*============================================================================* | ||
33 | * Local * | ||
34 | *============================================================================*/ | ||
35 | |||
36 | /** | ||
37 | * @cond LOCAL | ||
38 | */ | ||
39 | |||
40 | static const char EINA_MAGIC_ITERATOR_STR[] = "Eina Iterator"; | ||
41 | |||
42 | #define EINA_MAGIC_CHECK_ITERATOR(d) \ | ||
43 | do { \ | ||
44 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ITERATOR)) { \ | ||
45 | EINA_MAGIC_FAIL(d, EINA_MAGIC_ITERATOR); } \ | ||
46 | } while(0) | ||
47 | |||
48 | /** | ||
49 | * @endcond | ||
50 | */ | ||
51 | |||
52 | |||
53 | /*============================================================================* | ||
54 | * Global * | ||
55 | *============================================================================*/ | ||
56 | |||
57 | /** | ||
58 | * @internal | ||
59 | * @brief Initialize the iterator module. | ||
60 | * | ||
61 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
62 | * | ||
63 | * This function sets up the iterator module of Eina. It is called by | ||
64 | * eina_init(). | ||
65 | * | ||
66 | * @see eina_init() | ||
67 | */ | ||
68 | Eina_Bool | ||
69 | eina_iterator_init(void) | ||
70 | { | ||
71 | return eina_magic_string_set(EINA_MAGIC_ITERATOR, EINA_MAGIC_ITERATOR_STR); | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * @internal | ||
76 | * @brief Shut down the iterator module. | ||
77 | * | ||
78 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
79 | * | ||
80 | * This function shuts down the iterator module set up by | ||
81 | * eina_iterator_init(). It is called by eina_shutdown(). | ||
82 | * | ||
83 | * @see eina_shutdown() | ||
84 | */ | ||
85 | Eina_Bool | ||
86 | eina_iterator_shutdown(void) | ||
87 | { | ||
88 | return EINA_TRUE; | ||
89 | } | ||
90 | |||
91 | /*============================================================================* | ||
92 | * API * | ||
93 | *============================================================================*/ | ||
94 | |||
95 | EAPI void | ||
96 | eina_iterator_free(Eina_Iterator *iterator) | ||
97 | { | ||
98 | EINA_MAGIC_CHECK_ITERATOR(iterator); | ||
99 | EINA_SAFETY_ON_NULL_RETURN(iterator); | ||
100 | EINA_SAFETY_ON_NULL_RETURN(iterator->free); | ||
101 | iterator->free(iterator); | ||
102 | } | ||
103 | |||
104 | EAPI void * | ||
105 | eina_iterator_container_get(Eina_Iterator *iterator) | ||
106 | { | ||
107 | EINA_MAGIC_CHECK_ITERATOR(iterator); | ||
108 | EINA_SAFETY_ON_NULL_RETURN_VAL(iterator, NULL); | ||
109 | EINA_SAFETY_ON_NULL_RETURN_VAL(iterator->get_container, NULL); | ||
110 | return iterator->get_container(iterator); | ||
111 | } | ||
112 | |||
113 | EAPI Eina_Bool | ||
114 | eina_iterator_next(Eina_Iterator *iterator, void **data) | ||
115 | { | ||
116 | if (!iterator) | ||
117 | return EINA_FALSE; | ||
118 | |||
119 | EINA_MAGIC_CHECK_ITERATOR(iterator); | ||
120 | EINA_SAFETY_ON_NULL_RETURN_VAL(iterator, EINA_FALSE); | ||
121 | EINA_SAFETY_ON_NULL_RETURN_VAL(iterator->next, EINA_FALSE); | ||
122 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); | ||
123 | return iterator->next(iterator, data); | ||
124 | } | ||
125 | |||
126 | EAPI void | ||
127 | eina_iterator_foreach(Eina_Iterator *iterator, | ||
128 | Eina_Each_Cb cb, | ||
129 | const void *fdata) | ||
130 | { | ||
131 | const void *container; | ||
132 | void *data; | ||
133 | |||
134 | EINA_MAGIC_CHECK_ITERATOR(iterator); | ||
135 | EINA_SAFETY_ON_NULL_RETURN(iterator); | ||
136 | EINA_SAFETY_ON_NULL_RETURN(iterator->get_container); | ||
137 | EINA_SAFETY_ON_NULL_RETURN(iterator->next); | ||
138 | EINA_SAFETY_ON_NULL_RETURN(cb); | ||
139 | |||
140 | if (!eina_iterator_lock(iterator)) return ; | ||
141 | |||
142 | container = iterator->get_container(iterator); | ||
143 | while (iterator->next(iterator, &data) == EINA_TRUE) { | ||
144 | if (cb(container, data, (void *)fdata) != EINA_TRUE) | ||
145 | goto on_exit; | ||
146 | } | ||
147 | |||
148 | on_exit: | ||
149 | (void) eina_iterator_unlock(iterator); | ||
150 | } | ||
151 | |||
152 | EAPI Eina_Bool | ||
153 | eina_iterator_lock(Eina_Iterator *iterator) | ||
154 | { | ||
155 | EINA_MAGIC_CHECK_ITERATOR(iterator); | ||
156 | EINA_SAFETY_ON_NULL_RETURN_VAL(iterator, EINA_FALSE); | ||
157 | |||
158 | if (iterator->lock) | ||
159 | return iterator->lock(iterator); | ||
160 | return EINA_TRUE; | ||
161 | } | ||
162 | |||
163 | EAPI Eina_Bool | ||
164 | eina_iterator_unlock(Eina_Iterator *iterator) | ||
165 | { | ||
166 | EINA_MAGIC_CHECK_ITERATOR(iterator); | ||
167 | EINA_SAFETY_ON_NULL_RETURN_VAL(iterator, EINA_FALSE); | ||
168 | |||
169 | if (iterator->unlock) | ||
170 | return iterator->unlock(iterator); | ||
171 | return EINA_TRUE; | ||
172 | } | ||
diff --git a/libraries/eina/src/lib/eina_lalloc.c b/libraries/eina/src/lib/eina_lalloc.c deleted file mode 100644 index b1e62b7..0000000 --- a/libraries/eina/src/lib/eina_lalloc.c +++ /dev/null | |||
@@ -1,158 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2007-2008 Jorge Luis Zapata Muga | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdlib.h> | ||
24 | |||
25 | #include "eina_config.h" | ||
26 | #include "eina_private.h" | ||
27 | |||
28 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
29 | #include "eina_safety_checks.h" | ||
30 | #include "eina_lalloc.h" | ||
31 | |||
32 | /*============================================================================* | ||
33 | * Local * | ||
34 | *============================================================================*/ | ||
35 | |||
36 | /** | ||
37 | * @cond LOCAL | ||
38 | */ | ||
39 | |||
40 | struct _Eina_Lalloc | ||
41 | { | ||
42 | void *data; | ||
43 | int num_allocated; | ||
44 | int num_elements; | ||
45 | int acc; | ||
46 | Eina_Lalloc_Alloc alloc_cb; | ||
47 | Eina_Lalloc_Free free_cb; | ||
48 | }; | ||
49 | |||
50 | /** | ||
51 | * @endcond | ||
52 | */ | ||
53 | |||
54 | /*============================================================================* | ||
55 | * Global * | ||
56 | *============================================================================*/ | ||
57 | |||
58 | /*============================================================================* | ||
59 | * API * | ||
60 | *============================================================================*/ | ||
61 | |||
62 | /** | ||
63 | * @addtogroup Eina_Lalloc_Group Lazy allocator | ||
64 | * | ||
65 | * @{ | ||
66 | */ | ||
67 | |||
68 | EAPI Eina_Lalloc *eina_lalloc_new(void *data, | ||
69 | Eina_Lalloc_Alloc alloc_cb, | ||
70 | Eina_Lalloc_Free free_cb, | ||
71 | int num_init) | ||
72 | { | ||
73 | Eina_Lalloc *a; | ||
74 | |||
75 | EINA_SAFETY_ON_NULL_RETURN_VAL(alloc_cb, NULL); | ||
76 | EINA_SAFETY_ON_NULL_RETURN_VAL(free_cb, NULL); | ||
77 | |||
78 | a = calloc(1, sizeof(Eina_Lalloc)); | ||
79 | a->data = data; | ||
80 | a->alloc_cb = alloc_cb; | ||
81 | a->free_cb = free_cb; | ||
82 | if (num_init > 0) | ||
83 | { | ||
84 | a->num_allocated = num_init; | ||
85 | a->alloc_cb(a->data, a->num_allocated); | ||
86 | } | ||
87 | |||
88 | return a; | ||
89 | } | ||
90 | |||
91 | EAPI void eina_lalloc_free(Eina_Lalloc *a) | ||
92 | { | ||
93 | EINA_SAFETY_ON_NULL_RETURN(a); | ||
94 | EINA_SAFETY_ON_NULL_RETURN(a->free_cb); | ||
95 | a->free_cb(a->data); | ||
96 | free(a); | ||
97 | } | ||
98 | |||
99 | EAPI Eina_Bool eina_lalloc_element_add(Eina_Lalloc *a) | ||
100 | { | ||
101 | EINA_SAFETY_ON_NULL_RETURN_VAL(a, EINA_FALSE); | ||
102 | EINA_SAFETY_ON_NULL_RETURN_VAL(a->alloc_cb, EINA_FALSE); | ||
103 | |||
104 | if (a->num_elements == a->num_allocated) | ||
105 | { | ||
106 | if (a->alloc_cb(a->data, (1 << a->acc)) == EINA_TRUE) | ||
107 | { | ||
108 | a->num_allocated = (1 << a->acc); | ||
109 | a->acc++; | ||
110 | } | ||
111 | else | ||
112 | return EINA_FALSE; | ||
113 | } | ||
114 | |||
115 | a->num_elements++; | ||
116 | |||
117 | return EINA_TRUE; | ||
118 | } | ||
119 | |||
120 | EAPI Eina_Bool eina_lalloc_elements_add(Eina_Lalloc *a, int num) | ||
121 | { | ||
122 | int tmp; | ||
123 | |||
124 | EINA_SAFETY_ON_NULL_RETURN_VAL(a, EINA_FALSE); | ||
125 | EINA_SAFETY_ON_NULL_RETURN_VAL(a->alloc_cb, EINA_FALSE); | ||
126 | |||
127 | tmp = a->num_elements + num; | ||
128 | if (tmp > a->num_allocated) | ||
129 | { | ||
130 | int allocated; | ||
131 | int acc; | ||
132 | |||
133 | allocated = a->num_allocated; | ||
134 | acc = a->acc; | ||
135 | |||
136 | while (tmp > allocated) | ||
137 | { | ||
138 | allocated = (1 << acc); | ||
139 | acc++; | ||
140 | } | ||
141 | |||
142 | if (a->alloc_cb(a->data, allocated) == EINA_TRUE) | ||
143 | { | ||
144 | a->num_allocated = allocated; | ||
145 | a->acc = acc; | ||
146 | } | ||
147 | else | ||
148 | return EINA_FALSE; | ||
149 | } | ||
150 | |||
151 | a->num_elements += num; | ||
152 | |||
153 | return EINA_TRUE; | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * @} | ||
158 | */ | ||
diff --git a/libraries/eina/src/lib/eina_list.c b/libraries/eina/src/lib/eina_list.c deleted file mode 100644 index c85855f..0000000 --- a/libraries/eina/src/lib/eina_list.c +++ /dev/null | |||
@@ -1,1491 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2002-2008 Carsten Haitzler, Gustavo Sverzut Barbieri, Tilman Sauerbeck, | ||
3 | * Vincent Torri, Cedric Bail, Jorge Luis Zapata Muga, | ||
4 | * Corey Donohoe, Arnaud de Turckheim, Alexandre Becoulet | ||
5 | * | ||
6 | * This library is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU Lesser General Public | ||
8 | * License as published by the Free Software Foundation; either | ||
9 | * version 2.1 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * This library is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * Lesser General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU Lesser General Public | ||
17 | * License along with this library; | ||
18 | * if not, see <http://www.gnu.org/licenses/>. | ||
19 | * | ||
20 | * This file incorporates work covered by the following copyright and | ||
21 | * permission notice: | ||
22 | * | ||
23 | * Copyright (C) 2004 ncn | ||
24 | * Copyright (C) 2006 Sebastian Dransfeld | ||
25 | * Copyright (C) 2007 Christopher Michael | ||
26 | * | ||
27 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
28 | * of this software and associated documentation files (the "Software"), to | ||
29 | * deal in the Software without restriction, including without limitation the | ||
30 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
31 | * sell copies of the Software, and to permit persons to whom the Software is | ||
32 | * furnished to do so, subject to the following conditions: | ||
33 | |||
34 | * The above copyright notice and this permission notice shall be included in | ||
35 | * all copies of the Software and its Copyright notices. In addition publicly | ||
36 | * documented acknowledgment must be given that this software has been used if no | ||
37 | * source code of this software is made available publicly. This includes | ||
38 | * acknowledgments in either Copyright notices, Manuals, Publicity and Marketing | ||
39 | * documents or any documentation provided with any product containing this | ||
40 | * software. This License does not apply to any software that links to the | ||
41 | * libraries provided by this software (statically or dynamically), but only to | ||
42 | * the software provided. | ||
43 | |||
44 | * Please see the OLD-COPYING.PLAIN for a plain-english explanation of this notice | ||
45 | * and it's intent. | ||
46 | |||
47 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
48 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
49 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
50 | * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
51 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
52 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
53 | */ | ||
54 | |||
55 | |||
56 | #ifdef HAVE_CONFIG_H | ||
57 | # include "config.h" | ||
58 | #endif | ||
59 | |||
60 | #include <stdlib.h> | ||
61 | #include <stdio.h> | ||
62 | #include <string.h> | ||
63 | |||
64 | #ifdef HAVE_EVIL | ||
65 | # include <Evil.h> | ||
66 | #endif | ||
67 | |||
68 | #include "eina_config.h" | ||
69 | #include "eina_private.h" | ||
70 | #include "eina_error.h" | ||
71 | #include "eina_log.h" | ||
72 | #include "eina_mempool.h" | ||
73 | |||
74 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
75 | #include "eina_safety_checks.h" | ||
76 | #include "eina_list.h" | ||
77 | |||
78 | |||
79 | /*============================================================================* | ||
80 | * Local * | ||
81 | *============================================================================*/ | ||
82 | |||
83 | /** | ||
84 | * @cond LOCAL | ||
85 | */ | ||
86 | |||
87 | static const char EINA_MAGIC_LIST_STR[] = "Eina List"; | ||
88 | static const char EINA_MAGIC_LIST_ITERATOR_STR[] = "Eina List Iterator"; | ||
89 | static const char EINA_MAGIC_LIST_ACCESSOR_STR[] = "Eina List Accessor"; | ||
90 | static const char EINA_MAGIC_LIST_ACCOUNTING_STR[] = "Eina List Accounting"; | ||
91 | |||
92 | |||
93 | #define EINA_MAGIC_CHECK_LIST(d, ...) \ | ||
94 | do { \ | ||
95 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_LIST)) \ | ||
96 | { \ | ||
97 | EINA_MAGIC_FAIL(d, EINA_MAGIC_LIST); \ | ||
98 | return __VA_ARGS__; \ | ||
99 | } \ | ||
100 | } while(0) | ||
101 | |||
102 | #define EINA_MAGIC_CHECK_LIST_ITERATOR(d, ...) \ | ||
103 | do { \ | ||
104 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_LIST_ITERATOR)) \ | ||
105 | { \ | ||
106 | EINA_MAGIC_FAIL(d, EINA_MAGIC_LIST_ITERATOR); \ | ||
107 | return __VA_ARGS__; \ | ||
108 | } \ | ||
109 | } while(0) | ||
110 | |||
111 | #define EINA_MAGIC_CHECK_LIST_ACCESSOR(d, ...) \ | ||
112 | do { \ | ||
113 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_LIST_ACCESSOR)) \ | ||
114 | { \ | ||
115 | EINA_MAGIC_FAIL(d, EINA_MAGIC_LIST_ACCESSOR); \ | ||
116 | return __VA_ARGS__; \ | ||
117 | } \ | ||
118 | } while(0) | ||
119 | |||
120 | #define EINA_MAGIC_CHECK_LIST_ACCOUNTING(d) \ | ||
121 | do { \ | ||
122 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_LIST_ACCOUNTING)) \ | ||
123 | { \ | ||
124 | EINA_MAGIC_FAIL(d, EINA_MAGIC_LIST_ACCOUNTING); \ | ||
125 | return; \ | ||
126 | } \ | ||
127 | } while(0) | ||
128 | |||
129 | #define EINA_LIST_SORT_STACK_SIZE 32 | ||
130 | |||
131 | typedef struct _Eina_Iterator_List Eina_Iterator_List; | ||
132 | typedef struct _Eina_Accessor_List Eina_Accessor_List; | ||
133 | |||
134 | struct _Eina_Iterator_List | ||
135 | { | ||
136 | Eina_Iterator iterator; | ||
137 | |||
138 | const Eina_List *head; | ||
139 | const Eina_List *current; | ||
140 | |||
141 | EINA_MAGIC | ||
142 | }; | ||
143 | |||
144 | struct _Eina_Accessor_List | ||
145 | { | ||
146 | Eina_Accessor accessor; | ||
147 | |||
148 | const Eina_List *head; | ||
149 | const Eina_List *current; | ||
150 | |||
151 | unsigned int index; | ||
152 | |||
153 | EINA_MAGIC | ||
154 | }; | ||
155 | |||
156 | static Eina_Mempool *_eina_list_mp = NULL; | ||
157 | static Eina_Mempool *_eina_list_accounting_mp = NULL; | ||
158 | static int _eina_list_log_dom = -1; | ||
159 | |||
160 | #ifdef ERR | ||
161 | #undef ERR | ||
162 | #endif | ||
163 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_list_log_dom, __VA_ARGS__) | ||
164 | |||
165 | #ifdef DBG | ||
166 | #undef DBG | ||
167 | #endif | ||
168 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_list_log_dom, __VA_ARGS__) | ||
169 | |||
170 | static inline Eina_List_Accounting * | ||
171 | _eina_list_mempool_accounting_new(__UNUSED__ Eina_List *list) | ||
172 | { | ||
173 | Eina_List_Accounting *tmp; | ||
174 | |||
175 | tmp = | ||
176 | eina_mempool_malloc(_eina_list_accounting_mp, | ||
177 | sizeof (Eina_List_Accounting)); | ||
178 | if (!tmp) | ||
179 | return NULL; | ||
180 | |||
181 | EINA_MAGIC_SET(tmp, EINA_MAGIC_LIST_ACCOUNTING); | ||
182 | |||
183 | return tmp; | ||
184 | } | ||
185 | static inline void | ||
186 | _eina_list_mempool_accounting_free(Eina_List_Accounting *accounting) | ||
187 | { | ||
188 | EINA_MAGIC_CHECK_LIST_ACCOUNTING(accounting); | ||
189 | |||
190 | EINA_MAGIC_SET(accounting, EINA_MAGIC_NONE); | ||
191 | eina_mempool_free(_eina_list_accounting_mp, accounting); | ||
192 | } | ||
193 | |||
194 | static inline Eina_List * | ||
195 | _eina_list_mempool_list_new(__UNUSED__ Eina_List *list) | ||
196 | { | ||
197 | Eina_List *tmp; | ||
198 | |||
199 | tmp = eina_mempool_malloc(_eina_list_mp, sizeof (Eina_List)); | ||
200 | if (!tmp) | ||
201 | return NULL; | ||
202 | |||
203 | EINA_MAGIC_SET(tmp, EINA_MAGIC_LIST); | ||
204 | |||
205 | return tmp; | ||
206 | } | ||
207 | static inline void | ||
208 | _eina_list_mempool_list_free(Eina_List *list) | ||
209 | { | ||
210 | EINA_MAGIC_CHECK_LIST(list); | ||
211 | |||
212 | list->accounting->count--; | ||
213 | if (list->accounting->count == 0) | ||
214 | _eina_list_mempool_accounting_free(list->accounting); | ||
215 | |||
216 | EINA_MAGIC_SET(list, EINA_MAGIC_NONE); | ||
217 | eina_mempool_free(_eina_list_mp, list); | ||
218 | } | ||
219 | |||
220 | static Eina_List * | ||
221 | _eina_list_setup_accounting(Eina_List *list) | ||
222 | { | ||
223 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
224 | |||
225 | list->accounting = _eina_list_mempool_accounting_new(list); | ||
226 | if (!list->accounting) | ||
227 | goto on_error; | ||
228 | |||
229 | list->accounting->last = list; | ||
230 | list->accounting->count = 1; | ||
231 | |||
232 | return list; | ||
233 | |||
234 | on_error: | ||
235 | _eina_list_mempool_list_free(list); | ||
236 | return NULL; | ||
237 | } | ||
238 | |||
239 | static inline void | ||
240 | _eina_list_update_accounting(Eina_List *list, Eina_List *new_list) | ||
241 | { | ||
242 | EINA_MAGIC_CHECK_LIST(list); | ||
243 | EINA_MAGIC_CHECK_LIST(new_list); | ||
244 | |||
245 | list->accounting->count++; | ||
246 | new_list->accounting = list->accounting; | ||
247 | } | ||
248 | |||
249 | #if 0 | ||
250 | static Eina_Mempool2 _eina_list_mempool = | ||
251 | { | ||
252 | sizeof(Eina_List), | ||
253 | 320, | ||
254 | 0, NULL, NULL | ||
255 | }; | ||
256 | static Eina_Mempool2 _eina_list_accounting_mempool = | ||
257 | { | ||
258 | sizeof(Eina_List_Accounting), | ||
259 | 80, | ||
260 | 0, NULL, NULL | ||
261 | }; | ||
262 | #endif | ||
263 | |||
264 | static Eina_Bool | ||
265 | eina_list_iterator_next(Eina_Iterator_List *it, void **data) | ||
266 | { | ||
267 | EINA_MAGIC_CHECK_LIST_ITERATOR(it, EINA_FALSE); | ||
268 | |||
269 | if (!it->current) | ||
270 | return EINA_FALSE; | ||
271 | |||
272 | *data = eina_list_data_get(it->current); | ||
273 | |||
274 | it->current = eina_list_next(it->current); | ||
275 | |||
276 | return EINA_TRUE; | ||
277 | } | ||
278 | |||
279 | static Eina_Bool | ||
280 | eina_list_iterator_prev(Eina_Iterator_List *it, void **data) | ||
281 | { | ||
282 | EINA_MAGIC_CHECK_LIST_ITERATOR(it, EINA_FALSE); | ||
283 | |||
284 | if (!it->current) | ||
285 | return EINA_FALSE; | ||
286 | |||
287 | *data = eina_list_data_get(it->current); | ||
288 | |||
289 | it->current = eina_list_prev(it->current); | ||
290 | |||
291 | return EINA_TRUE; | ||
292 | } | ||
293 | |||
294 | static Eina_List * | ||
295 | eina_list_iterator_get_container(Eina_Iterator_List *it) | ||
296 | { | ||
297 | EINA_MAGIC_CHECK_LIST_ITERATOR(it, NULL); | ||
298 | |||
299 | return (Eina_List *)it->head; | ||
300 | } | ||
301 | |||
302 | static void | ||
303 | eina_list_iterator_free(Eina_Iterator_List *it) | ||
304 | { | ||
305 | EINA_MAGIC_CHECK_LIST_ITERATOR(it); | ||
306 | |||
307 | MAGIC_FREE(it); | ||
308 | } | ||
309 | |||
310 | static Eina_Bool | ||
311 | eina_list_accessor_get_at(Eina_Accessor_List *it, unsigned int idx, void **data) | ||
312 | { | ||
313 | const Eina_List *over; | ||
314 | unsigned int middle; | ||
315 | unsigned int i; | ||
316 | |||
317 | EINA_MAGIC_CHECK_LIST_ACCESSOR(it, EINA_FALSE); | ||
318 | |||
319 | if (idx >= eina_list_count(it->head)) | ||
320 | return EINA_FALSE; | ||
321 | |||
322 | if (it->index == idx) | ||
323 | over = it->current; | ||
324 | else if (idx > it->index) | ||
325 | { | ||
326 | /* After current position. */ | ||
327 | middle = ((eina_list_count(it->head) - it->index) >> 1) + it->index; | ||
328 | |||
329 | if (idx > middle) | ||
330 | /* Go backward from the end. */ | ||
331 | for (i = eina_list_count(it->head) - 1, | ||
332 | over = eina_list_last(it->head); | ||
333 | i > idx && over; | ||
334 | --i, over = eina_list_prev(over)) | ||
335 | ; | ||
336 | else | ||
337 | /* Go forward from current. */ | ||
338 | for (i = it->index, over = it->current; | ||
339 | i < idx && over; | ||
340 | ++i, over = eina_list_next(over)) | ||
341 | ; | ||
342 | } | ||
343 | else | ||
344 | { | ||
345 | /* Before current position. */ | ||
346 | middle = it->index >> 1; | ||
347 | |||
348 | if (idx > middle) | ||
349 | /* Go backward from current. */ | ||
350 | for (i = it->index, over = it->current; | ||
351 | i > idx && over; | ||
352 | --i, over = eina_list_prev(over)) | ||
353 | ; | ||
354 | else | ||
355 | /* Go forward from start. */ | ||
356 | for (i = 0, over = it->head; | ||
357 | i < idx && over; | ||
358 | ++i, over = eina_list_next(over)) | ||
359 | ; | ||
360 | } | ||
361 | |||
362 | if (!over) | ||
363 | return EINA_FALSE; | ||
364 | |||
365 | it->current = over; | ||
366 | it->index = idx; | ||
367 | |||
368 | *data = eina_list_data_get(it->current); | ||
369 | return EINA_TRUE; | ||
370 | } | ||
371 | |||
372 | static Eina_List * | ||
373 | eina_list_accessor_get_container(Eina_Accessor_List *it) | ||
374 | { | ||
375 | EINA_MAGIC_CHECK_LIST_ACCESSOR(it, NULL); | ||
376 | |||
377 | return (Eina_List *)it->head; | ||
378 | } | ||
379 | |||
380 | static void | ||
381 | eina_list_accessor_free(Eina_Accessor_List *it) | ||
382 | { | ||
383 | EINA_MAGIC_CHECK_LIST_ACCESSOR(it); | ||
384 | |||
385 | MAGIC_FREE(it); | ||
386 | } | ||
387 | |||
388 | static Eina_List * | ||
389 | eina_list_sort_rebuild_prev(Eina_List *list) | ||
390 | { | ||
391 | Eina_List *prev = NULL; | ||
392 | |||
393 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
394 | |||
395 | for (; list; list = list->next) | ||
396 | { | ||
397 | list->prev = prev; | ||
398 | prev = list; | ||
399 | } | ||
400 | |||
401 | return prev; | ||
402 | } | ||
403 | |||
404 | static Eina_List * | ||
405 | eina_list_sort_merge(Eina_List *a, Eina_List *b, Eina_Compare_Cb func) | ||
406 | { | ||
407 | Eina_List *first, *last; | ||
408 | |||
409 | if (func(a->data, b->data) < 0) | ||
410 | a = (last = first = a)->next; | ||
411 | else | ||
412 | b = (last = first = b)->next; | ||
413 | |||
414 | while (a && b) | ||
415 | if (func(a->data, b->data) < 0) | ||
416 | a = (last = last->next = a)->next; | ||
417 | else | ||
418 | b = (last = last->next = b)->next; | ||
419 | |||
420 | last->next = a ? a : b; | ||
421 | |||
422 | return first; | ||
423 | } | ||
424 | |||
425 | /** | ||
426 | * @endcond | ||
427 | */ | ||
428 | |||
429 | /*============================================================================* | ||
430 | * Global * | ||
431 | *============================================================================*/ | ||
432 | |||
433 | /** | ||
434 | * @internal | ||
435 | * @brief Initialize the list module. | ||
436 | * | ||
437 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
438 | * | ||
439 | * This function sets up the list module of Eina. It is called by | ||
440 | * eina_init(). | ||
441 | * | ||
442 | * This function creates mempool to speed up list node and accounting | ||
443 | * management, using EINA_MEMPOOL environment variable if it is set to | ||
444 | * choose the memory pool type to use. | ||
445 | * | ||
446 | * @see eina_init() | ||
447 | */ | ||
448 | Eina_Bool | ||
449 | eina_list_init(void) | ||
450 | { | ||
451 | const char *choice, *tmp; | ||
452 | |||
453 | _eina_list_log_dom = eina_log_domain_register("eina_list", | ||
454 | EINA_LOG_COLOR_DEFAULT); | ||
455 | if (_eina_list_log_dom < 0) | ||
456 | { | ||
457 | EINA_LOG_ERR("Could not register log domain: eina_list"); | ||
458 | return EINA_FALSE; | ||
459 | } | ||
460 | |||
461 | #ifdef EINA_DEFAULT_MEMPOOL | ||
462 | choice = "pass_through"; | ||
463 | #else | ||
464 | choice = "chained_mempool"; | ||
465 | #endif | ||
466 | tmp = getenv("EINA_MEMPOOL"); | ||
467 | if (tmp && tmp[0]) | ||
468 | choice = tmp; | ||
469 | |||
470 | _eina_list_mp = eina_mempool_add | ||
471 | (choice, "list", NULL, sizeof(Eina_List), 320); | ||
472 | if (!_eina_list_mp) | ||
473 | { | ||
474 | ERR("ERROR: Mempool for list cannot be allocated in list init."); | ||
475 | goto on_init_fail; | ||
476 | } | ||
477 | |||
478 | _eina_list_accounting_mp = eina_mempool_add | ||
479 | (choice, "list_accounting", NULL, sizeof(Eina_List_Accounting), 80); | ||
480 | if (!_eina_list_accounting_mp) | ||
481 | { | ||
482 | ERR( | ||
483 | "ERROR: Mempool for list accounting cannot be allocated in list init."); | ||
484 | eina_mempool_del(_eina_list_mp); | ||
485 | goto on_init_fail; | ||
486 | } | ||
487 | |||
488 | #define EMS(n) eina_magic_string_static_set(n, n ## _STR) | ||
489 | EMS(EINA_MAGIC_LIST); | ||
490 | EMS(EINA_MAGIC_LIST_ITERATOR); | ||
491 | EMS(EINA_MAGIC_LIST_ACCESSOR); | ||
492 | EMS(EINA_MAGIC_LIST_ACCOUNTING); | ||
493 | #undef EMS | ||
494 | |||
495 | return EINA_TRUE; | ||
496 | |||
497 | on_init_fail: | ||
498 | eina_log_domain_unregister(_eina_list_log_dom); | ||
499 | _eina_list_log_dom = -1; | ||
500 | return EINA_FALSE; | ||
501 | } | ||
502 | |||
503 | /** | ||
504 | * @internal | ||
505 | * @brief Shut down the list module. | ||
506 | * | ||
507 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
508 | * | ||
509 | * This function shuts down the list module set up by | ||
510 | * eina_list_init(). It is called by eina_shutdown(). | ||
511 | * | ||
512 | * @see eina_shutdown() | ||
513 | */ | ||
514 | Eina_Bool | ||
515 | eina_list_shutdown(void) | ||
516 | { | ||
517 | eina_mempool_del(_eina_list_accounting_mp); | ||
518 | eina_mempool_del(_eina_list_mp); | ||
519 | |||
520 | eina_log_domain_unregister(_eina_list_log_dom); | ||
521 | _eina_list_log_dom = -1; | ||
522 | return EINA_TRUE; | ||
523 | } | ||
524 | |||
525 | /*============================================================================* | ||
526 | * API * | ||
527 | *============================================================================*/ | ||
528 | |||
529 | EAPI Eina_List * | ||
530 | eina_list_append(Eina_List *list, const void *data) | ||
531 | { | ||
532 | Eina_List *l, *new_l; | ||
533 | |||
534 | eina_error_set(0); | ||
535 | new_l = _eina_list_mempool_list_new(list); | ||
536 | if (!new_l) | ||
537 | return list; | ||
538 | |||
539 | new_l->next = NULL; | ||
540 | new_l->data = (void *)data; | ||
541 | if (!list) | ||
542 | { | ||
543 | new_l->prev = NULL; | ||
544 | return _eina_list_setup_accounting(new_l); | ||
545 | } | ||
546 | |||
547 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
548 | |||
549 | l = list->accounting->last; | ||
550 | list->accounting->last = new_l; | ||
551 | |||
552 | l->next = new_l; | ||
553 | new_l->prev = l; | ||
554 | |||
555 | _eina_list_update_accounting(list, new_l); | ||
556 | return list; | ||
557 | } | ||
558 | |||
559 | EAPI Eina_List * | ||
560 | eina_list_prepend(Eina_List *list, const void *data) | ||
561 | { | ||
562 | Eina_List *new_l; | ||
563 | |||
564 | eina_error_set(0); | ||
565 | new_l = _eina_list_mempool_list_new(list); | ||
566 | if (!new_l) | ||
567 | return list; | ||
568 | |||
569 | new_l->prev = NULL; | ||
570 | new_l->next = list; | ||
571 | new_l->data = (void *)data; | ||
572 | |||
573 | if (!list) | ||
574 | return _eina_list_setup_accounting(new_l); | ||
575 | |||
576 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
577 | |||
578 | list->prev = new_l; | ||
579 | |||
580 | _eina_list_update_accounting(list, new_l); | ||
581 | |||
582 | return new_l; | ||
583 | } | ||
584 | |||
585 | EAPI Eina_List * | ||
586 | eina_list_append_relative(Eina_List *list, | ||
587 | const void *data, | ||
588 | const void *relative) | ||
589 | { | ||
590 | Eina_List *l; | ||
591 | void *list_data; | ||
592 | |||
593 | if (list) | ||
594 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
595 | |||
596 | EINA_LIST_FOREACH(list, l, list_data) | ||
597 | { | ||
598 | if (list_data == relative) | ||
599 | return eina_list_append_relative_list(list, data, l); | ||
600 | } | ||
601 | |||
602 | return eina_list_append(list, data); | ||
603 | } | ||
604 | |||
605 | EAPI Eina_List * | ||
606 | eina_list_append_relative_list(Eina_List *list, | ||
607 | const void *data, | ||
608 | Eina_List *relative) | ||
609 | { | ||
610 | Eina_List *new_l; | ||
611 | |||
612 | if ((!list) || (!relative)) | ||
613 | return eina_list_append(list, data); | ||
614 | |||
615 | eina_error_set(0); | ||
616 | new_l = _eina_list_mempool_list_new(list); | ||
617 | if (!new_l) | ||
618 | return list; | ||
619 | |||
620 | EINA_MAGIC_CHECK_LIST(relative, NULL); | ||
621 | new_l->next = relative->next; | ||
622 | new_l->data = (void *)data; | ||
623 | |||
624 | if (relative->next) | ||
625 | relative->next->prev = new_l; | ||
626 | |||
627 | relative->next = new_l; | ||
628 | new_l->prev = relative; | ||
629 | |||
630 | _eina_list_update_accounting(list, new_l); | ||
631 | |||
632 | if (!new_l->next) | ||
633 | new_l->accounting->last = new_l; | ||
634 | |||
635 | return list; | ||
636 | } | ||
637 | |||
638 | EAPI Eina_List * | ||
639 | eina_list_prepend_relative(Eina_List *list, | ||
640 | const void *data, | ||
641 | const void *relative) | ||
642 | { | ||
643 | Eina_List *l; | ||
644 | void *list_data; | ||
645 | |||
646 | if (list) | ||
647 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
648 | |||
649 | EINA_LIST_FOREACH(list, l, list_data) | ||
650 | { | ||
651 | if (list_data == relative) | ||
652 | return eina_list_prepend_relative_list(list, data, l); | ||
653 | } | ||
654 | return eina_list_prepend(list, data); | ||
655 | } | ||
656 | |||
657 | EAPI Eina_List * | ||
658 | eina_list_prepend_relative_list(Eina_List *list, | ||
659 | const void *data, | ||
660 | Eina_List *relative) | ||
661 | { | ||
662 | Eina_List *new_l; | ||
663 | |||
664 | if ((!list) || (!relative)) | ||
665 | return eina_list_prepend(list, data); | ||
666 | |||
667 | eina_error_set(0); | ||
668 | new_l = _eina_list_mempool_list_new(list); | ||
669 | if (!new_l) | ||
670 | return list; | ||
671 | |||
672 | EINA_MAGIC_CHECK_LIST(relative, NULL); | ||
673 | |||
674 | new_l->prev = relative->prev; | ||
675 | new_l->next = relative; | ||
676 | new_l->data = (void *)data; | ||
677 | |||
678 | if (relative->prev) | ||
679 | relative->prev->next = new_l; | ||
680 | |||
681 | relative->prev = new_l; | ||
682 | |||
683 | _eina_list_update_accounting(list, new_l); | ||
684 | |||
685 | if (new_l->prev) | ||
686 | return list; | ||
687 | |||
688 | return new_l; | ||
689 | } | ||
690 | |||
691 | EAPI Eina_List * | ||
692 | eina_list_sorted_insert(Eina_List *list, Eina_Compare_Cb func, const void *data) | ||
693 | { | ||
694 | Eina_List *lnear; | ||
695 | int cmp; | ||
696 | |||
697 | if (!list) | ||
698 | return eina_list_append(NULL, data); | ||
699 | |||
700 | lnear = eina_list_search_sorted_near_list(list, func, data, &cmp); | ||
701 | if (cmp < 0) | ||
702 | return eina_list_append_relative_list(list, data, lnear); | ||
703 | else | ||
704 | return eina_list_prepend_relative_list(list, data, lnear); | ||
705 | } | ||
706 | |||
707 | EAPI Eina_List * | ||
708 | eina_list_remove(Eina_List *list, const void *data) | ||
709 | { | ||
710 | Eina_List *l; | ||
711 | |||
712 | if (list) | ||
713 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
714 | |||
715 | l = eina_list_data_find_list(list, data); | ||
716 | return eina_list_remove_list(list, l); | ||
717 | } | ||
718 | |||
719 | EAPI Eina_List * | ||
720 | eina_list_remove_list(Eina_List *list, Eina_List *remove_list) | ||
721 | { | ||
722 | Eina_List *return_l; | ||
723 | |||
724 | if (!list) | ||
725 | return NULL; | ||
726 | |||
727 | if (!remove_list) | ||
728 | return list; | ||
729 | |||
730 | EINA_MAGIC_CHECK_LIST(remove_list, NULL); | ||
731 | |||
732 | if (remove_list->next) | ||
733 | remove_list->next->prev = remove_list->prev; | ||
734 | |||
735 | if (remove_list->prev) | ||
736 | { | ||
737 | remove_list->prev->next = remove_list->next; | ||
738 | return_l = list; | ||
739 | } | ||
740 | else | ||
741 | return_l = remove_list->next; | ||
742 | |||
743 | if (remove_list == remove_list->accounting->last) | ||
744 | { | ||
745 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
746 | list->accounting->last = remove_list->prev; | ||
747 | } | ||
748 | |||
749 | _eina_list_mempool_list_free(remove_list); | ||
750 | return return_l; | ||
751 | } | ||
752 | |||
753 | EAPI Eina_List * | ||
754 | eina_list_free(Eina_List *list) | ||
755 | { | ||
756 | Eina_List *l, *free_l; | ||
757 | |||
758 | if (!list) | ||
759 | return NULL; | ||
760 | |||
761 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
762 | |||
763 | for (l = list; l; ) | ||
764 | { | ||
765 | free_l = l; | ||
766 | l = l->next; | ||
767 | |||
768 | _eina_list_mempool_list_free(free_l); | ||
769 | } | ||
770 | |||
771 | return NULL; | ||
772 | } | ||
773 | |||
774 | EAPI Eina_List * | ||
775 | eina_list_promote_list(Eina_List *list, Eina_List *move_list) | ||
776 | { | ||
777 | if (!list) | ||
778 | return NULL; | ||
779 | |||
780 | if (!move_list) | ||
781 | { | ||
782 | return list; /* Promoting head to be head. */ | ||
783 | |||
784 | } | ||
785 | |||
786 | if (move_list == list) | ||
787 | return list; | ||
788 | |||
789 | if (move_list->next == list) | ||
790 | return move_list; | ||
791 | |||
792 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
793 | EINA_MAGIC_CHECK_LIST(move_list, NULL); | ||
794 | |||
795 | /* Remove the promoted item from the list. */ | ||
796 | if (!move_list->prev) | ||
797 | move_list->next->prev = NULL; | ||
798 | else | ||
799 | { | ||
800 | move_list->prev->next = move_list->next; | ||
801 | if (move_list == list->accounting->last) | ||
802 | list->accounting->last = move_list->prev; | ||
803 | else | ||
804 | move_list->next->prev = move_list->prev; | ||
805 | } | ||
806 | |||
807 | /* Add the promoted item in the list. */ | ||
808 | move_list->next = list; | ||
809 | move_list->prev = list->prev; | ||
810 | list->prev = move_list; | ||
811 | if (move_list->prev) | ||
812 | move_list->prev->next = move_list; | ||
813 | |||
814 | return move_list; | ||
815 | } | ||
816 | |||
817 | EAPI Eina_List * | ||
818 | eina_list_demote_list(Eina_List *list, Eina_List *move_list) | ||
819 | { | ||
820 | if (!list) | ||
821 | return NULL; | ||
822 | |||
823 | if (!move_list) | ||
824 | { | ||
825 | return list; /* Demoting tail to be tail. */ | ||
826 | |||
827 | } | ||
828 | |||
829 | if (move_list == list->accounting->last) | ||
830 | return list; | ||
831 | |||
832 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
833 | EINA_MAGIC_CHECK_LIST(move_list, NULL); | ||
834 | |||
835 | /* Update pointer list if necessary. */ | ||
836 | if (list == move_list) | ||
837 | { | ||
838 | list = move_list->next; /* Remove the demoted item from the list. */ | ||
839 | |||
840 | } | ||
841 | |||
842 | if (move_list->prev) | ||
843 | move_list->prev->next = move_list->next; | ||
844 | |||
845 | move_list->next->prev = move_list->prev; | ||
846 | /* Add the demoted item in the list. */ | ||
847 | move_list->prev = list->accounting->last; | ||
848 | move_list->prev->next = move_list; | ||
849 | move_list->next = NULL; | ||
850 | list->accounting->last = move_list; | ||
851 | |||
852 | return list; | ||
853 | } | ||
854 | |||
855 | EAPI void * | ||
856 | eina_list_data_find(const Eina_List *list, const void *data) | ||
857 | { | ||
858 | if (eina_list_data_find_list(list, data)) | ||
859 | return (void *)data; | ||
860 | |||
861 | return NULL; | ||
862 | } | ||
863 | |||
864 | EAPI Eina_Bool | ||
865 | eina_list_move(Eina_List **to, Eina_List **from, void *data) | ||
866 | { | ||
867 | Eina_List *l; | ||
868 | |||
869 | EINA_SAFETY_ON_NULL_RETURN_VAL(to, EINA_FALSE); | ||
870 | EINA_SAFETY_ON_NULL_RETURN_VAL(from, EINA_FALSE); | ||
871 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); | ||
872 | |||
873 | if (*to) EINA_MAGIC_CHECK_LIST(*to, EINA_FALSE); | ||
874 | EINA_MAGIC_CHECK_LIST(*from, EINA_FALSE); | ||
875 | |||
876 | l = eina_list_data_find_list(*from, data); | ||
877 | EINA_SAFETY_ON_NULL_RETURN_VAL(l, EINA_FALSE); | ||
878 | |||
879 | *to = eina_list_append(*to, data); | ||
880 | *from = eina_list_remove_list(*from, l); | ||
881 | return EINA_TRUE; | ||
882 | } | ||
883 | |||
884 | EAPI Eina_Bool | ||
885 | eina_list_move_list(Eina_List **to, Eina_List **from, Eina_List *data) | ||
886 | { | ||
887 | EINA_SAFETY_ON_NULL_RETURN_VAL(to, EINA_FALSE); | ||
888 | EINA_SAFETY_ON_NULL_RETURN_VAL(from, EINA_FALSE); | ||
889 | |||
890 | if (*to) EINA_MAGIC_CHECK_LIST(*to, EINA_FALSE); | ||
891 | EINA_MAGIC_CHECK_LIST(*from, EINA_FALSE); | ||
892 | EINA_MAGIC_CHECK_LIST(data, EINA_FALSE); | ||
893 | |||
894 | *to = eina_list_append(*to, data->data); | ||
895 | *from = eina_list_remove_list(*from, data); | ||
896 | return EINA_TRUE; | ||
897 | } | ||
898 | |||
899 | EAPI Eina_List * | ||
900 | eina_list_data_find_list(const Eina_List *list, const void *data) | ||
901 | { | ||
902 | const Eina_List *l; | ||
903 | void *list_data; | ||
904 | |||
905 | if (list) | ||
906 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
907 | |||
908 | EINA_LIST_FOREACH(list, l, list_data) | ||
909 | { | ||
910 | if (list_data == data) | ||
911 | return (Eina_List *)l; | ||
912 | } | ||
913 | |||
914 | return NULL; | ||
915 | } | ||
916 | |||
917 | EAPI void * | ||
918 | eina_list_nth(const Eina_List *list, unsigned int n) | ||
919 | { | ||
920 | Eina_List *l; | ||
921 | |||
922 | l = eina_list_nth_list(list, n); | ||
923 | return l ? l->data : NULL; | ||
924 | } | ||
925 | |||
926 | EAPI Eina_List * | ||
927 | eina_list_nth_list(const Eina_List *list, unsigned int n) | ||
928 | { | ||
929 | const Eina_List *l; | ||
930 | unsigned int i; | ||
931 | |||
932 | if (list) | ||
933 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
934 | |||
935 | /* check for non-existing nodes */ | ||
936 | if ((!list) || (n > (list->accounting->count - 1))) | ||
937 | return NULL; | ||
938 | |||
939 | /* if the node is in the 2nd half of the list, search from the end | ||
940 | * else, search from the beginning. | ||
941 | */ | ||
942 | if (n > (list->accounting->count / 2)) | ||
943 | for (i = list->accounting->count - 1, | ||
944 | l = list->accounting->last; | ||
945 | l; | ||
946 | l = l->prev, i--) | ||
947 | { | ||
948 | if (i == n) | ||
949 | return (Eina_List *)l; | ||
950 | } | ||
951 | else | ||
952 | for (i = 0, l = list; l; l = l->next, i++) | ||
953 | { | ||
954 | if (i == n) | ||
955 | return (Eina_List *)l; | ||
956 | } | ||
957 | |||
958 | abort(); | ||
959 | } | ||
960 | |||
961 | EAPI Eina_List * | ||
962 | eina_list_reverse(Eina_List *list) | ||
963 | { | ||
964 | Eina_List *l1, *l2; | ||
965 | |||
966 | if (!list) | ||
967 | return NULL; | ||
968 | |||
969 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
970 | |||
971 | l1 = list; | ||
972 | l2 = list->accounting->last; | ||
973 | while (l1 != l2) | ||
974 | { | ||
975 | void *data; | ||
976 | |||
977 | data = l1->data; | ||
978 | l1->data = l2->data; | ||
979 | l2->data = data; | ||
980 | l1 = l1->next; | ||
981 | if (l1 == l2) | ||
982 | break; | ||
983 | |||
984 | l2 = l2->prev; | ||
985 | } | ||
986 | |||
987 | return list; | ||
988 | } | ||
989 | |||
990 | EAPI Eina_List * | ||
991 | eina_list_reverse_clone(const Eina_List *list) | ||
992 | { | ||
993 | const Eina_List *l; | ||
994 | Eina_List *lclone; | ||
995 | void *data; | ||
996 | |||
997 | if (!list) | ||
998 | return NULL; | ||
999 | |||
1000 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
1001 | |||
1002 | lclone = NULL; | ||
1003 | EINA_LIST_FOREACH(list, l, data) | ||
1004 | lclone = eina_list_prepend(lclone, data); | ||
1005 | |||
1006 | return lclone; | ||
1007 | } | ||
1008 | |||
1009 | EAPI Eina_List * | ||
1010 | eina_list_clone(const Eina_List *list) | ||
1011 | { | ||
1012 | const Eina_List *l; | ||
1013 | Eina_List *lclone; | ||
1014 | void *data; | ||
1015 | |||
1016 | if (!list) | ||
1017 | return NULL; | ||
1018 | |||
1019 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
1020 | |||
1021 | lclone = NULL; | ||
1022 | EINA_LIST_FOREACH(list, l, data) | ||
1023 | lclone = eina_list_append(lclone, data); | ||
1024 | |||
1025 | return lclone; | ||
1026 | } | ||
1027 | |||
1028 | EAPI Eina_List * | ||
1029 | eina_list_sort(Eina_List *list, unsigned int limit, Eina_Compare_Cb func) | ||
1030 | { | ||
1031 | unsigned int i = 0; | ||
1032 | unsigned int n = 0; | ||
1033 | Eina_List *tail = list; | ||
1034 | Eina_List *unsort = NULL; | ||
1035 | Eina_List *stack[EINA_LIST_SORT_STACK_SIZE]; | ||
1036 | |||
1037 | EINA_SAFETY_ON_NULL_RETURN_VAL(func, list); | ||
1038 | if (!list) | ||
1039 | return NULL; | ||
1040 | |||
1041 | EINA_MAGIC_CHECK_LIST(list, NULL); | ||
1042 | |||
1043 | /* if the caller specified an invalid limit, sort the whole list */ | ||
1044 | if ((limit == 0) || | ||
1045 | (limit > list->accounting->count)) | ||
1046 | limit = list->accounting->count; | ||
1047 | |||
1048 | if (limit != list->accounting->count) | ||
1049 | { | ||
1050 | unsort = eina_list_nth_list(list, limit); | ||
1051 | if (unsort) | ||
1052 | unsort->prev->next = NULL; | ||
1053 | } | ||
1054 | |||
1055 | while (tail) | ||
1056 | { | ||
1057 | unsigned int idx, tmp; | ||
1058 | |||
1059 | Eina_List *a = tail; | ||
1060 | Eina_List *b = tail->next; | ||
1061 | |||
1062 | if (!b) | ||
1063 | { | ||
1064 | stack[i++] = a; | ||
1065 | break; | ||
1066 | } | ||
1067 | |||
1068 | tail = b->next; | ||
1069 | |||
1070 | if (func(a->data, b->data) < 0) | ||
1071 | ((stack[i++] = a)->next = b)->next = 0; | ||
1072 | else | ||
1073 | ((stack[i++] = b)->next = a)->next = 0; | ||
1074 | |||
1075 | tmp = n++; | ||
1076 | for (idx = n ^ tmp; idx &= idx - 1; i--) | ||
1077 | stack[i - 2] = eina_list_sort_merge(stack[i - 2], stack[i - 1], func); | ||
1078 | } | ||
1079 | |||
1080 | while (i-- > 1) | ||
1081 | stack[i - 1] = eina_list_sort_merge(stack[i - 1], stack[i], func); | ||
1082 | |||
1083 | list = stack[0]; | ||
1084 | tail = eina_list_sort_rebuild_prev(list); | ||
1085 | |||
1086 | if (unsort) | ||
1087 | { | ||
1088 | tail->next = unsort; | ||
1089 | unsort->prev = tail; | ||
1090 | } | ||
1091 | else | ||
1092 | list->accounting->last = tail; | ||
1093 | |||
1094 | return list; | ||
1095 | } | ||
1096 | |||
1097 | EAPI Eina_List * | ||
1098 | eina_list_merge(Eina_List *left, Eina_List *right) | ||
1099 | { | ||
1100 | unsigned int n_left, n_right; | ||
1101 | |||
1102 | if (!left) | ||
1103 | return right; | ||
1104 | |||
1105 | if (!right) | ||
1106 | return left; | ||
1107 | |||
1108 | left->accounting->last->next = right; | ||
1109 | right->prev = left->accounting->last; | ||
1110 | |||
1111 | n_left = left->accounting->count; | ||
1112 | n_right = right->accounting->count; | ||
1113 | |||
1114 | if (n_left >= n_right) | ||
1115 | { | ||
1116 | Eina_List *itr = right; | ||
1117 | left->accounting->last = right->accounting->last; | ||
1118 | left->accounting->count += n_right; | ||
1119 | |||
1120 | _eina_list_mempool_accounting_free(right->accounting); | ||
1121 | |||
1122 | do | ||
1123 | { | ||
1124 | itr->accounting = left->accounting; | ||
1125 | itr = itr->next; | ||
1126 | } | ||
1127 | while (itr); | ||
1128 | } | ||
1129 | else | ||
1130 | { | ||
1131 | Eina_List *itr = left->accounting->last; | ||
1132 | right->accounting->count += n_left; | ||
1133 | |||
1134 | _eina_list_mempool_accounting_free(left->accounting); | ||
1135 | |||
1136 | do | ||
1137 | { | ||
1138 | itr->accounting = right->accounting; | ||
1139 | itr = itr->prev; | ||
1140 | } | ||
1141 | while (itr); | ||
1142 | } | ||
1143 | |||
1144 | return left; | ||
1145 | } | ||
1146 | |||
1147 | |||
1148 | EAPI Eina_List * | ||
1149 | eina_list_split_list(Eina_List *list, Eina_List *relative, Eina_List **right) | ||
1150 | { | ||
1151 | Eina_List *next; | ||
1152 | Eina_List *itr; | ||
1153 | |||
1154 | if(!right) | ||
1155 | return list; | ||
1156 | |||
1157 | *right = NULL; | ||
1158 | |||
1159 | if (!list) | ||
1160 | return NULL; | ||
1161 | |||
1162 | if (!relative) | ||
1163 | { | ||
1164 | *right = list; | ||
1165 | return NULL; | ||
1166 | } | ||
1167 | |||
1168 | if (relative == eina_list_last(list)) | ||
1169 | return list; | ||
1170 | |||
1171 | next = eina_list_next(relative); | ||
1172 | next->prev = NULL; | ||
1173 | next->accounting = _eina_list_mempool_accounting_new(next); | ||
1174 | next->accounting->last = list->accounting->last; | ||
1175 | next->accounting->count = 0; | ||
1176 | *right = next; | ||
1177 | |||
1178 | itr = next; | ||
1179 | do | ||
1180 | { | ||
1181 | itr->accounting = next->accounting; | ||
1182 | next->accounting->count++; | ||
1183 | itr = itr->next; | ||
1184 | } | ||
1185 | while (itr); | ||
1186 | |||
1187 | relative->next = NULL; | ||
1188 | list->accounting->last = relative; | ||
1189 | list->accounting->count = list->accounting->count - next->accounting->count; | ||
1190 | |||
1191 | return list; | ||
1192 | } | ||
1193 | |||
1194 | EAPI Eina_List * | ||
1195 | eina_list_sorted_merge(Eina_List *left, Eina_List *right, Eina_Compare_Cb func) | ||
1196 | { | ||
1197 | Eina_List *ret; | ||
1198 | Eina_List *current; | ||
1199 | |||
1200 | EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL); | ||
1201 | |||
1202 | if (!left) | ||
1203 | return right; | ||
1204 | |||
1205 | if (!right) | ||
1206 | return left; | ||
1207 | |||
1208 | if (func(left->data, right->data) < 0) | ||
1209 | { | ||
1210 | ret = left; | ||
1211 | current = left; | ||
1212 | left = left->next; | ||
1213 | ret->accounting->count += right->accounting->count; | ||
1214 | |||
1215 | _eina_list_mempool_accounting_free(right->accounting); | ||
1216 | } | ||
1217 | else | ||
1218 | { | ||
1219 | ret = right; | ||
1220 | current = right; | ||
1221 | right = right->next; | ||
1222 | ret->accounting->count += left->accounting->count; | ||
1223 | |||
1224 | _eina_list_mempool_accounting_free(left->accounting); | ||
1225 | } | ||
1226 | |||
1227 | while (left && right) | ||
1228 | { | ||
1229 | if (func(left->data, right->data) < 0) | ||
1230 | { | ||
1231 | current->next = left; | ||
1232 | left->prev = current; | ||
1233 | left = left->next; | ||
1234 | } | ||
1235 | else | ||
1236 | { | ||
1237 | current->next = right; | ||
1238 | right->prev = current; | ||
1239 | right = right->next; | ||
1240 | } | ||
1241 | |||
1242 | current = current->next; | ||
1243 | current->accounting = ret->accounting; | ||
1244 | } | ||
1245 | |||
1246 | if (left) | ||
1247 | { | ||
1248 | current->next = left; | ||
1249 | left->prev = current; | ||
1250 | current->accounting = ret->accounting; | ||
1251 | } | ||
1252 | |||
1253 | if (right) | ||
1254 | { | ||
1255 | current->next = right; | ||
1256 | right->prev = current; | ||
1257 | current->accounting = ret->accounting; | ||
1258 | } | ||
1259 | |||
1260 | while (current->next) | ||
1261 | { | ||
1262 | current = current->next; | ||
1263 | current->accounting = ret->accounting; | ||
1264 | } | ||
1265 | |||
1266 | ret->accounting->last = current; | ||
1267 | |||
1268 | return ret; | ||
1269 | } | ||
1270 | |||
1271 | EAPI Eina_List * | ||
1272 | eina_list_search_sorted_near_list(const Eina_List *list, | ||
1273 | Eina_Compare_Cb func, | ||
1274 | const void *data, | ||
1275 | int *result_cmp) | ||
1276 | { | ||
1277 | const Eina_List *ct; | ||
1278 | unsigned int inf, sup, cur; | ||
1279 | int cmp; | ||
1280 | |||
1281 | if (!list) | ||
1282 | { | ||
1283 | if (result_cmp) | ||
1284 | *result_cmp = 0; | ||
1285 | |||
1286 | return NULL; | ||
1287 | } | ||
1288 | |||
1289 | if (list->accounting->count == 1) | ||
1290 | { | ||
1291 | if (result_cmp) | ||
1292 | *result_cmp = func(list->data, data); | ||
1293 | |||
1294 | return (Eina_List *)list; | ||
1295 | } | ||
1296 | |||
1297 | /* list walk is expensive, do quick check: tail */ | ||
1298 | ct = list->accounting->last; | ||
1299 | cmp = func(ct->data, data); | ||
1300 | if (cmp <= 0) | ||
1301 | goto end; | ||
1302 | |||
1303 | /* list walk is expensive, do quick check: head */ | ||
1304 | ct = list; | ||
1305 | cmp = func(ct->data, data); | ||
1306 | if (cmp >= 0) | ||
1307 | goto end; | ||
1308 | |||
1309 | /* inclusive bounds */ | ||
1310 | inf = 1; | ||
1311 | sup = list->accounting->count - 2; | ||
1312 | cur = 1; | ||
1313 | ct = list->next; | ||
1314 | |||
1315 | /* no loop, just compare if comparison value is important to caller */ | ||
1316 | if (inf > sup) | ||
1317 | { | ||
1318 | if (result_cmp) | ||
1319 | cmp = func(ct->data, data); | ||
1320 | |||
1321 | goto end; | ||
1322 | } | ||
1323 | |||
1324 | while (inf <= sup) | ||
1325 | { | ||
1326 | unsigned int tmp = cur; | ||
1327 | cur = inf + ((sup - inf) >> 1); | ||
1328 | if (tmp < cur) | ||
1329 | for (; tmp != cur; tmp++, ct = ct->next) ; | ||
1330 | else if (tmp > cur) | ||
1331 | for (; tmp != cur; tmp--, ct = ct->prev) ; | ||
1332 | |||
1333 | cmp = func(ct->data, data); | ||
1334 | if (cmp == 0) | ||
1335 | break; | ||
1336 | else if (cmp < 0) | ||
1337 | inf = cur + 1; | ||
1338 | else if (cmp > 0) | ||
1339 | { | ||
1340 | if (cur > 0) | ||
1341 | sup = cur - 1; | ||
1342 | else | ||
1343 | break; | ||
1344 | } | ||
1345 | else | ||
1346 | break; | ||
1347 | } | ||
1348 | |||
1349 | end: | ||
1350 | if (result_cmp) | ||
1351 | *result_cmp = cmp; | ||
1352 | |||
1353 | return (Eina_List *)ct; | ||
1354 | } | ||
1355 | |||
1356 | EAPI Eina_List * | ||
1357 | eina_list_search_sorted_list(const Eina_List *list, | ||
1358 | Eina_Compare_Cb func, | ||
1359 | const void *data) | ||
1360 | { | ||
1361 | Eina_List *lnear; | ||
1362 | int cmp; | ||
1363 | |||
1364 | lnear = eina_list_search_sorted_near_list(list, func, data, &cmp); | ||
1365 | if (!lnear) | ||
1366 | return NULL; | ||
1367 | |||
1368 | if (cmp == 0) | ||
1369 | return lnear; | ||
1370 | |||
1371 | return NULL; | ||
1372 | } | ||
1373 | |||
1374 | |||
1375 | EAPI void * | ||
1376 | eina_list_search_sorted(const Eina_List *list, | ||
1377 | Eina_Compare_Cb func, | ||
1378 | const void *data) | ||
1379 | { | ||
1380 | return eina_list_data_get(eina_list_search_sorted_list(list, func, data)); | ||
1381 | } | ||
1382 | |||
1383 | EAPI Eina_List * | ||
1384 | eina_list_search_unsorted_list(const Eina_List *list, | ||
1385 | Eina_Compare_Cb func, | ||
1386 | const void *data) | ||
1387 | { | ||
1388 | const Eina_List *l; | ||
1389 | void *d; | ||
1390 | |||
1391 | EINA_LIST_FOREACH(list, l, d) | ||
1392 | { | ||
1393 | if (!func(d, data)) | ||
1394 | return (Eina_List *)l; | ||
1395 | } | ||
1396 | return NULL; | ||
1397 | } | ||
1398 | |||
1399 | EAPI void * | ||
1400 | eina_list_search_unsorted(const Eina_List *list, | ||
1401 | Eina_Compare_Cb func, | ||
1402 | const void *data) | ||
1403 | { | ||
1404 | return eina_list_data_get(eina_list_search_unsorted_list(list, func, data)); | ||
1405 | } | ||
1406 | |||
1407 | |||
1408 | EAPI Eina_Iterator * | ||
1409 | eina_list_iterator_new(const Eina_List *list) | ||
1410 | { | ||
1411 | Eina_Iterator_List *it; | ||
1412 | |||
1413 | eina_error_set(0); | ||
1414 | it = calloc(1, sizeof (Eina_Iterator_List)); | ||
1415 | if (!it) | ||
1416 | { | ||
1417 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
1418 | return NULL; | ||
1419 | } | ||
1420 | |||
1421 | EINA_MAGIC_SET(it, EINA_MAGIC_LIST_ITERATOR); | ||
1422 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
1423 | |||
1424 | it->head = list; | ||
1425 | it->current = list; | ||
1426 | |||
1427 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
1428 | it->iterator.next = FUNC_ITERATOR_NEXT(eina_list_iterator_next); | ||
1429 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
1430 | eina_list_iterator_get_container); | ||
1431 | it->iterator.free = FUNC_ITERATOR_FREE(eina_list_iterator_free); | ||
1432 | |||
1433 | return &it->iterator; | ||
1434 | } | ||
1435 | |||
1436 | EAPI Eina_Iterator * | ||
1437 | eina_list_iterator_reversed_new(const Eina_List *list) | ||
1438 | { | ||
1439 | Eina_Iterator_List *it; | ||
1440 | |||
1441 | eina_error_set(0); | ||
1442 | it = calloc(1, sizeof (Eina_Iterator_List)); | ||
1443 | if (!it) | ||
1444 | { | ||
1445 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
1446 | return NULL; | ||
1447 | } | ||
1448 | |||
1449 | EINA_MAGIC_SET(it, EINA_MAGIC_LIST_ITERATOR); | ||
1450 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
1451 | |||
1452 | it->head = eina_list_last(list); | ||
1453 | it->current = it->head; | ||
1454 | |||
1455 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
1456 | it->iterator.next = FUNC_ITERATOR_NEXT(eina_list_iterator_prev); | ||
1457 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
1458 | eina_list_iterator_get_container); | ||
1459 | it->iterator.free = FUNC_ITERATOR_FREE(eina_list_iterator_free); | ||
1460 | |||
1461 | return &it->iterator; | ||
1462 | } | ||
1463 | |||
1464 | EAPI Eina_Accessor * | ||
1465 | eina_list_accessor_new(const Eina_List *list) | ||
1466 | { | ||
1467 | Eina_Accessor_List *ac; | ||
1468 | |||
1469 | eina_error_set(0); | ||
1470 | ac = calloc(1, sizeof (Eina_Accessor_List)); | ||
1471 | if (!ac) | ||
1472 | { | ||
1473 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
1474 | return NULL; | ||
1475 | } | ||
1476 | |||
1477 | EINA_MAGIC_SET(ac, EINA_MAGIC_LIST_ACCESSOR); | ||
1478 | EINA_MAGIC_SET(&ac->accessor, EINA_MAGIC_ACCESSOR); | ||
1479 | |||
1480 | ac->head = list; | ||
1481 | ac->current = list; | ||
1482 | ac->index = 0; | ||
1483 | |||
1484 | ac->accessor.version = EINA_ACCESSOR_VERSION; | ||
1485 | ac->accessor.get_at = FUNC_ACCESSOR_GET_AT(eina_list_accessor_get_at); | ||
1486 | ac->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER( | ||
1487 | eina_list_accessor_get_container); | ||
1488 | ac->accessor.free = FUNC_ACCESSOR_FREE(eina_list_accessor_free); | ||
1489 | |||
1490 | return &ac->accessor; | ||
1491 | } | ||
diff --git a/libraries/eina/src/lib/eina_log.c b/libraries/eina/src/lib/eina_log.c deleted file mode 100644 index 4e2bb6d..0000000 --- a/libraries/eina/src/lib/eina_log.c +++ /dev/null | |||
@@ -1,1993 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2007-2009 Jorge Luis Zapata Muga, Cedric Bail, Andre Dieb | ||
3 | * Martins | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Lesser General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2.1 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This library is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * Lesser General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Lesser General Public | ||
16 | * License along with this library; | ||
17 | * if not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #ifdef HAVE_CONFIG_H | ||
21 | # include "config.h" | ||
22 | #endif | ||
23 | |||
24 | #include <stdio.h> | ||
25 | #include <string.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <fnmatch.h> | ||
28 | #include <assert.h> | ||
29 | #include <errno.h> | ||
30 | |||
31 | #ifdef HAVE_UNISTD_H | ||
32 | # include <unistd.h> | ||
33 | #endif | ||
34 | |||
35 | #ifdef EFL_HAVE_POSIX_THREADS | ||
36 | # include <pthread.h> | ||
37 | #endif | ||
38 | |||
39 | #ifdef HAVE_EVIL | ||
40 | # include <Evil.h> | ||
41 | #endif | ||
42 | |||
43 | #include "eina_config.h" | ||
44 | #include "eina_private.h" | ||
45 | #include "eina_inlist.h" | ||
46 | |||
47 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
48 | #include "eina_safety_checks.h" | ||
49 | #include "eina_log.h" | ||
50 | |||
51 | /* TODO | ||
52 | * + printing logs to stdout or stderr can be implemented | ||
53 | * using a queue, useful for multiple threads printing | ||
54 | * + add a wrapper for assert? | ||
55 | */ | ||
56 | |||
57 | /*============================================================================* | ||
58 | * Local * | ||
59 | *============================================================================*/ | ||
60 | |||
61 | /** | ||
62 | * @cond LOCAL | ||
63 | */ | ||
64 | |||
65 | #define EINA_LOG_ENV_ABORT "EINA_LOG_ABORT" | ||
66 | #define EINA_LOG_ENV_ABORT_LEVEL "EINA_LOG_ABORT_LEVEL" | ||
67 | #define EINA_LOG_ENV_LEVEL "EINA_LOG_LEVEL" | ||
68 | #define EINA_LOG_ENV_LEVELS "EINA_LOG_LEVELS" | ||
69 | #define EINA_LOG_ENV_LEVELS_GLOB "EINA_LOG_LEVELS_GLOB" | ||
70 | #define EINA_LOG_ENV_COLOR_DISABLE "EINA_LOG_COLOR_DISABLE" | ||
71 | #define EINA_LOG_ENV_FILE_DISABLE "EINA_LOG_FILE_DISABLE" | ||
72 | #define EINA_LOG_ENV_FUNCTION_DISABLE "EINA_LOG_FUNCTION_DISABLE" | ||
73 | |||
74 | #ifdef EINA_ENABLE_LOG | ||
75 | |||
76 | // Structure for storing domain level settings passed from the command line | ||
77 | // that will be matched with application-defined domains. | ||
78 | typedef struct _Eina_Log_Domain_Level_Pending Eina_Log_Domain_Level_Pending; | ||
79 | struct _Eina_Log_Domain_Level_Pending | ||
80 | { | ||
81 | EINA_INLIST; | ||
82 | unsigned int level; | ||
83 | size_t namelen; | ||
84 | char name[]; | ||
85 | }; | ||
86 | |||
87 | /* | ||
88 | * List of levels for domains set by the user before the domains are registered, | ||
89 | * updates the domain levels on the first log and clears itself. | ||
90 | */ | ||
91 | static Eina_Inlist *_pending_list = NULL; | ||
92 | static Eina_Inlist *_glob_list = NULL; | ||
93 | |||
94 | // Disable color flag (can be changed through the env var | ||
95 | // EINA_LOG_ENV_COLOR_DISABLE). | ||
96 | static Eina_Bool _disable_color = EINA_FALSE; | ||
97 | static Eina_Bool _disable_file = EINA_FALSE; | ||
98 | static Eina_Bool _disable_function = EINA_FALSE; | ||
99 | static Eina_Bool _abort_on_critical = EINA_FALSE; | ||
100 | static int _abort_level_on_critical = EINA_LOG_LEVEL_CRITICAL; | ||
101 | |||
102 | #ifdef EFL_HAVE_THREADS | ||
103 | |||
104 | static Eina_Bool _threads_enabled = EINA_FALSE; | ||
105 | static Eina_Bool _threads_inited = EINA_FALSE; | ||
106 | |||
107 | # ifdef EFL_HAVE_POSIX_THREADS | ||
108 | |||
109 | typedef pthread_t Thread; | ||
110 | |||
111 | static pthread_t _main_thread; | ||
112 | |||
113 | # define SELF() pthread_self() | ||
114 | # define IS_MAIN(t) pthread_equal(t, _main_thread) | ||
115 | # define IS_OTHER(t) EINA_UNLIKELY(!IS_MAIN(t)) | ||
116 | # define CHECK_MAIN(...) \ | ||
117 | do { \ | ||
118 | if (!IS_MAIN(pthread_self())) { \ | ||
119 | fprintf(stderr, \ | ||
120 | "ERR: not main thread! current=%lu, main=%lu\n", \ | ||
121 | (unsigned long)pthread_self(), \ | ||
122 | (unsigned long)_main_thread); \ | ||
123 | return __VA_ARGS__; \ | ||
124 | } \ | ||
125 | } while (0) | ||
126 | |||
127 | # ifdef EFL_HAVE_POSIX_THREADS_SPINLOCK | ||
128 | |||
129 | static pthread_spinlock_t _log_lock; | ||
130 | |||
131 | static Eina_Bool _eina_log_spinlock_init(void) | ||
132 | { | ||
133 | if (pthread_spin_init(&_log_lock, PTHREAD_PROCESS_PRIVATE) == 0) | ||
134 | return EINA_TRUE; | ||
135 | |||
136 | fprintf(stderr, | ||
137 | "ERROR: pthread_spin_init(%p, PTHREAD_PROCESS_PRIVATE): %s\n", | ||
138 | &_log_lock, strerror(errno)); | ||
139 | return EINA_FALSE; | ||
140 | } | ||
141 | |||
142 | # define LOG_LOCK() \ | ||
143 | if (_threads_enabled) \ | ||
144 | do { \ | ||
145 | if (0) { \ | ||
146 | fprintf(stderr, "+++LOG LOG_LOCKED! [%s, %lu]\n", \ | ||
147 | __FUNCTION__, (unsigned long)pthread_self()); } \ | ||
148 | if (EINA_UNLIKELY(_threads_enabled)) { \ | ||
149 | pthread_spin_lock(&_log_lock); } \ | ||
150 | } while (0) | ||
151 | # define LOG_UNLOCK() \ | ||
152 | if (_threads_enabled) \ | ||
153 | do { \ | ||
154 | if (EINA_UNLIKELY(_threads_enabled)) { \ | ||
155 | pthread_spin_unlock(&_log_lock); } \ | ||
156 | if (0) { \ | ||
157 | fprintf(stderr, \ | ||
158 | "---LOG LOG_UNLOCKED! [%s, %lu]\n", \ | ||
159 | __FUNCTION__, (unsigned long)pthread_self()); } \ | ||
160 | } while (0) | ||
161 | # define INIT() _eina_log_spinlock_init() | ||
162 | # define SHUTDOWN() pthread_spin_destroy(&_log_lock) | ||
163 | |||
164 | # else /* ! EFL_HAVE_POSIX_THREADS_SPINLOCK */ | ||
165 | |||
166 | static pthread_mutex_t _log_mutex = PTHREAD_MUTEX_INITIALIZER; | ||
167 | # define LOG_LOCK() if(_threads_enabled) {pthread_mutex_lock(&_log_mutex); } | ||
168 | # define LOG_UNLOCK() if(_threads_enabled) {pthread_mutex_unlock(&_log_mutex); } | ||
169 | # define INIT() (1) | ||
170 | # define SHUTDOWN() do {} while (0) | ||
171 | |||
172 | # endif /* ! EFL_HAVE_POSIX_THREADS_SPINLOCK */ | ||
173 | |||
174 | # else /* EFL_HAVE_WIN32_THREADS */ | ||
175 | |||
176 | typedef DWORD Thread; | ||
177 | |||
178 | static DWORD _main_thread; | ||
179 | |||
180 | # define SELF() GetCurrentThreadId() | ||
181 | # define IS_MAIN(t) (t == _main_thread) | ||
182 | # define IS_OTHER(t) EINA_UNLIKELY(!IS_MAIN(t)) | ||
183 | # define CHECK_MAIN(...) \ | ||
184 | do { \ | ||
185 | if (!IS_MAIN(GetCurrentThreadId())) { \ | ||
186 | fprintf(stderr, \ | ||
187 | "ERR: not main thread! current=%lu, main=%lu\n", \ | ||
188 | GetCurrentThreadId(), _main_thread); \ | ||
189 | return __VA_ARGS__; \ | ||
190 | } \ | ||
191 | } while (0) | ||
192 | |||
193 | static HANDLE _log_mutex = NULL; | ||
194 | |||
195 | # define LOG_LOCK() if(_threads_enabled) WaitForSingleObject(_log_mutex, INFINITE) | ||
196 | # define LOG_UNLOCK() if(_threads_enabled) ReleaseMutex(_log_mutex) | ||
197 | # define INIT() ((_log_mutex = CreateMutex(NULL, FALSE, NULL)) ? 1 : 0) | ||
198 | # define SHUTDOWN() if (_log_mutex) CloseHandle(_log_mutex) | ||
199 | |||
200 | # endif /* EFL_HAVE_WIN32_THREADS */ | ||
201 | |||
202 | #else /* ! EFL_HAVE_THREADS */ | ||
203 | |||
204 | # define LOG_LOCK() do {} while (0) | ||
205 | # define LOG_UNLOCK() do {} while (0) | ||
206 | # define IS_MAIN(t) (1) | ||
207 | # define IS_OTHER(t) (0) | ||
208 | # define CHECK_MAIN(...) do {} while (0) | ||
209 | # define INIT() (1) | ||
210 | # define SHUTDOWN() do {} while (0) | ||
211 | |||
212 | #endif /* ! EFL_HAVE_THREADS */ | ||
213 | |||
214 | |||
215 | // List of domains registered | ||
216 | static Eina_Log_Domain *_log_domains = NULL; | ||
217 | static unsigned int _log_domains_count = 0; | ||
218 | static size_t _log_domains_allocated = 0; | ||
219 | |||
220 | // Default function for printing on domains | ||
221 | static Eina_Log_Print_Cb _print_cb = eina_log_print_cb_stderr; | ||
222 | static void *_print_cb_data = NULL; | ||
223 | |||
224 | #ifdef DEBUG | ||
225 | static Eina_Log_Level _log_level = EINA_LOG_LEVEL_DBG; | ||
226 | #elif DEBUG_CRITICAL | ||
227 | static Eina_Log_Level _log_level = EINA_LOG_LEVEL_CRITICAL; | ||
228 | #else | ||
229 | static Eina_Log_Level _log_level = EINA_LOG_LEVEL_ERR; | ||
230 | #endif | ||
231 | |||
232 | /* NOTE: if you change this, also change: | ||
233 | * eina_log_print_level_name_get() | ||
234 | * eina_log_print_level_name_color_get() | ||
235 | */ | ||
236 | static const char *_names[] = { | ||
237 | "CRI", | ||
238 | "ERR", | ||
239 | "WRN", | ||
240 | "INF", | ||
241 | "DBG", | ||
242 | }; | ||
243 | |||
244 | #ifdef _WIN32 | ||
245 | static int | ||
246 | eina_log_win32_color_get(const char *domain_str) | ||
247 | { | ||
248 | char *str; | ||
249 | char *tmp; | ||
250 | char *tmp2; | ||
251 | int code = -1; | ||
252 | int lighted = 0; | ||
253 | int ret = 0; | ||
254 | |||
255 | str = strdup(domain_str); | ||
256 | if (!str) | ||
257 | return 0; | ||
258 | |||
259 | /* this should not append */ | ||
260 | if (str[0] != '\033') | ||
261 | { | ||
262 | free(str); | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | /* we skip the first char and the [ */ | ||
267 | tmp = tmp2 = str + 2; | ||
268 | while (*tmp != 'm') | ||
269 | { | ||
270 | if (*tmp == ';') | ||
271 | { | ||
272 | *tmp = '\0'; | ||
273 | code = atol(tmp2); | ||
274 | tmp++; | ||
275 | tmp2 = tmp; | ||
276 | } | ||
277 | |||
278 | tmp++; | ||
279 | } | ||
280 | *tmp = '\0'; | ||
281 | if (code < 0) | ||
282 | code = atol(tmp2); | ||
283 | else | ||
284 | lighted = atol(tmp2); | ||
285 | |||
286 | free(str); | ||
287 | |||
288 | if (code < lighted) | ||
289 | { | ||
290 | int c; | ||
291 | |||
292 | c = code; | ||
293 | code = lighted; | ||
294 | lighted = c; | ||
295 | } | ||
296 | |||
297 | if (lighted) | ||
298 | ret = FOREGROUND_INTENSITY; | ||
299 | |||
300 | if (code == 31) | ||
301 | ret |= FOREGROUND_RED; | ||
302 | else if (code == 32) | ||
303 | ret |= FOREGROUND_GREEN; | ||
304 | else if (code == 33) | ||
305 | ret |= FOREGROUND_RED | FOREGROUND_GREEN; | ||
306 | else if (code == 34) | ||
307 | ret |= FOREGROUND_BLUE; | ||
308 | else if (code == 36) | ||
309 | ret |= FOREGROUND_GREEN | FOREGROUND_BLUE; | ||
310 | else if (code == 37) | ||
311 | ret |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; | ||
312 | |||
313 | return ret; | ||
314 | } | ||
315 | #endif | ||
316 | |||
317 | static inline unsigned int | ||
318 | eina_log_pid_get(void) | ||
319 | { | ||
320 | return (unsigned int)getpid(); | ||
321 | } | ||
322 | |||
323 | static inline void | ||
324 | eina_log_print_level_name_get(int level, const char **p_name) | ||
325 | { | ||
326 | static char buf[4]; | ||
327 | /* NOTE: if you change this, also change | ||
328 | * eina_log_print_level_name_color_get() | ||
329 | * eina_log_level_name_get() (at eina_inline_log.x) | ||
330 | */ | ||
331 | if (EINA_UNLIKELY(level < 0)) | ||
332 | { | ||
333 | snprintf(buf, sizeof(buf), "%03d", level); | ||
334 | *p_name = buf; | ||
335 | } | ||
336 | else if (EINA_UNLIKELY(level >= EINA_LOG_LEVELS)) | ||
337 | { | ||
338 | snprintf(buf, sizeof(buf), "%03d", level); | ||
339 | *p_name = buf; | ||
340 | } | ||
341 | else | ||
342 | *p_name = _names[level]; | ||
343 | } | ||
344 | |||
345 | #ifdef _WIN32 | ||
346 | static inline void | ||
347 | eina_log_print_level_name_color_get(int level, | ||
348 | const char **p_name, | ||
349 | int *p_color) | ||
350 | { | ||
351 | static char buf[4]; | ||
352 | /* NOTE: if you change this, also change: | ||
353 | * eina_log_print_level_name_get() | ||
354 | */ | ||
355 | if (EINA_UNLIKELY(level < 0)) | ||
356 | { | ||
357 | snprintf(buf, sizeof(buf), "%03d", level); | ||
358 | *p_name = buf; | ||
359 | } | ||
360 | else if (EINA_UNLIKELY(level >= EINA_LOG_LEVELS)) | ||
361 | { | ||
362 | snprintf(buf, sizeof(buf), "%03d", level); | ||
363 | *p_name = buf; | ||
364 | } | ||
365 | else | ||
366 | *p_name = _names[level]; | ||
367 | |||
368 | *p_color = eina_log_win32_color_get(eina_log_level_color_get(level)); | ||
369 | } | ||
370 | #else | ||
371 | static inline void | ||
372 | eina_log_print_level_name_color_get(int level, | ||
373 | const char **p_name, | ||
374 | const char **p_color) | ||
375 | { | ||
376 | static char buf[4]; | ||
377 | /* NOTE: if you change this, also change: | ||
378 | * eina_log_print_level_name_get() | ||
379 | */ | ||
380 | if (EINA_UNLIKELY(level < 0)) | ||
381 | { | ||
382 | snprintf(buf, sizeof(buf), "%03d", level); | ||
383 | *p_name = buf; | ||
384 | } | ||
385 | else if (EINA_UNLIKELY(level >= EINA_LOG_LEVELS)) | ||
386 | { | ||
387 | snprintf(buf, sizeof(buf), "%03d", level); | ||
388 | *p_name = buf; | ||
389 | } | ||
390 | else | ||
391 | *p_name = _names[level]; | ||
392 | |||
393 | *p_color = eina_log_level_color_get(level); | ||
394 | } | ||
395 | #endif | ||
396 | |||
397 | #define DECLARE_LEVEL_NAME(level) const char *name; \ | ||
398 | eina_log_print_level_name_get(level, &name) | ||
399 | #ifdef _WIN32 | ||
400 | # define DECLARE_LEVEL_NAME_COLOR(level) const char *name; int color; \ | ||
401 | eina_log_print_level_name_color_get(level, &name, &color) | ||
402 | #else | ||
403 | # define DECLARE_LEVEL_NAME_COLOR(level) const char *name, *color; \ | ||
404 | eina_log_print_level_name_color_get(level, &name, &color) | ||
405 | #endif | ||
406 | |||
407 | /** No threads, No color */ | ||
408 | static void | ||
409 | eina_log_print_prefix_NOthreads_NOcolor_file_func(FILE *fp, | ||
410 | const Eina_Log_Domain *d, | ||
411 | Eina_Log_Level level, | ||
412 | const char *file, | ||
413 | const char *fnc, | ||
414 | int line) | ||
415 | { | ||
416 | DECLARE_LEVEL_NAME(level); | ||
417 | fprintf(fp, "%s<%u>:%s %s:%d %s() ", name, eina_log_pid_get(), | ||
418 | d->domain_str, file, line, fnc); | ||
419 | } | ||
420 | |||
421 | static void | ||
422 | eina_log_print_prefix_NOthreads_NOcolor_NOfile_func(FILE *fp, | ||
423 | const Eina_Log_Domain *d, | ||
424 | Eina_Log_Level level, | ||
425 | const char *file __UNUSED__, | ||
426 | const char *fnc, | ||
427 | int line __UNUSED__) | ||
428 | { | ||
429 | DECLARE_LEVEL_NAME(level); | ||
430 | fprintf(fp, "%s<%u>:%s %s() ", name, eina_log_pid_get(), d->domain_str, | ||
431 | fnc); | ||
432 | } | ||
433 | |||
434 | static void | ||
435 | eina_log_print_prefix_NOthreads_NOcolor_file_NOfunc(FILE *fp, | ||
436 | const Eina_Log_Domain *d, | ||
437 | Eina_Log_Level level, | ||
438 | const char *file, | ||
439 | const char *fnc __UNUSED__, | ||
440 | int line) | ||
441 | { | ||
442 | DECLARE_LEVEL_NAME(level); | ||
443 | fprintf(fp, "%s<%u>:%s %s:%d ", name, eina_log_pid_get(), d->domain_str, | ||
444 | file, line); | ||
445 | } | ||
446 | |||
447 | /* No threads, color */ | ||
448 | static void | ||
449 | eina_log_print_prefix_NOthreads_color_file_func(FILE *fp, | ||
450 | const Eina_Log_Domain *d, | ||
451 | Eina_Log_Level level, | ||
452 | const char *file, | ||
453 | const char *fnc, | ||
454 | int line) | ||
455 | { | ||
456 | DECLARE_LEVEL_NAME_COLOR(level); | ||
457 | #ifdef _WIN32_WCE | ||
458 | fprintf(fp, "%s<%u>:%s %s:%d %s() ", name, eina_log_pid_get(), | ||
459 | d->domain_str, file, line, fnc); | ||
460 | #elif _WIN32 | ||
461 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
462 | color); | ||
463 | fprintf(fp, "%s", name); | ||
464 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
465 | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
466 | fprintf(fp, ":"); | ||
467 | SetConsoleTextAttribute(GetStdHandle( | ||
468 | STD_OUTPUT_HANDLE), | ||
469 | eina_log_win32_color_get(d->domain_str)); | ||
470 | fprintf(fp, "%s", d->name); | ||
471 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
472 | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
473 | fprintf(fp, " %s:%d ", file, line); | ||
474 | SetConsoleTextAttribute(GetStdHandle( | ||
475 | STD_OUTPUT_HANDLE), | ||
476 | FOREGROUND_INTENSITY | FOREGROUND_RED | | ||
477 | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
478 | fprintf(fp, "%s()", fnc); | ||
479 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
480 | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
481 | fprintf(fp, " "); | ||
482 | #else | ||
483 | fprintf(fp, "%s%s<%u>" EINA_COLOR_RESET ":%s %s:%d " | ||
484 | EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ", | ||
485 | color, name, eina_log_pid_get(), d->domain_str, file, line, fnc); | ||
486 | #endif | ||
487 | } | ||
488 | |||
489 | static void | ||
490 | eina_log_print_prefix_NOthreads_color_NOfile_func(FILE *fp, | ||
491 | const Eina_Log_Domain *d, | ||
492 | Eina_Log_Level level, | ||
493 | const char *file __UNUSED__, | ||
494 | const char *fnc, | ||
495 | int line __UNUSED__) | ||
496 | { | ||
497 | DECLARE_LEVEL_NAME_COLOR(level); | ||
498 | #ifdef _WIN32_WCE | ||
499 | fprintf(fp, "%s<%u>:%s %s() ", name, eina_log_pid_get(), d->domain_str, | ||
500 | fnc); | ||
501 | #elif _WIN32 | ||
502 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
503 | color); | ||
504 | fprintf(fp, "%s", name); | ||
505 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
506 | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
507 | fprintf(fp, ":"); | ||
508 | SetConsoleTextAttribute(GetStdHandle( | ||
509 | STD_OUTPUT_HANDLE), | ||
510 | eina_log_win32_color_get(d->domain_str)); | ||
511 | fprintf(fp, "%s", d->name); | ||
512 | SetConsoleTextAttribute(GetStdHandle( | ||
513 | STD_OUTPUT_HANDLE), | ||
514 | FOREGROUND_INTENSITY | FOREGROUND_RED | | ||
515 | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
516 | fprintf(fp, "%s()", fnc); | ||
517 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
518 | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
519 | fprintf(fp, " "); | ||
520 | #else | ||
521 | fprintf(fp, "%s%s<%u>" EINA_COLOR_RESET ":%s " | ||
522 | EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ", | ||
523 | color, name, eina_log_pid_get(), d->domain_str, fnc); | ||
524 | #endif | ||
525 | } | ||
526 | |||
527 | static void | ||
528 | eina_log_print_prefix_NOthreads_color_file_NOfunc(FILE *fp, | ||
529 | const Eina_Log_Domain *d, | ||
530 | Eina_Log_Level level, | ||
531 | const char *file, | ||
532 | const char *fnc __UNUSED__, | ||
533 | int line) | ||
534 | { | ||
535 | DECLARE_LEVEL_NAME_COLOR(level); | ||
536 | #ifdef _WIN32_WCE | ||
537 | fprintf(fp, "%s<%u>:%s %s:%d ", name, eina_log_pid_get(), d->domain_str, | ||
538 | file, line); | ||
539 | #elif _WIN32 | ||
540 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
541 | color); | ||
542 | fprintf(fp, "%s", name); | ||
543 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
544 | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
545 | fprintf(fp, ":"); | ||
546 | SetConsoleTextAttribute(GetStdHandle( | ||
547 | STD_OUTPUT_HANDLE), | ||
548 | eina_log_win32_color_get(d->domain_str)); | ||
549 | fprintf(fp, "%s", d->name); | ||
550 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
551 | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
552 | fprintf(fp, " %s:%d ", file, line); | ||
553 | #else | ||
554 | fprintf(fp, "%s%s<%u>" EINA_COLOR_RESET ":%s %s:%d ", | ||
555 | color, name, eina_log_pid_get(), d->domain_str, file, line); | ||
556 | #endif | ||
557 | } | ||
558 | |||
559 | /** threads, No color */ | ||
560 | #ifdef EFL_HAVE_THREADS | ||
561 | static void | ||
562 | eina_log_print_prefix_threads_NOcolor_file_func(FILE *fp, | ||
563 | const Eina_Log_Domain *d, | ||
564 | Eina_Log_Level level, | ||
565 | const char *file, | ||
566 | const char *fnc, | ||
567 | int line) | ||
568 | { | ||
569 | Thread cur; | ||
570 | |||
571 | DECLARE_LEVEL_NAME(level); | ||
572 | cur = SELF(); | ||
573 | if (IS_OTHER(cur)) | ||
574 | { | ||
575 | fprintf(fp, "%s<%u>:%s[T:%lu] %s:%d %s() ", | ||
576 | name, eina_log_pid_get(), d->domain_str, | ||
577 | (unsigned long)cur, file, line, fnc); | ||
578 | return; | ||
579 | } | ||
580 | fprintf(fp, "%s<%u>:%s %s:%d %s() ", | ||
581 | name, eina_log_pid_get(), d->domain_str, file, line, fnc); | ||
582 | } | ||
583 | |||
584 | static void | ||
585 | eina_log_print_prefix_threads_NOcolor_NOfile_func(FILE *fp, | ||
586 | const Eina_Log_Domain *d, | ||
587 | Eina_Log_Level level, | ||
588 | const char *file __UNUSED__, | ||
589 | const char *fnc, | ||
590 | int line __UNUSED__) | ||
591 | { | ||
592 | Thread cur; | ||
593 | |||
594 | DECLARE_LEVEL_NAME(level); | ||
595 | cur = SELF(); | ||
596 | if (IS_OTHER(cur)) | ||
597 | { | ||
598 | fprintf(fp, "%s<%u>:%s[T:%lu] %s() ", | ||
599 | name, eina_log_pid_get(), d->domain_str, | ||
600 | (unsigned long)cur, fnc); | ||
601 | return; | ||
602 | } | ||
603 | fprintf(fp, "%s<%u>:%s %s() ", | ||
604 | name, eina_log_pid_get(), d->domain_str, fnc); | ||
605 | } | ||
606 | |||
607 | static void | ||
608 | eina_log_print_prefix_threads_NOcolor_file_NOfunc(FILE *fp, | ||
609 | const Eina_Log_Domain *d, | ||
610 | Eina_Log_Level level, | ||
611 | const char *file, | ||
612 | const char *fnc __UNUSED__, | ||
613 | int line) | ||
614 | { | ||
615 | Thread cur; | ||
616 | |||
617 | DECLARE_LEVEL_NAME(level); | ||
618 | cur = SELF(); | ||
619 | if (IS_OTHER(cur)) | ||
620 | { | ||
621 | fprintf(fp, "%s<%u>:%s[T:%lu] %s:%d ", | ||
622 | name, eina_log_pid_get(), d->domain_str, (unsigned long)cur, | ||
623 | file, line); | ||
624 | return; | ||
625 | } | ||
626 | |||
627 | fprintf(fp, "%s<%u>:%s %s:%d ", | ||
628 | name, eina_log_pid_get(), d->domain_str, file, line); | ||
629 | } | ||
630 | |||
631 | /* threads, color */ | ||
632 | static void | ||
633 | eina_log_print_prefix_threads_color_file_func(FILE *fp, | ||
634 | const Eina_Log_Domain *d, | ||
635 | Eina_Log_Level level, | ||
636 | const char *file, | ||
637 | const char *fnc, | ||
638 | int line) | ||
639 | { | ||
640 | Thread cur; | ||
641 | |||
642 | DECLARE_LEVEL_NAME_COLOR(level); | ||
643 | cur = SELF(); | ||
644 | if (IS_OTHER(cur)) | ||
645 | { | ||
646 | # ifdef _WIN32 | ||
647 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
648 | color); | ||
649 | fprintf(fp, "%s", name); | ||
650 | SetConsoleTextAttribute(GetStdHandle( | ||
651 | STD_OUTPUT_HANDLE), | ||
652 | FOREGROUND_RED | FOREGROUND_GREEN | | ||
653 | FOREGROUND_BLUE); | ||
654 | fprintf(fp, ":"); | ||
655 | SetConsoleTextAttribute(GetStdHandle( | ||
656 | STD_OUTPUT_HANDLE), | ||
657 | eina_log_win32_color_get(d->domain_str)); | ||
658 | fprintf(fp, "%s[T:", d->name); | ||
659 | SetConsoleTextAttribute(GetStdHandle( | ||
660 | STD_OUTPUT_HANDLE), | ||
661 | FOREGROUND_RED | FOREGROUND_GREEN | | ||
662 | FOREGROUND_BLUE); | ||
663 | fprintf(fp, "[T:"); | ||
664 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
665 | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
666 | fprintf(fp, "%lu", (unsigned long)cur); | ||
667 | SetConsoleTextAttribute(GetStdHandle( | ||
668 | STD_OUTPUT_HANDLE), | ||
669 | FOREGROUND_RED | FOREGROUND_GREEN | | ||
670 | FOREGROUND_BLUE); | ||
671 | fprintf(fp, "] %s:%d ", file, line); | ||
672 | SetConsoleTextAttribute(GetStdHandle( | ||
673 | STD_OUTPUT_HANDLE), | ||
674 | FOREGROUND_INTENSITY | FOREGROUND_RED | | ||
675 | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
676 | fprintf(fp, "%s()", fnc); | ||
677 | SetConsoleTextAttribute(GetStdHandle( | ||
678 | STD_OUTPUT_HANDLE), | ||
679 | FOREGROUND_RED | FOREGROUND_GREEN | | ||
680 | FOREGROUND_BLUE); | ||
681 | fprintf(fp, " "); | ||
682 | # else | ||
683 | fprintf(fp, "%s%s<%u>" EINA_COLOR_RESET ":%s[T:" | ||
684 | EINA_COLOR_ORANGE "%lu" EINA_COLOR_RESET "] %s:%d " | ||
685 | EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ", | ||
686 | color, name, eina_log_pid_get() ,d->domain_str, | ||
687 | (unsigned long)cur, file, line, fnc); | ||
688 | # endif | ||
689 | return; | ||
690 | } | ||
691 | |||
692 | # ifdef _WIN32 | ||
693 | eina_log_print_prefix_NOthreads_color_file_func(fp, | ||
694 | d, | ||
695 | level, | ||
696 | file, | ||
697 | fnc, | ||
698 | line); | ||
699 | # else | ||
700 | fprintf(fp, "%s%s<%u>" EINA_COLOR_RESET ":%s %s:%d " | ||
701 | EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ", | ||
702 | color, name, eina_log_pid_get(), d->domain_str, file, line, fnc); | ||
703 | # endif | ||
704 | } | ||
705 | |||
706 | static void | ||
707 | eina_log_print_prefix_threads_color_NOfile_func(FILE *fp, | ||
708 | const Eina_Log_Domain *d, | ||
709 | Eina_Log_Level level, | ||
710 | const char *file __UNUSED__, | ||
711 | const char *fnc, | ||
712 | int line __UNUSED__) | ||
713 | { | ||
714 | Thread cur; | ||
715 | |||
716 | DECLARE_LEVEL_NAME_COLOR(level); | ||
717 | cur = SELF(); | ||
718 | if (IS_OTHER(cur)) | ||
719 | { | ||
720 | # ifdef _WIN32 | ||
721 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
722 | color); | ||
723 | fprintf(fp, "%s", name); | ||
724 | SetConsoleTextAttribute(GetStdHandle( | ||
725 | STD_OUTPUT_HANDLE), | ||
726 | FOREGROUND_RED | FOREGROUND_GREEN | | ||
727 | FOREGROUND_BLUE); | ||
728 | fprintf(fp, ":"); | ||
729 | SetConsoleTextAttribute(GetStdHandle( | ||
730 | STD_OUTPUT_HANDLE), | ||
731 | eina_log_win32_color_get(d->domain_str)); | ||
732 | fprintf(fp, "%s[T:", d->name); | ||
733 | SetConsoleTextAttribute(GetStdHandle( | ||
734 | STD_OUTPUT_HANDLE), | ||
735 | FOREGROUND_RED | FOREGROUND_GREEN | | ||
736 | FOREGROUND_BLUE); | ||
737 | fprintf(fp, "[T:"); | ||
738 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
739 | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
740 | fprintf(fp, "%lu", (unsigned long)cur); | ||
741 | SetConsoleTextAttribute(GetStdHandle( | ||
742 | STD_OUTPUT_HANDLE), | ||
743 | FOREGROUND_INTENSITY | FOREGROUND_RED | | ||
744 | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
745 | fprintf(fp, "%s()", fnc); | ||
746 | SetConsoleTextAttribute(GetStdHandle( | ||
747 | STD_OUTPUT_HANDLE), | ||
748 | FOREGROUND_RED | FOREGROUND_GREEN | | ||
749 | FOREGROUND_BLUE); | ||
750 | fprintf(fp, " "); | ||
751 | # else | ||
752 | fprintf(fp, "%s%s<%u>" EINA_COLOR_RESET ":%s[T:" | ||
753 | EINA_COLOR_ORANGE "%lu" EINA_COLOR_RESET "] " | ||
754 | EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ", | ||
755 | color, name, eina_log_pid_get(), d->domain_str, | ||
756 | (unsigned long)cur, fnc); | ||
757 | # endif | ||
758 | return; | ||
759 | } | ||
760 | |||
761 | # ifdef _WIN32 | ||
762 | eina_log_print_prefix_NOthreads_color_NOfile_func(fp, | ||
763 | d, | ||
764 | level, | ||
765 | file, | ||
766 | fnc, | ||
767 | line); | ||
768 | # else | ||
769 | fprintf(fp, "%s%s<%u>" EINA_COLOR_RESET ":%s " | ||
770 | EINA_COLOR_HIGH "%s()" EINA_COLOR_RESET " ", | ||
771 | color, name, eina_log_pid_get(), d->domain_str, fnc); | ||
772 | # endif | ||
773 | } | ||
774 | |||
775 | static void | ||
776 | eina_log_print_prefix_threads_color_file_NOfunc(FILE *fp, | ||
777 | const Eina_Log_Domain *d, | ||
778 | Eina_Log_Level level, | ||
779 | const char *file, | ||
780 | const char *fnc __UNUSED__, | ||
781 | int line) | ||
782 | { | ||
783 | Thread cur; | ||
784 | |||
785 | DECLARE_LEVEL_NAME_COLOR(level); | ||
786 | cur = SELF(); | ||
787 | if (IS_OTHER(cur)) | ||
788 | { | ||
789 | # ifdef _WIN32 | ||
790 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
791 | color); | ||
792 | fprintf(fp, "%s", name); | ||
793 | SetConsoleTextAttribute(GetStdHandle( | ||
794 | STD_OUTPUT_HANDLE), | ||
795 | FOREGROUND_RED | FOREGROUND_GREEN | | ||
796 | FOREGROUND_BLUE); | ||
797 | fprintf(fp, ":"); | ||
798 | SetConsoleTextAttribute(GetStdHandle( | ||
799 | STD_OUTPUT_HANDLE), | ||
800 | eina_log_win32_color_get(d->domain_str)); | ||
801 | fprintf(fp, "%s[T:", d->name); | ||
802 | SetConsoleTextAttribute(GetStdHandle( | ||
803 | STD_OUTPUT_HANDLE), | ||
804 | FOREGROUND_RED | FOREGROUND_GREEN | | ||
805 | FOREGROUND_BLUE); | ||
806 | fprintf(fp, "[T:"); | ||
807 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), | ||
808 | FOREGROUND_GREEN | FOREGROUND_BLUE); | ||
809 | fprintf(fp, "%lu", (unsigned long)cur); | ||
810 | SetConsoleTextAttribute(GetStdHandle( | ||
811 | STD_OUTPUT_HANDLE), | ||
812 | FOREGROUND_RED | FOREGROUND_GREEN | | ||
813 | FOREGROUND_BLUE); | ||
814 | fprintf(fp, "] %s:%d ", file, line); | ||
815 | # else | ||
816 | fprintf(fp, "%s%s<%u>" EINA_COLOR_RESET ":%s[T:" | ||
817 | EINA_COLOR_ORANGE "%lu" EINA_COLOR_RESET "] %s:%d ", | ||
818 | color, name, eina_log_pid_get(), d->domain_str, | ||
819 | (unsigned long)cur, file, line); | ||
820 | # endif | ||
821 | return; | ||
822 | } | ||
823 | |||
824 | # ifdef _WIN32 | ||
825 | eina_log_print_prefix_NOthreads_color_file_NOfunc(fp, | ||
826 | d, | ||
827 | level, | ||
828 | file, | ||
829 | fnc, | ||
830 | line); | ||
831 | # else | ||
832 | fprintf(fp, "%s%s" EINA_COLOR_RESET ":%s %s:%d ", | ||
833 | color, name, d->domain_str, file, line); | ||
834 | # endif | ||
835 | } | ||
836 | #endif /* EFL_HAVE_THREADS */ | ||
837 | |||
838 | static void (*_eina_log_print_prefix)(FILE *fp, const Eina_Log_Domain *d, | ||
839 | Eina_Log_Level level, const char *file, | ||
840 | const char *fnc, | ||
841 | int line) = | ||
842 | eina_log_print_prefix_NOthreads_color_file_func; | ||
843 | |||
844 | static inline void | ||
845 | eina_log_print_prefix_update(void) | ||
846 | { | ||
847 | if (_disable_file && _disable_function) | ||
848 | { | ||
849 | fprintf(stderr, "ERROR: cannot have " EINA_LOG_ENV_FILE_DISABLE " and " | ||
850 | EINA_LOG_ENV_FUNCTION_DISABLE " set at the same time, will " | ||
851 | "just disable function.\n"); | ||
852 | _disable_file = 0; | ||
853 | } | ||
854 | |||
855 | #define S(NOthread, NOcolor, NOfile, NOfunc) \ | ||
856 | _eina_log_print_prefix = \ | ||
857 | eina_log_print_prefix_ ## NOthread ## threads_ ## NOcolor ## color_ ## \ | ||
858 | NOfile \ | ||
859 | ## file_ ## NOfunc ## func | ||
860 | |||
861 | #ifdef EFL_HAVE_THREADS | ||
862 | if (_threads_enabled) | ||
863 | { | ||
864 | if (_disable_color) | ||
865 | { | ||
866 | if (_disable_file) | ||
867 | S(,NO,NO,); | ||
868 | else if (_disable_function) | ||
869 | S(,NO,,NO); | ||
870 | else | ||
871 | S(,NO,,); | ||
872 | } | ||
873 | else | ||
874 | { | ||
875 | if (_disable_file) | ||
876 | S(,,NO,); | ||
877 | else if (_disable_function) | ||
878 | S(,,,NO); | ||
879 | else | ||
880 | S(,,,); | ||
881 | } | ||
882 | |||
883 | return; | ||
884 | } | ||
885 | |||
886 | #endif | ||
887 | |||
888 | if (_disable_color) | ||
889 | { | ||
890 | if (_disable_file) | ||
891 | S(NO,NO,NO,); | ||
892 | else if (_disable_function) | ||
893 | S(NO,NO,,NO); | ||
894 | else | ||
895 | S(NO,NO,,); | ||
896 | } | ||
897 | else | ||
898 | { | ||
899 | if (_disable_file) | ||
900 | S(NO,,NO,); | ||
901 | else if (_disable_function) | ||
902 | S(NO,,,NO); | ||
903 | else | ||
904 | S(NO,,,); | ||
905 | } | ||
906 | |||
907 | #undef S | ||
908 | } | ||
909 | |||
910 | /* | ||
911 | * Creates a colored domain name string. | ||
912 | */ | ||
913 | static const char * | ||
914 | eina_log_domain_str_get(const char *name, const char *color) | ||
915 | { | ||
916 | const char *d; | ||
917 | |||
918 | if (color) | ||
919 | { | ||
920 | size_t name_len; | ||
921 | size_t color_len; | ||
922 | |||
923 | name_len = strlen(name); | ||
924 | color_len = strlen(color); | ||
925 | d = | ||
926 | malloc(sizeof(char) * | ||
927 | (color_len + name_len + strlen(EINA_COLOR_RESET) + 1)); | ||
928 | if (!d) | ||
929 | return NULL; | ||
930 | |||
931 | memcpy((char *)d, color, color_len); | ||
932 | memcpy((char *)(d + color_len), name, name_len); | ||
933 | memcpy((char *)(d + color_len + name_len), EINA_COLOR_RESET, | ||
934 | strlen(EINA_COLOR_RESET)); | ||
935 | ((char *)d)[color_len + name_len + strlen(EINA_COLOR_RESET)] = '\0'; | ||
936 | } | ||
937 | else | ||
938 | d = strdup(name); | ||
939 | |||
940 | return d; | ||
941 | } | ||
942 | |||
943 | /* | ||
944 | * Setups a new logging domain to the name and color specified. Note that this | ||
945 | * constructor acts upon an pre-allocated object. | ||
946 | */ | ||
947 | static Eina_Log_Domain * | ||
948 | eina_log_domain_new(Eina_Log_Domain *d, const char *name, const char *color) | ||
949 | { | ||
950 | EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL); | ||
951 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); | ||
952 | |||
953 | d->level = EINA_LOG_LEVEL_UNKNOWN; | ||
954 | d->deleted = EINA_FALSE; | ||
955 | |||
956 | if ((color) && (!_disable_color)) | ||
957 | d->domain_str = eina_log_domain_str_get(name, color); | ||
958 | else | ||
959 | d->domain_str = eina_log_domain_str_get(name, NULL); | ||
960 | |||
961 | d->name = strdup(name); | ||
962 | d->namelen = strlen(name); | ||
963 | |||
964 | return d; | ||
965 | } | ||
966 | |||
967 | /* | ||
968 | * Frees internal strings of a log domain, keeping the log domain itself as a | ||
969 | * slot for next domain registers. | ||
970 | */ | ||
971 | static void | ||
972 | eina_log_domain_free(Eina_Log_Domain *d) | ||
973 | { | ||
974 | EINA_SAFETY_ON_NULL_RETURN(d); | ||
975 | |||
976 | if (d->domain_str) | ||
977 | free((char *)d->domain_str); | ||
978 | |||
979 | if (d->name) | ||
980 | free((char *)d->name); | ||
981 | } | ||
982 | |||
983 | /* | ||
984 | * Parses domain levels passed through the env var. | ||
985 | */ | ||
986 | static void | ||
987 | eina_log_domain_parse_pendings(void) | ||
988 | { | ||
989 | const char *start; | ||
990 | |||
991 | if (!(start = getenv(EINA_LOG_ENV_LEVELS))) | ||
992 | return; | ||
993 | |||
994 | // name1:level1,name2:level2,name3:level3,... | ||
995 | while (1) | ||
996 | { | ||
997 | Eina_Log_Domain_Level_Pending *p; | ||
998 | char *end = NULL; | ||
999 | char *tmp = NULL; | ||
1000 | long int level; | ||
1001 | |||
1002 | end = strchr(start, ':'); | ||
1003 | if (!end) | ||
1004 | break; | ||
1005 | |||
1006 | // Parse level, keep going if failed | ||
1007 | level = strtol((char *)(end + 1), &tmp, 10); | ||
1008 | if (tmp == (end + 1)) | ||
1009 | goto parse_end; | ||
1010 | |||
1011 | // Parse name | ||
1012 | p = malloc(sizeof(Eina_Log_Domain_Level_Pending) + end - start + 1); | ||
1013 | if (!p) | ||
1014 | break; | ||
1015 | |||
1016 | p->namelen = end - start; | ||
1017 | memcpy((char *)p->name, start, end - start); | ||
1018 | ((char *)p->name)[end - start] = '\0'; | ||
1019 | p->level = level; | ||
1020 | |||
1021 | _pending_list = eina_inlist_append(_pending_list, EINA_INLIST_GET(p)); | ||
1022 | |||
1023 | parse_end: | ||
1024 | start = strchr(tmp, ','); | ||
1025 | if (start) | ||
1026 | start++; | ||
1027 | else | ||
1028 | break; | ||
1029 | } | ||
1030 | } | ||
1031 | |||
1032 | static void | ||
1033 | eina_log_domain_parse_pending_globs(void) | ||
1034 | { | ||
1035 | const char *start; | ||
1036 | |||
1037 | if (!(start = getenv(EINA_LOG_ENV_LEVELS_GLOB))) | ||
1038 | return; | ||
1039 | |||
1040 | // name1:level1,name2:level2,name3:level3,... | ||
1041 | while (1) | ||
1042 | { | ||
1043 | Eina_Log_Domain_Level_Pending *p; | ||
1044 | char *end = NULL; | ||
1045 | char *tmp = NULL; | ||
1046 | long int level; | ||
1047 | |||
1048 | end = strchr(start, ':'); | ||
1049 | if (!end) | ||
1050 | break; | ||
1051 | |||
1052 | // Parse level, keep going if failed | ||
1053 | level = strtol((char *)(end + 1), &tmp, 10); | ||
1054 | if (tmp == (end + 1)) | ||
1055 | goto parse_end; | ||
1056 | |||
1057 | // Parse name | ||
1058 | p = malloc(sizeof(Eina_Log_Domain_Level_Pending) + end - start + 1); | ||
1059 | if (!p) | ||
1060 | break; | ||
1061 | |||
1062 | p->namelen = 0; /* not that useful */ | ||
1063 | memcpy((char *)p->name, start, end - start); | ||
1064 | ((char *)p->name)[end - start] = '\0'; | ||
1065 | p->level = level; | ||
1066 | |||
1067 | _glob_list = eina_inlist_append(_glob_list, EINA_INLIST_GET(p)); | ||
1068 | |||
1069 | parse_end: | ||
1070 | start = strchr(tmp, ','); | ||
1071 | if (start) | ||
1072 | start++; | ||
1073 | else | ||
1074 | break; | ||
1075 | } | ||
1076 | } | ||
1077 | |||
1078 | static inline int | ||
1079 | eina_log_domain_register_unlocked(const char *name, const char *color) | ||
1080 | { | ||
1081 | Eina_Log_Domain_Level_Pending *pending = NULL; | ||
1082 | size_t namelen; | ||
1083 | unsigned int i; | ||
1084 | |||
1085 | for (i = 0; i < _log_domains_count; i++) | ||
1086 | { | ||
1087 | if (_log_domains[i].deleted) | ||
1088 | { | ||
1089 | // Found a flagged slot, free domain_str and replace slot | ||
1090 | eina_log_domain_new(&_log_domains[i], name, color); | ||
1091 | goto finish_register; | ||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | if (_log_domains_count >= _log_domains_allocated) | ||
1096 | { | ||
1097 | Eina_Log_Domain *tmp; | ||
1098 | size_t size; | ||
1099 | |||
1100 | if (!_log_domains) | ||
1101 | // special case for init, eina itself will allocate a dozen of domains | ||
1102 | size = 24; | ||
1103 | else | ||
1104 | // grow 8 buckets to minimize reallocs | ||
1105 | size = _log_domains_allocated + 8; | ||
1106 | |||
1107 | tmp = realloc(_log_domains, sizeof(Eina_Log_Domain) * size); | ||
1108 | |||
1109 | if (tmp) | ||
1110 | { | ||
1111 | // Success! | ||
1112 | _log_domains = tmp; | ||
1113 | _log_domains_allocated = size; | ||
1114 | } | ||
1115 | else | ||
1116 | return -1; | ||
1117 | } | ||
1118 | |||
1119 | // Use an allocated slot | ||
1120 | eina_log_domain_new(&_log_domains[i], name, color); | ||
1121 | _log_domains_count++; | ||
1122 | |||
1123 | finish_register: | ||
1124 | namelen = _log_domains[i].namelen; | ||
1125 | |||
1126 | EINA_INLIST_FOREACH(_pending_list, pending) | ||
1127 | { | ||
1128 | if ((namelen == pending->namelen) && (strcmp(pending->name, name) == 0)) | ||
1129 | { | ||
1130 | _log_domains[i].level = pending->level; | ||
1131 | _pending_list = | ||
1132 | eina_inlist_remove(_pending_list, EINA_INLIST_GET(pending)); | ||
1133 | free(pending); | ||
1134 | break; | ||
1135 | } | ||
1136 | } | ||
1137 | |||
1138 | if (_log_domains[i].level == EINA_LOG_LEVEL_UNKNOWN) | ||
1139 | { | ||
1140 | EINA_INLIST_FOREACH(_glob_list, pending) | ||
1141 | { | ||
1142 | if (!fnmatch(pending->name, name, 0)) | ||
1143 | { | ||
1144 | _log_domains[i].level = pending->level; | ||
1145 | break; | ||
1146 | } | ||
1147 | } | ||
1148 | } | ||
1149 | |||
1150 | // Check if level is still UNKNOWN, set it to global | ||
1151 | if (_log_domains[i].level == EINA_LOG_LEVEL_UNKNOWN) | ||
1152 | _log_domains[i].level = _log_level; | ||
1153 | |||
1154 | return i; | ||
1155 | } | ||
1156 | |||
1157 | static inline Eina_Bool | ||
1158 | eina_log_term_color_supported(const char *term) | ||
1159 | { | ||
1160 | const char *tail; | ||
1161 | |||
1162 | if (!term) | ||
1163 | return EINA_FALSE; | ||
1164 | |||
1165 | tail = term + 1; | ||
1166 | switch (term[0]) | ||
1167 | { | ||
1168 | /* list of known to support color terminals, | ||
1169 | * take from gentoo's portage. | ||
1170 | */ | ||
1171 | |||
1172 | case 'x': /* xterm and xterm-color */ | ||
1173 | return ((strncmp(tail, "term", sizeof("term") - 1) == 0) && | ||
1174 | ((tail[sizeof("term") - 1] == '\0') || | ||
1175 | (strcmp(tail + sizeof("term") - 1, "-color") == 0))); | ||
1176 | |||
1177 | case 'E': /* Eterm */ | ||
1178 | case 'a': /* aterm */ | ||
1179 | case 'k': /* kterm */ | ||
1180 | return (strcmp(tail, "term") == 0); | ||
1181 | |||
1182 | case 'r': /* xrvt or rxvt-unicode */ | ||
1183 | return ((strncmp(tail, "xvt", sizeof("xvt") - 1) == 0) && | ||
1184 | ((tail[sizeof("xvt") - 1] == '\0') || | ||
1185 | (strcmp(tail + sizeof("xvt") - 1, "-unicode") == 0))); | ||
1186 | |||
1187 | case 's': /* screen */ | ||
1188 | return (strcmp(tail, "creen") == 0); | ||
1189 | |||
1190 | case 'g': /* gnome */ | ||
1191 | return (strcmp(tail, "nome") == 0); | ||
1192 | |||
1193 | case 'i': /* interix */ | ||
1194 | return (strcmp(tail, "nterix") == 0); | ||
1195 | |||
1196 | default: | ||
1197 | return EINA_FALSE; | ||
1198 | } | ||
1199 | } | ||
1200 | |||
1201 | static inline void | ||
1202 | eina_log_domain_unregister_unlocked(int domain) | ||
1203 | { | ||
1204 | Eina_Log_Domain *d; | ||
1205 | |||
1206 | if ((unsigned int)domain >= _log_domains_count) | ||
1207 | return; | ||
1208 | |||
1209 | d = &_log_domains[domain]; | ||
1210 | eina_log_domain_free(d); | ||
1211 | d->deleted = 1; | ||
1212 | } | ||
1213 | |||
1214 | static inline void | ||
1215 | eina_log_print_unlocked(int domain, | ||
1216 | Eina_Log_Level level, | ||
1217 | const char *file, | ||
1218 | const char *fnc, | ||
1219 | int line, | ||
1220 | const char *fmt, | ||
1221 | va_list args) | ||
1222 | { | ||
1223 | Eina_Log_Domain *d; | ||
1224 | |||
1225 | #ifdef EINA_SAFETY_CHECKS | ||
1226 | if (EINA_UNLIKELY((unsigned int)domain >= _log_domains_count) || | ||
1227 | EINA_UNLIKELY(domain < 0)) | ||
1228 | { | ||
1229 | if (file && fnc && fmt) | ||
1230 | fprintf( | ||
1231 | stderr, | ||
1232 | "CRI: %s:%d %s() eina_log_print() unknown domain %d, original message format '%s'\n", | ||
1233 | file, | ||
1234 | line, | ||
1235 | fnc, | ||
1236 | domain, | ||
1237 | fmt); | ||
1238 | else | ||
1239 | fprintf( | ||
1240 | stderr, | ||
1241 | "CRI: eina_log_print() unknown domain %d, original message format '%s'\n", | ||
1242 | domain, | ||
1243 | fmt ? fmt : ""); | ||
1244 | |||
1245 | if (_abort_on_critical) | ||
1246 | abort(); | ||
1247 | |||
1248 | return; | ||
1249 | } | ||
1250 | |||
1251 | #endif | ||
1252 | d = _log_domains + domain; | ||
1253 | #ifdef EINA_SAFETY_CHECKS | ||
1254 | if (EINA_UNLIKELY(d->deleted)) | ||
1255 | { | ||
1256 | fprintf(stderr, | ||
1257 | "ERR: eina_log_print() domain %d is deleted\n", | ||
1258 | domain); | ||
1259 | return; | ||
1260 | } | ||
1261 | |||
1262 | #endif | ||
1263 | |||
1264 | if (level > d->level) | ||
1265 | return; | ||
1266 | |||
1267 | #ifdef _WIN32 | ||
1268 | { | ||
1269 | char *wfmt; | ||
1270 | char *tmp; | ||
1271 | |||
1272 | wfmt = strdup(fmt); | ||
1273 | if (!wfmt) | ||
1274 | { | ||
1275 | fprintf(stderr, "ERR: %s: can not allocate memory\n", __FUNCTION__); | ||
1276 | return; | ||
1277 | } | ||
1278 | |||
1279 | tmp = wfmt; | ||
1280 | while (strchr(tmp, '%')) | ||
1281 | { | ||
1282 | tmp++; | ||
1283 | if (*tmp == 'z') | ||
1284 | *tmp = 'I'; | ||
1285 | } | ||
1286 | _print_cb(d, level, file, fnc, line, wfmt, _print_cb_data, args); | ||
1287 | free(wfmt); | ||
1288 | } | ||
1289 | #else | ||
1290 | _print_cb(d, level, file, fnc, line, fmt, _print_cb_data, args); | ||
1291 | #endif | ||
1292 | |||
1293 | if (EINA_UNLIKELY(_abort_on_critical) && | ||
1294 | EINA_UNLIKELY(level <= _abort_level_on_critical)) | ||
1295 | abort(); | ||
1296 | } | ||
1297 | |||
1298 | #endif | ||
1299 | |||
1300 | /** | ||
1301 | * @endcond | ||
1302 | */ | ||
1303 | |||
1304 | |||
1305 | /*============================================================================* | ||
1306 | * Global * | ||
1307 | *============================================================================*/ | ||
1308 | |||
1309 | /** | ||
1310 | * @internal | ||
1311 | * @brief Initialize the log module. | ||
1312 | * | ||
1313 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
1314 | * | ||
1315 | * This function sets up the log module of Eina. It is called by | ||
1316 | * eina_init(). | ||
1317 | * | ||
1318 | * @see eina_init() | ||
1319 | * | ||
1320 | * @warning Not-MT: just call this function from main thread! The | ||
1321 | * place where this function was called the first time is | ||
1322 | * considered the main thread. | ||
1323 | */ | ||
1324 | Eina_Bool | ||
1325 | eina_log_init(void) | ||
1326 | { | ||
1327 | #ifdef EINA_ENABLE_LOG | ||
1328 | const char *level, *tmp; | ||
1329 | int color_disable; | ||
1330 | |||
1331 | assert((sizeof(_names) / sizeof(_names[0])) == EINA_LOG_LEVELS); | ||
1332 | |||
1333 | if ((tmp = getenv(EINA_LOG_ENV_COLOR_DISABLE))) | ||
1334 | color_disable = atoi(tmp); | ||
1335 | else | ||
1336 | color_disable = -1; | ||
1337 | |||
1338 | /* Check if color is explicitly disabled */ | ||
1339 | if (color_disable == 1) | ||
1340 | _disable_color = EINA_TRUE; | ||
1341 | |||
1342 | #ifndef _WIN32 | ||
1343 | /* color was not explicitly disabled or enabled, guess it */ | ||
1344 | else if (color_disable == -1) | ||
1345 | { | ||
1346 | if (!eina_log_term_color_supported(getenv("TERM"))) | ||
1347 | _disable_color = EINA_TRUE; | ||
1348 | else | ||
1349 | { | ||
1350 | /* if not a terminal, but redirected to a file, disable color */ | ||
1351 | int fd; | ||
1352 | |||
1353 | if (_print_cb == eina_log_print_cb_stderr) | ||
1354 | fd = STDERR_FILENO; | ||
1355 | else if (_print_cb == eina_log_print_cb_stdout) | ||
1356 | fd = STDOUT_FILENO; | ||
1357 | else | ||
1358 | fd = -1; | ||
1359 | |||
1360 | if ((fd >= 0) && (!isatty(fd))) | ||
1361 | _disable_color = EINA_TRUE; | ||
1362 | } | ||
1363 | } | ||
1364 | #endif | ||
1365 | |||
1366 | if ((tmp = getenv(EINA_LOG_ENV_FILE_DISABLE)) && (atoi(tmp) == 1)) | ||
1367 | _disable_file = EINA_TRUE; | ||
1368 | |||
1369 | if ((tmp = getenv(EINA_LOG_ENV_FUNCTION_DISABLE)) && (atoi(tmp) == 1)) | ||
1370 | _disable_function = EINA_TRUE; | ||
1371 | |||
1372 | if ((tmp = getenv(EINA_LOG_ENV_ABORT)) && (atoi(tmp) == 1)) | ||
1373 | _abort_on_critical = EINA_TRUE; | ||
1374 | |||
1375 | if ((tmp = getenv(EINA_LOG_ENV_ABORT_LEVEL))) | ||
1376 | _abort_level_on_critical = atoi(tmp); | ||
1377 | |||
1378 | eina_log_print_prefix_update(); | ||
1379 | |||
1380 | // Global log level | ||
1381 | if ((level = getenv(EINA_LOG_ENV_LEVEL))) | ||
1382 | _log_level = atoi(level); | ||
1383 | |||
1384 | // Register UNKNOWN domain, the default logger | ||
1385 | EINA_LOG_DOMAIN_GLOBAL = eina_log_domain_register("", NULL); | ||
1386 | |||
1387 | if (EINA_LOG_DOMAIN_GLOBAL < 0) | ||
1388 | { | ||
1389 | fprintf(stderr, "Failed to create global logging domain.\n"); | ||
1390 | return EINA_FALSE; | ||
1391 | } | ||
1392 | |||
1393 | // Parse pending domains passed through EINA_LOG_LEVELS_GLOB | ||
1394 | eina_log_domain_parse_pending_globs(); | ||
1395 | |||
1396 | // Parse pending domains passed through EINA_LOG_LEVELS | ||
1397 | eina_log_domain_parse_pendings(); | ||
1398 | |||
1399 | #endif | ||
1400 | return EINA_TRUE; | ||
1401 | } | ||
1402 | |||
1403 | /** | ||
1404 | * @internal | ||
1405 | * @brief Shut down the log module. | ||
1406 | * | ||
1407 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
1408 | * | ||
1409 | * This function shuts down the log module set up by | ||
1410 | * eina_log_init(). It is called by eina_shutdown(). | ||
1411 | * | ||
1412 | * @see eina_shutdown() | ||
1413 | * | ||
1414 | * @warning Not-MT: just call this function from main thread! The | ||
1415 | * place where eina_log_init() (eina_init()) was called the | ||
1416 | * first time is considered the main thread. | ||
1417 | */ | ||
1418 | Eina_Bool | ||
1419 | eina_log_shutdown(void) | ||
1420 | { | ||
1421 | #ifdef EINA_ENABLE_LOG | ||
1422 | Eina_Inlist *tmp; | ||
1423 | |||
1424 | while (_log_domains_count--) | ||
1425 | { | ||
1426 | if (_log_domains[_log_domains_count].deleted) | ||
1427 | continue; | ||
1428 | |||
1429 | eina_log_domain_free(&_log_domains[_log_domains_count]); | ||
1430 | } | ||
1431 | |||
1432 | free(_log_domains); | ||
1433 | |||
1434 | _log_domains = NULL; | ||
1435 | _log_domains_count = 0; | ||
1436 | _log_domains_allocated = 0; | ||
1437 | |||
1438 | while (_glob_list) | ||
1439 | { | ||
1440 | tmp = _glob_list; | ||
1441 | _glob_list = _glob_list->next; | ||
1442 | free(tmp); | ||
1443 | } | ||
1444 | |||
1445 | while (_pending_list) | ||
1446 | { | ||
1447 | tmp = _pending_list; | ||
1448 | _pending_list = _pending_list->next; | ||
1449 | free(tmp); | ||
1450 | } | ||
1451 | |||
1452 | #endif | ||
1453 | return EINA_TRUE; | ||
1454 | } | ||
1455 | |||
1456 | #ifdef EFL_HAVE_THREADS | ||
1457 | |||
1458 | /** | ||
1459 | * @internal | ||
1460 | * @brief Activate the log mutex. | ||
1461 | * | ||
1462 | * This function activate the mutex in the eina log module. It is called by | ||
1463 | * eina_threads_init(). | ||
1464 | * | ||
1465 | * @see eina_threads_init() | ||
1466 | */ | ||
1467 | void | ||
1468 | eina_log_threads_init(void) | ||
1469 | { | ||
1470 | #ifdef EINA_ENABLE_LOG | ||
1471 | if (_threads_inited) return; | ||
1472 | _main_thread = SELF(); | ||
1473 | if (!INIT()) return; | ||
1474 | _threads_inited = EINA_TRUE; | ||
1475 | #endif | ||
1476 | } | ||
1477 | |||
1478 | /** | ||
1479 | * @internal | ||
1480 | * @brief Shut down the log mutex. | ||
1481 | * | ||
1482 | * This function shuts down the mutex in the log module. | ||
1483 | * It is called by eina_threads_shutdown(). | ||
1484 | * | ||
1485 | * @see eina_threads_shutdown() | ||
1486 | */ | ||
1487 | void | ||
1488 | eina_log_threads_shutdown(void) | ||
1489 | { | ||
1490 | #ifdef EINA_ENABLE_LOG | ||
1491 | if (!_threads_inited) return; | ||
1492 | CHECK_MAIN(); | ||
1493 | SHUTDOWN(); | ||
1494 | _threads_enabled = EINA_FALSE; | ||
1495 | _threads_inited = EINA_FALSE; | ||
1496 | #endif | ||
1497 | } | ||
1498 | |||
1499 | #endif | ||
1500 | |||
1501 | /*============================================================================* | ||
1502 | * API * | ||
1503 | *============================================================================*/ | ||
1504 | |||
1505 | /** | ||
1506 | * @cond LOCAL | ||
1507 | */ | ||
1508 | |||
1509 | EAPI int EINA_LOG_DOMAIN_GLOBAL = 0; | ||
1510 | |||
1511 | /** | ||
1512 | * @endcond | ||
1513 | */ | ||
1514 | |||
1515 | EAPI void | ||
1516 | eina_log_threads_enable(void) | ||
1517 | { | ||
1518 | #if defined (EFL_HAVE_THREADS) && defined (EINA_ENABLE_LOG) | ||
1519 | if (_threads_enabled) return; | ||
1520 | if (!_threads_inited) eina_log_threads_init(); | ||
1521 | _threads_enabled = EINA_TRUE; | ||
1522 | eina_log_print_prefix_update(); | ||
1523 | #endif | ||
1524 | } | ||
1525 | |||
1526 | EAPI void | ||
1527 | eina_log_print_cb_set(Eina_Log_Print_Cb cb, void *data) | ||
1528 | { | ||
1529 | #ifdef EINA_ENABLE_LOG | ||
1530 | LOG_LOCK(); | ||
1531 | _print_cb = cb; | ||
1532 | _print_cb_data = data; | ||
1533 | eina_log_print_prefix_update(); | ||
1534 | LOG_UNLOCK(); | ||
1535 | #else | ||
1536 | (void) cb; | ||
1537 | (void) data; | ||
1538 | #endif | ||
1539 | } | ||
1540 | |||
1541 | EAPI void | ||
1542 | eina_log_level_set(int level) | ||
1543 | { | ||
1544 | #ifdef EINA_ENABLE_LOG | ||
1545 | _log_level = level; | ||
1546 | if (EINA_LIKELY((EINA_LOG_DOMAIN_GLOBAL >= 0) && | ||
1547 | ((unsigned int)EINA_LOG_DOMAIN_GLOBAL < _log_domains_count))) | ||
1548 | _log_domains[EINA_LOG_DOMAIN_GLOBAL].level = level; | ||
1549 | #else | ||
1550 | (void) level; | ||
1551 | #endif | ||
1552 | } | ||
1553 | |||
1554 | EAPI int | ||
1555 | eina_log_level_get(void) | ||
1556 | { | ||
1557 | #ifdef EINA_ENABLE_LOG | ||
1558 | return _log_level; | ||
1559 | #else | ||
1560 | return 0; | ||
1561 | #endif | ||
1562 | } | ||
1563 | |||
1564 | EAPI Eina_Bool | ||
1565 | eina_log_main_thread_check(void) | ||
1566 | { | ||
1567 | #if defined (EFL_HAVE_THREADS) && defined (EINA_ENABLE_LOG) | ||
1568 | return ((!_threads_enabled) || IS_MAIN(SELF())); | ||
1569 | #else | ||
1570 | return EINA_TRUE; | ||
1571 | #endif | ||
1572 | } | ||
1573 | |||
1574 | EAPI void | ||
1575 | eina_log_color_disable_set(Eina_Bool disabled) | ||
1576 | { | ||
1577 | #ifdef EINA_ENABLE_LOG | ||
1578 | _disable_color = disabled; | ||
1579 | #else | ||
1580 | (void) disabled; | ||
1581 | #endif | ||
1582 | } | ||
1583 | |||
1584 | EAPI Eina_Bool | ||
1585 | eina_log_color_disable_get(void) | ||
1586 | { | ||
1587 | #ifdef EINA_ENABLE_LOG | ||
1588 | return _disable_color; | ||
1589 | #else | ||
1590 | return EINA_TRUE; | ||
1591 | #endif | ||
1592 | } | ||
1593 | |||
1594 | EAPI void | ||
1595 | eina_log_file_disable_set(Eina_Bool disabled) | ||
1596 | { | ||
1597 | #ifdef EINA_ENABLE_LOG | ||
1598 | _disable_file = disabled; | ||
1599 | #else | ||
1600 | (void) disabled; | ||
1601 | #endif | ||
1602 | } | ||
1603 | |||
1604 | EAPI Eina_Bool | ||
1605 | eina_log_file_disable_get(void) | ||
1606 | { | ||
1607 | #ifdef EINA_ENABLE_LOG | ||
1608 | return _disable_file; | ||
1609 | #else | ||
1610 | return EINA_TRUE; | ||
1611 | #endif | ||
1612 | } | ||
1613 | |||
1614 | EAPI void | ||
1615 | eina_log_function_disable_set(Eina_Bool disabled) | ||
1616 | { | ||
1617 | #ifdef EINA_ENABLE_LOG | ||
1618 | _disable_function = disabled; | ||
1619 | #else | ||
1620 | (void) disabled; | ||
1621 | #endif | ||
1622 | } | ||
1623 | |||
1624 | EAPI Eina_Bool | ||
1625 | eina_log_function_disable_get(void) | ||
1626 | { | ||
1627 | #ifdef EINA_ENABLE_LOG | ||
1628 | return _disable_function; | ||
1629 | #else | ||
1630 | return EINA_TRUE; | ||
1631 | #endif | ||
1632 | } | ||
1633 | |||
1634 | EAPI void | ||
1635 | eina_log_abort_on_critical_set(Eina_Bool abort_on_critical) | ||
1636 | { | ||
1637 | #ifdef EINA_ENABLE_LOG | ||
1638 | _abort_on_critical = abort_on_critical; | ||
1639 | #else | ||
1640 | (void) abort_on_critical; | ||
1641 | #endif | ||
1642 | } | ||
1643 | |||
1644 | EAPI Eina_Bool | ||
1645 | eina_log_abort_on_critical_get(void) | ||
1646 | { | ||
1647 | #ifdef EINA_ENABLE_LOG | ||
1648 | return _abort_on_critical; | ||
1649 | #else | ||
1650 | return EINA_FALSE; | ||
1651 | #endif | ||
1652 | } | ||
1653 | |||
1654 | EAPI void | ||
1655 | eina_log_abort_on_critical_level_set(int critical_level) | ||
1656 | { | ||
1657 | #ifdef EINA_ENABLE_LOG | ||
1658 | _abort_level_on_critical = critical_level; | ||
1659 | #else | ||
1660 | (void) critical_level; | ||
1661 | #endif | ||
1662 | } | ||
1663 | |||
1664 | EAPI int | ||
1665 | eina_log_abort_on_critical_level_get(void) | ||
1666 | { | ||
1667 | #ifdef EINA_ENABLE_LOG | ||
1668 | return _abort_level_on_critical; | ||
1669 | #else | ||
1670 | return 0; | ||
1671 | #endif | ||
1672 | } | ||
1673 | |||
1674 | EAPI int | ||
1675 | eina_log_domain_register(const char *name, const char *color) | ||
1676 | { | ||
1677 | #ifdef EINA_ENABLE_LOG | ||
1678 | int r; | ||
1679 | |||
1680 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, -1); | ||
1681 | |||
1682 | LOG_LOCK(); | ||
1683 | r = eina_log_domain_register_unlocked(name, color); | ||
1684 | LOG_UNLOCK(); | ||
1685 | return r; | ||
1686 | #else | ||
1687 | (void) name; | ||
1688 | (void) color; | ||
1689 | return 0; | ||
1690 | #endif | ||
1691 | } | ||
1692 | |||
1693 | EAPI void | ||
1694 | eina_log_domain_unregister(int domain) | ||
1695 | { | ||
1696 | #ifdef EINA_ENABLE_LOG | ||
1697 | EINA_SAFETY_ON_FALSE_RETURN(domain >= 0); | ||
1698 | LOG_LOCK(); | ||
1699 | eina_log_domain_unregister_unlocked(domain); | ||
1700 | LOG_UNLOCK(); | ||
1701 | #else | ||
1702 | (void) domain; | ||
1703 | #endif | ||
1704 | } | ||
1705 | |||
1706 | EAPI void | ||
1707 | eina_log_domain_level_set(const char *domain_name, int level) | ||
1708 | { | ||
1709 | #ifdef EINA_ENABLE_LOG | ||
1710 | Eina_Log_Domain_Level_Pending *pending; | ||
1711 | size_t namelen; | ||
1712 | unsigned int i; | ||
1713 | |||
1714 | EINA_SAFETY_ON_NULL_RETURN(domain_name); | ||
1715 | |||
1716 | namelen = strlen(domain_name); | ||
1717 | |||
1718 | for (i = 0; i < _log_domains_count; i++) | ||
1719 | { | ||
1720 | if (_log_domains[i].deleted) | ||
1721 | continue; | ||
1722 | |||
1723 | if ((namelen != _log_domains[i].namelen) || | ||
1724 | (strcmp(_log_domains[i].name, domain_name) != 0)) | ||
1725 | continue; | ||
1726 | |||
1727 | _log_domains[i].level = level; | ||
1728 | return; | ||
1729 | } | ||
1730 | |||
1731 | EINA_INLIST_FOREACH(_pending_list, pending) | ||
1732 | { | ||
1733 | if ((namelen == pending->namelen) && | ||
1734 | (strcmp(pending->name, domain_name) == 0)) | ||
1735 | { | ||
1736 | pending->level = level; | ||
1737 | return; | ||
1738 | } | ||
1739 | } | ||
1740 | |||
1741 | pending = malloc(sizeof(Eina_Log_Domain_Level_Pending) + namelen + 1); | ||
1742 | if (!pending) | ||
1743 | return; | ||
1744 | |||
1745 | pending->level = level; | ||
1746 | pending->namelen = namelen; | ||
1747 | memcpy(pending->name, domain_name, namelen + 1); | ||
1748 | |||
1749 | _pending_list = eina_inlist_append(_pending_list, EINA_INLIST_GET(pending)); | ||
1750 | #else | ||
1751 | (void) domain_name; | ||
1752 | (void) level; | ||
1753 | #endif | ||
1754 | } | ||
1755 | |||
1756 | EAPI int | ||
1757 | eina_log_domain_level_get(const char *domain_name) | ||
1758 | { | ||
1759 | #ifdef EINA_ENABLE_LOG | ||
1760 | Eina_Log_Domain_Level_Pending *pending; | ||
1761 | size_t namelen; | ||
1762 | unsigned int i; | ||
1763 | |||
1764 | EINA_SAFETY_ON_NULL_RETURN_VAL(domain_name, EINA_LOG_LEVEL_UNKNOWN); | ||
1765 | |||
1766 | namelen = strlen(domain_name); | ||
1767 | |||
1768 | for (i = 0; i < _log_domains_count; i++) | ||
1769 | { | ||
1770 | if (_log_domains[i].deleted) | ||
1771 | continue; | ||
1772 | |||
1773 | if ((namelen != _log_domains[i].namelen) || | ||
1774 | (strcmp(_log_domains[i].name, domain_name) != 0)) | ||
1775 | continue; | ||
1776 | |||
1777 | return _log_domains[i].level; | ||
1778 | } | ||
1779 | |||
1780 | EINA_INLIST_FOREACH(_pending_list, pending) | ||
1781 | { | ||
1782 | if ((namelen == pending->namelen) && | ||
1783 | (strcmp(pending->name, domain_name) == 0)) | ||
1784 | return pending->level; | ||
1785 | } | ||
1786 | |||
1787 | EINA_INLIST_FOREACH(_glob_list, pending) | ||
1788 | { | ||
1789 | if (!fnmatch(pending->name, domain_name, 0)) | ||
1790 | return pending->level; | ||
1791 | } | ||
1792 | |||
1793 | return _log_level; | ||
1794 | #else | ||
1795 | (void) domain_name; | ||
1796 | return 0; | ||
1797 | #endif | ||
1798 | } | ||
1799 | |||
1800 | EAPI int | ||
1801 | eina_log_domain_registered_level_get(int domain) | ||
1802 | { | ||
1803 | #ifdef EINA_ENABLE_LOG | ||
1804 | EINA_SAFETY_ON_FALSE_RETURN_VAL(domain >= 0, EINA_LOG_LEVEL_UNKNOWN); | ||
1805 | EINA_SAFETY_ON_FALSE_RETURN_VAL((unsigned int)domain < _log_domains_count, | ||
1806 | EINA_LOG_LEVEL_UNKNOWN); | ||
1807 | EINA_SAFETY_ON_TRUE_RETURN_VAL(_log_domains[domain].deleted, | ||
1808 | EINA_LOG_LEVEL_UNKNOWN); | ||
1809 | return _log_domains[domain].level; | ||
1810 | #else | ||
1811 | (void) domain; | ||
1812 | return 0; | ||
1813 | #endif | ||
1814 | } | ||
1815 | |||
1816 | EAPI void | ||
1817 | eina_log_print_cb_stderr(const Eina_Log_Domain *d, | ||
1818 | Eina_Log_Level level, | ||
1819 | const char *file, | ||
1820 | const char *fnc, | ||
1821 | int line, | ||
1822 | const char *fmt, | ||
1823 | __UNUSED__ void *data, | ||
1824 | va_list args) | ||
1825 | { | ||
1826 | #ifdef EINA_ENABLE_LOG | ||
1827 | _eina_log_print_prefix(stderr, d, level, file, fnc, line); | ||
1828 | vfprintf(stderr, fmt, args); | ||
1829 | putc('\n', stderr); | ||
1830 | #else | ||
1831 | (void) d; | ||
1832 | (void) level; | ||
1833 | (void) file; | ||
1834 | (void) fnc; | ||
1835 | (void) line; | ||
1836 | (void) fmt; | ||
1837 | (void) data; | ||
1838 | (void) args; | ||
1839 | #endif | ||
1840 | } | ||
1841 | |||
1842 | EAPI void | ||
1843 | eina_log_print_cb_stdout(const Eina_Log_Domain *d, | ||
1844 | Eina_Log_Level level, | ||
1845 | const char *file, | ||
1846 | const char *fnc, | ||
1847 | int line, | ||
1848 | const char *fmt, | ||
1849 | __UNUSED__ void *data, | ||
1850 | va_list args) | ||
1851 | { | ||
1852 | #ifdef EINA_ENABLE_LOG | ||
1853 | _eina_log_print_prefix(stdout, d, level, file, fnc, line); | ||
1854 | vprintf(fmt, args); | ||
1855 | putchar('\n'); | ||
1856 | #else | ||
1857 | (void) d; | ||
1858 | (void) level; | ||
1859 | (void) file; | ||
1860 | (void) fnc; | ||
1861 | (void) line; | ||
1862 | (void) fmt; | ||
1863 | (void) data; | ||
1864 | (void) args; | ||
1865 | #endif | ||
1866 | } | ||
1867 | |||
1868 | EAPI void | ||
1869 | eina_log_print_cb_file(const Eina_Log_Domain *d, | ||
1870 | __UNUSED__ Eina_Log_Level level, | ||
1871 | const char *file, | ||
1872 | const char *fnc, | ||
1873 | int line, | ||
1874 | const char *fmt, | ||
1875 | void *data, | ||
1876 | va_list args) | ||
1877 | { | ||
1878 | #ifdef EINA_ENABLE_LOG | ||
1879 | FILE *f = data; | ||
1880 | #ifdef EFL_HAVE_THREADS | ||
1881 | if (_threads_enabled) | ||
1882 | { | ||
1883 | Thread cur; | ||
1884 | |||
1885 | cur = SELF(); | ||
1886 | if (IS_OTHER(cur)) | ||
1887 | { | ||
1888 | fprintf(f, "%s[T:%lu] %s:%d %s() ", d->name, (unsigned long)cur, | ||
1889 | file, line, fnc); | ||
1890 | goto end; | ||
1891 | } | ||
1892 | } | ||
1893 | |||
1894 | #endif | ||
1895 | fprintf(f, "%s<%u> %s:%d %s() ", d->name, eina_log_pid_get(), | ||
1896 | file, line, fnc); | ||
1897 | #ifdef EFL_HAVE_THREADS | ||
1898 | end: | ||
1899 | #endif | ||
1900 | vfprintf(f, fmt, args); | ||
1901 | putc('\n', f); | ||
1902 | #else | ||
1903 | (void) d; | ||
1904 | (void) file; | ||
1905 | (void) fnc; | ||
1906 | (void) line; | ||
1907 | (void) fmt; | ||
1908 | (void) data; | ||
1909 | (void) args; | ||
1910 | #endif | ||
1911 | } | ||
1912 | |||
1913 | EAPI void | ||
1914 | eina_log_print(int domain, Eina_Log_Level level, const char *file, | ||
1915 | const char *fnc, int line, const char *fmt, ...) | ||
1916 | { | ||
1917 | #ifdef EINA_ENABLE_LOG | ||
1918 | va_list args; | ||
1919 | |||
1920 | #ifdef EINA_SAFETY_CHECKS | ||
1921 | if (EINA_UNLIKELY(!file)) | ||
1922 | { | ||
1923 | fputs("ERR: eina_log_print() file == NULL\n", stderr); | ||
1924 | return; | ||
1925 | } | ||
1926 | |||
1927 | if (EINA_UNLIKELY(!fnc)) | ||
1928 | { | ||
1929 | fputs("ERR: eina_log_print() fnc == NULL\n", stderr); | ||
1930 | return; | ||
1931 | } | ||
1932 | |||
1933 | if (EINA_UNLIKELY(!fmt)) | ||
1934 | { | ||
1935 | fputs("ERR: eina_log_print() fmt == NULL\n", stderr); | ||
1936 | return; | ||
1937 | } | ||
1938 | |||
1939 | #endif | ||
1940 | va_start(args, fmt); | ||
1941 | LOG_LOCK(); | ||
1942 | eina_log_print_unlocked(domain, level, file, fnc, line, fmt, args); | ||
1943 | LOG_UNLOCK(); | ||
1944 | va_end(args); | ||
1945 | #else | ||
1946 | (void) domain; | ||
1947 | (void) level; | ||
1948 | (void) file; | ||
1949 | (void) fnc; | ||
1950 | (void) line; | ||
1951 | (void) fmt; | ||
1952 | #endif | ||
1953 | } | ||
1954 | |||
1955 | EAPI void | ||
1956 | eina_log_vprint(int domain, Eina_Log_Level level, const char *file, | ||
1957 | const char *fnc, int line, const char *fmt, va_list args) | ||
1958 | { | ||
1959 | #ifdef EINA_ENABLE_LOG | ||
1960 | |||
1961 | #ifdef EINA_SAFETY_CHECKS | ||
1962 | if (EINA_UNLIKELY(!file)) | ||
1963 | { | ||
1964 | fputs("ERR: eina_log_print() file == NULL\n", stderr); | ||
1965 | return; | ||
1966 | } | ||
1967 | |||
1968 | if (EINA_UNLIKELY(!fnc)) | ||
1969 | { | ||
1970 | fputs("ERR: eina_log_print() fnc == NULL\n", stderr); | ||
1971 | return; | ||
1972 | } | ||
1973 | |||
1974 | if (EINA_UNLIKELY(!fmt)) | ||
1975 | { | ||
1976 | fputs("ERR: eina_log_print() fmt == NULL\n", stderr); | ||
1977 | return; | ||
1978 | } | ||
1979 | |||
1980 | #endif | ||
1981 | LOG_LOCK(); | ||
1982 | eina_log_print_unlocked(domain, level, file, fnc, line, fmt, args); | ||
1983 | LOG_UNLOCK(); | ||
1984 | #else | ||
1985 | (void) domain; | ||
1986 | (void) level; | ||
1987 | (void) file; | ||
1988 | (void) fnc; | ||
1989 | (void) line; | ||
1990 | (void) fmt; | ||
1991 | (void) args; | ||
1992 | #endif | ||
1993 | } | ||
diff --git a/libraries/eina/src/lib/eina_magic.c b/libraries/eina/src/lib/eina_magic.c deleted file mode 100644 index a42db2d..0000000 --- a/libraries/eina/src/lib/eina_magic.c +++ /dev/null | |||
@@ -1,322 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdlib.h> | ||
24 | #include <string.h> | ||
25 | |||
26 | #ifdef HAVE_EVIL | ||
27 | # include <Evil.h> | ||
28 | #endif | ||
29 | |||
30 | #include "eina_config.h" | ||
31 | #include "eina_private.h" | ||
32 | #include "eina_error.h" | ||
33 | #include "eina_log.h" | ||
34 | |||
35 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
36 | #include "eina_safety_checks.h" | ||
37 | #include "eina_magic.h" | ||
38 | |||
39 | /*============================================================================* | ||
40 | * Local * | ||
41 | *============================================================================*/ | ||
42 | |||
43 | /** | ||
44 | * @cond LOCAL | ||
45 | */ | ||
46 | |||
47 | typedef struct _Eina_Magic_String Eina_Magic_String; | ||
48 | struct _Eina_Magic_String | ||
49 | { | ||
50 | Eina_Magic magic; | ||
51 | Eina_Bool string_allocated; | ||
52 | const char *string; | ||
53 | }; | ||
54 | |||
55 | static int _eina_magic_string_log_dom = -1; | ||
56 | |||
57 | #ifdef ERR | ||
58 | #undef ERR | ||
59 | #endif | ||
60 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_magic_string_log_dom, __VA_ARGS__) | ||
61 | |||
62 | #ifdef DBG | ||
63 | #undef DBG | ||
64 | #endif | ||
65 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_magic_string_log_dom, __VA_ARGS__) | ||
66 | |||
67 | static Eina_Magic_String *_eina_magic_strings = NULL; | ||
68 | static size_t _eina_magic_strings_count = 0; | ||
69 | static size_t _eina_magic_strings_allocated = 0; | ||
70 | static Eina_Bool _eina_magic_strings_dirty = 0; | ||
71 | |||
72 | static int | ||
73 | _eina_magic_strings_sort_cmp(const void *p1, const void *p2) | ||
74 | { | ||
75 | const Eina_Magic_String *a = p1, *b = p2; | ||
76 | return a->magic - b->magic; | ||
77 | } | ||
78 | |||
79 | static int | ||
80 | _eina_magic_strings_find_cmp(const void *p1, const void *p2) | ||
81 | { | ||
82 | Eina_Magic a = (Eina_Magic)(size_t)p1; | ||
83 | const Eina_Magic_String *b = p2; | ||
84 | return a - b->magic; | ||
85 | } | ||
86 | |||
87 | static Eina_Magic_String * | ||
88 | _eina_magic_strings_alloc(void) | ||
89 | { | ||
90 | size_t idx; | ||
91 | |||
92 | if (_eina_magic_strings_count == _eina_magic_strings_allocated) | ||
93 | { | ||
94 | void *tmp; | ||
95 | size_t size; | ||
96 | |||
97 | if (EINA_UNLIKELY(_eina_magic_strings_allocated == 0)) | ||
98 | size = 48; | ||
99 | else | ||
100 | size = _eina_magic_strings_allocated + 16; | ||
101 | |||
102 | tmp = realloc(_eina_magic_strings, sizeof(Eina_Magic_String) * size); | ||
103 | if (!tmp) | ||
104 | { | ||
105 | ERR("could not realloc magic_strings from %zu to %zu buckets.", | ||
106 | _eina_magic_strings_allocated, size); | ||
107 | return NULL; | ||
108 | } | ||
109 | |||
110 | _eina_magic_strings = tmp; | ||
111 | _eina_magic_strings_allocated = size; | ||
112 | } | ||
113 | |||
114 | idx = _eina_magic_strings_count; | ||
115 | _eina_magic_strings_count++; | ||
116 | return _eina_magic_strings + idx; | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * @endcond | ||
121 | */ | ||
122 | |||
123 | /*============================================================================* | ||
124 | * Global * | ||
125 | *============================================================================*/ | ||
126 | |||
127 | EAPI Eina_Error EINA_ERROR_MAGIC_FAILED = 0; | ||
128 | |||
129 | static const char EINA_ERROR_MAGIC_FAILED_STR[] = "Magic check failed."; | ||
130 | |||
131 | /** | ||
132 | * @internal | ||
133 | * @brief Initialize the magic string module. | ||
134 | * | ||
135 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
136 | * | ||
137 | * This function sets up the magic string module of Eina. It is called by | ||
138 | * eina_init(). | ||
139 | * | ||
140 | * @see eina_init() | ||
141 | */ | ||
142 | Eina_Bool | ||
143 | eina_magic_string_init(void) | ||
144 | { | ||
145 | _eina_magic_string_log_dom = eina_log_domain_register | ||
146 | ("eina_magic_string", EINA_LOG_COLOR_DEFAULT); | ||
147 | if (_eina_magic_string_log_dom < 0) | ||
148 | { | ||
149 | EINA_LOG_ERR("Could not register log domain: eina_magic_string"); | ||
150 | return EINA_FALSE; | ||
151 | } | ||
152 | EINA_ERROR_MAGIC_FAILED = eina_error_msg_static_register( | ||
153 | EINA_ERROR_MAGIC_FAILED_STR); | ||
154 | |||
155 | return EINA_TRUE; | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * @internal | ||
160 | * @brief Shut down the magic string module. | ||
161 | * | ||
162 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
163 | * | ||
164 | * This function shuts down the magic string module set up by | ||
165 | * eina_magic string_init(). It is called by eina_shutdown(). | ||
166 | * | ||
167 | * @see eina_shutdown() | ||
168 | */ | ||
169 | Eina_Bool | ||
170 | eina_magic_string_shutdown(void) | ||
171 | { | ||
172 | Eina_Magic_String *ems, *ems_end; | ||
173 | |||
174 | ems = _eina_magic_strings; | ||
175 | ems_end = ems + _eina_magic_strings_count; | ||
176 | |||
177 | for (; ems < ems_end; ems++) | ||
178 | if (ems->string_allocated) | ||
179 | free((char *)ems->string); | ||
180 | |||
181 | free(_eina_magic_strings); | ||
182 | _eina_magic_strings = NULL; | ||
183 | _eina_magic_strings_count = 0; | ||
184 | _eina_magic_strings_allocated = 0; | ||
185 | |||
186 | eina_log_domain_unregister(_eina_magic_string_log_dom); | ||
187 | _eina_magic_string_log_dom = -1; | ||
188 | |||
189 | return EINA_TRUE; | ||
190 | } | ||
191 | |||
192 | /*============================================================================* | ||
193 | * API * | ||
194 | *============================================================================*/ | ||
195 | EAPI const char * | ||
196 | eina_magic_string_get(Eina_Magic magic) | ||
197 | { | ||
198 | Eina_Magic_String *ems; | ||
199 | |||
200 | if (!_eina_magic_strings) | ||
201 | return "(none)"; | ||
202 | |||
203 | if (_eina_magic_strings_dirty) | ||
204 | { | ||
205 | qsort(_eina_magic_strings, _eina_magic_strings_count, | ||
206 | sizeof(Eina_Magic_String), _eina_magic_strings_sort_cmp); | ||
207 | _eina_magic_strings_dirty = 0; | ||
208 | } | ||
209 | |||
210 | ems = bsearch((void *)(size_t)magic, _eina_magic_strings, | ||
211 | _eina_magic_strings_count, sizeof(Eina_Magic_String), | ||
212 | _eina_magic_strings_find_cmp); | ||
213 | if (ems) | ||
214 | return ems->string ? ems->string : "(undefined)"; | ||
215 | |||
216 | return "(unknown)"; | ||
217 | } | ||
218 | |||
219 | EAPI Eina_Bool | ||
220 | eina_magic_string_set(Eina_Magic magic, const char *magic_name) | ||
221 | { | ||
222 | Eina_Magic_String *ems; | ||
223 | |||
224 | EINA_SAFETY_ON_NULL_RETURN_VAL(magic_name, EINA_FALSE); | ||
225 | |||
226 | ems = _eina_magic_strings_alloc(); | ||
227 | if (!ems) | ||
228 | return EINA_FALSE; | ||
229 | |||
230 | ems->magic = magic; | ||
231 | ems->string_allocated = EINA_TRUE; | ||
232 | ems->string = strdup(magic_name); | ||
233 | if (!ems->string) | ||
234 | { | ||
235 | ERR("could not allocate string '%s'", magic_name); | ||
236 | _eina_magic_strings_count--; | ||
237 | return EINA_FALSE; | ||
238 | } | ||
239 | |||
240 | _eina_magic_strings_dirty = 1; | ||
241 | return EINA_TRUE; | ||
242 | } | ||
243 | |||
244 | EAPI Eina_Bool | ||
245 | eina_magic_string_static_set(Eina_Magic magic, const char *magic_name) | ||
246 | { | ||
247 | Eina_Magic_String *ems; | ||
248 | |||
249 | EINA_SAFETY_ON_NULL_RETURN_VAL(magic_name, EINA_FALSE); | ||
250 | |||
251 | ems = _eina_magic_strings_alloc(); | ||
252 | if (!ems) | ||
253 | return EINA_FALSE; | ||
254 | |||
255 | ems->magic = magic; | ||
256 | ems->string_allocated = EINA_FALSE; | ||
257 | ems->string = magic_name; | ||
258 | |||
259 | _eina_magic_strings_dirty = 1; | ||
260 | return EINA_TRUE; | ||
261 | } | ||
262 | |||
263 | #ifdef eina_magic_fail | ||
264 | # undef eina_magic_fail | ||
265 | #endif | ||
266 | |||
267 | EAPI void | ||
268 | eina_magic_fail(void *d, | ||
269 | Eina_Magic m, | ||
270 | Eina_Magic req_m, | ||
271 | const char *file, | ||
272 | const char *fnc, | ||
273 | int line) | ||
274 | { | ||
275 | eina_error_set(EINA_ERROR_MAGIC_FAILED); | ||
276 | if (!d) | ||
277 | eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL, | ||
278 | file, fnc, line, | ||
279 | "*** Eina Magic Check Failed !!!\n" | ||
280 | " Input handle pointer is NULL !\n" | ||
281 | "*** NAUGHTY PROGRAMMER!!!\n" | ||
282 | "*** SPANK SPANK SPANK!!!\n" | ||
283 | "*** Now go fix your code. Tut tut tut!\n" | ||
284 | "\n"); | ||
285 | else | ||
286 | if (m == EINA_MAGIC_NONE) | ||
287 | eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL, | ||
288 | file, fnc, line, | ||
289 | "*** Eina Magic Check Failed !!!\n" | ||
290 | " Input handle has already been freed!\n" | ||
291 | "*** NAUGHTY PROGRAMMER!!!\n" | ||
292 | "*** SPANK SPANK SPANK!!!\n" | ||
293 | "*** Now go fix your code. Tut tut tut!\n" | ||
294 | "\n"); | ||
295 | else | ||
296 | if (m != req_m) | ||
297 | eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL, | ||
298 | file, fnc, line, | ||
299 | "*** Eina Magic Check Failed !!!\n" | ||
300 | " Input handle is wrong type\n" | ||
301 | " Expected: %08x - %s\n" | ||
302 | " Supplied: %08x - %s\n" | ||
303 | "*** NAUGHTY PROGRAMMER!!!\n" | ||
304 | "*** SPANK SPANK SPANK!!!\n" | ||
305 | "*** Now go fix your code. Tut tut tut!\n" | ||
306 | "\n", | ||
307 | req_m, eina_magic_string_get(req_m), | ||
308 | m, eina_magic_string_get(m)); | ||
309 | else | ||
310 | eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL, | ||
311 | file, fnc, line, | ||
312 | "*** Eina Magic Check Failed !!!\n" | ||
313 | " Why did you call me !\n" | ||
314 | "*** NAUGHTY PROGRAMMER!!!\n" | ||
315 | "*** SPANK SPANK SPANK!!!\n" | ||
316 | "*** Now go fix your code. Tut tut tut!\n" | ||
317 | "\n"); | ||
318 | } | ||
319 | |||
320 | /** | ||
321 | * @} | ||
322 | */ | ||
diff --git a/libraries/eina/src/lib/eina_main.c b/libraries/eina/src/lib/eina_main.c deleted file mode 100644 index f233929..0000000 --- a/libraries/eina/src/lib/eina_main.c +++ /dev/null | |||
@@ -1,440 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdio.h> | ||
24 | |||
25 | #ifdef EFL_HAVE_WIN32_THREADS | ||
26 | # define WIN32_LEAN_AND_MEAN | ||
27 | # include <windows.h> | ||
28 | # undef WIN32_LEAN_AND_MEAN | ||
29 | #endif | ||
30 | |||
31 | #ifdef EFL_HAVE_THREADS | ||
32 | # ifdef HAVE_SYS_TYPES_H | ||
33 | # include <sys/types.h> | ||
34 | # endif | ||
35 | # ifdef HAVE_UNISTD_H | ||
36 | # include <unistd.h> | ||
37 | # endif | ||
38 | #endif | ||
39 | |||
40 | #ifdef HAVE_MCHECK | ||
41 | # ifdef HAVE_MTRACE | ||
42 | # define MT 1 | ||
43 | # endif | ||
44 | #endif | ||
45 | |||
46 | #ifdef MT | ||
47 | #include <mcheck.h> | ||
48 | #endif | ||
49 | |||
50 | #include "eina_lock.h" | ||
51 | #include "eina_config.h" | ||
52 | #include "eina_private.h" | ||
53 | #include "eina_types.h" | ||
54 | #include "eina_main.h" | ||
55 | #include "eina_error.h" | ||
56 | #include "eina_log.h" | ||
57 | #include "eina_hash.h" | ||
58 | #include "eina_binshare.h" | ||
59 | #include "eina_stringshare.h" | ||
60 | #include "eina_ustringshare.h" | ||
61 | #include "eina_list.h" | ||
62 | #include "eina_matrixsparse.h" | ||
63 | #include "eina_array.h" | ||
64 | #include "eina_counter.h" | ||
65 | #include "eina_benchmark.h" | ||
66 | #include "eina_magic.h" | ||
67 | #include "eina_rectangle.h" | ||
68 | #include "eina_safety_checks.h" | ||
69 | #include "eina_inlist.h" | ||
70 | #include "eina_inarray.h" | ||
71 | #include "eina_value.h" | ||
72 | #include "eina_model.h" | ||
73 | |||
74 | /*============================================================================* | ||
75 | * Local * | ||
76 | *============================================================================*/ | ||
77 | |||
78 | /** | ||
79 | * @cond LOCAL | ||
80 | */ | ||
81 | |||
82 | static Eina_Version _version = { VMAJ, VMIN, VMIC, VREV }; | ||
83 | |||
84 | static int _eina_main_count = 0; | ||
85 | #ifdef EFL_HAVE_THREADS | ||
86 | static int _eina_main_thread_count = 0; | ||
87 | #endif | ||
88 | static int _eina_log_dom = -1; | ||
89 | |||
90 | #ifdef ERR | ||
91 | #undef ERR | ||
92 | #endif | ||
93 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_log_dom, __VA_ARGS__) | ||
94 | |||
95 | #ifdef DBG | ||
96 | #undef DBG | ||
97 | #endif | ||
98 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_log_dom, __VA_ARGS__) | ||
99 | |||
100 | EAPI Eina_Bool _eina_threads_activated = EINA_FALSE; | ||
101 | EAPI Eina_Error EINA_ERROR_NOT_MAIN_LOOP = 0; | ||
102 | |||
103 | static const char EINA_ERROR_NOT_MAIN_LOOP_STR[] = "Main loop thread check failed."; | ||
104 | |||
105 | #ifdef EFL_HAVE_THREADS | ||
106 | # ifdef _WIN32 | ||
107 | EAPI DWORD _eina_main_loop; | ||
108 | # else | ||
109 | EAPI pthread_t _eina_main_loop; | ||
110 | # endif | ||
111 | static pid_t _eina_pid; | ||
112 | #endif | ||
113 | |||
114 | #ifdef MT | ||
115 | static int _mt_enabled = 0; | ||
116 | #endif | ||
117 | |||
118 | #ifdef EFL_HAVE_THREADS | ||
119 | EAPI int _eina_threads_debug = 0; | ||
120 | # if !defined(_WIN32_WCE) && !defined(_WIN32) | ||
121 | EAPI pthread_mutex_t _eina_tracking_lock; | ||
122 | EAPI Eina_Inlist *_eina_tracking = NULL; | ||
123 | # endif | ||
124 | #endif | ||
125 | |||
126 | /* place module init/shutdown functions here to avoid other modules | ||
127 | * calling them by mistake. | ||
128 | */ | ||
129 | #define S(x) extern Eina_Bool eina_ ## x ## _init(void); \ | ||
130 | extern Eina_Bool eina_ ## x ## _shutdown(void) | ||
131 | S(log); | ||
132 | S(error); | ||
133 | S(safety_checks); | ||
134 | S(magic_string); | ||
135 | S(iterator); | ||
136 | S(accessor); | ||
137 | S(inarray); | ||
138 | S(array); | ||
139 | S(module); | ||
140 | S(mempool); | ||
141 | S(list); | ||
142 | S(binshare); | ||
143 | S(stringshare); | ||
144 | S(ustringshare); | ||
145 | S(matrixsparse); | ||
146 | S(convert); | ||
147 | S(counter); | ||
148 | S(benchmark); | ||
149 | S(rectangle); | ||
150 | S(strbuf); | ||
151 | S(ustrbuf); | ||
152 | S(quadtree); | ||
153 | S(simple_xml); | ||
154 | S(file); | ||
155 | S(prefix); | ||
156 | S(value); | ||
157 | S(model); | ||
158 | #undef S | ||
159 | |||
160 | struct eina_desc_setup | ||
161 | { | ||
162 | const char *name; | ||
163 | Eina_Bool (*init)(void); | ||
164 | Eina_Bool (*shutdown)(void); | ||
165 | }; | ||
166 | |||
167 | static const struct eina_desc_setup _eina_desc_setup[] = { | ||
168 | #define S(x) {# x, eina_ ## x ## _init, eina_ ## x ## _shutdown} | ||
169 | /* log is a special case as it needs printf */ | ||
170 | S(stringshare), | ||
171 | S(error), | ||
172 | S(safety_checks), | ||
173 | S(magic_string), | ||
174 | S(iterator), | ||
175 | S(accessor), | ||
176 | S(inarray), | ||
177 | S(array), | ||
178 | S(module), | ||
179 | S(mempool), | ||
180 | S(list), | ||
181 | S(binshare), | ||
182 | S(ustringshare), | ||
183 | S(matrixsparse), | ||
184 | S(convert), | ||
185 | S(counter), | ||
186 | S(benchmark), | ||
187 | S(rectangle), | ||
188 | S(strbuf), | ||
189 | S(ustrbuf), | ||
190 | S(quadtree), | ||
191 | S(simple_xml), | ||
192 | S(file), | ||
193 | S(prefix), | ||
194 | S(value), | ||
195 | S(model) | ||
196 | #undef S | ||
197 | }; | ||
198 | static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) / | ||
199 | sizeof(_eina_desc_setup[0]); | ||
200 | |||
201 | static void | ||
202 | _eina_shutdown_from_desc(const struct eina_desc_setup *itr) | ||
203 | { | ||
204 | for (itr--; itr >= _eina_desc_setup; itr--) | ||
205 | { | ||
206 | if (!itr->shutdown()) | ||
207 | ERR("Problems shutting down eina module '%s', ignored.", itr->name); | ||
208 | } | ||
209 | |||
210 | eina_log_domain_unregister(_eina_log_dom); | ||
211 | _eina_log_dom = -1; | ||
212 | eina_log_shutdown(); | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * @endcond | ||
217 | */ | ||
218 | |||
219 | /*============================================================================* | ||
220 | * Global * | ||
221 | *============================================================================*/ | ||
222 | |||
223 | |||
224 | /*============================================================================* | ||
225 | * API * | ||
226 | *============================================================================*/ | ||
227 | |||
228 | /** | ||
229 | * @var eina_version | ||
230 | * @brief Eina version (defined at configuration time) | ||
231 | */ | ||
232 | EAPI Eina_Version *eina_version = &_version; | ||
233 | |||
234 | EAPI int | ||
235 | eina_init(void) | ||
236 | { | ||
237 | const struct eina_desc_setup *itr, *itr_end; | ||
238 | |||
239 | if (EINA_LIKELY(_eina_main_count > 0)) | ||
240 | return ++_eina_main_count; | ||
241 | |||
242 | #ifdef MT | ||
243 | if ((getenv("EINA_MTRACE")) && (getenv("MALLOC_TRACE"))) | ||
244 | { | ||
245 | _mt_enabled = 1; | ||
246 | mtrace(); | ||
247 | } | ||
248 | #endif | ||
249 | |||
250 | if (!eina_log_init()) | ||
251 | { | ||
252 | fprintf(stderr, "Could not initialize eina logging system.\n"); | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | _eina_log_dom = eina_log_domain_register("eina", EINA_LOG_COLOR_DEFAULT); | ||
257 | if (_eina_log_dom < 0) | ||
258 | { | ||
259 | EINA_LOG_ERR("Could not register log domain: eina"); | ||
260 | eina_log_shutdown(); | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | EINA_ERROR_NOT_MAIN_LOOP = eina_error_msg_static_register( | ||
265 | EINA_ERROR_NOT_MAIN_LOOP_STR); | ||
266 | |||
267 | #ifdef EFL_HAVE_THREADS | ||
268 | # ifdef _WIN32 | ||
269 | _eina_main_loop = GetCurrentThreadId(); | ||
270 | # else | ||
271 | _eina_main_loop = pthread_self(); | ||
272 | # endif | ||
273 | _eina_pid = getpid(); | ||
274 | #endif | ||
275 | |||
276 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
277 | pthread_mutex_init(&_eina_tracking_lock, NULL); | ||
278 | |||
279 | if (getenv("EINA_DEBUG_THREADS")) | ||
280 | _eina_threads_debug = atoi(getenv("EINA_DEBUG_THREADS")); | ||
281 | #endif | ||
282 | |||
283 | itr = _eina_desc_setup; | ||
284 | itr_end = itr + _eina_desc_setup_len; | ||
285 | for (; itr < itr_end; itr++) | ||
286 | { | ||
287 | if (!itr->init()) | ||
288 | { | ||
289 | ERR("Could not initialize eina module '%s'.", itr->name); | ||
290 | _eina_shutdown_from_desc(itr); | ||
291 | return 0; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | _eina_main_count = 1; | ||
296 | return 1; | ||
297 | } | ||
298 | |||
299 | EAPI int | ||
300 | eina_shutdown(void) | ||
301 | { | ||
302 | _eina_main_count--; | ||
303 | if (EINA_UNLIKELY(_eina_main_count == 0)) | ||
304 | { | ||
305 | _eina_shutdown_from_desc(_eina_desc_setup + _eina_desc_setup_len); | ||
306 | |||
307 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
308 | pthread_mutex_destroy(&_eina_tracking_lock); | ||
309 | #endif | ||
310 | #ifdef MT | ||
311 | if (_mt_enabled) | ||
312 | { | ||
313 | muntrace(); | ||
314 | _mt_enabled = 0; | ||
315 | } | ||
316 | #endif | ||
317 | } | ||
318 | |||
319 | return _eina_main_count; | ||
320 | } | ||
321 | |||
322 | |||
323 | EAPI int | ||
324 | eina_threads_init(void) | ||
325 | { | ||
326 | #ifdef EFL_HAVE_THREADS | ||
327 | int ret; | ||
328 | |||
329 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
330 | assert(pthread_equal(_eina_main_loop, pthread_self())); | ||
331 | #endif | ||
332 | |||
333 | ++_eina_main_thread_count; | ||
334 | ret = _eina_main_thread_count; | ||
335 | |||
336 | if(_eina_main_thread_count > 1) | ||
337 | return ret; | ||
338 | |||
339 | eina_share_common_threads_init(); | ||
340 | eina_log_threads_init(); | ||
341 | _eina_threads_activated = EINA_TRUE; | ||
342 | |||
343 | return ret; | ||
344 | #else | ||
345 | return 0; | ||
346 | #endif | ||
347 | } | ||
348 | |||
349 | EAPI int | ||
350 | eina_threads_shutdown(void) | ||
351 | { | ||
352 | #ifdef EFL_HAVE_THREADS | ||
353 | int ret; | ||
354 | |||
355 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
356 | const Eina_Lock *lk; | ||
357 | |||
358 | assert(pthread_equal(_eina_main_loop, pthread_self())); | ||
359 | assert(_eina_main_thread_count > 0); | ||
360 | #endif | ||
361 | |||
362 | ret = --_eina_main_thread_count; | ||
363 | if(_eina_main_thread_count > 0) | ||
364 | return ret; | ||
365 | |||
366 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
367 | pthread_mutex_lock(&_eina_tracking_lock); | ||
368 | if (_eina_tracking) | ||
369 | { | ||
370 | fprintf(stderr, "*************************\n"); | ||
371 | fprintf(stderr, "* The IMPOSSIBLE HAPPEN *\n"); | ||
372 | fprintf(stderr, "* LOCK STILL TAKEN : *\n"); | ||
373 | fprintf(stderr, "*************************\n"); | ||
374 | EINA_INLIST_FOREACH(_eina_tracking, lk) | ||
375 | eina_lock_debug(lk); | ||
376 | fprintf(stderr, "*************************\n"); | ||
377 | abort(); | ||
378 | } | ||
379 | pthread_mutex_unlock(&_eina_tracking_lock); | ||
380 | #endif | ||
381 | |||
382 | eina_share_common_threads_shutdown(); | ||
383 | eina_log_threads_shutdown(); | ||
384 | |||
385 | _eina_threads_activated = EINA_FALSE; | ||
386 | |||
387 | return ret; | ||
388 | #else | ||
389 | return 0; | ||
390 | #endif | ||
391 | } | ||
392 | |||
393 | EAPI Eina_Bool | ||
394 | eina_main_loop_is(void) | ||
395 | { | ||
396 | #ifdef EFL_HAVE_THREADS | ||
397 | pid_t pid = getpid(); | ||
398 | |||
399 | # ifdef _WIN32 | ||
400 | if (pid != _eina_pid) | ||
401 | { | ||
402 | _eina_pid = pid; | ||
403 | _eina_main_loop = GetCurrentThreadId(); | ||
404 | return EINA_TRUE; | ||
405 | } | ||
406 | if (_eina_main_loop == GetCurrentThreadId()) | ||
407 | return EINA_TRUE; | ||
408 | # else | ||
409 | if (pid != _eina_pid) | ||
410 | { | ||
411 | /* This is in case of a fork, but don't like the solution */ | ||
412 | _eina_pid = pid; | ||
413 | _eina_main_loop = pthread_self(); | ||
414 | return EINA_TRUE; | ||
415 | } | ||
416 | |||
417 | if (pthread_equal(_eina_main_loop, pthread_self())) | ||
418 | return EINA_TRUE; | ||
419 | # endif | ||
420 | #endif | ||
421 | return EINA_FALSE; | ||
422 | } | ||
423 | |||
424 | /** The purpose of this API should not be documented, it is used only by the one who know what they are doing. */ | ||
425 | EAPI void | ||
426 | eina_main_loop_define(void) | ||
427 | { | ||
428 | #ifdef EFL_HAVE_THREADS | ||
429 | _eina_pid = getpid(); | ||
430 | # ifdef _WIN32 | ||
431 | _eina_main_loop = GetCurrentThreadId(); | ||
432 | # else | ||
433 | _eina_main_loop = pthread_self(); | ||
434 | # endif | ||
435 | #endif | ||
436 | } | ||
437 | |||
438 | /** | ||
439 | * @} | ||
440 | */ | ||
diff --git a/libraries/eina/src/lib/eina_matrixsparse.c b/libraries/eina/src/lib/eina_matrixsparse.c deleted file mode 100644 index 59cd66b..0000000 --- a/libraries/eina/src/lib/eina_matrixsparse.c +++ /dev/null | |||
@@ -1,1423 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2009 Gustavo Sverzut Barbieri | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | |||
20 | /** | ||
21 | * @page tutorial_matrixsparse_page Sparse Matrix Tutorial | ||
22 | * | ||
23 | * to be written... | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #ifdef HAVE_CONFIG_H | ||
28 | # include "config.h" | ||
29 | #endif | ||
30 | |||
31 | #include <stdlib.h> | ||
32 | #include <stdio.h> | ||
33 | #include <string.h> | ||
34 | #include <assert.h> | ||
35 | |||
36 | #ifdef HAVE_EVIL | ||
37 | # include <Evil.h> | ||
38 | #endif | ||
39 | |||
40 | #include "eina_config.h" | ||
41 | #include "eina_private.h" | ||
42 | #include "eina_error.h" | ||
43 | #include "eina_log.h" | ||
44 | #include "eina_magic.h" | ||
45 | #include "eina_mempool.h" | ||
46 | |||
47 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
48 | #include "eina_safety_checks.h" | ||
49 | #include "eina_matrixsparse.h" | ||
50 | |||
51 | |||
52 | /*============================================================================* | ||
53 | * Local * | ||
54 | *============================================================================*/ | ||
55 | |||
56 | /** | ||
57 | * @cond LOCAL | ||
58 | */ | ||
59 | |||
60 | static const char EINA_MAGIC_MATRIXSPARSE_STR[] = "Eina Matrixsparse"; | ||
61 | static const char EINA_MAGIC_MATRIXSPARSE_ROW_STR[] = "Eina Matrixsparse Row"; | ||
62 | static const char EINA_MAGIC_MATRIXSPARSE_CELL_STR[] = "Eina Matrixsparse Cell"; | ||
63 | static const char EINA_MAGIC_MATRIXSPARSE_ITERATOR_STR[] = | ||
64 | "Eina Matrixsparse Iterator"; | ||
65 | static const char EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR_STR[] = | ||
66 | "Eina Matrixsparse Row Accessor"; | ||
67 | static const char EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR_STR[] = | ||
68 | "Eina Matrixsparse Row Iterator"; | ||
69 | static const char EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR_STR[] = | ||
70 | "Eina Matrixsparse Cell Accessor"; | ||
71 | static const char EINA_MAGIC_MATRIXSPARSE_CELL_ITERATOR_STR[] = | ||
72 | "Eina Matrixsparse Cell Iterator"; | ||
73 | |||
74 | |||
75 | #define EINA_MAGIC_CHECK_MATRIXSPARSE(d, ...) \ | ||
76 | do { \ | ||
77 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE)) \ | ||
78 | { \ | ||
79 | EINA_MAGIC_FAIL(d, EINA_MAGIC_MATRIXSPARSE); \ | ||
80 | return __VA_ARGS__; \ | ||
81 | } \ | ||
82 | } while(0) | ||
83 | |||
84 | #define EINA_MAGIC_CHECK_MATRIXSPARSE_ROW(d, ...) \ | ||
85 | do { \ | ||
86 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE_ROW)) \ | ||
87 | { \ | ||
88 | EINA_MAGIC_FAIL(d, EINA_MAGIC_MATRIXSPARSE_ROW); \ | ||
89 | return __VA_ARGS__; \ | ||
90 | } \ | ||
91 | } while(0) | ||
92 | |||
93 | #define EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(d, ...) \ | ||
94 | do { \ | ||
95 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE_CELL)) \ | ||
96 | { \ | ||
97 | EINA_MAGIC_FAIL(d, EINA_MAGIC_MATRIXSPARSE_CELL); \ | ||
98 | return __VA_ARGS__; \ | ||
99 | } \ | ||
100 | } while(0) | ||
101 | |||
102 | #define EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(d, ...) \ | ||
103 | do { \ | ||
104 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_MATRIXSPARSE_ITERATOR)) \ | ||
105 | { \ | ||
106 | EINA_MAGIC_FAIL(d, EINA_MAGIC_MATRIXSPARSE_ITERATOR); \ | ||
107 | return __VA_ARGS__; \ | ||
108 | } \ | ||
109 | } while(0) | ||
110 | |||
111 | struct _Eina_Matrixsparse_Cell | ||
112 | { | ||
113 | Eina_Matrixsparse_Cell *next; | ||
114 | Eina_Matrixsparse_Cell *prev; | ||
115 | |||
116 | void *data; | ||
117 | unsigned long col; | ||
118 | |||
119 | Eina_Matrixsparse_Row *parent; | ||
120 | |||
121 | EINA_MAGIC | ||
122 | }; | ||
123 | |||
124 | struct _Eina_Matrixsparse_Row | ||
125 | { | ||
126 | Eina_Matrixsparse_Row *next; | ||
127 | Eina_Matrixsparse_Row *prev; | ||
128 | |||
129 | Eina_Matrixsparse_Cell *cols; | ||
130 | Eina_Matrixsparse_Cell *last_col; | ||
131 | Eina_Matrixsparse_Cell *last_used; /* fast sequential access */ | ||
132 | unsigned long row; | ||
133 | |||
134 | Eina_Matrixsparse *parent; | ||
135 | |||
136 | EINA_MAGIC | ||
137 | }; | ||
138 | |||
139 | struct _Eina_Matrixsparse | ||
140 | { | ||
141 | Eina_Matrixsparse_Row *rows; | ||
142 | Eina_Matrixsparse_Row *last_row; | ||
143 | Eina_Matrixsparse_Row *last_used; /* fast sequential access */ | ||
144 | |||
145 | struct | ||
146 | { | ||
147 | unsigned long rows; | ||
148 | unsigned long cols; | ||
149 | } size; | ||
150 | |||
151 | struct | ||
152 | { | ||
153 | void (*func)(void *user_data, void *cell_data); | ||
154 | void *user_data; | ||
155 | } free; | ||
156 | |||
157 | EINA_MAGIC | ||
158 | }; | ||
159 | |||
160 | typedef struct _Eina_Matrixsparse_Iterator Eina_Matrixsparse_Iterator; | ||
161 | typedef struct _Eina_Matrixsparse_Iterator_Complete | ||
162 | Eina_Matrixsparse_Iterator_Complete; | ||
163 | |||
164 | struct _Eina_Matrixsparse_Iterator | ||
165 | { | ||
166 | Eina_Iterator iterator; | ||
167 | |||
168 | const Eina_Matrixsparse *m; | ||
169 | struct | ||
170 | { | ||
171 | const Eina_Matrixsparse_Row *row; | ||
172 | const Eina_Matrixsparse_Cell *col; | ||
173 | } ref; | ||
174 | |||
175 | EINA_MAGIC | ||
176 | }; | ||
177 | |||
178 | struct _Eina_Matrixsparse_Iterator_Complete | ||
179 | { | ||
180 | Eina_Iterator iterator; | ||
181 | |||
182 | const Eina_Matrixsparse *m; | ||
183 | struct | ||
184 | { | ||
185 | const Eina_Matrixsparse_Row *row; | ||
186 | const Eina_Matrixsparse_Cell *col; | ||
187 | } ref; | ||
188 | |||
189 | struct | ||
190 | { | ||
191 | unsigned long row, col; | ||
192 | } idx; | ||
193 | |||
194 | struct | ||
195 | { | ||
196 | Eina_Matrixsparse_Row row; | ||
197 | Eina_Matrixsparse_Cell col; | ||
198 | } dummy; | ||
199 | |||
200 | EINA_MAGIC | ||
201 | }; | ||
202 | |||
203 | /** | ||
204 | * @todo Eina_Matrixsparse_Row_Iterator: iterator over rows in matrix | ||
205 | * @todo Eina_Matrixsparse_Row_Accessor: accessor over rows in matrix | ||
206 | * @todo Eina_Matrixsparse_Cell_Iterator: iterator over cells in row | ||
207 | * @todo Eina_Matrixsparse_Cell_Accessor: accessor over cells in row | ||
208 | */ | ||
209 | |||
210 | static int _eina_matrixsparse_log_dom = -1; | ||
211 | |||
212 | #ifdef ERR | ||
213 | #undef ERR | ||
214 | #endif | ||
215 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_matrixsparse_log_dom, __VA_ARGS__) | ||
216 | |||
217 | #ifdef DBG | ||
218 | #undef DBG | ||
219 | #endif | ||
220 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_matrixsparse_log_dom, __VA_ARGS__) | ||
221 | |||
222 | static Eina_Mempool *_eina_matrixsparse_cell_mp = NULL; | ||
223 | static Eina_Mempool *_eina_matrixsparse_row_mp = NULL; | ||
224 | |||
225 | static inline void | ||
226 | _eina_matrixsparse_cell_free(Eina_Matrixsparse_Cell *c, void (*free_func)( | ||
227 | void *, | ||
228 | void *), void *user_data) | ||
229 | { | ||
230 | if (free_func) | ||
231 | free_func(user_data, c->data); | ||
232 | |||
233 | EINA_MAGIC_SET(c, EINA_MAGIC_NONE); | ||
234 | eina_mempool_free(_eina_matrixsparse_cell_mp, c); | ||
235 | } | ||
236 | |||
237 | static inline void | ||
238 | _eina_matrixsparse_cell_unlink(Eina_Matrixsparse_Cell *c) | ||
239 | { | ||
240 | Eina_Matrixsparse_Row *r = c->parent; | ||
241 | |||
242 | if (r->last_used == c) | ||
243 | { | ||
244 | if (c->next) | ||
245 | r->last_used = c->next; | ||
246 | else | ||
247 | r->last_used = c->prev; | ||
248 | } | ||
249 | |||
250 | if (r->last_col == c) | ||
251 | r->last_col = c->prev; | ||
252 | |||
253 | if (r->cols == c) | ||
254 | r->cols = c->next; | ||
255 | |||
256 | if (c->next && c->prev) | ||
257 | { | ||
258 | c->next->prev = c->prev; | ||
259 | c->prev->next = c->next; | ||
260 | } | ||
261 | else if (c->next) | ||
262 | c->next->prev = NULL; | ||
263 | else if (c->prev) | ||
264 | c->prev->next = NULL; | ||
265 | } | ||
266 | |||
267 | static inline void | ||
268 | _eina_matrixsparse_row_cells_free(Eina_Matrixsparse_Row *r, void (*free_func)( | ||
269 | void *, | ||
270 | void *), void *user_data) | ||
271 | { | ||
272 | Eina_Matrixsparse_Cell *c = r->cols; | ||
273 | while (c) | ||
274 | { | ||
275 | Eina_Matrixsparse_Cell *c_aux = c; | ||
276 | c = c->next; | ||
277 | _eina_matrixsparse_cell_free(c_aux, free_func, user_data); | ||
278 | } | ||
279 | } | ||
280 | |||
281 | static inline void | ||
282 | _eina_matrixsparse_row_free(Eina_Matrixsparse_Row *r, void (*free_func)(void *, | ||
283 | void *), | ||
284 | void *user_data) | ||
285 | { | ||
286 | _eina_matrixsparse_row_cells_free(r, free_func, user_data); | ||
287 | EINA_MAGIC_SET(r, EINA_MAGIC_NONE); | ||
288 | eina_mempool_free(_eina_matrixsparse_row_mp, r); | ||
289 | } | ||
290 | |||
291 | static inline void | ||
292 | _eina_matrixsparse_row_unlink(Eina_Matrixsparse_Row *r) | ||
293 | { | ||
294 | Eina_Matrixsparse *m = r->parent; | ||
295 | |||
296 | if (m->last_used == r) | ||
297 | { | ||
298 | if (r->next) | ||
299 | m->last_used = r->next; | ||
300 | else | ||
301 | m->last_used = r->prev; | ||
302 | } | ||
303 | |||
304 | if (m->last_row == r) | ||
305 | m->last_row = r->prev; | ||
306 | |||
307 | if (m->rows == r) | ||
308 | m->rows = r->next; | ||
309 | |||
310 | if (r->next && r->prev) | ||
311 | { | ||
312 | r->next->prev = r->prev; | ||
313 | r->prev->next = r->next; | ||
314 | } | ||
315 | else if (r->next) | ||
316 | r->next->prev = NULL; | ||
317 | else if (r->prev) | ||
318 | r->prev->next = NULL; | ||
319 | } | ||
320 | |||
321 | static inline void | ||
322 | _eina_matrixsparse_row_find_parms_get(const Eina_Matrixsparse *m, | ||
323 | unsigned long row, | ||
324 | Eina_Matrixsparse_Row **p_r, | ||
325 | int *p_dir) | ||
326 | { | ||
327 | Eina_Matrixsparse_Row *r; | ||
328 | unsigned long dist; | ||
329 | int dir; | ||
330 | |||
331 | dist = row - m->rows->row; | ||
332 | r = m->rows; | ||
333 | dir = 1; | ||
334 | if (dist > m->last_row->row - row) | ||
335 | { | ||
336 | dist = m->last_row->row - row; | ||
337 | r = m->last_row; | ||
338 | dir = -1; | ||
339 | } | ||
340 | |||
341 | if (m->last_used) | ||
342 | { | ||
343 | if (m->last_used->row < row) | ||
344 | { | ||
345 | if (dist > row - m->last_used->row) | ||
346 | { | ||
347 | /* dist = row = m->last_used->row; */ | ||
348 | r = m->last_used; | ||
349 | dir = 1; | ||
350 | } | ||
351 | } | ||
352 | else if (dist > m->last_used->row - row) | ||
353 | { | ||
354 | /* dist = m->last_used->row - row; */ | ||
355 | r = m->last_used; | ||
356 | dir = -1; | ||
357 | } | ||
358 | } | ||
359 | |||
360 | *p_r = r; | ||
361 | *p_dir = dir; | ||
362 | } | ||
363 | |||
364 | static inline void | ||
365 | _eina_matrixsparse_row_cell_find_parms_get(const Eina_Matrixsparse_Row *r, | ||
366 | unsigned long col, | ||
367 | Eina_Matrixsparse_Cell **p_c, | ||
368 | int *p_dir) | ||
369 | { | ||
370 | Eina_Matrixsparse_Cell *c; | ||
371 | unsigned long dist; | ||
372 | int dir; | ||
373 | |||
374 | dist = col - r->cols->col; | ||
375 | c = r->cols; | ||
376 | dir = 1; | ||
377 | if (dist > r->last_col->col - col) | ||
378 | { | ||
379 | dist = r->last_col->col - col; | ||
380 | c = r->last_col; | ||
381 | dir = -1; | ||
382 | } | ||
383 | |||
384 | if (r->last_used) | ||
385 | { | ||
386 | if (r->last_used->col < col) | ||
387 | { | ||
388 | if (dist > col - r->last_used->col) | ||
389 | { | ||
390 | /* dist = col = r->last_used->col; */ | ||
391 | c = r->last_used; | ||
392 | dir = 1; | ||
393 | } | ||
394 | } | ||
395 | else if (dist > r->last_used->col - col) | ||
396 | { | ||
397 | /* dist = r->last_used->col - col; */ | ||
398 | c = r->last_used; | ||
399 | dir = -1; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | *p_c = c; | ||
404 | *p_dir = dir; | ||
405 | } | ||
406 | |||
407 | static inline Eina_Matrixsparse_Row * | ||
408 | _eina_matrixsparse_row_idx_get(const Eina_Matrixsparse *m, unsigned long row) | ||
409 | { | ||
410 | Eina_Matrixsparse_Row *r; | ||
411 | int dir; | ||
412 | |||
413 | if (!m->rows) | ||
414 | return NULL; | ||
415 | |||
416 | if (m->rows->row == row) | ||
417 | return m->rows; | ||
418 | else if (m->rows->row > row) | ||
419 | return NULL; | ||
420 | |||
421 | if (m->last_row->row == row) | ||
422 | return m->last_row; | ||
423 | else if (m->last_row->row < row) | ||
424 | return NULL; | ||
425 | |||
426 | if ((m->last_used) && (m->last_used->row == row)) | ||
427 | return m->last_used; | ||
428 | |||
429 | _eina_matrixsparse_row_find_parms_get(m, row, &r, &dir); | ||
430 | assert(dir != 0); | ||
431 | if (dir > 0) | ||
432 | { | ||
433 | for (; r; r = r->next) | ||
434 | if (r->row == row) | ||
435 | { | ||
436 | ((Eina_Matrixsparse *)m)->last_used = r; | ||
437 | return r; | ||
438 | } | ||
439 | else if (r->row > row) | ||
440 | return NULL; | ||
441 | |||
442 | } | ||
443 | else if (dir < 0) | ||
444 | { | ||
445 | for (; r; r = r->prev) | ||
446 | if (r->row == row) | ||
447 | { | ||
448 | ((Eina_Matrixsparse *)m)->last_used = r; | ||
449 | return r; | ||
450 | } | ||
451 | else if (r->row < row) | ||
452 | return NULL; | ||
453 | } | ||
454 | |||
455 | return NULL; | ||
456 | } | ||
457 | |||
458 | static inline Eina_Matrixsparse_Cell * | ||
459 | _eina_matrixsparse_row_cell_idx_get(const Eina_Matrixsparse_Row *r, | ||
460 | unsigned long col) | ||
461 | { | ||
462 | Eina_Matrixsparse_Cell *c; | ||
463 | int dir; | ||
464 | |||
465 | if (!r->cols) | ||
466 | return NULL; | ||
467 | |||
468 | if (r->cols->col == col) | ||
469 | return r->cols; | ||
470 | else if (r->cols->col > col) | ||
471 | return NULL; | ||
472 | |||
473 | if (r->last_col->col == col) | ||
474 | return r->last_col; | ||
475 | else if (r->last_col->col < col) | ||
476 | return NULL; | ||
477 | |||
478 | if ((r->last_used) && (r->last_used->col == col)) | ||
479 | return r->last_used; | ||
480 | |||
481 | _eina_matrixsparse_row_cell_find_parms_get(r, col, &c, &dir); | ||
482 | assert(dir != 0); | ||
483 | if (dir > 0) | ||
484 | { | ||
485 | for (; r; c = c->next) | ||
486 | if (c->col == col) | ||
487 | { | ||
488 | ((Eina_Matrixsparse_Row *)r)->last_used = c; | ||
489 | return c; | ||
490 | } | ||
491 | else if (c->col > col) | ||
492 | return NULL; | ||
493 | |||
494 | } | ||
495 | else if (dir < 0) | ||
496 | { | ||
497 | for (; r; c = c->prev) | ||
498 | if (c->col == col) | ||
499 | { | ||
500 | ((Eina_Matrixsparse_Row *)r)->last_used = c; | ||
501 | return c; | ||
502 | } | ||
503 | else if (c->col < col) | ||
504 | return NULL; | ||
505 | } | ||
506 | |||
507 | return NULL; | ||
508 | } | ||
509 | |||
510 | static inline Eina_Matrixsparse_Cell * | ||
511 | _eina_matrixsparse_cell_idx_get(const Eina_Matrixsparse *m, | ||
512 | unsigned long row, | ||
513 | unsigned long col) | ||
514 | { | ||
515 | Eina_Matrixsparse_Row *r = _eina_matrixsparse_row_idx_get(m, row); | ||
516 | if (!r) | ||
517 | return NULL; | ||
518 | |||
519 | return _eina_matrixsparse_row_cell_idx_get(r, col); | ||
520 | } | ||
521 | |||
522 | static inline void | ||
523 | _eina_matrixsparse_row_idx_siblings_find(const Eina_Matrixsparse *m, | ||
524 | unsigned long row, | ||
525 | Eina_Matrixsparse_Row **p_prev, | ||
526 | Eina_Matrixsparse_Row **p_next) | ||
527 | { | ||
528 | Eina_Matrixsparse_Row *r; | ||
529 | int dir; | ||
530 | |||
531 | _eina_matrixsparse_row_find_parms_get(m, row, &r, &dir); | ||
532 | assert(dir != 0); | ||
533 | if (dir > 0) | ||
534 | { | ||
535 | for (; r; r = r->next) | ||
536 | if (r->row > row) | ||
537 | break; | ||
538 | |||
539 | assert(r != NULL); | ||
540 | *p_prev = r->prev; | ||
541 | *p_next = r; | ||
542 | } | ||
543 | else if (dir < 0) | ||
544 | { | ||
545 | for (; r; r = r->prev) | ||
546 | if (r->row < row) | ||
547 | break; | ||
548 | |||
549 | assert(r != NULL); | ||
550 | *p_prev = r; | ||
551 | *p_next = r->next; | ||
552 | } | ||
553 | } | ||
554 | |||
555 | static inline void | ||
556 | _eina_matrixsparse_row_cell_idx_siblings_find(const Eina_Matrixsparse_Row *r, | ||
557 | unsigned long col, | ||
558 | Eina_Matrixsparse_Cell **p_prev, | ||
559 | Eina_Matrixsparse_Cell **p_next) | ||
560 | { | ||
561 | Eina_Matrixsparse_Cell *c; | ||
562 | int dir; | ||
563 | |||
564 | _eina_matrixsparse_row_cell_find_parms_get(r, col, &c, &dir); | ||
565 | assert(dir != 0); | ||
566 | if (dir > 0) | ||
567 | { | ||
568 | for (; c; c = c->next) | ||
569 | if (c->col > col) | ||
570 | break; | ||
571 | |||
572 | assert(c != NULL); | ||
573 | *p_prev = c->prev; | ||
574 | *p_next = c; | ||
575 | } | ||
576 | else if (dir < 0) | ||
577 | { | ||
578 | for (; c; c = c->prev) | ||
579 | if (c->col < col) | ||
580 | break; | ||
581 | |||
582 | assert(c != NULL); | ||
583 | *p_prev = c; | ||
584 | *p_next = c->next; | ||
585 | } | ||
586 | } | ||
587 | |||
588 | static inline Eina_Matrixsparse_Row * | ||
589 | _eina_matrixsparse_row_idx_add(Eina_Matrixsparse *m, unsigned long row) | ||
590 | { | ||
591 | Eina_Matrixsparse_Row *r = eina_mempool_malloc | ||
592 | (_eina_matrixsparse_row_mp, sizeof(Eina_Matrixsparse_Row)); | ||
593 | if (!r) | ||
594 | return NULL; | ||
595 | |||
596 | if (!m->rows) | ||
597 | { | ||
598 | r->prev = NULL; | ||
599 | r->next = NULL; | ||
600 | m->rows = r; | ||
601 | m->last_row = r; | ||
602 | } | ||
603 | else if (row < m->rows->row) | ||
604 | { | ||
605 | r->prev = NULL; | ||
606 | r->next = m->rows; | ||
607 | m->rows->prev = r; | ||
608 | m->rows = r; | ||
609 | } | ||
610 | else if (row > m->last_row->row) | ||
611 | { | ||
612 | r->prev = m->last_row; | ||
613 | m->last_row->next = r; | ||
614 | r->next = NULL; | ||
615 | m->last_row = r; | ||
616 | } | ||
617 | else | ||
618 | { | ||
619 | Eina_Matrixsparse_Row *prev = NULL, *next = NULL; | ||
620 | _eina_matrixsparse_row_idx_siblings_find(m, row, &prev, &next); | ||
621 | assert(prev != NULL); | ||
622 | assert(next != NULL); | ||
623 | r->prev = prev; | ||
624 | r->next = next; | ||
625 | prev->next = r; | ||
626 | next->prev = r; | ||
627 | } | ||
628 | |||
629 | r->cols = NULL; | ||
630 | r->last_col = NULL; | ||
631 | r->last_used = NULL; | ||
632 | r->row = row; | ||
633 | r->parent = m; | ||
634 | EINA_MAGIC_SET(r, EINA_MAGIC_MATRIXSPARSE_ROW); | ||
635 | m->last_used = r; | ||
636 | return r; | ||
637 | } | ||
638 | |||
639 | static inline Eina_Matrixsparse_Cell * | ||
640 | _eina_matrixsparse_row_cell_idx_add(Eina_Matrixsparse_Row *r, | ||
641 | unsigned long col, | ||
642 | const void *data) | ||
643 | { | ||
644 | Eina_Matrixsparse_Cell *c = eina_mempool_malloc | ||
645 | (_eina_matrixsparse_cell_mp, sizeof(Eina_Matrixsparse_Cell)); | ||
646 | if (!c) | ||
647 | return NULL; | ||
648 | |||
649 | if (!r->cols) | ||
650 | { | ||
651 | c->prev = NULL; | ||
652 | c->next = NULL; | ||
653 | r->cols = c; | ||
654 | r->last_col = c; | ||
655 | } | ||
656 | else if (col < r->cols->col) | ||
657 | { | ||
658 | c->prev = NULL; | ||
659 | c->next = r->cols; | ||
660 | r->cols->prev = c; | ||
661 | r->cols = c; | ||
662 | } | ||
663 | else if (col > r->last_col->col) | ||
664 | { | ||
665 | c->prev = r->last_col; | ||
666 | r->last_col->next = c; | ||
667 | c->next = NULL; | ||
668 | r->last_col = c; | ||
669 | } | ||
670 | else | ||
671 | { | ||
672 | Eina_Matrixsparse_Cell *prev = NULL, *next = NULL; | ||
673 | _eina_matrixsparse_row_cell_idx_siblings_find(r, col, &prev, &next); | ||
674 | assert(prev != NULL); | ||
675 | assert(next != NULL); | ||
676 | c->prev = prev; | ||
677 | c->next = next; | ||
678 | prev->next = c; | ||
679 | next->prev = c; | ||
680 | } | ||
681 | |||
682 | c->data = (void *)data; | ||
683 | c->col = col; | ||
684 | c->parent = r; | ||
685 | EINA_MAGIC_SET(c, EINA_MAGIC_MATRIXSPARSE_CELL); | ||
686 | r->last_used = c; | ||
687 | return c; | ||
688 | } | ||
689 | |||
690 | static inline Eina_Bool | ||
691 | _eina_matrixsparse_cell_idx_add(Eina_Matrixsparse *m, | ||
692 | unsigned long row, | ||
693 | unsigned long col, | ||
694 | const void *data) | ||
695 | { | ||
696 | Eina_Matrixsparse_Row *r = _eina_matrixsparse_row_idx_get(m, row); | ||
697 | if (!r) | ||
698 | r = _eina_matrixsparse_row_idx_add(m, row); | ||
699 | |||
700 | if (!r) | ||
701 | return 0; | ||
702 | |||
703 | if (_eina_matrixsparse_row_cell_idx_add(r, col, data)) | ||
704 | return 1; | ||
705 | |||
706 | if (r->cols) | ||
707 | return 0; | ||
708 | |||
709 | _eina_matrixsparse_row_unlink(r); | ||
710 | _eina_matrixsparse_row_free(r, m->free.func, m->free.user_data); | ||
711 | return 0; | ||
712 | } | ||
713 | |||
714 | /*============================================================================* | ||
715 | * Iterators * | ||
716 | *============================================================================*/ | ||
717 | static Eina_Bool | ||
718 | _eina_matrixsparse_iterator_next(Eina_Matrixsparse_Iterator *it, void **data) | ||
719 | { | ||
720 | EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it, EINA_FALSE); | ||
721 | |||
722 | /* do not touch it->idx */ | ||
723 | |||
724 | if (!it->ref.col) | ||
725 | return 0; | ||
726 | |||
727 | *data = (Eina_Matrixsparse_Cell *)it->ref.col; | ||
728 | |||
729 | it->ref.col = it->ref.col->next; | ||
730 | if (!it->ref.col) | ||
731 | { | ||
732 | it->ref.row = it->ref.row->next; | ||
733 | if (it->ref.row) | ||
734 | it->ref.col = it->ref.row->cols; | ||
735 | } | ||
736 | |||
737 | return 1; | ||
738 | } | ||
739 | |||
740 | static Eina_Matrixsparse * | ||
741 | _eina_matrixsparse_iterator_get_container(Eina_Matrixsparse_Iterator *it) | ||
742 | { | ||
743 | EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it, NULL); | ||
744 | return (Eina_Matrixsparse *)it->m; | ||
745 | } | ||
746 | |||
747 | static void | ||
748 | _eina_matrixsparse_iterator_free(Eina_Matrixsparse_Iterator *it) | ||
749 | { | ||
750 | EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it); | ||
751 | EINA_MAGIC_SET(it, EINA_MAGIC_NONE); | ||
752 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_NONE); | ||
753 | free(it); | ||
754 | } | ||
755 | |||
756 | static Eina_Bool | ||
757 | _eina_matrixsparse_iterator_complete_next( | ||
758 | Eina_Matrixsparse_Iterator_Complete *it, | ||
759 | void **data) | ||
760 | { | ||
761 | EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it, EINA_FALSE); | ||
762 | |||
763 | if (it->idx.row >= it->m->size.rows) | ||
764 | return 0; | ||
765 | |||
766 | if (it->dummy.col.data) | ||
767 | ERR("Last iterator call changed dummy cell!"); | ||
768 | |||
769 | if ((it->ref.col) && | ||
770 | (it->ref.col->col == it->idx.col) && | ||
771 | (it->ref.row->row == it->idx.row)) | ||
772 | { | ||
773 | *data = (Eina_Matrixsparse_Cell *)it->ref.col; | ||
774 | it->ref.col = it->ref.col->next; | ||
775 | if (!it->ref.col) | ||
776 | { | ||
777 | it->ref.row = it->ref.row->next; | ||
778 | if (it->ref.row) | ||
779 | it->ref.col = it->ref.row->cols; | ||
780 | } | ||
781 | } | ||
782 | else | ||
783 | { | ||
784 | it->dummy.col.data = NULL; | ||
785 | it->dummy.col.col = it->idx.col; | ||
786 | it->dummy.row.row = it->idx.row; | ||
787 | *data = &it->dummy.col; | ||
788 | } | ||
789 | |||
790 | it->idx.col++; | ||
791 | if (it->idx.col == it->m->size.cols) | ||
792 | { | ||
793 | it->idx.col = 0; | ||
794 | it->idx.row++; | ||
795 | } | ||
796 | |||
797 | return 1; | ||
798 | } | ||
799 | |||
800 | static Eina_Matrixsparse * | ||
801 | _eina_matrixsparse_iterator_complete_get_container( | ||
802 | Eina_Matrixsparse_Iterator_Complete *it) | ||
803 | { | ||
804 | EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it, NULL); | ||
805 | return (Eina_Matrixsparse *)it->m; | ||
806 | } | ||
807 | |||
808 | static void | ||
809 | _eina_matrixsparse_iterator_complete_free( | ||
810 | Eina_Matrixsparse_Iterator_Complete *it) | ||
811 | { | ||
812 | EINA_MAGIC_CHECK_MATRIXSPARSE_ITERATOR(it); | ||
813 | |||
814 | if (it->dummy.col.data) | ||
815 | ERR("Last iterator call changed dummy cell!"); | ||
816 | |||
817 | EINA_MAGIC_SET(it, EINA_MAGIC_NONE); | ||
818 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_NONE); | ||
819 | free(it); | ||
820 | } | ||
821 | |||
822 | |||
823 | /** | ||
824 | * @endcond | ||
825 | */ | ||
826 | |||
827 | /*============================================================================* | ||
828 | * Global * | ||
829 | *============================================================================*/ | ||
830 | |||
831 | /** | ||
832 | * @internal | ||
833 | * @brief Initialize the matrixsparse module. | ||
834 | * | ||
835 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
836 | * | ||
837 | * This function sets up the matrixsparse module of Eina. It is called by | ||
838 | * eina_init(). | ||
839 | * | ||
840 | * This function creates mempool to speed up matrix rows and cells | ||
841 | * management, using EINA_MEMPOOL environment variable if it is set to | ||
842 | * choose the memory pool type to use. | ||
843 | * | ||
844 | * @see eina_init() | ||
845 | */ | ||
846 | Eina_Bool | ||
847 | eina_matrixsparse_init(void) | ||
848 | { | ||
849 | const char *choice, *tmp; | ||
850 | |||
851 | _eina_matrixsparse_log_dom = eina_log_domain_register("eina_matrixsparse", | ||
852 | EINA_LOG_COLOR_DEFAULT); | ||
853 | if (_eina_matrixsparse_log_dom < 0) | ||
854 | { | ||
855 | EINA_LOG_ERR("Could not register log domain: eina_matrixsparse"); | ||
856 | return EINA_FALSE; | ||
857 | } | ||
858 | |||
859 | #ifdef EINA_DEFAULT_MEMPOOL | ||
860 | choice = "pass_through"; | ||
861 | #else | ||
862 | choice = "chained_mempool"; | ||
863 | #endif | ||
864 | tmp = getenv("EINA_MEMPOOL"); | ||
865 | if (tmp && tmp[0]) | ||
866 | choice = tmp; | ||
867 | |||
868 | _eina_matrixsparse_cell_mp = eina_mempool_add | ||
869 | (choice, | ||
870 | "matrixsparse_cell", | ||
871 | NULL, | ||
872 | sizeof (Eina_Matrixsparse_Cell), | ||
873 | 120); | ||
874 | if (!_eina_matrixsparse_cell_mp) | ||
875 | { | ||
876 | ERR( | ||
877 | "Mempool for matrixsparse_cell cannot be allocated in matrixsparse init."); | ||
878 | goto on_init_fail; | ||
879 | } | ||
880 | |||
881 | _eina_matrixsparse_row_mp = eina_mempool_add | ||
882 | (choice, "matrixsparse_row", NULL, sizeof (Eina_Matrixsparse_Row), 120); | ||
883 | if (!_eina_matrixsparse_row_mp) | ||
884 | { | ||
885 | ERR( | ||
886 | "Mempool for matrixsparse_row cannot be allocated in matrixsparse init."); | ||
887 | goto on_init_fail; | ||
888 | } | ||
889 | |||
890 | #define EMS(n) eina_magic_string_static_set(n, n ## _STR) | ||
891 | EMS(EINA_MAGIC_MATRIXSPARSE); | ||
892 | EMS(EINA_MAGIC_MATRIXSPARSE_ROW); | ||
893 | EMS(EINA_MAGIC_MATRIXSPARSE_CELL); | ||
894 | EMS(EINA_MAGIC_MATRIXSPARSE_ITERATOR); | ||
895 | EMS(EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR); | ||
896 | EMS(EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR); | ||
897 | EMS(EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR); | ||
898 | EMS(EINA_MAGIC_MATRIXSPARSE_CELL_ITERATOR); | ||
899 | #undef EMS | ||
900 | |||
901 | return EINA_TRUE; | ||
902 | |||
903 | on_init_fail: | ||
904 | eina_log_domain_unregister(_eina_matrixsparse_log_dom); | ||
905 | _eina_matrixsparse_log_dom = -1; | ||
906 | return EINA_FALSE; | ||
907 | } | ||
908 | |||
909 | /** | ||
910 | * @internal | ||
911 | * @brief Shut down the matrixsparse module. | ||
912 | * | ||
913 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
914 | * | ||
915 | * This function shuts down the matrixsparse module set up by | ||
916 | * eina_matrixsparse_init(). It is called by eina_shutdown(). | ||
917 | * | ||
918 | * @see eina_shutdown() | ||
919 | */ | ||
920 | Eina_Bool | ||
921 | eina_matrixsparse_shutdown(void) | ||
922 | { | ||
923 | eina_mempool_del(_eina_matrixsparse_row_mp); | ||
924 | eina_mempool_del(_eina_matrixsparse_cell_mp); | ||
925 | |||
926 | eina_log_domain_unregister(_eina_matrixsparse_log_dom); | ||
927 | _eina_matrixsparse_log_dom = -1; | ||
928 | return EINA_TRUE; | ||
929 | } | ||
930 | |||
931 | /*============================================================================* | ||
932 | * API * | ||
933 | *============================================================================*/ | ||
934 | |||
935 | EAPI Eina_Matrixsparse * | ||
936 | eina_matrixsparse_new(unsigned long rows, unsigned long cols, void (*free_func)( | ||
937 | void *user_data, | ||
938 | void *cell_data), const void *user_data) | ||
939 | { | ||
940 | Eina_Matrixsparse *m; | ||
941 | |||
942 | EINA_SAFETY_ON_FALSE_RETURN_VAL(rows > 0, NULL); | ||
943 | EINA_SAFETY_ON_FALSE_RETURN_VAL(cols > 0, NULL); | ||
944 | |||
945 | m = malloc(sizeof(Eina_Matrixsparse)); | ||
946 | if (!m) | ||
947 | { | ||
948 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
949 | return NULL; | ||
950 | } | ||
951 | |||
952 | EINA_MAGIC_SET(m, EINA_MAGIC_MATRIXSPARSE); | ||
953 | |||
954 | m->rows = NULL; | ||
955 | m->last_row = NULL; | ||
956 | m->last_used = NULL; | ||
957 | |||
958 | m->size.rows = rows; | ||
959 | m->size.cols = cols; | ||
960 | m->free.func = free_func; | ||
961 | m->free.user_data = (void *)user_data; | ||
962 | |||
963 | eina_error_set(0); | ||
964 | return m; | ||
965 | } | ||
966 | |||
967 | EAPI void | ||
968 | eina_matrixsparse_free(Eina_Matrixsparse *m) | ||
969 | { | ||
970 | void (*free_func)(void *, void *); | ||
971 | void *user_data; | ||
972 | |||
973 | Eina_Matrixsparse_Row *r; | ||
974 | EINA_MAGIC_CHECK_MATRIXSPARSE(m); | ||
975 | |||
976 | free_func = m->free.func; | ||
977 | user_data = m->free.user_data; | ||
978 | |||
979 | r = m->rows; | ||
980 | while (r) | ||
981 | { | ||
982 | Eina_Matrixsparse_Row *r_aux = r; | ||
983 | r = r->next; | ||
984 | _eina_matrixsparse_row_free(r_aux, free_func, user_data); | ||
985 | } | ||
986 | |||
987 | EINA_MAGIC_SET(m, EINA_MAGIC_NONE); | ||
988 | free(m); | ||
989 | } | ||
990 | |||
991 | EAPI void | ||
992 | eina_matrixsparse_size_get(const Eina_Matrixsparse *m, | ||
993 | unsigned long *rows, | ||
994 | unsigned long *cols) | ||
995 | { | ||
996 | if (rows) | ||
997 | *rows = 0; | ||
998 | |||
999 | if (cols) | ||
1000 | *cols = 0; | ||
1001 | |||
1002 | EINA_MAGIC_CHECK_MATRIXSPARSE(m); | ||
1003 | if (rows) | ||
1004 | *rows = m->size.rows; | ||
1005 | |||
1006 | if (cols) | ||
1007 | *cols = m->size.cols; | ||
1008 | } | ||
1009 | |||
1010 | EAPI Eina_Bool | ||
1011 | eina_matrixsparse_size_set(Eina_Matrixsparse *m, | ||
1012 | unsigned long rows, | ||
1013 | unsigned long cols) | ||
1014 | { | ||
1015 | Eina_Bool update_last_used_row; | ||
1016 | Eina_Matrixsparse_Row *r; | ||
1017 | void (*free_func)(void *, void *); | ||
1018 | void *user_data; | ||
1019 | |||
1020 | EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); | ||
1021 | EINA_SAFETY_ON_FALSE_RETURN_VAL(rows > 0, 0); | ||
1022 | EINA_SAFETY_ON_FALSE_RETURN_VAL(cols > 0, 0); | ||
1023 | |||
1024 | if ((rows == m->size.rows) && (cols == m->size.cols)) | ||
1025 | return 1; | ||
1026 | |||
1027 | update_last_used_row = ((m->last_used) && (m->last_used->row >= rows)); | ||
1028 | free_func = m->free.func; | ||
1029 | user_data = m->free.user_data; | ||
1030 | |||
1031 | r = m->last_row; | ||
1032 | while (r && r->row >= rows) | ||
1033 | { | ||
1034 | Eina_Matrixsparse_Row *r_aux = r; | ||
1035 | r = r->prev; | ||
1036 | _eina_matrixsparse_row_free(r_aux, free_func, user_data); | ||
1037 | } | ||
1038 | if (!r) | ||
1039 | { | ||
1040 | m->last_row = NULL; | ||
1041 | m->rows = NULL; | ||
1042 | } | ||
1043 | else if (r != m->last_row) | ||
1044 | { | ||
1045 | r->next = NULL; | ||
1046 | m->last_row = r; | ||
1047 | } | ||
1048 | |||
1049 | if (update_last_used_row) | ||
1050 | m->last_used = m->last_row; | ||
1051 | |||
1052 | r = m->rows; | ||
1053 | while (r) | ||
1054 | { | ||
1055 | Eina_Matrixsparse_Cell *c = r->last_col; | ||
1056 | Eina_Bool update_last_used_col; | ||
1057 | update_last_used_col = ((r->last_used) && (r->last_used->col >= cols)); | ||
1058 | while (c && c->col >= cols) | ||
1059 | { | ||
1060 | Eina_Matrixsparse_Cell *c_aux = c; | ||
1061 | c = c->prev; | ||
1062 | _eina_matrixsparse_cell_free(c_aux, free_func, user_data); | ||
1063 | } | ||
1064 | if (!c) | ||
1065 | { | ||
1066 | Eina_Matrixsparse_Row *r_aux = r; | ||
1067 | r->cols = NULL; | ||
1068 | r->last_col = NULL; | ||
1069 | if (r->next) | ||
1070 | r->next->prev = r->prev; | ||
1071 | else | ||
1072 | m->last_row = r->prev; | ||
1073 | |||
1074 | if (r->prev) | ||
1075 | r->prev->next = r->next; | ||
1076 | else | ||
1077 | m->rows = r->next; | ||
1078 | |||
1079 | r = r->next; | ||
1080 | _eina_matrixsparse_row_free(r_aux, free_func, user_data); | ||
1081 | if ((update_last_used_row) && (m->last_used == r_aux)) | ||
1082 | m->last_used = r; | ||
1083 | } | ||
1084 | else | ||
1085 | { | ||
1086 | if (c != r->last_col) | ||
1087 | { | ||
1088 | c->next = NULL; | ||
1089 | r->last_col = c; | ||
1090 | } | ||
1091 | |||
1092 | if (update_last_used_col) | ||
1093 | r->last_used = r->last_col; | ||
1094 | |||
1095 | r = r->next; | ||
1096 | } | ||
1097 | } | ||
1098 | |||
1099 | update_last_used_row = 0; | ||
1100 | if (m->last_used) | ||
1101 | { | ||
1102 | if (m->last_row) | ||
1103 | update_last_used_row = m->last_used->row > m->last_row->row; | ||
1104 | else | ||
1105 | update_last_used_row = 1; | ||
1106 | } | ||
1107 | |||
1108 | if (update_last_used_row) | ||
1109 | m->last_used = m->last_row; | ||
1110 | |||
1111 | m->size.rows = rows; | ||
1112 | m->size.cols = cols; | ||
1113 | return 1; | ||
1114 | } | ||
1115 | |||
1116 | EAPI Eina_Bool | ||
1117 | eina_matrixsparse_cell_idx_get(const Eina_Matrixsparse *m, | ||
1118 | unsigned long row, | ||
1119 | unsigned long col, | ||
1120 | Eina_Matrixsparse_Cell **cell) | ||
1121 | { | ||
1122 | EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); | ||
1123 | EINA_SAFETY_ON_NULL_RETURN_VAL(cell, 0); | ||
1124 | *cell = NULL; | ||
1125 | EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0); | ||
1126 | EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0); | ||
1127 | *cell = _eina_matrixsparse_cell_idx_get(m, row, col); | ||
1128 | return 1; | ||
1129 | } | ||
1130 | |||
1131 | EAPI void * | ||
1132 | eina_matrixsparse_cell_data_get(const Eina_Matrixsparse_Cell *cell) | ||
1133 | { | ||
1134 | EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, NULL); | ||
1135 | return cell->data; | ||
1136 | } | ||
1137 | |||
1138 | EAPI void * | ||
1139 | eina_matrixsparse_data_idx_get(const Eina_Matrixsparse *m, | ||
1140 | unsigned long row, | ||
1141 | unsigned long col) | ||
1142 | { | ||
1143 | Eina_Matrixsparse_Cell *c; | ||
1144 | EINA_MAGIC_CHECK_MATRIXSPARSE(m, NULL); | ||
1145 | c = _eina_matrixsparse_cell_idx_get(m, row, col); | ||
1146 | if (c) | ||
1147 | return c->data; | ||
1148 | else | ||
1149 | return NULL; | ||
1150 | } | ||
1151 | |||
1152 | EAPI Eina_Bool | ||
1153 | eina_matrixsparse_cell_position_get(const Eina_Matrixsparse_Cell *cell, | ||
1154 | unsigned long *row, | ||
1155 | unsigned long *col) | ||
1156 | { | ||
1157 | if (row) | ||
1158 | *row = 0; | ||
1159 | |||
1160 | if (col) | ||
1161 | *col = 0; | ||
1162 | |||
1163 | EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, 0); | ||
1164 | EINA_MAGIC_CHECK_MATRIXSPARSE_ROW(cell->parent, 0); | ||
1165 | if (row) | ||
1166 | *row = cell->parent->row; | ||
1167 | |||
1168 | if (col) | ||
1169 | *col = cell->col; | ||
1170 | |||
1171 | return 1; | ||
1172 | } | ||
1173 | |||
1174 | EAPI Eina_Bool | ||
1175 | eina_matrixsparse_cell_data_replace(Eina_Matrixsparse_Cell *cell, | ||
1176 | const void *data, | ||
1177 | void **p_old) | ||
1178 | { | ||
1179 | if (p_old) | ||
1180 | *p_old = NULL; | ||
1181 | |||
1182 | EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, 0); | ||
1183 | |||
1184 | if (p_old) | ||
1185 | *p_old = cell->data; | ||
1186 | |||
1187 | cell->data = (void *)data; | ||
1188 | return 1; | ||
1189 | } | ||
1190 | |||
1191 | EAPI Eina_Bool | ||
1192 | eina_matrixsparse_cell_data_set(Eina_Matrixsparse_Cell *cell, const void *data) | ||
1193 | { | ||
1194 | Eina_Matrixsparse *m; | ||
1195 | |||
1196 | EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, 0); | ||
1197 | EINA_MAGIC_CHECK_MATRIXSPARSE_ROW(cell->parent, 0); | ||
1198 | EINA_MAGIC_CHECK_MATRIXSPARSE(cell->parent->parent, 0); | ||
1199 | |||
1200 | m = cell->parent->parent; | ||
1201 | |||
1202 | if (m->free.func) | ||
1203 | m->free.func(m->free.user_data, cell->data); | ||
1204 | |||
1205 | cell->data = (void *)data; | ||
1206 | return 1; | ||
1207 | } | ||
1208 | |||
1209 | EAPI Eina_Bool | ||
1210 | eina_matrixsparse_data_idx_replace(Eina_Matrixsparse *m, | ||
1211 | unsigned long row, | ||
1212 | unsigned long col, | ||
1213 | const void *data, | ||
1214 | void **p_old) | ||
1215 | { | ||
1216 | Eina_Matrixsparse_Cell *cell; | ||
1217 | |||
1218 | if (p_old) | ||
1219 | *p_old = NULL; | ||
1220 | |||
1221 | EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); | ||
1222 | EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0); | ||
1223 | EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0); | ||
1224 | |||
1225 | cell = _eina_matrixsparse_cell_idx_get(m, row, col); | ||
1226 | if (cell) | ||
1227 | { | ||
1228 | if (p_old) | ||
1229 | *p_old = cell->data; | ||
1230 | |||
1231 | cell->data = (void *)data; | ||
1232 | return 1; | ||
1233 | } | ||
1234 | |||
1235 | return _eina_matrixsparse_cell_idx_add(m, row, col, data); | ||
1236 | } | ||
1237 | |||
1238 | EAPI Eina_Bool | ||
1239 | eina_matrixsparse_data_idx_set(Eina_Matrixsparse *m, | ||
1240 | unsigned long row, | ||
1241 | unsigned long col, | ||
1242 | const void *data) | ||
1243 | { | ||
1244 | Eina_Matrixsparse_Cell *cell; | ||
1245 | |||
1246 | EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); | ||
1247 | EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0); | ||
1248 | EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0); | ||
1249 | |||
1250 | cell = _eina_matrixsparse_cell_idx_get(m, row, col); | ||
1251 | if (cell) | ||
1252 | { | ||
1253 | if (m->free.func) | ||
1254 | m->free.func(m->free.user_data, cell->data); | ||
1255 | |||
1256 | cell->data = (void *)data; | ||
1257 | return 1; | ||
1258 | } | ||
1259 | |||
1260 | return _eina_matrixsparse_cell_idx_add(m, row, col, data); | ||
1261 | } | ||
1262 | |||
1263 | EAPI Eina_Bool | ||
1264 | eina_matrixsparse_row_idx_clear(Eina_Matrixsparse *m, unsigned long row) | ||
1265 | { | ||
1266 | Eina_Matrixsparse_Row *r; | ||
1267 | |||
1268 | EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); | ||
1269 | EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0); | ||
1270 | |||
1271 | r = _eina_matrixsparse_row_idx_get(m, row); | ||
1272 | if (!r) | ||
1273 | return 1; | ||
1274 | |||
1275 | _eina_matrixsparse_row_unlink(r); | ||
1276 | _eina_matrixsparse_row_free(r, m->free.func, m->free.user_data); | ||
1277 | |||
1278 | return 1; | ||
1279 | } | ||
1280 | |||
1281 | EAPI Eina_Bool | ||
1282 | eina_matrixsparse_column_idx_clear(Eina_Matrixsparse *m, unsigned long col) | ||
1283 | { | ||
1284 | Eina_Matrixsparse_Row *r; | ||
1285 | void (*free_func)(void *, void *); | ||
1286 | void *user_data; | ||
1287 | |||
1288 | EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); | ||
1289 | EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0); | ||
1290 | |||
1291 | free_func = m->free.func; | ||
1292 | user_data = m->free.user_data; | ||
1293 | |||
1294 | for (r = m->rows; r; ) | ||
1295 | { | ||
1296 | Eina_Matrixsparse_Row *r_aux = r; | ||
1297 | Eina_Matrixsparse_Cell *c; | ||
1298 | |||
1299 | c = _eina_matrixsparse_row_cell_idx_get(r, col); | ||
1300 | r = r->next; | ||
1301 | |||
1302 | if (!c) | ||
1303 | continue; | ||
1304 | |||
1305 | if ((r_aux->cols != c) || (r_aux->last_col != c)) | ||
1306 | { | ||
1307 | _eina_matrixsparse_cell_unlink(c); | ||
1308 | _eina_matrixsparse_cell_free(c, free_func, user_data); | ||
1309 | } | ||
1310 | else | ||
1311 | { | ||
1312 | _eina_matrixsparse_row_unlink(r_aux); | ||
1313 | _eina_matrixsparse_row_free(r_aux, free_func, user_data); | ||
1314 | } | ||
1315 | } | ||
1316 | |||
1317 | return 1; | ||
1318 | } | ||
1319 | |||
1320 | EAPI Eina_Bool | ||
1321 | eina_matrixsparse_cell_idx_clear(Eina_Matrixsparse *m, | ||
1322 | unsigned long row, | ||
1323 | unsigned long col) | ||
1324 | { | ||
1325 | Eina_Matrixsparse_Cell *c; | ||
1326 | |||
1327 | EINA_MAGIC_CHECK_MATRIXSPARSE(m, 0); | ||
1328 | EINA_SAFETY_ON_FALSE_RETURN_VAL(row < m->size.rows, 0); | ||
1329 | EINA_SAFETY_ON_FALSE_RETURN_VAL(col < m->size.cols, 0); | ||
1330 | |||
1331 | c = _eina_matrixsparse_cell_idx_get(m, row, col); | ||
1332 | if (!c) | ||
1333 | return 1; | ||
1334 | |||
1335 | _eina_matrixsparse_cell_unlink(c); | ||
1336 | _eina_matrixsparse_cell_free(c, m->free.func, m->free.user_data); | ||
1337 | |||
1338 | return 1; | ||
1339 | } | ||
1340 | |||
1341 | EAPI Eina_Bool | ||
1342 | eina_matrixsparse_cell_clear(Eina_Matrixsparse_Cell *cell) | ||
1343 | { | ||
1344 | Eina_Matrixsparse *m; | ||
1345 | |||
1346 | EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, 0); | ||
1347 | EINA_MAGIC_CHECK_MATRIXSPARSE_ROW(cell->parent, 0); | ||
1348 | EINA_MAGIC_CHECK_MATRIXSPARSE(cell->parent->parent, 0); | ||
1349 | |||
1350 | m = cell->parent->parent; | ||
1351 | |||
1352 | _eina_matrixsparse_cell_unlink(cell); | ||
1353 | _eina_matrixsparse_cell_free(cell, m->free.func, m->free.user_data); | ||
1354 | return 1; | ||
1355 | } | ||
1356 | |||
1357 | EAPI Eina_Iterator * | ||
1358 | eina_matrixsparse_iterator_new(const Eina_Matrixsparse *m) | ||
1359 | { | ||
1360 | Eina_Matrixsparse_Iterator *it; | ||
1361 | |||
1362 | it = calloc(1, sizeof(*it)); | ||
1363 | if (!it) | ||
1364 | { | ||
1365 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
1366 | return NULL; | ||
1367 | } | ||
1368 | |||
1369 | EINA_MAGIC_SET(it, EINA_MAGIC_MATRIXSPARSE_ITERATOR); | ||
1370 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
1371 | |||
1372 | it->m = m; | ||
1373 | it->ref.row = m->rows; | ||
1374 | it->ref.col = m->rows ? m->rows->cols : NULL; | ||
1375 | |||
1376 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
1377 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_matrixsparse_iterator_next); | ||
1378 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
1379 | _eina_matrixsparse_iterator_get_container); | ||
1380 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_matrixsparse_iterator_free); | ||
1381 | return &it->iterator; | ||
1382 | } | ||
1383 | |||
1384 | EAPI Eina_Iterator * | ||
1385 | eina_matrixsparse_iterator_complete_new(const Eina_Matrixsparse *m) | ||
1386 | { | ||
1387 | Eina_Matrixsparse_Iterator_Complete *it; | ||
1388 | |||
1389 | it = calloc(1, sizeof(*it)); | ||
1390 | if (!it) | ||
1391 | { | ||
1392 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
1393 | return NULL; | ||
1394 | } | ||
1395 | |||
1396 | EINA_MAGIC_SET(it, EINA_MAGIC_MATRIXSPARSE_ITERATOR); | ||
1397 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
1398 | |||
1399 | it->m = m; | ||
1400 | it->idx.row = 0; | ||
1401 | it->idx.col = 0; | ||
1402 | it->ref.row = m->rows; | ||
1403 | it->ref.col = m->rows ? m->rows->cols : NULL; | ||
1404 | |||
1405 | it->dummy.row.next = it->dummy.row.prev = NULL; | ||
1406 | it->dummy.row.cols = it->dummy.row.last_col = it->dummy.row.last_used = NULL; | ||
1407 | it->dummy.row.parent = (Eina_Matrixsparse *)m; | ||
1408 | EINA_MAGIC_SET(&it->dummy.row, EINA_MAGIC_MATRIXSPARSE_ROW); | ||
1409 | |||
1410 | it->dummy.col.next = it->dummy.col.prev = NULL; | ||
1411 | it->dummy.col.data = NULL; | ||
1412 | it->dummy.col.parent = &it->dummy.row; | ||
1413 | EINA_MAGIC_SET(&it->dummy.col, EINA_MAGIC_MATRIXSPARSE_CELL); | ||
1414 | |||
1415 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
1416 | it->iterator.next = FUNC_ITERATOR_NEXT( | ||
1417 | _eina_matrixsparse_iterator_complete_next); | ||
1418 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
1419 | _eina_matrixsparse_iterator_complete_get_container); | ||
1420 | it->iterator.free = FUNC_ITERATOR_FREE( | ||
1421 | _eina_matrixsparse_iterator_complete_free); | ||
1422 | return &it->iterator; | ||
1423 | } | ||
diff --git a/libraries/eina/src/lib/eina_mempool.c b/libraries/eina/src/lib/eina_mempool.c deleted file mode 100644 index 065532e..0000000 --- a/libraries/eina/src/lib/eina_mempool.c +++ /dev/null | |||
@@ -1,387 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2007-2008 Jorge Luis Zapata Muga | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <assert.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <stdio.h> | ||
26 | #include <string.h> | ||
27 | |||
28 | #include "eina_config.h" | ||
29 | #include "eina_private.h" | ||
30 | #include "eina_hash.h" | ||
31 | #include "eina_module.h" | ||
32 | #include "eina_log.h" | ||
33 | #include "eina_main.h" | ||
34 | |||
35 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
36 | #include "eina_safety_checks.h" | ||
37 | #include "eina_mempool.h" | ||
38 | |||
39 | /*============================================================================* | ||
40 | * Local * | ||
41 | *============================================================================*/ | ||
42 | |||
43 | /** | ||
44 | * @cond LOCAL | ||
45 | */ | ||
46 | |||
47 | static Eina_Hash *_backends; | ||
48 | static Eina_Array *_modules; | ||
49 | static int _eina_mempool_log_dom = -1; | ||
50 | |||
51 | #ifdef ERR | ||
52 | #undef ERR | ||
53 | #endif | ||
54 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_mempool_log_dom, __VA_ARGS__) | ||
55 | |||
56 | #ifdef DBG | ||
57 | #undef DBG | ||
58 | #endif | ||
59 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_mempool_log_dom, __VA_ARGS__) | ||
60 | |||
61 | |||
62 | static Eina_Mempool * | ||
63 | _new_va(const char *name, | ||
64 | const char *context, | ||
65 | const char *options, | ||
66 | va_list args) | ||
67 | { | ||
68 | Eina_Mempool_Backend *be; | ||
69 | Eina_Mempool *mp; | ||
70 | |||
71 | Eina_Error err = EINA_ERROR_NOT_MEMPOOL_MODULE; | ||
72 | |||
73 | eina_error_set(0); | ||
74 | be = eina_hash_find(_backends, name); | ||
75 | if ((!be) || (!be->init)) | ||
76 | goto on_error; | ||
77 | |||
78 | err = EINA_ERROR_OUT_OF_MEMORY; | ||
79 | mp = calloc(1, sizeof(Eina_Mempool)); | ||
80 | if (!mp) | ||
81 | goto on_error; | ||
82 | |||
83 | /* Work around ABI incompability introduced in Eina 1.1 */ | ||
84 | #define SBP(Property) mp->backend.Property = be->Property; | ||
85 | SBP(name); | ||
86 | SBP(init); | ||
87 | SBP(free); | ||
88 | SBP(alloc); | ||
89 | SBP(realloc); | ||
90 | SBP(garbage_collect); | ||
91 | SBP(statistics); | ||
92 | SBP(shutdown); | ||
93 | #undef SBP | ||
94 | |||
95 | if (be->repack) | ||
96 | { | ||
97 | mp->backend2 = calloc(1, sizeof (Eina_Mempool_Backend_ABI2)); | ||
98 | if (mp->backend2) | ||
99 | mp->backend2->repack = be->repack; | ||
100 | } | ||
101 | |||
102 | mp->backend_data = mp->backend.init(context, options, args); | ||
103 | |||
104 | return mp; | ||
105 | |||
106 | on_error: | ||
107 | eina_error_set(err); | ||
108 | return NULL; | ||
109 | } | ||
110 | |||
111 | /* Built-in backend's prototypes */ | ||
112 | |||
113 | #ifdef EINA_STATIC_BUILD_BUDDY | ||
114 | Eina_Bool buddy_init(void); | ||
115 | void buddy_shutdown(void); | ||
116 | #endif | ||
117 | |||
118 | #ifdef EINA_STATIC_BUILD_CHAINED_POOL | ||
119 | Eina_Bool chained_init(void); | ||
120 | void chained_shutdown(void); | ||
121 | #endif | ||
122 | |||
123 | #ifdef EINA_STATIC_BUILD_EMEMOA_FIXED | ||
124 | Eina_Bool ememoa_fixed_init(void); | ||
125 | void ememoa_fixed_shutdown(void); | ||
126 | #endif | ||
127 | |||
128 | #ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN | ||
129 | Eina_Bool ememoa_unknown_init(void); | ||
130 | void ememoa_unknown_shutdown(void); | ||
131 | #endif | ||
132 | |||
133 | #ifdef EINA_STATIC_BUILD_FIXED_BITMAP | ||
134 | Eina_Bool fixed_bitmap_init(void); | ||
135 | void fixed_bitmap_shutdown(void); | ||
136 | #endif | ||
137 | |||
138 | #ifdef EINA_STATIC_BUILD_ONE_BIG | ||
139 | Eina_Bool one_big_init(void); | ||
140 | void one_big_shutdown(void); | ||
141 | #endif | ||
142 | |||
143 | #ifdef EINA_STATIC_BUILD_PASS_THROUGH | ||
144 | Eina_Bool pass_through_init(void); | ||
145 | void pass_through_shutdown(void); | ||
146 | #endif | ||
147 | |||
148 | /** | ||
149 | * @endcond | ||
150 | */ | ||
151 | |||
152 | /*============================================================================* | ||
153 | * Global * | ||
154 | *============================================================================*/ | ||
155 | |||
156 | /** | ||
157 | * @cond LOCAL | ||
158 | */ | ||
159 | |||
160 | EAPI Eina_Error EINA_ERROR_NOT_MEMPOOL_MODULE = 0; | ||
161 | |||
162 | static const char EINA_ERROR_NOT_MEMPOOL_MODULE_STR[] = | ||
163 | "Not a memory pool module."; | ||
164 | |||
165 | /** | ||
166 | * @endcond | ||
167 | */ | ||
168 | |||
169 | EAPI Eina_Bool | ||
170 | eina_mempool_register(Eina_Mempool_Backend *be) | ||
171 | { | ||
172 | EINA_SAFETY_ON_NULL_RETURN_VAL(be, 0); | ||
173 | DBG("be=%p, name=%p", be, be->name); | ||
174 | return eina_hash_add(_backends, be->name, be); | ||
175 | } | ||
176 | |||
177 | EAPI void | ||
178 | eina_mempool_unregister(Eina_Mempool_Backend *be) | ||
179 | { | ||
180 | EINA_SAFETY_ON_NULL_RETURN(be); | ||
181 | DBG("be=%p, name=%p", be, be->name); | ||
182 | eina_hash_del(_backends, be->name, be); | ||
183 | } | ||
184 | |||
185 | Eina_Bool | ||
186 | eina_mempool_init(void) | ||
187 | { | ||
188 | char *path; | ||
189 | |||
190 | _eina_mempool_log_dom = eina_log_domain_register("eina_mempool", | ||
191 | EINA_LOG_COLOR_DEFAULT); | ||
192 | if (_eina_mempool_log_dom < 0) | ||
193 | { | ||
194 | EINA_LOG_ERR("Could not register log domain: eina_mempool"); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | EINA_ERROR_NOT_MEMPOOL_MODULE = eina_error_msg_static_register( | ||
199 | EINA_ERROR_NOT_MEMPOOL_MODULE_STR); | ||
200 | _backends = eina_hash_string_superfast_new(NULL); | ||
201 | |||
202 | /* dynamic backends */ | ||
203 | _modules = eina_module_arch_list_get(NULL, | ||
204 | PACKAGE_LIB_DIR "/eina/modules/mp", | ||
205 | MODULE_ARCH); | ||
206 | |||
207 | path = eina_module_environment_path_get("HOME", "/.eina/mp/modules/mp"); | ||
208 | _modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH); | ||
209 | if (path) | ||
210 | free(path); | ||
211 | |||
212 | path = eina_module_environment_path_get("EINA_MODULES_MEMPOOL_DIR", | ||
213 | "/eina/modules/mp"); | ||
214 | _modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH); | ||
215 | if (path) | ||
216 | free(path); | ||
217 | |||
218 | path = eina_module_symbol_path_get((const void *)eina_init, | ||
219 | "/eina/modules/mp"); | ||
220 | _modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH); | ||
221 | if (path) | ||
222 | free(path); | ||
223 | |||
224 | if (!_modules) | ||
225 | { | ||
226 | ERR("no mempool modules able to be loaded."); | ||
227 | eina_hash_free(_backends); | ||
228 | goto mempool_init_error; | ||
229 | } | ||
230 | |||
231 | eina_module_list_load(_modules); | ||
232 | |||
233 | /* builtin backends */ | ||
234 | #ifdef EINA_STATIC_BUILD_BUDDY | ||
235 | buddy_init(); | ||
236 | #endif | ||
237 | #ifdef EINA_STATIC_BUILD_CHAINED_POOL | ||
238 | chained_init(); | ||
239 | #endif | ||
240 | #ifdef EINA_STATIC_BUILD_EMEMOA_FIXED | ||
241 | ememoa_fixed_init(); | ||
242 | #endif | ||
243 | #ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN | ||
244 | ememoa_unknown_init(); | ||
245 | #endif | ||
246 | #ifdef EINA_STATIC_BUILD_FIXED_BITMAP | ||
247 | fixed_bitmap_init(); | ||
248 | #endif | ||
249 | #ifdef EINA_STATIC_BUILD_ONE_BIG | ||
250 | one_big_init(); | ||
251 | #endif | ||
252 | #ifdef EINA_STATIC_BUILD_PASS_THROUGH | ||
253 | pass_through_init(); | ||
254 | #endif | ||
255 | |||
256 | return EINA_TRUE; | ||
257 | |||
258 | mempool_init_error: | ||
259 | eina_log_domain_unregister(_eina_mempool_log_dom); | ||
260 | _eina_mempool_log_dom = -1; | ||
261 | |||
262 | return EINA_FALSE; | ||
263 | } | ||
264 | |||
265 | Eina_Bool | ||
266 | eina_mempool_shutdown(void) | ||
267 | { | ||
268 | /* builtin backends */ | ||
269 | #ifdef EINA_STATIC_BUILD_BUDDY | ||
270 | buddy_shutdown(); | ||
271 | #endif | ||
272 | #ifdef EINA_STATIC_BUILD_CHAINED_POOL | ||
273 | chained_shutdown(); | ||
274 | #endif | ||
275 | #ifdef EINA_STATIC_BUILD_EMEMOA_FIXED | ||
276 | ememoa_fixed_shutdown(); | ||
277 | #endif | ||
278 | #ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN | ||
279 | ememoa_unknown_shutdown(); | ||
280 | #endif | ||
281 | #ifdef EINA_STATIC_BUILD_FIXED_BITMAP | ||
282 | fixed_bitmap_shutdown(); | ||
283 | #endif | ||
284 | #ifdef EINA_STATIC_BUILD_ONE_BIG | ||
285 | one_big_shutdown(); | ||
286 | #endif | ||
287 | #ifdef EINA_STATIC_BUILD_PASS_THROUGH | ||
288 | pass_through_shutdown(); | ||
289 | #endif | ||
290 | /* dynamic backends */ | ||
291 | eina_module_list_free(_modules); | ||
292 | if (_modules) | ||
293 | eina_array_free(_modules); | ||
294 | |||
295 | if (_backends) | ||
296 | eina_hash_free(_backends); | ||
297 | |||
298 | eina_log_domain_unregister(_eina_mempool_log_dom); | ||
299 | _eina_mempool_log_dom = -1; | ||
300 | |||
301 | return EINA_TRUE; | ||
302 | } | ||
303 | |||
304 | /*============================================================================* | ||
305 | * API * | ||
306 | *============================================================================*/ | ||
307 | |||
308 | EAPI Eina_Mempool * | ||
309 | eina_mempool_add(const char *name, | ||
310 | const char *context, | ||
311 | const char *options, | ||
312 | ...) | ||
313 | { | ||
314 | Eina_Mempool *mp; | ||
315 | va_list args; | ||
316 | |||
317 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); | ||
318 | DBG("name=%s, context=%s, options=%s", | ||
319 | name, context ? context : "", options ? options : ""); | ||
320 | |||
321 | va_start(args, options); | ||
322 | mp = _new_va(name, context, options, args); | ||
323 | va_end(args); | ||
324 | |||
325 | DBG("name=%s, context=%s, options=%s, mp=%p", | ||
326 | name, context ? context : "", options ? options : "", mp); | ||
327 | |||
328 | return mp; | ||
329 | } | ||
330 | |||
331 | EAPI void eina_mempool_del(Eina_Mempool *mp) | ||
332 | { | ||
333 | EINA_SAFETY_ON_NULL_RETURN(mp); | ||
334 | EINA_SAFETY_ON_NULL_RETURN(mp->backend.shutdown); | ||
335 | DBG("mp=%p", mp); | ||
336 | mp->backend.shutdown(mp->backend_data); | ||
337 | free(mp->backend2); | ||
338 | free(mp); | ||
339 | } | ||
340 | |||
341 | EAPI void eina_mempool_repack(Eina_Mempool *mp, Eina_Mempool_Repack_Cb cb, void *data) | ||
342 | { | ||
343 | EINA_SAFETY_ON_NULL_RETURN(mp); | ||
344 | EINA_SAFETY_ON_NULL_RETURN(mp->backend2); | ||
345 | EINA_SAFETY_ON_NULL_RETURN(mp->backend2->repack); | ||
346 | DBG("mp=%p", mp); | ||
347 | mp->backend2->repack(mp->backend_data, cb, data); | ||
348 | } | ||
349 | |||
350 | EAPI void eina_mempool_gc(Eina_Mempool *mp) | ||
351 | { | ||
352 | EINA_SAFETY_ON_NULL_RETURN(mp); | ||
353 | EINA_SAFETY_ON_NULL_RETURN(mp->backend.garbage_collect); | ||
354 | DBG("mp=%p", mp); | ||
355 | mp->backend.garbage_collect(mp->backend_data); | ||
356 | } | ||
357 | |||
358 | EAPI void eina_mempool_statistics(Eina_Mempool *mp) | ||
359 | { | ||
360 | EINA_SAFETY_ON_NULL_RETURN(mp); | ||
361 | EINA_SAFETY_ON_NULL_RETURN(mp->backend.statistics); | ||
362 | DBG("mp=%p", mp); | ||
363 | mp->backend.statistics(mp->backend_data); | ||
364 | } | ||
365 | |||
366 | EAPI unsigned int | ||
367 | eina_mempool_alignof(unsigned int size) | ||
368 | { | ||
369 | int align; | ||
370 | |||
371 | if (size <= 2) | ||
372 | align = 2; | ||
373 | else if (size < 8) | ||
374 | align = 4; | ||
375 | else | ||
376 | #if __WORDSIZE == 32 | ||
377 | align = 8; | ||
378 | |||
379 | #else | ||
380 | if (size < 16) | ||
381 | align = 8; | ||
382 | else | ||
383 | align = 16; | ||
384 | #endif | ||
385 | |||
386 | return ((size / align) + 1) * align; | ||
387 | } | ||
diff --git a/libraries/eina/src/lib/eina_mmap.c b/libraries/eina/src/lib/eina_mmap.c deleted file mode 100644 index 7929f0e..0000000 --- a/libraries/eina/src/lib/eina_mmap.c +++ /dev/null | |||
@@ -1,190 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2011 Carsten Haitzler | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #ifdef HAVE_SIGINFO_T | ||
24 | |||
25 | #ifdef STDC_HEADERS | ||
26 | # include <stdlib.h> | ||
27 | # include <stddef.h> | ||
28 | #else | ||
29 | # ifdef HAVE_STDLIB_H | ||
30 | # include <stdlib.h> | ||
31 | # endif | ||
32 | #endif | ||
33 | |||
34 | #include <stdio.h> | ||
35 | #include <stdlib.h> | ||
36 | #include <string.h> | ||
37 | #include <sys/types.h> | ||
38 | #include <sys/stat.h> | ||
39 | #include <sys/mman.h> | ||
40 | #include <limits.h> | ||
41 | #include <signal.h> | ||
42 | #include <errno.h> | ||
43 | #include <fcntl.h> | ||
44 | #include <unistd.h> | ||
45 | |||
46 | #if HAVE_SIGINFO_H | ||
47 | # include <siginfo.h> | ||
48 | #endif | ||
49 | |||
50 | #endif | ||
51 | |||
52 | #include "eina_config.h" | ||
53 | #include "eina_private.h" | ||
54 | #include "eina_log.h" | ||
55 | #include "eina_mmap.h" | ||
56 | |||
57 | /*============================================================================* | ||
58 | * Local * | ||
59 | *============================================================================*/ | ||
60 | |||
61 | static Eina_Bool mmap_safe = EINA_FALSE; | ||
62 | #ifdef HAVE_SIGINFO_T | ||
63 | |||
64 | static int _eina_mmap_log_dom = -1; | ||
65 | static int _eina_mmap_zero_fd = -1; | ||
66 | static long _eina_mmap_pagesize = -1; | ||
67 | |||
68 | #ifdef ERR | ||
69 | #undef ERR | ||
70 | #endif | ||
71 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_mmap_log_dom, __VA_ARGS__) | ||
72 | |||
73 | #ifdef DBG | ||
74 | #undef DBG | ||
75 | #endif | ||
76 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_mmap_log_dom, __VA_ARGS__) | ||
77 | |||
78 | static void | ||
79 | _eina_mmap_safe_sigbus(int sig __UNUSED__, | ||
80 | siginfo_t *siginfo, | ||
81 | void *ptr __UNUSED__) | ||
82 | { | ||
83 | unsigned char *addr = (unsigned char *)(siginfo->si_addr); | ||
84 | int perrno; | ||
85 | |||
86 | /* save previous errno */ | ||
87 | perrno = errno; | ||
88 | /* if problems was an unaligned access - complain accordingly and abort */ | ||
89 | if (siginfo->si_code == BUS_ADRALN) | ||
90 | { | ||
91 | ERR("Unaligned memory access. SIGBUS!!!"); | ||
92 | errno = perrno; | ||
93 | abort(); | ||
94 | } | ||
95 | /* send this to stderr - not eina_log. Specifically want this on stderr */ | ||
96 | fprintf(stderr, | ||
97 | "EINA: Data at address 0x%lx is invalid. Replacing with zero page.\n", | ||
98 | (unsigned long)addr); | ||
99 | /* align address to the lower page boundary */ | ||
100 | addr = (unsigned char *)((long)addr & (~(_eina_mmap_pagesize - 1))); | ||
101 | /* mmap a pzge of zero's from /dev/zero in there */ | ||
102 | if (mmap(addr, _eina_mmap_pagesize, | ||
103 | PROT_READ | PROT_WRITE | PROT_EXEC, | ||
104 | MAP_PRIVATE | MAP_FIXED, | ||
105 | _eina_mmap_zero_fd, 0) == MAP_FAILED) | ||
106 | { | ||
107 | /* mmap of /dev/zero failed :( */ | ||
108 | perror("mmap"); | ||
109 | ERR("Failed to mmap() /dev/zero in place of page. SIGBUS!!!"); | ||
110 | errno = perrno; | ||
111 | abort(); | ||
112 | } | ||
113 | /* Look into mmaped Eina_File if it was one of them, just to remember for later request */ | ||
114 | eina_file_mmap_faulty(addr, _eina_mmap_pagesize); | ||
115 | /* restore previous errno */ | ||
116 | errno = perrno; | ||
117 | } | ||
118 | #endif | ||
119 | |||
120 | /*============================================================================* | ||
121 | * API * | ||
122 | *============================================================================*/ | ||
123 | |||
124 | EAPI Eina_Bool | ||
125 | eina_mmap_safety_enabled_set(Eina_Bool enabled) | ||
126 | { | ||
127 | #ifndef HAVE_SIGINFO_T | ||
128 | (void) enabled; | ||
129 | return EINA_FALSE; | ||
130 | #else | ||
131 | if (_eina_mmap_log_dom < 0) | ||
132 | { | ||
133 | _eina_mmap_log_dom = eina_log_domain_register("eina_mmap", | ||
134 | EINA_LOG_COLOR_DEFAULT); | ||
135 | if (_eina_mmap_log_dom < 0) | ||
136 | { | ||
137 | EINA_LOG_ERR("Could not register log domain: eina_mmap"); | ||
138 | return EINA_FALSE; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | enabled = !!enabled; | ||
143 | |||
144 | if (mmap_safe == enabled) return mmap_safe; | ||
145 | if (enabled) | ||
146 | { | ||
147 | struct sigaction sa; | ||
148 | |||
149 | /* find out system page size the cleanest way we can */ | ||
150 | #ifdef _SC_PAGESIZE | ||
151 | _eina_mmap_pagesize = sysconf(_SC_PAGESIZE); | ||
152 | if (_eina_mmap_pagesize <= 0) return EINA_FALSE; | ||
153 | #else | ||
154 | _eina_mmap_pagesize = 4096; | ||
155 | #endif | ||
156 | /* no zero page device - open it */ | ||
157 | if (_eina_mmap_zero_fd < 0) | ||
158 | { | ||
159 | _eina_mmap_zero_fd = open("/dev/zero", O_RDWR); | ||
160 | /* if we don;'t have one - fail to set up mmap safety */ | ||
161 | if (_eina_mmap_zero_fd < 0) return EINA_FALSE; | ||
162 | } | ||
163 | /* set up signal handler for SIGBUS */ | ||
164 | sa.sa_sigaction = _eina_mmap_safe_sigbus; | ||
165 | sa.sa_flags = SA_RESTART | SA_SIGINFO; | ||
166 | sigemptyset(&sa.sa_mask); | ||
167 | /* FIXME: This is rubbish. We return EINA_FALSE whether sigaction | ||
168 | * fails or not. And we never set mmap_safe, so we always hit this | ||
169 | * code path. */ | ||
170 | if (sigaction(SIGBUS, &sa, NULL) == 0) return EINA_FALSE; | ||
171 | /* setup of SIGBUS handler failed, lets close zero page dev and fail */ | ||
172 | close(_eina_mmap_zero_fd); | ||
173 | _eina_mmap_zero_fd = -1; | ||
174 | return EINA_FALSE; | ||
175 | } | ||
176 | else | ||
177 | { | ||
178 | /* reset signal handler to default for SIGBUS */ | ||
179 | signal(SIGBUS, SIG_DFL); | ||
180 | } | ||
181 | mmap_safe = enabled; | ||
182 | return mmap_safe; | ||
183 | #endif | ||
184 | } | ||
185 | |||
186 | EAPI Eina_Bool | ||
187 | eina_mmap_safety_enabled_get(void) | ||
188 | { | ||
189 | return mmap_safe; | ||
190 | } | ||
diff --git a/libraries/eina/src/lib/eina_model.c b/libraries/eina/src/lib/eina_model.c deleted file mode 100644 index ae06c1b..0000000 --- a/libraries/eina/src/lib/eina_model.c +++ /dev/null | |||
@@ -1,5548 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2012 ProFUSION embedded systems | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #ifdef HAVE_ALLOCA_H | ||
24 | # include <alloca.h> | ||
25 | #elif defined __GNUC__ | ||
26 | # define alloca __builtin_alloca | ||
27 | #elif defined _AIX | ||
28 | # define alloca __alloca | ||
29 | #elif defined _MSC_VER | ||
30 | # include <malloc.h> | ||
31 | # define alloca _alloca | ||
32 | #else | ||
33 | # include <stddef.h> | ||
34 | # ifdef __cplusplus | ||
35 | extern "C" | ||
36 | # endif | ||
37 | void *alloca (size_t); | ||
38 | #endif | ||
39 | |||
40 | #ifdef HAVE_EXECINFO_H | ||
41 | #include <execinfo.h> | ||
42 | #endif | ||
43 | |||
44 | #include "eina_config.h" | ||
45 | #include "eina_private.h" | ||
46 | #include "eina_error.h" | ||
47 | #include "eina_log.h" | ||
48 | #include "eina_mempool.h" | ||
49 | #include "eina_lock.h" | ||
50 | #include "eina_inlist.h" | ||
51 | #include "eina_strbuf.h" | ||
52 | |||
53 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
54 | #include "eina_safety_checks.h" | ||
55 | #include "eina_value.h" /* eina-safety used in inline.x */ | ||
56 | #include "eina_model.h" | ||
57 | |||
58 | /*============================================================================* | ||
59 | * Local * | ||
60 | *============================================================================*/ | ||
61 | |||
62 | /** | ||
63 | * @cond LOCAL | ||
64 | */ | ||
65 | |||
66 | static Eina_Mempool *_eina_model_mp = NULL; | ||
67 | static Eina_Hash *_eina_model_inner_mps = NULL; | ||
68 | static Eina_Lock _eina_model_inner_mps_lock; | ||
69 | static char *_eina_model_mp_choice = NULL; | ||
70 | static Eina_Hash *_eina_model_descriptions = NULL; | ||
71 | static Eina_Lock _eina_model_descriptions_lock; | ||
72 | static int _eina_model_log_dom = -1; | ||
73 | static enum { | ||
74 | EINA_MODEL_DEBUG_NONE = 0, | ||
75 | EINA_MODEL_DEBUG_CHECK = 1, | ||
76 | EINA_MODEL_DEBUG_BACKTRACE = 2, | ||
77 | } _eina_model_debug = EINA_MODEL_DEBUG_NONE; | ||
78 | static Eina_Lock _eina_model_debug_list_lock; | ||
79 | static Eina_List *_eina_model_debug_list = NULL; | ||
80 | |||
81 | static const char _eina_model_str_deleted[] = "deleted"; | ||
82 | static const char _eina_model_str_freed[] = "freed"; | ||
83 | static const char _eina_model_str_property_set[] = "property,set"; | ||
84 | static const char _eina_model_str_property_del[] = "property,deleted"; | ||
85 | static const char _eina_model_str_children_changed[] = "children,changed"; | ||
86 | static const char _eina_model_str_child_inserted[] = "child,inserted"; | ||
87 | static const char _eina_model_str_child_set[] = "child,set"; | ||
88 | static const char _eina_model_str_child_del[] = "child,deleted"; | ||
89 | static const char _eina_model_str_loaded[] = "loaded"; | ||
90 | static const char _eina_model_str_unloaded[] = "unloaded"; | ||
91 | static const char _eina_model_str_properties_loaded[] = "properties,loaded"; | ||
92 | static const char _eina_model_str_properties_unloaded[] = "properties,unloaded"; | ||
93 | static const char _eina_model_str_children_loaded[] = "children,loaded"; | ||
94 | static const char _eina_model_str_children_unloaded[] = "children,unloaded"; | ||
95 | |||
96 | #ifdef CRITICAL | ||
97 | #undef CRITICAL | ||
98 | #endif | ||
99 | #define CRITICAL(...) EINA_LOG_DOM_CRIT(_eina_model_log_dom, __VA_ARGS__) | ||
100 | |||
101 | #ifdef ERR | ||
102 | #undef ERR | ||
103 | #endif | ||
104 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_model_log_dom, __VA_ARGS__) | ||
105 | |||
106 | #ifdef WRN | ||
107 | #undef WRN | ||
108 | #endif | ||
109 | #define WRN(...) EINA_LOG_DOM_WARN(_eina_model_log_dom, __VA_ARGS__) | ||
110 | |||
111 | #ifdef INF | ||
112 | #undef INF | ||
113 | #endif | ||
114 | #define INF(...) EINA_LOG_DOM_INFO(_eina_model_log_dom, __VA_ARGS__) | ||
115 | |||
116 | #ifdef DBG | ||
117 | #undef DBG | ||
118 | #endif | ||
119 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_model_log_dom, __VA_ARGS__) | ||
120 | |||
121 | |||
122 | /* convenience sort array of Eina_Model* giving compare Eina_Model* instead of | ||
123 | * Eina_Model** | ||
124 | */ | ||
125 | static unsigned int | ||
126 | _eina_model_array_partition(Eina_Model **array, unsigned int start, unsigned int last, unsigned int pivot, Eina_Compare_Cb compare) | ||
127 | { | ||
128 | Eina_Model **itr, **itr_end, *tmp, *pivot_value; | ||
129 | |||
130 | pivot_value = tmp = array[pivot]; | ||
131 | array[pivot] = array[last]; | ||
132 | array[last] = tmp; | ||
133 | |||
134 | pivot = start; | ||
135 | itr = array + start; | ||
136 | itr_end = array + last; | ||
137 | for (; itr < itr_end; itr++) | ||
138 | { | ||
139 | if (compare(*itr, pivot_value) < 0) | ||
140 | { | ||
141 | tmp = *itr; | ||
142 | *itr = array[pivot]; | ||
143 | array[pivot] = tmp; | ||
144 | pivot++; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | tmp = array[last]; | ||
149 | array[last] = array[pivot]; | ||
150 | array[pivot] = tmp; | ||
151 | |||
152 | return pivot; | ||
153 | } | ||
154 | |||
155 | static void | ||
156 | _eina_model_array_sort(Eina_Model **array, unsigned int start, unsigned int last, Eina_Compare_Cb compare) | ||
157 | { | ||
158 | unsigned int pivot, new_pivot; | ||
159 | |||
160 | if (last <= start) | ||
161 | return; | ||
162 | |||
163 | pivot = start + (last - start) / 2; /* avoid overflow */ | ||
164 | new_pivot = _eina_model_array_partition(array, start, last, pivot, compare); | ||
165 | |||
166 | if (start + 1 < new_pivot) | ||
167 | _eina_model_array_sort(array, start, new_pivot - 1, compare); | ||
168 | |||
169 | if (new_pivot + 1 < last) | ||
170 | _eina_model_array_sort(array, new_pivot + 1, last, compare); | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * Most of inner allocations are made with internal mempools, types | ||
175 | * and thus instace private data will repeat and it's good to use them. | ||
176 | * | ||
177 | * To save on the number of mempools, they are kept per size, not per | ||
178 | * type. | ||
179 | * | ||
180 | * This is done by means of _eina_model_inner_alloc() and | ||
181 | * _eina_model_inner_free(), both at thread safe. | ||
182 | * | ||
183 | */ | ||
184 | typedef struct _Eina_Model_Inner_Mp Eina_Model_Inner_Mp; | ||
185 | struct _Eina_Model_Inner_Mp | ||
186 | { | ||
187 | Eina_Mempool *mempool; | ||
188 | int refcount; | ||
189 | }; | ||
190 | |||
191 | static inline void | ||
192 | _eina_model_inner_mp_dispose(int size, Eina_Model_Inner_Mp *imp) | ||
193 | { | ||
194 | EINA_SAFETY_ON_FALSE_RETURN(imp->refcount == 0); | ||
195 | |||
196 | eina_hash_del_by_key(_eina_model_inner_mps, &size); | ||
197 | eina_mempool_del(imp->mempool); | ||
198 | free(imp); | ||
199 | } | ||
200 | |||
201 | static inline Eina_Model_Inner_Mp * | ||
202 | _eina_model_inner_mp_get(int size) | ||
203 | { | ||
204 | Eina_Model_Inner_Mp *imp = eina_hash_find(_eina_model_inner_mps, &size); | ||
205 | if (imp) return imp; | ||
206 | |||
207 | imp = malloc(sizeof(Eina_Model_Inner_Mp)); | ||
208 | if (!imp) | ||
209 | return NULL; | ||
210 | |||
211 | imp->refcount = 0; | ||
212 | |||
213 | imp->mempool = eina_mempool_add(_eina_model_mp_choice, | ||
214 | "Eina_Model_Inner_Mp", NULL, size, 128); | ||
215 | if (!imp->mempool) | ||
216 | { | ||
217 | free(imp); | ||
218 | return NULL; | ||
219 | } | ||
220 | |||
221 | if (!eina_hash_add(_eina_model_inner_mps, &size, imp)) | ||
222 | { | ||
223 | eina_mempool_del(imp->mempool); | ||
224 | free(imp); | ||
225 | return NULL; | ||
226 | } | ||
227 | |||
228 | return imp; | ||
229 | } | ||
230 | |||
231 | static inline void * | ||
232 | _eina_model_inner_alloc_internal(int size) | ||
233 | { | ||
234 | Eina_Model_Inner_Mp *imp; | ||
235 | void *mem; | ||
236 | |||
237 | imp = _eina_model_inner_mp_get(size); | ||
238 | if (!imp) return NULL; | ||
239 | |||
240 | mem = eina_mempool_malloc(imp->mempool, size); | ||
241 | if (mem) imp->refcount++; | ||
242 | else if (imp->refcount == 0) _eina_model_inner_mp_dispose(size, imp); | ||
243 | |||
244 | return mem; | ||
245 | } | ||
246 | |||
247 | static inline void | ||
248 | _eina_model_inner_free_internal(int size, void *mem) | ||
249 | { | ||
250 | Eina_Model_Inner_Mp *imp = eina_hash_find(_eina_model_inner_mps, &size); | ||
251 | EINA_SAFETY_ON_NULL_RETURN(imp); | ||
252 | |||
253 | eina_mempool_free(imp->mempool, mem); | ||
254 | |||
255 | imp->refcount--; | ||
256 | if (imp->refcount > 0) return; | ||
257 | _eina_model_inner_mp_dispose(size, imp); | ||
258 | } | ||
259 | |||
260 | static void * | ||
261 | _eina_model_inner_alloc(size_t size) | ||
262 | { | ||
263 | void *mem; | ||
264 | |||
265 | if (size > 512) return malloc(size); | ||
266 | |||
267 | eina_lock_take(&_eina_model_inner_mps_lock); | ||
268 | mem = _eina_model_inner_alloc_internal(size); | ||
269 | eina_lock_release(&_eina_model_inner_mps_lock); | ||
270 | |||
271 | return mem; | ||
272 | } | ||
273 | |||
274 | static void | ||
275 | _eina_model_inner_free(size_t size, void *mem) | ||
276 | { | ||
277 | if (size > 512) | ||
278 | { | ||
279 | free(mem); | ||
280 | return; | ||
281 | } | ||
282 | |||
283 | eina_lock_take(&_eina_model_inner_mps_lock); | ||
284 | _eina_model_inner_free_internal(size, mem); | ||
285 | eina_lock_release(&_eina_model_inner_mps_lock); | ||
286 | } | ||
287 | |||
288 | |||
289 | typedef union _Eina_Model_Provider Eina_Model_Provider; | ||
290 | union _Eina_Model_Provider | ||
291 | { | ||
292 | const Eina_Model_Type *type; | ||
293 | const Eina_Model_Interface *iface; | ||
294 | }; | ||
295 | |||
296 | /* store event name to aid searching */ | ||
297 | typedef struct _Eina_Model_Event_Description_Cache Eina_Model_Event_Description_Cache; | ||
298 | struct _Eina_Model_Event_Description_Cache | ||
299 | { | ||
300 | const char *name; | ||
301 | const Eina_Model_Event_Description *desc; | ||
302 | Eina_Model_Provider provider; | ||
303 | }; | ||
304 | |||
305 | /* description is an optimized structure for type. It's built at runtime | ||
306 | * to avoid user input errors and help declaration. | ||
307 | * | ||
308 | * lookups (ifaces, events) are sorted for binary search. | ||
309 | * | ||
310 | * recursion is avoided by expansion of every possible value in "cache" | ||
311 | * struct. | ||
312 | * | ||
313 | * the first usable operation is stopred for type at "ops" struct, | ||
314 | * avoiding usage of _eina_model_type_find_offset(). | ||
315 | * | ||
316 | * Get a model type description using _eina_model_description_get(), | ||
317 | * when it's not used anymore use | ||
318 | * _eina_model_description_dispose(). These operations are thread | ||
319 | * safe. | ||
320 | */ | ||
321 | typedef struct _Eina_Model_Description Eina_Model_Description; | ||
322 | struct _Eina_Model_Description | ||
323 | { | ||
324 | struct { | ||
325 | const Eina_Model_Type **types; /* size = total.types */ | ||
326 | const Eina_Model_Interface **ifaces; /* sorted, size = total.ifaces */ | ||
327 | Eina_Model_Provider *privates; /* size = total.privates (types + ifaces) */ | ||
328 | Eina_Model_Event_Description_Cache *events; /* size = total.events */ | ||
329 | } cache; | ||
330 | struct { | ||
331 | /* ops are the topmost operation to use for type/interface */ | ||
332 | struct { | ||
333 | Eina_Bool (*setup)(Eina_Model *model); | ||
334 | Eina_Bool (*flush)(Eina_Model *model); | ||
335 | Eina_Bool (*constructor)(Eina_Model *model); | ||
336 | Eina_Bool (*destructor)(Eina_Model *model); | ||
337 | Eina_Bool (*copy)(const Eina_Model *src, Eina_Model *dst); | ||
338 | Eina_Bool (*deep_copy)(const Eina_Model *src, Eina_Model *dst); | ||
339 | Eina_Bool (*compare)(const Eina_Model *a, const Eina_Model *b, int *cmp); | ||
340 | Eina_Bool (*load)(Eina_Model *model); | ||
341 | Eina_Bool (*unload)(Eina_Model *model); | ||
342 | Eina_Bool (*property_get)(const Eina_Model *model, const char *name, Eina_Value *value); | ||
343 | Eina_Bool (*property_set)(Eina_Model *model, const char *name, const Eina_Value *value); | ||
344 | Eina_Bool (*property_del)(Eina_Model *model, const char *name); | ||
345 | Eina_List *(*properties_names_list_get)(const Eina_Model *model); | ||
346 | int (*child_count)(const Eina_Model *model); | ||
347 | Eina_Model *(*child_get)(const Eina_Model *model, unsigned int position); | ||
348 | Eina_Bool (*child_set)(Eina_Model *model, unsigned int position, Eina_Model *child); | ||
349 | Eina_Bool (*child_del)(Eina_Model *model, unsigned int position); | ||
350 | Eina_Bool (*child_insert_at)(Eina_Model *model, unsigned int position, Eina_Model *child); | ||
351 | int (*child_find)(const Eina_Model *model, unsigned int start_position, const Eina_Model *other); | ||
352 | int (*child_criteria_match)(const Eina_Model *model, unsigned int start_position, Eina_Each_Cb match, const void *data); | ||
353 | void (*child_sort)(Eina_Model *model, Eina_Compare_Cb compare); | ||
354 | Eina_Iterator *(*child_iterator_get)(Eina_Model *model, unsigned int start, unsigned int count); | ||
355 | Eina_Iterator *(*child_reversed_iterator_get)(Eina_Model *model, unsigned int start, unsigned int count); | ||
356 | Eina_Iterator *(*child_sorted_iterator_get)(Eina_Model *model, unsigned int start, unsigned int count, Eina_Compare_Cb compare); | ||
357 | Eina_Iterator *(*child_filtered_iterator_get)(Eina_Model *model, unsigned int start, unsigned int count, Eina_Each_Cb match, const void *data); | ||
358 | char *(*to_string)(const Eina_Model *model); /**< used to represent model as string, usually for debug purposes or user convenience */ | ||
359 | const void **extension; | ||
360 | } type; | ||
361 | } ops; | ||
362 | struct { | ||
363 | unsigned int types; | ||
364 | unsigned int ifaces; | ||
365 | unsigned int privates; | ||
366 | unsigned int size; /* sum of all private sizes */ | ||
367 | unsigned int events; | ||
368 | } total; | ||
369 | int refcount; | ||
370 | }; | ||
371 | |||
372 | static Eina_Bool | ||
373 | _eina_model_description_type_fill(Eina_Model_Description *desc, const Eina_Model_Type *type) | ||
374 | { | ||
375 | const Eina_Model_Type *itr, *last_itr = NULL; | ||
376 | unsigned int count, child_size = 0; | ||
377 | |||
378 | for (count = 0, itr = type; itr != NULL; itr = itr->parent, count++) | ||
379 | { | ||
380 | if (itr->version != EINA_MODEL_TYPE_VERSION) | ||
381 | { | ||
382 | CRITICAL("Type %p version is %u, expected %u instead.", | ||
383 | itr, itr->version, EINA_MODEL_TYPE_VERSION); | ||
384 | return EINA_FALSE; | ||
385 | } | ||
386 | if (!itr->name) | ||
387 | { | ||
388 | CRITICAL("Type %p provides no name!", itr); | ||
389 | return EINA_FALSE; | ||
390 | } | ||
391 | if (itr->type_size < sizeof(Eina_Model_Type)) | ||
392 | { | ||
393 | CRITICAL("Type %p %s size must be >= sizeof(Eina_Model_Type)!", | ||
394 | itr, itr->name); | ||
395 | return EINA_FALSE; | ||
396 | } | ||
397 | if (child_size == 0) child_size = itr->type_size; | ||
398 | else if (child_size < itr->type_size) | ||
399 | { | ||
400 | CRITICAL("Type %p %s size is bigger than its child type %p %s!", | ||
401 | itr, itr->name, last_itr, last_itr->name); | ||
402 | return EINA_FALSE; | ||
403 | } | ||
404 | last_itr = itr; | ||
405 | |||
406 | #define DEF_METH(meth) \ | ||
407 | if (!desc->ops.type.meth) desc->ops.type.meth = itr->meth | ||
408 | DEF_METH(setup); | ||
409 | DEF_METH(flush); | ||
410 | DEF_METH(constructor); | ||
411 | DEF_METH(destructor); | ||
412 | DEF_METH(copy); | ||
413 | DEF_METH(deep_copy); | ||
414 | DEF_METH(compare); | ||
415 | DEF_METH(load); | ||
416 | DEF_METH(unload); | ||
417 | DEF_METH(property_get); | ||
418 | DEF_METH(property_set); | ||
419 | DEF_METH(property_del); | ||
420 | DEF_METH(properties_names_list_get); | ||
421 | DEF_METH(child_count); | ||
422 | DEF_METH(child_get); | ||
423 | DEF_METH(child_set); | ||
424 | DEF_METH(child_del); | ||
425 | DEF_METH(child_insert_at); | ||
426 | DEF_METH(child_find); | ||
427 | DEF_METH(child_criteria_match); | ||
428 | DEF_METH(child_sort); | ||
429 | DEF_METH(child_iterator_get); | ||
430 | DEF_METH(child_reversed_iterator_get); | ||
431 | DEF_METH(child_sorted_iterator_get); | ||
432 | DEF_METH(child_filtered_iterator_get); | ||
433 | DEF_METH(to_string); | ||
434 | #undef DEF_METH | ||
435 | |||
436 | if ((!itr->parent) && (itr != EINA_MODEL_TYPE_BASE)) | ||
437 | { | ||
438 | CRITICAL("Type %p (%s) does not inherit from EINA_MODEL_TYPE_BASE!", | ||
439 | type, type->name); | ||
440 | return EINA_FALSE; | ||
441 | } | ||
442 | } | ||
443 | |||
444 | #define CK_METH(meth) \ | ||
445 | if (!desc->ops.type.meth) \ | ||
446 | { \ | ||
447 | CRITICAL("Mandatory method "#meth \ | ||
448 | "() was not provided by type %p (%s).", \ | ||
449 | type, type->name); \ | ||
450 | return EINA_FALSE; \ | ||
451 | } | ||
452 | CK_METH(setup); | ||
453 | CK_METH(flush); | ||
454 | CK_METH(constructor); | ||
455 | CK_METH(destructor); | ||
456 | CK_METH(property_get); | ||
457 | #undef CK_METH | ||
458 | |||
459 | if (child_size <= sizeof(Eina_Model_Type)) | ||
460 | desc->ops.type.extension = NULL; | ||
461 | else | ||
462 | { | ||
463 | unsigned ext_size = child_size - sizeof(Eina_Model_Type); | ||
464 | unsigned ext_count = ext_size / sizeof(void *); | ||
465 | |||
466 | if (ext_size % sizeof(void *) != 0) | ||
467 | { | ||
468 | CRITICAL("Extension size %u is not multiple of sizeof(void*)", | ||
469 | ext_size); | ||
470 | return EINA_FALSE; | ||
471 | } | ||
472 | |||
473 | desc->ops.type.extension = calloc(ext_count, sizeof(void *)); | ||
474 | EINA_SAFETY_ON_NULL_RETURN_VAL(desc->ops.type.extension, EINA_FALSE); | ||
475 | |||
476 | for (itr = type; itr != NULL; itr = itr->parent) | ||
477 | { | ||
478 | unsigned cur_size = itr->type_size - sizeof(Eina_Model_Type); | ||
479 | unsigned i, cur_count = cur_size / sizeof(void *); | ||
480 | const void * const *ptr = (const void **)((const char *)itr + sizeof(Eina_Model_Type)); | ||
481 | |||
482 | if (cur_size == 0) break; | ||
483 | |||
484 | for (i = 0; i < cur_count; i++) | ||
485 | { | ||
486 | if (desc->ops.type.extension[i]) continue; | ||
487 | desc->ops.type.extension[i] = ptr[i]; | ||
488 | } | ||
489 | } | ||
490 | } | ||
491 | |||
492 | desc->cache.types = malloc(count * sizeof(Eina_Model_Type *)); | ||
493 | EINA_SAFETY_ON_NULL_GOTO(desc->cache.types, cache_types_failed); | ||
494 | desc->total.types = count; | ||
495 | |||
496 | for (count = 0, itr = type; itr != NULL; itr = itr->parent, count++) | ||
497 | desc->cache.types[count] = itr; | ||
498 | |||
499 | return EINA_TRUE; | ||
500 | |||
501 | cache_types_failed: | ||
502 | free(desc->ops.type.extension); | ||
503 | return EINA_FALSE; | ||
504 | } | ||
505 | |||
506 | static inline Eina_Bool | ||
507 | _eina_model_interface_implements(const Eina_Model_Interface *iface, const Eina_Model_Interface *query) | ||
508 | { | ||
509 | const Eina_Model_Interface **itr; | ||
510 | |||
511 | if (iface == query) | ||
512 | return EINA_TRUE; | ||
513 | |||
514 | if (!iface->interfaces) | ||
515 | return EINA_FALSE; | ||
516 | |||
517 | for (itr = iface->interfaces; *itr != NULL; itr++) | ||
518 | if (_eina_model_interface_implements(*itr, query)) | ||
519 | return EINA_TRUE; | ||
520 | |||
521 | return EINA_FALSE; | ||
522 | } | ||
523 | |||
524 | /* apply topological sort and remove duplicates */ | ||
525 | /* | ||
526 | * TODO: Topological sort will only work for linked interfaces, but | ||
527 | * will ignore original ordering provided by types. Consider the | ||
528 | * following: | ||
529 | * | ||
530 | * - A_Type -> X_Iface (name: "MyIface") | ||
531 | * - B_Type -> Y_Iface (name: "MyIface") | ||
532 | * | ||
533 | * Both X_Iface and Y_Iface are different implementations of the | ||
534 | * "MyIface". | ||
535 | * | ||
536 | * B_Type inherits from A_Type, then Y_Iface must be looked up | ||
537 | * first, even though there is no link between Y_Iface and | ||
538 | * X_Iface. | ||
539 | * | ||
540 | * However, the way the current topological sort behaves, the | ||
541 | * roots may come out in any order. We need a stable version | ||
542 | * that sorts roots before removing them from graph. | ||
543 | * | ||
544 | * Thanks to Tasn to report it :-) | ||
545 | */ | ||
546 | static Eina_Bool | ||
547 | _eina_model_description_ifaces_fix(Eina_Model_Description *desc) | ||
548 | { | ||
549 | struct node { | ||
550 | const Eina_Model_Interface *iface; | ||
551 | unsigned int users; | ||
552 | Eina_List *deps; | ||
553 | } *nodes, **pending, **roots; | ||
554 | unsigned int n_nodes = desc->total.ifaces, n_pending = 0, n_roots = 0, i, j; | ||
555 | Eina_Bool ret = EINA_TRUE; | ||
556 | |||
557 | nodes = alloca(n_nodes * sizeof(struct node)); | ||
558 | pending = alloca(n_nodes * sizeof(struct node *)); | ||
559 | roots = alloca(n_nodes * sizeof(struct node *)); | ||
560 | |||
561 | /* populate */ | ||
562 | for (i = 0, j = 0; i < n_nodes; i++) | ||
563 | { | ||
564 | unsigned int k; | ||
565 | for (k = 0; k < j; k++) | ||
566 | { | ||
567 | if (nodes[k].iface == desc->cache.ifaces[i]) | ||
568 | break; | ||
569 | } | ||
570 | if (k < j) | ||
571 | continue; /* already exists */ | ||
572 | |||
573 | nodes[j].iface = desc->cache.ifaces[i]; | ||
574 | nodes[j].users = 0; | ||
575 | nodes[j].deps = NULL; | ||
576 | j++; | ||
577 | } | ||
578 | n_nodes = j; | ||
579 | |||
580 | for (i = 0; i < n_nodes; i++) | ||
581 | { | ||
582 | for (j = 0; j < n_nodes; j++) | ||
583 | { | ||
584 | if (i == j) continue; | ||
585 | if (!_eina_model_interface_implements(nodes[j].iface, | ||
586 | nodes[i].iface)) | ||
587 | continue; | ||
588 | |||
589 | nodes[i].users++; | ||
590 | nodes[j].deps = eina_list_append(nodes[j].deps, nodes + i); | ||
591 | } | ||
592 | } | ||
593 | for (i = 0; i < n_nodes; i++) | ||
594 | { | ||
595 | if (nodes[i].users == 0) | ||
596 | { | ||
597 | roots[n_roots] = nodes + i; | ||
598 | n_roots++; | ||
599 | } | ||
600 | else | ||
601 | { | ||
602 | pending[n_pending] = nodes + i; | ||
603 | n_pending++; | ||
604 | } | ||
605 | } | ||
606 | |||
607 | /* topological sort */ | ||
608 | desc->total.ifaces = 0; | ||
609 | while (n_roots > 0) | ||
610 | { | ||
611 | struct node *r, *d; | ||
612 | |||
613 | /* TODO: sort roots using input order? Or at least study if | ||
614 | * it's enough to change roots append to prepend. | ||
615 | * | ||
616 | * See comments above. | ||
617 | */ | ||
618 | n_roots--; | ||
619 | r = roots[n_roots]; | ||
620 | |||
621 | desc->cache.ifaces[desc->total.ifaces] = r->iface; | ||
622 | desc->total.ifaces++; | ||
623 | |||
624 | EINA_LIST_FREE(r->deps, d) | ||
625 | { | ||
626 | d->users--; | ||
627 | if (d->users > 0) continue; | ||
628 | |||
629 | roots[n_roots] = d; | ||
630 | n_roots++; | ||
631 | |||
632 | /* remove node, it became a root */ | ||
633 | for (j = 0; j < n_pending; j++) | ||
634 | { | ||
635 | if (pending[j] == d) | ||
636 | { | ||
637 | n_pending--; | ||
638 | if (j < n_pending) | ||
639 | pending[j] = pending[n_pending]; | ||
640 | break; | ||
641 | } | ||
642 | } | ||
643 | } | ||
644 | } | ||
645 | |||
646 | if (n_pending > 0) | ||
647 | { | ||
648 | ERR("Dependency loop found for interfaces!"); | ||
649 | for (i = 0; i < n_pending; i++) | ||
650 | ERR("%p (%s) is part of dependency loop!", | ||
651 | pending[i]->iface, pending[i]->iface->name); | ||
652 | CRITICAL("Cannot use type %p (%s) with broken interfaces!", | ||
653 | desc->cache.types[0], desc->cache.types[0]->name); | ||
654 | free(desc->cache.ifaces); | ||
655 | ret = EINA_FALSE; | ||
656 | } | ||
657 | |||
658 | /* likely from still pending (dependency loops) */ | ||
659 | for (i = 0; i < n_nodes; i++) | ||
660 | eina_list_free(nodes[i].deps); | ||
661 | |||
662 | return ret; | ||
663 | } | ||
664 | |||
665 | static Eina_Bool | ||
666 | _eina_model_description_ifaces_validate_and_count(const Eina_Model_Interface *iface, unsigned int *count) | ||
667 | { | ||
668 | if (iface->version != EINA_MODEL_INTERFACE_VERSION) | ||
669 | { | ||
670 | CRITICAL("Interface %p version is %u, expected %u instead.", | ||
671 | iface, iface->version, EINA_MODEL_INTERFACE_VERSION); | ||
672 | return EINA_FALSE; | ||
673 | } | ||
674 | |||
675 | if (!iface->name) | ||
676 | { | ||
677 | CRITICAL("Interface %p provides no name!", iface); | ||
678 | return EINA_FALSE; | ||
679 | } | ||
680 | |||
681 | if (iface->interfaces) | ||
682 | { | ||
683 | const Eina_Model_Interface **itr = iface->interfaces; | ||
684 | for (; *itr != NULL; itr++) | ||
685 | if (!_eina_model_description_ifaces_validate_and_count(*itr, count)) | ||
686 | return EINA_FALSE; | ||
687 | } | ||
688 | |||
689 | (*count)++; | ||
690 | return EINA_TRUE; | ||
691 | } | ||
692 | |||
693 | static void | ||
694 | _eina_model_description_ifaces_populate(Eina_Model_Description *desc, const Eina_Model_Interface *iface) | ||
695 | { | ||
696 | desc->cache.ifaces[desc->total.ifaces] = iface; | ||
697 | desc->total.ifaces++; | ||
698 | |||
699 | if (iface->interfaces) | ||
700 | { | ||
701 | const Eina_Model_Interface **itr = iface->interfaces; | ||
702 | for (; *itr != NULL; itr++) | ||
703 | _eina_model_description_ifaces_populate(desc, *itr); | ||
704 | } | ||
705 | } | ||
706 | |||
707 | static Eina_Bool | ||
708 | _eina_model_description_ifaces_fill(Eina_Model_Description *desc) | ||
709 | { | ||
710 | const Eina_Model_Type **titr, **titr_end; | ||
711 | unsigned int count; | ||
712 | |||
713 | titr = desc->cache.types; | ||
714 | titr_end = titr + desc->total.types; | ||
715 | |||
716 | /* naively count all interfaces, remove duplicates later */ | ||
717 | for (count = 0; titr < titr_end; titr++) | ||
718 | { | ||
719 | const Eina_Model_Type *type = *titr; | ||
720 | const Eina_Model_Interface **iitr = type->interfaces; | ||
721 | if (!type->interfaces) continue; | ||
722 | |||
723 | for (; *iitr != NULL; iitr++) | ||
724 | if (!_eina_model_description_ifaces_validate_and_count(*iitr, &count)) | ||
725 | return EINA_FALSE; | ||
726 | } | ||
727 | if (count == 0) | ||
728 | { | ||
729 | desc->cache.ifaces = NULL; | ||
730 | desc->total.ifaces = 0; | ||
731 | return EINA_TRUE; | ||
732 | } | ||
733 | |||
734 | desc->cache.ifaces = malloc(count * sizeof(Eina_Model_Interface *)); | ||
735 | EINA_SAFETY_ON_NULL_RETURN_VAL(desc->cache.ifaces, EINA_FALSE); | ||
736 | |||
737 | titr = desc->cache.types; | ||
738 | desc->total.ifaces = 0; | ||
739 | for (; titr < titr_end; titr++) | ||
740 | { | ||
741 | const Eina_Model_Type *type = *titr; | ||
742 | const Eina_Model_Interface **iitr = type->interfaces; | ||
743 | |||
744 | if (!type->interfaces) continue; | ||
745 | |||
746 | for (; *iitr != NULL; iitr++) | ||
747 | _eina_model_description_ifaces_populate(desc, *iitr); | ||
748 | } | ||
749 | |||
750 | return _eina_model_description_ifaces_fix(desc); | ||
751 | } | ||
752 | |||
753 | static Eina_Bool | ||
754 | _eina_model_description_privates_fill(Eina_Model_Description *desc) | ||
755 | { | ||
756 | unsigned int i; | ||
757 | |||
758 | desc->total.privates = desc->total.types + desc->total.ifaces; | ||
759 | desc->cache.privates = malloc(desc->total.privates * | ||
760 | sizeof(Eina_Model_Provider)); | ||
761 | EINA_SAFETY_ON_NULL_RETURN_VAL(desc->cache.privates, EINA_FALSE); | ||
762 | |||
763 | desc->total.size = 0; | ||
764 | |||
765 | for (i = 0; i < desc->total.types; i++) | ||
766 | { | ||
767 | const Eina_Model_Type *type = desc->cache.types[i]; | ||
768 | desc->cache.privates[i].type = type; | ||
769 | if (type->private_size > 0) | ||
770 | { | ||
771 | unsigned int size = type->private_size; | ||
772 | if (size % sizeof(void *) != 0) | ||
773 | size += sizeof(void *) - (size % sizeof(void *)); | ||
774 | desc->total.size += size; | ||
775 | } | ||
776 | } | ||
777 | |||
778 | for (i = 0; i < desc->total.ifaces; i++) | ||
779 | { | ||
780 | const Eina_Model_Interface *iface = desc->cache.ifaces[i]; | ||
781 | desc->cache.privates[desc->total.types + i].iface = iface; | ||
782 | if (iface->private_size > 0) | ||
783 | { | ||
784 | unsigned int size = iface->private_size; | ||
785 | if (size % sizeof(void *) != 0) | ||
786 | size += sizeof(void *) - (size % sizeof(void *)); | ||
787 | desc->total.size += size; | ||
788 | } | ||
789 | } | ||
790 | |||
791 | return EINA_TRUE; | ||
792 | } | ||
793 | |||
794 | static int | ||
795 | _eina_model_description_events_cmp(const void *pa, const void *pb) | ||
796 | { | ||
797 | const Eina_Model_Event_Description_Cache *a = pa, *b = pb; | ||
798 | return strcmp(a->name, b->name); | ||
799 | } | ||
800 | |||
801 | static int | ||
802 | _eina_model_description_events_find(const Eina_Model_Description *desc, const Eina_Model_Event_Description *query) | ||
803 | { | ||
804 | unsigned int i; | ||
805 | for (i = 0; i < desc->total.events; i++) | ||
806 | { | ||
807 | const Eina_Model_Event_Description_Cache *itr = desc->cache.events + i; | ||
808 | if ((itr->name == query->name) || (strcmp(itr->name, query->name) == 0)) | ||
809 | return i; | ||
810 | } | ||
811 | |||
812 | return -1; | ||
813 | } | ||
814 | |||
815 | /* warn and remove duplicates, sort items to speed up lookups */ | ||
816 | static Eina_Bool | ||
817 | _eina_model_description_events_fill(Eina_Model_Description *desc) | ||
818 | { | ||
819 | unsigned int i, count = 0, type_events; | ||
820 | |||
821 | for (i = 0; i < desc->total.types; i++) | ||
822 | { | ||
823 | const Eina_Model_Event_Description *itr = desc->cache.types[i]->events; | ||
824 | if (!itr) continue; | ||
825 | for (; itr->name != NULL; itr++) | ||
826 | { | ||
827 | count++; | ||
828 | } | ||
829 | } | ||
830 | type_events = count; | ||
831 | |||
832 | for (i = 0; i < desc->total.ifaces; i++) | ||
833 | { | ||
834 | const Eina_Model_Event_Description *itr = desc->cache.ifaces[i]->events; | ||
835 | if (!itr) continue; | ||
836 | for (; itr->name != NULL; itr++) | ||
837 | count++; | ||
838 | } | ||
839 | |||
840 | if (count == 0) | ||
841 | { | ||
842 | desc->cache.events = NULL; | ||
843 | desc->total.events = 0; | ||
844 | return EINA_TRUE; | ||
845 | } | ||
846 | |||
847 | desc->cache.events = malloc(count * | ||
848 | sizeof(Eina_Model_Event_Description_Cache)); | ||
849 | EINA_SAFETY_ON_NULL_RETURN_VAL(desc->cache.events, EINA_FALSE); | ||
850 | desc->total.events = 0; | ||
851 | |||
852 | for (i = 0; i < desc->total.types; i++) | ||
853 | { | ||
854 | const Eina_Model_Type *mtype = desc->cache.types[i]; | ||
855 | const Eina_Model_Event_Description *itr = mtype->events; | ||
856 | if (!itr) continue; | ||
857 | for (; itr->name != NULL; itr++) | ||
858 | { | ||
859 | int j = _eina_model_description_events_find(desc, itr); | ||
860 | if (j >= 0) | ||
861 | { | ||
862 | const Eina_Model_Event_Description_Cache *o = desc->cache.events + j; | ||
863 | const Eina_Model_Type *omtype = o->provider.type; | ||
864 | WRN("Ignored duplicated event '%s' (type: '%s') from " | ||
865 | "model type %p (%s): already exists with type '%s' " | ||
866 | "from model type %p (%s)", | ||
867 | itr->name, | ||
868 | itr->type ? itr->type : "", | ||
869 | mtype, mtype->name, | ||
870 | o->desc->type ? o->desc->type : "", | ||
871 | omtype, omtype->name); | ||
872 | continue; | ||
873 | } | ||
874 | |||
875 | desc->cache.events[desc->total.events].name = itr->name; | ||
876 | desc->cache.events[desc->total.events].desc = itr; | ||
877 | desc->cache.events[desc->total.events].provider.type = mtype; | ||
878 | desc->total.events++; | ||
879 | } | ||
880 | } | ||
881 | |||
882 | for (i = 0; i < desc->total.ifaces; i++) | ||
883 | { | ||
884 | const Eina_Model_Interface *miface = desc->cache.ifaces[i]; | ||
885 | const Eina_Model_Event_Description *itr = desc->cache.ifaces[i]->events; | ||
886 | if (!itr) continue; | ||
887 | for (; itr->name != NULL; itr++) | ||
888 | { | ||
889 | int j = _eina_model_description_events_find(desc, itr); | ||
890 | if (j >= 0) | ||
891 | { | ||
892 | const Eina_Model_Event_Description_Cache *o = desc->cache.events + j; | ||
893 | if ((unsigned)j < type_events) | ||
894 | { | ||
895 | const Eina_Model_Type *omtype = o->provider.type; | ||
896 | WRN("Ignored duplicated event '%s' (type: '%s') from " | ||
897 | "model interface %p (%s): already exists with " | ||
898 | "type '%s' from model interface %p (%s)", | ||
899 | itr->name, | ||
900 | itr->type ? itr->type : "", | ||
901 | miface, miface->name, | ||
902 | o->desc->type ? o->desc->type : "", | ||
903 | omtype, omtype->name); | ||
904 | } | ||
905 | else | ||
906 | { | ||
907 | const Eina_Model_Interface *omiface = o->provider.iface; | ||
908 | WRN("Ignored duplicated event '%s' (iface: '%s') from " | ||
909 | "model interface %p (%s): already exists with " | ||
910 | "interface '%s' from model interface %p (%s)", | ||
911 | itr->name, | ||
912 | itr->type ? itr->type : "", | ||
913 | miface, miface->name, | ||
914 | o->desc->type ? o->desc->type : "", | ||
915 | omiface, omiface->name); | ||
916 | } | ||
917 | continue; | ||
918 | } | ||
919 | |||
920 | desc->cache.events[desc->total.events].name = itr->name; | ||
921 | desc->cache.events[desc->total.events].desc = itr; | ||
922 | desc->cache.events[desc->total.events].provider.iface = miface; | ||
923 | desc->total.events++; | ||
924 | } | ||
925 | } | ||
926 | |||
927 | qsort(desc->cache.events, desc->total.events, | ||
928 | sizeof(Eina_Model_Event_Description_Cache), | ||
929 | _eina_model_description_events_cmp); | ||
930 | |||
931 | return EINA_TRUE; | ||
932 | } | ||
933 | |||
934 | static const Eina_Model_Description * | ||
935 | _eina_model_description_get_internal(const Eina_Model_Type *type) | ||
936 | { | ||
937 | Eina_Model_Description *desc; | ||
938 | |||
939 | desc = eina_hash_find(_eina_model_descriptions, &type); | ||
940 | if (desc) | ||
941 | { | ||
942 | desc->refcount++; | ||
943 | return desc; | ||
944 | } | ||
945 | |||
946 | desc = calloc(1, sizeof(Eina_Model_Description)); | ||
947 | EINA_SAFETY_ON_NULL_RETURN_VAL(desc, NULL); | ||
948 | |||
949 | if (!_eina_model_description_type_fill(desc, type)) goto failed_type; | ||
950 | if (!_eina_model_description_ifaces_fill(desc)) goto failed_ifaces; | ||
951 | if (!_eina_model_description_privates_fill(desc)) goto failed_privates; | ||
952 | if (!_eina_model_description_events_fill(desc)) goto failed_events; | ||
953 | if (!eina_hash_add(_eina_model_descriptions, &type, desc)) goto failed_hash; | ||
954 | |||
955 | desc->refcount = 1; | ||
956 | return desc; | ||
957 | |||
958 | failed_hash: | ||
959 | free(desc->cache.events); | ||
960 | failed_events: | ||
961 | free(desc->cache.privates); | ||
962 | failed_privates: | ||
963 | free(desc->cache.ifaces); | ||
964 | failed_ifaces: | ||
965 | free(desc->cache.types); | ||
966 | free(desc->ops.type.extension); | ||
967 | failed_type: | ||
968 | free(desc); | ||
969 | return NULL; | ||
970 | } | ||
971 | |||
972 | static void | ||
973 | _eina_model_description_dispose_internal(Eina_Model_Description *desc) | ||
974 | { | ||
975 | const Eina_Model_Type *type; | ||
976 | |||
977 | EINA_SAFETY_ON_FALSE_RETURN(desc->refcount > 0); | ||
978 | desc->refcount--; | ||
979 | if (desc->refcount > 0) return; | ||
980 | |||
981 | type = desc->cache.types[0]; | ||
982 | if (!eina_hash_del_by_key(_eina_model_descriptions, &type)) | ||
983 | ERR("Cannot find type %p (%s) in descriptions hash!", | ||
984 | type, type->name); | ||
985 | |||
986 | INF("Disposed model description for type %p (%s)", type, type->name); | ||
987 | |||
988 | free(desc->ops.type.extension); | ||
989 | free(desc->cache.types); | ||
990 | free(desc->cache.ifaces); | ||
991 | free(desc->cache.privates); | ||
992 | free(desc->cache.events); | ||
993 | free(desc); | ||
994 | } | ||
995 | |||
996 | static const Eina_Model_Description * | ||
997 | _eina_model_description_get(const Eina_Model_Type *type) | ||
998 | { | ||
999 | const Eina_Model_Description *desc; | ||
1000 | |||
1001 | eina_lock_take(&_eina_model_descriptions_lock); | ||
1002 | desc = _eina_model_description_get_internal(type); | ||
1003 | eina_lock_release(&_eina_model_descriptions_lock); | ||
1004 | |||
1005 | return desc; | ||
1006 | } | ||
1007 | |||
1008 | static void | ||
1009 | _eina_model_description_dispose(const Eina_Model_Description *desc) | ||
1010 | { | ||
1011 | eina_lock_take(&_eina_model_descriptions_lock); | ||
1012 | _eina_model_description_dispose_internal((Eina_Model_Description *)desc); | ||
1013 | eina_lock_release(&_eina_model_descriptions_lock); | ||
1014 | } | ||
1015 | |||
1016 | static inline int | ||
1017 | _eina_model_description_event_id_find(const Eina_Model_Description *desc, const char *event_name) | ||
1018 | { | ||
1019 | const Eina_Model_Event_Description_Cache *cache; | ||
1020 | Eina_Model_Event_Description_Cache criteria_match; | ||
1021 | |||
1022 | criteria_match.name = event_name; | ||
1023 | cache = bsearch(&criteria_match, desc->cache.events, desc->total.events, | ||
1024 | sizeof(Eina_Model_Event_Description_Cache), | ||
1025 | _eina_model_description_events_cmp); | ||
1026 | if (!cache) | ||
1027 | { | ||
1028 | ERR("No event named %s for type %p (%s)", event_name, | ||
1029 | desc->cache.types[0], desc->cache.types[0]->name); | ||
1030 | return -1; | ||
1031 | } | ||
1032 | |||
1033 | return cache - desc->cache.events; | ||
1034 | } | ||
1035 | |||
1036 | /* | ||
1037 | * Model management and book keeping | ||
1038 | */ | ||
1039 | typedef struct _Eina_Model_Event_Listener Eina_Model_Event_Listener; | ||
1040 | struct _Eina_Model_Event_Listener | ||
1041 | { | ||
1042 | EINA_INLIST; | ||
1043 | Eina_Model_Event_Cb cb; | ||
1044 | const void *data; | ||
1045 | Eina_Bool deleted:1; | ||
1046 | }; | ||
1047 | |||
1048 | struct _Eina_Model | ||
1049 | { | ||
1050 | const Eina_Model_Description *desc; /**< optimized model description */ | ||
1051 | struct { | ||
1052 | Eina_Inlist **entries; /**< connected/listeners for each event, array of lists of Eina_Model_Event_Listener */ | ||
1053 | Eina_List **deleted; /**< deleted listeners while was walking. array of lists of Eina_Model_Event_Listener with deleted flag */ | ||
1054 | int *freeze; /**< freeze count for each event */ | ||
1055 | int walking; /**< increased while walking entries lists */ | ||
1056 | } listeners; | ||
1057 | void **privates; /**< private data per type and interface, each level gets its own stuff */ | ||
1058 | Eina_Inlist *xrefs; /**< if EINA_MODEL_DEBUG and eina_model_xref() is used */ | ||
1059 | int refcount; /**< number of users of this model instance */ | ||
1060 | Eina_Bool deleted:1; /**< if deleted but still have references */ | ||
1061 | EINA_MAGIC | ||
1062 | }; | ||
1063 | |||
1064 | static inline Eina_Bool | ||
1065 | _eina_model_type_check(const Eina_Model_Type *type) | ||
1066 | { | ||
1067 | EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE); | ||
1068 | EINA_SAFETY_ON_FALSE_RETURN_VAL(type->version == EINA_MODEL_TYPE_VERSION, | ||
1069 | EINA_FALSE); | ||
1070 | return EINA_TRUE; | ||
1071 | } | ||
1072 | |||
1073 | /* find in type hierarchy the first one that the given offset is not a null | ||
1074 | * pointer. Use this to discover which method to call on a parent. | ||
1075 | */ | ||
1076 | static const void * | ||
1077 | _eina_model_type_find_offset(const Eina_Model_Type *type, unsigned int offset) | ||
1078 | { | ||
1079 | const unsigned char *ptr = (const unsigned char *)type; | ||
1080 | const void **addr = (const void **)(ptr + offset); | ||
1081 | |||
1082 | if (*addr) return *addr; | ||
1083 | if (!type->parent) return NULL; | ||
1084 | return _eina_model_type_find_offset(type->parent, offset); | ||
1085 | } | ||
1086 | |||
1087 | /* find in interface hierarchy the first one that the given offset is | ||
1088 | * not a null pointer. Use this to discover which method to call on a | ||
1089 | * parent. | ||
1090 | * | ||
1091 | * TODO: Keep Eina_Model_Interface_Description with topological sorted | ||
1092 | * entries for each interface? | ||
1093 | * I smell problems with the current code in more complex | ||
1094 | * situations (k-s) | ||
1095 | * | ||
1096 | * iface1 | ||
1097 | * ^ | ||
1098 | * | | ||
1099 | * .---------+---------. | ||
1100 | * | | | | ||
1101 | * iface2 iface3 iface4 | ||
1102 | * ^ ^ ^ | ||
1103 | * | | | | ||
1104 | * `---------+---------' | ||
1105 | * | | ||
1106 | * iface5 | ||
1107 | * | ||
1108 | * It should look: iface5 -> iface2 -> iface3 -> iface4 -> iface1 | ||
1109 | * Now it does: iface5 -> iface2 -> iface1 -> iface3 -> iface1 -> iface4 -> iface1 | ||
1110 | * | ||
1111 | * | ||
1112 | * iface1 | ||
1113 | * ^ | ||
1114 | * | | ||
1115 | * iface2 | ||
1116 | * ^ | ||
1117 | * | | ||
1118 | * .---------+---------. | ||
1119 | * | | | ||
1120 | * iface3 iface4 | ||
1121 | * ^ ^ | ||
1122 | * | | | ||
1123 | * `---------+---------' | ||
1124 | * | | ||
1125 | * iface5 | ||
1126 | * | ||
1127 | * It should look: iface5 -> iface3 -> iface4 -> iface2 -> iface1 | ||
1128 | * Now it does: iface5 -> iface3 -> iface2 -> iface1 -> iface4 -> iface2 -> iface1 | ||
1129 | * | ||
1130 | * | ||
1131 | * iface1 iface2 | ||
1132 | * ^ ^ | ||
1133 | * | | | ||
1134 | * `---------+---------' | ||
1135 | * | | ||
1136 | * iface3 | ||
1137 | * | ||
1138 | * It should look: iface3 -> iface1 -> iface2 | ||
1139 | * Now it does: iface3 -> iface1 -> iface2 | ||
1140 | * | ||
1141 | * For the common case it should work, let's see. | ||
1142 | */ | ||
1143 | static const void * | ||
1144 | _eina_model_interface_find_offset(const Eina_Model_Interface *iface, unsigned int offset) | ||
1145 | { | ||
1146 | const Eina_Model_Interface **itr; | ||
1147 | const unsigned char *ptr = (const unsigned char *)iface; | ||
1148 | const void **addr = (const void **)(ptr + offset); | ||
1149 | |||
1150 | if (offset + sizeof(void *) > iface->interface_size) return NULL; | ||
1151 | |||
1152 | if (*addr) return *addr; | ||
1153 | if (!iface->interfaces) return NULL; | ||
1154 | |||
1155 | for (itr = iface->interfaces; *itr != NULL; itr++) | ||
1156 | { | ||
1157 | const void *r = _eina_model_interface_find_offset(*itr, offset); | ||
1158 | if (r) | ||
1159 | return r; | ||
1160 | } | ||
1161 | |||
1162 | return NULL; | ||
1163 | } | ||
1164 | |||
1165 | static void | ||
1166 | _eina_model_event_callback_free_deleted(Eina_Model *model) | ||
1167 | { | ||
1168 | unsigned int i; | ||
1169 | |||
1170 | for (i = 0; i < model->desc->total.events; i++) | ||
1171 | { | ||
1172 | Eina_Model_Event_Listener *el; | ||
1173 | EINA_LIST_FREE(model->listeners.deleted[i], el) | ||
1174 | { | ||
1175 | model->listeners.entries[i] = eina_inlist_remove | ||
1176 | (model->listeners.entries[i], EINA_INLIST_GET(el)); | ||
1177 | _eina_model_inner_free(sizeof(Eina_Model_Event_Listener), el); | ||
1178 | } | ||
1179 | } | ||
1180 | |||
1181 | _eina_model_inner_free(model->desc->total.events * sizeof(Eina_List *), | ||
1182 | model->listeners.deleted); | ||
1183 | model->listeners.deleted = NULL; | ||
1184 | } | ||
1185 | |||
1186 | static inline Eina_Bool | ||
1187 | _eina_model_event_callback_call(Eina_Model *model, const char *name, const void *event_info) | ||
1188 | { | ||
1189 | Eina_Inlist *lst; | ||
1190 | Eina_Model_Event_Listener *el; | ||
1191 | const Eina_Model_Event_Description *ev_desc; | ||
1192 | int event_id = _eina_model_description_event_id_find(model->desc, name); | ||
1193 | |||
1194 | if (event_id < 0) return EINA_FALSE; | ||
1195 | if (!model->listeners.entries) return EINA_TRUE; | ||
1196 | |||
1197 | if ((model->listeners.freeze) && (model->listeners.freeze[event_id])) | ||
1198 | { | ||
1199 | DBG("Ignored event callback '%s' of model %p (%s): frozen", | ||
1200 | name, model, model->desc->cache.types[0]->name); | ||
1201 | return EINA_TRUE; | ||
1202 | } | ||
1203 | |||
1204 | lst = model->listeners.entries[event_id]; | ||
1205 | if (!lst) return EINA_TRUE; | ||
1206 | |||
1207 | ev_desc = model->desc->cache.events[event_id].desc; | ||
1208 | |||
1209 | model->listeners.walking++; | ||
1210 | EINA_INLIST_FOREACH(lst, el) | ||
1211 | { | ||
1212 | if (el->deleted) continue; | ||
1213 | el->cb((void *)el->data, model, ev_desc, (void *)event_info); | ||
1214 | } | ||
1215 | model->listeners.walking--; | ||
1216 | |||
1217 | if ((model->listeners.walking == 0) && (model->listeners.deleted)) | ||
1218 | _eina_model_event_callback_free_deleted(model); | ||
1219 | |||
1220 | return EINA_FALSE; | ||
1221 | } | ||
1222 | |||
1223 | static const char EINA_ERROR_MODEL_FAILED_STR[] = "Model check failed."; | ||
1224 | static const char EINA_ERROR_MODEL_METHOD_MISSING_STR[] = "Model method is missing."; | ||
1225 | static const char EINA_MAGIC_MODEL_STR[] = "Eina Model"; | ||
1226 | |||
1227 | static void _eina_model_unref(Eina_Model *model); | ||
1228 | |||
1229 | /** | ||
1230 | * @endcond | ||
1231 | */ | ||
1232 | |||
1233 | /* EINA_MODEL_TYPE_BASE: base of all other types **********************/ | ||
1234 | |||
1235 | static Eina_Bool | ||
1236 | _eina_model_type_base_setup(Eina_Model *model) | ||
1237 | { | ||
1238 | DBG("base setup of %p", model); | ||
1239 | return EINA_TRUE; | ||
1240 | } | ||
1241 | |||
1242 | static Eina_Bool | ||
1243 | _eina_model_type_base_flush(Eina_Model *model) | ||
1244 | { | ||
1245 | DBG("base flush of %p", model); | ||
1246 | return EINA_TRUE; | ||
1247 | } | ||
1248 | |||
1249 | static Eina_Bool | ||
1250 | _eina_model_type_base_constructor(Eina_Model *model) | ||
1251 | { | ||
1252 | DBG("base constructor of %p", model); | ||
1253 | return EINA_TRUE; | ||
1254 | } | ||
1255 | |||
1256 | static Eina_Bool | ||
1257 | _eina_model_type_base_destructor(Eina_Model *model) | ||
1258 | { | ||
1259 | DBG("base destructor of %p", model); | ||
1260 | return EINA_TRUE; | ||
1261 | } | ||
1262 | |||
1263 | static Eina_Bool | ||
1264 | _eina_model_type_base_properties_copy(const Eina_Model *model, Eina_Model *copy) | ||
1265 | { | ||
1266 | Eina_List *l, *props = eina_model_properties_names_list_get(model); | ||
1267 | const char *name; | ||
1268 | EINA_LIST_FOREACH(props, l, name) | ||
1269 | { | ||
1270 | Eina_Value tmp; | ||
1271 | if (!eina_model_property_get(model, name, &tmp)) | ||
1272 | { | ||
1273 | ERR("Could not get property %s from model %p (%s)", | ||
1274 | name, model, model->desc->cache.types[0]->name); | ||
1275 | eina_model_properties_names_list_free(props); | ||
1276 | return EINA_FALSE; | ||
1277 | } | ||
1278 | if (!eina_model_property_set(copy, name, &tmp)) | ||
1279 | { | ||
1280 | ERR("Could not set property %s on model %p (%s)", | ||
1281 | name, copy, copy->desc->cache.types[0]->name); | ||
1282 | eina_value_flush(&tmp); | ||
1283 | eina_model_properties_names_list_free(props); | ||
1284 | return EINA_FALSE; | ||
1285 | } | ||
1286 | eina_value_flush(&tmp); | ||
1287 | } | ||
1288 | eina_model_properties_names_list_free(props); | ||
1289 | return EINA_TRUE; | ||
1290 | } | ||
1291 | |||
1292 | static Eina_Bool | ||
1293 | _eina_model_type_base_children_copy(const Eina_Model *model, Eina_Model *copy) | ||
1294 | { | ||
1295 | int i, count = eina_model_child_count(model); | ||
1296 | |||
1297 | if (count < 0) | ||
1298 | { | ||
1299 | ERR("Could not get children count of model %p (%s)", | ||
1300 | model, model->desc->cache.types[0]->name); | ||
1301 | return EINA_FALSE; | ||
1302 | } | ||
1303 | |||
1304 | for (i = 0; i < count; i++) | ||
1305 | { | ||
1306 | Eina_Model *child = eina_model_child_get(model, i); | ||
1307 | Eina_Bool ret; | ||
1308 | |||
1309 | if (!child) | ||
1310 | { | ||
1311 | ERR("Could not get child #%d from model %p (%s)", | ||
1312 | i, model, model->desc->cache.types[0]->name); | ||
1313 | return EINA_FALSE; | ||
1314 | } | ||
1315 | |||
1316 | ret = eina_model_child_insert_at(copy, i, child); | ||
1317 | _eina_model_unref(child); | ||
1318 | |||
1319 | if (!ret) | ||
1320 | { | ||
1321 | ERR("Could not set child #%d on model %p (%s)", | ||
1322 | i, copy, copy->desc->cache.types[0]->name); | ||
1323 | return EINA_FALSE; | ||
1324 | } | ||
1325 | } | ||
1326 | |||
1327 | return EINA_TRUE; | ||
1328 | } | ||
1329 | |||
1330 | static Eina_Bool | ||
1331 | _eina_model_type_base_copy(const Eina_Model *model, Eina_Model *copy) | ||
1332 | { | ||
1333 | DBG("base copy of %p to %p", model, copy); | ||
1334 | |||
1335 | return _eina_model_type_base_properties_copy(model, copy) && | ||
1336 | _eina_model_type_base_children_copy(model, copy); | ||
1337 | } | ||
1338 | |||
1339 | static Eina_Bool | ||
1340 | _eina_model_type_base_children_deep_copy(const Eina_Model *model, Eina_Model *copy) | ||
1341 | { | ||
1342 | int i, count = eina_model_child_count(model); | ||
1343 | |||
1344 | if (count < 0) | ||
1345 | { | ||
1346 | ERR("Could not get children count of model %p (%s)", | ||
1347 | model, model->desc->cache.types[0]->name); | ||
1348 | return EINA_FALSE; | ||
1349 | } | ||
1350 | |||
1351 | for (i = 0; i < count; i++) | ||
1352 | { | ||
1353 | Eina_Model *child_copy, *child = eina_model_child_get(model, i); | ||
1354 | Eina_Bool ret; | ||
1355 | |||
1356 | if (!child) | ||
1357 | { | ||
1358 | ERR("Could not get child #%d from model %p (%s)", | ||
1359 | i, model, model->desc->cache.types[0]->name); | ||
1360 | return EINA_FALSE; | ||
1361 | } | ||
1362 | |||
1363 | child_copy = eina_model_deep_copy(child); | ||
1364 | if (!child_copy) | ||
1365 | { | ||
1366 | ERR("Could not deep copy child #%d %p (%s) from model %p (%s)", i, | ||
1367 | child, child->desc->cache.types[0]->name, | ||
1368 | model, model->desc->cache.types[0]->name); | ||
1369 | _eina_model_unref(child); | ||
1370 | return EINA_FALSE; | ||
1371 | } | ||
1372 | _eina_model_unref(child); | ||
1373 | |||
1374 | ret = eina_model_child_insert_at(copy, i, child_copy); | ||
1375 | _eina_model_unref(child_copy); | ||
1376 | |||
1377 | if (!ret) | ||
1378 | { | ||
1379 | ERR("Could not set child #%d on model %p (%s)", | ||
1380 | i, copy, copy->desc->cache.types[0]->name); | ||
1381 | return EINA_FALSE; | ||
1382 | } | ||
1383 | } | ||
1384 | |||
1385 | return EINA_TRUE; | ||
1386 | } | ||
1387 | |||
1388 | static Eina_Bool | ||
1389 | _eina_model_type_base_deep_copy(const Eina_Model *model, Eina_Model *copy) | ||
1390 | { | ||
1391 | DBG("base deep copy of %p to %p", model, copy); | ||
1392 | |||
1393 | return _eina_model_type_base_properties_copy(model, copy) && | ||
1394 | _eina_model_type_base_children_deep_copy(model, copy); | ||
1395 | } | ||
1396 | |||
1397 | static Eina_Bool | ||
1398 | _eina_model_type_base_properties_compare(const Eina_Model *a, const Eina_Model *b, int *cmp) | ||
1399 | { | ||
1400 | Eina_List *al, *aprops = eina_model_properties_names_list_get(a); | ||
1401 | Eina_List *bl, *bprops = eina_model_properties_names_list_get(b); | ||
1402 | Eina_List *l, *props = NULL; | ||
1403 | const char *aname, *bname, *name; | ||
1404 | Eina_Bool ret = EINA_TRUE; | ||
1405 | |||
1406 | EINA_LIST_FOREACH(aprops, al, aname) | ||
1407 | { | ||
1408 | EINA_LIST_FOREACH(bprops, bl, bname) | ||
1409 | if (strcmp(aname, bname) == 0) | ||
1410 | { | ||
1411 | props = eina_list_append(props, aname); | ||
1412 | break; | ||
1413 | } | ||
1414 | } | ||
1415 | |||
1416 | *cmp = 0; | ||
1417 | EINA_LIST_FOREACH(props, l, name) | ||
1418 | { | ||
1419 | Eina_Value atmp, btmp; | ||
1420 | |||
1421 | if (!eina_model_property_get(a, name, &atmp)) | ||
1422 | { | ||
1423 | ERR("Could not get property %s from model %p (%s)", | ||
1424 | name, a, a->desc->cache.types[0]->name); | ||
1425 | ret = EINA_FALSE; | ||
1426 | *cmp = -1; | ||
1427 | break; | ||
1428 | } | ||
1429 | |||
1430 | if (!eina_model_property_get(b, name, &btmp)) | ||
1431 | { | ||
1432 | ERR("Could not get property %s from model %p (%s)", | ||
1433 | name, b, b->desc->cache.types[0]->name); | ||
1434 | ret = EINA_FALSE; | ||
1435 | *cmp = -1; | ||
1436 | eina_value_flush(&atmp); | ||
1437 | break; | ||
1438 | } | ||
1439 | |||
1440 | *cmp = eina_value_compare(&atmp, &btmp); | ||
1441 | if (eina_error_get() != 0) | ||
1442 | { | ||
1443 | char *astr = eina_value_to_string(&atmp); | ||
1444 | char *bstr = eina_value_to_string(&btmp); | ||
1445 | ERR("Could not compare property %s: %s=%s, %s=%s", name, | ||
1446 | eina_value_type_name_get(eina_value_type_get(&atmp)), astr, | ||
1447 | eina_value_type_name_get(eina_value_type_get(&btmp)), bstr); | ||
1448 | free(astr); | ||
1449 | free(bstr); | ||
1450 | ret = EINA_FALSE; | ||
1451 | *cmp = -1; | ||
1452 | } | ||
1453 | |||
1454 | eina_value_flush(&atmp); | ||
1455 | eina_value_flush(&btmp); | ||
1456 | |||
1457 | if ((!ret) || (*cmp != 0)) | ||
1458 | break; | ||
1459 | } | ||
1460 | |||
1461 | if ((ret) && (*cmp == 0)) | ||
1462 | { | ||
1463 | int acount = eina_list_count(aprops); | ||
1464 | int bcount = eina_list_count(bprops); | ||
1465 | |||
1466 | if (acount < bcount) | ||
1467 | *cmp = -1; | ||
1468 | else if (acount > bcount) | ||
1469 | *cmp = 1; | ||
1470 | } | ||
1471 | |||
1472 | eina_model_properties_names_list_free(aprops); | ||
1473 | eina_model_properties_names_list_free(bprops); | ||
1474 | eina_list_free(props); | ||
1475 | return ret; | ||
1476 | } | ||
1477 | |||
1478 | static Eina_Bool | ||
1479 | _eina_model_type_base_children_compare(const Eina_Model *a, const Eina_Model *b, int *cmp) | ||
1480 | { | ||
1481 | int acount = eina_model_child_count(a); | ||
1482 | int bcount = eina_model_child_count(b); | ||
1483 | int i, count; | ||
1484 | Eina_Bool ret = EINA_TRUE; | ||
1485 | |||
1486 | if (acount < 0) | ||
1487 | { | ||
1488 | ERR("Could not get children count of model %p (%s)", | ||
1489 | a, a->desc->cache.types[0]->name); | ||
1490 | return EINA_FALSE; | ||
1491 | } | ||
1492 | if (bcount < 0) | ||
1493 | { | ||
1494 | ERR("Could not get children count of model %p (%s)", | ||
1495 | b, b->desc->cache.types[0]->name); | ||
1496 | return EINA_FALSE; | ||
1497 | } | ||
1498 | |||
1499 | if (acount < bcount) | ||
1500 | count = acount; | ||
1501 | else | ||
1502 | count = bcount; | ||
1503 | |||
1504 | for (i = 0; i < count; i++) | ||
1505 | { | ||
1506 | Eina_Model *achild, *bchild; | ||
1507 | |||
1508 | achild = eina_model_child_get(a, i); | ||
1509 | if (!achild) | ||
1510 | { | ||
1511 | ERR("Could not get child #%d from model %p (%s)", | ||
1512 | i, a, a->desc->cache.types[0]->name); | ||
1513 | *cmp = -1; | ||
1514 | return EINA_FALSE; | ||
1515 | } | ||
1516 | |||
1517 | bchild = eina_model_child_get(b, i); | ||
1518 | if (!bchild) | ||
1519 | { | ||
1520 | ERR("Could not get child #%d from model %p (%s)", | ||
1521 | i, b, b->desc->cache.types[0]->name); | ||
1522 | *cmp = -1; | ||
1523 | _eina_model_unref(achild); | ||
1524 | return EINA_FALSE; | ||
1525 | } | ||
1526 | |||
1527 | *cmp = eina_model_compare(achild, bchild); | ||
1528 | if (eina_error_get()) | ||
1529 | { | ||
1530 | ERR("Could not compare children #%d %p (%s) and %p (%s) " | ||
1531 | "from models %p (%s) and %p (%s)", i, | ||
1532 | achild, | ||
1533 | eina_model_type_name_get(eina_model_type_get(achild)), | ||
1534 | bchild, | ||
1535 | eina_model_type_name_get(eina_model_type_get(bchild)), | ||
1536 | a, a->desc->cache.types[0]->name, | ||
1537 | b, b->desc->cache.types[0]->name); | ||
1538 | ret = EINA_FALSE; | ||
1539 | } | ||
1540 | _eina_model_unref(achild); | ||
1541 | _eina_model_unref(bchild); | ||
1542 | |||
1543 | if ((!ret) || (*cmp != 0)) | ||
1544 | break; | ||
1545 | } | ||
1546 | |||
1547 | if ((ret) && (*cmp == 0)) | ||
1548 | { | ||
1549 | if (acount < bcount) | ||
1550 | *cmp = -1; | ||
1551 | else if (acount > bcount) | ||
1552 | *cmp = 1; | ||
1553 | } | ||
1554 | |||
1555 | return ret; | ||
1556 | } | ||
1557 | |||
1558 | static Eina_Bool | ||
1559 | _eina_model_type_base_compare(const Eina_Model *a, const Eina_Model *b, int *cmp) | ||
1560 | { | ||
1561 | *cmp = 0; | ||
1562 | DBG("base compare of %p and %p", a, b); | ||
1563 | |||
1564 | if (!_eina_model_type_base_properties_compare(a, b, cmp)) | ||
1565 | return EINA_FALSE; | ||
1566 | |||
1567 | if (*cmp != 0) | ||
1568 | return EINA_TRUE; | ||
1569 | |||
1570 | return _eina_model_type_base_children_compare(a, b, cmp); | ||
1571 | } | ||
1572 | |||
1573 | static int | ||
1574 | _eina_model_type_base_child_count(const Eina_Model *model) | ||
1575 | { | ||
1576 | DBG("base child_count of %p", model); | ||
1577 | return 0; | ||
1578 | } | ||
1579 | |||
1580 | static int | ||
1581 | _eina_model_type_base_child_find(const Eina_Model *model, unsigned int start_position, const Eina_Model *other) | ||
1582 | { | ||
1583 | int x = eina_model_child_count(model); | ||
1584 | unsigned int i, count; | ||
1585 | |||
1586 | DBG("base child_find of %p, %d children", model, x); | ||
1587 | |||
1588 | if (x < 0) | ||
1589 | return -1; | ||
1590 | |||
1591 | count = x; | ||
1592 | for (i = start_position; i < count; i++) | ||
1593 | { | ||
1594 | Eina_Model *current = eina_model_child_get(model, i); | ||
1595 | if (current) | ||
1596 | { | ||
1597 | _eina_model_unref(current); /* we'll not use it's value anyway */ | ||
1598 | if (current == other) | ||
1599 | return i; | ||
1600 | } | ||
1601 | } | ||
1602 | |||
1603 | return -1; | ||
1604 | } | ||
1605 | |||
1606 | static int | ||
1607 | _eina_model_type_base_child_criteria_match(const Eina_Model *model, unsigned int start_position, Eina_Each_Cb match, const void *user_data) | ||
1608 | { | ||
1609 | int x = eina_model_child_count(model); | ||
1610 | unsigned int i, count; | ||
1611 | |||
1612 | DBG("base child_criteria_match of %p, %d children", model, x); | ||
1613 | |||
1614 | if (x < 0) | ||
1615 | return -1; | ||
1616 | |||
1617 | count = x; | ||
1618 | for (i = start_position; i < count; i++) | ||
1619 | { | ||
1620 | Eina_Model *current = eina_model_child_get(model, i); | ||
1621 | if (current) | ||
1622 | { | ||
1623 | Eina_Bool r = match(model, current, (void *)user_data); | ||
1624 | _eina_model_unref(current); | ||
1625 | if (r) | ||
1626 | return i; | ||
1627 | } | ||
1628 | } | ||
1629 | |||
1630 | return -1; | ||
1631 | } | ||
1632 | |||
1633 | typedef struct _Eina_Iterator_Model_Base Eina_Iterator_Model_Base; | ||
1634 | struct _Eina_Iterator_Model_Base | ||
1635 | { | ||
1636 | Eina_Iterator base; | ||
1637 | Eina_Model *model; | ||
1638 | unsigned int current; | ||
1639 | unsigned int end; | ||
1640 | }; | ||
1641 | |||
1642 | static Eina_Bool | ||
1643 | _eina_model_type_base_child_iterator_next(Eina_Iterator *base, void **data) | ||
1644 | { | ||
1645 | Eina_Iterator_Model_Base *it; | ||
1646 | |||
1647 | it = (Eina_Iterator_Model_Base *)base; | ||
1648 | if (it->current >= it->end) | ||
1649 | return EINA_FALSE; | ||
1650 | |||
1651 | *data = eina_model_child_get(it->model, it->current); | ||
1652 | if (!*data) | ||
1653 | return EINA_FALSE; | ||
1654 | |||
1655 | it->current++; | ||
1656 | return EINA_TRUE; | ||
1657 | } | ||
1658 | |||
1659 | static void * | ||
1660 | _eina_model_type_base_child_iterator_get_container(Eina_Iterator *base) | ||
1661 | { | ||
1662 | Eina_Iterator_Model_Base *it; | ||
1663 | it = (Eina_Iterator_Model_Base *)base; | ||
1664 | return it->model; | ||
1665 | } | ||
1666 | |||
1667 | static void | ||
1668 | _eina_model_type_base_child_iterator_free(Eina_Iterator *base) | ||
1669 | { | ||
1670 | Eina_Iterator_Model_Base *it; | ||
1671 | it = (Eina_Iterator_Model_Base *)base; | ||
1672 | eina_model_xunref(it->model, it); | ||
1673 | free(it); | ||
1674 | } | ||
1675 | |||
1676 | static Eina_Iterator * | ||
1677 | _eina_model_type_base_child_iterator_get(Eina_Model *model, unsigned int start, unsigned int count) | ||
1678 | { | ||
1679 | Eina_Iterator_Model_Base *it = calloc(1, sizeof(*it)); | ||
1680 | EINA_SAFETY_ON_NULL_RETURN_VAL(it, NULL); | ||
1681 | |||
1682 | EINA_MAGIC_SET(&it->base, EINA_MAGIC_ITERATOR); | ||
1683 | it->base.version = EINA_ITERATOR_VERSION; | ||
1684 | it->base.next = _eina_model_type_base_child_iterator_next; | ||
1685 | it->base.get_container = _eina_model_type_base_child_iterator_get_container; | ||
1686 | it->base.free = _eina_model_type_base_child_iterator_free; | ||
1687 | |||
1688 | it->model = eina_model_xref(model, it, "eina_model_child_slice_iterator_get"); | ||
1689 | it->current = start; | ||
1690 | it->end = start + count; | ||
1691 | |||
1692 | return &it->base; | ||
1693 | } | ||
1694 | |||
1695 | typedef struct _Eina_Iterator_Model_Base_Reversed Eina_Iterator_Model_Base_Reversed; | ||
1696 | struct _Eina_Iterator_Model_Base_Reversed | ||
1697 | { | ||
1698 | Eina_Iterator base; | ||
1699 | Eina_Model *model; | ||
1700 | unsigned int current; | ||
1701 | unsigned int end; | ||
1702 | }; | ||
1703 | |||
1704 | static Eina_Bool | ||
1705 | _eina_model_type_base_child_reversed_iterator_next(Eina_Iterator *base, void **data) | ||
1706 | { | ||
1707 | Eina_Iterator_Model_Base_Reversed *it; | ||
1708 | |||
1709 | it = (Eina_Iterator_Model_Base_Reversed *)base; | ||
1710 | if (it->current == it->end) | ||
1711 | return EINA_FALSE; | ||
1712 | |||
1713 | it->current--; | ||
1714 | *data = eina_model_child_get(it->model, it->current); | ||
1715 | if (!*data) | ||
1716 | return EINA_FALSE; | ||
1717 | |||
1718 | return EINA_TRUE; | ||
1719 | } | ||
1720 | |||
1721 | static void * | ||
1722 | _eina_model_type_base_child_reversed_iterator_get_container(Eina_Iterator *base) | ||
1723 | { | ||
1724 | Eina_Iterator_Model_Base_Reversed *it; | ||
1725 | it = (Eina_Iterator_Model_Base_Reversed *)base; | ||
1726 | return it->model; | ||
1727 | } | ||
1728 | |||
1729 | static void | ||
1730 | _eina_model_type_base_child_reversed_iterator_free(Eina_Iterator *base) | ||
1731 | { | ||
1732 | Eina_Iterator_Model_Base_Reversed *it; | ||
1733 | it = (Eina_Iterator_Model_Base_Reversed *)base; | ||
1734 | eina_model_xunref(it->model, it); | ||
1735 | free(it); | ||
1736 | } | ||
1737 | |||
1738 | static Eina_Iterator * | ||
1739 | _eina_model_type_base_child_reversed_iterator_get(Eina_Model *model, unsigned int start, unsigned int count) | ||
1740 | { | ||
1741 | Eina_Iterator_Model_Base_Reversed *it; | ||
1742 | int children_count; | ||
1743 | |||
1744 | children_count = eina_model_child_count(model); | ||
1745 | if (children_count < 0) | ||
1746 | return NULL; | ||
1747 | |||
1748 | if (start + count > (unsigned int)children_count) | ||
1749 | { | ||
1750 | if (start >= (unsigned int)children_count) | ||
1751 | count = 0; | ||
1752 | else | ||
1753 | count = children_count - start; | ||
1754 | } | ||
1755 | |||
1756 | it = calloc(1, sizeof(*it)); | ||
1757 | EINA_SAFETY_ON_NULL_RETURN_VAL(it, NULL); | ||
1758 | EINA_MAGIC_SET(&it->base, EINA_MAGIC_ITERATOR); | ||
1759 | it->base.version = EINA_ITERATOR_VERSION; | ||
1760 | it->base.next = _eina_model_type_base_child_reversed_iterator_next; | ||
1761 | it->base.get_container = _eina_model_type_base_child_reversed_iterator_get_container; | ||
1762 | it->base.free = _eina_model_type_base_child_reversed_iterator_free; | ||
1763 | |||
1764 | it->model = eina_model_xref(model, it, "eina_model_child_slice_reversed_iterator_get"); | ||
1765 | it->current = start + count; | ||
1766 | it->end = start; | ||
1767 | |||
1768 | return &it->base; | ||
1769 | } | ||
1770 | |||
1771 | typedef struct _Eina_Iterator_Model_Base_Sorted Eina_Iterator_Model_Base_Sorted; | ||
1772 | struct _Eina_Iterator_Model_Base_Sorted | ||
1773 | { | ||
1774 | Eina_Iterator base; | ||
1775 | Eina_Model *model; | ||
1776 | unsigned int current; | ||
1777 | unsigned int count; | ||
1778 | Eina_Model *elements[]; | ||
1779 | }; | ||
1780 | |||
1781 | static Eina_Bool | ||
1782 | _eina_model_type_base_child_sorted_iterator_next(Eina_Iterator *base, void **data) | ||
1783 | { | ||
1784 | Eina_Iterator_Model_Base_Sorted *it; | ||
1785 | |||
1786 | it = (Eina_Iterator_Model_Base_Sorted *)base; | ||
1787 | if (it->current == it->count) | ||
1788 | return EINA_FALSE; | ||
1789 | |||
1790 | *data = eina_model_ref(it->elements[it->current]); | ||
1791 | it->current++; | ||
1792 | return EINA_TRUE; | ||
1793 | } | ||
1794 | |||
1795 | static void * | ||
1796 | _eina_model_type_base_child_sorted_iterator_get_container(Eina_Iterator *base) | ||
1797 | { | ||
1798 | Eina_Iterator_Model_Base_Sorted *it; | ||
1799 | it = (Eina_Iterator_Model_Base_Sorted *)base; | ||
1800 | return it->model; | ||
1801 | } | ||
1802 | |||
1803 | static void | ||
1804 | _eina_model_type_base_child_sorted_iterator_free(Eina_Iterator *base) | ||
1805 | { | ||
1806 | Eina_Iterator_Model_Base_Sorted *it; | ||
1807 | unsigned int i; | ||
1808 | it = (Eina_Iterator_Model_Base_Sorted *)base; | ||
1809 | eina_model_xunref(it->model, it); | ||
1810 | |||
1811 | for (i = 0; i < it->count; i++) | ||
1812 | _eina_model_unref(it->elements[i]); | ||
1813 | |||
1814 | free(it); | ||
1815 | } | ||
1816 | |||
1817 | static Eina_Iterator * | ||
1818 | _eina_model_type_base_child_sorted_iterator_get(Eina_Model *model, unsigned int start, unsigned int count, Eina_Compare_Cb compare) | ||
1819 | { | ||
1820 | Eina_Iterator_Model_Base_Sorted *it; | ||
1821 | int children_count; | ||
1822 | unsigned int i; | ||
1823 | |||
1824 | children_count = eina_model_child_count(model); | ||
1825 | if (children_count < 0) | ||
1826 | return NULL; | ||
1827 | |||
1828 | if (start + count > (unsigned int)children_count) | ||
1829 | { | ||
1830 | if (start >= (unsigned int)children_count) | ||
1831 | count = 0; | ||
1832 | else | ||
1833 | count = children_count - start; | ||
1834 | } | ||
1835 | |||
1836 | it = calloc(1, sizeof(*it) + count * sizeof(Eina_Model *)); | ||
1837 | EINA_SAFETY_ON_NULL_RETURN_VAL(it, NULL); | ||
1838 | EINA_MAGIC_SET(&it->base, EINA_MAGIC_ITERATOR); | ||
1839 | it->base.version = EINA_ITERATOR_VERSION; | ||
1840 | it->base.next = _eina_model_type_base_child_sorted_iterator_next; | ||
1841 | it->base.get_container = _eina_model_type_base_child_sorted_iterator_get_container; | ||
1842 | it->base.free = _eina_model_type_base_child_sorted_iterator_free; | ||
1843 | |||
1844 | it->model = eina_model_xref(model, it, "eina_model_child_slice_sorted_iterator_get"); | ||
1845 | it->current = 0; | ||
1846 | it->count = count; | ||
1847 | |||
1848 | for (i = 0; i < count; i++) | ||
1849 | { | ||
1850 | it->elements[i] = eina_model_child_get(model, i + start); | ||
1851 | if (!it->elements[i]) | ||
1852 | { | ||
1853 | ERR("Failed to get child %u of model %p (%s)", | ||
1854 | i + start, model, model->desc->cache.types[0]->name); | ||
1855 | free(it); | ||
1856 | return NULL; | ||
1857 | } | ||
1858 | } | ||
1859 | |||
1860 | if (count > 1) | ||
1861 | _eina_model_array_sort(it->elements, 0, count - 1, compare); | ||
1862 | |||
1863 | return &it->base; | ||
1864 | } | ||
1865 | |||
1866 | typedef struct _Eina_Iterator_Model_Base_Filtered Eina_Iterator_Model_Base_Filtered; | ||
1867 | struct _Eina_Iterator_Model_Base_Filtered | ||
1868 | { | ||
1869 | Eina_Iterator base; | ||
1870 | Eina_Model *model; | ||
1871 | Eina_Each_Cb match; | ||
1872 | const void *data; | ||
1873 | unsigned int current; | ||
1874 | unsigned int count; | ||
1875 | }; | ||
1876 | |||
1877 | static Eina_Bool | ||
1878 | _eina_model_type_base_child_filtered_iterator_next(Eina_Iterator *base, void **data) | ||
1879 | { | ||
1880 | Eina_Iterator_Model_Base_Filtered *it; | ||
1881 | unsigned int *ret; | ||
1882 | int i; | ||
1883 | |||
1884 | it = (Eina_Iterator_Model_Base_Filtered *)base; | ||
1885 | if (it->count == 0) return EINA_FALSE; | ||
1886 | |||
1887 | i = eina_model_child_criteria_match(it->model, it->current, it->match, it->data); | ||
1888 | if (i < 0) return EINA_FALSE; | ||
1889 | |||
1890 | it->current = i + 1; | ||
1891 | it->count--; | ||
1892 | ret = (unsigned int *)data; | ||
1893 | *ret = i; | ||
1894 | return EINA_TRUE; | ||
1895 | } | ||
1896 | |||
1897 | static void * | ||
1898 | _eina_model_type_base_child_filtered_iterator_get_container(Eina_Iterator *base) | ||
1899 | { | ||
1900 | Eina_Iterator_Model_Base_Filtered *it; | ||
1901 | it = (Eina_Iterator_Model_Base_Filtered *)base; | ||
1902 | return it->model; | ||
1903 | } | ||
1904 | |||
1905 | static void | ||
1906 | _eina_model_type_base_child_filtered_iterator_free(Eina_Iterator *base) | ||
1907 | { | ||
1908 | Eina_Iterator_Model_Base_Filtered *it; | ||
1909 | it = (Eina_Iterator_Model_Base_Filtered *)base; | ||
1910 | eina_model_xunref(it->model, it); | ||
1911 | free(it); | ||
1912 | } | ||
1913 | |||
1914 | static Eina_Iterator * | ||
1915 | _eina_model_type_base_child_filtered_iterator_get(Eina_Model *model, unsigned int start, unsigned int count, Eina_Each_Cb match, const void *data) | ||
1916 | { | ||
1917 | Eina_Iterator_Model_Base_Filtered *it = calloc(1, sizeof(*it)); | ||
1918 | EINA_SAFETY_ON_NULL_RETURN_VAL(it, NULL); | ||
1919 | |||
1920 | EINA_MAGIC_SET(&it->base, EINA_MAGIC_ITERATOR); | ||
1921 | it->base.version = EINA_ITERATOR_VERSION; | ||
1922 | it->base.next = _eina_model_type_base_child_filtered_iterator_next; | ||
1923 | it->base.get_container = _eina_model_type_base_child_filtered_iterator_get_container; | ||
1924 | it->base.free = _eina_model_type_base_child_filtered_iterator_free; | ||
1925 | |||
1926 | it->model = eina_model_xref(model, it, "eina_model_child_slice_filtered_iterator_get"); | ||
1927 | it->match = match; | ||
1928 | it->data = data; | ||
1929 | it->current = start; | ||
1930 | it->count = count; | ||
1931 | |||
1932 | return &it->base; | ||
1933 | } | ||
1934 | |||
1935 | static char * | ||
1936 | _eina_model_type_base_to_string(const Eina_Model *model) | ||
1937 | { | ||
1938 | Eina_List *l, *props; | ||
1939 | const char *name; | ||
1940 | Eina_Strbuf *str; | ||
1941 | Eina_Bool first; | ||
1942 | int i, count; | ||
1943 | char *ret; | ||
1944 | |||
1945 | str = eina_strbuf_new(); | ||
1946 | EINA_SAFETY_ON_NULL_RETURN_VAL(str, NULL); | ||
1947 | |||
1948 | eina_strbuf_append_printf(str, "%s({", model->desc->cache.types[0]->name); | ||
1949 | |||
1950 | props = eina_model_properties_names_list_get(model); | ||
1951 | props = eina_list_sort(props, 0, EINA_COMPARE_CB(strcmp)); | ||
1952 | |||
1953 | first = EINA_TRUE; | ||
1954 | EINA_LIST_FOREACH(props, l, name) | ||
1955 | { | ||
1956 | Eina_Value val; | ||
1957 | |||
1958 | if (!first) | ||
1959 | eina_strbuf_append_printf(str, ", %s: ", name); | ||
1960 | else | ||
1961 | { | ||
1962 | eina_strbuf_append_printf(str, "%s: ", name); | ||
1963 | first = EINA_FALSE; | ||
1964 | } | ||
1965 | |||
1966 | if (!eina_model_property_get(model, name, &val)) | ||
1967 | eina_strbuf_append_char(str, '?'); | ||
1968 | else | ||
1969 | { | ||
1970 | char *tmp = eina_value_to_string(&val); | ||
1971 | eina_strbuf_append(str, tmp ? tmp : "?"); | ||
1972 | free(tmp); | ||
1973 | eina_value_flush(&val); | ||
1974 | } | ||
1975 | } | ||
1976 | eina_list_free(props); | ||
1977 | |||
1978 | eina_strbuf_append(str, "}, ["); | ||
1979 | |||
1980 | count = eina_model_child_count(model); | ||
1981 | first = EINA_TRUE; | ||
1982 | for (i = 0; i < count; i++) | ||
1983 | { | ||
1984 | Eina_Model *c = eina_model_child_get(model, i); | ||
1985 | if (!c) | ||
1986 | { | ||
1987 | if (!first) | ||
1988 | eina_strbuf_append(str, ", ?"); | ||
1989 | else | ||
1990 | { | ||
1991 | eina_strbuf_append_char(str, '?'); | ||
1992 | first = EINA_FALSE; | ||
1993 | } | ||
1994 | } | ||
1995 | else | ||
1996 | { | ||
1997 | char *tmp = eina_model_to_string(c); | ||
1998 | if (!first) | ||
1999 | eina_strbuf_append_printf(str, ", %s", tmp ? tmp : "?"); | ||
2000 | else | ||
2001 | { | ||
2002 | eina_strbuf_append(str, tmp ? tmp : "?"); | ||
2003 | first = EINA_FALSE; | ||
2004 | } | ||
2005 | free(tmp); | ||
2006 | _eina_model_unref(c); | ||
2007 | } | ||
2008 | } | ||
2009 | |||
2010 | eina_strbuf_append(str, "])"); | ||
2011 | |||
2012 | ret = eina_strbuf_string_steal(str); | ||
2013 | eina_strbuf_free(str); | ||
2014 | |||
2015 | return ret; | ||
2016 | } | ||
2017 | |||
2018 | static const Eina_Model_Event_Description _eina_model_type_base_events[] = { | ||
2019 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_deleted, "", "model was deleted"), | ||
2020 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_freed, "", "model memory was released"), | ||
2021 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_property_set, "s", "model data was set, data name given as event information."), | ||
2022 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_property_del, "s", "model data was deleted, data name given as event information."), | ||
2023 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_children_changed, "", "model children changed (deleted, inserted)."), | ||
2024 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_child_inserted, "u", "model child was inserted, child position is given."), | ||
2025 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_child_set, "u", "model child was set, child position is given."), | ||
2026 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_child_del, "u", "model child was deleted, child position is given."), | ||
2027 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_loaded, "", "model was loaded"), | ||
2028 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_unloaded, "", "model was unloaded"), | ||
2029 | EINA_MODEL_EVENT_DESCRIPTION_SENTINEL | ||
2030 | }; | ||
2031 | |||
2032 | static const Eina_Model_Type _EINA_MODEL_TYPE_BASE = { | ||
2033 | EINA_MODEL_TYPE_VERSION, | ||
2034 | 0, /* there is no private data */ | ||
2035 | sizeof(Eina_Model_Type), | ||
2036 | "Eina_Model_Type_Base", | ||
2037 | NULL, /* should be the only type with NULL here! */ | ||
2038 | NULL, /* no interfaces implemented */ | ||
2039 | _eina_model_type_base_events, | ||
2040 | _eina_model_type_base_setup, | ||
2041 | _eina_model_type_base_flush, | ||
2042 | _eina_model_type_base_constructor, | ||
2043 | _eina_model_type_base_destructor, | ||
2044 | _eina_model_type_base_copy, | ||
2045 | _eina_model_type_base_deep_copy, | ||
2046 | _eina_model_type_base_compare, | ||
2047 | NULL, /* no load */ | ||
2048 | NULL, /* no unload */ | ||
2049 | NULL, /* no property value get */ | ||
2050 | NULL, /* no property value set */ | ||
2051 | NULL, /* no property del */ | ||
2052 | NULL, /* no properties names list */ | ||
2053 | _eina_model_type_base_child_count, | ||
2054 | NULL, /* no child get */ | ||
2055 | NULL, /* no child set */ | ||
2056 | NULL, /* no child del */ | ||
2057 | NULL, /* no child insert */ | ||
2058 | _eina_model_type_base_child_find, | ||
2059 | _eina_model_type_base_child_criteria_match, | ||
2060 | NULL, /* no child sort */ | ||
2061 | _eina_model_type_base_child_iterator_get, | ||
2062 | _eina_model_type_base_child_reversed_iterator_get, | ||
2063 | _eina_model_type_base_child_sorted_iterator_get, | ||
2064 | _eina_model_type_base_child_filtered_iterator_get, | ||
2065 | _eina_model_type_base_to_string, | ||
2066 | NULL, /* extension pointer */ | ||
2067 | NULL, /* extension pointer */ | ||
2068 | NULL, /* extension pointer */ | ||
2069 | NULL /* extension pointer */ | ||
2070 | }; | ||
2071 | |||
2072 | /* | ||
2073 | * EINA_MODEL_TYPE_MIXIN: | ||
2074 | * | ||
2075 | * Mix-in is a type that uses 2 interfaces, one for properties, | ||
2076 | * another for children. Users should inherit this model and implement | ||
2077 | * at least onf of the interfaces to get an usable model without | ||
2078 | * defining the methods. | ||
2079 | */ | ||
2080 | |||
2081 | static const char _EINA_MODEL_INTERFACE_NAME_PROPERTIES[] = "Eina_Model_Interface_Properties"; | ||
2082 | static const char _EINA_MODEL_INTERFACE_NAME_CHILDREN[] = "Eina_Model_Interface_Children"; | ||
2083 | |||
2084 | typedef struct _Eina_Model_Type_Mixin_Data Eina_Model_Type_Mixin_Data; | ||
2085 | struct _Eina_Model_Type_Mixin_Data | ||
2086 | { | ||
2087 | /* just keep interfaces to avoid lookups */ | ||
2088 | const Eina_Model_Interface *if_properties; | ||
2089 | const Eina_Model_Interface *if_children; | ||
2090 | }; | ||
2091 | |||
2092 | static Eina_Bool | ||
2093 | _eina_model_type_mixin_setup(Eina_Model *model) | ||
2094 | { | ||
2095 | DBG("mix-in setup of %p", model); | ||
2096 | return EINA_TRUE; | ||
2097 | } | ||
2098 | |||
2099 | static Eina_Bool | ||
2100 | _eina_model_type_mixin_flush(Eina_Model *model) | ||
2101 | { | ||
2102 | DBG("mix-in flush of %p", model); | ||
2103 | return EINA_TRUE; | ||
2104 | } | ||
2105 | |||
2106 | static Eina_Bool | ||
2107 | _eina_model_type_mixin_constructor(Eina_Model *model) | ||
2108 | { | ||
2109 | Eina_Model_Type_Mixin_Data *priv = eina_model_type_private_data_get | ||
2110 | (model, EINA_MODEL_TYPE_MIXIN); | ||
2111 | |||
2112 | DBG("mix-in constructor of %p (priv=%p)", model, priv); | ||
2113 | |||
2114 | priv->if_properties = eina_model_interface_get | ||
2115 | (model, EINA_MODEL_INTERFACE_NAME_PROPERTIES); | ||
2116 | if (priv->if_properties) | ||
2117 | { | ||
2118 | if (!eina_model_interface_constructor(priv->if_properties, model)) | ||
2119 | { | ||
2120 | ERR("Could not construct properties interface %p of %p (%s)", | ||
2121 | model, priv->if_properties, model->desc->cache.types[0]->name); | ||
2122 | return EINA_FALSE; | ||
2123 | } | ||
2124 | } | ||
2125 | |||
2126 | priv->if_children = eina_model_interface_get | ||
2127 | (model, EINA_MODEL_INTERFACE_NAME_CHILDREN); | ||
2128 | if (priv->if_children) | ||
2129 | { | ||
2130 | if (!eina_model_interface_constructor(priv->if_children, model)) | ||
2131 | { | ||
2132 | ERR("Could not construct children interface %p of %p (%s)", | ||
2133 | model, priv->if_children, model->desc->cache.types[0]->name); | ||
2134 | return EINA_FALSE; | ||
2135 | } | ||
2136 | } | ||
2137 | |||
2138 | if ((!priv->if_properties) && (!priv->if_children)) | ||
2139 | { | ||
2140 | ERR("Mix-in model %p (%s) does not implement properties or children " | ||
2141 | "interfaces!", | ||
2142 | model, model->desc->cache.types[0]->name); | ||
2143 | return EINA_FALSE; | ||
2144 | } | ||
2145 | |||
2146 | return EINA_TRUE; | ||
2147 | } | ||
2148 | |||
2149 | #define EINA_MODEL_TYPE_MIXIN_GET(model) \ | ||
2150 | Eina_Model_Type_Mixin_Data *priv = eina_model_type_private_data_get \ | ||
2151 | (model, EINA_MODEL_TYPE_MIXIN) | ||
2152 | |||
2153 | static Eina_Bool | ||
2154 | _eina_model_type_mixin_destructor(Eina_Model *model) | ||
2155 | { | ||
2156 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2157 | |||
2158 | DBG("mixin destructor of %p", model); | ||
2159 | |||
2160 | if (priv->if_properties) | ||
2161 | eina_model_interface_destructor(priv->if_properties, model); | ||
2162 | |||
2163 | if (priv->if_children) | ||
2164 | eina_model_interface_destructor(priv->if_children, model); | ||
2165 | |||
2166 | return EINA_TRUE; | ||
2167 | } | ||
2168 | |||
2169 | static Eina_Bool | ||
2170 | _eina_model_type_mixin_compare(const Eina_Model *a, const Eina_Model *b, int *cmp) | ||
2171 | { | ||
2172 | Eina_Bool ret = EINA_TRUE, did_prop = EINA_FALSE, did_child = EINA_FALSE; | ||
2173 | |||
2174 | *cmp = 0; | ||
2175 | |||
2176 | EINA_MODEL_TYPE_MIXIN_GET(a); | ||
2177 | |||
2178 | if (priv->if_properties) | ||
2179 | { | ||
2180 | Eina_Bool (*compare)(const Eina_Model*, const Eina_Model*, int *) = | ||
2181 | _eina_model_interface_find_offset | ||
2182 | (priv->if_properties, | ||
2183 | offsetof(Eina_Model_Interface_Properties, compare)); | ||
2184 | |||
2185 | if (compare) | ||
2186 | { | ||
2187 | ret &= compare(a, b, cmp); | ||
2188 | did_prop = EINA_TRUE; | ||
2189 | } | ||
2190 | } | ||
2191 | |||
2192 | if ((ret) && (*cmp == 0)) | ||
2193 | { | ||
2194 | if (priv->if_children) | ||
2195 | { | ||
2196 | Eina_Bool (*compare)(const Eina_Model*, const Eina_Model*, int *) = | ||
2197 | _eina_model_interface_find_offset | ||
2198 | (priv->if_children, | ||
2199 | offsetof(Eina_Model_Interface_Children, compare)); | ||
2200 | |||
2201 | if (compare) | ||
2202 | { | ||
2203 | ret &= compare(a, b, cmp); | ||
2204 | did_child = EINA_TRUE; | ||
2205 | } | ||
2206 | } | ||
2207 | } | ||
2208 | |||
2209 | if ((!did_prop) && (!did_child)) | ||
2210 | return eina_model_type_compare(EINA_MODEL_TYPE_BASE, a, b, cmp); | ||
2211 | |||
2212 | return ret; | ||
2213 | } | ||
2214 | |||
2215 | static Eina_Bool | ||
2216 | _eina_model_type_mixin_load(Eina_Model *model) | ||
2217 | { | ||
2218 | Eina_Bool ret = EINA_TRUE; | ||
2219 | |||
2220 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2221 | |||
2222 | if (priv->if_properties) | ||
2223 | ret &= eina_model_interface_properties_load(priv->if_properties, model); | ||
2224 | |||
2225 | if (priv->if_children) | ||
2226 | ret &= eina_model_interface_children_load(priv->if_children, model); | ||
2227 | |||
2228 | return ret; | ||
2229 | } | ||
2230 | |||
2231 | static Eina_Bool | ||
2232 | _eina_model_type_mixin_unload(Eina_Model *model) | ||
2233 | { | ||
2234 | Eina_Bool ret = EINA_TRUE; | ||
2235 | |||
2236 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2237 | |||
2238 | if (priv->if_properties) | ||
2239 | ret &= eina_model_interface_properties_unload(priv->if_properties, model); | ||
2240 | |||
2241 | if (priv->if_children) | ||
2242 | ret &= eina_model_interface_children_unload(priv->if_children, model); | ||
2243 | |||
2244 | return ret; | ||
2245 | } | ||
2246 | |||
2247 | static Eina_Bool | ||
2248 | _eina_model_type_mixin_property_get(const Eina_Model *model, const char *name, Eina_Value *value) | ||
2249 | { | ||
2250 | Eina_Bool ret = EINA_FALSE; | ||
2251 | |||
2252 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2253 | |||
2254 | if (priv->if_properties) | ||
2255 | ret = eina_model_interface_properties_get | ||
2256 | (priv->if_properties, model, name, value); | ||
2257 | |||
2258 | return ret; | ||
2259 | } | ||
2260 | |||
2261 | static Eina_Bool | ||
2262 | _eina_model_type_mixin_property_set(Eina_Model *model, const char *name, const Eina_Value *value) | ||
2263 | { | ||
2264 | Eina_Bool ret = EINA_FALSE; | ||
2265 | |||
2266 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2267 | |||
2268 | if (priv->if_properties) | ||
2269 | ret = eina_model_interface_properties_set | ||
2270 | (priv->if_properties, model, name, value); | ||
2271 | |||
2272 | return ret; | ||
2273 | } | ||
2274 | |||
2275 | static Eina_Bool | ||
2276 | _eina_model_type_mixin_property_del(Eina_Model *model, const char *name) | ||
2277 | { | ||
2278 | Eina_Bool ret = EINA_FALSE; | ||
2279 | |||
2280 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2281 | |||
2282 | if (priv->if_properties) | ||
2283 | ret = eina_model_interface_properties_del | ||
2284 | (priv->if_properties, model, name); | ||
2285 | |||
2286 | return ret; | ||
2287 | } | ||
2288 | |||
2289 | static Eina_List * | ||
2290 | _eina_model_type_mixin_properties_names_list_get(const Eina_Model *model) | ||
2291 | { | ||
2292 | Eina_List *ret = NULL; | ||
2293 | |||
2294 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2295 | |||
2296 | if (priv->if_properties) | ||
2297 | ret = eina_model_interface_properties_names_list_get | ||
2298 | (priv->if_properties, model); | ||
2299 | |||
2300 | return ret; | ||
2301 | } | ||
2302 | |||
2303 | static int | ||
2304 | _eina_model_type_mixin_child_count(const Eina_Model *model) | ||
2305 | { | ||
2306 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2307 | |||
2308 | if (!priv->if_children) | ||
2309 | return 0; | ||
2310 | |||
2311 | return eina_model_interface_children_count(priv->if_children, model); | ||
2312 | } | ||
2313 | |||
2314 | static Eina_Model * | ||
2315 | _eina_model_type_mixin_child_get(const Eina_Model *model, unsigned int position) | ||
2316 | { | ||
2317 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2318 | |||
2319 | if (!priv->if_children) | ||
2320 | return 0; | ||
2321 | |||
2322 | return eina_model_interface_children_get(priv->if_children, model, position); | ||
2323 | } | ||
2324 | |||
2325 | static Eina_Bool | ||
2326 | _eina_model_type_mixin_child_set(Eina_Model *model, unsigned int position, Eina_Model *child) | ||
2327 | { | ||
2328 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2329 | |||
2330 | if (!priv->if_children) | ||
2331 | return 0; | ||
2332 | |||
2333 | return eina_model_interface_children_set | ||
2334 | (priv->if_children, model, position, child); | ||
2335 | } | ||
2336 | |||
2337 | static Eina_Bool | ||
2338 | _eina_model_type_mixin_child_del(Eina_Model *model, unsigned int position) | ||
2339 | { | ||
2340 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2341 | |||
2342 | if (!priv->if_children) | ||
2343 | return 0; | ||
2344 | |||
2345 | return eina_model_interface_children_del | ||
2346 | (priv->if_children, model, position); | ||
2347 | } | ||
2348 | |||
2349 | static Eina_Bool | ||
2350 | _eina_model_type_mixin_child_insert_at(Eina_Model *model, unsigned int position, Eina_Model *child) | ||
2351 | { | ||
2352 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2353 | |||
2354 | if (!priv->if_children) | ||
2355 | return 0; | ||
2356 | |||
2357 | return eina_model_interface_children_insert_at | ||
2358 | (priv->if_children, model, position, child); | ||
2359 | } | ||
2360 | |||
2361 | static void | ||
2362 | _eina_model_type_mixin_child_sort(Eina_Model *model, Eina_Compare_Cb compare) | ||
2363 | { | ||
2364 | EINA_MODEL_TYPE_MIXIN_GET(model); | ||
2365 | |||
2366 | if (!priv->if_children) | ||
2367 | return; | ||
2368 | eina_model_interface_children_sort(priv->if_children, model, compare); | ||
2369 | } | ||
2370 | |||
2371 | static const Eina_Model_Type _EINA_MODEL_TYPE_MIXIN = { | ||
2372 | EINA_MODEL_TYPE_VERSION, | ||
2373 | sizeof(Eina_Model_Type_Mixin_Data), | ||
2374 | sizeof(Eina_Model_Type), | ||
2375 | "Eina_Model_Type_Mixin", | ||
2376 | &_EINA_MODEL_TYPE_BASE, | ||
2377 | NULL, /* no interfaces implemented */ | ||
2378 | NULL, /* no extra events */ | ||
2379 | _eina_model_type_mixin_setup, | ||
2380 | _eina_model_type_mixin_flush, | ||
2381 | _eina_model_type_mixin_constructor, | ||
2382 | _eina_model_type_mixin_destructor, | ||
2383 | NULL, /* no copy, as interface is called automatically */ | ||
2384 | NULL, /* no deep copy, as interface is called automatically */ | ||
2385 | _eina_model_type_mixin_compare, | ||
2386 | _eina_model_type_mixin_load, | ||
2387 | _eina_model_type_mixin_unload, | ||
2388 | _eina_model_type_mixin_property_get, | ||
2389 | _eina_model_type_mixin_property_set, | ||
2390 | _eina_model_type_mixin_property_del, | ||
2391 | _eina_model_type_mixin_properties_names_list_get, | ||
2392 | _eina_model_type_mixin_child_count, | ||
2393 | _eina_model_type_mixin_child_get, | ||
2394 | _eina_model_type_mixin_child_set, | ||
2395 | _eina_model_type_mixin_child_del, | ||
2396 | _eina_model_type_mixin_child_insert_at, | ||
2397 | NULL, /* use default find */ | ||
2398 | NULL, /* use default criteria_match */ | ||
2399 | _eina_model_type_mixin_child_sort, | ||
2400 | NULL, /* use default iterator get */ | ||
2401 | NULL, /* use default reversed iterator get */ | ||
2402 | NULL, /* use default sorted iterator get */ | ||
2403 | NULL, /* use default filtered iterator get */ | ||
2404 | NULL, /* use default to string */ | ||
2405 | NULL, /* extension pointer */ | ||
2406 | NULL, /* extension pointer */ | ||
2407 | NULL, /* extension pointer */ | ||
2408 | NULL /* extension pointer */ | ||
2409 | }; | ||
2410 | #undef EINA_MODEL_TYPE_MIXIN_GET | ||
2411 | |||
2412 | /* Events for all Properties interface */ | ||
2413 | static const Eina_Model_Event_Description _eina_model_interface_properties_events[] = { | ||
2414 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_properties_loaded, "", "model properties were loaded"), | ||
2415 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_properties_unloaded, "", "model properties were unloaded"), | ||
2416 | EINA_MODEL_EVENT_DESCRIPTION_SENTINEL | ||
2417 | }; | ||
2418 | |||
2419 | /* EINA_MODEL_INTERFACE_PROPERTIES_HASH ******************************/ | ||
2420 | |||
2421 | #define EINA_MODEL_INTERFACE_PROPERTIES_HASH_GET(model) \ | ||
2422 | Eina_Hash *priv = *(Eina_Hash **)eina_model_interface_private_data_get \ | ||
2423 | (model, EINA_MODEL_INTERFACE_PROPERTIES_HASH) | ||
2424 | |||
2425 | static Eina_Bool | ||
2426 | _eina_model_interface_properties_hash_setup(Eina_Model *model) | ||
2427 | { | ||
2428 | Eina_Hash **p_priv = eina_model_interface_private_data_get | ||
2429 | (model, EINA_MODEL_INTERFACE_PROPERTIES_HASH); | ||
2430 | |||
2431 | DBG("setup interface properties (hash) at %p model %p (%s)", | ||
2432 | p_priv, model, model->desc->cache.types[0]->name); | ||
2433 | |||
2434 | *p_priv = eina_hash_string_small_new(NULL); | ||
2435 | return !!*p_priv; | ||
2436 | } | ||
2437 | |||
2438 | static Eina_Bool | ||
2439 | _eina_model_interface_properties_hash_flush(Eina_Model *model) | ||
2440 | { | ||
2441 | EINA_MODEL_INTERFACE_PROPERTIES_HASH_GET(model); | ||
2442 | |||
2443 | DBG("flush interface properties (hash) at %p model %p (%s)", | ||
2444 | priv, model, model->desc->cache.types[0]->name); | ||
2445 | |||
2446 | if (priv) | ||
2447 | { | ||
2448 | ERR("interface properties flushed with values! priv=%p, model %p (%s)", | ||
2449 | priv, model, model->desc->cache.types[0]->name); | ||
2450 | eina_hash_free(priv); | ||
2451 | } | ||
2452 | |||
2453 | return EINA_TRUE; | ||
2454 | } | ||
2455 | |||
2456 | static Eina_Bool | ||
2457 | _eina_model_interface_properties_hash_constructor(Eina_Model *model) | ||
2458 | { | ||
2459 | EINA_MODEL_INTERFACE_PROPERTIES_HASH_GET(model); | ||
2460 | |||
2461 | DBG("construct interface properties (hash) at %p model %p (%s)", | ||
2462 | priv, model, model->desc->cache.types[0]->name); | ||
2463 | |||
2464 | return EINA_TRUE; | ||
2465 | } | ||
2466 | |||
2467 | static Eina_Bool | ||
2468 | _eina_model_interface_properties_hash_destructor_foreach(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__) | ||
2469 | { | ||
2470 | eina_value_free(data); | ||
2471 | return EINA_TRUE; | ||
2472 | } | ||
2473 | |||
2474 | static Eina_Bool | ||
2475 | _eina_model_interface_properties_hash_destructor(Eina_Model *model) | ||
2476 | { | ||
2477 | Eina_Hash **p_priv = eina_model_interface_private_data_get | ||
2478 | (model, EINA_MODEL_INTERFACE_PROPERTIES_HASH); | ||
2479 | int count = eina_hash_population(*p_priv); | ||
2480 | |||
2481 | DBG("destroy interface properties (hash) at %p model %p (%s). %d values.", | ||
2482 | *p_priv, model, model->desc->cache.types[0]->name, count); | ||
2483 | |||
2484 | eina_hash_foreach | ||
2485 | (*p_priv, _eina_model_interface_properties_hash_destructor_foreach, NULL); | ||
2486 | eina_hash_free(*p_priv); | ||
2487 | *p_priv = NULL; | ||
2488 | |||
2489 | return EINA_TRUE; | ||
2490 | } | ||
2491 | |||
2492 | static Eina_Bool | ||
2493 | _eina_model_interface_properties_hash_get(const Eina_Model *model, const char *name, Eina_Value *value) | ||
2494 | { | ||
2495 | EINA_MODEL_INTERFACE_PROPERTIES_HASH_GET(model); | ||
2496 | const Eina_Value *prop = eina_hash_find(priv, name); | ||
2497 | EINA_SAFETY_ON_NULL_RETURN_VAL(prop, EINA_FALSE); | ||
2498 | return eina_value_copy(prop, value); | ||
2499 | } | ||
2500 | |||
2501 | static Eina_Bool | ||
2502 | _eina_model_interface_properties_hash_set(Eina_Model *model, const char *name, const Eina_Value *value) | ||
2503 | { | ||
2504 | EINA_MODEL_INTERFACE_PROPERTIES_HASH_GET(model); | ||
2505 | Eina_Value *prop, *old = eina_hash_find(priv, name); | ||
2506 | |||
2507 | prop = eina_value_new(eina_value_type_get(value)); | ||
2508 | EINA_SAFETY_ON_NULL_RETURN_VAL(prop, EINA_FALSE); | ||
2509 | |||
2510 | eina_value_flush(prop); | ||
2511 | if (!eina_value_copy(value, prop)) | ||
2512 | { | ||
2513 | ERR("Could not copy value '%s' from %p to %p", name, value, prop); | ||
2514 | eina_value_free(prop); | ||
2515 | return EINA_FALSE; | ||
2516 | } | ||
2517 | |||
2518 | if (!old) | ||
2519 | { | ||
2520 | if (!eina_hash_add(priv, name, prop)) | ||
2521 | { | ||
2522 | ERR("Could not add value %p to hash as key '%s'", prop, name); | ||
2523 | eina_value_free(prop); | ||
2524 | return EINA_FALSE; | ||
2525 | } | ||
2526 | } | ||
2527 | else | ||
2528 | { | ||
2529 | eina_value_free(old); | ||
2530 | if (!eina_hash_modify(priv, name, prop)) | ||
2531 | { | ||
2532 | ERR("Could not modify hash key '%s' value from %p to %p", | ||
2533 | name, old, prop); | ||
2534 | eina_hash_del_by_key(priv, name); | ||
2535 | eina_value_free(prop); | ||
2536 | return EINA_FALSE; | ||
2537 | } | ||
2538 | } | ||
2539 | |||
2540 | return EINA_TRUE; | ||
2541 | } | ||
2542 | |||
2543 | static Eina_Bool | ||
2544 | _eina_model_interface_properties_hash_del(Eina_Model *model, const char *name) | ||
2545 | { | ||
2546 | EINA_MODEL_INTERFACE_PROPERTIES_HASH_GET(model); | ||
2547 | Eina_Value *old = eina_hash_find(priv, name); | ||
2548 | EINA_SAFETY_ON_NULL_RETURN_VAL(old, EINA_FALSE); | ||
2549 | eina_value_free(old); | ||
2550 | return eina_hash_del_by_key(priv, name); | ||
2551 | } | ||
2552 | |||
2553 | static Eina_Bool | ||
2554 | _eina_model_interface_properties_hash_names_list_foreach(const Eina_Hash *hash __UNUSED__, const void *key, void *data __UNUSED__, void *fdata) | ||
2555 | { | ||
2556 | Eina_List **p_list = fdata; | ||
2557 | *p_list = eina_list_append(*p_list, eina_stringshare_add(key)); | ||
2558 | return EINA_TRUE; | ||
2559 | } | ||
2560 | |||
2561 | static Eina_List * | ||
2562 | _eina_model_interface_properties_hash_names_list(const Eina_Model *model) | ||
2563 | { | ||
2564 | EINA_MODEL_INTERFACE_PROPERTIES_HASH_GET(model); | ||
2565 | Eina_List *list = NULL; | ||
2566 | eina_hash_foreach | ||
2567 | (priv, _eina_model_interface_properties_hash_names_list_foreach, &list); | ||
2568 | return list; | ||
2569 | } | ||
2570 | #undef EINA_MODEL_INTERFACE_PROPERTIES_HASH_GET | ||
2571 | |||
2572 | static const Eina_Model_Interface_Properties _EINA_MODEL_INTERFACE_PROPERTIES_HASH = { | ||
2573 | { | ||
2574 | EINA_MODEL_INTERFACE_VERSION, | ||
2575 | sizeof(Eina_Hash *), | ||
2576 | sizeof(Eina_Model_Interface_Properties), | ||
2577 | _EINA_MODEL_INTERFACE_NAME_PROPERTIES, | ||
2578 | NULL, /* no parent interfaces */ | ||
2579 | _eina_model_interface_properties_events, | ||
2580 | _eina_model_interface_properties_hash_setup, | ||
2581 | _eina_model_interface_properties_hash_flush, | ||
2582 | _eina_model_interface_properties_hash_constructor, | ||
2583 | _eina_model_interface_properties_hash_destructor, | ||
2584 | NULL, | ||
2585 | NULL, | ||
2586 | NULL, | ||
2587 | NULL, | ||
2588 | NULL, | ||
2589 | NULL | ||
2590 | }, | ||
2591 | EINA_MODEL_INTERFACE_PROPERTIES_VERSION, | ||
2592 | NULL, /* no compare */ | ||
2593 | NULL, /* no load */ | ||
2594 | NULL, /* no unload */ | ||
2595 | _eina_model_interface_properties_hash_get, | ||
2596 | _eina_model_interface_properties_hash_set, | ||
2597 | _eina_model_interface_properties_hash_del, | ||
2598 | _eina_model_interface_properties_hash_names_list | ||
2599 | }; | ||
2600 | |||
2601 | /* EINA_MODEL_INTERFACE_PROPERTIES_STRUCT ******************************/ | ||
2602 | |||
2603 | static Eina_Value_Struct * | ||
2604 | _eina_model_interface_properties_struct_private_get(const Eina_Model *model) | ||
2605 | { | ||
2606 | Eina_Value *val = eina_model_interface_private_data_get | ||
2607 | (model, EINA_MODEL_INTERFACE_PROPERTIES_STRUCT); | ||
2608 | return eina_value_memory_get(val); | ||
2609 | } | ||
2610 | |||
2611 | #define EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_GET(model) \ | ||
2612 | Eina_Value_Struct *priv = \ | ||
2613 | _eina_model_interface_properties_struct_private_get(model) | ||
2614 | |||
2615 | static Eina_Bool | ||
2616 | _eina_model_interface_properties_struct_setup(Eina_Model *model) | ||
2617 | { | ||
2618 | Eina_Value *val = eina_model_interface_private_data_get | ||
2619 | (model, EINA_MODEL_INTERFACE_PROPERTIES_STRUCT); | ||
2620 | |||
2621 | DBG("setup interface properties (struct) at %p model %p (%s)", | ||
2622 | val, model, model->desc->cache.types[0]->name); | ||
2623 | |||
2624 | return eina_value_setup(val, EINA_VALUE_TYPE_STRUCT); | ||
2625 | } | ||
2626 | |||
2627 | static Eina_Bool | ||
2628 | _eina_model_interface_properties_struct_flush(Eina_Model *model) | ||
2629 | { | ||
2630 | Eina_Value *val = eina_model_interface_private_data_get | ||
2631 | (model, EINA_MODEL_INTERFACE_PROPERTIES_STRUCT); | ||
2632 | |||
2633 | DBG("flush interface properties (struct) at %p model %p (%s)", | ||
2634 | val, model, model->desc->cache.types[0]->name); | ||
2635 | |||
2636 | if (val->type) | ||
2637 | { | ||
2638 | ERR("interface properties flushed with values! val=%p, model %p (%s)", | ||
2639 | val, model, model->desc->cache.types[0]->name); | ||
2640 | eina_value_flush(val); | ||
2641 | } | ||
2642 | |||
2643 | return EINA_TRUE; | ||
2644 | } | ||
2645 | |||
2646 | static Eina_Bool | ||
2647 | _eina_model_interface_properties_struct_constructor(Eina_Model *model) | ||
2648 | { | ||
2649 | EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_GET(model); | ||
2650 | |||
2651 | DBG("construct interface properties (struct) at %p model %p (%s)", | ||
2652 | priv, model, model->desc->cache.types[0]->name); | ||
2653 | |||
2654 | return EINA_TRUE; | ||
2655 | } | ||
2656 | |||
2657 | static Eina_Bool | ||
2658 | _eina_model_interface_properties_struct_destructor(Eina_Model *model) | ||
2659 | { | ||
2660 | Eina_Value *val = eina_model_interface_private_data_get | ||
2661 | (model, EINA_MODEL_INTERFACE_PROPERTIES_STRUCT); | ||
2662 | |||
2663 | DBG("destroy interface properties (struct) at %p model %p (%s)", | ||
2664 | val, model, model->desc->cache.types[0]->name); | ||
2665 | |||
2666 | eina_value_flush(val); | ||
2667 | val->type = NULL; | ||
2668 | |||
2669 | return EINA_TRUE; | ||
2670 | } | ||
2671 | |||
2672 | static Eina_Bool | ||
2673 | _eina_model_interface_properties_struct_get(const Eina_Model *model, const char *name, Eina_Value *val) | ||
2674 | { | ||
2675 | const Eina_Value *v = eina_model_interface_private_data_get | ||
2676 | (model, EINA_MODEL_INTERFACE_PROPERTIES_STRUCT); | ||
2677 | return eina_value_struct_value_get(v, name, val); | ||
2678 | } | ||
2679 | |||
2680 | static Eina_Bool | ||
2681 | _eina_model_interface_properties_struct_set(Eina_Model *model, const char *name, const Eina_Value *val) | ||
2682 | { | ||
2683 | Eina_Value *v = eina_model_interface_private_data_get | ||
2684 | (model, EINA_MODEL_INTERFACE_PROPERTIES_STRUCT); | ||
2685 | return eina_value_struct_value_set(v, name, val); | ||
2686 | } | ||
2687 | |||
2688 | static Eina_Bool | ||
2689 | _eina_model_interface_properties_struct_del(Eina_Model *model __UNUSED__, const char *name __UNUSED__) | ||
2690 | { | ||
2691 | return EINA_FALSE; /* not allowed */ | ||
2692 | } | ||
2693 | |||
2694 | static Eina_List * | ||
2695 | _eina_model_interface_properties_struct_names_list(const Eina_Model *model) | ||
2696 | { | ||
2697 | EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_GET(model); | ||
2698 | const Eina_Value_Struct_Member *itr; | ||
2699 | Eina_List *list = NULL; | ||
2700 | |||
2701 | EINA_SAFETY_ON_NULL_RETURN_VAL(priv, NULL); | ||
2702 | EINA_SAFETY_ON_NULL_RETURN_VAL(priv->desc, NULL); | ||
2703 | EINA_SAFETY_ON_NULL_RETURN_VAL(priv->desc->members, NULL); | ||
2704 | |||
2705 | itr = priv->desc->members; | ||
2706 | if (priv->desc->member_count) | ||
2707 | { | ||
2708 | const Eina_Value_Struct_Member *end = itr + priv->desc->member_count; | ||
2709 | for (; itr < end; itr++) | ||
2710 | list = eina_list_append(list, eina_stringshare_add(itr->name)); | ||
2711 | } | ||
2712 | else | ||
2713 | { | ||
2714 | for (; itr->name != NULL; itr++) | ||
2715 | list = eina_list_append(list, eina_stringshare_add(itr->name)); | ||
2716 | } | ||
2717 | |||
2718 | return list; | ||
2719 | } | ||
2720 | #undef EINA_MODEL_INTERFACE_PROPERTIES_STRUCT_GET | ||
2721 | |||
2722 | static const Eina_Model_Interface_Properties _EINA_MODEL_INTERFACE_PROPERTIES_STRUCT = { | ||
2723 | { | ||
2724 | EINA_MODEL_INTERFACE_VERSION, | ||
2725 | sizeof(Eina_Value), | ||
2726 | sizeof(Eina_Model_Interface_Properties), | ||
2727 | _EINA_MODEL_INTERFACE_NAME_PROPERTIES, | ||
2728 | NULL, /* no parent interfaces */ | ||
2729 | _eina_model_interface_properties_events, | ||
2730 | _eina_model_interface_properties_struct_setup, | ||
2731 | _eina_model_interface_properties_struct_flush, | ||
2732 | _eina_model_interface_properties_struct_constructor, | ||
2733 | _eina_model_interface_properties_struct_destructor, | ||
2734 | NULL, | ||
2735 | NULL, | ||
2736 | NULL, | ||
2737 | NULL, | ||
2738 | NULL, | ||
2739 | NULL | ||
2740 | }, | ||
2741 | EINA_MODEL_INTERFACE_PROPERTIES_VERSION, | ||
2742 | NULL, /* no compare */ | ||
2743 | NULL, /* no load */ | ||
2744 | NULL, /* no unload */ | ||
2745 | _eina_model_interface_properties_struct_get, | ||
2746 | _eina_model_interface_properties_struct_set, | ||
2747 | _eina_model_interface_properties_struct_del, | ||
2748 | _eina_model_interface_properties_struct_names_list | ||
2749 | }; | ||
2750 | |||
2751 | /* Events for all Children interface */ | ||
2752 | static const Eina_Model_Event_Description _eina_model_interface_children_events[] = { | ||
2753 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_children_loaded, "", "model children were loaded"), | ||
2754 | EINA_MODEL_EVENT_DESCRIPTION(_eina_model_str_children_unloaded, "", "model children were unloaded"), | ||
2755 | EINA_MODEL_EVENT_DESCRIPTION_SENTINEL | ||
2756 | }; | ||
2757 | |||
2758 | /* EINA_MODEL_INTERFACE_CHILDREN_INARRAY ******************************/ | ||
2759 | |||
2760 | #define EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model) \ | ||
2761 | Eina_Inarray *priv = eina_model_interface_private_data_get \ | ||
2762 | (model, EINA_MODEL_INTERFACE_CHILDREN_INARRAY) | ||
2763 | |||
2764 | static Eina_Bool | ||
2765 | _eina_model_interface_children_inarray_setup(Eina_Model *model) | ||
2766 | { | ||
2767 | EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model); | ||
2768 | |||
2769 | DBG("setup interface children (inarray) at %p model %p (%s)", | ||
2770 | priv, model, model->desc->cache.types[0]->name); | ||
2771 | |||
2772 | eina_inarray_setup(priv, sizeof(Eina_Model *), 0); | ||
2773 | return EINA_TRUE; | ||
2774 | } | ||
2775 | |||
2776 | static Eina_Bool | ||
2777 | _eina_model_interface_children_inarray_flush(Eina_Model *model) | ||
2778 | { | ||
2779 | EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model); | ||
2780 | int count; | ||
2781 | |||
2782 | DBG("flush interface children (inarray) at %p model %p (%s)", | ||
2783 | priv, model, model->desc->cache.types[0]->name); | ||
2784 | |||
2785 | count = eina_inarray_count(priv); | ||
2786 | if (count > 0) | ||
2787 | ERR("interface children flushed with %d members! priv=%p, model %p (%s)", | ||
2788 | count, priv, model, model->desc->cache.types[0]->name); | ||
2789 | |||
2790 | eina_inarray_flush(priv); | ||
2791 | return EINA_TRUE; | ||
2792 | } | ||
2793 | |||
2794 | static Eina_Bool | ||
2795 | _eina_model_interface_children_inarray_constructor(Eina_Model *model) | ||
2796 | { | ||
2797 | EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model); | ||
2798 | |||
2799 | DBG("construct interface children (inarray) at %p model %p (%s)", | ||
2800 | priv, model, model->desc->cache.types[0]->name); | ||
2801 | |||
2802 | return EINA_TRUE; | ||
2803 | } | ||
2804 | |||
2805 | static Eina_Bool | ||
2806 | _eina_model_interface_children_inarray_destructor(Eina_Model *model) | ||
2807 | { | ||
2808 | Eina_Model **itr, **itr_end; | ||
2809 | int count; | ||
2810 | |||
2811 | EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model); | ||
2812 | |||
2813 | count = eina_inarray_count(priv); | ||
2814 | |||
2815 | DBG("destroy interface children (inarray) at %p model %p (%s). %d members.", | ||
2816 | priv, model, model->desc->cache.types[0]->name, count); | ||
2817 | |||
2818 | itr = priv->members; | ||
2819 | itr_end = itr + count; | ||
2820 | for (; itr < itr_end; itr++) | ||
2821 | eina_model_xunref(*itr, EINA_MODEL_INTERFACE_CHILDREN_INARRAY); | ||
2822 | eina_inarray_flush(priv); | ||
2823 | |||
2824 | return EINA_TRUE; | ||
2825 | } | ||
2826 | |||
2827 | static int | ||
2828 | _eina_model_interface_children_inarray_count(const Eina_Model *model) | ||
2829 | { | ||
2830 | EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model); | ||
2831 | return eina_inarray_count(priv); | ||
2832 | } | ||
2833 | |||
2834 | static Eina_Model * | ||
2835 | _eina_model_interface_children_inarray_get(const Eina_Model *model, unsigned int position) | ||
2836 | { | ||
2837 | EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model); | ||
2838 | Eina_Model **child = eina_inarray_nth(priv, position); | ||
2839 | if (!child) | ||
2840 | return NULL; | ||
2841 | return eina_model_ref(*child); | ||
2842 | } | ||
2843 | |||
2844 | static Eina_Bool | ||
2845 | _eina_model_interface_children_inarray_set(Eina_Model *model, unsigned int position, Eina_Model *child) | ||
2846 | { | ||
2847 | EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model); | ||
2848 | Eina_Model **p_old = eina_inarray_nth(priv, position); | ||
2849 | Eina_Model *old; | ||
2850 | |||
2851 | if (!p_old) | ||
2852 | return EINA_FALSE; | ||
2853 | |||
2854 | old = *p_old; | ||
2855 | if (!eina_inarray_replace_at(priv, position, &child)) | ||
2856 | return EINA_FALSE; | ||
2857 | |||
2858 | eina_model_xref(child, EINA_MODEL_INTERFACE_CHILDREN_INARRAY, | ||
2859 | "eina_model_child_set"); | ||
2860 | eina_model_xunref(old, EINA_MODEL_INTERFACE_CHILDREN_INARRAY); | ||
2861 | return EINA_TRUE; | ||
2862 | } | ||
2863 | |||
2864 | static Eina_Bool | ||
2865 | _eina_model_interface_children_inarray_del(Eina_Model *model, unsigned int position) | ||
2866 | { | ||
2867 | EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model); | ||
2868 | Eina_Model **p_old = eina_inarray_nth(priv, position); | ||
2869 | Eina_Model *old; | ||
2870 | |||
2871 | if (!p_old) | ||
2872 | return EINA_FALSE; | ||
2873 | |||
2874 | old = *p_old; | ||
2875 | if (!eina_inarray_remove_at(priv, position)) | ||
2876 | return EINA_FALSE; | ||
2877 | |||
2878 | eina_model_xunref(old, EINA_MODEL_INTERFACE_CHILDREN_INARRAY); | ||
2879 | return EINA_TRUE; | ||
2880 | } | ||
2881 | |||
2882 | static Eina_Bool | ||
2883 | _eina_model_interface_children_inarray_insert_at(Eina_Model *model, unsigned int position, Eina_Model *child) | ||
2884 | { | ||
2885 | EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model); | ||
2886 | |||
2887 | if (!eina_inarray_insert_at(priv, position, &child)) | ||
2888 | return EINA_FALSE; | ||
2889 | |||
2890 | eina_model_xref(child, EINA_MODEL_INTERFACE_CHILDREN_INARRAY, | ||
2891 | "eina_model_child_insert_at"); | ||
2892 | return EINA_TRUE; | ||
2893 | } | ||
2894 | |||
2895 | static void | ||
2896 | _eina_model_interface_children_inarray_sort(Eina_Model *model, Eina_Compare_Cb compare) | ||
2897 | { | ||
2898 | EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET(model); | ||
2899 | int count = eina_inarray_count(priv); | ||
2900 | EINA_SAFETY_ON_FALSE_RETURN(count >= 0); | ||
2901 | |||
2902 | if (count > 1) | ||
2903 | _eina_model_array_sort(priv->members, 0, count - 1, compare); | ||
2904 | } | ||
2905 | #undef EINA_MODEL_INTERFACE_CHILDREN_INARRAY_GET | ||
2906 | |||
2907 | static const Eina_Model_Interface_Children _EINA_MODEL_INTERFACE_CHILDREN_INARRAY = { | ||
2908 | { | ||
2909 | EINA_MODEL_INTERFACE_VERSION, | ||
2910 | sizeof(Eina_Inarray), | ||
2911 | sizeof(Eina_Model_Interface_Children), | ||
2912 | _EINA_MODEL_INTERFACE_NAME_CHILDREN, | ||
2913 | NULL, /* no parent interfaces */ | ||
2914 | _eina_model_interface_children_events, | ||
2915 | _eina_model_interface_children_inarray_setup, | ||
2916 | _eina_model_interface_children_inarray_flush, | ||
2917 | _eina_model_interface_children_inarray_constructor, | ||
2918 | _eina_model_interface_children_inarray_destructor, | ||
2919 | NULL, | ||
2920 | NULL, | ||
2921 | NULL, | ||
2922 | NULL, | ||
2923 | NULL, | ||
2924 | NULL | ||
2925 | }, | ||
2926 | EINA_MODEL_INTERFACE_CHILDREN_VERSION, | ||
2927 | NULL, /* no compare */ | ||
2928 | NULL, /* no load */ | ||
2929 | NULL, /* no unload */ | ||
2930 | _eina_model_interface_children_inarray_count, | ||
2931 | _eina_model_interface_children_inarray_get, | ||
2932 | _eina_model_interface_children_inarray_set, | ||
2933 | _eina_model_interface_children_inarray_del, | ||
2934 | _eina_model_interface_children_inarray_insert_at, | ||
2935 | _eina_model_interface_children_inarray_sort | ||
2936 | }; | ||
2937 | |||
2938 | /* EINA_MODEL_TYPE_GENERIC ********************************************/ | ||
2939 | |||
2940 | static const Eina_Model_Interface *_EINA_MODEL_TYPE_GENERIC_IFACES[] = { | ||
2941 | &_EINA_MODEL_INTERFACE_PROPERTIES_HASH.base, | ||
2942 | &_EINA_MODEL_INTERFACE_CHILDREN_INARRAY.base, | ||
2943 | NULL | ||
2944 | }; | ||
2945 | |||
2946 | static const Eina_Model_Type _EINA_MODEL_TYPE_GENERIC = | ||
2947 | EINA_MODEL_TYPE_INIT_NOPRIVATE("Eina_Model_Type_Generic", | ||
2948 | Eina_Model_Type, | ||
2949 | &_EINA_MODEL_TYPE_MIXIN, | ||
2950 | _EINA_MODEL_TYPE_GENERIC_IFACES, | ||
2951 | NULL); | ||
2952 | |||
2953 | /* EINA_MODEL_TYPE_STRUCT ********************************************/ | ||
2954 | |||
2955 | static const Eina_Model_Interface *_EINA_MODEL_TYPE_STRUCT_IFACES[] = { | ||
2956 | &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT.base, | ||
2957 | &_EINA_MODEL_INTERFACE_CHILDREN_INARRAY.base, | ||
2958 | NULL | ||
2959 | }; | ||
2960 | |||
2961 | static const Eina_Model_Type _EINA_MODEL_TYPE_STRUCT = | ||
2962 | EINA_MODEL_TYPE_INIT_NOPRIVATE("Eina_Model_Type_Struct", | ||
2963 | Eina_Model_Type, | ||
2964 | &_EINA_MODEL_TYPE_MIXIN, | ||
2965 | _EINA_MODEL_TYPE_STRUCT_IFACES, | ||
2966 | NULL); | ||
2967 | |||
2968 | /** | ||
2969 | */ | ||
2970 | |||
2971 | /** | ||
2972 | * @internal | ||
2973 | * @brief Initialize the model module. | ||
2974 | * | ||
2975 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
2976 | * | ||
2977 | * This function sets up the model module of Eina. It is called | ||
2978 | * by eina_init(). | ||
2979 | * | ||
2980 | * @see eina_init() | ||
2981 | */ | ||
2982 | Eina_Bool | ||
2983 | eina_model_init(void) | ||
2984 | { | ||
2985 | const char *choice, *tmp; | ||
2986 | |||
2987 | _eina_model_log_dom = eina_log_domain_register("eina_model", | ||
2988 | EINA_LOG_COLOR_DEFAULT); | ||
2989 | if (_eina_model_log_dom < 0) | ||
2990 | { | ||
2991 | EINA_LOG_ERR("Could not register log domain: eina_model"); | ||
2992 | return EINA_FALSE; | ||
2993 | } | ||
2994 | |||
2995 | choice = getenv("EINA_MODEL_DEBUG"); | ||
2996 | if (choice) | ||
2997 | { | ||
2998 | if (strcmp(choice, "1") == 0) | ||
2999 | _eina_model_debug = EINA_MODEL_DEBUG_CHECK; | ||
3000 | else if (strcmp(choice, "backtrace") == 0) | ||
3001 | _eina_model_debug = EINA_MODEL_DEBUG_BACKTRACE; | ||
3002 | } | ||
3003 | |||
3004 | #ifdef EINA_DEFAULT_MEMPOOL | ||
3005 | choice = "pass_through"; | ||
3006 | #else | ||
3007 | choice = "chained_mempool"; | ||
3008 | #endif | ||
3009 | tmp = getenv("EINA_MEMPOOL"); | ||
3010 | if (tmp && tmp[0]) | ||
3011 | choice = tmp; | ||
3012 | |||
3013 | if (choice) | ||
3014 | _eina_model_mp_choice = strdup(choice); | ||
3015 | |||
3016 | _eina_model_mp = eina_mempool_add | ||
3017 | (_eina_model_mp_choice, "model", NULL, sizeof(Eina_Model), 320); | ||
3018 | if (!_eina_model_mp) | ||
3019 | { | ||
3020 | ERR("Mempool for model cannot be allocated in model init."); | ||
3021 | goto on_init_fail_mp; | ||
3022 | } | ||
3023 | |||
3024 | if (!eina_lock_new(&_eina_model_inner_mps_lock)) | ||
3025 | { | ||
3026 | ERR("Cannot create inner mempools lock in model init."); | ||
3027 | goto on_init_fail_lock_mp; | ||
3028 | } | ||
3029 | _eina_model_inner_mps = eina_hash_int32_new(NULL); | ||
3030 | if (!_eina_model_inner_mps) | ||
3031 | { | ||
3032 | ERR("Cannot create hash for inner mempools in model init."); | ||
3033 | goto on_init_fail_hash_mp; | ||
3034 | } | ||
3035 | |||
3036 | if (!eina_lock_new(&_eina_model_descriptions_lock)) | ||
3037 | { | ||
3038 | ERR("Cannot create model descriptions lock in model init."); | ||
3039 | goto on_init_fail_lock_desc; | ||
3040 | } | ||
3041 | _eina_model_descriptions = eina_hash_pointer_new(NULL); | ||
3042 | if (!_eina_model_descriptions) | ||
3043 | { | ||
3044 | ERR("Cannot create model descriptions hash in model init."); | ||
3045 | goto on_init_fail_hash_desc; | ||
3046 | } | ||
3047 | |||
3048 | if (!eina_lock_new(&_eina_model_debug_list_lock)) | ||
3049 | { | ||
3050 | ERR("Cannot create model debug list lock in model init."); | ||
3051 | goto on_init_fail_lock_debug; | ||
3052 | } | ||
3053 | |||
3054 | EINA_ERROR_MODEL_FAILED = eina_error_msg_static_register( | ||
3055 | EINA_ERROR_MODEL_FAILED_STR); | ||
3056 | EINA_ERROR_MODEL_METHOD_MISSING = eina_error_msg_static_register( | ||
3057 | EINA_ERROR_MODEL_METHOD_MISSING_STR); | ||
3058 | |||
3059 | EINA_MODEL_TYPE_BASE = &_EINA_MODEL_TYPE_BASE; | ||
3060 | EINA_MODEL_TYPE_MIXIN = &_EINA_MODEL_TYPE_MIXIN; | ||
3061 | EINA_MODEL_TYPE_GENERIC = &_EINA_MODEL_TYPE_GENERIC; | ||
3062 | EINA_MODEL_TYPE_STRUCT = &_EINA_MODEL_TYPE_STRUCT; | ||
3063 | |||
3064 | EINA_MODEL_INTERFACE_PROPERTIES_HASH = &_EINA_MODEL_INTERFACE_PROPERTIES_HASH.base; | ||
3065 | EINA_MODEL_INTERFACE_PROPERTIES_STRUCT = &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT.base; | ||
3066 | |||
3067 | EINA_MODEL_INTERFACE_CHILDREN_INARRAY = &_EINA_MODEL_INTERFACE_CHILDREN_INARRAY.base; | ||
3068 | |||
3069 | EINA_MODEL_INTERFACE_NAME_PROPERTIES = _EINA_MODEL_INTERFACE_NAME_PROPERTIES; | ||
3070 | EINA_MODEL_INTERFACE_NAME_CHILDREN = _EINA_MODEL_INTERFACE_NAME_CHILDREN; | ||
3071 | |||
3072 | eina_magic_string_static_set(EINA_MAGIC_MODEL, EINA_MAGIC_MODEL_STR); | ||
3073 | |||
3074 | return EINA_TRUE; | ||
3075 | |||
3076 | on_init_fail_lock_debug: | ||
3077 | eina_hash_free(_eina_model_descriptions); | ||
3078 | on_init_fail_hash_desc: | ||
3079 | eina_lock_free(&_eina_model_descriptions_lock); | ||
3080 | on_init_fail_lock_desc: | ||
3081 | eina_hash_free(_eina_model_inner_mps); | ||
3082 | _eina_model_inner_mps = NULL; | ||
3083 | on_init_fail_hash_mp: | ||
3084 | eina_lock_free(&_eina_model_inner_mps_lock); | ||
3085 | on_init_fail_lock_mp: | ||
3086 | eina_mempool_del(_eina_model_mp); | ||
3087 | on_init_fail_mp: | ||
3088 | free(_eina_model_mp_choice); | ||
3089 | _eina_model_mp_choice = NULL; | ||
3090 | eina_log_domain_unregister(_eina_model_log_dom); | ||
3091 | _eina_model_log_dom = -1; | ||
3092 | return EINA_FALSE; | ||
3093 | } | ||
3094 | |||
3095 | /** | ||
3096 | * @internal | ||
3097 | * @brief Shut down the model module. | ||
3098 | * | ||
3099 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
3100 | * | ||
3101 | * This function shuts down the model module set up by | ||
3102 | * eina_model_init(). It is called by eina_shutdown(). | ||
3103 | * | ||
3104 | * @see eina_shutdown() | ||
3105 | */ | ||
3106 | Eina_Bool | ||
3107 | eina_model_shutdown(void) | ||
3108 | { | ||
3109 | eina_lock_take(&_eina_model_debug_list_lock); | ||
3110 | if (eina_list_count(_eina_model_debug_list) > 0) | ||
3111 | ERR("%d models are still alive!", eina_list_count(_eina_model_debug_list)); | ||
3112 | eina_lock_release(&_eina_model_debug_list_lock); | ||
3113 | eina_lock_free(&_eina_model_debug_list_lock); | ||
3114 | |||
3115 | eina_lock_take(&_eina_model_inner_mps_lock); | ||
3116 | if (eina_hash_population(_eina_model_inner_mps) != 0) | ||
3117 | ERR("Cannot free eina_model internal memory pools -- still in use!"); | ||
3118 | else | ||
3119 | eina_hash_free(_eina_model_inner_mps); | ||
3120 | eina_lock_release(&_eina_model_inner_mps_lock); | ||
3121 | eina_lock_free(&_eina_model_inner_mps_lock); | ||
3122 | |||
3123 | eina_lock_take(&_eina_model_descriptions_lock); | ||
3124 | if (eina_hash_population(_eina_model_descriptions) != 0) | ||
3125 | ERR("Cannot free eina_model internal descriptions -- still in use!"); | ||
3126 | else | ||
3127 | eina_hash_free(_eina_model_descriptions); | ||
3128 | eina_lock_release(&_eina_model_descriptions_lock); | ||
3129 | eina_lock_free(&_eina_model_descriptions_lock); | ||
3130 | |||
3131 | free(_eina_model_mp_choice); | ||
3132 | _eina_model_mp_choice = NULL; | ||
3133 | eina_mempool_del(_eina_model_mp); | ||
3134 | eina_log_domain_unregister(_eina_model_log_dom); | ||
3135 | _eina_model_log_dom = -1; | ||
3136 | return EINA_TRUE; | ||
3137 | } | ||
3138 | |||
3139 | /*============================================================================* | ||
3140 | * Global * | ||
3141 | *============================================================================*/ | ||
3142 | |||
3143 | /*============================================================================* | ||
3144 | * API * | ||
3145 | *============================================================================*/ | ||
3146 | |||
3147 | |||
3148 | EAPI Eina_Error EINA_ERROR_MODEL_FAILED = 0; | ||
3149 | EAPI Eina_Error EINA_ERROR_MODEL_METHOD_MISSING = 0; | ||
3150 | |||
3151 | EAPI const Eina_Model_Type *EINA_MODEL_TYPE_BASE = NULL; | ||
3152 | EAPI const Eina_Model_Type *EINA_MODEL_TYPE_MIXIN = NULL; | ||
3153 | EAPI const Eina_Model_Type *EINA_MODEL_TYPE_GENERIC = NULL; | ||
3154 | EAPI const Eina_Model_Type *EINA_MODEL_TYPE_STRUCT = NULL; | ||
3155 | |||
3156 | EAPI const Eina_Model_Interface *EINA_MODEL_INTERFACE_PROPERTIES_HASH = NULL; | ||
3157 | EAPI const Eina_Model_Interface *EINA_MODEL_INTERFACE_PROPERTIES_STRUCT = NULL; | ||
3158 | EAPI const Eina_Model_Interface *EINA_MODEL_INTERFACE_CHILDREN_INARRAY = NULL; | ||
3159 | |||
3160 | EAPI const char *EINA_MODEL_INTERFACE_NAME_PROPERTIES = "Eina_Model_Interface_Properties"; | ||
3161 | EAPI const char *EINA_MODEL_INTERFACE_NAME_CHILDREN = "Eina_Model_Interface_Children"; | ||
3162 | |||
3163 | EAPI Eina_Model * | ||
3164 | eina_model_new(const Eina_Model_Type *type) | ||
3165 | { | ||
3166 | const Eina_Model_Description *desc; | ||
3167 | Eina_Model *model; | ||
3168 | unsigned int i; | ||
3169 | |||
3170 | EINA_SAFETY_ON_NULL_RETURN_VAL(type, NULL); | ||
3171 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_model_type_check(type), NULL); | ||
3172 | |||
3173 | desc = _eina_model_description_get(type); | ||
3174 | EINA_SAFETY_ON_NULL_RETURN_VAL(desc, NULL); | ||
3175 | |||
3176 | model = eina_mempool_malloc(_eina_model_mp, sizeof(Eina_Model)); | ||
3177 | EINA_SAFETY_ON_NULL_GOTO(model, failed_model); | ||
3178 | |||
3179 | model->desc = desc; | ||
3180 | model->listeners.entries = NULL; | ||
3181 | model->listeners.deleted = NULL; | ||
3182 | model->listeners.freeze = NULL; | ||
3183 | model->listeners.walking = 0; | ||
3184 | |||
3185 | if (desc->total.size == 0) | ||
3186 | model->privates = NULL; | ||
3187 | else | ||
3188 | { | ||
3189 | unsigned char *ptr; | ||
3190 | |||
3191 | model->privates = _eina_model_inner_alloc | ||
3192 | (desc->total.privates * sizeof(void *) + | ||
3193 | desc->total.size); | ||
3194 | EINA_SAFETY_ON_NULL_GOTO(model->privates, failed_privates); | ||
3195 | |||
3196 | ptr = (unsigned char *)(model->privates + desc->total.privates); | ||
3197 | for (i = 0; i < desc->total.privates; i++) | ||
3198 | { | ||
3199 | unsigned int size; | ||
3200 | if (i < desc->total.types) | ||
3201 | size = desc->cache.privates[i].type->private_size; | ||
3202 | else | ||
3203 | size = desc->cache.privates[i].iface->private_size; | ||
3204 | |||
3205 | if (size == 0) | ||
3206 | { | ||
3207 | model->privates[i] = NULL; | ||
3208 | continue; | ||
3209 | } | ||
3210 | |||
3211 | model->privates[i] = ptr; | ||
3212 | memset(ptr, 0, size); | ||
3213 | |||
3214 | if (size % sizeof(void *) != 0) | ||
3215 | size += sizeof(void *) - (size % sizeof(void *)); | ||
3216 | ptr += size; | ||
3217 | } | ||
3218 | } | ||
3219 | |||
3220 | model->refcount = 1; | ||
3221 | model->xrefs = NULL; | ||
3222 | model->deleted = EINA_FALSE; | ||
3223 | EINA_MAGIC_SET(model, EINA_MAGIC_MODEL); | ||
3224 | |||
3225 | /* call setup of every type in the reverse order, | ||
3226 | * they should not call parent's setup. | ||
3227 | */ | ||
3228 | for (i = desc->total.types; i > 0; i--) | ||
3229 | { | ||
3230 | if (desc->cache.types[i - 1]->setup) | ||
3231 | { | ||
3232 | if (!desc->cache.types[i - 1]->setup(model)) | ||
3233 | { | ||
3234 | ERR("Failed to setup model %p at type %p (%s)", | ||
3235 | model, desc->cache.types[i - 1], | ||
3236 | desc->cache.types[i - 1]->name); | ||
3237 | goto failed_types; | ||
3238 | } | ||
3239 | } | ||
3240 | } | ||
3241 | |||
3242 | /* call setup of every interface in the reverse order, | ||
3243 | * they should not call parent's setup. | ||
3244 | */ | ||
3245 | for (i = desc->total.ifaces; i > 0; i--) | ||
3246 | { | ||
3247 | if (desc->cache.ifaces[i - 1]->setup) | ||
3248 | { | ||
3249 | if (!desc->cache.ifaces[i - 1]->setup(model)) | ||
3250 | { | ||
3251 | ERR("Failed to setup model %p at interface %p (%s)", | ||
3252 | model, desc->cache.ifaces[i - 1], | ||
3253 | desc->cache.ifaces[i - 1]->name); | ||
3254 | goto failed_ifaces; | ||
3255 | } | ||
3256 | } | ||
3257 | } | ||
3258 | |||
3259 | if (!desc->ops.type.constructor(model)) | ||
3260 | { | ||
3261 | ERR("Failed to construct model %p, type %p (%s)", | ||
3262 | model, desc->cache.types[0], desc->cache.types[0]->name); | ||
3263 | goto failed_constructor; | ||
3264 | } | ||
3265 | |||
3266 | if (EINA_UNLIKELY(_eina_model_debug)) | ||
3267 | { | ||
3268 | eina_lock_take(&_eina_model_debug_list_lock); | ||
3269 | _eina_model_debug_list = eina_list_append | ||
3270 | (_eina_model_debug_list, model); | ||
3271 | eina_lock_release(&_eina_model_debug_list_lock); | ||
3272 | } | ||
3273 | |||
3274 | return model; | ||
3275 | |||
3276 | failed_constructor: | ||
3277 | i = 0; | ||
3278 | failed_ifaces: | ||
3279 | /* flush every setup interface, natural order */ | ||
3280 | for (; i < desc->total.ifaces; i++) | ||
3281 | desc->cache.ifaces[i]->flush(model); | ||
3282 | i = 0; | ||
3283 | failed_types: | ||
3284 | /* flush every setup type, natural order */ | ||
3285 | for (; i < desc->total.types; i++) | ||
3286 | desc->cache.types[i]->flush(model); | ||
3287 | |||
3288 | if (model->privates) | ||
3289 | _eina_model_inner_free(desc->total.privates * sizeof(void *) + | ||
3290 | desc->total.size, | ||
3291 | model->privates); | ||
3292 | |||
3293 | failed_privates: | ||
3294 | EINA_MAGIC_SET(model, EINA_MAGIC_NONE); | ||
3295 | eina_mempool_free(_eina_model_mp, model); | ||
3296 | failed_model: | ||
3297 | _eina_model_description_dispose(desc); | ||
3298 | return NULL; | ||
3299 | } | ||
3300 | |||
3301 | static void | ||
3302 | _eina_model_free(Eina_Model *model) | ||
3303 | { | ||
3304 | const Eina_Model_Description *desc = model->desc; | ||
3305 | unsigned int i; | ||
3306 | |||
3307 | DBG("model %p (%s) refcount=%d deleted=%hhu", | ||
3308 | model, model->desc->cache.types[0]->name, | ||
3309 | model->refcount, model->deleted); | ||
3310 | |||
3311 | if (EINA_UNLIKELY(_eina_model_debug)) | ||
3312 | { | ||
3313 | if (model->xrefs) | ||
3314 | { | ||
3315 | ERR("Model %p (%s) released with references pending:", | ||
3316 | model, model->desc->cache.types[0]->name); | ||
3317 | while (model->xrefs) | ||
3318 | { | ||
3319 | Eina_Model_XRef *ref = (Eina_Model_XRef *)model->xrefs; | ||
3320 | model->xrefs = eina_inlist_remove(model->xrefs, model->xrefs); | ||
3321 | |||
3322 | ERR("xref: %p '%s'", ref->id, ref->label); | ||
3323 | free(ref); | ||
3324 | } | ||
3325 | } | ||
3326 | |||
3327 | eina_lock_take(&_eina_model_debug_list_lock); | ||
3328 | _eina_model_debug_list = eina_list_remove | ||
3329 | (_eina_model_debug_list, model); | ||
3330 | eina_lock_release(&_eina_model_debug_list_lock); | ||
3331 | } | ||
3332 | |||
3333 | /* flush every interface, natural order */ | ||
3334 | for (i = 0; i < desc->total.ifaces; i++) | ||
3335 | if (desc->cache.ifaces[i]->flush) | ||
3336 | desc->cache.ifaces[i]->flush(model); | ||
3337 | |||
3338 | /* flush every type, natural order */ | ||
3339 | for (i = 0; i < desc->total.types; i++) | ||
3340 | if (desc->cache.types[i]->flush) | ||
3341 | desc->cache.types[i]->flush(model); | ||
3342 | |||
3343 | model->refcount--; | ||
3344 | _eina_model_event_callback_call(model, _eina_model_str_freed, NULL); | ||
3345 | |||
3346 | if (model->privates) | ||
3347 | _eina_model_inner_free(desc->total.privates * sizeof(void *) + | ||
3348 | desc->total.size, | ||
3349 | model->privates); | ||
3350 | |||
3351 | if (model->listeners.deleted) | ||
3352 | _eina_model_event_callback_free_deleted(model); | ||
3353 | |||
3354 | if (model->listeners.entries) | ||
3355 | { | ||
3356 | for (i = 0; i < desc->total.events; i++) | ||
3357 | { | ||
3358 | Eina_Inlist *lst = model->listeners.entries[i]; | ||
3359 | while (lst) | ||
3360 | { | ||
3361 | void *tmp = lst; | ||
3362 | lst = lst->next; | ||
3363 | _eina_model_inner_free(sizeof(Eina_Model_Event_Listener), | ||
3364 | tmp); | ||
3365 | } | ||
3366 | } | ||
3367 | |||
3368 | _eina_model_inner_free(desc->total.events * sizeof(Eina_Inlist *), | ||
3369 | model->listeners.entries); | ||
3370 | } | ||
3371 | |||
3372 | if (model->listeners.freeze) | ||
3373 | _eina_model_inner_free(model->desc->total.events * sizeof(int), | ||
3374 | model->listeners.freeze); | ||
3375 | |||
3376 | EINA_MAGIC_SET(model, EINA_MAGIC_NONE); | ||
3377 | eina_mempool_free(_eina_model_mp, model); | ||
3378 | |||
3379 | _eina_model_description_dispose(desc); | ||
3380 | } | ||
3381 | |||
3382 | static void | ||
3383 | _eina_model_del(Eina_Model *model) | ||
3384 | { | ||
3385 | const Eina_Model_Description *desc = model->desc; | ||
3386 | |||
3387 | DBG("model %p (%s) refcount=%d deleted=%hhu", | ||
3388 | model, model->desc->cache.types[0]->name, | ||
3389 | model->refcount, model->deleted); | ||
3390 | |||
3391 | EINA_SAFETY_ON_TRUE_RETURN(model->deleted); | ||
3392 | |||
3393 | model->deleted = EINA_TRUE; | ||
3394 | _eina_model_event_callback_call(model, _eina_model_str_deleted, NULL); | ||
3395 | |||
3396 | if (!desc->ops.type.destructor(model)) | ||
3397 | ERR("Failed to destroy model %p, type %p (%s)", | ||
3398 | model, desc->cache.types[0], desc->cache.types[0]->name); | ||
3399 | } | ||
3400 | |||
3401 | static void | ||
3402 | _eina_model_unref(Eina_Model *model) | ||
3403 | { | ||
3404 | DBG("model %p (%s) refcount=%d deleted=%hhu", | ||
3405 | model, model->desc->cache.types[0]->name, | ||
3406 | model->refcount, model->deleted); | ||
3407 | |||
3408 | if (model->refcount > 1) | ||
3409 | { | ||
3410 | model->refcount--; | ||
3411 | return; | ||
3412 | } | ||
3413 | |||
3414 | if (!model->deleted) _eina_model_del(model); | ||
3415 | _eina_model_free(model); | ||
3416 | } | ||
3417 | |||
3418 | #define EINA_MODEL_INSTANCE_CHECK_VAL(inst, retval) \ | ||
3419 | do \ | ||
3420 | { \ | ||
3421 | if (!EINA_MAGIC_CHECK(inst, EINA_MAGIC_MODEL)) \ | ||
3422 | { \ | ||
3423 | EINA_MAGIC_FAIL(inst, EINA_MAGIC_MODEL); \ | ||
3424 | return retval; \ | ||
3425 | } \ | ||
3426 | EINA_SAFETY_ON_NULL_RETURN_VAL(inst->desc, retval); \ | ||
3427 | EINA_SAFETY_ON_FALSE_RETURN_VAL(inst->refcount > 0, retval); \ | ||
3428 | EINA_SAFETY_ON_FALSE_RETURN_VAL(inst->desc->refcount > 0, retval); \ | ||
3429 | } \ | ||
3430 | while (0) | ||
3431 | |||
3432 | #define EINA_MODEL_INSTANCE_CHECK(inst) \ | ||
3433 | do \ | ||
3434 | { \ | ||
3435 | if (!EINA_MAGIC_CHECK(inst, EINA_MAGIC_MODEL)) \ | ||
3436 | { \ | ||
3437 | EINA_MAGIC_FAIL(inst, EINA_MAGIC_MODEL); \ | ||
3438 | return; \ | ||
3439 | } \ | ||
3440 | EINA_SAFETY_ON_NULL_RETURN(inst->desc); \ | ||
3441 | EINA_SAFETY_ON_FALSE_RETURN(inst->refcount > 0); \ | ||
3442 | EINA_SAFETY_ON_FALSE_RETURN(inst->desc->refcount > 0); \ | ||
3443 | } \ | ||
3444 | while (0) | ||
3445 | |||
3446 | #define EINA_MODEL_TYPE_CALL_OPTIONAL_RETURN(model, method, def_retval, ...) \ | ||
3447 | do \ | ||
3448 | { \ | ||
3449 | eina_error_set(0); \ | ||
3450 | if (model->desc->ops.type.method) \ | ||
3451 | return model->desc->ops.type.method(model, ## __VA_ARGS__); \ | ||
3452 | DBG("Optional method" # method "() not implemented for model %p (%s)", \ | ||
3453 | model, model->desc->cache.types[0]->name); \ | ||
3454 | return def_retval; \ | ||
3455 | } \ | ||
3456 | while (0) | ||
3457 | |||
3458 | #define EINA_MODEL_TYPE_CALL_OPTIONAL(model, method, ...) \ | ||
3459 | do \ | ||
3460 | { \ | ||
3461 | eina_error_set(0); \ | ||
3462 | if (model->desc->ops.type.method) \ | ||
3463 | model->desc->ops.type.method(model, ## __VA_ARGS__); \ | ||
3464 | else \ | ||
3465 | DBG("Optional method" # method "() not implemented for model %p (%s)", \ | ||
3466 | model, model->desc->cache.types[0]->name); \ | ||
3467 | } \ | ||
3468 | while (0) | ||
3469 | |||
3470 | #define EINA_MODEL_TYPE_CALL_MANDATORY_RETURN(model, method, def_retval, ...) \ | ||
3471 | do \ | ||
3472 | { \ | ||
3473 | eina_error_set(0); \ | ||
3474 | if (model->desc->ops.type.method) \ | ||
3475 | return model->desc->ops.type.method(model, ## __VA_ARGS__); \ | ||
3476 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); \ | ||
3477 | CRITICAL("Mandatory method" # method "() not implemented for model %p (%s)", \ | ||
3478 | model, model->desc->cache.types[0]->name); \ | ||
3479 | return def_retval; \ | ||
3480 | } \ | ||
3481 | while (0) | ||
3482 | |||
3483 | #define EINA_MODEL_TYPE_CALL_MANDATORY(model, method, ...) \ | ||
3484 | do \ | ||
3485 | { \ | ||
3486 | eina_error_set(0); \ | ||
3487 | if (model->desc->ops.type.method) \ | ||
3488 | model->desc->ops.type.method(model, ## __VA_ARGS__); \ | ||
3489 | else \ | ||
3490 | { \ | ||
3491 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); \ | ||
3492 | CRITICAL("Mandatory method" # method "() not implemented for model %p (%s)", \ | ||
3493 | model, model->desc->cache.types[0]->name); \ | ||
3494 | } \ | ||
3495 | } \ | ||
3496 | while (0) | ||
3497 | |||
3498 | |||
3499 | #define EINA_MODEL_TYPE_CALL_RETURN(model, method, def_retval, ...) \ | ||
3500 | do \ | ||
3501 | { \ | ||
3502 | eina_error_set(0); \ | ||
3503 | if (model->desc->ops.type.method) \ | ||
3504 | return model->desc->ops.type.method(model, ## __VA_ARGS__); \ | ||
3505 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); \ | ||
3506 | ERR("Method" # method "() not implemented for model %p (%s)", \ | ||
3507 | model, model->desc->cache.types[0]->name); \ | ||
3508 | return def_retval; \ | ||
3509 | } \ | ||
3510 | while (0) | ||
3511 | |||
3512 | #define EINA_MODEL_TYPE_CALL(model, method, ...) \ | ||
3513 | do \ | ||
3514 | { \ | ||
3515 | eina_error_set(0); \ | ||
3516 | if (model->desc->ops.type.method) \ | ||
3517 | model->desc->ops.type.method(model, ## __VA_ARGS__); \ | ||
3518 | else \ | ||
3519 | { \ | ||
3520 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); \ | ||
3521 | ERR("Method" # method "() not implemented for model %p (%s)", \ | ||
3522 | model, model->desc->cache.types[0]->name); \ | ||
3523 | } \ | ||
3524 | } \ | ||
3525 | while (0) | ||
3526 | |||
3527 | EAPI void | ||
3528 | eina_model_del(Eina_Model *model) | ||
3529 | { | ||
3530 | EINA_MODEL_INSTANCE_CHECK(model); | ||
3531 | _eina_model_del(model); | ||
3532 | _eina_model_unref(model); | ||
3533 | } | ||
3534 | |||
3535 | EAPI const Eina_Model_Type * | ||
3536 | eina_model_type_get(const Eina_Model *model) | ||
3537 | { | ||
3538 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
3539 | return model->desc->cache.types[0]; | ||
3540 | } | ||
3541 | |||
3542 | EAPI const Eina_Model_Interface * | ||
3543 | eina_model_interface_get(const Eina_Model *model, const char *name) | ||
3544 | { | ||
3545 | const Eina_Model_Description *desc; | ||
3546 | const Eina_Model_Interface **itr, **itr_end; | ||
3547 | |||
3548 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
3549 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); | ||
3550 | |||
3551 | desc = model->desc; | ||
3552 | itr = desc->cache.ifaces; | ||
3553 | itr_end = itr + desc->total.ifaces; | ||
3554 | |||
3555 | /* fallback to strcmp if user is lazy about speed */ | ||
3556 | for (; itr < itr_end; itr++) | ||
3557 | if (strcmp((*itr)->name, name) == 0) | ||
3558 | return *itr; | ||
3559 | |||
3560 | return NULL; | ||
3561 | } | ||
3562 | |||
3563 | static Eina_Bool | ||
3564 | _eina_model_instance_check(const Eina_Model *model, const Eina_Model_Type *type) | ||
3565 | { | ||
3566 | const Eina_Model_Type **itr, **itr_end; | ||
3567 | |||
3568 | itr = model->desc->cache.types; | ||
3569 | itr_end = itr + model->desc->total.types; | ||
3570 | |||
3571 | for (; itr < itr_end; itr++) | ||
3572 | if (*itr == type) | ||
3573 | return EINA_TRUE; | ||
3574 | |||
3575 | return EINA_FALSE; | ||
3576 | } | ||
3577 | |||
3578 | EAPI Eina_Bool | ||
3579 | eina_model_instance_check(const Eina_Model *model, const Eina_Model_Type *type) | ||
3580 | { | ||
3581 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
3582 | EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE); | ||
3583 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_type_check(type), EINA_FALSE); | ||
3584 | return _eina_model_instance_check(model, type); | ||
3585 | } | ||
3586 | |||
3587 | EAPI Eina_Model * | ||
3588 | eina_model_ref(Eina_Model *model) | ||
3589 | { | ||
3590 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
3591 | DBG("model %p (%s) refcount=%d deleted=%hhu", | ||
3592 | model, model->desc->cache.types[0]->name, | ||
3593 | model->refcount, model->deleted); | ||
3594 | model->refcount++; | ||
3595 | return model; | ||
3596 | } | ||
3597 | |||
3598 | static Eina_Model * | ||
3599 | _eina_model_xref_add(Eina_Model *model, const void *id, const char *label) | ||
3600 | { | ||
3601 | Eina_Model_XRef *ref; | ||
3602 | void *bt[256]; | ||
3603 | int btlen, labellen; | ||
3604 | |||
3605 | labellen = label ? strlen(label): 0; | ||
3606 | btlen = 0; | ||
3607 | |||
3608 | #ifdef HAVE_BACKTRACE | ||
3609 | if (_eina_model_debug == EINA_MODEL_DEBUG_BACKTRACE) | ||
3610 | btlen = backtrace(bt, EINA_C_ARRAY_LENGTH(bt)); | ||
3611 | #endif | ||
3612 | |||
3613 | ref = calloc(1, sizeof(*ref) + (btlen * sizeof(void *)) + (labellen + 1)); | ||
3614 | EINA_SAFETY_ON_NULL_RETURN_VAL(ref, NULL); | ||
3615 | |||
3616 | ref->id = id; | ||
3617 | memcpy(ref->label, label, labellen); | ||
3618 | ref->label[labellen] = '\0'; | ||
3619 | ref->backtrace.count = btlen; | ||
3620 | if (btlen == 0) ref->backtrace.symbols = NULL; | ||
3621 | else | ||
3622 | { | ||
3623 | void *ptr = (unsigned char *)ref + sizeof(*ref) + (labellen + 1); | ||
3624 | ref->backtrace.symbols = ptr; | ||
3625 | memcpy(ptr, bt, btlen * sizeof(void *)); | ||
3626 | } | ||
3627 | |||
3628 | model->xrefs = eina_inlist_append(model->xrefs, EINA_INLIST_GET(ref)); | ||
3629 | return model; | ||
3630 | } | ||
3631 | |||
3632 | EAPI Eina_Model * | ||
3633 | eina_model_xref(Eina_Model *model, const void *id, const char *label) | ||
3634 | { | ||
3635 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
3636 | DBG("model %p (%s) refcount=%d deleted=%hhu id=%p label=%s", | ||
3637 | model, model->desc->cache.types[0]->name, | ||
3638 | model->refcount, model->deleted, id, label ? label : ""); | ||
3639 | |||
3640 | model->refcount++; | ||
3641 | |||
3642 | if (EINA_LIKELY(!_eina_model_debug)) | ||
3643 | return model; | ||
3644 | |||
3645 | return _eina_model_xref_add(model, id, label); | ||
3646 | } | ||
3647 | |||
3648 | EAPI void | ||
3649 | eina_model_unref(Eina_Model *model) | ||
3650 | { | ||
3651 | EINA_MODEL_INSTANCE_CHECK(model); | ||
3652 | _eina_model_unref(model); | ||
3653 | } | ||
3654 | |||
3655 | EAPI void | ||
3656 | eina_model_xunref(Eina_Model *model, const void *id) | ||
3657 | { | ||
3658 | Eina_Model_XRef *ref; | ||
3659 | EINA_MODEL_INSTANCE_CHECK(model); | ||
3660 | |||
3661 | if (EINA_LIKELY(!_eina_model_debug)) | ||
3662 | { | ||
3663 | _eina_model_unref(model); | ||
3664 | return; | ||
3665 | } | ||
3666 | |||
3667 | EINA_INLIST_FOREACH(model->xrefs, ref) | ||
3668 | { | ||
3669 | if (ref->id != id) continue; | ||
3670 | |||
3671 | model->xrefs = eina_inlist_remove(model->xrefs, EINA_INLIST_GET(ref)); | ||
3672 | free(ref); | ||
3673 | _eina_model_unref(model); | ||
3674 | return; | ||
3675 | } | ||
3676 | |||
3677 | ERR("Could not find existing reference %p to model %p", id, model); | ||
3678 | } | ||
3679 | |||
3680 | EAPI int | ||
3681 | eina_model_refcount(const Eina_Model *model) | ||
3682 | { | ||
3683 | EINA_MODEL_INSTANCE_CHECK_VAL(model, -1); | ||
3684 | return model->refcount; | ||
3685 | } | ||
3686 | |||
3687 | EAPI const Eina_Inlist * | ||
3688 | eina_model_xrefs_get(const Eina_Model *model) | ||
3689 | { | ||
3690 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
3691 | return model->xrefs; | ||
3692 | } | ||
3693 | |||
3694 | EAPI Eina_Bool | ||
3695 | eina_model_event_callback_add(Eina_Model *model, const char *event_name, Eina_Model_Event_Cb cb, const void *data) | ||
3696 | { | ||
3697 | const Eina_Model_Description *desc; | ||
3698 | Eina_Model_Event_Listener *el; | ||
3699 | int event_id; | ||
3700 | |||
3701 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
3702 | EINA_SAFETY_ON_NULL_RETURN_VAL(event_name, EINA_FALSE); | ||
3703 | EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE); | ||
3704 | |||
3705 | desc = model->desc; | ||
3706 | event_id = _eina_model_description_event_id_find(desc, event_name); | ||
3707 | if (event_id < 0) | ||
3708 | { | ||
3709 | ERR("No event named %s for model %p (%s)", | ||
3710 | event_name, model, model->desc->cache.types[0]->name); | ||
3711 | return EINA_FALSE; | ||
3712 | } | ||
3713 | |||
3714 | if (!model->listeners.entries) | ||
3715 | { | ||
3716 | model->listeners.entries = _eina_model_inner_alloc | ||
3717 | (desc->total.events * sizeof(Eina_Inlist *)); | ||
3718 | EINA_SAFETY_ON_NULL_RETURN_VAL(model->listeners.entries, EINA_FALSE); | ||
3719 | memset(model->listeners.entries, 0, | ||
3720 | desc->total.events * sizeof(Eina_Inlist *)); | ||
3721 | } | ||
3722 | |||
3723 | el = _eina_model_inner_alloc(sizeof(Eina_Model_Event_Listener)); | ||
3724 | EINA_SAFETY_ON_NULL_RETURN_VAL(el, EINA_FALSE); | ||
3725 | |||
3726 | el->cb = cb; | ||
3727 | el->data = data; | ||
3728 | el->deleted = EINA_FALSE; | ||
3729 | model->listeners.entries[event_id] = eina_inlist_append | ||
3730 | (model->listeners.entries[event_id], EINA_INLIST_GET(el)); | ||
3731 | |||
3732 | return EINA_TRUE; | ||
3733 | } | ||
3734 | |||
3735 | EAPI Eina_Bool | ||
3736 | eina_model_event_callback_del(Eina_Model *model, const char *event_name, Eina_Model_Event_Cb cb, const void *data) | ||
3737 | { | ||
3738 | int event_id; | ||
3739 | Eina_Inlist *lst; | ||
3740 | Eina_Model_Event_Listener *el; | ||
3741 | |||
3742 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
3743 | EINA_SAFETY_ON_NULL_RETURN_VAL(event_name, EINA_FALSE); | ||
3744 | EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE); | ||
3745 | |||
3746 | if (!model->listeners.entries) | ||
3747 | { | ||
3748 | ERR("No event callbacks for model %p (%s)", | ||
3749 | model, model->desc->cache.types[0]->name); | ||
3750 | return EINA_FALSE; | ||
3751 | } | ||
3752 | |||
3753 | event_id = _eina_model_description_event_id_find(model->desc, event_name); | ||
3754 | if (event_id < 0) | ||
3755 | { | ||
3756 | ERR("No event named %s for model %p (%s)", | ||
3757 | event_name, model, model->desc->cache.types[0]->name); | ||
3758 | return EINA_FALSE; | ||
3759 | } | ||
3760 | |||
3761 | lst = model->listeners.entries[event_id]; | ||
3762 | EINA_INLIST_FOREACH(lst, el) | ||
3763 | { | ||
3764 | if (el->cb != cb) continue; | ||
3765 | if ((data) && (el->data != data)) continue; | ||
3766 | |||
3767 | if (model->listeners.walking == 0) | ||
3768 | { | ||
3769 | model->listeners.entries[event_id] = eina_inlist_remove | ||
3770 | (model->listeners.entries[event_id], EINA_INLIST_GET(el)); | ||
3771 | _eina_model_inner_free(sizeof(Eina_Model_Event_Listener), el); | ||
3772 | } | ||
3773 | else | ||
3774 | { | ||
3775 | el->deleted = EINA_TRUE; | ||
3776 | if (!model->listeners.deleted) | ||
3777 | { | ||
3778 | model->listeners.deleted = _eina_model_inner_alloc | ||
3779 | (model->desc->total.events * sizeof(Eina_List *)); | ||
3780 | EINA_SAFETY_ON_NULL_RETURN_VAL(model->listeners.deleted, | ||
3781 | EINA_FALSE); | ||
3782 | |||
3783 | memset(model->listeners.deleted, 0, | ||
3784 | model->desc->total.events * sizeof(Eina_List *)); | ||
3785 | |||
3786 | } | ||
3787 | model->listeners.deleted[event_id] = eina_list_append | ||
3788 | (model->listeners.deleted[event_id], el); | ||
3789 | } | ||
3790 | return EINA_TRUE; | ||
3791 | } | ||
3792 | |||
3793 | ERR("No callback %p data %p found for event named %s for model %p (%s)", | ||
3794 | cb, data, event_name, model, model->desc->cache.types[0]->name); | ||
3795 | return EINA_FALSE; | ||
3796 | } | ||
3797 | |||
3798 | EAPI const Eina_Model_Event_Description * | ||
3799 | eina_model_event_description_get(const Eina_Model *model, const char *event_name) | ||
3800 | { | ||
3801 | const Eina_Model_Description *desc; | ||
3802 | int event_id; | ||
3803 | |||
3804 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
3805 | EINA_SAFETY_ON_NULL_RETURN_VAL(event_name, NULL); | ||
3806 | |||
3807 | desc = model->desc; | ||
3808 | event_id = _eina_model_description_event_id_find(desc, event_name); | ||
3809 | if (event_id < 0) | ||
3810 | return NULL; | ||
3811 | |||
3812 | return desc->cache.events[event_id].desc; | ||
3813 | } | ||
3814 | |||
3815 | EAPI Eina_List * | ||
3816 | eina_model_event_names_list_get(const Eina_Model *model) | ||
3817 | { | ||
3818 | const Eina_Model_Event_Description_Cache *itr, *itr_end; | ||
3819 | Eina_List *lst = NULL; | ||
3820 | |||
3821 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
3822 | |||
3823 | itr = model->desc->cache.events; | ||
3824 | itr_end = itr + model->desc->total.events; | ||
3825 | |||
3826 | for (; itr < itr_end; itr++) | ||
3827 | lst = eina_list_append(lst, eina_stringshare_add(itr->name)); | ||
3828 | |||
3829 | return lst; | ||
3830 | } | ||
3831 | |||
3832 | EAPI void | ||
3833 | eina_model_event_names_list_free(Eina_List *list) | ||
3834 | { | ||
3835 | const char *str; | ||
3836 | EINA_LIST_FREE(list, str) | ||
3837 | eina_stringshare_del(str); | ||
3838 | } | ||
3839 | |||
3840 | EAPI Eina_Bool | ||
3841 | eina_model_event_callback_call(Eina_Model *model, const char *name, const void *event_info) | ||
3842 | { | ||
3843 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
3844 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); | ||
3845 | return _eina_model_event_callback_call(model, name, event_info); | ||
3846 | } | ||
3847 | |||
3848 | EAPI int | ||
3849 | eina_model_event_callback_freeze(Eina_Model *model, const char *name) | ||
3850 | { | ||
3851 | int event_id; | ||
3852 | |||
3853 | EINA_MODEL_INSTANCE_CHECK_VAL(model, -1); | ||
3854 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, -1); | ||
3855 | |||
3856 | event_id = _eina_model_description_event_id_find(model->desc, name); | ||
3857 | if (event_id < 0) return -1; | ||
3858 | |||
3859 | if (!model->listeners.freeze) | ||
3860 | { | ||
3861 | model->listeners.freeze = _eina_model_inner_alloc | ||
3862 | (model->desc->total.events * sizeof(int)); | ||
3863 | EINA_SAFETY_ON_NULL_RETURN_VAL(model->listeners.freeze, -1); | ||
3864 | |||
3865 | memset(model->listeners.freeze, 0, | ||
3866 | model->desc->total.events * sizeof(int)); | ||
3867 | } | ||
3868 | |||
3869 | if (model->listeners.freeze[event_id] == 0) | ||
3870 | DBG("model %p (%s) event %s frozen", | ||
3871 | model, model->desc->cache.types[0]->name, name); | ||
3872 | |||
3873 | model->listeners.freeze[event_id]++; | ||
3874 | return model->listeners.freeze[event_id]; | ||
3875 | } | ||
3876 | |||
3877 | EAPI int | ||
3878 | eina_model_event_callback_thaw(Eina_Model *model, const char *name) | ||
3879 | { | ||
3880 | int event_id; | ||
3881 | |||
3882 | EINA_MODEL_INSTANCE_CHECK_VAL(model, -1); | ||
3883 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, -1); | ||
3884 | EINA_SAFETY_ON_NULL_RETURN_VAL(model->listeners.freeze, -1); | ||
3885 | |||
3886 | event_id = _eina_model_description_event_id_find(model->desc, name); | ||
3887 | if (event_id < 0) return -1; | ||
3888 | |||
3889 | model->listeners.freeze[event_id]--; | ||
3890 | if (model->listeners.freeze[event_id] == 0) | ||
3891 | DBG("model %p (%s) event %s unfrozen", | ||
3892 | model, model->desc->cache.types[0]->name, name); | ||
3893 | return model->listeners.freeze[event_id]; | ||
3894 | } | ||
3895 | |||
3896 | EAPI Eina_Model * | ||
3897 | eina_model_copy(const Eina_Model *model) | ||
3898 | { | ||
3899 | const Eina_Model_Description *desc; | ||
3900 | Eina_Model *copy; | ||
3901 | unsigned int i; | ||
3902 | |||
3903 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
3904 | desc = model->desc; | ||
3905 | copy = eina_model_new(desc->cache.types[0]); | ||
3906 | EINA_SAFETY_ON_NULL_RETURN_VAL(copy, NULL); | ||
3907 | |||
3908 | /* call copy of every type in the reverse order, | ||
3909 | * they should not call parent's copy. | ||
3910 | */ | ||
3911 | for (i = desc->total.types; i > 0; i--) | ||
3912 | { | ||
3913 | if (desc->cache.types[i - 1]->copy) | ||
3914 | { | ||
3915 | if (!desc->cache.types[i - 1]->copy(model, copy)) | ||
3916 | goto failed; | ||
3917 | } | ||
3918 | } | ||
3919 | |||
3920 | /* call copy of every interface in the reverse order, | ||
3921 | * they should not call parent's copy. | ||
3922 | */ | ||
3923 | for (i = desc->total.ifaces; i > 0; i--) | ||
3924 | { | ||
3925 | if (desc->cache.ifaces[i - 1]->copy) | ||
3926 | { | ||
3927 | if (!desc->cache.ifaces[i - 1]->copy(model, copy)) | ||
3928 | goto failed; | ||
3929 | } | ||
3930 | } | ||
3931 | |||
3932 | return copy; | ||
3933 | |||
3934 | failed: | ||
3935 | ERR("Failed to copy model %p %s", model, desc->cache.types[0]->name); | ||
3936 | eina_model_del(copy); | ||
3937 | return NULL; | ||
3938 | } | ||
3939 | |||
3940 | EAPI Eina_Model * | ||
3941 | eina_model_deep_copy(const Eina_Model *model) | ||
3942 | { | ||
3943 | const Eina_Model_Description *desc; | ||
3944 | Eina_Model *deep_copy; | ||
3945 | unsigned int i; | ||
3946 | |||
3947 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
3948 | desc = model->desc; | ||
3949 | deep_copy = eina_model_new(desc->cache.types[0]); | ||
3950 | EINA_SAFETY_ON_NULL_RETURN_VAL(deep_copy, NULL); | ||
3951 | |||
3952 | /* call deep_copy of every type in the reverse order, | ||
3953 | * they should not call parent's deep_copy. | ||
3954 | */ | ||
3955 | for (i = desc->total.types; i > 0; i--) | ||
3956 | { | ||
3957 | if (desc->cache.types[i - 1]->deep_copy) | ||
3958 | { | ||
3959 | if (!desc->cache.types[i - 1]->deep_copy(model, deep_copy)) | ||
3960 | goto failed; | ||
3961 | } | ||
3962 | } | ||
3963 | |||
3964 | /* call deep_copy of every interface in the reverse order, | ||
3965 | * they should not call parent's deep_copy. | ||
3966 | */ | ||
3967 | for (i = desc->total.ifaces; i > 0; i--) | ||
3968 | { | ||
3969 | if (desc->cache.ifaces[i - 1]->deep_copy) | ||
3970 | { | ||
3971 | if (!desc->cache.ifaces[i - 1]->deep_copy(model, deep_copy)) | ||
3972 | goto failed; | ||
3973 | } | ||
3974 | } | ||
3975 | |||
3976 | return deep_copy; | ||
3977 | |||
3978 | failed: | ||
3979 | ERR("Failed to deep copy model %p %s", model, desc->cache.types[0]->name); | ||
3980 | eina_model_del(deep_copy); | ||
3981 | return NULL; | ||
3982 | } | ||
3983 | |||
3984 | EAPI int | ||
3985 | eina_model_compare(const Eina_Model *a, const Eina_Model *b) | ||
3986 | { | ||
3987 | const Eina_Model_Description *desc_a, *desc_b; | ||
3988 | Eina_Bool ok; | ||
3989 | int cmp = -1; | ||
3990 | |||
3991 | EINA_MODEL_INSTANCE_CHECK_VAL(a, -1); | ||
3992 | EINA_MODEL_INSTANCE_CHECK_VAL(b, -1); | ||
3993 | desc_a = a->desc; | ||
3994 | desc_b = b->desc; | ||
3995 | |||
3996 | if ((!desc_a->ops.type.compare) && (!desc_b->ops.type.compare)) | ||
3997 | { | ||
3998 | ERR("Models %p (%s) and %p (%s) can't compare", | ||
3999 | a, desc_a->cache.types[0]->name, | ||
4000 | b, desc_b->cache.types[0]->name); | ||
4001 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); | ||
4002 | return -1; | ||
4003 | } | ||
4004 | else if ((desc_a->ops.type.compare) && (desc_b->ops.type.compare)) | ||
4005 | { | ||
4006 | ok = desc_a->ops.type.compare(a, b, &cmp); | ||
4007 | if (!ok) | ||
4008 | { | ||
4009 | ok = desc_b->ops.type.compare(b, a, &cmp); | ||
4010 | if (ok) | ||
4011 | cmp = -cmp; /* swapped sides! */ | ||
4012 | } | ||
4013 | } | ||
4014 | else if (desc_a->ops.type.compare) | ||
4015 | ok = desc_a->ops.type.compare(a, b, &cmp); | ||
4016 | else | ||
4017 | { | ||
4018 | ok = desc_b->ops.type.compare(b, a, &cmp); | ||
4019 | if (ok) | ||
4020 | cmp = -cmp; /* swapped sides! */ | ||
4021 | } | ||
4022 | |||
4023 | if (!ok) | ||
4024 | { | ||
4025 | ERR("Could not compare models %p (%s) and %p (%s)", | ||
4026 | a, desc_a->cache.types[0]->name, | ||
4027 | b, desc_b->cache.types[0]->name); | ||
4028 | eina_error_set(EINA_ERROR_MODEL_FAILED); | ||
4029 | return -1; | ||
4030 | } | ||
4031 | |||
4032 | return cmp; | ||
4033 | } | ||
4034 | |||
4035 | EAPI Eina_Bool | ||
4036 | eina_model_load(Eina_Model *model) | ||
4037 | { | ||
4038 | Eina_Bool ret; | ||
4039 | |||
4040 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
4041 | |||
4042 | eina_error_set(0); | ||
4043 | if (model->desc->ops.type.load) | ||
4044 | { | ||
4045 | ret = model->desc->ops.type.load(model); | ||
4046 | if (ret) | ||
4047 | _eina_model_event_callback_call(model, _eina_model_str_loaded, NULL); | ||
4048 | } | ||
4049 | else | ||
4050 | { | ||
4051 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); | ||
4052 | ret = EINA_FALSE; | ||
4053 | ERR("Method load() not implemented for model %p (%s)", | ||
4054 | model, model->desc->cache.types[0]->name); | ||
4055 | } | ||
4056 | |||
4057 | return ret; | ||
4058 | } | ||
4059 | |||
4060 | EAPI Eina_Bool | ||
4061 | eina_model_unload(Eina_Model *model) | ||
4062 | { | ||
4063 | Eina_Bool ret; | ||
4064 | |||
4065 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
4066 | |||
4067 | eina_error_set(0); | ||
4068 | if (model->desc->ops.type.unload) | ||
4069 | { | ||
4070 | ret = model->desc->ops.type.unload(model); | ||
4071 | if (ret) | ||
4072 | _eina_model_event_callback_call | ||
4073 | (model, _eina_model_str_unloaded, NULL); | ||
4074 | } | ||
4075 | else | ||
4076 | { | ||
4077 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); | ||
4078 | ret = EINA_FALSE; | ||
4079 | ERR("Method unload() not implemented for model %p (%s)", | ||
4080 | model, model->desc->cache.types[0]->name); | ||
4081 | } | ||
4082 | |||
4083 | return ret; | ||
4084 | } | ||
4085 | |||
4086 | EAPI Eina_Bool | ||
4087 | eina_model_property_get(const Eina_Model *model, const char *name, Eina_Value *value) | ||
4088 | { | ||
4089 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
4090 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); | ||
4091 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); | ||
4092 | EINA_MODEL_TYPE_CALL_MANDATORY_RETURN(model, property_get, EINA_FALSE, | ||
4093 | name, value); | ||
4094 | } | ||
4095 | |||
4096 | EAPI Eina_Bool | ||
4097 | eina_model_property_set(Eina_Model *model, const const char *name, const Eina_Value *value) | ||
4098 | { | ||
4099 | Eina_Bool ret; | ||
4100 | |||
4101 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
4102 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); | ||
4103 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); | ||
4104 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), EINA_FALSE); | ||
4105 | |||
4106 | eina_error_set(0); | ||
4107 | if (model->desc->ops.type.property_set) | ||
4108 | { | ||
4109 | ret = model->desc->ops.type.property_set(model, name, value); | ||
4110 | if (ret) | ||
4111 | _eina_model_event_callback_call | ||
4112 | (model, _eina_model_str_property_set, name); | ||
4113 | } | ||
4114 | else | ||
4115 | { | ||
4116 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); | ||
4117 | ret = EINA_FALSE; | ||
4118 | ERR("Method property_set() not implemented for model %p (%s)", | ||
4119 | model, model->desc->cache.types[0]->name); | ||
4120 | } | ||
4121 | |||
4122 | return ret; | ||
4123 | } | ||
4124 | |||
4125 | EAPI Eina_Bool | ||
4126 | eina_model_property_del(Eina_Model *model, const char *name) | ||
4127 | { | ||
4128 | Eina_Bool ret; | ||
4129 | |||
4130 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
4131 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); | ||
4132 | |||
4133 | eina_error_set(0); | ||
4134 | if (model->desc->ops.type.property_del) | ||
4135 | { | ||
4136 | ret = model->desc->ops.type.property_del(model, name); | ||
4137 | if (ret) | ||
4138 | _eina_model_event_callback_call | ||
4139 | (model, _eina_model_str_property_del, name); | ||
4140 | } | ||
4141 | else | ||
4142 | { | ||
4143 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); | ||
4144 | ret = EINA_FALSE; | ||
4145 | ERR("Method property_del() not implemented for model %p (%s)", | ||
4146 | model, model->desc->cache.types[0]->name); | ||
4147 | } | ||
4148 | |||
4149 | return ret; | ||
4150 | } | ||
4151 | |||
4152 | EAPI Eina_List * | ||
4153 | eina_model_properties_names_list_get(const Eina_Model *model) | ||
4154 | { | ||
4155 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4156 | EINA_MODEL_TYPE_CALL_OPTIONAL_RETURN(model, properties_names_list_get, NULL); | ||
4157 | } | ||
4158 | |||
4159 | EAPI void | ||
4160 | eina_model_properties_names_list_free(Eina_List *list) | ||
4161 | { | ||
4162 | const char *str; | ||
4163 | EINA_LIST_FREE(list, str) | ||
4164 | eina_stringshare_del(str); | ||
4165 | } | ||
4166 | |||
4167 | EAPI int | ||
4168 | eina_model_child_count(const Eina_Model *model) | ||
4169 | { | ||
4170 | EINA_MODEL_INSTANCE_CHECK_VAL(model, -1); | ||
4171 | EINA_MODEL_TYPE_CALL_OPTIONAL_RETURN(model, child_count, 0); | ||
4172 | } | ||
4173 | |||
4174 | EAPI Eina_Model * | ||
4175 | eina_model_child_get(const Eina_Model *model, unsigned int position) | ||
4176 | { | ||
4177 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4178 | EINA_MODEL_TYPE_CALL_RETURN(model, child_get, NULL, position); | ||
4179 | } | ||
4180 | |||
4181 | EAPI Eina_Bool | ||
4182 | eina_model_child_set(Eina_Model *model, unsigned int position, Eina_Model *child) | ||
4183 | { | ||
4184 | Eina_Bool ret; | ||
4185 | |||
4186 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
4187 | EINA_MODEL_INSTANCE_CHECK_VAL(child, EINA_FALSE); | ||
4188 | |||
4189 | eina_error_set(0); | ||
4190 | if (model->desc->ops.type.child_set) | ||
4191 | { | ||
4192 | ret = model->desc->ops.type.child_set(model, position, child); | ||
4193 | if (ret) | ||
4194 | _eina_model_event_callback_call | ||
4195 | (model, _eina_model_str_child_set, &position); | ||
4196 | } | ||
4197 | else | ||
4198 | { | ||
4199 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); | ||
4200 | ret = EINA_FALSE; | ||
4201 | ERR("Method child_set() not implemented for model %p (%s)", | ||
4202 | model, model->desc->cache.types[0]->name); | ||
4203 | } | ||
4204 | |||
4205 | return ret; | ||
4206 | } | ||
4207 | |||
4208 | EAPI Eina_Bool | ||
4209 | eina_model_child_del(Eina_Model *model, unsigned int position) | ||
4210 | { | ||
4211 | Eina_Bool ret; | ||
4212 | |||
4213 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
4214 | |||
4215 | eina_error_set(0); | ||
4216 | if (model->desc->ops.type.child_del) | ||
4217 | { | ||
4218 | ret = model->desc->ops.type.child_del(model, position); | ||
4219 | if (ret) | ||
4220 | { | ||
4221 | _eina_model_event_callback_call | ||
4222 | (model, _eina_model_str_child_del, &position); | ||
4223 | _eina_model_event_callback_call | ||
4224 | (model, _eina_model_str_children_changed, NULL); | ||
4225 | } | ||
4226 | } | ||
4227 | else | ||
4228 | { | ||
4229 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); | ||
4230 | ret = EINA_FALSE; | ||
4231 | ERR("Method child_del() not implemented for model %p (%s)", | ||
4232 | model, model->desc->cache.types[0]->name); | ||
4233 | } | ||
4234 | |||
4235 | return ret; | ||
4236 | } | ||
4237 | |||
4238 | EAPI Eina_Bool | ||
4239 | eina_model_child_insert_at(Eina_Model *model, unsigned int position, Eina_Model *child) | ||
4240 | { | ||
4241 | Eina_Bool ret; | ||
4242 | |||
4243 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
4244 | EINA_SAFETY_ON_NULL_RETURN_VAL(child, EINA_FALSE); | ||
4245 | |||
4246 | eina_error_set(0); | ||
4247 | if (model->desc->ops.type.child_insert_at) | ||
4248 | { | ||
4249 | ret = model->desc->ops.type.child_insert_at(model, position, child); | ||
4250 | if (ret) | ||
4251 | { | ||
4252 | _eina_model_event_callback_call | ||
4253 | (model, _eina_model_str_child_inserted, &position); | ||
4254 | _eina_model_event_callback_call | ||
4255 | (model, _eina_model_str_children_changed, NULL); | ||
4256 | } | ||
4257 | } | ||
4258 | else | ||
4259 | { | ||
4260 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); | ||
4261 | ret = EINA_FALSE; | ||
4262 | ERR("Method child_insert_at() not implemented for model %p (%s)", | ||
4263 | model, model->desc->cache.types[0]->name); | ||
4264 | } | ||
4265 | |||
4266 | return ret; | ||
4267 | } | ||
4268 | |||
4269 | EAPI int | ||
4270 | eina_model_child_append(Eina_Model *model, Eina_Model *child) | ||
4271 | { | ||
4272 | Eina_Bool ret; | ||
4273 | int position; | ||
4274 | |||
4275 | EINA_MODEL_INSTANCE_CHECK_VAL(model, -1); | ||
4276 | EINA_SAFETY_ON_NULL_RETURN_VAL(child, -1); | ||
4277 | |||
4278 | position = eina_model_child_count(model); | ||
4279 | if (position < 0) | ||
4280 | return -1; | ||
4281 | |||
4282 | eina_error_set(0); | ||
4283 | if (model->desc->ops.type.child_insert_at) | ||
4284 | { | ||
4285 | ret = model->desc->ops.type.child_insert_at(model, position, child); | ||
4286 | if (ret) | ||
4287 | { | ||
4288 | _eina_model_event_callback_call | ||
4289 | (model, _eina_model_str_child_inserted, &position); | ||
4290 | _eina_model_event_callback_call | ||
4291 | (model, _eina_model_str_children_changed, NULL); | ||
4292 | } | ||
4293 | } | ||
4294 | else | ||
4295 | { | ||
4296 | eina_error_set(EINA_ERROR_MODEL_METHOD_MISSING); | ||
4297 | ret = EINA_FALSE; | ||
4298 | ERR("Method child_insert_at() not implemented for model %p (%s)", | ||
4299 | model, model->desc->cache.types[0]->name); | ||
4300 | } | ||
4301 | |||
4302 | return ret ? position : -1; | ||
4303 | } | ||
4304 | |||
4305 | EAPI int | ||
4306 | eina_model_child_find(const Eina_Model *model, unsigned int start_position, const Eina_Model *other) | ||
4307 | { | ||
4308 | EINA_MODEL_INSTANCE_CHECK_VAL(model, -1); | ||
4309 | EINA_SAFETY_ON_NULL_RETURN_VAL(other, -1); | ||
4310 | EINA_MODEL_TYPE_CALL_RETURN(model, child_find, -1, start_position, other); | ||
4311 | } | ||
4312 | |||
4313 | EAPI int | ||
4314 | eina_model_child_criteria_match(const Eina_Model *model, unsigned int start_position, Eina_Each_Cb match, const void *data) | ||
4315 | { | ||
4316 | EINA_MODEL_INSTANCE_CHECK_VAL(model, -1); | ||
4317 | EINA_SAFETY_ON_NULL_RETURN_VAL(match, -1); | ||
4318 | EINA_MODEL_TYPE_CALL_RETURN(model, child_criteria_match, -1, | ||
4319 | start_position, match, data); | ||
4320 | } | ||
4321 | |||
4322 | EAPI Eina_Bool | ||
4323 | eina_model_child_sort(Eina_Model *model, Eina_Compare_Cb compare) | ||
4324 | { | ||
4325 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
4326 | EINA_SAFETY_ON_NULL_RETURN_VAL(compare, EINA_FALSE); | ||
4327 | EINA_MODEL_TYPE_CALL(model, child_sort, compare); | ||
4328 | _eina_model_event_callback_call | ||
4329 | (model, _eina_model_str_children_changed, NULL); | ||
4330 | return EINA_TRUE; | ||
4331 | } | ||
4332 | |||
4333 | EAPI Eina_Iterator * | ||
4334 | eina_model_child_iterator_get(Eina_Model *model) | ||
4335 | { | ||
4336 | int count; | ||
4337 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4338 | count = eina_model_child_count(model); | ||
4339 | if (count < 0) | ||
4340 | return NULL; | ||
4341 | EINA_MODEL_TYPE_CALL_RETURN(model, child_iterator_get, NULL, 0, count); | ||
4342 | } | ||
4343 | |||
4344 | EAPI Eina_Iterator * | ||
4345 | eina_model_child_slice_iterator_get(Eina_Model *model, unsigned int start, unsigned int count) | ||
4346 | { | ||
4347 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4348 | EINA_MODEL_TYPE_CALL_RETURN(model, child_iterator_get, NULL, start, count); | ||
4349 | } | ||
4350 | |||
4351 | EAPI Eina_Iterator * | ||
4352 | eina_model_child_reversed_iterator_get(Eina_Model *model) | ||
4353 | { | ||
4354 | int count; | ||
4355 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4356 | count = eina_model_child_count(model); | ||
4357 | if (count < 0) | ||
4358 | return NULL; | ||
4359 | EINA_MODEL_TYPE_CALL_RETURN(model, child_reversed_iterator_get, NULL, | ||
4360 | 0, count); | ||
4361 | } | ||
4362 | |||
4363 | EAPI Eina_Iterator * | ||
4364 | eina_model_child_slice_reversed_iterator_get(Eina_Model *model, unsigned int start, unsigned int count) | ||
4365 | { | ||
4366 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4367 | EINA_MODEL_TYPE_CALL_RETURN(model, child_reversed_iterator_get, NULL, | ||
4368 | start, count); | ||
4369 | } | ||
4370 | |||
4371 | EAPI Eina_Iterator * | ||
4372 | eina_model_child_sorted_iterator_get(Eina_Model *model, Eina_Compare_Cb compare) | ||
4373 | { | ||
4374 | int count; | ||
4375 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4376 | EINA_SAFETY_ON_NULL_RETURN_VAL(compare, NULL); | ||
4377 | count = eina_model_child_count(model); | ||
4378 | if (count < 0) | ||
4379 | return NULL; | ||
4380 | EINA_MODEL_TYPE_CALL_RETURN(model, child_sorted_iterator_get, NULL, | ||
4381 | 0, count, compare); | ||
4382 | } | ||
4383 | |||
4384 | EAPI Eina_Iterator * | ||
4385 | eina_model_child_slice_sorted_iterator_get(Eina_Model *model, unsigned int start, unsigned int count, Eina_Compare_Cb compare) | ||
4386 | { | ||
4387 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4388 | EINA_SAFETY_ON_NULL_RETURN_VAL(compare, NULL); | ||
4389 | EINA_MODEL_TYPE_CALL_RETURN(model, child_sorted_iterator_get, NULL, | ||
4390 | start, count, compare); | ||
4391 | } | ||
4392 | |||
4393 | EAPI Eina_Iterator * | ||
4394 | eina_model_child_filtered_iterator_get(Eina_Model *model, Eina_Each_Cb match, const void *data) | ||
4395 | { | ||
4396 | int count; | ||
4397 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4398 | EINA_SAFETY_ON_NULL_RETURN_VAL(match, NULL); | ||
4399 | count = eina_model_child_count(model); | ||
4400 | if (count < 0) | ||
4401 | return NULL; | ||
4402 | EINA_MODEL_TYPE_CALL_RETURN(model, child_filtered_iterator_get, NULL, | ||
4403 | 0, count, match, data); | ||
4404 | } | ||
4405 | |||
4406 | EAPI Eina_Iterator * | ||
4407 | eina_model_child_slice_filtered_iterator_get(Eina_Model *model, unsigned int start, unsigned int count, Eina_Each_Cb match, const void *data) | ||
4408 | { | ||
4409 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4410 | EINA_SAFETY_ON_NULL_RETURN_VAL(match, NULL); | ||
4411 | EINA_MODEL_TYPE_CALL_RETURN(model, child_filtered_iterator_get, NULL, | ||
4412 | start, count, match, data); | ||
4413 | } | ||
4414 | |||
4415 | EAPI char * | ||
4416 | eina_model_to_string(const Eina_Model *model) | ||
4417 | { | ||
4418 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4419 | EINA_MODEL_TYPE_CALL_RETURN(model, to_string, NULL); | ||
4420 | } | ||
4421 | |||
4422 | /* type functions *****************************************************/ | ||
4423 | |||
4424 | EAPI Eina_Bool | ||
4425 | eina_model_type_check(const Eina_Model_Type *type) | ||
4426 | { | ||
4427 | EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE); | ||
4428 | return _eina_model_type_check(type); | ||
4429 | } | ||
4430 | |||
4431 | EAPI const char * | ||
4432 | eina_model_type_name_get(const Eina_Model_Type *type) | ||
4433 | { | ||
4434 | EINA_SAFETY_ON_NULL_RETURN_VAL(type, NULL); | ||
4435 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_type_check(type), NULL); | ||
4436 | return type->name; | ||
4437 | } | ||
4438 | |||
4439 | EAPI const Eina_Model_Type * | ||
4440 | eina_model_type_parent_get(const Eina_Model_Type *type) | ||
4441 | { | ||
4442 | EINA_SAFETY_ON_NULL_RETURN_VAL(type, NULL); | ||
4443 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_type_check(type), NULL); | ||
4444 | return type->parent; | ||
4445 | } | ||
4446 | |||
4447 | #define EINA_MODEL_TYPE_INSTANCE_CHECK(type, model) \ | ||
4448 | EINA_SAFETY_ON_NULL_RETURN(type); \ | ||
4449 | EINA_SAFETY_ON_FALSE_RETURN(_eina_model_type_check(type)); \ | ||
4450 | EINA_MODEL_INSTANCE_CHECK(model); \ | ||
4451 | EINA_SAFETY_ON_FALSE_RETURN(_eina_model_instance_check(model, type)); | ||
4452 | |||
4453 | #define EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, retval) \ | ||
4454 | EINA_SAFETY_ON_NULL_RETURN_VAL(type, retval); \ | ||
4455 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_type_check(type), retval); \ | ||
4456 | EINA_MODEL_INSTANCE_CHECK_VAL(model, retval); \ | ||
4457 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_instance_check(model, type), retval); | ||
4458 | |||
4459 | EAPI Eina_Bool | ||
4460 | eina_model_type_constructor(const Eina_Model_Type *type, Eina_Model *model) | ||
4461 | { | ||
4462 | Eina_Bool (*constructor)(Eina_Model *); | ||
4463 | |||
4464 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, EINA_FALSE); | ||
4465 | |||
4466 | constructor = _eina_model_type_find_offset | ||
4467 | (type, offsetof(Eina_Model_Type, constructor)); | ||
4468 | EINA_SAFETY_ON_NULL_RETURN_VAL(constructor, EINA_FALSE); | ||
4469 | |||
4470 | return constructor(model); | ||
4471 | } | ||
4472 | |||
4473 | EAPI Eina_Bool | ||
4474 | eina_model_type_destructor(const Eina_Model_Type *type, Eina_Model *model) | ||
4475 | { | ||
4476 | Eina_Bool (*destructor)(Eina_Model *); | ||
4477 | |||
4478 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, EINA_FALSE); | ||
4479 | |||
4480 | destructor = _eina_model_type_find_offset | ||
4481 | (type, offsetof(Eina_Model_Type, destructor)); | ||
4482 | EINA_SAFETY_ON_NULL_RETURN_VAL(destructor, EINA_FALSE); | ||
4483 | |||
4484 | return destructor(model); | ||
4485 | } | ||
4486 | |||
4487 | EAPI Eina_Bool | ||
4488 | eina_model_type_copy(const Eina_Model_Type *type, const Eina_Model *src, Eina_Model *dst) | ||
4489 | { | ||
4490 | Eina_Bool (*copy)(const Eina_Model *, Eina_Model *); | ||
4491 | |||
4492 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, src, EINA_FALSE); | ||
4493 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, dst, EINA_FALSE); | ||
4494 | |||
4495 | copy = _eina_model_type_find_offset | ||
4496 | (type, offsetof(Eina_Model_Type, copy)); | ||
4497 | EINA_SAFETY_ON_NULL_RETURN_VAL(copy, EINA_FALSE); | ||
4498 | |||
4499 | return copy(src, dst); | ||
4500 | } | ||
4501 | |||
4502 | EAPI Eina_Bool | ||
4503 | eina_model_type_deep_copy(const Eina_Model_Type *type, const Eina_Model *src, Eina_Model *dst) | ||
4504 | { | ||
4505 | Eina_Bool (*deep_copy)(const Eina_Model *, Eina_Model *); | ||
4506 | |||
4507 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, src, EINA_FALSE); | ||
4508 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, dst, EINA_FALSE); | ||
4509 | |||
4510 | deep_copy = _eina_model_type_find_offset | ||
4511 | (type, offsetof(Eina_Model_Type, deep_copy)); | ||
4512 | EINA_SAFETY_ON_NULL_RETURN_VAL(deep_copy, EINA_FALSE); | ||
4513 | |||
4514 | return deep_copy(src, dst); | ||
4515 | } | ||
4516 | |||
4517 | EAPI Eina_Bool | ||
4518 | eina_model_type_compare(const Eina_Model_Type *type, const Eina_Model *a, const Eina_Model *b, int *cmp) | ||
4519 | { | ||
4520 | Eina_Bool (*compare)(const Eina_Model *, const Eina_Model *, int *); | ||
4521 | |||
4522 | EINA_SAFETY_ON_NULL_RETURN_VAL(cmp, EINA_FALSE); | ||
4523 | *cmp = 0; | ||
4524 | |||
4525 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, a, EINA_FALSE); | ||
4526 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, b, EINA_FALSE); | ||
4527 | |||
4528 | compare = _eina_model_type_find_offset | ||
4529 | (type, offsetof(Eina_Model_Type, compare)); | ||
4530 | EINA_SAFETY_ON_NULL_RETURN_VAL(compare, EINA_FALSE); | ||
4531 | |||
4532 | return compare(a, b, cmp); | ||
4533 | } | ||
4534 | |||
4535 | EAPI Eina_Bool | ||
4536 | eina_model_type_load(const Eina_Model_Type *type, Eina_Model *model) | ||
4537 | { | ||
4538 | Eina_Bool (*load)(Eina_Model *); | ||
4539 | |||
4540 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, EINA_FALSE); | ||
4541 | |||
4542 | load = _eina_model_type_find_offset | ||
4543 | (type, offsetof(Eina_Model_Type, load)); | ||
4544 | EINA_SAFETY_ON_NULL_RETURN_VAL(load, EINA_FALSE); | ||
4545 | |||
4546 | return load(model); | ||
4547 | } | ||
4548 | |||
4549 | EAPI Eina_Bool | ||
4550 | eina_model_type_unload(const Eina_Model_Type *type, Eina_Model *model) | ||
4551 | { | ||
4552 | Eina_Bool (*unload)(Eina_Model *); | ||
4553 | |||
4554 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, EINA_FALSE); | ||
4555 | |||
4556 | unload = _eina_model_type_find_offset | ||
4557 | (type, offsetof(Eina_Model_Type, unload)); | ||
4558 | EINA_SAFETY_ON_NULL_RETURN_VAL(unload, EINA_FALSE); | ||
4559 | |||
4560 | return unload(model); | ||
4561 | } | ||
4562 | |||
4563 | EAPI Eina_Bool | ||
4564 | eina_model_type_property_get(const Eina_Model_Type *type, const Eina_Model *model, const char *name, Eina_Value *value) | ||
4565 | { | ||
4566 | Eina_Bool (*property_get)(const Eina_Model *, const char *, Eina_Value *); | ||
4567 | |||
4568 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); | ||
4569 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); | ||
4570 | |||
4571 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, EINA_FALSE); | ||
4572 | |||
4573 | property_get = _eina_model_type_find_offset | ||
4574 | (type, offsetof(Eina_Model_Type, property_get)); | ||
4575 | EINA_SAFETY_ON_NULL_RETURN_VAL(property_get, EINA_FALSE); | ||
4576 | |||
4577 | return property_get(model, name, value); | ||
4578 | } | ||
4579 | |||
4580 | EAPI Eina_Bool | ||
4581 | eina_model_type_property_set(const Eina_Model_Type *type, Eina_Model *model, const char *name, const Eina_Value *value) | ||
4582 | { | ||
4583 | Eina_Bool (*property_set)(Eina_Model *, const char *, const Eina_Value *); | ||
4584 | |||
4585 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); | ||
4586 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); | ||
4587 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), EINA_FALSE); | ||
4588 | |||
4589 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, EINA_FALSE); | ||
4590 | |||
4591 | property_set = _eina_model_type_find_offset | ||
4592 | (type, offsetof(Eina_Model_Type, property_set)); | ||
4593 | EINA_SAFETY_ON_NULL_RETURN_VAL(property_set, EINA_FALSE); | ||
4594 | |||
4595 | return property_set(model, name, value); | ||
4596 | } | ||
4597 | |||
4598 | EAPI Eina_Bool | ||
4599 | eina_model_type_property_del(const Eina_Model_Type *type, Eina_Model *model, const char *name) | ||
4600 | { | ||
4601 | Eina_Bool (*property_del)(const Eina_Model *, const char *); | ||
4602 | |||
4603 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); | ||
4604 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, EINA_FALSE); | ||
4605 | |||
4606 | property_del = _eina_model_type_find_offset | ||
4607 | (type, offsetof(Eina_Model_Type, property_del)); | ||
4608 | EINA_SAFETY_ON_NULL_RETURN_VAL(property_del, EINA_FALSE); | ||
4609 | |||
4610 | return property_del(model, name); | ||
4611 | } | ||
4612 | |||
4613 | EAPI Eina_List * | ||
4614 | eina_model_type_properties_names_list_get(const Eina_Model_Type *type, const Eina_Model *model) | ||
4615 | { | ||
4616 | Eina_List *(*properties_names_list_get)(const Eina_Model *); | ||
4617 | |||
4618 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, NULL); | ||
4619 | |||
4620 | properties_names_list_get = _eina_model_type_find_offset | ||
4621 | (type, offsetof(Eina_Model_Type, properties_names_list_get)); | ||
4622 | EINA_SAFETY_ON_NULL_RETURN_VAL(properties_names_list_get, NULL); | ||
4623 | |||
4624 | return properties_names_list_get(model); | ||
4625 | } | ||
4626 | |||
4627 | EAPI int | ||
4628 | eina_model_type_child_count(const Eina_Model_Type *type, const Eina_Model *model) | ||
4629 | { | ||
4630 | int (*child_count)(const Eina_Model *); | ||
4631 | |||
4632 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, -1); | ||
4633 | |||
4634 | child_count = _eina_model_type_find_offset | ||
4635 | (type, offsetof(Eina_Model_Type, child_count)); | ||
4636 | EINA_SAFETY_ON_NULL_RETURN_VAL(child_count, -1); | ||
4637 | |||
4638 | return child_count(model); | ||
4639 | } | ||
4640 | |||
4641 | EAPI Eina_Model * | ||
4642 | eina_model_type_child_get(const Eina_Model_Type *type, const Eina_Model *model, unsigned int position) | ||
4643 | { | ||
4644 | Eina_Model *(*child_get)(const Eina_Model *, unsigned int); | ||
4645 | |||
4646 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, NULL); | ||
4647 | |||
4648 | child_get = _eina_model_type_find_offset | ||
4649 | (type, offsetof(Eina_Model_Type, child_get)); | ||
4650 | EINA_SAFETY_ON_NULL_RETURN_VAL(child_get, NULL); | ||
4651 | |||
4652 | return child_get(model, position); | ||
4653 | } | ||
4654 | |||
4655 | EAPI Eina_Bool | ||
4656 | eina_model_type_child_set(const Eina_Model_Type *type, Eina_Model *model, unsigned int position, Eina_Model *child) | ||
4657 | { | ||
4658 | Eina_Bool (*child_set)(Eina_Model *, unsigned int, Eina_Model *); | ||
4659 | |||
4660 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, EINA_FALSE); | ||
4661 | EINA_MODEL_INSTANCE_CHECK_VAL(child, EINA_FALSE); | ||
4662 | |||
4663 | child_set = _eina_model_type_find_offset | ||
4664 | (type, offsetof(Eina_Model_Type, child_set)); | ||
4665 | EINA_SAFETY_ON_NULL_RETURN_VAL(child_set, EINA_FALSE); | ||
4666 | |||
4667 | return child_set(model, position, child); | ||
4668 | } | ||
4669 | |||
4670 | EAPI Eina_Bool | ||
4671 | eina_model_type_child_del(const Eina_Model_Type *type, Eina_Model *model, unsigned int position) | ||
4672 | { | ||
4673 | Eina_Bool (*child_del)(Eina_Model *, unsigned int); | ||
4674 | |||
4675 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, EINA_FALSE); | ||
4676 | |||
4677 | child_del = _eina_model_type_find_offset | ||
4678 | (type, offsetof(Eina_Model_Type, child_del)); | ||
4679 | EINA_SAFETY_ON_NULL_RETURN_VAL(child_del, EINA_FALSE); | ||
4680 | |||
4681 | return child_del(model, position); | ||
4682 | } | ||
4683 | |||
4684 | EAPI Eina_Bool | ||
4685 | eina_model_type_child_insert_at(const Eina_Model_Type *type, Eina_Model *model, unsigned int position, Eina_Model *child) | ||
4686 | { | ||
4687 | Eina_Bool (*child_insert_at)(Eina_Model *, unsigned int, Eina_Model *); | ||
4688 | |||
4689 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, EINA_FALSE); | ||
4690 | EINA_MODEL_INSTANCE_CHECK_VAL(child, EINA_FALSE); | ||
4691 | |||
4692 | child_insert_at = _eina_model_type_find_offset | ||
4693 | (type, offsetof(Eina_Model_Type, child_insert_at)); | ||
4694 | EINA_SAFETY_ON_NULL_RETURN_VAL(child_insert_at, EINA_FALSE); | ||
4695 | |||
4696 | return child_insert_at(model, position, child); | ||
4697 | } | ||
4698 | |||
4699 | EAPI int | ||
4700 | eina_model_type_child_find(const Eina_Model_Type *type, const Eina_Model *model, unsigned int start_position, const Eina_Model *other) | ||
4701 | { | ||
4702 | int (*child_find)(const Eina_Model *, unsigned int, const Eina_Model *); | ||
4703 | |||
4704 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, -1); | ||
4705 | EINA_MODEL_INSTANCE_CHECK_VAL(other, -1); | ||
4706 | |||
4707 | child_find = _eina_model_type_find_offset | ||
4708 | (type, offsetof(Eina_Model_Type, child_find)); | ||
4709 | EINA_SAFETY_ON_NULL_RETURN_VAL(child_find, -1); | ||
4710 | |||
4711 | return child_find(model, start_position, other); | ||
4712 | } | ||
4713 | |||
4714 | EAPI int | ||
4715 | eina_model_type_child_criteria_match(const Eina_Model_Type *type, const Eina_Model *model, unsigned int start_position, Eina_Each_Cb match, const void *data) | ||
4716 | { | ||
4717 | int (*child_criteria_match)(const Eina_Model *, unsigned int, Eina_Each_Cb, const void *); | ||
4718 | |||
4719 | EINA_SAFETY_ON_NULL_RETURN_VAL(match, -1); | ||
4720 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, -1); | ||
4721 | |||
4722 | child_criteria_match = _eina_model_type_find_offset | ||
4723 | (type, offsetof(Eina_Model_Type, child_criteria_match)); | ||
4724 | EINA_SAFETY_ON_NULL_RETURN_VAL(child_criteria_match, -1); | ||
4725 | |||
4726 | return child_criteria_match(model, start_position, match, data); | ||
4727 | } | ||
4728 | |||
4729 | EAPI void | ||
4730 | eina_model_type_child_sort(const Eina_Model_Type *type, Eina_Model *model, Eina_Compare_Cb compare) | ||
4731 | { | ||
4732 | void (*child_sort)(Eina_Model *, Eina_Compare_Cb); | ||
4733 | |||
4734 | EINA_SAFETY_ON_NULL_RETURN(compare); | ||
4735 | EINA_MODEL_TYPE_INSTANCE_CHECK(type, model); | ||
4736 | |||
4737 | child_sort = _eina_model_type_find_offset | ||
4738 | (type, offsetof(Eina_Model_Type, child_sort)); | ||
4739 | EINA_SAFETY_ON_NULL_RETURN(child_sort); | ||
4740 | |||
4741 | return child_sort(model, compare); | ||
4742 | } | ||
4743 | |||
4744 | EAPI Eina_Iterator * | ||
4745 | eina_model_type_child_iterator_get(const Eina_Model_Type *type, Eina_Model *model, unsigned int start, unsigned int count) | ||
4746 | { | ||
4747 | Eina_Iterator *(*child_iterator_get)(const Eina_Model *, unsigned int, unsigned int); | ||
4748 | |||
4749 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, NULL); | ||
4750 | |||
4751 | child_iterator_get = _eina_model_type_find_offset | ||
4752 | (type, offsetof(Eina_Model_Type, child_iterator_get)); | ||
4753 | EINA_SAFETY_ON_NULL_RETURN_VAL(child_iterator_get, NULL); | ||
4754 | |||
4755 | return child_iterator_get(model, start, count); | ||
4756 | } | ||
4757 | |||
4758 | EAPI Eina_Iterator * | ||
4759 | eina_model_type_child_reversed_iterator_get(const Eina_Model_Type *type, Eina_Model *model, unsigned int start, unsigned int count) | ||
4760 | { | ||
4761 | Eina_Iterator *(*child_reversed_iterator_get)(const Eina_Model *, unsigned int, unsigned int); | ||
4762 | |||
4763 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, NULL); | ||
4764 | |||
4765 | child_reversed_iterator_get = _eina_model_type_find_offset | ||
4766 | (type, offsetof(Eina_Model_Type, child_reversed_iterator_get)); | ||
4767 | EINA_SAFETY_ON_NULL_RETURN_VAL(child_reversed_iterator_get, NULL); | ||
4768 | |||
4769 | return child_reversed_iterator_get(model, start, count); | ||
4770 | } | ||
4771 | |||
4772 | EAPI Eina_Iterator * | ||
4773 | eina_model_type_child_sorted_iterator_get(const Eina_Model_Type *type, Eina_Model *model, unsigned int start, unsigned int count, Eina_Compare_Cb compare) | ||
4774 | { | ||
4775 | Eina_Iterator *(*child_sorted_iterator_get)(const Eina_Model *, unsigned int, unsigned int, Eina_Compare_Cb); | ||
4776 | |||
4777 | EINA_SAFETY_ON_NULL_RETURN_VAL(compare, NULL); | ||
4778 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, NULL); | ||
4779 | |||
4780 | child_sorted_iterator_get = _eina_model_type_find_offset | ||
4781 | (type, offsetof(Eina_Model_Type, child_sorted_iterator_get)); | ||
4782 | EINA_SAFETY_ON_NULL_RETURN_VAL(child_sorted_iterator_get, NULL); | ||
4783 | |||
4784 | return child_sorted_iterator_get(model, start, count, compare); | ||
4785 | } | ||
4786 | |||
4787 | EAPI Eina_Iterator * | ||
4788 | eina_model_type_child_filtered_iterator_get(const Eina_Model_Type *type, Eina_Model *model, unsigned int start, unsigned int count, Eina_Each_Cb match, const void *data) | ||
4789 | { | ||
4790 | Eina_Iterator *(*child_filtered_iterator_get)(const Eina_Model *, unsigned int, unsigned int, Eina_Each_Cb, const void *); | ||
4791 | |||
4792 | EINA_SAFETY_ON_NULL_RETURN_VAL(match, NULL); | ||
4793 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, NULL); | ||
4794 | |||
4795 | child_filtered_iterator_get = _eina_model_type_find_offset | ||
4796 | (type, offsetof(Eina_Model_Type, child_filtered_iterator_get)); | ||
4797 | EINA_SAFETY_ON_NULL_RETURN_VAL(child_filtered_iterator_get, NULL); | ||
4798 | |||
4799 | return child_filtered_iterator_get(model, start, count, match, data); | ||
4800 | } | ||
4801 | |||
4802 | EAPI char * | ||
4803 | eina_model_type_to_string(const Eina_Model_Type *type, const Eina_Model *model) | ||
4804 | { | ||
4805 | char *(*to_string)(const Eina_Model *); | ||
4806 | |||
4807 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, NULL); | ||
4808 | |||
4809 | to_string = _eina_model_type_find_offset | ||
4810 | (type, offsetof(Eina_Model_Type, to_string)); | ||
4811 | EINA_SAFETY_ON_NULL_RETURN_VAL(to_string, NULL); | ||
4812 | |||
4813 | return to_string(model); | ||
4814 | } | ||
4815 | |||
4816 | EAPI Eina_Bool | ||
4817 | eina_model_type_subclass_setup(Eina_Model_Type *type, const Eina_Model_Type *parent) | ||
4818 | { | ||
4819 | EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE); | ||
4820 | EINA_SAFETY_ON_NULL_RETURN_VAL(parent, EINA_FALSE); | ||
4821 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_type_check(parent), EINA_FALSE); | ||
4822 | EINA_SAFETY_ON_FALSE_RETURN_VAL(type->version == EINA_MODEL_TYPE_VERSION, | ||
4823 | EINA_FALSE); | ||
4824 | |||
4825 | type->parent = parent; | ||
4826 | type->type_size = parent->type_size; | ||
4827 | type->interfaces = NULL; | ||
4828 | type->events = NULL; | ||
4829 | |||
4830 | type->setup = NULL; | ||
4831 | type->flush = NULL; | ||
4832 | type->constructor = NULL; | ||
4833 | type->destructor = NULL; | ||
4834 | type->copy = NULL; | ||
4835 | type->deep_copy = NULL; | ||
4836 | type->compare = NULL; | ||
4837 | type->load = NULL; | ||
4838 | type->unload = NULL; | ||
4839 | type->property_get = NULL; | ||
4840 | type->property_set = NULL; | ||
4841 | type->property_del = NULL; | ||
4842 | type->properties_names_list_get = NULL; | ||
4843 | type->child_count = NULL; | ||
4844 | type->child_get = NULL; | ||
4845 | type->child_set = NULL; | ||
4846 | type->child_del = NULL; | ||
4847 | type->child_insert_at = NULL; | ||
4848 | type->child_find = NULL; | ||
4849 | type->child_criteria_match = NULL; | ||
4850 | type->child_sort = NULL; | ||
4851 | type->child_iterator_get = NULL; | ||
4852 | type->child_reversed_iterator_get = NULL; | ||
4853 | type->child_sorted_iterator_get = NULL; | ||
4854 | type->child_filtered_iterator_get = NULL; | ||
4855 | type->to_string = NULL; | ||
4856 | type->__extension_ptr0 = NULL; | ||
4857 | type->__extension_ptr1 = NULL; | ||
4858 | type->__extension_ptr2 = NULL; | ||
4859 | type->__extension_ptr3 = NULL; | ||
4860 | |||
4861 | if (type->type_size > sizeof(Eina_Model_Type)) | ||
4862 | { | ||
4863 | unsigned char *p = (unsigned char *)type; | ||
4864 | p += sizeof(Eina_Model_Type); | ||
4865 | memset(p, 0, type->type_size - sizeof(Eina_Model_Type)); | ||
4866 | } | ||
4867 | |||
4868 | return EINA_TRUE; | ||
4869 | } | ||
4870 | |||
4871 | EAPI Eina_Bool | ||
4872 | eina_model_type_subclass_check(const Eina_Model_Type *type, const Eina_Model_Type *self_or_parent) | ||
4873 | { | ||
4874 | EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE); | ||
4875 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_type_check(type), EINA_FALSE); | ||
4876 | EINA_SAFETY_ON_NULL_RETURN_VAL(self_or_parent, EINA_FALSE); | ||
4877 | |||
4878 | for (; type != NULL; type = type->parent) | ||
4879 | { | ||
4880 | if (type == self_or_parent) | ||
4881 | return EINA_TRUE; | ||
4882 | } | ||
4883 | |||
4884 | return EINA_FALSE; | ||
4885 | } | ||
4886 | |||
4887 | static inline const Eina_Model_Interface * | ||
4888 | _eina_model_type_interface_get(const Eina_Model_Type *type, const char *name, Eina_Bool ptr_cmp __UNUSED__) | ||
4889 | { | ||
4890 | const Eina_Model_Interface **itr; | ||
4891 | |||
4892 | if (!type) | ||
4893 | return NULL; | ||
4894 | |||
4895 | if (!type->interfaces) | ||
4896 | return _eina_model_type_interface_get(type->parent, name, ptr_cmp); | ||
4897 | |||
4898 | { | ||
4899 | for (itr = type->interfaces ; itr != NULL ; itr++) | ||
4900 | if (strcmp((*itr)->name, name) == 0) | ||
4901 | return *itr; | ||
4902 | } | ||
4903 | |||
4904 | return NULL; | ||
4905 | } | ||
4906 | |||
4907 | static inline Eina_Bool | ||
4908 | _eina_model_interface_check(const Eina_Model_Interface *iface) | ||
4909 | { | ||
4910 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
4911 | (iface->version == EINA_MODEL_INTERFACE_VERSION, EINA_FALSE); | ||
4912 | return EINA_TRUE; | ||
4913 | } | ||
4914 | |||
4915 | EAPI const Eina_Model_Interface * | ||
4916 | eina_model_type_interface_get(const Eina_Model_Type *type, const char *name) | ||
4917 | { | ||
4918 | const Eina_Model_Interface *iface; | ||
4919 | |||
4920 | EINA_SAFETY_ON_NULL_RETURN_VAL(type, NULL); | ||
4921 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_type_check(type), NULL); | ||
4922 | |||
4923 | /* search for pointer, make speed-aware users fast */ | ||
4924 | iface = _eina_model_type_interface_get(type, name, EINA_TRUE); | ||
4925 | |||
4926 | if (!iface) | ||
4927 | { | ||
4928 | /* search using strcmp(), slow users don't care */ | ||
4929 | iface = _eina_model_type_interface_get(type, name, EINA_FALSE); | ||
4930 | } | ||
4931 | else if (!_eina_model_interface_check(iface)) | ||
4932 | iface = NULL; | ||
4933 | |||
4934 | return iface; | ||
4935 | } | ||
4936 | |||
4937 | EAPI void * | ||
4938 | eina_model_type_private_data_get(const Eina_Model *model, const Eina_Model_Type *type) | ||
4939 | { | ||
4940 | const Eina_Model_Description *desc; | ||
4941 | unsigned int i; | ||
4942 | |||
4943 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4944 | EINA_SAFETY_ON_NULL_RETURN_VAL(type, NULL); | ||
4945 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_type_check(type), NULL); | ||
4946 | |||
4947 | desc = model->desc; | ||
4948 | |||
4949 | for (i = 0; i < desc->total.types; i++) | ||
4950 | if (desc->cache.types[i] == type) | ||
4951 | return model->privates[i]; | ||
4952 | |||
4953 | CRITICAL("Model %p (%s) is not an instance of type %p (%s)", | ||
4954 | model, desc->cache.types[0]->name, | ||
4955 | type, type->name); | ||
4956 | return NULL; | ||
4957 | } | ||
4958 | |||
4959 | EAPI const void * | ||
4960 | eina_model_method_offset_resolve(const Eina_Model *model, unsigned int offset) | ||
4961 | { | ||
4962 | const Eina_Model_Description *desc; | ||
4963 | |||
4964 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
4965 | EINA_SAFETY_ON_FALSE_RETURN_VAL(offset >= sizeof(Eina_Model_Type), NULL); | ||
4966 | EINA_SAFETY_ON_FALSE_RETURN_VAL(offset % sizeof(void *) == 0, NULL); | ||
4967 | |||
4968 | desc = model->desc; | ||
4969 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
4970 | (offset + sizeof(void *) <= desc->cache.types[0]->type_size, NULL); | ||
4971 | |||
4972 | offset -= sizeof(Eina_Model_Type); | ||
4973 | offset /= sizeof(void *); | ||
4974 | return desc->ops.type.extension[offset]; | ||
4975 | } | ||
4976 | |||
4977 | EAPI const void * | ||
4978 | eina_model_type_method_offset_resolve(const Eina_Model_Type *type, const Eina_Model *model, unsigned int offset) | ||
4979 | { | ||
4980 | const Eina_Model_Description *desc; | ||
4981 | |||
4982 | EINA_MODEL_TYPE_INSTANCE_CHECK_VAL(type, model, NULL); | ||
4983 | EINA_SAFETY_ON_FALSE_RETURN_VAL(offset >= sizeof(Eina_Model_Type), NULL); | ||
4984 | EINA_SAFETY_ON_FALSE_RETURN_VAL(offset % sizeof(void *) == 0, NULL); | ||
4985 | |||
4986 | desc = model->desc; | ||
4987 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
4988 | (offset + sizeof(void *) <= desc->cache.types[0]->type_size, NULL); | ||
4989 | |||
4990 | return _eina_model_type_find_offset(type, offset); | ||
4991 | } | ||
4992 | |||
4993 | /* interface functions ************************************************/ | ||
4994 | |||
4995 | EAPI Eina_Bool | ||
4996 | eina_model_interface_check(const Eina_Model_Interface *iface) | ||
4997 | { | ||
4998 | EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE); | ||
4999 | return _eina_model_interface_check(iface); | ||
5000 | } | ||
5001 | |||
5002 | EAPI void * | ||
5003 | eina_model_interface_private_data_get(const Eina_Model *model, const Eina_Model_Interface *iface) | ||
5004 | { | ||
5005 | const Eina_Model_Description *desc; | ||
5006 | unsigned int i; | ||
5007 | |||
5008 | EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL); | ||
5009 | EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL); | ||
5010 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_interface_check(iface), NULL); | ||
5011 | |||
5012 | desc = model->desc; | ||
5013 | |||
5014 | for (i = 0; i < desc->total.ifaces; i++) | ||
5015 | if (desc->cache.ifaces[i] == iface) | ||
5016 | return model->privates[desc->total.types + i]; | ||
5017 | |||
5018 | CRITICAL("Model %p (%s) does not implement interface %p (%s)", | ||
5019 | model, desc->cache.types[0]->name, | ||
5020 | iface, iface->name); | ||
5021 | return NULL; | ||
5022 | } | ||
5023 | |||
5024 | static Eina_Bool | ||
5025 | _eina_model_interface_implemented(const Eina_Model *model, const Eina_Model_Interface *iface) | ||
5026 | { | ||
5027 | const Eina_Model_Interface **itr, **itr_end; | ||
5028 | |||
5029 | itr = model->desc->cache.ifaces; | ||
5030 | itr_end = itr + model->desc->total.ifaces; | ||
5031 | |||
5032 | for (; itr < itr_end; itr++) | ||
5033 | if (*itr == iface) | ||
5034 | return EINA_TRUE; | ||
5035 | |||
5036 | return EINA_FALSE; | ||
5037 | } | ||
5038 | |||
5039 | EAPI Eina_Bool | ||
5040 | eina_model_interface_implemented(const Eina_Model *model, const Eina_Model_Interface *iface) | ||
5041 | { | ||
5042 | EINA_MODEL_INSTANCE_CHECK_VAL(model, EINA_FALSE); | ||
5043 | EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE); | ||
5044 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_interface_check(iface), | ||
5045 | EINA_FALSE); | ||
5046 | return _eina_model_interface_implemented(model, iface); | ||
5047 | } | ||
5048 | |||
5049 | #define EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK(iface, model) \ | ||
5050 | EINA_SAFETY_ON_NULL_RETURN(iface); \ | ||
5051 | EINA_SAFETY_ON_FALSE_RETURN(_eina_model_interface_check(iface)); \ | ||
5052 | EINA_MODEL_INSTANCE_CHECK(model); \ | ||
5053 | EINA_SAFETY_ON_FALSE_RETURN(_eina_model_interface_implemented(model, iface)); | ||
5054 | |||
5055 | #define EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, retval) \ | ||
5056 | EINA_SAFETY_ON_NULL_RETURN_VAL(iface, retval); \ | ||
5057 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_interface_check(iface), retval); \ | ||
5058 | EINA_MODEL_INSTANCE_CHECK_VAL(model, retval); \ | ||
5059 | EINA_SAFETY_ON_FALSE_RETURN_VAL(_eina_model_interface_implemented(model, iface), retval); | ||
5060 | |||
5061 | |||
5062 | EAPI Eina_Bool | ||
5063 | eina_model_interface_constructor(const Eina_Model_Interface *iface, Eina_Model *model) | ||
5064 | { | ||
5065 | Eina_Bool (*constructor)(Eina_Model *); | ||
5066 | |||
5067 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE); | ||
5068 | |||
5069 | constructor = _eina_model_interface_find_offset | ||
5070 | (iface, offsetof(Eina_Model_Interface, constructor)); | ||
5071 | EINA_SAFETY_ON_NULL_RETURN_VAL(constructor, EINA_FALSE); | ||
5072 | return constructor(model); | ||
5073 | } | ||
5074 | |||
5075 | EAPI Eina_Bool | ||
5076 | eina_model_interface_destructor(const Eina_Model_Interface *iface, Eina_Model *model) | ||
5077 | { | ||
5078 | Eina_Bool (*destructor)(Eina_Model *); | ||
5079 | |||
5080 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE); | ||
5081 | |||
5082 | destructor = _eina_model_interface_find_offset | ||
5083 | (iface, offsetof(Eina_Model_Interface, destructor)); | ||
5084 | EINA_SAFETY_ON_NULL_RETURN_VAL(destructor, EINA_FALSE); | ||
5085 | return destructor(model); | ||
5086 | } | ||
5087 | |||
5088 | EAPI Eina_Bool | ||
5089 | eina_model_interface_copy(const Eina_Model_Interface *iface, const Eina_Model *src, Eina_Model *dst) | ||
5090 | { | ||
5091 | Eina_Bool (*copy)(const Eina_Model *, Eina_Model *); | ||
5092 | |||
5093 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, src, EINA_FALSE); | ||
5094 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, dst, EINA_FALSE); | ||
5095 | |||
5096 | copy = _eina_model_interface_find_offset | ||
5097 | (iface, offsetof(Eina_Model_Interface, copy)); | ||
5098 | EINA_SAFETY_ON_NULL_RETURN_VAL(copy, EINA_FALSE); | ||
5099 | return copy(src, dst); | ||
5100 | } | ||
5101 | |||
5102 | EAPI Eina_Bool | ||
5103 | eina_model_interface_deep_copy(const Eina_Model_Interface *iface, const Eina_Model *src, Eina_Model *dst) | ||
5104 | { | ||
5105 | Eina_Bool (*deep_copy)(const Eina_Model *, Eina_Model *); | ||
5106 | |||
5107 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, src, EINA_FALSE); | ||
5108 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, dst, EINA_FALSE); | ||
5109 | |||
5110 | deep_copy = _eina_model_interface_find_offset | ||
5111 | (iface, offsetof(Eina_Model_Interface, deep_copy)); | ||
5112 | EINA_SAFETY_ON_NULL_RETURN_VAL(deep_copy, EINA_FALSE); | ||
5113 | return deep_copy(src, dst); | ||
5114 | } | ||
5115 | |||
5116 | EAPI const void | ||
5117 | *eina_model_interface_method_offset_resolve(const Eina_Model_Interface *iface, const Eina_Model *model, unsigned int offset) | ||
5118 | { | ||
5119 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, NULL); | ||
5120 | EINA_SAFETY_ON_FALSE_RETURN_VAL(offset >= sizeof(Eina_Model_Interface), NULL); | ||
5121 | EINA_SAFETY_ON_FALSE_RETURN_VAL(offset % sizeof(void *) == 0, NULL); | ||
5122 | return _eina_model_interface_find_offset(iface, offset); | ||
5123 | } | ||
5124 | |||
5125 | |||
5126 | /* Eina_Model_Interface_Properties ************************************/ | ||
5127 | |||
5128 | EAPI Eina_Bool | ||
5129 | eina_model_interface_properties_compare(const Eina_Model_Interface *iface, const Eina_Model *a, const Eina_Model *b, int *cmp) | ||
5130 | { | ||
5131 | Eina_Bool (*compare)(const Eina_Model *, const Eina_Model *, int *cmp); | ||
5132 | |||
5133 | EINA_SAFETY_ON_NULL_RETURN_VAL(cmp, EINA_FALSE); | ||
5134 | |||
5135 | *cmp = 0; | ||
5136 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, a, EINA_FALSE); | ||
5137 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, b, EINA_FALSE); | ||
5138 | |||
5139 | compare = _eina_model_interface_find_offset | ||
5140 | (iface, offsetof(Eina_Model_Interface_Properties, compare)); | ||
5141 | EINA_SAFETY_ON_NULL_RETURN_VAL(compare, EINA_FALSE); | ||
5142 | return compare(a, b, cmp); | ||
5143 | } | ||
5144 | |||
5145 | EAPI Eina_Bool | ||
5146 | eina_model_interface_properties_load(const Eina_Model_Interface *iface, Eina_Model *model) | ||
5147 | { | ||
5148 | Eina_Bool (*load)(Eina_Model *); | ||
5149 | Eina_Bool ret; | ||
5150 | |||
5151 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE); | ||
5152 | |||
5153 | load = _eina_model_interface_find_offset | ||
5154 | (iface, offsetof(Eina_Model_Interface_Properties, load)); | ||
5155 | EINA_SAFETY_ON_NULL_RETURN_VAL(load, EINA_FALSE); | ||
5156 | ret = load(model); | ||
5157 | |||
5158 | if (ret) | ||
5159 | _eina_model_event_callback_call | ||
5160 | (model, _eina_model_str_properties_loaded, NULL); | ||
5161 | |||
5162 | return ret; | ||
5163 | } | ||
5164 | |||
5165 | EAPI Eina_Bool | ||
5166 | eina_model_interface_properties_unload(const Eina_Model_Interface *iface, Eina_Model *model) | ||
5167 | { | ||
5168 | Eina_Bool (*unload)(Eina_Model *); | ||
5169 | Eina_Bool ret; | ||
5170 | |||
5171 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE); | ||
5172 | |||
5173 | unload = _eina_model_interface_find_offset | ||
5174 | (iface, offsetof(Eina_Model_Interface_Properties, unload)); | ||
5175 | EINA_SAFETY_ON_NULL_RETURN_VAL(unload, EINA_FALSE); | ||
5176 | ret = unload(model); | ||
5177 | |||
5178 | if (ret) | ||
5179 | _eina_model_event_callback_call | ||
5180 | (model, _eina_model_str_properties_unloaded, NULL); | ||
5181 | |||
5182 | return ret; | ||
5183 | } | ||
5184 | |||
5185 | EAPI Eina_Bool | ||
5186 | eina_model_interface_properties_get(const Eina_Model_Interface *iface, const Eina_Model *model, const char *name, Eina_Value *value) | ||
5187 | { | ||
5188 | Eina_Bool (*get)(const Eina_Model *, const char *, Eina_Value *); | ||
5189 | |||
5190 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); | ||
5191 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); | ||
5192 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE); | ||
5193 | |||
5194 | get = _eina_model_interface_find_offset | ||
5195 | (iface, offsetof(Eina_Model_Interface_Properties, get)); | ||
5196 | EINA_SAFETY_ON_NULL_RETURN_VAL(get, EINA_FALSE); | ||
5197 | return get(model, name, value); | ||
5198 | } | ||
5199 | |||
5200 | EAPI Eina_Bool | ||
5201 | eina_model_interface_properties_set(const Eina_Model_Interface *iface, Eina_Model *model, const char *name, const Eina_Value *value) | ||
5202 | { | ||
5203 | Eina_Bool (*set)(Eina_Model *, const char *, const Eina_Value *); | ||
5204 | |||
5205 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); | ||
5206 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); | ||
5207 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), EINA_FALSE); | ||
5208 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE); | ||
5209 | |||
5210 | set = _eina_model_interface_find_offset | ||
5211 | (iface, offsetof(Eina_Model_Interface_Properties, set)); | ||
5212 | EINA_SAFETY_ON_NULL_RETURN_VAL(set, EINA_FALSE); | ||
5213 | return set(model, name, value); | ||
5214 | } | ||
5215 | |||
5216 | EAPI Eina_Bool | ||
5217 | eina_model_interface_properties_del(const Eina_Model_Interface *iface, Eina_Model *model, const char *name) | ||
5218 | { | ||
5219 | Eina_Bool (*del)(Eina_Model *, const char *); | ||
5220 | |||
5221 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); | ||
5222 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE); | ||
5223 | |||
5224 | del = _eina_model_interface_find_offset | ||
5225 | (iface, offsetof(Eina_Model_Interface_Properties, del)); | ||
5226 | EINA_SAFETY_ON_NULL_RETURN_VAL(del, EINA_FALSE); | ||
5227 | return del(model, name); | ||
5228 | } | ||
5229 | |||
5230 | EAPI Eina_List * | ||
5231 | eina_model_interface_properties_names_list_get(const Eina_Model_Interface *iface, const Eina_Model *model) | ||
5232 | { | ||
5233 | Eina_List *(*names_list_get)(const Eina_Model *); | ||
5234 | |||
5235 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, NULL); | ||
5236 | |||
5237 | names_list_get = _eina_model_interface_find_offset | ||
5238 | (iface, offsetof(Eina_Model_Interface_Properties, names_list_get)); | ||
5239 | EINA_SAFETY_ON_NULL_RETURN_VAL(names_list_get, NULL); | ||
5240 | return names_list_get(model); | ||
5241 | } | ||
5242 | |||
5243 | /* Eina_Model_Interface_Children **************************************/ | ||
5244 | |||
5245 | EAPI Eina_Bool | ||
5246 | eina_model_interface_children_compare(const Eina_Model_Interface *iface, const Eina_Model *a, const Eina_Model *b, int *cmp) | ||
5247 | { | ||
5248 | Eina_Bool (*compare)(const Eina_Model *, const Eina_Model *, int *); | ||
5249 | |||
5250 | EINA_SAFETY_ON_NULL_RETURN_VAL(cmp, EINA_FALSE); | ||
5251 | |||
5252 | *cmp = 0; | ||
5253 | |||
5254 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, a, EINA_FALSE); | ||
5255 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, b, EINA_FALSE); | ||
5256 | |||
5257 | compare = _eina_model_interface_find_offset | ||
5258 | (iface, offsetof(Eina_Model_Interface_Children, compare)); | ||
5259 | EINA_SAFETY_ON_NULL_RETURN_VAL(compare, EINA_FALSE); | ||
5260 | return compare(a, b, cmp); | ||
5261 | } | ||
5262 | |||
5263 | EAPI Eina_Bool | ||
5264 | eina_model_interface_children_load(const Eina_Model_Interface *iface, Eina_Model *model) | ||
5265 | { | ||
5266 | Eina_Bool (*load)(Eina_Model *); | ||
5267 | Eina_Bool ret; | ||
5268 | |||
5269 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE); | ||
5270 | |||
5271 | load = _eina_model_interface_find_offset | ||
5272 | (iface, offsetof(Eina_Model_Interface_Children, load)); | ||
5273 | EINA_SAFETY_ON_NULL_RETURN_VAL(load, EINA_FALSE); | ||
5274 | ret = load(model); | ||
5275 | |||
5276 | if (ret) | ||
5277 | _eina_model_event_callback_call | ||
5278 | (model, _eina_model_str_children_loaded, NULL); | ||
5279 | |||
5280 | return ret; | ||
5281 | } | ||
5282 | |||
5283 | EAPI Eina_Bool | ||
5284 | eina_model_interface_children_unload(const Eina_Model_Interface *iface, Eina_Model *model) | ||
5285 | { | ||
5286 | Eina_Bool (*unload)(Eina_Model *); | ||
5287 | Eina_Bool ret; | ||
5288 | |||
5289 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE); | ||
5290 | |||
5291 | unload = _eina_model_interface_find_offset | ||
5292 | (iface, offsetof(Eina_Model_Interface_Children, unload)); | ||
5293 | EINA_SAFETY_ON_NULL_RETURN_VAL(unload, EINA_FALSE); | ||
5294 | ret = unload(model); | ||
5295 | |||
5296 | if (ret) | ||
5297 | _eina_model_event_callback_call | ||
5298 | (model, _eina_model_str_children_unloaded, NULL); | ||
5299 | |||
5300 | return ret; | ||
5301 | } | ||
5302 | |||
5303 | EAPI int | ||
5304 | eina_model_interface_children_count(const Eina_Model_Interface *iface, const Eina_Model *model) | ||
5305 | { | ||
5306 | int (*count)(const Eina_Model *); | ||
5307 | |||
5308 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, -1); | ||
5309 | |||
5310 | count = _eina_model_interface_find_offset | ||
5311 | (iface, offsetof(Eina_Model_Interface_Children, count)); | ||
5312 | EINA_SAFETY_ON_NULL_RETURN_VAL(count, -1); | ||
5313 | return count(model); | ||
5314 | } | ||
5315 | |||
5316 | EAPI Eina_Model * | ||
5317 | eina_model_interface_children_get(const Eina_Model_Interface *iface, const Eina_Model *model, unsigned int position) | ||
5318 | { | ||
5319 | Eina_Model *(*get)(const Eina_Model *, unsigned int); | ||
5320 | |||
5321 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, NULL); | ||
5322 | |||
5323 | get = _eina_model_interface_find_offset | ||
5324 | (iface, offsetof(Eina_Model_Interface_Children, get)); | ||
5325 | EINA_SAFETY_ON_NULL_RETURN_VAL(get, NULL); | ||
5326 | return get(model, position); | ||
5327 | } | ||
5328 | |||
5329 | EAPI Eina_Bool eina_model_interface_children_set(const Eina_Model_Interface *iface, Eina_Model *model, unsigned int position, Eina_Model *child) | ||
5330 | { | ||
5331 | Eina_Bool (*set)(const Eina_Model *, unsigned int, Eina_Model *); | ||
5332 | |||
5333 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE); | ||
5334 | EINA_MODEL_INSTANCE_CHECK_VAL(child, EINA_FALSE); | ||
5335 | |||
5336 | set = _eina_model_interface_find_offset | ||
5337 | (iface, offsetof(Eina_Model_Interface_Children, set)); | ||
5338 | EINA_SAFETY_ON_NULL_RETURN_VAL(set, EINA_FALSE); | ||
5339 | return set(model, position, child); | ||
5340 | } | ||
5341 | |||
5342 | EAPI Eina_Bool | ||
5343 | eina_model_interface_children_del(const Eina_Model_Interface *iface, Eina_Model *model, unsigned int position) | ||
5344 | { | ||
5345 | Eina_Bool (*del)(Eina_Model *, unsigned int); | ||
5346 | |||
5347 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE); | ||
5348 | |||
5349 | del = _eina_model_interface_find_offset | ||
5350 | (iface, offsetof(Eina_Model_Interface_Children, del)); | ||
5351 | EINA_SAFETY_ON_NULL_RETURN_VAL(del, EINA_FALSE); | ||
5352 | return del(model, position); | ||
5353 | } | ||
5354 | |||
5355 | |||
5356 | EAPI Eina_Bool | ||
5357 | eina_model_interface_children_insert_at(const Eina_Model_Interface *iface, Eina_Model *model, unsigned int position, Eina_Model *child) | ||
5358 | { | ||
5359 | Eina_Bool (*insert_at)(const Eina_Model *, unsigned int, Eina_Model *); | ||
5360 | |||
5361 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL(iface, model, EINA_FALSE); | ||
5362 | EINA_MODEL_INSTANCE_CHECK_VAL(child, EINA_FALSE); | ||
5363 | |||
5364 | insert_at = _eina_model_interface_find_offset | ||
5365 | (iface, offsetof(Eina_Model_Interface_Children, insert_at)); | ||
5366 | EINA_SAFETY_ON_NULL_RETURN_VAL(insert_at, EINA_FALSE); | ||
5367 | return insert_at(model, position, child); | ||
5368 | } | ||
5369 | |||
5370 | EAPI void | ||
5371 | eina_model_interface_children_sort(const Eina_Model_Interface *iface, Eina_Model *model, Eina_Compare_Cb compare) | ||
5372 | { | ||
5373 | void (*sort)(const Eina_Model *, Eina_Compare_Cb); | ||
5374 | |||
5375 | EINA_SAFETY_ON_NULL_RETURN(compare); | ||
5376 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK(iface, model); | ||
5377 | |||
5378 | sort = _eina_model_interface_find_offset | ||
5379 | (iface, offsetof(Eina_Model_Interface_Children, sort)); | ||
5380 | EINA_SAFETY_ON_NULL_RETURN(sort); | ||
5381 | return sort(model, compare); | ||
5382 | } | ||
5383 | |||
5384 | static Eina_Bool | ||
5385 | _eina_model_struct_set(Eina_Model *m, const Eina_Value_Struct_Desc *desc, void *memory) | ||
5386 | { | ||
5387 | Eina_Value_Struct st = {desc, memory}; | ||
5388 | Eina_Value *val = eina_model_interface_private_data_get | ||
5389 | (m, &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT.base); | ||
5390 | return eina_value_pset(val, &st); | ||
5391 | } | ||
5392 | |||
5393 | EAPI Eina_Model * | ||
5394 | eina_model_struct_new(const Eina_Value_Struct_Desc *desc) | ||
5395 | { | ||
5396 | Eina_Model *m; | ||
5397 | |||
5398 | EINA_SAFETY_ON_NULL_RETURN_VAL(desc, NULL); | ||
5399 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
5400 | (desc->version == EINA_VALUE_STRUCT_DESC_VERSION, NULL); | ||
5401 | |||
5402 | m = eina_model_new(EINA_MODEL_TYPE_STRUCT); | ||
5403 | EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL); | ||
5404 | |||
5405 | EINA_SAFETY_ON_FALSE_GOTO(_eina_model_struct_set(m, desc, NULL), error); | ||
5406 | return m; | ||
5407 | |||
5408 | error: | ||
5409 | eina_model_del(m); | ||
5410 | return NULL; | ||
5411 | } | ||
5412 | |||
5413 | EAPI Eina_Model * | ||
5414 | eina_model_type_struct_new(const Eina_Model_Type *type, const Eina_Value_Struct_Desc *desc) | ||
5415 | { | ||
5416 | Eina_Model *m; | ||
5417 | |||
5418 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
5419 | (eina_model_type_subclass_check(type, EINA_MODEL_TYPE_STRUCT), NULL); | ||
5420 | EINA_SAFETY_ON_NULL_RETURN_VAL(desc, NULL); | ||
5421 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
5422 | (desc->version == EINA_VALUE_STRUCT_DESC_VERSION, NULL); | ||
5423 | |||
5424 | m = eina_model_new(type); | ||
5425 | EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL); | ||
5426 | |||
5427 | EINA_SAFETY_ON_FALSE_GOTO(_eina_model_struct_set(m, desc, NULL), error); | ||
5428 | return m; | ||
5429 | |||
5430 | error: | ||
5431 | eina_model_del(m); | ||
5432 | return NULL; | ||
5433 | } | ||
5434 | |||
5435 | EAPI Eina_Bool | ||
5436 | eina_model_struct_set(Eina_Model *model, const Eina_Value_Struct_Desc *desc, void *memory) | ||
5437 | { | ||
5438 | EINA_SAFETY_ON_NULL_RETURN_VAL(desc, EINA_FALSE); | ||
5439 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
5440 | (desc->version == EINA_VALUE_STRUCT_DESC_VERSION, EINA_FALSE); | ||
5441 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL | ||
5442 | (&_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT.base, model, EINA_FALSE); | ||
5443 | |||
5444 | return _eina_model_struct_set(model, desc, memory); | ||
5445 | } | ||
5446 | |||
5447 | EAPI Eina_Bool | ||
5448 | eina_model_struct_get(const Eina_Model *model, const Eina_Value_Struct_Desc **p_desc, void **p_memory) | ||
5449 | { | ||
5450 | const Eina_Value *val; | ||
5451 | Eina_Value_Struct st; | ||
5452 | |||
5453 | EINA_SAFETY_ON_NULL_RETURN_VAL(p_desc, EINA_FALSE); | ||
5454 | |||
5455 | *p_desc = NULL; | ||
5456 | if (p_memory) *p_memory = NULL; | ||
5457 | |||
5458 | EINA_MODEL_INTERFACE_IMPLEMENTED_CHECK_VAL | ||
5459 | (&_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT.base, model, EINA_FALSE); | ||
5460 | |||
5461 | val = eina_model_interface_private_data_get | ||
5462 | (model, &_EINA_MODEL_INTERFACE_PROPERTIES_STRUCT.base); | ||
5463 | |||
5464 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_pget(val, &st), EINA_FALSE); | ||
5465 | |||
5466 | *p_desc = st.desc; | ||
5467 | if (p_memory) *p_memory = st.memory; | ||
5468 | return EINA_FALSE; | ||
5469 | } | ||
5470 | |||
5471 | EAPI void | ||
5472 | eina_models_usage_dump(void) | ||
5473 | { | ||
5474 | const Eina_List *l; | ||
5475 | const Eina_Model *m; | ||
5476 | |||
5477 | eina_lock_take(&_eina_model_debug_list_lock); | ||
5478 | |||
5479 | puts("DDD: model refs info (type, holders, backtrace)"); | ||
5480 | puts("DDD: -------------- -------------- ---------------------------------"); | ||
5481 | |||
5482 | EINA_LIST_FOREACH(_eina_model_debug_list, l, m) | ||
5483 | { | ||
5484 | Eina_Model_XRef *ref; | ||
5485 | |||
5486 | printf("DDD: %14p %14d %s\n", | ||
5487 | m, m->refcount, m->desc->cache.types[0]->name); | ||
5488 | |||
5489 | EINA_INLIST_FOREACH(m->xrefs, ref) | ||
5490 | { | ||
5491 | printf("DDD: id: %p '%s'\n", | ||
5492 | ref->id, ref->label); | ||
5493 | if (ref->backtrace.count) | ||
5494 | { | ||
5495 | char **symbols; | ||
5496 | unsigned int i; | ||
5497 | |||
5498 | #ifdef HAVE_BACKTRACE_SYMBOLS | ||
5499 | symbols = backtrace_symbols((void * const *)ref->backtrace.symbols, | ||
5500 | ref->backtrace.count); | ||
5501 | #else | ||
5502 | symbols = NULL; | ||
5503 | #endif | ||
5504 | |||
5505 | printf("DDD: Backtrace: Address Symbol\n"); | ||
5506 | for (i = 0; i < ref->backtrace.count; i++) | ||
5507 | printf("DDD: %14p %s\n", | ||
5508 | ref->backtrace.symbols[i], | ||
5509 | symbols ? symbols[i] : "???"); | ||
5510 | |||
5511 | free(symbols); | ||
5512 | puts("DDD:"); | ||
5513 | } | ||
5514 | } | ||
5515 | } | ||
5516 | |||
5517 | eina_lock_release(&_eina_model_debug_list_lock); | ||
5518 | } | ||
5519 | |||
5520 | EAPI Eina_List * | ||
5521 | eina_models_list_get(void) | ||
5522 | { | ||
5523 | const Eina_List *l; | ||
5524 | Eina_Model *m; | ||
5525 | Eina_List *ret = NULL; | ||
5526 | |||
5527 | eina_lock_take(&_eina_model_debug_list_lock); | ||
5528 | |||
5529 | EINA_LIST_FOREACH(_eina_model_debug_list, l, m) | ||
5530 | { | ||
5531 | ret = eina_list_append | ||
5532 | (ret, eina_model_xref | ||
5533 | (m, eina_models_list_get, "eina_models_list_get")); | ||
5534 | } | ||
5535 | |||
5536 | eina_lock_release(&_eina_model_debug_list_lock); | ||
5537 | |||
5538 | return ret; | ||
5539 | } | ||
5540 | |||
5541 | EAPI void | ||
5542 | eina_models_list_free(Eina_List *list) | ||
5543 | { | ||
5544 | Eina_Model *m; | ||
5545 | |||
5546 | EINA_LIST_FREE(list, m) | ||
5547 | eina_model_xunref(m, eina_models_list_get); | ||
5548 | } | ||
diff --git a/libraries/eina/src/lib/eina_module.c b/libraries/eina/src/lib/eina_module.c deleted file mode 100644 index f4f3242..0000000 --- a/libraries/eina/src/lib/eina_module.c +++ /dev/null | |||
@@ -1,604 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2007-2008 Jorge Luis Zapata Muga, Cedric BAIL | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #ifdef HAVE_ALLOCA_H | ||
24 | # include <alloca.h> | ||
25 | #elif defined __GNUC__ | ||
26 | # define alloca __builtin_alloca | ||
27 | #elif defined _AIX | ||
28 | # define alloca __alloca | ||
29 | #elif defined _MSC_VER | ||
30 | # include <malloc.h> | ||
31 | # define alloca _alloca | ||
32 | #else | ||
33 | # include <stddef.h> | ||
34 | # ifdef __cplusplus | ||
35 | extern "C" | ||
36 | # endif | ||
37 | void *alloca (size_t); | ||
38 | #endif | ||
39 | |||
40 | #include <stdlib.h> | ||
41 | #include <stdio.h> | ||
42 | #include <sys/types.h> | ||
43 | #include <string.h> | ||
44 | |||
45 | #ifdef HAVE_LIBGEN_H | ||
46 | # include <libgen.h> | ||
47 | #endif | ||
48 | |||
49 | #ifdef HAVE_DLOPEN | ||
50 | # include <dlfcn.h> | ||
51 | #endif | ||
52 | |||
53 | #ifdef HAVE_EVIL | ||
54 | # include <Evil.h> | ||
55 | #endif | ||
56 | |||
57 | #ifdef HAVE_ESCAPE | ||
58 | # include <Escape.h> | ||
59 | #endif | ||
60 | |||
61 | #ifdef HAVE_EXOTIC_H | ||
62 | # include <Exotic.h> | ||
63 | #endif | ||
64 | |||
65 | #include "eina_config.h" | ||
66 | #include "eina_private.h" | ||
67 | #include "eina_error.h" | ||
68 | #include "eina_file.h" | ||
69 | #include "eina_log.h" | ||
70 | |||
71 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
72 | #include "eina_safety_checks.h" | ||
73 | #include "eina_module.h" | ||
74 | |||
75 | /*============================================================================* | ||
76 | * Local * | ||
77 | *============================================================================*/ | ||
78 | |||
79 | /** | ||
80 | * @cond LOCAL | ||
81 | */ | ||
82 | |||
83 | static int EINA_MODULE_LOG_DOM = -1; | ||
84 | #ifdef ERR | ||
85 | #undef ERR | ||
86 | #endif | ||
87 | #define ERR(...) EINA_LOG_DOM_ERR(EINA_MODULE_LOG_DOM, __VA_ARGS__) | ||
88 | |||
89 | #ifdef WRN | ||
90 | #undef WRN | ||
91 | #endif | ||
92 | #define WRN(...) EINA_LOG_DOM_WARN(EINA_MODULE_LOG_DOM, __VA_ARGS__) | ||
93 | |||
94 | #ifdef DBG | ||
95 | #undef DBG | ||
96 | #endif | ||
97 | #define DBG(...) EINA_LOG_DOM_DBG(EINA_MODULE_LOG_DOM, __VA_ARGS__) | ||
98 | |||
99 | #ifdef _WIN32 | ||
100 | # define SEP_C '\\' | ||
101 | # define SEP_S "\\" | ||
102 | #else | ||
103 | # define SEP_C '/' | ||
104 | # define SEP_S "/" | ||
105 | #endif | ||
106 | |||
107 | #define EINA_MODULE_SYMBOL_INIT "__eina_module_init" | ||
108 | #define EINA_MODULE_SYMBOL_SHUTDOWN "__eina_module_shutdown" | ||
109 | |||
110 | struct _Eina_Module | ||
111 | { | ||
112 | void *handle; | ||
113 | int ref; | ||
114 | const char file[]; | ||
115 | }; | ||
116 | |||
117 | typedef struct _Dir_List_Get_Cb_Data | ||
118 | { | ||
119 | Eina_Module_Cb cb; | ||
120 | void *data; | ||
121 | Eina_Array *array; | ||
122 | } Dir_List_Get_Cb_Data; | ||
123 | |||
124 | typedef struct _Dir_List_Cb_Data | ||
125 | { | ||
126 | Eina_Module_Cb cb; | ||
127 | void *data; | ||
128 | } Dir_List_Cb_Data; | ||
129 | |||
130 | static Eina_Bool _dir_list_get_cb(Eina_Module *m, void *data) | ||
131 | { | ||
132 | Dir_List_Get_Cb_Data *cb_data = data; | ||
133 | Eina_Bool ret = EINA_TRUE; | ||
134 | |||
135 | if (cb_data->cb) | ||
136 | ret = cb_data->cb(m, cb_data->data); | ||
137 | |||
138 | if (ret) | ||
139 | eina_array_push(cb_data->array, m); | ||
140 | |||
141 | return ret; | ||
142 | } | ||
143 | |||
144 | static void _dir_list_cb(const char *name, const char *path, void *data) | ||
145 | { | ||
146 | Dir_List_Cb_Data *cb_data = data; | ||
147 | size_t length; | ||
148 | |||
149 | length = strlen(name); | ||
150 | if (length < sizeof(SHARED_LIB_SUFFIX)) /* x.so */ | ||
151 | return; | ||
152 | |||
153 | if (!strcmp(name + length - sizeof(SHARED_LIB_SUFFIX) + 1, | ||
154 | SHARED_LIB_SUFFIX)) | ||
155 | { | ||
156 | char *file; | ||
157 | Eina_Module *m; | ||
158 | |||
159 | length = strlen(path) + strlen(name) + 2; | ||
160 | |||
161 | file = alloca(sizeof (char) * length); | ||
162 | |||
163 | snprintf(file, length, "%s" SEP_S "%s", path, name); | ||
164 | m = eina_module_new(file); | ||
165 | if (!m) | ||
166 | { | ||
167 | return; /* call the user provided cb on this module */ | ||
168 | |||
169 | } | ||
170 | |||
171 | if (!cb_data->cb(m, cb_data->data)) | ||
172 | eina_module_free(m); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | static void _dir_arch_list_cb(const char *name, const char *path, void *data) | ||
177 | { | ||
178 | Dir_List_Get_Cb_Data *cb_data = data; | ||
179 | Eina_Module *m; | ||
180 | char *file = NULL; | ||
181 | size_t length; | ||
182 | |||
183 | length = strlen(path) + 1 + strlen(name) + 1 + | ||
184 | strlen((char *)(cb_data->data)) + 1 + sizeof("module") + | ||
185 | sizeof(SHARED_LIB_SUFFIX) + 1; | ||
186 | |||
187 | file = alloca(length); | ||
188 | snprintf(file, length, "%s" SEP_S "%s" SEP_S "%s" SEP_S "module" SHARED_LIB_SUFFIX, | ||
189 | path, name, (char *)(cb_data->data)); | ||
190 | m = eina_module_new(file); | ||
191 | if (!m) | ||
192 | return; | ||
193 | |||
194 | eina_array_push(cb_data->array, m); | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * @endcond | ||
199 | */ | ||
200 | |||
201 | |||
202 | /*============================================================================* | ||
203 | * Global * | ||
204 | *============================================================================*/ | ||
205 | |||
206 | /** | ||
207 | * @cond LOCAL | ||
208 | */ | ||
209 | |||
210 | static const char EINA_ERROR_WRONG_MODULE_STR[] = | ||
211 | "Wrong file format or no file module found"; | ||
212 | static const char EINA_ERROR_MODULE_INIT_FAILED_STR[] = | ||
213 | "Module initialisation function failed"; | ||
214 | |||
215 | EAPI Eina_Error EINA_ERROR_WRONG_MODULE = 0; | ||
216 | EAPI Eina_Error EINA_ERROR_MODULE_INIT_FAILED = 0; | ||
217 | |||
218 | /** | ||
219 | * @endcond | ||
220 | */ | ||
221 | |||
222 | /** | ||
223 | * @internal | ||
224 | * @brief Initialize the module loader module. | ||
225 | * | ||
226 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
227 | * | ||
228 | * This function sets up the module loader module of Eina. It is | ||
229 | * called by eina_init(). | ||
230 | * | ||
231 | * This function sets up the module module of Eina. It also registers | ||
232 | * the errors #EINA_ERROR_WRONG_MODULE and | ||
233 | * #EINA_ERROR_MODULE_INIT_FAILED. | ||
234 | * | ||
235 | * @see eina_init() | ||
236 | */ | ||
237 | Eina_Bool | ||
238 | eina_module_init(void) | ||
239 | { | ||
240 | EINA_MODULE_LOG_DOM = eina_log_domain_register | ||
241 | ("eina_module", EINA_LOG_COLOR_DEFAULT); | ||
242 | if (EINA_MODULE_LOG_DOM < 0) | ||
243 | { | ||
244 | EINA_LOG_ERR("Could not register log domain: eina_module"); | ||
245 | return EINA_FALSE; | ||
246 | } | ||
247 | |||
248 | #define EEMR(n) n = eina_error_msg_static_register(n ## _STR) | ||
249 | EEMR(EINA_ERROR_WRONG_MODULE); | ||
250 | EEMR(EINA_ERROR_MODULE_INIT_FAILED); | ||
251 | #undef EEMR | ||
252 | |||
253 | return EINA_TRUE; | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * @internal | ||
258 | * @brief Shut down the module loader module. | ||
259 | * | ||
260 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
261 | * | ||
262 | * This function shuts down the module loader module set up by | ||
263 | * eina_module_init(). It is called by eina_shutdown(). | ||
264 | * | ||
265 | * @see eina_shutdown() | ||
266 | */ | ||
267 | Eina_Bool | ||
268 | eina_module_shutdown(void) | ||
269 | { | ||
270 | /* TODO should we store every module when "new" is called and | ||
271 | * delete the list of modules here | ||
272 | */ | ||
273 | |||
274 | eina_log_domain_unregister(EINA_MODULE_LOG_DOM); | ||
275 | EINA_MODULE_LOG_DOM = -1; | ||
276 | return EINA_TRUE; | ||
277 | } | ||
278 | |||
279 | /*============================================================================* | ||
280 | * API * | ||
281 | *============================================================================*/ | ||
282 | |||
283 | EAPI Eina_Module *eina_module_new(const char *file) | ||
284 | { | ||
285 | Eina_Module *m; | ||
286 | size_t len; | ||
287 | |||
288 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
289 | /* TODO check that the file exists. Update doc too */ | ||
290 | |||
291 | len = strlen(file); | ||
292 | EINA_SAFETY_ON_FALSE_RETURN_VAL(len > 0, NULL); | ||
293 | |||
294 | m = malloc(sizeof(Eina_Module) + len + 1); | ||
295 | if (!m) | ||
296 | { | ||
297 | ERR("could not malloc(%lu)", | ||
298 | (unsigned long)(sizeof(Eina_Module) + len + 1)); | ||
299 | return NULL; | ||
300 | } | ||
301 | |||
302 | memcpy((char *)m->file, file, len + 1); | ||
303 | m->ref = 0; | ||
304 | m->handle = NULL; | ||
305 | DBG("m=%p, file=%s", m, file); | ||
306 | |||
307 | return m; | ||
308 | } | ||
309 | |||
310 | EAPI Eina_Bool eina_module_free(Eina_Module *m) | ||
311 | { | ||
312 | EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); | ||
313 | |||
314 | DBG("m=%p, handle=%p, file=%s, refs=%d", m, m->handle, m->file, m->ref); | ||
315 | |||
316 | if (m->handle) | ||
317 | if (eina_module_unload(m) == EINA_FALSE) | ||
318 | return EINA_FALSE; | ||
319 | |||
320 | free(m); | ||
321 | return EINA_TRUE; | ||
322 | } | ||
323 | |||
324 | EAPI Eina_Bool eina_module_load(Eina_Module *m) | ||
325 | { | ||
326 | #ifdef HAVE_DLOPEN | ||
327 | void *dl_handle; | ||
328 | Eina_Module_Init *initcall; | ||
329 | |||
330 | EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); | ||
331 | |||
332 | DBG("m=%p, handle=%p, file=%s, refs=%d", m, m->handle, m->file, m->ref); | ||
333 | |||
334 | if (m->handle) | ||
335 | goto loaded; | ||
336 | |||
337 | dl_handle = dlopen(m->file, RTLD_NOW); | ||
338 | if (!dl_handle) | ||
339 | { | ||
340 | WRN("could not dlopen(\"%s\", RTLD_NOW): %s", m->file, dlerror()); | ||
341 | eina_error_set(EINA_ERROR_WRONG_MODULE); | ||
342 | return EINA_FALSE; | ||
343 | } | ||
344 | |||
345 | initcall = dlsym(dl_handle, EINA_MODULE_SYMBOL_INIT); | ||
346 | if ((!initcall) || (!(*initcall))) | ||
347 | goto ok; | ||
348 | |||
349 | if ((*initcall)() == EINA_TRUE) | ||
350 | goto ok; | ||
351 | |||
352 | WRN("could not find eina's entry symbol %s inside module %s", | ||
353 | EINA_MODULE_SYMBOL_INIT, m->file); | ||
354 | eina_error_set(EINA_ERROR_MODULE_INIT_FAILED); | ||
355 | dlclose(dl_handle); | ||
356 | return EINA_FALSE; | ||
357 | ok: | ||
358 | DBG("successfully loaded %s", m->file); | ||
359 | m->handle = dl_handle; | ||
360 | loaded: | ||
361 | m->ref++; | ||
362 | DBG("ref %d", m->ref); | ||
363 | |||
364 | eina_error_set(0); | ||
365 | return EINA_TRUE; | ||
366 | #else | ||
367 | (void) m; | ||
368 | return EINA_FALSE; | ||
369 | #endif | ||
370 | } | ||
371 | |||
372 | EAPI Eina_Bool eina_module_unload(Eina_Module *m) | ||
373 | { | ||
374 | #ifdef HAVE_DLOPEN | ||
375 | Eina_Module_Shutdown *shut; | ||
376 | EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); | ||
377 | |||
378 | DBG("m=%p, handle=%p, file=%s, refs=%d", m, m->handle, m->file, m->ref); | ||
379 | |||
380 | m->ref--; | ||
381 | if (!m->ref) | ||
382 | { | ||
383 | shut = dlsym(m->handle, EINA_MODULE_SYMBOL_SHUTDOWN); | ||
384 | if ((shut) && (*shut)) | ||
385 | (*shut)(); | ||
386 | |||
387 | dlclose(m->handle); | ||
388 | m->handle = NULL; | ||
389 | DBG("unloaded module %s", m->file); | ||
390 | return EINA_TRUE; | ||
391 | } | ||
392 | |||
393 | return EINA_FALSE; | ||
394 | #else | ||
395 | (void) m; | ||
396 | return EINA_FALSE; | ||
397 | #endif | ||
398 | } | ||
399 | |||
400 | EAPI void *eina_module_symbol_get(const Eina_Module *m, const char *symbol) | ||
401 | { | ||
402 | #ifdef HAVE_DLOPEN | ||
403 | EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL); | ||
404 | EINA_SAFETY_ON_NULL_RETURN_VAL(m->handle, NULL); | ||
405 | return dlsym(m->handle, symbol); | ||
406 | #else | ||
407 | (void) m; | ||
408 | (void) symbol; | ||
409 | return NULL; | ||
410 | #endif | ||
411 | } | ||
412 | |||
413 | EAPI const char *eina_module_file_get(const Eina_Module *m) | ||
414 | { | ||
415 | EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL); | ||
416 | return m->file; | ||
417 | } | ||
418 | |||
419 | EAPI char *eina_module_symbol_path_get(const void *symbol, const char *sub_dir) | ||
420 | { | ||
421 | #ifdef HAVE_DLADDR | ||
422 | Dl_info eina_dl; | ||
423 | |||
424 | EINA_SAFETY_ON_NULL_RETURN_VAL(symbol, NULL); | ||
425 | |||
426 | if (dladdr(symbol, &eina_dl)) | ||
427 | { | ||
428 | char *pos = strrchr(eina_dl.dli_fname, SEP_C); | ||
429 | if (pos) | ||
430 | { | ||
431 | char *path; | ||
432 | int l0; | ||
433 | int l1; | ||
434 | int l2 = 0; | ||
435 | |||
436 | l0 = strlen(eina_dl.dli_fname); | ||
437 | l1 = strlen(pos); | ||
438 | if (sub_dir && (*sub_dir != '\0')) | ||
439 | l2 = strlen(sub_dir); | ||
440 | |||
441 | path = malloc(l0 - l1 + l2 + 1); | ||
442 | if (path) | ||
443 | { | ||
444 | memcpy(path, eina_dl.dli_fname, l0 - l1); | ||
445 | if (sub_dir && (*sub_dir != '\0')) | ||
446 | memcpy(path + l0 - l1, sub_dir, l2); | ||
447 | |||
448 | path[l0 - l1 + l2] = '\0'; | ||
449 | return path; | ||
450 | } | ||
451 | } | ||
452 | } | ||
453 | #else | ||
454 | (void) symbol; | ||
455 | (void) sub_dir; | ||
456 | #endif /* ! HAVE_DLADDR */ | ||
457 | |||
458 | return NULL; | ||
459 | } | ||
460 | |||
461 | EAPI char *eina_module_environment_path_get(const char *env, | ||
462 | const char *sub_dir) | ||
463 | { | ||
464 | const char *env_dir; | ||
465 | |||
466 | EINA_SAFETY_ON_NULL_RETURN_VAL(env, NULL); | ||
467 | |||
468 | env_dir = getenv(env); | ||
469 | if (env_dir) | ||
470 | { | ||
471 | char *path; | ||
472 | size_t l1; | ||
473 | size_t l2 = 0; | ||
474 | |||
475 | l1 = strlen(env_dir); | ||
476 | if (sub_dir && (*sub_dir != '\0')) | ||
477 | l2 = strlen(sub_dir); | ||
478 | |||
479 | path = (char *)malloc(l1 + l2 + 1); | ||
480 | if (path) | ||
481 | { | ||
482 | memcpy(path, env_dir, l1); | ||
483 | if (sub_dir && (*sub_dir != '\0')) | ||
484 | memcpy(path + l1, sub_dir, l2); | ||
485 | |||
486 | path[l1 + l2] = '\0'; | ||
487 | |||
488 | return path; | ||
489 | } | ||
490 | } | ||
491 | |||
492 | return NULL; | ||
493 | } | ||
494 | |||
495 | EAPI Eina_Array *eina_module_arch_list_get(Eina_Array *array, | ||
496 | const char *path, | ||
497 | const char *arch) | ||
498 | { | ||
499 | Dir_List_Get_Cb_Data list_get_cb_data; | ||
500 | |||
501 | if ((!path) || (!arch)) | ||
502 | return array; | ||
503 | |||
504 | list_get_cb_data.array = array ? array : eina_array_new(4); | ||
505 | list_get_cb_data.cb = NULL; | ||
506 | list_get_cb_data.data = (void *)arch; | ||
507 | |||
508 | eina_file_dir_list(path, 0, &_dir_arch_list_cb, &list_get_cb_data); | ||
509 | |||
510 | return list_get_cb_data.array; | ||
511 | } | ||
512 | |||
513 | EAPI Eina_Array *eina_module_list_get(Eina_Array *array, | ||
514 | const char *path, | ||
515 | Eina_Bool recursive, | ||
516 | Eina_Module_Cb cb, | ||
517 | void *data) | ||
518 | { | ||
519 | Dir_List_Get_Cb_Data list_get_cb_data; | ||
520 | Dir_List_Cb_Data list_cb_data; | ||
521 | |||
522 | if (!path) | ||
523 | return array; | ||
524 | |||
525 | list_get_cb_data.array = array ? array : eina_array_new(4); | ||
526 | list_get_cb_data.cb = cb; | ||
527 | list_get_cb_data.data = data; | ||
528 | |||
529 | list_cb_data.cb = &_dir_list_get_cb; | ||
530 | list_cb_data.data = &list_get_cb_data; | ||
531 | |||
532 | eina_file_dir_list(path, recursive, &_dir_list_cb, &list_cb_data); | ||
533 | |||
534 | return list_get_cb_data.array; | ||
535 | } | ||
536 | |||
537 | EAPI Eina_Module * | ||
538 | eina_module_find(const Eina_Array *array, const char *module) | ||
539 | { | ||
540 | unsigned int i; | ||
541 | Eina_Array_Iterator iterator; | ||
542 | Eina_Module *m; | ||
543 | |||
544 | EINA_ARRAY_ITER_NEXT(array, i, m, iterator) | ||
545 | { | ||
546 | char *file_m; | ||
547 | char *tmp; | ||
548 | ssize_t len; | ||
549 | |||
550 | /* basename() can modify its argument, so we first get a copie */ | ||
551 | /* do not use strdupa, as opensolaris does not have it */ | ||
552 | len = strlen(eina_module_file_get(m)); | ||
553 | tmp = alloca(len + 1); | ||
554 | memcpy(tmp, eina_module_file_get(m), len + 1); | ||
555 | file_m = basename(tmp); | ||
556 | len = strlen(file_m); | ||
557 | len -= sizeof(SHARED_LIB_SUFFIX) - 1; | ||
558 | if (len <= 0) | ||
559 | continue; | ||
560 | |||
561 | if (!strncmp(module, file_m, len)) | ||
562 | return m;; | ||
563 | } | ||
564 | |||
565 | return NULL; | ||
566 | } | ||
567 | |||
568 | EAPI void eina_module_list_load(Eina_Array *array) | ||
569 | { | ||
570 | Eina_Array_Iterator iterator; | ||
571 | Eina_Module *m; | ||
572 | unsigned int i; | ||
573 | |||
574 | EINA_SAFETY_ON_NULL_RETURN(array); | ||
575 | DBG("array %p, count %u", array, array->count); | ||
576 | EINA_ARRAY_ITER_NEXT(array, i, m, iterator) | ||
577 | eina_module_load(m); | ||
578 | } | ||
579 | |||
580 | EAPI void eina_module_list_unload(Eina_Array *array) | ||
581 | { | ||
582 | Eina_Array_Iterator iterator; | ||
583 | Eina_Module *m; | ||
584 | unsigned int i; | ||
585 | |||
586 | EINA_SAFETY_ON_NULL_RETURN(array); | ||
587 | DBG("array %p, count %u", array, array->count); | ||
588 | EINA_ARRAY_ITER_NEXT(array, i, m, iterator) | ||
589 | eina_module_unload(m); | ||
590 | } | ||
591 | |||
592 | EAPI void eina_module_list_free(Eina_Array *array) | ||
593 | { | ||
594 | Eina_Array_Iterator iterator; | ||
595 | Eina_Module *m; | ||
596 | unsigned int i; | ||
597 | |||
598 | EINA_SAFETY_ON_NULL_RETURN(array); | ||
599 | DBG("array %p, count %u", array, array->count); | ||
600 | EINA_ARRAY_ITER_NEXT(array, i, m, iterator) | ||
601 | eina_module_free(m); | ||
602 | |||
603 | eina_array_flush(array); | ||
604 | } | ||
diff --git a/libraries/eina/src/lib/eina_prefix.c b/libraries/eina/src/lib/eina_prefix.c deleted file mode 100644 index 2322311..0000000 --- a/libraries/eina/src/lib/eina_prefix.c +++ /dev/null | |||
@@ -1,726 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2011 Carsten Haitzler | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #ifdef STDC_HEADERS | ||
24 | # include <stdlib.h> | ||
25 | # include <stddef.h> | ||
26 | #else | ||
27 | # ifdef HAVE_STDLIB_H | ||
28 | # include <stdlib.h> | ||
29 | # endif | ||
30 | #endif | ||
31 | #ifdef HAVE_ALLOCA_H | ||
32 | # include <alloca.h> | ||
33 | #elif !defined alloca | ||
34 | # ifdef __GNUC__ | ||
35 | # define alloca __builtin_alloca | ||
36 | # elif defined _AIX | ||
37 | # define alloca __alloca | ||
38 | # elif defined _MSC_VER | ||
39 | # include <malloc.h> | ||
40 | # define alloca _alloca | ||
41 | # elif !defined HAVE_ALLOCA | ||
42 | # ifdef __cplusplus | ||
43 | extern "C" | ||
44 | # endif | ||
45 | void *alloca (size_t); | ||
46 | # endif | ||
47 | #endif | ||
48 | |||
49 | #include <stdio.h> | ||
50 | #include <stdlib.h> | ||
51 | #include <string.h> | ||
52 | #include <sys/types.h> | ||
53 | #include <sys/stat.h> | ||
54 | #include <limits.h> | ||
55 | |||
56 | #ifdef HAVE_UNISTD_H | ||
57 | # include <unistd.h> | ||
58 | #endif | ||
59 | |||
60 | #ifdef HAVE_DLADDR | ||
61 | # include <dlfcn.h> | ||
62 | #endif | ||
63 | |||
64 | #ifdef HAVE_EVIL | ||
65 | # include <Evil.h> | ||
66 | #endif | ||
67 | |||
68 | #ifdef HAVE_ESCAPE | ||
69 | # include <Escape.h> | ||
70 | #endif | ||
71 | |||
72 | #include "eina_config.h" | ||
73 | #include "eina_private.h" | ||
74 | #include "eina_log.h" | ||
75 | #include "eina_prefix.h" | ||
76 | |||
77 | #ifdef _WIN32 | ||
78 | # define PSEP_C ';' | ||
79 | # define DSEP_C '\\' | ||
80 | # define DSEP_S "\\" | ||
81 | #else | ||
82 | # define PSEP_C ':' | ||
83 | # define DSEP_C '/' | ||
84 | # define DSEP_S "/" | ||
85 | #endif /* _WIN32 */ | ||
86 | |||
87 | /*============================================================================* | ||
88 | * Local * | ||
89 | *============================================================================*/ | ||
90 | |||
91 | /** | ||
92 | * @cond LOCAL | ||
93 | */ | ||
94 | |||
95 | struct _Eina_Prefix | ||
96 | { | ||
97 | char *exe_path; | ||
98 | |||
99 | char *prefix_path; | ||
100 | char *prefix_path_bin; | ||
101 | char *prefix_path_data; | ||
102 | char *prefix_path_lib; | ||
103 | char *prefix_path_locale; | ||
104 | |||
105 | unsigned char fallback : 1; | ||
106 | unsigned char no_common_prefix : 1; | ||
107 | unsigned char env_used : 1; | ||
108 | }; | ||
109 | |||
110 | #define STRDUP_REP(x, y) do { if (x) free(x); x = strdup(y); } while (0) | ||
111 | #define IF_FREE_NULL(p) do { if (p) { free(p); p = NULL; } } while (0) | ||
112 | |||
113 | #ifndef EINA_LOG_COLOR_DEFAULT | ||
114 | #define EINA_LOG_COLOR_DEFAULT EINA_COLOR_CYAN | ||
115 | #endif | ||
116 | |||
117 | #ifdef ERR | ||
118 | #undef ERR | ||
119 | #endif | ||
120 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_prefix_log_dom, __VA_ARGS__) | ||
121 | |||
122 | #ifdef WRN | ||
123 | #undef WRN | ||
124 | #endif | ||
125 | #define WRN(...) EINA_LOG_DOM_WARN(_eina_prefix_log_dom, __VA_ARGS__) | ||
126 | |||
127 | #ifdef INF | ||
128 | #undef INF | ||
129 | #endif | ||
130 | #define INF(...) EINA_LOG_DOM_INFO(_eina_prefix_log_dom, __VA_ARGS__) | ||
131 | |||
132 | #ifdef DBG | ||
133 | #undef DBG | ||
134 | #endif | ||
135 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_prefix_log_dom, __VA_ARGS__) | ||
136 | |||
137 | static int _eina_prefix_log_dom = -1; | ||
138 | |||
139 | static int | ||
140 | _fallback(Eina_Prefix *pfx, const char *pkg_bin, const char *pkg_lib, | ||
141 | const char *pkg_data, const char *pkg_locale, const char *envprefix) | ||
142 | { | ||
143 | char *p; | ||
144 | |||
145 | STRDUP_REP(pfx->prefix_path, pkg_bin); | ||
146 | if (!pfx->prefix_path) return 0; | ||
147 | p = strrchr(pfx->prefix_path, DSEP_C); | ||
148 | if (p) *p = 0; | ||
149 | STRDUP_REP(pfx->prefix_path_bin, pkg_bin); | ||
150 | STRDUP_REP(pfx->prefix_path_lib, pkg_lib); | ||
151 | STRDUP_REP(pfx->prefix_path_data, pkg_data); | ||
152 | STRDUP_REP(pfx->prefix_path_locale, pkg_locale); | ||
153 | WRN("Could not determine its installed prefix for '%s'\n" | ||
154 | " so am falling back on the compiled in default:\n" | ||
155 | " %s\n" | ||
156 | " implied by the following:\n" | ||
157 | " bindir = %s\n" | ||
158 | " libdir = %s\n" | ||
159 | " datadir = %s\n" | ||
160 | " localedir = %s\n" | ||
161 | " Try setting the following environment variables:\n" | ||
162 | " %s_PREFIX - points to the base prefix of install\n" | ||
163 | " or the next 4 variables\n" | ||
164 | " %s_BIN_DIR - provide a specific binary directory\n" | ||
165 | " %s_LIB_DIR - provide a specific library directory\n" | ||
166 | " %s_DATA_DIR - provide a specific data directory\n" | ||
167 | " %s_LOCALE_DIR - provide a specific locale directory", | ||
168 | envprefix, | ||
169 | pfx->prefix_path, pkg_bin, pkg_lib, pkg_data, pkg_locale, | ||
170 | envprefix, envprefix, envprefix, envprefix, envprefix); | ||
171 | pfx->fallback = 1; | ||
172 | return 1; | ||
173 | } | ||
174 | |||
175 | #ifndef _WIN32 | ||
176 | static int | ||
177 | _try_proc(Eina_Prefix *pfx, void *symbol) | ||
178 | { | ||
179 | FILE *f; | ||
180 | char buf[4096]; | ||
181 | |||
182 | DBG("Try /proc/self/maps"); | ||
183 | f = fopen("/proc/self/maps", "rb"); | ||
184 | if (!f) return 0; | ||
185 | DBG("Exists /proc/self/maps"); | ||
186 | while (fgets(buf, sizeof(buf), f)) | ||
187 | { | ||
188 | int len; | ||
189 | char *p, mode[5] = ""; | ||
190 | unsigned long ptr1 = 0, ptr2 = 0; | ||
191 | |||
192 | len = strlen(buf); | ||
193 | if (buf[len - 1] == '\n') | ||
194 | { | ||
195 | buf[len - 1] = 0; | ||
196 | len--; | ||
197 | } | ||
198 | if (sscanf(buf, "%lx-%lx %4s", &ptr1, &ptr2, mode) == 3) | ||
199 | { | ||
200 | if (!strcmp(mode, "r-xp")) | ||
201 | { | ||
202 | if (((void *)ptr1 <= symbol) && (symbol < (void *)ptr2)) | ||
203 | { | ||
204 | DBG("Found in /proc/self/maps: %s", buf); | ||
205 | p = strchr(buf, '/'); | ||
206 | if (p) | ||
207 | { | ||
208 | DBG("Found in /proc/self/maps: found last /"); | ||
209 | if (len > 10) | ||
210 | { | ||
211 | if (!strcmp(buf + len - 10, " (deleted)")) | ||
212 | buf[len - 10] = 0; | ||
213 | } | ||
214 | STRDUP_REP(pfx->exe_path, p); | ||
215 | INF("Found in /proc/self/maps: guess exe path is %s", pfx->exe_path); | ||
216 | fclose(f); | ||
217 | return 1; | ||
218 | } | ||
219 | else break; | ||
220 | } | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | fclose(f); | ||
225 | WRN("Failed in /proc/self/maps"); | ||
226 | return 0; | ||
227 | } | ||
228 | #endif | ||
229 | |||
230 | static int | ||
231 | _try_argv(Eina_Prefix *pfx, const char *argv0) | ||
232 | { | ||
233 | char *path, *p, *cp, *s; | ||
234 | int len, lenexe; | ||
235 | char buf[PATH_MAX], buf2[PATH_MAX], buf3[PATH_MAX]; | ||
236 | |||
237 | DBG("Try argv0 = %s", argv0); | ||
238 | /* 1. is argv0 abs path? */ | ||
239 | #ifdef _WIN32 | ||
240 | if (evil_path_is_absolute(argv0)) | ||
241 | #else | ||
242 | if (argv0[0] == DSEP_C) | ||
243 | #endif | ||
244 | { | ||
245 | DBG("Match arvg0 is full path: %s", argv0); | ||
246 | STRDUP_REP(pfx->exe_path, argv0); | ||
247 | if (access(pfx->exe_path, X_OK) == 0) | ||
248 | { | ||
249 | INF("Executable argv0 = %s", argv0); | ||
250 | return 1; | ||
251 | } | ||
252 | IF_FREE_NULL(pfx->exe_path); | ||
253 | DBG("Non existent argv0: %s", argv0); | ||
254 | return 0; | ||
255 | } | ||
256 | /* 2. relative path */ | ||
257 | if (strchr(argv0, DSEP_C)) | ||
258 | { | ||
259 | DBG("Relative path argv0: %s", argv0); | ||
260 | if (getcwd(buf3, sizeof(buf3))) | ||
261 | { | ||
262 | snprintf(buf2, sizeof(buf2), "%s" DSEP_S "%s", buf3, argv0); | ||
263 | DBG("Relative to CWD: %s", buf2); | ||
264 | if (realpath(buf2, buf)) | ||
265 | { | ||
266 | DBG("Realpath is: %s", buf); | ||
267 | STRDUP_REP(pfx->exe_path, buf); | ||
268 | if (access(pfx->exe_path, X_OK) == 0) | ||
269 | { | ||
270 | INF("Path %s is executable", pfx->exe_path); | ||
271 | return 1; | ||
272 | } | ||
273 | DBG("Fail check for executable: %s", pfx->exe_path); | ||
274 | IF_FREE_NULL(pfx->exe_path); | ||
275 | } | ||
276 | } | ||
277 | } | ||
278 | /* 3. argv0 no path - look in PATH */ | ||
279 | DBG("Look for argv0=%s in $PATH", argv0); | ||
280 | path = getenv("PATH"); | ||
281 | if (!path) return 0; | ||
282 | p = path; | ||
283 | cp = p; | ||
284 | lenexe = strlen(argv0); | ||
285 | while ((p = strchr(cp, PSEP_C))) | ||
286 | { | ||
287 | len = p - cp; | ||
288 | s = malloc(len + 1 + lenexe + 1); | ||
289 | if (s) | ||
290 | { | ||
291 | strncpy(s, cp, len); | ||
292 | s[len] = DSEP_C; | ||
293 | strcpy(s + len + 1, argv0); | ||
294 | DBG("Try path: %s", s); | ||
295 | if (realpath(s, buf)) | ||
296 | { | ||
297 | DBG("Realpath is: %s", buf); | ||
298 | if (access(buf, X_OK) == 0) | ||
299 | { | ||
300 | STRDUP_REP(pfx->exe_path, buf); | ||
301 | INF("Path %s is executable", pfx->exe_path); | ||
302 | free(s); | ||
303 | return 1; | ||
304 | } | ||
305 | } | ||
306 | free(s); | ||
307 | } | ||
308 | cp = p + 1; | ||
309 | } | ||
310 | /* 4. big problems. arg[0] != executable - weird execution */ | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static int | ||
315 | _get_env_var(char **var, const char *env, const char *prefix, const char *dir) | ||
316 | { | ||
317 | char buf[PATH_MAX]; | ||
318 | const char *s = getenv(env); | ||
319 | |||
320 | DBG("Try env var %s", env); | ||
321 | if (s) | ||
322 | { | ||
323 | INF("Have env %s = %s", env, s); | ||
324 | STRDUP_REP(*var, s); | ||
325 | return 1; | ||
326 | } | ||
327 | else if (prefix) | ||
328 | { | ||
329 | snprintf(buf, sizeof(buf), "%s" DSEP_S "%s", prefix, dir); | ||
330 | INF("Have prefix %s = %s", prefix, buf); | ||
331 | STRDUP_REP(*var, buf); | ||
332 | return 1; | ||
333 | } | ||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | static int | ||
338 | _get_env_vars(Eina_Prefix *pfx, | ||
339 | const char *envprefix, | ||
340 | const char *bindir, | ||
341 | const char *libdir, | ||
342 | const char *datadir, | ||
343 | const char *localedir) | ||
344 | { | ||
345 | char env[1024]; | ||
346 | const char *s; | ||
347 | int ret = 0; | ||
348 | |||
349 | snprintf(env, sizeof(env), "%s_PREFIX", envprefix); | ||
350 | if ((s = getenv(env))) STRDUP_REP(pfx->prefix_path, s); | ||
351 | snprintf(env, sizeof(env), "%s_BIN_DIR", envprefix); | ||
352 | ret += _get_env_var(&pfx->prefix_path_bin, env, s, bindir); | ||
353 | snprintf(env, sizeof(env), "%s_LIB_DIR", envprefix); | ||
354 | ret += _get_env_var(&pfx->prefix_path_lib, env, s, libdir); | ||
355 | snprintf(env, sizeof(env), "%s_DATA_DIR", envprefix); | ||
356 | ret += _get_env_var(&pfx->prefix_path_data, env, s, datadir); | ||
357 | snprintf(env, sizeof(env), "%s_LOCALE_DIR", envprefix); | ||
358 | ret += _get_env_var(&pfx->prefix_path_locale, env, s, localedir); | ||
359 | return ret; | ||
360 | } | ||
361 | |||
362 | /** | ||
363 | * @endcond | ||
364 | */ | ||
365 | |||
366 | |||
367 | /*============================================================================* | ||
368 | * Global * | ||
369 | *============================================================================*/ | ||
370 | |||
371 | |||
372 | /*============================================================================* | ||
373 | * API * | ||
374 | *============================================================================*/ | ||
375 | |||
376 | |||
377 | EAPI Eina_Prefix * | ||
378 | eina_prefix_new(const char *argv0, void *symbol, const char *envprefix, | ||
379 | const char *sharedir, const char *magicsharefile, | ||
380 | const char *pkg_bin, const char *pkg_lib, | ||
381 | const char *pkg_data, const char *pkg_locale) | ||
382 | { | ||
383 | Eina_Prefix *pfx; | ||
384 | char *p, buf[4096], *tmp, *magic = NULL; | ||
385 | struct stat st; | ||
386 | const char *p1, *p2; | ||
387 | const char *pkg_bin_p = NULL; | ||
388 | const char *pkg_lib_p = NULL; | ||
389 | const char *pkg_data_p = NULL; | ||
390 | const char *pkg_locale_p = NULL; | ||
391 | const char *bindir = "bin"; | ||
392 | const char *libdir = "lib"; | ||
393 | const char *datadir = "share"; | ||
394 | const char *localedir = "share"; | ||
395 | |||
396 | DBG("EINA PREFIX: argv0=%s, symbol=%p, magicsharefile=%s, envprefix=%s", | ||
397 | argv0, symbol, magicsharefile, envprefix); | ||
398 | pfx = calloc(1, sizeof(Eina_Prefix)); | ||
399 | if (!pfx) return NULL; | ||
400 | |||
401 | /* if provided with a share dir use datadir/sharedir as the share dir */ | ||
402 | if (sharedir) | ||
403 | { | ||
404 | int len; | ||
405 | |||
406 | len = snprintf(buf, sizeof(buf), "%s" DSEP_S "%s", datadir, sharedir); | ||
407 | if (len > 0) | ||
408 | { | ||
409 | #ifdef _WIN32 | ||
410 | /* on win32 convert / to \ for path here */ | ||
411 | for (p = buf + strlen(datadir) + strlen(DSEP_S); *p; p++) | ||
412 | { | ||
413 | if (*p == '/') *p = DSEP_C; | ||
414 | } | ||
415 | #endif | ||
416 | tmp = alloca(len + 1); | ||
417 | strcpy(tmp, buf); | ||
418 | datadir = tmp; | ||
419 | } | ||
420 | } | ||
421 | if (magicsharefile) | ||
422 | { | ||
423 | magic = alloca(strlen(magicsharefile)); | ||
424 | strcpy(magic, magicsharefile); | ||
425 | #ifdef _WIN32 | ||
426 | /* on win32 convert / to \ for path here */ | ||
427 | for (p = magic; *p; p++) | ||
428 | { | ||
429 | if (*p == '/') *p = DSEP_C; | ||
430 | } | ||
431 | #endif | ||
432 | } | ||
433 | |||
434 | /* look at compile-time package bin/lib/datadir etc. and figure out the | ||
435 | * bin, lib and data dirs from these, if possible. i.e. | ||
436 | * bin = /usr/local/bin | ||
437 | * lib = /usr/local/lib | ||
438 | * data = /usr/local/share/enlightenment | ||
439 | * thus they all have a common prefix string of /usr/local/ and | ||
440 | * bindir = bin | ||
441 | * libdir = lib | ||
442 | * datadir = share/enlightenment | ||
443 | * this addresses things like libdir is lib64 or lib32 or other such | ||
444 | * junk distributions like to do so then: | ||
445 | * bin = /usr/local/bin | ||
446 | * lib = /usr/local/lib64 | ||
447 | * data = /usr/local/share/enlightenment | ||
448 | * then | ||
449 | * bindir = bin | ||
450 | * libdir = lib64 | ||
451 | * datadir = share/enlightennment | ||
452 | * in theory this should also work with debians new multiarch style like | ||
453 | * bindir = bin | ||
454 | * libdir = lib/i386-linux-gnu | ||
455 | * or | ||
456 | * libdir = lib/x86_64-linux-gnu | ||
457 | * all with a common prefix that can be relocated | ||
458 | */ | ||
459 | /* 1. check last common char in bin and lib strings */ | ||
460 | for (p1 = pkg_bin, p2 = pkg_lib; *p1 && *p2; p1++, p2++) | ||
461 | { | ||
462 | if (*p1 != *p2) | ||
463 | { | ||
464 | pkg_bin_p = p1; | ||
465 | pkg_lib_p = p2; | ||
466 | break; | ||
467 | } | ||
468 | } | ||
469 | /* 1. check last common char in bin and data strings */ | ||
470 | for (p1 = pkg_bin, p2 = pkg_data; *p1 && *p2; p1++, p2++) | ||
471 | { | ||
472 | if (*p1 != *p2) | ||
473 | { | ||
474 | pkg_data_p = p2; | ||
475 | break; | ||
476 | } | ||
477 | } | ||
478 | /* 1. check last common char in bin and locale strings */ | ||
479 | for (p1 = pkg_bin, p2 = pkg_locale; *p1 && *p2; p1++, p2++) | ||
480 | { | ||
481 | if (*p1 != *p2) | ||
482 | { | ||
483 | pkg_locale_p = p2; | ||
484 | break; | ||
485 | } | ||
486 | } | ||
487 | /* 2. if all the common string offsets match we compiled with a common prefix */ | ||
488 | if (((pkg_bin_p - pkg_bin) == (pkg_lib_p - pkg_lib)) | ||
489 | && ((pkg_bin_p - pkg_bin) == (pkg_data_p - pkg_data)) | ||
490 | && ((pkg_bin_p - pkg_bin) == (pkg_locale_p - pkg_locale)) | ||
491 | ) | ||
492 | { | ||
493 | bindir = pkg_bin_p; | ||
494 | libdir = pkg_lib_p; | ||
495 | datadir = pkg_data_p; | ||
496 | localedir = pkg_locale_p; | ||
497 | DBG("Prefix relative bindir = %s", bindir); | ||
498 | DBG("Prefix relative libdir = %s", libdir); | ||
499 | DBG("Prefix relative datadir = %s", datadir); | ||
500 | DBG("Prefix relative localedir = %s", localedir); | ||
501 | } | ||
502 | /* 3. some galoot thought it awesome not to give us a common prefix at compile time | ||
503 | * so fall back to the compile time directories. we are no longer relocatable */ | ||
504 | else | ||
505 | { | ||
506 | STRDUP_REP(pfx->prefix_path_bin, pkg_bin); | ||
507 | STRDUP_REP(pfx->prefix_path_lib, pkg_lib); | ||
508 | STRDUP_REP(pfx->prefix_path_data, pkg_data); | ||
509 | STRDUP_REP(pfx->prefix_path_locale, pkg_locale); | ||
510 | pfx->no_common_prefix = 1; | ||
511 | DBG("Can't work out a common prefix - compiled in fallback"); | ||
512 | } | ||
513 | |||
514 | /* if user provides env vars - then use that or also more specific sub | ||
515 | * dirs for bin, lib, data and locale */ | ||
516 | if ((envprefix) && | ||
517 | (_get_env_vars(pfx, envprefix, bindir, libdir, datadir, localedir) > 0)) | ||
518 | { | ||
519 | pfx->env_used = 1; | ||
520 | return pfx; | ||
521 | } | ||
522 | |||
523 | #ifdef HAVE_DLADDR | ||
524 | DBG("Try dladdr on %p", symbol); | ||
525 | if (symbol) | ||
526 | { | ||
527 | Dl_info info_dl; | ||
528 | |||
529 | if (dladdr(symbol, &info_dl)) | ||
530 | { | ||
531 | DBG("Dlinfo worked"); | ||
532 | if (info_dl.dli_fname) | ||
533 | { | ||
534 | DBG("Dlinfo dli_fname = %s", info_dl.dli_fname); | ||
535 | # ifdef _WIN32 | ||
536 | if (evil_path_is_absolute(info_dl.dli_fname)) | ||
537 | # else | ||
538 | if (info_dl.dli_fname[0] == DSEP_C) | ||
539 | # endif | ||
540 | { | ||
541 | INF("Dlsym gave full path = %s", info_dl.dli_fname); | ||
542 | STRDUP_REP(pfx->exe_path, info_dl.dli_fname); | ||
543 | } | ||
544 | } | ||
545 | } | ||
546 | } | ||
547 | #endif | ||
548 | /* no env var - examine process and possible argv0 */ | ||
549 | if ((argv0) && (!pfx->exe_path) && (symbol)) | ||
550 | { | ||
551 | #ifndef _WIN32 | ||
552 | if (!_try_proc(pfx, symbol)) | ||
553 | { | ||
554 | #endif | ||
555 | if (!_try_argv(pfx, argv0)) | ||
556 | { | ||
557 | _fallback(pfx, pkg_bin, pkg_lib, pkg_data, pkg_locale, | ||
558 | envprefix); | ||
559 | return pfx; | ||
560 | } | ||
561 | #ifndef _WIN32 | ||
562 | } | ||
563 | #endif | ||
564 | } | ||
565 | if (!pfx->exe_path) | ||
566 | { | ||
567 | WRN("Fallback - nothing found"); | ||
568 | _fallback(pfx, pkg_bin, pkg_lib, pkg_data, pkg_locale, envprefix); | ||
569 | return pfx; | ||
570 | } | ||
571 | /* _exe_path is now a full absolute path TO this exe - figure out rest */ | ||
572 | /* if | ||
573 | * exe = /blah/whatever/bin/exe | ||
574 | * or | ||
575 | * exe = /blah/whatever/lib/libexe.so | ||
576 | * then | ||
577 | * prefix = /blah/whatever | ||
578 | * bin_dir = /blah/whatever/bin | ||
579 | * data_dir = /blah/whatever/share/enlightenment | ||
580 | * lib_dir = /blah/whatever/lib | ||
581 | */ | ||
582 | DBG("From exe %s figure out the rest", pfx->exe_path); | ||
583 | p = strrchr(pfx->exe_path, DSEP_C); | ||
584 | if (p) | ||
585 | { | ||
586 | p--; | ||
587 | while (p >= pfx->exe_path) | ||
588 | { | ||
589 | if (*p == DSEP_C) | ||
590 | { | ||
591 | pfx->prefix_path = malloc(p - pfx->exe_path + 1); | ||
592 | if (pfx->prefix_path) | ||
593 | { | ||
594 | strncpy(pfx->prefix_path, pfx->exe_path, | ||
595 | p - pfx->exe_path); | ||
596 | pfx->prefix_path[p - pfx->exe_path] = 0; | ||
597 | DBG("Have prefix = %s", pfx->prefix_path); | ||
598 | |||
599 | /* bin */ | ||
600 | snprintf(buf, sizeof(buf), "%s" DSEP_S "%s", | ||
601 | pfx->prefix_path, bindir); | ||
602 | STRDUP_REP(pfx->prefix_path_bin, buf); | ||
603 | DBG("Have bin = %s", pfx->prefix_path_bin); | ||
604 | /* lib */ | ||
605 | snprintf(buf, sizeof(buf), "%s" DSEP_S "%s", | ||
606 | pfx->prefix_path, libdir); | ||
607 | STRDUP_REP(pfx->prefix_path_lib, buf); | ||
608 | DBG("Have lib = %s", pfx->prefix_path_lib); | ||
609 | /* locale */ | ||
610 | snprintf(buf, sizeof(buf), "%s" DSEP_S "%s", | ||
611 | pfx->prefix_path, localedir); | ||
612 | STRDUP_REP(pfx->prefix_path_locale, buf); | ||
613 | DBG("Have locale = %s", pfx->prefix_path_locale); | ||
614 | /* check if magic file is there - then our guess is right */ | ||
615 | if (magic) | ||
616 | { | ||
617 | DBG("Magic = %s", magic); | ||
618 | snprintf(buf, sizeof(buf), | ||
619 | "%s" DSEP_S "%s" DSEP_S "%s", | ||
620 | pfx->prefix_path, datadir, magic); | ||
621 | DBG("Check in %s", buf); | ||
622 | } | ||
623 | if ((!magic) || (stat(buf, &st) == 0)) | ||
624 | { | ||
625 | if (buf[0]) | ||
626 | DBG("Magic path %s stat passed", buf); | ||
627 | else | ||
628 | DBG("No magic file"); | ||
629 | snprintf(buf, sizeof(buf), "%s" DSEP_S "%s", | ||
630 | pfx->prefix_path, datadir); | ||
631 | STRDUP_REP(pfx->prefix_path_data, buf); | ||
632 | } | ||
633 | /* magic file not there. time to start hunting! */ | ||
634 | else | ||
635 | { | ||
636 | WRN("Magic failed"); | ||
637 | _fallback(pfx, pkg_bin, pkg_lib, pkg_data, | ||
638 | pkg_locale, envprefix); | ||
639 | } | ||
640 | } | ||
641 | else | ||
642 | { | ||
643 | WRN("No Prefix path (alloc fail)"); | ||
644 | _fallback(pfx, pkg_bin, pkg_lib, pkg_data, pkg_locale, | ||
645 | envprefix); | ||
646 | } | ||
647 | return pfx; | ||
648 | } | ||
649 | p--; | ||
650 | } | ||
651 | } | ||
652 | WRN("Final fallback"); | ||
653 | _fallback(pfx, pkg_bin, pkg_lib, pkg_data, pkg_locale, envprefix); | ||
654 | return pfx; | ||
655 | } | ||
656 | |||
657 | EAPI void | ||
658 | eina_prefix_free(Eina_Prefix *pfx) | ||
659 | { | ||
660 | if (!pfx) return; | ||
661 | |||
662 | IF_FREE_NULL(pfx->exe_path); | ||
663 | IF_FREE_NULL(pfx->prefix_path); | ||
664 | IF_FREE_NULL(pfx->prefix_path_bin); | ||
665 | IF_FREE_NULL(pfx->prefix_path_data); | ||
666 | IF_FREE_NULL(pfx->prefix_path_lib); | ||
667 | IF_FREE_NULL(pfx->prefix_path_locale); | ||
668 | free(pfx); | ||
669 | } | ||
670 | |||
671 | EAPI const char * | ||
672 | eina_prefix_get(Eina_Prefix *pfx) | ||
673 | { | ||
674 | if (!pfx) return ""; | ||
675 | return pfx->prefix_path; | ||
676 | } | ||
677 | |||
678 | EAPI const char * | ||
679 | eina_prefix_bin_get(Eina_Prefix *pfx) | ||
680 | { | ||
681 | if (!pfx) return ""; | ||
682 | return pfx->prefix_path_bin; | ||
683 | } | ||
684 | |||
685 | EAPI const char * | ||
686 | eina_prefix_lib_get(Eina_Prefix *pfx) | ||
687 | { | ||
688 | if (!pfx) return ""; | ||
689 | return pfx->prefix_path_lib; | ||
690 | } | ||
691 | |||
692 | EAPI const char * | ||
693 | eina_prefix_data_get(Eina_Prefix *pfx) | ||
694 | { | ||
695 | if (!pfx) return ""; | ||
696 | return pfx->prefix_path_data; | ||
697 | } | ||
698 | |||
699 | EAPI const char * | ||
700 | eina_prefix_locale_get(Eina_Prefix *pfx) | ||
701 | { | ||
702 | if (!pfx) return ""; | ||
703 | return pfx->prefix_path_locale; | ||
704 | } | ||
705 | |||
706 | Eina_Bool | ||
707 | eina_prefix_init(void) | ||
708 | { | ||
709 | _eina_prefix_log_dom = eina_log_domain_register("eina_prefix", | ||
710 | EINA_LOG_COLOR_DEFAULT); | ||
711 | if (_eina_prefix_log_dom < 0) | ||
712 | { | ||
713 | EINA_LOG_ERR("Could not register log domain: eina_prefix"); | ||
714 | return EINA_FALSE; | ||
715 | } | ||
716 | |||
717 | return EINA_TRUE; | ||
718 | } | ||
719 | |||
720 | Eina_Bool | ||
721 | eina_prefix_shutdown(void) | ||
722 | { | ||
723 | eina_log_domain_unregister(_eina_prefix_log_dom); | ||
724 | _eina_prefix_log_dom = -1; | ||
725 | return EINA_TRUE; | ||
726 | } | ||
diff --git a/libraries/eina/src/lib/eina_private.h b/libraries/eina/src/lib/eina_private.h deleted file mode 100644 index 49df565..0000000 --- a/libraries/eina/src/lib/eina_private.h +++ /dev/null | |||
@@ -1,148 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Carsten Haitzler, Vincent Torri, Jorge Luis Zapata Muga | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifndef EINA_PRIVATE_H_ | ||
20 | #define EINA_PRIVATE_H_ | ||
21 | |||
22 | #include <stdarg.h> | ||
23 | |||
24 | #include "eina_magic.h" | ||
25 | #include "eina_iterator.h" | ||
26 | #include "eina_accessor.h" | ||
27 | |||
28 | #ifndef MIN | ||
29 | # define MIN(x, y) (((x) > (y)) ? (y) : (x)) | ||
30 | #endif | ||
31 | |||
32 | #ifndef MAX | ||
33 | # define MAX(x, y) (((x) > (y)) ? (x) : (y)) | ||
34 | #endif | ||
35 | |||
36 | #ifndef ABS | ||
37 | # define ABS(x) ((x) < 0 ? -(x) : (x)) | ||
38 | #endif | ||
39 | |||
40 | #ifndef CLAMP | ||
41 | # define CLAMP(x, min, \ | ||
42 | max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x))) | ||
43 | #endif | ||
44 | |||
45 | #define EINA_INLIST_JUMP_SIZE 256 | ||
46 | |||
47 | #define READBUFSIZ 65536 | ||
48 | |||
49 | #define EINA_LOG_COLOR_DEFAULT "\033[36m" | ||
50 | |||
51 | /* eina magic types */ | ||
52 | #define EINA_MAGIC_SHARE 0x98761234 | ||
53 | #define EINA_MAGIC_SHARE_HEAD 0x98761235 | ||
54 | #define EINA_MAGIC_STRINGSHARE_NODE 0x98761254 | ||
55 | #define EINA_MAGIC_USTRINGSHARE_NODE 0x98761255 | ||
56 | #define EINA_MAGIC_BINSHARE_NODE 0x98761256 | ||
57 | |||
58 | #define EINA_MAGIC_LIST 0x98761237 | ||
59 | #define EINA_MAGIC_LIST_ITERATOR 0x98761238 | ||
60 | #define EINA_MAGIC_LIST_ACCESSOR 0x98761239 | ||
61 | #define EINA_MAGIC_LIST_ACCOUNTING 0x9876123a | ||
62 | |||
63 | #define EINA_MAGIC_ARRAY 0x9876123b | ||
64 | #define EINA_MAGIC_ARRAY_ITERATOR 0x9876123c | ||
65 | #define EINA_MAGIC_ARRAY_ACCESSOR 0x9876123d | ||
66 | |||
67 | #define EINA_MAGIC_HASH 0x9876123e | ||
68 | #define EINA_MAGIC_HASH_ITERATOR 0x9876123f | ||
69 | |||
70 | #define EINA_MAGIC_TILER 0x98761240 | ||
71 | #define EINA_MAGIC_TILER_ITERATOR 0x98761241 | ||
72 | |||
73 | #define EINA_MAGIC_MATRIXSPARSE 0x98761242 | ||
74 | #define EINA_MAGIC_MATRIXSPARSE_ROW 0x98761243 | ||
75 | #define EINA_MAGIC_MATRIXSPARSE_CELL 0x98761244 | ||
76 | #define EINA_MAGIC_MATRIXSPARSE_ITERATOR 0x98761245 | ||
77 | #define EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR 0x98761246 | ||
78 | #define EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR 0x98761247 | ||
79 | #define EINA_MAGIC_MATRIXSPARSE_CELL_ITERATOR 0x98761248 | ||
80 | #define EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR 0x98761249 | ||
81 | |||
82 | #define EINA_MAGIC_STRBUF 0x98761250 | ||
83 | #define EINA_MAGIC_USTRBUF 0x98761257 | ||
84 | #define EINA_MAGIC_BINBUF 0x98761258 | ||
85 | |||
86 | #define EINA_MAGIC_QUADTREE 0x98761251 | ||
87 | #define EINA_MAGIC_QUADTREE_ROOT 0x98761252 | ||
88 | #define EINA_MAGIC_QUADTREE_ITEM 0x98761253 | ||
89 | |||
90 | #define EINA_MAGIC_SIMPLE_XML_TAG 0x98761260 | ||
91 | #define EINA_MAGIC_SIMPLE_XML_DATA 0x98761261 | ||
92 | #define EINA_MAGIC_SIMPLE_XML_ATTRIBUTE 0x98761262 | ||
93 | |||
94 | #define EINA_MAGIC_INARRAY 0x98761270 | ||
95 | #define EINA_MAGIC_INARRAY_ITERATOR 0x98761271 | ||
96 | #define EINA_MAGIC_INARRAY_ACCESSOR 0x98761272 | ||
97 | |||
98 | #define EINA_MAGIC_MODEL 0x98761280 | ||
99 | |||
100 | #define EINA_MAGIC_CLASS 0x9877CB30 | ||
101 | |||
102 | /* undef the following, we want out version */ | ||
103 | #undef FREE | ||
104 | #define FREE(ptr) \ | ||
105 | do { \ | ||
106 | free(ptr); \ | ||
107 | ptr = NULL; \ | ||
108 | } while(0); | ||
109 | |||
110 | #undef IF_FREE | ||
111 | #define IF_FREE(ptr) \ | ||
112 | do { \ | ||
113 | if (ptr) { \ | ||
114 | free(ptr); \ | ||
115 | ptr = NULL; \ | ||
116 | } \ | ||
117 | } while(0); | ||
118 | |||
119 | #undef IF_FN_DEL | ||
120 | #define IF_FN_DEL(_fn, ptr) \ | ||
121 | do { \ | ||
122 | if (ptr) { \ | ||
123 | _fn(ptr); \ | ||
124 | ptr = NULL; \ | ||
125 | } \ | ||
126 | } while(0); | ||
127 | |||
128 | #define MAGIC_FREE(ptr) \ | ||
129 | do { \ | ||
130 | if (ptr) { \ | ||
131 | EINA_MAGIC_SET(ptr, EINA_MAGIC_NONE); \ | ||
132 | FREE(ptr); \ | ||
133 | } \ | ||
134 | } while(0); | ||
135 | |||
136 | #ifdef EFL_HAVE_THREADS | ||
137 | extern Eina_Bool _threads_activated; | ||
138 | |||
139 | void eina_share_common_threads_init(void); | ||
140 | void eina_share_common_threads_shutdown(void); | ||
141 | void eina_log_threads_init(void); | ||
142 | void eina_log_threads_shutdown(void); | ||
143 | #endif | ||
144 | |||
145 | void eina_file_mmap_faulty(void *addr, long page_size); | ||
146 | |||
147 | #endif /* EINA_PRIVATE_H_ */ | ||
148 | |||
diff --git a/libraries/eina/src/lib/eina_quadtree.c b/libraries/eina/src/lib/eina_quadtree.c deleted file mode 100644 index daf03d0..0000000 --- a/libraries/eina/src/lib/eina_quadtree.c +++ /dev/null | |||
@@ -1,935 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2010 Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | /** | ||
20 | * @page tutorial_quadtree_page QuadTree Tutorial | ||
21 | * | ||
22 | * to be written... | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #ifdef HAVE_CONFIG_H | ||
27 | # include "config.h" | ||
28 | #endif | ||
29 | |||
30 | #include <stdlib.h> | ||
31 | #include <stdio.h> | ||
32 | |||
33 | #ifdef HAVE_EVIL | ||
34 | # include <Evil.h> | ||
35 | #endif | ||
36 | |||
37 | #include "eina_quadtree.h" | ||
38 | #include "eina_magic.h" | ||
39 | #include "eina_mempool.h" | ||
40 | #include "eina_list.h" | ||
41 | #include "eina_inlist.h" | ||
42 | #include "eina_trash.h" | ||
43 | #include "eina_log.h" | ||
44 | #include "eina_rectangle.h" | ||
45 | |||
46 | #include "eina_private.h" | ||
47 | |||
48 | typedef struct _Eina_QuadTree_Root Eina_QuadTree_Root; | ||
49 | |||
50 | static const char EINA_MAGIC_QUADTREE_STR[] = "Eina QuadTree"; | ||
51 | static const char EINA_MAGIC_QUADTREE_ROOT_STR[] = "Eina QuadTree Root"; | ||
52 | static const char EINA_MAGIC_QUADTREE_ITEM_STR[] = "Eina QuadTree Item"; | ||
53 | |||
54 | #define EINA_MAGIC_CHECK_QUADTREE(d, ...) \ | ||
55 | do { \ | ||
56 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_QUADTREE)) \ | ||
57 | { \ | ||
58 | EINA_MAGIC_FAIL(d, EINA_MAGIC_QUADTREE); \ | ||
59 | return __VA_ARGS__; \ | ||
60 | } \ | ||
61 | } while(0); | ||
62 | |||
63 | #define EINA_MAGIC_CHECK_QUADTREE_ROOT(d, ...) \ | ||
64 | do { \ | ||
65 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_QUADTREE_ROOT)) \ | ||
66 | { \ | ||
67 | EINA_MAGIC_FAIL(d, EINA_MAGIC_QUADTREE_ROOT); \ | ||
68 | return __VA_ARGS__; \ | ||
69 | } \ | ||
70 | } while(0); | ||
71 | |||
72 | #define EINA_MAGIC_CHECK_QUADTREE_ITEM(d, ...) \ | ||
73 | do { \ | ||
74 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_QUADTREE_ITEM)) \ | ||
75 | { \ | ||
76 | EINA_MAGIC_FAIL(d, EINA_MAGIC_QUADTREE_ITEM); \ | ||
77 | return __VA_ARGS__; \ | ||
78 | } \ | ||
79 | } while(0); | ||
80 | |||
81 | struct _Eina_QuadTree | ||
82 | { | ||
83 | Eina_QuadTree_Root *root; | ||
84 | |||
85 | Eina_List *hidden; | ||
86 | |||
87 | size_t root_count; | ||
88 | size_t items_count; | ||
89 | |||
90 | Eina_Trash *items_trash; | ||
91 | Eina_Trash *root_trash; | ||
92 | |||
93 | Eina_Inlist *change; | ||
94 | Eina_Inlist *cached; | ||
95 | Eina_Rectangle target; | ||
96 | |||
97 | size_t index; | ||
98 | |||
99 | struct | ||
100 | { | ||
101 | Eina_Quad_Callback v; | ||
102 | Eina_Quad_Callback h; | ||
103 | } func; | ||
104 | |||
105 | struct | ||
106 | { | ||
107 | size_t w; | ||
108 | size_t h; | ||
109 | } geom; | ||
110 | |||
111 | Eina_Bool resize : 1; | ||
112 | Eina_Bool lost : 1; | ||
113 | |||
114 | EINA_MAGIC | ||
115 | }; | ||
116 | |||
117 | struct _Eina_QuadTree_Root | ||
118 | { | ||
119 | Eina_QuadTree_Root *parent; | ||
120 | Eina_QuadTree_Root *left; | ||
121 | Eina_QuadTree_Root *right; | ||
122 | |||
123 | Eina_List *both; | ||
124 | |||
125 | Eina_Bool sorted : 1; | ||
126 | |||
127 | EINA_MAGIC | ||
128 | }; | ||
129 | |||
130 | struct _Eina_QuadTree_Item | ||
131 | { | ||
132 | EINA_INLIST; | ||
133 | |||
134 | Eina_QuadTree *quad; | ||
135 | Eina_QuadTree_Root *root; | ||
136 | |||
137 | const void *object; | ||
138 | |||
139 | size_t index; | ||
140 | |||
141 | Eina_Bool change : 1; | ||
142 | Eina_Bool delete_me : 1; | ||
143 | Eina_Bool visible : 1; | ||
144 | Eina_Bool hidden : 1; | ||
145 | |||
146 | EINA_MAGIC | ||
147 | }; | ||
148 | |||
149 | static int _eina_quadtree_log_dom = -1; | ||
150 | static Eina_Mempool *eina_quadtree_root_mp = NULL; | ||
151 | static Eina_Mempool *_eina_quadtree_items_mp = NULL; | ||
152 | |||
153 | #ifdef ERR | ||
154 | #undef ERR | ||
155 | #endif | ||
156 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_quadtree_log_dom, __VA_ARGS__) | ||
157 | |||
158 | #ifdef DBG | ||
159 | #undef DBG | ||
160 | #endif | ||
161 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_quadtree_log_dom, __VA_ARGS__) | ||
162 | |||
163 | |||
164 | static int | ||
165 | _eina_quadtree_item_cmp(const void *a, const void *b) | ||
166 | { | ||
167 | const Eina_QuadTree_Item *i = a; | ||
168 | const Eina_QuadTree_Item *j = b; | ||
169 | |||
170 | return i->index - j->index; | ||
171 | } | ||
172 | |||
173 | static Eina_QuadTree_Root * | ||
174 | eina_quadtree_root_free(Eina_QuadTree *q, Eina_QuadTree_Root *root) | ||
175 | { | ||
176 | Eina_QuadTree_Item *item; | ||
177 | |||
178 | if (!root) | ||
179 | return NULL; | ||
180 | |||
181 | EINA_MAGIC_CHECK_QUADTREE_ROOT(root, NULL); | ||
182 | |||
183 | EINA_LIST_FREE(root->both, item) | ||
184 | eina_mempool_free(_eina_quadtree_items_mp, item); | ||
185 | |||
186 | root->left = eina_quadtree_root_free(q, root->left); | ||
187 | root->right = eina_quadtree_root_free(q, root->right); | ||
188 | |||
189 | EINA_MAGIC_SET(root, 0); | ||
190 | eina_mempool_free(eina_quadtree_root_mp, root); | ||
191 | |||
192 | return NULL; | ||
193 | } | ||
194 | |||
195 | static Eina_QuadTree_Root * | ||
196 | eina_quadtree_root_rebuild_pre(Eina_QuadTree *q, | ||
197 | Eina_Inlist **change, | ||
198 | Eina_QuadTree_Root *root) | ||
199 | { | ||
200 | Eina_QuadTree_Item *item; | ||
201 | |||
202 | if (!root) | ||
203 | return NULL; | ||
204 | |||
205 | EINA_LIST_FREE(root->both, item) | ||
206 | { | ||
207 | if (item->visible) | ||
208 | *change = eina_inlist_append(*change, EINA_INLIST_GET(item)); | ||
209 | else if (!item->hidden) | ||
210 | { | ||
211 | q->hidden = eina_list_append(q->hidden, item); | ||
212 | item->hidden = EINA_TRUE; | ||
213 | item->root = NULL; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | root->left = eina_quadtree_root_rebuild_pre(q, change, root->left); | ||
218 | root->right = eina_quadtree_root_rebuild_pre(q, change, root->right); | ||
219 | |||
220 | EINA_MAGIC_SET(root, 0); | ||
221 | if (q->root_count > 50) | ||
222 | eina_mempool_free(eina_quadtree_root_mp, root); | ||
223 | else | ||
224 | { | ||
225 | eina_trash_push(&q->root_trash, root); | ||
226 | q->root_count++; | ||
227 | } | ||
228 | |||
229 | return NULL; | ||
230 | } | ||
231 | |||
232 | static size_t | ||
233 | _eina_quadtree_split(Eina_Inlist *objects, | ||
234 | Eina_QuadTree_Root *root, | ||
235 | Eina_Inlist **left, | ||
236 | Eina_Inlist **right, | ||
237 | Eina_Quad_Callback func, | ||
238 | int border, | ||
239 | int middle) | ||
240 | { | ||
241 | Eina_QuadTree_Item *object; | ||
242 | |||
243 | middle /= 2; | ||
244 | |||
245 | if (middle <= 4) | ||
246 | while (objects) | ||
247 | { | ||
248 | object = EINA_INLIST_CONTAINER_GET(objects, Eina_QuadTree_Item); | ||
249 | objects = objects->next; | ||
250 | |||
251 | object->change = EINA_FALSE; | ||
252 | if (!object->visible) | ||
253 | { | ||
254 | if (!object->hidden) | ||
255 | { | ||
256 | object->hidden = EINA_TRUE; | ||
257 | object->quad->hidden = eina_list_append( | ||
258 | object->quad->hidden, | ||
259 | object); | ||
260 | } | ||
261 | |||
262 | continue; | ||
263 | } | ||
264 | |||
265 | if (object->hidden) | ||
266 | { | ||
267 | object->hidden = EINA_FALSE; | ||
268 | object->quad->hidden = eina_list_remove(object->quad->hidden, | ||
269 | object); | ||
270 | } | ||
271 | |||
272 | if (!object->delete_me) | ||
273 | { | ||
274 | if (root->sorted) | ||
275 | root->both = eina_list_sorted_insert(root->both, | ||
276 | _eina_quadtree_item_cmp, | ||
277 | object); | ||
278 | else | ||
279 | root->both = eina_list_append(root->both, object); | ||
280 | |||
281 | object->root = root; | ||
282 | } | ||
283 | else | ||
284 | eina_quadtree_del(object); | ||
285 | } | ||
286 | else | ||
287 | while (objects) | ||
288 | { | ||
289 | object = EINA_INLIST_CONTAINER_GET(objects, Eina_QuadTree_Item); | ||
290 | objects = objects->next; | ||
291 | |||
292 | object->change = EINA_FALSE; | ||
293 | if (!object->visible) | ||
294 | { | ||
295 | if (!object->hidden) | ||
296 | { | ||
297 | object->hidden = EINA_TRUE; | ||
298 | object->quad->hidden = eina_list_append( | ||
299 | object->quad->hidden, | ||
300 | object); | ||
301 | } | ||
302 | |||
303 | continue; | ||
304 | } | ||
305 | |||
306 | if (object->hidden) | ||
307 | { | ||
308 | object->hidden = EINA_FALSE; | ||
309 | object->quad->hidden = eina_list_remove(object->quad->hidden, | ||
310 | object); | ||
311 | } | ||
312 | |||
313 | if (!object->delete_me) | ||
314 | { | ||
315 | switch (func(object->object, border + middle)) | ||
316 | { | ||
317 | case EINA_QUAD_LEFT: | ||
318 | *left = eina_inlist_append(*left, EINA_INLIST_GET(object)); | ||
319 | break; | ||
320 | |||
321 | case EINA_QUAD_RIGHT: | ||
322 | *right = | ||
323 | eina_inlist_append(*right, EINA_INLIST_GET(object)); | ||
324 | break; | ||
325 | |||
326 | case EINA_QUAD_BOTH: | ||
327 | root->both = eina_list_append(root->both, object); | ||
328 | object->root = root; | ||
329 | break; | ||
330 | |||
331 | default: | ||
332 | abort(); | ||
333 | } | ||
334 | } | ||
335 | else | ||
336 | eina_quadtree_del(object); | ||
337 | } | ||
338 | |||
339 | return middle; | ||
340 | } | ||
341 | |||
342 | |||
343 | static Eina_QuadTree_Root * | ||
344 | _eina_quadtree_update(Eina_QuadTree *q, Eina_QuadTree_Root *parent, | ||
345 | Eina_QuadTree_Root *root, Eina_Inlist *objects, | ||
346 | Eina_Bool direction, Eina_Rectangle *size) | ||
347 | { | ||
348 | Eina_Inlist *right = NULL; | ||
349 | Eina_Inlist *left = NULL; | ||
350 | size_t w2; | ||
351 | size_t h2; | ||
352 | |||
353 | if (!objects) | ||
354 | return root; | ||
355 | |||
356 | if (!root) | ||
357 | { | ||
358 | root = eina_trash_pop(&q->root_trash); | ||
359 | if (!root) | ||
360 | root = eina_mempool_malloc(eina_quadtree_root_mp, sizeof (Eina_QuadTree_Root)); | ||
361 | else | ||
362 | q->root_count--; | ||
363 | |||
364 | if (!root) | ||
365 | /* FIXME: NOT GOOD TIMING, WE ARE GOING TO LEAK MORE MEMORY */ | ||
366 | return NULL; | ||
367 | |||
368 | root->parent = parent; | ||
369 | root->both = NULL; | ||
370 | root->left = NULL; | ||
371 | root->right = NULL; | ||
372 | root->sorted = EINA_TRUE; | ||
373 | |||
374 | EINA_MAGIC_SET(root, EINA_MAGIC_QUADTREE_ROOT); | ||
375 | } | ||
376 | |||
377 | w2 = 0; | ||
378 | h2 = 0; | ||
379 | |||
380 | if (direction) | ||
381 | w2 = _eina_quadtree_split(objects, root, | ||
382 | &left, &right, | ||
383 | q->func.h, size->x, size->w); | ||
384 | else | ||
385 | h2 = _eina_quadtree_split(objects, root, | ||
386 | &left, &right, | ||
387 | q->func.v, size->y, size->h); | ||
388 | |||
389 | size->w -= w2; size->h -= h2; | ||
390 | root->left = _eina_quadtree_update(q, root, | ||
391 | root->left, left, | ||
392 | !direction, size); | ||
393 | size->x += w2; size->y += h2; | ||
394 | root->right = _eina_quadtree_update(q, root, | ||
395 | root->right, right, | ||
396 | !direction, size); | ||
397 | size->x -= w2; size->y -= h2; | ||
398 | size->w += w2; size->h += h2; | ||
399 | |||
400 | return root; | ||
401 | } | ||
402 | |||
403 | static Eina_Inlist * | ||
404 | _eina_quadtree_merge(Eina_Inlist *result, | ||
405 | Eina_List *both) | ||
406 | { | ||
407 | Eina_QuadTree_Item *item; | ||
408 | Eina_QuadTree_Item *b; | ||
409 | Eina_Inlist *moving; | ||
410 | |||
411 | if (!both) | ||
412 | return result; | ||
413 | |||
414 | if (!result) | ||
415 | { | ||
416 | Eina_List *l; | ||
417 | |||
418 | EINA_LIST_FOREACH(both, l, item) | ||
419 | if (item->visible) | ||
420 | result = eina_inlist_append(result, EINA_INLIST_GET(item)); | ||
421 | |||
422 | return result; | ||
423 | } | ||
424 | |||
425 | moving = result; | ||
426 | |||
427 | item = EINA_INLIST_CONTAINER_GET(moving, Eina_QuadTree_Item); | ||
428 | b = eina_list_data_get(both); | ||
429 | |||
430 | while (both && moving) | ||
431 | { | ||
432 | if (!b->visible) | ||
433 | { | ||
434 | both = eina_list_next(both); | ||
435 | b = eina_list_data_get(both); | ||
436 | continue; | ||
437 | } | ||
438 | |||
439 | if (_eina_quadtree_item_cmp(item, b) < 0) | ||
440 | { | ||
441 | /* moving is still lower than item, so we can continue to the next one. */ | ||
442 | moving = moving->next; | ||
443 | item = EINA_INLIST_CONTAINER_GET(moving, Eina_QuadTree_Item); | ||
444 | } | ||
445 | else | ||
446 | { | ||
447 | /* we just get above the limit of both, so insert it */ | ||
448 | result = eina_inlist_prepend_relative(result, | ||
449 | EINA_INLIST_GET(b), | ||
450 | moving); | ||
451 | both = eina_list_next(both); | ||
452 | b = eina_list_data_get(both); | ||
453 | } | ||
454 | } | ||
455 | |||
456 | item = EINA_INLIST_CONTAINER_GET(result->last, Eina_QuadTree_Item); | ||
457 | |||
458 | while (both) | ||
459 | { | ||
460 | b = eina_list_data_get(both); | ||
461 | if (b->visible) | ||
462 | { | ||
463 | if (_eina_quadtree_item_cmp(item, b) < 0) | ||
464 | break; | ||
465 | |||
466 | result = eina_inlist_prepend_relative(result, | ||
467 | EINA_INLIST_GET(b), | ||
468 | result->last); | ||
469 | } | ||
470 | |||
471 | both = eina_list_next(both); | ||
472 | } | ||
473 | |||
474 | while (both) | ||
475 | { | ||
476 | b = eina_list_data_get(both); | ||
477 | if (b->visible) | ||
478 | result = eina_inlist_append(result, EINA_INLIST_GET(b)); | ||
479 | |||
480 | both = eina_list_next(both); | ||
481 | } | ||
482 | |||
483 | return result; | ||
484 | } | ||
485 | |||
486 | static Eina_Inlist * | ||
487 | _eina_quadtree_collide(Eina_Inlist *result, | ||
488 | Eina_QuadTree_Root *root, | ||
489 | Eina_Bool direction, Eina_Rectangle *size, | ||
490 | Eina_Rectangle *target) | ||
491 | { | ||
492 | if (!root) | ||
493 | return result; | ||
494 | |||
495 | if (!root->sorted) | ||
496 | { | ||
497 | root->both = eina_list_sort(root->both, -1, _eina_quadtree_item_cmp); | ||
498 | root->sorted = EINA_TRUE; | ||
499 | } | ||
500 | |||
501 | result = _eina_quadtree_merge(result, root->both); | ||
502 | DBG("%p: %i in both for (%i, %i - %i, %i)", | ||
503 | root, eina_list_count(root->both), | ||
504 | size->x, size->y, size->w, size->h); | ||
505 | |||
506 | if (direction) | ||
507 | { | ||
508 | int middle = size->w / 2; | ||
509 | |||
510 | size->w -= middle; | ||
511 | if (eina_spans_intersect(size->x, size->w, target->x, target->w)) | ||
512 | result = _eina_quadtree_collide(result, root->left, | ||
513 | !direction, size, | ||
514 | target); | ||
515 | |||
516 | size->x += middle; | ||
517 | if (eina_spans_intersect(size->x, size->w, target->x, target->w)) | ||
518 | result = _eina_quadtree_collide(result, root->right, | ||
519 | !direction, size, | ||
520 | target); | ||
521 | |||
522 | size->x -= middle; | ||
523 | size->w += middle; | ||
524 | } | ||
525 | else | ||
526 | { | ||
527 | int middle = size->h / 2; | ||
528 | |||
529 | size->h -= middle; | ||
530 | if (eina_spans_intersect(size->y, size->h, target->y, target->h)) | ||
531 | result = _eina_quadtree_collide(result, root->left, | ||
532 | !direction, size, | ||
533 | target); | ||
534 | |||
535 | size->y += middle; | ||
536 | if (eina_spans_intersect(size->y, size->h, target->y, target->h)) | ||
537 | result = _eina_quadtree_collide(result, root->right, | ||
538 | !direction, size, | ||
539 | target); | ||
540 | |||
541 | size->y -= middle; | ||
542 | size->h += middle; | ||
543 | } | ||
544 | |||
545 | return result; | ||
546 | } | ||
547 | |||
548 | static void | ||
549 | _eina_quadtree_remove(Eina_QuadTree_Item *object) | ||
550 | { | ||
551 | if (!object->root) | ||
552 | return; | ||
553 | |||
554 | object->root->both = eina_list_remove(object->root->both, object); | ||
555 | if (object->root->both) | ||
556 | goto end; | ||
557 | |||
558 | if (object->root->left) | ||
559 | goto end; | ||
560 | |||
561 | if (object->root->right) | ||
562 | goto end; | ||
563 | |||
564 | /* The root is not useful anymore... */ | ||
565 | if (object->root->parent) | ||
566 | { | ||
567 | if (object->root->parent->left == object->root) | ||
568 | object->root->parent->left = NULL; | ||
569 | else | ||
570 | object->root->parent->right = NULL; | ||
571 | |||
572 | object->root->parent = NULL; | ||
573 | } | ||
574 | else | ||
575 | object->quad->root = NULL; | ||
576 | |||
577 | if (object->quad->root_count > 50) | ||
578 | eina_mempool_free(eina_quadtree_root_mp, object->root); | ||
579 | else | ||
580 | { | ||
581 | eina_trash_push(&object->quad->root_trash, object->root); | ||
582 | object->quad->root_count++; | ||
583 | } | ||
584 | |||
585 | end: | ||
586 | object->root = NULL; | ||
587 | } | ||
588 | |||
589 | EAPI Eina_QuadTree * | ||
590 | eina_quadtree_new(size_t w, size_t h, | ||
591 | Eina_Quad_Callback vertical, Eina_Quad_Callback horizontal) | ||
592 | { | ||
593 | Eina_QuadTree *result; | ||
594 | |||
595 | if (!vertical || !horizontal || h == 0 || w == 0) | ||
596 | return NULL; | ||
597 | |||
598 | result = calloc(1, sizeof (Eina_QuadTree)); | ||
599 | if (!result) | ||
600 | return NULL; | ||
601 | |||
602 | result->func.v = vertical; | ||
603 | result->func.h = horizontal; | ||
604 | |||
605 | result->geom.w = w; | ||
606 | result->geom.h = h; | ||
607 | |||
608 | result->change = NULL; | ||
609 | |||
610 | result->lost = EINA_TRUE; | ||
611 | |||
612 | EINA_MAGIC_SET(result, EINA_MAGIC_QUADTREE); | ||
613 | |||
614 | return result; | ||
615 | } | ||
616 | |||
617 | EAPI void | ||
618 | eina_quadtree_free(Eina_QuadTree *q) | ||
619 | { | ||
620 | Eina_QuadTree_Item *item; | ||
621 | |||
622 | if (!q) | ||
623 | return; | ||
624 | |||
625 | EINA_MAGIC_CHECK_QUADTREE(q); | ||
626 | |||
627 | while (q->change) | ||
628 | { | ||
629 | item = EINA_INLIST_CONTAINER_GET(q->change, Eina_QuadTree_Item); | ||
630 | q->change = q->change->next; | ||
631 | if (!item->hidden) | ||
632 | eina_mempool_free(_eina_quadtree_items_mp, item); | ||
633 | } | ||
634 | |||
635 | EINA_LIST_FREE(q->hidden, item) | ||
636 | eina_mempool_free(_eina_quadtree_items_mp, item); | ||
637 | |||
638 | eina_quadtree_root_free(q, q->root); | ||
639 | |||
640 | while (q->items_trash) | ||
641 | { | ||
642 | item = eina_trash_pop(&q->items_trash); | ||
643 | eina_mempool_free(_eina_quadtree_items_mp, item); | ||
644 | } | ||
645 | |||
646 | while (q->root_trash) | ||
647 | { | ||
648 | Eina_QuadTree_Root *root; | ||
649 | |||
650 | root = eina_trash_pop(&q->root_trash); | ||
651 | eina_mempool_free(eina_quadtree_root_mp, root); | ||
652 | } | ||
653 | |||
654 | EINA_MAGIC_SET(q, 0); | ||
655 | free(q); | ||
656 | } | ||
657 | |||
658 | EAPI Eina_QuadTree_Item * | ||
659 | eina_quadtree_add(Eina_QuadTree *q, const void *object) | ||
660 | { | ||
661 | Eina_QuadTree_Item *result; | ||
662 | |||
663 | EINA_MAGIC_CHECK_QUADTREE(q, NULL); | ||
664 | |||
665 | if (!object) | ||
666 | return NULL; | ||
667 | |||
668 | result = eina_trash_pop(&q->items_trash); | ||
669 | if (!result) | ||
670 | result = eina_mempool_malloc(_eina_quadtree_items_mp, sizeof (Eina_QuadTree_Item)); | ||
671 | else | ||
672 | q->items_count--; | ||
673 | |||
674 | if (!result) | ||
675 | return NULL; | ||
676 | |||
677 | result->quad = q; | ||
678 | result->root = NULL; | ||
679 | result->object = object; | ||
680 | |||
681 | result->index = q->index++; | ||
682 | |||
683 | result->change = EINA_TRUE; | ||
684 | result->delete_me = EINA_FALSE; | ||
685 | result->visible = EINA_TRUE; | ||
686 | result->hidden = EINA_FALSE; | ||
687 | |||
688 | EINA_MAGIC_SET(result, EINA_MAGIC_QUADTREE_ITEM); | ||
689 | |||
690 | /* Insertion is delayed until we really need to use it */ | ||
691 | q->change = eina_inlist_append(q->change, EINA_INLIST_GET(result)); | ||
692 | |||
693 | return result; | ||
694 | } | ||
695 | |||
696 | EAPI Eina_Bool | ||
697 | eina_quadtree_del(Eina_QuadTree_Item *object) | ||
698 | { | ||
699 | if (!object) | ||
700 | return EINA_FALSE; | ||
701 | |||
702 | EINA_MAGIC_CHECK_QUADTREE_ITEM(object, EINA_FALSE); | ||
703 | |||
704 | _eina_quadtree_remove(object); | ||
705 | |||
706 | if (object->change) | ||
707 | { | ||
708 | /* This object is still in the update array, delaying it's removal !*/ | ||
709 | object->delete_me = EINA_TRUE; | ||
710 | object->visible = EINA_TRUE; | ||
711 | return EINA_TRUE; | ||
712 | } | ||
713 | |||
714 | if (object->hidden) | ||
715 | { | ||
716 | object->quad->hidden = eina_list_remove(object->quad->hidden, object); | ||
717 | object->hidden = EINA_TRUE; | ||
718 | } | ||
719 | |||
720 | /* This object is not anymore inside the tree, we can remove it now !*/ | ||
721 | EINA_MAGIC_SET(object, 0); | ||
722 | if (object->quad->items_count > 256) | ||
723 | eina_mempool_free(_eina_quadtree_items_mp, object); | ||
724 | else | ||
725 | { | ||
726 | object->quad->items_count++; | ||
727 | eina_trash_push(&object->quad->items_trash, object); | ||
728 | } | ||
729 | |||
730 | return EINA_TRUE; | ||
731 | } | ||
732 | |||
733 | EAPI Eina_Bool | ||
734 | eina_quadtree_change(Eina_QuadTree_Item *object) | ||
735 | { | ||
736 | EINA_MAGIC_CHECK_QUADTREE_ITEM(object, EINA_FALSE); | ||
737 | |||
738 | if (object->delete_me || !object->visible) | ||
739 | return EINA_FALSE; | ||
740 | |||
741 | if (object->quad->resize) | ||
742 | return EINA_TRUE; | ||
743 | |||
744 | /* Delaying change until needed */ | ||
745 | if (!object->change) | ||
746 | object->quad->change = eina_inlist_append(object->quad->change, | ||
747 | EINA_INLIST_GET(object)); | ||
748 | |||
749 | object->change = EINA_TRUE; | ||
750 | |||
751 | _eina_quadtree_remove(object); | ||
752 | |||
753 | return EINA_TRUE; | ||
754 | } | ||
755 | |||
756 | EAPI Eina_Bool | ||
757 | eina_quadtree_hide(Eina_QuadTree_Item *object) | ||
758 | { | ||
759 | EINA_MAGIC_CHECK_QUADTREE_ITEM(object, EINA_FALSE); | ||
760 | |||
761 | object->visible = EINA_FALSE; | ||
762 | |||
763 | return EINA_TRUE; | ||
764 | } | ||
765 | |||
766 | EAPI Eina_Bool | ||
767 | eina_quadtree_show(Eina_QuadTree_Item *object) | ||
768 | { | ||
769 | EINA_MAGIC_CHECK_QUADTREE_ITEM(object, EINA_FALSE); | ||
770 | |||
771 | object->quad->lost = EINA_TRUE; | ||
772 | |||
773 | if (object->visible) | ||
774 | return EINA_TRUE; | ||
775 | |||
776 | object->visible = EINA_TRUE; | ||
777 | if (!object->change) | ||
778 | return eina_quadtree_change(object); | ||
779 | |||
780 | return EINA_TRUE; | ||
781 | } | ||
782 | |||
783 | EAPI Eina_Inlist * | ||
784 | eina_quadtree_collide(Eina_QuadTree *q, int x, int y, int w, int h) | ||
785 | { | ||
786 | Eina_Rectangle canvas; | ||
787 | |||
788 | EINA_MAGIC_CHECK_QUADTREE(q, NULL); | ||
789 | |||
790 | /* Now we need the tree to be up to date, so it's time */ | ||
791 | if (q->resize) /* Full rebuild needed ! */ | ||
792 | { | ||
793 | DBG("resizing quadtree"); | ||
794 | q->root = eina_quadtree_root_rebuild_pre(q, &q->change, q->root); | ||
795 | q->resize = EINA_FALSE; | ||
796 | } | ||
797 | |||
798 | EINA_RECTANGLE_SET(&canvas, 0, 0, q->geom.w, q->geom.h); | ||
799 | |||
800 | if (q->change) | ||
801 | { | ||
802 | DBG("updating quadtree content"); | ||
803 | q->root = _eina_quadtree_update(q, NULL, q->root, q->change, | ||
804 | EINA_FALSE, &canvas); | ||
805 | q->change = NULL; | ||
806 | q->lost = EINA_TRUE; | ||
807 | } | ||
808 | |||
809 | if (q->target.x != x | ||
810 | || q->target.y != y | ||
811 | || q->target.w != w | ||
812 | || q->target.h != h) | ||
813 | { | ||
814 | DBG("new target"); | ||
815 | EINA_RECTANGLE_SET(&q->target, x, y, w, h); | ||
816 | q->lost = EINA_TRUE; | ||
817 | } | ||
818 | |||
819 | if (q->lost) | ||
820 | { | ||
821 | DBG("computing collide"); | ||
822 | q->cached = _eina_quadtree_collide(NULL, q->root, | ||
823 | EINA_FALSE, &canvas, | ||
824 | &q->target); | ||
825 | q->lost = EINA_FALSE; | ||
826 | } | ||
827 | |||
828 | return q->cached; | ||
829 | } | ||
830 | |||
831 | EAPI void * | ||
832 | eina_quadtree_object(Eina_Inlist *item) | ||
833 | { | ||
834 | Eina_QuadTree_Item *qi; | ||
835 | |||
836 | if (!item) | ||
837 | return NULL; | ||
838 | |||
839 | qi = EINA_INLIST_CONTAINER_GET(item, Eina_QuadTree_Item); | ||
840 | if (!qi) | ||
841 | return NULL; | ||
842 | |||
843 | EINA_MAGIC_CHECK_QUADTREE_ITEM(qi, NULL); | ||
844 | |||
845 | if (!qi->visible) | ||
846 | return NULL; | ||
847 | |||
848 | return (void *)qi->object; | ||
849 | } | ||
850 | |||
851 | EAPI void | ||
852 | eina_quadtree_resize(Eina_QuadTree *q, size_t w, size_t h) | ||
853 | { | ||
854 | EINA_MAGIC_CHECK_QUADTREE(q); | ||
855 | |||
856 | if (q->geom.w == w | ||
857 | && q->geom.h == h) | ||
858 | return; | ||
859 | |||
860 | q->resize = EINA_TRUE; | ||
861 | q->geom.w = w; | ||
862 | q->geom.h = h; | ||
863 | } | ||
864 | |||
865 | EAPI void | ||
866 | eina_quadtree_cycle(Eina_QuadTree *q) | ||
867 | { | ||
868 | EINA_MAGIC_CHECK_QUADTREE(q); | ||
869 | |||
870 | q->index = 0; | ||
871 | } | ||
872 | |||
873 | EAPI void | ||
874 | eina_quadtree_increase(Eina_QuadTree_Item *object) | ||
875 | { | ||
876 | size_t tmp; | ||
877 | |||
878 | tmp = object->quad->index++; | ||
879 | if (object->index == tmp) | ||
880 | return; | ||
881 | |||
882 | object->index = tmp; | ||
883 | if (object->root) | ||
884 | object->root->sorted = EINA_FALSE; | ||
885 | } | ||
886 | |||
887 | Eina_Bool | ||
888 | eina_quadtree_init(void) | ||
889 | { | ||
890 | const char *choice, *tmp; | ||
891 | |||
892 | _eina_quadtree_log_dom = eina_log_domain_register("eina_quadtree", | ||
893 | EINA_LOG_COLOR_DEFAULT); | ||
894 | if (_eina_quadtree_log_dom < 0) | ||
895 | { | ||
896 | EINA_LOG_ERR("Could not register log domain: eina_quadtree"); | ||
897 | return EINA_FALSE; | ||
898 | } | ||
899 | |||
900 | #define EMS(n) eina_magic_string_static_set(n, n ## _STR) | ||
901 | EMS(EINA_MAGIC_QUADTREE); | ||
902 | EMS(EINA_MAGIC_QUADTREE_ROOT); | ||
903 | EMS(EINA_MAGIC_QUADTREE_ITEM); | ||
904 | #undef EMS | ||
905 | |||
906 | #ifdef EINA_DEFAULT_MEMPOOL | ||
907 | choice = "pass_through"; | ||
908 | #else | ||
909 | choice = "chained_mempool"; | ||
910 | #endif | ||
911 | tmp = getenv("EINA_MEMPOOL"); | ||
912 | if (tmp && tmp[0]) | ||
913 | choice = tmp; | ||
914 | |||
915 | _eina_quadtree_items_mp = eina_mempool_add(choice, "QuadTree Item", NULL, | ||
916 | sizeof (Eina_QuadTree_Item), 320); | ||
917 | eina_quadtree_root_mp = eina_mempool_add(choice, "QuadTree Root", NULL, | ||
918 | sizeof (Eina_QuadTree_Root), 32); | ||
919 | |||
920 | return EINA_TRUE; | ||
921 | } | ||
922 | |||
923 | Eina_Bool | ||
924 | eina_quadtree_shutdown(void) | ||
925 | { | ||
926 | eina_mempool_del(eina_quadtree_root_mp); | ||
927 | eina_mempool_del(_eina_quadtree_items_mp); | ||
928 | |||
929 | eina_log_domain_unregister(_eina_quadtree_log_dom); | ||
930 | _eina_quadtree_log_dom = -1; | ||
931 | return EINA_TRUE; | ||
932 | } | ||
933 | |||
934 | |||
935 | |||
diff --git a/libraries/eina/src/lib/eina_rbtree.c b/libraries/eina/src/lib/eina_rbtree.c deleted file mode 100644 index a9d777a..0000000 --- a/libraries/eina/src/lib/eina_rbtree.c +++ /dev/null | |||
@@ -1,519 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Cedric Bail | ||
3 | * Copyright (C) 2011 Alexandre Becoulet | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Lesser General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2.1 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This library is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * Lesser General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Lesser General Public | ||
16 | * License along with this library; | ||
17 | * if not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #ifdef HAVE_CONFIG_H | ||
21 | # include "config.h" | ||
22 | #endif | ||
23 | |||
24 | #include <stdlib.h> | ||
25 | #include <stdio.h> | ||
26 | #include <string.h> | ||
27 | #include <stdint.h> | ||
28 | |||
29 | #include "eina_config.h" | ||
30 | #include "eina_private.h" | ||
31 | #include "eina_array.h" | ||
32 | |||
33 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
34 | #include "eina_safety_checks.h" | ||
35 | #include "eina_rbtree.h" | ||
36 | |||
37 | /*============================================================================* | ||
38 | * Local * | ||
39 | *============================================================================*/ | ||
40 | |||
41 | #define EINA_RBTREE_ITERATOR_PREFIX_MASK 0x1 | ||
42 | #define EINA_RBTREE_ITERATOR_INFIX_MASK 0x2 | ||
43 | #define EINA_RBTREE_ITERATOR_POSTFIX_MASK 0x4 | ||
44 | |||
45 | typedef struct _Eina_Iterator_Rbtree Eina_Iterator_Rbtree; | ||
46 | typedef struct _Eina_Iterator_Rbtree_List Eina_Iterator_Rbtree_List; | ||
47 | |||
48 | struct _Eina_Iterator_Rbtree | ||
49 | { | ||
50 | Eina_Iterator iterator; | ||
51 | |||
52 | Eina_Array *stack; | ||
53 | |||
54 | unsigned char mask; | ||
55 | }; | ||
56 | |||
57 | struct _Eina_Iterator_Rbtree_List | ||
58 | { | ||
59 | Eina_Rbtree *tree; | ||
60 | |||
61 | Eina_Rbtree_Direction dir : 1; | ||
62 | Eina_Bool up : 1; | ||
63 | }; | ||
64 | |||
65 | static Eina_Iterator_Rbtree_List * | ||
66 | _eina_rbtree_iterator_list_new(const Eina_Rbtree *tree) | ||
67 | { | ||
68 | Eina_Iterator_Rbtree_List *new; | ||
69 | |||
70 | eina_error_set(0); | ||
71 | new = malloc(sizeof (Eina_Iterator_Rbtree_List)); | ||
72 | if (!new) | ||
73 | { | ||
74 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
75 | return NULL; | ||
76 | } | ||
77 | |||
78 | new->tree = (Eina_Rbtree *)tree; | ||
79 | new->dir = EINA_RBTREE_RIGHT; | ||
80 | new->up = EINA_FALSE; | ||
81 | |||
82 | return new; | ||
83 | } | ||
84 | |||
85 | static Eina_Rbtree * | ||
86 | _eina_rbtree_iterator_get_content(Eina_Iterator_Rbtree *it) | ||
87 | { | ||
88 | if (eina_array_count(it->stack) <= 0) | ||
89 | return NULL; | ||
90 | |||
91 | return eina_array_data_get(it->stack, 0); | ||
92 | } | ||
93 | |||
94 | static void | ||
95 | _eina_rbtree_iterator_free(Eina_Iterator_Rbtree *it) | ||
96 | { | ||
97 | Eina_Iterator_Rbtree_List *item; | ||
98 | Eina_Array_Iterator et; | ||
99 | unsigned int i; | ||
100 | |||
101 | EINA_ARRAY_ITER_NEXT(it->stack, i, item, et) | ||
102 | free(item); | ||
103 | |||
104 | eina_array_free(it->stack); | ||
105 | free(it); | ||
106 | } | ||
107 | |||
108 | static Eina_Bool | ||
109 | _eina_rbtree_iterator_next(Eina_Iterator_Rbtree *it, void **data) | ||
110 | { | ||
111 | Eina_Iterator_Rbtree_List *last; | ||
112 | Eina_Iterator_Rbtree_List *new; | ||
113 | Eina_Rbtree *tree; | ||
114 | |||
115 | if (eina_array_count(it->stack) <= 0) | ||
116 | return EINA_FALSE; | ||
117 | |||
118 | last = eina_array_data_get(it->stack, eina_array_count(it->stack) - 1); | ||
119 | tree = last->tree; | ||
120 | |||
121 | if (!last->tree || last->up == EINA_TRUE) | ||
122 | { | ||
123 | last = eina_array_pop(it->stack); | ||
124 | while (last->dir == EINA_RBTREE_LEFT | ||
125 | || !last->tree) | ||
126 | { | ||
127 | if (tree) | ||
128 | if ((it->mask & EINA_RBTREE_ITERATOR_POSTFIX_MASK) == | ||
129 | EINA_RBTREE_ITERATOR_POSTFIX_MASK) | ||
130 | { | ||
131 | free(last); | ||
132 | |||
133 | if (eina_array_count(it->stack) > 0) | ||
134 | { | ||
135 | last = eina_array_data_get(it->stack, | ||
136 | eina_array_count( | ||
137 | it-> | ||
138 | stack) | ||
139 | - 1); | ||
140 | last->up = EINA_TRUE; | ||
141 | } | ||
142 | |||
143 | goto onfix; | ||
144 | } | ||
145 | |||
146 | free(last); | ||
147 | |||
148 | last = eina_array_pop(it->stack); | ||
149 | if (!last) | ||
150 | return EINA_FALSE; | ||
151 | |||
152 | tree = last->tree; | ||
153 | } | ||
154 | |||
155 | last->dir = EINA_RBTREE_LEFT; | ||
156 | last->up = EINA_FALSE; | ||
157 | |||
158 | eina_array_push(it->stack, last); | ||
159 | |||
160 | if ((it->mask & EINA_RBTREE_ITERATOR_INFIX_MASK) == | ||
161 | EINA_RBTREE_ITERATOR_INFIX_MASK) | ||
162 | goto onfix; | ||
163 | } | ||
164 | |||
165 | new = _eina_rbtree_iterator_list_new(last->tree->son[last->dir]); | ||
166 | if (!new) | ||
167 | return EINA_FALSE; | ||
168 | |||
169 | eina_array_push(it->stack, new); | ||
170 | |||
171 | if (last->dir == EINA_RBTREE_RIGHT) | ||
172 | if ((it->mask & EINA_RBTREE_ITERATOR_PREFIX_MASK) == | ||
173 | EINA_RBTREE_ITERATOR_PREFIX_MASK) | ||
174 | goto onfix; | ||
175 | |||
176 | return _eina_rbtree_iterator_next(it, data); | ||
177 | |||
178 | onfix: | ||
179 | *data = tree; | ||
180 | return EINA_TRUE; | ||
181 | } | ||
182 | |||
183 | static Eina_Iterator * | ||
184 | _eina_rbtree_iterator_build(const Eina_Rbtree *root, unsigned char mask) | ||
185 | { | ||
186 | Eina_Iterator_Rbtree_List *first; | ||
187 | Eina_Iterator_Rbtree *it; | ||
188 | |||
189 | eina_error_set(0); | ||
190 | it = calloc(1, sizeof (Eina_Iterator_Rbtree)); | ||
191 | if (!it) | ||
192 | { | ||
193 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
194 | return NULL; | ||
195 | } | ||
196 | |||
197 | it->stack = eina_array_new(8); | ||
198 | if (!it->stack) | ||
199 | goto on_error2; | ||
200 | |||
201 | first = _eina_rbtree_iterator_list_new(root); | ||
202 | if (!first) | ||
203 | goto on_error; | ||
204 | |||
205 | eina_array_push(it->stack, first); | ||
206 | |||
207 | it->mask = mask; | ||
208 | |||
209 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
210 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_rbtree_iterator_next); | ||
211 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
212 | _eina_rbtree_iterator_get_content); | ||
213 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_rbtree_iterator_free); | ||
214 | |||
215 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
216 | |||
217 | return &it->iterator; | ||
218 | |||
219 | on_error: | ||
220 | eina_array_free(it->stack); | ||
221 | on_error2: | ||
222 | free(it); | ||
223 | |||
224 | return NULL; | ||
225 | } | ||
226 | |||
227 | static void | ||
228 | _eina_rbtree_node_init(Eina_Rbtree *node) | ||
229 | { | ||
230 | if (!node) | ||
231 | return; | ||
232 | |||
233 | node->son[0] = NULL; | ||
234 | node->son[1] = NULL; | ||
235 | |||
236 | node->color = EINA_RBTREE_RED; | ||
237 | } | ||
238 | |||
239 | static inline Eina_Bool | ||
240 | _eina_rbtree_is_red(Eina_Rbtree *node) | ||
241 | { | ||
242 | return !!node && node->color == EINA_RBTREE_RED; | ||
243 | } | ||
244 | |||
245 | static inline Eina_Rbtree * | ||
246 | _eina_rbtree_inline_single_rotation(Eina_Rbtree *node, | ||
247 | Eina_Rbtree_Direction dir) | ||
248 | { | ||
249 | Eina_Rbtree *save = node->son[dir ^ 1]; | ||
250 | |||
251 | node->son[dir ^ 1] = save->son[dir]; | ||
252 | save->son[dir] = node; | ||
253 | |||
254 | node->color = EINA_RBTREE_RED; | ||
255 | save->color = EINA_RBTREE_BLACK; | ||
256 | |||
257 | return save; | ||
258 | } | ||
259 | |||
260 | static inline Eina_Rbtree * | ||
261 | _eina_rbtree_inline_double_rotation(Eina_Rbtree *node, | ||
262 | Eina_Rbtree_Direction dir) | ||
263 | { | ||
264 | node->son[dir ^ 1] = _eina_rbtree_inline_single_rotation(node->son[dir ^ 1], dir ^ 1); | ||
265 | return _eina_rbtree_inline_single_rotation(node, dir); | ||
266 | } | ||
267 | |||
268 | /*============================================================================* | ||
269 | * Global * | ||
270 | *============================================================================*/ | ||
271 | |||
272 | /*============================================================================* | ||
273 | * API * | ||
274 | *============================================================================*/ | ||
275 | |||
276 | EAPI Eina_Rbtree * | ||
277 | eina_rbtree_inline_insert(Eina_Rbtree *root, | ||
278 | Eina_Rbtree *node, | ||
279 | Eina_Rbtree_Cmp_Node_Cb cmp, | ||
280 | const void *data) | ||
281 | { | ||
282 | Eina_Rbtree **r = &root; | ||
283 | Eina_Rbtree *q = root; | ||
284 | uintptr_t stack[48]; | ||
285 | unsigned int s = 0; | ||
286 | |||
287 | EINA_SAFETY_ON_NULL_RETURN_VAL(node, root); | ||
288 | EINA_SAFETY_ON_NULL_RETURN_VAL( cmp, root); | ||
289 | |||
290 | /* Find insertion leaf */ | ||
291 | while (q != NULL) | ||
292 | { | ||
293 | Eina_Rbtree_Direction dir = cmp(q, node, (void *)data); | ||
294 | |||
295 | /* Keep path in stack */ | ||
296 | stack[s++] = (uintptr_t)r | dir; | ||
297 | |||
298 | r = q->son + dir; | ||
299 | q = *r; | ||
300 | } | ||
301 | |||
302 | /* Insert */ | ||
303 | *r = node; | ||
304 | _eina_rbtree_node_init(node); | ||
305 | |||
306 | /* Rebalance */ | ||
307 | while (s > 0) | ||
308 | { | ||
309 | Eina_Rbtree *a, *b; | ||
310 | uintptr_t top = stack[--s]; /* Pop link pointer and direction */ | ||
311 | Eina_Rbtree_Direction dir = top & 1; | ||
312 | |||
313 | r = (Eina_Rbtree **)(top & ~(uintptr_t)1); | ||
314 | q = *r; | ||
315 | |||
316 | a = q->son[dir]; | ||
317 | /* Rebalance done ? */ | ||
318 | if (a == NULL || a->color == EINA_RBTREE_BLACK) | ||
319 | break; | ||
320 | |||
321 | b = q->son[dir ^ 1]; | ||
322 | if (b != NULL && b->color == EINA_RBTREE_RED) | ||
323 | { | ||
324 | q->color = EINA_RBTREE_RED; | ||
325 | b->color = a->color = EINA_RBTREE_BLACK; | ||
326 | } | ||
327 | else | ||
328 | { | ||
329 | Eina_Rbtree *c = a->son[dir]; | ||
330 | Eina_Rbtree *d = a->son[dir ^ 1]; | ||
331 | |||
332 | if (c != NULL && c->color == EINA_RBTREE_RED) | ||
333 | *r = _eina_rbtree_inline_single_rotation(*r, dir ^ 1); | ||
334 | else if (d != NULL && d->color == EINA_RBTREE_RED) | ||
335 | *r = _eina_rbtree_inline_double_rotation(*r, dir ^ 1); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | root->color = EINA_RBTREE_BLACK; | ||
340 | return root; | ||
341 | } | ||
342 | |||
343 | EAPI Eina_Rbtree * | ||
344 | eina_rbtree_inline_remove(Eina_Rbtree *root, | ||
345 | Eina_Rbtree *node, | ||
346 | Eina_Rbtree_Cmp_Node_Cb cmp, | ||
347 | const void *data) | ||
348 | { | ||
349 | Eina_Rbtree *l0, *l1, *r, **rt = &root; | ||
350 | Eina_Rbtree_Direction dir; | ||
351 | uintptr_t stack[48]; | ||
352 | unsigned int s = 0; | ||
353 | |||
354 | EINA_SAFETY_ON_NULL_RETURN_VAL(node, root); | ||
355 | EINA_SAFETY_ON_NULL_RETURN_VAL( cmp, root); | ||
356 | |||
357 | /* Item search loop */ | ||
358 | for (r = *rt; r != NULL; r = *rt) | ||
359 | { | ||
360 | if (r == node) | ||
361 | goto found; | ||
362 | |||
363 | dir = cmp(r, node, (void*)data); | ||
364 | stack[s++] = (uintptr_t)rt | dir; | ||
365 | rt = r->son + dir; | ||
366 | } | ||
367 | return root; | ||
368 | |||
369 | found: | ||
370 | /* remove entry */ | ||
371 | l0 = node->son[0]; | ||
372 | l1 = node->son[1]; | ||
373 | |||
374 | if (l0 != NULL && l1 != NULL) /* two links case */ | ||
375 | { | ||
376 | Eina_Rbtree *q, **t, **p; | ||
377 | uintptr_t ss; | ||
378 | |||
379 | stack[s++] = (uintptr_t)rt | 1; | ||
380 | ss = s; /* keep predecessor right link stack index */ | ||
381 | |||
382 | /* find predecessor */ | ||
383 | p = node->son + 1; | ||
384 | q = *p; | ||
385 | |||
386 | while (1) | ||
387 | { | ||
388 | t = q->son; | ||
389 | q = *t; | ||
390 | if (q == NULL) | ||
391 | break; | ||
392 | stack[s++] = (uintptr_t)p | 0; | ||
393 | p = t; | ||
394 | } | ||
395 | |||
396 | /* detach predecessor */ | ||
397 | q = *p; | ||
398 | *p = q->son[1]; | ||
399 | |||
400 | int c = q->color; | ||
401 | |||
402 | /* replace entry by predecessor */ | ||
403 | memcpy(q, node, sizeof(Eina_Rbtree)); | ||
404 | *rt = q; | ||
405 | |||
406 | if (c == EINA_RBTREE_RED) | ||
407 | goto end; | ||
408 | |||
409 | /* fix stack for replaced entry */ | ||
410 | if (s > ss) | ||
411 | stack[ss] = (uintptr_t)(q->son + 1) | 0; | ||
412 | } | ||
413 | else /* single link case */ | ||
414 | { | ||
415 | if (l0 == NULL) | ||
416 | l0 = l1; | ||
417 | |||
418 | *rt = l0; | ||
419 | |||
420 | if (node->color == EINA_RBTREE_RED) | ||
421 | goto end; /* removed red */ | ||
422 | |||
423 | if (l0 != NULL && l0->color == EINA_RBTREE_RED) | ||
424 | { | ||
425 | /* red child replace removed black */ | ||
426 | l0->color = EINA_RBTREE_BLACK; | ||
427 | goto end; | ||
428 | } | ||
429 | } | ||
430 | |||
431 | /* rebalance */ | ||
432 | while (s > 0) | ||
433 | { | ||
434 | Eina_Rbtree *q; | ||
435 | uintptr_t st = stack[--s]; | ||
436 | |||
437 | rt = (Eina_Rbtree**)(st & ~(uintptr_t)1); | ||
438 | dir = st & 1; | ||
439 | r = *rt; | ||
440 | q = r->son[dir ^ 1]; | ||
441 | |||
442 | if (q != NULL && q->color == EINA_RBTREE_RED) | ||
443 | { | ||
444 | *rt = _eina_rbtree_inline_single_rotation(*rt, dir); | ||
445 | q = r->son[dir ^ 1]; | ||
446 | rt = (*rt)->son + dir; | ||
447 | } | ||
448 | |||
449 | if (q != NULL) | ||
450 | { | ||
451 | int r_color = r->color; | ||
452 | Eina_Rbtree *nd = q->son[dir ^ 1]; | ||
453 | |||
454 | if (nd != NULL && nd->color == EINA_RBTREE_RED) | ||
455 | { | ||
456 | *rt = _eina_rbtree_inline_single_rotation(*rt, dir); | ||
457 | } | ||
458 | else | ||
459 | { | ||
460 | Eina_Rbtree *d = q->son[dir]; | ||
461 | |||
462 | if (d != NULL && d->color == EINA_RBTREE_RED) | ||
463 | { | ||
464 | *rt = _eina_rbtree_inline_double_rotation(*rt, dir); | ||
465 | } | ||
466 | else | ||
467 | { | ||
468 | r->color = EINA_RBTREE_BLACK; | ||
469 | q->color = EINA_RBTREE_RED; | ||
470 | if (r_color == EINA_RBTREE_RED) | ||
471 | break; | ||
472 | continue; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | r = *rt; | ||
477 | r->color = r_color; | ||
478 | r->son[1]->color = r->son[0]->color = EINA_RBTREE_BLACK; | ||
479 | |||
480 | break; | ||
481 | } | ||
482 | } | ||
483 | |||
484 | end: | ||
485 | if (root != NULL) | ||
486 | root->color = EINA_RBTREE_BLACK; | ||
487 | return root; | ||
488 | } | ||
489 | |||
490 | EAPI Eina_Iterator * | ||
491 | eina_rbtree_iterator_prefix(const Eina_Rbtree *root) | ||
492 | { | ||
493 | return _eina_rbtree_iterator_build(root, EINA_RBTREE_ITERATOR_PREFIX_MASK); | ||
494 | } | ||
495 | |||
496 | EAPI Eina_Iterator * | ||
497 | eina_rbtree_iterator_infix(const Eina_Rbtree *root) | ||
498 | { | ||
499 | return _eina_rbtree_iterator_build(root, EINA_RBTREE_ITERATOR_INFIX_MASK); | ||
500 | } | ||
501 | |||
502 | EAPI Eina_Iterator * | ||
503 | eina_rbtree_iterator_postfix(const Eina_Rbtree *root) | ||
504 | { | ||
505 | return _eina_rbtree_iterator_build(root, EINA_RBTREE_ITERATOR_POSTFIX_MASK); | ||
506 | } | ||
507 | |||
508 | EAPI void | ||
509 | eina_rbtree_delete(Eina_Rbtree *root, Eina_Rbtree_Free_Cb func, void *data) | ||
510 | { | ||
511 | if (!root) | ||
512 | return; | ||
513 | |||
514 | EINA_SAFETY_ON_NULL_RETURN(func); | ||
515 | |||
516 | eina_rbtree_delete(root->son[0], func, data); | ||
517 | eina_rbtree_delete(root->son[1], func, data); | ||
518 | func(root, data); | ||
519 | } | ||
diff --git a/libraries/eina/src/lib/eina_rectangle.c b/libraries/eina/src/lib/eina_rectangle.c deleted file mode 100644 index 7f0a619..0000000 --- a/libraries/eina/src/lib/eina_rectangle.c +++ /dev/null | |||
@@ -1,568 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2007-2008 Cedric BAIL, Carsten Haitzler | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | |||
26 | #ifdef HAVE_EVIL | ||
27 | # include <Evil.h> | ||
28 | #endif | ||
29 | |||
30 | #include "eina_config.h" | ||
31 | #include "eina_private.h" | ||
32 | #include "eina_magic.h" | ||
33 | #include "eina_inlist.h" | ||
34 | #include "eina_mempool.h" | ||
35 | #include "eina_list.h" | ||
36 | #include "eina_trash.h" | ||
37 | #include "eina_log.h" | ||
38 | |||
39 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
40 | #include "eina_safety_checks.h" | ||
41 | #include "eina_rectangle.h" | ||
42 | |||
43 | /*============================================================================* | ||
44 | * Local * | ||
45 | *============================================================================*/ | ||
46 | |||
47 | /** | ||
48 | * @cond LOCAL | ||
49 | */ | ||
50 | |||
51 | #define EINA_RECTANGLE_POOL_MAGIC 0x1578FCB0 | ||
52 | #define EINA_RECTANGLE_ALLOC_MAGIC 0x1578FCB1 | ||
53 | |||
54 | #define BUCKET_THRESHOLD 110 | ||
55 | |||
56 | typedef struct _Eina_Rectangle_Alloc Eina_Rectangle_Alloc; | ||
57 | |||
58 | struct _Eina_Rectangle_Pool | ||
59 | { | ||
60 | Eina_Inlist *head; | ||
61 | Eina_List *empty; | ||
62 | void *data; | ||
63 | |||
64 | Eina_Trash *bucket; | ||
65 | unsigned int bucket_count; | ||
66 | |||
67 | unsigned int references; | ||
68 | int w; | ||
69 | int h; | ||
70 | |||
71 | Eina_Bool sorted; | ||
72 | EINA_MAGIC | ||
73 | }; | ||
74 | |||
75 | struct _Eina_Rectangle_Alloc | ||
76 | { | ||
77 | EINA_INLIST; | ||
78 | Eina_Rectangle_Pool *pool; | ||
79 | EINA_MAGIC | ||
80 | }; | ||
81 | |||
82 | #define EINA_MAGIC_CHECK_RECTANGLE_POOL(d) \ | ||
83 | do { \ | ||
84 | if (!EINA_MAGIC_CHECK((d), EINA_RECTANGLE_POOL_MAGIC)) { \ | ||
85 | EINA_MAGIC_FAIL((d), EINA_RECTANGLE_POOL_MAGIC); } \ | ||
86 | } while (0) | ||
87 | |||
88 | #define EINA_MAGIC_CHECK_RECTANGLE_ALLOC(d) \ | ||
89 | do { \ | ||
90 | if (!EINA_MAGIC_CHECK((d), EINA_RECTANGLE_ALLOC_MAGIC)) { \ | ||
91 | EINA_MAGIC_FAIL((d), EINA_RECTANGLE_ALLOC_MAGIC); } \ | ||
92 | } while (0) | ||
93 | |||
94 | static Eina_Mempool *_eina_rectangle_alloc_mp = NULL; | ||
95 | static Eina_Mempool *_eina_rectangle_mp = NULL; | ||
96 | |||
97 | static Eina_Trash *_eina_rectangles = NULL; | ||
98 | static unsigned int _eina_rectangles_count = 0; | ||
99 | static int _eina_rectangle_log_dom = -1; | ||
100 | |||
101 | #ifdef ERR | ||
102 | #undef ERR | ||
103 | #endif | ||
104 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_rectangle_log_dom, __VA_ARGS__) | ||
105 | |||
106 | #ifdef DBG | ||
107 | #undef DBG | ||
108 | #endif | ||
109 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_rectangle_log_dom, __VA_ARGS__) | ||
110 | |||
111 | static int | ||
112 | _eina_rectangle_cmp(const Eina_Rectangle *r1, const Eina_Rectangle *r2) | ||
113 | { | ||
114 | return (r2->w * r2->h) - (r1->w * r1->h); | ||
115 | } | ||
116 | |||
117 | static Eina_List * | ||
118 | _eina_rectangle_merge_list(Eina_List *empty, Eina_Rectangle *r) | ||
119 | { | ||
120 | Eina_Rectangle *match; | ||
121 | Eina_List *l; | ||
122 | int xw; | ||
123 | int yh; | ||
124 | |||
125 | if (r->w == 0 || r->h == 0) | ||
126 | { | ||
127 | eina_rectangle_free(r); | ||
128 | return empty; | ||
129 | } | ||
130 | |||
131 | start_again: | ||
132 | xw = r->x + r->w; | ||
133 | yh = r->y + r->h; | ||
134 | |||
135 | EINA_LIST_FOREACH(empty, l, match) | ||
136 | { | ||
137 | if (match->x == r->x && match->w == r->w | ||
138 | && (match->y == yh || r->y == match->y + match->h)) | ||
139 | { | ||
140 | if (match->y > r->y) | ||
141 | match->y = r->y; | ||
142 | |||
143 | match->h += r->h; | ||
144 | |||
145 | eina_rectangle_free(r); | ||
146 | |||
147 | empty = eina_list_remove_list(empty, l); | ||
148 | |||
149 | r = match; | ||
150 | |||
151 | goto start_again; | ||
152 | } | ||
153 | else if (match->y == r->y && match->h == r->h | ||
154 | && (match->x == xw || r->x == match->x + match->w)) | ||
155 | { | ||
156 | if (match->x > r->x) | ||
157 | match->x = r->x; | ||
158 | |||
159 | match->w += r->w; | ||
160 | |||
161 | eina_rectangle_free(r); | ||
162 | |||
163 | empty = eina_list_remove_list(empty, l); | ||
164 | |||
165 | r = match; | ||
166 | |||
167 | goto start_again; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | return eina_list_append(empty, r); | ||
172 | } | ||
173 | |||
174 | static Eina_List * | ||
175 | _eina_rectangle_empty_space_find(Eina_List *empty, int w, int h, int *x, int *y) | ||
176 | { | ||
177 | Eina_Rectangle *r; | ||
178 | Eina_List *l; | ||
179 | |||
180 | EINA_LIST_FOREACH(empty, l, r) | ||
181 | { | ||
182 | if (r->w >= w && r->h >= h) | ||
183 | { | ||
184 | /* Remove l from empty */ | ||
185 | empty = eina_list_remove_list(empty, l); | ||
186 | /* Remember x and y */ | ||
187 | *x = r->x; | ||
188 | *y = r->y; | ||
189 | /* Split r in 2 rectangle if needed (only the empty one) and insert them */ | ||
190 | if (r->w == w) | ||
191 | { | ||
192 | r->y += h; | ||
193 | r->h -= h; | ||
194 | } | ||
195 | else if (r->h == h) | ||
196 | { | ||
197 | r->x += w; | ||
198 | r->w -= w; | ||
199 | } | ||
200 | else | ||
201 | { | ||
202 | int rx1, ry1, rw1, rh1; | ||
203 | int x2, y2, w2, h2; | ||
204 | |||
205 | rx1 = r->x + w; | ||
206 | ry1 = r->y; | ||
207 | rw1 = r->w - w; | ||
208 | /* h1 could be h or r->h */ | ||
209 | x2 = r->x; | ||
210 | y2 = r->y + h; | ||
211 | /* w2 could be w or r->w */ | ||
212 | h2 = r->h - h; | ||
213 | |||
214 | if (rw1 * r->h > h2 * r->w) | ||
215 | { | ||
216 | rh1 = r->h; | ||
217 | w2 = w; | ||
218 | } | ||
219 | else | ||
220 | { | ||
221 | rh1 = h; | ||
222 | w2 = r->w; | ||
223 | } | ||
224 | |||
225 | EINA_RECTANGLE_SET(r, rx1, ry1, rw1, rh1); | ||
226 | empty = _eina_rectangle_merge_list(empty, r); | ||
227 | |||
228 | r = eina_rectangle_new(x2, y2, w2, h2); | ||
229 | } | ||
230 | |||
231 | if (r) | ||
232 | { | ||
233 | empty = _eina_rectangle_merge_list(empty, r); /* Return empty */ | ||
234 | |||
235 | } | ||
236 | |||
237 | return empty; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | *x = -1; | ||
242 | *y = -1; | ||
243 | return empty; | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * @endcond | ||
248 | */ | ||
249 | |||
250 | /*============================================================================* | ||
251 | * Global * | ||
252 | *============================================================================*/ | ||
253 | |||
254 | Eina_Bool | ||
255 | eina_rectangle_init(void) | ||
256 | { | ||
257 | const char *choice, *tmp; | ||
258 | |||
259 | _eina_rectangle_log_dom = eina_log_domain_register("eina_rectangle", | ||
260 | EINA_LOG_COLOR_DEFAULT); | ||
261 | if (_eina_rectangle_log_dom < 0) | ||
262 | { | ||
263 | EINA_LOG_ERR("Could not register log domain: eina_rectangle"); | ||
264 | return EINA_FALSE; | ||
265 | } | ||
266 | |||
267 | #ifdef EINA_DEFAULT_MEMPOOL | ||
268 | choice = "pass_through"; | ||
269 | #else | ||
270 | choice = "chained_mempool"; | ||
271 | #endif | ||
272 | tmp = getenv("EINA_MEMPOOL"); | ||
273 | if (tmp && tmp[0]) | ||
274 | choice = tmp; | ||
275 | |||
276 | _eina_rectangle_alloc_mp = eina_mempool_add | ||
277 | (choice, "rectangle-alloc", NULL, | ||
278 | sizeof(Eina_Rectangle_Alloc) + sizeof(Eina_Rectangle), 1024); | ||
279 | if (!_eina_rectangle_alloc_mp) | ||
280 | { | ||
281 | ERR("Mempool for rectangle cannot be allocated in rectangle init."); | ||
282 | goto init_error; | ||
283 | } | ||
284 | |||
285 | _eina_rectangle_mp = eina_mempool_add | ||
286 | (choice, "rectangle", NULL, sizeof(Eina_Rectangle), 256); | ||
287 | if (!_eina_rectangle_mp) | ||
288 | { | ||
289 | ERR("Mempool for rectangle cannot be allocated in rectangle init."); | ||
290 | goto init_error; | ||
291 | } | ||
292 | |||
293 | return EINA_TRUE; | ||
294 | |||
295 | init_error: | ||
296 | eina_log_domain_unregister(_eina_rectangle_log_dom); | ||
297 | _eina_rectangle_log_dom = -1; | ||
298 | |||
299 | return EINA_FALSE; | ||
300 | } | ||
301 | |||
302 | Eina_Bool | ||
303 | eina_rectangle_shutdown(void) | ||
304 | { | ||
305 | Eina_Rectangle *del; | ||
306 | |||
307 | while ((del = eina_trash_pop(&_eina_rectangles))) | ||
308 | eina_mempool_free(_eina_rectangle_mp, del); | ||
309 | _eina_rectangles_count = 0; | ||
310 | |||
311 | eina_mempool_del(_eina_rectangle_alloc_mp); | ||
312 | eina_mempool_del(_eina_rectangle_mp); | ||
313 | |||
314 | eina_log_domain_unregister(_eina_rectangle_log_dom); | ||
315 | _eina_rectangle_log_dom = -1; | ||
316 | |||
317 | return EINA_TRUE; | ||
318 | } | ||
319 | |||
320 | /*============================================================================* | ||
321 | * API * | ||
322 | *============================================================================*/ | ||
323 | |||
324 | EAPI Eina_Rectangle * | ||
325 | eina_rectangle_new(int x, int y, int w, int h) | ||
326 | { | ||
327 | Eina_Rectangle *rect; | ||
328 | |||
329 | if (_eina_rectangles) | ||
330 | { | ||
331 | rect = eina_trash_pop(&_eina_rectangles); | ||
332 | _eina_rectangles_count--; | ||
333 | } | ||
334 | else | ||
335 | rect = eina_mempool_malloc(_eina_rectangle_mp, sizeof (Eina_Rectangle)); | ||
336 | |||
337 | if (!rect) | ||
338 | return NULL; | ||
339 | |||
340 | EINA_RECTANGLE_SET(rect, x, y, w, h); | ||
341 | |||
342 | return rect; | ||
343 | } | ||
344 | |||
345 | EAPI void | ||
346 | eina_rectangle_free(Eina_Rectangle *rect) | ||
347 | { | ||
348 | EINA_SAFETY_ON_NULL_RETURN(rect); | ||
349 | |||
350 | if (_eina_rectangles_count > BUCKET_THRESHOLD) | ||
351 | eina_mempool_free(_eina_rectangle_mp, rect); | ||
352 | else | ||
353 | { | ||
354 | eina_trash_push(&_eina_rectangles, rect); | ||
355 | _eina_rectangles_count++; | ||
356 | } | ||
357 | } | ||
358 | |||
359 | EAPI Eina_Rectangle_Pool * | ||
360 | eina_rectangle_pool_new(int w, int h) | ||
361 | { | ||
362 | Eina_Rectangle_Pool *new; | ||
363 | |||
364 | new = malloc(sizeof (Eina_Rectangle_Pool)); | ||
365 | if (!new) | ||
366 | return NULL; | ||
367 | |||
368 | new->head = NULL; | ||
369 | new->empty = eina_list_append(NULL, eina_rectangle_new(0, 0, w, h)); | ||
370 | new->references = 0; | ||
371 | new->sorted = EINA_FALSE; | ||
372 | new->w = w; | ||
373 | new->h = h; | ||
374 | new->bucket = NULL; | ||
375 | new->bucket_count = 0; | ||
376 | |||
377 | EINA_MAGIC_SET(new, EINA_RECTANGLE_POOL_MAGIC); | ||
378 | DBG("pool=%p, size=(%d, %d)", new, w, h); | ||
379 | |||
380 | return new; | ||
381 | } | ||
382 | |||
383 | EAPI void | ||
384 | eina_rectangle_pool_free(Eina_Rectangle_Pool *pool) | ||
385 | { | ||
386 | Eina_Rectangle_Alloc *del; | ||
387 | |||
388 | EINA_SAFETY_ON_NULL_RETURN(pool); | ||
389 | DBG("pool=%p, size=(%d, %d), references=%u", | ||
390 | pool, pool->w, pool->h, pool->references); | ||
391 | while (pool->head) | ||
392 | { | ||
393 | del = (Eina_Rectangle_Alloc *)pool->head; | ||
394 | |||
395 | pool->head = (EINA_INLIST_GET(del))->next; | ||
396 | |||
397 | EINA_MAGIC_SET(del, EINA_MAGIC_NONE); | ||
398 | eina_mempool_free(_eina_rectangle_alloc_mp, del); | ||
399 | } | ||
400 | |||
401 | while (pool->bucket) | ||
402 | { | ||
403 | del = eina_trash_pop(&pool->bucket); | ||
404 | eina_mempool_free(_eina_rectangle_alloc_mp, del); | ||
405 | } | ||
406 | |||
407 | MAGIC_FREE(pool); | ||
408 | } | ||
409 | |||
410 | EAPI int | ||
411 | eina_rectangle_pool_count(Eina_Rectangle_Pool *pool) | ||
412 | { | ||
413 | EINA_SAFETY_ON_NULL_RETURN_VAL(pool, 0); | ||
414 | return pool->references; | ||
415 | } | ||
416 | |||
417 | EAPI Eina_Rectangle * | ||
418 | eina_rectangle_pool_request(Eina_Rectangle_Pool *pool, int w, int h) | ||
419 | { | ||
420 | Eina_Rectangle_Alloc *new; | ||
421 | Eina_Rectangle *rect; | ||
422 | int x; | ||
423 | int y; | ||
424 | |||
425 | EINA_SAFETY_ON_NULL_RETURN_VAL(pool, NULL); | ||
426 | |||
427 | DBG("pool=%p, size=(%d, %d), references=%u", | ||
428 | pool, pool->w, pool->h, pool->references); | ||
429 | |||
430 | if (w <= 0 || h <= 0) | ||
431 | return NULL; | ||
432 | |||
433 | if (w > pool->w || h > pool->h) | ||
434 | return NULL; | ||
435 | |||
436 | /* Sort empty if dirty */ | ||
437 | if (pool->sorted) | ||
438 | { | ||
439 | pool->empty = | ||
440 | eina_list_sort(pool->empty, 0, EINA_COMPARE_CB(_eina_rectangle_cmp)); | ||
441 | pool->sorted = EINA_TRUE; | ||
442 | } | ||
443 | |||
444 | pool->empty = _eina_rectangle_empty_space_find(pool->empty, w, h, &x, &y); | ||
445 | if (x == -1) | ||
446 | return NULL; | ||
447 | |||
448 | pool->sorted = EINA_FALSE; | ||
449 | |||
450 | if (pool->bucket_count > 0) | ||
451 | { | ||
452 | new = eina_trash_pop(&pool->bucket); | ||
453 | pool->bucket_count--; | ||
454 | } | ||
455 | else | ||
456 | new = eina_mempool_malloc(_eina_rectangle_alloc_mp, | ||
457 | sizeof (Eina_Rectangle_Alloc) + | ||
458 | sizeof (Eina_Rectangle)); | ||
459 | |||
460 | if (!new) | ||
461 | return NULL; | ||
462 | |||
463 | rect = (Eina_Rectangle *)(new + 1); | ||
464 | eina_rectangle_coords_from(rect, x, y, w, h); | ||
465 | |||
466 | pool->head = eina_inlist_prepend(pool->head, EINA_INLIST_GET(new)); | ||
467 | pool->references++; | ||
468 | |||
469 | new->pool = pool; | ||
470 | |||
471 | EINA_MAGIC_SET(new, EINA_RECTANGLE_ALLOC_MAGIC); | ||
472 | DBG("rect=%p pool=%p, size=(%d, %d), references=%u", | ||
473 | rect, pool, pool->w, pool->h, pool->references); | ||
474 | |||
475 | return rect; | ||
476 | } | ||
477 | |||
478 | EAPI void | ||
479 | eina_rectangle_pool_release(Eina_Rectangle *rect) | ||
480 | { | ||
481 | Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *)rect) - 1; | ||
482 | Eina_Rectangle *r; | ||
483 | |||
484 | EINA_SAFETY_ON_NULL_RETURN(rect); | ||
485 | |||
486 | EINA_MAGIC_CHECK_RECTANGLE_ALLOC(era); | ||
487 | EINA_MAGIC_CHECK_RECTANGLE_POOL(era->pool); | ||
488 | |||
489 | DBG("rect=%p pool=%p, size=(%d, %d), references=%u", | ||
490 | rect, era->pool, era->pool->w, era->pool->h, era->pool->references); | ||
491 | |||
492 | era->pool->references--; | ||
493 | era->pool->head = eina_inlist_remove(era->pool->head, EINA_INLIST_GET(era)); | ||
494 | |||
495 | r = eina_rectangle_new(rect->x, rect->y, rect->w, rect->h); | ||
496 | if (r) | ||
497 | { | ||
498 | era->pool->empty = _eina_rectangle_merge_list(era->pool->empty, r); | ||
499 | era->pool->sorted = EINA_FALSE; | ||
500 | } | ||
501 | |||
502 | if (era->pool->bucket_count < BUCKET_THRESHOLD) | ||
503 | { | ||
504 | Eina_Rectangle_Pool *pool; | ||
505 | |||
506 | pool = era->pool; | ||
507 | |||
508 | pool->bucket_count++; | ||
509 | eina_trash_push(&pool->bucket, era); | ||
510 | } | ||
511 | else | ||
512 | { | ||
513 | EINA_MAGIC_SET(era, EINA_MAGIC_NONE); | ||
514 | eina_mempool_free(_eina_rectangle_alloc_mp, era); | ||
515 | } | ||
516 | } | ||
517 | |||
518 | EAPI Eina_Rectangle_Pool * | ||
519 | eina_rectangle_pool_get(Eina_Rectangle *rect) | ||
520 | { | ||
521 | Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *)rect) - 1; | ||
522 | |||
523 | EINA_SAFETY_ON_NULL_RETURN_VAL(rect, NULL); | ||
524 | |||
525 | EINA_MAGIC_CHECK_RECTANGLE_ALLOC(era); | ||
526 | EINA_MAGIC_CHECK_RECTANGLE_POOL(era->pool); | ||
527 | |||
528 | return era->pool; | ||
529 | } | ||
530 | |||
531 | EAPI void | ||
532 | eina_rectangle_pool_data_set(Eina_Rectangle_Pool *pool, const void *data) | ||
533 | { | ||
534 | EINA_MAGIC_CHECK_RECTANGLE_POOL(pool); | ||
535 | EINA_SAFETY_ON_NULL_RETURN(pool); | ||
536 | |||
537 | DBG("data=%p pool=%p, size=(%d, %d), references=%u", | ||
538 | data, pool, pool->w, pool->h, pool->references); | ||
539 | |||
540 | pool->data = (void *)data; | ||
541 | } | ||
542 | |||
543 | EAPI void * | ||
544 | eina_rectangle_pool_data_get(Eina_Rectangle_Pool *pool) | ||
545 | { | ||
546 | EINA_MAGIC_CHECK_RECTANGLE_POOL(pool); | ||
547 | EINA_SAFETY_ON_NULL_RETURN_VAL(pool, NULL); | ||
548 | |||
549 | return pool->data; | ||
550 | } | ||
551 | |||
552 | EAPI Eina_Bool | ||
553 | eina_rectangle_pool_geometry_get(Eina_Rectangle_Pool *pool, int *w, int *h) | ||
554 | { | ||
555 | if (!pool) | ||
556 | return EINA_FALSE; | ||
557 | |||
558 | EINA_MAGIC_CHECK_RECTANGLE_POOL(pool); | ||
559 | EINA_SAFETY_ON_NULL_RETURN_VAL(pool, EINA_FALSE); | ||
560 | |||
561 | if (w) | ||
562 | *w = pool->w; | ||
563 | |||
564 | if (h) | ||
565 | *h = pool->h; | ||
566 | |||
567 | return EINA_TRUE; | ||
568 | } | ||
diff --git a/libraries/eina/src/lib/eina_safety_checks.c b/libraries/eina/src/lib/eina_safety_checks.c deleted file mode 100644 index eed7c59..0000000 --- a/libraries/eina/src/lib/eina_safety_checks.c +++ /dev/null | |||
@@ -1,90 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Gustavo Sverzut Barbieri | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include "eina_private.h" | ||
24 | #include "eina_error.h" | ||
25 | #include "eina_log.h" | ||
26 | #include "eina_safety_checks.h" | ||
27 | |||
28 | /*============================================================================* | ||
29 | * Local * | ||
30 | *============================================================================*/ | ||
31 | |||
32 | /*============================================================================* | ||
33 | * Global * | ||
34 | *============================================================================*/ | ||
35 | |||
36 | /** | ||
37 | * @internal | ||
38 | * @brief Shut down the safety checks module. | ||
39 | * | ||
40 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
41 | * | ||
42 | * This function shuts down the error module set up by | ||
43 | * eina_safety_checks_init(). It is called by eina_shutdown(). | ||
44 | * | ||
45 | * @see eina_shutdown() | ||
46 | */ | ||
47 | Eina_Bool | ||
48 | eina_safety_checks_shutdown(void) | ||
49 | { | ||
50 | return EINA_TRUE; | ||
51 | } | ||
52 | |||
53 | /*============================================================================* | ||
54 | * API * | ||
55 | *============================================================================*/ | ||
56 | |||
57 | /** | ||
58 | * @cond LOCAL | ||
59 | */ | ||
60 | |||
61 | EAPI Eina_Error EINA_ERROR_SAFETY_FAILED = 0; | ||
62 | |||
63 | static const char EINA_ERROR_SAFETY_FAILED_STR[] = "Safety check failed."; | ||
64 | |||
65 | /** | ||
66 | * @endcond | ||
67 | */ | ||
68 | |||
69 | /** | ||
70 | * @internal | ||
71 | * @brief Initialize the safety checks module. | ||
72 | * | ||
73 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
74 | * | ||
75 | * This function sets up the safety checks module of Eina. It is | ||
76 | * called by eina_init(). | ||
77 | * | ||
78 | * @see eina_init() | ||
79 | */ | ||
80 | Eina_Bool | ||
81 | eina_safety_checks_init(void) | ||
82 | { | ||
83 | EINA_ERROR_SAFETY_FAILED = eina_error_msg_static_register( | ||
84 | EINA_ERROR_SAFETY_FAILED_STR); | ||
85 | return EINA_TRUE; | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * @} | ||
90 | */ | ||
diff --git a/libraries/eina/src/lib/eina_sched.c b/libraries/eina/src/lib/eina_sched.c deleted file mode 100644 index b8e7000..0000000 --- a/libraries/eina/src/lib/eina_sched.c +++ /dev/null | |||
@@ -1,101 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2010 ProFUSION embedded systems | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #ifdef EFL_HAVE_POSIX_THREADS | ||
24 | # include <pthread.h> | ||
25 | # ifdef __linux__ | ||
26 | # include <sched.h> | ||
27 | # include <sys/time.h> | ||
28 | # include <sys/resource.h> | ||
29 | # include <errno.h> | ||
30 | # endif | ||
31 | #endif | ||
32 | |||
33 | #ifdef EFL_HAVE_WIN32_THREADS | ||
34 | # ifndef WIN32_LEAN_AND_MEAN | ||
35 | # define WIN32_LEAN_AND_MEAN | ||
36 | # endif | ||
37 | # include <windows.h> | ||
38 | # undef WIN32_LEAN_AND_MEAN | ||
39 | #endif | ||
40 | |||
41 | #include "eina_sched.h" | ||
42 | #include "eina_log.h" | ||
43 | |||
44 | #define RTNICENESS 1 | ||
45 | #define NICENESS 5 | ||
46 | |||
47 | EAPI void | ||
48 | eina_sched_prio_drop(void) | ||
49 | { | ||
50 | #ifdef EFL_HAVE_POSIX_THREADS | ||
51 | struct sched_param param; | ||
52 | int pol, prio, ret; | ||
53 | pthread_t pthread_id; | ||
54 | |||
55 | pthread_id = pthread_self(); | ||
56 | ret = pthread_getschedparam(pthread_id, &pol, ¶m); | ||
57 | if (ret) | ||
58 | { | ||
59 | EINA_LOG_ERR("Unable to query sched parameters"); | ||
60 | return; | ||
61 | } | ||
62 | |||
63 | if (EINA_UNLIKELY(pol == SCHED_RR || pol == SCHED_FIFO)) | ||
64 | { | ||
65 | param.sched_priority -= RTNICENESS; | ||
66 | |||
67 | /* We don't change the policy */ | ||
68 | if (param.sched_priority < 1) | ||
69 | { | ||
70 | EINA_LOG_INFO("RT prio < 1, setting to 1 instead"); | ||
71 | param.sched_priority = 1; | ||
72 | } | ||
73 | |||
74 | pthread_setschedparam(pthread_id, pol, ¶m); | ||
75 | } | ||
76 | # ifdef __linux__ | ||
77 | else | ||
78 | { | ||
79 | errno = 0; | ||
80 | prio = getpriority(PRIO_PROCESS, 0); | ||
81 | if (errno == 0) | ||
82 | { | ||
83 | prio += NICENESS; | ||
84 | if (prio > 19) | ||
85 | { | ||
86 | EINA_LOG_INFO("Max niceness reached; keeping max (19)"); | ||
87 | prio = 19; | ||
88 | } | ||
89 | |||
90 | setpriority(PRIO_PROCESS, 0, prio); | ||
91 | } | ||
92 | } | ||
93 | # endif | ||
94 | #elif defined EFL_HAVE_WIN32_THREADS | ||
95 | if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL)) | ||
96 | EINA_LOG_ERR("Can not set thread priority"); | ||
97 | #else | ||
98 | EINA_LOG_ERR("Eina does not have support for threads enabled" | ||
99 | "or it doesn't support setting scheduler priorities"); | ||
100 | #endif | ||
101 | } | ||
diff --git a/libraries/eina/src/lib/eina_share_common.c b/libraries/eina/src/lib/eina_share_common.c deleted file mode 100644 index 776e429..0000000 --- a/libraries/eina/src/lib/eina_share_common.c +++ /dev/null | |||
@@ -1,949 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2010 | ||
3 | * Carsten Haitzler, | ||
4 | * Jorge Luis Zapata Muga, | ||
5 | * Cedric Bail, | ||
6 | * Gustavo Sverzut Barbieri | ||
7 | * Tom Hacohen | ||
8 | * Brett Nash | ||
9 | * | ||
10 | * This library is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU Lesser General Public | ||
12 | * License as published by the Free Software Foundation; either | ||
13 | * version 2.1 of the License, or (at your option) any later version. | ||
14 | * | ||
15 | * This library is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | * Lesser General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU Lesser General Public | ||
21 | * License along with this library; | ||
22 | * if not, see <http://www.gnu.org/licenses/>. | ||
23 | * | ||
24 | * This file incorporates work covered by the following copyright and | ||
25 | * permission notice: | ||
26 | * | ||
27 | * Copyright (C) 2008 Peter Wehrfritz | ||
28 | * | ||
29 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
30 | * of this software and associated documentation files (the "Software"), to | ||
31 | * deal in the Software without restriction, including without limitation the | ||
32 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
33 | * sell copies of the Software, and to permit persons to whom the Software is | ||
34 | * furnished to do so, subject to the following conditions: | ||
35 | * | ||
36 | * The above copyright notice and this permission notice shall be included in | ||
37 | * all copies of the Software and its Copyright notices. In addition publicly | ||
38 | * documented acknowledgment must be given that this software has been used if no | ||
39 | * source code of this software is made available publicly. This includes | ||
40 | * acknowledgments in either Copyright notices, Manuals, Publicity and Marketing | ||
41 | * documents or any documentation provided with any product containing this | ||
42 | * software. This License does not apply to any software that links to the | ||
43 | * libraries provided by this software (statically or dynamically), but only to | ||
44 | * the software provided. | ||
45 | * | ||
46 | * Please see the OLD-COPYING.PLAIN for a plain-english explanation of this notice | ||
47 | * and it's intent. | ||
48 | * | ||
49 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
50 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
51 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
52 | * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
53 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
54 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
55 | */ | ||
56 | |||
57 | #ifdef HAVE_CONFIG_H | ||
58 | # include "config.h" | ||
59 | #endif | ||
60 | |||
61 | #include <stdlib.h> | ||
62 | #include <stdio.h> | ||
63 | #include <string.h> | ||
64 | #include <stddef.h> | ||
65 | |||
66 | #ifdef EFL_HAVE_POSIX_THREADS | ||
67 | # include <pthread.h> | ||
68 | #endif | ||
69 | |||
70 | #ifdef HAVE_EVIL | ||
71 | # include <Evil.h> | ||
72 | #endif | ||
73 | |||
74 | #include "eina_config.h" | ||
75 | #include "eina_private.h" | ||
76 | #include "eina_hash.h" | ||
77 | #include "eina_rbtree.h" | ||
78 | #include "eina_error.h" | ||
79 | #include "eina_lock.h" | ||
80 | |||
81 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
82 | #include "eina_safety_checks.h" | ||
83 | #include "eina_share_common.h" | ||
84 | |||
85 | /*============================================================================* | ||
86 | * Local * | ||
87 | *============================================================================*/ | ||
88 | |||
89 | /** | ||
90 | * @cond LOCAL | ||
91 | */ | ||
92 | |||
93 | #define EINA_SHARE_COMMON_BUCKETS 256 | ||
94 | #define EINA_SHARE_COMMON_MASK 0xFF | ||
95 | |||
96 | static const char EINA_MAGIC_SHARE_STR[] = "Eina Share"; | ||
97 | static const char EINA_MAGIC_SHARE_HEAD_STR[] = "Eina Share Head"; | ||
98 | |||
99 | static int _eina_share_common_count = 0; | ||
100 | |||
101 | #define EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(d, unlock, ...) \ | ||
102 | do { \ | ||
103 | if (!EINA_MAGIC_CHECK((d), EINA_MAGIC_SHARE_HEAD)) \ | ||
104 | { \ | ||
105 | EINA_MAGIC_FAIL((d), EINA_MAGIC_SHARE_HEAD); \ | ||
106 | unlock; \ | ||
107 | return __VA_ARGS__; \ | ||
108 | } \ | ||
109 | } while (0) | ||
110 | |||
111 | #define EINA_MAGIC_CHECK_SHARE_COMMON_NODE(d, _node_magic, unlock) \ | ||
112 | do { \ | ||
113 | if (!EINA_MAGIC_CHECK((d), _node_magic)) \ | ||
114 | { \ | ||
115 | EINA_MAGIC_FAIL((d), _node_magic); \ | ||
116 | unlock; \ | ||
117 | } \ | ||
118 | } while (0) | ||
119 | |||
120 | #ifdef EINA_SHARE_USAGE | ||
121 | typedef struct _Eina_Share_Common_Population Eina_Share_Common_Population; | ||
122 | #endif | ||
123 | |||
124 | typedef struct _Eina_Share_Common Eina_Share_Common; | ||
125 | typedef struct _Eina_Share_Common_Node Eina_Share_Common_Node; | ||
126 | typedef struct _Eina_Share_Common_Head Eina_Share_Common_Head; | ||
127 | |||
128 | struct _Eina_Share | ||
129 | { | ||
130 | Eina_Share_Common *share; | ||
131 | Eina_Magic node_magic; | ||
132 | #ifdef EINA_SHARE_COMMON_USAGE | ||
133 | Eina_Share_Common_Population population; | ||
134 | int max_node_population; | ||
135 | #endif | ||
136 | }; | ||
137 | |||
138 | struct _Eina_Share_Common | ||
139 | { | ||
140 | Eina_Share_Common_Head *buckets[EINA_SHARE_COMMON_BUCKETS]; | ||
141 | |||
142 | EINA_MAGIC | ||
143 | }; | ||
144 | |||
145 | struct _Eina_Share_Common_Node | ||
146 | { | ||
147 | Eina_Share_Common_Node *next; | ||
148 | |||
149 | EINA_MAGIC | ||
150 | |||
151 | unsigned int length; | ||
152 | unsigned int references; | ||
153 | char str[]; | ||
154 | }; | ||
155 | |||
156 | struct _Eina_Share_Common_Head | ||
157 | { | ||
158 | EINA_RBTREE; | ||
159 | EINA_MAGIC | ||
160 | |||
161 | int hash; | ||
162 | |||
163 | #ifdef EINA_SHARE_COMMON_USAGE | ||
164 | int population; | ||
165 | #endif | ||
166 | |||
167 | Eina_Share_Common_Node *head; | ||
168 | Eina_Share_Common_Node builtin_node; | ||
169 | }; | ||
170 | |||
171 | Eina_Bool _share_common_threads_activated = EINA_FALSE; | ||
172 | |||
173 | static Eina_Lock _mutex_big; | ||
174 | |||
175 | #ifdef EINA_SHARE_COMMON_USAGE | ||
176 | struct _Eina_Share_Common_Population | ||
177 | { | ||
178 | int count; | ||
179 | int max; | ||
180 | }; | ||
181 | |||
182 | static Eina_Share_Common_Population population = { 0, 0 }; | ||
183 | |||
184 | static Eina_Share_Common_Population population_group[4] = | ||
185 | { | ||
186 | { 0, 0 }, | ||
187 | { 0, 0 }, | ||
188 | { 0, 0 }, | ||
189 | { 0, 0 } | ||
190 | }; | ||
191 | |||
192 | static void | ||
193 | _eina_share_common_population_init(Eina_Share *share) | ||
194 | { | ||
195 | unsigned int i; | ||
196 | |||
197 | for (i = 0; | ||
198 | i < sizeof (share->population_group) / | ||
199 | sizeof (share->population_group[0]); | ||
200 | ++i) | ||
201 | { | ||
202 | share->population_group[i].count = 0; | ||
203 | share->population_group[i].max = 0; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | static void | ||
208 | _eina_share_common_population_shutdown(Eina_Share *share) | ||
209 | { | ||
210 | unsigned int i; | ||
211 | |||
212 | share->max_node_population = 0; | ||
213 | share->population.count = 0; | ||
214 | share->population.max = 0; | ||
215 | |||
216 | for (i = 0; | ||
217 | i < sizeof (share->population_group) / | ||
218 | sizeof (share->population_group[0]); | ||
219 | ++i) | ||
220 | { | ||
221 | share->population_group[i].count = 0; | ||
222 | share->population_group[i].max = 0; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | static void | ||
227 | _eina_share_common_population_stats(Eina_Share *share) | ||
228 | { | ||
229 | unsigned int i; | ||
230 | |||
231 | fprintf(stderr, "eina share_common statistic:\n"); | ||
232 | fprintf(stderr, | ||
233 | " * maximum shared strings : %i\n", | ||
234 | share->population.max); | ||
235 | fprintf(stderr, | ||
236 | " * maximum shared strings per node : %i\n", | ||
237 | share->max_node_population); | ||
238 | |||
239 | for (i = 0; | ||
240 | i < sizeof (share->population_group) / | ||
241 | sizeof (share->population_group[0]); | ||
242 | ++i) | ||
243 | fprintf(stderr, | ||
244 | "DDD: %i strings of length %i, max strings: %i\n", | ||
245 | share->population_group[i].count, | ||
246 | i, | ||
247 | share->population_group[i].max); | ||
248 | } | ||
249 | |||
250 | void | ||
251 | eina_share_common_population_add(Eina_Share *share, int slen) | ||
252 | { | ||
253 | eina_lock_take(&_mutex_big); | ||
254 | |||
255 | share->population.count++; | ||
256 | if (share->population.count > share->population.max) | ||
257 | share->population.max = share->population.count; | ||
258 | |||
259 | if (slen < 4) | ||
260 | { | ||
261 | share->population_group[slen].count++; | ||
262 | if (share->population_group[slen].count > | ||
263 | share->population_group[slen].max) | ||
264 | share->population_group[slen].max = | ||
265 | share->population_group[slen].count; | ||
266 | } | ||
267 | |||
268 | eina_lock_release(&_mutex_big); | ||
269 | } | ||
270 | |||
271 | void | ||
272 | eina_share_common_population_del(Eina_Share *share, int slen) | ||
273 | { | ||
274 | eina_lock_take(&_mutex_big); | ||
275 | |||
276 | share->population.count--; | ||
277 | if (slen < 4) | ||
278 | share->population_group[slen].count--; | ||
279 | |||
280 | eina_lock_release(&_mutex_big); | ||
281 | } | ||
282 | |||
283 | static void | ||
284 | _eina_share_common_population_head_init(Eina_Share *share, | ||
285 | Eina_Share_Common_Head *head) | ||
286 | { | ||
287 | head->population = 1; | ||
288 | } | ||
289 | |||
290 | static void | ||
291 | _eina_share_common_population_head_add(Eina_Share *share, | ||
292 | Eina_Share_Common_Head *head) | ||
293 | { | ||
294 | head->population++; | ||
295 | if (head->population > share->max_node_population) | ||
296 | share->max_node_population = head->population; | ||
297 | } | ||
298 | |||
299 | static void | ||
300 | _eina_share_common_population_head_del(Eina_Share *share, | ||
301 | Eina_Share_Common_Head *head) | ||
302 | { | ||
303 | head->population--; | ||
304 | } | ||
305 | |||
306 | #else /* EINA_SHARE_COMMON_USAGE undefined */ | ||
307 | |||
308 | static void _eina_share_common_population_init(__UNUSED__ Eina_Share *share) { | ||
309 | } | ||
310 | static void _eina_share_common_population_shutdown(__UNUSED__ Eina_Share *share) | ||
311 | { | ||
312 | } | ||
313 | static void _eina_share_common_population_stats(__UNUSED__ Eina_Share *share) { | ||
314 | } | ||
315 | void eina_share_common_population_add(__UNUSED__ Eina_Share *share, | ||
316 | __UNUSED__ int slen) { | ||
317 | } | ||
318 | void eina_share_common_population_del(__UNUSED__ Eina_Share *share, | ||
319 | __UNUSED__ int slen) { | ||
320 | } | ||
321 | static void _eina_share_common_population_head_init( | ||
322 | __UNUSED__ Eina_Share *share, | ||
323 | __UNUSED__ Eina_Share_Common_Head *head) { | ||
324 | } | ||
325 | static void _eina_share_common_population_head_add( | ||
326 | __UNUSED__ Eina_Share *share, | ||
327 | __UNUSED__ | ||
328 | Eina_Share_Common_Head *head) { | ||
329 | } | ||
330 | static void _eina_share_common_population_head_del( | ||
331 | __UNUSED__ Eina_Share *share, | ||
332 | __UNUSED__ | ||
333 | Eina_Share_Common_Head *head) { | ||
334 | } | ||
335 | #endif | ||
336 | |||
337 | static int | ||
338 | _eina_share_common_cmp(const Eina_Share_Common_Head *ed, | ||
339 | const int *hash, | ||
340 | __UNUSED__ int length, | ||
341 | __UNUSED__ void *data) | ||
342 | { | ||
343 | EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(ed, , 0); | ||
344 | |||
345 | return ed->hash - *hash; | ||
346 | } | ||
347 | |||
348 | static Eina_Rbtree_Direction | ||
349 | _eina_share_common_node(const Eina_Share_Common_Head *left, | ||
350 | const Eina_Share_Common_Head *right, | ||
351 | __UNUSED__ void *data) | ||
352 | { | ||
353 | EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(left, , 0); | ||
354 | EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(right, , 0); | ||
355 | |||
356 | if (left->hash - right->hash < 0) | ||
357 | return EINA_RBTREE_LEFT; | ||
358 | |||
359 | return EINA_RBTREE_RIGHT; | ||
360 | } | ||
361 | |||
362 | static void | ||
363 | _eina_share_common_head_free(Eina_Share_Common_Head *ed, __UNUSED__ void *data) | ||
364 | { | ||
365 | EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(ed, ); | ||
366 | |||
367 | while (ed->head) | ||
368 | { | ||
369 | Eina_Share_Common_Node *el = ed->head; | ||
370 | |||
371 | ed->head = ed->head->next; | ||
372 | if (el != &ed->builtin_node) | ||
373 | MAGIC_FREE(el); | ||
374 | } | ||
375 | MAGIC_FREE(ed); | ||
376 | } | ||
377 | |||
378 | static void | ||
379 | _eina_share_common_node_init(Eina_Share_Common_Node *node, | ||
380 | const char *str, | ||
381 | int slen, | ||
382 | unsigned int null_size, | ||
383 | Eina_Magic node_magic) | ||
384 | { | ||
385 | EINA_MAGIC_SET(node, node_magic); | ||
386 | node->references = 1; | ||
387 | node->length = slen; | ||
388 | memcpy(node->str, str, slen); | ||
389 | memset(node->str + slen, 0, null_size); /* Nullify the null */ | ||
390 | |||
391 | (void) node_magic; /* When magic are disable, node_magic is unused, this remove a warning. */ | ||
392 | } | ||
393 | |||
394 | static Eina_Share_Common_Head * | ||
395 | _eina_share_common_head_alloc(int slen) | ||
396 | { | ||
397 | Eina_Share_Common_Head *head; | ||
398 | const size_t head_size = offsetof(Eina_Share_Common_Head, builtin_node.str); | ||
399 | |||
400 | head = malloc(head_size + slen); | ||
401 | if (!head) | ||
402 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
403 | |||
404 | return head; | ||
405 | } | ||
406 | |||
407 | static const char * | ||
408 | _eina_share_common_add_head(Eina_Share *share, | ||
409 | Eina_Share_Common_Head **p_bucket, | ||
410 | int hash, | ||
411 | const char *str, | ||
412 | unsigned int slen, | ||
413 | unsigned int null_size) | ||
414 | { | ||
415 | Eina_Rbtree **p_tree = (Eina_Rbtree **)p_bucket; | ||
416 | Eina_Share_Common_Head *head; | ||
417 | |||
418 | head = _eina_share_common_head_alloc(slen + null_size); | ||
419 | if (!head) | ||
420 | return NULL; | ||
421 | |||
422 | EINA_MAGIC_SET(head, EINA_MAGIC_SHARE_HEAD); | ||
423 | head->hash = hash; | ||
424 | head->head = &head->builtin_node; | ||
425 | _eina_share_common_node_init(head->head, | ||
426 | str, | ||
427 | slen, | ||
428 | null_size, | ||
429 | share->node_magic); | ||
430 | head->head->next = NULL; | ||
431 | |||
432 | _eina_share_common_population_head_init(share, head); | ||
433 | |||
434 | *p_tree = eina_rbtree_inline_insert | ||
435 | (*p_tree, EINA_RBTREE_GET(head), | ||
436 | EINA_RBTREE_CMP_NODE_CB(_eina_share_common_node), NULL); | ||
437 | |||
438 | return head->head->str; | ||
439 | } | ||
440 | |||
441 | static void | ||
442 | _eina_share_common_del_head(Eina_Share_Common_Head **p_bucket, | ||
443 | Eina_Share_Common_Head *head) | ||
444 | { | ||
445 | Eina_Rbtree **p_tree = (Eina_Rbtree **)p_bucket; | ||
446 | |||
447 | *p_tree = eina_rbtree_inline_remove | ||
448 | (*p_tree, EINA_RBTREE_GET(head), | ||
449 | EINA_RBTREE_CMP_NODE_CB(_eina_share_common_node), NULL); | ||
450 | |||
451 | MAGIC_FREE(head); | ||
452 | } | ||
453 | |||
454 | |||
455 | static inline Eina_Bool | ||
456 | _eina_share_common_node_eq(const Eina_Share_Common_Node *node, | ||
457 | const char *str, | ||
458 | unsigned int slen) | ||
459 | { | ||
460 | return ((node->length == slen) && | ||
461 | (memcmp(node->str, str, slen) == 0)); | ||
462 | } | ||
463 | |||
464 | static Eina_Share_Common_Node * | ||
465 | _eina_share_common_head_find(Eina_Share_Common_Head *head, | ||
466 | const char *str, | ||
467 | unsigned int slen) | ||
468 | { | ||
469 | Eina_Share_Common_Node *node, *prev; | ||
470 | |||
471 | node = head->head; | ||
472 | if (_eina_share_common_node_eq(node, str, slen)) | ||
473 | return node; | ||
474 | |||
475 | prev = node; | ||
476 | node = node->next; | ||
477 | for (; node; prev = node, node = node->next) | ||
478 | if (_eina_share_common_node_eq(node, str, slen)) | ||
479 | { | ||
480 | /* promote node, make hot items be at the beginning */ | ||
481 | prev->next = node->next; | ||
482 | node->next = head->head; | ||
483 | head->head = node; | ||
484 | return node; | ||
485 | } | ||
486 | |||
487 | return NULL; | ||
488 | } | ||
489 | |||
490 | static Eina_Bool | ||
491 | _eina_share_common_head_remove_node(Eina_Share_Common_Head *head, | ||
492 | const Eina_Share_Common_Node *node) | ||
493 | { | ||
494 | Eina_Share_Common_Node *cur, *prev; | ||
495 | |||
496 | if (head->head == node) | ||
497 | { | ||
498 | head->head = node->next; | ||
499 | return 1; | ||
500 | } | ||
501 | |||
502 | prev = head->head; | ||
503 | cur = head->head->next; | ||
504 | for (; cur; prev = cur, cur = cur->next) | ||
505 | if (cur == node) | ||
506 | { | ||
507 | prev->next = cur->next; | ||
508 | return 1; | ||
509 | } | ||
510 | |||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | static Eina_Share_Common_Head * | ||
515 | _eina_share_common_find_hash(Eina_Share_Common_Head *bucket, int hash) | ||
516 | { | ||
517 | return (Eina_Share_Common_Head *)eina_rbtree_inline_lookup | ||
518 | (EINA_RBTREE_GET(bucket), &hash, 0, | ||
519 | EINA_RBTREE_CMP_KEY_CB(_eina_share_common_cmp), NULL); | ||
520 | } | ||
521 | |||
522 | static Eina_Share_Common_Node * | ||
523 | _eina_share_common_node_alloc(unsigned int slen, unsigned int null_size) | ||
524 | { | ||
525 | Eina_Share_Common_Node *node; | ||
526 | const size_t node_size = offsetof(Eina_Share_Common_Node, str); | ||
527 | |||
528 | node = malloc(node_size + slen + null_size); | ||
529 | if (!node) | ||
530 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
531 | |||
532 | return node; | ||
533 | } | ||
534 | |||
535 | static Eina_Share_Common_Node * | ||
536 | _eina_share_common_node_from_str(const char *str, Eina_Magic node_magic) | ||
537 | { | ||
538 | Eina_Share_Common_Node *node; | ||
539 | const size_t offset = offsetof(Eina_Share_Common_Node, str); | ||
540 | |||
541 | node = (Eina_Share_Common_Node *)(str - offset); | ||
542 | EINA_MAGIC_CHECK_SHARE_COMMON_NODE(node, node_magic, node = NULL); | ||
543 | return node; | ||
544 | |||
545 | (void) node_magic; /* When magic are disable, node_magic is unused, this remove a warning. */ | ||
546 | } | ||
547 | |||
548 | static Eina_Bool | ||
549 | eina_iterator_array_check(const Eina_Rbtree *rbtree __UNUSED__, | ||
550 | Eina_Share_Common_Head *head, | ||
551 | struct dumpinfo *fdata) | ||
552 | { | ||
553 | Eina_Share_Common_Node *node; | ||
554 | |||
555 | fdata->used += sizeof(Eina_Share_Common_Head); | ||
556 | for (node = head->head; node; node = node->next) | ||
557 | { | ||
558 | printf("DDD: %5i %5i ", node->length, node->references); | ||
559 | printf("'%.*s'\n", node->length, ((char *)node) + sizeof(Eina_Share_Common_Node)); | ||
560 | fdata->used += sizeof(Eina_Share_Common_Node); | ||
561 | fdata->used += node->length; | ||
562 | fdata->saved += (node->references - 1) * node->length; | ||
563 | fdata->dups += node->references - 1; | ||
564 | fdata->unique++; | ||
565 | } | ||
566 | |||
567 | return EINA_TRUE; | ||
568 | } | ||
569 | |||
570 | /** | ||
571 | * @endcond | ||
572 | */ | ||
573 | |||
574 | |||
575 | /*============================================================================* | ||
576 | * Global * | ||
577 | *============================================================================*/ | ||
578 | |||
579 | /** | ||
580 | * @internal | ||
581 | * @brief Initialize the share_common module. | ||
582 | * | ||
583 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
584 | * | ||
585 | * This function sets up the share_common module of Eina. It is called by | ||
586 | * eina_init(). | ||
587 | * | ||
588 | * @see eina_init() | ||
589 | */ | ||
590 | Eina_Bool | ||
591 | eina_share_common_init(Eina_Share **_share, | ||
592 | Eina_Magic node_magic, | ||
593 | const char *node_magic_STR) | ||
594 | { | ||
595 | Eina_Share *share; | ||
596 | |||
597 | share = *_share = calloc(sizeof(Eina_Share), 1); | ||
598 | if (!share) goto on_error; | ||
599 | |||
600 | share->share = calloc(1, sizeof(Eina_Share_Common)); | ||
601 | if (!share->share) goto on_error; | ||
602 | |||
603 | share->node_magic = node_magic; | ||
604 | #define EMS(n) eina_magic_string_static_set(n, n ## _STR) | ||
605 | EMS(EINA_MAGIC_SHARE); | ||
606 | EMS(EINA_MAGIC_SHARE_HEAD); | ||
607 | EMS(node_magic); | ||
608 | #undef EMS | ||
609 | EINA_MAGIC_SET(share->share, EINA_MAGIC_SHARE); | ||
610 | |||
611 | _eina_share_common_population_init(share); | ||
612 | |||
613 | /* below is the common part among other all eina_share_common user */ | ||
614 | if (_eina_share_common_count++ != 0) | ||
615 | return EINA_TRUE; | ||
616 | |||
617 | eina_lock_new(&_mutex_big); | ||
618 | return EINA_TRUE; | ||
619 | |||
620 | on_error: | ||
621 | _eina_share_common_count--; | ||
622 | return EINA_FALSE; | ||
623 | } | ||
624 | |||
625 | /** | ||
626 | * @internal | ||
627 | * @brief Shut down the share_common module. | ||
628 | * | ||
629 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
630 | * | ||
631 | * This function shuts down the share_common module set up by | ||
632 | * eina_share_common_init(). It is called by eina_shutdown(). | ||
633 | * | ||
634 | * @see eina_shutdown() | ||
635 | */ | ||
636 | Eina_Bool | ||
637 | eina_share_common_shutdown(Eina_Share **_share) | ||
638 | { | ||
639 | unsigned int i; | ||
640 | Eina_Share *share = *_share; | ||
641 | |||
642 | eina_lock_take(&_mutex_big); | ||
643 | |||
644 | _eina_share_common_population_stats(share); | ||
645 | |||
646 | /* remove any string still in the table */ | ||
647 | for (i = 0; i < EINA_SHARE_COMMON_BUCKETS; i++) | ||
648 | { | ||
649 | eina_rbtree_delete(EINA_RBTREE_GET( | ||
650 | share->share->buckets[i]), | ||
651 | EINA_RBTREE_FREE_CB( | ||
652 | _eina_share_common_head_free), NULL); | ||
653 | share->share->buckets[i] = NULL; | ||
654 | } | ||
655 | MAGIC_FREE(share->share); | ||
656 | |||
657 | _eina_share_common_population_shutdown(share); | ||
658 | |||
659 | eina_lock_release(&_mutex_big); | ||
660 | |||
661 | free(*_share); | ||
662 | *_share = NULL; | ||
663 | |||
664 | /* below is the common part among other all eina_share_common user */ | ||
665 | if (--_eina_share_common_count != 0) | ||
666 | return EINA_TRUE; | ||
667 | |||
668 | eina_lock_free(&_mutex_big); | ||
669 | |||
670 | return EINA_TRUE; | ||
671 | } | ||
672 | |||
673 | #ifdef EFL_HAVE_THREADS | ||
674 | |||
675 | /** | ||
676 | * @internal | ||
677 | * @brief Activate the share_common mutexes. | ||
678 | * | ||
679 | * This function activate the mutexes in the eina share_common module. It is called by | ||
680 | * eina_threads_init(). | ||
681 | * | ||
682 | * @see eina_threads_init() | ||
683 | */ | ||
684 | void | ||
685 | eina_share_common_threads_init(void) | ||
686 | { | ||
687 | _share_common_threads_activated = EINA_TRUE; | ||
688 | } | ||
689 | |||
690 | /** | ||
691 | * @internal | ||
692 | * @brief Shut down the share_common mutexes. | ||
693 | * | ||
694 | * This function shuts down the mutexes in the share_common module. | ||
695 | * It is called by eina_threads_shutdown(). | ||
696 | * | ||
697 | * @see eina_threads_shutdown() | ||
698 | */ | ||
699 | void | ||
700 | eina_share_common_threads_shutdown(void) | ||
701 | { | ||
702 | _share_common_threads_activated = EINA_FALSE; | ||
703 | } | ||
704 | |||
705 | #endif | ||
706 | |||
707 | /*============================================================================* | ||
708 | * API * | ||
709 | *============================================================================*/ | ||
710 | |||
711 | /** | ||
712 | * @cond LOCAL | ||
713 | */ | ||
714 | |||
715 | const char * | ||
716 | eina_share_common_add_length(Eina_Share *share, | ||
717 | const char *str, | ||
718 | unsigned int slen, | ||
719 | unsigned int null_size) | ||
720 | { | ||
721 | Eina_Share_Common_Head **p_bucket, *ed; | ||
722 | Eina_Share_Common_Node *el; | ||
723 | int hash_num, hash; | ||
724 | |||
725 | if (!str) | ||
726 | return NULL; | ||
727 | |||
728 | eina_share_common_population_add(share, slen); | ||
729 | |||
730 | if (slen <= 0) | ||
731 | return NULL; | ||
732 | |||
733 | hash = eina_hash_superfast(str, slen); | ||
734 | hash_num = hash & 0xFF; | ||
735 | hash = (hash >> 8) & EINA_SHARE_COMMON_MASK; | ||
736 | |||
737 | eina_lock_take(&_mutex_big); | ||
738 | p_bucket = share->share->buckets + hash_num; | ||
739 | |||
740 | ed = _eina_share_common_find_hash(*p_bucket, hash); | ||
741 | if (!ed) | ||
742 | { | ||
743 | const char *s = _eina_share_common_add_head(share, | ||
744 | p_bucket, | ||
745 | hash, | ||
746 | str, | ||
747 | slen, | ||
748 | null_size); | ||
749 | eina_lock_release(&_mutex_big); | ||
750 | return s; | ||
751 | } | ||
752 | |||
753 | EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(ed, eina_lock_release(&_mutex_big), NULL); | ||
754 | |||
755 | el = _eina_share_common_head_find(ed, str, slen); | ||
756 | if (el) | ||
757 | { | ||
758 | EINA_MAGIC_CHECK_SHARE_COMMON_NODE(el, | ||
759 | share->node_magic, | ||
760 | eina_lock_release(&_mutex_big)); | ||
761 | el->references++; | ||
762 | eina_lock_release(&_mutex_big); | ||
763 | return el->str; | ||
764 | } | ||
765 | |||
766 | el = _eina_share_common_node_alloc(slen, null_size); | ||
767 | if (!el) | ||
768 | { | ||
769 | eina_lock_release(&_mutex_big); | ||
770 | return NULL; | ||
771 | } | ||
772 | |||
773 | _eina_share_common_node_init(el, str, slen, null_size, share->node_magic); | ||
774 | el->next = ed->head; | ||
775 | ed->head = el; | ||
776 | _eina_share_common_population_head_add(share, ed); | ||
777 | |||
778 | eina_lock_release(&_mutex_big); | ||
779 | |||
780 | return el->str; | ||
781 | } | ||
782 | |||
783 | const char * | ||
784 | eina_share_common_ref(Eina_Share *share, const char *str) | ||
785 | { | ||
786 | Eina_Share_Common_Node *node; | ||
787 | |||
788 | if (!str) | ||
789 | return NULL; | ||
790 | |||
791 | eina_lock_take(&_mutex_big); | ||
792 | node = _eina_share_common_node_from_str(str, share->node_magic); | ||
793 | if (!node) | ||
794 | { | ||
795 | eina_lock_release(&_mutex_big); | ||
796 | return str; | ||
797 | } | ||
798 | node->references++; | ||
799 | |||
800 | eina_lock_release(&_mutex_big); | ||
801 | |||
802 | eina_share_common_population_add(share, node->length); | ||
803 | |||
804 | return str; | ||
805 | } | ||
806 | |||
807 | |||
808 | Eina_Bool | ||
809 | eina_share_common_del(Eina_Share *share, const char *str) | ||
810 | { | ||
811 | unsigned int slen; | ||
812 | Eina_Share_Common_Head *ed; | ||
813 | Eina_Share_Common_Head **p_bucket; | ||
814 | Eina_Share_Common_Node *node; | ||
815 | int hash_num, hash; | ||
816 | |||
817 | if (!str) | ||
818 | return EINA_TRUE; | ||
819 | |||
820 | eina_lock_take(&_mutex_big); | ||
821 | |||
822 | node = _eina_share_common_node_from_str(str, share->node_magic); | ||
823 | if (!node) | ||
824 | goto on_error; | ||
825 | |||
826 | slen = node->length; | ||
827 | eina_share_common_population_del(share, slen); | ||
828 | if (node->references > 1) | ||
829 | { | ||
830 | node->references--; | ||
831 | eina_lock_release(&_mutex_big); | ||
832 | return EINA_TRUE; | ||
833 | } | ||
834 | |||
835 | node->references = 0; | ||
836 | |||
837 | hash = eina_hash_superfast(str, slen); | ||
838 | hash_num = hash & 0xFF; | ||
839 | hash = (hash >> 8) & EINA_SHARE_COMMON_MASK; | ||
840 | |||
841 | p_bucket = share->share->buckets + hash_num; | ||
842 | ed = _eina_share_common_find_hash(*p_bucket, hash); | ||
843 | if (!ed) | ||
844 | goto on_error; | ||
845 | |||
846 | EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(ed, eina_lock_release(&_mutex_big), EINA_FALSE); | ||
847 | |||
848 | if (!_eina_share_common_head_remove_node(ed, node)) | ||
849 | goto on_error; | ||
850 | |||
851 | if (node != &ed->builtin_node) | ||
852 | MAGIC_FREE(node); | ||
853 | |||
854 | if (!ed->head) | ||
855 | _eina_share_common_del_head(p_bucket, ed); | ||
856 | else | ||
857 | _eina_share_common_population_head_del(share, ed); | ||
858 | |||
859 | eina_lock_release(&_mutex_big); | ||
860 | |||
861 | return EINA_TRUE; | ||
862 | |||
863 | on_error: | ||
864 | eina_lock_release(&_mutex_big); | ||
865 | /* possible segfault happened before here, but... */ | ||
866 | return EINA_FALSE; | ||
867 | } | ||
868 | |||
869 | int | ||
870 | eina_share_common_length(__UNUSED__ Eina_Share *share, const char *str) | ||
871 | { | ||
872 | const Eina_Share_Common_Node *node; | ||
873 | |||
874 | if (!str) | ||
875 | return -1; | ||
876 | |||
877 | node = _eina_share_common_node_from_str(str, share->node_magic); | ||
878 | if (!node) return 0; | ||
879 | return node->length; | ||
880 | } | ||
881 | |||
882 | void | ||
883 | eina_share_common_dump(Eina_Share *share, void (*additional_dump)( | ||
884 | struct dumpinfo *), int used) | ||
885 | { | ||
886 | Eina_Iterator *it; | ||
887 | unsigned int i; | ||
888 | struct dumpinfo di; | ||
889 | |||
890 | if (!share) | ||
891 | return; | ||
892 | |||
893 | di.used = used; | ||
894 | di.saved = 0; | ||
895 | di.dups = 0; | ||
896 | di.unique = 0; | ||
897 | printf("DDD: len ref string\n"); | ||
898 | printf("DDD:-------------------\n"); | ||
899 | |||
900 | eina_lock_take(&_mutex_big); | ||
901 | for (i = 0; i < EINA_SHARE_COMMON_BUCKETS; i++) | ||
902 | { | ||
903 | if (!share->share->buckets[i]) | ||
904 | { | ||
905 | continue; // printf("DDD: BUCKET # %i (HEAD=%i, NODE=%i)\n", i, | ||
906 | |||
907 | } | ||
908 | |||
909 | // sizeof(Eina_Share_Common_Head), sizeof(Eina_Share_Common_Node)); | ||
910 | it = eina_rbtree_iterator_prefix( | ||
911 | (Eina_Rbtree *)share->share->buckets[i]); | ||
912 | eina_iterator_foreach(it, EINA_EACH_CB(eina_iterator_array_check), &di); | ||
913 | eina_iterator_free(it); | ||
914 | } | ||
915 | if (additional_dump) | ||
916 | additional_dump(&di); | ||
917 | |||
918 | #ifdef EINA_SHARE_COMMON_USAGE | ||
919 | /* One character strings are not counted in the hash. */ | ||
920 | di.saved += share->population_group[0].count * sizeof(char); | ||
921 | di.saved += share->population_group[1].count * sizeof(char) * 2; | ||
922 | #endif | ||
923 | printf("DDD:-------------------\n"); | ||
924 | printf("DDD: usage (bytes) = %i, saved = %i (%3.0f%%)\n", | ||
925 | di.used, di.saved, di.used ? (di.saved * 100.0 / di.used) : 0.0); | ||
926 | printf("DDD: unique: %d, duplicates: %d (%3.0f%%)\n", | ||
927 | di.unique, di.dups, di.unique ? (di.dups * 100.0 / di.unique) : 0.0); | ||
928 | |||
929 | #ifdef EINA_SHARE_COMMON_USAGE | ||
930 | printf("DDD: Allocated strings: %i\n", share->population.count); | ||
931 | printf("DDD: Max allocated strings: %i\n", share->population.max); | ||
932 | |||
933 | for (i = 0; | ||
934 | i < sizeof (share->population_group) / | ||
935 | sizeof (share->population_group[0]); | ||
936 | ++i) | ||
937 | fprintf(stderr, | ||
938 | "DDD: %i strings of length %i, max strings: %i\n", | ||
939 | share->population_group[i].count, | ||
940 | i, | ||
941 | share->population_group[i].max); | ||
942 | #endif | ||
943 | |||
944 | eina_lock_release(&_mutex_big); | ||
945 | } | ||
946 | |||
947 | /** | ||
948 | * @endcond | ||
949 | */ | ||
diff --git a/libraries/eina/src/lib/eina_share_common.h b/libraries/eina/src/lib/eina_share_common.h deleted file mode 100644 index 6bc11ef..0000000 --- a/libraries/eina/src/lib/eina_share_common.h +++ /dev/null | |||
@@ -1,86 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2002-2008 Carsten Haitzler, Jorge Luis Zapata Muga, Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * This file incorporates work covered by the following copyright and | ||
19 | * permission notice: | ||
20 | * | ||
21 | * Copyright (C) 2008 Peter Wehrfritz | ||
22 | * | ||
23 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
24 | * of this software and associated documentation files (the "Software"), to | ||
25 | * deal in the Software without restriction, including without limitation the | ||
26 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
27 | * sell copies of the Software, and to permit persons to whom the Software is | ||
28 | * furnished to do so, subject to the following conditions: | ||
29 | * | ||
30 | * The above copyright notice and this permission notice shall be included in | ||
31 | * all copies of the Software and its Copyright notices. In addition publicly | ||
32 | * documented acknowledgment must be given that this software has been used if no | ||
33 | * source code of this software is made available publicly. This includes | ||
34 | * acknowledgments in either Copyright notices, Manuals, Publicity and Marketing | ||
35 | * documents or any documentation provided with any product containing this | ||
36 | * software. This License does not apply to any software that links to the | ||
37 | * libraries provided by this software (statically or dynamically), but only to | ||
38 | * the software provided. | ||
39 | * | ||
40 | * Please see the OLD-COPYING.PLAIN for a plain-english explanation of this notice | ||
41 | * and it's intent. | ||
42 | * | ||
43 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
44 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
45 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
46 | * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
47 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
48 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
49 | */ | ||
50 | |||
51 | #ifndef EINA_SHARE_COMMON_H_ | ||
52 | #define EINA_SHARE_COMMON_H_ | ||
53 | |||
54 | #include "eina_types.h" | ||
55 | #include "eina_magic.h" | ||
56 | |||
57 | typedef struct _Eina_Share Eina_Share; | ||
58 | |||
59 | struct dumpinfo | ||
60 | { | ||
61 | int used, saved, dups, unique; | ||
62 | }; | ||
63 | |||
64 | Eina_Bool eina_share_common_init(Eina_Share **share, | ||
65 | Eina_Magic node_magic, | ||
66 | const char *node_magic_STR); | ||
67 | Eina_Bool eina_share_common_shutdown(Eina_Share **share); | ||
68 | const char *eina_share_common_add_length(Eina_Share *share, | ||
69 | const char *str, | ||
70 | unsigned int slen, | ||
71 | unsigned int null_size) | ||
72 | EINA_WARN_UNUSED_RESULT; | ||
73 | const char *eina_share_common_ref(Eina_Share *share, const char *str); | ||
74 | Eina_Bool eina_share_common_del(Eina_Share *share, const char *str) EINA_WARN_UNUSED_RESULT; | ||
75 | int eina_share_common_length(Eina_Share *share, | ||
76 | const char *str) EINA_CONST | ||
77 | EINA_WARN_UNUSED_RESULT; | ||
78 | void eina_share_common_dump(Eina_Share *share, void (*additional_dump)( | ||
79 | struct dumpinfo *), int used); | ||
80 | |||
81 | |||
82 | /* Population functions */ | ||
83 | void eina_share_common_population_add(Eina_Share *share, int slen); | ||
84 | void eina_share_common_population_del(Eina_Share *share, int slen); | ||
85 | |||
86 | #endif /* EINA_SHARE_COMMON_H_ */ | ||
diff --git a/libraries/eina/src/lib/eina_simple_xml_parser.c b/libraries/eina/src/lib/eina_simple_xml_parser.c deleted file mode 100644 index 4e357ba..0000000 --- a/libraries/eina/src/lib/eina_simple_xml_parser.c +++ /dev/null | |||
@@ -1,1073 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2011 Gustavo Sverzut Barbieri | ||
3 | * Cedric Bail | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Lesser General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2.1 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This library is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * Lesser General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Lesser General Public | ||
16 | * License along with this library; | ||
17 | * if not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #ifdef HAVE_CONFIG_H | ||
21 | # include "config.h" | ||
22 | #endif | ||
23 | |||
24 | #ifdef HAVE_ALLOCA_H | ||
25 | # include <alloca.h> | ||
26 | #elif defined __GNUC__ | ||
27 | # define alloca __builtin_alloca | ||
28 | #elif defined _AIX | ||
29 | # define alloca __alloca | ||
30 | #elif defined _MSC_VER | ||
31 | # include <malloc.h> | ||
32 | # define alloca _alloca | ||
33 | #else | ||
34 | # include <stddef.h> | ||
35 | # ifdef __cplusplus | ||
36 | extern "C" | ||
37 | # endif | ||
38 | void *alloca (size_t); | ||
39 | #endif | ||
40 | |||
41 | #ifdef HAVE_STRINGS_H | ||
42 | # include <strings.h> | ||
43 | #endif | ||
44 | #include <stdlib.h> | ||
45 | #include <string.h> | ||
46 | #include <ctype.h> | ||
47 | |||
48 | #ifdef HAVE_EVIL | ||
49 | # include <Evil.h> | ||
50 | #endif | ||
51 | |||
52 | #include "eina_private.h" | ||
53 | #include "eina_log.h" | ||
54 | #include "eina_mempool.h" | ||
55 | #include "eina_stringshare.h" | ||
56 | #include "eina_strbuf.h" | ||
57 | #include "eina_simple_xml_parser.h" | ||
58 | |||
59 | /*============================================================================* | ||
60 | * Local * | ||
61 | *============================================================================*/ | ||
62 | |||
63 | /** | ||
64 | * @cond LOCAL | ||
65 | */ | ||
66 | |||
67 | static Eina_Mempool *_eina_simple_xml_tag_mp = NULL; | ||
68 | static Eina_Mempool *_eina_simple_xml_attribute_mp = NULL; | ||
69 | static int _eina_simple_xml_log_dom = -1; | ||
70 | |||
71 | static const char EINA_MAGIC_SIMPLE_XML_TAG_STR[] = "Eina Simple XML Tag"; | ||
72 | static const char EINA_MAGIC_SIMPLE_XML_DATA_STR[] = "Eina Simple XML Data"; | ||
73 | static const char EINA_MAGIC_SIMPLE_XML_ATTRIBUTE_STR[] = "Eina Simple XML Attribute"; | ||
74 | |||
75 | #define EINA_MAGIC_CHECK_TAG(d, ...) \ | ||
76 | do { \ | ||
77 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_SIMPLE_XML_TAG)) \ | ||
78 | { \ | ||
79 | EINA_MAGIC_FAIL(d, EINA_MAGIC_SIMPLE_XML_TAG); \ | ||
80 | return __VA_ARGS__; \ | ||
81 | } \ | ||
82 | } while(0) | ||
83 | |||
84 | #define EINA_MAGIC_CHECK_DATA(d, ...) \ | ||
85 | do { \ | ||
86 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_SIMPLE_XML_DATA)) \ | ||
87 | { \ | ||
88 | EINA_MAGIC_FAIL(d, EINA_MAGIC_SIMPLE_XML_DATA); \ | ||
89 | return __VA_ARGS__; \ | ||
90 | } \ | ||
91 | } while(0) | ||
92 | |||
93 | #define EINA_MAGIC_CHECK_ATTRIBUTE(d, ...) \ | ||
94 | do { \ | ||
95 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_SIMPLE_XML_ATTRIBUTE)) \ | ||
96 | { \ | ||
97 | EINA_MAGIC_FAIL(d, EINA_MAGIC_SIMPLE_XML_ATTRIBUTE); \ | ||
98 | return __VA_ARGS__; \ | ||
99 | } \ | ||
100 | } while(0) | ||
101 | |||
102 | |||
103 | #ifndef EINA_LOG_COLOR_DEFAULT | ||
104 | #define EINA_LOG_COLOR_DEFAULT EINA_COLOR_CYAN | ||
105 | #endif | ||
106 | |||
107 | #ifdef ERR | ||
108 | #undef ERR | ||
109 | #endif | ||
110 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_simple_xml_log_dom, __VA_ARGS__) | ||
111 | |||
112 | #ifdef WRN | ||
113 | #undef WRN | ||
114 | #endif | ||
115 | #define WRN(...) EINA_LOG_DOM_WARN(_eina_simple_xml_log_dom, __VA_ARGS__) | ||
116 | |||
117 | #ifdef DBG | ||
118 | #undef DBG | ||
119 | #endif | ||
120 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_simple_xml_log_dom, __VA_ARGS__) | ||
121 | |||
122 | |||
123 | static inline const char * | ||
124 | _eina_simple_xml_whitespace_find(const char *itr, const char *itr_end) | ||
125 | { | ||
126 | for (; itr < itr_end; itr++) | ||
127 | if (isspace((unsigned char)*itr)) break; | ||
128 | return itr; | ||
129 | } | ||
130 | |||
131 | static inline const char * | ||
132 | _eina_simple_xml_whitespace_skip(const char *itr, const char *itr_end) | ||
133 | { | ||
134 | for (; itr < itr_end; itr++) | ||
135 | if (!isspace((unsigned char)*itr)) break; | ||
136 | return itr; | ||
137 | } | ||
138 | |||
139 | static inline const char * | ||
140 | _eina_simple_xml_whitespace_unskip(const char *itr, const char *itr_start) | ||
141 | { | ||
142 | for (itr--; itr > itr_start; itr--) | ||
143 | if (!isspace((unsigned char)*itr)) break; | ||
144 | return itr + 1; | ||
145 | } | ||
146 | |||
147 | static inline const char * | ||
148 | _eina_simple_xml_tag_start_find(const char *itr, const char *itr_end) | ||
149 | { | ||
150 | return memchr(itr, '<', itr_end - itr); | ||
151 | } | ||
152 | |||
153 | static inline const char * | ||
154 | _eina_simple_xml_tag_end_find(const char *itr, const char *itr_end) | ||
155 | { | ||
156 | for (; itr < itr_end; itr++) | ||
157 | if ((*itr == '>') || (*itr == '<')) /* consider < also ends a tag */ | ||
158 | return itr; | ||
159 | return NULL; | ||
160 | } | ||
161 | |||
162 | /** | ||
163 | * @endcond | ||
164 | */ | ||
165 | |||
166 | /*============================================================================* | ||
167 | * Global * | ||
168 | *============================================================================*/ | ||
169 | |||
170 | |||
171 | /** | ||
172 | * @internal | ||
173 | * @brief Initialize the simple xml parser module. | ||
174 | * | ||
175 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
176 | * | ||
177 | * This function sets up the simple xml parser module of Eina. It is called by | ||
178 | * eina_init(). | ||
179 | * | ||
180 | * @see eina_init() | ||
181 | */ | ||
182 | Eina_Bool | ||
183 | eina_simple_xml_init(void) | ||
184 | { | ||
185 | const char *choice, *tmp; | ||
186 | |||
187 | _eina_simple_xml_log_dom = eina_log_domain_register("eina_simple_xml", | ||
188 | EINA_LOG_COLOR_DEFAULT); | ||
189 | if (_eina_simple_xml_log_dom < 0) | ||
190 | { | ||
191 | EINA_LOG_ERR("Could not register log domain: eina_simple_xml"); | ||
192 | return EINA_FALSE; | ||
193 | } | ||
194 | |||
195 | #ifdef EINA_DEFAULT_MEMPOOL | ||
196 | choice = "pass_through"; | ||
197 | #else | ||
198 | choice = "chained_mempool"; | ||
199 | #endif | ||
200 | tmp = getenv("EINA_MEMPOOL"); | ||
201 | if (tmp && tmp[0]) | ||
202 | choice = tmp; | ||
203 | |||
204 | _eina_simple_xml_tag_mp = eina_mempool_add | ||
205 | (choice, "simple_xml_tag", NULL, | ||
206 | sizeof(Eina_Simple_XML_Node_Tag), 320); | ||
207 | if (!_eina_simple_xml_tag_mp) | ||
208 | { | ||
209 | ERR("Mempool for simple_xml_tag cannot be allocated in init."); | ||
210 | goto on_init_fail; | ||
211 | } | ||
212 | |||
213 | _eina_simple_xml_attribute_mp = eina_mempool_add | ||
214 | (choice, "simple_xml_attribute", NULL, | ||
215 | sizeof(Eina_Simple_XML_Attribute), 80); | ||
216 | if (!_eina_simple_xml_attribute_mp) | ||
217 | { | ||
218 | ERR("Mempool for simple_xml_attribute cannot be allocated in init."); | ||
219 | eina_mempool_del(_eina_simple_xml_tag_mp); | ||
220 | goto on_init_fail; | ||
221 | } | ||
222 | |||
223 | #define EMS(n) eina_magic_string_static_set(n, n ## _STR) | ||
224 | EMS(EINA_MAGIC_SIMPLE_XML_TAG); | ||
225 | EMS(EINA_MAGIC_SIMPLE_XML_DATA); | ||
226 | EMS(EINA_MAGIC_SIMPLE_XML_ATTRIBUTE); | ||
227 | #undef EMS | ||
228 | |||
229 | return EINA_TRUE; | ||
230 | |||
231 | on_init_fail: | ||
232 | eina_log_domain_unregister(_eina_simple_xml_log_dom); | ||
233 | _eina_simple_xml_log_dom = -1; | ||
234 | return EINA_FALSE; | ||
235 | } | ||
236 | |||
237 | /** | ||
238 | * @internal | ||
239 | * @brief Shut down the simple xml parser module. | ||
240 | * | ||
241 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
242 | * | ||
243 | * This function shuts down the simple xml parser module set | ||
244 | * up by eina_simple_xml_init(). It is called by | ||
245 | * eina_shutdown(). | ||
246 | * | ||
247 | * @see eina_shutdown() | ||
248 | */ | ||
249 | Eina_Bool | ||
250 | eina_simple_xml_shutdown(void) | ||
251 | { | ||
252 | eina_mempool_del(_eina_simple_xml_attribute_mp); | ||
253 | eina_mempool_del(_eina_simple_xml_tag_mp); | ||
254 | |||
255 | eina_log_domain_unregister(_eina_simple_xml_log_dom); | ||
256 | _eina_simple_xml_log_dom = -1; | ||
257 | return EINA_TRUE; | ||
258 | } | ||
259 | |||
260 | |||
261 | /*============================================================================* | ||
262 | * API * | ||
263 | *============================================================================*/ | ||
264 | |||
265 | |||
266 | EAPI Eina_Bool | ||
267 | eina_simple_xml_parse(const char *buf, unsigned buflen, Eina_Bool strip, Eina_Simple_XML_Cb func, const void *data) | ||
268 | { | ||
269 | const char *itr = buf, *itr_end = buf + buflen; | ||
270 | |||
271 | if (!buf) return EINA_FALSE; | ||
272 | if (!func) return EINA_FALSE; | ||
273 | |||
274 | #define CB(type, start, end) \ | ||
275 | do \ | ||
276 | { \ | ||
277 | size_t _sz = end - start; \ | ||
278 | Eina_Bool _ret; \ | ||
279 | _ret = func((void*)data, type, start, start - buf, _sz); \ | ||
280 | if (!_ret) return EINA_FALSE; \ | ||
281 | } \ | ||
282 | while (0) | ||
283 | |||
284 | while (itr < itr_end) | ||
285 | { | ||
286 | if (itr[0] == '<') | ||
287 | { | ||
288 | if (itr + 1 >= itr_end) | ||
289 | { | ||
290 | CB(EINA_SIMPLE_XML_ERROR, itr, itr_end); | ||
291 | return EINA_FALSE; | ||
292 | } | ||
293 | else | ||
294 | { | ||
295 | Eina_Simple_XML_Type type; | ||
296 | size_t toff; | ||
297 | const char *p; | ||
298 | |||
299 | if (itr[1] == '/') | ||
300 | { | ||
301 | type = EINA_SIMPLE_XML_CLOSE; | ||
302 | toff = 1; | ||
303 | } | ||
304 | else if (itr[1] == '?') | ||
305 | { | ||
306 | type = EINA_SIMPLE_XML_PROCESSING; | ||
307 | toff = 1; | ||
308 | } | ||
309 | else if (itr[1] == '!') | ||
310 | { | ||
311 | if ((itr + sizeof("<!DOCTYPE>") - 1 < itr_end) && | ||
312 | (!memcmp(itr + 2, "DOCTYPE", | ||
313 | sizeof("DOCTYPE") - 1)) && | ||
314 | ((itr[2 + sizeof("DOCTYPE") - 1] == '>') || | ||
315 | (isspace((unsigned char)itr[2 + sizeof("DOCTYPE") - 1])))) | ||
316 | { | ||
317 | type = EINA_SIMPLE_XML_DOCTYPE; | ||
318 | toff = sizeof("!DOCTYPE") - 1; | ||
319 | } | ||
320 | else if ((itr + sizeof("<!---->") - 1 < itr_end) && | ||
321 | (!memcmp(itr + 2, "--", sizeof("--") - 1))) | ||
322 | { | ||
323 | type = EINA_SIMPLE_XML_COMMENT; | ||
324 | toff = sizeof("!--") - 1; | ||
325 | } | ||
326 | else if ((itr + sizeof("<![CDATA[]]>") - 1 < itr_end) && | ||
327 | (!memcmp(itr + 2, "[CDATA[", | ||
328 | sizeof("[CDATA[") - 1))) | ||
329 | { | ||
330 | type = EINA_SIMPLE_XML_CDATA; | ||
331 | toff = sizeof("![CDATA[") - 1; | ||
332 | } | ||
333 | else | ||
334 | { | ||
335 | type = EINA_SIMPLE_XML_OPEN; | ||
336 | toff = 0; | ||
337 | } | ||
338 | } | ||
339 | else | ||
340 | { | ||
341 | type = EINA_SIMPLE_XML_OPEN; | ||
342 | toff = 0; | ||
343 | } | ||
344 | |||
345 | p = _eina_simple_xml_tag_end_find(itr + 1 + toff, itr_end); | ||
346 | if (p) | ||
347 | { | ||
348 | if (type == EINA_SIMPLE_XML_CDATA) | ||
349 | { | ||
350 | /* must end with ]]> */ | ||
351 | while ((p) && (memcmp(p - 2, "]]>", 3))) | ||
352 | p = _eina_simple_xml_tag_end_find(p + 1, itr_end); | ||
353 | } | ||
354 | |||
355 | if ((p) && (*p == '<')) | ||
356 | { | ||
357 | type = EINA_SIMPLE_XML_ERROR; | ||
358 | toff = 0; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | if (p) | ||
363 | { | ||
364 | const char *start, *end; | ||
365 | |||
366 | start = itr + 1 + toff; | ||
367 | end = p; | ||
368 | |||
369 | switch (type) | ||
370 | { | ||
371 | case EINA_SIMPLE_XML_OPEN: | ||
372 | if (p[-1] == '/') | ||
373 | { | ||
374 | type = EINA_SIMPLE_XML_OPEN_EMPTY; | ||
375 | end--; | ||
376 | } | ||
377 | break; | ||
378 | case EINA_SIMPLE_XML_CDATA: | ||
379 | if (!memcmp(p - 2, "]]", 2)) end -= 2; | ||
380 | break; | ||
381 | case EINA_SIMPLE_XML_PROCESSING: | ||
382 | if (p[-1] == '?') end--; | ||
383 | break; | ||
384 | case EINA_SIMPLE_XML_COMMENT: | ||
385 | if (!memcmp(p - 2, "--", 2)) end -= 2; | ||
386 | break; | ||
387 | case EINA_SIMPLE_XML_OPEN_EMPTY: | ||
388 | case EINA_SIMPLE_XML_CLOSE: | ||
389 | case EINA_SIMPLE_XML_DATA: | ||
390 | case EINA_SIMPLE_XML_ERROR: | ||
391 | case EINA_SIMPLE_XML_DOCTYPE: | ||
392 | case EINA_SIMPLE_XML_IGNORED: | ||
393 | break; | ||
394 | } | ||
395 | |||
396 | if ((strip) && (type != EINA_SIMPLE_XML_ERROR)) | ||
397 | { | ||
398 | start = _eina_simple_xml_whitespace_skip | ||
399 | (start, end); | ||
400 | end = _eina_simple_xml_whitespace_unskip | ||
401 | (end, start + 1); | ||
402 | } | ||
403 | |||
404 | CB(type, start, end); | ||
405 | |||
406 | if (type != EINA_SIMPLE_XML_ERROR) | ||
407 | itr = p + 1; | ||
408 | else | ||
409 | itr = p; | ||
410 | } | ||
411 | else | ||
412 | { | ||
413 | CB(EINA_SIMPLE_XML_ERROR, itr, itr_end); | ||
414 | return EINA_FALSE; | ||
415 | } | ||
416 | } | ||
417 | } | ||
418 | else | ||
419 | { | ||
420 | const char *p, *end; | ||
421 | |||
422 | if (strip) | ||
423 | { | ||
424 | p = _eina_simple_xml_whitespace_skip(itr, itr_end); | ||
425 | if (p) | ||
426 | { | ||
427 | CB(EINA_SIMPLE_XML_IGNORED, itr, p); | ||
428 | itr = p; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | p = _eina_simple_xml_tag_start_find(itr, itr_end); | ||
433 | if (!p) p = itr_end; | ||
434 | |||
435 | end = p; | ||
436 | if (strip) | ||
437 | end = _eina_simple_xml_whitespace_unskip(end, itr); | ||
438 | |||
439 | if (itr != end) | ||
440 | CB(EINA_SIMPLE_XML_DATA, itr, end); | ||
441 | |||
442 | if ((strip) && (end < p)) | ||
443 | CB(EINA_SIMPLE_XML_IGNORED, end, p); | ||
444 | |||
445 | itr = p; | ||
446 | } | ||
447 | } | ||
448 | |||
449 | #undef CB | ||
450 | |||
451 | return EINA_TRUE; | ||
452 | } | ||
453 | |||
454 | EAPI const char * | ||
455 | eina_simple_xml_tag_attributes_find(const char *buf, unsigned buflen) | ||
456 | { | ||
457 | const char *itr = buf, *itr_end = buf + buflen; | ||
458 | |||
459 | for (; itr < itr_end; itr++) | ||
460 | { | ||
461 | if (!isspace((unsigned char)*itr)) | ||
462 | { | ||
463 | /* user skip tagname and already gave it the attributes */ | ||
464 | if (*itr == '=') | ||
465 | return buf; | ||
466 | } | ||
467 | else | ||
468 | { | ||
469 | itr = _eina_simple_xml_whitespace_skip(itr + 1, itr_end); | ||
470 | if (itr == itr_end) | ||
471 | return NULL; | ||
472 | return itr; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | return NULL; | ||
477 | } | ||
478 | |||
479 | EAPI Eina_Bool | ||
480 | eina_simple_xml_attributes_parse(const char *buf, unsigned buflen, Eina_Simple_XML_Attribute_Cb func, const void *data) | ||
481 | { | ||
482 | const char *itr = buf, *itr_end = buf + buflen; | ||
483 | char *tmpbuf = alloca(buflen + 1); | ||
484 | |||
485 | if (!buf) return EINA_FALSE; | ||
486 | if (!func) return EINA_FALSE; | ||
487 | |||
488 | while (itr < itr_end) | ||
489 | { | ||
490 | const char *p = _eina_simple_xml_whitespace_skip(itr, itr_end); | ||
491 | const char *key, *key_end, *value, *value_end; | ||
492 | char *tval; | ||
493 | |||
494 | if (p == itr_end) return EINA_TRUE; | ||
495 | |||
496 | key = p; | ||
497 | for (key_end = key; key_end < itr_end; key_end++) | ||
498 | if ((*key_end == '=') || (isspace((unsigned char)*key_end))) break; | ||
499 | if (key_end == itr_end) return EINA_FALSE; | ||
500 | if (key_end == key) continue; | ||
501 | |||
502 | if (*key_end == '=') value = key_end + 1; | ||
503 | else | ||
504 | { | ||
505 | value = memchr(key_end, '=', itr_end - key_end); | ||
506 | if (!value) return EINA_FALSE; | ||
507 | value++; | ||
508 | } | ||
509 | for (; value < itr_end; value++) | ||
510 | if (!isspace((unsigned char)*value)) break; | ||
511 | if (value == itr_end) return EINA_FALSE; | ||
512 | |||
513 | if ((*value == '"') || (*value == '\'')) | ||
514 | { | ||
515 | value_end = memchr(value + 1, *value, itr_end - value); | ||
516 | if (!value_end) return EINA_FALSE; | ||
517 | value++; | ||
518 | } | ||
519 | else | ||
520 | { | ||
521 | value_end = _eina_simple_xml_whitespace_find(value, itr_end); | ||
522 | } | ||
523 | |||
524 | memcpy(tmpbuf, key, key_end - key); | ||
525 | tmpbuf[key_end - key] = '\0'; | ||
526 | |||
527 | tval = tmpbuf + (key_end - key) + 1; | ||
528 | memcpy(tval, value, value_end - value); | ||
529 | tval[value_end - value] = '\0'; | ||
530 | |||
531 | if (!func((void*)data, tmpbuf, tval)) | ||
532 | return EINA_FALSE; | ||
533 | |||
534 | itr = value_end + 1; | ||
535 | } | ||
536 | return EINA_TRUE; | ||
537 | } | ||
538 | |||
539 | /* Node loader *************************************************************/ | ||
540 | |||
541 | EAPI Eina_Simple_XML_Attribute * | ||
542 | eina_simple_xml_attribute_new(Eina_Simple_XML_Node_Tag *parent, const char *key, const char *value) | ||
543 | { | ||
544 | Eina_Simple_XML_Attribute *attr; | ||
545 | |||
546 | if (!key) return NULL; | ||
547 | |||
548 | attr = eina_mempool_malloc(_eina_simple_xml_attribute_mp, sizeof(*attr)); | ||
549 | if (!attr) | ||
550 | { | ||
551 | ERR("could not allocate memory for attribute from mempool"); | ||
552 | return NULL; | ||
553 | } | ||
554 | |||
555 | EINA_MAGIC_SET(attr, EINA_MAGIC_SIMPLE_XML_ATTRIBUTE); | ||
556 | attr->parent = parent; | ||
557 | attr->key = eina_stringshare_add(key); | ||
558 | attr->value = eina_stringshare_add(value ? value : ""); | ||
559 | |||
560 | if (parent) | ||
561 | parent->attributes = eina_inlist_append | ||
562 | (parent->attributes, EINA_INLIST_GET(attr)); | ||
563 | |||
564 | return attr; | ||
565 | } | ||
566 | |||
567 | EAPI void | ||
568 | eina_simple_xml_attribute_free(Eina_Simple_XML_Attribute *attr) | ||
569 | { | ||
570 | EINA_MAGIC_CHECK_ATTRIBUTE(attr); | ||
571 | |||
572 | if (attr->parent) | ||
573 | attr->parent->attributes = eina_inlist_remove | ||
574 | (attr->parent->attributes, EINA_INLIST_GET(attr)); | ||
575 | |||
576 | eina_stringshare_del(attr->key); | ||
577 | eina_stringshare_del(attr->value); | ||
578 | EINA_MAGIC_SET(attr, EINA_MAGIC_NONE); | ||
579 | eina_mempool_free(_eina_simple_xml_attribute_mp, attr); | ||
580 | } | ||
581 | |||
582 | static void | ||
583 | _eina_simple_xml_node_data_free(Eina_Simple_XML_Node_Data *node) | ||
584 | { | ||
585 | if (node->base.parent) | ||
586 | node->base.parent->children = eina_inlist_remove | ||
587 | (node->base.parent->children, EINA_INLIST_GET(&node->base)); | ||
588 | |||
589 | EINA_MAGIC_SET(&node->base, EINA_MAGIC_NONE); | ||
590 | free(node); | ||
591 | } | ||
592 | |||
593 | EAPI Eina_Simple_XML_Node_Tag * | ||
594 | eina_simple_xml_node_tag_new(Eina_Simple_XML_Node_Tag *parent, const char *name) | ||
595 | { | ||
596 | Eina_Simple_XML_Node_Tag *n; | ||
597 | |||
598 | if (!name) return NULL; | ||
599 | |||
600 | n = eina_mempool_malloc(_eina_simple_xml_tag_mp, sizeof(*n)); | ||
601 | if (!n) | ||
602 | { | ||
603 | ERR("could not allocate memory for node from mempool"); | ||
604 | return NULL; | ||
605 | } | ||
606 | |||
607 | memset(n, 0, sizeof(*n)); | ||
608 | |||
609 | EINA_MAGIC_SET(&n->base, EINA_MAGIC_SIMPLE_XML_TAG); | ||
610 | |||
611 | n->base.type = EINA_SIMPLE_XML_NODE_TAG; | ||
612 | n->base.parent = parent; | ||
613 | n->name = eina_stringshare_add(name); | ||
614 | |||
615 | if (parent) | ||
616 | parent->children = eina_inlist_append | ||
617 | (parent->children, EINA_INLIST_GET(&n->base)); | ||
618 | |||
619 | return n; | ||
620 | } | ||
621 | |||
622 | void | ||
623 | _eina_simple_xml_node_tag_free(Eina_Simple_XML_Node_Tag *tag) | ||
624 | { | ||
625 | while (tag->children) | ||
626 | { | ||
627 | Eina_Simple_XML_Node *n = EINA_INLIST_CONTAINER_GET | ||
628 | (tag->children, Eina_Simple_XML_Node); | ||
629 | if (n->type == EINA_SIMPLE_XML_NODE_TAG) | ||
630 | _eina_simple_xml_node_tag_free((Eina_Simple_XML_Node_Tag *)n); | ||
631 | else | ||
632 | _eina_simple_xml_node_data_free((Eina_Simple_XML_Node_Data *)n); | ||
633 | } | ||
634 | |||
635 | while (tag->attributes) | ||
636 | { | ||
637 | Eina_Simple_XML_Attribute *a = EINA_INLIST_CONTAINER_GET | ||
638 | (tag->attributes, Eina_Simple_XML_Attribute); | ||
639 | eina_simple_xml_attribute_free(a); | ||
640 | } | ||
641 | |||
642 | if (tag->base.parent) | ||
643 | tag->base.parent->children = eina_inlist_remove | ||
644 | (tag->base.parent->children, EINA_INLIST_GET(&tag->base)); | ||
645 | |||
646 | eina_stringshare_del(tag->name); | ||
647 | EINA_MAGIC_SET(&tag->base, EINA_MAGIC_NONE); | ||
648 | eina_mempool_free(_eina_simple_xml_tag_mp, tag); | ||
649 | } | ||
650 | |||
651 | EAPI void | ||
652 | eina_simple_xml_node_tag_free(Eina_Simple_XML_Node_Tag *tag) | ||
653 | { | ||
654 | EINA_MAGIC_CHECK_TAG(&tag->base); | ||
655 | if (tag->base.type != EINA_SIMPLE_XML_NODE_TAG) | ||
656 | { | ||
657 | ERR("expected tag node!"); | ||
658 | return; | ||
659 | } | ||
660 | _eina_simple_xml_node_tag_free(tag); | ||
661 | } | ||
662 | |||
663 | static Eina_Simple_XML_Node_Data * | ||
664 | _eina_simple_xml_node_data_new(Eina_Simple_XML_Node_Tag *parent, Eina_Simple_XML_Node_Type type, const char *content, unsigned length) | ||
665 | { | ||
666 | Eina_Simple_XML_Node_Data *n = malloc(sizeof(*n) + length + 1); | ||
667 | |||
668 | if (!content) return NULL; | ||
669 | |||
670 | if (!n) | ||
671 | { | ||
672 | ERR("could not allocate memory for node"); | ||
673 | return NULL; | ||
674 | } | ||
675 | |||
676 | EINA_MAGIC_SET(&n->base, EINA_MAGIC_SIMPLE_XML_DATA); | ||
677 | n->base.type = type; | ||
678 | n->base.parent = parent; | ||
679 | |||
680 | n->length = length; | ||
681 | memcpy(n->data, content, length); | ||
682 | n->data[length] = '\0'; | ||
683 | |||
684 | if (parent) | ||
685 | parent->children = eina_inlist_append | ||
686 | (parent->children, EINA_INLIST_GET(&n->base)); | ||
687 | |||
688 | return n; | ||
689 | } | ||
690 | |||
691 | EAPI Eina_Simple_XML_Node_Data * | ||
692 | eina_simple_xml_node_data_new(Eina_Simple_XML_Node_Tag *parent, const char *contents, size_t length) | ||
693 | { | ||
694 | return _eina_simple_xml_node_data_new | ||
695 | (parent, EINA_SIMPLE_XML_NODE_DATA, contents, length); | ||
696 | } | ||
697 | |||
698 | EAPI void | ||
699 | eina_simple_xml_node_data_free(Eina_Simple_XML_Node_Data *node) | ||
700 | { | ||
701 | EINA_MAGIC_CHECK_DATA(&node->base); | ||
702 | if (node->base.type != EINA_SIMPLE_XML_NODE_DATA) | ||
703 | { | ||
704 | ERR("expected node of type: data!"); | ||
705 | return; | ||
706 | } | ||
707 | _eina_simple_xml_node_data_free(node); | ||
708 | } | ||
709 | |||
710 | EAPI Eina_Simple_XML_Node_CData * | ||
711 | eina_simple_xml_node_cdata_new(Eina_Simple_XML_Node_Tag *parent, const char *contents, size_t length) | ||
712 | { | ||
713 | return _eina_simple_xml_node_data_new | ||
714 | (parent, EINA_SIMPLE_XML_NODE_CDATA, contents, length); | ||
715 | } | ||
716 | |||
717 | EAPI void | ||
718 | eina_simple_xml_node_cdata_free(Eina_Simple_XML_Node_Data *node) | ||
719 | { | ||
720 | EINA_MAGIC_CHECK_DATA(&node->base); | ||
721 | if (node->base.type != EINA_SIMPLE_XML_NODE_CDATA) | ||
722 | { | ||
723 | ERR("expected node of type: cdata!"); | ||
724 | return; | ||
725 | } | ||
726 | _eina_simple_xml_node_data_free(node); | ||
727 | } | ||
728 | |||
729 | EAPI Eina_Simple_XML_Node_Processing * | ||
730 | eina_simple_xml_node_processing_new(Eina_Simple_XML_Node_Tag *parent, const char *contents, size_t length) | ||
731 | { | ||
732 | return _eina_simple_xml_node_data_new | ||
733 | (parent, EINA_SIMPLE_XML_NODE_PROCESSING, contents, length); | ||
734 | } | ||
735 | |||
736 | EAPI void | ||
737 | eina_simple_xml_node_processing_free(Eina_Simple_XML_Node_Data *node) | ||
738 | { | ||
739 | EINA_MAGIC_CHECK_DATA(&node->base); | ||
740 | if (node->base.type != EINA_SIMPLE_XML_NODE_PROCESSING) | ||
741 | { | ||
742 | ERR("expected node of type: processing!"); | ||
743 | return; | ||
744 | } | ||
745 | _eina_simple_xml_node_data_free(node); | ||
746 | } | ||
747 | |||
748 | EAPI Eina_Simple_XML_Node_Doctype * | ||
749 | eina_simple_xml_node_doctype_new(Eina_Simple_XML_Node_Tag *parent, const char *contents, size_t length) | ||
750 | { | ||
751 | return _eina_simple_xml_node_data_new | ||
752 | (parent, EINA_SIMPLE_XML_NODE_DOCTYPE, contents, length); | ||
753 | } | ||
754 | |||
755 | EAPI void | ||
756 | eina_simple_xml_node_doctype_free(Eina_Simple_XML_Node_Data *node) | ||
757 | { | ||
758 | EINA_MAGIC_CHECK_DATA(&node->base); | ||
759 | if (node->base.type != EINA_SIMPLE_XML_NODE_DOCTYPE) | ||
760 | { | ||
761 | ERR("expected node of type: doctype!"); | ||
762 | return; | ||
763 | } | ||
764 | _eina_simple_xml_node_data_free(node); | ||
765 | } | ||
766 | |||
767 | EAPI Eina_Simple_XML_Node_Comment * | ||
768 | eina_simple_xml_node_comment_new(Eina_Simple_XML_Node_Tag *parent, const char *contents, size_t length) | ||
769 | { | ||
770 | return _eina_simple_xml_node_data_new | ||
771 | (parent, EINA_SIMPLE_XML_NODE_COMMENT, contents, length); | ||
772 | } | ||
773 | |||
774 | EAPI void | ||
775 | eina_simple_xml_node_comment_free(Eina_Simple_XML_Node_Data *node) | ||
776 | { | ||
777 | EINA_MAGIC_CHECK_DATA(&node->base); | ||
778 | if (node->base.type != EINA_SIMPLE_XML_NODE_COMMENT) | ||
779 | { | ||
780 | ERR("expected node of type: comment!"); | ||
781 | return; | ||
782 | } | ||
783 | _eina_simple_xml_node_data_free(node); | ||
784 | } | ||
785 | |||
786 | struct eina_simple_xml_node_load_ctxt | ||
787 | { | ||
788 | Eina_Simple_XML_Node_Root *root; | ||
789 | Eina_Simple_XML_Node_Tag *current; | ||
790 | }; | ||
791 | |||
792 | static Eina_Bool | ||
793 | _eina_simple_xml_attrs_parse(void *data, const char *key, const char *value) | ||
794 | { | ||
795 | Eina_Simple_XML_Node_Tag *n = data; | ||
796 | Eina_Simple_XML_Attribute *attr; | ||
797 | |||
798 | attr = eina_simple_xml_attribute_new(n, key, value); | ||
799 | return !!attr; | ||
800 | } | ||
801 | |||
802 | static Eina_Bool | ||
803 | _eina_simple_xml_node_parse(void *data, Eina_Simple_XML_Type type, const char *content, unsigned offset, unsigned length) | ||
804 | { | ||
805 | struct eina_simple_xml_node_load_ctxt *ctx = data; | ||
806 | |||
807 | switch (type) | ||
808 | { | ||
809 | case EINA_SIMPLE_XML_OPEN: | ||
810 | case EINA_SIMPLE_XML_OPEN_EMPTY: | ||
811 | { | ||
812 | Eina_Simple_XML_Node_Tag *n; | ||
813 | const char *name, *name_end, *attrs; | ||
814 | |||
815 | attrs = eina_simple_xml_tag_attributes_find(content, length); | ||
816 | if (!attrs) | ||
817 | name_end = content + length; | ||
818 | else | ||
819 | name_end = attrs; | ||
820 | |||
821 | name_end = _eina_simple_xml_whitespace_unskip(name_end, content); | ||
822 | |||
823 | name = eina_stringshare_add_length(content, name_end - content); | ||
824 | n = eina_simple_xml_node_tag_new(ctx->current, name); | ||
825 | eina_stringshare_del(name); | ||
826 | if (!n) return EINA_FALSE; | ||
827 | |||
828 | if (attrs) | ||
829 | eina_simple_xml_attributes_parse | ||
830 | (attrs, length - (attrs - content), | ||
831 | _eina_simple_xml_attrs_parse, n); | ||
832 | |||
833 | if (type == EINA_SIMPLE_XML_OPEN) | ||
834 | ctx->current = n; | ||
835 | } | ||
836 | break; | ||
837 | |||
838 | case EINA_SIMPLE_XML_CLOSE: | ||
839 | if (ctx->current->base.parent) | ||
840 | { | ||
841 | const char *end = _eina_simple_xml_whitespace_unskip | ||
842 | (content + length, content); | ||
843 | int len; | ||
844 | len = end - content; | ||
845 | if ((len == 0) /* </> closes the tag for us. */ || | ||
846 | ((eina_stringshare_strlen(ctx->current->name) == len) && | ||
847 | (memcmp(ctx->current->name, content, len) == 0))) | ||
848 | ctx->current = ctx->current->base.parent; | ||
849 | else | ||
850 | WRN("closed incorrect tag: '%.*s', '%s' was expected!", | ||
851 | len, content, ctx->current->name); | ||
852 | } | ||
853 | else | ||
854 | WRN("closed tag '%.*s' but already at document root!", | ||
855 | length, content); | ||
856 | break; | ||
857 | |||
858 | case EINA_SIMPLE_XML_DATA: | ||
859 | return !!eina_simple_xml_node_data_new | ||
860 | (ctx->current, content, length); | ||
861 | case EINA_SIMPLE_XML_CDATA: | ||
862 | return !!eina_simple_xml_node_cdata_new | ||
863 | (ctx->current, content, length); | ||
864 | case EINA_SIMPLE_XML_PROCESSING: | ||
865 | return !!eina_simple_xml_node_processing_new | ||
866 | (ctx->current, content, length); | ||
867 | case EINA_SIMPLE_XML_DOCTYPE: | ||
868 | return !!eina_simple_xml_node_doctype_new | ||
869 | (ctx->current, content, length); | ||
870 | case EINA_SIMPLE_XML_COMMENT: | ||
871 | return !!eina_simple_xml_node_comment_new | ||
872 | (ctx->current, content, length); | ||
873 | |||
874 | case EINA_SIMPLE_XML_ERROR: | ||
875 | ERR("parser error at offset %u-%u: %.*s", | ||
876 | offset, length, length, content); | ||
877 | break; | ||
878 | case EINA_SIMPLE_XML_IGNORED: | ||
879 | DBG("ignored contents at offset %u-%u: %.*s", | ||
880 | offset, length, length, content); | ||
881 | break; | ||
882 | } | ||
883 | |||
884 | return EINA_TRUE; | ||
885 | } | ||
886 | |||
887 | EAPI Eina_Simple_XML_Node_Root * | ||
888 | eina_simple_xml_node_load(const char *buf, unsigned buflen, Eina_Bool strip) | ||
889 | { | ||
890 | Eina_Simple_XML_Node_Root *root; | ||
891 | struct eina_simple_xml_node_load_ctxt ctx; | ||
892 | |||
893 | if (!buf) return NULL; | ||
894 | |||
895 | root = eina_mempool_malloc(_eina_simple_xml_tag_mp, sizeof(*root)); | ||
896 | if (!root) return NULL; | ||
897 | |||
898 | memset(root, 0, sizeof(*root)); | ||
899 | EINA_MAGIC_SET(&root->base, EINA_MAGIC_SIMPLE_XML_TAG); | ||
900 | root->base.type = EINA_SIMPLE_XML_NODE_ROOT; | ||
901 | |||
902 | ctx.root = root; | ||
903 | ctx.current = root; | ||
904 | eina_simple_xml_parse(buf, buflen, strip, _eina_simple_xml_node_parse, &ctx); | ||
905 | |||
906 | return root; | ||
907 | } | ||
908 | |||
909 | EAPI void | ||
910 | eina_simple_xml_node_root_free(Eina_Simple_XML_Node_Root *root) | ||
911 | { | ||
912 | if (!root) return; | ||
913 | EINA_MAGIC_CHECK_TAG(&root->base); | ||
914 | if (root->base.type != EINA_SIMPLE_XML_NODE_ROOT) | ||
915 | { | ||
916 | ERR("expected root node!"); | ||
917 | return; | ||
918 | } | ||
919 | _eina_simple_xml_node_tag_free(root); | ||
920 | } | ||
921 | |||
922 | static inline void | ||
923 | _eina_simple_xml_node_dump_indent(Eina_Strbuf *buf, const char *indent, unsigned level) | ||
924 | { | ||
925 | unsigned i, indent_len = strlen(indent); | ||
926 | for (i = 0; i < level; i++) | ||
927 | eina_strbuf_append_length(buf, indent, indent_len); | ||
928 | } | ||
929 | |||
930 | static void | ||
931 | _eina_simple_xml_node_tag_attributes_append(Eina_Strbuf *buf, Eina_Simple_XML_Node_Tag *tag) | ||
932 | { | ||
933 | Eina_Simple_XML_Attribute *a; | ||
934 | |||
935 | EINA_INLIST_FOREACH(tag->attributes, a) | ||
936 | eina_strbuf_append_printf(buf, " %s=\"%s\"", a->key, a->value); | ||
937 | } | ||
938 | |||
939 | static void _eina_simple_xml_node_dump(Eina_Strbuf *buf, Eina_Simple_XML_Node *node, const char *indent, unsigned level); | ||
940 | |||
941 | static void | ||
942 | _eina_simple_xml_node_children_dump(Eina_Strbuf *buf, Eina_Simple_XML_Node_Tag *tag, const char *indent, unsigned level) | ||
943 | { | ||
944 | Eina_Simple_XML_Node *node; | ||
945 | |||
946 | EINA_INLIST_FOREACH(tag->children, node) | ||
947 | _eina_simple_xml_node_dump(buf, node, indent, level); | ||
948 | } | ||
949 | |||
950 | static void | ||
951 | _eina_simple_xml_node_dump(Eina_Strbuf *buf, Eina_Simple_XML_Node *node, const char *indent, unsigned level) | ||
952 | { | ||
953 | switch (node->type) | ||
954 | { | ||
955 | case EINA_SIMPLE_XML_NODE_ROOT: | ||
956 | _eina_simple_xml_node_children_dump | ||
957 | (buf, (Eina_Simple_XML_Node_Tag *)node, indent, level); | ||
958 | break; | ||
959 | |||
960 | case EINA_SIMPLE_XML_NODE_TAG: | ||
961 | { | ||
962 | Eina_Simple_XML_Node_Tag *n = (Eina_Simple_XML_Node_Tag *)node; | ||
963 | |||
964 | if (indent) _eina_simple_xml_node_dump_indent(buf, indent, level); | ||
965 | |||
966 | eina_strbuf_append_char(buf, '<'); | ||
967 | eina_strbuf_append_length | ||
968 | (buf, n->name, eina_stringshare_strlen(n->name)); | ||
969 | |||
970 | if (n->attributes) | ||
971 | _eina_simple_xml_node_tag_attributes_append(buf, n); | ||
972 | |||
973 | if (n->children) | ||
974 | eina_strbuf_append_char(buf, '>'); | ||
975 | else | ||
976 | eina_strbuf_append_length(buf, "/>", sizeof("/>") - 1); | ||
977 | |||
978 | if (indent) eina_strbuf_append_char(buf, '\n'); | ||
979 | |||
980 | if (n->children) | ||
981 | { | ||
982 | _eina_simple_xml_node_children_dump(buf, n, indent, level + 1); | ||
983 | |||
984 | if (indent) | ||
985 | _eina_simple_xml_node_dump_indent(buf, indent, level); | ||
986 | |||
987 | eina_strbuf_append_length(buf, "</", sizeof("</") - 1); | ||
988 | eina_strbuf_append_length | ||
989 | (buf, n->name, eina_stringshare_strlen(n->name)); | ||
990 | eina_strbuf_append_char(buf, '>'); | ||
991 | |||
992 | if (indent) eina_strbuf_append_char(buf, '\n'); | ||
993 | } | ||
994 | } | ||
995 | break; | ||
996 | case EINA_SIMPLE_XML_NODE_DATA: | ||
997 | { | ||
998 | Eina_Simple_XML_Node_Data *n = (Eina_Simple_XML_Node_Data *)node; | ||
999 | |||
1000 | if (indent) _eina_simple_xml_node_dump_indent(buf, indent, level); | ||
1001 | eina_strbuf_append_length(buf, n->data, n->length); | ||
1002 | if (indent) eina_strbuf_append_char(buf, '\n'); | ||
1003 | } | ||
1004 | break; | ||
1005 | |||
1006 | case EINA_SIMPLE_XML_NODE_CDATA: | ||
1007 | { | ||
1008 | Eina_Simple_XML_Node_Data *n = (Eina_Simple_XML_Node_Data *)node; | ||
1009 | |||
1010 | if (indent) _eina_simple_xml_node_dump_indent(buf, indent, level); | ||
1011 | eina_strbuf_append_length(buf, "<![CDATA[", sizeof("<![CDATA[") - 1); | ||
1012 | eina_strbuf_append_length(buf, n->data, n->length); | ||
1013 | eina_strbuf_append_length(buf, "]]>", sizeof("]]>") - 1); | ||
1014 | if (indent) eina_strbuf_append_char(buf, '\n'); | ||
1015 | } | ||
1016 | break; | ||
1017 | |||
1018 | case EINA_SIMPLE_XML_NODE_PROCESSING: | ||
1019 | { | ||
1020 | Eina_Simple_XML_Node_Data *n = (Eina_Simple_XML_Node_Data *)node; | ||
1021 | |||
1022 | if (indent) _eina_simple_xml_node_dump_indent(buf, indent, level); | ||
1023 | eina_strbuf_append_length(buf, "<?", sizeof("<?") - 1); | ||
1024 | eina_strbuf_append_length(buf, n->data, n->length); | ||
1025 | eina_strbuf_append_length(buf, " ?>", sizeof(" ?>") - 1); | ||
1026 | if (indent) eina_strbuf_append_char(buf, '\n'); | ||
1027 | } | ||
1028 | break; | ||
1029 | |||
1030 | case EINA_SIMPLE_XML_NODE_DOCTYPE: | ||
1031 | { | ||
1032 | Eina_Simple_XML_Node_Data *n = (Eina_Simple_XML_Node_Data *)node; | ||
1033 | |||
1034 | if (indent) _eina_simple_xml_node_dump_indent(buf, indent, level); | ||
1035 | eina_strbuf_append_length | ||
1036 | (buf, "<!DOCTYPE ", sizeof("<!DOCTYPE ") - 1); | ||
1037 | eina_strbuf_append_length(buf, n->data, n->length); | ||
1038 | eina_strbuf_append_char(buf, '>'); | ||
1039 | if (indent) eina_strbuf_append_char(buf, '\n'); | ||
1040 | } | ||
1041 | break; | ||
1042 | |||
1043 | case EINA_SIMPLE_XML_NODE_COMMENT: | ||
1044 | { | ||
1045 | Eina_Simple_XML_Node_Data *n = (Eina_Simple_XML_Node_Data *)node; | ||
1046 | |||
1047 | if (indent) _eina_simple_xml_node_dump_indent(buf, indent, level); | ||
1048 | eina_strbuf_append_length(buf, "<!-- ", sizeof("<!-- ") - 1); | ||
1049 | eina_strbuf_append_length(buf, n->data, n->length); | ||
1050 | eina_strbuf_append_length(buf, " -->", sizeof(" -->") - 1); | ||
1051 | if (indent) eina_strbuf_append_char(buf, '\n'); | ||
1052 | } | ||
1053 | break; | ||
1054 | } | ||
1055 | } | ||
1056 | |||
1057 | EAPI char * | ||
1058 | eina_simple_xml_node_dump(Eina_Simple_XML_Node *node, const char *indent) | ||
1059 | { | ||
1060 | Eina_Strbuf *buf; | ||
1061 | char *ret; | ||
1062 | |||
1063 | if (!node) return NULL; | ||
1064 | |||
1065 | buf = eina_strbuf_new(); | ||
1066 | if (!buf) return NULL; | ||
1067 | |||
1068 | _eina_simple_xml_node_dump(buf, node, indent, 0); | ||
1069 | |||
1070 | ret = eina_strbuf_string_steal(buf); | ||
1071 | eina_strbuf_free(buf); | ||
1072 | return ret; | ||
1073 | } | ||
diff --git a/libraries/eina/src/lib/eina_str.c b/libraries/eina/src/lib/eina_str.c deleted file mode 100644 index 8d27c65..0000000 --- a/libraries/eina/src/lib/eina_str.c +++ /dev/null | |||
@@ -1,462 +0,0 @@ | |||
1 | /* Leave the OpenBSD version below so we can track upstream fixes */ | ||
2 | /* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ | ||
3 | |||
4 | /* | ||
5 | * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> | ||
6 | * | ||
7 | * Permission to use, copy, modify, and distribute this software for any | ||
8 | * purpose with or without fee is hereby granted, provided that the above | ||
9 | * copyright notice and this permission notice appear in all copies. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
18 | */ | ||
19 | |||
20 | |||
21 | #ifdef HAVE_CONFIG_H | ||
22 | # include "config.h" | ||
23 | #endif | ||
24 | |||
25 | #include <stdio.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <string.h> | ||
28 | #include <limits.h> | ||
29 | #include <ctype.h> | ||
30 | |||
31 | #ifdef HAVE_ICONV | ||
32 | # include <errno.h> | ||
33 | # include <iconv.h> | ||
34 | #endif | ||
35 | |||
36 | #include "eina_private.h" | ||
37 | #include "eina_str.h" | ||
38 | |||
39 | /*============================================================================* | ||
40 | * Local * | ||
41 | *============================================================================*/ | ||
42 | |||
43 | /** | ||
44 | * @cond LOCAL | ||
45 | */ | ||
46 | |||
47 | /* | ||
48 | * Internal helper function used by eina_str_has_suffix() and | ||
49 | * eina_str_has_extension() | ||
50 | */ | ||
51 | static inline Eina_Bool | ||
52 | eina_str_has_suffix_helper(const char *str, | ||
53 | const char *suffix, | ||
54 | int (*cmp)(const char *, const char *)) | ||
55 | { | ||
56 | size_t str_len; | ||
57 | size_t suffix_len; | ||
58 | |||
59 | if ((!str) || (!suffix)) return EINA_FALSE; | ||
60 | str_len = strlen(str); | ||
61 | suffix_len = eina_strlen_bounded(suffix, str_len); | ||
62 | if (suffix_len == (size_t)-1) | ||
63 | return EINA_FALSE; | ||
64 | |||
65 | return cmp(str + str_len - suffix_len, suffix) == 0; | ||
66 | } | ||
67 | |||
68 | static inline char ** | ||
69 | eina_str_split_full_helper(const char *str, | ||
70 | const char *delim, | ||
71 | int max_tokens, | ||
72 | unsigned int *elements) | ||
73 | { | ||
74 | char *s, **str_array; | ||
75 | const char *src; | ||
76 | size_t len, dlen; | ||
77 | unsigned int tokens; | ||
78 | |||
79 | dlen = strlen(delim); | ||
80 | if (dlen == 0) | ||
81 | { | ||
82 | if (elements) | ||
83 | *elements = 0; | ||
84 | |||
85 | return NULL; | ||
86 | } | ||
87 | |||
88 | tokens = 0; | ||
89 | src = str; | ||
90 | /* count tokens and check strlen(str) */ | ||
91 | while (*src != '\0') | ||
92 | { | ||
93 | const char *d = delim, *d_end = d + dlen; | ||
94 | const char *tmp = src; | ||
95 | for (; (d < d_end) && (*tmp != '\0'); d++, tmp++) | ||
96 | { | ||
97 | if (EINA_LIKELY(*d != *tmp)) | ||
98 | break; | ||
99 | } | ||
100 | if (EINA_UNLIKELY(d == d_end)) | ||
101 | { | ||
102 | src = tmp; | ||
103 | tokens++; | ||
104 | } | ||
105 | else | ||
106 | src++; | ||
107 | } | ||
108 | len = src - str; | ||
109 | |||
110 | if ((max_tokens > 0) && (tokens > (unsigned int)max_tokens)) | ||
111 | tokens = max_tokens; | ||
112 | |||
113 | str_array = malloc(sizeof(char *) * (tokens + 2)); | ||
114 | if (!str_array) | ||
115 | { | ||
116 | if (elements) | ||
117 | *elements = 0; | ||
118 | |||
119 | return NULL; | ||
120 | } | ||
121 | |||
122 | s = malloc(len + 1); | ||
123 | if (!s) | ||
124 | { | ||
125 | free(str_array); | ||
126 | if (elements) | ||
127 | *elements = 0; | ||
128 | |||
129 | return NULL; | ||
130 | } | ||
131 | |||
132 | /* copy tokens and string */ | ||
133 | tokens = 0; | ||
134 | str_array[0] = s; | ||
135 | src = str; | ||
136 | while (*src != '\0') | ||
137 | { | ||
138 | const char *d = delim, *d_end = d + dlen; | ||
139 | const char *tmp = src; | ||
140 | for (; (d < d_end) && (*tmp != '\0'); d++, tmp++) | ||
141 | { | ||
142 | if (EINA_LIKELY(*d != *tmp)) | ||
143 | break; | ||
144 | } | ||
145 | if (EINA_UNLIKELY(d == d_end)) | ||
146 | { | ||
147 | src = tmp; | ||
148 | *s = '\0'; | ||
149 | s += dlen; | ||
150 | tokens++; | ||
151 | str_array[tokens] = s; | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | *s = *src; | ||
156 | s++; | ||
157 | src++; | ||
158 | } | ||
159 | } | ||
160 | *s = '\0'; | ||
161 | str_array[tokens + 1] = NULL; | ||
162 | if (elements) | ||
163 | *elements = (tokens + 1); | ||
164 | |||
165 | return str_array; | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * @endcond | ||
170 | */ | ||
171 | |||
172 | /*============================================================================* | ||
173 | * Global * | ||
174 | *============================================================================*/ | ||
175 | |||
176 | /*============================================================================* | ||
177 | * API * | ||
178 | *============================================================================*/ | ||
179 | |||
180 | EAPI size_t | ||
181 | eina_strlcpy(char *dst, const char *src, size_t siz) | ||
182 | { | ||
183 | #ifdef HAVE_STRLCPY | ||
184 | return strlcpy(dst, src, siz); | ||
185 | #else | ||
186 | char *d = dst; | ||
187 | const char *s = src; | ||
188 | size_t n = siz; | ||
189 | |||
190 | /* Copy as many bytes as will fit */ | ||
191 | if (n != 0) | ||
192 | while (--n != 0) | ||
193 | { | ||
194 | if ((*d++ = *s++) == '\0') | ||
195 | break; | ||
196 | } | ||
197 | |||
198 | /* Not enough room in dst, add NUL and traverse rest of src */ | ||
199 | if (n == 0) | ||
200 | { | ||
201 | if (siz != 0) | ||
202 | *d = '\0'; /* NUL-terminate dst */ | ||
203 | |||
204 | while (*s++) | ||
205 | ; | ||
206 | } | ||
207 | |||
208 | return(s - src - 1); /* count does not include NUL */ | ||
209 | #endif | ||
210 | } | ||
211 | |||
212 | EAPI size_t | ||
213 | eina_strlcat(char *dst, const char *src, size_t siz) | ||
214 | { | ||
215 | char *d = dst; | ||
216 | const char *s = src; | ||
217 | size_t n = siz; | ||
218 | size_t dlen; | ||
219 | |||
220 | /* Find the end of dst and adjust bytes left but don't go past end */ | ||
221 | while (n-- != 0 && *d != '\0') | ||
222 | d++; | ||
223 | dlen = d - dst; | ||
224 | n = siz - dlen; | ||
225 | |||
226 | if (n == 0) | ||
227 | return(dlen + strlen(s)); | ||
228 | |||
229 | while (*s != '\0') { | ||
230 | if (n != 1) | ||
231 | { | ||
232 | *d++ = *s; | ||
233 | n--; | ||
234 | } | ||
235 | |||
236 | s++; | ||
237 | } | ||
238 | *d = '\0'; | ||
239 | |||
240 | return(dlen + (s - src)); /* count does not include NUL */ | ||
241 | } | ||
242 | |||
243 | EAPI Eina_Bool | ||
244 | eina_str_has_prefix(const char *str, const char *prefix) | ||
245 | { | ||
246 | size_t str_len; | ||
247 | size_t prefix_len; | ||
248 | |||
249 | str_len = strlen(str); | ||
250 | prefix_len = eina_strlen_bounded(prefix, str_len); | ||
251 | if (prefix_len == (size_t)-1) | ||
252 | return EINA_FALSE; | ||
253 | |||
254 | return (strncmp(str, prefix, prefix_len) == 0); | ||
255 | } | ||
256 | |||
257 | EAPI Eina_Bool | ||
258 | eina_str_has_suffix(const char *str, const char *suffix) | ||
259 | { | ||
260 | return eina_str_has_suffix_helper(str, suffix, strcmp); | ||
261 | } | ||
262 | |||
263 | EAPI Eina_Bool | ||
264 | eina_str_has_extension(const char *str, const char *ext) | ||
265 | { | ||
266 | return eina_str_has_suffix_helper(str, ext, strcasecmp); | ||
267 | } | ||
268 | |||
269 | EAPI char ** | ||
270 | eina_str_split_full(const char *str, | ||
271 | const char *delim, | ||
272 | int max_tokens, | ||
273 | unsigned int *elements) | ||
274 | { | ||
275 | return eina_str_split_full_helper(str, delim, max_tokens, elements); | ||
276 | } | ||
277 | |||
278 | |||
279 | EAPI char ** | ||
280 | eina_str_split(const char *str, const char *delim, int max_tokens) | ||
281 | { | ||
282 | return eina_str_split_full_helper(str, delim, max_tokens, NULL); | ||
283 | } | ||
284 | |||
285 | EAPI size_t | ||
286 | eina_str_join_len(char *dst, | ||
287 | size_t size, | ||
288 | char sep, | ||
289 | const char *a, | ||
290 | size_t a_len, | ||
291 | const char *b, | ||
292 | size_t b_len) | ||
293 | { | ||
294 | size_t ret = a_len + b_len + 1; | ||
295 | size_t off; | ||
296 | |||
297 | if (size < 1) | ||
298 | return ret; | ||
299 | |||
300 | if (size <= a_len) | ||
301 | { | ||
302 | memcpy(dst, a, size - 1); | ||
303 | dst[size - 1] = '\0'; | ||
304 | return ret; | ||
305 | } | ||
306 | |||
307 | memcpy(dst, a, a_len); | ||
308 | off = a_len; | ||
309 | |||
310 | if (size <= off + 1) | ||
311 | { | ||
312 | dst[size - 1] = '\0'; | ||
313 | return ret; | ||
314 | } | ||
315 | |||
316 | dst[off] = sep; | ||
317 | off++; | ||
318 | |||
319 | if (size <= off + b_len + 1) | ||
320 | { | ||
321 | memcpy(dst + off, b, size - off - 1); | ||
322 | dst[size - 1] = '\0'; | ||
323 | return ret; | ||
324 | } | ||
325 | |||
326 | memcpy(dst + off, b, b_len); | ||
327 | dst[off + b_len] = '\0'; | ||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | #ifdef HAVE_ICONV | ||
332 | EAPI char * | ||
333 | eina_str_convert(const char *enc_from, const char *enc_to, const char *text) | ||
334 | { | ||
335 | iconv_t ic; | ||
336 | char *new_txt, *inp, *outp; | ||
337 | size_t inb, outb, outlen, tob, outalloc; | ||
338 | |||
339 | if (!text) | ||
340 | return NULL; | ||
341 | |||
342 | ic = iconv_open(enc_to, enc_from); | ||
343 | if (ic == (iconv_t)(-1)) | ||
344 | return NULL; | ||
345 | |||
346 | new_txt = malloc(64); | ||
347 | inb = strlen(text); | ||
348 | outb = 64; | ||
349 | inp = (char *)text; | ||
350 | outp = new_txt; | ||
351 | outalloc = 64; | ||
352 | outlen = 0; | ||
353 | |||
354 | for (;; ) | ||
355 | { | ||
356 | size_t count; | ||
357 | |||
358 | tob = outb; | ||
359 | count = iconv(ic, &inp, &inb, &outp, &outb); | ||
360 | outlen += tob - outb; | ||
361 | if (count == (size_t)(-1)) | ||
362 | { | ||
363 | if (errno == E2BIG) | ||
364 | { | ||
365 | new_txt = realloc(new_txt, outalloc + 64); | ||
366 | outp = new_txt + outlen; | ||
367 | outalloc += 64; | ||
368 | outb += 64; | ||
369 | } | ||
370 | else if (errno == EILSEQ) | ||
371 | { | ||
372 | if (new_txt) | ||
373 | free(new_txt); | ||
374 | |||
375 | new_txt = NULL; | ||
376 | break; | ||
377 | } | ||
378 | else if (errno == EINVAL) | ||
379 | { | ||
380 | if (new_txt) | ||
381 | free(new_txt); | ||
382 | |||
383 | new_txt = NULL; | ||
384 | break; | ||
385 | } | ||
386 | else | ||
387 | { | ||
388 | if (new_txt) | ||
389 | free(new_txt); | ||
390 | |||
391 | new_txt = NULL; | ||
392 | break; | ||
393 | } | ||
394 | } | ||
395 | |||
396 | if (inb == 0) | ||
397 | { | ||
398 | if (outalloc == outlen) | ||
399 | new_txt = realloc(new_txt, outalloc + 1); | ||
400 | |||
401 | new_txt[outlen] = 0; | ||
402 | break; | ||
403 | } | ||
404 | } | ||
405 | iconv_close(ic); | ||
406 | return new_txt; | ||
407 | } | ||
408 | #else | ||
409 | EAPI char * | ||
410 | eina_str_convert(const char *enc_from __UNUSED__, | ||
411 | const char *enc_to __UNUSED__, | ||
412 | const char *text __UNUSED__) | ||
413 | { | ||
414 | return NULL; | ||
415 | } | ||
416 | #endif | ||
417 | |||
418 | EAPI char * | ||
419 | eina_str_escape(const char *str) | ||
420 | { | ||
421 | char *s2, *d; | ||
422 | const char *s; | ||
423 | |||
424 | s2 = malloc((strlen(str) * 2) + 1); | ||
425 | if (!s2) | ||
426 | return NULL; | ||
427 | |||
428 | for (s = str, d = s2; *s != 0; s++, d++) | ||
429 | { | ||
430 | if ((*s == ' ') || (*s == '\\') || (*s == '\'')) | ||
431 | { | ||
432 | *d = '\\'; | ||
433 | d++; | ||
434 | } | ||
435 | |||
436 | *d = *s; | ||
437 | } | ||
438 | *d = 0; | ||
439 | return s2; | ||
440 | } | ||
441 | |||
442 | EAPI void | ||
443 | eina_str_tolower(char **str) | ||
444 | { | ||
445 | char *p; | ||
446 | if ((!str) || (!(*str))) | ||
447 | return; | ||
448 | |||
449 | for (p = *str; (*p); p++) | ||
450 | *p = tolower((unsigned char )(*p)); | ||
451 | } | ||
452 | |||
453 | EAPI void | ||
454 | eina_str_toupper(char **str) | ||
455 | { | ||
456 | char *p; | ||
457 | if ((!str) || (!(*str))) | ||
458 | return; | ||
459 | |||
460 | for (p = *str; (*p); p++) | ||
461 | *p = toupper((unsigned char)(*p)); | ||
462 | } | ||
diff --git a/libraries/eina/src/lib/eina_strbuf.c b/libraries/eina/src/lib/eina_strbuf.c deleted file mode 100644 index 828d842..0000000 --- a/libraries/eina/src/lib/eina_strbuf.c +++ /dev/null | |||
@@ -1,202 +0,0 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include "config.h" | ||
3 | #endif | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <string.h> | ||
7 | #include <ctype.h> | ||
8 | |||
9 | #ifdef HAVE_EVIL | ||
10 | # include <Evil.h> | ||
11 | #endif | ||
12 | |||
13 | #include "eina_private.h" | ||
14 | #include "eina_str.h" | ||
15 | #include "eina_strbuf_common.h" | ||
16 | #include "eina_unicode.h" | ||
17 | |||
18 | /*============================================================================* | ||
19 | * Local * | ||
20 | *============================================================================*/ | ||
21 | |||
22 | /** | ||
23 | * @cond LOCAL | ||
24 | */ | ||
25 | |||
26 | #ifdef _STRBUF_DATA_TYPE | ||
27 | # undef _STRBUF_DATA_TYPE | ||
28 | #endif | ||
29 | |||
30 | #ifdef _STRBUF_CSIZE | ||
31 | # undef _STRBUF_CSIZE | ||
32 | #endif | ||
33 | |||
34 | #ifdef _STRBUF_STRUCT_NAME | ||
35 | # undef _STRBUF_STRUCT_NAME | ||
36 | #endif | ||
37 | |||
38 | #ifdef _STRBUF_STRLEN_FUNC | ||
39 | # undef _STRBUF_STRLEN_FUNC | ||
40 | #endif | ||
41 | |||
42 | #ifdef _STRBUF_STRESCAPE_FUNC | ||
43 | # undef _STRBUF_STRESCAPE_FUNC | ||
44 | #endif | ||
45 | |||
46 | #ifdef _STRBUF_MAGIC | ||
47 | # undef _STRBUF_MAGIC | ||
48 | #endif | ||
49 | |||
50 | #ifdef _STRBUF_MAGIC_STR | ||
51 | # undef _STRBUF_MAGIC_STR | ||
52 | #endif | ||
53 | |||
54 | #ifdef _FUNC_EXPAND | ||
55 | # undef _FUNC_EXPAND | ||
56 | #endif | ||
57 | |||
58 | |||
59 | #define _STRBUF_DATA_TYPE char | ||
60 | #define _STRBUF_CSIZE sizeof(_STRBUF_DATA_TYPE) | ||
61 | #define _STRBUF_STRUCT_NAME Eina_Strbuf | ||
62 | #define _STRBUF_STRLEN_FUNC(x) strlen(x) | ||
63 | #define _STRBUF_STRESCAPE_FUNC(x) eina_str_escape(x) | ||
64 | #define _STRBUF_MAGIC EINA_MAGIC_STRBUF | ||
65 | #define _STRBUF_MAGIC_STR __STRBUF_MAGIC_STR | ||
66 | static const char __STRBUF_MAGIC_STR[] = "Eina Strbuf"; | ||
67 | |||
68 | #define _FUNC_EXPAND(y) eina_strbuf_ ## y | ||
69 | |||
70 | /** | ||
71 | * @endcond | ||
72 | */ | ||
73 | |||
74 | |||
75 | /*============================================================================* | ||
76 | * Global * | ||
77 | *============================================================================*/ | ||
78 | |||
79 | |||
80 | /*============================================================================* | ||
81 | * API * | ||
82 | *============================================================================*/ | ||
83 | |||
84 | |||
85 | EAPI Eina_Bool | ||
86 | eina_strbuf_append_printf(Eina_Strbuf *buf, const char *fmt, ...) | ||
87 | { | ||
88 | va_list args; | ||
89 | char *str; | ||
90 | size_t len; | ||
91 | Eina_Bool ret; | ||
92 | |||
93 | va_start(args, fmt); | ||
94 | len = vasprintf(&str, fmt, args); | ||
95 | va_end(args); | ||
96 | |||
97 | if (len <= 0 || !str) | ||
98 | return EINA_FALSE; | ||
99 | |||
100 | ret = eina_strbuf_append_length(buf, str, len); | ||
101 | free(str); | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | EAPI Eina_Bool | ||
106 | eina_strbuf_append_vprintf(Eina_Strbuf *buf, const char *fmt, va_list args) | ||
107 | { | ||
108 | char *str; | ||
109 | size_t len; | ||
110 | Eina_Bool ret; | ||
111 | |||
112 | len = vasprintf(&str, fmt, args); | ||
113 | |||
114 | if (len <= 0 || !str) | ||
115 | return EINA_FALSE; | ||
116 | |||
117 | ret = eina_strbuf_append_length(buf, str, len); | ||
118 | free(str); | ||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | EAPI Eina_Bool | ||
123 | eina_strbuf_insert_printf(Eina_Strbuf *buf, const char *fmt, size_t pos, ...) | ||
124 | { | ||
125 | va_list args; | ||
126 | char *str; | ||
127 | size_t len; | ||
128 | Eina_Bool ret; | ||
129 | |||
130 | va_start(args, pos); | ||
131 | len = vasprintf(&str, fmt, args); | ||
132 | va_end(args); | ||
133 | |||
134 | if (len <= 0 || !str) | ||
135 | return EINA_FALSE; | ||
136 | |||
137 | ret = eina_strbuf_insert(buf, str, pos); | ||
138 | free(str); | ||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | EAPI Eina_Bool | ||
143 | eina_strbuf_insert_vprintf(Eina_Strbuf *buf, | ||
144 | const char *fmt, | ||
145 | size_t pos, | ||
146 | va_list args) | ||
147 | { | ||
148 | char *str; | ||
149 | size_t len; | ||
150 | Eina_Bool ret; | ||
151 | |||
152 | len = vasprintf(&str, fmt, args); | ||
153 | |||
154 | if (len <= 0 || !str) | ||
155 | return EINA_FALSE; | ||
156 | |||
157 | ret = eina_strbuf_insert(buf, str, pos); | ||
158 | free(str); | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | EAPI void | ||
163 | eina_strbuf_trim(Eina_Strbuf *buf) | ||
164 | { | ||
165 | unsigned char *c = buf->buf; | ||
166 | |||
167 | while (buf->len > 0 && isspace(c[buf->len - 1])) | ||
168 | buf->len--; | ||
169 | while (buf->len > 0 && isspace(*c)) | ||
170 | { | ||
171 | c++; | ||
172 | buf->len--; | ||
173 | } | ||
174 | memmove(buf->buf, c, buf->len); | ||
175 | ((unsigned char *)buf->buf)[buf->len] = '\0'; | ||
176 | } | ||
177 | |||
178 | EAPI void | ||
179 | eina_strbuf_ltrim(Eina_Strbuf *buf) | ||
180 | { | ||
181 | unsigned char *c = buf->buf; | ||
182 | |||
183 | while (buf->len > 0 && isspace(*c)) | ||
184 | { | ||
185 | c++; | ||
186 | buf->len--; | ||
187 | } | ||
188 | memmove(buf->buf, c, buf->len); | ||
189 | ((unsigned char *)buf->buf)[buf->len] = '\0'; | ||
190 | } | ||
191 | |||
192 | EAPI void | ||
193 | eina_strbuf_rtrim(Eina_Strbuf *buf) | ||
194 | { | ||
195 | while (buf->len > 0 && isspace(((unsigned char*)(buf->buf))[buf->len - 1])) | ||
196 | buf->len--; | ||
197 | ((unsigned char *)buf->buf)[buf->len] = '\0'; | ||
198 | } | ||
199 | |||
200 | /* Unicode */ | ||
201 | |||
202 | #include "eina_strbuf_template_c.x" | ||
diff --git a/libraries/eina/src/lib/eina_strbuf_common.c b/libraries/eina/src/lib/eina_strbuf_common.c deleted file mode 100644 index 46067cd..0000000 --- a/libraries/eina/src/lib/eina_strbuf_common.c +++ /dev/null | |||
@@ -1,874 +0,0 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include "config.h" | ||
3 | #endif | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <stdlib.h> | ||
7 | #include <string.h> | ||
8 | |||
9 | #ifdef _WIN32 | ||
10 | # include <Evil.h> | ||
11 | #endif | ||
12 | |||
13 | #include "eina_private.h" | ||
14 | #include "eina_str.h" | ||
15 | #include "eina_magic.h" | ||
16 | #include "eina_error.h" | ||
17 | #include "eina_safety_checks.h" | ||
18 | #include "eina_strbuf.h" | ||
19 | #include "eina_strbuf_common.h" | ||
20 | |||
21 | /*============================================================================* | ||
22 | * Local * | ||
23 | *============================================================================*/ | ||
24 | |||
25 | /** | ||
26 | * @cond LOCAL | ||
27 | */ | ||
28 | |||
29 | #define EINA_STRBUF_INIT_SIZE 32 | ||
30 | #define EINA_STRBUF_INIT_STEP 32 | ||
31 | #define EINA_STRBUF_MAX_STEP 4096 | ||
32 | |||
33 | /** | ||
34 | * @endcond | ||
35 | */ | ||
36 | |||
37 | /*============================================================================* | ||
38 | * Global * | ||
39 | *============================================================================*/ | ||
40 | |||
41 | /** | ||
42 | * @internal | ||
43 | * @brief Initialize the strbuf module. | ||
44 | * | ||
45 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
46 | * | ||
47 | * This function sets up the strbuf module of Eina. It is called by | ||
48 | * eina_init(). | ||
49 | * | ||
50 | * @see eina_init() | ||
51 | */ | ||
52 | Eina_Bool | ||
53 | eina_strbuf_common_init(void) | ||
54 | { | ||
55 | return EINA_TRUE; | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * @internal | ||
60 | * @brief Shut down the strbuf module. | ||
61 | * | ||
62 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
63 | * | ||
64 | * This function shuts down the strbuf module set up by | ||
65 | * eina_strbuf_common_init(). It is called by eina_shutdown(). | ||
66 | * | ||
67 | * @see eina_shutdown() | ||
68 | */ | ||
69 | Eina_Bool | ||
70 | eina_strbuf_common_shutdown(void) | ||
71 | { | ||
72 | return EINA_TRUE; | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * @internal | ||
77 | * | ||
78 | * init the buffer | ||
79 | * @param csize the character size | ||
80 | * @param buf the buffer to init | ||
81 | * | ||
82 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
83 | */ | ||
84 | static Eina_Bool | ||
85 | _eina_strbuf_common_init(size_t csize, Eina_Strbuf *buf) | ||
86 | { | ||
87 | buf->len = 0; | ||
88 | buf->size = EINA_STRBUF_INIT_SIZE; | ||
89 | buf->step = EINA_STRBUF_INIT_STEP; | ||
90 | |||
91 | eina_error_set(0); | ||
92 | buf->buf = calloc(csize, buf->size); | ||
93 | if (EINA_UNLIKELY(!buf->buf)) | ||
94 | { | ||
95 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
96 | return EINA_FALSE; | ||
97 | } | ||
98 | |||
99 | return EINA_TRUE; | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * @internal | ||
104 | * | ||
105 | * init the buffer without allocating the actual string (for managed) | ||
106 | * @param csize the character size | ||
107 | * @param buf the buffer to init | ||
108 | * | ||
109 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
110 | */ | ||
111 | static Eina_Bool | ||
112 | _eina_strbuf_common_manage_init(size_t csize __UNUSED__, | ||
113 | Eina_Strbuf *buf, | ||
114 | void *str, | ||
115 | size_t len) | ||
116 | { | ||
117 | buf->len = len; | ||
118 | buf->size = len + 1; | ||
119 | buf->step = EINA_STRBUF_INIT_STEP; | ||
120 | buf->buf = str; | ||
121 | |||
122 | return EINA_TRUE; | ||
123 | } | ||
124 | |||
125 | |||
126 | /** | ||
127 | * @internal | ||
128 | * | ||
129 | * resize the buffer | ||
130 | * @param csize the character size | ||
131 | * @param buf the buffer to resize | ||
132 | * @param size the minimum size of the buffer | ||
133 | * | ||
134 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
135 | */ | ||
136 | static inline Eina_Bool | ||
137 | _eina_strbuf_common_resize(size_t csize, Eina_Strbuf *buf, size_t size) | ||
138 | { | ||
139 | size_t new_size, new_step, delta; | ||
140 | void *buffer; | ||
141 | |||
142 | size += 1; // Add extra space for '\0' | ||
143 | |||
144 | /* nothing to do */ | ||
145 | if (size == buf->size) return EINA_TRUE; | ||
146 | else if (size > buf->size) delta = size - buf->size; | ||
147 | else delta = buf->size - size; | ||
148 | |||
149 | /* check if should keep the same step (just used while growing) */ | ||
150 | if ((delta <= buf->step) && (size > buf->size)) new_step = buf->step; | ||
151 | else | ||
152 | { | ||
153 | new_step = (((delta / EINA_STRBUF_INIT_STEP) + 1) | ||
154 | * EINA_STRBUF_INIT_STEP); | ||
155 | if (new_step > EINA_STRBUF_MAX_STEP) new_step = EINA_STRBUF_MAX_STEP; | ||
156 | } | ||
157 | |||
158 | new_size = (((size / new_step) + 1) * new_step); | ||
159 | |||
160 | /* reallocate the buffer to the new size */ | ||
161 | buffer = realloc(buf->buf, new_size * csize); | ||
162 | if (EINA_UNLIKELY(!buffer)) | ||
163 | { | ||
164 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
165 | return EINA_FALSE; | ||
166 | } | ||
167 | |||
168 | buf->buf = buffer; | ||
169 | buf->size = new_size; | ||
170 | buf->step = new_step; | ||
171 | eina_error_set(0); | ||
172 | return EINA_TRUE; | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * @internal | ||
177 | * | ||
178 | * If required, enlarge the buffer to fit the new size. | ||
179 | * | ||
180 | * @param csize the character size | ||
181 | * @param buf the buffer to resize | ||
182 | * @param size the minimum size of the buffer | ||
183 | * | ||
184 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
185 | */ | ||
186 | Eina_Bool | ||
187 | _eina_strbuf_common_grow(size_t csize, Eina_Strbuf *buf, size_t size) | ||
188 | { | ||
189 | if ((size + 1) < buf->size) return EINA_TRUE; | ||
190 | return _eina_strbuf_common_resize(csize, buf, size); | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * @internal | ||
195 | * | ||
196 | * insert string of known length at random within existing strbuf limits. | ||
197 | * | ||
198 | * @param csize the character size | ||
199 | * @param buf the buffer to resize, must be valid. | ||
200 | * @param str the string to copy, must be valid (!NULL and smaller than @a len) | ||
201 | * @param len the amount of bytes in @a str to copy, must be valid. | ||
202 | * @param pos the position inside buffer to insert, must be valid (smaller | ||
203 | * than eina_strbuf_common_length_get()) | ||
204 | * | ||
205 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
206 | */ | ||
207 | static inline Eina_Bool | ||
208 | _eina_strbuf_common_insert_length(size_t csize, | ||
209 | Eina_Strbuf *buf, | ||
210 | const void *str, | ||
211 | size_t len, | ||
212 | size_t pos) | ||
213 | { | ||
214 | if (EINA_UNLIKELY(!_eina_strbuf_common_grow(csize, buf, buf->len + len))) | ||
215 | return EINA_FALSE; | ||
216 | |||
217 | /* move the existing text */ | ||
218 | memmove(((unsigned char *)(buf->buf)) + ((len + pos) * csize), | ||
219 | ((unsigned char *)(buf->buf)) + (pos * csize), | ||
220 | (buf->len - pos) * csize); | ||
221 | |||
222 | /* and now insert the given string */ | ||
223 | memcpy((unsigned char *)buf->buf + (pos * csize), str, len * csize); | ||
224 | |||
225 | buf->len += len; | ||
226 | memset(((unsigned char *)(buf->buf)) + (buf->len * csize), 0, csize); | ||
227 | return EINA_TRUE; | ||
228 | } | ||
229 | |||
230 | /*============================================================================* | ||
231 | * API * | ||
232 | *============================================================================*/ | ||
233 | |||
234 | /** | ||
235 | * @internal | ||
236 | * @brief Create a new string buffer. | ||
237 | * | ||
238 | * @param csize the character size | ||
239 | * @return Newly allocated string buffer instance. | ||
240 | * | ||
241 | * This function creates a new string buffer. On error, @c NULL is | ||
242 | * returned and Eina error is set to #EINA_ERROR_OUT_OF_MEMORY. To | ||
243 | * free the resources, use eina_strbuf_common_free(). | ||
244 | * | ||
245 | * @see eina_strbuf_common_free() | ||
246 | * @see eina_strbuf_common_append() | ||
247 | * @see eina_strbuf_common_string_get() | ||
248 | */ | ||
249 | Eina_Strbuf * | ||
250 | eina_strbuf_common_new(size_t csize) | ||
251 | { | ||
252 | Eina_Strbuf *buf; | ||
253 | |||
254 | eina_error_set(0); | ||
255 | buf = malloc(sizeof(Eina_Strbuf)); | ||
256 | if (EINA_UNLIKELY(!buf)) | ||
257 | { | ||
258 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
259 | return NULL; | ||
260 | } | ||
261 | if (EINA_UNLIKELY(!_eina_strbuf_common_init(csize, buf))) | ||
262 | { | ||
263 | eina_strbuf_common_free(buf); | ||
264 | return NULL; | ||
265 | } | ||
266 | return buf; | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * @internal | ||
271 | * @brief Create a new string buffer managing str. | ||
272 | * | ||
273 | * @param csize the character size | ||
274 | * @param str the string to manage | ||
275 | * @param len the length of the string to manage | ||
276 | * @return Newly allocated string buffer instance. | ||
277 | * | ||
278 | * This function creates a new string buffer. On error, @c NULL is | ||
279 | * returned and Eina error is set to #EINA_ERROR_OUT_OF_MEMORY. To | ||
280 | * free the resources, use eina_strbuf_common_free(). | ||
281 | * | ||
282 | * @see eina_strbuf_common_free() | ||
283 | * @see eina_strbuf_common_append() | ||
284 | * @see eina_strbuf_common_string_get() | ||
285 | * @since 1.1.0 | ||
286 | */ | ||
287 | Eina_Strbuf * | ||
288 | eina_strbuf_common_manage_new(size_t csize, | ||
289 | void *str, | ||
290 | size_t len) | ||
291 | { | ||
292 | Eina_Strbuf *buf; | ||
293 | |||
294 | eina_error_set(0); | ||
295 | buf = malloc(sizeof(Eina_Strbuf)); | ||
296 | if (EINA_UNLIKELY(!buf)) | ||
297 | { | ||
298 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
299 | return NULL; | ||
300 | } | ||
301 | if (EINA_UNLIKELY(!_eina_strbuf_common_manage_init(csize, buf, str, len))) | ||
302 | { | ||
303 | eina_strbuf_common_free(buf); | ||
304 | return NULL; | ||
305 | } | ||
306 | return buf; | ||
307 | } | ||
308 | |||
309 | /** | ||
310 | * @internal | ||
311 | * @brief Free a string buffer. | ||
312 | * | ||
313 | * @param buf The string buffer to free. | ||
314 | * | ||
315 | * This function frees the memory of @p buf. @p buf must have been | ||
316 | * created by eina_strbuf_common_new(). | ||
317 | */ | ||
318 | void | ||
319 | eina_strbuf_common_free(Eina_Strbuf *buf) | ||
320 | { | ||
321 | free(buf->buf); | ||
322 | free(buf); | ||
323 | } | ||
324 | |||
325 | /** | ||
326 | * @internal | ||
327 | * @brief Reset a string buffer. | ||
328 | * | ||
329 | * @param csize the character size | ||
330 | * @param buf The string buffer to reset. | ||
331 | * | ||
332 | * This function reset @p buf: the buffer len is set to 0, and the | ||
333 | * string is set to '\\0'. No memory is free'd. | ||
334 | */ | ||
335 | void | ||
336 | eina_strbuf_common_reset(size_t csize, Eina_Strbuf *buf) | ||
337 | { | ||
338 | buf->len = 0; | ||
339 | buf->step = EINA_STRBUF_INIT_STEP; | ||
340 | memset(buf->buf, 0, csize); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * @internal | ||
345 | * @brief Append a string to a buffer, reallocating as necessary. | ||
346 | * | ||
347 | * @param csize the character size | ||
348 | * @param buf The string buffer to append to. | ||
349 | * @param str The string to append. | ||
350 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
351 | * | ||
352 | * This function appends @p str to @p buf. It computes the length of | ||
353 | * @p str, so is slightly slower than eina_strbuf_common_append_length(). If | ||
354 | * the length is known beforehand, consider using that variant. If | ||
355 | * @p buf can't append it, #EINA_FALSE is returned, otherwise | ||
356 | * #EINA_TRUE is returned. | ||
357 | * | ||
358 | * @see eina_strbuf_common_append() | ||
359 | * @see eina_strbuf_common_append_length() | ||
360 | */ | ||
361 | Eina_Bool | ||
362 | eina_strbuf_common_append(size_t csize, | ||
363 | Eina_Strbuf *buf, | ||
364 | const void *str, | ||
365 | size_t len) | ||
366 | { | ||
367 | EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); | ||
368 | |||
369 | if (EINA_UNLIKELY(!_eina_strbuf_common_grow(csize, buf, buf->len + len))) | ||
370 | return EINA_FALSE; | ||
371 | memcpy(((unsigned char *)(buf->buf)) + (buf->len * csize), str, | ||
372 | (len + 1) * csize); | ||
373 | buf->len += len; | ||
374 | return EINA_TRUE; | ||
375 | } | ||
376 | |||
377 | /** | ||
378 | * @internal | ||
379 | * @brief Append a string to a buffer, reallocating as necessary, | ||
380 | * limited by the given length. | ||
381 | * | ||
382 | * @param csize the character size | ||
383 | * @param buf The string buffer to append to. | ||
384 | * @param str The string to append. | ||
385 | * @param maxlen The maximum number of characters to append. | ||
386 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
387 | * | ||
388 | * This function appends at most @p maxlen characters of @p str to | ||
389 | * @p buf. It can't appends more than the length of @p str. It | ||
390 | * computes the length of @p str, so is slightly slower than | ||
391 | * eina_strbuf_common_append_length(). If the length is known beforehand, | ||
392 | * consider using that variant (@p maxlen should then be checked so | ||
393 | * that it is greater than the size of @p str). If @p str can not be | ||
394 | * appended, #EINA_FALSE is returned, otherwise, #EINA_TRUE is | ||
395 | * returned. | ||
396 | * | ||
397 | * @see eina_strbuf_common_append() | ||
398 | * @see eina_strbuf_common_append_length() | ||
399 | */ | ||
400 | Eina_Bool | ||
401 | eina_strbuf_common_append_n(size_t csize, | ||
402 | Eina_Strbuf *buf, | ||
403 | const void *str, | ||
404 | size_t len, | ||
405 | size_t maxlen) | ||
406 | { | ||
407 | EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); | ||
408 | |||
409 | if (len > maxlen) len = maxlen; | ||
410 | if (EINA_UNLIKELY(!_eina_strbuf_common_grow(csize, buf, buf->len + len))) | ||
411 | return EINA_FALSE; | ||
412 | memcpy(((unsigned char *)(buf->buf)) + (buf->len * csize), str, | ||
413 | len * csize); | ||
414 | buf->len += len; | ||
415 | memset(((unsigned char *)(buf->buf)) + (buf->len * csize), 0, csize); | ||
416 | return EINA_TRUE; | ||
417 | } | ||
418 | |||
419 | /** | ||
420 | * @internal | ||
421 | * @brief Append a string of exact length to a buffer, reallocating as necessary. | ||
422 | * | ||
423 | * @param csize the character size | ||
424 | * @param buf The string buffer to append to. | ||
425 | * @param str The string to append. | ||
426 | * @param length The exact length to use. | ||
427 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
428 | * | ||
429 | * This function appends @p str to @p buf. @p str must be of size at | ||
430 | * most @p length. It is slightly faster than eina_strbuf_common_append() as | ||
431 | * it does not compute the size of @p str. It is useful when dealing | ||
432 | * with strings of known size, such as eina_strngshare. If @p buf | ||
433 | * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is | ||
434 | * returned. | ||
435 | * | ||
436 | * @see eina_stringshare_length() | ||
437 | * @see eina_strbuf_common_append() | ||
438 | * @see eina_strbuf_common_append_n() | ||
439 | */ | ||
440 | Eina_Bool | ||
441 | eina_strbuf_common_append_length(size_t csize, | ||
442 | Eina_Strbuf *buf, | ||
443 | const void *str, | ||
444 | size_t length) | ||
445 | { | ||
446 | EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); | ||
447 | |||
448 | if (EINA_UNLIKELY(!_eina_strbuf_common_grow(csize, buf, buf->len + length))) | ||
449 | return EINA_FALSE; | ||
450 | memcpy(((unsigned char *)(buf->buf)) + (buf->len * csize), str, | ||
451 | length * csize); | ||
452 | buf->len += length; | ||
453 | memset(((unsigned char *)(buf->buf)) + (buf->len * csize), 0, csize); | ||
454 | return EINA_TRUE; | ||
455 | } | ||
456 | |||
457 | /** | ||
458 | * @internal | ||
459 | * @brief Insert a string to a buffer, reallocating as necessary. | ||
460 | * | ||
461 | * @param csize the character size | ||
462 | * @param buf The string buffer to insert. | ||
463 | * @param str The string to insert. | ||
464 | * @param pos The position to insert the string. | ||
465 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
466 | * | ||
467 | * This function inserts @p str to @p buf at position @p pos. It | ||
468 | * computes the length of @p str, so is slightly slower than | ||
469 | * eina_strbuf_common_insert_length(). If the length is known beforehand, | ||
470 | * consider using that variant. If @p buf can't insert it, #EINA_FALSE | ||
471 | * is returned, otherwise #EINA_TRUE is returned. | ||
472 | */ | ||
473 | Eina_Bool | ||
474 | eina_strbuf_common_insert(size_t csize, | ||
475 | Eina_Strbuf *buf, | ||
476 | const void *str, | ||
477 | size_t len, | ||
478 | size_t pos) | ||
479 | { | ||
480 | EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); | ||
481 | |||
482 | if (pos >= buf->len) return eina_strbuf_common_append(csize, buf, str, len); | ||
483 | return _eina_strbuf_common_insert_length(csize, buf, str, len, pos); | ||
484 | } | ||
485 | |||
486 | /** | ||
487 | * @internal | ||
488 | * @brief Insert a string to a buffer, reallocating as necessary. Limited by maxlen. | ||
489 | * | ||
490 | * @param csize the character size | ||
491 | * @param buf The string buffer to insert to. | ||
492 | * @param str The string to insert. | ||
493 | * @param maxlen The maximum number of chars to insert. | ||
494 | * @param pos The position to insert the string. | ||
495 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
496 | * | ||
497 | * This function inserts @p str ot @p buf at position @p pos, with at | ||
498 | * most @p maxlen bytes. The number of inserted characters can not be | ||
499 | * greater than the length of @p str. It computes the length of | ||
500 | * @p str, so is slightly slower than eina_strbuf_common_insert_length(). If the | ||
501 | * length is known beforehand, consider using that variant (@p maxlen | ||
502 | * should then be checked so that it is greater than the size of | ||
503 | * @p str). If @p str can not be inserted, #EINA_FALSE is returned, | ||
504 | * otherwise, #EINA_TRUE is returned. | ||
505 | */ | ||
506 | Eina_Bool | ||
507 | eina_strbuf_common_insert_n(size_t csize, | ||
508 | Eina_Strbuf *buf, | ||
509 | const void *str, | ||
510 | size_t len, | ||
511 | size_t maxlen, | ||
512 | size_t pos) | ||
513 | { | ||
514 | EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); | ||
515 | |||
516 | if (pos >= buf->len) | ||
517 | return eina_strbuf_common_append_n(csize, buf, str, len, maxlen); | ||
518 | if (len > maxlen) len = maxlen; | ||
519 | return _eina_strbuf_common_insert_length(csize, buf, str, len, pos); | ||
520 | } | ||
521 | |||
522 | /** | ||
523 | * @internal | ||
524 | * @brief Insert a string of exact length to a buffer, reallocating as necessary. | ||
525 | * | ||
526 | * @param csize the character size | ||
527 | * @param buf The string buffer to insert to. | ||
528 | * @param str The string to insert. | ||
529 | * @param length The exact length to use. | ||
530 | * @param pos The position to insert the string. | ||
531 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
532 | * | ||
533 | * This function inserts @p str to @p buf. @p str must be of size at | ||
534 | * most @p length. It is slightly faster than eina_strbuf_common_insert() as | ||
535 | * it does not compute the size of @p str. It is useful when dealing | ||
536 | * with strings of known size, such as eina_strngshare. If @p buf | ||
537 | * can't insert it, #EINA_FALSE is returned, otherwise #EINA_TRUE is | ||
538 | * returned. | ||
539 | * | ||
540 | * @see eina_stringshare_length() | ||
541 | * @see eina_strbuf_common_insert() | ||
542 | * @see eina_strbuf_common_insert_n() | ||
543 | */ | ||
544 | Eina_Bool | ||
545 | eina_strbuf_common_insert_length(size_t csize, | ||
546 | Eina_Strbuf *buf, | ||
547 | const void *str, | ||
548 | size_t length, | ||
549 | size_t pos) | ||
550 | { | ||
551 | EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE); | ||
552 | |||
553 | if (pos >= buf->len) | ||
554 | return eina_strbuf_common_append_length(csize, buf, str, length); | ||
555 | return _eina_strbuf_common_insert_length(csize, buf, str, length, pos); | ||
556 | } | ||
557 | |||
558 | /** | ||
559 | * @internal | ||
560 | * @brief Append a character to a string buffer, reallocating as | ||
561 | * necessary. | ||
562 | * | ||
563 | * @param csize the character size | ||
564 | * @param buf The string buffer to append to. | ||
565 | * @param c The char to append. | ||
566 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
567 | * | ||
568 | * This function inserts @p c to @p buf. If it can not insert it, | ||
569 | * #EINA_FALSE is returned, otherwise #EINA_TRUE is returned. | ||
570 | */ | ||
571 | Eina_Bool | ||
572 | eina_strbuf_common_append_char(size_t csize, Eina_Strbuf *buf, const void *c) | ||
573 | { | ||
574 | if (EINA_UNLIKELY(!_eina_strbuf_common_grow(csize, buf, buf->len + 1))) | ||
575 | return EINA_FALSE; | ||
576 | |||
577 | memcpy(((unsigned char *)(buf->buf)) + ((buf->len)++ *csize), c, csize); | ||
578 | memset(((unsigned char *)(buf->buf)) + (buf->len * csize), 0, csize); | ||
579 | return EINA_TRUE; | ||
580 | } | ||
581 | |||
582 | /** | ||
583 | * @internal | ||
584 | * @brief Insert a character to a string buffer, reallocating as | ||
585 | * necessary. | ||
586 | * | ||
587 | * @param csize the character size | ||
588 | * @param buf The string buffer to insert to. | ||
589 | * @param c The char to insert. | ||
590 | * @param pos The position to insert the char. | ||
591 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
592 | * | ||
593 | * This function inserts @p c to @p buf at position @p pos. If @p buf | ||
594 | * can't append it, #EINA_FALSE is returned, otherwise #EINA_TRUE is | ||
595 | * returned. | ||
596 | */ | ||
597 | Eina_Bool | ||
598 | eina_strbuf_common_insert_char(size_t csize, | ||
599 | Eina_Strbuf *buf, | ||
600 | const void *c, | ||
601 | size_t pos) | ||
602 | { | ||
603 | if (pos >= buf->len) | ||
604 | return eina_strbuf_common_append_char(csize, buf, c); | ||
605 | return _eina_strbuf_common_insert_length(csize, buf, c, 1, pos); | ||
606 | } | ||
607 | |||
608 | /** | ||
609 | * @internal | ||
610 | * @brief Remove a slice of the given string buffer. | ||
611 | * | ||
612 | * @param csize the character size | ||
613 | * @param buf The string buffer to remove a slice. | ||
614 | * @param start The initial (inclusive) slice position to start | ||
615 | * removing, in bytes. | ||
616 | * @param end The final (non-inclusive) slice position to finish | ||
617 | * removing, in bytes. | ||
618 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
619 | * | ||
620 | * This function removes a slice of @p buf, starting at @p start | ||
621 | * (inclusive) and ending at @p end (non-inclusive). Both values are | ||
622 | * in bytes. It returns #EINA_FALSE on failure, #EINA_TRUE otherwise. | ||
623 | */ | ||
624 | Eina_Bool | ||
625 | eina_strbuf_common_remove(size_t csize, | ||
626 | Eina_Strbuf *buf, | ||
627 | size_t start, | ||
628 | size_t end) | ||
629 | { | ||
630 | size_t remove_len, tail_len; | ||
631 | |||
632 | if (end >= buf->len) end = buf->len; | ||
633 | if (end <= start) return EINA_TRUE; | ||
634 | |||
635 | remove_len = end - start; | ||
636 | if (remove_len == buf->len) | ||
637 | { | ||
638 | free(buf->buf); | ||
639 | return _eina_strbuf_common_init(csize, buf); | ||
640 | } | ||
641 | |||
642 | tail_len = buf->len - end + 1; /* includes '\0' */ | ||
643 | memmove(((unsigned char *)(buf->buf)) + (start * csize), | ||
644 | ((unsigned char *)(buf->buf)) + (end * csize), | ||
645 | tail_len * csize); | ||
646 | buf->len -= remove_len; | ||
647 | return _eina_strbuf_common_resize(csize, buf, buf->len); | ||
648 | } | ||
649 | |||
650 | /** | ||
651 | * @internal | ||
652 | * @brief Retrieve a pointer to the contents of a string buffer | ||
653 | * | ||
654 | * @param buf The string buffer. | ||
655 | * @return The current string in the string buffer. | ||
656 | * | ||
657 | * This function returns the string contained in @p buf. The returned | ||
658 | * value must not be modified and will no longer be valid if @p buf is | ||
659 | * modified. In other words, any eina_strbuf_common_append() or similar will | ||
660 | * make that pointer invalid. | ||
661 | * | ||
662 | * @see eina_strbuf_common_string_steal() | ||
663 | */ | ||
664 | const void * | ||
665 | eina_strbuf_common_string_get(const Eina_Strbuf *buf) | ||
666 | { | ||
667 | return buf->buf; | ||
668 | } | ||
669 | |||
670 | /** | ||
671 | * @internal | ||
672 | * @brief Steal the contents of a string buffer. | ||
673 | * | ||
674 | * @param csize the character size | ||
675 | * @param buf The string buffer to steal. | ||
676 | * @return The current string in the string buffer. | ||
677 | * | ||
678 | * This function returns the string contained in @p buf. @p buf is | ||
679 | * then initialized and does not own the returned string anymore. The | ||
680 | * caller must release the memory of the returned string by calling | ||
681 | * free(). | ||
682 | * | ||
683 | * @see eina_strbuf_common_string_get() | ||
684 | */ | ||
685 | void * | ||
686 | eina_strbuf_common_string_steal(size_t csize, Eina_Strbuf *buf) | ||
687 | { | ||
688 | void *ret; | ||
689 | |||
690 | ret = buf->buf; | ||
691 | // TODO: Check return value and do something clever | ||
692 | _eina_strbuf_common_init(csize, buf); | ||
693 | return ret; | ||
694 | } | ||
695 | |||
696 | /** | ||
697 | * @internal | ||
698 | * @brief Free the contents of a string buffer but not the buffer. | ||
699 | * | ||
700 | * @param csize the character size | ||
701 | * @param buf The string buffer to free the string of. | ||
702 | * | ||
703 | * This function frees the string contained in @p buf without freeing | ||
704 | * @p buf. | ||
705 | */ | ||
706 | void | ||
707 | eina_strbuf_common_string_free(size_t csize, Eina_Strbuf *buf) | ||
708 | { | ||
709 | free(buf->buf); | ||
710 | _eina_strbuf_common_init(csize, buf); | ||
711 | } | ||
712 | |||
713 | /** | ||
714 | * @internal | ||
715 | * @brief Retrieve the length of the string buffer content. | ||
716 | * | ||
717 | * @param buf The string buffer. | ||
718 | * @return The current length of the string, in bytes. | ||
719 | * | ||
720 | * This function returns the length of @p buf. | ||
721 | */ | ||
722 | size_t | ||
723 | eina_strbuf_common_length_get(const Eina_Strbuf *buf) | ||
724 | { | ||
725 | return buf->len; | ||
726 | } | ||
727 | |||
728 | /** | ||
729 | * @cond LOCAL | ||
730 | */ | ||
731 | |||
732 | /*FIXME: Implementing them here is a hack! */ | ||
733 | |||
734 | #ifdef _STRBUF_CSIZE | ||
735 | # undef _STRBUF_CSIZE | ||
736 | #endif | ||
737 | |||
738 | #ifdef _STRBUF_MAGIC | ||
739 | # undef _STRBUF_MAGIC | ||
740 | #endif | ||
741 | |||
742 | #ifdef _STRBUF_MAGIC_STR | ||
743 | # undef _STRBUF_MAGIC_STR | ||
744 | #endif | ||
745 | |||
746 | #define _STRBUF_CSIZE 1 | ||
747 | #define _STRBUF_MAGIC EINA_MAGIC_STRBUF | ||
748 | #define _STRBUF_MAGIC_STR __STRBUF_STR_MAGIC_STR | ||
749 | static const char __STRBUF_STR_MAGIC_STR[] = "Eina Strbuf"; | ||
750 | |||
751 | |||
752 | /** | ||
753 | * @endcond | ||
754 | */ | ||
755 | |||
756 | |||
757 | EAPI Eina_Bool | ||
758 | eina_strbuf_replace(Eina_Strbuf *buf, | ||
759 | const char *str, | ||
760 | const char *with, | ||
761 | unsigned int n) | ||
762 | { | ||
763 | size_t len1, len2; | ||
764 | char *spos; | ||
765 | size_t pos; | ||
766 | |||
767 | EINA_SAFETY_ON_NULL_RETURN_VAL( str, EINA_FALSE); | ||
768 | EINA_SAFETY_ON_NULL_RETURN_VAL(with, EINA_FALSE); | ||
769 | EINA_MAGIC_CHECK_STRBUF(buf, 0); | ||
770 | if (n == 0) return EINA_FALSE; | ||
771 | |||
772 | spos = buf->buf; | ||
773 | while (n--) | ||
774 | { | ||
775 | spos = strstr(spos, str); | ||
776 | if (!spos || *spos == '\0') return EINA_FALSE; | ||
777 | if (n) spos++; | ||
778 | } | ||
779 | |||
780 | pos = spos - (const char *)buf->buf; | ||
781 | len1 = strlen(str); | ||
782 | len2 = strlen(with); | ||
783 | if (len1 != len2) | ||
784 | { | ||
785 | /* resize the buffer if necessary */ | ||
786 | if (EINA_UNLIKELY(!_eina_strbuf_common_grow(_STRBUF_CSIZE, buf, | ||
787 | buf->len - len1 + len2))) | ||
788 | return EINA_FALSE; /* move the existing text */ | ||
789 | memmove(((unsigned char *)(buf->buf)) + pos + len2, | ||
790 | ((unsigned char *)(buf->buf)) + pos + len1, | ||
791 | buf->len - pos - len1); | ||
792 | } | ||
793 | /* and now insert the given string */ | ||
794 | memcpy(((unsigned char *)(buf->buf)) + pos, with, len2); | ||
795 | buf->len += len2 - len1; | ||
796 | memset(((unsigned char *)(buf->buf)) + buf->len, 0, 1); | ||
797 | return EINA_TRUE; | ||
798 | } | ||
799 | |||
800 | EAPI int | ||
801 | eina_strbuf_replace_all(Eina_Strbuf *buf, const char *str, const char *with) | ||
802 | { | ||
803 | size_t len1, len2, len; | ||
804 | char *tmp_buf = NULL; | ||
805 | char *spos; | ||
806 | size_t pos, start; | ||
807 | size_t pos_tmp, start_tmp; | ||
808 | int n = 0; | ||
809 | |||
810 | EINA_SAFETY_ON_NULL_RETURN_VAL( str, 0); | ||
811 | EINA_SAFETY_ON_NULL_RETURN_VAL(with, 0); | ||
812 | EINA_MAGIC_CHECK_STRBUF(buf, 0); | ||
813 | |||
814 | spos = strstr(buf->buf, str); | ||
815 | if (!spos || *spos == '\0') return 0; | ||
816 | len1 = strlen(str); | ||
817 | len2 = strlen(with); | ||
818 | /* if the size of the two string is equal, it is fairly easy to replace them | ||
819 | * we don't need to resize the buffer or doing other calculations */ | ||
820 | if (len1 == len2) | ||
821 | { | ||
822 | while (spos) | ||
823 | { | ||
824 | memcpy(spos, with, len2); | ||
825 | spos = strstr(spos + len2, str); | ||
826 | n++; | ||
827 | } | ||
828 | return n; | ||
829 | } | ||
830 | pos = pos_tmp = spos - (const char *)buf->buf; | ||
831 | tmp_buf = buf->buf; | ||
832 | buf->buf = malloc(buf->size); | ||
833 | if (EINA_UNLIKELY(!buf->buf)) | ||
834 | { | ||
835 | buf->buf = tmp_buf; | ||
836 | return 0; | ||
837 | } | ||
838 | start = start_tmp = 0; | ||
839 | len = buf->len; | ||
840 | while (spos) | ||
841 | { | ||
842 | n++; | ||
843 | len = (len + len2) - len1; | ||
844 | /* resize the buffer if necessary */ | ||
845 | if (EINA_UNLIKELY(!_eina_strbuf_common_grow(_STRBUF_CSIZE, buf, len))) | ||
846 | { | ||
847 | /* we have to stop replacing here, because we haven't enough | ||
848 | * memory to go on */ | ||
849 | len = (len + len1) - len2; | ||
850 | break; | ||
851 | } | ||
852 | /* copy the untouched text */ | ||
853 | memcpy(((unsigned char *)(buf->buf)) + start, tmp_buf + start_tmp, | ||
854 | pos - start); | ||
855 | /* copy the new string */ | ||
856 | memcpy(((unsigned char *)(buf->buf)) + pos, with, len2); | ||
857 | /* calculate the next positions */ | ||
858 | start_tmp = pos_tmp + len1; | ||
859 | start = pos + len2; | ||
860 | spos = strstr(tmp_buf + start_tmp, str); | ||
861 | /* this calculations don't make sense if spos == NULL, but the | ||
862 | * calculated values won't be used, because the loop will stop | ||
863 | * then */ | ||
864 | pos_tmp = spos - tmp_buf; | ||
865 | pos = start + pos_tmp - start_tmp; | ||
866 | } | ||
867 | /* and now copy the rest of the text */ | ||
868 | memcpy(((unsigned char *)(buf->buf)) + start, tmp_buf + start_tmp, | ||
869 | len - start); | ||
870 | buf->len = len; | ||
871 | memset(((unsigned char *)(buf->buf)) + buf->len, 0, 1); | ||
872 | free(tmp_buf); | ||
873 | return n; | ||
874 | } | ||
diff --git a/libraries/eina/src/lib/eina_strbuf_common.h b/libraries/eina/src/lib/eina_strbuf_common.h deleted file mode 100644 index 06a1353..0000000 --- a/libraries/eina/src/lib/eina_strbuf_common.h +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | #ifndef EINA_STRBUF_COMMON_H | ||
2 | #define EINA_STRBUF_COMMON_H | ||
3 | |||
4 | #include <stdlib.h> | ||
5 | |||
6 | #include "eina_private.h" | ||
7 | #include "eina_magic.h" | ||
8 | #include "eina_strbuf.h" | ||
9 | |||
10 | /** | ||
11 | * @struct _Eina_Strbuf | ||
12 | * String buffer to facilitate string operations. | ||
13 | */ | ||
14 | struct _Eina_Strbuf | ||
15 | { | ||
16 | void *buf; | ||
17 | size_t len; | ||
18 | size_t size; | ||
19 | size_t step; | ||
20 | |||
21 | EINA_MAGIC | ||
22 | }; | ||
23 | |||
24 | #define EINA_MAGIC_CHECK_STRBUF(d, ...) \ | ||
25 | do { \ | ||
26 | if (!EINA_MAGIC_CHECK((d), _STRBUF_MAGIC)) \ | ||
27 | { \ | ||
28 | EINA_MAGIC_FAIL((d), _STRBUF_MAGIC); \ | ||
29 | return __VA_ARGS__; \ | ||
30 | } \ | ||
31 | } while (0) | ||
32 | |||
33 | Eina_Bool | ||
34 | eina_strbuf_common_init(void); | ||
35 | |||
36 | Eina_Bool | ||
37 | eina_strbuf_common_shutdown(void); | ||
38 | Eina_Strbuf * | ||
39 | eina_strbuf_common_new(size_t csize); | ||
40 | Eina_Strbuf * | ||
41 | eina_strbuf_common_manage_new(size_t csize, | ||
42 | void *str, | ||
43 | size_t len); | ||
44 | void | ||
45 | eina_strbuf_common_free(Eina_Strbuf *buf); | ||
46 | void | ||
47 | eina_strbuf_common_reset(size_t csize, Eina_Strbuf *buf); | ||
48 | Eina_Bool | ||
49 | eina_strbuf_common_append(size_t csize, | ||
50 | Eina_Strbuf *buf, | ||
51 | const void *str, | ||
52 | size_t len); | ||
53 | Eina_Bool | ||
54 | eina_strbuf_common_append_escaped(size_t csize, | ||
55 | Eina_Strbuf *buf, | ||
56 | const void *str); | ||
57 | Eina_Bool | ||
58 | eina_strbuf_common_append_n(size_t csize, | ||
59 | Eina_Strbuf *buf, | ||
60 | const void *str, | ||
61 | size_t len, | ||
62 | size_t maxlen); | ||
63 | Eina_Bool | ||
64 | eina_strbuf_common_append_length(size_t csize, | ||
65 | Eina_Strbuf *buf, | ||
66 | const void *str, | ||
67 | size_t length); | ||
68 | Eina_Bool | ||
69 | eina_strbuf_common_insert(size_t csize, | ||
70 | Eina_Strbuf *buf, | ||
71 | const void *str, | ||
72 | size_t len, | ||
73 | size_t pos); | ||
74 | Eina_Bool | ||
75 | eina_strbuf_common_insert_escaped(size_t csize, | ||
76 | Eina_Strbuf *buf, | ||
77 | const void *str, | ||
78 | size_t len, | ||
79 | size_t pos); | ||
80 | Eina_Bool | ||
81 | eina_strbuf_common_insert_n(size_t csize, | ||
82 | Eina_Strbuf *buf, | ||
83 | const void *str, | ||
84 | size_t len, | ||
85 | size_t maxlen, | ||
86 | size_t pos); | ||
87 | Eina_Bool | ||
88 | eina_strbuf_common_insert_length(size_t csize, | ||
89 | Eina_Strbuf *buf, | ||
90 | const void *str, | ||
91 | size_t length, | ||
92 | size_t pos); | ||
93 | Eina_Bool | ||
94 | eina_strbuf_common_append_char(size_t csize, Eina_Strbuf *buf, const void *c); | ||
95 | Eina_Bool | ||
96 | eina_strbuf_common_insert_char(size_t csize, | ||
97 | Eina_Strbuf *buf, | ||
98 | const void *c, | ||
99 | size_t pos); | ||
100 | Eina_Bool | ||
101 | eina_strbuf_common_remove(size_t csize, | ||
102 | Eina_Strbuf *buf, | ||
103 | size_t start, | ||
104 | size_t end); | ||
105 | const void * | ||
106 | eina_strbuf_common_string_get(const Eina_Strbuf *buf); | ||
107 | void * | ||
108 | eina_strbuf_common_string_steal(size_t csize, Eina_Strbuf *buf); | ||
109 | void | ||
110 | eina_strbuf_common_string_free(size_t csize, Eina_Strbuf *buf); | ||
111 | size_t | ||
112 | eina_strbuf_common_length_get(const Eina_Strbuf *buf); | ||
113 | |||
114 | Eina_Bool | ||
115 | _eina_strbuf_common_grow(size_t csize, Eina_Strbuf *buf, size_t size); | ||
116 | /** | ||
117 | * @} | ||
118 | */ | ||
119 | |||
120 | #endif | ||
diff --git a/libraries/eina/src/lib/eina_strbuf_template_c.x b/libraries/eina/src/lib/eina_strbuf_template_c.x deleted file mode 100644 index e8c3b61..0000000 --- a/libraries/eina/src/lib/eina_strbuf_template_c.x +++ /dev/null | |||
@@ -1,97 +0,0 @@ | |||
1 | /* | ||
2 | * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 | ||
3 | */ | ||
4 | |||
5 | /* This file should be included from files implementing strbuf. | ||
6 | The including file should define the following macros: | ||
7 | * _STRBUF_DATA_TYPE | ||
8 | * _STRBUF_CSIZE | ||
9 | * _STRBUF_STRUCT_NAME | ||
10 | * _STRBUF_STRLEN_FUNC(x) | ||
11 | * _STRBUF_STRESCAPE_FUNC(x) | ||
12 | * _STRBUF_STRSTR_FUNC(x, y) | ||
13 | * _STRBUF_MAGIC | ||
14 | * _STRBUF_MAGIC_STR | ||
15 | * See how it's done in eina_ustrbuf.c and eina_strbuf.c. This just makes things | ||
16 | * a lot easier since those are essentially the same just with different sizes. | ||
17 | */ | ||
18 | |||
19 | #include "eina_binbuf_template_c.x" | ||
20 | |||
21 | /*============================================================================* | ||
22 | * API * | ||
23 | *============================================================================*/ | ||
24 | |||
25 | EAPI _STRBUF_STRUCT_NAME * | ||
26 | _FUNC_EXPAND(manage_new)(_STRBUF_DATA_TYPE *str) | ||
27 | { | ||
28 | _STRBUF_STRUCT_NAME *buf = eina_strbuf_common_manage_new(_STRBUF_CSIZE, | ||
29 | (void *) str, _STRBUF_STRLEN_FUNC(str)); | ||
30 | EINA_MAGIC_SET(buf, _STRBUF_MAGIC); | ||
31 | return buf; | ||
32 | } | ||
33 | |||
34 | EAPI Eina_Bool | ||
35 | _FUNC_EXPAND(append)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str) | ||
36 | { | ||
37 | EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); | ||
38 | return eina_strbuf_common_append(_STRBUF_CSIZE, buf, (const void *) str, _STRBUF_STRLEN_FUNC(str)); | ||
39 | } | ||
40 | |||
41 | EAPI Eina_Bool | ||
42 | _FUNC_EXPAND(append_escaped)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str) | ||
43 | { | ||
44 | _STRBUF_DATA_TYPE *esc; | ||
45 | Eina_Bool ret; | ||
46 | |||
47 | EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); | ||
48 | esc = _STRBUF_STRESCAPE_FUNC(str); | ||
49 | if (!esc) { | ||
50 | return _FUNC_EXPAND(append)(buf, str); | ||
51 | } | ||
52 | ret = _FUNC_EXPAND(append)(buf, esc); | ||
53 | if (esc) | ||
54 | free(esc); | ||
55 | |||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | EAPI Eina_Bool | ||
60 | _FUNC_EXPAND(append_n)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t maxlen) | ||
61 | { | ||
62 | EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); | ||
63 | return eina_strbuf_common_append_n(_STRBUF_CSIZE, buf, (const void *) str, _STRBUF_STRLEN_FUNC(str), maxlen); | ||
64 | } | ||
65 | |||
66 | EAPI Eina_Bool | ||
67 | _FUNC_EXPAND(insert)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t pos) | ||
68 | { | ||
69 | EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); | ||
70 | return eina_strbuf_common_insert(_STRBUF_CSIZE, buf, (const void *) str, _STRBUF_STRLEN_FUNC(str), pos); | ||
71 | } | ||
72 | |||
73 | EAPI Eina_Bool | ||
74 | _FUNC_EXPAND(insert_escaped)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t pos) | ||
75 | { | ||
76 | _STRBUF_DATA_TYPE *esc; | ||
77 | Eina_Bool ret; | ||
78 | EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); | ||
79 | |||
80 | esc = _STRBUF_STRESCAPE_FUNC(str); | ||
81 | if (!esc) { | ||
82 | return _FUNC_EXPAND(insert)(buf, str, pos); | ||
83 | } | ||
84 | ret = _FUNC_EXPAND(insert)(buf, esc, pos); | ||
85 | if (esc) | ||
86 | free(esc); | ||
87 | |||
88 | return ret; | ||
89 | } | ||
90 | |||
91 | EAPI Eina_Bool | ||
92 | _FUNC_EXPAND(insert_n)(_STRBUF_STRUCT_NAME *buf, const _STRBUF_DATA_TYPE *str, size_t maxlen, size_t pos) | ||
93 | { | ||
94 | EINA_MAGIC_CHECK_STRBUF(buf, EINA_FALSE); | ||
95 | return eina_strbuf_common_insert_n(_STRBUF_CSIZE, buf, (const void *) str, _STRBUF_STRLEN_FUNC(str), maxlen, pos); | ||
96 | } | ||
97 | |||
diff --git a/libraries/eina/src/lib/eina_stringshare.c b/libraries/eina/src/lib/eina_stringshare.c deleted file mode 100644 index f371fcd..0000000 --- a/libraries/eina/src/lib/eina_stringshare.c +++ /dev/null | |||
@@ -1,792 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2010 | ||
3 | * Carsten Haitzler, | ||
4 | * Jorge Luis Zapata Muga, | ||
5 | * Cedric Bail, | ||
6 | * Gustavo Sverzut Barbieri | ||
7 | * Tom Hacohen | ||
8 | * Brett Nash | ||
9 | * | ||
10 | * This library is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU Lesser General Public | ||
12 | * License as published by the Free Software Foundation; either | ||
13 | * version 2.1 of the License, or (at your option) any later version. | ||
14 | * | ||
15 | * This library is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | * Lesser General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU Lesser General Public | ||
21 | * License along with this library; | ||
22 | * if not, see <http://www.gnu.org/licenses/>. | ||
23 | */ | ||
24 | |||
25 | #ifdef HAVE_CONFIG_H | ||
26 | # include "config.h" | ||
27 | #endif | ||
28 | |||
29 | #ifdef HAVE_ALLOCA_H | ||
30 | # include <alloca.h> | ||
31 | #elif defined __GNUC__ | ||
32 | # define alloca __builtin_alloca | ||
33 | #elif defined _AIX | ||
34 | # define alloca __alloca | ||
35 | #elif defined _MSC_VER | ||
36 | # include <malloc.h> | ||
37 | # define alloca _alloca | ||
38 | #else | ||
39 | # include <stddef.h> | ||
40 | # ifdef __cplusplus | ||
41 | extern "C" | ||
42 | # endif | ||
43 | void *alloca (size_t); | ||
44 | #endif | ||
45 | |||
46 | #include <stdlib.h> | ||
47 | #include <stdio.h> | ||
48 | #include <string.h> | ||
49 | |||
50 | #ifdef HAVE_EVIL | ||
51 | # include <Evil.h> | ||
52 | #endif | ||
53 | |||
54 | #include "eina_config.h" | ||
55 | #include "eina_private.h" | ||
56 | #include "eina_error.h" | ||
57 | #include "eina_log.h" | ||
58 | #include "eina_lock.h" | ||
59 | #include "eina_share_common.h" | ||
60 | |||
61 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
62 | #include "eina_safety_checks.h" | ||
63 | #include "eina_stringshare.h" | ||
64 | |||
65 | |||
66 | #ifdef CRITICAL | ||
67 | #undef CRITICAL | ||
68 | #endif | ||
69 | #define CRITICAL(...) EINA_LOG_DOM_CRIT(_eina_share_stringshare_log_dom, __VA_ARGS__) | ||
70 | |||
71 | #ifdef ERR | ||
72 | #undef ERR | ||
73 | #endif | ||
74 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_share_stringshare_log_dom, __VA_ARGS__) | ||
75 | |||
76 | #ifdef DBG | ||
77 | #undef DBG | ||
78 | #endif | ||
79 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_share_stringshare_log_dom, __VA_ARGS__) | ||
80 | |||
81 | static int _eina_share_stringshare_log_dom = -1; | ||
82 | |||
83 | /* The actual share */ | ||
84 | static Eina_Share *stringshare_share; | ||
85 | static const char EINA_MAGIC_STRINGSHARE_NODE_STR[] = "Eina Stringshare Node"; | ||
86 | |||
87 | extern Eina_Bool _share_common_threads_activated; | ||
88 | static Eina_Lock _mutex_small; | ||
89 | |||
90 | /* Stringshare optimizations */ | ||
91 | static const unsigned char _eina_stringshare_single[512] = { | ||
92 | 0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0, | ||
93 | 16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0, | ||
94 | 31,0,32,0,33,0,34,0,35,0,36,0,37,0,38,0,39,0,40,0,41,0,42,0,43,0,44,0,45,0, | ||
95 | 46,0,47,0,48,0,49,0,50,0,51,0,52,0,53,0,54,0,55,0,56,0,57,0,58,0,59,0,60,0, | ||
96 | 61,0,62,0,63,0,64,0,65,0,66,0,67,0,68,0,69,0,70,0,71,0,72,0,73,0,74,0,75,0, | ||
97 | 76,0,77,0,78,0,79,0,80,0,81,0,82,0,83,0,84,0,85,0,86,0,87,0,88,0,89,0,90,0, | ||
98 | 91,0,92,0,93,0,94,0,95,0,96,0,97,0,98,0,99,0,100,0,101,0,102,0,103,0,104,0, | ||
99 | 105,0, | ||
100 | 106,0,107,0,108,0,109,0,110,0,111,0,112,0,113,0,114,0,115,0,116,0,117,0,118, | ||
101 | 0,119,0,120,0, | ||
102 | 121,0,122,0,123,0,124,0,125,0,126,0,127,0,128,0,129,0,130,0,131,0,132,0,133, | ||
103 | 0,134,0,135,0, | ||
104 | 136,0,137,0,138,0,139,0,140,0,141,0,142,0,143,0,144,0,145,0,146,0,147,0,148, | ||
105 | 0,149,0,150,0, | ||
106 | 151,0,152,0,153,0,154,0,155,0,156,0,157,0,158,0,159,0,160,0,161,0,162,0,163, | ||
107 | 0,164,0,165,0, | ||
108 | 166,0,167,0,168,0,169,0,170,0,171,0,172,0,173,0,174,0,175,0,176,0,177,0,178, | ||
109 | 0,179,0,180,0, | ||
110 | 181,0,182,0,183,0,184,0,185,0,186,0,187,0,188,0,189,0,190,0,191,0,192,0,193, | ||
111 | 0,194,0,195,0, | ||
112 | 196,0,197,0,198,0,199,0,200,0,201,0,202,0,203,0,204,0,205,0,206,0,207,0,208, | ||
113 | 0,209,0,210,0, | ||
114 | 211,0,212,0,213,0,214,0,215,0,216,0,217,0,218,0,219,0,220,0,221,0,222,0,223, | ||
115 | 0,224,0,225,0, | ||
116 | 226,0,227,0,228,0,229,0,230,0,231,0,232,0,233,0,234,0,235,0,236,0,237,0,238, | ||
117 | 0,239,0,240,0, | ||
118 | 241,0,242,0,243,0,244,0,245,0,246,0,247,0,248,0,249,0,250,0,251,0,252,0,253, | ||
119 | 0,254,0,255,0 | ||
120 | }; | ||
121 | |||
122 | typedef struct _Eina_Stringshare_Small Eina_Stringshare_Small; | ||
123 | typedef struct _Eina_Stringshare_Small_Bucket Eina_Stringshare_Small_Bucket; | ||
124 | |||
125 | struct _Eina_Stringshare_Small_Bucket | ||
126 | { | ||
127 | /* separate arrays for faster lookups */ | ||
128 | const char **strings; | ||
129 | unsigned char *lengths; | ||
130 | unsigned short *references; | ||
131 | int count; | ||
132 | int size; | ||
133 | }; | ||
134 | |||
135 | struct _Eina_Stringshare_Small | ||
136 | { | ||
137 | Eina_Stringshare_Small_Bucket *buckets[256]; | ||
138 | }; | ||
139 | |||
140 | #define EINA_STRINGSHARE_SMALL_BUCKET_STEP 8 | ||
141 | static Eina_Stringshare_Small _eina_small_share; | ||
142 | |||
143 | static inline int | ||
144 | _eina_stringshare_small_cmp(const Eina_Stringshare_Small_Bucket *bucket, | ||
145 | int i, | ||
146 | const char *pstr, | ||
147 | unsigned char plength) | ||
148 | { | ||
149 | /* pstr and plength are from second char and on, since the first is | ||
150 | * always the same. | ||
151 | * | ||
152 | * First string being always the same, size being between 2 and 3 | ||
153 | * characters (there is a check for special case length==1 and then | ||
154 | * small stringshare is applied to strings < 4), we just need to | ||
155 | * compare 2 characters of both strings. | ||
156 | */ | ||
157 | const unsigned char cur_plength = bucket->lengths[i] - 1; | ||
158 | const char *cur_pstr; | ||
159 | |||
160 | if (cur_plength > plength) | ||
161 | return 1; | ||
162 | else if (cur_plength < plength) | ||
163 | return -1; | ||
164 | |||
165 | cur_pstr = bucket->strings[i] + 1; | ||
166 | |||
167 | if (cur_pstr[0] > pstr[0]) | ||
168 | return 1; | ||
169 | else if (cur_pstr[0] < pstr[0]) | ||
170 | return -1; | ||
171 | |||
172 | if (plength == 1) | ||
173 | return 0; | ||
174 | |||
175 | if (cur_pstr[1] > pstr[1]) | ||
176 | return 1; | ||
177 | else if (cur_pstr[1] < pstr[1]) | ||
178 | return -1; | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static const char * | ||
184 | _eina_stringshare_small_bucket_find(const Eina_Stringshare_Small_Bucket *bucket, | ||
185 | const char *str, | ||
186 | unsigned char length, | ||
187 | int *idx) | ||
188 | { | ||
189 | const char *pstr = str + 1; /* skip first letter, it's always the same */ | ||
190 | unsigned char plength = length - 1; | ||
191 | int i, low, high; | ||
192 | |||
193 | if (bucket->count == 0) | ||
194 | { | ||
195 | *idx = 0; | ||
196 | return NULL; | ||
197 | } | ||
198 | |||
199 | low = 0; | ||
200 | high = bucket->count; | ||
201 | |||
202 | while (low < high) | ||
203 | { | ||
204 | int r; | ||
205 | |||
206 | i = (low + high - 1) / 2; | ||
207 | |||
208 | r = _eina_stringshare_small_cmp(bucket, i, pstr, plength); | ||
209 | if (r > 0) | ||
210 | high = i; | ||
211 | else if (r < 0) | ||
212 | low = i + 1; | ||
213 | else | ||
214 | { | ||
215 | *idx = i; | ||
216 | return bucket->strings[i]; | ||
217 | } | ||
218 | } | ||
219 | |||
220 | *idx = low; | ||
221 | return NULL; | ||
222 | } | ||
223 | |||
224 | static Eina_Bool | ||
225 | _eina_stringshare_small_bucket_resize(Eina_Stringshare_Small_Bucket *bucket, | ||
226 | int size) | ||
227 | { | ||
228 | void *tmp; | ||
229 | |||
230 | tmp = realloc((void *)bucket->strings, size * sizeof(bucket->strings[0])); | ||
231 | if (!tmp) | ||
232 | { | ||
233 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | bucket->strings = tmp; | ||
238 | |||
239 | tmp = realloc(bucket->lengths, size * sizeof(bucket->lengths[0])); | ||
240 | if (!tmp) | ||
241 | { | ||
242 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | bucket->lengths = tmp; | ||
247 | |||
248 | tmp = realloc(bucket->references, size * sizeof(bucket->references[0])); | ||
249 | if (!tmp) | ||
250 | { | ||
251 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | bucket->references = tmp; | ||
256 | |||
257 | bucket->size = size; | ||
258 | return 1; | ||
259 | } | ||
260 | |||
261 | static const char * | ||
262 | _eina_stringshare_small_bucket_insert_at( | ||
263 | Eina_Stringshare_Small_Bucket **p_bucket, | ||
264 | const char *str, | ||
265 | unsigned char length, | ||
266 | int idx) | ||
267 | { | ||
268 | Eina_Stringshare_Small_Bucket *bucket = *p_bucket; | ||
269 | int todo, off; | ||
270 | char *snew; | ||
271 | |||
272 | if (!bucket) | ||
273 | { | ||
274 | *p_bucket = bucket = calloc(1, sizeof(*bucket)); | ||
275 | if (!bucket) | ||
276 | { | ||
277 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
278 | return NULL; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | if (bucket->count + 1 >= bucket->size) | ||
283 | { | ||
284 | int size = bucket->size + EINA_STRINGSHARE_SMALL_BUCKET_STEP; | ||
285 | if (!_eina_stringshare_small_bucket_resize(bucket, size)) | ||
286 | return NULL; | ||
287 | } | ||
288 | |||
289 | snew = malloc(length + 1); | ||
290 | if (!snew) | ||
291 | { | ||
292 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
293 | return NULL; | ||
294 | } | ||
295 | |||
296 | memcpy(snew, str, length); | ||
297 | snew[length] = '\0'; | ||
298 | |||
299 | off = idx + 1; | ||
300 | todo = bucket->count - idx; | ||
301 | if (todo > 0) | ||
302 | { | ||
303 | memmove((void *)(bucket->strings + off), bucket->strings + idx, | ||
304 | todo * sizeof(bucket->strings[0])); | ||
305 | memmove(bucket->lengths + off, bucket->lengths + idx, | ||
306 | todo * sizeof(bucket->lengths[0])); | ||
307 | memmove(bucket->references + off, bucket->references + idx, | ||
308 | todo * sizeof(bucket->references[0])); | ||
309 | } | ||
310 | |||
311 | bucket->strings[idx] = snew; | ||
312 | bucket->lengths[idx] = length; | ||
313 | bucket->references[idx] = 1; | ||
314 | bucket->count++; | ||
315 | |||
316 | return snew; | ||
317 | } | ||
318 | |||
319 | static void | ||
320 | _eina_stringshare_small_bucket_remove_at( | ||
321 | Eina_Stringshare_Small_Bucket **p_bucket, | ||
322 | int idx) | ||
323 | { | ||
324 | Eina_Stringshare_Small_Bucket *bucket = *p_bucket; | ||
325 | int todo, off; | ||
326 | |||
327 | if (bucket->references[idx] > 1) | ||
328 | { | ||
329 | bucket->references[idx]--; | ||
330 | return; | ||
331 | } | ||
332 | |||
333 | free((char *)bucket->strings[idx]); | ||
334 | |||
335 | if (bucket->count == 1) | ||
336 | { | ||
337 | free((void *)bucket->strings); | ||
338 | free(bucket->lengths); | ||
339 | free(bucket->references); | ||
340 | free(bucket); | ||
341 | *p_bucket = NULL; | ||
342 | return; | ||
343 | } | ||
344 | |||
345 | bucket->count--; | ||
346 | if (idx == bucket->count) | ||
347 | goto end; | ||
348 | |||
349 | off = idx + 1; | ||
350 | todo = bucket->count - idx; | ||
351 | |||
352 | memmove((void *)(bucket->strings + idx), bucket->strings + off, | ||
353 | todo * sizeof(bucket->strings[0])); | ||
354 | memmove(bucket->lengths + idx, bucket->lengths + off, | ||
355 | todo * sizeof(bucket->lengths[0])); | ||
356 | memmove(bucket->references + idx, bucket->references + off, | ||
357 | todo * sizeof(bucket->references[0])); | ||
358 | |||
359 | end: | ||
360 | if (bucket->count + EINA_STRINGSHARE_SMALL_BUCKET_STEP < bucket->size) | ||
361 | { | ||
362 | int size = bucket->size - EINA_STRINGSHARE_SMALL_BUCKET_STEP; | ||
363 | _eina_stringshare_small_bucket_resize(bucket, size); | ||
364 | } | ||
365 | } | ||
366 | |||
367 | static const char * | ||
368 | _eina_stringshare_small_add(const char *str, unsigned char length) | ||
369 | { | ||
370 | Eina_Stringshare_Small_Bucket **bucket; | ||
371 | int i; | ||
372 | |||
373 | bucket = _eina_small_share.buckets + (unsigned char)str[0]; | ||
374 | if (!*bucket) | ||
375 | i = 0; | ||
376 | else | ||
377 | { | ||
378 | const char *ret; | ||
379 | ret = _eina_stringshare_small_bucket_find(*bucket, str, length, &i); | ||
380 | if (ret) | ||
381 | { | ||
382 | (*bucket)->references[i]++; | ||
383 | return ret; | ||
384 | } | ||
385 | } | ||
386 | |||
387 | return _eina_stringshare_small_bucket_insert_at(bucket, str, length, i); | ||
388 | } | ||
389 | |||
390 | static void | ||
391 | _eina_stringshare_small_del(const char *str, unsigned char length) | ||
392 | { | ||
393 | Eina_Stringshare_Small_Bucket **bucket; | ||
394 | const char *ret; | ||
395 | int i; | ||
396 | |||
397 | bucket = _eina_small_share.buckets + (unsigned char)str[0]; | ||
398 | if (!*bucket) | ||
399 | goto error; | ||
400 | |||
401 | ret = _eina_stringshare_small_bucket_find(*bucket, str, length, &i); | ||
402 | if (!ret) | ||
403 | goto error; | ||
404 | |||
405 | _eina_stringshare_small_bucket_remove_at(bucket, i); | ||
406 | return; | ||
407 | |||
408 | error: | ||
409 | CRITICAL("EEEK trying to del non-shared stringshare \"%s\"", str); | ||
410 | } | ||
411 | |||
412 | static void | ||
413 | _eina_stringshare_small_init(void) | ||
414 | { | ||
415 | eina_lock_new(&_mutex_small); | ||
416 | memset(&_eina_small_share, 0, sizeof(_eina_small_share)); | ||
417 | } | ||
418 | |||
419 | static void | ||
420 | _eina_stringshare_small_shutdown(void) | ||
421 | { | ||
422 | Eina_Stringshare_Small_Bucket **p_bucket, **p_bucket_end; | ||
423 | |||
424 | p_bucket = _eina_small_share.buckets; | ||
425 | p_bucket_end = p_bucket + 256; | ||
426 | |||
427 | for (; p_bucket < p_bucket_end; p_bucket++) | ||
428 | { | ||
429 | Eina_Stringshare_Small_Bucket *bucket = *p_bucket; | ||
430 | char **s, **s_end; | ||
431 | |||
432 | if (!bucket) | ||
433 | continue; | ||
434 | |||
435 | s = (char **)bucket->strings; | ||
436 | s_end = s + bucket->count; | ||
437 | for (; s < s_end; s++) | ||
438 | free(*s); | ||
439 | |||
440 | free((void *)bucket->strings); | ||
441 | free(bucket->lengths); | ||
442 | free(bucket->references); | ||
443 | free(bucket); | ||
444 | *p_bucket = NULL; | ||
445 | } | ||
446 | |||
447 | eina_lock_free(&_mutex_small); | ||
448 | } | ||
449 | |||
450 | static void | ||
451 | _eina_stringshare_small_bucket_dump(Eina_Stringshare_Small_Bucket *bucket, | ||
452 | struct dumpinfo *di) | ||
453 | { | ||
454 | const char **s = bucket->strings; | ||
455 | unsigned char *l = bucket->lengths; | ||
456 | unsigned short *r = bucket->references; | ||
457 | int i; | ||
458 | |||
459 | di->used += sizeof(*bucket); | ||
460 | di->used += bucket->count * sizeof(*s); | ||
461 | di->used += bucket->count * sizeof(*l); | ||
462 | di->used += bucket->count * sizeof(*r); | ||
463 | di->unique += bucket->count; | ||
464 | |||
465 | for (i = 0; i < bucket->count; i++, s++, l++, r++) | ||
466 | { | ||
467 | int dups; | ||
468 | |||
469 | printf("DDD: %5hhu %5hu '%s'\n", *l, *r, *s); | ||
470 | |||
471 | dups = (*r - 1); | ||
472 | |||
473 | di->used += *l; | ||
474 | di->saved += *l * dups; | ||
475 | di->dups += dups; | ||
476 | } | ||
477 | } | ||
478 | |||
479 | static void | ||
480 | _eina_stringshare_small_dump(struct dumpinfo *di) | ||
481 | { | ||
482 | Eina_Stringshare_Small_Bucket **p_bucket, **p_bucket_end; | ||
483 | |||
484 | p_bucket = _eina_small_share.buckets; | ||
485 | p_bucket_end = p_bucket + 256; | ||
486 | |||
487 | for (; p_bucket < p_bucket_end; p_bucket++) | ||
488 | { | ||
489 | Eina_Stringshare_Small_Bucket *bucket = *p_bucket; | ||
490 | |||
491 | if (!bucket) | ||
492 | continue; | ||
493 | |||
494 | _eina_stringshare_small_bucket_dump(bucket, di); | ||
495 | } | ||
496 | } | ||
497 | |||
498 | |||
499 | /*============================================================================* | ||
500 | * Global * | ||
501 | *============================================================================*/ | ||
502 | |||
503 | /** | ||
504 | * @internal | ||
505 | * @brief Initialize the share_common module. | ||
506 | * | ||
507 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
508 | * | ||
509 | * This function sets up the share_common module of Eina. It is called by | ||
510 | * eina_init(). | ||
511 | * | ||
512 | * @see eina_init() | ||
513 | */ | ||
514 | Eina_Bool | ||
515 | eina_stringshare_init(void) | ||
516 | { | ||
517 | Eina_Bool ret; | ||
518 | |||
519 | if (_eina_share_stringshare_log_dom < 0) | ||
520 | { | ||
521 | _eina_share_stringshare_log_dom = eina_log_domain_register | ||
522 | ("eina_stringshare", EINA_LOG_COLOR_DEFAULT); | ||
523 | |||
524 | if (_eina_share_stringshare_log_dom < 0) | ||
525 | { | ||
526 | EINA_LOG_ERR("Could not register log domain: eina_stringshare"); | ||
527 | return EINA_FALSE; | ||
528 | } | ||
529 | } | ||
530 | |||
531 | ret = eina_share_common_init(&stringshare_share, | ||
532 | EINA_MAGIC_STRINGSHARE_NODE, | ||
533 | EINA_MAGIC_STRINGSHARE_NODE_STR); | ||
534 | if (ret) | ||
535 | _eina_stringshare_small_init(); | ||
536 | else | ||
537 | { | ||
538 | eina_log_domain_unregister(_eina_share_stringshare_log_dom); | ||
539 | _eina_share_stringshare_log_dom = -1; | ||
540 | } | ||
541 | |||
542 | return ret; | ||
543 | } | ||
544 | |||
545 | /** | ||
546 | * @internal | ||
547 | * @brief Shut down the share_common module. | ||
548 | * | ||
549 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
550 | * | ||
551 | * This function shuts down the share_common module set up by | ||
552 | * eina_share_common_init(). It is called by eina_shutdown(). | ||
553 | * | ||
554 | * @see eina_shutdown() | ||
555 | */ | ||
556 | Eina_Bool | ||
557 | eina_stringshare_shutdown(void) | ||
558 | { | ||
559 | Eina_Bool ret; | ||
560 | _eina_stringshare_small_shutdown(); | ||
561 | ret = eina_share_common_shutdown(&stringshare_share); | ||
562 | |||
563 | if (_eina_share_stringshare_log_dom >= 0) | ||
564 | { | ||
565 | eina_log_domain_unregister(_eina_share_stringshare_log_dom); | ||
566 | _eina_share_stringshare_log_dom = -1; | ||
567 | } | ||
568 | |||
569 | return ret; | ||
570 | } | ||
571 | |||
572 | /*============================================================================* | ||
573 | * API * | ||
574 | *============================================================================*/ | ||
575 | |||
576 | EAPI void | ||
577 | eina_stringshare_del(Eina_Stringshare *str) | ||
578 | { | ||
579 | int slen; | ||
580 | |||
581 | if (!str) | ||
582 | return; | ||
583 | |||
584 | /* special cases */ | ||
585 | if (str[0] == '\0') | ||
586 | slen = 0; | ||
587 | else if (str[1] == '\0') | ||
588 | slen = 1; | ||
589 | else if (str[2] == '\0') | ||
590 | slen = 2; | ||
591 | else if (str[3] == '\0') | ||
592 | slen = 3; | ||
593 | else | ||
594 | slen = 4; /* handled later */ | ||
595 | |||
596 | if (slen < 2) | ||
597 | return; | ||
598 | else if (slen < 4) | ||
599 | { | ||
600 | eina_share_common_population_del(stringshare_share, slen); | ||
601 | eina_lock_take(&_mutex_small); | ||
602 | _eina_stringshare_small_del(str, slen); | ||
603 | eina_lock_release(&_mutex_small); | ||
604 | return; | ||
605 | } | ||
606 | |||
607 | if (!eina_share_common_del(stringshare_share, str)) | ||
608 | CRITICAL("EEEK trying to del non-shared stringshare \"%s\"", str); | ||
609 | } | ||
610 | |||
611 | EAPI Eina_Stringshare * | ||
612 | eina_stringshare_add_length(const char *str, unsigned int slen) | ||
613 | { | ||
614 | if ((!str) || (slen <= 0)) | ||
615 | return ""; | ||
616 | else if (slen == 1) | ||
617 | return (Eina_Stringshare *) _eina_stringshare_single + ((*str) << 1); | ||
618 | else if (slen < 4) | ||
619 | { | ||
620 | const char *s; | ||
621 | |||
622 | eina_lock_take(&_mutex_small); | ||
623 | s = _eina_stringshare_small_add(str, slen); | ||
624 | eina_lock_release(&_mutex_small); | ||
625 | return s; | ||
626 | } | ||
627 | |||
628 | return eina_share_common_add_length(stringshare_share, str, slen * | ||
629 | sizeof(char), sizeof(char)); | ||
630 | } | ||
631 | |||
632 | EAPI Eina_Stringshare * | ||
633 | eina_stringshare_add(const char *str) | ||
634 | { | ||
635 | int slen; | ||
636 | if (!str) | ||
637 | return NULL; | ||
638 | |||
639 | if (str[0] == '\0') | ||
640 | slen = 0; | ||
641 | else if (str[1] == '\0') | ||
642 | slen = 1; | ||
643 | else if (str[2] == '\0') | ||
644 | slen = 2; | ||
645 | else if (str[3] == '\0') | ||
646 | slen = 3; | ||
647 | else | ||
648 | slen = 3 + (int)strlen(str + 3); | ||
649 | |||
650 | return eina_stringshare_add_length(str, slen); | ||
651 | } | ||
652 | |||
653 | EAPI Eina_Stringshare * | ||
654 | eina_stringshare_printf(const char *fmt, ...) | ||
655 | { | ||
656 | va_list args; | ||
657 | char *tmp; | ||
658 | const char *ret; | ||
659 | int len; | ||
660 | |||
661 | if (!fmt) | ||
662 | return NULL; | ||
663 | |||
664 | va_start(args, fmt); | ||
665 | len = vasprintf(&tmp, fmt, args); | ||
666 | va_end(args); | ||
667 | |||
668 | if (len < 1) | ||
669 | return NULL; | ||
670 | |||
671 | ret = eina_stringshare_add_length(tmp, len); | ||
672 | free(tmp); | ||
673 | |||
674 | return ret; | ||
675 | } | ||
676 | |||
677 | EAPI Eina_Stringshare * | ||
678 | eina_stringshare_vprintf(const char *fmt, va_list args) | ||
679 | { | ||
680 | char *tmp; | ||
681 | const char *ret; | ||
682 | int len; | ||
683 | |||
684 | if (!fmt) | ||
685 | return NULL; | ||
686 | |||
687 | len = vasprintf(&tmp, fmt, args); | ||
688 | |||
689 | if (len < 1) | ||
690 | return NULL; | ||
691 | |||
692 | ret = eina_stringshare_add_length(tmp, len); | ||
693 | free(tmp); | ||
694 | |||
695 | return ret; | ||
696 | } | ||
697 | |||
698 | EAPI Eina_Stringshare * | ||
699 | eina_stringshare_nprintf(unsigned int len, const char *fmt, ...) | ||
700 | { | ||
701 | va_list args; | ||
702 | char *tmp; | ||
703 | int size; | ||
704 | |||
705 | if (!fmt) | ||
706 | return NULL; | ||
707 | |||
708 | if (len < 1) | ||
709 | return NULL; | ||
710 | |||
711 | tmp = alloca(sizeof(char) * len + 1); | ||
712 | |||
713 | va_start(args, fmt); | ||
714 | size = vsnprintf(tmp, len, fmt, args); | ||
715 | va_end(args); | ||
716 | |||
717 | if (size < 1) | ||
718 | return NULL; | ||
719 | |||
720 | return eina_stringshare_add_length(tmp, len); | ||
721 | } | ||
722 | |||
723 | EAPI Eina_Stringshare * | ||
724 | eina_stringshare_ref(Eina_Stringshare *str) | ||
725 | { | ||
726 | int slen; | ||
727 | |||
728 | if (!str) | ||
729 | return eina_share_common_ref(stringshare_share, str); | ||
730 | |||
731 | /* special cases */ | ||
732 | if (str[0] == '\0') | ||
733 | slen = 0; | ||
734 | else if (str[1] == '\0') | ||
735 | slen = 1; | ||
736 | else if (str[2] == '\0') | ||
737 | slen = 2; | ||
738 | else if (str[3] == '\0') | ||
739 | slen = 3; | ||
740 | else | ||
741 | slen = 3 + (int)strlen(str + 3); | ||
742 | |||
743 | if (slen < 2) | ||
744 | { | ||
745 | eina_share_common_population_add(stringshare_share, slen); | ||
746 | |||
747 | return str; | ||
748 | } | ||
749 | else if (slen < 4) | ||
750 | { | ||
751 | const char *s; | ||
752 | eina_share_common_population_add(stringshare_share, slen); | ||
753 | |||
754 | eina_lock_take(&_mutex_small); | ||
755 | s = _eina_stringshare_small_add(str, slen); | ||
756 | eina_lock_release(&_mutex_small); | ||
757 | |||
758 | return s; | ||
759 | } | ||
760 | |||
761 | return eina_share_common_ref(stringshare_share, str); | ||
762 | } | ||
763 | |||
764 | EAPI int | ||
765 | eina_stringshare_strlen(Eina_Stringshare *str) | ||
766 | { | ||
767 | int len; | ||
768 | /* special cases */ | ||
769 | if (str[0] == '\0') | ||
770 | return 0; | ||
771 | |||
772 | if (str[1] == '\0') | ||
773 | return 1; | ||
774 | |||
775 | if (str[2] == '\0') | ||
776 | return 2; | ||
777 | |||
778 | if (str[3] == '\0') | ||
779 | return 3; | ||
780 | |||
781 | len = eina_share_common_length(stringshare_share, (Eina_Stringshare *) str); | ||
782 | len = (len > 0) ? len / (int)sizeof(char) : -1; | ||
783 | return len; | ||
784 | } | ||
785 | |||
786 | EAPI void | ||
787 | eina_stringshare_dump(void) | ||
788 | { | ||
789 | eina_share_common_dump(stringshare_share, | ||
790 | _eina_stringshare_small_dump, | ||
791 | sizeof(_eina_stringshare_single)); | ||
792 | } | ||
diff --git a/libraries/eina/src/lib/eina_tiler.c b/libraries/eina/src/lib/eina_tiler.c deleted file mode 100644 index 69b944e..0000000 --- a/libraries/eina/src/lib/eina_tiler.c +++ /dev/null | |||
@@ -1,1276 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2007-2008 Gustavo Sverzut Barbieri, Jorge Luis Zapata Muga | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | /* TODO | ||
20 | * it is possible to have more than one tiler algorithm, but for now the | ||
21 | * version Gustavo did is hardcoded here | ||
22 | * http://blog.gustavobarbieri.com.br/2007/06/03/evas-now-using-rectangle-split-and-merge/ | ||
23 | */ | ||
24 | |||
25 | #ifdef HAVE_CONFIG_H | ||
26 | # include "config.h" | ||
27 | #endif | ||
28 | |||
29 | #include <stdlib.h> | ||
30 | #include <stdio.h> | ||
31 | |||
32 | #include "eina_config.h" | ||
33 | #include "eina_private.h" | ||
34 | #include "eina_tiler.h" | ||
35 | #include "eina_error.h" | ||
36 | |||
37 | /*============================================================================* | ||
38 | * Local * | ||
39 | *============================================================================*/ | ||
40 | |||
41 | /* The splitter data types */ | ||
42 | typedef struct list_node list_node_t; | ||
43 | typedef struct list list_t; | ||
44 | typedef struct rect rect_t; | ||
45 | typedef struct rect_node rect_node_t; | ||
46 | |||
47 | struct list_node | ||
48 | { | ||
49 | struct list_node *next; | ||
50 | }; | ||
51 | |||
52 | struct list | ||
53 | { | ||
54 | struct list_node *head; | ||
55 | struct list_node *tail; | ||
56 | }; | ||
57 | |||
58 | struct rect | ||
59 | { | ||
60 | short right; | ||
61 | short bottom; | ||
62 | short left; | ||
63 | short top; | ||
64 | short width; | ||
65 | short height; | ||
66 | int area; | ||
67 | }; | ||
68 | |||
69 | struct rect_node | ||
70 | { | ||
71 | struct list_node _lst; | ||
72 | struct rect rect; | ||
73 | }; | ||
74 | |||
75 | typedef struct splitter | ||
76 | { | ||
77 | Eina_Bool need_merge; | ||
78 | list_t rects; | ||
79 | } splitter_t; | ||
80 | |||
81 | typedef struct list_node_pool | ||
82 | { | ||
83 | list_node_t *node; | ||
84 | int len; | ||
85 | int max; | ||
86 | } list_node_pool_t; | ||
87 | |||
88 | |||
89 | static const list_node_t list_node_zeroed = { NULL }; | ||
90 | static const list_t list_zeroed = { NULL, NULL }; | ||
91 | static list_node_pool_t list_node_pool = { NULL, 0, 1024 }; | ||
92 | |||
93 | |||
94 | typedef struct _Eina_Iterator_Tiler | ||
95 | { | ||
96 | Eina_Iterator iterator; | ||
97 | const Eina_Tiler *tiler; | ||
98 | list_node_t *curr; | ||
99 | Eina_Rectangle r; | ||
100 | EINA_MAGIC | ||
101 | } Eina_Iterator_Tiler; | ||
102 | |||
103 | struct _Eina_Tiler | ||
104 | { | ||
105 | struct | ||
106 | { | ||
107 | int w, h; | ||
108 | } tile; | ||
109 | Eina_Rectangle area; | ||
110 | EINA_MAGIC | ||
111 | splitter_t splitter; | ||
112 | }; | ||
113 | |||
114 | #define EINA_MAGIC_CHECK_TILER(d, ...) \ | ||
115 | do { \ | ||
116 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_TILER)) \ | ||
117 | { \ | ||
118 | EINA_MAGIC_FAIL(d, EINA_MAGIC_TILER); \ | ||
119 | return __VA_ARGS__; \ | ||
120 | } \ | ||
121 | } while(0) | ||
122 | |||
123 | |||
124 | #define EINA_MAGIC_CHECK_TILER_ITERATOR(d, ...) \ | ||
125 | do { \ | ||
126 | if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_TILER_ITERATOR)) \ | ||
127 | { \ | ||
128 | EINA_MAGIC_FAIL(d, EINA_MAGIC_TILER_ITERATOR); \ | ||
129 | return __VA_ARGS__; \ | ||
130 | } \ | ||
131 | } while(0) | ||
132 | |||
133 | /* The Splitter algorithm */ | ||
134 | static inline void rect_init(rect_t *r, int x, int y, int w, int h) | ||
135 | { | ||
136 | r->area = w * h; | ||
137 | |||
138 | r->left = x; | ||
139 | r->top = y; | ||
140 | |||
141 | r->right = x + w; | ||
142 | r->bottom = y + h; | ||
143 | |||
144 | r->width = w; | ||
145 | r->height = h; | ||
146 | } | ||
147 | |||
148 | static inline list_node_t * | ||
149 | rect_list_node_pool_get(void) | ||
150 | { | ||
151 | if (list_node_pool.node) | ||
152 | { | ||
153 | list_node_t *node; | ||
154 | |||
155 | node = list_node_pool.node; | ||
156 | list_node_pool.node = node->next; | ||
157 | list_node_pool.len--; | ||
158 | |||
159 | return node; | ||
160 | } | ||
161 | else | ||
162 | return malloc(sizeof(rect_node_t)); | ||
163 | } | ||
164 | |||
165 | |||
166 | static inline void rect_list_concat(list_t *rects, list_t *other) | ||
167 | { | ||
168 | if (!other->head) | ||
169 | return; | ||
170 | |||
171 | if (rects->tail) | ||
172 | { | ||
173 | rects->tail->next = other->head; | ||
174 | rects->tail = other->tail; | ||
175 | } | ||
176 | else | ||
177 | { | ||
178 | rects->head = other->head; | ||
179 | rects->tail = other->tail; | ||
180 | } | ||
181 | |||
182 | *other = list_zeroed; | ||
183 | } | ||
184 | |||
185 | static inline void rect_list_append_node(list_t *rects, list_node_t *node) | ||
186 | { | ||
187 | if (rects->tail) | ||
188 | { | ||
189 | rects->tail->next = node; | ||
190 | rects->tail = node; | ||
191 | } | ||
192 | else | ||
193 | { | ||
194 | rects->head = node; | ||
195 | rects->tail = node; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | static inline void rect_list_append(list_t *rects, const rect_t r) | ||
200 | { | ||
201 | rect_node_t *rect_node; | ||
202 | |||
203 | rect_node = (rect_node_t *)rect_list_node_pool_get(); | ||
204 | rect_node->rect = r; | ||
205 | rect_node->_lst = list_node_zeroed; | ||
206 | |||
207 | rect_list_append_node(rects, (list_node_t *)rect_node); | ||
208 | } | ||
209 | |||
210 | static inline void rect_list_append_xywh(list_t *rects, | ||
211 | int x, | ||
212 | int y, | ||
213 | int w, | ||
214 | int h) | ||
215 | { | ||
216 | rect_t r; | ||
217 | |||
218 | rect_init(&r, x, y, w, h); | ||
219 | rect_list_append(rects, r); | ||
220 | } | ||
221 | |||
222 | static inline void _calc_intra_rect_area(const rect_t a, const rect_t b, | ||
223 | int *width, int *height) | ||
224 | { | ||
225 | int max_left, min_right, max_top, min_bottom; | ||
226 | |||
227 | if (a.left < b.left) | ||
228 | max_left = b.left; | ||
229 | else | ||
230 | max_left = a.left; | ||
231 | |||
232 | if (a.right < b.right) | ||
233 | min_right = a.right; | ||
234 | else | ||
235 | min_right = b.right; | ||
236 | |||
237 | *width = min_right - max_left; | ||
238 | |||
239 | if (a.top < b.top) | ||
240 | max_top = b.top; | ||
241 | else | ||
242 | max_top = a.top; | ||
243 | |||
244 | if (a.bottom < b.bottom) | ||
245 | min_bottom = a.bottom; | ||
246 | else | ||
247 | min_bottom = b.bottom; | ||
248 | |||
249 | *height = min_bottom - max_top; | ||
250 | } | ||
251 | |||
252 | static inline void _split_strict(list_t *dirty, const rect_t current, rect_t r) | ||
253 | { | ||
254 | int h_1, h_2, w_1, w_2; | ||
255 | |||
256 | h_1 = current.top - r.top; | ||
257 | h_2 = r.bottom - current.bottom; | ||
258 | w_1 = current.left - r.left; | ||
259 | w_2 = r.right - current.right; | ||
260 | |||
261 | if (h_1 > 0) | ||
262 | { | ||
263 | /* .--.r (b) .---.r2 | ||
264 | * | | | | | ||
265 | * .-------.cur (a) .---.r '---' | ||
266 | * | | | | -> | | + | ||
267 | * | `--' | `---' | ||
268 | * `-------' | ||
269 | */ | ||
270 | rect_list_append_xywh(dirty, r.left, r.top, r.width, h_1); | ||
271 | r.height -= h_1; | ||
272 | r.top = current.top; | ||
273 | } | ||
274 | |||
275 | if (h_2 > 0) | ||
276 | { | ||
277 | /* .-------.cur (a) | ||
278 | * | .---. | .---.r | ||
279 | * | | | | -> | | | ||
280 | * `-------' `---' + .---.r2 | ||
281 | * | | | | | ||
282 | * `---'r (b) `---' | ||
283 | */ | ||
284 | rect_list_append_xywh(dirty, r.left, current.bottom, r.width, | ||
285 | h_2); | ||
286 | r.height -= h_2; | ||
287 | } | ||
288 | |||
289 | if (w_1 > 0) | ||
290 | /* (b) r .----.cur (a) | ||
291 | * .--|-. | .--.r2 .-.r | ||
292 | * | | | | -> | | + | | | ||
293 | * `--|-' | `--' `-' | ||
294 | * `----' | ||
295 | */ | ||
296 | rect_list_append_xywh(dirty, r.left, r.top, w_1, r.height); /* not necessary to keep these, r (b) will be destroyed */ | ||
297 | |||
298 | /* r.width -= w_1; */ | ||
299 | /* r.left = current.left; */ | ||
300 | |||
301 | if (w_2 > 0) | ||
302 | /* .----.cur (a) | ||
303 | * | | | ||
304 | * | .-|--.r (b) .-.r .--.r2 | ||
305 | * | | | | -> | | + | | | ||
306 | * | `-|--' `-' `--' | ||
307 | * `----' | ||
308 | */ | ||
309 | rect_list_append_xywh(dirty, current.right, r.top, w_2, | ||
310 | r.height); /* not necessary to keep this, r (b) will be destroyed */ | ||
311 | |||
312 | /* r.width -= w_2; */ | ||
313 | } | ||
314 | |||
315 | static inline void _calc_intra_outer_rect_area(const rect_t a, const rect_t b, | ||
316 | rect_t *intra, rect_t *outer) | ||
317 | { | ||
318 | int min_left, max_left, min_right, max_right; | ||
319 | int min_top, max_top, min_bottom, max_bottom; | ||
320 | |||
321 | if (a.left < b.left) | ||
322 | { | ||
323 | max_left = b.left; | ||
324 | min_left = a.left; | ||
325 | } | ||
326 | else | ||
327 | { | ||
328 | max_left = a.left; | ||
329 | min_left = b.left; | ||
330 | } | ||
331 | |||
332 | if (a.right < b.right) | ||
333 | { | ||
334 | min_right = a.right; | ||
335 | max_right = b.right; | ||
336 | } | ||
337 | else | ||
338 | { | ||
339 | min_right = b.right; | ||
340 | max_right = a.right; | ||
341 | } | ||
342 | |||
343 | intra->left = max_left; | ||
344 | intra->right = min_right; | ||
345 | intra->width = min_right - max_left; | ||
346 | |||
347 | outer->left = min_left; | ||
348 | outer->right = max_right; | ||
349 | outer->width = max_right - min_left; | ||
350 | |||
351 | if (a.top < b.top) | ||
352 | { | ||
353 | max_top = b.top; | ||
354 | min_top = a.top; | ||
355 | } | ||
356 | else | ||
357 | { | ||
358 | max_top = a.top; | ||
359 | min_top = b.top; | ||
360 | } | ||
361 | |||
362 | if (a.bottom < b.bottom) | ||
363 | { | ||
364 | min_bottom = a.bottom; | ||
365 | max_bottom = b.bottom; | ||
366 | } | ||
367 | else | ||
368 | { | ||
369 | min_bottom = b.bottom; | ||
370 | max_bottom = a.bottom; | ||
371 | } | ||
372 | |||
373 | intra->top = max_top; | ||
374 | intra->bottom = min_bottom; | ||
375 | intra->height = min_bottom - max_top; | ||
376 | if ((intra->width > 0) && (intra->height > 0)) | ||
377 | intra->area = intra->width * intra->height; | ||
378 | else | ||
379 | intra->area = 0; | ||
380 | |||
381 | outer->top = min_top; | ||
382 | outer->bottom = max_bottom; | ||
383 | outer->height = max_bottom - min_top; | ||
384 | outer->area = outer->width * outer->height; | ||
385 | } | ||
386 | |||
387 | enum | ||
388 | { | ||
389 | SPLIT_FUZZY_ACTION_NONE, | ||
390 | SPLIT_FUZZY_ACTION_SPLIT, | ||
391 | SPLIT_FUZZY_ACTION_MERGE | ||
392 | }; | ||
393 | |||
394 | static inline int _split_fuzzy(list_t *dirty, const rect_t a, rect_t *b) | ||
395 | { | ||
396 | int h_1, h_2, w_1, w_2, action; | ||
397 | |||
398 | h_1 = a.top - b->top; | ||
399 | h_2 = b->bottom - a.bottom; | ||
400 | w_1 = a.left - b->left; | ||
401 | w_2 = b->right - a.right; | ||
402 | |||
403 | action = SPLIT_FUZZY_ACTION_NONE; | ||
404 | |||
405 | if (h_1 > 0) | ||
406 | { | ||
407 | /* .--.r (b) .---.r2 | ||
408 | * | | | | | ||
409 | * .-------.cur (a) .---.r '---' | ||
410 | * | | | | -> | | + | ||
411 | * | `--' | `---' | ||
412 | * `-------' | ||
413 | */ | ||
414 | rect_list_append_xywh(dirty, b->left, b->top, b->width, h_1); | ||
415 | b->height -= h_1; | ||
416 | b->top = a.top; | ||
417 | action = SPLIT_FUZZY_ACTION_SPLIT; | ||
418 | } | ||
419 | |||
420 | if (h_2 > 0) | ||
421 | { | ||
422 | /* .-------.cur (a) | ||
423 | * | .---. | .---.r | ||
424 | * | | | | -> | | | ||
425 | * `-------' `---' + .---.r2 | ||
426 | * | | | | | ||
427 | * `---'r (b) `---' | ||
428 | */ | ||
429 | rect_list_append_xywh(dirty, b->left, a.bottom, b->width, h_2); | ||
430 | b->height -= h_2; | ||
431 | action = SPLIT_FUZZY_ACTION_SPLIT; | ||
432 | } | ||
433 | |||
434 | if (((w_1 > 0) || (w_2 > 0)) && (a.height == b->height)) | ||
435 | return SPLIT_FUZZY_ACTION_MERGE; | ||
436 | |||
437 | if (w_1 > 0) | ||
438 | { | ||
439 | /* (b) r .----.cur (a) | ||
440 | * .--|-. | .--.r2 .-.r | ||
441 | * | | | | -> | | + | | | ||
442 | * `--|-' | `--' `-' | ||
443 | * `----' | ||
444 | */ | ||
445 | rect_list_append_xywh(dirty, b->left, b->top, w_1, b->height); | ||
446 | /* not necessary to keep these, r (b) will be destroyed */ | ||
447 | /* b->width -= w_1; */ | ||
448 | /* b->left = a.left; */ | ||
449 | action = SPLIT_FUZZY_ACTION_SPLIT; | ||
450 | } | ||
451 | |||
452 | if (w_2 > 0) | ||
453 | { | ||
454 | /* .----.cur (a) | ||
455 | * | | | ||
456 | * | .-|--.r (b) .-.r .--.r2 | ||
457 | * | | | | -> | | + | | | ||
458 | * | `-|--' `-' `--' | ||
459 | * `----' | ||
460 | */ | ||
461 | rect_list_append_xywh(dirty, a.right, b->top, w_2, b->height); | ||
462 | /* not necessary to keep these, r (b) will be destroyed */ | ||
463 | /* b->width -= w_2; */ | ||
464 | action = SPLIT_FUZZY_ACTION_SPLIT; | ||
465 | } | ||
466 | |||
467 | return action; | ||
468 | } | ||
469 | |||
470 | #if 0 | ||
471 | static void rect_list_node_pool_set_max(int max) | ||
472 | { | ||
473 | int diff; | ||
474 | |||
475 | diff = list_node_pool.len - max; | ||
476 | for (; diff > 0 && list_node_pool.node != NULL; diff--) | ||
477 | { | ||
478 | list_node_t *node; | ||
479 | |||
480 | node = list_node_pool.node; | ||
481 | list_node_pool.node = node->next; | ||
482 | list_node_pool.len--; | ||
483 | |||
484 | free(node); | ||
485 | } | ||
486 | |||
487 | list_node_pool.max = max; | ||
488 | } | ||
489 | #endif | ||
490 | |||
491 | static void rect_list_node_pool_flush(void) | ||
492 | { | ||
493 | while (list_node_pool.node) | ||
494 | { | ||
495 | list_node_t *node; | ||
496 | |||
497 | node = list_node_pool.node; | ||
498 | list_node_pool.node = node->next; | ||
499 | list_node_pool.len--; | ||
500 | |||
501 | free(node); | ||
502 | } | ||
503 | } | ||
504 | |||
505 | |||
506 | |||
507 | static inline void rect_list_node_pool_put(list_node_t *node) | ||
508 | { | ||
509 | if (list_node_pool.len < list_node_pool.max) | ||
510 | { | ||
511 | node->next = list_node_pool.node; | ||
512 | list_node_pool.node = node; | ||
513 | list_node_pool.len++; | ||
514 | } | ||
515 | else | ||
516 | free(node); | ||
517 | } | ||
518 | |||
519 | #if 0 | ||
520 | static void rect_print(const rect_t r) | ||
521 | { | ||
522 | printf("<rect(%d, %d, %d, %d)>", r.left, r.top, r.width, r.height); | ||
523 | } | ||
524 | |||
525 | static void rect_list_print(const list_t rects) | ||
526 | { | ||
527 | list_node_t *node; | ||
528 | int len; | ||
529 | |||
530 | len = 0; | ||
531 | for (node = rects.head; node != NULL; node = node->next) | ||
532 | len++; | ||
533 | |||
534 | printf("["); | ||
535 | for (node = rects.head; node != NULL; node = node->next) | ||
536 | { | ||
537 | rect_print(((rect_node_t *)node)->rect); | ||
538 | if (node->next) | ||
539 | { | ||
540 | putchar(','); | ||
541 | if (len < 4) | ||
542 | putchar(' '); | ||
543 | else | ||
544 | { | ||
545 | putchar('\n'); | ||
546 | putchar(' '); | ||
547 | } | ||
548 | } | ||
549 | } | ||
550 | printf("]\n"); | ||
551 | } | ||
552 | #endif | ||
553 | |||
554 | static inline list_node_t * | ||
555 | rect_list_unlink_next(list_t *rects, list_node_t *parent_node) | ||
556 | { | ||
557 | list_node_t *node; | ||
558 | |||
559 | if (parent_node) | ||
560 | { | ||
561 | node = parent_node->next; | ||
562 | parent_node->next = node->next; | ||
563 | } | ||
564 | else | ||
565 | { | ||
566 | node = rects->head; | ||
567 | rects->head = node->next; | ||
568 | } | ||
569 | |||
570 | if (rects->tail == node) | ||
571 | rects->tail = parent_node; | ||
572 | |||
573 | *node = list_node_zeroed; | ||
574 | return node; | ||
575 | } | ||
576 | |||
577 | static inline void rect_list_del_next(list_t *rects, list_node_t *parent_node) | ||
578 | { | ||
579 | list_node_t *node; | ||
580 | |||
581 | node = rect_list_unlink_next(rects, parent_node); | ||
582 | rect_list_node_pool_put(node); | ||
583 | } | ||
584 | |||
585 | static void rect_list_clear(list_t *rects) | ||
586 | { | ||
587 | list_node_t *node; | ||
588 | |||
589 | node = rects->head; | ||
590 | while (node) | ||
591 | { | ||
592 | list_node_t *aux; | ||
593 | |||
594 | aux = node->next; | ||
595 | rect_list_node_pool_put(node); | ||
596 | node = aux; | ||
597 | } | ||
598 | *rects = list_zeroed; | ||
599 | } | ||
600 | |||
601 | static void rect_list_del_split_strict(list_t *rects, const rect_t del_r) | ||
602 | { | ||
603 | list_t modified = list_zeroed; | ||
604 | list_node_t *cur_node, *prev_node; | ||
605 | |||
606 | prev_node = NULL; | ||
607 | cur_node = rects->head; | ||
608 | while (cur_node) | ||
609 | { | ||
610 | int intra_width, intra_height; | ||
611 | rect_t current; | ||
612 | |||
613 | current = ((rect_node_t *)cur_node)->rect; | ||
614 | |||
615 | _calc_intra_rect_area(del_r, current, &intra_width, | ||
616 | &intra_height); | ||
617 | if ((intra_width <= 0) || (intra_height <= 0)) | ||
618 | { | ||
619 | /* .---.current .---.del_r | ||
620 | * | | | | | ||
621 | * `---+---.del_r `---+---.current | ||
622 | * | | | | | ||
623 | * `---' `---' | ||
624 | * no intersection, nothing to do | ||
625 | */ | ||
626 | prev_node = cur_node; | ||
627 | cur_node = cur_node->next; | ||
628 | } | ||
629 | else if ((intra_width == current.width) && (intra_height | ||
630 | == current.height)) | ||
631 | { | ||
632 | /* .-------.del_r | ||
633 | * | .---. | | ||
634 | * | | | | | ||
635 | * | `---'current | ||
636 | * `-------' | ||
637 | * current is contained, remove from rects | ||
638 | */ | ||
639 | cur_node = cur_node->next; | ||
640 | rect_list_del_next(rects, prev_node); | ||
641 | } | ||
642 | else | ||
643 | { | ||
644 | _split_strict(&modified, del_r, current); | ||
645 | cur_node = cur_node->next; | ||
646 | rect_list_del_next(rects, prev_node); | ||
647 | } | ||
648 | } | ||
649 | |||
650 | rect_list_concat(rects, &modified); | ||
651 | } | ||
652 | |||
653 | #if 0 | ||
654 | static void rect_list_add_split_strict(list_t *rects, list_node_t *node) | ||
655 | { | ||
656 | list_t dirty = list_zeroed; | ||
657 | list_t new_dirty = list_zeroed; | ||
658 | list_node_t *cur_node; | ||
659 | |||
660 | if (!rects->head) | ||
661 | { | ||
662 | rect_list_append_node(rects, node); | ||
663 | return; | ||
664 | } | ||
665 | |||
666 | rect_list_append_node(&dirty, node); | ||
667 | |||
668 | cur_node = rects->head; | ||
669 | while (dirty.head) | ||
670 | { | ||
671 | rect_t current; | ||
672 | |||
673 | if (!cur_node) | ||
674 | { | ||
675 | rect_list_concat(rects, &dirty); | ||
676 | break; | ||
677 | } | ||
678 | |||
679 | current = ((rect_node_t *)cur_node)->rect; | ||
680 | |||
681 | while (dirty.head) | ||
682 | { | ||
683 | int intra_width, intra_height; | ||
684 | rect_t r; | ||
685 | |||
686 | r = ((rect_node_t *)dirty.head)->rect; | ||
687 | _calc_intra_rect_area(r, current, &intra_width, | ||
688 | &intra_height); | ||
689 | if ((intra_width == r.width) && (intra_height | ||
690 | == r.height)) | ||
691 | /* .-------.cur | ||
692 | * | .---.r| | ||
693 | * | | | | | ||
694 | * | `---' | | ||
695 | * `-------' | ||
696 | */ | ||
697 | rect_list_del_next(&dirty, NULL); | ||
698 | else if ((intra_width <= 0) || (intra_height <= 0)) | ||
699 | { | ||
700 | /* .---.cur .---.r | ||
701 | * | | | | | ||
702 | * `---+---.r `---+---.cur | ||
703 | * | | | | | ||
704 | * `---' `---' | ||
705 | */ | ||
706 | list_node_t *tmp; | ||
707 | tmp = rect_list_unlink_next(&dirty, NULL); | ||
708 | rect_list_append_node(&new_dirty, tmp); | ||
709 | } | ||
710 | else | ||
711 | { | ||
712 | _split_strict(&new_dirty, current, r); | ||
713 | rect_list_del_next(&dirty, NULL); | ||
714 | } | ||
715 | } | ||
716 | dirty = new_dirty; | ||
717 | new_dirty = list_zeroed; | ||
718 | |||
719 | cur_node = cur_node->next; | ||
720 | } | ||
721 | } | ||
722 | #endif | ||
723 | |||
724 | static list_node_t * | ||
725 | rect_list_add_split_fuzzy(list_t *rects, list_node_t *node, int accepted_error) | ||
726 | { | ||
727 | list_t dirty = list_zeroed; | ||
728 | list_node_t *old_last; | ||
729 | |||
730 | old_last = rects->tail; | ||
731 | |||
732 | if (!rects->head) | ||
733 | { | ||
734 | rect_list_append_node(rects, node); | ||
735 | return old_last; | ||
736 | } | ||
737 | |||
738 | rect_list_append_node(&dirty, node); | ||
739 | while (dirty.head) | ||
740 | { | ||
741 | list_node_t *d_node, *cur_node, *prev_cur_node; | ||
742 | int keep_dirty; | ||
743 | rect_t r; | ||
744 | |||
745 | d_node = rect_list_unlink_next(&dirty, NULL); | ||
746 | r = ((rect_node_t *)d_node)->rect; | ||
747 | |||
748 | prev_cur_node = NULL; | ||
749 | cur_node = rects->head; | ||
750 | keep_dirty = 1; | ||
751 | while (cur_node) | ||
752 | { | ||
753 | int area, action; | ||
754 | rect_t current, intra, outer; | ||
755 | |||
756 | current = ((rect_node_t *)cur_node)->rect; | ||
757 | |||
758 | _calc_intra_outer_rect_area(r, current, &intra, &outer); | ||
759 | area = current.area + r.area - intra.area; | ||
760 | |||
761 | if ((intra.width == r.width) && (intra.height | ||
762 | == r.height)) | ||
763 | { | ||
764 | /* .-------.cur | ||
765 | * | .---.r| | ||
766 | * | | | | | ||
767 | * | `---' | | ||
768 | * `-------' | ||
769 | */ | ||
770 | keep_dirty = 0; | ||
771 | break; | ||
772 | } | ||
773 | else if ((intra.width == current.width) | ||
774 | && (intra.height == current.height)) | ||
775 | { | ||
776 | /* .-------.r | ||
777 | * | .---.cur | ||
778 | * | | | | | ||
779 | * | `---' | | ||
780 | * `-------' | ||
781 | */ | ||
782 | if (old_last == cur_node) | ||
783 | old_last = prev_cur_node; | ||
784 | |||
785 | cur_node = cur_node->next; | ||
786 | rect_list_del_next(rects, prev_cur_node); | ||
787 | } | ||
788 | else if ((outer.area - area) <= accepted_error) | ||
789 | { | ||
790 | /* .-----------. bounding box (outer) | ||
791 | * |.---. .---.| | ||
792 | * ||cur| |r || | ||
793 | * || | | || | ||
794 | * |`---' `---'| | ||
795 | * `-----------' | ||
796 | * merge them, remove both and add merged | ||
797 | */ | ||
798 | rect_node_t *n; | ||
799 | |||
800 | if (old_last == cur_node) | ||
801 | old_last = prev_cur_node; | ||
802 | |||
803 | n = (rect_node_t *)rect_list_unlink_next( | ||
804 | rects, prev_cur_node); | ||
805 | n->rect = outer; | ||
806 | rect_list_append_node(&dirty, (list_node_t *)n); | ||
807 | |||
808 | keep_dirty = 0; | ||
809 | break; | ||
810 | } | ||
811 | else if (intra.area <= accepted_error) | ||
812 | { | ||
813 | /* .---.cur .---.r | ||
814 | * | | | | | ||
815 | * `---+---.r `---+---.cur | ||
816 | * | | | | | ||
817 | * `---' `---' | ||
818 | * no split, no merge | ||
819 | */ | ||
820 | prev_cur_node = cur_node; | ||
821 | cur_node = cur_node->next; | ||
822 | } | ||
823 | else | ||
824 | { | ||
825 | /* split is required */ | ||
826 | action = _split_fuzzy(&dirty, current, &r); | ||
827 | if (action == SPLIT_FUZZY_ACTION_MERGE) | ||
828 | { | ||
829 | /* horizontal merge is possible: remove both, add merged */ | ||
830 | rect_node_t *n; | ||
831 | |||
832 | if (old_last == cur_node) | ||
833 | old_last = prev_cur_node; | ||
834 | |||
835 | n | ||
836 | = (rect_node_t *)rect_list_unlink_next( | ||
837 | rects, | ||
838 | prev_cur_node); | ||
839 | |||
840 | n->rect.left = outer.left; | ||
841 | n->rect.width = outer.width; | ||
842 | n->rect.right = outer.right; | ||
843 | n->rect.area = outer.width * r.height; | ||
844 | rect_list_append_node(&dirty, | ||
845 | (list_node_t *)n); | ||
846 | } | ||
847 | else if (action == SPLIT_FUZZY_ACTION_NONE) | ||
848 | { | ||
849 | /* | ||
850 | * this rect check was totally useless, | ||
851 | * should never happen | ||
852 | */ | ||
853 | /* prev_cur_node = cur_node; */ | ||
854 | /* cur_node = cur_node->next; */ | ||
855 | printf("Should not get here!\n"); | ||
856 | abort(); | ||
857 | } | ||
858 | |||
859 | keep_dirty = 0; | ||
860 | break; | ||
861 | } | ||
862 | } | ||
863 | if (EINA_UNLIKELY(keep_dirty)) | ||
864 | rect_list_append_node(rects, d_node); | ||
865 | else | ||
866 | rect_list_node_pool_put(d_node); | ||
867 | } | ||
868 | |||
869 | return old_last; | ||
870 | } | ||
871 | |||
872 | static inline void _calc_outer_rect_area(const rect_t a, const rect_t b, | ||
873 | rect_t *outer) | ||
874 | { | ||
875 | int min_left, max_right; | ||
876 | int min_top, max_bottom; | ||
877 | |||
878 | if (a.left < b.left) | ||
879 | min_left = a.left; | ||
880 | else | ||
881 | min_left = b.left; | ||
882 | |||
883 | if (a.right < b.right) | ||
884 | max_right = b.right; | ||
885 | else | ||
886 | max_right = a.right; | ||
887 | |||
888 | outer->left = min_left; | ||
889 | outer->right = max_right; | ||
890 | outer->width = max_right - min_left; | ||
891 | |||
892 | if (a.top < b.top) | ||
893 | min_top = a.top; | ||
894 | else | ||
895 | min_top = b.top; | ||
896 | |||
897 | if (a.bottom < b.bottom) | ||
898 | max_bottom = b.bottom; | ||
899 | else | ||
900 | max_bottom = a.bottom; | ||
901 | |||
902 | outer->top = min_top; | ||
903 | outer->bottom = max_bottom; | ||
904 | outer->height = max_bottom - min_top; | ||
905 | |||
906 | outer->area = outer->width * outer->height; | ||
907 | } | ||
908 | |||
909 | static void rect_list_merge_rects(list_t *rects, | ||
910 | list_t *to_merge, | ||
911 | int accepted_error) | ||
912 | { | ||
913 | while (to_merge->head) | ||
914 | { | ||
915 | list_node_t *node, *parent_node; | ||
916 | rect_t r1; | ||
917 | int merged; | ||
918 | |||
919 | r1 = ((rect_node_t *)to_merge->head)->rect; | ||
920 | |||
921 | merged = 0; | ||
922 | parent_node = NULL; | ||
923 | node = rects->head; | ||
924 | while (node) | ||
925 | { | ||
926 | rect_t r2, outer; | ||
927 | int area; | ||
928 | |||
929 | r2 = ((rect_node_t *)node)->rect; | ||
930 | |||
931 | _calc_outer_rect_area(r1, r2, &outer); | ||
932 | area = r1.area + r2.area; /* intra area is taken as 0 */ | ||
933 | if (outer.area - area <= accepted_error) | ||
934 | { | ||
935 | /* | ||
936 | * remove both r1 and r2, create r3 | ||
937 | * actually r3 uses r2 instance, saves memory | ||
938 | */ | ||
939 | rect_node_t *n; | ||
940 | |||
941 | n = (rect_node_t *)rect_list_unlink_next( | ||
942 | rects, parent_node); | ||
943 | n->rect = outer; | ||
944 | rect_list_append_node(to_merge, | ||
945 | (list_node_t *)n); | ||
946 | merged = 1; | ||
947 | break; | ||
948 | } | ||
949 | |||
950 | parent_node = node; | ||
951 | node = node->next; | ||
952 | } | ||
953 | |||
954 | if (!merged) | ||
955 | { | ||
956 | list_node_t *n; | ||
957 | n = rect_list_unlink_next(to_merge, NULL); | ||
958 | rect_list_append_node(rects, n); | ||
959 | } | ||
960 | else | ||
961 | rect_list_del_next(to_merge, NULL); | ||
962 | } | ||
963 | } | ||
964 | |||
965 | static void rect_list_add_split_fuzzy_and_merge(list_t *rects, | ||
966 | list_node_t *node, | ||
967 | int split_accepted_error, | ||
968 | int merge_accepted_error) | ||
969 | { | ||
970 | list_node_t *n; | ||
971 | |||
972 | n = rect_list_add_split_fuzzy(rects, node, split_accepted_error); | ||
973 | if (n && n->next) | ||
974 | { | ||
975 | list_t to_merge; | ||
976 | |||
977 | /* split list into 2 segments, already merged and to merge */ | ||
978 | to_merge.head = n->next; | ||
979 | to_merge.tail = rects->tail; | ||
980 | rects->tail = n; | ||
981 | n->next = NULL; | ||
982 | |||
983 | rect_list_merge_rects(rects, &to_merge, merge_accepted_error); | ||
984 | } | ||
985 | } | ||
986 | |||
987 | static inline void _splitter_new(Eina_Tiler *t) | ||
988 | { | ||
989 | t->splitter.rects = list_zeroed; | ||
990 | t->splitter.need_merge = EINA_FALSE; | ||
991 | } | ||
992 | |||
993 | static inline void _splitter_del(Eina_Tiler *t) | ||
994 | { | ||
995 | rect_list_clear(&t->splitter.rects); | ||
996 | rect_list_node_pool_flush(); | ||
997 | } | ||
998 | |||
999 | static inline void _splitter_tile_size_set(Eina_Tiler *t, | ||
1000 | int w __UNUSED__, | ||
1001 | int h __UNUSED__) | ||
1002 | { | ||
1003 | /* TODO are w and h used for something? */ | ||
1004 | t->splitter.rects = list_zeroed; | ||
1005 | } | ||
1006 | |||
1007 | static inline Eina_Bool _splitter_rect_add(Eina_Tiler *t, Eina_Rectangle *rect) | ||
1008 | { | ||
1009 | rect_node_t *rn; | ||
1010 | |||
1011 | //printf("ACCOUNTING[1]: add_redraw: %4d,%4d %3dx%3d\n", x, y, w, h); | ||
1012 | rect->x >>= 1; | ||
1013 | rect->y >>= 1; | ||
1014 | rect->w += 2; | ||
1015 | rect->w >>= 1; | ||
1016 | rect->h += 2; | ||
1017 | rect->h >>= 1; | ||
1018 | |||
1019 | rn = (rect_node_t *)rect_list_node_pool_get(); | ||
1020 | rn->_lst = list_node_zeroed; | ||
1021 | rect_init(&rn->rect, rect->x, rect->y, rect->w, rect->h); | ||
1022 | //printf("ACCOUNTING[2]: add_redraw: %4d,%4d %3dx%3d\n", x, y, w, h); | ||
1023 | //testing on my core2 duo desktop - fuzz of 32 or 48 is best. | ||
1024 | #define FUZZ 32 | ||
1025 | rect_list_add_split_fuzzy_and_merge(&t->splitter.rects, | ||
1026 | (list_node_t *)rn, | ||
1027 | FUZZ * FUZZ, | ||
1028 | FUZZ * FUZZ); | ||
1029 | return EINA_TRUE; | ||
1030 | } | ||
1031 | |||
1032 | static inline void _splitter_rect_del(Eina_Tiler *t, Eina_Rectangle *rect) | ||
1033 | { | ||
1034 | rect_t r; | ||
1035 | |||
1036 | if (!t->splitter.rects.head) | ||
1037 | return; | ||
1038 | |||
1039 | rect->x += 1; | ||
1040 | rect->y += 1; | ||
1041 | rect->x >>= 1; | ||
1042 | rect->y >>= 1; | ||
1043 | rect->w -= 1; | ||
1044 | rect->w >>= 1; | ||
1045 | rect->h -= 1; | ||
1046 | rect->h >>= 1; | ||
1047 | |||
1048 | if ((rect->w <= 0) || (rect->h <= 0)) | ||
1049 | return; | ||
1050 | |||
1051 | rect_init(&r, rect->x, rect->y, rect->w, rect->h); | ||
1052 | //fprintf(stderr, "ACCOUNTING: del_redraw: %4d,%4d %3dx%3d\n", x, y, w, h); | ||
1053 | |||
1054 | rect_list_del_split_strict(&t->splitter.rects, r); | ||
1055 | t->splitter.need_merge = EINA_TRUE; | ||
1056 | return; | ||
1057 | } | ||
1058 | |||
1059 | static inline void _splitter_clear(Eina_Tiler *t) | ||
1060 | { | ||
1061 | rect_list_clear(&t->splitter.rects); | ||
1062 | t->splitter.need_merge = EINA_FALSE; | ||
1063 | } | ||
1064 | /* end of splitter algorithm */ | ||
1065 | |||
1066 | static Eina_Bool _iterator_next(Eina_Iterator_Tiler *it, void **data) | ||
1067 | { | ||
1068 | list_node_t *n; | ||
1069 | |||
1070 | for (n = it->curr; n; n = n->next) | ||
1071 | { | ||
1072 | rect_t cur; | ||
1073 | |||
1074 | cur = ((rect_node_t *)n)->rect; | ||
1075 | |||
1076 | it->r.x = cur.left << 1; | ||
1077 | it->r.y = cur.top << 1; | ||
1078 | it->r.w = cur.width << 1; | ||
1079 | it->r.h = cur.height << 1; | ||
1080 | |||
1081 | if (eina_rectangle_intersection(&it->r, &it->tiler->area) == EINA_FALSE) | ||
1082 | continue; | ||
1083 | |||
1084 | if ((it->r.w <= 0) || (it->r.h <= 0)) | ||
1085 | continue; | ||
1086 | |||
1087 | it->curr = n->next; | ||
1088 | *(Eina_Rectangle **)data = &it->r; | ||
1089 | return EINA_TRUE; | ||
1090 | } | ||
1091 | return EINA_FALSE; | ||
1092 | } | ||
1093 | |||
1094 | static void *_iterator_get_container(Eina_Iterator_Tiler *it) | ||
1095 | { | ||
1096 | EINA_MAGIC_CHECK_TILER_ITERATOR(it, NULL); | ||
1097 | return (void *)it->tiler; | ||
1098 | } | ||
1099 | |||
1100 | static void _iterator_free(Eina_Iterator_Tiler *it) | ||
1101 | { | ||
1102 | EINA_MAGIC_CHECK_TILER_ITERATOR(it); | ||
1103 | free(it); | ||
1104 | } | ||
1105 | |||
1106 | /*============================================================================* | ||
1107 | * Global * | ||
1108 | *============================================================================*/ | ||
1109 | |||
1110 | /*============================================================================* | ||
1111 | * API * | ||
1112 | *============================================================================*/ | ||
1113 | |||
1114 | EAPI Eina_Tiler *eina_tiler_new(int w, int h) | ||
1115 | { | ||
1116 | Eina_Tiler *t; | ||
1117 | |||
1118 | t = calloc(1, sizeof(Eina_Tiler)); | ||
1119 | t->area.w = w; | ||
1120 | t->area.h = h; | ||
1121 | t->tile.w = w; | ||
1122 | t->tile.h = h; | ||
1123 | EINA_MAGIC_SET(t, EINA_MAGIC_TILER); | ||
1124 | _splitter_new(t); | ||
1125 | return t; | ||
1126 | } | ||
1127 | |||
1128 | EAPI void eina_tiler_free(Eina_Tiler *t) | ||
1129 | { | ||
1130 | EINA_MAGIC_CHECK_TILER(t); | ||
1131 | _splitter_del(t); | ||
1132 | free(t); | ||
1133 | } | ||
1134 | |||
1135 | EAPI void eina_tiler_tile_size_set(Eina_Tiler *t, int w, int h) | ||
1136 | { | ||
1137 | EINA_MAGIC_CHECK_TILER(t); | ||
1138 | if ((w <= 0) || (h <= 0)) | ||
1139 | return; | ||
1140 | |||
1141 | t->tile.w = w; | ||
1142 | t->tile.h = h; | ||
1143 | _splitter_tile_size_set(t, w, h); | ||
1144 | } | ||
1145 | |||
1146 | EAPI Eina_Bool eina_tiler_rect_add(Eina_Tiler *t, const Eina_Rectangle *r) | ||
1147 | { | ||
1148 | Eina_Rectangle tmp; | ||
1149 | |||
1150 | EINA_MAGIC_CHECK_TILER(t, EINA_FALSE); | ||
1151 | if ((r->w <= 0) || (r->h <= 0)) | ||
1152 | return EINA_FALSE; | ||
1153 | |||
1154 | tmp = *r; | ||
1155 | if (eina_rectangle_intersection(&tmp, &t->area) == EINA_FALSE) | ||
1156 | return EINA_FALSE; | ||
1157 | |||
1158 | if ((tmp.w <= 0) || (tmp.h <= 0)) | ||
1159 | return EINA_FALSE; | ||
1160 | |||
1161 | return _splitter_rect_add(t, &tmp); | ||
1162 | } | ||
1163 | |||
1164 | EAPI void eina_tiler_rect_del(Eina_Tiler *t, const Eina_Rectangle *r) | ||
1165 | { | ||
1166 | Eina_Rectangle tmp; | ||
1167 | |||
1168 | EINA_MAGIC_CHECK_TILER(t); | ||
1169 | if ((r->w <= 0) || (r->h <= 0)) | ||
1170 | return; | ||
1171 | |||
1172 | tmp = *r; | ||
1173 | if (eina_rectangle_intersection(&tmp, &t->area) == EINA_FALSE) | ||
1174 | return; | ||
1175 | |||
1176 | if ((tmp.w <= 0) || (tmp.h <= 0)) | ||
1177 | return; | ||
1178 | |||
1179 | _splitter_rect_del(t, &tmp); | ||
1180 | } | ||
1181 | |||
1182 | EAPI void eina_tiler_clear(Eina_Tiler *t) | ||
1183 | { | ||
1184 | EINA_MAGIC_CHECK_TILER(t); | ||
1185 | _splitter_clear(t); | ||
1186 | } | ||
1187 | |||
1188 | |||
1189 | EAPI Eina_Iterator *eina_tiler_iterator_new(const Eina_Tiler *t) | ||
1190 | { | ||
1191 | Eina_Iterator_Tiler *it; | ||
1192 | |||
1193 | EINA_MAGIC_CHECK_TILER(t, NULL); | ||
1194 | |||
1195 | it = calloc(1, sizeof (Eina_Iterator_Tiler)); | ||
1196 | if (!it) | ||
1197 | return NULL; | ||
1198 | |||
1199 | it->tiler = t; | ||
1200 | |||
1201 | if (t->splitter.need_merge == EINA_TRUE) | ||
1202 | { | ||
1203 | list_t to_merge; | ||
1204 | splitter_t *sp; | ||
1205 | |||
1206 | sp = (splitter_t *)&(t->splitter); | ||
1207 | to_merge = t->splitter.rects; | ||
1208 | sp->rects = list_zeroed; | ||
1209 | rect_list_merge_rects(&sp->rects, &to_merge, FUZZ * FUZZ); | ||
1210 | sp->need_merge = 0; | ||
1211 | } | ||
1212 | |||
1213 | it->curr = it->tiler->splitter.rects.head; | ||
1214 | |||
1215 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
1216 | it->iterator.next = FUNC_ITERATOR_NEXT(_iterator_next); | ||
1217 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( | ||
1218 | _iterator_get_container); | ||
1219 | it->iterator.free = FUNC_ITERATOR_FREE(_iterator_free); | ||
1220 | |||
1221 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
1222 | EINA_MAGIC_SET(it, EINA_MAGIC_TILER_ITERATOR); | ||
1223 | |||
1224 | return &it->iterator; | ||
1225 | } | ||
1226 | |||
1227 | struct _Eina_Tile_Grid_Slicer_Iterator | ||
1228 | { | ||
1229 | Eina_Iterator iterator; | ||
1230 | Eina_Tile_Grid_Slicer priv; | ||
1231 | }; | ||
1232 | |||
1233 | typedef struct _Eina_Tile_Grid_Slicer_Iterator Eina_Tile_Grid_Slicer_Iterator; | ||
1234 | |||
1235 | static void | ||
1236 | eina_tile_grid_slicer_iterator_free(Eina_Tile_Grid_Slicer_Iterator *it) | ||
1237 | { | ||
1238 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_NONE); | ||
1239 | free(it); | ||
1240 | } | ||
1241 | |||
1242 | static Eina_Bool | ||
1243 | eina_tile_grid_slicer_iterator_next(Eina_Tile_Grid_Slicer_Iterator *it, | ||
1244 | void **data) | ||
1245 | { | ||
1246 | return eina_tile_grid_slicer_next | ||
1247 | (&it->priv, (const Eina_Tile_Grid_Info **)data); | ||
1248 | } | ||
1249 | |||
1250 | EAPI Eina_Iterator * | ||
1251 | eina_tile_grid_slicer_iterator_new(int x, | ||
1252 | int y, | ||
1253 | int w, | ||
1254 | int h, | ||
1255 | int tile_w, | ||
1256 | int tile_h) | ||
1257 | { | ||
1258 | Eina_Tile_Grid_Slicer_Iterator *it; | ||
1259 | |||
1260 | it = calloc(1, sizeof(*it)); | ||
1261 | if (!it) | ||
1262 | { | ||
1263 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
1264 | return NULL; | ||
1265 | } | ||
1266 | |||
1267 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
1268 | |||
1269 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
1270 | it->iterator.next = FUNC_ITERATOR_NEXT(eina_tile_grid_slicer_iterator_next); | ||
1271 | it->iterator.free = FUNC_ITERATOR_FREE(eina_tile_grid_slicer_iterator_free); | ||
1272 | |||
1273 | eina_tile_grid_slicer_setup(&it->priv, x, y, w, h, tile_w, tile_h); | ||
1274 | |||
1275 | return &it->iterator; | ||
1276 | } | ||
diff --git a/libraries/eina/src/lib/eina_unicode.c b/libraries/eina/src/lib/eina_unicode.c deleted file mode 100644 index 7505906..0000000 --- a/libraries/eina/src/lib/eina_unicode.c +++ /dev/null | |||
@@ -1,450 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2010 Tom Hacohen, | ||
3 | * Brett Nash | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Lesser General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2.1 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This library is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * Lesser General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Lesser General Public | ||
16 | * License along with this library; | ||
17 | * if not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #ifdef HAVE_CONFIG_H | ||
21 | # include "config.h" | ||
22 | #endif | ||
23 | |||
24 | #include "eina_config.h" | ||
25 | #include "eina_private.h" | ||
26 | #include <string.h> | ||
27 | |||
28 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
29 | #include "eina_safety_checks.h" | ||
30 | #include "eina_unicode.h" | ||
31 | |||
32 | /* FIXME: check if sizeof(wchar_t) == sizeof(Eina_Unicode) if so, | ||
33 | * probably better to use the standard functions */ | ||
34 | |||
35 | /* Maybe I'm too tired, but this is the only thing that actually worked. */ | ||
36 | const Eina_Unicode _EINA_UNICODE_EMPTY_STRING[1] = {0}; | ||
37 | EAPI const Eina_Unicode *EINA_UNICODE_EMPTY_STRING = _EINA_UNICODE_EMPTY_STRING; | ||
38 | EAPI int | ||
39 | eina_unicode_strcmp(const Eina_Unicode *a, const Eina_Unicode *b) | ||
40 | { | ||
41 | EINA_SAFETY_ON_NULL_RETURN_VAL(a, -1); | ||
42 | EINA_SAFETY_ON_NULL_RETURN_VAL(b, -1); | ||
43 | |||
44 | for (; *a && *a == *b; a++, b++) | ||
45 | ; | ||
46 | if (*a == *b) | ||
47 | return 0; | ||
48 | else if (*a < *b) | ||
49 | return -1; | ||
50 | else | ||
51 | return 1; | ||
52 | } | ||
53 | |||
54 | EAPI Eina_Unicode * | ||
55 | eina_unicode_strcpy(Eina_Unicode *dest, const Eina_Unicode *source) | ||
56 | { | ||
57 | Eina_Unicode *ret = dest; | ||
58 | |||
59 | EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL); | ||
60 | EINA_SAFETY_ON_NULL_RETURN_VAL(source, NULL); | ||
61 | |||
62 | while (*source) | ||
63 | *dest++ = *source++; | ||
64 | *dest = 0; | ||
65 | return ret; | ||
66 | } | ||
67 | |||
68 | EAPI Eina_Unicode * | ||
69 | eina_unicode_strncpy(Eina_Unicode *dest, const Eina_Unicode *source, size_t n) | ||
70 | { | ||
71 | Eina_Unicode *ret = dest; | ||
72 | |||
73 | EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL); | ||
74 | EINA_SAFETY_ON_NULL_RETURN_VAL(source, NULL); | ||
75 | |||
76 | for ( ; n && *source ; n--) | ||
77 | *dest++ = *source++; | ||
78 | for (; n; n--) | ||
79 | *dest++ = 0; | ||
80 | return ret; | ||
81 | } | ||
82 | |||
83 | EAPI size_t | ||
84 | eina_unicode_strlen(const Eina_Unicode *ustr) | ||
85 | { | ||
86 | const Eina_Unicode *end; | ||
87 | |||
88 | EINA_SAFETY_ON_NULL_RETURN_VAL(ustr, 0); | ||
89 | |||
90 | for (end = ustr; *end; end++) | ||
91 | ; | ||
92 | return end - ustr; | ||
93 | } | ||
94 | |||
95 | EAPI size_t | ||
96 | eina_unicode_strnlen(const Eina_Unicode *ustr, int n) | ||
97 | { | ||
98 | const Eina_Unicode *end; | ||
99 | const Eina_Unicode *last = ustr + n; /* technically not portable ;-) */ | ||
100 | |||
101 | EINA_SAFETY_ON_NULL_RETURN_VAL(ustr, 0); | ||
102 | |||
103 | for (end = ustr; end < last && *end; end++) | ||
104 | ; | ||
105 | return end - ustr; | ||
106 | } | ||
107 | |||
108 | |||
109 | |||
110 | |||
111 | EAPI Eina_Unicode * | ||
112 | eina_unicode_strndup(const Eina_Unicode *text, size_t n) | ||
113 | { | ||
114 | Eina_Unicode *ustr; | ||
115 | |||
116 | EINA_SAFETY_ON_NULL_RETURN_VAL(text, NULL); | ||
117 | |||
118 | ustr = malloc((n + 1) * sizeof(Eina_Unicode)); | ||
119 | memcpy(ustr, text, n * sizeof(Eina_Unicode)); | ||
120 | ustr[n] = 0; | ||
121 | return ustr; | ||
122 | } | ||
123 | |||
124 | EAPI Eina_Unicode * | ||
125 | eina_unicode_strdup(const Eina_Unicode *text) | ||
126 | { | ||
127 | size_t len; | ||
128 | |||
129 | EINA_SAFETY_ON_NULL_RETURN_VAL(text, NULL); | ||
130 | |||
131 | len = eina_unicode_strlen(text); | ||
132 | return eina_unicode_strndup(text, len); | ||
133 | } | ||
134 | |||
135 | EAPI Eina_Unicode * | ||
136 | eina_unicode_strstr(const Eina_Unicode *haystack, const Eina_Unicode *needle) | ||
137 | { | ||
138 | const Eina_Unicode *i, *j; | ||
139 | |||
140 | EINA_SAFETY_ON_NULL_RETURN_VAL(haystack, NULL); | ||
141 | EINA_SAFETY_ON_NULL_RETURN_VAL(needle, NULL); | ||
142 | |||
143 | for (i = haystack; *i; i++) | ||
144 | { | ||
145 | haystack = i; /* set this location as the base position */ | ||
146 | for (j = needle; *j && *i && *j == *i; j++, i++) | ||
147 | ; | ||
148 | |||
149 | if (!*j) /*if we got to the end of j this means we got a full match */ | ||
150 | { | ||
151 | return (Eina_Unicode *)haystack; /* return the new base position */ | ||
152 | } | ||
153 | } | ||
154 | |||
155 | return NULL; | ||
156 | } | ||
157 | |||
158 | EAPI Eina_Unicode * | ||
159 | eina_unicode_escape(const Eina_Unicode *str) | ||
160 | { | ||
161 | Eina_Unicode *s2, *d; | ||
162 | const Eina_Unicode *s; | ||
163 | |||
164 | EINA_SAFETY_ON_NULL_RETURN_VAL(str, NULL); | ||
165 | |||
166 | s2 = malloc((eina_unicode_strlen(str) * 2) + 1); | ||
167 | if (!s2) | ||
168 | return NULL; | ||
169 | |||
170 | for (s = str, d = s2; *s != 0; s++, d++) | ||
171 | { | ||
172 | if ((*s == ' ') || (*s == '\\') || (*s == '\'')) | ||
173 | { | ||
174 | *d = '\\'; | ||
175 | d++; | ||
176 | } | ||
177 | |||
178 | *d = *s; | ||
179 | } | ||
180 | *d = 0; | ||
181 | return s2; | ||
182 | } | ||
183 | |||
184 | /* UTF-8 Handling */ | ||
185 | |||
186 | #define EINA_UNICODE_UTF8_BYTES_PER_CHAR 6 | ||
187 | /* The replacement range that will be used for bad utf8 chars. */ | ||
188 | #define ERROR_REPLACEMENT_BASE 0xDC80 | ||
189 | #define ERROR_REPLACEMENT_END 0xDCFF | ||
190 | #define IS_INVALID_BYTE(x) ((x == 192) || (x == 193) || (x >= 245)) | ||
191 | #define IS_CONTINUATION_BYTE(x) ((x & 0xC0) == 0x80) | ||
192 | |||
193 | EAPI Eina_Unicode | ||
194 | eina_unicode_utf8_get_next(const char *buf, int *iindex) | ||
195 | { | ||
196 | int ind = *iindex; | ||
197 | Eina_Unicode r; | ||
198 | unsigned char d; | ||
199 | |||
200 | EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0); | ||
201 | EINA_SAFETY_ON_NULL_RETURN_VAL(iindex, 0); | ||
202 | |||
203 | /* if this char is the null terminator, exit */ | ||
204 | if ((d = buf[ind++]) == 0) return 0; | ||
205 | |||
206 | if ((d & 0x80) == 0) | ||
207 | { // 1 byte (7bit) - 0xxxxxxx | ||
208 | *iindex = ind; | ||
209 | return d; | ||
210 | } | ||
211 | if ((d & 0xe0) == 0xc0) | ||
212 | { // 2 byte (11bit) - 110xxxxx 10xxxxxx | ||
213 | r = (d & 0x1f) << 6; | ||
214 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
215 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
216 | r |= (d & 0x3f); | ||
217 | if (r <= 0x7F) goto error; | ||
218 | *iindex = ind; | ||
219 | return r; | ||
220 | } | ||
221 | if ((d & 0xf0) == 0xe0) | ||
222 | { // 3 byte (16bit) - 1110xxxx 10xxxxxx 10xxxxxx | ||
223 | r = (d & 0x0f) << 12; | ||
224 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
225 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
226 | r |= (d & 0x3f) << 6; | ||
227 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
228 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
229 | r |= (d & 0x3f); | ||
230 | if (r <= 0x7FF) goto error; | ||
231 | *iindex = ind; | ||
232 | return r; | ||
233 | } | ||
234 | if ((d & 0xf8) == 0xf0) | ||
235 | { // 4 byte (21bit) - 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | ||
236 | r = (d & 0x07) << 18; | ||
237 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
238 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
239 | r |= (d & 0x3f) << 12; | ||
240 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
241 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
242 | r |= (d & 0x3f) << 6; | ||
243 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
244 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
245 | r |= (d & 0x3f); | ||
246 | if (r <= 0xFFFF) goto error; | ||
247 | *iindex = ind; | ||
248 | return r; | ||
249 | } | ||
250 | if ((d & 0xfc) == 0xf8) | ||
251 | { // 5 byte (26bit) - 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx | ||
252 | r = (d & 0x03) << 24; | ||
253 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
254 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
255 | r |= (d & 0x3f) << 18; | ||
256 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
257 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
258 | r |= (d & 0x3f) << 12; | ||
259 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
260 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
261 | r |= (d & 0x3f) << 6; | ||
262 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
263 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
264 | r |= (d & 0x3f); | ||
265 | if (r <= 0x1FFFFF) goto error; | ||
266 | *iindex = ind; | ||
267 | return r; | ||
268 | } | ||
269 | if ((d & 0xfe) == 0xfc) | ||
270 | { // 6 byte (31bit) - 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx | ||
271 | r = (d & 0x01) << 30; | ||
272 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
273 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
274 | r |= (d & 0x3f) << 24; | ||
275 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
276 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
277 | r |= (d & 0x3f) << 18; | ||
278 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
279 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
280 | r |= (d & 0x3f) << 12; | ||
281 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
282 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
283 | r |= (d & 0x3f) << 6; | ||
284 | if (((d = buf[ind++]) == 0) || IS_INVALID_BYTE(d) || | ||
285 | !IS_CONTINUATION_BYTE(d)) goto error; | ||
286 | r |= (d & 0x3f); | ||
287 | if (r <= 0x3FFFFFF) goto error; | ||
288 | *iindex = ind; | ||
289 | return r; | ||
290 | } | ||
291 | |||
292 | /* Gets here where there was an error and we want to replace the char | ||
293 | * we just use the invalid unicode codepoints 8 lower bits represent | ||
294 | * the original char */ | ||
295 | error: | ||
296 | d = buf[*iindex]; | ||
297 | (*iindex)++; | ||
298 | return ERROR_REPLACEMENT_BASE | d; | ||
299 | } | ||
300 | |||
301 | EAPI Eina_Unicode | ||
302 | eina_unicode_utf8_get_prev(const char *buf, int *iindex) | ||
303 | { | ||
304 | int r, ind; | ||
305 | |||
306 | EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0); | ||
307 | EINA_SAFETY_ON_NULL_RETURN_VAL(iindex, 0); | ||
308 | |||
309 | ind = *iindex; | ||
310 | /* First obtain the codepoint at iindex */ | ||
311 | r = eina_unicode_utf8_get_next(buf, &ind); | ||
312 | |||
313 | /* although when ind == 0 there's no previous char, we still want to get | ||
314 | * the current char */ | ||
315 | if (*iindex <= 0) | ||
316 | return r; | ||
317 | |||
318 | /* Next advance iindex to previous codepoint */ | ||
319 | ind = *iindex; | ||
320 | ind--; | ||
321 | while ((ind > 0) && ((buf[ind] & 0xc0) == 0x80)) | ||
322 | ind--; | ||
323 | |||
324 | *iindex = ind; | ||
325 | return r; | ||
326 | } | ||
327 | |||
328 | EAPI int | ||
329 | eina_unicode_utf8_get_len(const char *buf) | ||
330 | { | ||
331 | /* returns the number of utf8 characters (not bytes) in the string */ | ||
332 | int i = 0, len = 0; | ||
333 | |||
334 | EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0); | ||
335 | |||
336 | while (eina_unicode_utf8_get_next(buf, &i)) | ||
337 | len++; | ||
338 | |||
339 | return len; | ||
340 | } | ||
341 | |||
342 | EAPI Eina_Unicode * | ||
343 | eina_unicode_utf8_to_unicode(const char *utf, int *_len) | ||
344 | { | ||
345 | /* FIXME: Should optimize! */ | ||
346 | int len, i; | ||
347 | int ind; | ||
348 | Eina_Unicode *buf, *uind; | ||
349 | |||
350 | EINA_SAFETY_ON_NULL_RETURN_VAL(utf, NULL); | ||
351 | |||
352 | len = eina_unicode_utf8_get_len(utf); | ||
353 | if (_len) | ||
354 | *_len = len; | ||
355 | buf = (Eina_Unicode *) calloc(sizeof(Eina_Unicode), (len + 1)); | ||
356 | if (!buf) return buf; | ||
357 | |||
358 | for (i = 0, ind = 0, uind = buf ; i < len ; i++, uind++) | ||
359 | { | ||
360 | *uind = eina_unicode_utf8_get_next(utf, &ind); | ||
361 | } | ||
362 | |||
363 | return buf; | ||
364 | } | ||
365 | |||
366 | EAPI char * | ||
367 | eina_unicode_unicode_to_utf8(const Eina_Unicode *uni, int *_len) | ||
368 | { | ||
369 | char *buf; | ||
370 | const Eina_Unicode *uind; | ||
371 | char *ind; | ||
372 | int ulen, len; | ||
373 | |||
374 | EINA_SAFETY_ON_NULL_RETURN_VAL(uni, NULL); | ||
375 | |||
376 | ulen = eina_unicode_strlen(uni); | ||
377 | buf = (char *) calloc(ulen + 1, EINA_UNICODE_UTF8_BYTES_PER_CHAR); | ||
378 | |||
379 | len = 0; | ||
380 | for (uind = uni, ind = buf ; *uind ; uind++) | ||
381 | { | ||
382 | if (*uind <= 0x7F) /* 1 byte char */ | ||
383 | { | ||
384 | *ind++ = *uind; | ||
385 | len += 1; | ||
386 | } | ||
387 | else if (*uind <= 0x7FF) /* 2 byte char */ | ||
388 | { | ||
389 | *ind++ = 0xC0 | (unsigned char) (*uind >> 6); | ||
390 | *ind++ = 0x80 | (unsigned char) (*uind & 0x3F); | ||
391 | len += 2; | ||
392 | } | ||
393 | else if (*uind <= 0xFFFF) /* 3 byte char */ | ||
394 | { | ||
395 | /* If it's a special replacement codepoint */ | ||
396 | if (*uind >= ERROR_REPLACEMENT_BASE && | ||
397 | *uind <= ERROR_REPLACEMENT_END) | ||
398 | { | ||
399 | *ind++ = *uind & 0xFF; | ||
400 | len += 1; | ||
401 | } | ||
402 | else | ||
403 | { | ||
404 | *ind++ = 0xE0 | (unsigned char) (*uind >> 12); | ||
405 | *ind++ = 0x80 | (unsigned char) ((*uind >> 6) & 0x3F); | ||
406 | *ind++ = 0x80 | (unsigned char) (*uind & 0x3F); | ||
407 | len += 3; | ||
408 | } | ||
409 | } | ||
410 | else if (*uind <= 0x1FFFFF) /* 4 byte char */ | ||
411 | { | ||
412 | *ind++ = 0xF0 | (unsigned char) ((*uind >> 18) & 0x07); | ||
413 | *ind++ = 0x80 | (unsigned char) ((*uind >> 12) & 0x3F); | ||
414 | *ind++ = 0x80 | (unsigned char) ((*uind >> 6) & 0x3F); | ||
415 | *ind++ = 0x80 | (unsigned char) (*uind & 0x3F); | ||
416 | len += 4; | ||
417 | } | ||
418 | else if (*uind <= 0x3FFFFFF) /* 5 byte char */ | ||
419 | { | ||
420 | *ind++ = 0xF8 | (unsigned char) ((*uind >> 24) & 0x03); | ||
421 | *ind++ = 0x80 | (unsigned char) ((*uind >> 18) & 0x3F); | ||
422 | *ind++ = 0x80 | (unsigned char) ((*uind >> 12) & 0x3F); | ||
423 | *ind++ = 0x80 | (unsigned char) ((*uind >> 6) & 0x3F); | ||
424 | *ind++ = 0x80 | (unsigned char) (*uind & 0x3F); | ||
425 | len += 5; | ||
426 | } | ||
427 | else if (*uind <= 0x7FFFFFFF) /* 6 byte char */ | ||
428 | { | ||
429 | *ind++ = 0xFC | (unsigned char) ((*uind >> 30) & 0x01); | ||
430 | *ind++ = 0x80 | (unsigned char) ((*uind >> 24) & 0x3F); | ||
431 | *ind++ = 0x80 | (unsigned char) ((*uind >> 18) & 0x3F); | ||
432 | *ind++ = 0x80 | (unsigned char) ((*uind >> 12) & 0x3F); | ||
433 | *ind++ = 0x80 | (unsigned char) ((*uind >> 6) & 0x3F); | ||
434 | *ind++ = 0x80 | (unsigned char) (*uind & 0x3F); | ||
435 | len += 6; | ||
436 | } | ||
437 | else /* error */ | ||
438 | { | ||
439 | /* Do something */ | ||
440 | } | ||
441 | } | ||
442 | buf = realloc(buf, len + 1); | ||
443 | buf[len] = '\0'; | ||
444 | if (_len) | ||
445 | *_len = len; | ||
446 | return buf; | ||
447 | } | ||
448 | |||
449 | |||
450 | |||
diff --git a/libraries/eina/src/lib/eina_ustrbuf.c b/libraries/eina/src/lib/eina_ustrbuf.c deleted file mode 100644 index 7c1c2db..0000000 --- a/libraries/eina/src/lib/eina_ustrbuf.c +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include "config.h" | ||
3 | #endif | ||
4 | |||
5 | #include "eina_strbuf_common.h" | ||
6 | #include "eina_unicode.h" | ||
7 | #include "eina_ustrbuf.h" | ||
8 | |||
9 | /*============================================================================* | ||
10 | * Local * | ||
11 | *============================================================================*/ | ||
12 | |||
13 | /** | ||
14 | * @cond LOCAL | ||
15 | */ | ||
16 | |||
17 | #ifdef _STRBUF_DATA_TYPE | ||
18 | # undef _STRBUF_DATA_TYPE | ||
19 | #endif | ||
20 | |||
21 | #ifdef _STRBUF_CSIZE | ||
22 | # undef _STRBUF_CSIZE | ||
23 | #endif | ||
24 | |||
25 | #ifdef _STRBUF_STRUCT_NAME | ||
26 | # undef _STRBUF_STRUCT_NAME | ||
27 | #endif | ||
28 | |||
29 | #ifdef _STRBUF_STRLEN_FUNC | ||
30 | # undef _STRBUF_STRLEN_FUNC | ||
31 | #endif | ||
32 | |||
33 | #ifdef _STRBUF_STRESCAPE_FUNC | ||
34 | # undef _STRBUF_STRESCAPE_FUNC | ||
35 | #endif | ||
36 | |||
37 | #ifdef _STRBUF_MAGIC | ||
38 | # undef _STRBUF_MAGIC | ||
39 | #endif | ||
40 | |||
41 | #ifdef _STRBUF_MAGIC_STR | ||
42 | # undef _STRBUF_MAGIC_STR | ||
43 | #endif | ||
44 | |||
45 | #ifdef _FUNC_EXPAND | ||
46 | # undef _FUNC_EXPAND | ||
47 | #endif | ||
48 | |||
49 | #define _STRBUF_DATA_TYPE Eina_Unicode | ||
50 | #define _STRBUF_CSIZE sizeof(_STRBUF_DATA_TYPE) | ||
51 | #define _STRBUF_STRUCT_NAME Eina_UStrbuf | ||
52 | #define _STRBUF_STRLEN_FUNC(x) eina_unicode_strlen(x) | ||
53 | #define _STRBUF_STRESCAPE_FUNC(x) eina_unicode_escape(x) | ||
54 | #define _STRBUF_MAGIC EINA_MAGIC_USTRBUF | ||
55 | #define _STRBUF_MAGIC_STR __USTRBUF_MAGIC_STR | ||
56 | static const char __USTRBUF_MAGIC_STR[] = "Eina UStrbuf"; | ||
57 | |||
58 | #define _FUNC_EXPAND(y) eina_ustrbuf_ ## y | ||
59 | |||
60 | /** | ||
61 | * @endcond | ||
62 | */ | ||
63 | |||
64 | |||
65 | /*============================================================================* | ||
66 | * Global * | ||
67 | *============================================================================*/ | ||
68 | |||
69 | |||
70 | /*============================================================================* | ||
71 | * API * | ||
72 | *============================================================================*/ | ||
73 | |||
74 | #include "eina_strbuf_template_c.x" | ||
diff --git a/libraries/eina/src/lib/eina_ustringshare.c b/libraries/eina/src/lib/eina_ustringshare.c deleted file mode 100644 index 33be242..0000000 --- a/libraries/eina/src/lib/eina_ustringshare.c +++ /dev/null | |||
@@ -1,189 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2002-2008 Carsten Haitzler, | ||
3 | * Jorge Luis Zapata Muga, | ||
4 | * Cedric Bail, | ||
5 | * Gustavo Sverzut Barbieri | ||
6 | * Tom Hacohen | ||
7 | * | ||
8 | * This library is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU Lesser General Public | ||
10 | * License as published by the Free Software Foundation; either | ||
11 | * version 2.1 of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * This library is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * Lesser General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU Lesser General Public | ||
19 | * License along with this library; | ||
20 | * if not, see <http://www.gnu.org/licenses/>. | ||
21 | |||
22 | */ | ||
23 | /** | ||
24 | * @page tutorial_ustringshare_page UStringshare Tutorial | ||
25 | * | ||
26 | * to be written... | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #ifdef HAVE_CONFIG_H | ||
31 | # include "config.h" | ||
32 | #endif | ||
33 | |||
34 | #include "eina_config.h" | ||
35 | #include "eina_private.h" | ||
36 | #include "eina_unicode.h" | ||
37 | #include "eina_log.h" | ||
38 | #include "eina_share_common.h" | ||
39 | |||
40 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
41 | #include "eina_safety_checks.h" | ||
42 | #include "eina_ustringshare.h" | ||
43 | |||
44 | |||
45 | #ifdef CRITICAL | ||
46 | #undef CRITICAL | ||
47 | #endif | ||
48 | #define CRITICAL(...) EINA_LOG_DOM_CRIT(_eina_share_ustringshare_log_dom, __VA_ARGS__) | ||
49 | |||
50 | #ifdef ERR | ||
51 | #undef ERR | ||
52 | #endif | ||
53 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_share_ustringshare_log_dom, __VA_ARGS__) | ||
54 | |||
55 | #ifdef DBG | ||
56 | #undef DBG | ||
57 | #endif | ||
58 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_share_ustringshare_log_dom, __VA_ARGS__) | ||
59 | |||
60 | static int _eina_share_ustringshare_log_dom = -1; | ||
61 | |||
62 | /* The actual share */ | ||
63 | static Eina_Share *ustringshare_share; | ||
64 | static const char EINA_MAGIC_USTRINGSHARE_NODE_STR[] = "Eina UStringshare Node"; | ||
65 | |||
66 | /*============================================================================* | ||
67 | * Global * | ||
68 | *============================================================================*/ | ||
69 | |||
70 | /** | ||
71 | * @internal | ||
72 | * @brief Initialize the share_common module. | ||
73 | * | ||
74 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
75 | * | ||
76 | * This function sets up the share_common module of Eina. It is called by | ||
77 | * eina_init(). | ||
78 | * | ||
79 | * @see eina_init() | ||
80 | */ | ||
81 | Eina_Bool | ||
82 | eina_ustringshare_init(void) | ||
83 | { | ||
84 | Eina_Bool ret; | ||
85 | |||
86 | if (_eina_share_ustringshare_log_dom < 0) | ||
87 | { | ||
88 | _eina_share_ustringshare_log_dom = eina_log_domain_register | ||
89 | ("eina_ustringshare", EINA_LOG_COLOR_DEFAULT); | ||
90 | |||
91 | if (_eina_share_ustringshare_log_dom < 0) | ||
92 | { | ||
93 | EINA_LOG_ERR("Could not register log domain: eina_ustringshare"); | ||
94 | return EINA_FALSE; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | ret = eina_share_common_init(&ustringshare_share, | ||
99 | EINA_MAGIC_USTRINGSHARE_NODE, | ||
100 | EINA_MAGIC_USTRINGSHARE_NODE_STR); | ||
101 | |||
102 | if (!ret) | ||
103 | { | ||
104 | eina_log_domain_unregister(_eina_share_ustringshare_log_dom); | ||
105 | _eina_share_ustringshare_log_dom = -1; | ||
106 | } | ||
107 | |||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | /** | ||
112 | * @internal | ||
113 | * @brief Shut down the share_common module. | ||
114 | * | ||
115 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
116 | * | ||
117 | * This function shuts down the share_common module set up by | ||
118 | * eina_share_common_init(). It is called by eina_shutdown(). | ||
119 | * | ||
120 | * @see eina_shutdown() | ||
121 | */ | ||
122 | Eina_Bool | ||
123 | eina_ustringshare_shutdown(void) | ||
124 | { | ||
125 | Eina_Bool ret; | ||
126 | ret = eina_share_common_shutdown(&ustringshare_share); | ||
127 | |||
128 | if (_eina_share_ustringshare_log_dom >= 0) | ||
129 | { | ||
130 | eina_log_domain_unregister(_eina_share_ustringshare_log_dom); | ||
131 | _eina_share_ustringshare_log_dom = -1; | ||
132 | } | ||
133 | |||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | /*============================================================================* | ||
138 | * API * | ||
139 | *============================================================================*/ | ||
140 | |||
141 | EAPI void | ||
142 | eina_ustringshare_del(const Eina_Unicode *str) | ||
143 | { | ||
144 | if (!str) | ||
145 | return; | ||
146 | |||
147 | if (!eina_share_common_del(ustringshare_share, (const char *)str)) | ||
148 | CRITICAL("EEEK trying to del non-shared ustringshare \"%s\"", (const char *)str); | ||
149 | } | ||
150 | |||
151 | EAPI const Eina_Unicode * | ||
152 | eina_ustringshare_add_length(const Eina_Unicode *str, unsigned int slen) | ||
153 | { | ||
154 | return (const Eina_Unicode *)eina_share_common_add_length(ustringshare_share, | ||
155 | (const char *)str, | ||
156 | slen * | ||
157 | sizeof( | ||
158 | Eina_Unicode), | ||
159 | sizeof( | ||
160 | Eina_Unicode)); | ||
161 | } | ||
162 | |||
163 | EAPI const Eina_Unicode * | ||
164 | eina_ustringshare_add(const Eina_Unicode *str) | ||
165 | { | ||
166 | int slen = (str) ? (int)eina_unicode_strlen(str) : -1; | ||
167 | return eina_ustringshare_add_length(str, slen); | ||
168 | } | ||
169 | |||
170 | EAPI const Eina_Unicode * | ||
171 | eina_ustringshare_ref(const Eina_Unicode *str) | ||
172 | { | ||
173 | return (const Eina_Unicode *)eina_share_common_ref(ustringshare_share, | ||
174 | (const char *)str); | ||
175 | } | ||
176 | |||
177 | EAPI int | ||
178 | eina_ustringshare_strlen(const Eina_Unicode *str) | ||
179 | { | ||
180 | int len = eina_share_common_length(ustringshare_share, (const char *)str); | ||
181 | len = (len > 0) ? len / (int)sizeof(Eina_Unicode) : -1; | ||
182 | return len; | ||
183 | } | ||
184 | |||
185 | EAPI void | ||
186 | eina_ustringshare_dump(void) | ||
187 | { | ||
188 | eina_share_common_dump(ustringshare_share, NULL, 0); | ||
189 | } | ||
diff --git a/libraries/eina/src/lib/eina_value.c b/libraries/eina/src/lib/eina_value.c deleted file mode 100644 index b8df693..0000000 --- a/libraries/eina/src/lib/eina_value.c +++ /dev/null | |||
@@ -1,5309 +0,0 @@ | |||
1 | /* eina_value.c | ||
2 | |||
3 | Copyright (C) 2001 Christopher Rosendahl <smugg@fatelabs.com> | ||
4 | Nathan Ingersoll <ningerso@d.umn.edu> | ||
5 | |||
6 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
7 | of this software and associated documentation files (the "Software"), to | ||
8 | deal in the Software without restriction, including without limitation the | ||
9 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
10 | sell copies of the Software, and to permit persons to whom the Software is | ||
11 | furnished to do so, subject to the following conditions: | ||
12 | |||
13 | The above copyright notice and this permission notice shall be included in | ||
14 | all copies of the Software and its documentation and acknowledgment shall be | ||
15 | given in the documentation and software packages that this Software was | ||
16 | used. | ||
17 | |||
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
21 | THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
22 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
23 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
24 | |||
25 | */ | ||
26 | |||
27 | #ifdef HAVE_CONFIG_H | ||
28 | # include "config.h" | ||
29 | #endif | ||
30 | |||
31 | #ifdef HAVE_ALLOCA_H | ||
32 | # include <alloca.h> | ||
33 | #elif defined __GNUC__ | ||
34 | # define alloca __builtin_alloca | ||
35 | #elif defined _AIX | ||
36 | # define alloca __alloca | ||
37 | #elif defined _MSC_VER | ||
38 | # include <malloc.h> | ||
39 | # define alloca _alloca | ||
40 | #else | ||
41 | # include <stddef.h> | ||
42 | # ifdef __cplusplus | ||
43 | extern "C" | ||
44 | # endif | ||
45 | void *alloca (size_t); | ||
46 | #endif | ||
47 | |||
48 | #include <stdio.h> /* asprintf() */ | ||
49 | #include <inttypes.h> /* PRId64 and PRIu64 */ | ||
50 | #include <sys/time.h> /* struct timeval */ | ||
51 | |||
52 | #ifdef HAVE_EVIL | ||
53 | # include <Evil.h> | ||
54 | #endif | ||
55 | |||
56 | #include "eina_config.h" | ||
57 | #include "eina_private.h" | ||
58 | #include "eina_error.h" | ||
59 | #include "eina_log.h" | ||
60 | #include "eina_strbuf.h" | ||
61 | #include "eina_mempool.h" | ||
62 | #include "eina_lock.h" | ||
63 | |||
64 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
65 | #include "eina_safety_checks.h" | ||
66 | #include "eina_value.h" | ||
67 | #include "eina_model.h" /* uses eina_value.h */ | ||
68 | |||
69 | /*============================================================================* | ||
70 | * Local * | ||
71 | *============================================================================*/ | ||
72 | |||
73 | /** | ||
74 | * @cond LOCAL | ||
75 | */ | ||
76 | |||
77 | static Eina_Mempool *_eina_value_mp = NULL; | ||
78 | static Eina_Hash *_eina_value_inner_mps = NULL; | ||
79 | static Eina_Lock _eina_value_inner_mps_lock; | ||
80 | static char *_eina_value_mp_choice = NULL; | ||
81 | static int _eina_value_log_dom = -1; | ||
82 | |||
83 | #ifdef ERR | ||
84 | #undef ERR | ||
85 | #endif | ||
86 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_value_log_dom, __VA_ARGS__) | ||
87 | |||
88 | #ifdef DBG | ||
89 | #undef DBG | ||
90 | #endif | ||
91 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_value_log_dom, __VA_ARGS__) | ||
92 | |||
93 | static const unsigned char eina_value_uchar_max = 255U; | ||
94 | static const char eina_value_char_max = 127; | ||
95 | static const char eina_value_char_min = -127 - 1; | ||
96 | |||
97 | static const unsigned short eina_value_ushort_max = 65535U; | ||
98 | static const short eina_value_short_max = 32767; | ||
99 | static const short eina_value_short_min = -32767 - 1; | ||
100 | |||
101 | static const unsigned int eina_value_uint_max = 4294967295U; | ||
102 | static const int eina_value_int_max = 2147483647; | ||
103 | static const int eina_value_int_min = -2147483647 - 1; | ||
104 | |||
105 | static const uint64_t eina_value_uint64_max = 18446744073709551615ULL; | ||
106 | static const int64_t eina_value_int64_max = 9223372036854775807LL; | ||
107 | static const int64_t eina_value_int64_min = -9223372036854775807LL - 1LL; | ||
108 | |||
109 | #if __WORDSIZE == 64 | ||
110 | static const unsigned long eina_value_ulong_max = 18446744073709551615ULL; | ||
111 | static const long eina_value_long_max = 9223372036854775807LL; | ||
112 | static const long eina_value_long_min = -9223372036854775807LL - 1LL; | ||
113 | #else | ||
114 | static const unsigned long eina_value_ulong_max = 4294967295U; | ||
115 | static const long eina_value_long_max = 2147483647; | ||
116 | static const long eina_value_long_min = -2147483647 - 1; | ||
117 | #endif | ||
118 | |||
119 | |||
120 | static Eina_Bool | ||
121 | _eina_value_type_uchar_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
122 | { | ||
123 | unsigned char *tmem = mem; | ||
124 | *tmem = 0; | ||
125 | return EINA_TRUE; | ||
126 | } | ||
127 | |||
128 | static Eina_Bool | ||
129 | _eina_value_type_uchar_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
130 | { | ||
131 | return EINA_TRUE; | ||
132 | } | ||
133 | |||
134 | static Eina_Bool | ||
135 | _eina_value_type_uchar_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
136 | { | ||
137 | const unsigned char *s = src; | ||
138 | unsigned char *d = dst; | ||
139 | *d = *s; | ||
140 | return EINA_TRUE; | ||
141 | } | ||
142 | |||
143 | static int | ||
144 | _eina_value_type_uchar_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
145 | { | ||
146 | const unsigned char *ta = a, *tb = b; | ||
147 | if (*ta < *tb) | ||
148 | return -1; | ||
149 | else if (*ta > *tb) | ||
150 | return 1; | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static Eina_Bool | ||
155 | _eina_value_type_uchar_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
156 | { | ||
157 | const unsigned char v = *(const unsigned char *)type_mem; | ||
158 | |||
159 | eina_error_set(0); | ||
160 | |||
161 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
162 | { | ||
163 | unsigned char other_mem = v; | ||
164 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
165 | } | ||
166 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
167 | { | ||
168 | unsigned short other_mem = v; | ||
169 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
170 | } | ||
171 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
172 | { | ||
173 | unsigned int other_mem = v; | ||
174 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
175 | } | ||
176 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
177 | { | ||
178 | unsigned long other_mem = v; | ||
179 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
180 | } | ||
181 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
182 | { | ||
183 | uint64_t other_mem = v; | ||
184 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
185 | } | ||
186 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
187 | { | ||
188 | char other_mem = v; | ||
189 | if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max)) | ||
190 | return EINA_FALSE; | ||
191 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
192 | } | ||
193 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
194 | { | ||
195 | short other_mem = v; | ||
196 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
197 | } | ||
198 | else if (convert == EINA_VALUE_TYPE_INT) | ||
199 | { | ||
200 | int other_mem = v; | ||
201 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
202 | } | ||
203 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
204 | { | ||
205 | long other_mem = v; | ||
206 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
207 | } | ||
208 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
209 | { | ||
210 | int64_t other_mem = v; | ||
211 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
212 | } | ||
213 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
214 | { | ||
215 | float other_mem = v; | ||
216 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
217 | } | ||
218 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
219 | { | ||
220 | double other_mem = v; | ||
221 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
222 | } | ||
223 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
224 | convert == EINA_VALUE_TYPE_STRING) | ||
225 | { | ||
226 | const char *other_mem; | ||
227 | char buf[64]; | ||
228 | snprintf(buf, sizeof(buf), "%hhu", v); | ||
229 | other_mem = buf; /* required due &buf == buf */ | ||
230 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
231 | } | ||
232 | else | ||
233 | { | ||
234 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
235 | return EINA_FALSE; | ||
236 | } | ||
237 | |||
238 | return EINA_TRUE; | ||
239 | } | ||
240 | |||
241 | static Eina_Bool | ||
242 | _eina_value_type_uchar_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
243 | { | ||
244 | unsigned char *tmem = mem; | ||
245 | *tmem = va_arg(args, unsigned int); /* char is promoted to int for va_arg */ | ||
246 | return EINA_TRUE; | ||
247 | } | ||
248 | |||
249 | static Eina_Bool | ||
250 | _eina_value_type_uchar_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
251 | { | ||
252 | unsigned char *tmem = mem; | ||
253 | const unsigned char *p = ptr; | ||
254 | *tmem = *p; | ||
255 | return EINA_TRUE; | ||
256 | } | ||
257 | |||
258 | static Eina_Bool | ||
259 | _eina_value_type_uchar_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
260 | { | ||
261 | const unsigned char *tmem = mem; | ||
262 | unsigned char *p = ptr; | ||
263 | *p = *tmem; | ||
264 | return EINA_TRUE; | ||
265 | } | ||
266 | |||
267 | static Eina_Bool | ||
268 | _eina_value_type_ushort_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
269 | { | ||
270 | unsigned short *tmem = mem; | ||
271 | *tmem = 0; | ||
272 | return EINA_TRUE; | ||
273 | } | ||
274 | |||
275 | static Eina_Bool | ||
276 | _eina_value_type_ushort_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
277 | { | ||
278 | return EINA_TRUE; | ||
279 | } | ||
280 | |||
281 | static Eina_Bool | ||
282 | _eina_value_type_ushort_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
283 | { | ||
284 | const unsigned short *s = src; | ||
285 | unsigned short *d = dst; | ||
286 | *d = *s; | ||
287 | return EINA_TRUE; | ||
288 | } | ||
289 | |||
290 | static int | ||
291 | _eina_value_type_ushort_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
292 | { | ||
293 | const unsigned short *ta = a, *tb = b; | ||
294 | if (*ta < *tb) | ||
295 | return -1; | ||
296 | else if (*ta > *tb) | ||
297 | return 1; | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static Eina_Bool | ||
302 | _eina_value_type_ushort_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
303 | { | ||
304 | const unsigned short v = *(const unsigned short *)type_mem; | ||
305 | |||
306 | eina_error_set(0); | ||
307 | |||
308 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
309 | { | ||
310 | unsigned char other_mem = v; | ||
311 | if (EINA_UNLIKELY(v > eina_value_uchar_max)) | ||
312 | return EINA_FALSE; | ||
313 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
314 | } | ||
315 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
316 | { | ||
317 | unsigned short other_mem = v; | ||
318 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
319 | } | ||
320 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
321 | { | ||
322 | unsigned int other_mem = v; | ||
323 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
324 | } | ||
325 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
326 | { | ||
327 | unsigned long other_mem = v; | ||
328 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
329 | } | ||
330 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
331 | { | ||
332 | uint64_t other_mem = v; | ||
333 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
334 | } | ||
335 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
336 | { | ||
337 | char other_mem = v; | ||
338 | if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max)) | ||
339 | return EINA_FALSE; | ||
340 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
341 | } | ||
342 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
343 | { | ||
344 | short other_mem = v; | ||
345 | if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max)) | ||
346 | return EINA_FALSE; | ||
347 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
348 | } | ||
349 | else if (convert == EINA_VALUE_TYPE_INT) | ||
350 | { | ||
351 | int other_mem = v; | ||
352 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
353 | } | ||
354 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
355 | { | ||
356 | long other_mem = v; | ||
357 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
358 | } | ||
359 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
360 | { | ||
361 | int64_t other_mem = v; | ||
362 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
363 | } | ||
364 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
365 | { | ||
366 | float other_mem = v; | ||
367 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
368 | } | ||
369 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
370 | { | ||
371 | double other_mem = v; | ||
372 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
373 | } | ||
374 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
375 | convert == EINA_VALUE_TYPE_STRING) | ||
376 | { | ||
377 | const char *other_mem; | ||
378 | char buf[64]; | ||
379 | snprintf(buf, sizeof(buf), "%hu", v); | ||
380 | other_mem = buf; /* required due &buf == buf */ | ||
381 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
382 | } | ||
383 | else | ||
384 | { | ||
385 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
386 | return EINA_FALSE; | ||
387 | } | ||
388 | |||
389 | return EINA_TRUE; | ||
390 | } | ||
391 | |||
392 | static Eina_Bool | ||
393 | _eina_value_type_ushort_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
394 | { | ||
395 | unsigned short *tmem = mem; | ||
396 | *tmem = va_arg(args, unsigned int); /* short is promoted to int for va_arg */ | ||
397 | return EINA_TRUE; | ||
398 | } | ||
399 | |||
400 | static Eina_Bool | ||
401 | _eina_value_type_ushort_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
402 | { | ||
403 | unsigned short *tmem = mem; | ||
404 | const unsigned short *p = ptr; | ||
405 | *tmem = *p; | ||
406 | return EINA_TRUE; | ||
407 | } | ||
408 | |||
409 | static Eina_Bool | ||
410 | _eina_value_type_ushort_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
411 | { | ||
412 | const unsigned short *tmem = mem; | ||
413 | unsigned short *p = ptr; | ||
414 | *p = *tmem; | ||
415 | return EINA_TRUE; | ||
416 | } | ||
417 | |||
418 | static Eina_Bool | ||
419 | _eina_value_type_uint_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
420 | { | ||
421 | unsigned int *tmem = mem; | ||
422 | *tmem = 0; | ||
423 | return EINA_TRUE; | ||
424 | } | ||
425 | |||
426 | static Eina_Bool | ||
427 | _eina_value_type_uint_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
428 | { | ||
429 | return EINA_TRUE; | ||
430 | } | ||
431 | |||
432 | static Eina_Bool | ||
433 | _eina_value_type_uint_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
434 | { | ||
435 | const unsigned int *s = src; | ||
436 | unsigned int *d = dst; | ||
437 | *d = *s; | ||
438 | return EINA_TRUE; | ||
439 | } | ||
440 | |||
441 | static int | ||
442 | _eina_value_type_uint_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
443 | { | ||
444 | const unsigned int *ta = a, *tb = b; | ||
445 | if (*ta < *tb) | ||
446 | return -1; | ||
447 | else if (*ta > *tb) | ||
448 | return 1; | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static Eina_Bool | ||
453 | _eina_value_type_uint_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
454 | { | ||
455 | const unsigned int v = *(const unsigned int *)type_mem; | ||
456 | |||
457 | eina_error_set(0); | ||
458 | |||
459 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
460 | { | ||
461 | unsigned char other_mem = v; | ||
462 | if (EINA_UNLIKELY(v > eina_value_uchar_max)) | ||
463 | return EINA_FALSE; | ||
464 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
465 | } | ||
466 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
467 | { | ||
468 | unsigned short other_mem = v; | ||
469 | if (EINA_UNLIKELY(v > eina_value_ushort_max)) | ||
470 | return EINA_FALSE; | ||
471 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
472 | } | ||
473 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
474 | { | ||
475 | unsigned int other_mem = v; | ||
476 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
477 | } | ||
478 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
479 | { | ||
480 | unsigned long other_mem = v; | ||
481 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
482 | } | ||
483 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
484 | { | ||
485 | uint64_t other_mem = v; | ||
486 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
487 | } | ||
488 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
489 | { | ||
490 | char other_mem = v; | ||
491 | if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max)) | ||
492 | return EINA_FALSE; | ||
493 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
494 | } | ||
495 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
496 | { | ||
497 | short other_mem = v; | ||
498 | if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max)) | ||
499 | return EINA_FALSE; | ||
500 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
501 | } | ||
502 | else if (convert == EINA_VALUE_TYPE_INT) | ||
503 | { | ||
504 | int other_mem = v; | ||
505 | if (EINA_UNLIKELY(v > (unsigned int)eina_value_int_max)) | ||
506 | return EINA_FALSE; | ||
507 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
508 | } | ||
509 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
510 | { | ||
511 | long other_mem = v; | ||
512 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
513 | } | ||
514 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
515 | { | ||
516 | int64_t other_mem = v; | ||
517 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
518 | } | ||
519 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
520 | { | ||
521 | float other_mem = v; | ||
522 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
523 | } | ||
524 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
525 | { | ||
526 | double other_mem = v; | ||
527 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
528 | } | ||
529 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
530 | convert == EINA_VALUE_TYPE_STRING) | ||
531 | { | ||
532 | const char *other_mem; | ||
533 | char buf[64]; | ||
534 | snprintf(buf, sizeof(buf), "%u", v); | ||
535 | other_mem = buf; /* required due &buf == buf */ | ||
536 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
537 | } | ||
538 | else | ||
539 | { | ||
540 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
541 | return EINA_FALSE; | ||
542 | } | ||
543 | |||
544 | return EINA_TRUE; | ||
545 | } | ||
546 | |||
547 | static Eina_Bool | ||
548 | _eina_value_type_uint_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
549 | { | ||
550 | unsigned int *tmem = mem; | ||
551 | *tmem = va_arg(args, unsigned int); | ||
552 | return EINA_TRUE; | ||
553 | } | ||
554 | |||
555 | static Eina_Bool | ||
556 | _eina_value_type_uint_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
557 | { | ||
558 | unsigned int *tmem = mem; | ||
559 | const unsigned int *p = ptr; | ||
560 | *tmem = *p; | ||
561 | return EINA_TRUE; | ||
562 | } | ||
563 | |||
564 | static Eina_Bool | ||
565 | _eina_value_type_uint_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
566 | { | ||
567 | const unsigned int *tmem = mem; | ||
568 | unsigned int *p = ptr; | ||
569 | *p = *tmem; | ||
570 | return EINA_TRUE; | ||
571 | } | ||
572 | |||
573 | static Eina_Bool | ||
574 | _eina_value_type_ulong_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
575 | { | ||
576 | unsigned long *tmem = mem; | ||
577 | *tmem = 0; | ||
578 | return EINA_TRUE; | ||
579 | } | ||
580 | |||
581 | static Eina_Bool | ||
582 | _eina_value_type_ulong_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
583 | { | ||
584 | return EINA_TRUE; | ||
585 | } | ||
586 | |||
587 | static Eina_Bool | ||
588 | _eina_value_type_ulong_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
589 | { | ||
590 | const unsigned long *s = src; | ||
591 | unsigned long *d = dst; | ||
592 | *d = *s; | ||
593 | return EINA_TRUE; | ||
594 | } | ||
595 | |||
596 | static int | ||
597 | _eina_value_type_ulong_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
598 | { | ||
599 | const unsigned long *ta = a, *tb = b; | ||
600 | if (*ta < *tb) | ||
601 | return -1; | ||
602 | else if (*ta > *tb) | ||
603 | return 1; | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | static Eina_Bool | ||
608 | _eina_value_type_ulong_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
609 | { | ||
610 | const unsigned long v = *(const unsigned long *)type_mem; | ||
611 | |||
612 | eina_error_set(0); | ||
613 | |||
614 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
615 | { | ||
616 | unsigned char other_mem = v; | ||
617 | if (EINA_UNLIKELY(v > eina_value_uchar_max)) | ||
618 | return EINA_FALSE; | ||
619 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
620 | } | ||
621 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
622 | { | ||
623 | unsigned short other_mem = v; | ||
624 | if (EINA_UNLIKELY(v > eina_value_ushort_max)) | ||
625 | return EINA_FALSE; | ||
626 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
627 | } | ||
628 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
629 | { | ||
630 | unsigned int other_mem = v; | ||
631 | if (EINA_UNLIKELY(v > eina_value_uint_max)) | ||
632 | return EINA_FALSE; | ||
633 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
634 | } | ||
635 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
636 | { | ||
637 | unsigned long other_mem = v; | ||
638 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
639 | } | ||
640 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
641 | { | ||
642 | uint64_t other_mem = v; | ||
643 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
644 | } | ||
645 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
646 | { | ||
647 | char other_mem = v; | ||
648 | if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max)) | ||
649 | return EINA_FALSE; | ||
650 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
651 | } | ||
652 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
653 | { | ||
654 | short other_mem = v; | ||
655 | if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max)) | ||
656 | return EINA_FALSE; | ||
657 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
658 | } | ||
659 | else if (convert == EINA_VALUE_TYPE_INT) | ||
660 | { | ||
661 | int other_mem = v; | ||
662 | if (EINA_UNLIKELY(v > (unsigned int)eina_value_int_max)) | ||
663 | return EINA_FALSE; | ||
664 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
665 | } | ||
666 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
667 | { | ||
668 | long other_mem = v; | ||
669 | if (EINA_UNLIKELY(v > (unsigned long)eina_value_long_max)) | ||
670 | return EINA_FALSE; | ||
671 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
672 | } | ||
673 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
674 | { | ||
675 | int64_t other_mem = v; | ||
676 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
677 | } | ||
678 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
679 | { | ||
680 | float other_mem = v; | ||
681 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
682 | } | ||
683 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
684 | { | ||
685 | double other_mem = v; | ||
686 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
687 | } | ||
688 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
689 | convert == EINA_VALUE_TYPE_STRING) | ||
690 | { | ||
691 | const char *other_mem; | ||
692 | char buf[64]; | ||
693 | snprintf(buf, sizeof(buf), "%lu", v); | ||
694 | other_mem = buf; /* required due &buf == buf */ | ||
695 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
696 | } | ||
697 | else | ||
698 | { | ||
699 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
700 | return EINA_FALSE; | ||
701 | } | ||
702 | |||
703 | return EINA_TRUE; | ||
704 | } | ||
705 | |||
706 | static Eina_Bool | ||
707 | _eina_value_type_ulong_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
708 | { | ||
709 | unsigned long *tmem = mem; | ||
710 | *tmem = va_arg(args, unsigned long); | ||
711 | return EINA_TRUE; | ||
712 | } | ||
713 | |||
714 | static Eina_Bool | ||
715 | _eina_value_type_ulong_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
716 | { | ||
717 | unsigned long *tmem = mem; | ||
718 | const unsigned long *p = ptr; | ||
719 | *tmem = *p; | ||
720 | return EINA_TRUE; | ||
721 | } | ||
722 | |||
723 | static Eina_Bool | ||
724 | _eina_value_type_ulong_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
725 | { | ||
726 | const unsigned long *tmem = mem; | ||
727 | unsigned long *p = ptr; | ||
728 | *p = *tmem; | ||
729 | return EINA_TRUE; | ||
730 | } | ||
731 | |||
732 | static Eina_Bool | ||
733 | _eina_value_type_uint64_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
734 | { | ||
735 | uint64_t *tmem = mem; | ||
736 | *tmem = 0; | ||
737 | return EINA_TRUE; | ||
738 | } | ||
739 | |||
740 | static Eina_Bool | ||
741 | _eina_value_type_uint64_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
742 | { | ||
743 | return EINA_TRUE; | ||
744 | } | ||
745 | |||
746 | static Eina_Bool | ||
747 | _eina_value_type_uint64_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
748 | { | ||
749 | const uint64_t *s = src; | ||
750 | uint64_t *d = dst; | ||
751 | *d = *s; | ||
752 | return EINA_TRUE; | ||
753 | } | ||
754 | |||
755 | static int | ||
756 | _eina_value_type_uint64_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
757 | { | ||
758 | const uint64_t *ta = a, *tb = b; | ||
759 | if (*ta < *tb) | ||
760 | return -1; | ||
761 | else if (*ta > *tb) | ||
762 | return 1; | ||
763 | return 0; | ||
764 | } | ||
765 | |||
766 | static Eina_Bool | ||
767 | _eina_value_type_uint64_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
768 | { | ||
769 | const uint64_t v = *(const uint64_t *)type_mem; | ||
770 | |||
771 | eina_error_set(0); | ||
772 | |||
773 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
774 | { | ||
775 | unsigned char other_mem = v; | ||
776 | if (EINA_UNLIKELY(v > eina_value_uchar_max)) | ||
777 | return EINA_FALSE; | ||
778 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
779 | } | ||
780 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
781 | { | ||
782 | unsigned short other_mem = v; | ||
783 | if (EINA_UNLIKELY(v > eina_value_ushort_max)) | ||
784 | return EINA_FALSE; | ||
785 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
786 | } | ||
787 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
788 | { | ||
789 | unsigned int other_mem = v; | ||
790 | if (EINA_UNLIKELY(v > eina_value_uint_max)) | ||
791 | return EINA_FALSE; | ||
792 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
793 | } | ||
794 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
795 | { | ||
796 | unsigned long other_mem = v; | ||
797 | if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) && | ||
798 | (v > eina_value_ulong_max))) | ||
799 | return EINA_FALSE; | ||
800 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
801 | } | ||
802 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
803 | { | ||
804 | uint64_t other_mem = v; | ||
805 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
806 | } | ||
807 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
808 | { | ||
809 | char other_mem = v; | ||
810 | if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max)) | ||
811 | return EINA_FALSE; | ||
812 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
813 | } | ||
814 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
815 | { | ||
816 | short other_mem = v; | ||
817 | if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max)) | ||
818 | return EINA_FALSE; | ||
819 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
820 | } | ||
821 | else if (convert == EINA_VALUE_TYPE_INT) | ||
822 | { | ||
823 | int other_mem = v; | ||
824 | if (EINA_UNLIKELY(v > (unsigned int)eina_value_int_max)) | ||
825 | return EINA_FALSE; | ||
826 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
827 | } | ||
828 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
829 | { | ||
830 | long other_mem = v; | ||
831 | if (EINA_UNLIKELY(v > (unsigned long)eina_value_long_max)) | ||
832 | return EINA_FALSE; | ||
833 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
834 | } | ||
835 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
836 | { | ||
837 | int64_t other_mem = v; | ||
838 | if (EINA_UNLIKELY(v > (uint64_t)eina_value_int64_max)) | ||
839 | return EINA_FALSE; | ||
840 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
841 | } | ||
842 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
843 | { | ||
844 | float other_mem = v; | ||
845 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
846 | } | ||
847 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
848 | { | ||
849 | double other_mem = v; | ||
850 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
851 | } | ||
852 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
853 | convert == EINA_VALUE_TYPE_STRING) | ||
854 | { | ||
855 | const char *other_mem; | ||
856 | char buf[64]; | ||
857 | snprintf(buf, sizeof(buf), "%"PRIu64, v); | ||
858 | other_mem = buf; /* required due &buf == buf */ | ||
859 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
860 | } | ||
861 | else | ||
862 | { | ||
863 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
864 | return EINA_FALSE; | ||
865 | } | ||
866 | |||
867 | return EINA_TRUE; | ||
868 | } | ||
869 | |||
870 | static Eina_Bool | ||
871 | _eina_value_type_uint64_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
872 | { | ||
873 | uint64_t *tmem = mem; | ||
874 | *tmem = va_arg(args, uint64_t); | ||
875 | return EINA_TRUE; | ||
876 | } | ||
877 | |||
878 | static Eina_Bool | ||
879 | _eina_value_type_uint64_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
880 | { | ||
881 | uint64_t *tmem = mem; | ||
882 | const uint64_t *p = ptr; | ||
883 | *tmem = *p; | ||
884 | return EINA_TRUE; | ||
885 | } | ||
886 | |||
887 | static Eina_Bool | ||
888 | _eina_value_type_uint64_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
889 | { | ||
890 | const uint64_t *tmem = mem; | ||
891 | uint64_t *p = ptr; | ||
892 | *p = *tmem; | ||
893 | return EINA_TRUE; | ||
894 | } | ||
895 | |||
896 | static Eina_Bool | ||
897 | _eina_value_type_char_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
898 | { | ||
899 | char *tmem = mem; | ||
900 | *tmem = 0; | ||
901 | return EINA_TRUE; | ||
902 | } | ||
903 | |||
904 | static Eina_Bool | ||
905 | _eina_value_type_char_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
906 | { | ||
907 | return EINA_TRUE; | ||
908 | } | ||
909 | |||
910 | static Eina_Bool | ||
911 | _eina_value_type_char_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
912 | { | ||
913 | const char *s = src; | ||
914 | char *d = dst; | ||
915 | *d = *s; | ||
916 | return EINA_TRUE; | ||
917 | } | ||
918 | |||
919 | static int | ||
920 | _eina_value_type_char_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
921 | { | ||
922 | const char *ta = a, *tb = b; | ||
923 | if (*ta < *tb) | ||
924 | return -1; | ||
925 | else if (*ta > *tb) | ||
926 | return 1; | ||
927 | return 0; | ||
928 | } | ||
929 | |||
930 | static Eina_Bool | ||
931 | _eina_value_type_char_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
932 | { | ||
933 | const signed char v = *(const signed char *)type_mem; | ||
934 | |||
935 | eina_error_set(0); | ||
936 | |||
937 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
938 | { | ||
939 | unsigned char other_mem = v; | ||
940 | if (EINA_UNLIKELY(v < 0)) | ||
941 | return EINA_FALSE; | ||
942 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
943 | } | ||
944 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
945 | { | ||
946 | unsigned short other_mem = v; | ||
947 | if (EINA_UNLIKELY(v < 0)) | ||
948 | return EINA_FALSE; | ||
949 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
950 | } | ||
951 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
952 | { | ||
953 | unsigned int other_mem = v; | ||
954 | if (EINA_UNLIKELY(v < 0)) | ||
955 | return EINA_FALSE; | ||
956 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
957 | } | ||
958 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
959 | { | ||
960 | unsigned long other_mem = v; | ||
961 | if (EINA_UNLIKELY(v < 0)) | ||
962 | return EINA_FALSE; | ||
963 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
964 | } | ||
965 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
966 | { | ||
967 | uint64_t other_mem = v; | ||
968 | if (EINA_UNLIKELY(v < 0)) | ||
969 | return EINA_FALSE; | ||
970 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
971 | } | ||
972 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
973 | { | ||
974 | char other_mem = v; | ||
975 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
976 | } | ||
977 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
978 | { | ||
979 | short other_mem = v; | ||
980 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
981 | } | ||
982 | else if (convert == EINA_VALUE_TYPE_INT) | ||
983 | { | ||
984 | int other_mem = v; | ||
985 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
986 | } | ||
987 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
988 | { | ||
989 | long other_mem = v; | ||
990 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
991 | } | ||
992 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
993 | { | ||
994 | int64_t other_mem = v; | ||
995 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
996 | } | ||
997 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
998 | { | ||
999 | float other_mem = v; | ||
1000 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1001 | } | ||
1002 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
1003 | { | ||
1004 | double other_mem = v; | ||
1005 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1006 | } | ||
1007 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
1008 | convert == EINA_VALUE_TYPE_STRING) | ||
1009 | { | ||
1010 | const char *other_mem; | ||
1011 | char buf[64]; | ||
1012 | snprintf(buf, sizeof(buf), "%hhd", v); | ||
1013 | other_mem = buf; /* required due &buf == buf */ | ||
1014 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1015 | } | ||
1016 | else | ||
1017 | { | ||
1018 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
1019 | return EINA_FALSE; | ||
1020 | } | ||
1021 | |||
1022 | return EINA_TRUE; | ||
1023 | } | ||
1024 | |||
1025 | static Eina_Bool | ||
1026 | _eina_value_type_char_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
1027 | { | ||
1028 | char *tmem = mem; | ||
1029 | *tmem = va_arg(args, int); /* char is promoted to int for va_arg */ | ||
1030 | return EINA_TRUE; | ||
1031 | } | ||
1032 | |||
1033 | static Eina_Bool | ||
1034 | _eina_value_type_char_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
1035 | { | ||
1036 | char *tmem = mem; | ||
1037 | const char *p = ptr; | ||
1038 | *tmem = *p; | ||
1039 | return EINA_TRUE; | ||
1040 | } | ||
1041 | |||
1042 | static Eina_Bool | ||
1043 | _eina_value_type_char_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
1044 | { | ||
1045 | const char *tmem = mem; | ||
1046 | char *p = ptr; | ||
1047 | *p = *tmem; | ||
1048 | return EINA_TRUE; | ||
1049 | } | ||
1050 | |||
1051 | static Eina_Bool | ||
1052 | _eina_value_type_short_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
1053 | { | ||
1054 | short *tmem = mem; | ||
1055 | *tmem = 0; | ||
1056 | return EINA_TRUE; | ||
1057 | } | ||
1058 | |||
1059 | static Eina_Bool | ||
1060 | _eina_value_type_short_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
1061 | { | ||
1062 | return EINA_TRUE; | ||
1063 | } | ||
1064 | |||
1065 | static Eina_Bool | ||
1066 | _eina_value_type_short_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
1067 | { | ||
1068 | const short *s = src; | ||
1069 | short *d = dst; | ||
1070 | *d = *s; | ||
1071 | return EINA_TRUE; | ||
1072 | } | ||
1073 | |||
1074 | static int | ||
1075 | _eina_value_type_short_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
1076 | { | ||
1077 | const short *ta = a, *tb = b; | ||
1078 | if (*ta < *tb) | ||
1079 | return -1; | ||
1080 | else if (*ta > *tb) | ||
1081 | return 1; | ||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | static Eina_Bool | ||
1086 | _eina_value_type_short_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
1087 | { | ||
1088 | const short v = *(const short *)type_mem; | ||
1089 | |||
1090 | eina_error_set(0); | ||
1091 | |||
1092 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
1093 | { | ||
1094 | unsigned char other_mem = v; | ||
1095 | if (EINA_UNLIKELY(v < 0)) | ||
1096 | return EINA_FALSE; | ||
1097 | if (EINA_UNLIKELY(v > eina_value_uchar_max)) | ||
1098 | return EINA_FALSE; | ||
1099 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1100 | } | ||
1101 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
1102 | { | ||
1103 | unsigned short other_mem = v; | ||
1104 | if (EINA_UNLIKELY(v < 0)) | ||
1105 | return EINA_FALSE; | ||
1106 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1107 | } | ||
1108 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
1109 | { | ||
1110 | unsigned int other_mem = v; | ||
1111 | if (EINA_UNLIKELY(v < 0)) | ||
1112 | return EINA_FALSE; | ||
1113 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1114 | } | ||
1115 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
1116 | { | ||
1117 | unsigned long other_mem = v; | ||
1118 | if (EINA_UNLIKELY(v < 0)) | ||
1119 | return EINA_FALSE; | ||
1120 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1121 | } | ||
1122 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
1123 | { | ||
1124 | uint64_t other_mem = v; | ||
1125 | if (EINA_UNLIKELY(v < 0)) | ||
1126 | return EINA_FALSE; | ||
1127 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1128 | } | ||
1129 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
1130 | { | ||
1131 | char other_mem = v; | ||
1132 | if (EINA_UNLIKELY(v < eina_value_char_min)) | ||
1133 | return EINA_FALSE; | ||
1134 | if (EINA_UNLIKELY(v > eina_value_char_max)) | ||
1135 | return EINA_FALSE; | ||
1136 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1137 | } | ||
1138 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
1139 | { | ||
1140 | short other_mem = v; | ||
1141 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1142 | } | ||
1143 | else if (convert == EINA_VALUE_TYPE_INT) | ||
1144 | { | ||
1145 | int other_mem = v; | ||
1146 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1147 | } | ||
1148 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
1149 | { | ||
1150 | long other_mem = v; | ||
1151 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1152 | } | ||
1153 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
1154 | { | ||
1155 | int64_t other_mem = v; | ||
1156 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1157 | } | ||
1158 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
1159 | { | ||
1160 | float other_mem = v; | ||
1161 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1162 | } | ||
1163 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
1164 | { | ||
1165 | double other_mem = v; | ||
1166 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1167 | } | ||
1168 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
1169 | convert == EINA_VALUE_TYPE_STRING) | ||
1170 | { | ||
1171 | const char *other_mem; | ||
1172 | char buf[64]; | ||
1173 | snprintf(buf, sizeof(buf), "%hd", v); | ||
1174 | other_mem = buf; /* required due &buf == buf */ | ||
1175 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1176 | } | ||
1177 | else | ||
1178 | { | ||
1179 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
1180 | return EINA_FALSE; | ||
1181 | } | ||
1182 | |||
1183 | return EINA_TRUE; | ||
1184 | } | ||
1185 | |||
1186 | static Eina_Bool | ||
1187 | _eina_value_type_short_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
1188 | { | ||
1189 | short *tmem = mem; | ||
1190 | *tmem = va_arg(args, int); /* short int is promoted to int for va_arg */ | ||
1191 | return EINA_TRUE; | ||
1192 | } | ||
1193 | |||
1194 | static Eina_Bool | ||
1195 | _eina_value_type_short_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
1196 | { | ||
1197 | short *tmem = mem; | ||
1198 | const short *p = ptr; | ||
1199 | *tmem = *p; | ||
1200 | return EINA_TRUE; | ||
1201 | } | ||
1202 | |||
1203 | static Eina_Bool | ||
1204 | _eina_value_type_short_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
1205 | { | ||
1206 | const short *tmem = mem; | ||
1207 | short *p = ptr; | ||
1208 | *p = *tmem; | ||
1209 | return EINA_TRUE; | ||
1210 | } | ||
1211 | |||
1212 | static Eina_Bool | ||
1213 | _eina_value_type_int_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
1214 | { | ||
1215 | int *tmem = mem; | ||
1216 | *tmem = 0; | ||
1217 | return EINA_TRUE; | ||
1218 | } | ||
1219 | |||
1220 | static Eina_Bool | ||
1221 | _eina_value_type_int_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
1222 | { | ||
1223 | return EINA_TRUE; | ||
1224 | } | ||
1225 | |||
1226 | static Eina_Bool | ||
1227 | _eina_value_type_int_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
1228 | { | ||
1229 | const int *s = src; | ||
1230 | int *d = dst; | ||
1231 | *d = *s; | ||
1232 | return EINA_TRUE; | ||
1233 | } | ||
1234 | |||
1235 | static int | ||
1236 | _eina_value_type_int_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
1237 | { | ||
1238 | const int *ta = a, *tb = b; | ||
1239 | if (*ta < *tb) | ||
1240 | return -1; | ||
1241 | else if (*ta > *tb) | ||
1242 | return 1; | ||
1243 | return 0; | ||
1244 | } | ||
1245 | |||
1246 | static Eina_Bool | ||
1247 | _eina_value_type_int_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
1248 | { | ||
1249 | const int v = *(const int *)type_mem; | ||
1250 | |||
1251 | eina_error_set(0); | ||
1252 | |||
1253 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
1254 | { | ||
1255 | unsigned char other_mem = v; | ||
1256 | if (EINA_UNLIKELY(v < 0)) | ||
1257 | return EINA_FALSE; | ||
1258 | if (EINA_UNLIKELY(v > eina_value_uchar_max)) | ||
1259 | return EINA_FALSE; | ||
1260 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1261 | } | ||
1262 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
1263 | { | ||
1264 | unsigned short other_mem = v; | ||
1265 | if (EINA_UNLIKELY(v < 0)) | ||
1266 | return EINA_FALSE; | ||
1267 | if (EINA_UNLIKELY(v > eina_value_ushort_max)) | ||
1268 | return EINA_FALSE; | ||
1269 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1270 | } | ||
1271 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
1272 | { | ||
1273 | unsigned int other_mem = v; | ||
1274 | if (EINA_UNLIKELY(v < 0)) | ||
1275 | return EINA_FALSE; | ||
1276 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1277 | } | ||
1278 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
1279 | { | ||
1280 | unsigned long other_mem = v; | ||
1281 | if (EINA_UNLIKELY(v < 0)) | ||
1282 | return EINA_FALSE; | ||
1283 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1284 | } | ||
1285 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
1286 | { | ||
1287 | uint64_t other_mem = v; | ||
1288 | if (EINA_UNLIKELY(v < 0)) | ||
1289 | return EINA_FALSE; | ||
1290 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1291 | } | ||
1292 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
1293 | { | ||
1294 | char other_mem = v; | ||
1295 | if (EINA_UNLIKELY(v < eina_value_char_min)) | ||
1296 | return EINA_FALSE; | ||
1297 | if (EINA_UNLIKELY(v > eina_value_char_max)) | ||
1298 | return EINA_FALSE; | ||
1299 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1300 | } | ||
1301 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
1302 | { | ||
1303 | short other_mem = v; | ||
1304 | if (EINA_UNLIKELY(v < eina_value_short_min)) | ||
1305 | return EINA_FALSE; | ||
1306 | if (EINA_UNLIKELY(v > eina_value_short_max)) | ||
1307 | return EINA_FALSE; | ||
1308 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1309 | } | ||
1310 | else if (convert == EINA_VALUE_TYPE_INT) | ||
1311 | { | ||
1312 | int other_mem = v; | ||
1313 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1314 | } | ||
1315 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
1316 | { | ||
1317 | long other_mem = v; | ||
1318 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1319 | } | ||
1320 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
1321 | { | ||
1322 | int64_t other_mem = v; | ||
1323 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1324 | } | ||
1325 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
1326 | { | ||
1327 | float other_mem = v; | ||
1328 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1329 | } | ||
1330 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
1331 | { | ||
1332 | double other_mem = v; | ||
1333 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1334 | } | ||
1335 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
1336 | convert == EINA_VALUE_TYPE_STRING) | ||
1337 | { | ||
1338 | const char *other_mem; | ||
1339 | char buf[64]; | ||
1340 | snprintf(buf, sizeof(buf), "%d", v); | ||
1341 | other_mem = buf; /* required due &buf == buf */ | ||
1342 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1343 | } | ||
1344 | else | ||
1345 | { | ||
1346 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
1347 | return EINA_FALSE; | ||
1348 | } | ||
1349 | |||
1350 | return EINA_TRUE; | ||
1351 | } | ||
1352 | |||
1353 | static Eina_Bool | ||
1354 | _eina_value_type_int_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
1355 | { | ||
1356 | int *tmem = mem; | ||
1357 | *tmem = va_arg(args, int); | ||
1358 | return EINA_TRUE; | ||
1359 | } | ||
1360 | |||
1361 | static Eina_Bool | ||
1362 | _eina_value_type_int_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
1363 | { | ||
1364 | int *tmem = mem; | ||
1365 | const int *p = ptr; | ||
1366 | *tmem = *p; | ||
1367 | return EINA_TRUE; | ||
1368 | } | ||
1369 | |||
1370 | static Eina_Bool | ||
1371 | _eina_value_type_int_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
1372 | { | ||
1373 | const int *tmem = mem; | ||
1374 | int *p = ptr; | ||
1375 | *p = *tmem; | ||
1376 | return EINA_TRUE; | ||
1377 | } | ||
1378 | |||
1379 | static Eina_Bool | ||
1380 | _eina_value_type_long_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
1381 | { | ||
1382 | long *tmem = mem; | ||
1383 | *tmem = 0; | ||
1384 | return EINA_TRUE; | ||
1385 | } | ||
1386 | |||
1387 | static Eina_Bool | ||
1388 | _eina_value_type_long_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
1389 | { | ||
1390 | return EINA_TRUE; | ||
1391 | } | ||
1392 | |||
1393 | static Eina_Bool | ||
1394 | _eina_value_type_long_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
1395 | { | ||
1396 | const long *s = src; | ||
1397 | long *d = dst; | ||
1398 | *d = *s; | ||
1399 | return EINA_TRUE; | ||
1400 | } | ||
1401 | |||
1402 | static int | ||
1403 | _eina_value_type_long_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
1404 | { | ||
1405 | const long *ta = a, *tb = b; | ||
1406 | if (*ta < *tb) | ||
1407 | return -1; | ||
1408 | else if (*ta > *tb) | ||
1409 | return 1; | ||
1410 | return 0; | ||
1411 | } | ||
1412 | |||
1413 | static Eina_Bool | ||
1414 | _eina_value_type_long_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
1415 | { | ||
1416 | const long v = *(const long *)type_mem; | ||
1417 | |||
1418 | eina_error_set(0); | ||
1419 | |||
1420 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
1421 | { | ||
1422 | unsigned char other_mem = v; | ||
1423 | if (EINA_UNLIKELY(v < 0)) | ||
1424 | return EINA_FALSE; | ||
1425 | if (EINA_UNLIKELY((unsigned long) v > eina_value_uchar_max)) | ||
1426 | return EINA_FALSE; | ||
1427 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1428 | } | ||
1429 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
1430 | { | ||
1431 | unsigned short other_mem = v; | ||
1432 | if (EINA_UNLIKELY(v < 0)) | ||
1433 | return EINA_FALSE; | ||
1434 | if (EINA_UNLIKELY((unsigned long) v > eina_value_ushort_max)) | ||
1435 | return EINA_FALSE; | ||
1436 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1437 | } | ||
1438 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
1439 | { | ||
1440 | unsigned int other_mem = v; | ||
1441 | if (EINA_UNLIKELY(v < 0)) | ||
1442 | return EINA_FALSE; | ||
1443 | if (EINA_UNLIKELY((unsigned long) v > eina_value_uint_max)) | ||
1444 | return EINA_FALSE; | ||
1445 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1446 | } | ||
1447 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
1448 | { | ||
1449 | unsigned long other_mem = v; | ||
1450 | if (EINA_UNLIKELY(v < 0)) | ||
1451 | return EINA_FALSE; | ||
1452 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1453 | } | ||
1454 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
1455 | { | ||
1456 | uint64_t other_mem = v; | ||
1457 | if (EINA_UNLIKELY(v < 0)) | ||
1458 | return EINA_FALSE; | ||
1459 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1460 | } | ||
1461 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
1462 | { | ||
1463 | char other_mem = v; | ||
1464 | if (EINA_UNLIKELY(v < eina_value_char_min)) | ||
1465 | return EINA_FALSE; | ||
1466 | if (EINA_UNLIKELY(v > eina_value_char_max)) | ||
1467 | return EINA_FALSE; | ||
1468 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1469 | } | ||
1470 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
1471 | { | ||
1472 | short other_mem = v; | ||
1473 | if (EINA_UNLIKELY(v < eina_value_short_min)) | ||
1474 | return EINA_FALSE; | ||
1475 | if (EINA_UNLIKELY(v > eina_value_short_max)) | ||
1476 | return EINA_FALSE; | ||
1477 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1478 | } | ||
1479 | else if (convert == EINA_VALUE_TYPE_INT) | ||
1480 | { | ||
1481 | int other_mem = v; | ||
1482 | if (EINA_UNLIKELY(v < eina_value_int_min)) | ||
1483 | return EINA_FALSE; | ||
1484 | if (EINA_UNLIKELY(v > eina_value_int_max)) | ||
1485 | return EINA_FALSE; | ||
1486 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1487 | } | ||
1488 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
1489 | { | ||
1490 | long other_mem = v; | ||
1491 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1492 | } | ||
1493 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
1494 | { | ||
1495 | int64_t other_mem = v; | ||
1496 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1497 | } | ||
1498 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
1499 | { | ||
1500 | float other_mem = v; | ||
1501 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1502 | } | ||
1503 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
1504 | { | ||
1505 | double other_mem = v; | ||
1506 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1507 | } | ||
1508 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
1509 | convert == EINA_VALUE_TYPE_STRING) | ||
1510 | { | ||
1511 | const char *other_mem; | ||
1512 | char buf[64]; | ||
1513 | snprintf(buf, sizeof(buf), "%ld", v); | ||
1514 | other_mem = buf; /* required due &buf == buf */ | ||
1515 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1516 | } | ||
1517 | else | ||
1518 | { | ||
1519 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
1520 | return EINA_FALSE; | ||
1521 | } | ||
1522 | |||
1523 | return EINA_TRUE; | ||
1524 | } | ||
1525 | |||
1526 | static Eina_Bool | ||
1527 | _eina_value_type_long_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
1528 | { | ||
1529 | long *tmem = mem; | ||
1530 | *tmem = va_arg(args, long); | ||
1531 | return EINA_TRUE; | ||
1532 | } | ||
1533 | |||
1534 | static Eina_Bool | ||
1535 | _eina_value_type_long_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
1536 | { | ||
1537 | long *tmem = mem; | ||
1538 | const long *p = ptr; | ||
1539 | *tmem = *p; | ||
1540 | return EINA_TRUE; | ||
1541 | } | ||
1542 | |||
1543 | static Eina_Bool | ||
1544 | _eina_value_type_long_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
1545 | { | ||
1546 | const long *tmem = mem; | ||
1547 | long *p = ptr; | ||
1548 | *p = *tmem; | ||
1549 | return EINA_TRUE; | ||
1550 | } | ||
1551 | |||
1552 | static Eina_Bool | ||
1553 | _eina_value_type_int64_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
1554 | { | ||
1555 | int64_t *tmem = mem; | ||
1556 | *tmem = 0; | ||
1557 | return EINA_TRUE; | ||
1558 | } | ||
1559 | |||
1560 | static Eina_Bool | ||
1561 | _eina_value_type_int64_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
1562 | { | ||
1563 | return EINA_TRUE; | ||
1564 | } | ||
1565 | |||
1566 | static Eina_Bool | ||
1567 | _eina_value_type_int64_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
1568 | { | ||
1569 | const int64_t *s = src; | ||
1570 | int64_t *d = dst; | ||
1571 | *d = *s; | ||
1572 | return EINA_TRUE; | ||
1573 | } | ||
1574 | |||
1575 | static int | ||
1576 | _eina_value_type_int64_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
1577 | { | ||
1578 | const int64_t *ta = a, *tb = b; | ||
1579 | if (*ta < *tb) | ||
1580 | return -1; | ||
1581 | else if (*ta > *tb) | ||
1582 | return 1; | ||
1583 | return 0; | ||
1584 | } | ||
1585 | |||
1586 | static Eina_Bool | ||
1587 | _eina_value_type_int64_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
1588 | { | ||
1589 | const int64_t v = *(const int64_t *)type_mem; | ||
1590 | |||
1591 | eina_error_set(0); | ||
1592 | |||
1593 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
1594 | { | ||
1595 | unsigned char other_mem = v; | ||
1596 | if (EINA_UNLIKELY(v < 0)) | ||
1597 | return EINA_FALSE; | ||
1598 | if (EINA_UNLIKELY(v > eina_value_uchar_max)) | ||
1599 | return EINA_FALSE; | ||
1600 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1601 | } | ||
1602 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
1603 | { | ||
1604 | unsigned short other_mem = v; | ||
1605 | if (EINA_UNLIKELY(v < 0)) | ||
1606 | return EINA_FALSE; | ||
1607 | if (EINA_UNLIKELY(v > eina_value_ushort_max)) | ||
1608 | return EINA_FALSE; | ||
1609 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1610 | } | ||
1611 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
1612 | { | ||
1613 | unsigned int other_mem = v; | ||
1614 | if (EINA_UNLIKELY(v < 0)) | ||
1615 | return EINA_FALSE; | ||
1616 | if (EINA_UNLIKELY(v > eina_value_uint_max)) | ||
1617 | return EINA_FALSE; | ||
1618 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1619 | } | ||
1620 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
1621 | { | ||
1622 | unsigned long other_mem = v; | ||
1623 | if (EINA_UNLIKELY(v < 0)) | ||
1624 | return EINA_FALSE; | ||
1625 | if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) && | ||
1626 | (v > eina_value_ulong_max))) | ||
1627 | return EINA_FALSE; | ||
1628 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1629 | } | ||
1630 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
1631 | { | ||
1632 | uint64_t other_mem = v; | ||
1633 | if (EINA_UNLIKELY(v < 0)) | ||
1634 | return EINA_FALSE; | ||
1635 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1636 | } | ||
1637 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
1638 | { | ||
1639 | char other_mem = v; | ||
1640 | if (EINA_UNLIKELY(v < eina_value_char_min)) | ||
1641 | return EINA_FALSE; | ||
1642 | if (EINA_UNLIKELY(v > eina_value_char_max)) | ||
1643 | return EINA_FALSE; | ||
1644 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1645 | } | ||
1646 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
1647 | { | ||
1648 | short other_mem = v; | ||
1649 | if (EINA_UNLIKELY(v < eina_value_short_min)) | ||
1650 | return EINA_FALSE; | ||
1651 | if (EINA_UNLIKELY(v > eina_value_short_max)) | ||
1652 | return EINA_FALSE; | ||
1653 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1654 | } | ||
1655 | else if (convert == EINA_VALUE_TYPE_INT) | ||
1656 | { | ||
1657 | int other_mem = v; | ||
1658 | if (EINA_UNLIKELY(v < eina_value_int_min)) | ||
1659 | return EINA_FALSE; | ||
1660 | if (EINA_UNLIKELY(v > eina_value_int_max)) | ||
1661 | return EINA_FALSE; | ||
1662 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1663 | } | ||
1664 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
1665 | { | ||
1666 | long other_mem = v; | ||
1667 | if (EINA_UNLIKELY(v < eina_value_long_min)) | ||
1668 | return EINA_FALSE; | ||
1669 | if (EINA_UNLIKELY(v > eina_value_long_max)) | ||
1670 | return EINA_FALSE; | ||
1671 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1672 | } | ||
1673 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
1674 | { | ||
1675 | int64_t other_mem = v; | ||
1676 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1677 | } | ||
1678 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
1679 | { | ||
1680 | float other_mem = v; | ||
1681 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1682 | } | ||
1683 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
1684 | { | ||
1685 | double other_mem = v; | ||
1686 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1687 | } | ||
1688 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
1689 | convert == EINA_VALUE_TYPE_STRING) | ||
1690 | { | ||
1691 | const char *other_mem; | ||
1692 | char buf[64]; | ||
1693 | snprintf(buf, sizeof(buf), "%"PRId64, v); | ||
1694 | other_mem = buf; /* required due &buf == buf */ | ||
1695 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1696 | } | ||
1697 | else | ||
1698 | { | ||
1699 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
1700 | return EINA_FALSE; | ||
1701 | } | ||
1702 | |||
1703 | return EINA_TRUE; | ||
1704 | } | ||
1705 | |||
1706 | static Eina_Bool | ||
1707 | _eina_value_type_int64_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
1708 | { | ||
1709 | int64_t *tmem = mem; | ||
1710 | *tmem = va_arg(args, int64_t); | ||
1711 | return EINA_TRUE; | ||
1712 | } | ||
1713 | |||
1714 | static Eina_Bool | ||
1715 | _eina_value_type_int64_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
1716 | { | ||
1717 | int64_t *tmem = mem; | ||
1718 | const int64_t *p = ptr; | ||
1719 | *tmem = *p; | ||
1720 | return EINA_TRUE; | ||
1721 | } | ||
1722 | |||
1723 | static Eina_Bool | ||
1724 | _eina_value_type_int64_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
1725 | { | ||
1726 | const int64_t *tmem = mem; | ||
1727 | int64_t *p = ptr; | ||
1728 | *p = *tmem; | ||
1729 | return EINA_TRUE; | ||
1730 | } | ||
1731 | |||
1732 | static Eina_Bool | ||
1733 | _eina_value_type_float_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
1734 | { | ||
1735 | float *tmem = mem; | ||
1736 | *tmem = 0; | ||
1737 | return EINA_TRUE; | ||
1738 | } | ||
1739 | |||
1740 | static Eina_Bool | ||
1741 | _eina_value_type_float_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
1742 | { | ||
1743 | return EINA_TRUE; | ||
1744 | } | ||
1745 | |||
1746 | static Eina_Bool | ||
1747 | _eina_value_type_float_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
1748 | { | ||
1749 | const float *s = src; | ||
1750 | float *d = dst; | ||
1751 | *d = *s; | ||
1752 | return EINA_TRUE; | ||
1753 | } | ||
1754 | |||
1755 | static int | ||
1756 | _eina_value_type_float_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
1757 | { | ||
1758 | const float *ta = a, *tb = b; | ||
1759 | if (*ta < *tb) | ||
1760 | return -1; | ||
1761 | else if (*ta > *tb) | ||
1762 | return 1; | ||
1763 | return 0; | ||
1764 | } | ||
1765 | |||
1766 | static Eina_Bool | ||
1767 | _eina_value_type_float_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
1768 | { | ||
1769 | const float v = *(const float *)type_mem; | ||
1770 | |||
1771 | eina_error_set(0); | ||
1772 | |||
1773 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
1774 | { | ||
1775 | unsigned char other_mem = v; | ||
1776 | if (EINA_UNLIKELY(v < 0)) | ||
1777 | return EINA_FALSE; | ||
1778 | if (EINA_UNLIKELY(v > eina_value_uchar_max)) | ||
1779 | return EINA_FALSE; | ||
1780 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1781 | } | ||
1782 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
1783 | { | ||
1784 | unsigned short other_mem = v; | ||
1785 | if (EINA_UNLIKELY(v < 0)) | ||
1786 | return EINA_FALSE; | ||
1787 | if (EINA_UNLIKELY(v > eina_value_ushort_max)) | ||
1788 | return EINA_FALSE; | ||
1789 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1790 | } | ||
1791 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
1792 | { | ||
1793 | unsigned int other_mem = v; | ||
1794 | if (EINA_UNLIKELY(v < 0)) | ||
1795 | return EINA_FALSE; | ||
1796 | if (EINA_UNLIKELY(v > eina_value_uint_max)) | ||
1797 | return EINA_FALSE; | ||
1798 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1799 | } | ||
1800 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
1801 | { | ||
1802 | unsigned long other_mem = v; | ||
1803 | if (EINA_UNLIKELY(v < 0)) | ||
1804 | return EINA_FALSE; | ||
1805 | if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) && | ||
1806 | (v > eina_value_ulong_max))) | ||
1807 | return EINA_FALSE; | ||
1808 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1809 | } | ||
1810 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
1811 | { | ||
1812 | uint64_t other_mem = v; | ||
1813 | if (EINA_UNLIKELY(v < 0)) | ||
1814 | return EINA_FALSE; | ||
1815 | if (EINA_UNLIKELY(v > eina_value_uint64_max)) | ||
1816 | return EINA_FALSE; | ||
1817 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1818 | } | ||
1819 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
1820 | { | ||
1821 | char other_mem = v; | ||
1822 | if (EINA_UNLIKELY(v < eina_value_char_min)) | ||
1823 | return EINA_FALSE; | ||
1824 | if (EINA_UNLIKELY(v > eina_value_char_max)) | ||
1825 | return EINA_FALSE; | ||
1826 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1827 | } | ||
1828 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
1829 | { | ||
1830 | short other_mem = v; | ||
1831 | if (EINA_UNLIKELY(v < eina_value_short_min)) | ||
1832 | return EINA_FALSE; | ||
1833 | if (EINA_UNLIKELY(v > eina_value_short_max)) | ||
1834 | return EINA_FALSE; | ||
1835 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1836 | } | ||
1837 | else if (convert == EINA_VALUE_TYPE_INT) | ||
1838 | { | ||
1839 | int other_mem = v; | ||
1840 | if (EINA_UNLIKELY(v < eina_value_int_min)) | ||
1841 | return EINA_FALSE; | ||
1842 | if (EINA_UNLIKELY(v > eina_value_int_max)) | ||
1843 | return EINA_FALSE; | ||
1844 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1845 | } | ||
1846 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
1847 | { | ||
1848 | long other_mem = v; | ||
1849 | if (EINA_UNLIKELY(v < eina_value_long_min)) | ||
1850 | return EINA_FALSE; | ||
1851 | if (EINA_UNLIKELY(v > eina_value_long_max)) | ||
1852 | return EINA_FALSE; | ||
1853 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1854 | } | ||
1855 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
1856 | { | ||
1857 | int64_t other_mem = v; | ||
1858 | if (EINA_UNLIKELY(v < eina_value_int64_min)) | ||
1859 | return EINA_FALSE; | ||
1860 | if (EINA_UNLIKELY(v > eina_value_int64_max)) | ||
1861 | return EINA_FALSE; | ||
1862 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1863 | } | ||
1864 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
1865 | { | ||
1866 | float other_mem = v; | ||
1867 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1868 | } | ||
1869 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
1870 | { | ||
1871 | double other_mem = v; | ||
1872 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1873 | } | ||
1874 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
1875 | convert == EINA_VALUE_TYPE_STRING) | ||
1876 | { | ||
1877 | const char *other_mem; | ||
1878 | char buf[64]; | ||
1879 | snprintf(buf, sizeof(buf), "%f", v); | ||
1880 | other_mem = buf; /* required due &buf == buf */ | ||
1881 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1882 | } | ||
1883 | else | ||
1884 | { | ||
1885 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
1886 | return EINA_FALSE; | ||
1887 | } | ||
1888 | |||
1889 | return EINA_TRUE; | ||
1890 | } | ||
1891 | |||
1892 | static Eina_Bool | ||
1893 | _eina_value_type_float_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
1894 | { | ||
1895 | float *tmem = mem; | ||
1896 | *tmem = va_arg(args, double); /* float is promoted to double for va_args */ | ||
1897 | return EINA_TRUE; | ||
1898 | } | ||
1899 | |||
1900 | static Eina_Bool | ||
1901 | _eina_value_type_float_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
1902 | { | ||
1903 | float *tmem = mem; | ||
1904 | const float *p = ptr; | ||
1905 | *tmem = *p; | ||
1906 | return EINA_TRUE; | ||
1907 | } | ||
1908 | |||
1909 | static Eina_Bool | ||
1910 | _eina_value_type_float_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
1911 | { | ||
1912 | const float *tmem = mem; | ||
1913 | float *p = ptr; | ||
1914 | *p = *tmem; | ||
1915 | return EINA_TRUE; | ||
1916 | } | ||
1917 | |||
1918 | static Eina_Bool | ||
1919 | _eina_value_type_double_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
1920 | { | ||
1921 | double *tmem = mem; | ||
1922 | *tmem = 0; | ||
1923 | return EINA_TRUE; | ||
1924 | } | ||
1925 | |||
1926 | static Eina_Bool | ||
1927 | _eina_value_type_double_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
1928 | { | ||
1929 | return EINA_TRUE; | ||
1930 | } | ||
1931 | |||
1932 | static Eina_Bool | ||
1933 | _eina_value_type_double_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
1934 | { | ||
1935 | const double *s = src; | ||
1936 | double *d = dst; | ||
1937 | *d = *s; | ||
1938 | return EINA_TRUE; | ||
1939 | } | ||
1940 | |||
1941 | static int | ||
1942 | _eina_value_type_double_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
1943 | { | ||
1944 | const double *ta = a, *tb = b; | ||
1945 | if (*ta < *tb) | ||
1946 | return -1; | ||
1947 | else if (*ta > *tb) | ||
1948 | return 1; | ||
1949 | return 0; | ||
1950 | } | ||
1951 | |||
1952 | static Eina_Bool | ||
1953 | _eina_value_type_double_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
1954 | { | ||
1955 | const double v = *(const double *)type_mem; | ||
1956 | |||
1957 | eina_error_set(0); | ||
1958 | |||
1959 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
1960 | { | ||
1961 | unsigned char other_mem = v; | ||
1962 | if (EINA_UNLIKELY(v < 0)) | ||
1963 | return EINA_FALSE; | ||
1964 | if (EINA_UNLIKELY(v > eina_value_uchar_max)) | ||
1965 | return EINA_FALSE; | ||
1966 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1967 | } | ||
1968 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
1969 | { | ||
1970 | unsigned short other_mem = v; | ||
1971 | if (EINA_UNLIKELY(v < 0)) | ||
1972 | return EINA_FALSE; | ||
1973 | if (EINA_UNLIKELY(v > eina_value_ushort_max)) | ||
1974 | return EINA_FALSE; | ||
1975 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1976 | } | ||
1977 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
1978 | { | ||
1979 | unsigned int other_mem = v; | ||
1980 | if (EINA_UNLIKELY(v < 0)) | ||
1981 | return EINA_FALSE; | ||
1982 | if (EINA_UNLIKELY(v > eina_value_uint_max)) | ||
1983 | return EINA_FALSE; | ||
1984 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1985 | } | ||
1986 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
1987 | { | ||
1988 | unsigned long other_mem = v; | ||
1989 | if (EINA_UNLIKELY(v < 0)) | ||
1990 | return EINA_FALSE; | ||
1991 | if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) && | ||
1992 | (v > eina_value_ulong_max))) | ||
1993 | return EINA_FALSE; | ||
1994 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
1995 | } | ||
1996 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
1997 | { | ||
1998 | uint64_t other_mem = v; | ||
1999 | if (EINA_UNLIKELY(v < 0)) | ||
2000 | return EINA_FALSE; | ||
2001 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2002 | } | ||
2003 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
2004 | { | ||
2005 | char other_mem = v; | ||
2006 | if (EINA_UNLIKELY(v < eina_value_char_min)) | ||
2007 | return EINA_FALSE; | ||
2008 | if (EINA_UNLIKELY(v > eina_value_char_max)) | ||
2009 | return EINA_FALSE; | ||
2010 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2011 | } | ||
2012 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
2013 | { | ||
2014 | short other_mem = v; | ||
2015 | if (EINA_UNLIKELY(v < eina_value_short_min)) | ||
2016 | return EINA_FALSE; | ||
2017 | if (EINA_UNLIKELY(v > eina_value_short_max)) | ||
2018 | return EINA_FALSE; | ||
2019 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2020 | } | ||
2021 | else if (convert == EINA_VALUE_TYPE_INT) | ||
2022 | { | ||
2023 | int other_mem = v; | ||
2024 | if (EINA_UNLIKELY(v < eina_value_int_min)) | ||
2025 | return EINA_FALSE; | ||
2026 | if (EINA_UNLIKELY(v > eina_value_int_max)) | ||
2027 | return EINA_FALSE; | ||
2028 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2029 | } | ||
2030 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
2031 | { | ||
2032 | long other_mem = v; | ||
2033 | if (EINA_UNLIKELY(v < eina_value_long_min)) | ||
2034 | return EINA_FALSE; | ||
2035 | if (EINA_UNLIKELY(v > eina_value_long_max)) | ||
2036 | return EINA_FALSE; | ||
2037 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2038 | } | ||
2039 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
2040 | { | ||
2041 | int64_t other_mem = v; | ||
2042 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2043 | } | ||
2044 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
2045 | { | ||
2046 | float other_mem = v; | ||
2047 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2048 | } | ||
2049 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
2050 | { | ||
2051 | double other_mem = v; | ||
2052 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2053 | } | ||
2054 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
2055 | convert == EINA_VALUE_TYPE_STRING) | ||
2056 | { | ||
2057 | const char *other_mem; | ||
2058 | char buf[64]; | ||
2059 | snprintf(buf, sizeof(buf), "%g", (double)v); | ||
2060 | other_mem = buf; /* required due &buf == buf */ | ||
2061 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2062 | } | ||
2063 | else | ||
2064 | { | ||
2065 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
2066 | return EINA_FALSE; | ||
2067 | } | ||
2068 | |||
2069 | return EINA_TRUE; | ||
2070 | } | ||
2071 | |||
2072 | static Eina_Bool | ||
2073 | _eina_value_type_double_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
2074 | { | ||
2075 | double *tmem = mem; | ||
2076 | *tmem = va_arg(args, double); | ||
2077 | return EINA_TRUE; | ||
2078 | } | ||
2079 | |||
2080 | static Eina_Bool | ||
2081 | _eina_value_type_double_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
2082 | { | ||
2083 | double *tmem = mem; | ||
2084 | const double *p = ptr; | ||
2085 | *tmem = *p; | ||
2086 | return EINA_TRUE; | ||
2087 | } | ||
2088 | |||
2089 | static Eina_Bool | ||
2090 | _eina_value_type_double_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
2091 | { | ||
2092 | const double *tmem = mem; | ||
2093 | double *p = ptr; | ||
2094 | *p = *tmem; | ||
2095 | return EINA_TRUE; | ||
2096 | } | ||
2097 | |||
2098 | static Eina_Bool | ||
2099 | _eina_value_type_string_common_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
2100 | { | ||
2101 | const char **tmem = mem; | ||
2102 | *tmem = NULL; | ||
2103 | return EINA_TRUE; | ||
2104 | } | ||
2105 | |||
2106 | static int | ||
2107 | _eina_value_type_string_common_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
2108 | { | ||
2109 | const char *sa = *(const char **)a; | ||
2110 | const char *sb = *(const char **)b; | ||
2111 | if (sa == sb) | ||
2112 | return 0; | ||
2113 | if (sa == NULL) | ||
2114 | return -1; | ||
2115 | if (sb == NULL) | ||
2116 | return 1; | ||
2117 | return strcmp(sa, sb); | ||
2118 | } | ||
2119 | |||
2120 | static Eina_Bool | ||
2121 | _eina_value_type_string_common_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
2122 | { | ||
2123 | const char *v = *(const char **)type_mem; | ||
2124 | |||
2125 | eina_error_set(0); | ||
2126 | |||
2127 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
2128 | { | ||
2129 | unsigned char other_mem; | ||
2130 | if ((sscanf(v, "%hhu", &other_mem) != 1) && | ||
2131 | (sscanf(v, "%hhx", &other_mem) != 1) && | ||
2132 | (sscanf(v, "%hho", &other_mem) != 1)) | ||
2133 | return EINA_FALSE; | ||
2134 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2135 | } | ||
2136 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
2137 | { | ||
2138 | unsigned short other_mem; | ||
2139 | if ((sscanf(v, "%hu", &other_mem) != 1) && | ||
2140 | (sscanf(v, "%hx", &other_mem) != 1) && | ||
2141 | (sscanf(v, "%ho", &other_mem) != 1)) | ||
2142 | return EINA_FALSE; | ||
2143 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2144 | } | ||
2145 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
2146 | { | ||
2147 | unsigned int other_mem; | ||
2148 | if ((sscanf(v, "%u", &other_mem) != 1) && | ||
2149 | (sscanf(v, "%x", &other_mem) != 1) && | ||
2150 | (sscanf(v, "%o", &other_mem) != 1)) | ||
2151 | return EINA_FALSE; | ||
2152 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2153 | } | ||
2154 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
2155 | { | ||
2156 | unsigned long other_mem; | ||
2157 | if ((sscanf(v, "%lu", &other_mem) != 1) && | ||
2158 | (sscanf(v, "%lx", &other_mem) != 1) && | ||
2159 | (sscanf(v, "%lo", &other_mem) != 1)) | ||
2160 | return EINA_FALSE; | ||
2161 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2162 | } | ||
2163 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
2164 | { | ||
2165 | uint64_t other_mem; | ||
2166 | if ((sscanf(v, "%"SCNu64, &other_mem) != 1) && | ||
2167 | (sscanf(v, "%"SCNx64, &other_mem) != 1) && | ||
2168 | (sscanf(v, "%"SCNo64, &other_mem) != 1)) | ||
2169 | return EINA_FALSE; | ||
2170 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2171 | } | ||
2172 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
2173 | { | ||
2174 | char other_mem; | ||
2175 | if ((sscanf(v, "%hhd", &other_mem) != 1) && | ||
2176 | (sscanf(v, "%hhx", &other_mem) != 1) && | ||
2177 | (sscanf(v, "%hho", &other_mem) != 1)) | ||
2178 | return EINA_FALSE; | ||
2179 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2180 | } | ||
2181 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
2182 | { | ||
2183 | short other_mem; | ||
2184 | if ((sscanf(v, "%hd", &other_mem) != 1) && | ||
2185 | (sscanf(v, "%hx", &other_mem) != 1) && | ||
2186 | (sscanf(v, "%ho", &other_mem) != 1)) | ||
2187 | return EINA_FALSE; | ||
2188 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2189 | } | ||
2190 | else if (convert == EINA_VALUE_TYPE_INT) | ||
2191 | { | ||
2192 | int other_mem; | ||
2193 | if ((sscanf(v, "%d", &other_mem) != 1) && | ||
2194 | (sscanf(v, "%x", &other_mem) != 1) && | ||
2195 | (sscanf(v, "%o", &other_mem) != 1)) | ||
2196 | return EINA_FALSE; | ||
2197 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2198 | } | ||
2199 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
2200 | { | ||
2201 | long other_mem; | ||
2202 | if ((sscanf(v, "%ld", &other_mem) != 1) && | ||
2203 | (sscanf(v, "%lx", &other_mem) != 1) && | ||
2204 | (sscanf(v, "%lo", &other_mem) != 1)) | ||
2205 | return EINA_FALSE; | ||
2206 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2207 | } | ||
2208 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
2209 | { | ||
2210 | int64_t other_mem; | ||
2211 | if ((sscanf(v, "%"SCNd64, &other_mem) != 1) && | ||
2212 | (sscanf(v, "%"SCNx64, &other_mem) != 1) && | ||
2213 | (sscanf(v, "%"SCNo64, &other_mem) != 1)) | ||
2214 | return EINA_FALSE; | ||
2215 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2216 | } | ||
2217 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
2218 | { | ||
2219 | float other_mem; | ||
2220 | if (sscanf(v, "%f", &other_mem) != 1) | ||
2221 | return EINA_FALSE; | ||
2222 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2223 | } | ||
2224 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
2225 | { | ||
2226 | double other_mem; | ||
2227 | if (sscanf(v, "%lf", &other_mem) != 1) | ||
2228 | return EINA_FALSE; | ||
2229 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
2230 | } | ||
2231 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
2232 | convert == EINA_VALUE_TYPE_STRING) | ||
2233 | { | ||
2234 | return eina_value_type_pset(convert, convert_mem, &v); | ||
2235 | } | ||
2236 | else | ||
2237 | { | ||
2238 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
2239 | return EINA_FALSE; | ||
2240 | } | ||
2241 | |||
2242 | return EINA_TRUE; | ||
2243 | } | ||
2244 | |||
2245 | static Eina_Bool | ||
2246 | _eina_value_type_string_common_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
2247 | { | ||
2248 | memcpy(ptr, mem, sizeof(const char *)); | ||
2249 | return EINA_TRUE; | ||
2250 | } | ||
2251 | |||
2252 | static Eina_Bool | ||
2253 | _eina_value_type_stringshare_flush(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
2254 | { | ||
2255 | const char **tmem = mem; | ||
2256 | if (*tmem) | ||
2257 | { | ||
2258 | eina_stringshare_del(*tmem); | ||
2259 | *tmem = NULL; | ||
2260 | } | ||
2261 | return EINA_TRUE; | ||
2262 | } | ||
2263 | |||
2264 | static Eina_Bool | ||
2265 | _eina_value_type_stringshare_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
2266 | { | ||
2267 | const char * const*s = src; | ||
2268 | const char **d = dst; | ||
2269 | *d = eina_stringshare_add(*s); | ||
2270 | return EINA_TRUE; | ||
2271 | } | ||
2272 | |||
2273 | static Eina_Bool | ||
2274 | _eina_value_type_stringshare_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
2275 | { | ||
2276 | const char *str = va_arg(args, const char *); | ||
2277 | return eina_stringshare_replace((const char **)mem, str); | ||
2278 | } | ||
2279 | |||
2280 | static Eina_Bool | ||
2281 | _eina_value_type_stringshare_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
2282 | { | ||
2283 | const char * const *str = ptr; | ||
2284 | return eina_stringshare_replace((const char **)mem, *str); | ||
2285 | } | ||
2286 | |||
2287 | static Eina_Bool | ||
2288 | _eina_value_type_string_flush(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
2289 | { | ||
2290 | char **tmem = mem; | ||
2291 | if (*tmem) | ||
2292 | { | ||
2293 | free(*tmem); | ||
2294 | *tmem = NULL; | ||
2295 | } | ||
2296 | return EINA_TRUE; | ||
2297 | } | ||
2298 | |||
2299 | static Eina_Bool | ||
2300 | _eina_value_type_string_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
2301 | { | ||
2302 | const char * const *s = src; | ||
2303 | char **d = dst; | ||
2304 | if (*s == NULL) | ||
2305 | *d = NULL; | ||
2306 | else | ||
2307 | { | ||
2308 | *d = strdup(*s); | ||
2309 | if (*d == NULL) | ||
2310 | { | ||
2311 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
2312 | return EINA_FALSE; | ||
2313 | } | ||
2314 | } | ||
2315 | return EINA_TRUE; | ||
2316 | } | ||
2317 | |||
2318 | static Eina_Bool | ||
2319 | _eina_value_type_string_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
2320 | { | ||
2321 | char **tmem = mem; | ||
2322 | const char *str = va_arg(args, const char *); | ||
2323 | eina_error_set(0); | ||
2324 | if (str == *tmem) return EINA_TRUE; | ||
2325 | if (!str) | ||
2326 | { | ||
2327 | free(*tmem); | ||
2328 | *tmem = NULL; | ||
2329 | } | ||
2330 | else | ||
2331 | { | ||
2332 | char *tmp = strdup(str); | ||
2333 | if (!tmp) | ||
2334 | { | ||
2335 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
2336 | return EINA_FALSE; | ||
2337 | } | ||
2338 | free(*tmem); | ||
2339 | *tmem = tmp; | ||
2340 | } | ||
2341 | return EINA_TRUE; | ||
2342 | } | ||
2343 | |||
2344 | static Eina_Bool | ||
2345 | _eina_value_type_string_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
2346 | { | ||
2347 | char **tmem = mem; | ||
2348 | const char * const *str = ptr; | ||
2349 | eina_error_set(0); | ||
2350 | if (*str == *tmem) return EINA_TRUE; | ||
2351 | if (!*str) | ||
2352 | { | ||
2353 | free(*tmem); | ||
2354 | *tmem = NULL; | ||
2355 | } | ||
2356 | else | ||
2357 | { | ||
2358 | char *tmp = strdup(*str); | ||
2359 | if (!tmp) | ||
2360 | { | ||
2361 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
2362 | return EINA_FALSE; | ||
2363 | } | ||
2364 | free(*tmem); | ||
2365 | *tmem = tmp; | ||
2366 | } | ||
2367 | return EINA_TRUE; | ||
2368 | } | ||
2369 | |||
2370 | static Eina_Bool | ||
2371 | _eina_value_type_array_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
2372 | { | ||
2373 | memset(mem, 0, sizeof(Eina_Value_Array)); | ||
2374 | return EINA_TRUE; | ||
2375 | } | ||
2376 | |||
2377 | static Eina_Bool | ||
2378 | _eina_value_type_array_flush_elements(Eina_Value_Array *tmem) | ||
2379 | { | ||
2380 | const Eina_Value_Type *subtype = tmem->subtype; | ||
2381 | Eina_Bool ret = EINA_TRUE; | ||
2382 | unsigned char sz; | ||
2383 | char *ptr, *ptr_end; | ||
2384 | |||
2385 | if (!tmem->array) return EINA_TRUE; | ||
2386 | |||
2387 | sz = tmem->array->member_size; | ||
2388 | ptr = tmem->array->members; | ||
2389 | ptr_end = ptr + tmem->array->len * sz; | ||
2390 | |||
2391 | for (; ptr < ptr_end; ptr += sz) | ||
2392 | ret &= eina_value_type_flush(subtype, ptr); | ||
2393 | |||
2394 | eina_inarray_flush(tmem->array); | ||
2395 | return ret; | ||
2396 | } | ||
2397 | |||
2398 | static Eina_Bool | ||
2399 | _eina_value_type_array_flush(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
2400 | { | ||
2401 | Eina_Value_Array *tmem = mem; | ||
2402 | Eina_Bool ret =_eina_value_type_array_flush_elements(tmem); | ||
2403 | |||
2404 | if (tmem->array) eina_inarray_free(tmem->array); | ||
2405 | tmem->array = NULL; | ||
2406 | tmem->subtype = NULL; | ||
2407 | return ret; | ||
2408 | } | ||
2409 | |||
2410 | static Eina_Bool | ||
2411 | _eina_value_type_array_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
2412 | { | ||
2413 | const Eina_Value_Type *subtype; | ||
2414 | const Eina_Value_Array *s = src; | ||
2415 | Eina_Value_Array *d = dst; | ||
2416 | unsigned int i, count, sz; | ||
2417 | char *ptr, *ptr_end; | ||
2418 | |||
2419 | d->subtype = subtype = s->subtype; | ||
2420 | d->step = s->step; | ||
2421 | |||
2422 | if ((!s->array) || (!s->subtype)) | ||
2423 | { | ||
2424 | d->array = NULL; | ||
2425 | return EINA_TRUE; | ||
2426 | } | ||
2427 | |||
2428 | if (!subtype->copy) | ||
2429 | { | ||
2430 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
2431 | return EINA_FALSE; | ||
2432 | } | ||
2433 | |||
2434 | d->array = eina_inarray_new(subtype->value_size, s->step); | ||
2435 | if (!d->array) | ||
2436 | return EINA_FALSE; | ||
2437 | |||
2438 | sz = s->array->member_size; | ||
2439 | |||
2440 | count = eina_inarray_count(s->array); | ||
2441 | ptr = s->array->members; | ||
2442 | ptr_end = ptr + (count * sz); | ||
2443 | |||
2444 | for (i = 0; ptr < ptr_end; ptr += sz, i++) | ||
2445 | { | ||
2446 | void *imem = eina_inarray_alloc_at(d->array, i, 1); | ||
2447 | if (!imem) goto error; | ||
2448 | if (!subtype->copy(subtype, ptr, imem)) | ||
2449 | { | ||
2450 | eina_inarray_pop(d->array); | ||
2451 | goto error; | ||
2452 | } | ||
2453 | } | ||
2454 | |||
2455 | return EINA_TRUE; | ||
2456 | |||
2457 | error: | ||
2458 | _eina_value_type_array_flush_elements(d); | ||
2459 | return EINA_FALSE; | ||
2460 | } | ||
2461 | |||
2462 | static int | ||
2463 | _eina_value_type_array_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
2464 | { | ||
2465 | const Eina_Value_Type *subtype; | ||
2466 | const Eina_Value_Array *eva_a = a, *eva_b = b; | ||
2467 | const char *a_ptr, *a_ptr_end, *b_ptr; | ||
2468 | unsigned int count_a, count_b, count, sz; | ||
2469 | int cmp = 0; | ||
2470 | |||
2471 | if (eva_a->subtype != eva_b->subtype) | ||
2472 | { | ||
2473 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
2474 | return -1; | ||
2475 | } | ||
2476 | |||
2477 | subtype = eva_a->subtype; | ||
2478 | if (!subtype->compare) | ||
2479 | { | ||
2480 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
2481 | return 0; | ||
2482 | } | ||
2483 | |||
2484 | if ((!eva_a->array) && (!eva_b->array)) | ||
2485 | return 0; | ||
2486 | else if (!eva_a->array) | ||
2487 | return -1; | ||
2488 | else if (!eva_b->array) | ||
2489 | return 1; | ||
2490 | |||
2491 | count_a = eina_inarray_count(eva_a->array); | ||
2492 | count_b = eina_inarray_count(eva_b->array); | ||
2493 | |||
2494 | if (count_a <= count_b) | ||
2495 | count = count_a; | ||
2496 | else | ||
2497 | count = count_b; | ||
2498 | |||
2499 | sz = eva_a->array->member_size; | ||
2500 | |||
2501 | a_ptr = eva_a->array->members; | ||
2502 | a_ptr_end = a_ptr + (count * sz); | ||
2503 | b_ptr = eva_b->array->members; | ||
2504 | |||
2505 | for (; (cmp == 0) && (a_ptr < a_ptr_end); a_ptr += sz, b_ptr += sz) | ||
2506 | cmp = subtype->compare(subtype, a_ptr, b_ptr); | ||
2507 | |||
2508 | if (cmp == 0) | ||
2509 | { | ||
2510 | if (count_a < count_b) | ||
2511 | return -1; | ||
2512 | else if (count_a > count_b) | ||
2513 | return 1; | ||
2514 | return 0; | ||
2515 | } | ||
2516 | |||
2517 | return cmp; | ||
2518 | } | ||
2519 | |||
2520 | static Eina_Bool | ||
2521 | _eina_value_type_array_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
2522 | { | ||
2523 | const Eina_Value_Array *tmem = type_mem; | ||
2524 | Eina_Bool ret = EINA_FALSE; | ||
2525 | |||
2526 | if ((convert == EINA_VALUE_TYPE_STRING) || | ||
2527 | (convert == EINA_VALUE_TYPE_STRINGSHARE)) | ||
2528 | { | ||
2529 | Eina_Strbuf *str = eina_strbuf_new(); | ||
2530 | const char *ptr; | ||
2531 | if (!tmem->array) eina_strbuf_append(str, "[]"); | ||
2532 | else | ||
2533 | { | ||
2534 | const Eina_Value_Type *subtype = tmem->subtype; | ||
2535 | unsigned char sz; | ||
2536 | const char *ptr_end; | ||
2537 | Eina_Value tmp; | ||
2538 | Eina_Bool first = EINA_TRUE; | ||
2539 | |||
2540 | eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING); | ||
2541 | |||
2542 | eina_strbuf_append_char(str, '['); | ||
2543 | |||
2544 | sz = tmem->array->member_size; | ||
2545 | ptr = tmem->array->members; | ||
2546 | ptr_end = ptr + tmem->array->len * sz; | ||
2547 | for (; ptr < ptr_end; ptr += sz) | ||
2548 | { | ||
2549 | Eina_Bool r = EINA_FALSE; | ||
2550 | if (subtype->convert_to) | ||
2551 | { | ||
2552 | r = subtype->convert_to(subtype, EINA_VALUE_TYPE_STRING, | ||
2553 | ptr, tmp.value.buf); | ||
2554 | if (r) | ||
2555 | { | ||
2556 | if (first) first = EINA_FALSE; | ||
2557 | else eina_strbuf_append_length(str, ", ", 2); | ||
2558 | eina_strbuf_append(str, tmp.value.ptr); | ||
2559 | free(tmp.value.ptr); | ||
2560 | tmp.value.ptr = NULL; | ||
2561 | } | ||
2562 | } | ||
2563 | |||
2564 | if (!r) | ||
2565 | { | ||
2566 | if (first) | ||
2567 | { | ||
2568 | first = EINA_FALSE; | ||
2569 | eina_strbuf_append_char(str, '?'); | ||
2570 | } | ||
2571 | else | ||
2572 | eina_strbuf_append_length(str, ", ?", 3); | ||
2573 | } | ||
2574 | } | ||
2575 | |||
2576 | eina_strbuf_append_char(str, ']'); | ||
2577 | } | ||
2578 | ptr = eina_strbuf_string_get(str); | ||
2579 | ret = eina_value_type_pset(convert, convert_mem, &ptr); | ||
2580 | eina_strbuf_free(str); | ||
2581 | } | ||
2582 | else if ((tmem->array) && (tmem->array->len == 1)) | ||
2583 | { | ||
2584 | const Eina_Value_Type *subtype = tmem->subtype; | ||
2585 | void *imem = tmem->array->members; | ||
2586 | |||
2587 | if (subtype->convert_to) | ||
2588 | ret = subtype->convert_to(subtype, convert, imem, convert_mem); | ||
2589 | if ((!ret) && (convert->convert_from)) | ||
2590 | ret = convert->convert_from(convert, subtype, convert_mem, imem); | ||
2591 | } | ||
2592 | |||
2593 | if (!ret) | ||
2594 | { | ||
2595 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
2596 | return EINA_FALSE; | ||
2597 | } | ||
2598 | return EINA_TRUE; | ||
2599 | } | ||
2600 | |||
2601 | static Eina_Bool | ||
2602 | _eina_value_type_array_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem) | ||
2603 | { | ||
2604 | Eina_Value_Array *tmem = type_mem; | ||
2605 | Eina_Value_Array desc = {convert, tmem->step, NULL}; | ||
2606 | char *buf; | ||
2607 | void *imem; | ||
2608 | |||
2609 | if (!eina_value_type_pset(type, tmem, &desc)) | ||
2610 | return EINA_FALSE; | ||
2611 | |||
2612 | buf = alloca(convert->value_size); | ||
2613 | if (!eina_value_type_pget(convert, convert_mem, &buf)) | ||
2614 | return EINA_FALSE; | ||
2615 | |||
2616 | imem = eina_inarray_alloc_at(tmem->array, 0, 1); | ||
2617 | if (!imem) | ||
2618 | return EINA_FALSE; | ||
2619 | |||
2620 | if (!eina_value_type_setup(convert, imem)) goto error_setup; | ||
2621 | if (!eina_value_type_pset(convert, imem, &buf)) goto error_set; | ||
2622 | return EINA_TRUE; | ||
2623 | |||
2624 | error_set: | ||
2625 | eina_value_type_flush(convert, imem); | ||
2626 | error_setup: | ||
2627 | eina_inarray_remove_at(tmem->array, 0); | ||
2628 | return EINA_FALSE; | ||
2629 | } | ||
2630 | |||
2631 | static Eina_Bool | ||
2632 | _eina_value_type_array_pset(const Eina_Value_Type *type, void *mem, const void *ptr) | ||
2633 | { | ||
2634 | Eina_Value_Array *tmem = mem; | ||
2635 | const Eina_Value_Array *desc = ptr; | ||
2636 | Eina_Inarray *desc_array; | ||
2637 | |||
2638 | eina_error_set(0); | ||
2639 | if ((!tmem->subtype) && (!desc->subtype)) | ||
2640 | return EINA_TRUE; | ||
2641 | |||
2642 | desc_array = desc->array; | ||
2643 | if (desc_array) | ||
2644 | { | ||
2645 | Eina_Value_Array tmp; | ||
2646 | |||
2647 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
2648 | (desc_array->member_size == desc->subtype->value_size, EINA_FALSE); | ||
2649 | |||
2650 | if (desc_array == tmem->array) | ||
2651 | { | ||
2652 | tmem->subtype = desc->subtype; | ||
2653 | return EINA_TRUE; | ||
2654 | } | ||
2655 | |||
2656 | if (!_eina_value_type_array_copy(type, desc, &tmp)) | ||
2657 | return EINA_FALSE; | ||
2658 | |||
2659 | _eina_value_type_array_flush(type, tmem); | ||
2660 | memcpy(tmem, &tmp, sizeof(tmp)); | ||
2661 | return EINA_TRUE; | ||
2662 | } | ||
2663 | |||
2664 | if (tmem->array) | ||
2665 | { | ||
2666 | _eina_value_type_array_flush_elements(tmem); | ||
2667 | eina_inarray_setup(tmem->array, desc->subtype->value_size, desc->step); | ||
2668 | } | ||
2669 | else | ||
2670 | { | ||
2671 | tmem->array = eina_inarray_new(desc->subtype->value_size, desc->step); | ||
2672 | if (!tmem->array) | ||
2673 | return EINA_FALSE; | ||
2674 | } | ||
2675 | |||
2676 | tmem->subtype = desc->subtype; | ||
2677 | return EINA_TRUE; | ||
2678 | } | ||
2679 | |||
2680 | static Eina_Bool | ||
2681 | _eina_value_type_array_vset(const Eina_Value_Type *type, void *mem, va_list args) | ||
2682 | { | ||
2683 | const Eina_Value_Array desc = va_arg(args, Eina_Value_Array); | ||
2684 | _eina_value_type_array_pset(type, mem, &desc); | ||
2685 | return EINA_TRUE; | ||
2686 | } | ||
2687 | |||
2688 | static Eina_Bool | ||
2689 | _eina_value_type_array_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
2690 | { | ||
2691 | memcpy(ptr, mem, sizeof(Eina_Value_Array)); | ||
2692 | return EINA_TRUE; | ||
2693 | } | ||
2694 | |||
2695 | static const Eina_Value_Type _EINA_VALUE_TYPE_ARRAY = { | ||
2696 | EINA_VALUE_TYPE_VERSION, | ||
2697 | sizeof(Eina_Value_Array), | ||
2698 | "Eina_Value_Array", | ||
2699 | _eina_value_type_array_setup, | ||
2700 | _eina_value_type_array_flush, | ||
2701 | _eina_value_type_array_copy, | ||
2702 | _eina_value_type_array_compare, | ||
2703 | _eina_value_type_array_convert_to, | ||
2704 | _eina_value_type_array_convert_from, | ||
2705 | _eina_value_type_array_vset, | ||
2706 | _eina_value_type_array_pset, | ||
2707 | _eina_value_type_array_pget | ||
2708 | }; | ||
2709 | |||
2710 | static Eina_Bool | ||
2711 | _eina_value_type_list_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
2712 | { | ||
2713 | memset(mem, 0, sizeof(Eina_Value_List)); | ||
2714 | return EINA_TRUE; | ||
2715 | } | ||
2716 | |||
2717 | static Eina_Bool | ||
2718 | _eina_value_type_list_flush_elements(Eina_Value_List *tmem) | ||
2719 | { | ||
2720 | const Eina_Value_Type *subtype = tmem->subtype; | ||
2721 | Eina_Bool ret = EINA_TRUE; | ||
2722 | |||
2723 | if (!tmem->list) return EINA_TRUE; | ||
2724 | |||
2725 | while (tmem->list) | ||
2726 | { | ||
2727 | void *mem = eina_value_list_node_memory_get(tmem->subtype, tmem->list); | ||
2728 | ret &= eina_value_type_flush(subtype, mem); | ||
2729 | eina_value_list_node_memory_flush(tmem->subtype, tmem->list); | ||
2730 | tmem->list = eina_list_remove_list(tmem->list, tmem->list); | ||
2731 | } | ||
2732 | |||
2733 | return ret; | ||
2734 | } | ||
2735 | |||
2736 | static Eina_Bool | ||
2737 | _eina_value_type_list_flush(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
2738 | { | ||
2739 | Eina_Value_List *tmem = mem; | ||
2740 | Eina_Bool ret =_eina_value_type_list_flush_elements(tmem); | ||
2741 | |||
2742 | if (tmem->list) eina_list_free(tmem->list); | ||
2743 | tmem->list = NULL; | ||
2744 | tmem->subtype = NULL; | ||
2745 | return ret; | ||
2746 | } | ||
2747 | |||
2748 | static Eina_Bool | ||
2749 | _eina_value_type_list_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
2750 | { | ||
2751 | const Eina_Value_Type *subtype; | ||
2752 | const Eina_Value_List *s = src; | ||
2753 | Eina_Value_List *d = dst; | ||
2754 | const Eina_List *snode; | ||
2755 | |||
2756 | d->subtype = subtype = s->subtype; | ||
2757 | if ((!s->list) || (!s->subtype)) | ||
2758 | { | ||
2759 | d->list = NULL; | ||
2760 | return EINA_TRUE; | ||
2761 | } | ||
2762 | |||
2763 | if (!subtype->copy) | ||
2764 | { | ||
2765 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
2766 | return EINA_FALSE; | ||
2767 | } | ||
2768 | |||
2769 | d->list = NULL; | ||
2770 | for (snode = s->list; snode != NULL; snode = snode->next) | ||
2771 | { | ||
2772 | const void *ptr = eina_value_list_node_memory_get(subtype, snode); | ||
2773 | Eina_List *dnode; | ||
2774 | void *imem; | ||
2775 | |||
2776 | d->list = eina_list_append(d->list, (void*)1L); | ||
2777 | dnode = eina_list_last(d->list); | ||
2778 | EINA_SAFETY_ON_NULL_GOTO(dnode, error); | ||
2779 | EINA_SAFETY_ON_FALSE_GOTO(dnode->data == (void*)1L, error); | ||
2780 | |||
2781 | imem = eina_value_list_node_memory_setup(subtype, dnode); | ||
2782 | if (!subtype->copy(subtype, ptr, imem)) | ||
2783 | { | ||
2784 | eina_value_list_node_memory_flush(subtype, dnode); | ||
2785 | d->list = eina_list_remove_list(d->list, dnode); | ||
2786 | goto error; | ||
2787 | } | ||
2788 | } | ||
2789 | return EINA_TRUE; | ||
2790 | |||
2791 | error: | ||
2792 | _eina_value_type_list_flush_elements(d); | ||
2793 | return EINA_FALSE; | ||
2794 | } | ||
2795 | |||
2796 | static int | ||
2797 | _eina_value_type_list_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
2798 | { | ||
2799 | const Eina_Value_Type *subtype; | ||
2800 | const Eina_Value_List *eva_a = a, *eva_b = b; | ||
2801 | const Eina_List *anode, *bnode; | ||
2802 | int cmp = 0; | ||
2803 | |||
2804 | if (eva_a->subtype != eva_b->subtype) | ||
2805 | { | ||
2806 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
2807 | return -1; | ||
2808 | } | ||
2809 | |||
2810 | subtype = eva_a->subtype; | ||
2811 | if (!subtype->compare) | ||
2812 | { | ||
2813 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
2814 | return 0; | ||
2815 | } | ||
2816 | |||
2817 | if ((!eva_a->list) && (!eva_b->list)) | ||
2818 | return 0; | ||
2819 | else if (!eva_a->list) | ||
2820 | return -1; | ||
2821 | else if (!eva_b->list) | ||
2822 | return 1; | ||
2823 | |||
2824 | for (anode = eva_a->list, bnode = eva_b->list; | ||
2825 | (cmp == 0) && (anode) && (bnode); | ||
2826 | anode = anode->next, bnode = bnode->next) | ||
2827 | { | ||
2828 | const void *amem = eina_value_list_node_memory_get(subtype, anode); | ||
2829 | const void *bmem = eina_value_list_node_memory_get(subtype, bnode); | ||
2830 | cmp = subtype->compare(subtype, amem, bmem); | ||
2831 | } | ||
2832 | |||
2833 | if (cmp == 0) | ||
2834 | { | ||
2835 | if ((!anode) && (bnode)) | ||
2836 | return -1; | ||
2837 | else if ((anode) && (!bnode)) | ||
2838 | return 1; | ||
2839 | return 0; | ||
2840 | } | ||
2841 | |||
2842 | return cmp; | ||
2843 | } | ||
2844 | |||
2845 | static Eina_Bool | ||
2846 | _eina_value_type_list_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
2847 | { | ||
2848 | const Eina_Value_List *tmem = type_mem; | ||
2849 | Eina_Bool ret = EINA_FALSE; | ||
2850 | |||
2851 | if ((convert == EINA_VALUE_TYPE_STRING) || | ||
2852 | (convert == EINA_VALUE_TYPE_STRINGSHARE)) | ||
2853 | { | ||
2854 | Eina_Strbuf *str = eina_strbuf_new(); | ||
2855 | const char *s; | ||
2856 | if (!tmem->list) eina_strbuf_append(str, "[]"); | ||
2857 | else | ||
2858 | { | ||
2859 | const Eina_Value_Type *subtype = tmem->subtype; | ||
2860 | const Eina_List *node; | ||
2861 | Eina_Value tmp; | ||
2862 | Eina_Bool first = EINA_TRUE; | ||
2863 | |||
2864 | eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING); | ||
2865 | |||
2866 | eina_strbuf_append_char(str, '['); | ||
2867 | |||
2868 | for (node = tmem->list; node != NULL; node = node->next) | ||
2869 | { | ||
2870 | Eina_Bool r = EINA_FALSE; | ||
2871 | |||
2872 | if (subtype->convert_to) | ||
2873 | { | ||
2874 | const void *ptr; | ||
2875 | ptr = eina_value_list_node_memory_get(subtype, node); | ||
2876 | r = subtype->convert_to(subtype, EINA_VALUE_TYPE_STRING, | ||
2877 | ptr, tmp.value.buf); | ||
2878 | if (r) | ||
2879 | { | ||
2880 | if (first) first = EINA_FALSE; | ||
2881 | else eina_strbuf_append_length(str, ", ", 2); | ||
2882 | eina_strbuf_append(str, tmp.value.ptr); | ||
2883 | free(tmp.value.ptr); | ||
2884 | tmp.value.ptr = NULL; | ||
2885 | } | ||
2886 | } | ||
2887 | |||
2888 | if (!r) | ||
2889 | { | ||
2890 | if (first) | ||
2891 | { | ||
2892 | first = EINA_FALSE; | ||
2893 | eina_strbuf_append_char(str, '?'); | ||
2894 | } | ||
2895 | else | ||
2896 | eina_strbuf_append_length(str, ", ?", 3); | ||
2897 | } | ||
2898 | } | ||
2899 | |||
2900 | eina_strbuf_append_char(str, ']'); | ||
2901 | } | ||
2902 | s = eina_strbuf_string_get(str); | ||
2903 | ret = eina_value_type_pset(convert, convert_mem, &s); | ||
2904 | eina_strbuf_free(str); | ||
2905 | } | ||
2906 | else if ((tmem->list) && (tmem->list->next == NULL)) | ||
2907 | { | ||
2908 | const Eina_Value_Type *subtype = tmem->subtype; | ||
2909 | void *imem = eina_value_list_node_memory_get(subtype, tmem->list); | ||
2910 | |||
2911 | if (subtype->convert_to) | ||
2912 | ret = subtype->convert_to(subtype, convert, imem, convert_mem); | ||
2913 | if ((!ret) && (convert->convert_from)) | ||
2914 | ret = convert->convert_from(convert, subtype, convert_mem, imem); | ||
2915 | } | ||
2916 | |||
2917 | if (!ret) | ||
2918 | { | ||
2919 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
2920 | return EINA_FALSE; | ||
2921 | } | ||
2922 | return EINA_TRUE; | ||
2923 | } | ||
2924 | |||
2925 | static Eina_Bool | ||
2926 | _eina_value_type_list_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem) | ||
2927 | { | ||
2928 | Eina_Value_List *tmem = type_mem; | ||
2929 | Eina_Value_List desc = {convert, NULL}; | ||
2930 | Eina_List *node; | ||
2931 | char *buf; | ||
2932 | void *imem; | ||
2933 | |||
2934 | if (!eina_value_type_pset(type, tmem, &desc)) | ||
2935 | return EINA_FALSE; | ||
2936 | |||
2937 | buf = alloca(convert->value_size); | ||
2938 | if (!eina_value_type_pget(convert, convert_mem, &buf)) | ||
2939 | return EINA_FALSE; | ||
2940 | |||
2941 | tmem->list = eina_list_append(tmem->list, (void*)1L); | ||
2942 | node = eina_list_last(tmem->list); | ||
2943 | EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE); | ||
2944 | EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE); | ||
2945 | |||
2946 | imem = eina_value_list_node_memory_setup(tmem->subtype, node); | ||
2947 | if (!imem) | ||
2948 | { | ||
2949 | tmem->list = eina_list_remove_list(tmem->list, node); | ||
2950 | return EINA_FALSE; | ||
2951 | } | ||
2952 | |||
2953 | if (!eina_value_type_setup(tmem->subtype, imem)) goto error_setup; | ||
2954 | if (!eina_value_type_pset(tmem->subtype, imem, &buf)) goto error_set; | ||
2955 | return EINA_TRUE; | ||
2956 | |||
2957 | error_set: | ||
2958 | eina_value_type_flush(tmem->subtype, imem); | ||
2959 | error_setup: | ||
2960 | eina_value_list_node_memory_flush(tmem->subtype, node); | ||
2961 | tmem->list = eina_list_remove_list(tmem->list, node); | ||
2962 | return EINA_FALSE; | ||
2963 | } | ||
2964 | |||
2965 | static Eina_Bool | ||
2966 | _eina_value_type_list_pset(const Eina_Value_Type *type, void *mem, const void *ptr) | ||
2967 | { | ||
2968 | Eina_Value_List *tmem = mem; | ||
2969 | const Eina_Value_List *desc = ptr; | ||
2970 | |||
2971 | eina_error_set(0); | ||
2972 | if ((!tmem->subtype) && (!desc->subtype)) | ||
2973 | return EINA_TRUE; | ||
2974 | |||
2975 | if ((tmem->list) && (tmem->list == desc->list)) | ||
2976 | { | ||
2977 | tmem->subtype = desc->subtype; | ||
2978 | return EINA_TRUE; | ||
2979 | } | ||
2980 | |||
2981 | if (desc->list) | ||
2982 | { | ||
2983 | Eina_Value_List tmp; | ||
2984 | |||
2985 | if (!_eina_value_type_list_copy(type, desc, &tmp)) | ||
2986 | return EINA_FALSE; | ||
2987 | |||
2988 | _eina_value_type_list_flush(type, tmem); | ||
2989 | memcpy(tmem, &tmp, sizeof(tmp)); | ||
2990 | return EINA_TRUE; | ||
2991 | } | ||
2992 | |||
2993 | _eina_value_type_list_flush_elements(tmem); | ||
2994 | |||
2995 | tmem->subtype = desc->subtype; | ||
2996 | return EINA_TRUE; | ||
2997 | } | ||
2998 | |||
2999 | static Eina_Bool | ||
3000 | _eina_value_type_list_vset(const Eina_Value_Type *type, void *mem, va_list args) | ||
3001 | { | ||
3002 | const Eina_Value_List desc = va_arg(args, Eina_Value_List); | ||
3003 | _eina_value_type_list_pset(type, mem, &desc); | ||
3004 | return EINA_TRUE; | ||
3005 | } | ||
3006 | |||
3007 | static Eina_Bool | ||
3008 | _eina_value_type_list_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
3009 | { | ||
3010 | memcpy(ptr, mem, sizeof(Eina_Value_List)); | ||
3011 | return EINA_TRUE; | ||
3012 | } | ||
3013 | |||
3014 | static const Eina_Value_Type _EINA_VALUE_TYPE_LIST = { | ||
3015 | EINA_VALUE_TYPE_VERSION, | ||
3016 | sizeof(Eina_Value_List), | ||
3017 | "Eina_Value_List", | ||
3018 | _eina_value_type_list_setup, | ||
3019 | _eina_value_type_list_flush, | ||
3020 | _eina_value_type_list_copy, | ||
3021 | _eina_value_type_list_compare, | ||
3022 | _eina_value_type_list_convert_to, | ||
3023 | _eina_value_type_list_convert_from, | ||
3024 | _eina_value_type_list_vset, | ||
3025 | _eina_value_type_list_pset, | ||
3026 | _eina_value_type_list_pget | ||
3027 | }; | ||
3028 | |||
3029 | static Eina_Bool | ||
3030 | _eina_value_type_hash_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
3031 | { | ||
3032 | memset(mem, 0, sizeof(Eina_Value_Hash)); | ||
3033 | return EINA_TRUE; | ||
3034 | } | ||
3035 | |||
3036 | struct _eina_value_type_hash_flush_each_ctx | ||
3037 | { | ||
3038 | const Eina_Value_Type *subtype; | ||
3039 | Eina_Bool ret; | ||
3040 | }; | ||
3041 | |||
3042 | static Eina_Bool | ||
3043 | _eina_value_type_hash_flush_each(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *mem, void *user_data) | ||
3044 | { | ||
3045 | struct _eina_value_type_hash_flush_each_ctx *ctx = user_data; | ||
3046 | ctx->ret &= eina_value_type_flush(ctx->subtype, mem); | ||
3047 | free(mem); | ||
3048 | return EINA_TRUE; | ||
3049 | } | ||
3050 | |||
3051 | static Eina_Bool | ||
3052 | _eina_value_type_hash_flush_elements(Eina_Value_Hash *tmem) | ||
3053 | { | ||
3054 | struct _eina_value_type_hash_flush_each_ctx ctx = { | ||
3055 | tmem->subtype, | ||
3056 | EINA_TRUE | ||
3057 | }; | ||
3058 | |||
3059 | if (!tmem->hash) return EINA_TRUE; | ||
3060 | |||
3061 | eina_hash_foreach(tmem->hash, _eina_value_type_hash_flush_each, &ctx); | ||
3062 | eina_hash_free(tmem->hash); | ||
3063 | tmem->hash = NULL; | ||
3064 | return ctx.ret; | ||
3065 | } | ||
3066 | |||
3067 | static Eina_Bool | ||
3068 | _eina_value_type_hash_flush(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
3069 | { | ||
3070 | Eina_Value_Hash *tmem = mem; | ||
3071 | Eina_Bool ret =_eina_value_type_hash_flush_elements(tmem); | ||
3072 | tmem->subtype = NULL; | ||
3073 | return ret; | ||
3074 | } | ||
3075 | |||
3076 | static unsigned int | ||
3077 | _eina_value_hash_key_length(const void *key) | ||
3078 | { | ||
3079 | if (!key) | ||
3080 | return 0; | ||
3081 | return (int)strlen(key) + 1; | ||
3082 | } | ||
3083 | |||
3084 | static int | ||
3085 | _eina_value_hash_key_cmp(const void *key1, int key1_len, const void *key2, int key2_len) | ||
3086 | { | ||
3087 | int r = key1_len - key2_len; | ||
3088 | if (r != 0) | ||
3089 | return r; | ||
3090 | return strcmp(key1, key2); | ||
3091 | } | ||
3092 | |||
3093 | static Eina_Bool | ||
3094 | _eina_value_type_hash_create(Eina_Value_Hash *desc) | ||
3095 | { | ||
3096 | if (!desc->buckets_power_size) | ||
3097 | desc->buckets_power_size = 5; | ||
3098 | |||
3099 | desc->hash = eina_hash_new(_eina_value_hash_key_length, | ||
3100 | _eina_value_hash_key_cmp, | ||
3101 | EINA_KEY_HASH(eina_hash_superfast), | ||
3102 | NULL, desc->buckets_power_size); | ||
3103 | return !!desc->hash; | ||
3104 | } | ||
3105 | |||
3106 | struct _eina_value_type_hash_copy_each_ctx | ||
3107 | { | ||
3108 | const Eina_Value_Type *subtype; | ||
3109 | Eina_Value_Hash *dest; | ||
3110 | Eina_Bool ret; | ||
3111 | }; | ||
3112 | |||
3113 | static Eina_Bool | ||
3114 | _eina_value_type_hash_copy_each(const Eina_Hash *hash __UNUSED__, const void *key, void *_ptr, void *user_data) | ||
3115 | { | ||
3116 | struct _eina_value_type_hash_copy_each_ctx *ctx = user_data; | ||
3117 | const void *ptr = _ptr; | ||
3118 | void *imem = malloc(ctx->subtype->value_size); | ||
3119 | if (!imem) | ||
3120 | { | ||
3121 | ctx->ret = EINA_FALSE; | ||
3122 | return EINA_FALSE; | ||
3123 | } | ||
3124 | if (!ctx->subtype->copy(ctx->subtype, ptr, imem)) | ||
3125 | { | ||
3126 | free(imem); | ||
3127 | ctx->ret = EINA_FALSE; | ||
3128 | return EINA_FALSE; | ||
3129 | } | ||
3130 | if (!eina_hash_add(ctx->dest->hash, key, imem)) | ||
3131 | { | ||
3132 | eina_value_type_flush(ctx->subtype, imem); | ||
3133 | free(imem); | ||
3134 | ctx->ret = EINA_FALSE; | ||
3135 | return EINA_FALSE; | ||
3136 | } | ||
3137 | return EINA_TRUE; | ||
3138 | } | ||
3139 | |||
3140 | static Eina_Bool | ||
3141 | _eina_value_type_hash_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
3142 | { | ||
3143 | const Eina_Value_Hash *s = src; | ||
3144 | Eina_Value_Hash *d = dst; | ||
3145 | struct _eina_value_type_hash_copy_each_ctx ctx = {s->subtype, d, EINA_TRUE}; | ||
3146 | |||
3147 | d->subtype = s->subtype; | ||
3148 | d->buckets_power_size = s->buckets_power_size; | ||
3149 | |||
3150 | if ((!s->hash) || (!s->subtype)) | ||
3151 | { | ||
3152 | d->hash = NULL; | ||
3153 | return EINA_TRUE; | ||
3154 | } | ||
3155 | |||
3156 | if (!s->subtype->copy) | ||
3157 | { | ||
3158 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
3159 | return EINA_FALSE; | ||
3160 | } | ||
3161 | |||
3162 | if (!_eina_value_type_hash_create(d)) | ||
3163 | return EINA_FALSE; | ||
3164 | |||
3165 | eina_hash_foreach(s->hash, _eina_value_type_hash_copy_each, &ctx); | ||
3166 | if (!ctx.ret) | ||
3167 | { | ||
3168 | _eina_value_type_hash_flush_elements(d); | ||
3169 | return EINA_FALSE; | ||
3170 | } | ||
3171 | return EINA_TRUE; | ||
3172 | } | ||
3173 | |||
3174 | struct _eina_value_type_hash_compare_each_ctx | ||
3175 | { | ||
3176 | const Eina_Value_Type *subtype; | ||
3177 | const Eina_Hash *other; | ||
3178 | int cmp; | ||
3179 | }; | ||
3180 | |||
3181 | static Eina_Bool | ||
3182 | _eina_value_type_hash_compare_each(const Eina_Hash *hash __UNUSED__, const void *key, void *_ptr, void *user_data) | ||
3183 | { | ||
3184 | struct _eina_value_type_hash_compare_each_ctx *ctx = user_data; | ||
3185 | const void *self_ptr = _ptr; | ||
3186 | const void *other_ptr = eina_hash_find(ctx->other, key); | ||
3187 | if (!other_ptr) return EINA_TRUE; | ||
3188 | ctx->cmp = ctx->subtype->compare(ctx->subtype, self_ptr, other_ptr); | ||
3189 | return ctx->cmp == 0; | ||
3190 | } | ||
3191 | |||
3192 | static int | ||
3193 | _eina_value_type_hash_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
3194 | { | ||
3195 | const Eina_Value_Hash *eva_a = a, *eva_b = b; | ||
3196 | struct _eina_value_type_hash_compare_each_ctx ctx = { | ||
3197 | eva_a->subtype, eva_b->hash, 0 | ||
3198 | }; | ||
3199 | |||
3200 | if (eva_a->subtype != eva_b->subtype) | ||
3201 | { | ||
3202 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
3203 | return -1; | ||
3204 | } | ||
3205 | |||
3206 | if (!eva_a->subtype->compare) | ||
3207 | { | ||
3208 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
3209 | return 0; | ||
3210 | } | ||
3211 | |||
3212 | if ((!eva_a->hash) && (!eva_b->hash)) | ||
3213 | return 0; | ||
3214 | else if (!eva_a->hash) | ||
3215 | return -1; | ||
3216 | else if (!eva_b->hash) | ||
3217 | return 1; | ||
3218 | |||
3219 | eina_hash_foreach(eva_a->hash, _eina_value_type_hash_compare_each, &ctx); | ||
3220 | if (ctx.cmp == 0) | ||
3221 | { | ||
3222 | unsigned int count_a = eina_hash_population(eva_a->hash); | ||
3223 | unsigned int count_b = eina_hash_population(eva_b->hash); | ||
3224 | if (count_a < count_b) | ||
3225 | return -1; | ||
3226 | else if (count_a > count_b) | ||
3227 | return 1; | ||
3228 | return 0; | ||
3229 | } | ||
3230 | |||
3231 | return ctx.cmp; | ||
3232 | } | ||
3233 | |||
3234 | static Eina_Bool | ||
3235 | _eina_value_type_hash_find_first(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *ptr, void *user_data) | ||
3236 | { | ||
3237 | void **ret = user_data; | ||
3238 | *ret = ptr; | ||
3239 | return EINA_FALSE; | ||
3240 | } | ||
3241 | |||
3242 | struct _eina_value_type_hash_convert_to_string_each_ctx | ||
3243 | { | ||
3244 | const Eina_Value_Type *subtype; | ||
3245 | Eina_Strbuf *str; | ||
3246 | Eina_Value tmp; | ||
3247 | Eina_Bool first; | ||
3248 | }; | ||
3249 | |||
3250 | static Eina_Bool | ||
3251 | _eina_value_type_hash_convert_to_string_each(const Eina_Hash *hash __UNUSED__, const void *_key, void *_ptr, void *user_data) | ||
3252 | { | ||
3253 | struct _eina_value_type_hash_convert_to_string_each_ctx *ctx = user_data; | ||
3254 | const char *key = _key; | ||
3255 | const void *ptr = _ptr; | ||
3256 | Eina_Bool r = EINA_FALSE; | ||
3257 | |||
3258 | if (ctx->first) ctx->first = EINA_FALSE; | ||
3259 | else eina_strbuf_append_length(ctx->str, ", ", 2); | ||
3260 | |||
3261 | eina_strbuf_append(ctx->str, key); | ||
3262 | eina_strbuf_append_length(ctx->str, ": ", 2); | ||
3263 | |||
3264 | if (ctx->subtype->convert_to) | ||
3265 | { | ||
3266 | r = ctx->subtype->convert_to(ctx->subtype, EINA_VALUE_TYPE_STRING, | ||
3267 | ptr, ctx->tmp.value.buf); | ||
3268 | if (r) | ||
3269 | { | ||
3270 | eina_strbuf_append(ctx->str, ctx->tmp.value.ptr); | ||
3271 | free(ctx->tmp.value.ptr); | ||
3272 | ctx->tmp.value.ptr = NULL; | ||
3273 | } | ||
3274 | } | ||
3275 | |||
3276 | if (!r) | ||
3277 | eina_strbuf_append_char(ctx->str, '?'); | ||
3278 | |||
3279 | return EINA_TRUE; | ||
3280 | } | ||
3281 | |||
3282 | static Eina_Bool | ||
3283 | _eina_value_type_hash_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
3284 | { | ||
3285 | const Eina_Value_Hash *tmem = type_mem; | ||
3286 | Eina_Bool ret = EINA_FALSE; | ||
3287 | |||
3288 | if ((convert == EINA_VALUE_TYPE_STRING) || | ||
3289 | (convert == EINA_VALUE_TYPE_STRINGSHARE)) | ||
3290 | { | ||
3291 | Eina_Strbuf *str = eina_strbuf_new(); | ||
3292 | const char *s; | ||
3293 | if (!tmem->hash) eina_strbuf_append(str, "{}"); | ||
3294 | else | ||
3295 | { | ||
3296 | struct _eina_value_type_hash_convert_to_string_each_ctx ctx; | ||
3297 | |||
3298 | ctx.subtype = tmem->subtype; | ||
3299 | ctx.str = str; | ||
3300 | ctx.first = EINA_TRUE; | ||
3301 | eina_value_setup(&ctx.tmp, EINA_VALUE_TYPE_STRING); | ||
3302 | |||
3303 | eina_strbuf_append_char(str, '{'); | ||
3304 | |||
3305 | eina_hash_foreach(tmem->hash, | ||
3306 | _eina_value_type_hash_convert_to_string_each, | ||
3307 | &ctx); | ||
3308 | |||
3309 | eina_strbuf_append_char(str, '}'); | ||
3310 | } | ||
3311 | s = eina_strbuf_string_get(str); | ||
3312 | ret = eina_value_type_pset(convert, convert_mem, &s); | ||
3313 | eina_strbuf_free(str); | ||
3314 | } | ||
3315 | else if ((tmem->hash) && (eina_hash_population(tmem->hash) == 1)) | ||
3316 | { | ||
3317 | const Eina_Value_Type *subtype = tmem->subtype; | ||
3318 | void *imem = NULL; | ||
3319 | |||
3320 | eina_hash_foreach(tmem->hash, _eina_value_type_hash_find_first, &imem); | ||
3321 | if (!imem) /* shouldn't happen... */ | ||
3322 | ret = EINA_FALSE; | ||
3323 | else | ||
3324 | { | ||
3325 | if (subtype->convert_to) | ||
3326 | ret = subtype->convert_to(subtype, convert, imem, convert_mem); | ||
3327 | if ((!ret) && (convert->convert_from)) | ||
3328 | ret = convert->convert_from(convert, subtype, convert_mem, imem); | ||
3329 | } | ||
3330 | } | ||
3331 | |||
3332 | if (!ret) | ||
3333 | { | ||
3334 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
3335 | return EINA_FALSE; | ||
3336 | } | ||
3337 | return EINA_TRUE; | ||
3338 | } | ||
3339 | |||
3340 | static Eina_Bool | ||
3341 | _eina_value_type_hash_pset(const Eina_Value_Type *type, void *mem, const void *ptr) | ||
3342 | { | ||
3343 | Eina_Value_Hash *tmem = mem; | ||
3344 | const Eina_Value_Hash *desc = ptr; | ||
3345 | |||
3346 | eina_error_set(0); | ||
3347 | if ((!tmem->subtype) && (!desc->subtype)) | ||
3348 | return EINA_TRUE; | ||
3349 | |||
3350 | if ((tmem->hash) && (tmem->hash == desc->hash)) | ||
3351 | { | ||
3352 | tmem->subtype = desc->subtype; | ||
3353 | return EINA_TRUE; | ||
3354 | } | ||
3355 | |||
3356 | if (desc->hash) | ||
3357 | { | ||
3358 | Eina_Value_Hash tmp; | ||
3359 | |||
3360 | if (!_eina_value_type_hash_copy(type, desc, &tmp)) | ||
3361 | return EINA_FALSE; | ||
3362 | |||
3363 | _eina_value_type_hash_flush(type, tmem); | ||
3364 | memcpy(tmem, &tmp, sizeof(tmp)); | ||
3365 | return EINA_TRUE; | ||
3366 | } | ||
3367 | |||
3368 | if (tmem->hash) _eina_value_type_hash_flush_elements(tmem); | ||
3369 | |||
3370 | tmem->subtype = desc->subtype; | ||
3371 | if (!_eina_value_type_hash_create(tmem)) | ||
3372 | return EINA_FALSE; | ||
3373 | |||
3374 | return EINA_TRUE; | ||
3375 | } | ||
3376 | |||
3377 | static Eina_Bool | ||
3378 | _eina_value_type_hash_vset(const Eina_Value_Type *type, void *mem, va_list args) | ||
3379 | { | ||
3380 | const Eina_Value_Hash desc = va_arg(args, Eina_Value_Hash); | ||
3381 | _eina_value_type_hash_pset(type, mem, &desc); | ||
3382 | return EINA_TRUE; | ||
3383 | } | ||
3384 | |||
3385 | static Eina_Bool | ||
3386 | _eina_value_type_hash_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
3387 | { | ||
3388 | memcpy(ptr, mem, sizeof(Eina_Value_Hash)); | ||
3389 | return EINA_TRUE; | ||
3390 | } | ||
3391 | |||
3392 | static const Eina_Value_Type _EINA_VALUE_TYPE_HASH = { | ||
3393 | EINA_VALUE_TYPE_VERSION, | ||
3394 | sizeof(Eina_Value_Hash), | ||
3395 | "Eina_Value_Hash", | ||
3396 | _eina_value_type_hash_setup, | ||
3397 | _eina_value_type_hash_flush, | ||
3398 | _eina_value_type_hash_copy, | ||
3399 | _eina_value_type_hash_compare, | ||
3400 | _eina_value_type_hash_convert_to, | ||
3401 | NULL, /* no convert from */ | ||
3402 | _eina_value_type_hash_vset, | ||
3403 | _eina_value_type_hash_pset, | ||
3404 | _eina_value_type_hash_pget | ||
3405 | }; | ||
3406 | |||
3407 | static Eina_Bool | ||
3408 | _eina_value_type_timeval_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
3409 | { | ||
3410 | memset(mem, 0, sizeof(struct timeval)); | ||
3411 | return EINA_TRUE; | ||
3412 | } | ||
3413 | |||
3414 | static Eina_Bool | ||
3415 | _eina_value_type_timeval_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) | ||
3416 | { | ||
3417 | return EINA_TRUE; | ||
3418 | } | ||
3419 | |||
3420 | static Eina_Bool | ||
3421 | _eina_value_type_timeval_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
3422 | { | ||
3423 | const struct timeval *s = src; | ||
3424 | struct timeval *d = dst; | ||
3425 | *d = *s; | ||
3426 | return EINA_TRUE; | ||
3427 | } | ||
3428 | |||
3429 | static inline struct timeval _eina_value_type_timeval_fix(const struct timeval *input) | ||
3430 | { | ||
3431 | struct timeval ret = *input; | ||
3432 | if (EINA_UNLIKELY(ret.tv_usec < 0)) | ||
3433 | { | ||
3434 | ret.tv_sec -= 1; | ||
3435 | ret.tv_usec += 1e6; | ||
3436 | } | ||
3437 | return ret; | ||
3438 | } | ||
3439 | |||
3440 | static int | ||
3441 | _eina_value_type_timeval_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
3442 | { | ||
3443 | struct timeval va = _eina_value_type_timeval_fix(a); | ||
3444 | struct timeval vb = _eina_value_type_timeval_fix(b); | ||
3445 | |||
3446 | if (va.tv_sec < vb.tv_sec) | ||
3447 | return -1; | ||
3448 | else if (va.tv_sec > vb.tv_sec) | ||
3449 | return 1; | ||
3450 | |||
3451 | if (va.tv_usec < vb.tv_usec) | ||
3452 | return -1; | ||
3453 | else if (va.tv_usec > vb.tv_usec) | ||
3454 | return 1; | ||
3455 | |||
3456 | return 0; | ||
3457 | } | ||
3458 | |||
3459 | static Eina_Bool | ||
3460 | _eina_value_type_timeval_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
3461 | { | ||
3462 | struct timeval v = _eina_value_type_timeval_fix(type_mem); | ||
3463 | |||
3464 | eina_error_set(0); | ||
3465 | |||
3466 | if (convert == EINA_VALUE_TYPE_UCHAR) | ||
3467 | { | ||
3468 | unsigned char other_mem = v.tv_sec; | ||
3469 | if (EINA_UNLIKELY(v.tv_sec < 0)) | ||
3470 | return EINA_FALSE; | ||
3471 | if (EINA_UNLIKELY(v.tv_sec > eina_value_uchar_max)) | ||
3472 | return EINA_FALSE; | ||
3473 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3474 | } | ||
3475 | else if (convert == EINA_VALUE_TYPE_USHORT) | ||
3476 | { | ||
3477 | unsigned short other_mem = v.tv_sec; | ||
3478 | if (EINA_UNLIKELY(v.tv_sec < 0)) | ||
3479 | return EINA_FALSE; | ||
3480 | if (EINA_UNLIKELY(v.tv_sec > eina_value_ushort_max)) | ||
3481 | return EINA_FALSE; | ||
3482 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3483 | } | ||
3484 | else if (convert == EINA_VALUE_TYPE_UINT) | ||
3485 | { | ||
3486 | unsigned int other_mem = v.tv_sec; | ||
3487 | if (EINA_UNLIKELY(v.tv_sec < 0)) | ||
3488 | return EINA_FALSE; | ||
3489 | if (EINA_UNLIKELY((unsigned long) v.tv_sec > eina_value_uint_max)) | ||
3490 | return EINA_FALSE; | ||
3491 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3492 | } | ||
3493 | else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP)) | ||
3494 | { | ||
3495 | unsigned long other_mem = v.tv_sec; | ||
3496 | if (EINA_UNLIKELY(v.tv_sec < 0)) | ||
3497 | return EINA_FALSE; | ||
3498 | if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) && | ||
3499 | ((unsigned long)v.tv_sec > eina_value_ulong_max))) | ||
3500 | return EINA_FALSE; | ||
3501 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3502 | } | ||
3503 | else if (convert == EINA_VALUE_TYPE_UINT64) | ||
3504 | { | ||
3505 | uint64_t other_mem = v.tv_sec; | ||
3506 | if (EINA_UNLIKELY(v.tv_sec < 0)) | ||
3507 | return EINA_FALSE; | ||
3508 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3509 | } | ||
3510 | else if (convert == EINA_VALUE_TYPE_CHAR) | ||
3511 | { | ||
3512 | char other_mem = v.tv_sec; | ||
3513 | if (EINA_UNLIKELY(v.tv_sec < eina_value_char_min)) | ||
3514 | return EINA_FALSE; | ||
3515 | if (EINA_UNLIKELY(v.tv_sec > eina_value_char_max)) | ||
3516 | return EINA_FALSE; | ||
3517 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3518 | } | ||
3519 | else if (convert == EINA_VALUE_TYPE_SHORT) | ||
3520 | { | ||
3521 | short other_mem = v.tv_sec; | ||
3522 | if (EINA_UNLIKELY(v.tv_sec < eina_value_short_min)) | ||
3523 | return EINA_FALSE; | ||
3524 | if (EINA_UNLIKELY(v.tv_sec > eina_value_short_max)) | ||
3525 | return EINA_FALSE; | ||
3526 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3527 | } | ||
3528 | else if (convert == EINA_VALUE_TYPE_INT) | ||
3529 | { | ||
3530 | int other_mem = v.tv_sec; | ||
3531 | if (EINA_UNLIKELY(v.tv_sec < eina_value_int_min)) | ||
3532 | return EINA_FALSE; | ||
3533 | if (EINA_UNLIKELY(v.tv_sec > eina_value_int_max)) | ||
3534 | return EINA_FALSE; | ||
3535 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3536 | } | ||
3537 | else if (convert == EINA_VALUE_TYPE_LONG) | ||
3538 | { | ||
3539 | long other_mem = v.tv_sec; | ||
3540 | if (EINA_UNLIKELY(v.tv_sec < eina_value_long_min)) | ||
3541 | return EINA_FALSE; | ||
3542 | if (EINA_UNLIKELY(v.tv_sec > eina_value_long_max)) | ||
3543 | return EINA_FALSE; | ||
3544 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3545 | } | ||
3546 | else if (convert == EINA_VALUE_TYPE_INT64) | ||
3547 | { | ||
3548 | int64_t other_mem = v.tv_sec; | ||
3549 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3550 | } | ||
3551 | else if (convert == EINA_VALUE_TYPE_FLOAT) | ||
3552 | { | ||
3553 | float other_mem = (float)v.tv_sec + (float)v.tv_usec / 1.0e6; | ||
3554 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3555 | } | ||
3556 | else if (convert == EINA_VALUE_TYPE_DOUBLE) | ||
3557 | { | ||
3558 | double other_mem = (double)v.tv_sec + (double)v.tv_usec / 1.0e6; | ||
3559 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3560 | } | ||
3561 | else if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
3562 | convert == EINA_VALUE_TYPE_STRING) | ||
3563 | { | ||
3564 | const char *other_mem; | ||
3565 | char buf[64]; | ||
3566 | snprintf(buf, sizeof(buf), "%ld.%06ld", v.tv_sec, v.tv_usec); | ||
3567 | other_mem = buf; /* required due &buf == buf */ | ||
3568 | return eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3569 | } | ||
3570 | else | ||
3571 | { | ||
3572 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
3573 | return EINA_FALSE; | ||
3574 | } | ||
3575 | } | ||
3576 | |||
3577 | static Eina_Bool | ||
3578 | _eina_value_type_timeval_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
3579 | { | ||
3580 | struct timeval *tmem = mem; | ||
3581 | *tmem = _eina_value_type_timeval_fix(ptr); | ||
3582 | return EINA_TRUE; | ||
3583 | } | ||
3584 | |||
3585 | static Eina_Bool | ||
3586 | _eina_value_type_timeval_vset(const Eina_Value_Type *type, void *mem, va_list args) | ||
3587 | { | ||
3588 | const struct timeval desc = va_arg(args, struct timeval); | ||
3589 | _eina_value_type_timeval_pset(type, mem, &desc); | ||
3590 | return EINA_TRUE; | ||
3591 | } | ||
3592 | |||
3593 | static Eina_Bool | ||
3594 | _eina_value_type_timeval_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
3595 | { | ||
3596 | memcpy(ptr, mem, sizeof(struct timeval)); | ||
3597 | return EINA_TRUE; | ||
3598 | } | ||
3599 | |||
3600 | static const Eina_Value_Type _EINA_VALUE_TYPE_TIMEVAL = { | ||
3601 | EINA_VALUE_TYPE_VERSION, | ||
3602 | sizeof(struct timeval), | ||
3603 | "struct timeval", | ||
3604 | _eina_value_type_timeval_setup, | ||
3605 | _eina_value_type_timeval_flush, | ||
3606 | _eina_value_type_timeval_copy, | ||
3607 | _eina_value_type_timeval_compare, | ||
3608 | _eina_value_type_timeval_convert_to, | ||
3609 | NULL, /* no convert from */ | ||
3610 | _eina_value_type_timeval_vset, | ||
3611 | _eina_value_type_timeval_pset, | ||
3612 | _eina_value_type_timeval_pget | ||
3613 | }; | ||
3614 | |||
3615 | static Eina_Bool | ||
3616 | _eina_value_type_blob_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
3617 | { | ||
3618 | memset(mem, 0, sizeof(Eina_Value_Blob)); | ||
3619 | return EINA_TRUE; | ||
3620 | } | ||
3621 | |||
3622 | static inline const Eina_Value_Blob_Operations * | ||
3623 | _eina_value_type_blob_ops_get(const Eina_Value_Blob *blob) | ||
3624 | { | ||
3625 | if (!blob) return NULL; | ||
3626 | if (!blob->ops) return NULL; | ||
3627 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
3628 | (blob->ops->version == EINA_VALUE_BLOB_OPERATIONS_VERSION, NULL); | ||
3629 | return blob->ops; | ||
3630 | } | ||
3631 | |||
3632 | static Eina_Bool | ||
3633 | _eina_value_type_blob_flush(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
3634 | { | ||
3635 | const Eina_Value_Blob_Operations *ops = _eina_value_type_blob_ops_get(mem); | ||
3636 | Eina_Value_Blob *tmem = mem; | ||
3637 | if ((ops) && (ops->free)) | ||
3638 | ops->free(ops, (void *)tmem->memory, tmem->size); | ||
3639 | tmem->memory = NULL; | ||
3640 | tmem->size = 0; | ||
3641 | return EINA_TRUE; | ||
3642 | } | ||
3643 | |||
3644 | static Eina_Bool | ||
3645 | _eina_value_type_blob_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
3646 | { | ||
3647 | const Eina_Value_Blob_Operations *ops = _eina_value_type_blob_ops_get(src); | ||
3648 | const Eina_Value_Blob *s = src; | ||
3649 | Eina_Value_Blob *d = dst; | ||
3650 | |||
3651 | *d = *s; | ||
3652 | |||
3653 | if ((ops) && (ops->copy)) | ||
3654 | { | ||
3655 | d->memory = ops->copy(ops, s->memory, s->size); | ||
3656 | if ((d->memory == NULL) && (s->size > 0)) | ||
3657 | return EINA_FALSE; | ||
3658 | } | ||
3659 | |||
3660 | return EINA_TRUE; | ||
3661 | } | ||
3662 | |||
3663 | static int | ||
3664 | _eina_value_type_blob_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
3665 | { | ||
3666 | const Eina_Value_Blob_Operations *ops = _eina_value_type_blob_ops_get(a); | ||
3667 | const Eina_Value_Blob *ta = a, *tb = b; | ||
3668 | size_t minsize; | ||
3669 | if (ta->ops != tb->ops) | ||
3670 | { | ||
3671 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
3672 | return -1; | ||
3673 | } | ||
3674 | if ((ops) && (ops->compare)) | ||
3675 | return ops->compare(ops, ta->memory, ta->size, tb->memory, tb->size); | ||
3676 | |||
3677 | if (ta->size < tb->size) | ||
3678 | minsize = ta->size; | ||
3679 | else | ||
3680 | minsize = tb->size; | ||
3681 | |||
3682 | return memcmp(ta->memory, tb->memory, minsize); | ||
3683 | } | ||
3684 | |||
3685 | static Eina_Bool | ||
3686 | _eina_value_type_blob_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
3687 | { | ||
3688 | const Eina_Value_Blob *tmem = type_mem; | ||
3689 | |||
3690 | eina_error_set(0); | ||
3691 | if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
3692 | convert == EINA_VALUE_TYPE_STRING) | ||
3693 | { | ||
3694 | const Eina_Value_Blob_Operations *ops; | ||
3695 | Eina_Strbuf *str; | ||
3696 | const char *other_mem; | ||
3697 | Eina_Bool ret = EINA_FALSE, first = EINA_TRUE; | ||
3698 | const unsigned char *ptr, *ptr_end; | ||
3699 | |||
3700 | ops = _eina_value_type_blob_ops_get(tmem); | ||
3701 | if ((ops) && (ops->to_string)) | ||
3702 | { | ||
3703 | char *x = ops->to_string(ops, tmem->memory, tmem->size); | ||
3704 | if (x) | ||
3705 | { | ||
3706 | ret = eina_value_type_pset(convert, convert_mem, &x); | ||
3707 | free(x); | ||
3708 | } | ||
3709 | return ret; | ||
3710 | } | ||
3711 | |||
3712 | str = eina_strbuf_new(); | ||
3713 | if (!str) | ||
3714 | return EINA_FALSE; | ||
3715 | |||
3716 | if (!eina_strbuf_append_printf(str, "BLOB(%u, [", tmem->size)) | ||
3717 | goto error; | ||
3718 | |||
3719 | ptr = tmem->memory; | ||
3720 | ptr_end = ptr + tmem->size; | ||
3721 | for (; ptr < ptr_end; ptr++) | ||
3722 | { | ||
3723 | if (first) | ||
3724 | { | ||
3725 | first = EINA_FALSE; | ||
3726 | if (!eina_strbuf_append_printf(str, "%02hhx", *ptr)) | ||
3727 | goto error; | ||
3728 | } | ||
3729 | else | ||
3730 | { | ||
3731 | if (!eina_strbuf_append_printf(str, " %02hhx", *ptr)) | ||
3732 | goto error; | ||
3733 | } | ||
3734 | } | ||
3735 | |||
3736 | if (!eina_strbuf_append(str, "])")) | ||
3737 | goto error; | ||
3738 | |||
3739 | other_mem = eina_strbuf_string_get(str); | ||
3740 | ret = eina_value_type_pset(convert, convert_mem, &other_mem); | ||
3741 | |||
3742 | error: | ||
3743 | eina_strbuf_free(str); | ||
3744 | return ret; | ||
3745 | } | ||
3746 | else | ||
3747 | { | ||
3748 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
3749 | return EINA_FALSE; | ||
3750 | } | ||
3751 | } | ||
3752 | |||
3753 | static Eina_Bool | ||
3754 | _eina_value_type_blob_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem) | ||
3755 | { | ||
3756 | Eina_Value_Blob desc; | ||
3757 | char *buf; | ||
3758 | |||
3759 | desc.ops = EINA_VALUE_BLOB_OPERATIONS_MALLOC; | ||
3760 | |||
3761 | if ((convert == EINA_VALUE_TYPE_STRING) || | ||
3762 | (convert == EINA_VALUE_TYPE_STRINGSHARE)) | ||
3763 | { | ||
3764 | const char *str = *(const char **)convert_mem; | ||
3765 | if (!str) | ||
3766 | { | ||
3767 | desc.size = 0; | ||
3768 | desc.memory = NULL; | ||
3769 | } | ||
3770 | else | ||
3771 | { | ||
3772 | desc.size = strlen(str) + 1; | ||
3773 | desc.memory = buf = malloc(desc.size); | ||
3774 | if (!desc.memory) | ||
3775 | { | ||
3776 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
3777 | return EINA_FALSE; | ||
3778 | } | ||
3779 | memcpy(buf, str, desc.size); | ||
3780 | } | ||
3781 | } | ||
3782 | else if (convert == EINA_VALUE_TYPE_ARRAY) | ||
3783 | { | ||
3784 | const Eina_Value_Array *a = convert_mem; | ||
3785 | if ((!a->array) || (a->array->len == 0)) | ||
3786 | { | ||
3787 | desc.size = 0; | ||
3788 | desc.memory = NULL; | ||
3789 | } | ||
3790 | else | ||
3791 | { | ||
3792 | desc.size = a->array->len * a->array->member_size; | ||
3793 | desc.memory = buf = malloc(desc.size); | ||
3794 | if (!desc.memory) | ||
3795 | { | ||
3796 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
3797 | return EINA_FALSE; | ||
3798 | } | ||
3799 | memcpy(buf, a->array->members, desc.size); | ||
3800 | } | ||
3801 | } | ||
3802 | else if (convert == EINA_VALUE_TYPE_BLOB) | ||
3803 | { | ||
3804 | const Eina_Value_Blob *b = convert_mem; | ||
3805 | if (b->size == 0) | ||
3806 | { | ||
3807 | desc.size = 0; | ||
3808 | desc.memory = NULL; | ||
3809 | } | ||
3810 | else | ||
3811 | { | ||
3812 | desc.size = b->size; | ||
3813 | desc.memory = buf = malloc(desc.size); | ||
3814 | if (!desc.memory) | ||
3815 | { | ||
3816 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
3817 | return EINA_FALSE; | ||
3818 | } | ||
3819 | memcpy(buf, b->memory, desc.size); | ||
3820 | } | ||
3821 | } | ||
3822 | else | ||
3823 | { | ||
3824 | desc.size = convert->value_size; | ||
3825 | desc.memory = buf = malloc(convert->value_size); | ||
3826 | if (!desc.memory) | ||
3827 | { | ||
3828 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
3829 | return EINA_FALSE; | ||
3830 | } | ||
3831 | if (!eina_value_type_pget(convert, convert_mem, buf)) | ||
3832 | { | ||
3833 | free(buf); | ||
3834 | return EINA_FALSE; | ||
3835 | } | ||
3836 | } | ||
3837 | return eina_value_type_pset(type, type_mem, &desc); | ||
3838 | } | ||
3839 | |||
3840 | static Eina_Bool | ||
3841 | _eina_value_type_blob_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
3842 | { | ||
3843 | const Eina_Value_Blob_Operations *ops = _eina_value_type_blob_ops_get(mem); | ||
3844 | Eina_Value_Blob *tmem = mem; | ||
3845 | const Eina_Value_Blob *desc = ptr; | ||
3846 | |||
3847 | eina_error_set(0); | ||
3848 | if ((tmem->memory) && (tmem->memory == desc->memory)) | ||
3849 | { | ||
3850 | tmem->ops = desc->ops; | ||
3851 | tmem->size = desc->size; | ||
3852 | return EINA_TRUE; | ||
3853 | } | ||
3854 | |||
3855 | if ((ops) && (ops->free)) | ||
3856 | ops->free(ops, (void *)tmem->memory, tmem->size); | ||
3857 | |||
3858 | *tmem = *desc; | ||
3859 | return EINA_TRUE; | ||
3860 | } | ||
3861 | |||
3862 | static Eina_Bool | ||
3863 | _eina_value_type_blob_vset(const Eina_Value_Type *type, void *mem, va_list args) | ||
3864 | { | ||
3865 | const Eina_Value_Blob desc = va_arg(args, Eina_Value_Blob); | ||
3866 | _eina_value_type_blob_pset(type, mem, &desc); | ||
3867 | return EINA_TRUE; | ||
3868 | } | ||
3869 | |||
3870 | static Eina_Bool | ||
3871 | _eina_value_type_blob_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
3872 | { | ||
3873 | memcpy(ptr, mem, sizeof(Eina_Value_Blob)); | ||
3874 | return EINA_TRUE; | ||
3875 | } | ||
3876 | |||
3877 | static const Eina_Value_Type _EINA_VALUE_TYPE_BLOB = { | ||
3878 | EINA_VALUE_TYPE_VERSION, | ||
3879 | sizeof(Eina_Value_Blob), | ||
3880 | "Eina_Value_Blob", | ||
3881 | _eina_value_type_blob_setup, | ||
3882 | _eina_value_type_blob_flush, | ||
3883 | _eina_value_type_blob_copy, | ||
3884 | _eina_value_type_blob_compare, | ||
3885 | _eina_value_type_blob_convert_to, | ||
3886 | _eina_value_type_blob_convert_from, | ||
3887 | _eina_value_type_blob_vset, | ||
3888 | _eina_value_type_blob_pset, | ||
3889 | _eina_value_type_blob_pget | ||
3890 | }; | ||
3891 | |||
3892 | static int | ||
3893 | _eina_value_struct_operations_binsearch_cmp(const void *pa, const void *pb) | ||
3894 | { | ||
3895 | const Eina_Value_Struct_Member *a = pa, *b = pb; | ||
3896 | return strcmp(a->name, b->name); | ||
3897 | } | ||
3898 | |||
3899 | static const Eina_Value_Struct_Member * | ||
3900 | _eina_value_struct_operations_binsearch_find_member(const Eina_Value_Struct_Operations *ops __UNUSED__, const Eina_Value_Struct_Desc *desc, const char *name) | ||
3901 | { | ||
3902 | unsigned int count = desc->member_count; | ||
3903 | Eina_Value_Struct_Member search; | ||
3904 | if (count == 0) | ||
3905 | { | ||
3906 | const Eina_Value_Struct_Member *itr = desc->members; | ||
3907 | for (; itr->name != NULL; itr++) | ||
3908 | count++; | ||
3909 | } | ||
3910 | |||
3911 | search.name = name; | ||
3912 | return bsearch(&search, desc->members, count, | ||
3913 | sizeof(Eina_Value_Struct_Member), | ||
3914 | _eina_value_struct_operations_binsearch_cmp); | ||
3915 | } | ||
3916 | |||
3917 | static Eina_Value_Struct_Operations _EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH = { | ||
3918 | EINA_VALUE_STRUCT_OPERATIONS_VERSION, | ||
3919 | NULL, /* default alloc */ | ||
3920 | NULL, /* default free */ | ||
3921 | NULL, /* default copy */ | ||
3922 | NULL, /* default compare */ | ||
3923 | _eina_value_struct_operations_binsearch_find_member | ||
3924 | }; | ||
3925 | |||
3926 | static const Eina_Value_Struct_Member * | ||
3927 | _eina_value_struct_operations_stringshare_find_member(const Eina_Value_Struct_Operations *ops __UNUSED__, const Eina_Value_Struct_Desc *desc, const char *name) | ||
3928 | { | ||
3929 | const Eina_Value_Struct_Member *itr = desc->members; | ||
3930 | |||
3931 | /* assumes name is stringshared. | ||
3932 | * | ||
3933 | * we do this because it's the recommended usage pattern, moreover | ||
3934 | * we expect to find the member, as users shouldn't look for | ||
3935 | * non-existent members! | ||
3936 | */ | ||
3937 | if (desc->member_count > 0) | ||
3938 | { | ||
3939 | const Eina_Value_Struct_Member *itr_end = itr + desc->member_count; | ||
3940 | for (; itr < itr_end; itr++) | ||
3941 | if (itr->name == name) | ||
3942 | return itr; | ||
3943 | } | ||
3944 | else | ||
3945 | { | ||
3946 | for (; itr->name != NULL; itr++) | ||
3947 | if (itr->name == name) | ||
3948 | return itr; | ||
3949 | } | ||
3950 | |||
3951 | itr = desc->members; | ||
3952 | name = eina_stringshare_add(name); | ||
3953 | eina_stringshare_del(name); /* we'll not use the contents, this is fine */ | ||
3954 | /* stringshare and look again */ | ||
3955 | if (desc->member_count > 0) | ||
3956 | { | ||
3957 | const Eina_Value_Struct_Member *itr_end = itr + desc->member_count; | ||
3958 | for (; itr < itr_end; itr++) | ||
3959 | if (itr->name == name) | ||
3960 | return itr; | ||
3961 | } | ||
3962 | else | ||
3963 | { | ||
3964 | for (; itr->name != NULL; itr++) | ||
3965 | if (itr->name == name) | ||
3966 | return itr; | ||
3967 | } | ||
3968 | |||
3969 | return NULL; | ||
3970 | } | ||
3971 | |||
3972 | static Eina_Value_Struct_Operations _EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE = { | ||
3973 | EINA_VALUE_STRUCT_OPERATIONS_VERSION, | ||
3974 | NULL, /* default alloc */ | ||
3975 | NULL, /* default free */ | ||
3976 | NULL, /* default copy */ | ||
3977 | NULL, /* default compare */ | ||
3978 | _eina_value_struct_operations_stringshare_find_member | ||
3979 | }; | ||
3980 | |||
3981 | static inline const Eina_Value_Struct_Operations * | ||
3982 | _eina_value_type_struct_ops_get(const Eina_Value_Struct *st) | ||
3983 | { | ||
3984 | if (!st) return NULL; | ||
3985 | if (!st->desc) return NULL; | ||
3986 | if (!st->desc->ops) return NULL; | ||
3987 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
3988 | (st->desc->ops->version == EINA_VALUE_STRUCT_OPERATIONS_VERSION, NULL); | ||
3989 | return st->desc->ops; | ||
3990 | } | ||
3991 | |||
3992 | EAPI const Eina_Value_Struct_Member * | ||
3993 | eina_value_struct_member_find(const Eina_Value_Struct *st, const char *name) | ||
3994 | { | ||
3995 | const Eina_Value_Struct_Operations *ops; | ||
3996 | const Eina_Value_Struct_Member *itr; | ||
3997 | |||
3998 | EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL); | ||
3999 | EINA_SAFETY_ON_NULL_RETURN_VAL(st->desc, NULL); | ||
4000 | |||
4001 | ops = _eina_value_type_struct_ops_get(st); | ||
4002 | if ((ops) && (ops->find_member)) | ||
4003 | return ops->find_member(ops, st->desc, name); | ||
4004 | |||
4005 | itr = st->desc->members; | ||
4006 | if (st->desc->member_count) | ||
4007 | { | ||
4008 | const Eina_Value_Struct_Member *itr_end = itr + st->desc->member_count; | ||
4009 | for (; itr < itr_end; itr++) | ||
4010 | { | ||
4011 | if (strcmp(name, itr->name) == 0) | ||
4012 | return itr; | ||
4013 | } | ||
4014 | return NULL; | ||
4015 | } | ||
4016 | else | ||
4017 | { | ||
4018 | for (; itr->name != NULL; itr++) | ||
4019 | { | ||
4020 | if (strcmp(name, itr->name) == 0) | ||
4021 | return itr; | ||
4022 | } | ||
4023 | return NULL; | ||
4024 | } | ||
4025 | } | ||
4026 | |||
4027 | static Eina_Bool | ||
4028 | _eina_value_type_struct_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
4029 | { | ||
4030 | memset(mem, 0, sizeof(Eina_Value_Struct)); | ||
4031 | return EINA_TRUE; | ||
4032 | } | ||
4033 | |||
4034 | static Eina_Bool | ||
4035 | _eina_value_type_struct_setup_member(const Eina_Value_Struct_Member *member, Eina_Value_Struct *st) | ||
4036 | { | ||
4037 | unsigned char *base = st->memory; | ||
4038 | return eina_value_type_setup(member->type, base + member->offset); | ||
4039 | } | ||
4040 | |||
4041 | static Eina_Bool | ||
4042 | _eina_value_type_struct_flush_member(const Eina_Value_Struct_Member *member, Eina_Value_Struct *st) | ||
4043 | { | ||
4044 | unsigned char *base = st->memory; | ||
4045 | return eina_value_type_flush(member->type, base + member->offset); | ||
4046 | } | ||
4047 | |||
4048 | static Eina_Bool | ||
4049 | _eina_value_type_struct_flush(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
4050 | { | ||
4051 | const Eina_Value_Struct_Operations *ops; | ||
4052 | const Eina_Value_Struct_Member *itr; | ||
4053 | Eina_Value_Struct *tmem = mem; | ||
4054 | Eina_Bool ret = EINA_TRUE; | ||
4055 | |||
4056 | if ((!tmem->desc) || (!tmem->memory)) | ||
4057 | return EINA_TRUE; | ||
4058 | |||
4059 | itr = tmem->desc->members; | ||
4060 | if (tmem->desc->member_count > 0) | ||
4061 | { | ||
4062 | const Eina_Value_Struct_Member *itr_end; | ||
4063 | itr_end = itr + tmem->desc->member_count; | ||
4064 | for (; itr < itr_end; itr++) | ||
4065 | ret &= _eina_value_type_struct_flush_member(itr, tmem); | ||
4066 | } | ||
4067 | else | ||
4068 | { | ||
4069 | for (; itr->name != NULL; itr++) | ||
4070 | ret &= _eina_value_type_struct_flush_member(itr, tmem); | ||
4071 | } | ||
4072 | |||
4073 | ops = _eina_value_type_struct_ops_get(mem); | ||
4074 | if ((ops) && (ops->free)) | ||
4075 | ops->free(ops, tmem->desc, tmem->memory); | ||
4076 | else | ||
4077 | free(tmem->memory); | ||
4078 | |||
4079 | tmem->memory = NULL; | ||
4080 | tmem->desc = NULL; | ||
4081 | |||
4082 | return ret; | ||
4083 | } | ||
4084 | |||
4085 | static Eina_Bool | ||
4086 | _eina_value_type_struct_copy_member(const Eina_Value_Struct_Member *member, const Eina_Value_Struct *s, Eina_Value_Struct *d) | ||
4087 | { | ||
4088 | const unsigned char *base_s = s->memory; | ||
4089 | unsigned char *base_d = d->memory; | ||
4090 | return eina_value_type_copy(member->type, | ||
4091 | base_s + member->offset, | ||
4092 | base_d + member->offset); | ||
4093 | } | ||
4094 | |||
4095 | static Eina_Bool | ||
4096 | _eina_value_type_struct_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
4097 | { | ||
4098 | const Eina_Value_Struct_Operations *ops; | ||
4099 | const Eina_Value_Struct_Member *itr; | ||
4100 | const Eina_Value_Struct *s = src; | ||
4101 | Eina_Value_Struct *d = dst; | ||
4102 | |||
4103 | *d = *s; | ||
4104 | |||
4105 | if ((!s->desc) || (!s->memory)) | ||
4106 | return EINA_TRUE; | ||
4107 | |||
4108 | ops = _eina_value_type_struct_ops_get(src); | ||
4109 | if ((ops) && (ops->copy)) | ||
4110 | { | ||
4111 | d->memory = ops->copy(ops, s->desc, s->memory); | ||
4112 | if (d->memory == NULL) | ||
4113 | return EINA_FALSE; | ||
4114 | return EINA_TRUE; | ||
4115 | } | ||
4116 | |||
4117 | if ((ops) && (ops->alloc)) | ||
4118 | d->memory = ops->alloc(ops, s->desc); | ||
4119 | else | ||
4120 | d->memory = malloc(s->desc->size); | ||
4121 | if (!d->memory) | ||
4122 | { | ||
4123 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
4124 | return EINA_FALSE; | ||
4125 | } | ||
4126 | |||
4127 | itr = s->desc->members; | ||
4128 | if (s->desc->member_count > 0) | ||
4129 | { | ||
4130 | const Eina_Value_Struct_Member *itr_end = itr + s->desc->member_count; | ||
4131 | for (; itr < itr_end; itr++) | ||
4132 | if (!_eina_value_type_struct_copy_member(itr, s, d)) | ||
4133 | goto error; | ||
4134 | } | ||
4135 | else | ||
4136 | { | ||
4137 | for (; itr->name != NULL; itr++) | ||
4138 | if (!_eina_value_type_struct_copy_member(itr, s, d)) | ||
4139 | goto error; | ||
4140 | } | ||
4141 | |||
4142 | return EINA_TRUE; | ||
4143 | |||
4144 | error: | ||
4145 | itr--; | ||
4146 | for (; itr >= s->desc->members; itr--) | ||
4147 | _eina_value_type_struct_flush_member(itr, d); | ||
4148 | |||
4149 | if ((ops) && (ops->free)) | ||
4150 | ops->free(ops, s->desc, d->memory); | ||
4151 | else | ||
4152 | free(d->memory); | ||
4153 | return EINA_FALSE; | ||
4154 | } | ||
4155 | |||
4156 | static inline int | ||
4157 | _eina_value_type_struct_compare_member(const Eina_Value_Struct_Member *member, const Eina_Value_Struct *ta, const Eina_Value_Struct *tb) | ||
4158 | { | ||
4159 | const unsigned char *base_a = ta->memory; | ||
4160 | const unsigned char *base_b = tb->memory; | ||
4161 | return eina_value_type_compare(member->type, | ||
4162 | base_a + member->offset, | ||
4163 | base_b + member->offset); | ||
4164 | } | ||
4165 | |||
4166 | static int | ||
4167 | _eina_value_type_struct_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
4168 | { | ||
4169 | const Eina_Value_Struct_Operations *ops = _eina_value_type_struct_ops_get(a); | ||
4170 | const Eina_Value_Struct *ta = a, *tb = b; | ||
4171 | const Eina_Value_Struct_Member *itr; | ||
4172 | int cmp = 0; | ||
4173 | |||
4174 | if ((!ta->desc) && (!tb->desc)) | ||
4175 | return 0; | ||
4176 | else if (ta->desc != tb->desc) | ||
4177 | { | ||
4178 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
4179 | return -1; | ||
4180 | } | ||
4181 | if (ta->desc->ops != tb->desc->ops) | ||
4182 | { | ||
4183 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
4184 | return -1; | ||
4185 | } | ||
4186 | if ((!ta->memory) && (!tb->memory)) | ||
4187 | return 0; | ||
4188 | else if (!ta->memory) | ||
4189 | return -1; | ||
4190 | else if (!tb->memory) | ||
4191 | return 1; | ||
4192 | |||
4193 | if ((ops) && (ops->compare)) | ||
4194 | return ops->compare(ops, ta->desc, ta->memory, tb->memory); | ||
4195 | |||
4196 | itr = ta->desc->members; | ||
4197 | if (ta->desc->member_count > 0) | ||
4198 | { | ||
4199 | const Eina_Value_Struct_Member *itr_end = itr + ta->desc->member_count; | ||
4200 | for (; (cmp == 0) && (itr < itr_end); itr++) | ||
4201 | cmp = _eina_value_type_struct_compare_member(itr, ta, tb); | ||
4202 | } | ||
4203 | else | ||
4204 | { | ||
4205 | for (; (cmp == 0) && (itr->name != NULL); itr++) | ||
4206 | cmp = _eina_value_type_struct_compare_member(itr, ta, tb); | ||
4207 | } | ||
4208 | return cmp; | ||
4209 | } | ||
4210 | |||
4211 | static void | ||
4212 | _eina_value_type_struct_convert_to_string_member(const Eina_Value_Struct *st, const Eina_Value_Struct_Member *member, Eina_Strbuf *str) | ||
4213 | { | ||
4214 | const unsigned char *p = st->memory; | ||
4215 | Eina_Bool first = st->desc->members == member; | ||
4216 | Eina_Bool r = EINA_FALSE; | ||
4217 | |||
4218 | if (first) eina_strbuf_append_printf(str, "%s: ", member->name); | ||
4219 | else eina_strbuf_append_printf(str, ", %s: ", member->name); | ||
4220 | |||
4221 | if ((member->type) && (member->type->convert_to)) | ||
4222 | { | ||
4223 | const Eina_Value_Type *type = member->type; | ||
4224 | char *conv = NULL; | ||
4225 | |||
4226 | r = eina_value_type_convert_to(type, EINA_VALUE_TYPE_STRING, | ||
4227 | p + member->offset, &conv); | ||
4228 | if (r) | ||
4229 | { | ||
4230 | eina_strbuf_append(str, conv); | ||
4231 | free(conv); | ||
4232 | } | ||
4233 | } | ||
4234 | |||
4235 | if (!r) | ||
4236 | eina_strbuf_append_char(str, '?'); | ||
4237 | } | ||
4238 | |||
4239 | static Eina_Bool | ||
4240 | _eina_value_type_struct_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
4241 | { | ||
4242 | const Eina_Value_Struct *tmem = type_mem; | ||
4243 | |||
4244 | eina_error_set(0); | ||
4245 | if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
4246 | convert == EINA_VALUE_TYPE_STRING) | ||
4247 | { | ||
4248 | Eina_Strbuf *str = eina_strbuf_new(); | ||
4249 | const char *s; | ||
4250 | Eina_Bool ret; | ||
4251 | |||
4252 | if (!tmem->memory) eina_strbuf_append(str, "{}"); | ||
4253 | else | ||
4254 | { | ||
4255 | const Eina_Value_Struct_Member *itr = tmem->desc->members; | ||
4256 | |||
4257 | eina_strbuf_append_char(str, '{'); | ||
4258 | |||
4259 | if (tmem->desc->member_count > 0) | ||
4260 | { | ||
4261 | const Eina_Value_Struct_Member *itr_end; | ||
4262 | |||
4263 | itr_end = itr + tmem->desc->member_count; | ||
4264 | for (; itr < itr_end; itr++) | ||
4265 | _eina_value_type_struct_convert_to_string_member | ||
4266 | (tmem, itr, str); | ||
4267 | } | ||
4268 | else | ||
4269 | { | ||
4270 | for (; itr->name != NULL; itr++) | ||
4271 | _eina_value_type_struct_convert_to_string_member | ||
4272 | (tmem, itr, str); | ||
4273 | } | ||
4274 | |||
4275 | eina_strbuf_append_char(str, '}'); | ||
4276 | } | ||
4277 | s = eina_strbuf_string_get(str); | ||
4278 | ret = eina_value_type_pset(convert, convert_mem, &s); | ||
4279 | eina_strbuf_free(str); | ||
4280 | return ret; | ||
4281 | } | ||
4282 | else | ||
4283 | { | ||
4284 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
4285 | return EINA_FALSE; | ||
4286 | } | ||
4287 | } | ||
4288 | |||
4289 | static Eina_Bool | ||
4290 | _eina_value_type_struct_desc_check(const Eina_Value_Struct_Desc *desc) | ||
4291 | { | ||
4292 | unsigned int minsize = 0; | ||
4293 | const Eina_Value_Struct_Member *itr; | ||
4294 | |||
4295 | EINA_SAFETY_ON_NULL_RETURN_VAL(desc, EINA_FALSE); | ||
4296 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
4297 | (desc->version == EINA_VALUE_STRUCT_DESC_VERSION, EINA_FALSE); | ||
4298 | |||
4299 | itr = desc->members; | ||
4300 | if (desc->member_count > 0) | ||
4301 | { | ||
4302 | const Eina_Value_Struct_Member *itr_end = itr + desc->member_count; | ||
4303 | for (; itr < itr_end; itr++) | ||
4304 | { | ||
4305 | unsigned int member_end; | ||
4306 | |||
4307 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
4308 | (eina_value_type_check(itr->type), EINA_FALSE); | ||
4309 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
4310 | (itr->type->value_size > 0, EINA_FALSE); | ||
4311 | |||
4312 | member_end = itr->offset + itr->type->value_size; | ||
4313 | if (minsize < member_end) | ||
4314 | minsize = member_end; | ||
4315 | } | ||
4316 | } | ||
4317 | else | ||
4318 | { | ||
4319 | for (; itr->name != NULL; itr++) | ||
4320 | { | ||
4321 | unsigned int member_end; | ||
4322 | |||
4323 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
4324 | (eina_value_type_check(itr->type), EINA_FALSE); | ||
4325 | EINA_SAFETY_ON_FALSE_RETURN_VAL | ||
4326 | (itr->type->value_size > 0, EINA_FALSE); | ||
4327 | |||
4328 | member_end = itr->offset + itr->type->value_size; | ||
4329 | if (minsize < member_end) | ||
4330 | minsize = member_end; | ||
4331 | } | ||
4332 | } | ||
4333 | |||
4334 | EINA_SAFETY_ON_FALSE_RETURN_VAL(minsize > 0, EINA_FALSE); | ||
4335 | EINA_SAFETY_ON_FALSE_RETURN_VAL(desc->size >= minsize, EINA_FALSE); | ||
4336 | return EINA_TRUE; | ||
4337 | } | ||
4338 | |||
4339 | static Eina_Bool | ||
4340 | _eina_value_type_struct_pset(const Eina_Value_Type *type, void *mem, const void *ptr) | ||
4341 | { | ||
4342 | const Eina_Value_Struct_Operations *ops; | ||
4343 | Eina_Value_Struct *tmem = mem; | ||
4344 | const Eina_Value_Struct *desc = ptr; | ||
4345 | const Eina_Value_Struct_Member *itr; | ||
4346 | |||
4347 | if (!_eina_value_type_struct_desc_check(desc->desc)) | ||
4348 | { | ||
4349 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
4350 | return EINA_FALSE; | ||
4351 | } | ||
4352 | |||
4353 | eina_error_set(0); | ||
4354 | if ((tmem->memory) && (tmem->memory == desc->memory)) | ||
4355 | { | ||
4356 | tmem->desc = desc->desc; | ||
4357 | return EINA_TRUE; | ||
4358 | } | ||
4359 | |||
4360 | if (desc->memory) | ||
4361 | { | ||
4362 | Eina_Value_Struct tmp; | ||
4363 | |||
4364 | if (!_eina_value_type_struct_copy(type, desc, &tmp)) | ||
4365 | return EINA_FALSE; | ||
4366 | |||
4367 | _eina_value_type_struct_flush(type, tmem); | ||
4368 | memcpy(tmem, &tmp, sizeof(tmp)); | ||
4369 | return EINA_TRUE; | ||
4370 | } | ||
4371 | |||
4372 | if (tmem->memory) _eina_value_type_struct_flush(type, mem); | ||
4373 | |||
4374 | tmem->desc = desc->desc; | ||
4375 | |||
4376 | ops = _eina_value_type_struct_ops_get(desc); | ||
4377 | if ((ops) && (ops->alloc)) | ||
4378 | tmem->memory = ops->alloc(ops, tmem->desc); | ||
4379 | else | ||
4380 | tmem->memory = malloc(tmem->desc->size); | ||
4381 | |||
4382 | if (!tmem->memory) | ||
4383 | { | ||
4384 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
4385 | return EINA_FALSE; | ||
4386 | } | ||
4387 | |||
4388 | itr = tmem->desc->members; | ||
4389 | if (tmem->desc->member_count > 0) | ||
4390 | { | ||
4391 | const Eina_Value_Struct_Member *itr_end; | ||
4392 | itr_end = itr + tmem->desc->member_count; | ||
4393 | for (; itr < itr_end; itr++) | ||
4394 | if (!_eina_value_type_struct_setup_member(itr, tmem)) | ||
4395 | goto error; | ||
4396 | } | ||
4397 | else | ||
4398 | { | ||
4399 | for (; itr->name != NULL; itr++) | ||
4400 | if (!_eina_value_type_struct_setup_member(itr, tmem)) | ||
4401 | goto error; | ||
4402 | } | ||
4403 | |||
4404 | return EINA_TRUE; | ||
4405 | |||
4406 | error: | ||
4407 | itr--; | ||
4408 | for (; itr >= tmem->desc->members; itr--) | ||
4409 | _eina_value_type_struct_flush_member(itr, tmem); | ||
4410 | |||
4411 | if ((ops) && (ops->free)) | ||
4412 | ops->free(ops, tmem->desc, tmem->memory); | ||
4413 | else | ||
4414 | free(tmem->memory); | ||
4415 | tmem->memory = NULL; | ||
4416 | tmem->desc = NULL; | ||
4417 | return EINA_FALSE; | ||
4418 | } | ||
4419 | |||
4420 | static Eina_Bool | ||
4421 | _eina_value_type_struct_vset(const Eina_Value_Type *type, void *mem, va_list args) | ||
4422 | { | ||
4423 | const Eina_Value_Struct desc = va_arg(args, Eina_Value_Struct); | ||
4424 | _eina_value_type_struct_pset(type, mem, &desc); | ||
4425 | return EINA_TRUE; | ||
4426 | } | ||
4427 | |||
4428 | static Eina_Bool | ||
4429 | _eina_value_type_struct_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
4430 | { | ||
4431 | memcpy(ptr, mem, sizeof(Eina_Value_Struct)); | ||
4432 | return EINA_TRUE; | ||
4433 | } | ||
4434 | |||
4435 | static const Eina_Value_Type _EINA_VALUE_TYPE_STRUCT = { | ||
4436 | EINA_VALUE_TYPE_VERSION, | ||
4437 | sizeof(Eina_Value_Struct), | ||
4438 | "Eina_Value_Struct", | ||
4439 | _eina_value_type_struct_setup, | ||
4440 | _eina_value_type_struct_flush, | ||
4441 | _eina_value_type_struct_copy, | ||
4442 | _eina_value_type_struct_compare, | ||
4443 | _eina_value_type_struct_convert_to, | ||
4444 | NULL, /* no convert from */ | ||
4445 | _eina_value_type_struct_vset, | ||
4446 | _eina_value_type_struct_pset, | ||
4447 | _eina_value_type_struct_pget | ||
4448 | }; | ||
4449 | |||
4450 | static Eina_Bool | ||
4451 | _eina_value_type_model_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
4452 | { | ||
4453 | Eina_Model **tmem = mem; | ||
4454 | *tmem = NULL; | ||
4455 | return EINA_TRUE; | ||
4456 | } | ||
4457 | |||
4458 | static Eina_Bool | ||
4459 | _eina_value_type_model_flush(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
4460 | { | ||
4461 | Eina_Model **tmem = mem; | ||
4462 | if (*tmem) | ||
4463 | { | ||
4464 | eina_model_unref(*tmem); | ||
4465 | *tmem = NULL; | ||
4466 | } | ||
4467 | return EINA_TRUE; | ||
4468 | } | ||
4469 | |||
4470 | static Eina_Bool | ||
4471 | _eina_value_type_model_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
4472 | { | ||
4473 | const Eina_Model * const *s = src; | ||
4474 | Eina_Model **d = dst; | ||
4475 | if (*s) | ||
4476 | *d = eina_model_copy(*s); /* is it better to deep-copy? */ | ||
4477 | else | ||
4478 | *d = NULL; | ||
4479 | return EINA_TRUE; | ||
4480 | } | ||
4481 | |||
4482 | static int | ||
4483 | _eina_value_type_model_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
4484 | { | ||
4485 | const Eina_Model * const *ta = a; | ||
4486 | const Eina_Model * const *tb = b; | ||
4487 | |||
4488 | if ((!*ta) && (!*tb)) return 0; | ||
4489 | else if (!*ta) return 1; | ||
4490 | else if (!*tb) return -1; | ||
4491 | else return eina_model_compare(*ta, *tb); | ||
4492 | } | ||
4493 | |||
4494 | static Eina_Bool | ||
4495 | _eina_value_type_model_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
4496 | { | ||
4497 | const Eina_Model *v = *(const Eina_Model **)type_mem; | ||
4498 | |||
4499 | eina_error_set(0); | ||
4500 | |||
4501 | if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
4502 | convert == EINA_VALUE_TYPE_STRING) | ||
4503 | { | ||
4504 | char *other_mem = v ? eina_model_to_string(v) : NULL; | ||
4505 | Eina_Bool ret = eina_value_type_pset(convert, convert_mem, &other_mem); | ||
4506 | free(other_mem); | ||
4507 | return ret; | ||
4508 | } | ||
4509 | else | ||
4510 | { | ||
4511 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
4512 | return EINA_FALSE; | ||
4513 | } | ||
4514 | |||
4515 | return EINA_TRUE; | ||
4516 | } | ||
4517 | |||
4518 | static Eina_Bool | ||
4519 | _eina_value_type_model_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
4520 | { | ||
4521 | Eina_Model **tmem = mem, *tmp; | ||
4522 | |||
4523 | tmp = va_arg(args, Eina_Model *); | ||
4524 | |||
4525 | if (tmp) eina_model_ref(tmp); | ||
4526 | if (*tmem) eina_model_unref(*tmem); | ||
4527 | |||
4528 | *tmem = tmp; | ||
4529 | |||
4530 | return EINA_TRUE; | ||
4531 | } | ||
4532 | |||
4533 | static Eina_Bool | ||
4534 | _eina_value_type_model_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
4535 | { | ||
4536 | Eina_Model **tmem = mem; | ||
4537 | Eina_Model **p = (Eina_Model **)ptr; | ||
4538 | |||
4539 | eina_error_set(0); | ||
4540 | if (*tmem == *p) return EINA_TRUE; | ||
4541 | |||
4542 | if (*p) eina_model_ref(*p); | ||
4543 | if (*tmem) eina_model_unref(*tmem); | ||
4544 | |||
4545 | *tmem = *p; | ||
4546 | |||
4547 | return EINA_TRUE; | ||
4548 | } | ||
4549 | |||
4550 | static Eina_Bool | ||
4551 | _eina_value_type_model_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
4552 | { | ||
4553 | Eina_Model **tmem = (Eina_Model **)mem; | ||
4554 | Eina_Model **p = ptr; | ||
4555 | *p = *tmem; | ||
4556 | return EINA_TRUE; | ||
4557 | } | ||
4558 | |||
4559 | static const Eina_Value_Type _EINA_VALUE_TYPE_MODEL = { | ||
4560 | EINA_VALUE_TYPE_VERSION, | ||
4561 | sizeof(Eina_Model *), | ||
4562 | "Eina_Model", | ||
4563 | _eina_value_type_model_setup, | ||
4564 | _eina_value_type_model_flush, | ||
4565 | _eina_value_type_model_copy, | ||
4566 | _eina_value_type_model_compare, | ||
4567 | _eina_value_type_model_convert_to, | ||
4568 | NULL, /* no convert from */ | ||
4569 | _eina_value_type_model_vset, | ||
4570 | _eina_value_type_model_pset, | ||
4571 | _eina_value_type_model_pget | ||
4572 | }; | ||
4573 | |||
4574 | /* keep all basic types inlined in an array so we can compare if it's | ||
4575 | * a basic type using pointer arithmetic. | ||
4576 | * | ||
4577 | * NOTE-1: JUST BASIC TYPES, DO NOT ADD MORE TYPES HERE!!! | ||
4578 | * NOTE-2: KEEP ORDER, see eina_value_init() | ||
4579 | */ | ||
4580 | static const Eina_Value_Type _EINA_VALUE_TYPE_BASICS[] = { | ||
4581 | { | ||
4582 | EINA_VALUE_TYPE_VERSION, | ||
4583 | sizeof(unsigned char), | ||
4584 | "unsigned char", | ||
4585 | _eina_value_type_uchar_setup, | ||
4586 | _eina_value_type_uchar_flush, | ||
4587 | _eina_value_type_uchar_copy, | ||
4588 | _eina_value_type_uchar_compare, | ||
4589 | _eina_value_type_uchar_convert_to, | ||
4590 | NULL, /* no convert from */ | ||
4591 | _eina_value_type_uchar_vset, | ||
4592 | _eina_value_type_uchar_pset, | ||
4593 | _eina_value_type_uchar_pget | ||
4594 | }, | ||
4595 | { | ||
4596 | EINA_VALUE_TYPE_VERSION, | ||
4597 | sizeof(unsigned short), | ||
4598 | "unsigned short", | ||
4599 | _eina_value_type_ushort_setup, | ||
4600 | _eina_value_type_ushort_flush, | ||
4601 | _eina_value_type_ushort_copy, | ||
4602 | _eina_value_type_ushort_compare, | ||
4603 | _eina_value_type_ushort_convert_to, | ||
4604 | NULL, /* no convert from */ | ||
4605 | _eina_value_type_ushort_vset, | ||
4606 | _eina_value_type_ushort_pset, | ||
4607 | _eina_value_type_ushort_pget | ||
4608 | }, | ||
4609 | { | ||
4610 | EINA_VALUE_TYPE_VERSION, | ||
4611 | sizeof(unsigned int), | ||
4612 | "unsigned int", | ||
4613 | _eina_value_type_uint_setup, | ||
4614 | _eina_value_type_uint_flush, | ||
4615 | _eina_value_type_uint_copy, | ||
4616 | _eina_value_type_uint_compare, | ||
4617 | _eina_value_type_uint_convert_to, | ||
4618 | NULL, /* no convert from */ | ||
4619 | _eina_value_type_uint_vset, | ||
4620 | _eina_value_type_uint_pset, | ||
4621 | _eina_value_type_uint_pget | ||
4622 | }, | ||
4623 | { | ||
4624 | EINA_VALUE_TYPE_VERSION, | ||
4625 | sizeof(unsigned long), | ||
4626 | "unsigned long", | ||
4627 | _eina_value_type_ulong_setup, | ||
4628 | _eina_value_type_ulong_flush, | ||
4629 | _eina_value_type_ulong_copy, | ||
4630 | _eina_value_type_ulong_compare, | ||
4631 | _eina_value_type_ulong_convert_to, | ||
4632 | NULL, /* no convert from */ | ||
4633 | _eina_value_type_ulong_vset, | ||
4634 | _eina_value_type_ulong_pset, | ||
4635 | _eina_value_type_ulong_pget | ||
4636 | }, | ||
4637 | { | ||
4638 | EINA_VALUE_TYPE_VERSION, | ||
4639 | sizeof(uint64_t), | ||
4640 | "uint64_t", | ||
4641 | _eina_value_type_uint64_setup, | ||
4642 | _eina_value_type_uint64_flush, | ||
4643 | _eina_value_type_uint64_copy, | ||
4644 | _eina_value_type_uint64_compare, | ||
4645 | _eina_value_type_uint64_convert_to, | ||
4646 | NULL, /* no convert from */ | ||
4647 | _eina_value_type_uint64_vset, | ||
4648 | _eina_value_type_uint64_pset, | ||
4649 | _eina_value_type_uint64_pget | ||
4650 | }, | ||
4651 | { | ||
4652 | EINA_VALUE_TYPE_VERSION, | ||
4653 | sizeof(char), | ||
4654 | "char", | ||
4655 | _eina_value_type_char_setup, | ||
4656 | _eina_value_type_char_flush, | ||
4657 | _eina_value_type_char_copy, | ||
4658 | _eina_value_type_char_compare, | ||
4659 | _eina_value_type_char_convert_to, | ||
4660 | NULL, /* no convert from */ | ||
4661 | _eina_value_type_char_vset, | ||
4662 | _eina_value_type_char_pset, | ||
4663 | _eina_value_type_char_pget | ||
4664 | }, | ||
4665 | { | ||
4666 | EINA_VALUE_TYPE_VERSION, | ||
4667 | sizeof(short), | ||
4668 | "short", | ||
4669 | _eina_value_type_short_setup, | ||
4670 | _eina_value_type_short_flush, | ||
4671 | _eina_value_type_short_copy, | ||
4672 | _eina_value_type_short_compare, | ||
4673 | _eina_value_type_short_convert_to, | ||
4674 | NULL, /* no convert from */ | ||
4675 | _eina_value_type_short_vset, | ||
4676 | _eina_value_type_short_pset, | ||
4677 | _eina_value_type_short_pget | ||
4678 | }, | ||
4679 | { | ||
4680 | EINA_VALUE_TYPE_VERSION, | ||
4681 | sizeof(int), | ||
4682 | "int", | ||
4683 | _eina_value_type_int_setup, | ||
4684 | _eina_value_type_int_flush, | ||
4685 | _eina_value_type_int_copy, | ||
4686 | _eina_value_type_int_compare, | ||
4687 | _eina_value_type_int_convert_to, | ||
4688 | NULL, /* no convert from */ | ||
4689 | _eina_value_type_int_vset, | ||
4690 | _eina_value_type_int_pset, | ||
4691 | _eina_value_type_int_pget | ||
4692 | }, | ||
4693 | { | ||
4694 | EINA_VALUE_TYPE_VERSION, | ||
4695 | sizeof(long), | ||
4696 | "long", | ||
4697 | _eina_value_type_long_setup, | ||
4698 | _eina_value_type_long_flush, | ||
4699 | _eina_value_type_long_copy, | ||
4700 | _eina_value_type_long_compare, | ||
4701 | _eina_value_type_long_convert_to, | ||
4702 | NULL, /* no convert from */ | ||
4703 | _eina_value_type_long_vset, | ||
4704 | _eina_value_type_long_pset, | ||
4705 | _eina_value_type_long_pget | ||
4706 | }, | ||
4707 | { | ||
4708 | EINA_VALUE_TYPE_VERSION, | ||
4709 | sizeof(int64_t), | ||
4710 | "int64_t", | ||
4711 | _eina_value_type_int64_setup, | ||
4712 | _eina_value_type_int64_flush, | ||
4713 | _eina_value_type_int64_copy, | ||
4714 | _eina_value_type_int64_compare, | ||
4715 | _eina_value_type_int64_convert_to, | ||
4716 | NULL, /* no convert from */ | ||
4717 | _eina_value_type_int64_vset, | ||
4718 | _eina_value_type_int64_pset, | ||
4719 | _eina_value_type_int64_pget | ||
4720 | }, | ||
4721 | { | ||
4722 | EINA_VALUE_TYPE_VERSION, | ||
4723 | sizeof(float), | ||
4724 | "float", | ||
4725 | _eina_value_type_float_setup, | ||
4726 | _eina_value_type_float_flush, | ||
4727 | _eina_value_type_float_copy, | ||
4728 | _eina_value_type_float_compare, | ||
4729 | _eina_value_type_float_convert_to, | ||
4730 | NULL, /* no convert from */ | ||
4731 | _eina_value_type_float_vset, | ||
4732 | _eina_value_type_float_pset, | ||
4733 | _eina_value_type_float_pget | ||
4734 | }, | ||
4735 | { | ||
4736 | EINA_VALUE_TYPE_VERSION, | ||
4737 | sizeof(double), | ||
4738 | "double", | ||
4739 | _eina_value_type_double_setup, | ||
4740 | _eina_value_type_double_flush, | ||
4741 | _eina_value_type_double_copy, | ||
4742 | _eina_value_type_double_compare, | ||
4743 | _eina_value_type_double_convert_to, | ||
4744 | NULL, /* no convert from */ | ||
4745 | _eina_value_type_double_vset, | ||
4746 | _eina_value_type_double_pset, | ||
4747 | _eina_value_type_double_pget | ||
4748 | }, | ||
4749 | { | ||
4750 | EINA_VALUE_TYPE_VERSION, | ||
4751 | sizeof(const char *), | ||
4752 | "stringshare", | ||
4753 | _eina_value_type_string_common_setup, | ||
4754 | _eina_value_type_stringshare_flush, | ||
4755 | _eina_value_type_stringshare_copy, | ||
4756 | _eina_value_type_string_common_compare, | ||
4757 | _eina_value_type_string_common_convert_to, | ||
4758 | NULL, /* no convert from */ | ||
4759 | _eina_value_type_stringshare_vset, | ||
4760 | _eina_value_type_stringshare_pset, | ||
4761 | _eina_value_type_string_common_pget | ||
4762 | }, | ||
4763 | { | ||
4764 | EINA_VALUE_TYPE_VERSION, | ||
4765 | sizeof(char *), | ||
4766 | "string", | ||
4767 | _eina_value_type_string_common_setup, | ||
4768 | _eina_value_type_string_flush, | ||
4769 | _eina_value_type_string_copy, | ||
4770 | _eina_value_type_string_common_compare, | ||
4771 | _eina_value_type_string_common_convert_to, | ||
4772 | NULL, /* no convert from */ | ||
4773 | _eina_value_type_string_vset, | ||
4774 | _eina_value_type_string_pset, | ||
4775 | _eina_value_type_string_common_pget | ||
4776 | }, | ||
4777 | { | ||
4778 | EINA_VALUE_TYPE_VERSION, | ||
4779 | sizeof(unsigned long), | ||
4780 | "timestamp", | ||
4781 | _eina_value_type_ulong_setup, | ||
4782 | _eina_value_type_ulong_flush, | ||
4783 | _eina_value_type_ulong_copy, | ||
4784 | _eina_value_type_ulong_compare, | ||
4785 | _eina_value_type_ulong_convert_to, | ||
4786 | NULL, /* no convert from */ | ||
4787 | _eina_value_type_ulong_vset, | ||
4788 | _eina_value_type_ulong_pset, | ||
4789 | _eina_value_type_ulong_pget | ||
4790 | } | ||
4791 | }; | ||
4792 | |||
4793 | static void | ||
4794 | _eina_value_blob_operations_malloc_free(const Eina_Value_Blob_Operations *ops __UNUSED__, void *memory, size_t size __UNUSED__) | ||
4795 | { | ||
4796 | free(memory); | ||
4797 | } | ||
4798 | |||
4799 | static void * | ||
4800 | _eina_value_blob_operations_malloc_copy(const Eina_Value_Blob_Operations *ops __UNUSED__, const void *memory, size_t size) | ||
4801 | { | ||
4802 | void *ret = malloc(size); | ||
4803 | if (!ret) | ||
4804 | { | ||
4805 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
4806 | return NULL; | ||
4807 | } | ||
4808 | memcpy(ret, memory, size); | ||
4809 | return ret; | ||
4810 | } | ||
4811 | |||
4812 | static const Eina_Value_Blob_Operations _EINA_VALUE_BLOB_OPERATIONS_MALLOC = { | ||
4813 | EINA_VALUE_BLOB_OPERATIONS_VERSION, | ||
4814 | _eina_value_blob_operations_malloc_free, | ||
4815 | _eina_value_blob_operations_malloc_copy, | ||
4816 | NULL, | ||
4817 | NULL | ||
4818 | }; | ||
4819 | |||
4820 | typedef struct _Eina_Value_Inner_Mp Eina_Value_Inner_Mp; | ||
4821 | struct _Eina_Value_Inner_Mp | ||
4822 | { | ||
4823 | Eina_Mempool *mempool; | ||
4824 | int references; | ||
4825 | }; | ||
4826 | |||
4827 | /** | ||
4828 | * @endcond | ||
4829 | */ | ||
4830 | |||
4831 | static const char EINA_ERROR_VALUE_FAILED_STR[] = "Value check failed."; | ||
4832 | |||
4833 | /** | ||
4834 | */ | ||
4835 | |||
4836 | static inline void | ||
4837 | _eina_value_inner_mp_dispose(int size, Eina_Value_Inner_Mp *imp) | ||
4838 | { | ||
4839 | EINA_SAFETY_ON_FALSE_RETURN(imp->references == 0); | ||
4840 | |||
4841 | eina_hash_del_by_key(_eina_value_inner_mps, &size); | ||
4842 | eina_mempool_del(imp->mempool); | ||
4843 | free(imp); | ||
4844 | } | ||
4845 | |||
4846 | static inline Eina_Value_Inner_Mp * | ||
4847 | _eina_value_inner_mp_get(int size) | ||
4848 | { | ||
4849 | Eina_Value_Inner_Mp *imp = eina_hash_find(_eina_value_inner_mps, &size); | ||
4850 | if (imp) return imp; | ||
4851 | |||
4852 | imp = malloc(sizeof(Eina_Value_Inner_Mp)); | ||
4853 | if (!imp) | ||
4854 | return NULL; | ||
4855 | |||
4856 | imp->references = 0; | ||
4857 | |||
4858 | imp->mempool = eina_mempool_add(_eina_value_mp_choice, | ||
4859 | "Eina_Value_Inner_Mp", NULL, size, 128); | ||
4860 | if (!imp->mempool) | ||
4861 | { | ||
4862 | free(imp); | ||
4863 | return NULL; | ||
4864 | } | ||
4865 | |||
4866 | if (!eina_hash_add(_eina_value_inner_mps, &size, imp)) | ||
4867 | { | ||
4868 | eina_mempool_del(imp->mempool); | ||
4869 | free(imp); | ||
4870 | return NULL; | ||
4871 | } | ||
4872 | |||
4873 | return imp; | ||
4874 | } | ||
4875 | |||
4876 | static inline void * | ||
4877 | _eina_value_inner_alloc_internal(int size) | ||
4878 | { | ||
4879 | Eina_Value_Inner_Mp *imp; | ||
4880 | void *mem; | ||
4881 | |||
4882 | imp = _eina_value_inner_mp_get(size); | ||
4883 | if (!imp) return NULL; | ||
4884 | |||
4885 | mem = eina_mempool_malloc(imp->mempool, size); | ||
4886 | if (mem) imp->references++; | ||
4887 | else if (imp->references == 0) _eina_value_inner_mp_dispose(size, imp); | ||
4888 | |||
4889 | return mem; | ||
4890 | } | ||
4891 | |||
4892 | static inline void | ||
4893 | _eina_value_inner_free_internal(int size, void *mem) | ||
4894 | { | ||
4895 | Eina_Value_Inner_Mp *imp = eina_hash_find(_eina_value_inner_mps, &size); | ||
4896 | EINA_SAFETY_ON_NULL_RETURN(imp); | ||
4897 | |||
4898 | eina_mempool_free(imp->mempool, mem); | ||
4899 | |||
4900 | imp->references--; | ||
4901 | if (imp->references > 0) return; | ||
4902 | _eina_value_inner_mp_dispose(size, imp); | ||
4903 | } | ||
4904 | |||
4905 | EAPI void * | ||
4906 | eina_value_inner_alloc(size_t size) | ||
4907 | { | ||
4908 | void *mem; | ||
4909 | |||
4910 | if (size > 256) return malloc(size); | ||
4911 | |||
4912 | eina_lock_take(&_eina_value_inner_mps_lock); | ||
4913 | mem = _eina_value_inner_alloc_internal(size); | ||
4914 | eina_lock_release(&_eina_value_inner_mps_lock); | ||
4915 | |||
4916 | return mem; | ||
4917 | } | ||
4918 | |||
4919 | EAPI void | ||
4920 | eina_value_inner_free(size_t size, void *mem) | ||
4921 | { | ||
4922 | if (size > 256) | ||
4923 | { | ||
4924 | free(mem); | ||
4925 | return; | ||
4926 | } | ||
4927 | |||
4928 | eina_lock_take(&_eina_value_inner_mps_lock); | ||
4929 | _eina_value_inner_free_internal(size, mem); | ||
4930 | eina_lock_release(&_eina_value_inner_mps_lock); | ||
4931 | } | ||
4932 | |||
4933 | /** | ||
4934 | * @internal | ||
4935 | * @brief Initialize the value module. | ||
4936 | * | ||
4937 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
4938 | * | ||
4939 | * This function sets up the value module of Eina. It is called | ||
4940 | * by eina_init(). | ||
4941 | * | ||
4942 | * @see eina_init() | ||
4943 | */ | ||
4944 | Eina_Bool | ||
4945 | eina_value_init(void) | ||
4946 | { | ||
4947 | const char *choice, *tmp; | ||
4948 | |||
4949 | _eina_value_log_dom = eina_log_domain_register("eina_value", | ||
4950 | EINA_LOG_COLOR_DEFAULT); | ||
4951 | if (_eina_value_log_dom < 0) | ||
4952 | { | ||
4953 | EINA_LOG_ERR("Could not register log domain: eina_value"); | ||
4954 | return EINA_FALSE; | ||
4955 | } | ||
4956 | |||
4957 | #ifdef EINA_DEFAULT_MEMPOOL | ||
4958 | choice = "pass_through"; | ||
4959 | #else | ||
4960 | choice = "chained_mempool"; | ||
4961 | #endif | ||
4962 | tmp = getenv("EINA_MEMPOOL"); | ||
4963 | if (tmp && tmp[0]) | ||
4964 | choice = tmp; | ||
4965 | |||
4966 | if (choice) | ||
4967 | _eina_value_mp_choice = strdup(choice); | ||
4968 | |||
4969 | _eina_value_mp = eina_mempool_add | ||
4970 | (_eina_value_mp_choice, "value", NULL, sizeof(Eina_Value), 320); | ||
4971 | if (!_eina_value_mp) | ||
4972 | { | ||
4973 | ERR("Mempool for value cannot be allocated in value init."); | ||
4974 | goto on_init_fail_mp; | ||
4975 | } | ||
4976 | |||
4977 | if (!eina_lock_new(&_eina_value_inner_mps_lock)) | ||
4978 | { | ||
4979 | ERR("Cannot create lock in value init."); | ||
4980 | goto on_init_fail_lock; | ||
4981 | } | ||
4982 | _eina_value_inner_mps = eina_hash_int32_new(NULL); | ||
4983 | if (!_eina_value_inner_mps) | ||
4984 | { | ||
4985 | ERR("Cannot create hash for inner mempools in value init."); | ||
4986 | goto on_init_fail_hash; | ||
4987 | } | ||
4988 | |||
4989 | EINA_ERROR_VALUE_FAILED = eina_error_msg_static_register( | ||
4990 | EINA_ERROR_VALUE_FAILED_STR); | ||
4991 | |||
4992 | EINA_VALUE_TYPE_UCHAR = _EINA_VALUE_TYPE_BASICS + 0; | ||
4993 | EINA_VALUE_TYPE_USHORT = _EINA_VALUE_TYPE_BASICS + 1; | ||
4994 | EINA_VALUE_TYPE_UINT = _EINA_VALUE_TYPE_BASICS + 2; | ||
4995 | EINA_VALUE_TYPE_ULONG = _EINA_VALUE_TYPE_BASICS + 3; | ||
4996 | EINA_VALUE_TYPE_UINT64 = _EINA_VALUE_TYPE_BASICS + 4; | ||
4997 | EINA_VALUE_TYPE_CHAR = _EINA_VALUE_TYPE_BASICS + 5; | ||
4998 | EINA_VALUE_TYPE_SHORT = _EINA_VALUE_TYPE_BASICS + 6; | ||
4999 | EINA_VALUE_TYPE_INT = _EINA_VALUE_TYPE_BASICS + 7; | ||
5000 | EINA_VALUE_TYPE_LONG = _EINA_VALUE_TYPE_BASICS + 8; | ||
5001 | EINA_VALUE_TYPE_INT64 = _EINA_VALUE_TYPE_BASICS + 9; | ||
5002 | EINA_VALUE_TYPE_FLOAT = _EINA_VALUE_TYPE_BASICS + 10; | ||
5003 | EINA_VALUE_TYPE_DOUBLE = _EINA_VALUE_TYPE_BASICS + 11; | ||
5004 | EINA_VALUE_TYPE_STRINGSHARE = _EINA_VALUE_TYPE_BASICS + 12; | ||
5005 | EINA_VALUE_TYPE_STRING = _EINA_VALUE_TYPE_BASICS + 13; | ||
5006 | EINA_VALUE_TYPE_TIMESTAMP = _EINA_VALUE_TYPE_BASICS + 14; | ||
5007 | |||
5008 | _EINA_VALUE_TYPE_BASICS_START = _EINA_VALUE_TYPE_BASICS + 0; | ||
5009 | _EINA_VALUE_TYPE_BASICS_END = _EINA_VALUE_TYPE_BASICS + 14; | ||
5010 | |||
5011 | EINA_SAFETY_ON_FALSE_RETURN_VAL((sizeof(_EINA_VALUE_TYPE_BASICS)/sizeof(_EINA_VALUE_TYPE_BASICS[0])) == 15, EINA_FALSE); | ||
5012 | |||
5013 | |||
5014 | EINA_VALUE_TYPE_ARRAY = &_EINA_VALUE_TYPE_ARRAY; | ||
5015 | EINA_VALUE_TYPE_LIST = &_EINA_VALUE_TYPE_LIST; | ||
5016 | EINA_VALUE_TYPE_HASH = &_EINA_VALUE_TYPE_HASH; | ||
5017 | EINA_VALUE_TYPE_TIMEVAL = &_EINA_VALUE_TYPE_TIMEVAL; | ||
5018 | EINA_VALUE_TYPE_BLOB = &_EINA_VALUE_TYPE_BLOB; | ||
5019 | EINA_VALUE_TYPE_STRUCT = &_EINA_VALUE_TYPE_STRUCT; | ||
5020 | EINA_VALUE_TYPE_MODEL = &_EINA_VALUE_TYPE_MODEL; | ||
5021 | |||
5022 | EINA_VALUE_BLOB_OPERATIONS_MALLOC = &_EINA_VALUE_BLOB_OPERATIONS_MALLOC; | ||
5023 | |||
5024 | EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH = &_EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH; | ||
5025 | EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE = &_EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE; | ||
5026 | |||
5027 | return EINA_TRUE; | ||
5028 | |||
5029 | on_init_fail_hash: | ||
5030 | eina_lock_free(&_eina_value_inner_mps_lock); | ||
5031 | on_init_fail_lock: | ||
5032 | eina_mempool_del(_eina_value_mp); | ||
5033 | on_init_fail_mp: | ||
5034 | free(_eina_value_mp_choice); | ||
5035 | _eina_value_mp_choice = NULL; | ||
5036 | eina_log_domain_unregister(_eina_value_log_dom); | ||
5037 | _eina_value_log_dom = -1; | ||
5038 | return EINA_FALSE; | ||
5039 | } | ||
5040 | |||
5041 | /** | ||
5042 | * @internal | ||
5043 | * @brief Shut down the value module. | ||
5044 | * | ||
5045 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
5046 | * | ||
5047 | * This function shuts down the value module set up by | ||
5048 | * eina_value_init(). It is called by eina_shutdown(). | ||
5049 | * | ||
5050 | * @see eina_shutdown() | ||
5051 | */ | ||
5052 | Eina_Bool | ||
5053 | eina_value_shutdown(void) | ||
5054 | { | ||
5055 | eina_lock_take(&_eina_value_inner_mps_lock); | ||
5056 | if (eina_hash_population(_eina_value_inner_mps) != 0) | ||
5057 | ERR("Cannot free eina_value internal memory pools -- still in use!"); | ||
5058 | else | ||
5059 | eina_hash_free(_eina_value_inner_mps); | ||
5060 | eina_lock_release(&_eina_value_inner_mps_lock); | ||
5061 | eina_lock_free(&_eina_value_inner_mps_lock); | ||
5062 | |||
5063 | free(_eina_value_mp_choice); | ||
5064 | _eina_value_mp_choice = NULL; | ||
5065 | eina_mempool_del(_eina_value_mp); | ||
5066 | eina_log_domain_unregister(_eina_value_log_dom); | ||
5067 | _eina_value_log_dom = -1; | ||
5068 | return EINA_TRUE; | ||
5069 | } | ||
5070 | |||
5071 | /*============================================================================* | ||
5072 | * Global * | ||
5073 | *============================================================================*/ | ||
5074 | |||
5075 | /*============================================================================* | ||
5076 | * API * | ||
5077 | *============================================================================*/ | ||
5078 | |||
5079 | EAPI const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_START = NULL; | ||
5080 | EAPI const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_END = NULL; | ||
5081 | |||
5082 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UCHAR = NULL; | ||
5083 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_USHORT = NULL; | ||
5084 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT = NULL; | ||
5085 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ULONG = NULL; | ||
5086 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMESTAMP = NULL; | ||
5087 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT64 = NULL; | ||
5088 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_CHAR = NULL; | ||
5089 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_SHORT = NULL; | ||
5090 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_INT = NULL; | ||
5091 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_LONG = NULL; | ||
5092 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_INT64 = NULL; | ||
5093 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_FLOAT = NULL; | ||
5094 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_DOUBLE = NULL; | ||
5095 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRINGSHARE = NULL; | ||
5096 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRING = NULL; | ||
5097 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ARRAY = NULL; | ||
5098 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_LIST = NULL; | ||
5099 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_HASH = NULL; | ||
5100 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMEVAL = NULL; | ||
5101 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_BLOB = NULL; | ||
5102 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRUCT = NULL; | ||
5103 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_MODEL = NULL; | ||
5104 | |||
5105 | EAPI const Eina_Value_Blob_Operations *EINA_VALUE_BLOB_OPERATIONS_MALLOC = NULL; | ||
5106 | |||
5107 | EAPI const Eina_Value_Struct_Operations *EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH = NULL; | ||
5108 | EAPI const Eina_Value_Struct_Operations *EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE = NULL; | ||
5109 | |||
5110 | EAPI Eina_Error EINA_ERROR_VALUE_FAILED = 0; | ||
5111 | |||
5112 | EAPI const unsigned int eina_prime_table[] = | ||
5113 | { | ||
5114 | 17, 31, 61, 127, 257, 509, 1021, | ||
5115 | 2053, 4093, 8191, 16381, 32771, 65537, 131071, 262147, 524287, 1048573, | ||
5116 | 2097143, 4194301, 8388617, 16777213 | ||
5117 | }; | ||
5118 | |||
5119 | EAPI Eina_Value * | ||
5120 | eina_value_new(const Eina_Value_Type *type) | ||
5121 | { | ||
5122 | Eina_Value *value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));; | ||
5123 | if (!value) | ||
5124 | { | ||
5125 | eina_error_set(EINA_ERROR_OUT_OF_MEMORY); | ||
5126 | return NULL; | ||
5127 | } | ||
5128 | if (!eina_value_setup(value, type)) | ||
5129 | { | ||
5130 | free(value); | ||
5131 | return NULL; | ||
5132 | } | ||
5133 | return value; | ||
5134 | } | ||
5135 | |||
5136 | EAPI void | ||
5137 | eina_value_free(Eina_Value *value) | ||
5138 | { | ||
5139 | EINA_SAFETY_ON_NULL_RETURN(value); | ||
5140 | eina_value_flush(value); | ||
5141 | eina_mempool_free(_eina_value_mp, value); | ||
5142 | } | ||
5143 | |||
5144 | |||
5145 | EAPI Eina_Bool | ||
5146 | eina_value_copy(const Eina_Value *value, Eina_Value *copy) | ||
5147 | { | ||
5148 | const Eina_Value_Type *type; | ||
5149 | const void *src; | ||
5150 | void *dst; | ||
5151 | Eina_Bool ret; | ||
5152 | |||
5153 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); | ||
5154 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), | ||
5155 | EINA_FALSE); | ||
5156 | EINA_SAFETY_ON_NULL_RETURN_VAL(copy, EINA_FALSE); | ||
5157 | EINA_SAFETY_ON_NULL_RETURN_VAL(value->type->copy, EINA_FALSE); | ||
5158 | |||
5159 | type = value->type; | ||
5160 | if (!eina_value_setup(copy, type)) | ||
5161 | return EINA_FALSE; | ||
5162 | |||
5163 | src = eina_value_memory_get(value); | ||
5164 | dst = eina_value_memory_get(copy); | ||
5165 | ret = type->copy(type, src, dst); | ||
5166 | if (!ret) | ||
5167 | eina_value_flush(copy); | ||
5168 | |||
5169 | return ret; | ||
5170 | } | ||
5171 | |||
5172 | EAPI Eina_Bool | ||
5173 | eina_value_convert(const Eina_Value *value, Eina_Value *convert) | ||
5174 | { | ||
5175 | Eina_Bool ret = EINA_FALSE; | ||
5176 | const Eina_Value_Type *type, *convert_type; | ||
5177 | const void *type_mem; | ||
5178 | void *convert_mem; | ||
5179 | |||
5180 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); | ||
5181 | EINA_SAFETY_ON_NULL_RETURN_VAL(convert, EINA_FALSE); | ||
5182 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), | ||
5183 | EINA_FALSE); | ||
5184 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(convert->type), | ||
5185 | EINA_FALSE); | ||
5186 | |||
5187 | type = value->type; | ||
5188 | convert_type = convert->type; | ||
5189 | |||
5190 | type_mem = eina_value_memory_get(value); | ||
5191 | convert_mem = eina_value_memory_get(convert); | ||
5192 | |||
5193 | if (type->convert_to) | ||
5194 | ret = type->convert_to(type, convert_type, type_mem, convert_mem); | ||
5195 | |||
5196 | if ((!ret) && (convert_type->convert_from)) | ||
5197 | ret = convert_type->convert_from(convert_type, type, convert_mem, | ||
5198 | type_mem); | ||
5199 | |||
5200 | return ret; | ||
5201 | } | ||
5202 | |||
5203 | EAPI char * | ||
5204 | eina_value_to_string(const Eina_Value *value) | ||
5205 | { | ||
5206 | Eina_Value tmp; | ||
5207 | |||
5208 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, NULL); | ||
5209 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), NULL); | ||
5210 | |||
5211 | if (!eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING)) | ||
5212 | return NULL; | ||
5213 | if (!eina_value_convert(value, &tmp)) | ||
5214 | return NULL; | ||
5215 | |||
5216 | return tmp.value.ptr; /* steal value */ | ||
5217 | } | ||
5218 | |||
5219 | EAPI Eina_Value * | ||
5220 | eina_value_array_new(const Eina_Value_Type *subtype, unsigned int step) | ||
5221 | { | ||
5222 | Eina_Value *value; | ||
5223 | |||
5224 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(subtype), EINA_FALSE); | ||
5225 | |||
5226 | value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));; | ||
5227 | if (!value) | ||
5228 | return NULL; | ||
5229 | |||
5230 | if (!eina_value_array_setup(value, subtype, step)) | ||
5231 | { | ||
5232 | eina_mempool_free(_eina_value_mp, value); | ||
5233 | return NULL; | ||
5234 | } | ||
5235 | |||
5236 | return value; | ||
5237 | } | ||
5238 | |||
5239 | EAPI Eina_Value * | ||
5240 | eina_value_list_new(const Eina_Value_Type *subtype) | ||
5241 | { | ||
5242 | Eina_Value *value; | ||
5243 | |||
5244 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(subtype), EINA_FALSE); | ||
5245 | |||
5246 | value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));; | ||
5247 | if (!value) | ||
5248 | return NULL; | ||
5249 | |||
5250 | if (!eina_value_list_setup(value, subtype)) | ||
5251 | { | ||
5252 | eina_mempool_free(_eina_value_mp, value); | ||
5253 | return NULL; | ||
5254 | } | ||
5255 | |||
5256 | return value; | ||
5257 | } | ||
5258 | |||
5259 | EAPI Eina_Value * | ||
5260 | eina_value_hash_new(const Eina_Value_Type *subtype, unsigned int buckets_power_size) | ||
5261 | { | ||
5262 | Eina_Value *value; | ||
5263 | |||
5264 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(subtype), EINA_FALSE); | ||
5265 | |||
5266 | value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));; | ||
5267 | if (!value) | ||
5268 | return NULL; | ||
5269 | |||
5270 | if (!eina_value_hash_setup(value, subtype, buckets_power_size)) | ||
5271 | { | ||
5272 | eina_mempool_free(_eina_value_mp, value); | ||
5273 | return NULL; | ||
5274 | } | ||
5275 | |||
5276 | return value; | ||
5277 | } | ||
5278 | |||
5279 | EAPI Eina_Value * | ||
5280 | eina_value_struct_new(const Eina_Value_Struct_Desc *desc) | ||
5281 | { | ||
5282 | Eina_Value *value; | ||
5283 | |||
5284 | value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));; | ||
5285 | if (!value) | ||
5286 | return NULL; | ||
5287 | |||
5288 | if (!eina_value_struct_setup(value, desc)) | ||
5289 | { | ||
5290 | eina_mempool_free(_eina_value_mp, value); | ||
5291 | return NULL; | ||
5292 | } | ||
5293 | |||
5294 | return value; | ||
5295 | } | ||
5296 | |||
5297 | EAPI Eina_Bool | ||
5298 | eina_value_type_check(const Eina_Value_Type *type) | ||
5299 | { | ||
5300 | EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE); | ||
5301 | return type->version == EINA_VALUE_TYPE_VERSION; | ||
5302 | } | ||
5303 | |||
5304 | EAPI const char * | ||
5305 | eina_value_type_name_get(const Eina_Value_Type *type) | ||
5306 | { | ||
5307 | EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), NULL); | ||
5308 | return type->name; | ||
5309 | } | ||
diff --git a/libraries/eina/src/lib/eina_xattr.c b/libraries/eina/src/lib/eina_xattr.c deleted file mode 100644 index d4ed139..0000000 --- a/libraries/eina/src/lib/eina_xattr.c +++ /dev/null | |||
@@ -1,483 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2011 Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library 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 GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdlib.h> | ||
24 | #include <sys/types.h> | ||
25 | #include <string.h> | ||
26 | #include <math.h> | ||
27 | |||
28 | #ifdef HAVE_XATTR | ||
29 | # include <sys/xattr.h> | ||
30 | #endif | ||
31 | |||
32 | #include "eina_config.h" | ||
33 | #include "eina_private.h" | ||
34 | |||
35 | #include "eina_safety_checks.h" | ||
36 | #include "eina_xattr.h" | ||
37 | #include "eina_convert.h" | ||
38 | #include "eina_stringshare.h" | ||
39 | |||
40 | /*============================================================================* | ||
41 | * Local * | ||
42 | *============================================================================*/ | ||
43 | |||
44 | /** | ||
45 | * @cond LOCAL | ||
46 | */ | ||
47 | |||
48 | typedef struct _Eina_Xattr_Iterator Eina_Xattr_Iterator; | ||
49 | |||
50 | struct _Eina_Xattr_Iterator | ||
51 | { | ||
52 | Eina_Iterator iterator; | ||
53 | |||
54 | const char *file; | ||
55 | Eina_Xattr *attr; | ||
56 | |||
57 | ssize_t length; | ||
58 | ssize_t offset; | ||
59 | |||
60 | int fd; | ||
61 | |||
62 | char xattr[1]; | ||
63 | }; | ||
64 | |||
65 | #ifdef HAVE_XATTR | ||
66 | static Eina_Bool | ||
67 | _eina_xattr_value_ls_fd_iterator_next(Eina_Xattr_Iterator *it, void **data) | ||
68 | { | ||
69 | char *tmp; | ||
70 | |||
71 | if (it->offset >= it->length) | ||
72 | return EINA_FALSE; | ||
73 | |||
74 | *data = it->attr; | ||
75 | it->attr->name = it->xattr + it->offset; | ||
76 | |||
77 | it->attr->length = fgetxattr(it->fd, it->attr->name, NULL, 0); | ||
78 | if (it->attr->length) | ||
79 | { | ||
80 | tmp = realloc((void*) it->attr->value, it->attr->length); | ||
81 | if (!tmp) | ||
82 | { | ||
83 | free((void*) it->attr->value); | ||
84 | it->attr->value = NULL; | ||
85 | it->attr->length = 0; | ||
86 | } | ||
87 | else | ||
88 | { | ||
89 | it->attr->length = fgetxattr(it->fd, it->attr->name, | ||
90 | (void *) it->attr->value, | ||
91 | it->attr->length); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | return EINA_TRUE; | ||
96 | } | ||
97 | |||
98 | static Eina_Bool | ||
99 | _eina_xattr_value_ls_iterator_next(Eina_Xattr_Iterator *it, void **data) | ||
100 | { | ||
101 | char *tmp; | ||
102 | |||
103 | if (it->offset >= it->length) | ||
104 | return EINA_FALSE; | ||
105 | |||
106 | *data = it->attr; | ||
107 | it->attr->name = it->xattr + it->offset; | ||
108 | |||
109 | it->attr->length = getxattr(it->file, it->attr->name, NULL, 0); | ||
110 | if (it->attr->length) | ||
111 | { | ||
112 | tmp = realloc((void*) it->attr->value, it->attr->length); | ||
113 | if (!tmp) | ||
114 | { | ||
115 | free((void*) it->attr->value); | ||
116 | it->attr->value = NULL; | ||
117 | it->attr->length = 0; | ||
118 | } | ||
119 | else | ||
120 | { | ||
121 | it->attr->length = getxattr(it->file, it->attr->name, | ||
122 | (void*) it->attr->value, | ||
123 | it->attr->length); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | return EINA_TRUE; | ||
128 | } | ||
129 | |||
130 | static Eina_Bool | ||
131 | _eina_xattr_ls_iterator_next(Eina_Xattr_Iterator *it, void **data) | ||
132 | { | ||
133 | if (it->offset >= it->length) | ||
134 | return EINA_FALSE; | ||
135 | |||
136 | *data = it->xattr + it->offset; | ||
137 | it->offset += strlen(it->xattr + it->offset) + 1; | ||
138 | |||
139 | return EINA_TRUE; | ||
140 | } | ||
141 | |||
142 | static void * | ||
143 | _eina_xattr_ls_iterator_container(Eina_Xattr_Iterator *it __UNUSED__) | ||
144 | { | ||
145 | return NULL; | ||
146 | } | ||
147 | |||
148 | static void | ||
149 | _eina_xattr_ls_iterator_free(Eina_Xattr_Iterator *it) | ||
150 | { | ||
151 | EINA_MAGIC_SET(&it->iterator, 0); | ||
152 | if (it->attr) free((void *) it->attr->value); | ||
153 | eina_stringshare_del(it->file); | ||
154 | free(it->attr); | ||
155 | free(it); | ||
156 | } | ||
157 | #endif | ||
158 | |||
159 | /** | ||
160 | * @endcond | ||
161 | */ | ||
162 | |||
163 | |||
164 | /*============================================================================* | ||
165 | * Global * | ||
166 | *============================================================================*/ | ||
167 | |||
168 | |||
169 | /*============================================================================* | ||
170 | * API * | ||
171 | *============================================================================*/ | ||
172 | |||
173 | EAPI Eina_Iterator * | ||
174 | eina_xattr_value_fd_ls(int fd) | ||
175 | { | ||
176 | #ifdef HAVE_XATTR | ||
177 | Eina_Xattr_Iterator *it; | ||
178 | ssize_t length; | ||
179 | |||
180 | if (fd < 0) return NULL; | ||
181 | |||
182 | length = flistxattr(fd, NULL, 0); | ||
183 | if (length <= 0) return NULL; | ||
184 | |||
185 | it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); | ||
186 | if (!it) return NULL; | ||
187 | |||
188 | it->attr = calloc(1, sizeof (Eina_Xattr)); | ||
189 | if (!it->attr) | ||
190 | { | ||
191 | free(it); | ||
192 | return NULL; | ||
193 | } | ||
194 | |||
195 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
196 | |||
197 | it->fd = fd; | ||
198 | it->length = flistxattr(fd, it->xattr, length); | ||
199 | if (it->length != length) | ||
200 | { | ||
201 | free(it); | ||
202 | return NULL; | ||
203 | } | ||
204 | |||
205 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
206 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_value_ls_fd_iterator_next); | ||
207 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); | ||
208 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); | ||
209 | |||
210 | return &it->iterator; | ||
211 | #else | ||
212 | return NULL; | ||
213 | (void)fd; | ||
214 | #endif | ||
215 | } | ||
216 | |||
217 | EAPI Eina_Iterator * | ||
218 | eina_xattr_fd_ls(int fd) | ||
219 | { | ||
220 | #ifdef HAVE_XATTR | ||
221 | Eina_Xattr_Iterator *it; | ||
222 | ssize_t length; | ||
223 | |||
224 | if (fd < 0) return NULL; | ||
225 | |||
226 | length = flistxattr(fd, NULL, 0); | ||
227 | if (length <= 0) return NULL; | ||
228 | |||
229 | it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); | ||
230 | if (!it) return NULL; | ||
231 | |||
232 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
233 | |||
234 | it->length = flistxattr(fd, it->xattr, length); | ||
235 | if (it->length != length) | ||
236 | { | ||
237 | free(it); | ||
238 | return NULL; | ||
239 | } | ||
240 | |||
241 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
242 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_ls_iterator_next); | ||
243 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); | ||
244 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); | ||
245 | |||
246 | return &it->iterator; | ||
247 | #else | ||
248 | return NULL; | ||
249 | (void)fd; | ||
250 | #endif | ||
251 | } | ||
252 | |||
253 | EAPI Eina_Iterator * | ||
254 | eina_xattr_ls(const char *file) | ||
255 | { | ||
256 | #ifdef HAVE_XATTR | ||
257 | Eina_Xattr_Iterator *it; | ||
258 | ssize_t length; | ||
259 | |||
260 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
261 | |||
262 | length = listxattr(file, NULL, 0); | ||
263 | if (length <= 0) return NULL; | ||
264 | |||
265 | it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); | ||
266 | if (!it) return NULL; | ||
267 | |||
268 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
269 | |||
270 | it->length = listxattr(file, it->xattr, length); | ||
271 | if (it->length != length) | ||
272 | { | ||
273 | free(it); | ||
274 | return NULL; | ||
275 | } | ||
276 | |||
277 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
278 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_ls_iterator_next); | ||
279 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); | ||
280 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); | ||
281 | |||
282 | return &it->iterator; | ||
283 | #else | ||
284 | return NULL; | ||
285 | (void)file; | ||
286 | #endif | ||
287 | } | ||
288 | |||
289 | EAPI Eina_Iterator * | ||
290 | eina_xattr_value_ls(const char *file) | ||
291 | { | ||
292 | #ifdef HAVE_XATTR | ||
293 | Eina_Xattr_Iterator *it; | ||
294 | ssize_t length; | ||
295 | |||
296 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
297 | |||
298 | length = listxattr(file, NULL, 0); | ||
299 | if (length <= 0) return NULL; | ||
300 | |||
301 | it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); | ||
302 | if (!it) return NULL; | ||
303 | |||
304 | EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); | ||
305 | |||
306 | it->length = listxattr(file, it->xattr, length); | ||
307 | if (it->length != length) | ||
308 | { | ||
309 | free(it); | ||
310 | return NULL; | ||
311 | } | ||
312 | |||
313 | it->file = eina_stringshare_add(file); | ||
314 | |||
315 | it->iterator.version = EINA_ITERATOR_VERSION; | ||
316 | it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_value_ls_iterator_next); | ||
317 | it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); | ||
318 | it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); | ||
319 | |||
320 | return &it->iterator; | ||
321 | #else | ||
322 | return NULL; | ||
323 | (void)file; | ||
324 | #endif | ||
325 | } | ||
326 | |||
327 | EAPI void * | ||
328 | eina_xattr_get(const char *file, const char *attribute, ssize_t *size) | ||
329 | { | ||
330 | #ifdef HAVE_XATTR | ||
331 | void *ret = NULL; | ||
332 | ssize_t tmp; | ||
333 | |||
334 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
335 | EINA_SAFETY_ON_NULL_RETURN_VAL(attribute, NULL); | ||
336 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!size, NULL); | ||
337 | |||
338 | *size = getxattr(file, attribute, NULL, 0); | ||
339 | /* Size should be less than 2MB (already huge in my opinion) */ | ||
340 | if (!(*size > 0 && *size < 2 * 1024 * 1024)) | ||
341 | goto on_error; | ||
342 | |||
343 | ret = malloc(*size); | ||
344 | if (!ret) return NULL; | ||
345 | |||
346 | tmp = getxattr(file, attribute, ret, *size); | ||
347 | if (tmp != *size) | ||
348 | goto on_error; | ||
349 | |||
350 | return ret; | ||
351 | |||
352 | on_error: | ||
353 | free(ret); | ||
354 | *size = 0; | ||
355 | return NULL; | ||
356 | #else | ||
357 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!size, NULL); | ||
358 | *size = 0; | ||
359 | return NULL; | ||
360 | (void)file; | ||
361 | (void)attribute; | ||
362 | #endif | ||
363 | } | ||
364 | |||
365 | EAPI Eina_Bool | ||
366 | eina_xattr_set(const char *file, const char *attribute, const void *data, ssize_t length, Eina_Xattr_Flags flags) | ||
367 | { | ||
368 | #ifdef HAVE_XATTR | ||
369 | int iflags; | ||
370 | |||
371 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE); | ||
372 | EINA_SAFETY_ON_NULL_RETURN_VAL(attribute, EINA_FALSE); | ||
373 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); | ||
374 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!(length > 0 && length < 2 * 1024 * 1024), EINA_FALSE); | ||
375 | |||
376 | switch (flags) | ||
377 | { | ||
378 | case EINA_XATTR_INSERT: iflags = 0; break; | ||
379 | case EINA_XATTR_REPLACE: iflags = XATTR_REPLACE; break; | ||
380 | case EINA_XATTR_CREATED: iflags = XATTR_CREATE; break; | ||
381 | default: | ||
382 | return EINA_FALSE; | ||
383 | } | ||
384 | |||
385 | if (setxattr(file, attribute, data, length, iflags)) | ||
386 | return EINA_FALSE; | ||
387 | return EINA_TRUE; | ||
388 | #else | ||
389 | return EINA_FALSE; | ||
390 | (void)file; | ||
391 | (void)attribute; | ||
392 | (void)data; | ||
393 | (void)length; | ||
394 | (void)flags; | ||
395 | #endif | ||
396 | } | ||
397 | |||
398 | EAPI Eina_Bool | ||
399 | eina_xattr_string_set(const char *file, const char *attribute, const char *data, Eina_Xattr_Flags flags) | ||
400 | { | ||
401 | EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE); | ||
402 | |||
403 | return eina_xattr_set(file, attribute, data, strlen(data) + 1, flags); | ||
404 | } | ||
405 | |||
406 | EAPI char * | ||
407 | eina_xattr_string_get(const char *file, const char *attribute) | ||
408 | { | ||
409 | char *tmp; | ||
410 | ssize_t size; | ||
411 | |||
412 | tmp = eina_xattr_get(file, attribute, &size); | ||
413 | if (!tmp) return NULL; | ||
414 | |||
415 | if (tmp[size - 1] != '\0') | ||
416 | { | ||
417 | free(tmp); | ||
418 | return NULL; | ||
419 | } | ||
420 | |||
421 | return tmp; | ||
422 | } | ||
423 | |||
424 | EAPI Eina_Bool | ||
425 | eina_xattr_double_set(const char *file, const char *attribute, double value, Eina_Xattr_Flags flags) | ||
426 | { | ||
427 | char buffer[128]; | ||
428 | |||
429 | eina_convert_dtoa(value, buffer); | ||
430 | return eina_xattr_string_set(file, attribute, buffer, flags); | ||
431 | } | ||
432 | |||
433 | EAPI Eina_Bool | ||
434 | eina_xattr_double_get(const char *file, const char *attribute, double *value) | ||
435 | { | ||
436 | char *tmp; | ||
437 | long long int m = 0; | ||
438 | long int e = 0; | ||
439 | |||
440 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); | ||
441 | |||
442 | tmp = eina_xattr_string_get(file, attribute); | ||
443 | if (!tmp) return EINA_FALSE; | ||
444 | |||
445 | if (!eina_convert_atod(tmp, strlen(tmp), &m, &e)) | ||
446 | { | ||
447 | free(tmp); | ||
448 | return EINA_FALSE; | ||
449 | } | ||
450 | |||
451 | *value = ldexp((double)m, e); | ||
452 | free(tmp); | ||
453 | |||
454 | return EINA_TRUE; | ||
455 | } | ||
456 | |||
457 | EAPI Eina_Bool | ||
458 | eina_xattr_int_set(const char *file, const char *attribute, int value, Eina_Xattr_Flags flags) | ||
459 | { | ||
460 | char buffer[10]; | ||
461 | |||
462 | eina_convert_itoa(value, buffer); | ||
463 | return eina_xattr_string_set(file, attribute, buffer, flags); | ||
464 | } | ||
465 | |||
466 | EAPI Eina_Bool | ||
467 | eina_xattr_int_get(const char *file, const char *attribute, int *value) | ||
468 | { | ||
469 | char *tmp; | ||
470 | char *eos; | ||
471 | Eina_Bool result; | ||
472 | |||
473 | EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); | ||
474 | |||
475 | tmp = eina_xattr_string_get(file, attribute); | ||
476 | if (!tmp) return EINA_FALSE; | ||
477 | |||
478 | *value = (int) strtol(tmp, &eos, 10); | ||
479 | result = (*eos == '\0'); | ||
480 | free(tmp); | ||
481 | |||
482 | return result; | ||
483 | } | ||