diff options
Diffstat (limited to '')
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 | ||
12 | base_sources = \ | 12 | base_sources = \ |
13 | eina_accessor.c \ | 13 | eina_accessor.c \ |
@@ -33,6 +33,7 @@ eina_main.c \ | |||
33 | eina_matrixsparse.c \ | 33 | eina_matrixsparse.c \ |
34 | eina_mempool.c \ | 34 | eina_mempool.c \ |
35 | eina_mmap.c \ | 35 | eina_mmap.c \ |
36 | eina_model.c \ | ||
36 | eina_module.c \ | 37 | eina_module.c \ |
37 | eina_prefix.c \ | 38 | eina_prefix.c \ |
38 | eina_quadtree.c \ | 39 | eina_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@ | |||
49 | subdir = src/lib | 49 | subdir = src/lib |
50 | DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in | 50 | DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in |
51 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | 51 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 |
52 | am__aclocal_m4_deps = $(top_srcdir)/m4/efl_attribute.m4 \ | 52 | am__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 | ||
66 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ | 70 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ |
67 | $(ACLOCAL_M4) | 71 | $(ACLOCAL_M4) |
68 | mkinstalldirs = $(install_sh) -d | 72 | mkinstalldirs = $(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@ | |||
236 | EINA_CONFIGURE_ENABLE_LOG = @EINA_CONFIGURE_ENABLE_LOG@ | 240 | EINA_CONFIGURE_ENABLE_LOG = @EINA_CONFIGURE_ENABLE_LOG@ |
237 | EINA_CONFIGURE_HAVE_DEBUG_THREADS = @EINA_CONFIGURE_HAVE_DEBUG_THREADS@ | 241 | EINA_CONFIGURE_HAVE_DEBUG_THREADS = @EINA_CONFIGURE_HAVE_DEBUG_THREADS@ |
238 | EINA_CONFIGURE_HAVE_DIRENT_H = @EINA_CONFIGURE_HAVE_DIRENT_H@ | 242 | EINA_CONFIGURE_HAVE_DIRENT_H = @EINA_CONFIGURE_HAVE_DIRENT_H@ |
243 | EINA_CONFIGURE_HAVE_EXOTIC = @EINA_CONFIGURE_HAVE_EXOTIC@ | ||
239 | EINA_CONFIGURE_HAVE_INTTYPES_H = @EINA_CONFIGURE_HAVE_INTTYPES_H@ | 244 | EINA_CONFIGURE_HAVE_INTTYPES_H = @EINA_CONFIGURE_HAVE_INTTYPES_H@ |
240 | EINA_CONFIGURE_HAVE_ON_OFF_THREADS = @EINA_CONFIGURE_HAVE_ON_OFF_THREADS@ | 245 | EINA_CONFIGURE_HAVE_ON_OFF_THREADS = @EINA_CONFIGURE_HAVE_ON_OFF_THREADS@ |
241 | EINA_CONFIGURE_HAVE_STDINT_H = @EINA_CONFIGURE_HAVE_STDINT_H@ | 246 | EINA_CONFIGURE_HAVE_STDINT_H = @EINA_CONFIGURE_HAVE_STDINT_H@ |
242 | EINA_CONFIGURE_HAVE_THREADS = @EINA_CONFIGURE_HAVE_THREADS@ | 247 | EINA_CONFIGURE_HAVE_THREADS = @EINA_CONFIGURE_HAVE_THREADS@ |
243 | EINA_CONFIGURE_MAGIC_DEBUG = @EINA_CONFIGURE_MAGIC_DEBUG@ | 248 | EINA_CONFIGURE_MAGIC_DEBUG = @EINA_CONFIGURE_MAGIC_DEBUG@ |
244 | EINA_CONFIGURE_SAFETY_CHECKS = @EINA_CONFIGURE_SAFETY_CHECKS@ | 249 | EINA_CONFIGURE_SAFETY_CHECKS = @EINA_CONFIGURE_SAFETY_CHECKS@ |
245 | EINA_CPPFLAGS = @EINA_CPPFLAGS@ | ||
246 | EINA_LIBS = @EINA_LIBS@ | 250 | EINA_LIBS = @EINA_LIBS@ |
247 | EINA_SIZEOF_WCHAR_T = @EINA_SIZEOF_WCHAR_T@ | 251 | EINA_SIZEOF_WCHAR_T = @EINA_SIZEOF_WCHAR_T@ |
248 | EMEMOA_CFLAGS = @EMEMOA_CFLAGS@ | 252 | EMEMOA_CFLAGS = @EMEMOA_CFLAGS@ |
@@ -252,6 +256,8 @@ ESCAPE_LIBS = @ESCAPE_LIBS@ | |||
252 | EVIL_CFLAGS = @EVIL_CFLAGS@ | 256 | EVIL_CFLAGS = @EVIL_CFLAGS@ |
253 | EVIL_LIBS = @EVIL_LIBS@ | 257 | EVIL_LIBS = @EVIL_LIBS@ |
254 | EXEEXT = @EXEEXT@ | 258 | EXEEXT = @EXEEXT@ |
259 | EXOTIC_CFLAGS = @EXOTIC_CFLAGS@ | ||
260 | EXOTIC_LIBS = @EXOTIC_LIBS@ | ||
255 | FGREP = @FGREP@ | 261 | FGREP = @FGREP@ |
256 | GLIB_CFLAGS = @GLIB_CFLAGS@ | 262 | GLIB_CFLAGS = @GLIB_CFLAGS@ |
257 | GLIB_LIBS = @GLIB_LIBS@ | 263 | GLIB_LIBS = @GLIB_LIBS@ |
@@ -287,6 +293,8 @@ PACKAGE_URL = @PACKAGE_URL@ | |||
287 | PACKAGE_VERSION = @PACKAGE_VERSION@ | 293 | PACKAGE_VERSION = @PACKAGE_VERSION@ |
288 | PATH_SEPARATOR = @PATH_SEPARATOR@ | 294 | PATH_SEPARATOR = @PATH_SEPARATOR@ |
289 | PKG_CONFIG = @PKG_CONFIG@ | 295 | PKG_CONFIG = @PKG_CONFIG@ |
296 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ | ||
297 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ | ||
290 | RANLIB = @RANLIB@ | 298 | RANLIB = @RANLIB@ |
291 | SED = @SED@ | 299 | SED = @SED@ |
292 | SET_MAKE = @SET_MAKE@ | 300 | SET_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 | ||
373 | base_sources = eina_accessor.c eina_array.c eina_benchmark.c \ | 381 | base_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) | ||
387 | EXTRA_DIST = \ | 396 | EXTRA_DIST = \ |
388 | eina_share_common.h \ | 397 | eina_share_common.h \ |
389 | eina_private.h \ | 398 | eina_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 | ||
745 | libeina_la-eina_model.lo: eina_model.c | ||
746 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_model.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_model.Tpo -c -o libeina_la-eina_model.lo `test -f 'eina_model.c' || echo '$(srcdir)/'`eina_model.c | ||
747 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_model.Tpo $(DEPDIR)/libeina_la-eina_model.Plo | ||
748 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
749 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_model.c' object='libeina_la-eina_model.lo' libtool=yes @AMDEPBACKSLASH@ | ||
750 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
751 | @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_model.lo `test -f 'eina_model.c' || echo '$(srcdir)/'`eina_model.c | ||
752 | |||
735 | libeina_la-eina_module.lo: eina_module.c | 753 | libeina_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 | |||
61 | static int _eina_share_binshare_log_dom = -1; | ||
62 | |||
37 | /* The actual share */ | 63 | /* The actual share */ |
38 | static Eina_Share *binshare_share; | 64 | static Eina_Share *binshare_share; |
39 | static const char EINA_MAGIC_BINSHARE_NODE_STR[] = "Eina Binshare Node"; | 65 | static 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"; | |||
61 | EAPI Eina_Bool | 86 | EAPI Eina_Bool |
62 | eina_binshare_init(void) | 87 | eina_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 | ||
102 | EAPI const void * | 157 | EAPI 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) | |||
362 | static Eina_Bool | 362 | static 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 | |||
596 | Eina_Bool | 578 | Eina_Bool |
597 | eina_file_init(void) | 579 | eina_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 | /** | 626 | void |
645 | * @endcond | 627 | eina_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 | |||
1217 | eina_file_map_faulted(Eina_File *file, void *map) | 1246 | eina_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 | ||
1233 | EAPI Eina_Iterator * | 1270 | EAPI 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 | ||
1249 | void | 1286 | EAPI int |
1250 | eina_file_mmap_faulty(void *addr, long page_size) | 1287 | eina_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 |
35 | extern "C" | 35 | extern "C" |
36 | # endif | 36 | # endif |
37 | void *alloca (size_t); | 37 | void *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 | ||
88 | typedef struct _Eina_File_Iterator Eina_File_Iterator; | 88 | #ifdef MAP_FAILED |
89 | typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator; | 89 | # undef MAP_FAILED |
90 | typedef struct _Eina_File_Map Eina_File_Map; | 90 | #endif |
91 | 91 | #define MAP_FAILED ((void *)-1) | |
92 | struct _Eina_File_Iterator | 92 | |
93 | { | 93 | typedef struct _Eina_File_Iterator Eina_File_Iterator; |
94 | Eina_Iterator iterator; | 94 | typedef struct _Eina_File_Direct_Iterator Eina_File_Direct_Iterator; |
95 | 95 | typedef struct _Eina_File_Map Eina_File_Map; | |
96 | WIN32_FIND_DATA data; | 96 | |
97 | HANDLE handle; | 97 | struct _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; | |
104 | struct _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; | 109 | struct _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 | ||
118 | struct _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; | 123 | struct _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 | ||
139 | struct _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; | 146 | struct _Eina_File_Map |
147 | }; | 147 | { |
148 | 148 | void *map; | |
149 | static Eina_Hash *_eina_file_cache = NULL; | 149 | |
150 | static Eina_List *_eina_file_cache_lru = NULL; | 150 | unsigned long int offset; |
151 | static Eina_List *_eina_file_cache_delete = NULL; | 151 | unsigned long int length; |
152 | 152 | ||
153 | static int _eina_file_log_dom = -1; | 153 | int refcount; |
154 | 154 | }; | |
155 | static void | 155 | |
156 | _eina_file_win32_backslash_change(char *dir) | 156 | static Eina_Hash *_eina_file_cache = NULL; |
157 | { | 157 | static Eina_Lock _eina_file_lock_cache; |
158 | char *tmp; | 158 | |
159 | 159 | static int _eina_file_log_dom = -1; | |
160 | tmp = dir; | 160 | |
161 | while (*tmp) | 161 | static 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) | |
168 | static 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; | 174 | static 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 | ||
197 | static 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); | 203 | static 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); | |
216 | static 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 | 222 | static 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)) | |
247 | static 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; | 253 | static 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 | ||
313 | static 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 | ||
319 | static void | 319 | static 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); | 325 | static 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) | |
329 | static 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; | 335 | static 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 | ||
427 | static 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 | ||
433 | static void | 433 | static 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); | 439 | static 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) | |
443 | static 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) | 449 | static 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); | |
460 | static 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); | 464 | static void |
465 | free(map); | 465 | _eina_file_map_close(Eina_File_Map *map) |
466 | } | 466 | { |
467 | 467 | if (map->map != MAP_FAILED) | |
468 | static 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 | } | 472 | static unsigned int |
473 | 473 | _eina_file_map_key_length(const void *key __UNUSED__) | |
474 | static 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]; | 478 | static 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 | { | |
482 | static 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)); | 486 | static int |
487 | } | 487 | _eina_file_map_key_hash(const unsigned long int *key, int key_length __UNUSED__) |
488 | 488 | { | |
489 | Eina_Bool | 489 | return eina_hash_int64(&key[0], sizeof (unsigned long int)) |
490 | eina_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); | 493 | static 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 | { | |
512 | Eina_Bool | 512 | memmove(p, p + 1, --len - (p - result)); |
513 | eina_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; | |
555 | EAPI Eina_Bool | 555 | } |
556 | eina_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) | 573 | Eina_Bool |
574 | return EINA_FALSE; | 574 | eina_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 | 598 | Eina_Bool | |
599 | path = alloca(strlen(dir) + strlen(filename) + 2); | 599 | eina_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 | } | |
620 | EAPI Eina_Array * | 620 | |
621 | eina_file_split(char *path) | 621 | /*============================================================================* |
622 | { | 622 | * API * |
623 | Eina_Array *ea; | 623 | *============================================================================*/ |
624 | char *current; | 624 | |
625 | size_t length; | 625 | |
626 | 626 | EAPI char * | |
627 | EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); | 627 | eina_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 | ||
653 | EAPI Eina_Iterator * | 653 | len += l + 2; |
654 | eina_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 | 665 | EAPI Eina_Bool | |
666 | length = strlen(dir); | 666 | eina_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 | ||
703 | EAPI Eina_Iterator * | 703 | cb(filename, dir, data); |
704 | eina_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) | 730 | EAPI Eina_Array * |
731 | goto free_it; | 731 | eina_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 | ||
760 | EAPI Eina_Iterator * | 760 | return ea; |
761 | eina_file_stat_ls(const char *dir) | 761 | } |
762 | { | 762 | |
763 | return eina_file_direct_ls(dir); | 763 | EAPI Eina_Iterator * |
764 | } | 764 | eina_file_ls(const char *dir) |
765 | 765 | { | |
766 | EAPI Eina_File * | 766 | Eina_File_Iterator *it; |
767 | eina_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 | { | 815 | EAPI Eina_Iterator * |
816 | _eina_file_cache_lru = eina_list_prepend(_eina_file_cache_lru, file); | 816 | eina_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 | 874 | EAPI Eina_Iterator * | |
875 | EAPI void | 875 | eina_file_stat_ls(const char *dir) |
876 | eina_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 ; | 880 | EAPI Eina_File * |
881 | 881 | eina_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); | |
893 | EAPI size_t | 893 | |
894 | eina_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 | |
899 | EAPI time_t | 899 | if (shared) |
900 | eina_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 | |
905 | EAPI const char * | 905 | handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, |
906 | eina_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; | |
911 | EAPI void * | 911 | |
912 | eina_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 | } | |
935 | EAPI void * | 935 | |
936 | eina_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 | } | |
989 | EAPI void | 989 | |
990 | eina_file_map_free(Eina_File *file, void *map) | 990 | EAPI void |
991 | { | 991 | eina_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); | 1008 | EAPI size_t |
1009 | if (!em) return ; | 1009 | eina_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; | 1015 | EAPI time_t |
1016 | key[1] = em->length; | 1016 | eina_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 | |
1022 | EAPI const char * | ||
1023 | eina_file_filename_get(Eina_File *file) | ||
1024 | { | ||
1025 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
1026 | return file->filename; | ||
1027 | } | ||
1028 | |||
1029 | EAPI Eina_Iterator *eina_file_xattr_get(Eina_File *file __UNUSED__) | ||
1030 | { | ||
1031 | return NULL; | ||
1032 | } | ||
1033 | |||
1034 | EAPI Eina_Iterator *eina_file_xattr_value_get(Eina_File *file __UNUSED__) | ||
1035 | { | ||
1036 | return NULL; | ||
1037 | } | ||
1038 | |||
1039 | EAPI void * | ||
1040 | eina_file_map_all(Eina_File *file, Eina_File_Populate rule __UNUSED__) | ||
1041 | { | ||
1042 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
1043 | |||
1044 | eina_lock_take(&file->lock); | ||
1045 | if (file->global_map == MAP_FAILED) | ||
1046 | { | ||
1047 | void *data; | ||
1048 | |||
1049 | data = MapViewOfFile(file->fm, FILE_MAP_READ, | ||
1050 | 0, 0, file->length); | ||
1051 | if (!data) | ||
1052 | file->global_map = MAP_FAILED; | ||
1053 | else | ||
1054 | file->global_map = data; | ||
1055 | } | ||
1056 | |||
1057 | if (file->global_map != MAP_FAILED) | ||
1058 | { | ||
1059 | file->global_refcount++; | ||
1060 | return file->global_map; | ||
1061 | } | ||
1062 | |||
1063 | eina_lock_release(&file->lock); | ||
1064 | return NULL; | ||
1065 | } | ||
1066 | |||
1067 | EAPI void * | ||
1068 | eina_file_map_new(Eina_File *file, Eina_File_Populate rule, | ||
1069 | unsigned long int offset, unsigned long int length) | ||
1070 | { | ||
1071 | Eina_File_Map *map; | ||
1072 | unsigned long int key[2]; | ||
1073 | |||
1074 | EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); | ||
1075 | |||
1076 | if (offset > file->length) | ||
1077 | return NULL; | ||
1078 | if (offset + length > file->length) | ||
1079 | return NULL; | ||
1080 | |||
1081 | if (offset == 0 && length == file->length) | ||
1082 | return eina_file_map_all(file, rule); | ||
1083 | |||
1084 | key[0] = offset; | ||
1085 | key[1] = length; | ||
1086 | |||
1087 | eina_lock_take(&file->lock); | ||
1088 | |||
1089 | map = eina_hash_find(file->map, &key); | ||
1090 | if (!map) | ||
1091 | { | ||
1092 | void *data; | ||
1093 | |||
1094 | map = malloc(sizeof (Eina_File_Map)); | ||
1095 | if (!map) | ||
1096 | { | ||
1097 | eina_lock_release(&file->lock); | ||
1098 | return NULL; | ||
1099 | } | ||
1100 | |||
1101 | data = MapViewOfFile(file->fm, FILE_MAP_READ, | ||
1102 | offset & 0xffff0000, | ||
1103 | offset & 0x0000ffff, | ||
1104 | length); | ||
1105 | if (!data) | ||
1106 | map->map = MAP_FAILED; | ||
1107 | else | ||
1108 | map->map = data; | ||
1109 | |||
1110 | map->offset = offset; | ||
1111 | map->length = length; | ||
1112 | map->refcount = 0; | ||
1113 | |||
1114 | if (map->map == MAP_FAILED) | ||
1115 | { | ||
1116 | free(map); | ||
1117 | eina_lock_release(&file->lock); | ||
1118 | return NULL; | ||
1119 | } | ||
1120 | |||
1121 | eina_hash_add(file->map, &key, map); | ||
1122 | eina_hash_direct_add(file->rmap, map->map, map); | ||
1123 | } | ||
1124 | |||
1125 | map->refcount++; | ||
1126 | |||
1127 | eina_lock_release(&file->lock); | ||
1128 | |||
1129 | return map->map; | ||
1130 | } | ||
1131 | |||
1132 | EAPI void | ||
1133 | eina_file_map_free(Eina_File *file, void *map) | ||
1134 | { | ||
1135 | EINA_SAFETY_ON_NULL_RETURN(file); | ||
1136 | |||
1137 | eina_lock_take(&file->lock); | ||
1138 | |||
1139 | if (file->global_map == map) | ||
1140 | { | ||
1141 | file->global_refcount--; | ||
1142 | |||
1143 | if (file->global_refcount > 0) goto on_exit; | ||
1144 | |||
1145 | UnmapViewOfFile(file->global_map); | ||
1146 | file->global_map = MAP_FAILED; | ||
1147 | } | ||
1148 | else | ||
1149 | { | ||
1150 | Eina_File_Map *em; | ||
1151 | unsigned long int key[2]; | ||
1152 | |||
1153 | em = eina_hash_find(file->rmap, &map); | ||
1154 | if (!em) goto on_exit; | ||
1155 | |||
1156 | em->refcount--; | ||
1157 | |||
1158 | if (em->refcount > 0) goto on_exit; | ||
1159 | |||
1160 | key[0] = em->offset; | ||
1161 | key[1] = em->length; | ||
1162 | |||
1163 | eina_hash_del(file->rmap, &map, em); | ||
1164 | eina_hash_del(file->map, &key, em); | ||
1165 | } | ||
1166 | |||
1167 | on_exit: | ||
1168 | eina_lock_release(&file->lock); | ||
1169 | } | ||
1170 | |||
1171 | EAPI int | ||
1172 | eina_file_statat(void *container __UNUSED__, Eina_File_Direct_Info *info, Eina_Stat *st) | ||
1173 | { | ||
1174 | struct __stat64 buf; | ||
1175 | |||
1176 | EINA_SAFETY_ON_NULL_RETURN_VAL(info, -1); | ||
1177 | EINA_SAFETY_ON_NULL_RETURN_VAL(st, -1); | ||
1178 | |||
1179 | if (stat64(info->path, &buf)) | ||
1180 | { | ||
1181 | if (info->type != EINA_FILE_LNK) | ||
1182 | info->type = EINA_FILE_UNKNOWN; | ||
1183 | return -1; | ||
1184 | } | ||
1185 | |||
1186 | if (info->type == EINA_FILE_UNKNOWN) | ||
1187 | { | ||
1188 | if (S_ISREG(buf.st_mode)) | ||
1189 | info->type = EINA_FILE_REG; | ||
1190 | else if (S_ISDIR(buf.st_mode)) | ||
1191 | info->type = EINA_FILE_DIR; | ||
1192 | else | ||
1193 | info->type = EINA_FILE_UNKNOWN; | ||
1194 | } | ||
1195 | |||
1196 | st->dev = buf.st_dev; | ||
1197 | st->ino = buf.st_ino; | ||
1198 | st->mode = buf.st_mode; | ||
1199 | st->nlink = buf.st_nlink; | ||
1200 | st->uid = buf.st_uid; | ||
1201 | st->gid = buf.st_gid; | ||
1202 | st->rdev = buf.st_rdev; | ||
1203 | st->size = buf.st_size; | ||
1204 | st->blksize = 0; | ||
1205 | st->blocks = 0; | ||
1206 | st->atime = buf.st_atime; | ||
1207 | st->mtime = buf.st_mtime; | ||
1208 | st->ctime = buf.st_ctime; | ||
1209 | st->atimensec = 0; | ||
1210 | st->mtimensec = 0; | ||
1211 | st->ctimensec = 0; | ||
1212 | |||
1213 | return 0; | ||
1214 | } | ||
diff --git a/libraries/eina/src/lib/eina_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 | ||
1028 | EAPI Eina_List * | 1028 | EAPI Eina_List * |
1029 | eina_list_sort(Eina_List *list, unsigned int size, Eina_Compare_Cb func) | 1029 | eina_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 | ||
158 | struct eina_desc_setup | 160 | struct 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 | }; |
195 | static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) / | 198 | static 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 |
43 | extern "C" | 43 | extern "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 | ||
357 | end_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 | ||
47 | EAPI void | 47 | EAPI 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, ¶m); | 74 | pthread_setschedparam(pthread_id, pol, ¶m); |
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; | |||
126 | typedef struct _Eina_Share_Common_Node Eina_Share_Common_Node; | 125 | typedef struct _Eina_Share_Common_Node Eina_Share_Common_Node; |
127 | typedef struct _Eina_Share_Common_Head Eina_Share_Common_Head; | 126 | typedef struct _Eina_Share_Common_Head Eina_Share_Common_Head; |
128 | 127 | ||
129 | int _eina_share_common_log_dom = -1; | ||
130 | |||
131 | struct _Eina_Share | 128 | struct _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 | ||
836 | void | 808 | Eina_Bool |
837 | eina_share_common_del(Eina_Share *share, const char *str) | 809 | eina_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 | ||
891 | on_error: | 863 | on_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 | ||
897 | int | 869 | int |
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) |
72 | EINA_WARN_UNUSED_RESULT; | 72 | EINA_WARN_UNUSED_RESULT; |
73 | const char *eina_share_common_ref(Eina_Share *share, const char *str); | 73 | const char *eina_share_common_ref(Eina_Share *share, const char *str); |
74 | void eina_share_common_del(Eina_Share *share, const char *str); | 74 | Eina_Bool eina_share_common_del(Eina_Share *share, const char *str) EINA_WARN_UNUSED_RESULT; |
75 | int eina_share_common_length(Eina_Share *share, | 75 | int eina_share_common_length(Eina_Share *share, |
76 | const char *str) EINA_CONST | 76 | const char *str) EINA_CONST |
77 | EINA_WARN_UNUSED_RESULT; | 77 | EINA_WARN_UNUSED_RESULT; |
@@ -83,21 +83,4 @@ void eina_share_common_dump(Eina_Share *share, void (*additional_dump)( | |||
83 | void eina_share_common_population_add(Eina_Share *share, int slen); | 83 | void eina_share_common_population_add(Eina_Share *share, int slen); |
84 | void eina_share_common_population_del(Eina_Share *share, int slen); | 84 | void 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__) | ||
101 | extern 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 | |||
81 | static int _eina_share_stringshare_log_dom = -1; | ||
64 | 82 | ||
65 | /* The actual share */ | 83 | /* The actual share */ |
66 | static Eina_Share *stringshare_share; | 84 | static 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 | |||
500 | eina_stringshare_init(void) | 515 | eina_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 | ||
536 | EAPI void | 576 | EAPI void |
537 | eina_stringshare_del(const char *str) | 577 | eina_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 | ||
570 | EAPI const char * | 611 | EAPI Eina_Stringshare * |
571 | eina_stringshare_add_length(const char *str, unsigned int slen) | 612 | eina_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 | ||
591 | EAPI const char * | 632 | EAPI Eina_Stringshare * |
592 | eina_stringshare_add(const char *str) | 633 | eina_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 | ||
612 | EAPI const char * | 653 | EAPI Eina_Stringshare * |
613 | eina_stringshare_printf(const char *fmt, ...) | 654 | eina_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 | ||
636 | EAPI const char * | 677 | EAPI Eina_Stringshare * |
637 | eina_stringshare_vprintf(const char *fmt, va_list args) | 678 | eina_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 | ||
657 | EAPI const char * | 698 | EAPI Eina_Stringshare * |
658 | eina_stringshare_nprintf(unsigned int len, const char *fmt, ...) | 699 | eina_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 | ||
682 | EAPI const char * | 723 | EAPI Eina_Stringshare * |
683 | eina_stringshare_ref(const char *str) | 724 | eina_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 | ||
723 | EAPI int | 764 | EAPI int |
724 | eina_stringshare_strlen(const char *str) | 765 | eina_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; | |||
30 | EAPI int | 38 | EAPI int |
31 | eina_unicode_strcmp(const Eina_Unicode *a, const Eina_Unicode *b) | 39 | eina_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 | |||
67 | eina_unicode_strlen(const Eina_Unicode *ustr) | 84 | eina_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: | |||
266 | EAPI Eina_Unicode | 301 | EAPI Eina_Unicode |
267 | eina_unicode_utf8_get_prev(const char *buf, int *iindex) | 302 | eina_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 | |||
60 | static int _eina_share_ustringshare_log_dom = -1; | ||
61 | |||
35 | /* The actual share */ | 62 | /* The actual share */ |
36 | static Eina_Share *ustringshare_share; | 63 | static Eina_Share *ustringshare_share; |
37 | static const char EINA_MAGIC_USTRINGSHARE_NODE_STR[] = "Eina UStringshare Node"; | 64 | static 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"; | |||
54 | Eina_Bool | 81 | Eina_Bool |
55 | eina_ustringshare_init(void) | 82 | eina_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 | ||
94 | EAPI const Eina_Unicode * | 151 | EAPI 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 | ||
2608 | static Eina_Bool | 2631 | static 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 | ||
2934 | static Eina_Bool | 2965 | static 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 | ||
3290 | static Eina_Bool | 3340 | static 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 | ||
3957 | static Eina_Bool | 4034 | static Eina_Bool |
4035 | _eina_value_type_struct_setup_member(const Eina_Value_Struct_Member *member, Eina_Value_Struct *st) | ||
4036 | { | ||
4037 | unsigned char *base = st->memory; | ||
4038 | return eina_value_type_setup(member->type, base + member->offset); | ||
4039 | } | ||
4040 | |||
4041 | static Eina_Bool | ||
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 | ||
4238 | static Eina_Bool | 4339 | static 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 | ||
4277 | static Eina_Bool | 4420 | static 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 | ||
4450 | static Eina_Bool | ||
4451 | _eina_value_type_model_setup(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
4452 | { | ||
4453 | Eina_Model **tmem = mem; | ||
4454 | *tmem = NULL; | ||
4455 | return EINA_TRUE; | ||
4456 | } | ||
4457 | |||
4458 | static Eina_Bool | ||
4459 | _eina_value_type_model_flush(const Eina_Value_Type *type __UNUSED__, void *mem) | ||
4460 | { | ||
4461 | Eina_Model **tmem = mem; | ||
4462 | if (*tmem) | ||
4463 | { | ||
4464 | eina_model_unref(*tmem); | ||
4465 | *tmem = NULL; | ||
4466 | } | ||
4467 | return EINA_TRUE; | ||
4468 | } | ||
4469 | |||
4470 | static Eina_Bool | ||
4471 | _eina_value_type_model_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) | ||
4472 | { | ||
4473 | const Eina_Model * const *s = src; | ||
4474 | Eina_Model **d = dst; | ||
4475 | if (*s) | ||
4476 | *d = eina_model_copy(*s); /* is it better to deep-copy? */ | ||
4477 | else | ||
4478 | *d = NULL; | ||
4479 | return EINA_TRUE; | ||
4480 | } | ||
4481 | |||
4482 | static int | ||
4483 | _eina_value_type_model_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) | ||
4484 | { | ||
4485 | const Eina_Model * const *ta = a; | ||
4486 | const Eina_Model * const *tb = b; | ||
4487 | |||
4488 | if ((!*ta) && (!*tb)) return 0; | ||
4489 | else if (!*ta) return 1; | ||
4490 | else if (!*tb) return -1; | ||
4491 | else return eina_model_compare(*ta, *tb); | ||
4492 | } | ||
4493 | |||
4494 | static Eina_Bool | ||
4495 | _eina_value_type_model_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) | ||
4496 | { | ||
4497 | const Eina_Model *v = *(const Eina_Model **)type_mem; | ||
4498 | |||
4499 | eina_error_set(0); | ||
4500 | |||
4501 | if (convert == EINA_VALUE_TYPE_STRINGSHARE || | ||
4502 | convert == EINA_VALUE_TYPE_STRING) | ||
4503 | { | ||
4504 | char *other_mem = v ? eina_model_to_string(v) : NULL; | ||
4505 | Eina_Bool ret = eina_value_type_pset(convert, convert_mem, &other_mem); | ||
4506 | free(other_mem); | ||
4507 | return ret; | ||
4508 | } | ||
4509 | else | ||
4510 | { | ||
4511 | eina_error_set(EINA_ERROR_VALUE_FAILED); | ||
4512 | return EINA_FALSE; | ||
4513 | } | ||
4514 | |||
4515 | return EINA_TRUE; | ||
4516 | } | ||
4517 | |||
4518 | static Eina_Bool | ||
4519 | _eina_value_type_model_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) | ||
4520 | { | ||
4521 | Eina_Model **tmem = mem, *tmp; | ||
4522 | |||
4523 | tmp = va_arg(args, Eina_Model *); | ||
4524 | |||
4525 | if (tmp) eina_model_ref(tmp); | ||
4526 | if (*tmem) eina_model_unref(*tmem); | ||
4527 | |||
4528 | *tmem = tmp; | ||
4529 | |||
4530 | return EINA_TRUE; | ||
4531 | } | ||
4532 | |||
4533 | static Eina_Bool | ||
4534 | _eina_value_type_model_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) | ||
4535 | { | ||
4536 | Eina_Model **tmem = mem; | ||
4537 | Eina_Model **p = (Eina_Model **)ptr; | ||
4538 | |||
4539 | eina_error_set(0); | ||
4540 | if (*tmem == *p) return EINA_TRUE; | ||
4541 | |||
4542 | if (*p) eina_model_ref(*p); | ||
4543 | if (*tmem) eina_model_unref(*tmem); | ||
4544 | |||
4545 | *tmem = *p; | ||
4546 | |||
4547 | return EINA_TRUE; | ||
4548 | } | ||
4549 | |||
4550 | static Eina_Bool | ||
4551 | _eina_value_type_model_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) | ||
4552 | { | ||
4553 | Eina_Model **tmem = (Eina_Model **)mem; | ||
4554 | Eina_Model **p = ptr; | ||
4555 | *p = *tmem; | ||
4556 | return EINA_TRUE; | ||
4557 | } | ||
4558 | |||
4559 | static const Eina_Value_Type _EINA_VALUE_TYPE_MODEL = { | ||
4560 | EINA_VALUE_TYPE_VERSION, | ||
4561 | sizeof(Eina_Model *), | ||
4562 | "Eina_Model", | ||
4563 | _eina_value_type_model_setup, | ||
4564 | _eina_value_type_model_flush, | ||
4565 | _eina_value_type_model_copy, | ||
4566 | _eina_value_type_model_compare, | ||
4567 | _eina_value_type_model_convert_to, | ||
4568 | NULL, /* no convert from */ | ||
4569 | _eina_value_type_model_vset, | ||
4570 | _eina_value_type_model_pset, | ||
4571 | _eina_value_type_model_pget | ||
4572 | }; | ||
4573 | |||
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; | |||
4800 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_USHORT = NULL; | 5083 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_USHORT = NULL; |
4801 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT = NULL; | 5084 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT = NULL; |
4802 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ULONG = NULL; | 5085 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ULONG = NULL; |
5086 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMESTAMP = NULL; | ||
4803 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT64 = NULL; | 5087 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT64 = NULL; |
4804 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_CHAR = NULL; | 5088 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_CHAR = NULL; |
4805 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_SHORT = NULL; | 5089 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_SHORT = NULL; |
@@ -4816,6 +5100,7 @@ EAPI const Eina_Value_Type *EINA_VALUE_TYPE_HASH = NULL; | |||
4816 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMEVAL = NULL; | 5100 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMEVAL = NULL; |
4817 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_BLOB = NULL; | 5101 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_BLOB = NULL; |
4818 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRUCT = NULL; | 5102 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRUCT = NULL; |
5103 | EAPI const Eina_Value_Type *EINA_VALUE_TYPE_MODEL = NULL; | ||
4819 | 5104 | ||
4820 | EAPI const Eina_Value_Blob_Operations *EINA_VALUE_BLOB_OPERATIONS_MALLOC = NULL; | 5105 | EAPI const Eina_Value_Blob_Operations *EINA_VALUE_BLOB_OPERATIONS_MALLOC = NULL; |
4821 | 5106 | ||