aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/lib')
-rw-r--r--libraries/eina/src/lib/Makefile.am5
-rw-r--r--libraries/eina/src/lib/Makefile.in94
-rw-r--r--libraries/eina/src/lib/eina_binshare.c69
-rw-r--r--libraries/eina/src/lib/eina_file.c232
-rw-r--r--libraries/eina/src/lib/eina_file_win32.c2235
-rw-r--r--libraries/eina/src/lib/eina_inlist.c5
-rw-r--r--libraries/eina/src/lib/eina_list.c15
-rw-r--r--libraries/eina/src/lib/eina_magic.c5
-rw-r--r--libraries/eina/src/lib/eina_main.c5
-rw-r--r--libraries/eina/src/lib/eina_matrixsparse.c2
-rw-r--r--libraries/eina/src/lib/eina_module.c4
-rw-r--r--libraries/eina/src/lib/eina_prefix.c22
-rw-r--r--libraries/eina/src/lib/eina_private.h2
-rw-r--r--libraries/eina/src/lib/eina_rbtree.c365
-rw-r--r--libraries/eina/src/lib/eina_sched.c19
-rw-r--r--libraries/eina/src/lib/eina_share_common.c42
-rw-r--r--libraries/eina/src/lib/eina_share_common.h21
-rw-r--r--libraries/eina/src/lib/eina_stringshare.c77
-rw-r--r--libraries/eina/src/lib/eina_unicode.c55
-rw-r--r--libraries/eina/src/lib/eina_ustringshare.c69
-rw-r--r--libraries/eina/src/lib/eina_value.c453
21 files changed, 2261 insertions, 1535 deletions
diff --git a/libraries/eina/src/lib/Makefile.am b/libraries/eina/src/lib/Makefile.am
index d8c9d20..5de2848 100644
--- a/libraries/eina/src/lib/Makefile.am
+++ b/libraries/eina/src/lib/Makefile.am
@@ -6,8 +6,8 @@ AM_CPPFLAGS = \
6-DPACKAGE_BIN_DIR=\"$(bindir)\" \ 6-DPACKAGE_BIN_DIR=\"$(bindir)\" \
7-DPACKAGE_LIB_DIR=\"$(libdir)\" \ 7-DPACKAGE_LIB_DIR=\"$(libdir)\" \
8-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ 8-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
9@EINA_CPPFLAGS@ \ 9@EFL_EINA_BUILD@ \
10@EFL_EINA_BUILD@ 10@VALGRIND_CFLAGS@
11 11
12base_sources = \ 12base_sources = \
13eina_accessor.c \ 13eina_accessor.c \
@@ -33,6 +33,7 @@ eina_main.c \
33eina_matrixsparse.c \ 33eina_matrixsparse.c \
34eina_mempool.c \ 34eina_mempool.c \
35eina_mmap.c \ 35eina_mmap.c \
36eina_model.c \
36eina_module.c \ 37eina_module.c \
37eina_prefix.c \ 38eina_prefix.c \
38eina_quadtree.c \ 39eina_quadtree.c \
diff --git a/libraries/eina/src/lib/Makefile.in b/libraries/eina/src/lib/Makefile.in
index 878bcbe..f15bb00 100644
--- a/libraries/eina/src/lib/Makefile.in
+++ b/libraries/eina/src/lib/Makefile.in
@@ -49,20 +49,24 @@ host_triplet = @host@
49subdir = src/lib 49subdir = src/lib
50DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in 50DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
51ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 51ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
52am__aclocal_m4_deps = $(top_srcdir)/m4/efl_attribute.m4 \ 52am__aclocal_m4_deps = $(top_srcdir)/m4/eina/eina_bench.m4 \
53 $(top_srcdir)/m4/efl_benchmark.m4 \ 53 $(top_srcdir)/m4/eina/eina_check.m4 \
54 $(top_srcdir)/m4/efl_compiler_flag.m4 \ 54 $(top_srcdir)/m4/common/efl_attribute.m4 \
55 $(top_srcdir)/m4/efl_coverage.m4 $(top_srcdir)/m4/efl_cpu.m4 \ 55 $(top_srcdir)/m4/common/efl_benchmark.m4 \
56 $(top_srcdir)/m4/efl_doxygen.m4 \ 56 $(top_srcdir)/m4/common/efl_compiler_flag.m4 \
57 $(top_srcdir)/m4/efl_examples.m4 \ 57 $(top_srcdir)/m4/common/efl_coverage.m4 \
58 $(top_srcdir)/m4/efl_fnmatch.m4 \ 58 $(top_srcdir)/m4/common/efl_cpu.m4 \
59 $(top_srcdir)/m4/efl_path_max.m4 $(top_srcdir)/m4/efl_tests.m4 \ 59 $(top_srcdir)/m4/common/efl_doxygen.m4 \
60 $(top_srcdir)/m4/efl_threads.m4 \ 60 $(top_srcdir)/m4/common/efl_examples.m4 \
61 $(top_srcdir)/m4/efl_voltron.m4 $(top_srcdir)/m4/eina_bench.m4 \ 61 $(top_srcdir)/m4/common/efl_fnmatch.m4 \
62 $(top_srcdir)/m4/eina_check.m4 $(top_srcdir)/m4/libtool.m4 \ 62 $(top_srcdir)/m4/common/efl_path_max.m4 \
63 $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ 63 $(top_srcdir)/m4/common/efl_tests.m4 \
64 $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ 64 $(top_srcdir)/m4/common/efl_threads.m4 \
65 $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac 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
66am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 70am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
67 $(ACLOCAL_M4) 71 $(ACLOCAL_M4)
68mkinstalldirs = $(install_sh) -d 72mkinstalldirs = $(install_sh) -d
@@ -99,13 +103,13 @@ am__libeina_la_SOURCES_DIST = eina_accessor.c eina_array.c \
99 eina_hamster.c eina_hash.c eina_inarray.c eina_inlist.c \ 103 eina_hamster.c eina_hash.c eina_inarray.c eina_inlist.c \
100 eina_iterator.c eina_lalloc.c eina_list.c eina_log.c \ 104 eina_iterator.c eina_lalloc.c eina_list.c eina_log.c \
101 eina_magic.c eina_main.c eina_matrixsparse.c eina_mempool.c \ 105 eina_magic.c eina_main.c eina_matrixsparse.c eina_mempool.c \
102 eina_mmap.c eina_module.c eina_prefix.c eina_quadtree.c \ 106 eina_mmap.c eina_model.c eina_module.c eina_prefix.c \
103 eina_rbtree.c eina_rectangle.c eina_safety_checks.c \ 107 eina_quadtree.c eina_rbtree.c eina_rectangle.c \
104 eina_sched.c eina_share_common.c eina_simple_xml_parser.c \ 108 eina_safety_checks.c eina_sched.c eina_share_common.c \
105 eina_str.c eina_strbuf.c eina_strbuf_common.c \ 109 eina_simple_xml_parser.c eina_str.c eina_strbuf.c \
106 eina_stringshare.c eina_tiler.c eina_unicode.c eina_ustrbuf.c \ 110 eina_strbuf_common.c eina_stringshare.c eina_tiler.c \
107 eina_ustringshare.c eina_value.c eina_xattr.c \ 111 eina_unicode.c eina_ustrbuf.c eina_ustringshare.c eina_value.c \
108 eina_file_win32.c eina_file.c \ 112 eina_xattr.c eina_file_win32.c eina_file.c \
109 $(top_srcdir)/src/modules/mp/buddy/eina_buddy.c \ 113 $(top_srcdir)/src/modules/mp/buddy/eina_buddy.c \
110 $(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c \ 114 $(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c \
111 $(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c \ 115 $(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c \
@@ -135,11 +139,11 @@ am__objects_10 = libeina_la-eina_accessor.lo libeina_la-eina_array.lo \
135 libeina_la-eina_list.lo libeina_la-eina_log.lo \ 139 libeina_la-eina_list.lo libeina_la-eina_log.lo \
136 libeina_la-eina_magic.lo libeina_la-eina_main.lo \ 140 libeina_la-eina_magic.lo libeina_la-eina_main.lo \
137 libeina_la-eina_matrixsparse.lo libeina_la-eina_mempool.lo \ 141 libeina_la-eina_matrixsparse.lo libeina_la-eina_mempool.lo \
138 libeina_la-eina_mmap.lo libeina_la-eina_module.lo \ 142 libeina_la-eina_mmap.lo libeina_la-eina_model.lo \
139 libeina_la-eina_prefix.lo libeina_la-eina_quadtree.lo \ 143 libeina_la-eina_module.lo libeina_la-eina_prefix.lo \
140 libeina_la-eina_rbtree.lo libeina_la-eina_rectangle.lo \ 144 libeina_la-eina_quadtree.lo libeina_la-eina_rbtree.lo \
141 libeina_la-eina_safety_checks.lo libeina_la-eina_sched.lo \ 145 libeina_la-eina_rectangle.lo libeina_la-eina_safety_checks.lo \
142 libeina_la-eina_share_common.lo \ 146 libeina_la-eina_sched.lo libeina_la-eina_share_common.lo \
143 libeina_la-eina_simple_xml_parser.lo libeina_la-eina_str.lo \ 147 libeina_la-eina_simple_xml_parser.lo libeina_la-eina_str.lo \
144 libeina_la-eina_strbuf.lo libeina_la-eina_strbuf_common.lo \ 148 libeina_la-eina_strbuf.lo libeina_la-eina_strbuf_common.lo \
145 libeina_la-eina_stringshare.lo libeina_la-eina_tiler.lo \ 149 libeina_la-eina_stringshare.lo libeina_la-eina_tiler.lo \
@@ -236,13 +240,13 @@ EINA_CONFIGURE_DEFAULT_MEMPOOL = @EINA_CONFIGURE_DEFAULT_MEMPOOL@
236EINA_CONFIGURE_ENABLE_LOG = @EINA_CONFIGURE_ENABLE_LOG@ 240EINA_CONFIGURE_ENABLE_LOG = @EINA_CONFIGURE_ENABLE_LOG@
237EINA_CONFIGURE_HAVE_DEBUG_THREADS = @EINA_CONFIGURE_HAVE_DEBUG_THREADS@ 241EINA_CONFIGURE_HAVE_DEBUG_THREADS = @EINA_CONFIGURE_HAVE_DEBUG_THREADS@
238EINA_CONFIGURE_HAVE_DIRENT_H = @EINA_CONFIGURE_HAVE_DIRENT_H@ 242EINA_CONFIGURE_HAVE_DIRENT_H = @EINA_CONFIGURE_HAVE_DIRENT_H@
243EINA_CONFIGURE_HAVE_EXOTIC = @EINA_CONFIGURE_HAVE_EXOTIC@
239EINA_CONFIGURE_HAVE_INTTYPES_H = @EINA_CONFIGURE_HAVE_INTTYPES_H@ 244EINA_CONFIGURE_HAVE_INTTYPES_H = @EINA_CONFIGURE_HAVE_INTTYPES_H@
240EINA_CONFIGURE_HAVE_ON_OFF_THREADS = @EINA_CONFIGURE_HAVE_ON_OFF_THREADS@ 245EINA_CONFIGURE_HAVE_ON_OFF_THREADS = @EINA_CONFIGURE_HAVE_ON_OFF_THREADS@
241EINA_CONFIGURE_HAVE_STDINT_H = @EINA_CONFIGURE_HAVE_STDINT_H@ 246EINA_CONFIGURE_HAVE_STDINT_H = @EINA_CONFIGURE_HAVE_STDINT_H@
242EINA_CONFIGURE_HAVE_THREADS = @EINA_CONFIGURE_HAVE_THREADS@ 247EINA_CONFIGURE_HAVE_THREADS = @EINA_CONFIGURE_HAVE_THREADS@
243EINA_CONFIGURE_MAGIC_DEBUG = @EINA_CONFIGURE_MAGIC_DEBUG@ 248EINA_CONFIGURE_MAGIC_DEBUG = @EINA_CONFIGURE_MAGIC_DEBUG@
244EINA_CONFIGURE_SAFETY_CHECKS = @EINA_CONFIGURE_SAFETY_CHECKS@ 249EINA_CONFIGURE_SAFETY_CHECKS = @EINA_CONFIGURE_SAFETY_CHECKS@
245EINA_CPPFLAGS = @EINA_CPPFLAGS@
246EINA_LIBS = @EINA_LIBS@ 250EINA_LIBS = @EINA_LIBS@
247EINA_SIZEOF_WCHAR_T = @EINA_SIZEOF_WCHAR_T@ 251EINA_SIZEOF_WCHAR_T = @EINA_SIZEOF_WCHAR_T@
248EMEMOA_CFLAGS = @EMEMOA_CFLAGS@ 252EMEMOA_CFLAGS = @EMEMOA_CFLAGS@
@@ -252,6 +256,8 @@ ESCAPE_LIBS = @ESCAPE_LIBS@
252EVIL_CFLAGS = @EVIL_CFLAGS@ 256EVIL_CFLAGS = @EVIL_CFLAGS@
253EVIL_LIBS = @EVIL_LIBS@ 257EVIL_LIBS = @EVIL_LIBS@
254EXEEXT = @EXEEXT@ 258EXEEXT = @EXEEXT@
259EXOTIC_CFLAGS = @EXOTIC_CFLAGS@
260EXOTIC_LIBS = @EXOTIC_LIBS@
255FGREP = @FGREP@ 261FGREP = @FGREP@
256GLIB_CFLAGS = @GLIB_CFLAGS@ 262GLIB_CFLAGS = @GLIB_CFLAGS@
257GLIB_LIBS = @GLIB_LIBS@ 263GLIB_LIBS = @GLIB_LIBS@
@@ -287,6 +293,8 @@ PACKAGE_URL = @PACKAGE_URL@
287PACKAGE_VERSION = @PACKAGE_VERSION@ 293PACKAGE_VERSION = @PACKAGE_VERSION@
288PATH_SEPARATOR = @PATH_SEPARATOR@ 294PATH_SEPARATOR = @PATH_SEPARATOR@
289PKG_CONFIG = @PKG_CONFIG@ 295PKG_CONFIG = @PKG_CONFIG@
296PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
297PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
290RANLIB = @RANLIB@ 298RANLIB = @RANLIB@
291SED = @SED@ 299SED = @SED@
292SET_MAKE = @SET_MAKE@ 300SET_MAKE = @SET_MAKE@
@@ -367,23 +375,24 @@ AM_CPPFLAGS = \
367-DPACKAGE_BIN_DIR=\"$(bindir)\" \ 375-DPACKAGE_BIN_DIR=\"$(bindir)\" \
368-DPACKAGE_LIB_DIR=\"$(libdir)\" \ 376-DPACKAGE_LIB_DIR=\"$(libdir)\" \
369-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ 377-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
370@EINA_CPPFLAGS@ \ 378@EFL_EINA_BUILD@ \
371@EFL_EINA_BUILD@ 379@VALGRIND_CFLAGS@
372 380
373base_sources = eina_accessor.c eina_array.c eina_benchmark.c \ 381base_sources = eina_accessor.c eina_array.c eina_benchmark.c \
374 eina_binbuf.c eina_binshare.c eina_convert.c eina_counter.c \ 382 eina_binbuf.c eina_binshare.c eina_convert.c eina_counter.c \
375 eina_cpu.c eina_error.c eina_fp.c eina_hamster.c eina_hash.c \ 383 eina_cpu.c eina_error.c eina_fp.c eina_hamster.c eina_hash.c \
376 eina_inarray.c eina_inlist.c eina_iterator.c eina_lalloc.c \ 384 eina_inarray.c eina_inlist.c eina_iterator.c eina_lalloc.c \
377 eina_list.c eina_log.c eina_magic.c eina_main.c \ 385 eina_list.c eina_log.c eina_magic.c eina_main.c \
378 eina_matrixsparse.c eina_mempool.c eina_mmap.c eina_module.c \ 386 eina_matrixsparse.c eina_mempool.c eina_mmap.c eina_model.c \
379 eina_prefix.c eina_quadtree.c eina_rbtree.c eina_rectangle.c \ 387 eina_module.c eina_prefix.c eina_quadtree.c eina_rbtree.c \
380 eina_safety_checks.c eina_sched.c eina_share_common.c \ 388 eina_rectangle.c eina_safety_checks.c eina_sched.c \
381 eina_simple_xml_parser.c eina_str.c eina_strbuf.c \ 389 eina_share_common.c eina_simple_xml_parser.c eina_str.c \
382 eina_strbuf_common.c eina_stringshare.c eina_tiler.c \ 390 eina_strbuf.c eina_strbuf_common.c eina_stringshare.c \
383 eina_unicode.c eina_ustrbuf.c eina_ustringshare.c eina_value.c \ 391 eina_tiler.c eina_unicode.c eina_ustrbuf.c eina_ustringshare.c \
384 eina_xattr.c $(am__append_1) $(am__append_2) $(am__append_3) \ 392 eina_value.c eina_xattr.c $(am__append_1) $(am__append_2) \
385 $(am__append_4) $(am__append_5) $(am__append_6) \ 393 $(am__append_3) $(am__append_4) $(am__append_5) \
386 $(am__append_7) $(am__append_8) $(am__append_9) 394 $(am__append_6) $(am__append_7) $(am__append_8) \
395 $(am__append_9)
387EXTRA_DIST = \ 396EXTRA_DIST = \
388eina_share_common.h \ 397eina_share_common.h \
389eina_private.h \ 398eina_private.h \
@@ -502,6 +511,7 @@ distclean-compile:
502@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_matrixsparse.Plo@am__quote@ 511@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_matrixsparse.Plo@am__quote@
503@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_mempool.Plo@am__quote@ 512@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_mempool.Plo@am__quote@
504@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_mmap.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@
505@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_module.Plo@am__quote@ 515@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_module.Plo@am__quote@
506@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_one_big.Plo@am__quote@ 516@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_one_big.Plo@am__quote@
507@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_pass_through.Plo@am__quote@ 517@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_pass_through.Plo@am__quote@
@@ -732,6 +742,14 @@ libeina_la-eina_mmap.lo: eina_mmap.c
732@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 742@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
733@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 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
734 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
735libeina_la-eina_module.lo: eina_module.c 753libeina_la-eina_module.lo: eina_module.c
736@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 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
737@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_module.Tpo $(DEPDIR)/libeina_la-eina_module.Plo 755@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_module.Tpo $(DEPDIR)/libeina_la-eina_module.Plo
diff --git a/libraries/eina/src/lib/eina_binshare.c b/libraries/eina/src/lib/eina_binshare.c
index 68a82fc..01e8046 100644
--- a/libraries/eina/src/lib/eina_binshare.c
+++ b/libraries/eina/src/lib/eina_binshare.c
@@ -21,9 +21,18 @@
21 21
22 */ 22 */
23 23
24#include "eina_share_common.h" 24#ifdef HAVE_CONFIG_H
25#include "eina_unicode.h" 25# include "config.h"
26#endif
27
28#include "eina_config.h"
26#include "eina_private.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"
27#include "eina_binshare.h" 36#include "eina_binshare.h"
28 37
29/*============================================================================* 38/*============================================================================*
@@ -34,6 +43,23 @@
34 * @cond LOCAL 43 * @cond LOCAL
35 */ 44 */
36 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
37/* The actual share */ 63/* The actual share */
38static Eina_Share *binshare_share; 64static Eina_Share *binshare_share;
39static const char EINA_MAGIC_BINSHARE_NODE_STR[] = "Eina Binshare Node"; 65static const char EINA_MAGIC_BINSHARE_NODE_STR[] = "Eina Binshare Node";
@@ -42,7 +68,6 @@ static const char EINA_MAGIC_BINSHARE_NODE_STR[] = "Eina Binshare Node";
42 * @endcond 68 * @endcond
43 */ 69 */
44 70
45
46/*============================================================================* 71/*============================================================================*
47* Global * 72* Global *
48*============================================================================*/ 73*============================================================================*/
@@ -61,9 +86,31 @@ static const char EINA_MAGIC_BINSHARE_NODE_STR[] = "Eina Binshare Node";
61EAPI Eina_Bool 86EAPI Eina_Bool
62eina_binshare_init(void) 87eina_binshare_init(void)
63{ 88{
64 return eina_share_common_init(&binshare_share, 89 Eina_Bool ret;
65 EINA_MAGIC_BINSHARE_NODE, 90
66 EINA_MAGIC_BINSHARE_NODE_STR); 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;
67} 114}
68 115
69/** 116/**
@@ -82,6 +129,13 @@ eina_binshare_shutdown(void)
82{ 129{
83 Eina_Bool ret; 130 Eina_Bool ret;
84 ret = eina_share_common_shutdown(&binshare_share); 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
85 return ret; 139 return ret;
86} 140}
87 141
@@ -96,7 +150,8 @@ eina_binshare_del(const void *obj)
96 if (!obj) 150 if (!obj)
97 return; 151 return;
98 152
99 eina_share_common_del(binshare_share, obj); 153 if (!eina_share_common_del(binshare_share, obj))
154 CRITICAL("EEEK trying to del non-shared binshare %p", obj);
100} 155}
101 156
102EAPI const void * 157EAPI const void *
diff --git a/libraries/eina/src/lib/eina_file.c b/libraries/eina/src/lib/eina_file.c
index 0b836b3..c465301 100644
--- a/libraries/eina/src/lib/eina_file.c
+++ b/libraries/eina/src/lib/eina_file.c
@@ -362,41 +362,15 @@ _eina_file_direct_ls_iterator_free(Eina_File_Direct_Iterator *it)
362static Eina_Bool 362static Eina_Bool
363_eina_file_stat_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data) 363_eina_file_stat_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data)
364{ 364{
365 struct stat st; 365 Eina_Stat st;
366 366
367 if (!_eina_file_direct_ls_iterator_next(it, data)) 367 if (!_eina_file_direct_ls_iterator_next(it, data))
368 return EINA_FALSE; 368 return EINA_FALSE;
369 369
370 if (it->info.type == EINA_FILE_UNKNOWN) 370 if (it->info.type == EINA_FILE_UNKNOWN)
371 { 371 {
372#ifdef HAVE_FSTATAT 372 if (eina_file_statat(it->dirp, &it->info, &st) != 0)
373 int fd;
374
375 fd = dirfd(it->dirp);
376 if (fstatat(fd, it->info.path + it->info.name_start, &st, 0))
377#else
378 if (stat(it->info.path, &st))
379#endif
380 it->info.type = EINA_FILE_UNKNOWN; 373 it->info.type = EINA_FILE_UNKNOWN;
381 else
382 {
383 if (S_ISREG(st.st_mode))
384 it->info.type = EINA_FILE_REG;
385 else if (S_ISDIR(st.st_mode))
386 it->info.type = EINA_FILE_DIR;
387 else if (S_ISCHR(st.st_mode))
388 it->info.type = EINA_FILE_CHR;
389 else if (S_ISBLK(st.st_mode))
390 it->info.type = EINA_FILE_BLK;
391 else if (S_ISFIFO(st.st_mode))
392 it->info.type = EINA_FILE_FIFO;
393 else if (S_ISLNK(st.st_mode))
394 it->info.type = EINA_FILE_LNK;
395 else if (S_ISSOCK(st.st_mode))
396 it->info.type = EINA_FILE_SOCK;
397 else
398 it->info.type = EINA_FILE_UNKNOWN;
399 }
400 } 374 }
401 375
402 return EINA_TRUE; 376 return EINA_TRUE;
@@ -593,6 +567,14 @@ _eina_file_escape(const char *path, int *length)
593 return result; 567 return result;
594} 568}
595 569
570/**
571 * @endcond
572 */
573
574/*============================================================================*
575 * Global *
576 *============================================================================*/
577
596Eina_Bool 578Eina_Bool
597eina_file_init(void) 579eina_file_init(void)
598{ 580{
@@ -641,13 +623,60 @@ eina_file_shutdown(void)
641 return EINA_TRUE; 623 return EINA_TRUE;
642} 624}
643 625
644/** 626void
645 * @endcond 627eina_file_mmap_faulty(void *addr, long page_size)
646 */ 628{
629 Eina_File_Map *m;
630 Eina_File *f;
631 Eina_Iterator *itf;
632 Eina_Iterator *itm;
647 633
648/*============================================================================* 634 /* NOTE: I actually don't know if other thread are running, I will try to take the lock.
649 * Global * 635 It may be possible that if other thread are not running and they were in the middle of
650 *============================================================================*/ 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}
651 680
652/*============================================================================* 681/*============================================================================*
653 * API * 682 * API *
@@ -950,7 +979,7 @@ eina_file_open(const char *path, Eina_Bool shared)
950 eina_lock_take(&_eina_file_lock_cache); 979 eina_lock_take(&_eina_file_lock_cache);
951 980
952 file = eina_hash_find(_eina_file_cache, filename); 981 file = eina_hash_find(_eina_file_cache, filename);
953 if ((file) && _eina_file_timestamp_compare(file, &file_stat)) 982 if ((file) && !_eina_file_timestamp_compare(file, &file_stat))
954 { 983 {
955 file->delete_me = EINA_TRUE; 984 file->delete_me = EINA_TRUE;
956 eina_hash_del(_eina_file_cache, file->filename, file); 985 eina_hash_del(_eina_file_cache, file->filename, file);
@@ -1029,7 +1058,7 @@ eina_file_close(Eina_File *file)
1029 1058
1030 eina_hash_del(_eina_file_cache, file->filename, file); 1059 eina_hash_del(_eina_file_cache, file->filename, file);
1031 _eina_file_real_close(file); 1060 _eina_file_real_close(file);
1032 1061
1033 eina_lock_release(&_eina_file_lock_cache); 1062 eina_lock_release(&_eina_file_lock_cache);
1034} 1063}
1035 1064
@@ -1196,7 +1225,7 @@ eina_file_map_free(Eina_File *file, void *map)
1196 unsigned long int key[2]; 1225 unsigned long int key[2];
1197 1226
1198 em = eina_hash_find(file->rmap, &map); 1227 em = eina_hash_find(file->rmap, &map);
1199 if (!em) return ; 1228 if (!em) goto on_exit;
1200 1229
1201 em->refcount--; 1230 em->refcount--;
1202 1231
@@ -1217,17 +1246,25 @@ EAPI Eina_Bool
1217eina_file_map_faulted(Eina_File *file, void *map) 1246eina_file_map_faulted(Eina_File *file, void *map)
1218{ 1247{
1219 Eina_File_Map *em; 1248 Eina_File_Map *em;
1249 Eina_Bool r = EINA_FALSE;
1220 1250
1221 EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE); 1251 EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
1222 1252
1223 eina_lock_take(&file->lock); 1253 eina_lock_take(&file->lock);
1224 1254
1225 if (file->global_map == map) return file->global_faulty; 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 }
1226 1264
1227 em = eina_hash_find(file->rmap, &map); 1265 eina_lock_release(&file->lock);
1228 if (!em) return EINA_FALSE;
1229 1266
1230 return em->faulty; 1267 return r;
1231} 1268}
1232 1269
1233EAPI Eina_Iterator * 1270EAPI Eina_Iterator *
@@ -1246,58 +1283,77 @@ eina_file_xattr_value_get(Eina_File *file)
1246 return eina_xattr_value_fd_ls(file->fd); 1283 return eina_xattr_value_fd_ls(file->fd);
1247} 1284}
1248 1285
1249void 1286EAPI int
1250eina_file_mmap_faulty(void *addr, long page_size) 1287eina_file_statat(void *container, Eina_File_Direct_Info *info, Eina_Stat *st)
1251{ 1288{
1252 Eina_File_Map *m; 1289 struct stat buf;
1253 Eina_File *f; 1290#ifdef HAVE_FSTATAT
1254 Eina_Iterator *itf; 1291 int fd;
1255 Eina_Iterator *itm; 1292#endif
1256 1293
1257 /* NOTE: I actually don't know if other thread are running, I will try to take the lock. 1294 EINA_SAFETY_ON_NULL_RETURN_VAL(info, -1);
1258 It may be possible that if other thread are not running and they were in the middle of 1295 EINA_SAFETY_ON_NULL_RETURN_VAL(st, -1);
1259 accessing an Eina_File this lock are still taken and we will result as a deadlock. */
1260 eina_lock_take(&_eina_file_lock_cache);
1261 1296
1262 itf = eina_hash_iterator_data_new(_eina_file_cache); 1297#ifdef HAVE_FSTATAT
1263 EINA_ITERATOR_FOREACH(itf, f) 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
1264 { 1304 {
1265 Eina_Bool faulty = EINA_FALSE; 1305 if (info->type != EINA_FILE_LNK)
1266 1306 info->type = EINA_FILE_UNKNOWN;
1267 eina_lock_take(&f->lock); 1307 return -1;
1268 1308 }
1269 if (f->global_map)
1270 {
1271 if ((unsigned char *) addr < (((unsigned char *)f->global_map) + f->length) &&
1272 (((unsigned char *) addr) + page_size) >= (unsigned char *) f->global_map)
1273 {
1274 f->global_faulty = EINA_TRUE;
1275 faulty = EINA_TRUE;
1276 }
1277 }
1278
1279 if (!faulty)
1280 {
1281 itm = eina_hash_iterator_data_new(f->map);
1282 EINA_ITERATOR_FOREACH(itm, m)
1283 {
1284 if ((unsigned char *) addr < (((unsigned char *)m->map) + m->length) &&
1285 (((unsigned char *) addr) + page_size) >= (unsigned char *) m->map)
1286 {
1287 m->faulty = EINA_TRUE;
1288 faulty = EINA_TRUE;
1289 break;
1290 }
1291 }
1292 eina_iterator_free(itm);
1293 }
1294
1295 eina_lock_release(&f->lock);
1296 1309
1297 if (faulty) break; 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;
1298 } 1328 }
1299 eina_iterator_free(itf);
1300 1329
1301 eina_lock_release(&_eina_file_lock_cache); 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;
1302} 1359}
1303
diff --git a/libraries/eina/src/lib/eina_file_win32.c b/libraries/eina/src/lib/eina_file_win32.c
index 1cd8665..5c20fdd 100644
--- a/libraries/eina/src/lib/eina_file_win32.c
+++ b/libraries/eina/src/lib/eina_file_win32.c
@@ -1,1021 +1,1214 @@
1/* EINA - EFL data type library 1/* EINA - EFL data type library
2 * Copyright (C) 2010 Vincent Torri 2 * Copyright (C) 2010 Vincent Torri
3 * 3 *
4 * This library is free software; you can redistribute it and/or 4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public 5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either 6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version. 7 * version 2.1 of the License, or (at your option) any later version.
8 * 8 *
9 * This library is distributed in the hope that it will be useful, 9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details. 12 * Lesser General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU Lesser General Public 14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; 15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>. 16 * if not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19#ifdef HAVE_CONFIG_H 19#ifdef HAVE_CONFIG_H
20# include "config.h" 20# include "config.h"
21#endif 21#endif
22 22
23#ifdef HAVE_ALLOCA_H 23#ifdef HAVE_ALLOCA_H
24# include <alloca.h> 24# include <alloca.h>
25#elif defined __GNUC__ 25#elif defined __GNUC__
26# define alloca __builtin_alloca 26# define alloca __builtin_alloca
27#elif defined _AIX 27#elif defined _AIX
28# define alloca __alloca 28# define alloca __alloca
29#elif defined _MSC_VER 29#elif defined _MSC_VER
30# include <malloc.h> 30# include <malloc.h>
31# define alloca _alloca 31# define alloca _alloca
32#else 32#else
33# include <stddef.h> 33# include <stddef.h>
34# ifdef __cplusplus 34# ifdef __cplusplus
35extern "C" 35extern "C"
36# endif 36# endif
37void *alloca (size_t); 37void *alloca (size_t);
38#endif 38#endif
39 39
40#define WIN32_LEAN_AND_MEAN 40#include <sys/types.h>
41#include <windows.h> 41#include <sys/stat.h>
42#undef WIN32_LEAN_AND_MEAN 42
43 43#define WIN32_LEAN_AND_MEAN
44//#include <Evil.h> 44#include <windows.h>
45 45#undef WIN32_LEAN_AND_MEAN
46#include "eina_config.h" 46
47#include "eina_private.h" 47#include <Evil.h>
48 48
49/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ 49#include "eina_config.h"
50#include "eina_safety_checks.h" 50#include "eina_private.h"
51#include "eina_file.h" 51
52#include "eina_stringshare.h" 52/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
53#include "eina_hash.h" 53#include "eina_safety_checks.h"
54#include "eina_list.h" 54#include "eina_file.h"
55 55#include "eina_stringshare.h"
56/*============================================================================* 56#include "eina_hash.h"
57 * Local * 57#include "eina_list.h"
58 *============================================================================*/ 58#include "eina_lock.h"
59 59#include "eina_log.h"
60/** 60
61 * @cond LOCAL 61/*============================================================================*
62 */ 62 * Local *
63 63 *============================================================================*/
64#ifndef EINA_LOG_COLOR_DEFAULT 64
65#define EINA_LOG_COLOR_DEFAULT EINA_COLOR_CYAN 65/**
66#endif 66 * @cond LOCAL
67 67 */
68#ifdef ERR 68
69#undef ERR 69#ifndef EINA_LOG_COLOR_DEFAULT
70#endif 70#define EINA_LOG_COLOR_DEFAULT EINA_COLOR_CYAN
71#define ERR(...) EINA_LOG_DOM_ERR(_eina_file_log_dom, __VA_ARGS__) 71#endif
72 72
73#ifdef WRN 73#ifdef ERR
74#undef WRN 74#undef ERR
75#endif 75#endif
76#define WRN(...) EINA_LOG_DOM_WARN(_eina_file_log_dom, __VA_ARGS__) 76#define ERR(...) EINA_LOG_DOM_ERR(_eina_file_log_dom, __VA_ARGS__)
77 77
78#ifdef DBG 78#ifdef WRN
79#undef DBG 79#undef WRN
80#endif 80#endif
81#define DBG(...) EINA_LOG_DOM_DBG(_eina_file_log_dom, __VA_ARGS__) 81#define WRN(...) EINA_LOG_DOM_WARN(_eina_file_log_dom, __VA_ARGS__)
82 82
83#ifdef MAP_FAILED 83#ifdef DBG
84# undef MAP_FAILED 84#undef DBG
85#endif 85#endif
86#define MAP_FAILED ((void *)-1) 86#define DBG(...) EINA_LOG_DOM_DBG(_eina_file_log_dom, __VA_ARGS__)
87 87
88typedef struct _Eina_File_Iterator Eina_File_Iterator; 88#ifdef MAP_FAILED
89typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator; 89# undef MAP_FAILED
90typedef struct _Eina_File_Map Eina_File_Map; 90#endif
91 91#define MAP_FAILED ((void *)-1)
92struct _Eina_File_Iterator 92
93{ 93typedef struct _Eina_File_Iterator Eina_File_Iterator;
94 Eina_Iterator iterator; 94typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator;
95 95typedef struct _Eina_File_Map Eina_File_Map;
96 WIN32_FIND_DATA data; 96
97 HANDLE handle; 97struct _Eina_File_Iterator
98 size_t length; 98{
99 Eina_Bool is_last : 1; 99 Eina_Iterator iterator;
100 100
101 char dir[1]; 101 WIN32_FIND_DATA data;
102}; 102 HANDLE handle;
103 103 size_t length;
104struct _Eina_File_Direct_Iterator 104 Eina_Bool is_last : 1;
105{ 105
106 Eina_Iterator iterator; 106 char dir[1];
107 107};
108 WIN32_FIND_DATA data; 108
109 HANDLE handle; 109struct _Eina_File_Direct_Iterator
110 size_t length; 110{
111 Eina_Bool is_last : 1; 111 Eina_Iterator iterator;
112 112
113 Eina_File_Direct_Info info; 113 WIN32_FIND_DATA data;
114 114 HANDLE handle;
115 char dir[1]; 115 size_t length;
116}; 116 Eina_Bool is_last : 1;
117 117
118struct _Eina_File 118 Eina_File_Direct_Info info;
119{ 119
120 const char *filename; 120 char dir[1];
121 121};
122 Eina_Hash *map; 122
123 Eina_Hash *rmap; 123struct _Eina_File
124 void *global_map; 124{
125 125 const char *filename;
126 ULONGLONG length; 126
127 ULONGLONG mtime; 127 Eina_Hash *map;
128 128 Eina_Hash *rmap;
129 int refcount; 129 void *global_map;
130 int global_refcount; 130
131 131 Eina_Lock lock;
132 HANDLE handle; 132
133 HANDLE fm; 133 ULONGLONG length;
134 134 ULONGLONG mtime;
135 Eina_Bool shared : 1; 135
136 Eina_Bool delete_me : 1; 136 int refcount;
137}; 137 int global_refcount;
138 138
139struct _Eina_File_Map 139 HANDLE handle;
140{ 140 HANDLE fm;
141 void *map; 141
142 142 Eina_Bool shared : 1;
143 unsigned long int offset; 143 Eina_Bool delete_me : 1;
144 unsigned long int length; 144};
145 145
146 int refcount; 146struct _Eina_File_Map
147}; 147{
148 148 void *map;
149static Eina_Hash *_eina_file_cache = NULL; 149
150static Eina_List *_eina_file_cache_lru = NULL; 150 unsigned long int offset;
151static Eina_List *_eina_file_cache_delete = NULL; 151 unsigned long int length;
152 152
153static int _eina_file_log_dom = -1; 153 int refcount;
154 154};
155static void 155
156_eina_file_win32_backslash_change(char *dir) 156static Eina_Hash *_eina_file_cache = NULL;
157{ 157static Eina_Lock _eina_file_lock_cache;
158 char *tmp; 158
159 159static int _eina_file_log_dom = -1;
160 tmp = dir; 160
161 while (*tmp) 161static void
162 { 162_eina_file_win32_backslash_change(char *dir)
163 if (*tmp == '/') *tmp = '\\'; 163{
164 tmp++; 164 char *tmp;
165 } 165
166} 166 tmp = dir;
167 167 while (*tmp)
168static Eina_Bool 168 {
169_eina_file_win32_is_dir(const char *dir) 169 if (*tmp == '/') *tmp = '\\';
170{ 170 tmp++;
171#ifdef UNICODE 171 }
172 wchar_t *wdir = NULL; 172}
173#endif 173
174 DWORD attr; 174static Eina_Bool
175 175_eina_file_win32_is_dir(const char *dir)
176 /* check if it's a directory */ 176{
177#ifdef UNICODE 177#ifdef UNICODE
178 wdir = evil_char_to_wchar(dir); 178 wchar_t *wdir = NULL;
179 if (!wdir) 179#endif
180 return EINA_FALSE; 180 DWORD attr;
181 181
182 attr = GetFileAttributes(wdir); 182 /* check if it's a directory */
183 free(wdir); 183#ifdef UNICODE
184#else 184 wdir = evil_char_to_wchar(dir);
185 attr = GetFileAttributes(dir); 185 if (!wdir)
186#endif 186 return EINA_FALSE;
187 187
188 if (attr == 0xFFFFFFFF) 188 attr = GetFileAttributes(wdir);
189 return EINA_FALSE; 189 free(wdir);
190 190#else
191 if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) 191 attr = GetFileAttributes(dir);
192 return EINA_FALSE; 192#endif
193 193
194 return EINA_TRUE; 194 if (attr == 0xFFFFFFFF)
195} 195 return EINA_FALSE;
196 196
197static char * 197 if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
198_eina_file_win32_dir_new(const char *dir) 198 return EINA_FALSE;
199{ 199
200 char *new_dir; 200 return EINA_TRUE;
201 size_t length; 201}
202 202
203 length = strlen(dir); 203static char *
204 204_eina_file_win32_dir_new(const char *dir)
205 new_dir = (char *)malloc(sizeof(char) * length + 5); 205{
206 if (!new_dir) 206 char *new_dir;
207 return NULL; 207 size_t length;
208 208
209 memcpy(new_dir, dir, length); 209 length = strlen(dir);
210 memcpy(new_dir + length, "\\*.*", 5); 210
211 _eina_file_win32_backslash_change(new_dir); 211 new_dir = (char *)malloc(sizeof(char) * length + 5);
212 212 if (!new_dir)
213 return new_dir; 213 return NULL;
214} 214
215 215 memcpy(new_dir, dir, length);
216static HANDLE 216 memcpy(new_dir + length, "\\*.*", 5);
217_eina_file_win32_first_file(const char *dir, WIN32_FIND_DATA *fd) 217 _eina_file_win32_backslash_change(new_dir);
218{ 218
219 HANDLE h; 219 return new_dir;
220#ifdef UNICODE 220}
221 wchar_t *wdir = NULL; 221
222 222static HANDLE
223 wdir = evil_char_to_wchar(dir); 223_eina_file_win32_first_file(const char *dir, WIN32_FIND_DATA *fd)
224 if (!wdir) 224{
225 return NULL; 225 HANDLE h;
226 226#ifdef UNICODE
227 h = FindFirstFile(wdir, fd); 227 wchar_t *wdir = NULL;
228 free(wdir); 228
229#else 229 wdir = evil_char_to_wchar(dir);
230 h = FindFirstFile(dir, fd); 230 if (!wdir)
231#endif 231 return NULL;
232 232
233 if (!h) 233 h = FindFirstFile(wdir, fd);
234 return NULL; 234 free(wdir);
235 235#else
236 while ((fd->cFileName[0] == '.') && 236 h = FindFirstFile(dir, fd);
237 ((fd->cFileName[1] == '\0') || 237#endif
238 ((fd->cFileName[1] == '.') && (fd->cFileName[2] == '\0')))) 238
239 { 239 if (!h)
240 if (!FindNextFile(h, fd)) 240 return NULL;
241 return NULL; 241
242 } 242 while ((fd->cFileName[0] == '.') &&
243 243 ((fd->cFileName[1] == '\0') ||
244 return h; 244 ((fd->cFileName[1] == '.') && (fd->cFileName[2] == '\0'))))
245} 245 {
246 246 if (!FindNextFile(h, fd))
247static Eina_Bool 247 return NULL;
248_eina_file_win32_ls_iterator_next(Eina_File_Iterator *it, void **data) 248 }
249{ 249
250#ifdef UNICODE 250 return h;
251 wchar_t *old_name; 251}
252#else 252
253 char *old_name; 253static Eina_Bool
254#endif 254_eina_file_win32_ls_iterator_next(Eina_File_Iterator *it, void **data)
255 char *name; 255{
256 char *cname; 256#ifdef UNICODE
257 size_t length; 257 wchar_t *old_name;
258 Eina_Bool is_last; 258#else
259 Eina_Bool res = EINA_TRUE; 259 char *old_name;
260 260#endif
261 if (it->handle == INVALID_HANDLE_VALUE) 261 char *name;
262 return EINA_FALSE; 262 char *cname;
263 263 size_t length;
264 is_last = it->is_last; 264 Eina_Bool is_last;
265#ifdef UNICODE 265 Eina_Bool res = EINA_TRUE;
266 old_name = _wcsdup(it->data.cFileName); 266
267#else 267 if (it->handle == INVALID_HANDLE_VALUE)
268 old_name = _strdup(it->data.cFileName); 268 return EINA_FALSE;
269#endif 269
270 if (!old_name) 270 is_last = it->is_last;
271 return EINA_FALSE; 271#ifdef UNICODE
272 272 old_name = _wcsdup(it->data.cFileName);
273 do { 273#else
274 if (!FindNextFile(it->handle, &it->data)) 274 old_name = _strdup(it->data.cFileName);
275 { 275#endif
276 if (GetLastError() == ERROR_NO_MORE_FILES) 276 if (!old_name)
277 it->is_last = EINA_TRUE; 277 return EINA_FALSE;
278 else 278
279 res = EINA_FALSE; 279 do {
280 } 280 if (!FindNextFile(it->handle, &it->data))
281 } while ((it->data.cFileName[0] == '.') && 281 {
282 ((it->data.cFileName[1] == '\0') || 282 if (GetLastError() == ERROR_NO_MORE_FILES)
283 ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */ 283 it->is_last = EINA_TRUE;
284 284 else
285#ifdef UNICODE 285 res = EINA_FALSE;
286 cname = evil_wchar_to_char(old_name); 286 }
287 if (!cname) 287 } while ((it->data.cFileName[0] == '.') &&
288 return EINA_FALSE; 288 ((it->data.cFileName[1] == '\0') ||
289#else 289 ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */
290 cname = old_name; 290
291#endif 291#ifdef UNICODE
292 292 cname = evil_wchar_to_char(old_name);
293 length = strlen(cname); 293 if (!cname)
294 name = alloca(length + 2 + it->length); 294 return EINA_FALSE;
295 295#else
296 memcpy(name, it->dir, it->length); 296 cname = old_name;
297 memcpy(name + it->length, "\\", 1); 297#endif
298 memcpy(name + it->length + 1, cname, length + 1); 298
299 299 length = strlen(cname);
300 *data = (char *)eina_stringshare_add(name); 300 name = alloca(length + 2 + it->length);
301 301
302#ifdef UNICODE 302 memcpy(name, it->dir, it->length);
303 free(cname); 303 memcpy(name + it->length, "\\", 1);
304#endif 304 memcpy(name + it->length + 1, cname, length + 1);
305 free(old_name); 305
306 306 *data = (char *)eina_stringshare_add(name);
307 if (is_last) 307
308 res = EINA_FALSE; 308#ifdef UNICODE
309 309 free(cname);
310 return res; 310#endif
311} 311 free(old_name);
312 312
313static HANDLE 313 if (is_last)
314_eina_file_win32_ls_iterator_container(Eina_File_Iterator *it) 314 res = EINA_FALSE;
315{ 315
316 return it->handle; 316 return res;
317} 317}
318 318
319static void 319static HANDLE
320_eina_file_win32_ls_iterator_free(Eina_File_Iterator *it) 320_eina_file_win32_ls_iterator_container(Eina_File_Iterator *it)
321{ 321{
322 if (it->handle != INVALID_HANDLE_VALUE) 322 return it->handle;
323 FindClose(it->handle); 323}
324 324
325 EINA_MAGIC_SET(&it->iterator, 0); 325static void
326 free(it); 326_eina_file_win32_ls_iterator_free(Eina_File_Iterator *it)
327} 327{
328 328 if (it->handle != INVALID_HANDLE_VALUE)
329static Eina_Bool 329 FindClose(it->handle);
330_eina_file_win32_direct_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data) 330
331{ 331 EINA_MAGIC_SET(&it->iterator, 0);
332#ifdef UNICODE 332 free(it);
333 wchar_t *old_name; 333}
334#else 334
335 char *old_name; 335static Eina_Bool
336#endif 336_eina_file_win32_direct_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data)
337 char *cname; 337{
338 size_t length; 338#ifdef UNICODE
339 DWORD attr; 339 wchar_t *old_name;
340 Eina_Bool is_last; 340#else
341 Eina_Bool res = EINA_TRUE; 341 char *old_name;
342 342#endif
343 if (it->handle == INVALID_HANDLE_VALUE) 343 char *cname;
344 return EINA_FALSE; 344 size_t length;
345 345 DWORD attr;
346 attr = it->data.dwFileAttributes; 346 Eina_Bool is_last;
347 is_last = it->is_last; 347 Eina_Bool res = EINA_TRUE;
348#ifdef UNICODE 348
349 old_name = _wcsdup(it->data.cFileName); 349 if (it->handle == INVALID_HANDLE_VALUE)
350#else 350 return EINA_FALSE;
351 old_name = _strdup(it->data.cFileName); 351
352#endif 352 attr = it->data.dwFileAttributes;
353 if (!old_name) 353 is_last = it->is_last;
354 return EINA_FALSE; 354#ifdef UNICODE
355 355 old_name = _wcsdup(it->data.cFileName);
356 do { 356#else
357 if (!FindNextFile(it->handle, &it->data)) 357 old_name = _strdup(it->data.cFileName);
358 { 358#endif
359 if (GetLastError() == ERROR_NO_MORE_FILES) 359 if (!old_name)
360 it->is_last = EINA_TRUE; 360 return EINA_FALSE;
361 else 361
362 res = EINA_FALSE; 362 do {
363 } 363 if (!FindNextFile(it->handle, &it->data))
364 364 {
365#ifdef UNICODE 365 if (GetLastError() == ERROR_NO_MORE_FILES)
366 length = wcslen(old_name); 366 it->is_last = EINA_TRUE;
367#else 367 else
368 length = strlen(old_name); 368 res = EINA_FALSE;
369#endif 369 }
370 if (it->info.name_start + length + 1 >= PATH_MAX) 370
371 { 371#ifdef UNICODE
372 free(old_name); 372 length = wcslen(old_name);
373#ifdef UNICODE 373#else
374 old_name = _wcsdup(it->data.cFileName); 374 length = strlen(old_name);
375#else 375#endif
376 old_name = _strdup(it->data.cFileName); 376 if (it->info.name_start + length + 1 >= PATH_MAX)
377#endif 377 {
378 continue; 378 free(old_name);
379 } 379#ifdef UNICODE
380 380 old_name = _wcsdup(it->data.cFileName);
381 } while ((it->data.cFileName[0] == '.') && 381#else
382 ((it->data.cFileName[1] == '\0') || 382 old_name = _strdup(it->data.cFileName);
383 ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */ 383#endif
384 384 continue;
385#ifdef UNICODE 385 }
386 cname = evil_wchar_to_char(old_name); 386
387 if (!cname) 387 } while ((it->data.cFileName[0] == '.') &&
388 return EINA_FALSE; 388 ((it->data.cFileName[1] == '\0') ||
389#else 389 ((it->data.cFileName[1] == '.') && (it->data.cFileName[2] == '\0')))); /* FIXME: what about UNICODE ? */
390 cname = old_name; 390
391#endif 391#ifdef UNICODE
392 392 cname = evil_wchar_to_char(old_name);
393 memcpy(it->info.path + it->info.name_start, cname, length); 393 if (!cname)
394 it->info.name_length = length; 394 return EINA_FALSE;
395 it->info.path_length = it->info.name_start + length; 395#else
396 it->info.path[it->info.path_length] = '\0'; 396 cname = old_name;
397 397#endif
398 if (attr & FILE_ATTRIBUTE_DIRECTORY) 398
399 it->info.type = EINA_FILE_DIR; 399 memcpy(it->info.path + it->info.name_start, cname, length);
400 else if (attr & FILE_ATTRIBUTE_REPARSE_POINT) 400 it->info.name_length = length;
401 it->info.type = EINA_FILE_LNK; 401 it->info.path_length = it->info.name_start + length;
402 else if (attr & (FILE_ATTRIBUTE_ARCHIVE | 402 it->info.path[it->info.path_length] = '\0';
403 FILE_ATTRIBUTE_COMPRESSED | 403
404 FILE_ATTRIBUTE_COMPRESSED | 404 if (attr & FILE_ATTRIBUTE_DIRECTORY)
405 FILE_ATTRIBUTE_HIDDEN | 405 it->info.type = EINA_FILE_DIR;
406 FILE_ATTRIBUTE_NORMAL | 406 else if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
407 FILE_ATTRIBUTE_SPARSE_FILE | 407 it->info.type = EINA_FILE_LNK;
408 FILE_ATTRIBUTE_TEMPORARY)) 408 else if (attr & (FILE_ATTRIBUTE_ARCHIVE |
409 it->info.type = EINA_FILE_REG; 409 FILE_ATTRIBUTE_COMPRESSED |
410 else 410 FILE_ATTRIBUTE_COMPRESSED |
411 it->info.type = EINA_FILE_UNKNOWN; 411 FILE_ATTRIBUTE_HIDDEN |
412 412 FILE_ATTRIBUTE_NORMAL |
413 *data = &it->info; 413 FILE_ATTRIBUTE_SPARSE_FILE |
414 414 FILE_ATTRIBUTE_TEMPORARY))
415#ifdef UNICODE 415 it->info.type = EINA_FILE_REG;
416 free(cname); 416 else
417#endif 417 it->info.type = EINA_FILE_UNKNOWN;
418 418
419 free(old_name); 419 *data = &it->info;
420 420
421 if (is_last) 421#ifdef UNICODE
422 res = EINA_FALSE; 422 free(cname);
423 423#endif
424 return res; 424
425} 425 free(old_name);
426 426
427static HANDLE 427 if (is_last)
428_eina_file_win32_direct_ls_iterator_container(Eina_File_Direct_Iterator *it) 428 res = EINA_FALSE;
429{ 429
430 return it->handle; 430 return res;
431} 431}
432 432
433static void 433static HANDLE
434_eina_file_win32_direct_ls_iterator_free(Eina_File_Direct_Iterator *it) 434_eina_file_win32_direct_ls_iterator_container(Eina_File_Direct_Iterator *it)
435{ 435{
436 if (it->handle != INVALID_HANDLE_VALUE) 436 return it->handle;
437 FindClose(it->handle); 437}
438 438
439 EINA_MAGIC_SET(&it->iterator, 0); 439static void
440 free(it); 440_eina_file_win32_direct_ls_iterator_free(Eina_File_Direct_Iterator *it)
441} 441{
442 442 if (it->handle != INVALID_HANDLE_VALUE)
443static void 443 FindClose(it->handle);
444_eina_file_real_close(Eina_File *file) 444
445{ 445 EINA_MAGIC_SET(&it->iterator, 0);
446 eina_hash_free(file->rmap); 446 free(it);
447 eina_hash_free(file->map); 447}
448 448
449 if (file->global_map != MAP_FAILED) 449static void
450 UnmapViewOfFile(file->global_map); 450_eina_file_real_close(Eina_File *file)
451 451{
452 CloseHandle(file->fm); 452 eina_hash_free(file->rmap);
453 CloseHandle(file->handle); 453 eina_hash_free(file->map);
454 454
455 eina_stringshare_del(file->filename); 455 if (file->global_map != MAP_FAILED)
456 456 UnmapViewOfFile(file->global_map);
457 free(file); 457
458} 458 CloseHandle(file->fm);
459 459 CloseHandle(file->handle);
460static void 460
461_eina_file_map_close(Eina_File_Map *map) 461 free(file);
462{ 462}
463 if (map->map != MAP_FAILED) 463
464 UnmapViewOfFile(map->map); 464static void
465 free(map); 465_eina_file_map_close(Eina_File_Map *map)
466} 466{
467 467 if (map->map != MAP_FAILED)
468static unsigned int 468 UnmapViewOfFile(map->map);
469_eina_file_map_key_length(const void *key __UNUSED__) 469 free(map);
470{ 470}
471 return sizeof (unsigned long int) * 2; 471
472} 472static unsigned int
473 473_eina_file_map_key_length(const void *key __UNUSED__)
474static int 474{
475_eina_file_map_key_cmp(const unsigned long int *key1, int key1_length __UNUSED__, 475 return sizeof (unsigned long int) * 2;
476 const unsigned long int *key2, int key2_length __UNUSED__) 476}
477{ 477
478 if (key1[0] - key2[0] == 0) return key1[1] - key2[1]; 478static int
479 return key1[0] - key2[0]; 479_eina_file_map_key_cmp(const unsigned long int *key1, int key1_length __UNUSED__,
480} 480 const unsigned long int *key2, int key2_length __UNUSED__)
481 481{
482static int 482 if (key1[0] - key2[0] == 0) return key1[1] - key2[1];
483_eina_file_map_key_hash(const unsigned long int *key, int key_length __UNUSED__) 483 return key1[0] - key2[0];
484{ 484}
485 return eina_hash_int64(&key[0], sizeof (unsigned long int)) 485
486 ^ eina_hash_int64(&key[1], sizeof (unsigned long int)); 486static int
487} 487_eina_file_map_key_hash(const unsigned long int *key, int key_length __UNUSED__)
488 488{
489Eina_Bool 489 return eina_hash_int64(&key[0], sizeof (unsigned long int))
490eina_file_init(void) 490 ^ eina_hash_int64(&key[1], sizeof (unsigned long int));
491{ 491}
492 _eina_file_log_dom = eina_log_domain_register("eina_file", 492
493 EINA_LOG_COLOR_DEFAULT); 493static char *
494 if (_eina_file_log_dom < 0) 494_eina_file_win32_escape(const char *path, size_t *length)
495 { 495{
496 EINA_LOG_ERR("Could not register log domain: eina_file"); 496 char *result = strdup(path ? path : "");
497 return EINA_FALSE; 497 char *p = result;
498 } 498 char *q = result;
499 499 size_t len;
500 _eina_file_cache = eina_hash_string_djb2_new(EINA_FREE_CB(_eina_file_real_close)); 500
501 if (!_eina_file_cache) 501 if (!result)
502 { 502 return NULL;
503 ERR("Could not create cache."); 503
504 eina_log_domain_unregister(_eina_file_log_dom); 504 if (length) len = *length;
505 _eina_file_log_dom = -1; 505 else len = strlen(result);
506 return EINA_FALSE; 506
507 } 507 while ((p = strchr(p, '/')))
508 508 {
509 return EINA_TRUE; 509 // remove double `/'
510} 510 if (p[1] == '/')
511 511 {
512Eina_Bool 512 memmove(p, p + 1, --len - (p - result));
513eina_file_shutdown(void) 513 result[len] = '\0';
514{ 514 }
515 Eina_File *f; 515 else
516 Eina_List *l; 516 if (p[1] == '.'
517 517 && p[2] == '.')
518 EINA_LIST_FREE(_eina_file_cache_delete, f) 518 {
519 _eina_file_real_close(f); 519 // remove `/../'
520 520 if (p[3] == '/')
521 EINA_LIST_FOREACH(_eina_file_cache_lru, l, f) 521 {
522 eina_hash_del(_eina_file_cache, f->filename, f); 522 char tmp;
523 523
524 if (eina_hash_population(_eina_file_cache) > 0) 524 len -= p + 3 - q;
525 { 525 memmove(q, p + 3, len - (q - result));
526 Eina_Iterator *it; 526 result[len] = '\0';
527 const char *key; 527 p = q;
528 528
529 it = eina_hash_iterator_key_new(_eina_file_cache); 529 /* Update q correctly. */
530 EINA_ITERATOR_FOREACH(it, key) 530 tmp = *p;
531 ERR("File [%s] still open !", key); 531 *p = '\0';
532 eina_iterator_free(it); 532 q = strrchr(result, '/');
533 } 533 if (!q) q = result;
534 534 *p = tmp;
535 eina_hash_free(_eina_file_cache); 535 }
536 536 else
537 eina_log_domain_unregister(_eina_file_log_dom); 537 // remove '/..$'
538 _eina_file_log_dom = -1; 538 if (p[3] == '\0')
539 return EINA_TRUE; 539 {
540} 540 len -= p + 2 - q;
541 541 result[len] = '\0';
542 542 q = p;
543/** 543 ++p;
544 * @endcond 544 }
545 */ 545 else
546 546 {
547/*============================================================================* 547 q = p;
548 * Global * 548 ++p;
549 *============================================================================*/ 549 }
550 550 }
551/*============================================================================* 551 else
552 * API * 552 {
553 *============================================================================*/ 553 q = p;
554 554 ++p;
555EAPI Eina_Bool 555 }
556eina_file_dir_list(const char *dir, 556 }
557 Eina_Bool recursive, 557
558 Eina_File_Dir_List_Cb cb, 558 if (length)
559 void *data) 559 *length = len;
560{ 560
561 WIN32_FIND_DATA file; 561 return result;
562 HANDLE h; 562}
563 char *new_dir; 563
564 564
565 EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE); 565/**
566 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE); 566 * @endcond
567 EINA_SAFETY_ON_TRUE_RETURN_VAL(dir[0] == '\0', EINA_FALSE); 567 */
568 568
569 if (!_eina_file_win32_is_dir(dir)) 569/*============================================================================*
570 return EINA_FALSE; 570 * Global *
571 571 *============================================================================*/
572 new_dir = _eina_file_win32_dir_new(dir); 572
573 if (!new_dir) 573Eina_Bool
574 return EINA_FALSE; 574eina_file_init(void)
575 575{
576 h = _eina_file_win32_first_file(new_dir, &file); 576 _eina_file_log_dom = eina_log_domain_register("eina_file",
577 577 EINA_LOG_COLOR_DEFAULT);
578 if (h == INVALID_HANDLE_VALUE) 578 if (_eina_file_log_dom < 0)
579 return EINA_FALSE; 579 {
580 580 EINA_LOG_ERR("Could not register log domain: eina_file");
581 do 581 return EINA_FALSE;
582 { 582 }
583 char *filename; 583
584 584 _eina_file_cache = eina_hash_string_djb2_new(NULL);
585# ifdef UNICODE 585 if (!_eina_file_cache)
586 filename = evil_wchar_to_char(file.cFileName); 586 {
587# else 587 ERR("Could not create cache.");
588 filename = file.cFileName; 588 eina_log_domain_unregister(_eina_file_log_dom);
589# endif /* ! UNICODE */ 589 _eina_file_log_dom = -1;
590 if (!strcmp(filename, ".") || !strcmp(filename, "..")) 590 return EINA_FALSE;
591 continue; 591 }
592 592
593 cb(filename, dir, data); 593 eina_lock_new(&_eina_file_lock_cache);
594 594
595 if (recursive == EINA_TRUE) 595 return EINA_TRUE;
596 { 596}
597 char *path; 597
598 598Eina_Bool
599 path = alloca(strlen(dir) + strlen(filename) + 2); 599eina_file_shutdown(void)
600 strcpy(path, dir); 600{
601 strcat(path, "/"); 601 if (eina_hash_population(_eina_file_cache) > 0)
602 strcat(path, filename); 602 {
603 603 Eina_Iterator *it;
604 if (!(file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 604 const char *key;
605 continue; 605
606 606 it = eina_hash_iterator_key_new(_eina_file_cache);
607 eina_file_dir_list(path, recursive, cb, data); 607 EINA_ITERATOR_FOREACH(it, key)
608 } 608 ERR("File [%s] still open !", key);
609 609 eina_iterator_free(it);
610# ifdef UNICODE 610 }
611 free(filename); 611
612# endif /* UNICODE */ 612 eina_hash_free(_eina_file_cache);
613 613
614 } while (FindNextFile(h, &file)); 614 eina_lock_free(&_eina_file_lock_cache);
615 FindClose(h); 615
616 616 eina_log_domain_unregister(_eina_file_log_dom);
617 return EINA_TRUE; 617 _eina_file_log_dom = -1;
618} 618 return EINA_TRUE;
619 619}
620EAPI Eina_Array * 620
621eina_file_split(char *path) 621/*============================================================================*
622{ 622 * API *
623 Eina_Array *ea; 623 *============================================================================*/
624 char *current; 624
625 size_t length; 625
626 626EAPI char *
627 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); 627eina_file_path_sanitize(const char *path)
628 628{
629 ea = eina_array_new(16); 629 char *result = NULL;
630 630 size_t len;
631 if (!ea) 631
632 return NULL; 632 if (!path) return NULL;
633 633
634 for (current = strchr(path, '\\'); 634 len = strlen(path);
635 current; 635 if (len < 3) return NULL;
636 path = current + 1, current = strchr(path, '\\')) 636
637 { 637 if (!evil_path_is_absolute(path))
638 length = current - path; 638 {
639 639 DWORD l;
640 if (length <= 0) 640
641 continue; 641 l = GetCurrentDirectory(0, NULL);
642 642 if (l > 0)
643 eina_array_push(ea, path); 643 {
644 *current = '\0'; 644 char *cwd;
645 } 645 DWORD l2;
646 646
647 if (*path != '\0') 647 cwd = alloca(sizeof(char) * (l + 1));
648 eina_array_push(ea, path); 648 l2 = GetCurrentDirectory(l + 1, cwd);
649 649 if (l2 == l)
650 return ea; 650 {
651} 651 char *tmp;
652 652
653EAPI Eina_Iterator * 653 len += l + 2;
654eina_file_ls(const char *dir) 654 tmp = alloca(sizeof (char) * len);
655{ 655 snprintf(tmp, len, "%s/%s", cwd, path);
656 Eina_File_Iterator *it; 656 tmp[len - 1] = '\0';
657 char *new_dir; 657 result = tmp;
658 size_t length; 658 }
659 659 }
660 if (!dir || !*dir) 660 }
661 return NULL; 661
662 662 return _eina_file_win32_escape(result ? result : path, &len);
663 if (!_eina_file_win32_is_dir(dir)) 663}
664 return NULL; 664
665 665EAPI Eina_Bool
666 length = strlen(dir); 666eina_file_dir_list(const char *dir,
667 667 Eina_Bool recursive,
668 it = calloc(1, sizeof (Eina_File_Iterator) + length); 668 Eina_File_Dir_List_Cb cb,
669 if (!it) 669 void *data)
670 return NULL; 670{
671 671 WIN32_FIND_DATA file;
672 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); 672 HANDLE h;
673 673 char *new_dir;
674 new_dir = _eina_file_win32_dir_new(dir); 674
675 if (!new_dir) 675 EINA_SAFETY_ON_NULL_RETURN_VAL(cb, EINA_FALSE);
676 goto free_it; 676 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, EINA_FALSE);
677 677 EINA_SAFETY_ON_TRUE_RETURN_VAL(dir[0] == '\0', EINA_FALSE);
678 it->handle = _eina_file_win32_first_file(new_dir, &it->data); 678
679 free(new_dir); 679 if (!_eina_file_win32_is_dir(dir))
680 if (it->handle == INVALID_HANDLE_VALUE) 680 return EINA_FALSE;
681 goto free_it; 681
682 682 new_dir = _eina_file_win32_dir_new(dir);
683 memcpy(it->dir, dir, length + 1); 683 if (!new_dir)
684 if (dir[length - 1] != '\\') 684 return EINA_FALSE;
685 it->length = length; 685
686 else 686 h = _eina_file_win32_first_file(new_dir, &file);
687 it->length = length - 1; 687
688 _eina_file_win32_backslash_change(it->dir); 688 if (h == INVALID_HANDLE_VALUE)
689 689 return EINA_FALSE;
690 it->iterator.version = EINA_ITERATOR_VERSION; 690
691 it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_ls_iterator_next); 691 do
692 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_ls_iterator_container); 692 {
693 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_ls_iterator_free); 693 char *filename;
694 694
695 return &it->iterator; 695# ifdef UNICODE
696 696 filename = evil_wchar_to_char(file.cFileName);
697 free_it: 697# else
698 free(it); 698 filename = file.cFileName;
699 699# endif /* ! UNICODE */
700 return NULL; 700 if (!strcmp(filename, ".") || !strcmp(filename, ".."))
701} 701 continue;
702 702
703EAPI Eina_Iterator * 703 cb(filename, dir, data);
704eina_file_direct_ls(const char *dir) 704
705{ 705 if (recursive == EINA_TRUE)
706 Eina_File_Direct_Iterator *it; 706 {
707 char *new_dir; 707 char *path;
708 size_t length; 708
709 709 path = alloca(strlen(dir) + strlen(filename) + 2);
710 if (!dir || !*dir) 710 strcpy(path, dir);
711 return NULL; 711 strcat(path, "/");
712 712 strcat(path, filename);
713 length = strlen(dir); 713
714 714 if (!(file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
715 if (length + 12 + 2 >= MAX_PATH) 715 continue;
716 return NULL; 716
717 717 eina_file_dir_list(path, recursive, cb, data);
718 it = calloc(1, sizeof(Eina_File_Direct_Iterator) + length); 718 }
719 if (!it) 719
720 return NULL; 720# ifdef UNICODE
721 721 free(filename);
722 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); 722# endif /* UNICODE */
723 723
724 new_dir = _eina_file_win32_dir_new(dir); 724 } while (FindNextFile(h, &file));
725 if (!new_dir) 725 FindClose(h);
726 goto free_it; 726
727 727 return EINA_TRUE;
728 it->handle = _eina_file_win32_first_file(new_dir, &it->data); 728}
729 free(new_dir); 729
730 if (it->handle == INVALID_HANDLE_VALUE) 730EAPI Eina_Array *
731 goto free_it; 731eina_file_split(char *path)
732 732{
733 memcpy(it->dir, dir, length + 1); 733 Eina_Array *ea;
734 it->length = length; 734 char *current;
735 _eina_file_win32_backslash_change(it->dir); 735 size_t length;
736 736
737 memcpy(it->info.path, dir, length); 737 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
738 if (dir[length - 1] == '\\') 738
739 it->info.name_start = length; 739 ea = eina_array_new(16);
740 else 740
741 { 741 if (!ea)
742 it->info.path[length] = '\\'; 742 return NULL;
743 it->info.name_start = length + 1; 743
744 } 744 for (current = strchr(path, '\\');
745 _eina_file_win32_backslash_change(it->info.path); 745 current;
746 746 path = current + 1, current = strchr(path, '\\'))
747 it->iterator.version = EINA_ITERATOR_VERSION; 747 {
748 it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_direct_ls_iterator_next); 748 length = current - path;
749 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_direct_ls_iterator_container); 749
750 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_direct_ls_iterator_free); 750 if (length <= 0)
751 751 continue;
752 return &it->iterator; 752
753 753 eina_array_push(ea, path);
754 free_it: 754 *current = '\0';
755 free(it); 755 }
756 756
757 return NULL; 757 if (*path != '\0')
758} 758 eina_array_push(ea, path);
759 759
760EAPI Eina_Iterator * 760 return ea;
761eina_file_stat_ls(const char *dir) 761}
762{ 762
763 return eina_file_direct_ls(dir); 763EAPI Eina_Iterator *
764} 764eina_file_ls(const char *dir)
765 765{
766EAPI Eina_File * 766 Eina_File_Iterator *it;
767eina_file_open(const char *filename, Eina_Bool shared) 767 char *new_dir;
768{ 768 size_t length;
769 Eina_File *file; 769
770 Eina_File *n; 770 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
771 HANDLE handle; 771
772 HANDLE fm; 772 if (!dir || !*dir)
773 WIN32_FILE_ATTRIBUTE_DATA fad; 773 return NULL;
774 ULARGE_INTEGER length; 774
775 ULARGE_INTEGER mtime; 775 if (!_eina_file_win32_is_dir(dir))
776 Eina_Bool create = EINA_FALSE; 776 return NULL;
777 777
778 /* FIXME: always open absolute path (need to fix filename according to current 778 length = strlen(dir);
779 directory) */ 779
780 780 it = calloc(1, sizeof (Eina_File_Iterator) + length);
781 /* FIXME: how to emulate shm_open ? Just OpenFileMapping ? */ 781 if (!it)
782#if 0 782 return NULL;
783 if (shared) 783
784 handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 784 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
785 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, 785
786 NULL); 786 new_dir = _eina_file_win32_dir_new(dir);
787 else 787 if (!new_dir)
788#endif 788 goto free_it;
789 handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 789
790 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, 790 it->handle = _eina_file_win32_first_file(new_dir, &it->data);
791 NULL); 791 free(new_dir);
792 792 if (it->handle == INVALID_HANDLE_VALUE)
793 if (handle == INVALID_HANDLE_VALUE) 793 goto free_it;
794 return NULL; 794
795 795 memcpy(it->dir, dir, length + 1);
796 fm = CreateFileMapping(handle, NULL, PAGE_READONLY, 0, 0, NULL); 796 if (dir[length - 1] != '\\')
797 if (!fm) 797 it->length = length;
798 goto close_handle; 798 else
799 799 it->length = length - 1;
800 if (!GetFileAttributesEx(filename, GetFileExInfoStandard, &fad)) 800 _eina_file_win32_backslash_change(it->dir);
801 goto close_fm; 801
802 802 it->iterator.version = EINA_ITERATOR_VERSION;
803 length.u.LowPart = fad.nFileSizeLow; 803 it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_ls_iterator_next);
804 length.u.HighPart = fad.nFileSizeHigh; 804 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_ls_iterator_container);
805 mtime.u.LowPart = fad.ftLastWriteTime.dwLowDateTime; 805 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_ls_iterator_free);
806 mtime.u.HighPart = fad.ftLastWriteTime.dwHighDateTime; 806
807 807 return &it->iterator;
808 file = eina_hash_find(_eina_file_cache, filename); 808
809 if (file && 809 free_it:
810 (file->mtime != mtime.QuadPart || file->length != length.QuadPart)) 810 free(it);
811 { 811
812 create = EINA_TRUE; 812 return NULL;
813 813}
814 if (file->refcount == 0) 814
815 { 815EAPI Eina_Iterator *
816 _eina_file_cache_lru = eina_list_prepend(_eina_file_cache_lru, file); 816eina_file_direct_ls(const char *dir)
817 eina_hash_del(_eina_file_cache, file->filename, file); 817{
818 818 Eina_File_Direct_Iterator *it;
819 file = NULL; 819 char *new_dir;
820 } 820 size_t length;
821 else if (!file->delete_me) 821
822 { 822 EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL);
823 file->delete_me = EINA_TRUE; 823
824 _eina_file_cache_delete = eina_list_prepend(_eina_file_cache_delete, file); 824 if (!dir || !*dir)
825 } 825 return NULL;
826 } 826
827 827 length = strlen(dir);
828 if (!file || create) 828
829 { 829 if (length + 12 + 2 >= MAX_PATH)
830 n = calloc(1, sizeof (Eina_File)); 830 return NULL;
831 if (!n) 831
832 goto close_fm; 832 it = calloc(1, sizeof(Eina_File_Direct_Iterator) + length);
833 833 if (!it)
834 n->filename = eina_stringshare_add(filename); 834 return NULL;
835 n->map = eina_hash_new(EINA_KEY_LENGTH(_eina_file_map_key_length), 835
836 EINA_KEY_CMP(_eina_file_map_key_cmp), 836 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
837 EINA_KEY_HASH(_eina_file_map_key_hash), 837
838 EINA_FREE_CB(_eina_file_map_close), 838 new_dir = _eina_file_win32_dir_new(dir);
839 3); 839 if (!new_dir)
840 n->rmap = eina_hash_pointer_new(NULL); 840 goto free_it;
841 n->global_map = MAP_FAILED; 841
842 n->length = length.QuadPart; 842 it->handle = _eina_file_win32_first_file(new_dir, &it->data);
843 n->mtime = mtime.QuadPart; 843 free(new_dir);
844 n->refcount = 0; 844 if (it->handle == INVALID_HANDLE_VALUE)
845 n->handle = handle; 845 goto free_it;
846 n->fm = fm; 846
847 n->shared = shared; 847 memcpy(it->dir, dir, length + 1);
848 n->delete_me = EINA_FALSE; 848 it->length = length;
849 849 _eina_file_win32_backslash_change(it->dir);
850 eina_hash_set(_eina_file_cache, filename, n); 850
851 } 851 memcpy(it->info.path, dir, length);
852 else 852 if (dir[length - 1] == '\\')
853 { 853 it->info.name_start = length;
854 CloseHandle(fm); 854 else
855 CloseHandle(handle); 855 {
856 856 it->info.path[length] = '\\';
857 n = file; 857 it->info.name_start = length + 1;
858 858 }
859 if (n->refcount == 0) 859 _eina_file_win32_backslash_change(it->info.path);
860 _eina_file_cache_lru = eina_list_remove(_eina_file_cache_lru, n); 860
861 } 861 it->iterator.version = EINA_ITERATOR_VERSION;
862 862 it->iterator.next = FUNC_ITERATOR_NEXT(_eina_file_win32_direct_ls_iterator_next);
863 n->refcount++; 863 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_file_win32_direct_ls_iterator_container);
864 864 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_win32_direct_ls_iterator_free);
865 return n; 865
866 866 return &it->iterator;
867 close_fm: 867
868 CloseHandle(fm); 868 free_it:
869 close_handle: 869 free(it);
870 CloseHandle(handle); 870
871 871 return NULL;
872 return NULL; 872}
873} 873
874 874EAPI Eina_Iterator *
875EAPI void 875eina_file_stat_ls(const char *dir)
876eina_file_close(Eina_File *file) 876{
877{ 877 return eina_file_direct_ls(dir);
878 file->refcount--; 878}
879 879
880 if (file->refcount != 0) return ; 880EAPI Eina_File *
881 881eina_file_open(const char *path, Eina_Bool shared)
882 if (file->delete_me) 882{
883 { 883 Eina_File *file;
884 _eina_file_cache_delete = eina_list_remove(_eina_file_cache_delete, file); 884 Eina_File *n;
885 _eina_file_real_close(file); 885 char *filename;
886 } 886 HANDLE handle;
887 else 887 HANDLE fm;
888 { 888 WIN32_FILE_ATTRIBUTE_DATA fad;
889 _eina_file_cache_lru = eina_list_prepend(_eina_file_cache_lru, file); 889 ULARGE_INTEGER length;
890 } 890 ULARGE_INTEGER mtime;
891} 891
892 892 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
893EAPI size_t 893
894eina_file_size_get(Eina_File *file) 894 filename = eina_file_path_sanitize(path);
895{ 895 if (!filename) return NULL;
896 return file->length; 896
897} 897 /* FIXME: how to emulate shm_open ? Just OpenFileMapping ? */
898 898#if 0
899EAPI time_t 899 if (shared)
900eina_file_mtime_get(Eina_File *file) 900 handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
901{ 901 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY,
902 return file->mtime; 902 NULL);
903} 903 else
904 904#endif
905EAPI const char * 905 handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
906eina_file_filename_get(Eina_File *file) 906 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY,
907{ 907 NULL);
908 return file->filename; 908
909} 909 if (handle == INVALID_HANDLE_VALUE)
910 910 return NULL;
911EAPI void * 911
912eina_file_map_all(Eina_File *file, Eina_File_Populate rule __UNUSED__) 912 fm = CreateFileMapping(handle, NULL, PAGE_READONLY, 0, 0, NULL);
913{ 913 if (!fm)
914 if (file->global_map == MAP_FAILED) 914 goto close_handle;
915 { 915
916 void *data; 916 if (!GetFileAttributesEx(filename, GetFileExInfoStandard, &fad))
917 917 goto close_fm;
918 data = MapViewOfFile(file->fm, FILE_MAP_READ, 918
919 0, 0, file->length); 919 length.u.LowPart = fad.nFileSizeLow;
920 if (!data) 920 length.u.HighPart = fad.nFileSizeHigh;
921 file->global_map = MAP_FAILED; 921 mtime.u.LowPart = fad.ftLastWriteTime.dwLowDateTime;
922 else 922 mtime.u.HighPart = fad.ftLastWriteTime.dwHighDateTime;
923 file->global_map = data; 923
924 } 924 eina_lock_take(&_eina_file_lock_cache);
925 925
926 if (file->global_map != MAP_FAILED) 926 file = eina_hash_find(_eina_file_cache, filename);
927 { 927 if (file &&
928 file->global_refcount++; 928 (file->mtime != mtime.QuadPart || file->length != length.QuadPart))
929 return file->global_map; 929 {
930 } 930 file->delete_me = EINA_TRUE;
931 931 eina_hash_del(_eina_file_cache, file->filename, file);
932 return NULL; 932 _eina_file_real_close(file);
933} 933 file = NULL;
934 934 }
935EAPI void * 935
936eina_file_map_new(Eina_File *file, Eina_File_Populate rule, 936 if (!file)
937 unsigned long int offset, unsigned long int length) 937 {
938{ 938 n = malloc(sizeof (Eina_File) + strlen(filename) + 1);
939 Eina_File_Map *map; 939 if (!n)
940 unsigned long int key[2]; 940 {
941 941 eina_lock_release(&_eina_file_lock_cache);
942 if (offset > file->length) 942 goto close_fm;
943 return NULL; 943 }
944 if (offset + length > file->length) 944
945 return NULL; 945 n->filename = (char*) (n + 1);
946 946 strcpy((char*) n->filename, filename);
947 if (offset == 0 && length == file->length) 947 n->map = eina_hash_new(EINA_KEY_LENGTH(_eina_file_map_key_length),
948 return eina_file_map_all(file, rule); 948 EINA_KEY_CMP(_eina_file_map_key_cmp),
949 949 EINA_KEY_HASH(_eina_file_map_key_hash),
950 key[0] = offset; 950 EINA_FREE_CB(_eina_file_map_close),
951 key[1] = length; 951 3);
952 952 n->rmap = eina_hash_pointer_new(NULL);
953 map = eina_hash_find(file->map, &key); 953 n->global_map = MAP_FAILED;
954 if (!map) 954 n->global_refcount = 0;
955 { 955 n->length = length.QuadPart;
956 void *data; 956 n->mtime = mtime.QuadPart;
957 957 n->refcount = 0;
958 map = malloc(sizeof (Eina_File_Map)); 958 n->handle = handle;
959 if (!map) return NULL; 959 n->fm = fm;
960 960 n->shared = shared;
961 data = MapViewOfFile(file->fm, FILE_MAP_READ, 961 n->delete_me = EINA_FALSE;
962 offset & 0xffff0000, 962 eina_lock_new(&n->lock);
963 offset & 0x0000ffff, 963 eina_hash_direct_add(_eina_file_cache, n->filename, n);
964 length); 964 }
965 if (!data) 965 else
966 map->map = MAP_FAILED; 966 {
967 else 967 CloseHandle(fm);
968 map->map = data; 968 CloseHandle(handle);
969 969
970 map->offset = offset; 970 n = file;
971 map->length = length; 971 }
972 map->refcount = 0; 972 eina_lock_take(&n->lock);
973 973 n->refcount++;
974 if (map->map == MAP_FAILED) 974 eina_lock_release(&n->lock);
975 { 975
976 free(map); 976 eina_lock_release(&_eina_file_lock_cache);
977 return NULL; 977
978 } 978 free(filename);
979 979
980 eina_hash_add(file->map, &key, map); 980 return n;
981 eina_hash_direct_add(file->rmap, map->map, map); 981
982 } 982 close_fm:
983 983 CloseHandle(fm);
984 map->refcount++; 984 close_handle:
985 985 CloseHandle(handle);
986 return map->map; 986
987} 987 return NULL;
988 988}
989EAPI void 989
990eina_file_map_free(Eina_File *file, void *map) 990EAPI void
991{ 991eina_file_close(Eina_File *file)
992 if (file->global_map == map) 992{
993 { 993 EINA_SAFETY_ON_NULL_RETURN(file);
994 file->global_refcount--; 994
995 995 eina_lock_take(&file->lock);
996 if (file->global_refcount > 0) return ; 996 file->refcount--;
997 997 eina_lock_release(&file->lock);
998 /* FIXME: are we sure that file->global_map != MAP_FAILED ? */ 998
999 if (file->global_map != MAP_FAILED) 999 if (file->refcount != 0) return ;
1000 UnmapViewOfFile(file->global_map); 1000 eina_lock_take(&_eina_file_lock_cache);
1001 file->global_map = MAP_FAILED; 1001
1002 } 1002 eina_hash_del(_eina_file_cache, file->filename, file);
1003 else 1003 _eina_file_real_close(file);
1004 { 1004
1005 Eina_File_Map *em; 1005 eina_lock_release(&_eina_file_lock_cache);
1006 unsigned long int key[2]; 1006}
1007 1007
1008 em = eina_hash_find(file->rmap, &map); 1008EAPI size_t
1009 if (!em) return ; 1009eina_file_size_get(Eina_File *file)
1010 1010{
1011 em->refcount--; 1011 EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
1012 1012 return file->length;
1013 if (em->refcount > 0) return ; 1013}
1014 1014
1015 key[0] = em->offset; 1015EAPI time_t
1016 key[1] = em->length; 1016eina_file_mtime_get(Eina_File *file)
1017 1017{
1018 eina_hash_del(file->rmap, &map, em); 1018 EINA_SAFETY_ON_NULL_RETURN_VAL(file, 0);
1019 eina_hash_del(file->map, &key, em); 1019 return file->mtime;
1020 } 1020}
1021} 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_inlist.c b/libraries/eina/src/lib/eina_inlist.c
index 75a2cc1..c80f87b 100644
--- a/libraries/eina/src/lib/eina_inlist.c
+++ b/libraries/eina/src/lib/eina_inlist.c
@@ -430,6 +430,8 @@ eina_inlist_find(Eina_Inlist *list, Eina_Inlist *item)
430{ 430{
431 Eina_Inlist *l; 431 Eina_Inlist *l;
432 432
433 EINA_SAFETY_ON_NULL_RETURN_VAL(item, NULL);
434
433 for (l = list; l; l = l->next) { 435 for (l = list; l; l = l->next) {
434 if (l == item) 436 if (l == item)
435 return item; 437 return item;
@@ -559,6 +561,9 @@ eina_inlist_sorted_insert(Eina_Inlist *list,
559 int cur = 0; 561 int cur = 0;
560 int count; 562 int count;
561 563
564 EINA_SAFETY_ON_NULL_RETURN_VAL(item, list);
565 EINA_SAFETY_ON_NULL_RETURN_VAL(func, list);
566
562 if (!list) return eina_inlist_append(NULL, item); 567 if (!list) return eina_inlist_append(NULL, item);
563 568
564 if (!list->next) 569 if (!list->next)
diff --git a/libraries/eina/src/lib/eina_list.c b/libraries/eina/src/lib/eina_list.c
index d45cffd..c85855f 100644
--- a/libraries/eina/src/lib/eina_list.c
+++ b/libraries/eina/src/lib/eina_list.c
@@ -1026,7 +1026,7 @@ eina_list_clone(const Eina_List *list)
1026} 1026}
1027 1027
1028EAPI Eina_List * 1028EAPI Eina_List *
1029eina_list_sort(Eina_List *list, unsigned int size, Eina_Compare_Cb func) 1029eina_list_sort(Eina_List *list, unsigned int limit, Eina_Compare_Cb func)
1030{ 1030{
1031 unsigned int i = 0; 1031 unsigned int i = 0;
1032 unsigned int n = 0; 1032 unsigned int n = 0;
@@ -1040,14 +1040,14 @@ eina_list_sort(Eina_List *list, unsigned int size, Eina_Compare_Cb func)
1040 1040
1041 EINA_MAGIC_CHECK_LIST(list, NULL); 1041 EINA_MAGIC_CHECK_LIST(list, NULL);
1042 1042
1043 /* if the caller specified an invalid size, sort the whole list */ 1043 /* if the caller specified an invalid limit, sort the whole list */
1044 if ((size == 0) || 1044 if ((limit == 0) ||
1045 (size > list->accounting->count)) 1045 (limit > list->accounting->count))
1046 size = list->accounting->count; 1046 limit = list->accounting->count;
1047 1047
1048 if (size != list->accounting->count) 1048 if (limit != list->accounting->count)
1049 { 1049 {
1050 unsort = eina_list_nth_list(list, size); 1050 unsort = eina_list_nth_list(list, limit);
1051 if (unsort) 1051 if (unsort)
1052 unsort->prev->next = NULL; 1052 unsort->prev->next = NULL;
1053 } 1053 }
@@ -1172,6 +1172,7 @@ eina_list_split_list(Eina_List *list, Eina_List *relative, Eina_List **right)
1172 next->prev = NULL; 1172 next->prev = NULL;
1173 next->accounting = _eina_list_mempool_accounting_new(next); 1173 next->accounting = _eina_list_mempool_accounting_new(next);
1174 next->accounting->last = list->accounting->last; 1174 next->accounting->last = list->accounting->last;
1175 next->accounting->count = 0;
1175 *right = next; 1176 *right = next;
1176 1177
1177 itr = next; 1178 itr = next;
diff --git a/libraries/eina/src/lib/eina_magic.c b/libraries/eina/src/lib/eina_magic.c
index d1f71cc..a42db2d 100644
--- a/libraries/eina/src/lib/eina_magic.c
+++ b/libraries/eina/src/lib/eina_magic.c
@@ -102,13 +102,8 @@ _eina_magic_strings_alloc(void)
102 tmp = realloc(_eina_magic_strings, sizeof(Eina_Magic_String) * size); 102 tmp = realloc(_eina_magic_strings, sizeof(Eina_Magic_String) * size);
103 if (!tmp) 103 if (!tmp)
104 { 104 {
105#ifdef _WIN32
106 ERR("could not realloc magic_strings from %Iu to %Iu buckets.",
107 _eina_magic_strings_allocated, size);
108#else
109 ERR("could not realloc magic_strings from %zu to %zu buckets.", 105 ERR("could not realloc magic_strings from %zu to %zu buckets.",
110 _eina_magic_strings_allocated, size); 106 _eina_magic_strings_allocated, size);
111#endif
112 return NULL; 107 return NULL;
113 } 108 }
114 109
diff --git a/libraries/eina/src/lib/eina_main.c b/libraries/eina/src/lib/eina_main.c
index 79f8a36..f233929 100644
--- a/libraries/eina/src/lib/eina_main.c
+++ b/libraries/eina/src/lib/eina_main.c
@@ -69,6 +69,7 @@
69#include "eina_inlist.h" 69#include "eina_inlist.h"
70#include "eina_inarray.h" 70#include "eina_inarray.h"
71#include "eina_value.h" 71#include "eina_value.h"
72#include "eina_model.h"
72 73
73/*============================================================================* 74/*============================================================================*
74* Local * 75* Local *
@@ -153,6 +154,7 @@ EAPI Eina_Inlist *_eina_tracking = NULL;
153 S(file); 154 S(file);
154 S(prefix); 155 S(prefix);
155 S(value); 156 S(value);
157 S(model);
156#undef S 158#undef S
157 159
158struct eina_desc_setup 160struct eina_desc_setup
@@ -189,7 +191,8 @@ static const struct eina_desc_setup _eina_desc_setup[] = {
189 S(simple_xml), 191 S(simple_xml),
190 S(file), 192 S(file),
191 S(prefix), 193 S(prefix),
192 S(value) 194 S(value),
195 S(model)
193#undef S 196#undef S
194}; 197};
195static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) / 198static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) /
diff --git a/libraries/eina/src/lib/eina_matrixsparse.c b/libraries/eina/src/lib/eina_matrixsparse.c
index 3ac0439..59cd66b 100644
--- a/libraries/eina/src/lib/eina_matrixsparse.c
+++ b/libraries/eina/src/lib/eina_matrixsparse.c
@@ -1078,6 +1078,8 @@ eina_matrixsparse_size_set(Eina_Matrixsparse *m,
1078 1078
1079 r = r->next; 1079 r = r->next;
1080 _eina_matrixsparse_row_free(r_aux, free_func, user_data); 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;
1081 } 1083 }
1082 else 1084 else
1083 { 1085 {
diff --git a/libraries/eina/src/lib/eina_module.c b/libraries/eina/src/lib/eina_module.c
index 26df980..f4f3242 100644
--- a/libraries/eina/src/lib/eina_module.c
+++ b/libraries/eina/src/lib/eina_module.c
@@ -58,6 +58,10 @@ void *alloca (size_t);
58# include <Escape.h> 58# include <Escape.h>
59#endif 59#endif
60 60
61#ifdef HAVE_EXOTIC_H
62# include <Exotic.h>
63#endif
64
61#include "eina_config.h" 65#include "eina_config.h"
62#include "eina_private.h" 66#include "eina_private.h"
63#include "eina_error.h" 67#include "eina_error.h"
diff --git a/libraries/eina/src/lib/eina_prefix.c b/libraries/eina/src/lib/eina_prefix.c
index 5b4b0c0..2322311 100644
--- a/libraries/eina/src/lib/eina_prefix.c
+++ b/libraries/eina/src/lib/eina_prefix.c
@@ -30,15 +30,15 @@
30#endif 30#endif
31#ifdef HAVE_ALLOCA_H 31#ifdef HAVE_ALLOCA_H
32# include <alloca.h> 32# include <alloca.h>
33#elif defined __GNUC__ 33#elif !defined alloca
34# define alloca __builtin_alloca 34# ifdef __GNUC__
35#elif defined _AIX 35# define alloca __builtin_alloca
36# define alloca __alloca 36# elif defined _AIX
37#elif defined _MSC_VER 37# define alloca __alloca
38# include <malloc.h> 38# elif defined _MSC_VER
39# define alloca _alloca 39# include <malloc.h>
40#else 40# define alloca _alloca
41# ifndef HAVE_ALLOCA 41# elif !defined HAVE_ALLOCA
42# ifdef __cplusplus 42# ifdef __cplusplus
43extern "C" 43extern "C"
44# endif 44# endif
@@ -237,7 +237,7 @@ _try_argv(Eina_Prefix *pfx, const char *argv0)
237 DBG("Try argv0 = %s", argv0); 237 DBG("Try argv0 = %s", argv0);
238 /* 1. is argv0 abs path? */ 238 /* 1. is argv0 abs path? */
239#ifdef _WIN32 239#ifdef _WIN32
240 if (argv0[0] && (argv0[1] == ':')) 240 if (evil_path_is_absolute(argv0))
241#else 241#else
242 if (argv0[0] == DSEP_C) 242 if (argv0[0] == DSEP_C)
243#endif 243#endif
@@ -533,7 +533,7 @@ eina_prefix_new(const char *argv0, void *symbol, const char *envprefix,
533 { 533 {
534 DBG("Dlinfo dli_fname = %s", info_dl.dli_fname); 534 DBG("Dlinfo dli_fname = %s", info_dl.dli_fname);
535# ifdef _WIN32 535# ifdef _WIN32
536 if (info_dl.dli_fname[0] && (info_dl.dli_fname[1] == ':')) 536 if (evil_path_is_absolute(info_dl.dli_fname))
537# else 537# else
538 if (info_dl.dli_fname[0] == DSEP_C) 538 if (info_dl.dli_fname[0] == DSEP_C)
539# endif 539# endif
diff --git a/libraries/eina/src/lib/eina_private.h b/libraries/eina/src/lib/eina_private.h
index e31ab47..49df565 100644
--- a/libraries/eina/src/lib/eina_private.h
+++ b/libraries/eina/src/lib/eina_private.h
@@ -95,6 +95,8 @@
95#define EINA_MAGIC_INARRAY_ITERATOR 0x98761271 95#define EINA_MAGIC_INARRAY_ITERATOR 0x98761271
96#define EINA_MAGIC_INARRAY_ACCESSOR 0x98761272 96#define EINA_MAGIC_INARRAY_ACCESSOR 0x98761272
97 97
98#define EINA_MAGIC_MODEL 0x98761280
99
98#define EINA_MAGIC_CLASS 0x9877CB30 100#define EINA_MAGIC_CLASS 0x9877CB30
99 101
100/* undef the following, we want out version */ 102/* undef the following, we want out version */
diff --git a/libraries/eina/src/lib/eina_rbtree.c b/libraries/eina/src/lib/eina_rbtree.c
index 5f1232c..a9d777a 100644
--- a/libraries/eina/src/lib/eina_rbtree.c
+++ b/libraries/eina/src/lib/eina_rbtree.c
@@ -1,5 +1,6 @@
1/* EINA - EFL data type library 1/* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric Bail 2 * Copyright (C) 2008 Cedric Bail
3 * Copyright (C) 2011 Alexandre Becoulet
3 * 4 *
4 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public 6 * modify it under the terms of the GNU Lesser General Public
@@ -23,6 +24,7 @@
23#include <stdlib.h> 24#include <stdlib.h>
24#include <stdio.h> 25#include <stdio.h>
25#include <string.h> 26#include <string.h>
27#include <stdint.h>
26 28
27#include "eina_config.h" 29#include "eina_config.h"
28#include "eina_private.h" 30#include "eina_private.h"
@@ -244,9 +246,9 @@ static inline Eina_Rbtree *
244_eina_rbtree_inline_single_rotation(Eina_Rbtree *node, 246_eina_rbtree_inline_single_rotation(Eina_Rbtree *node,
245 Eina_Rbtree_Direction dir) 247 Eina_Rbtree_Direction dir)
246{ 248{
247 Eina_Rbtree *save = node->son[!dir]; 249 Eina_Rbtree *save = node->son[dir ^ 1];
248 250
249 node->son[!dir] = save->son[dir]; 251 node->son[dir ^ 1] = save->son[dir];
250 save->son[dir] = node; 252 save->son[dir] = node;
251 253
252 node->color = EINA_RBTREE_RED; 254 node->color = EINA_RBTREE_RED;
@@ -259,7 +261,7 @@ static inline Eina_Rbtree *
259_eina_rbtree_inline_double_rotation(Eina_Rbtree *node, 261_eina_rbtree_inline_double_rotation(Eina_Rbtree *node,
260 Eina_Rbtree_Direction dir) 262 Eina_Rbtree_Direction dir)
261{ 263{
262 node->son[!dir] = _eina_rbtree_inline_single_rotation(node->son[!dir], !dir); 264 node->son[dir ^ 1] = _eina_rbtree_inline_single_rotation(node->son[dir ^ 1], dir ^ 1);
263 return _eina_rbtree_inline_single_rotation(node, dir); 265 return _eina_rbtree_inline_single_rotation(node, dir);
264} 266}
265 267
@@ -277,87 +279,64 @@ eina_rbtree_inline_insert(Eina_Rbtree *root,
277 Eina_Rbtree_Cmp_Node_Cb cmp, 279 Eina_Rbtree_Cmp_Node_Cb cmp,
278 const void *data) 280 const void *data)
279{ 281{
280 Eina_Rbtree head; 282 Eina_Rbtree **r = &root;
281 Eina_Rbtree *g, *t; /* Grandparent & parent */ 283 Eina_Rbtree *q = root;
282 Eina_Rbtree *p, *q; /* Iterator & parent */ 284 uintptr_t stack[48];
283 /* WARNING: 285 unsigned int s = 0;
284 Compiler is not able to understand the underlying algorithm and don't know that
285 first top node is always black, so it will never use last before running the loop
286 one time.
287 */
288 Eina_Rbtree_Direction dir, last;
289 286
290 EINA_SAFETY_ON_NULL_RETURN_VAL(node, root); 287 EINA_SAFETY_ON_NULL_RETURN_VAL(node, root);
291 EINA_SAFETY_ON_NULL_RETURN_VAL( cmp, root); 288 EINA_SAFETY_ON_NULL_RETURN_VAL( cmp, root);
292 289
293 if (!node) 290 /* Find insertion leaf */
294 return root; 291 while (q != NULL)
295 292 {
296 _eina_rbtree_node_init(node); 293 Eina_Rbtree_Direction dir = cmp(q, node, (void *)data);
297
298 if (!root)
299 {
300 root = node;
301 goto end_add;
302 }
303
304 memset(&head, 0, sizeof (Eina_Rbtree));
305 last = dir = EINA_RBTREE_LEFT;
306
307 /* Set up helpers */
308 t = &head;
309 g = p = NULL;
310 q = t->son[1] = root;
311
312 /* Search down the tree */
313 for (;; )
314 {
315 if (!q)
316 /* Insert new node at the bottom */
317 p->son[dir] = q = node;
318 else if (_eina_rbtree_is_red(q->son[0])
319 && _eina_rbtree_is_red(q->son[1]))
320 {
321 /* Color flip */
322 q->color = EINA_RBTREE_RED;
323 q->son[0]->color = EINA_RBTREE_BLACK;
324 q->son[1]->color = EINA_RBTREE_BLACK;
325 }
326
327 /* Fix red violation */
328 if (_eina_rbtree_is_red(q) && _eina_rbtree_is_red(p))
329 {
330 Eina_Rbtree_Direction dir2;
331 294
332 dir2 = (t->son[1] == g) ? EINA_RBTREE_RIGHT : EINA_RBTREE_LEFT; 295 /* Keep path in stack */
296 stack[s++] = (uintptr_t)r | dir;
333 297
334 if (q == p->son[last]) 298 r = q->son + dir;
335 t->son[dir2] = _eina_rbtree_inline_single_rotation(g, !last); 299 q = *r;
336 else 300 }
337 t->son[dir2] = _eina_rbtree_inline_double_rotation(g, !last);
338 }
339
340 /* Stop if found */
341 if (q == node)
342 break;
343
344 last = dir;
345 dir = cmp(q, node, (void *)data);
346 301
347 /* Update helpers */ 302 /* Insert */
348 if ( g ) 303 *r = node;
349 t = g; 304 _eina_rbtree_node_init(node);
350
351 g = p, p = q;
352 q = q->son[dir];
353 }
354 305
355 root = head.son[1]; 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 }
356 338
357end_add:
358 /* Make root black */
359 root->color = EINA_RBTREE_BLACK; 339 root->color = EINA_RBTREE_BLACK;
360
361 return root; 340 return root;
362} 341}
363 342
@@ -367,122 +346,144 @@ eina_rbtree_inline_remove(Eina_Rbtree *root,
367 Eina_Rbtree_Cmp_Node_Cb cmp, 346 Eina_Rbtree_Cmp_Node_Cb cmp,
368 const void *data) 347 const void *data)
369{ 348{
370 Eina_Rbtree head; 349 Eina_Rbtree *l0, *l1, *r, **rt = &root;
371 Eina_Rbtree *q, *p;
372 Eina_Rbtree *f = NULL;
373 Eina_Rbtree_Direction dir; 350 Eina_Rbtree_Direction dir;
351 uintptr_t stack[48];
352 unsigned int s = 0;
374 353
375 EINA_SAFETY_ON_NULL_RETURN_VAL(node, root); 354 EINA_SAFETY_ON_NULL_RETURN_VAL(node, root);
376 EINA_SAFETY_ON_NULL_RETURN_VAL( cmp, root); 355 EINA_SAFETY_ON_NULL_RETURN_VAL( cmp, root);
377 356
378 if (!root || !node) 357 /* Item search loop */
379 return root; 358 for (r = *rt; r != NULL; r = *rt)
380 359 {
381 memset(&head, 0, sizeof(Eina_Rbtree)); 360 if (r == node)
382 361 goto found;
383 dir = EINA_RBTREE_RIGHT;
384 q = &head;
385 p = NULL;
386 q->son[EINA_RBTREE_RIGHT] = root;
387
388 /* Search and push a red down */
389 while (q->son[dir])
390 {
391 Eina_Rbtree_Direction last = dir;
392 Eina_Rbtree *g;
393
394 /* Update helpers */
395 g = p; p = q;
396 q = q->son[dir];
397 dir = cmp(q, node, (void *)data);
398
399 /* Save parent node found */
400 if (q == node)
401 f = p;
402 362
403 /* Push the red node down */ 363 dir = cmp(r, node, (void*)data);
404 if (!_eina_rbtree_is_red(q) 364 stack[s++] = (uintptr_t)rt | dir;
405 && !_eina_rbtree_is_red(q->son[dir])) 365 rt = r->son + dir;
406 { 366 }
407 if (_eina_rbtree_is_red(q->son[!dir])) 367 return root;
408 q = p->son[last] = _eina_rbtree_inline_single_rotation(q, dir);
409 else if (!_eina_rbtree_is_red(q->son[!dir]))
410 {
411 Eina_Rbtree *s = p->son[!last];
412
413 if (s)
414 {
415 if (!_eina_rbtree_is_red(s->son[EINA_RBTREE_LEFT])
416 && !_eina_rbtree_is_red(s->son[EINA_RBTREE_RIGHT]))
417 {
418/* Color flip */
419 p->color = EINA_RBTREE_BLACK;
420 p->son[EINA_RBTREE_LEFT]->color = EINA_RBTREE_RED;
421 p->son[EINA_RBTREE_RIGHT]->color = EINA_RBTREE_RED;
422 }
423 else
424 {
425 Eina_Rbtree_Direction dir2;
426
427 dir2 = g->son[1] ==
428 p ? EINA_RBTREE_RIGHT : EINA_RBTREE_LEFT;
429
430 if (_eina_rbtree_is_red(s->son[last]))
431 {
432 g->son[dir2] =
433 _eina_rbtree_inline_double_rotation(p, last);
434 if (f == g)
435 {
436 p = g->son[dir2]->son[last];
437 f = g->son[dir2];
438 }
439 }
440 else if (_eina_rbtree_is_red(s->son[!last]))
441 {
442 g->son[dir2] =
443 _eina_rbtree_inline_single_rotation(p, last);
444 if (f == g)
445 {
446 p = g->son[dir2]->son[last];
447 f = g->son[dir2];
448 }
449 }
450
451/* Ensure correct coloring */
452 q->color = g->son[dir2]->color = EINA_RBTREE_RED;
453 g->son[dir2]->son[EINA_RBTREE_LEFT]->color =
454 EINA_RBTREE_BLACK;
455 g->son[dir2]->son[EINA_RBTREE_RIGHT]->color =
456 EINA_RBTREE_BLACK;
457 }
458 }
459 }
460 }
461 }
462
463 /* Replace and remove if found */
464 if (f)
465 {
466 /* 'q' should take the place of 'node' parent */
467 f->son[f->son[1] == node] = q;
468
469 /* Switch the link from the parent to q's son */
470 p->son[p->son[1] == q] = q->son[!q->son[0]];
471
472 /* Put q at the place of node */
473 q->son[0] = node->son[0];
474 q->son[1] = node->son[1];
475 q->color = node->color;
476
477 /* Reset node link */
478 node->son[0] = NULL;
479 node->son[1] = NULL;
480 }
481 368
482 root = head.son[1]; 369 found:
483 if (root) 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)
484 root->color = EINA_RBTREE_BLACK; 486 root->color = EINA_RBTREE_BLACK;
485
486 return root; 487 return root;
487} 488}
488 489
diff --git a/libraries/eina/src/lib/eina_sched.c b/libraries/eina/src/lib/eina_sched.c
index 8c7f7fe..b8e7000 100644
--- a/libraries/eina/src/lib/eina_sched.c
+++ b/libraries/eina/src/lib/eina_sched.c
@@ -41,7 +41,7 @@
41#include "eina_sched.h" 41#include "eina_sched.h"
42#include "eina_log.h" 42#include "eina_log.h"
43 43
44#define RTNICENESS 5 44#define RTNICENESS 1
45#define NICENESS 5 45#define NICENESS 5
46 46
47EAPI void 47EAPI void
@@ -62,10 +62,14 @@ eina_sched_prio_drop(void)
62 62
63 if (EINA_UNLIKELY(pol == SCHED_RR || pol == SCHED_FIFO)) 63 if (EINA_UNLIKELY(pol == SCHED_RR || pol == SCHED_FIFO))
64 { 64 {
65 prio = sched_get_priority_max(pol); 65 param.sched_priority -= RTNICENESS;
66 param.sched_priority += RTNICENESS; 66
67 if (prio > 0 && param.sched_priority > prio) 67 /* We don't change the policy */
68 param.sched_priority = prio; 68 if (param.sched_priority < 1)
69 {
70 EINA_LOG_INFO("RT prio < 1, setting to 1 instead");
71 param.sched_priority = 1;
72 }
69 73
70 pthread_setschedparam(pthread_id, pol, &param); 74 pthread_setschedparam(pthread_id, pol, &param);
71 } 75 }
@@ -78,7 +82,10 @@ eina_sched_prio_drop(void)
78 { 82 {
79 prio += NICENESS; 83 prio += NICENESS;
80 if (prio > 19) 84 if (prio > 19)
81 prio = 19; 85 {
86 EINA_LOG_INFO("Max niceness reached; keeping max (19)");
87 prio = 19;
88 }
82 89
83 setpriority(PRIO_PROCESS, 0, prio); 90 setpriority(PRIO_PROCESS, 0, prio);
84 } 91 }
diff --git a/libraries/eina/src/lib/eina_share_common.c b/libraries/eina/src/lib/eina_share_common.c
index 90e1868..776e429 100644
--- a/libraries/eina/src/lib/eina_share_common.c
+++ b/libraries/eina/src/lib/eina_share_common.c
@@ -76,7 +76,6 @@
76#include "eina_hash.h" 76#include "eina_hash.h"
77#include "eina_rbtree.h" 77#include "eina_rbtree.h"
78#include "eina_error.h" 78#include "eina_error.h"
79#include "eina_log.h"
80#include "eina_lock.h" 79#include "eina_lock.h"
81 80
82/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ 81/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
@@ -126,8 +125,6 @@ typedef struct _Eina_Share_Common Eina_Share_Common;
126typedef struct _Eina_Share_Common_Node Eina_Share_Common_Node; 125typedef struct _Eina_Share_Common_Node Eina_Share_Common_Node;
127typedef struct _Eina_Share_Common_Head Eina_Share_Common_Head; 126typedef struct _Eina_Share_Common_Head Eina_Share_Common_Head;
128 127
129int _eina_share_common_log_dom = -1;
130
131struct _Eina_Share 128struct _Eina_Share
132{ 129{
133 Eina_Share_Common *share; 130 Eina_Share_Common *share;
@@ -600,28 +597,8 @@ eina_share_common_init(Eina_Share **_share,
600 share = *_share = calloc(sizeof(Eina_Share), 1); 597 share = *_share = calloc(sizeof(Eina_Share), 1);
601 if (!share) goto on_error; 598 if (!share) goto on_error;
602 599
603 if (_eina_share_common_log_dom < 0) /*Only register if not already */
604 _eina_share_common_log_dom = eina_log_domain_register(
605 "eina_share",
606 EINA_LOG_COLOR_DEFAULT);
607
608 if (_eina_share_common_log_dom < 0)
609 {
610 EINA_LOG_ERR("Could not register log domain: eina_share_common");
611 goto on_error;
612 }
613
614 share->share = calloc(1, sizeof(Eina_Share_Common)); 600 share->share = calloc(1, sizeof(Eina_Share_Common));
615 if (!share->share) 601 if (!share->share) goto on_error;
616 {
617 if (_eina_share_common_log_dom > 0)
618 {
619 eina_log_domain_unregister(_eina_share_common_log_dom);
620 _eina_share_common_log_dom = -1;
621 }
622
623 goto on_error;
624 }
625 602
626 share->node_magic = node_magic; 603 share->node_magic = node_magic;
627#define EMS(n) eina_magic_string_static_set(n, n ## _STR) 604#define EMS(n) eina_magic_string_static_set(n, n ## _STR)
@@ -678,11 +655,6 @@ eina_share_common_shutdown(Eina_Share **_share)
678 MAGIC_FREE(share->share); 655 MAGIC_FREE(share->share);
679 656
680 _eina_share_common_population_shutdown(share); 657 _eina_share_common_population_shutdown(share);
681 if (_eina_share_common_log_dom > 0) /* Only free if necessary */
682 {
683 eina_log_domain_unregister(_eina_share_common_log_dom);
684 _eina_share_common_log_dom = -1;
685 }
686 658
687 eina_lock_release(&_mutex_big); 659 eina_lock_release(&_mutex_big);
688 660
@@ -833,7 +805,7 @@ eina_share_common_ref(Eina_Share *share, const char *str)
833} 805}
834 806
835 807
836void 808Eina_Bool
837eina_share_common_del(Eina_Share *share, const char *str) 809eina_share_common_del(Eina_Share *share, const char *str)
838{ 810{
839 unsigned int slen; 811 unsigned int slen;
@@ -843,7 +815,7 @@ eina_share_common_del(Eina_Share *share, const char *str)
843 int hash_num, hash; 815 int hash_num, hash;
844 816
845 if (!str) 817 if (!str)
846 return; 818 return EINA_TRUE;
847 819
848 eina_lock_take(&_mutex_big); 820 eina_lock_take(&_mutex_big);
849 821
@@ -857,7 +829,7 @@ eina_share_common_del(Eina_Share *share, const char *str)
857 { 829 {
858 node->references--; 830 node->references--;
859 eina_lock_release(&_mutex_big); 831 eina_lock_release(&_mutex_big);
860 return; 832 return EINA_TRUE;
861 } 833 }
862 834
863 node->references = 0; 835 node->references = 0;
@@ -871,7 +843,7 @@ eina_share_common_del(Eina_Share *share, const char *str)
871 if (!ed) 843 if (!ed)
872 goto on_error; 844 goto on_error;
873 845
874 EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(ed, eina_lock_release(&_mutex_big)); 846 EINA_MAGIC_CHECK_SHARE_COMMON_HEAD(ed, eina_lock_release(&_mutex_big), EINA_FALSE);
875 847
876 if (!_eina_share_common_head_remove_node(ed, node)) 848 if (!_eina_share_common_head_remove_node(ed, node))
877 goto on_error; 849 goto on_error;
@@ -886,12 +858,12 @@ eina_share_common_del(Eina_Share *share, const char *str)
886 858
887 eina_lock_release(&_mutex_big); 859 eina_lock_release(&_mutex_big);
888 860
889 return; 861 return EINA_TRUE;
890 862
891on_error: 863on_error:
892 eina_lock_release(&_mutex_big); 864 eina_lock_release(&_mutex_big);
893 /* possible segfault happened before here, but... */ 865 /* possible segfault happened before here, but... */
894 CRITICAL("EEEK trying to del non-shared share_common \"%s\"", str); 866 return EINA_FALSE;
895} 867}
896 868
897int 869int
diff --git a/libraries/eina/src/lib/eina_share_common.h b/libraries/eina/src/lib/eina_share_common.h
index 002c652..6bc11ef 100644
--- a/libraries/eina/src/lib/eina_share_common.h
+++ b/libraries/eina/src/lib/eina_share_common.h
@@ -71,7 +71,7 @@ const char *eina_share_common_add_length(Eina_Share *share,
71 unsigned int null_size) 71 unsigned int null_size)
72EINA_WARN_UNUSED_RESULT; 72EINA_WARN_UNUSED_RESULT;
73const char *eina_share_common_ref(Eina_Share *share, const char *str); 73const char *eina_share_common_ref(Eina_Share *share, const char *str);
74void eina_share_common_del(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, 75int eina_share_common_length(Eina_Share *share,
76 const char *str) EINA_CONST 76 const char *str) EINA_CONST
77EINA_WARN_UNUSED_RESULT; 77EINA_WARN_UNUSED_RESULT;
@@ -83,21 +83,4 @@ void eina_share_common_dump(Eina_Share *share, void (*additional_dump)(
83void eina_share_common_population_add(Eina_Share *share, int slen); 83void eina_share_common_population_add(Eina_Share *share, int slen);
84void eina_share_common_population_del(Eina_Share *share, int slen); 84void eina_share_common_population_del(Eina_Share *share, int slen);
85 85
86/* Share logging */ 86#endif /* EINA_SHARE_COMMON_H_ */
87#ifdef CRITICAL
88#undef CRITICAL
89#endif
90#define CRITICAL(...) EINA_LOG_DOM_CRIT(_eina_share_common_log_dom, __VA_ARGS__)
91
92#ifdef ERR
93#undef ERR
94#endif
95#define ERR(...) EINA_LOG_DOM_ERR(_eina_share_common_log_dom, __VA_ARGS__)
96
97#ifdef DBG
98#undef DBG
99#endif
100#define DBG(...) EINA_LOG_DOM_DBG(_eina_share_common_log_dom, __VA_ARGS__)
101extern int _eina_share_common_log_dom;
102
103#endif /* EINA_STRINGSHARE_H_ */
diff --git a/libraries/eina/src/lib/eina_stringshare.c b/libraries/eina/src/lib/eina_stringshare.c
index 478b300..f371fcd 100644
--- a/libraries/eina/src/lib/eina_stringshare.c
+++ b/libraries/eina/src/lib/eina_stringshare.c
@@ -55,12 +55,30 @@ void *alloca (size_t);
55#include "eina_private.h" 55#include "eina_private.h"
56#include "eina_error.h" 56#include "eina_error.h"
57#include "eina_log.h" 57#include "eina_log.h"
58#include "eina_stringshare.h"
59#include "eina_lock.h" 58#include "eina_lock.h"
59#include "eina_share_common.h"
60 60
61/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ 61/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
62#include "eina_safety_checks.h" 62#include "eina_safety_checks.h"
63#include "eina_share_common.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;
64 82
65/* The actual share */ 83/* The actual share */
66static Eina_Share *stringshare_share; 84static Eina_Share *stringshare_share;
@@ -447,11 +465,8 @@ _eina_stringshare_small_bucket_dump(Eina_Stringshare_Small_Bucket *bucket,
447 for (i = 0; i < bucket->count; i++, s++, l++, r++) 465 for (i = 0; i < bucket->count; i++, s++, l++, r++)
448 { 466 {
449 int dups; 467 int dups;
450#ifdef _WIN32 468
451 printf("DDD: %5hu %5hu '%s'\n", *l, *r, *s);
452#else
453 printf("DDD: %5hhu %5hu '%s'\n", *l, *r, *s); 469 printf("DDD: %5hhu %5hu '%s'\n", *l, *r, *s);
454#endif
455 470
456 dups = (*r - 1); 471 dups = (*r - 1);
457 472
@@ -500,11 +515,29 @@ Eina_Bool
500eina_stringshare_init(void) 515eina_stringshare_init(void)
501{ 516{
502 Eina_Bool ret; 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
503 ret = eina_share_common_init(&stringshare_share, 531 ret = eina_share_common_init(&stringshare_share,
504 EINA_MAGIC_STRINGSHARE_NODE, 532 EINA_MAGIC_STRINGSHARE_NODE,
505 EINA_MAGIC_STRINGSHARE_NODE_STR); 533 EINA_MAGIC_STRINGSHARE_NODE_STR);
506 if (ret) 534 if (ret)
507 _eina_stringshare_small_init(); 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 }
508 541
509 return ret; 542 return ret;
510} 543}
@@ -526,6 +559,13 @@ eina_stringshare_shutdown(void)
526 Eina_Bool ret; 559 Eina_Bool ret;
527 _eina_stringshare_small_shutdown(); 560 _eina_stringshare_small_shutdown();
528 ret = eina_share_common_shutdown(&stringshare_share); 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
529 return ret; 569 return ret;
530} 570}
531 571
@@ -534,7 +574,7 @@ eina_stringshare_shutdown(void)
534*============================================================================*/ 574*============================================================================*/
535 575
536EAPI void 576EAPI void
537eina_stringshare_del(const char *str) 577eina_stringshare_del(Eina_Stringshare *str)
538{ 578{
539 int slen; 579 int slen;
540 580
@@ -564,16 +604,17 @@ eina_stringshare_del(const char *str)
564 return; 604 return;
565 } 605 }
566 606
567 eina_share_common_del(stringshare_share, str); 607 if (!eina_share_common_del(stringshare_share, str))
608 CRITICAL("EEEK trying to del non-shared stringshare \"%s\"", str);
568} 609}
569 610
570EAPI const char * 611EAPI Eina_Stringshare *
571eina_stringshare_add_length(const char *str, unsigned int slen) 612eina_stringshare_add_length(const char *str, unsigned int slen)
572{ 613{
573 if ((!str) || (slen <= 0)) 614 if ((!str) || (slen <= 0))
574 return ""; 615 return "";
575 else if (slen == 1) 616 else if (slen == 1)
576 return (const char *)_eina_stringshare_single + ((*str) << 1); 617 return (Eina_Stringshare *) _eina_stringshare_single + ((*str) << 1);
577 else if (slen < 4) 618 else if (slen < 4)
578 { 619 {
579 const char *s; 620 const char *s;
@@ -588,7 +629,7 @@ eina_stringshare_add_length(const char *str, unsigned int slen)
588 sizeof(char), sizeof(char)); 629 sizeof(char), sizeof(char));
589} 630}
590 631
591EAPI const char * 632EAPI Eina_Stringshare *
592eina_stringshare_add(const char *str) 633eina_stringshare_add(const char *str)
593{ 634{
594 int slen; 635 int slen;
@@ -609,7 +650,7 @@ eina_stringshare_add(const char *str)
609 return eina_stringshare_add_length(str, slen); 650 return eina_stringshare_add_length(str, slen);
610} 651}
611 652
612EAPI const char * 653EAPI Eina_Stringshare *
613eina_stringshare_printf(const char *fmt, ...) 654eina_stringshare_printf(const char *fmt, ...)
614{ 655{
615 va_list args; 656 va_list args;
@@ -633,7 +674,7 @@ eina_stringshare_printf(const char *fmt, ...)
633 return ret; 674 return ret;
634} 675}
635 676
636EAPI const char * 677EAPI Eina_Stringshare *
637eina_stringshare_vprintf(const char *fmt, va_list args) 678eina_stringshare_vprintf(const char *fmt, va_list args)
638{ 679{
639 char *tmp; 680 char *tmp;
@@ -654,7 +695,7 @@ eina_stringshare_vprintf(const char *fmt, va_list args)
654 return ret; 695 return ret;
655} 696}
656 697
657EAPI const char * 698EAPI Eina_Stringshare *
658eina_stringshare_nprintf(unsigned int len, const char *fmt, ...) 699eina_stringshare_nprintf(unsigned int len, const char *fmt, ...)
659{ 700{
660 va_list args; 701 va_list args;
@@ -679,8 +720,8 @@ eina_stringshare_nprintf(unsigned int len, const char *fmt, ...)
679 return eina_stringshare_add_length(tmp, len); 720 return eina_stringshare_add_length(tmp, len);
680} 721}
681 722
682EAPI const char * 723EAPI Eina_Stringshare *
683eina_stringshare_ref(const char *str) 724eina_stringshare_ref(Eina_Stringshare *str)
684{ 725{
685 int slen; 726 int slen;
686 727
@@ -721,7 +762,7 @@ eina_stringshare_ref(const char *str)
721} 762}
722 763
723EAPI int 764EAPI int
724eina_stringshare_strlen(const char *str) 765eina_stringshare_strlen(Eina_Stringshare *str)
725{ 766{
726 int len; 767 int len;
727 /* special cases */ 768 /* special cases */
@@ -737,7 +778,7 @@ eina_stringshare_strlen(const char *str)
737 if (str[3] == '\0') 778 if (str[3] == '\0')
738 return 3; 779 return 3;
739 780
740 len = eina_share_common_length(stringshare_share, (const char *)str); 781 len = eina_share_common_length(stringshare_share, (Eina_Stringshare *) str);
741 len = (len > 0) ? len / (int)sizeof(char) : -1; 782 len = (len > 0) ? len / (int)sizeof(char) : -1;
742 return len; 783 return len;
743} 784}
diff --git a/libraries/eina/src/lib/eina_unicode.c b/libraries/eina/src/lib/eina_unicode.c
index 342e3cb..7505906 100644
--- a/libraries/eina/src/lib/eina_unicode.c
+++ b/libraries/eina/src/lib/eina_unicode.c
@@ -15,10 +15,18 @@
15 * You should have received a copy of the GNU Lesser General Public 15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; 16 * License along with this library;
17 * if not, see <http://www.gnu.org/licenses/>. 17 * if not, see <http://www.gnu.org/licenses/>.
18
19 */ 18 */
20 19
21#include <Eina.h> 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"
22#include "eina_unicode.h" 30#include "eina_unicode.h"
23 31
24/* FIXME: check if sizeof(wchar_t) == sizeof(Eina_Unicode) if so, 32/* FIXME: check if sizeof(wchar_t) == sizeof(Eina_Unicode) if so,
@@ -30,6 +38,9 @@ EAPI const Eina_Unicode *EINA_UNICODE_EMPTY_STRING = _EINA_UNICODE_EMPTY_STRING;
30EAPI int 38EAPI int
31eina_unicode_strcmp(const Eina_Unicode *a, const Eina_Unicode *b) 39eina_unicode_strcmp(const Eina_Unicode *a, const Eina_Unicode *b)
32{ 40{
41 EINA_SAFETY_ON_NULL_RETURN_VAL(a, -1);
42 EINA_SAFETY_ON_NULL_RETURN_VAL(b, -1);
43
33 for (; *a && *a == *b; a++, b++) 44 for (; *a && *a == *b; a++, b++)
34 ; 45 ;
35 if (*a == *b) 46 if (*a == *b)
@@ -45,6 +56,9 @@ eina_unicode_strcpy(Eina_Unicode *dest, const Eina_Unicode *source)
45{ 56{
46 Eina_Unicode *ret = dest; 57 Eina_Unicode *ret = dest;
47 58
59 EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL);
60 EINA_SAFETY_ON_NULL_RETURN_VAL(source, NULL);
61
48 while (*source) 62 while (*source)
49 *dest++ = *source++; 63 *dest++ = *source++;
50 *dest = 0; 64 *dest = 0;
@@ -56,6 +70,9 @@ eina_unicode_strncpy(Eina_Unicode *dest, const Eina_Unicode *source, size_t n)
56{ 70{
57 Eina_Unicode *ret = dest; 71 Eina_Unicode *ret = dest;
58 72
73 EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL);
74 EINA_SAFETY_ON_NULL_RETURN_VAL(source, NULL);
75
59 for ( ; n && *source ; n--) 76 for ( ; n && *source ; n--)
60 *dest++ = *source++; 77 *dest++ = *source++;
61 for (; n; n--) 78 for (; n; n--)
@@ -67,6 +84,9 @@ EAPI size_t
67eina_unicode_strlen(const Eina_Unicode *ustr) 84eina_unicode_strlen(const Eina_Unicode *ustr)
68{ 85{
69 const Eina_Unicode *end; 86 const Eina_Unicode *end;
87
88 EINA_SAFETY_ON_NULL_RETURN_VAL(ustr, 0);
89
70 for (end = ustr; *end; end++) 90 for (end = ustr; *end; end++)
71 ; 91 ;
72 return end - ustr; 92 return end - ustr;
@@ -77,6 +97,9 @@ eina_unicode_strnlen(const Eina_Unicode *ustr, int n)
77{ 97{
78 const Eina_Unicode *end; 98 const Eina_Unicode *end;
79 const Eina_Unicode *last = ustr + n; /* technically not portable ;-) */ 99 const Eina_Unicode *last = ustr + n; /* technically not portable ;-) */
100
101 EINA_SAFETY_ON_NULL_RETURN_VAL(ustr, 0);
102
80 for (end = ustr; end < last && *end; end++) 103 for (end = ustr; end < last && *end; end++)
81 ; 104 ;
82 return end - ustr; 105 return end - ustr;
@@ -90,7 +113,9 @@ eina_unicode_strndup(const Eina_Unicode *text, size_t n)
90{ 113{
91 Eina_Unicode *ustr; 114 Eina_Unicode *ustr;
92 115
93 ustr = (Eina_Unicode *) malloc((n + 1) * sizeof(Eina_Unicode)); 116 EINA_SAFETY_ON_NULL_RETURN_VAL(text, NULL);
117
118 ustr = malloc((n + 1) * sizeof(Eina_Unicode));
94 memcpy(ustr, text, n * sizeof(Eina_Unicode)); 119 memcpy(ustr, text, n * sizeof(Eina_Unicode));
95 ustr[n] = 0; 120 ustr[n] = 0;
96 return ustr; 121 return ustr;
@@ -101,6 +126,8 @@ eina_unicode_strdup(const Eina_Unicode *text)
101{ 126{
102 size_t len; 127 size_t len;
103 128
129 EINA_SAFETY_ON_NULL_RETURN_VAL(text, NULL);
130
104 len = eina_unicode_strlen(text); 131 len = eina_unicode_strlen(text);
105 return eina_unicode_strndup(text, len); 132 return eina_unicode_strndup(text, len);
106} 133}
@@ -110,6 +137,9 @@ eina_unicode_strstr(const Eina_Unicode *haystack, const Eina_Unicode *needle)
110{ 137{
111 const Eina_Unicode *i, *j; 138 const Eina_Unicode *i, *j;
112 139
140 EINA_SAFETY_ON_NULL_RETURN_VAL(haystack, NULL);
141 EINA_SAFETY_ON_NULL_RETURN_VAL(needle, NULL);
142
113 for (i = haystack; *i; i++) 143 for (i = haystack; *i; i++)
114 { 144 {
115 haystack = i; /* set this location as the base position */ 145 haystack = i; /* set this location as the base position */
@@ -131,6 +161,8 @@ eina_unicode_escape(const Eina_Unicode *str)
131 Eina_Unicode *s2, *d; 161 Eina_Unicode *s2, *d;
132 const Eina_Unicode *s; 162 const Eina_Unicode *s;
133 163
164 EINA_SAFETY_ON_NULL_RETURN_VAL(str, NULL);
165
134 s2 = malloc((eina_unicode_strlen(str) * 2) + 1); 166 s2 = malloc((eina_unicode_strlen(str) * 2) + 1);
135 if (!s2) 167 if (!s2)
136 return NULL; 168 return NULL;
@@ -165,6 +197,9 @@ eina_unicode_utf8_get_next(const char *buf, int *iindex)
165 Eina_Unicode r; 197 Eina_Unicode r;
166 unsigned char d; 198 unsigned char d;
167 199
200 EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0);
201 EINA_SAFETY_ON_NULL_RETURN_VAL(iindex, 0);
202
168 /* if this char is the null terminator, exit */ 203 /* if this char is the null terminator, exit */
169 if ((d = buf[ind++]) == 0) return 0; 204 if ((d = buf[ind++]) == 0) return 0;
170 205
@@ -266,8 +301,12 @@ error:
266EAPI Eina_Unicode 301EAPI Eina_Unicode
267eina_unicode_utf8_get_prev(const char *buf, int *iindex) 302eina_unicode_utf8_get_prev(const char *buf, int *iindex)
268{ 303{
269 int r; 304 int r, ind;
270 int ind = *iindex; 305
306 EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0);
307 EINA_SAFETY_ON_NULL_RETURN_VAL(iindex, 0);
308
309 ind = *iindex;
271 /* First obtain the codepoint at iindex */ 310 /* First obtain the codepoint at iindex */
272 r = eina_unicode_utf8_get_next(buf, &ind); 311 r = eina_unicode_utf8_get_next(buf, &ind);
273 312
@@ -292,6 +331,8 @@ eina_unicode_utf8_get_len(const char *buf)
292 /* returns the number of utf8 characters (not bytes) in the string */ 331 /* returns the number of utf8 characters (not bytes) in the string */
293 int i = 0, len = 0; 332 int i = 0, len = 0;
294 333
334 EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0);
335
295 while (eina_unicode_utf8_get_next(buf, &i)) 336 while (eina_unicode_utf8_get_next(buf, &i))
296 len++; 337 len++;
297 338
@@ -306,6 +347,8 @@ eina_unicode_utf8_to_unicode(const char *utf, int *_len)
306 int ind; 347 int ind;
307 Eina_Unicode *buf, *uind; 348 Eina_Unicode *buf, *uind;
308 349
350 EINA_SAFETY_ON_NULL_RETURN_VAL(utf, NULL);
351
309 len = eina_unicode_utf8_get_len(utf); 352 len = eina_unicode_utf8_get_len(utf);
310 if (_len) 353 if (_len)
311 *_len = len; 354 *_len = len;
@@ -328,6 +371,8 @@ eina_unicode_unicode_to_utf8(const Eina_Unicode *uni, int *_len)
328 char *ind; 371 char *ind;
329 int ulen, len; 372 int ulen, len;
330 373
374 EINA_SAFETY_ON_NULL_RETURN_VAL(uni, NULL);
375
331 ulen = eina_unicode_strlen(uni); 376 ulen = eina_unicode_strlen(uni);
332 buf = (char *) calloc(ulen + 1, EINA_UNICODE_UTF8_BYTES_PER_CHAR); 377 buf = (char *) calloc(ulen + 1, EINA_UNICODE_UTF8_BYTES_PER_CHAR);
333 378
diff --git a/libraries/eina/src/lib/eina_ustringshare.c b/libraries/eina/src/lib/eina_ustringshare.c
index 3992dc6..33be242 100644
--- a/libraries/eina/src/lib/eina_ustringshare.c
+++ b/libraries/eina/src/lib/eina_ustringshare.c
@@ -27,11 +27,38 @@
27 * 27 *
28 */ 28 */
29 29
30#include "eina_share_common.h" 30#ifdef HAVE_CONFIG_H
31#include "eina_unicode.h" 31# include "config.h"
32#endif
33
34#include "eina_config.h"
32#include "eina_private.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"
33#include "eina_ustringshare.h" 42#include "eina_ustringshare.h"
34 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
35/* The actual share */ 62/* The actual share */
36static Eina_Share *ustringshare_share; 63static Eina_Share *ustringshare_share;
37static const char EINA_MAGIC_USTRINGSHARE_NODE_STR[] = "Eina UStringshare Node"; 64static const char EINA_MAGIC_USTRINGSHARE_NODE_STR[] = "Eina UStringshare Node";
@@ -54,9 +81,31 @@ static const char EINA_MAGIC_USTRINGSHARE_NODE_STR[] = "Eina UStringshare Node";
54Eina_Bool 81Eina_Bool
55eina_ustringshare_init(void) 82eina_ustringshare_init(void)
56{ 83{
57 return eina_share_common_init(&ustringshare_share, 84 Eina_Bool ret;
58 EINA_MAGIC_USTRINGSHARE_NODE, 85
59 EINA_MAGIC_USTRINGSHARE_NODE_STR); 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;
60} 109}
61 110
62/** 111/**
@@ -75,6 +124,13 @@ eina_ustringshare_shutdown(void)
75{ 124{
76 Eina_Bool ret; 125 Eina_Bool ret;
77 ret = eina_share_common_shutdown(&ustringshare_share); 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
78 return ret; 134 return ret;
79} 135}
80 136
@@ -88,7 +144,8 @@ eina_ustringshare_del(const Eina_Unicode *str)
88 if (!str) 144 if (!str)
89 return; 145 return;
90 146
91 eina_share_common_del(ustringshare_share,(const char *)str); 147 if (!eina_share_common_del(ustringshare_share, (const char *)str))
148 CRITICAL("EEEK trying to del non-shared ustringshare \"%s\"", (const char *)str);
92} 149}
93 150
94EAPI const Eina_Unicode * 151EAPI const Eina_Unicode *
diff --git a/libraries/eina/src/lib/eina_value.c b/libraries/eina/src/lib/eina_value.c
index ba8af52..b8df693 100644
--- a/libraries/eina/src/lib/eina_value.c
+++ b/libraries/eina/src/lib/eina_value.c
@@ -49,6 +49,10 @@ void *alloca (size_t);
49#include <inttypes.h> /* PRId64 and PRIu64 */ 49#include <inttypes.h> /* PRId64 and PRIu64 */
50#include <sys/time.h> /* struct timeval */ 50#include <sys/time.h> /* struct timeval */
51 51
52#ifdef HAVE_EVIL
53# include <Evil.h>
54#endif
55
52#include "eina_config.h" 56#include "eina_config.h"
53#include "eina_private.h" 57#include "eina_private.h"
54#include "eina_error.h" 58#include "eina_error.h"
@@ -60,6 +64,7 @@ void *alloca (size_t);
60/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ 64/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
61#include "eina_safety_checks.h" 65#include "eina_safety_checks.h"
62#include "eina_value.h" 66#include "eina_value.h"
67#include "eina_model.h" /* uses eina_value.h */
63 68
64/*============================================================================* 69/*============================================================================*
65* Local * 70* Local *
@@ -168,7 +173,7 @@ _eina_value_type_uchar_convert_to(const Eina_Value_Type *type __UNUSED__, const
168 unsigned int other_mem = v; 173 unsigned int other_mem = v;
169 return eina_value_type_pset(convert, convert_mem, &other_mem); 174 return eina_value_type_pset(convert, convert_mem, &other_mem);
170 } 175 }
171 else if (convert == EINA_VALUE_TYPE_ULONG) 176 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
172 { 177 {
173 unsigned long other_mem = v; 178 unsigned long other_mem = v;
174 return eina_value_type_pset(convert, convert_mem, &other_mem); 179 return eina_value_type_pset(convert, convert_mem, &other_mem);
@@ -317,7 +322,7 @@ _eina_value_type_ushort_convert_to(const Eina_Value_Type *type __UNUSED__, const
317 unsigned int other_mem = v; 322 unsigned int other_mem = v;
318 return eina_value_type_pset(convert, convert_mem, &other_mem); 323 return eina_value_type_pset(convert, convert_mem, &other_mem);
319 } 324 }
320 else if (convert == EINA_VALUE_TYPE_ULONG) 325 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
321 { 326 {
322 unsigned long other_mem = v; 327 unsigned long other_mem = v;
323 return eina_value_type_pset(convert, convert_mem, &other_mem); 328 return eina_value_type_pset(convert, convert_mem, &other_mem);
@@ -470,7 +475,7 @@ _eina_value_type_uint_convert_to(const Eina_Value_Type *type __UNUSED__, const E
470 unsigned int other_mem = v; 475 unsigned int other_mem = v;
471 return eina_value_type_pset(convert, convert_mem, &other_mem); 476 return eina_value_type_pset(convert, convert_mem, &other_mem);
472 } 477 }
473 else if (convert == EINA_VALUE_TYPE_ULONG) 478 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
474 { 479 {
475 unsigned long other_mem = v; 480 unsigned long other_mem = v;
476 return eina_value_type_pset(convert, convert_mem, &other_mem); 481 return eina_value_type_pset(convert, convert_mem, &other_mem);
@@ -627,7 +632,7 @@ _eina_value_type_ulong_convert_to(const Eina_Value_Type *type __UNUSED__, const
627 return EINA_FALSE; 632 return EINA_FALSE;
628 return eina_value_type_pset(convert, convert_mem, &other_mem); 633 return eina_value_type_pset(convert, convert_mem, &other_mem);
629 } 634 }
630 else if (convert == EINA_VALUE_TYPE_ULONG) 635 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
631 { 636 {
632 unsigned long other_mem = v; 637 unsigned long other_mem = v;
633 return eina_value_type_pset(convert, convert_mem, &other_mem); 638 return eina_value_type_pset(convert, convert_mem, &other_mem);
@@ -786,7 +791,7 @@ _eina_value_type_uint64_convert_to(const Eina_Value_Type *type __UNUSED__, const
786 return EINA_FALSE; 791 return EINA_FALSE;
787 return eina_value_type_pset(convert, convert_mem, &other_mem); 792 return eina_value_type_pset(convert, convert_mem, &other_mem);
788 } 793 }
789 else if (convert == EINA_VALUE_TYPE_ULONG) 794 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
790 { 795 {
791 unsigned long other_mem = v; 796 unsigned long other_mem = v;
792 if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) && 797 if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) &&
@@ -950,7 +955,7 @@ _eina_value_type_char_convert_to(const Eina_Value_Type *type __UNUSED__, const E
950 return EINA_FALSE; 955 return EINA_FALSE;
951 return eina_value_type_pset(convert, convert_mem, &other_mem); 956 return eina_value_type_pset(convert, convert_mem, &other_mem);
952 } 957 }
953 else if (convert == EINA_VALUE_TYPE_ULONG) 958 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
954 { 959 {
955 unsigned long other_mem = v; 960 unsigned long other_mem = v;
956 if (EINA_UNLIKELY(v < 0)) 961 if (EINA_UNLIKELY(v < 0))
@@ -1107,7 +1112,7 @@ _eina_value_type_short_convert_to(const Eina_Value_Type *type __UNUSED__, const
1107 return EINA_FALSE; 1112 return EINA_FALSE;
1108 return eina_value_type_pset(convert, convert_mem, &other_mem); 1113 return eina_value_type_pset(convert, convert_mem, &other_mem);
1109 } 1114 }
1110 else if (convert == EINA_VALUE_TYPE_ULONG) 1115 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
1111 { 1116 {
1112 unsigned long other_mem = v; 1117 unsigned long other_mem = v;
1113 if (EINA_UNLIKELY(v < 0)) 1118 if (EINA_UNLIKELY(v < 0))
@@ -1270,7 +1275,7 @@ _eina_value_type_int_convert_to(const Eina_Value_Type *type __UNUSED__, const Ei
1270 return EINA_FALSE; 1275 return EINA_FALSE;
1271 return eina_value_type_pset(convert, convert_mem, &other_mem); 1276 return eina_value_type_pset(convert, convert_mem, &other_mem);
1272 } 1277 }
1273 else if (convert == EINA_VALUE_TYPE_ULONG) 1278 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
1274 { 1279 {
1275 unsigned long other_mem = v; 1280 unsigned long other_mem = v;
1276 if (EINA_UNLIKELY(v < 0)) 1281 if (EINA_UNLIKELY(v < 0))
@@ -1439,7 +1444,7 @@ _eina_value_type_long_convert_to(const Eina_Value_Type *type __UNUSED__, const E
1439 return EINA_FALSE; 1444 return EINA_FALSE;
1440 return eina_value_type_pset(convert, convert_mem, &other_mem); 1445 return eina_value_type_pset(convert, convert_mem, &other_mem);
1441 } 1446 }
1442 else if (convert == EINA_VALUE_TYPE_ULONG) 1447 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
1443 { 1448 {
1444 unsigned long other_mem = v; 1449 unsigned long other_mem = v;
1445 if (EINA_UNLIKELY(v < 0)) 1450 if (EINA_UNLIKELY(v < 0))
@@ -1612,7 +1617,7 @@ _eina_value_type_int64_convert_to(const Eina_Value_Type *type __UNUSED__, const
1612 return EINA_FALSE; 1617 return EINA_FALSE;
1613 return eina_value_type_pset(convert, convert_mem, &other_mem); 1618 return eina_value_type_pset(convert, convert_mem, &other_mem);
1614 } 1619 }
1615 else if (convert == EINA_VALUE_TYPE_ULONG) 1620 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
1616 { 1621 {
1617 unsigned long other_mem = v; 1622 unsigned long other_mem = v;
1618 if (EINA_UNLIKELY(v < 0)) 1623 if (EINA_UNLIKELY(v < 0))
@@ -1792,7 +1797,7 @@ _eina_value_type_float_convert_to(const Eina_Value_Type *type __UNUSED__, const
1792 return EINA_FALSE; 1797 return EINA_FALSE;
1793 return eina_value_type_pset(convert, convert_mem, &other_mem); 1798 return eina_value_type_pset(convert, convert_mem, &other_mem);
1794 } 1799 }
1795 else if (convert == EINA_VALUE_TYPE_ULONG) 1800 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
1796 { 1801 {
1797 unsigned long other_mem = v; 1802 unsigned long other_mem = v;
1798 if (EINA_UNLIKELY(v < 0)) 1803 if (EINA_UNLIKELY(v < 0))
@@ -1978,7 +1983,7 @@ _eina_value_type_double_convert_to(const Eina_Value_Type *type __UNUSED__, const
1978 return EINA_FALSE; 1983 return EINA_FALSE;
1979 return eina_value_type_pset(convert, convert_mem, &other_mem); 1984 return eina_value_type_pset(convert, convert_mem, &other_mem);
1980 } 1985 }
1981 else if (convert == EINA_VALUE_TYPE_ULONG) 1986 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
1982 { 1987 {
1983 unsigned long other_mem = v; 1988 unsigned long other_mem = v;
1984 if (EINA_UNLIKELY(v < 0)) 1989 if (EINA_UNLIKELY(v < 0))
@@ -2146,7 +2151,7 @@ _eina_value_type_string_common_convert_to(const Eina_Value_Type *type __UNUSED__
2146 return EINA_FALSE; 2151 return EINA_FALSE;
2147 return eina_value_type_pset(convert, convert_mem, &other_mem); 2152 return eina_value_type_pset(convert, convert_mem, &other_mem);
2148 } 2153 }
2149 else if (convert == EINA_VALUE_TYPE_ULONG) 2154 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
2150 { 2155 {
2151 unsigned long other_mem; 2156 unsigned long other_mem;
2152 if ((sscanf(v, "%lu", &other_mem) != 1) && 2157 if ((sscanf(v, "%lu", &other_mem) != 1) &&
@@ -2248,7 +2253,11 @@ static Eina_Bool
2248_eina_value_type_stringshare_flush(const Eina_Value_Type *type __UNUSED__, void *mem) 2253_eina_value_type_stringshare_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
2249{ 2254{
2250 const char **tmem = mem; 2255 const char **tmem = mem;
2251 if (*tmem) eina_stringshare_del(*tmem); 2256 if (*tmem)
2257 {
2258 eina_stringshare_del(*tmem);
2259 *tmem = NULL;
2260 }
2252 return EINA_TRUE; 2261 return EINA_TRUE;
2253} 2262}
2254 2263
@@ -2257,8 +2266,7 @@ _eina_value_type_stringshare_copy(const Eina_Value_Type *type __UNUSED__, const
2257{ 2266{
2258 const char * const*s = src; 2267 const char * const*s = src;
2259 const char **d = dst; 2268 const char **d = dst;
2260 *d = *s; 2269 *d = eina_stringshare_add(*s);
2261 eina_stringshare_ref(*d);
2262 return EINA_TRUE; 2270 return EINA_TRUE;
2263} 2271}
2264 2272
@@ -2280,7 +2288,11 @@ static Eina_Bool
2280_eina_value_type_string_flush(const Eina_Value_Type *type __UNUSED__, void *mem) 2288_eina_value_type_string_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
2281{ 2289{
2282 char **tmem = mem; 2290 char **tmem = mem;
2283 if (*tmem) free(*tmem); 2291 if (*tmem)
2292 {
2293 free(*tmem);
2294 *tmem = NULL;
2295 }
2284 return EINA_TRUE; 2296 return EINA_TRUE;
2285} 2297}
2286 2298
@@ -2308,19 +2320,24 @@ _eina_value_type_string_vset(const Eina_Value_Type *type __UNUSED__, void *mem,
2308{ 2320{
2309 char **tmem = mem; 2321 char **tmem = mem;
2310 const char *str = va_arg(args, const char *); 2322 const char *str = va_arg(args, const char *);
2311 free(*tmem); 2323 eina_error_set(0);
2312 if (str == NULL) 2324 if (str == *tmem) return EINA_TRUE;
2313 *tmem = NULL; 2325 if (!str)
2326 {
2327 free(*tmem);
2328 *tmem = NULL;
2329 }
2314 else 2330 else
2315 { 2331 {
2316 *tmem = strdup(str); 2332 char *tmp = strdup(str);
2317 if (*tmem == NULL) 2333 if (!tmp)
2318 { 2334 {
2319 eina_error_set(EINA_ERROR_OUT_OF_MEMORY); 2335 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
2320 return EINA_FALSE; 2336 return EINA_FALSE;
2321 } 2337 }
2338 free(*tmem);
2339 *tmem = tmp;
2322 } 2340 }
2323 eina_error_set(0);
2324 return EINA_TRUE; 2341 return EINA_TRUE;
2325} 2342}
2326 2343
@@ -2329,19 +2346,24 @@ _eina_value_type_string_pset(const Eina_Value_Type *type __UNUSED__, void *mem,
2329{ 2346{
2330 char **tmem = mem; 2347 char **tmem = mem;
2331 const char * const *str = ptr; 2348 const char * const *str = ptr;
2332 free(*tmem); 2349 eina_error_set(0);
2333 if (*str == NULL) 2350 if (*str == *tmem) return EINA_TRUE;
2334 *tmem = NULL; 2351 if (!*str)
2352 {
2353 free(*tmem);
2354 *tmem = NULL;
2355 }
2335 else 2356 else
2336 { 2357 {
2337 *tmem = strdup(*str); 2358 char *tmp = strdup(*str);
2338 if (*tmem == NULL) 2359 if (!tmp)
2339 { 2360 {
2340 eina_error_set(EINA_ERROR_OUT_OF_MEMORY); 2361 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
2341 return EINA_FALSE; 2362 return EINA_FALSE;
2342 } 2363 }
2364 free(*tmem);
2365 *tmem = tmp;
2343 } 2366 }
2344 eina_error_set(0);
2345 return EINA_TRUE; 2367 return EINA_TRUE;
2346} 2368}
2347 2369
@@ -2505,12 +2527,13 @@ _eina_value_type_array_convert_to(const Eina_Value_Type *type __UNUSED__, const
2505 (convert == EINA_VALUE_TYPE_STRINGSHARE)) 2527 (convert == EINA_VALUE_TYPE_STRINGSHARE))
2506 { 2528 {
2507 Eina_Strbuf *str = eina_strbuf_new(); 2529 Eina_Strbuf *str = eina_strbuf_new();
2530 const char *ptr;
2508 if (!tmem->array) eina_strbuf_append(str, "[]"); 2531 if (!tmem->array) eina_strbuf_append(str, "[]");
2509 else 2532 else
2510 { 2533 {
2511 const Eina_Value_Type *subtype = tmem->subtype; 2534 const Eina_Value_Type *subtype = tmem->subtype;
2512 unsigned char sz; 2535 unsigned char sz;
2513 const char *ptr, *ptr_end; 2536 const char *ptr_end;
2514 Eina_Value tmp; 2537 Eina_Value tmp;
2515 Eina_Bool first = EINA_TRUE; 2538 Eina_Bool first = EINA_TRUE;
2516 2539
@@ -2551,10 +2574,10 @@ _eina_value_type_array_convert_to(const Eina_Value_Type *type __UNUSED__, const
2551 } 2574 }
2552 2575
2553 eina_strbuf_append_char(str, ']'); 2576 eina_strbuf_append_char(str, ']');
2554 ptr = eina_strbuf_string_get(str);
2555 ret = eina_value_type_pset(convert, convert_mem, &ptr);
2556 eina_strbuf_free(str);
2557 } 2577 }
2578 ptr = eina_strbuf_string_get(str);
2579 ret = eina_value_type_pset(convert, convert_mem, &ptr);
2580 eina_strbuf_free(str);
2558 } 2581 }
2559 else if ((tmem->array) && (tmem->array->len == 1)) 2582 else if ((tmem->array) && (tmem->array->len == 1))
2560 { 2583 {
@@ -2606,43 +2629,51 @@ _eina_value_type_array_convert_from(const Eina_Value_Type *type, const Eina_Valu
2606} 2629}
2607 2630
2608static Eina_Bool 2631static Eina_Bool
2609_eina_value_type_array_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) 2632_eina_value_type_array_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
2610{ 2633{
2611 Eina_Value_Array *tmem = mem; 2634 Eina_Value_Array *tmem = mem;
2612 const Eina_Value_Array *desc = ptr; 2635 const Eina_Value_Array *desc = ptr;
2613 Eina_Inarray *desc_array; 2636 Eina_Inarray *desc_array;
2614 2637
2638 eina_error_set(0);
2615 if ((!tmem->subtype) && (!desc->subtype)) 2639 if ((!tmem->subtype) && (!desc->subtype))
2616 return EINA_TRUE; 2640 return EINA_TRUE;
2617 2641
2618 desc_array = desc->array; 2642 desc_array = desc->array;
2619 if (desc_array) 2643 if (desc_array)
2620 { 2644 {
2645 Eina_Value_Array tmp;
2646
2621 EINA_SAFETY_ON_FALSE_RETURN_VAL 2647 EINA_SAFETY_ON_FALSE_RETURN_VAL
2622 (desc_array->member_size == desc->subtype->value_size, EINA_FALSE); 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;
2623 } 2662 }
2624 2663
2625 if (tmem->array) 2664 if (tmem->array)
2626 { 2665 {
2627 _eina_value_type_array_flush_elements(tmem); 2666 _eina_value_type_array_flush_elements(tmem);
2628 if (desc_array) 2667 eina_inarray_setup(tmem->array, desc->subtype->value_size, desc->step);
2629 eina_inarray_free(tmem->array);
2630 else
2631 eina_inarray_setup(tmem->array, desc->subtype->value_size,
2632 desc->step);
2633 } 2668 }
2634 else if (!desc_array) 2669 else
2635 { 2670 {
2636 tmem->array = eina_inarray_new(desc->subtype->value_size, desc->step); 2671 tmem->array = eina_inarray_new(desc->subtype->value_size, desc->step);
2637 if (!tmem->array) 2672 if (!tmem->array)
2638 return EINA_FALSE; 2673 return EINA_FALSE;
2639 } 2674 }
2640 2675
2641 if (desc_array)
2642 tmem->array = desc_array;
2643
2644 tmem->subtype = desc->subtype; 2676 tmem->subtype = desc->subtype;
2645
2646 return EINA_TRUE; 2677 return EINA_TRUE;
2647} 2678}
2648 2679
@@ -2821,13 +2852,13 @@ _eina_value_type_list_convert_to(const Eina_Value_Type *type __UNUSED__, const E
2821 (convert == EINA_VALUE_TYPE_STRINGSHARE)) 2852 (convert == EINA_VALUE_TYPE_STRINGSHARE))
2822 { 2853 {
2823 Eina_Strbuf *str = eina_strbuf_new(); 2854 Eina_Strbuf *str = eina_strbuf_new();
2855 const char *s;
2824 if (!tmem->list) eina_strbuf_append(str, "[]"); 2856 if (!tmem->list) eina_strbuf_append(str, "[]");
2825 else 2857 else
2826 { 2858 {
2827 const Eina_Value_Type *subtype = tmem->subtype; 2859 const Eina_Value_Type *subtype = tmem->subtype;
2828 const Eina_List *node; 2860 const Eina_List *node;
2829 Eina_Value tmp; 2861 Eina_Value tmp;
2830 const char *s;
2831 Eina_Bool first = EINA_TRUE; 2862 Eina_Bool first = EINA_TRUE;
2832 2863
2833 eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING); 2864 eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING);
@@ -2867,10 +2898,10 @@ _eina_value_type_list_convert_to(const Eina_Value_Type *type __UNUSED__, const E
2867 } 2898 }
2868 2899
2869 eina_strbuf_append_char(str, ']'); 2900 eina_strbuf_append_char(str, ']');
2870 s = eina_strbuf_string_get(str);
2871 ret = eina_value_type_pset(convert, convert_mem, &s);
2872 eina_strbuf_free(str);
2873 } 2901 }
2902 s = eina_strbuf_string_get(str);
2903 ret = eina_value_type_pset(convert, convert_mem, &s);
2904 eina_strbuf_free(str);
2874 } 2905 }
2875 else if ((tmem->list) && (tmem->list->next == NULL)) 2906 else if ((tmem->list) && (tmem->list->next == NULL))
2876 { 2907 {
@@ -2932,18 +2963,36 @@ _eina_value_type_list_convert_from(const Eina_Value_Type *type, const Eina_Value
2932} 2963}
2933 2964
2934static Eina_Bool 2965static Eina_Bool
2935_eina_value_type_list_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) 2966_eina_value_type_list_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
2936{ 2967{
2937 Eina_Value_List *tmem = mem; 2968 Eina_Value_List *tmem = mem;
2938 const Eina_Value_List *desc = ptr; 2969 const Eina_Value_List *desc = ptr;
2939 2970
2971 eina_error_set(0);
2940 if ((!tmem->subtype) && (!desc->subtype)) 2972 if ((!tmem->subtype) && (!desc->subtype))
2941 return EINA_TRUE; 2973 return EINA_TRUE;
2942 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
2943 _eina_value_type_list_flush_elements(tmem); 2993 _eina_value_type_list_flush_elements(tmem);
2944 tmem->subtype = desc->subtype;
2945 tmem->list = desc->list;
2946 2994
2995 tmem->subtype = desc->subtype;
2947 return EINA_TRUE; 2996 return EINA_TRUE;
2948} 2997}
2949 2998
@@ -2995,6 +3044,7 @@ _eina_value_type_hash_flush_each(const Eina_Hash *hash __UNUSED__, const void *k
2995{ 3044{
2996 struct _eina_value_type_hash_flush_each_ctx *ctx = user_data; 3045 struct _eina_value_type_hash_flush_each_ctx *ctx = user_data;
2997 ctx->ret &= eina_value_type_flush(ctx->subtype, mem); 3046 ctx->ret &= eina_value_type_flush(ctx->subtype, mem);
3047 free(mem);
2998 return EINA_TRUE; 3048 return EINA_TRUE;
2999} 3049}
3000 3050
@@ -3239,11 +3289,11 @@ _eina_value_type_hash_convert_to(const Eina_Value_Type *type __UNUSED__, const E
3239 (convert == EINA_VALUE_TYPE_STRINGSHARE)) 3289 (convert == EINA_VALUE_TYPE_STRINGSHARE))
3240 { 3290 {
3241 Eina_Strbuf *str = eina_strbuf_new(); 3291 Eina_Strbuf *str = eina_strbuf_new();
3292 const char *s;
3242 if (!tmem->hash) eina_strbuf_append(str, "{}"); 3293 if (!tmem->hash) eina_strbuf_append(str, "{}");
3243 else 3294 else
3244 { 3295 {
3245 struct _eina_value_type_hash_convert_to_string_each_ctx ctx; 3296 struct _eina_value_type_hash_convert_to_string_each_ctx ctx;
3246 const char *s;
3247 3297
3248 ctx.subtype = tmem->subtype; 3298 ctx.subtype = tmem->subtype;
3249 ctx.str = str; 3299 ctx.str = str;
@@ -3257,10 +3307,10 @@ _eina_value_type_hash_convert_to(const Eina_Value_Type *type __UNUSED__, const E
3257 &ctx); 3307 &ctx);
3258 3308
3259 eina_strbuf_append_char(str, '}'); 3309 eina_strbuf_append_char(str, '}');
3260 s = eina_strbuf_string_get(str);
3261 ret = eina_value_type_pset(convert, convert_mem, &s);
3262 eina_strbuf_free(str);
3263 } 3310 }
3311 s = eina_strbuf_string_get(str);
3312 ret = eina_value_type_pset(convert, convert_mem, &s);
3313 eina_strbuf_free(str);
3264 } 3314 }
3265 else if ((tmem->hash) && (eina_hash_population(tmem->hash) == 1)) 3315 else if ((tmem->hash) && (eina_hash_population(tmem->hash) == 1))
3266 { 3316 {
@@ -3288,22 +3338,38 @@ _eina_value_type_hash_convert_to(const Eina_Value_Type *type __UNUSED__, const E
3288} 3338}
3289 3339
3290static Eina_Bool 3340static Eina_Bool
3291_eina_value_type_hash_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) 3341_eina_value_type_hash_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
3292{ 3342{
3293 Eina_Value_Hash *tmem = mem; 3343 Eina_Value_Hash *tmem = mem;
3294 const Eina_Value_Hash *desc = ptr; 3344 const Eina_Value_Hash *desc = ptr;
3295 3345
3346 eina_error_set(0);
3296 if ((!tmem->subtype) && (!desc->subtype)) 3347 if ((!tmem->subtype) && (!desc->subtype))
3297 return EINA_TRUE; 3348 return EINA_TRUE;
3298 3349
3299 if (tmem->hash) _eina_value_type_hash_flush_elements(tmem); 3350 if ((tmem->hash) && (tmem->hash == desc->hash))
3351 {
3352 tmem->subtype = desc->subtype;
3353 return EINA_TRUE;
3354 }
3300 3355
3301 if (desc->hash) 3356 if (desc->hash)
3302 tmem->hash = desc->hash; 3357 {
3303 else if (!_eina_value_type_hash_create(tmem)) 3358 Eina_Value_Hash tmp;
3304 return EINA_FALSE; 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);
3305 3369
3306 tmem->subtype = desc->subtype; 3370 tmem->subtype = desc->subtype;
3371 if (!_eina_value_type_hash_create(tmem))
3372 return EINA_FALSE;
3307 3373
3308 return EINA_TRUE; 3374 return EINA_TRUE;
3309} 3375}
@@ -3424,7 +3490,7 @@ _eina_value_type_timeval_convert_to(const Eina_Value_Type *type __UNUSED__, cons
3424 return EINA_FALSE; 3490 return EINA_FALSE;
3425 return eina_value_type_pset(convert, convert_mem, &other_mem); 3491 return eina_value_type_pset(convert, convert_mem, &other_mem);
3426 } 3492 }
3427 else if (convert == EINA_VALUE_TYPE_ULONG) 3493 else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
3428 { 3494 {
3429 unsigned long other_mem = v.tv_sec; 3495 unsigned long other_mem = v.tv_sec;
3430 if (EINA_UNLIKELY(v.tv_sec < 0)) 3496 if (EINA_UNLIKELY(v.tv_sec < 0))
@@ -3570,6 +3636,8 @@ _eina_value_type_blob_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
3570 Eina_Value_Blob *tmem = mem; 3636 Eina_Value_Blob *tmem = mem;
3571 if ((ops) && (ops->free)) 3637 if ((ops) && (ops->free))
3572 ops->free(ops, (void *)tmem->memory, tmem->size); 3638 ops->free(ops, (void *)tmem->memory, tmem->size);
3639 tmem->memory = NULL;
3640 tmem->size = 0;
3573 return EINA_TRUE; 3641 return EINA_TRUE;
3574} 3642}
3575 3643
@@ -3776,6 +3844,14 @@ _eina_value_type_blob_pset(const Eina_Value_Type *type __UNUSED__, void *mem, co
3776 Eina_Value_Blob *tmem = mem; 3844 Eina_Value_Blob *tmem = mem;
3777 const Eina_Value_Blob *desc = ptr; 3845 const Eina_Value_Blob *desc = ptr;
3778 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
3779 if ((ops) && (ops->free)) 3855 if ((ops) && (ops->free))
3780 ops->free(ops, (void *)tmem->memory, tmem->size); 3856 ops->free(ops, (void *)tmem->memory, tmem->size);
3781 3857
@@ -3872,6 +3948,7 @@ _eina_value_struct_operations_stringshare_find_member(const Eina_Value_Struct_Op
3872 return itr; 3948 return itr;
3873 } 3949 }
3874 3950
3951 itr = desc->members;
3875 name = eina_stringshare_add(name); 3952 name = eina_stringshare_add(name);
3876 eina_stringshare_del(name); /* we'll not use the contents, this is fine */ 3953 eina_stringshare_del(name); /* we'll not use the contents, this is fine */
3877 /* stringshare and look again */ 3954 /* stringshare and look again */
@@ -3955,6 +4032,13 @@ _eina_value_type_struct_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
3955} 4032}
3956 4033
3957static Eina_Bool 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
3958_eina_value_type_struct_flush_member(const Eina_Value_Struct_Member *member, Eina_Value_Struct *st) 4042_eina_value_type_struct_flush_member(const Eina_Value_Struct_Member *member, Eina_Value_Struct *st)
3959{ 4043{
3960 unsigned char *base = st->memory; 4044 unsigned char *base = st->memory;
@@ -3969,6 +4053,9 @@ _eina_value_type_struct_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
3969 Eina_Value_Struct *tmem = mem; 4053 Eina_Value_Struct *tmem = mem;
3970 Eina_Bool ret = EINA_TRUE; 4054 Eina_Bool ret = EINA_TRUE;
3971 4055
4056 if ((!tmem->desc) || (!tmem->memory))
4057 return EINA_TRUE;
4058
3972 itr = tmem->desc->members; 4059 itr = tmem->desc->members;
3973 if (tmem->desc->member_count > 0) 4060 if (tmem->desc->member_count > 0)
3974 { 4061 {
@@ -3989,6 +4076,9 @@ _eina_value_type_struct_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
3989 else 4076 else
3990 free(tmem->memory); 4077 free(tmem->memory);
3991 4078
4079 tmem->memory = NULL;
4080 tmem->desc = NULL;
4081
3992 return ret; 4082 return ret;
3993} 4083}
3994 4084
@@ -4012,6 +4102,9 @@ _eina_value_type_struct_copy(const Eina_Value_Type *type __UNUSED__, const void
4012 4102
4013 *d = *s; 4103 *d = *s;
4014 4104
4105 if ((!s->desc) || (!s->memory))
4106 return EINA_TRUE;
4107
4015 ops = _eina_value_type_struct_ops_get(src); 4108 ops = _eina_value_type_struct_ops_get(src);
4016 if ((ops) && (ops->copy)) 4109 if ((ops) && (ops->copy))
4017 { 4110 {
@@ -4021,7 +4114,10 @@ _eina_value_type_struct_copy(const Eina_Value_Type *type __UNUSED__, const void
4021 return EINA_TRUE; 4114 return EINA_TRUE;
4022 } 4115 }
4023 4116
4024 d->memory = malloc(s->desc->size); 4117 if ((ops) && (ops->alloc))
4118 d->memory = ops->alloc(ops, s->desc);
4119 else
4120 d->memory = malloc(s->desc->size);
4025 if (!d->memory) 4121 if (!d->memory)
4026 { 4122 {
4027 eina_error_set(EINA_ERROR_OUT_OF_MEMORY); 4123 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
@@ -4043,14 +4139,17 @@ _eina_value_type_struct_copy(const Eina_Value_Type *type __UNUSED__, const void
4043 goto error; 4139 goto error;
4044 } 4140 }
4045 4141
4046
4047 return EINA_TRUE; 4142 return EINA_TRUE;
4048 4143
4049 error: 4144 error:
4050 itr--; 4145 itr--;
4051 for (; itr >= s->desc->members; itr--) 4146 for (; itr >= s->desc->members; itr--)
4052 _eina_value_type_struct_flush_member(itr, d); 4147 _eina_value_type_struct_flush_member(itr, d);
4053 free(d->memory); 4148
4149 if ((ops) && (ops->free))
4150 ops->free(ops, s->desc, d->memory);
4151 else
4152 free(d->memory);
4054 return EINA_FALSE; 4153 return EINA_FALSE;
4055} 4154}
4056 4155
@@ -4072,7 +4171,9 @@ _eina_value_type_struct_compare(const Eina_Value_Type *type __UNUSED__, const vo
4072 const Eina_Value_Struct_Member *itr; 4171 const Eina_Value_Struct_Member *itr;
4073 int cmp = 0; 4172 int cmp = 0;
4074 4173
4075 if (ta->desc != tb->desc) 4174 if ((!ta->desc) && (!tb->desc))
4175 return 0;
4176 else if (ta->desc != tb->desc)
4076 { 4177 {
4077 eina_error_set(EINA_ERROR_VALUE_FAILED); 4178 eina_error_set(EINA_ERROR_VALUE_FAILED);
4078 return -1; 4179 return -1;
@@ -4236,11 +4337,12 @@ _eina_value_type_struct_desc_check(const Eina_Value_Struct_Desc *desc)
4236} 4337}
4237 4338
4238static Eina_Bool 4339static Eina_Bool
4239_eina_value_type_struct_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) 4340_eina_value_type_struct_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
4240{ 4341{
4241 const Eina_Value_Struct_Operations *ops = _eina_value_type_struct_ops_get(mem); 4342 const Eina_Value_Struct_Operations *ops;
4242 Eina_Value_Struct *tmem = mem; 4343 Eina_Value_Struct *tmem = mem;
4243 const Eina_Value_Struct *desc = ptr; 4344 const Eina_Value_Struct *desc = ptr;
4345 const Eina_Value_Struct_Member *itr;
4244 4346
4245 if (!_eina_value_type_struct_desc_check(desc->desc)) 4347 if (!_eina_value_type_struct_desc_check(desc->desc))
4246 { 4348 {
@@ -4248,30 +4350,71 @@ _eina_value_type_struct_pset(const Eina_Value_Type *type __UNUSED__, void *mem,
4248 return EINA_FALSE; 4350 return EINA_FALSE;
4249 } 4351 }
4250 4352
4251 if ((ops) && (ops->free)) 4353 eina_error_set(0);
4252 ops->free(ops, tmem->desc, tmem->memory); 4354 if ((tmem->memory) && (tmem->memory == desc->memory))
4253 else 4355 {
4254 free(tmem->memory); 4356 tmem->desc = desc->desc;
4357 return EINA_TRUE;
4358 }
4255 4359
4256 *tmem = *desc; 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;
4257 4375
4258 ops = _eina_value_type_struct_ops_get(desc); 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
4259 if (!tmem->memory) 4382 if (!tmem->memory)
4260 { 4383 {
4261 if ((ops) && (ops->alloc)) 4384 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
4262 tmem->memory = ops->alloc(ops, tmem->desc); 4385 return EINA_FALSE;
4263 else 4386 }
4264 tmem->memory = malloc(tmem->desc->size);
4265 4387
4266 if (!tmem->memory) 4388 itr = tmem->desc->members;
4267 { 4389 if (tmem->desc->member_count > 0)
4268 eina_error_set(EINA_ERROR_OUT_OF_MEMORY); 4390 {
4269 return EINA_FALSE; 4391 const Eina_Value_Struct_Member *itr_end;
4270 } 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;
4271 } 4402 }
4272 4403
4273 eina_error_set(0);
4274 return EINA_TRUE; 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;
4275} 4418}
4276 4419
4277static Eina_Bool 4420static Eina_Bool
@@ -4304,6 +4447,130 @@ static const Eina_Value_Type _EINA_VALUE_TYPE_STRUCT = {
4304 _eina_value_type_struct_pget 4447 _eina_value_type_struct_pget
4305}; 4448};
4306 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
4307/* keep all basic types inlined in an array so we can compare if it's 4574/* keep all basic types inlined in an array so we can compare if it's
4308 * a basic type using pointer arithmetic. 4575 * a basic type using pointer arithmetic.
4309 * 4576 *
@@ -4506,6 +4773,20 @@ static const Eina_Value_Type _EINA_VALUE_TYPE_BASICS[] = {
4506 _eina_value_type_string_vset, 4773 _eina_value_type_string_vset,
4507 _eina_value_type_string_pset, 4774 _eina_value_type_string_pset,
4508 _eina_value_type_string_common_pget 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
4509 } 4790 }
4510}; 4791};
4511 4792
@@ -4722,11 +5003,12 @@ eina_value_init(void)
4722 EINA_VALUE_TYPE_DOUBLE = _EINA_VALUE_TYPE_BASICS + 11; 5003 EINA_VALUE_TYPE_DOUBLE = _EINA_VALUE_TYPE_BASICS + 11;
4723 EINA_VALUE_TYPE_STRINGSHARE = _EINA_VALUE_TYPE_BASICS + 12; 5004 EINA_VALUE_TYPE_STRINGSHARE = _EINA_VALUE_TYPE_BASICS + 12;
4724 EINA_VALUE_TYPE_STRING = _EINA_VALUE_TYPE_BASICS + 13; 5005 EINA_VALUE_TYPE_STRING = _EINA_VALUE_TYPE_BASICS + 13;
5006 EINA_VALUE_TYPE_TIMESTAMP = _EINA_VALUE_TYPE_BASICS + 14;
4725 5007
4726 _EINA_VALUE_TYPE_BASICS_START = _EINA_VALUE_TYPE_BASICS + 0; 5008 _EINA_VALUE_TYPE_BASICS_START = _EINA_VALUE_TYPE_BASICS + 0;
4727 _EINA_VALUE_TYPE_BASICS_END = _EINA_VALUE_TYPE_BASICS + 13; 5009 _EINA_VALUE_TYPE_BASICS_END = _EINA_VALUE_TYPE_BASICS + 14;
4728 5010
4729 EINA_SAFETY_ON_FALSE_RETURN_VAL((sizeof(_EINA_VALUE_TYPE_BASICS)/sizeof(_EINA_VALUE_TYPE_BASICS[0])) == 14, EINA_FALSE); 5011 EINA_SAFETY_ON_FALSE_RETURN_VAL((sizeof(_EINA_VALUE_TYPE_BASICS)/sizeof(_EINA_VALUE_TYPE_BASICS[0])) == 15, EINA_FALSE);
4730 5012
4731 5013
4732 EINA_VALUE_TYPE_ARRAY = &_EINA_VALUE_TYPE_ARRAY; 5014 EINA_VALUE_TYPE_ARRAY = &_EINA_VALUE_TYPE_ARRAY;
@@ -4735,6 +5017,7 @@ eina_value_init(void)
4735 EINA_VALUE_TYPE_TIMEVAL = &_EINA_VALUE_TYPE_TIMEVAL; 5017 EINA_VALUE_TYPE_TIMEVAL = &_EINA_VALUE_TYPE_TIMEVAL;
4736 EINA_VALUE_TYPE_BLOB = &_EINA_VALUE_TYPE_BLOB; 5018 EINA_VALUE_TYPE_BLOB = &_EINA_VALUE_TYPE_BLOB;
4737 EINA_VALUE_TYPE_STRUCT = &_EINA_VALUE_TYPE_STRUCT; 5019 EINA_VALUE_TYPE_STRUCT = &_EINA_VALUE_TYPE_STRUCT;
5020 EINA_VALUE_TYPE_MODEL = &_EINA_VALUE_TYPE_MODEL;
4738 5021
4739 EINA_VALUE_BLOB_OPERATIONS_MALLOC = &_EINA_VALUE_BLOB_OPERATIONS_MALLOC; 5022 EINA_VALUE_BLOB_OPERATIONS_MALLOC = &_EINA_VALUE_BLOB_OPERATIONS_MALLOC;
4740 5023
@@ -4800,6 +5083,7 @@ EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UCHAR = NULL;
4800EAPI const Eina_Value_Type *EINA_VALUE_TYPE_USHORT = NULL; 5083EAPI const Eina_Value_Type *EINA_VALUE_TYPE_USHORT = NULL;
4801EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT = NULL; 5084EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT = NULL;
4802EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ULONG = NULL; 5085EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ULONG = NULL;
5086EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMESTAMP = NULL;
4803EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT64 = NULL; 5087EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT64 = NULL;
4804EAPI const Eina_Value_Type *EINA_VALUE_TYPE_CHAR = NULL; 5088EAPI const Eina_Value_Type *EINA_VALUE_TYPE_CHAR = NULL;
4805EAPI const Eina_Value_Type *EINA_VALUE_TYPE_SHORT = NULL; 5089EAPI const Eina_Value_Type *EINA_VALUE_TYPE_SHORT = NULL;
@@ -4816,6 +5100,7 @@ EAPI const Eina_Value_Type *EINA_VALUE_TYPE_HASH = NULL;
4816EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMEVAL = NULL; 5100EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMEVAL = NULL;
4817EAPI const Eina_Value_Type *EINA_VALUE_TYPE_BLOB = NULL; 5101EAPI const Eina_Value_Type *EINA_VALUE_TYPE_BLOB = NULL;
4818EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRUCT = NULL; 5102EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRUCT = NULL;
5103EAPI const Eina_Value_Type *EINA_VALUE_TYPE_MODEL = NULL;
4819 5104
4820EAPI const Eina_Value_Blob_Operations *EINA_VALUE_BLOB_OPERATIONS_MALLOC = NULL; 5105EAPI const Eina_Value_Blob_Operations *EINA_VALUE_BLOB_OPERATIONS_MALLOC = NULL;
4821 5106