aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/lib
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 17:29:19 +1000
committerDavid Walter Seikel2013-01-13 17:29:19 +1000
commit07274513e984f0b5544586c74508ccd16e7dcafa (patch)
treeb32ff2a9136fbc1a4a6a0ed1e4d79cde0f5f16d9 /libraries/eina/src/lib
parentAdded Irrlicht 1.8, but without all the Windows binaries. (diff)
downloadSledjHamr-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 '')
-rw-r--r--libraries/eina/src/lib/Makefile.am178
-rw-r--r--libraries/eina/src/lib/Makefile.in1260
-rw-r--r--libraries/eina/src/lib/eina_accessor.c176
-rw-r--r--libraries/eina/src/lib/eina_array.c491
-rw-r--r--libraries/eina/src/lib/eina_benchmark.c372
-rw-r--r--libraries/eina/src/lib/eina_binbuf.c62
-rw-r--r--libraries/eina/src/lib/eina_binbuf_template_c.x153
-rw-r--r--libraries/eina/src/lib/eina_binshare.c182
-rw-r--r--libraries/eina/src/lib/eina_convert.c483
-rw-r--r--libraries/eina/src/lib/eina_counter.c362
-rw-r--r--libraries/eina/src/lib/eina_cpu.c207
-rw-r--r--libraries/eina/src/lib/eina_error.c279
-rw-r--r--libraries/eina/src/lib/eina_file.c1359
-rw-r--r--libraries/eina/src/lib/eina_file_win32.c1214
-rw-r--r--libraries/eina/src/lib/eina_fp.c532
-rw-r--r--libraries/eina/src/lib/eina_hamster.c113
-rw-r--r--libraries/eina/src/lib/eina_hash.c1377
-rw-r--r--libraries/eina/src/lib/eina_inarray.c777
-rw-r--r--libraries/eina/src/lib/eina_inlist.c914
-rw-r--r--libraries/eina/src/lib/eina_iterator.c172
-rw-r--r--libraries/eina/src/lib/eina_lalloc.c158
-rw-r--r--libraries/eina/src/lib/eina_list.c1491
-rw-r--r--libraries/eina/src/lib/eina_log.c1993
-rw-r--r--libraries/eina/src/lib/eina_magic.c322
-rw-r--r--libraries/eina/src/lib/eina_main.c440
-rw-r--r--libraries/eina/src/lib/eina_matrixsparse.c1423
-rw-r--r--libraries/eina/src/lib/eina_mempool.c387
-rw-r--r--libraries/eina/src/lib/eina_mmap.c190
-rw-r--r--libraries/eina/src/lib/eina_model.c5548
-rw-r--r--libraries/eina/src/lib/eina_module.c604
-rw-r--r--libraries/eina/src/lib/eina_prefix.c726
-rw-r--r--libraries/eina/src/lib/eina_private.h148
-rw-r--r--libraries/eina/src/lib/eina_quadtree.c935
-rw-r--r--libraries/eina/src/lib/eina_rbtree.c519
-rw-r--r--libraries/eina/src/lib/eina_rectangle.c568
-rw-r--r--libraries/eina/src/lib/eina_safety_checks.c90
-rw-r--r--libraries/eina/src/lib/eina_sched.c101
-rw-r--r--libraries/eina/src/lib/eina_share_common.c949
-rw-r--r--libraries/eina/src/lib/eina_share_common.h86
-rw-r--r--libraries/eina/src/lib/eina_simple_xml_parser.c1073
-rw-r--r--libraries/eina/src/lib/eina_str.c462
-rw-r--r--libraries/eina/src/lib/eina_strbuf.c202
-rw-r--r--libraries/eina/src/lib/eina_strbuf_common.c874
-rw-r--r--libraries/eina/src/lib/eina_strbuf_common.h120
-rw-r--r--libraries/eina/src/lib/eina_strbuf_template_c.x97
-rw-r--r--libraries/eina/src/lib/eina_stringshare.c792
-rw-r--r--libraries/eina/src/lib/eina_tiler.c1276
-rw-r--r--libraries/eina/src/lib/eina_unicode.c450
-rw-r--r--libraries/eina/src/lib/eina_ustrbuf.c74
-rw-r--r--libraries/eina/src/lib/eina_ustringshare.c189
-rw-r--r--libraries/eina/src/lib/eina_value.c5309
-rw-r--r--libraries/eina/src/lib/eina_xattr.c483
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 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_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
12base_sources = \
13eina_accessor.c \
14eina_array.c \
15eina_benchmark.c \
16eina_binbuf.c \
17eina_binshare.c \
18eina_convert.c \
19eina_counter.c \
20eina_cpu.c \
21eina_error.c \
22eina_fp.c \
23eina_hamster.c \
24eina_hash.c \
25eina_inarray.c \
26eina_inlist.c \
27eina_iterator.c \
28eina_lalloc.c \
29eina_list.c \
30eina_log.c \
31eina_magic.c \
32eina_main.c \
33eina_matrixsparse.c \
34eina_mempool.c \
35eina_mmap.c \
36eina_model.c \
37eina_module.c \
38eina_prefix.c \
39eina_quadtree.c \
40eina_rbtree.c \
41eina_rectangle.c \
42eina_safety_checks.c \
43eina_sched.c \
44eina_share_common.c \
45eina_simple_xml_parser.c \
46eina_str.c \
47eina_strbuf.c \
48eina_strbuf_common.c \
49eina_stringshare.c \
50eina_tiler.c \
51eina_unicode.c \
52eina_ustrbuf.c \
53eina_ustringshare.c \
54eina_value.c \
55eina_xattr.c
56
57# Will be back for developper after 1.1
58# eina_object.c
59
60if EINA_HAVE_WIN32
61base_sources += eina_file_win32.c
62else
63base_sources += eina_file.c
64endif
65
66EXTRA_DIST = \
67eina_share_common.h \
68eina_private.h \
69eina_strbuf_common.h \
70eina_strbuf_template_c.x \
71eina_binbuf_template_c.x
72
73
74
75if EINA_STATIC_BUILD_BUDDY
76base_sources += $(top_srcdir)/src/modules/mp/buddy/eina_buddy.c
77endif
78
79if EINA_STATIC_BUILD_CHAINED_POOL
80base_sources += $(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c
81endif
82
83if EINA_STATIC_BUILD_EMEMOA_FIXED
84base_sources += $(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c
85endif
86
87if EINA_STATIC_BUILD_EMEMOA_UNKNOWN
88base_sources += $(top_srcdir)/src/modules/mp/ememoa_unknown/eina_ememoa_unknown.c
89endif
90
91if EINA_STATIC_BUILD_FIXED_BITMAP
92base_sources += $(top_srcdir)/src/modules/mp/fixed_bitmap/eina_fixed_bitmap.c
93endif
94
95if EINA_STATIC_BUILD_ONE_BIG
96base_sources += $(top_srcdir)/src/modules/mp/one_big/eina_one_big.c
97endif
98
99if EINA_STATIC_BUILD_PASS_THROUGH
100base_sources += $(top_srcdir)/src/modules/mp/pass_through/eina_pass_through.c
101endif
102
103lib_LTLIBRARIES = libeina.la
104
105if EINA_AMALGAMATION
106nodist_libeina_la_SOURCES = eina_amalgamation.c
107
108eina_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
169else
170libeina_la_SOURCES = $(base_sources)
171endif
172
173libeina_la_LIBADD = @iconv_libs@ @rt_libs@ @EINA_LIBS@ @dlopen_libs@
174libeina_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ @EFL_PTHREAD_LIBS@
175libeina_la_CFLAGS = @EINA_CFLAGS@ @EFL_PTHREAD_CFLAGS@
176
177clean-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
18VPATH = @srcdir@
19pkgdatadir = $(datadir)/@PACKAGE@
20pkgincludedir = $(includedir)/@PACKAGE@
21pkglibdir = $(libdir)/@PACKAGE@
22pkglibexecdir = $(libexecdir)/@PACKAGE@
23am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
24install_sh_DATA = $(install_sh) -c -m 644
25install_sh_PROGRAM = $(install_sh) -c
26install_sh_SCRIPT = $(install_sh) -c
27INSTALL_HEADER = $(INSTALL_DATA)
28transform = $(program_transform_name)
29NORMAL_INSTALL = :
30PRE_INSTALL = :
31POST_INSTALL = :
32NORMAL_UNINSTALL = :
33PRE_UNINSTALL = :
34POST_UNINSTALL = :
35build_triplet = @build@
36host_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
49subdir = src/lib
50DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
51ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
52am__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
70am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
71 $(ACLOCAL_M4)
72mkinstalldirs = $(install_sh) -d
73CONFIG_HEADER = $(top_builddir)/config.h
74CONFIG_CLEAN_FILES =
75CONFIG_CLEAN_VPATH_FILES =
76am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
77am__vpath_adj = case $$p in \
78 $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
79 *) f=$$p;; \
80 esac;
81am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
82am__install_max = 40
83am__nobase_strip_setup = \
84 srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
85am__nobase_strip = \
86 for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
87am__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] }'
94am__base_list = \
95 sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
96 sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
97am__installdirs = "$(DESTDIR)$(libdir)"
98LTLIBRARIES = $(lib_LTLIBRARIES)
99libeina_la_DEPENDENCIES =
100am__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
131am__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
159libeina_la_OBJECTS = $(am_libeina_la_OBJECTS) \
160 $(nodist_libeina_la_OBJECTS)
161AM_V_lt = $(am__v_lt_$(V))
162am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
163am__v_lt_0 = --silent
164libeina_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 $@
167DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
168depcomp = $(SHELL) $(top_srcdir)/depcomp
169am__depfiles_maybe = depfiles
170am__mv = mv -f
171COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
172 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
173LTCOMPILE = $(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)
177AM_V_CC = $(am__v_CC_$(V))
178am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
179am__v_CC_0 = @echo " CC " $@;
180AM_V_at = $(am__v_at_$(V))
181am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
182am__v_at_0 = @
183CCLD = $(CC)
184LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
185 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
186 $(AM_LDFLAGS) $(LDFLAGS) -o $@
187AM_V_CCLD = $(am__v_CCLD_$(V))
188am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
189am__v_CCLD_0 = @echo " CCLD " $@;
190AM_V_GEN = $(am__v_GEN_$(V))
191am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
192am__v_GEN_0 = @echo " GEN " $@;
193SOURCES = $(libeina_la_SOURCES) $(nodist_libeina_la_SOURCES)
194DIST_SOURCES = $(am__libeina_la_SOURCES_DIST)
195ETAGS = etags
196CTAGS = ctags
197DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
198ACLOCAL = @ACLOCAL@
199ALLOCA = @ALLOCA@
200AMTAR = @AMTAR@
201AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
202AR = @AR@
203AS = @AS@
204AUTOCONF = @AUTOCONF@
205AUTOHEADER = @AUTOHEADER@
206AUTOMAKE = @AUTOMAKE@
207AWK = @AWK@
208CC = @CC@
209CCDEPMODE = @CCDEPMODE@
210CFLAGS = @CFLAGS@
211CHECK_CFLAGS = @CHECK_CFLAGS@
212CHECK_LIBS = @CHECK_LIBS@
213CPP = @CPP@
214CPPFLAGS = @CPPFLAGS@
215CXX = @CXX@
216CXXCPP = @CXXCPP@
217CXXDEPMODE = @CXXDEPMODE@
218CXXFLAGS = @CXXFLAGS@
219CYGPATH_W = @CYGPATH_W@
220DEFS = @DEFS@
221DEPDIR = @DEPDIR@
222DLLTOOL = @DLLTOOL@
223DSYMUTIL = @DSYMUTIL@
224DUMPBIN = @DUMPBIN@
225ECHO_C = @ECHO_C@
226ECHO_N = @ECHO_N@
227ECHO_T = @ECHO_T@
228ECORE_EVAS_CFLAGS = @ECORE_EVAS_CFLAGS@
229ECORE_EVAS_LIBS = @ECORE_EVAS_LIBS@
230EFL_COVERAGE_CFLAGS = @EFL_COVERAGE_CFLAGS@
231EFL_COVERAGE_LIBS = @EFL_COVERAGE_LIBS@
232EFL_EINA_BUILD = @EFL_EINA_BUILD@
233EFL_FNMATCH_LIBS = @EFL_FNMATCH_LIBS@
234EFL_PTHREAD_CFLAGS = @EFL_PTHREAD_CFLAGS@
235EFL_PTHREAD_LIBS = @EFL_PTHREAD_LIBS@
236EFL_SIMD_FLAGS = @EFL_SIMD_FLAGS@
237EGREP = @EGREP@
238EINA_CFLAGS = @EINA_CFLAGS@
239EINA_CONFIGURE_DEFAULT_MEMPOOL = @EINA_CONFIGURE_DEFAULT_MEMPOOL@
240EINA_CONFIGURE_ENABLE_LOG = @EINA_CONFIGURE_ENABLE_LOG@
241EINA_CONFIGURE_HAVE_DEBUG_THREADS = @EINA_CONFIGURE_HAVE_DEBUG_THREADS@
242EINA_CONFIGURE_HAVE_DIRENT_H = @EINA_CONFIGURE_HAVE_DIRENT_H@
243EINA_CONFIGURE_HAVE_EXOTIC = @EINA_CONFIGURE_HAVE_EXOTIC@
244EINA_CONFIGURE_HAVE_INTTYPES_H = @EINA_CONFIGURE_HAVE_INTTYPES_H@
245EINA_CONFIGURE_HAVE_ON_OFF_THREADS = @EINA_CONFIGURE_HAVE_ON_OFF_THREADS@
246EINA_CONFIGURE_HAVE_STDINT_H = @EINA_CONFIGURE_HAVE_STDINT_H@
247EINA_CONFIGURE_HAVE_THREADS = @EINA_CONFIGURE_HAVE_THREADS@
248EINA_CONFIGURE_MAGIC_DEBUG = @EINA_CONFIGURE_MAGIC_DEBUG@
249EINA_CONFIGURE_SAFETY_CHECKS = @EINA_CONFIGURE_SAFETY_CHECKS@
250EINA_LIBS = @EINA_LIBS@
251EINA_SIZEOF_WCHAR_T = @EINA_SIZEOF_WCHAR_T@
252EMEMOA_CFLAGS = @EMEMOA_CFLAGS@
253EMEMOA_LIBS = @EMEMOA_LIBS@
254ESCAPE_CFLAGS = @ESCAPE_CFLAGS@
255ESCAPE_LIBS = @ESCAPE_LIBS@
256EVIL_CFLAGS = @EVIL_CFLAGS@
257EVIL_LIBS = @EVIL_LIBS@
258EXEEXT = @EXEEXT@
259EXOTIC_CFLAGS = @EXOTIC_CFLAGS@
260EXOTIC_LIBS = @EXOTIC_LIBS@
261FGREP = @FGREP@
262GLIB_CFLAGS = @GLIB_CFLAGS@
263GLIB_LIBS = @GLIB_LIBS@
264GREP = @GREP@
265INSTALL = @INSTALL@
266INSTALL_DATA = @INSTALL_DATA@
267INSTALL_PROGRAM = @INSTALL_PROGRAM@
268INSTALL_SCRIPT = @INSTALL_SCRIPT@
269INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
270LD = @LD@
271LDFLAGS = @LDFLAGS@
272LIBOBJS = @LIBOBJS@
273LIBS = @LIBS@
274LIBTOOL = @LIBTOOL@
275LIPO = @LIPO@
276LN_S = @LN_S@
277LTLIBOBJS = @LTLIBOBJS@
278MAKEINFO = @MAKEINFO@
279MKDIR_P = @MKDIR_P@
280MODULE_ARCH = @MODULE_ARCH@
281NM = @NM@
282NMEDIT = @NMEDIT@
283OBJDUMP = @OBJDUMP@
284OBJEXT = @OBJEXT@
285OTOOL = @OTOOL@
286OTOOL64 = @OTOOL64@
287PACKAGE = @PACKAGE@
288PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
289PACKAGE_NAME = @PACKAGE_NAME@
290PACKAGE_STRING = @PACKAGE_STRING@
291PACKAGE_TARNAME = @PACKAGE_TARNAME@
292PACKAGE_URL = @PACKAGE_URL@
293PACKAGE_VERSION = @PACKAGE_VERSION@
294PATH_SEPARATOR = @PATH_SEPARATOR@
295PKG_CONFIG = @PKG_CONFIG@
296PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
297PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
298RANLIB = @RANLIB@
299SED = @SED@
300SET_MAKE = @SET_MAKE@
301SHELL = @SHELL@
302STRIP = @STRIP@
303VALGRIND_CFLAGS = @VALGRIND_CFLAGS@
304VALGRIND_LIBS = @VALGRIND_LIBS@
305VERSION = @VERSION@
306VMAJ = @VMAJ@
307abs_builddir = @abs_builddir@
308abs_srcdir = @abs_srcdir@
309abs_top_builddir = @abs_top_builddir@
310abs_top_srcdir = @abs_top_srcdir@
311ac_ct_CC = @ac_ct_CC@
312ac_ct_CXX = @ac_ct_CXX@
313ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
314am__include = @am__include@
315am__leading_dot = @am__leading_dot@
316am__quote = @am__quote@
317am__tar = @am__tar@
318am__untar = @am__untar@
319bindir = @bindir@
320build = @build@
321build_alias = @build_alias@
322build_cpu = @build_cpu@
323build_os = @build_os@
324build_vendor = @build_vendor@
325builddir = @builddir@
326datadir = @datadir@
327datarootdir = @datarootdir@
328dlopen_libs = @dlopen_libs@
329docdir = @docdir@
330dvidir = @dvidir@
331efl_doxygen = @efl_doxygen@
332efl_have_doxygen = @efl_have_doxygen@
333exec_prefix = @exec_prefix@
334have_lcov = @have_lcov@
335host = @host@
336host_alias = @host_alias@
337host_cpu = @host_cpu@
338host_os = @host_os@
339host_vendor = @host_vendor@
340htmldir = @htmldir@
341iconv_libs = @iconv_libs@
342includedir = @includedir@
343infodir = @infodir@
344install_sh = @install_sh@
345libdir = @libdir@
346libexecdir = @libexecdir@
347localedir = @localedir@
348localstatedir = @localstatedir@
349lt_ECHO = @lt_ECHO@
350lt_enable_auto_import = @lt_enable_auto_import@
351mandir = @mandir@
352mkdir_p = @mkdir_p@
353oldincludedir = @oldincludedir@
354pdfdir = @pdfdir@
355pkgconfig_requires_private = @pkgconfig_requires_private@
356prefix = @prefix@
357program_transform_name = @program_transform_name@
358psdir = @psdir@
359release_info = @release_info@
360requirement_eina = @requirement_eina@
361rt_libs = @rt_libs@
362sbindir = @sbindir@
363sharedstatedir = @sharedstatedir@
364srcdir = @srcdir@
365sysconfdir = @sysconfdir@
366target_alias = @target_alias@
367top_build_prefix = @top_build_prefix@
368top_builddir = @top_builddir@
369top_srcdir = @top_srcdir@
370version_info = @version_info@
371MAINTAINERCLEANFILES = Makefile.in
372AM_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
381base_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)
396EXTRA_DIST = \
397eina_share_common.h \
398eina_private.h \
399eina_strbuf_common.h \
400eina_strbuf_template_c.x \
401eina_binbuf_template_c.x
402
403lib_LTLIBRARIES = libeina.la
404@EINA_AMALGAMATION_TRUE@nodist_libeina_la_SOURCES = eina_amalgamation.c
405@EINA_AMALGAMATION_FALSE@libeina_la_SOURCES = $(base_sources)
406libeina_la_LIBADD = @iconv_libs@ @rt_libs@ @EINA_LIBS@ @dlopen_libs@
407libeina_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ @EFL_PTHREAD_LIBS@
408libeina_la_CFLAGS = @EINA_CFLAGS@ @EFL_PTHREAD_CFLAGS@
409all: 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
426Makefile: $(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):
443install-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
457uninstall-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
466clean-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
474libeina.la: $(libeina_la_OBJECTS) $(libeina_la_DEPENDENCIES)
475 $(AM_V_CCLD)$(libeina_la_LINK) -rpath $(libdir) $(libeina_la_OBJECTS) $(libeina_la_LIBADD) $(LIBS)
476
477mostlyclean-compile:
478 -rm -f *.$(OBJEXT)
479
480distclean-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
561libeina_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
569libeina_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
577libeina_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
585libeina_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
593libeina_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
601libeina_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
609libeina_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
617libeina_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
625libeina_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
633libeina_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
641libeina_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
649libeina_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
657libeina_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
665libeina_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
673libeina_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
681libeina_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
689libeina_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
697libeina_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
705libeina_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
713libeina_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
721libeina_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
729libeina_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
737libeina_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
745libeina_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
753libeina_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
761libeina_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
769libeina_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
777libeina_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
785libeina_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
793libeina_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
801libeina_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
809libeina_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
817libeina_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
825libeina_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
833libeina_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
841libeina_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
849libeina_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
857libeina_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
865libeina_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
873libeina_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
881libeina_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
889libeina_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
897libeina_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
905libeina_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
913libeina_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
921libeina_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
929libeina_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
937libeina_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
945libeina_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
953libeina_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
961libeina_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
969libeina_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
977libeina_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
985mostlyclean-libtool:
986 -rm -f *.lo
987
988clean-libtool:
989 -rm -rf .libs _libs
990
991ID: $(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
999tags: TAGS
1000
1001TAGS: $(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
1022ctags: CTAGS
1023CTAGS: $(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
1035GTAGS:
1036 here=`$(am__cd) $(top_builddir) && pwd` \
1037 && $(am__cd) $(top_srcdir) \
1038 && gtags -i $(GTAGS_ARGS) "$$here"
1039
1040distclean-tags:
1041 -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
1042
1043distdir: $(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
1073check-am: all-am
1074check: check-am
1075all-am: Makefile $(LTLIBRARIES)
1076installdirs:
1077 for dir in "$(DESTDIR)$(libdir)"; do \
1078 test -z "$$dir" || $(MKDIR_P) "$$dir"; \
1079 done
1080install: install-am
1081install-exec: install-exec-am
1082install-data: install-data-am
1083uninstall: uninstall-am
1084
1085install-am: all-am
1086 @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
1087
1088installcheck: installcheck-am
1089install-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
1094mostlyclean-generic:
1095
1096clean-generic:
1097
1098distclean-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
1102maintainer-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)
1106clean: clean-am
1107
1108clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \
1109 mostlyclean-am
1110
1111distclean: distclean-am
1112 -rm -rf ./$(DEPDIR)
1113 -rm -f Makefile
1114distclean-am: clean-am distclean-compile distclean-generic \
1115 distclean-tags
1116
1117dvi: dvi-am
1118
1119dvi-am:
1120
1121html: html-am
1122
1123html-am:
1124
1125info: info-am
1126
1127info-am:
1128
1129install-data-am:
1130
1131install-dvi: install-dvi-am
1132
1133install-dvi-am:
1134
1135install-exec-am: install-libLTLIBRARIES
1136
1137install-html: install-html-am
1138
1139install-html-am:
1140
1141install-info: install-info-am
1142
1143install-info-am:
1144
1145install-man:
1146
1147install-pdf: install-pdf-am
1148
1149install-pdf-am:
1150
1151install-ps: install-ps-am
1152
1153install-ps-am:
1154
1155installcheck-am:
1156
1157maintainer-clean: maintainer-clean-am
1158 -rm -rf ./$(DEPDIR)
1159 -rm -f Makefile
1160maintainer-clean-am: distclean-am maintainer-clean-generic
1161
1162mostlyclean: mostlyclean-am
1163
1164mostlyclean-am: mostlyclean-compile mostlyclean-generic \
1165 mostlyclean-libtool
1166
1167pdf: pdf-am
1168
1169pdf-am:
1170
1171ps: ps-am
1172
1173ps-am:
1174
1175uninstall-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
1255clean-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
40static 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 */
67Eina_Bool
68eina_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 */
84Eina_Bool
85eina_accessor_shutdown(void)
86{
87 return EINA_TRUE;
88}
89
90/*============================================================================*
91* API *
92*============================================================================*/
93
94
95EAPI void
96eina_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
104EAPI void *
105eina_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
113EAPI Eina_Bool
114eina_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
125EAPI void
126eina_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
156EAPI Eina_Bool
157eina_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
167EAPI Eina_Bool
168eina_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
46static const char EINA_MAGIC_ARRAY_STR[] = "Eina Array";
47static const char EINA_MAGIC_ARRAY_ITERATOR_STR[] = "Eina Array Iterator";
48static 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
75typedef struct _Eina_Iterator_Array Eina_Iterator_Array;
76struct _Eina_Iterator_Array
77{
78 Eina_Iterator iterator;
79
80 const Eina_Array *array;
81 unsigned int index;
82
83 EINA_MAGIC
84};
85
86typedef struct _Eina_Accessor_Array Eina_Accessor_Array;
87struct _Eina_Accessor_Array
88{
89 Eina_Accessor accessor;
90 const Eina_Array *array;
91 EINA_MAGIC
92};
93
94static 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
106static void eina_array_iterator_free(Eina_Iterator_Array *it) EINA_ARG_NONNULL(1);
107static Eina_Array *eina_array_iterator_get_container(Eina_Iterator_Array *it) EINA_ARG_NONNULL(1);
108static Eina_Bool eina_array_iterator_next(Eina_Iterator_Array *it,
109 void **data) EINA_ARG_NONNULL(1);
110
111static Eina_Bool eina_array_accessor_get_at(Eina_Accessor_Array *it,
112 unsigned int idx,
113 void **data) EINA_ARG_NONNULL(1);
114static Eina_Array *eina_array_accessor_get_container(Eina_Accessor_Array *it) EINA_ARG_NONNULL(1);
115static void eina_array_accessor_free(Eina_Accessor_Array *it) EINA_ARG_NONNULL(1);
116
117static Eina_Bool
118eina_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
132static Eina_Array *
133eina_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
139static void
140eina_array_iterator_free(Eina_Iterator_Array *it)
141{
142 EINA_MAGIC_CHECK_ARRAY_ITERATOR(it);
143 MAGIC_FREE(it);
144}
145
146static Eina_Bool
147eina_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
162static Eina_Array *
163eina_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
169static void
170eina_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 */
177EAPI Eina_Bool
178eina_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 */
222Eina_Bool
223eina_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 */
252Eina_Bool
253eina_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
264EAPI Eina_Array *
265eina_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
288EAPI void
289eina_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
298EAPI void
299eina_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
323EAPI void
324eina_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
339EAPI Eina_Bool
340eina_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
433EAPI Eina_Iterator *
434eina_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
463EAPI Eina_Accessor *
464eina_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
35extern "C"
36# endif
37void *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
67typedef struct _Eina_Run Eina_Run;
68struct _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
79struct _Eina_Benchmark
80{
81 const char *name;
82 const char *run;
83
84 Eina_Inlist *runs;
85 Eina_List *names;
86};
87
88static 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 */
119Eina_Bool
120eina_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 */
144Eina_Bool
145eina_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
156EAPI Eina_Benchmark *
157eina_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
175EAPI void
176eina_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
206EAPI Eina_Bool
207eina_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
241EAPI Eina_Array *
242eina_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
54static 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 */
32Eina_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 */
50Eina_Bool
51_FUNC_EXPAND(shutdown)(void)
52{
53 return eina_strbuf_common_shutdown();
54}
55
56/*============================================================================*
57 * API *
58 *============================================================================*/
59
60EAPI _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
68EAPI _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
77EAPI 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
85EAPI 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
92EAPI 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
99EAPI 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
106EAPI 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
113EAPI 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
120EAPI 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
127EAPI 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
134EAPI _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
141EAPI 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
148EAPI 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
61static int _eina_share_binshare_log_dom = -1;
62
63/* The actual share */
64static Eina_Share *binshare_share;
65static 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 */
86EAPI Eina_Bool
87eina_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 */
127EAPI Eina_Bool
128eina_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
147EAPI void
148eina_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
157EAPI const void *
158eina_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
166EAPI const void *
167eina_binshare_ref(const void *obj)
168{
169 return eina_share_common_ref(binshare_share, obj);
170}
171
172EAPI int
173eina_binshare_length(const void *obj)
174{
175 return eina_share_common_length(binshare_share, obj);
176}
177
178EAPI void
179eina_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
49static const char look_up_table[] = {'0', '1', '2', '3', '4',
50 '5', '6', '7', '8', '9',
51 'a', 'b', 'c', 'd', 'e', 'f'};
52static 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
66static 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
91EAPI Eina_Error EINA_ERROR_CONVERT_P_NOT_FOUND = 0;
92EAPI Eina_Error EINA_ERROR_CONVERT_0X_NOT_FOUND = 0;
93EAPI Eina_Error EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH = 0;
94
95static const char EINA_ERROR_CONVERT_0X_NOT_FOUND_STR[] =
96 "Error during string conversion to float, First '0x' was not found.";
97static const char EINA_ERROR_CONVERT_P_NOT_FOUND_STR[] =
98 "Error during string conversion to float, First 'p' was not found.";
99static 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 */
122Eina_Bool
123eina_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 */
153Eina_Bool
154eina_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
169EAPI int
170eina_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
195EAPI int
196eina_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
214EAPI Eina_Bool
215eina_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
307on_length_error:
308 eina_error_set(EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH);
309 return EINA_FALSE;
310}
311
312EAPI int
313eina_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
375EAPI int
376eina_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
459EAPI Eina_Bool
460eina_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
58typedef struct timespec Eina_Nano_Time;
59#else
60typedef LARGE_INTEGER Eina_Nano_Time;
61#endif
62
63typedef struct _Eina_Clock Eina_Clock;
64
65struct _Eina_Counter
66{
67 EINA_INLIST;
68
69 Eina_Inlist *clocks;
70 const char *name;
71};
72
73struct _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
85static 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
107static const char EINA_ERROR_COUNTER_WINDOWS_STR[] =
108 "Change your OS, you moron !";
109static int EINA_ERROR_COUNTER_WINDOWS = 0;
110static LARGE_INTEGER _eina_counter_frequency;
111
112static inline int
113_eina_counter_time_get(Eina_Nano_Time *tp)
114{
115 return QueryPerformanceCounter(tp);
116}
117#endif /* _WIN2 */
118
119static 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 */
184Eina_Bool
185eina_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 */
211Eina_Bool
212eina_counter_shutdown(void)
213{
214 return EINA_TRUE;
215}
216
217/*============================================================================*
218 * API *
219 *============================================================================*/
220
221EAPI Eina_Counter *
222eina_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
245EAPI void
246eina_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
261EAPI void
262eina_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
285EAPI void
286eina_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
305EAPI char *
306eina_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 */
58static 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
78static
79void _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 */
124EAPI 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
133EAPI 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
55typedef struct _Eina_Error_Message Eina_Error_Message;
56struct _Eina_Error_Message
57{
58 Eina_Bool string_allocated;
59 const char *string;
60};
61
62static Eina_Error_Message *_eina_errors = NULL;
63static size_t _eina_errors_count = 0;
64static size_t _eina_errors_allocated = 0;
65static Eina_Error _eina_last_error;
66
67static 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
108EAPI Eina_Error EINA_ERROR_OUT_OF_MEMORY = 0;
109
110static 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 */
129Eina_Bool
130eina_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 */
149Eina_Bool
150eina_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
173EAPI Eina_Error
174eina_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
195EAPI Eina_Error
196eina_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
211EAPI Eina_Bool
212eina_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
237EAPI const char *
238eina_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
249EAPI Eina_Error
250eina_error_get(void)
251{
252 return _eina_last_error;
253}
254
255EAPI void
256eina_error_set(Eina_Error err)
257{
258 _eina_last_error = err;
259}
260
261EAPI Eina_Error
262eina_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
36extern "C"
37# endif
38void *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
106typedef struct _Eina_File_Iterator Eina_File_Iterator;
107struct _Eina_File_Iterator
108{
109 Eina_Iterator iterator;
110
111 DIR *dirp;
112 int length;
113
114 char dir[1];
115};
116#endif
117
118struct _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
145typedef struct _Eina_File_Map Eina_File_Map;
146struct _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
159static Eina_Hash *_eina_file_cache = NULL;
160static Eina_Lock _eina_file_lock_cache;
161
162static 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
170static 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
202static 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
213static 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
248static DIR *
249_eina_file_ls_iterator_container(Eina_File_Iterator *it)
250{
251 return it->dirp;
252}
253
254static 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
263typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator;
264struct _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
276static 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
347static DIR *
348_eina_file_direct_ls_iterator_container(Eina_File_Direct_Iterator *it)
349{
350 return it->dirp;
351}
352
353static 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
362static 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
380static 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
396static void
397_eina_file_map_close(Eina_File_Map *map)
398{
399 munmap(map->map, map->length);
400 free(map);
401}
402
403static unsigned int
404_eina_file_map_key_length(const void *key __UNUSED__)
405{
406 return sizeof (unsigned long int) * 2;
407}
408
409static 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
417static 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
425static 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
443static 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
469static 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
487static void
488slprintf(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
500static 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
578Eina_Bool
579eina_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
603Eina_Bool
604eina_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
626void
627eina_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
685EAPI char *
686eina_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
714EAPI Eina_Bool
715eina_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
746EAPI Eina_Array *
747eina_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
779EAPI Eina_Iterator *
780eina_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
824EAPI Eina_Iterator *
825eina_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
881EAPI Eina_Iterator *
882eina_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
938EAPI Eina_File *
939eina_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
1047EAPI void
1048eina_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
1065EAPI size_t
1066eina_file_size_get(Eina_File *file)
1067{
1068 EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
1069 return file->length;
1070}
1071
1072EAPI time_t
1073eina_file_mtime_get(Eina_File *file)
1074{
1075 EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
1076 return file->mtime;
1077}
1078
1079EAPI const char *
1080eina_file_filename_get(Eina_File *file)
1081{
1082 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
1083 return file->filename;
1084}
1085
1086EAPI void *
1087eina_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
1130EAPI void *
1131eina_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
1206EAPI void
1207eina_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
1245EAPI Eina_Bool
1246eina_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
1270EAPI Eina_Iterator *
1271eina_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
1278EAPI Eina_Iterator *
1279eina_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
1286EAPI int
1287eina_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
35extern "C"
36# endif
37void *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
93typedef struct _Eina_File_Iterator Eina_File_Iterator;
94typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator;
95typedef struct _Eina_File_Map Eina_File_Map;
96
97struct _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
109struct _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
123struct _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
146struct _Eina_File_Map
147{
148 void *map;
149
150 unsigned long int offset;
151 unsigned long int length;
152
153 int refcount;
154};
155
156static Eina_Hash *_eina_file_cache = NULL;
157static Eina_Lock _eina_file_lock_cache;
158
159static int _eina_file_log_dom = -1;
160
161static 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
174static 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
203static 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
222static 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
253static 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
319static HANDLE
320_eina_file_win32_ls_iterator_container(Eina_File_Iterator *it)
321{
322 return it->handle;
323}
324
325static 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
335static 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
433static HANDLE
434_eina_file_win32_direct_ls_iterator_container(Eina_File_Direct_Iterator *it)
435{
436 return it->handle;
437}
438
439static 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
449static 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
464static 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
472static unsigned int
473_eina_file_map_key_length(const void *key __UNUSED__)
474{
475 return sizeof (unsigned long int) * 2;
476}
477
478static 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
486static 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
493static 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
573Eina_Bool
574eina_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
598Eina_Bool
599eina_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
626EAPI char *
627eina_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
665EAPI Eina_Bool
666eina_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
730EAPI Eina_Array *
731eina_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
763EAPI Eina_Iterator *
764eina_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
815EAPI Eina_Iterator *
816eina_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
874EAPI Eina_Iterator *
875eina_file_stat_ls(const char *dir)
876{
877 return eina_file_direct_ls(dir);
878}
879
880EAPI Eina_File *
881eina_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
990EAPI void
991eina_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
1008EAPI size_t
1009eina_file_size_get(Eina_File *file)
1010{
1011 EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
1012 return file->length;
1013}
1014
1015EAPI time_t
1016eina_file_mtime_get(Eina_File *file)
1017{
1018 EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
1019 return file->mtime;
1020}
1021
1022EAPI const char *
1023eina_file_filename_get(Eina_File *file)
1024{
1025 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
1026 return file->filename;
1027}
1028
1029EAPI Eina_Iterator *eina_file_xattr_get(Eina_File *file __UNUSED__)
1030{
1031 return NULL;
1032}
1033
1034EAPI Eina_Iterator *eina_file_xattr_value_get(Eina_File *file __UNUSED__)
1035{
1036 return NULL;
1037}
1038
1039EAPI void *
1040eina_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
1067EAPI void *
1068eina_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
1132EAPI void
1133eina_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
1171EAPI int
1172eina_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
12static 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
426EAPI Eina_F32p32
427eina_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
478EAPI Eina_F32p32
479eina_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
38const char *_eina_hamster_time = __TIME__;
39const char *_eina_hamster_date = __DATE__;
40static int _eina_hamsters = -1;
41
42/**
43 * @endcond
44 */
45
46/*============================================================================*
47* Global *
48*============================================================================*/
49
50/*============================================================================*
51* API *
52*============================================================================*/
53
54EAPI int
55eina_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
73typedef struct _Eina_Hash_Head Eina_Hash_Head;
74typedef struct _Eina_Hash_Element Eina_Hash_Element;
75typedef struct _Eina_Hash_Foreach_Data Eina_Hash_Foreach_Data;
76typedef struct _Eina_Iterator_Hash Eina_Iterator_Hash;
77typedef struct _Eina_Hash_Each Eina_Hash_Each;
78
79struct _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
95struct _Eina_Hash_Head
96{
97 EINA_RBTREE;
98 int hash;
99
100 Eina_Rbtree *head;
101};
102
103struct _Eina_Hash_Element
104{
105 EINA_RBTREE;
106 Eina_Hash_Tuple tuple;
107 Eina_Bool begin : 1;
108};
109
110struct _Eina_Hash_Foreach_Data
111{
112 Eina_Hash_Foreach cb;
113 const void *fdata;
114};
115
116typedef 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
120struct _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
138struct _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
156static 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
165static 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
176static 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
195static 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
211static inline Eina_Bool
212eina_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
304on_error:
305 eina_error_set(error);
306 return EINA_FALSE;
307}
308
309static 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
334static 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
367static 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
403static 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
413static 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
420static 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
454static 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
483static 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
503static 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
512static 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
519static 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
526static unsigned int
527_eina_int32_key_length(__UNUSED__ const uint32_t *key)
528{
529 return 4;
530}
531
532static 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
539static unsigned int
540_eina_int64_key_length(__UNUSED__ const uint32_t *key)
541{
542 return 8;
543}
544
545static 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
552static 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
563static 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
578static 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
593static 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
608static 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
684static 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
691static 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
716EAPI void
717eina_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
725EAPI Eina_Hash *
726eina_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
759on_error:
760 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
761 return NULL;
762}
763
764EAPI Eina_Hash *
765eina_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
774EAPI Eina_Hash *
775eina_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
784EAPI Eina_Hash *
785eina_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
794EAPI Eina_Hash *
795eina_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
804EAPI Eina_Hash *
805eina_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
814EAPI Eina_Hash *
815eina_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
832EAPI Eina_Hash *
833eina_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
842EAPI int
843eina_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
852EAPI void
853eina_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
870EAPI void
871eina_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
890EAPI Eina_Bool
891eina_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
905EAPI Eina_Bool
906eina_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
915EAPI Eina_Bool
916eina_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
933EAPI Eina_Bool
934eina_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
951EAPI Eina_Bool
952eina_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
963EAPI Eina_Bool
964eina_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
972EAPI Eina_Bool
973eina_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
992error:
993 return EINA_FALSE;
994}
995
996EAPI Eina_Bool
997eina_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
1016EAPI Eina_Bool
1017eina_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
1028EAPI void *
1029eina_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
1055EAPI void *
1056eina_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
1074EAPI void *
1075eina_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
1105EAPI void *
1106eina_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}
1155EAPI void *
1156eina_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
1173EAPI Eina_Bool
1174eina_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
1197error:
1198 return result;
1199}
1200
1201/*============================================================================*
1202* Iterator *
1203*============================================================================*/
1204
1205EAPI void
1206eina_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
1228EAPI Eina_Iterator *
1229eina_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
1259EAPI Eina_Iterator *
1260eina_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
1291EAPI Eina_Iterator *
1292eina_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/) */
1327EAPI int
1328eina_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
43static const char EINA_MAGIC_INARRAY_STR[] = "Eina Inline Array";
44static const char EINA_MAGIC_INARRAY_ITERATOR_STR[] = "Eina Inline Array Iterator";
45static const char EINA_MAGIC_INARRAY_ACCESSOR_STR[] = "Eina Inline Array Accessor";
46
47typedef struct _Eina_Iterator_Inarray Eina_Iterator_Inarray;
48typedef struct _Eina_Accessor_Inarray Eina_Accessor_Inarray;
49
50struct _Eina_Iterator_Inarray
51{
52 Eina_Iterator iterator;
53 const Eina_Inarray *array;
54 unsigned int pos;
55 EINA_MAGIC
56};
57
58struct _Eina_Accessor_Inarray
59{
60 Eina_Accessor accessor;
61 const Eina_Inarray *array;
62 EINA_MAGIC
63};
64
65static 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
113static 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
124static 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
150static 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
157static 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
168static 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
206static 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
220static 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
234static 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
241static void
242_eina_inarray_iterator_free(Eina_Iterator_Inarray *it)
243{
244 EINA_MAGIC_CHECK_INARRAY_ITERATOR(it);
245 MAGIC_FREE(it);
246}
247
248static 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
260static 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
267static 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 */
294Eina_Bool
295eina_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 */
325Eina_Bool
326eina_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*============================================================================*/
336EAPI Eina_Inarray *
337eina_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
354EAPI void
355eina_inarray_free(Eina_Inarray *array)
356{
357 EINA_MAGIC_CHECK_INARRAY(array);
358 free(array->members);
359 free(array);
360}
361
362EAPI void
363eina_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
370EAPI void
371eina_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
380EAPI int
381eina_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
398EAPI int
399eina_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
427EAPI int
428eina_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
446EAPI int
447eina_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
478found:
479 if (!eina_inarray_remove_at(array, position))
480 return -1;
481 return position;
482}
483
484EAPI int
485eina_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
495EAPI void *
496eina_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
503EAPI Eina_Bool
504eina_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
525EAPI void *
526eina_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
547EAPI Eina_Bool
548eina_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
561EAPI Eina_Bool
562eina_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
579EAPI void
580eina_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
609EAPI void
610eina_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
617EAPI int
618eina_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
626EAPI int
627eina_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
642EAPI Eina_Bool
643eina_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
660EAPI int
661eina_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
684EAPI unsigned int
685eina_inarray_count(const Eina_Inarray *array)
686{
687 EINA_MAGIC_CHECK_INARRAY(array, 0);
688 return array->len;
689}
690
691EAPI Eina_Iterator *
692eina_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
720EAPI Eina_Iterator *
721eina_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
750EAPI Eina_Accessor *
751eina_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
49typedef struct _Eina_Iterator_Inlist Eina_Iterator_Inlist;
50typedef struct _Eina_Accessor_Inlist Eina_Accessor_Inlist;
51
52struct _Eina_Iterator_Inlist
53{
54 Eina_Iterator iterator;
55 const Eina_Inlist *head;
56 const Eina_Inlist *current;
57};
58
59struct _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
69struct _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
79static Eina_Bool
80eina_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
92static Eina_Inlist *
93eina_inlist_iterator_get_container(Eina_Iterator_Inlist *it) {
94 return (Eina_Inlist *)it->head;
95}
96
97static void
98eina_inlist_iterator_free(Eina_Iterator_Inlist *it) {
99 free(it);
100}
101
102static Eina_Bool
103eina_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
148static Eina_Inlist *
149eina_inlist_accessor_get_container(Eina_Accessor_Inlist *it) {
150 return (Eina_Inlist *)it->head;
151}
152
153static void
154eina_inlist_accessor_free(Eina_Accessor_Inlist *it) {
155 free(it);
156}
157
158static Eina_Inlist *
159eina_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
179static Eina_Inlist *
180eina_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
193static 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
221EAPI Eina_Inlist *
222eina_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
248EAPI Eina_Inlist *
249eina_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
268EAPI Eina_Inlist *
269eina_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
296EAPI Eina_Inlist *
297eina_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
329EAPI Eina_Inlist *
330eina_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
367EAPI Eina_Inlist *
368eina_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
394EAPI Eina_Inlist *
395eina_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
428EAPI Eina_Inlist *
429eina_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
442EAPI unsigned int
443eina_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
454EAPI int
455eina_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
484EAPI Eina_Inlist_Sorted_State *
485eina_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
497EAPI void
498eina_inlist_sorted_state_free(Eina_Inlist_Sorted_State *state)
499{
500 free(state);
501}
502
503static 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
552EAPI Eina_Inlist *
553eina_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
663EAPI Eina_Inlist *
664eina_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
806EAPI Eina_Inlist *
807eina_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
861EAPI Eina_Iterator *
862eina_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
888EAPI Eina_Accessor *
889eina_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
40static 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 */
68Eina_Bool
69eina_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 */
85Eina_Bool
86eina_iterator_shutdown(void)
87{
88 return EINA_TRUE;
89}
90
91/*============================================================================*
92* API *
93*============================================================================*/
94
95EAPI void
96eina_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
104EAPI void *
105eina_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
113EAPI Eina_Bool
114eina_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
126EAPI void
127eina_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
152EAPI Eina_Bool
153eina_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
163EAPI Eina_Bool
164eina_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
40struct _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
68EAPI 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
91EAPI 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
99EAPI 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
120EAPI 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
87static const char EINA_MAGIC_LIST_STR[] = "Eina List";
88static const char EINA_MAGIC_LIST_ITERATOR_STR[] = "Eina List Iterator";
89static const char EINA_MAGIC_LIST_ACCESSOR_STR[] = "Eina List Accessor";
90static 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
131typedef struct _Eina_Iterator_List Eina_Iterator_List;
132typedef struct _Eina_Accessor_List Eina_Accessor_List;
133
134struct _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
144struct _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
156static Eina_Mempool *_eina_list_mp = NULL;
157static Eina_Mempool *_eina_list_accounting_mp = NULL;
158static 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
170static 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}
185static 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
194static 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}
207static 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
220static 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
234on_error:
235 _eina_list_mempool_list_free(list);
236 return NULL;
237}
238
239static 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
250static Eina_Mempool2 _eina_list_mempool =
251{
252 sizeof(Eina_List),
253 320,
254 0, NULL, NULL
255};
256static Eina_Mempool2 _eina_list_accounting_mempool =
257{
258 sizeof(Eina_List_Accounting),
259 80,
260 0, NULL, NULL
261};
262#endif
263
264static Eina_Bool
265eina_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
279static Eina_Bool
280eina_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
294static Eina_List *
295eina_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
302static void
303eina_list_iterator_free(Eina_Iterator_List *it)
304{
305 EINA_MAGIC_CHECK_LIST_ITERATOR(it);
306
307 MAGIC_FREE(it);
308}
309
310static Eina_Bool
311eina_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
372static Eina_List *
373eina_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
380static void
381eina_list_accessor_free(Eina_Accessor_List *it)
382{
383 EINA_MAGIC_CHECK_LIST_ACCESSOR(it);
384
385 MAGIC_FREE(it);
386}
387
388static Eina_List *
389eina_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
404static Eina_List *
405eina_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 */
448Eina_Bool
449eina_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
497on_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 */
514Eina_Bool
515eina_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
529EAPI Eina_List *
530eina_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
559EAPI Eina_List *
560eina_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
585EAPI Eina_List *
586eina_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
605EAPI Eina_List *
606eina_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
638EAPI Eina_List *
639eina_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
657EAPI Eina_List *
658eina_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
691EAPI Eina_List *
692eina_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
707EAPI Eina_List *
708eina_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
719EAPI Eina_List *
720eina_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
753EAPI Eina_List *
754eina_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
774EAPI Eina_List *
775eina_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
817EAPI Eina_List *
818eina_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
855EAPI void *
856eina_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
864EAPI Eina_Bool
865eina_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
884EAPI Eina_Bool
885eina_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
899EAPI Eina_List *
900eina_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
917EAPI void *
918eina_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
926EAPI Eina_List *
927eina_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
961EAPI Eina_List *
962eina_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
990EAPI Eina_List *
991eina_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
1009EAPI Eina_List *
1010eina_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
1028EAPI Eina_List *
1029eina_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
1097EAPI Eina_List *
1098eina_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
1148EAPI Eina_List *
1149eina_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
1194EAPI Eina_List *
1195eina_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
1271EAPI Eina_List *
1272eina_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
1349end:
1350 if (result_cmp)
1351 *result_cmp = cmp;
1352
1353 return (Eina_List *)ct;
1354}
1355
1356EAPI Eina_List *
1357eina_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
1375EAPI void *
1376eina_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
1383EAPI Eina_List *
1384eina_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
1399EAPI void *
1400eina_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
1408EAPI Eina_Iterator *
1409eina_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
1436EAPI Eina_Iterator *
1437eina_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
1464EAPI Eina_Accessor *
1465eina_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.
78typedef struct _Eina_Log_Domain_Level_Pending Eina_Log_Domain_Level_Pending;
79struct _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 */
91static Eina_Inlist *_pending_list = NULL;
92static Eina_Inlist *_glob_list = NULL;
93
94// Disable color flag (can be changed through the env var
95// EINA_LOG_ENV_COLOR_DISABLE).
96static Eina_Bool _disable_color = EINA_FALSE;
97static Eina_Bool _disable_file = EINA_FALSE;
98static Eina_Bool _disable_function = EINA_FALSE;
99static Eina_Bool _abort_on_critical = EINA_FALSE;
100static int _abort_level_on_critical = EINA_LOG_LEVEL_CRITICAL;
101
102#ifdef EFL_HAVE_THREADS
103
104static Eina_Bool _threads_enabled = EINA_FALSE;
105static Eina_Bool _threads_inited = EINA_FALSE;
106
107# ifdef EFL_HAVE_POSIX_THREADS
108
109typedef pthread_t Thread;
110
111static 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
129static pthread_spinlock_t _log_lock;
130
131static 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
166static 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
176typedef DWORD Thread;
177
178static 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
193static 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
216static Eina_Log_Domain *_log_domains = NULL;
217static unsigned int _log_domains_count = 0;
218static size_t _log_domains_allocated = 0;
219
220// Default function for printing on domains
221static Eina_Log_Print_Cb _print_cb = eina_log_print_cb_stderr;
222static void *_print_cb_data = NULL;
223
224#ifdef DEBUG
225static Eina_Log_Level _log_level = EINA_LOG_LEVEL_DBG;
226#elif DEBUG_CRITICAL
227static Eina_Log_Level _log_level = EINA_LOG_LEVEL_CRITICAL;
228#else
229static 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 */
236static const char *_names[] = {
237 "CRI",
238 "ERR",
239 "WRN",
240 "INF",
241 "DBG",
242};
243
244#ifdef _WIN32
245static int
246eina_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
317static inline unsigned int
318eina_log_pid_get(void)
319{
320 return (unsigned int)getpid();
321}
322
323static inline void
324eina_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
346static inline void
347eina_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
371static inline void
372eina_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 */
408static void
409eina_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
421static void
422eina_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
434static void
435eina_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 */
448static void
449eina_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
489static void
490eina_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
527static void
528eina_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
561static void
562eina_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
584static void
585eina_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
607static void
608eina_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 */
632static void
633eina_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
706static void
707eina_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
775static void
776eina_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
838static 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
844static inline void
845eina_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 */
913static const char *
914eina_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 */
947static Eina_Log_Domain *
948eina_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 */
971static void
972eina_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 */
986static void
987eina_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
1023parse_end:
1024 start = strchr(tmp, ',');
1025 if (start)
1026 start++;
1027 else
1028 break;
1029 }
1030}
1031
1032static void
1033eina_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
1069parse_end:
1070 start = strchr(tmp, ',');
1071 if (start)
1072 start++;
1073 else
1074 break;
1075 }
1076}
1077
1078static inline int
1079eina_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
1123finish_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
1157static inline Eina_Bool
1158eina_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
1201static inline void
1202eina_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
1214static inline void
1215eina_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 */
1324Eina_Bool
1325eina_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 */
1418Eina_Bool
1419eina_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 */
1467void
1468eina_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 */
1487void
1488eina_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
1509EAPI int EINA_LOG_DOMAIN_GLOBAL = 0;
1510
1511/**
1512 * @endcond
1513 */
1514
1515EAPI void
1516eina_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
1526EAPI void
1527eina_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
1541EAPI void
1542eina_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
1554EAPI int
1555eina_log_level_get(void)
1556{
1557#ifdef EINA_ENABLE_LOG
1558 return _log_level;
1559#else
1560 return 0;
1561#endif
1562}
1563
1564EAPI Eina_Bool
1565eina_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
1574EAPI void
1575eina_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
1584EAPI Eina_Bool
1585eina_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
1594EAPI void
1595eina_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
1604EAPI Eina_Bool
1605eina_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
1614EAPI void
1615eina_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
1624EAPI Eina_Bool
1625eina_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
1634EAPI void
1635eina_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
1644EAPI Eina_Bool
1645eina_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
1654EAPI void
1655eina_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
1664EAPI int
1665eina_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
1674EAPI int
1675eina_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
1693EAPI void
1694eina_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
1706EAPI void
1707eina_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
1756EAPI int
1757eina_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
1800EAPI int
1801eina_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
1816EAPI void
1817eina_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
1842EAPI void
1843eina_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
1868EAPI void
1869eina_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
1898end:
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
1913EAPI void
1914eina_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
1955EAPI void
1956eina_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
47typedef struct _Eina_Magic_String Eina_Magic_String;
48struct _Eina_Magic_String
49{
50 Eina_Magic magic;
51 Eina_Bool string_allocated;
52 const char *string;
53};
54
55static 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
67static Eina_Magic_String *_eina_magic_strings = NULL;
68static size_t _eina_magic_strings_count = 0;
69static size_t _eina_magic_strings_allocated = 0;
70static Eina_Bool _eina_magic_strings_dirty = 0;
71
72static 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
79static 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
87static 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
127EAPI Eina_Error EINA_ERROR_MAGIC_FAILED = 0;
128
129static 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 */
142Eina_Bool
143eina_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 */
169Eina_Bool
170eina_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*============================================================================*/
195EAPI const char *
196eina_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
219EAPI Eina_Bool
220eina_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
244EAPI Eina_Bool
245eina_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
267EAPI void
268eina_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
82static Eina_Version _version = { VMAJ, VMIN, VMIC, VREV };
83
84static int _eina_main_count = 0;
85#ifdef EFL_HAVE_THREADS
86static int _eina_main_thread_count = 0;
87#endif
88static 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
100EAPI Eina_Bool _eina_threads_activated = EINA_FALSE;
101EAPI Eina_Error EINA_ERROR_NOT_MAIN_LOOP = 0;
102
103static const char EINA_ERROR_NOT_MAIN_LOOP_STR[] = "Main loop thread check failed.";
104
105#ifdef EFL_HAVE_THREADS
106# ifdef _WIN32
107EAPI DWORD _eina_main_loop;
108# else
109EAPI pthread_t _eina_main_loop;
110# endif
111static pid_t _eina_pid;
112#endif
113
114#ifdef MT
115static int _mt_enabled = 0;
116#endif
117
118#ifdef EFL_HAVE_THREADS
119EAPI int _eina_threads_debug = 0;
120# if !defined(_WIN32_WCE) && !defined(_WIN32)
121EAPI pthread_mutex_t _eina_tracking_lock;
122EAPI 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
160struct eina_desc_setup
161{
162 const char *name;
163 Eina_Bool (*init)(void);
164 Eina_Bool (*shutdown)(void);
165};
166
167static 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};
198static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) /
199 sizeof(_eina_desc_setup[0]);
200
201static 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 */
232EAPI Eina_Version *eina_version = &_version;
233
234EAPI int
235eina_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
299EAPI int
300eina_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
323EAPI int
324eina_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
349EAPI int
350eina_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
393EAPI Eina_Bool
394eina_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. */
425EAPI void
426eina_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
60static const char EINA_MAGIC_MATRIXSPARSE_STR[] = "Eina Matrixsparse";
61static const char EINA_MAGIC_MATRIXSPARSE_ROW_STR[] = "Eina Matrixsparse Row";
62static const char EINA_MAGIC_MATRIXSPARSE_CELL_STR[] = "Eina Matrixsparse Cell";
63static const char EINA_MAGIC_MATRIXSPARSE_ITERATOR_STR[] =
64 "Eina Matrixsparse Iterator";
65static const char EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR_STR[] =
66 "Eina Matrixsparse Row Accessor";
67static const char EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR_STR[] =
68 "Eina Matrixsparse Row Iterator";
69static const char EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR_STR[] =
70 "Eina Matrixsparse Cell Accessor";
71static 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
111struct _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
124struct _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
139struct _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
160typedef struct _Eina_Matrixsparse_Iterator Eina_Matrixsparse_Iterator;
161typedef struct _Eina_Matrixsparse_Iterator_Complete
162Eina_Matrixsparse_Iterator_Complete;
163
164struct _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
178struct _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
210static 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
222static Eina_Mempool *_eina_matrixsparse_cell_mp = NULL;
223static Eina_Mempool *_eina_matrixsparse_row_mp = NULL;
224
225static 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
237static 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
267static 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
281static 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
291static 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
321static 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
364static 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
407static 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
458static 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
510static 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
522static 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
555static 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
588static 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
639static 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
690static 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*============================================================================*/
717static 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
740static 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
747static 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
756static 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
800static 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
808static 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 */
846Eina_Bool
847eina_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
903on_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 */
920Eina_Bool
921eina_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
935EAPI Eina_Matrixsparse *
936eina_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
967EAPI void
968eina_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
991EAPI void
992eina_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
1010EAPI Eina_Bool
1011eina_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
1116EAPI Eina_Bool
1117eina_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
1131EAPI void *
1132eina_matrixsparse_cell_data_get(const Eina_Matrixsparse_Cell *cell)
1133{
1134 EINA_MAGIC_CHECK_MATRIXSPARSE_CELL(cell, NULL);
1135 return cell->data;
1136}
1137
1138EAPI void *
1139eina_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
1152EAPI Eina_Bool
1153eina_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
1174EAPI Eina_Bool
1175eina_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
1191EAPI Eina_Bool
1192eina_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
1209EAPI Eina_Bool
1210eina_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
1238EAPI Eina_Bool
1239eina_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
1263EAPI Eina_Bool
1264eina_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
1281EAPI Eina_Bool
1282eina_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
1320EAPI Eina_Bool
1321eina_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
1341EAPI Eina_Bool
1342eina_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
1357EAPI Eina_Iterator *
1358eina_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
1384EAPI Eina_Iterator *
1385eina_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
47static Eina_Hash *_backends;
48static Eina_Array *_modules;
49static 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
62static 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
106on_error:
107 eina_error_set(err);
108 return NULL;
109}
110
111/* Built-in backend's prototypes */
112
113#ifdef EINA_STATIC_BUILD_BUDDY
114Eina_Bool buddy_init(void);
115void buddy_shutdown(void);
116#endif
117
118#ifdef EINA_STATIC_BUILD_CHAINED_POOL
119Eina_Bool chained_init(void);
120void chained_shutdown(void);
121#endif
122
123#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
124Eina_Bool ememoa_fixed_init(void);
125void ememoa_fixed_shutdown(void);
126#endif
127
128#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
129Eina_Bool ememoa_unknown_init(void);
130void ememoa_unknown_shutdown(void);
131#endif
132
133#ifdef EINA_STATIC_BUILD_FIXED_BITMAP
134Eina_Bool fixed_bitmap_init(void);
135void fixed_bitmap_shutdown(void);
136#endif
137
138#ifdef EINA_STATIC_BUILD_ONE_BIG
139Eina_Bool one_big_init(void);
140void one_big_shutdown(void);
141#endif
142
143#ifdef EINA_STATIC_BUILD_PASS_THROUGH
144Eina_Bool pass_through_init(void);
145void pass_through_shutdown(void);
146#endif
147
148/**
149 * @endcond
150 */
151
152/*============================================================================*
153* Global *
154*============================================================================*/
155
156/**
157 * @cond LOCAL
158 */
159
160EAPI Eina_Error EINA_ERROR_NOT_MEMPOOL_MODULE = 0;
161
162static const char EINA_ERROR_NOT_MEMPOOL_MODULE_STR[] =
163 "Not a memory pool module.";
164
165/**
166 * @endcond
167 */
168
169EAPI Eina_Bool
170eina_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
177EAPI void
178eina_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
185Eina_Bool
186eina_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
258mempool_init_error:
259 eina_log_domain_unregister(_eina_mempool_log_dom);
260 _eina_mempool_log_dom = -1;
261
262 return EINA_FALSE;
263}
264
265Eina_Bool
266eina_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
308EAPI Eina_Mempool *
309eina_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
331EAPI 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
341EAPI 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
350EAPI 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
358EAPI 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
366EAPI unsigned int
367eina_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
61static Eina_Bool mmap_safe = EINA_FALSE;
62#ifdef HAVE_SIGINFO_T
63
64static int _eina_mmap_log_dom = -1;
65static int _eina_mmap_zero_fd = -1;
66static 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
78static 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
124EAPI Eina_Bool
125eina_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
186EAPI Eina_Bool
187eina_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
35extern "C"
36# endif
37void *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
66static Eina_Mempool *_eina_model_mp = NULL;
67static Eina_Hash *_eina_model_inner_mps = NULL;
68static Eina_Lock _eina_model_inner_mps_lock;
69static char *_eina_model_mp_choice = NULL;
70static Eina_Hash *_eina_model_descriptions = NULL;
71static Eina_Lock _eina_model_descriptions_lock;
72static int _eina_model_log_dom = -1;
73static 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;
78static Eina_Lock _eina_model_debug_list_lock;
79static Eina_List *_eina_model_debug_list = NULL;
80
81static const char _eina_model_str_deleted[] = "deleted";
82static const char _eina_model_str_freed[] = "freed";
83static const char _eina_model_str_property_set[] = "property,set";
84static const char _eina_model_str_property_del[] = "property,deleted";
85static const char _eina_model_str_children_changed[] = "children,changed";
86static const char _eina_model_str_child_inserted[] = "child,inserted";
87static const char _eina_model_str_child_set[] = "child,set";
88static const char _eina_model_str_child_del[] = "child,deleted";
89static const char _eina_model_str_loaded[] = "loaded";
90static const char _eina_model_str_unloaded[] = "unloaded";
91static const char _eina_model_str_properties_loaded[] = "properties,loaded";
92static const char _eina_model_str_properties_unloaded[] = "properties,unloaded";
93static const char _eina_model_str_children_loaded[] = "children,loaded";
94static 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 */
125static 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
155static 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 */
184typedef struct _Eina_Model_Inner_Mp Eina_Model_Inner_Mp;
185struct _Eina_Model_Inner_Mp
186{
187 Eina_Mempool *mempool;
188 int refcount;
189};
190
191static 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
201static 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
231static 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
247static 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
260static 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
274static 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
289typedef union _Eina_Model_Provider Eina_Model_Provider;
290union _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 */
297typedef struct _Eina_Model_Event_Description_Cache Eina_Model_Event_Description_Cache;
298struct _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 */
321typedef struct _Eina_Model_Description Eina_Model_Description;
322struct _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
372static 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
506static 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 */
546static 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
665static 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
693static 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
707static 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
753static 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
794static 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
801static 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 */
816static 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
934static 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
972static 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
996static 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
1008static 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
1016static 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 */
1039typedef struct _Eina_Model_Event_Listener Eina_Model_Event_Listener;
1040struct _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
1048struct _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
1064static 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 */
1076static 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 */
1143static 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
1165static 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
1186static 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
1223static const char EINA_ERROR_MODEL_FAILED_STR[] = "Model check failed.";
1224static const char EINA_ERROR_MODEL_METHOD_MISSING_STR[] = "Model method is missing.";
1225static const char EINA_MAGIC_MODEL_STR[] = "Eina Model";
1226
1227static void _eina_model_unref(Eina_Model *model);
1228
1229/**
1230 * @endcond
1231 */
1232
1233/* EINA_MODEL_TYPE_BASE: base of all other types **********************/
1234
1235static 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
1242static 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
1249static 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
1256static 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
1263static 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
1292static 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
1330static 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
1339static 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
1388static 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
1397static 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
1478static 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
1558static 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
1573static 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
1580static 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
1606static 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
1633typedef struct _Eina_Iterator_Model_Base Eina_Iterator_Model_Base;
1634struct _Eina_Iterator_Model_Base
1635{
1636 Eina_Iterator base;
1637 Eina_Model *model;
1638 unsigned int current;
1639 unsigned int end;
1640};
1641
1642static 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
1659static 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
1667static 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
1676static 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
1695typedef struct _Eina_Iterator_Model_Base_Reversed Eina_Iterator_Model_Base_Reversed;
1696struct _Eina_Iterator_Model_Base_Reversed
1697{
1698 Eina_Iterator base;
1699 Eina_Model *model;
1700 unsigned int current;
1701 unsigned int end;
1702};
1703
1704static 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
1721static 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
1729static 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
1738static 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
1771typedef struct _Eina_Iterator_Model_Base_Sorted Eina_Iterator_Model_Base_Sorted;
1772struct _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
1781static 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
1795static 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
1803static 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
1817static 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
1866typedef struct _Eina_Iterator_Model_Base_Filtered Eina_Iterator_Model_Base_Filtered;
1867struct _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
1877static 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
1897static 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
1905static 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
1914static 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
1935static 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
2018static 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
2032static 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
2081static const char _EINA_MODEL_INTERFACE_NAME_PROPERTIES[] = "Eina_Model_Interface_Properties";
2082static const char _EINA_MODEL_INTERFACE_NAME_CHILDREN[] = "Eina_Model_Interface_Children";
2083
2084typedef struct _Eina_Model_Type_Mixin_Data Eina_Model_Type_Mixin_Data;
2085struct _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
2092static 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
2099static 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
2106static 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
2153static 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
2169static 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
2215static 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
2231static 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
2247static 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
2261static 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
2275static 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
2289static 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
2303static 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
2314static 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
2325static 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
2337static 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
2349static 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
2361static 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
2371static 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 */
2413static 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
2425static 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
2438static 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
2456static 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
2467static 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
2474static 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
2492static 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
2501static 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
2543static 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
2553static 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
2561static 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
2572static 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
2603static 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
2615static 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
2627static 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
2646static 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
2657static 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
2672static 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
2680static 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
2688static 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
2694static 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
2722static 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 */
2752static 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
2764static 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
2776static 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
2794static 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
2805static 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
2827static 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
2834static 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
2844static 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
2864static 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
2882static 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
2895static 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
2907static 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
2940static 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
2946static 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
2955static 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
2961static 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 */
2982Eina_Bool
2983eina_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 */
3106Eina_Bool
3107eina_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
3148EAPI Eina_Error EINA_ERROR_MODEL_FAILED = 0;
3149EAPI Eina_Error EINA_ERROR_MODEL_METHOD_MISSING = 0;
3150
3151EAPI const Eina_Model_Type *EINA_MODEL_TYPE_BASE = NULL;
3152EAPI const Eina_Model_Type *EINA_MODEL_TYPE_MIXIN = NULL;
3153EAPI const Eina_Model_Type *EINA_MODEL_TYPE_GENERIC = NULL;
3154EAPI const Eina_Model_Type *EINA_MODEL_TYPE_STRUCT = NULL;
3155
3156EAPI const Eina_Model_Interface *EINA_MODEL_INTERFACE_PROPERTIES_HASH = NULL;
3157EAPI const Eina_Model_Interface *EINA_MODEL_INTERFACE_PROPERTIES_STRUCT = NULL;
3158EAPI const Eina_Model_Interface *EINA_MODEL_INTERFACE_CHILDREN_INARRAY = NULL;
3159
3160EAPI const char *EINA_MODEL_INTERFACE_NAME_PROPERTIES = "Eina_Model_Interface_Properties";
3161EAPI const char *EINA_MODEL_INTERFACE_NAME_CHILDREN = "Eina_Model_Interface_Children";
3162
3163EAPI Eina_Model *
3164eina_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
3301static 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
3382static 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
3401static 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
3527EAPI void
3528eina_model_del(Eina_Model *model)
3529{
3530 EINA_MODEL_INSTANCE_CHECK(model);
3531 _eina_model_del(model);
3532 _eina_model_unref(model);
3533}
3534
3535EAPI const Eina_Model_Type *
3536eina_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
3542EAPI const Eina_Model_Interface *
3543eina_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
3563static 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
3578EAPI Eina_Bool
3579eina_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
3587EAPI Eina_Model *
3588eina_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
3598static 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
3632EAPI Eina_Model *
3633eina_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
3648EAPI void
3649eina_model_unref(Eina_Model *model)
3650{
3651 EINA_MODEL_INSTANCE_CHECK(model);
3652 _eina_model_unref(model);
3653}
3654
3655EAPI void
3656eina_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
3680EAPI int
3681eina_model_refcount(const Eina_Model *model)
3682{
3683 EINA_MODEL_INSTANCE_CHECK_VAL(model, -1);
3684 return model->refcount;
3685}
3686
3687EAPI const Eina_Inlist *
3688eina_model_xrefs_get(const Eina_Model *model)
3689{
3690 EINA_MODEL_INSTANCE_CHECK_VAL(model, NULL);
3691 return model->xrefs;
3692}
3693
3694EAPI Eina_Bool
3695eina_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
3735EAPI Eina_Bool
3736eina_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
3798EAPI const Eina_Model_Event_Description *
3799eina_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
3815EAPI Eina_List *
3816eina_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
3832EAPI void
3833eina_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
3840EAPI Eina_Bool
3841eina_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
3848EAPI int
3849eina_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
3877EAPI int
3878eina_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
3896EAPI Eina_Model *
3897eina_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
3940EAPI Eina_Model *
3941eina_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
3984EAPI int
3985eina_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
4035EAPI Eina_Bool
4036eina_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
4060EAPI Eina_Bool
4061eina_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
4086EAPI Eina_Bool
4087eina_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
4096EAPI Eina_Bool
4097eina_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
4125EAPI Eina_Bool
4126eina_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
4152EAPI Eina_List *
4153eina_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
4159EAPI void
4160eina_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
4167EAPI int
4168eina_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
4174EAPI Eina_Model *
4175eina_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
4181EAPI Eina_Bool
4182eina_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
4208EAPI Eina_Bool
4209eina_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
4238EAPI Eina_Bool
4239eina_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
4269EAPI int
4270eina_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
4305EAPI int
4306eina_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
4313EAPI int
4314eina_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
4322EAPI Eina_Bool
4323eina_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
4333EAPI Eina_Iterator *
4334eina_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
4344EAPI Eina_Iterator *
4345eina_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
4351EAPI Eina_Iterator *
4352eina_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
4363EAPI Eina_Iterator *
4364eina_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
4371EAPI Eina_Iterator *
4372eina_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
4384EAPI Eina_Iterator *
4385eina_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
4393EAPI Eina_Iterator *
4394eina_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
4406EAPI Eina_Iterator *
4407eina_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
4415EAPI char *
4416eina_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
4424EAPI Eina_Bool
4425eina_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
4431EAPI const char *
4432eina_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
4439EAPI const Eina_Model_Type *
4440eina_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
4459EAPI Eina_Bool
4460eina_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
4473EAPI Eina_Bool
4474eina_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
4487EAPI Eina_Bool
4488eina_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
4502EAPI Eina_Bool
4503eina_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
4517EAPI Eina_Bool
4518eina_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
4535EAPI Eina_Bool
4536eina_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
4549EAPI Eina_Bool
4550eina_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
4563EAPI Eina_Bool
4564eina_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
4580EAPI Eina_Bool
4581eina_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
4598EAPI Eina_Bool
4599eina_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
4613EAPI Eina_List *
4614eina_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
4627EAPI int
4628eina_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
4641EAPI Eina_Model *
4642eina_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
4655EAPI Eina_Bool
4656eina_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
4670EAPI Eina_Bool
4671eina_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
4684EAPI Eina_Bool
4685eina_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
4699EAPI int
4700eina_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
4714EAPI int
4715eina_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
4729EAPI void
4730eina_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
4744EAPI Eina_Iterator *
4745eina_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
4758EAPI Eina_Iterator *
4759eina_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
4772EAPI Eina_Iterator *
4773eina_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
4787EAPI Eina_Iterator *
4788eina_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
4802EAPI char *
4803eina_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
4816EAPI Eina_Bool
4817eina_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
4871EAPI Eina_Bool
4872eina_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
4887static 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
4907static 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
4915EAPI const Eina_Model_Interface *
4916eina_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
4937EAPI void *
4938eina_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
4959EAPI const void *
4960eina_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
4977EAPI const void *
4978eina_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
4995EAPI Eina_Bool
4996eina_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
5002EAPI void *
5003eina_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
5024static 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
5039EAPI Eina_Bool
5040eina_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
5062EAPI Eina_Bool
5063eina_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
5075EAPI Eina_Bool
5076eina_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
5088EAPI Eina_Bool
5089eina_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
5102EAPI Eina_Bool
5103eina_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
5116EAPI 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
5128EAPI Eina_Bool
5129eina_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
5145EAPI Eina_Bool
5146eina_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
5165EAPI Eina_Bool
5166eina_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
5185EAPI Eina_Bool
5186eina_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
5200EAPI Eina_Bool
5201eina_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
5216EAPI Eina_Bool
5217eina_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
5230EAPI Eina_List *
5231eina_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
5245EAPI Eina_Bool
5246eina_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
5263EAPI Eina_Bool
5264eina_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
5283EAPI Eina_Bool
5284eina_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
5303EAPI int
5304eina_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
5316EAPI Eina_Model *
5317eina_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
5329EAPI 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
5342EAPI Eina_Bool
5343eina_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
5356EAPI Eina_Bool
5357eina_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
5370EAPI void
5371eina_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
5384static 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
5393EAPI Eina_Model *
5394eina_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
5413EAPI Eina_Model *
5414eina_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
5435EAPI Eina_Bool
5436eina_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
5447EAPI Eina_Bool
5448eina_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
5471EAPI void
5472eina_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
5520EAPI Eina_List *
5521eina_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
5541EAPI void
5542eina_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
35extern "C"
36# endif
37void *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
83static 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
110struct _Eina_Module
111{
112 void *handle;
113 int ref;
114 const char file[];
115};
116
117typedef 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
124typedef struct _Dir_List_Cb_Data
125{
126 Eina_Module_Cb cb;
127 void *data;
128} Dir_List_Cb_Data;
129
130static 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
144static 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
176static 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
210static const char EINA_ERROR_WRONG_MODULE_STR[] =
211 "Wrong file format or no file module found";
212static const char EINA_ERROR_MODULE_INIT_FAILED_STR[] =
213 "Module initialisation function failed";
214
215EAPI Eina_Error EINA_ERROR_WRONG_MODULE = 0;
216EAPI 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 */
237Eina_Bool
238eina_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 */
267Eina_Bool
268eina_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
283EAPI 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
310EAPI 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
324EAPI 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;
357ok:
358 DBG("successfully loaded %s", m->file);
359 m->handle = dl_handle;
360loaded:
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
372EAPI 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
400EAPI 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
413EAPI 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
419EAPI 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
461EAPI 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
495EAPI 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
513EAPI 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
537EAPI Eina_Module *
538eina_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
568EAPI 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
580EAPI 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
592EAPI 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
43extern "C"
44# endif
45void *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
95struct _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
137static int _eina_prefix_log_dom = -1;
138
139static 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
176static 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
230static 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
314static 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
337static 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
377EAPI Eina_Prefix *
378eina_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
657EAPI void
658eina_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
671EAPI const char *
672eina_prefix_get(Eina_Prefix *pfx)
673{
674 if (!pfx) return "";
675 return pfx->prefix_path;
676}
677
678EAPI const char *
679eina_prefix_bin_get(Eina_Prefix *pfx)
680{
681 if (!pfx) return "";
682 return pfx->prefix_path_bin;
683}
684
685EAPI const char *
686eina_prefix_lib_get(Eina_Prefix *pfx)
687{
688 if (!pfx) return "";
689 return pfx->prefix_path_lib;
690}
691
692EAPI const char *
693eina_prefix_data_get(Eina_Prefix *pfx)
694{
695 if (!pfx) return "";
696 return pfx->prefix_path_data;
697}
698
699EAPI const char *
700eina_prefix_locale_get(Eina_Prefix *pfx)
701{
702 if (!pfx) return "";
703 return pfx->prefix_path_locale;
704}
705
706Eina_Bool
707eina_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
720Eina_Bool
721eina_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
137extern Eina_Bool _threads_activated;
138
139void eina_share_common_threads_init(void);
140void eina_share_common_threads_shutdown(void);
141void eina_log_threads_init(void);
142void eina_log_threads_shutdown(void);
143#endif
144
145void 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
48typedef struct _Eina_QuadTree_Root Eina_QuadTree_Root;
49
50static const char EINA_MAGIC_QUADTREE_STR[] = "Eina QuadTree";
51static const char EINA_MAGIC_QUADTREE_ROOT_STR[] = "Eina QuadTree Root";
52static 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
81struct _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
117struct _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
130struct _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
149static int _eina_quadtree_log_dom = -1;
150static Eina_Mempool *eina_quadtree_root_mp = NULL;
151static 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
164static 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
173static Eina_QuadTree_Root *
174eina_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
195static Eina_QuadTree_Root *
196eina_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
232static 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
343static 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
403static 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
486static 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
548static 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
585end:
586 object->root = NULL;
587}
588
589EAPI Eina_QuadTree *
590eina_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
617EAPI void
618eina_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
658EAPI Eina_QuadTree_Item *
659eina_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
696EAPI Eina_Bool
697eina_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
733EAPI Eina_Bool
734eina_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
756EAPI Eina_Bool
757eina_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
766EAPI Eina_Bool
767eina_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
783EAPI Eina_Inlist *
784eina_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
831EAPI void *
832eina_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
851EAPI void
852eina_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
865EAPI void
866eina_quadtree_cycle(Eina_QuadTree *q)
867{
868 EINA_MAGIC_CHECK_QUADTREE(q);
869
870 q->index = 0;
871}
872
873EAPI void
874eina_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
887Eina_Bool
888eina_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
923Eina_Bool
924eina_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
45typedef struct _Eina_Iterator_Rbtree Eina_Iterator_Rbtree;
46typedef struct _Eina_Iterator_Rbtree_List Eina_Iterator_Rbtree_List;
47
48struct _Eina_Iterator_Rbtree
49{
50 Eina_Iterator iterator;
51
52 Eina_Array *stack;
53
54 unsigned char mask;
55};
56
57struct _Eina_Iterator_Rbtree_List
58{
59 Eina_Rbtree *tree;
60
61 Eina_Rbtree_Direction dir : 1;
62 Eina_Bool up : 1;
63};
64
65static 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
85static 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
94static 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
108static 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
178onfix:
179 *data = tree;
180 return EINA_TRUE;
181}
182
183static 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
219on_error:
220 eina_array_free(it->stack);
221on_error2:
222 free(it);
223
224 return NULL;
225}
226
227static 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
239static inline Eina_Bool
240_eina_rbtree_is_red(Eina_Rbtree *node)
241{
242 return !!node && node->color == EINA_RBTREE_RED;
243}
244
245static 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
260static 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
276EAPI Eina_Rbtree *
277eina_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
343EAPI Eina_Rbtree *
344eina_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
490EAPI Eina_Iterator *
491eina_rbtree_iterator_prefix(const Eina_Rbtree *root)
492{
493 return _eina_rbtree_iterator_build(root, EINA_RBTREE_ITERATOR_PREFIX_MASK);
494}
495
496EAPI Eina_Iterator *
497eina_rbtree_iterator_infix(const Eina_Rbtree *root)
498{
499 return _eina_rbtree_iterator_build(root, EINA_RBTREE_ITERATOR_INFIX_MASK);
500}
501
502EAPI Eina_Iterator *
503eina_rbtree_iterator_postfix(const Eina_Rbtree *root)
504{
505 return _eina_rbtree_iterator_build(root, EINA_RBTREE_ITERATOR_POSTFIX_MASK);
506}
507
508EAPI void
509eina_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
56typedef struct _Eina_Rectangle_Alloc Eina_Rectangle_Alloc;
57
58struct _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
75struct _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
94static Eina_Mempool *_eina_rectangle_alloc_mp = NULL;
95static Eina_Mempool *_eina_rectangle_mp = NULL;
96
97static Eina_Trash *_eina_rectangles = NULL;
98static unsigned int _eina_rectangles_count = 0;
99static 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
111static 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
117static 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
131start_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
174static 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
254Eina_Bool
255eina_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
295init_error:
296 eina_log_domain_unregister(_eina_rectangle_log_dom);
297 _eina_rectangle_log_dom = -1;
298
299 return EINA_FALSE;
300}
301
302Eina_Bool
303eina_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
324EAPI Eina_Rectangle *
325eina_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
345EAPI void
346eina_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
359EAPI Eina_Rectangle_Pool *
360eina_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
383EAPI void
384eina_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
410EAPI int
411eina_rectangle_pool_count(Eina_Rectangle_Pool *pool)
412{
413 EINA_SAFETY_ON_NULL_RETURN_VAL(pool, 0);
414 return pool->references;
415}
416
417EAPI Eina_Rectangle *
418eina_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
478EAPI void
479eina_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
518EAPI Eina_Rectangle_Pool *
519eina_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
531EAPI void
532eina_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
543EAPI void *
544eina_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
552EAPI Eina_Bool
553eina_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 */
47Eina_Bool
48eina_safety_checks_shutdown(void)
49{
50 return EINA_TRUE;
51}
52
53/*============================================================================*
54* API *
55*============================================================================*/
56
57/**
58 * @cond LOCAL
59 */
60
61EAPI Eina_Error EINA_ERROR_SAFETY_FAILED = 0;
62
63static 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 */
80Eina_Bool
81eina_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
47EAPI void
48eina_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, &param);
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, &param);
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
96static const char EINA_MAGIC_SHARE_STR[] = "Eina Share";
97static const char EINA_MAGIC_SHARE_HEAD_STR[] = "Eina Share Head";
98
99static 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
121typedef struct _Eina_Share_Common_Population Eina_Share_Common_Population;
122#endif
123
124typedef struct _Eina_Share_Common Eina_Share_Common;
125typedef struct _Eina_Share_Common_Node Eina_Share_Common_Node;
126typedef struct _Eina_Share_Common_Head Eina_Share_Common_Head;
127
128struct _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
138struct _Eina_Share_Common
139{
140 Eina_Share_Common_Head *buckets[EINA_SHARE_COMMON_BUCKETS];
141
142 EINA_MAGIC
143};
144
145struct _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
156struct _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
171Eina_Bool _share_common_threads_activated = EINA_FALSE;
172
173static Eina_Lock _mutex_big;
174
175#ifdef EINA_SHARE_COMMON_USAGE
176struct _Eina_Share_Common_Population
177{
178 int count;
179 int max;
180};
181
182static Eina_Share_Common_Population population = { 0, 0 };
183
184static Eina_Share_Common_Population population_group[4] =
185{
186 { 0, 0 },
187 { 0, 0 },
188 { 0, 0 },
189 { 0, 0 }
190};
191
192static 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
207static 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
226static 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
250void
251eina_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
271void
272eina_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
283static void
284_eina_share_common_population_head_init(Eina_Share *share,
285 Eina_Share_Common_Head *head)
286{
287 head->population = 1;
288}
289
290static 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
299static 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
308static void _eina_share_common_population_init(__UNUSED__ Eina_Share *share) {
309}
310static void _eina_share_common_population_shutdown(__UNUSED__ Eina_Share *share)
311{
312}
313static void _eina_share_common_population_stats(__UNUSED__ Eina_Share *share) {
314}
315void eina_share_common_population_add(__UNUSED__ Eina_Share *share,
316 __UNUSED__ int slen) {
317}
318void eina_share_common_population_del(__UNUSED__ Eina_Share *share,
319 __UNUSED__ int slen) {
320}
321static void _eina_share_common_population_head_init(
322 __UNUSED__ Eina_Share *share,
323 __UNUSED__ Eina_Share_Common_Head *head) {
324}
325static void _eina_share_common_population_head_add(
326 __UNUSED__ Eina_Share *share,
327 __UNUSED__
328 Eina_Share_Common_Head *head) {
329}
330static void _eina_share_common_population_head_del(
331 __UNUSED__ Eina_Share *share,
332 __UNUSED__
333 Eina_Share_Common_Head *head) {
334}
335#endif
336
337static 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
348static 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
362static 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
378static 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
394static 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
407static 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
441static 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
455static 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
464static 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
490static 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
514static 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
522static 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
535static 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
548static Eina_Bool
549eina_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 */
590Eina_Bool
591eina_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 */
636Eina_Bool
637eina_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 */
684void
685eina_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 */
699void
700eina_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
715const char *
716eina_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
783const char *
784eina_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
808Eina_Bool
809eina_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
863on_error:
864 eina_lock_release(&_mutex_big);
865 /* possible segfault happened before here, but... */
866 return EINA_FALSE;
867}
868
869int
870eina_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
882void
883eina_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
57typedef struct _Eina_Share Eina_Share;
58
59struct dumpinfo
60{
61 int used, saved, dups, unique;
62};
63
64Eina_Bool eina_share_common_init(Eina_Share **share,
65 Eina_Magic node_magic,
66 const char *node_magic_STR);
67Eina_Bool eina_share_common_shutdown(Eina_Share **share);
68const char *eina_share_common_add_length(Eina_Share *share,
69 const char *str,
70 unsigned int slen,
71 unsigned int null_size)
72EINA_WARN_UNUSED_RESULT;
73const char *eina_share_common_ref(Eina_Share *share, const char *str);
74Eina_Bool eina_share_common_del(Eina_Share *share, const char *str) EINA_WARN_UNUSED_RESULT;
75int eina_share_common_length(Eina_Share *share,
76 const char *str) EINA_CONST
77EINA_WARN_UNUSED_RESULT;
78void eina_share_common_dump(Eina_Share *share, void (*additional_dump)(
79 struct dumpinfo *), int used);
80
81
82/* Population functions */
83void eina_share_common_population_add(Eina_Share *share, int slen);
84void 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
36extern "C"
37# endif
38void *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
67static Eina_Mempool *_eina_simple_xml_tag_mp = NULL;
68static Eina_Mempool *_eina_simple_xml_attribute_mp = NULL;
69static int _eina_simple_xml_log_dom = -1;
70
71static const char EINA_MAGIC_SIMPLE_XML_TAG_STR[] = "Eina Simple XML Tag";
72static const char EINA_MAGIC_SIMPLE_XML_DATA_STR[] = "Eina Simple XML Data";
73static 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
123static 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
131static 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
139static 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
147static 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
153static 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 */
182Eina_Bool
183eina_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
231on_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 */
249Eina_Bool
250eina_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
266EAPI Eina_Bool
267eina_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
454EAPI const char *
455eina_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
479EAPI Eina_Bool
480eina_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
541EAPI Eina_Simple_XML_Attribute *
542eina_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
567EAPI void
568eina_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
582static 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
593EAPI Eina_Simple_XML_Node_Tag *
594eina_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
622void
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
651EAPI void
652eina_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
663static 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
691EAPI Eina_Simple_XML_Node_Data *
692eina_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
698EAPI void
699eina_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
710EAPI Eina_Simple_XML_Node_CData *
711eina_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
717EAPI void
718eina_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
729EAPI Eina_Simple_XML_Node_Processing *
730eina_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
736EAPI void
737eina_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
748EAPI Eina_Simple_XML_Node_Doctype *
749eina_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
755EAPI void
756eina_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
767EAPI Eina_Simple_XML_Node_Comment *
768eina_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
774EAPI void
775eina_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
786struct eina_simple_xml_node_load_ctxt
787{
788 Eina_Simple_XML_Node_Root *root;
789 Eina_Simple_XML_Node_Tag *current;
790};
791
792static 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
802static 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
887EAPI Eina_Simple_XML_Node_Root *
888eina_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
909EAPI void
910eina_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
922static 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
930static 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
939static void _eina_simple_xml_node_dump(Eina_Strbuf *buf, Eina_Simple_XML_Node *node, const char *indent, unsigned level);
940
941static 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
950static 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
1057EAPI char *
1058eina_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 */
51static inline Eina_Bool
52eina_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
68static inline char **
69eina_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
180EAPI size_t
181eina_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
212EAPI size_t
213eina_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
243EAPI Eina_Bool
244eina_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
257EAPI Eina_Bool
258eina_str_has_suffix(const char *str, const char *suffix)
259{
260 return eina_str_has_suffix_helper(str, suffix, strcmp);
261}
262
263EAPI Eina_Bool
264eina_str_has_extension(const char *str, const char *ext)
265{
266 return eina_str_has_suffix_helper(str, ext, strcasecmp);
267}
268
269EAPI char **
270eina_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
279EAPI char **
280eina_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
285EAPI size_t
286eina_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
332EAPI char *
333eina_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
409EAPI char *
410eina_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
418EAPI char *
419eina_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
442EAPI void
443eina_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
453EAPI void
454eina_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
66static 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
85EAPI Eina_Bool
86eina_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
105EAPI Eina_Bool
106eina_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
122EAPI Eina_Bool
123eina_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
142EAPI Eina_Bool
143eina_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
162EAPI void
163eina_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
178EAPI void
179eina_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
192EAPI void
193eina_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 */
52Eina_Bool
53eina_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 */
69Eina_Bool
70eina_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 */
84static 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 */
111static 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 */
136static 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 */
186Eina_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 */
207static 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 */
249Eina_Strbuf *
250eina_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 */
287Eina_Strbuf *
288eina_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 */
318void
319eina_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 */
335void
336eina_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 */
361Eina_Bool
362eina_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 */
400Eina_Bool
401eina_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 */
440Eina_Bool
441eina_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 */
473Eina_Bool
474eina_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 */
506Eina_Bool
507eina_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 */
544Eina_Bool
545eina_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 */
571Eina_Bool
572eina_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 */
597Eina_Bool
598eina_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 */
624Eina_Bool
625eina_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 */
664const void *
665eina_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 */
685void *
686eina_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 */
706void
707eina_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 */
722size_t
723eina_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
749static const char __STRBUF_STR_MAGIC_STR[] = "Eina Strbuf";
750
751
752/**
753 * @endcond
754 */
755
756
757EAPI Eina_Bool
758eina_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
800EAPI int
801eina_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 */
14struct _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
33Eina_Bool
34eina_strbuf_common_init(void);
35
36Eina_Bool
37eina_strbuf_common_shutdown(void);
38Eina_Strbuf *
39eina_strbuf_common_new(size_t csize);
40Eina_Strbuf *
41eina_strbuf_common_manage_new(size_t csize,
42 void *str,
43 size_t len);
44void
45eina_strbuf_common_free(Eina_Strbuf *buf);
46void
47eina_strbuf_common_reset(size_t csize, Eina_Strbuf *buf);
48Eina_Bool
49eina_strbuf_common_append(size_t csize,
50 Eina_Strbuf *buf,
51 const void *str,
52 size_t len);
53Eina_Bool
54eina_strbuf_common_append_escaped(size_t csize,
55 Eina_Strbuf *buf,
56 const void *str);
57Eina_Bool
58eina_strbuf_common_append_n(size_t csize,
59 Eina_Strbuf *buf,
60 const void *str,
61 size_t len,
62 size_t maxlen);
63Eina_Bool
64eina_strbuf_common_append_length(size_t csize,
65 Eina_Strbuf *buf,
66 const void *str,
67 size_t length);
68Eina_Bool
69eina_strbuf_common_insert(size_t csize,
70 Eina_Strbuf *buf,
71 const void *str,
72 size_t len,
73 size_t pos);
74Eina_Bool
75eina_strbuf_common_insert_escaped(size_t csize,
76 Eina_Strbuf *buf,
77 const void *str,
78 size_t len,
79 size_t pos);
80Eina_Bool
81eina_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);
87Eina_Bool
88eina_strbuf_common_insert_length(size_t csize,
89 Eina_Strbuf *buf,
90 const void *str,
91 size_t length,
92 size_t pos);
93Eina_Bool
94eina_strbuf_common_append_char(size_t csize, Eina_Strbuf *buf, const void *c);
95Eina_Bool
96eina_strbuf_common_insert_char(size_t csize,
97 Eina_Strbuf *buf,
98 const void *c,
99 size_t pos);
100Eina_Bool
101eina_strbuf_common_remove(size_t csize,
102 Eina_Strbuf *buf,
103 size_t start,
104 size_t end);
105const void *
106eina_strbuf_common_string_get(const Eina_Strbuf *buf);
107void *
108eina_strbuf_common_string_steal(size_t csize, Eina_Strbuf *buf);
109void
110eina_strbuf_common_string_free(size_t csize, Eina_Strbuf *buf);
111size_t
112eina_strbuf_common_length_get(const Eina_Strbuf *buf);
113
114Eina_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
25EAPI _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
34EAPI 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
41EAPI 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
59EAPI 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
66EAPI 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
73EAPI 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
91EAPI 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
41extern "C"
42# endif
43void *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
81static int _eina_share_stringshare_log_dom = -1;
82
83/* The actual share */
84static Eina_Share *stringshare_share;
85static const char EINA_MAGIC_STRINGSHARE_NODE_STR[] = "Eina Stringshare Node";
86
87extern Eina_Bool _share_common_threads_activated;
88static Eina_Lock _mutex_small;
89
90/* Stringshare optimizations */
91static 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
122typedef struct _Eina_Stringshare_Small Eina_Stringshare_Small;
123typedef struct _Eina_Stringshare_Small_Bucket Eina_Stringshare_Small_Bucket;
124
125struct _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
135struct _Eina_Stringshare_Small
136{
137 Eina_Stringshare_Small_Bucket *buckets[256];
138};
139
140#define EINA_STRINGSHARE_SMALL_BUCKET_STEP 8
141static Eina_Stringshare_Small _eina_small_share;
142
143static 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
183static 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
224static 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
261static 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
319static 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
359end:
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
367static 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
390static 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
408error:
409 CRITICAL("EEEK trying to del non-shared stringshare \"%s\"", str);
410}
411
412static 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
419static 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
450static 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
479static 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 */
514Eina_Bool
515eina_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 */
556Eina_Bool
557eina_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
576EAPI void
577eina_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
611EAPI Eina_Stringshare *
612eina_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
632EAPI Eina_Stringshare *
633eina_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
653EAPI Eina_Stringshare *
654eina_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
677EAPI Eina_Stringshare *
678eina_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
698EAPI Eina_Stringshare *
699eina_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
723EAPI Eina_Stringshare *
724eina_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
764EAPI int
765eina_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
786EAPI void
787eina_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 */
42typedef struct list_node list_node_t;
43typedef struct list list_t;
44typedef struct rect rect_t;
45typedef struct rect_node rect_node_t;
46
47struct list_node
48{
49 struct list_node *next;
50};
51
52struct list
53{
54 struct list_node *head;
55 struct list_node *tail;
56};
57
58struct 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
69struct rect_node
70{
71 struct list_node _lst;
72 struct rect rect;
73};
74
75typedef struct splitter
76{
77 Eina_Bool need_merge;
78 list_t rects;
79} splitter_t;
80
81typedef struct list_node_pool
82{
83 list_node_t *node;
84 int len;
85 int max;
86} list_node_pool_t;
87
88
89static const list_node_t list_node_zeroed = { NULL };
90static const list_t list_zeroed = { NULL, NULL };
91static list_node_pool_t list_node_pool = { NULL, 0, 1024 };
92
93
94typedef 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
103struct _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 */
134static 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
148static inline list_node_t *
149rect_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
166static 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
185static 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
199static 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
210static 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
222static 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
252static 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
315static 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
387enum
388{
389 SPLIT_FUZZY_ACTION_NONE,
390 SPLIT_FUZZY_ACTION_SPLIT,
391 SPLIT_FUZZY_ACTION_MERGE
392};
393
394static 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
471static 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
491static 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
507static 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
520static 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
525static 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
554static inline list_node_t *
555rect_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
577static 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
585static 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
601static 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
654static 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
724static list_node_t *
725rect_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
872static 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
909static 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
965static 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
987static inline void _splitter_new(Eina_Tiler *t)
988{
989 t->splitter.rects = list_zeroed;
990 t->splitter.need_merge = EINA_FALSE;
991}
992
993static inline void _splitter_del(Eina_Tiler *t)
994{
995 rect_list_clear(&t->splitter.rects);
996 rect_list_node_pool_flush();
997}
998
999static 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
1007static 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
1032static 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
1059static 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
1066static 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
1094static void *_iterator_get_container(Eina_Iterator_Tiler *it)
1095{
1096 EINA_MAGIC_CHECK_TILER_ITERATOR(it, NULL);
1097 return (void *)it->tiler;
1098}
1099
1100static 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
1114EAPI 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
1128EAPI void eina_tiler_free(Eina_Tiler *t)
1129{
1130 EINA_MAGIC_CHECK_TILER(t);
1131 _splitter_del(t);
1132 free(t);
1133}
1134
1135EAPI 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
1146EAPI 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
1164EAPI 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
1182EAPI void eina_tiler_clear(Eina_Tiler *t)
1183{
1184 EINA_MAGIC_CHECK_TILER(t);
1185 _splitter_clear(t);
1186}
1187
1188
1189EAPI 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
1227struct _Eina_Tile_Grid_Slicer_Iterator
1228{
1229 Eina_Iterator iterator;
1230 Eina_Tile_Grid_Slicer priv;
1231};
1232
1233typedef struct _Eina_Tile_Grid_Slicer_Iterator Eina_Tile_Grid_Slicer_Iterator;
1234
1235static void
1236eina_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
1242static Eina_Bool
1243eina_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
1250EAPI Eina_Iterator *
1251eina_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. */
36const Eina_Unicode _EINA_UNICODE_EMPTY_STRING[1] = {0};
37EAPI const Eina_Unicode *EINA_UNICODE_EMPTY_STRING = _EINA_UNICODE_EMPTY_STRING;
38EAPI int
39eina_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
54EAPI Eina_Unicode *
55eina_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
68EAPI Eina_Unicode *
69eina_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
83EAPI size_t
84eina_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
95EAPI size_t
96eina_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
111EAPI Eina_Unicode *
112eina_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
124EAPI Eina_Unicode *
125eina_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
135EAPI Eina_Unicode *
136eina_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
158EAPI Eina_Unicode *
159eina_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
193EAPI Eina_Unicode
194eina_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 */
295error:
296 d = buf[*iindex];
297 (*iindex)++;
298 return ERROR_REPLACEMENT_BASE | d;
299}
300
301EAPI Eina_Unicode
302eina_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
328EAPI int
329eina_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
342EAPI Eina_Unicode *
343eina_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
366EAPI char *
367eina_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
56static 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
60static int _eina_share_ustringshare_log_dom = -1;
61
62/* The actual share */
63static Eina_Share *ustringshare_share;
64static 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 */
81Eina_Bool
82eina_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 */
122Eina_Bool
123eina_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
141EAPI void
142eina_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
151EAPI const Eina_Unicode *
152eina_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
163EAPI const Eina_Unicode *
164eina_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
170EAPI const Eina_Unicode *
171eina_ustringshare_ref(const Eina_Unicode *str)
172{
173 return (const Eina_Unicode *)eina_share_common_ref(ustringshare_share,
174 (const char *)str);
175}
176
177EAPI int
178eina_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
185EAPI void
186eina_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
43extern "C"
44# endif
45void *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
77static Eina_Mempool *_eina_value_mp = NULL;
78static Eina_Hash *_eina_value_inner_mps = NULL;
79static Eina_Lock _eina_value_inner_mps_lock;
80static char *_eina_value_mp_choice = NULL;
81static 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
93static const unsigned char eina_value_uchar_max = 255U;
94static const char eina_value_char_max = 127;
95static const char eina_value_char_min = -127 - 1;
96
97static const unsigned short eina_value_ushort_max = 65535U;
98static const short eina_value_short_max = 32767;
99static const short eina_value_short_min = -32767 - 1;
100
101static const unsigned int eina_value_uint_max = 4294967295U;
102static const int eina_value_int_max = 2147483647;
103static const int eina_value_int_min = -2147483647 - 1;
104
105static const uint64_t eina_value_uint64_max = 18446744073709551615ULL;
106static const int64_t eina_value_int64_max = 9223372036854775807LL;
107static const int64_t eina_value_int64_min = -9223372036854775807LL - 1LL;
108
109#if __WORDSIZE == 64
110static const unsigned long eina_value_ulong_max = 18446744073709551615ULL;
111static const long eina_value_long_max = 9223372036854775807LL;
112static const long eina_value_long_min = -9223372036854775807LL - 1LL;
113#else
114static const unsigned long eina_value_ulong_max = 4294967295U;
115static const long eina_value_long_max = 2147483647;
116static const long eina_value_long_min = -2147483647 - 1;
117#endif
118
119
120static 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
128static Eina_Bool
129_eina_value_type_uchar_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
130{
131 return EINA_TRUE;
132}
133
134static 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
143static 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
154static 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
241static 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
249static 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
258static 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
267static 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
275static Eina_Bool
276_eina_value_type_ushort_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
277{
278 return EINA_TRUE;
279}
280
281static 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
290static 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
301static 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
392static 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
400static 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
409static 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
418static 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
426static Eina_Bool
427_eina_value_type_uint_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
428{
429 return EINA_TRUE;
430}
431
432static 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
441static 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
452static 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
547static 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
555static 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
564static 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
573static 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
581static Eina_Bool
582_eina_value_type_ulong_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
583{
584 return EINA_TRUE;
585}
586
587static 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
596static 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
607static 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
706static 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
714static 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
723static 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
732static 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
740static Eina_Bool
741_eina_value_type_uint64_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
742{
743 return EINA_TRUE;
744}
745
746static 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
755static 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
766static 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
870static 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
878static 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
887static 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
896static 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
904static Eina_Bool
905_eina_value_type_char_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
906{
907 return EINA_TRUE;
908}
909
910static 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
919static 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
930static 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
1025static 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
1033static 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
1042static 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
1051static 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
1059static Eina_Bool
1060_eina_value_type_short_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
1061{
1062 return EINA_TRUE;
1063}
1064
1065static 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
1074static 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
1085static 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
1186static 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
1194static 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
1203static 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
1212static 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
1220static Eina_Bool
1221_eina_value_type_int_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
1222{
1223 return EINA_TRUE;
1224}
1225
1226static 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
1235static 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
1246static 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
1353static 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
1361static 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
1370static 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
1379static 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
1387static Eina_Bool
1388_eina_value_type_long_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
1389{
1390 return EINA_TRUE;
1391}
1392
1393static 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
1402static 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
1413static 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
1526static 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
1534static 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
1543static 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
1552static 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
1560static Eina_Bool
1561_eina_value_type_int64_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
1562{
1563 return EINA_TRUE;
1564}
1565
1566static 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
1575static 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
1586static 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
1706static 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
1714static 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
1723static 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
1732static 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
1740static Eina_Bool
1741_eina_value_type_float_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
1742{
1743 return EINA_TRUE;
1744}
1745
1746static 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
1755static 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
1766static 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
1892static 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
1900static 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
1909static 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
1918static 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
1926static Eina_Bool
1927_eina_value_type_double_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
1928{
1929 return EINA_TRUE;
1930}
1931
1932static 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
1941static 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
1952static 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
2072static 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
2080static 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
2089static 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
2098static 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
2106static 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
2120static 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
2245static 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
2252static 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
2264static 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
2273static 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
2280static 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
2287static 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
2299static 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
2318static 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
2344static 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
2370static 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
2377static 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
2398static 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
2410static 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
2462static 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
2520static 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
2601static 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
2631static 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
2680static 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
2688static 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
2695static 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
2710static 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
2717static 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
2736static 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
2748static 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
2796static 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
2845static 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
2925static 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
2965static 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
2999static 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
3007static 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
3014static 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
3029static 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
3036struct _eina_value_type_hash_flush_each_ctx
3037{
3038 const Eina_Value_Type *subtype;
3039 Eina_Bool ret;
3040};
3041
3042static 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
3051static 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
3067static 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
3076static 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
3084static 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
3093static 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
3106struct _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
3113static 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
3140static 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
3174struct _eina_value_type_hash_compare_each_ctx
3175{
3176 const Eina_Value_Type *subtype;
3177 const Eina_Hash *other;
3178 int cmp;
3179};
3180
3181static 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
3192static 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
3234static 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
3242struct _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
3250static 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
3282static 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
3340static 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
3377static 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
3385static 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
3392static 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
3407static 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
3414static Eina_Bool
3415_eina_value_type_timeval_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
3416{
3417 return EINA_TRUE;
3418}
3419
3420static 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
3429static 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
3440static 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
3459static 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
3577static 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
3585static 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
3593static 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
3600static 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
3615static 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
3622static 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
3632static 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
3644static 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
3663static 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
3685static 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
3753static 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
3840static 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
3862static 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
3870static 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
3877static 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
3892static 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
3899static 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
3917static 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
3926static 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
3972static 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
3981static 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
3992EAPI const Eina_Value_Struct_Member *
3993eina_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
4027static 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
4034static 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
4041static 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
4048static 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
4085static 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
4095static 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
4156static 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
4166static 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
4211static 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
4239static 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
4289static 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
4339static 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
4420static 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
4428static 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
4435static 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
4450static 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
4458static 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
4470static 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
4482static 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
4494static 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
4518static 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
4533static 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
4550static 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
4559static 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 */
4580static 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
4793static 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
4799static 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
4812static 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
4820typedef struct _Eina_Value_Inner_Mp Eina_Value_Inner_Mp;
4821struct _Eina_Value_Inner_Mp
4822{
4823 Eina_Mempool *mempool;
4824 int references;
4825};
4826
4827/**
4828 * @endcond
4829 */
4830
4831static const char EINA_ERROR_VALUE_FAILED_STR[] = "Value check failed.";
4832
4833/**
4834 */
4835
4836static 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
4846static 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
4876static 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
4892static 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
4905EAPI void *
4906eina_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
4919EAPI void
4920eina_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 */
4944Eina_Bool
4945eina_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 */
5052Eina_Bool
5053eina_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
5079EAPI const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_START = NULL;
5080EAPI const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_END = NULL;
5081
5082EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UCHAR = NULL;
5083EAPI const Eina_Value_Type *EINA_VALUE_TYPE_USHORT = NULL;
5084EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT = NULL;
5085EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ULONG = NULL;
5086EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMESTAMP = NULL;
5087EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT64 = NULL;
5088EAPI const Eina_Value_Type *EINA_VALUE_TYPE_CHAR = NULL;
5089EAPI const Eina_Value_Type *EINA_VALUE_TYPE_SHORT = NULL;
5090EAPI const Eina_Value_Type *EINA_VALUE_TYPE_INT = NULL;
5091EAPI const Eina_Value_Type *EINA_VALUE_TYPE_LONG = NULL;
5092EAPI const Eina_Value_Type *EINA_VALUE_TYPE_INT64 = NULL;
5093EAPI const Eina_Value_Type *EINA_VALUE_TYPE_FLOAT = NULL;
5094EAPI const Eina_Value_Type *EINA_VALUE_TYPE_DOUBLE = NULL;
5095EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRINGSHARE = NULL;
5096EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRING = NULL;
5097EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ARRAY = NULL;
5098EAPI const Eina_Value_Type *EINA_VALUE_TYPE_LIST = NULL;
5099EAPI const Eina_Value_Type *EINA_VALUE_TYPE_HASH = NULL;
5100EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMEVAL = NULL;
5101EAPI const Eina_Value_Type *EINA_VALUE_TYPE_BLOB = NULL;
5102EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRUCT = NULL;
5103EAPI const Eina_Value_Type *EINA_VALUE_TYPE_MODEL = NULL;
5104
5105EAPI const Eina_Value_Blob_Operations *EINA_VALUE_BLOB_OPERATIONS_MALLOC = NULL;
5106
5107EAPI const Eina_Value_Struct_Operations *EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH = NULL;
5108EAPI const Eina_Value_Struct_Operations *EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE = NULL;
5109
5110EAPI Eina_Error EINA_ERROR_VALUE_FAILED = 0;
5111
5112EAPI 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
5119EAPI Eina_Value *
5120eina_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
5136EAPI void
5137eina_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
5145EAPI Eina_Bool
5146eina_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
5172EAPI Eina_Bool
5173eina_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
5203EAPI char *
5204eina_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
5219EAPI Eina_Value *
5220eina_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
5239EAPI Eina_Value *
5240eina_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
5259EAPI Eina_Value *
5260eina_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
5279EAPI Eina_Value *
5280eina_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
5297EAPI Eina_Bool
5298eina_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
5304EAPI const char *
5305eina_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
48typedef struct _Eina_Xattr_Iterator Eina_Xattr_Iterator;
49
50struct _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
66static 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
98static 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
130static 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
142static void *
143_eina_xattr_ls_iterator_container(Eina_Xattr_Iterator *it __UNUSED__)
144{
145 return NULL;
146}
147
148static 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
173EAPI Eina_Iterator *
174eina_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
217EAPI Eina_Iterator *
218eina_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
253EAPI Eina_Iterator *
254eina_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
289EAPI Eina_Iterator *
290eina_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
327EAPI void *
328eina_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
365EAPI Eina_Bool
366eina_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
398EAPI Eina_Bool
399eina_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
406EAPI char *
407eina_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
424EAPI Eina_Bool
425eina_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
433EAPI Eina_Bool
434eina_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
457EAPI Eina_Bool
458eina_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
466EAPI Eina_Bool
467eina_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}