Adding turran work to unify EFL data types and functions.
authorcedric <cedric>
Wed, 30 Jul 2008 12:46:55 +0000 (12:46 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 30 Jul 2008 12:46:55 +0000 (12:46 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/e17/proto/eina@35248 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

44 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
Doxyfile [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.in [new file with mode: 0644]
eina.pc.in [new file with mode: 0644]
gendoc [new file with mode: 0755]
src/Makefile.am [new file with mode: 0644]
src/include/Eina.h [new file with mode: 0644]
src/include/Makefile.am [new file with mode: 0644]
src/include/eina_error.h [new file with mode: 0644]
src/include/eina_f16p16.h [new file with mode: 0644]
src/include/eina_file.h [new file with mode: 0644]
src/include/eina_hash.h [new file with mode: 0644]
src/include/eina_inlist.h [new file with mode: 0644]
src/include/eina_lalloc.h [new file with mode: 0644]
src/include/eina_list.h [new file with mode: 0644]
src/include/eina_mempool.h [new file with mode: 0644]
src/include/eina_module.h [new file with mode: 0644]
src/include/eina_private.h [new file with mode: 0644]
src/include/eina_rectangle.h [new file with mode: 0644]
src/include/eina_types.h [new file with mode: 0644]
src/lib/Makefile.am [new file with mode: 0644]
src/lib/eina_error.c [new file with mode: 0644]
src/lib/eina_file.c [new file with mode: 0644]
src/lib/eina_hash.c [new file with mode: 0644]
src/lib/eina_inlist.c [new file with mode: 0644]
src/lib/eina_lalloc.c [new file with mode: 0644]
src/lib/eina_list.c [new file with mode: 0644]
src/lib/eina_mempool.c [new file with mode: 0644]
src/lib/eina_module.c [new file with mode: 0644]
src/lib/eina_value.c [new file with mode: 0644]
src/modules/Makefile.am [new file with mode: 0644]
src/modules/mm_policies/Makefile.am [new file with mode: 0644]
src/modules/mm_policies/ememoa.c [new file with mode: 0644]
src/modules/mm_policies/ememoa_memory_base.h [new file with mode: 0644]
src/modules/mm_policies/ememoa_mempool_error.h [new file with mode: 0644]
src/modules/mm_policies/fixed.c [new file with mode: 0644]
src/modules/mm_policies/mempool_struct.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..9e8b8f0
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Jorge Luis "turran" Zapata <jorgeluis.zapata@gmail.com>
+Carsten Haitzler <raster@rasterman.com>
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Doxyfile b/Doxyfile
new file mode 100644 (file)
index 0000000..73c5bc7
--- /dev/null
+++ b/Doxyfile
@@ -0,0 +1,139 @@
+PROJECT_NAME           = Eina
+PROJECT_NUMBER         =
+OUTPUT_DIRECTORY       = doc
+INPUT                  = ./src/lib
+IMAGE_PATH             = doc/img
+OUTPUT_LANGUAGE        = English
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+ENUM_VALUES_PER_LINE   = 1
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = NO
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = NO
+HIDE_UNDOC_MEMBERS     = YES
+HIDE_UNDOC_CLASSES     = YES
+HIDE_FRIEND_COMPOUNDS  = YES
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+INTERNAL_DOCS          = NO
+STRIP_CODE_COMMENTS    = YES
+CASE_SENSE_NAMES       = YES
+SHORT_NAMES            = NO
+HIDE_SCOPE_NAMES       = NO
+VERBATIM_HEADERS       = NO
+SHOW_INCLUDE_FILES     = NO
+JAVADOC_AUTOBRIEF      = YES
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 2
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ALIASES                = 
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+OPTIMIZE_OUTPUT_FOR_C  = YES
+OPTIMIZE_OUTPUT_JAVA   = NO
+SHOW_USED_FILES        = NO
+QUIET                  = YES
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+FILE_PATTERNS          =
+RECURSIVE              = YES 
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+INPUT_FILTER           = 
+FILTER_SOURCE_FILES    = NO
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+ALPHABETICAL_INDEX     = YES
+COLS_IN_ALPHA_INDEX    = 2
+IGNORE_PREFIX          = 
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+GENERATE_LATEX         = YES
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = YES
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+GENERATE_MAN           = YES
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = YES
+GENERATE_XML           = NO
+XML_SCHEMA             = 
+XML_DTD                = 
+GENERATE_AUTOGEN_DEF   = NO
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = NO
+INCLUDE_PATH           =
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+CLASS_DIAGRAMS         = NO
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = NO
+COLLABORATION_GRAPH    = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = NO
+INCLUDED_BY_GRAPH      = NO
+GRAPHICAL_HIERARCHY    = NO
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 512
+MAX_DOT_GRAPH_HEIGHT   = 512
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+SEARCHENGINE           = NO
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..5f5ae10
--- /dev/null
@@ -0,0 +1,32 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS = src
+
+MAINTAINERCLEANFILES = \
+Makefile.in \
+aclocal.m4 \
+config.guess \
+config.h.in \
+config.sub \
+configure \
+install-sh \
+ltconfig \
+ltmain.sh \
+missing mkinstalldirs \
+stamp-h.in \
+build-stamp \
+configure-stamp \
+depcomp \
+eina.pc \
+eina_docs.tar.gz
+
+EXTRA_DIST = \
+AUTHORS \
+COPYING \
+gendoc \
+Doxyfile \
+README \
+eina.pc
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = eina.pc
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..7aeabb6
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+rm -rf autom4te.cache
+rm -f aclocal.m4 ltmain.sh
+
+echo "Running aclocal..." ; aclocal $ACLOCAL_FLAGS || exit 1
+echo "Running autoheader..." ; autoheader || exit 1
+echo "Running autoconf..." ; autoconf || exit 1
+echo "Running libtoolize..." ; (libtoolize --copy --automake || glibtoolize --automake) || exit 1
+echo "Running automake..." ; automake --add-missing --copy --gnu || exit 1
+
+if [ -z "$NOCONFIGURE" ]; then
+       ./configure "$@"
+fi
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..da8a540
--- /dev/null
@@ -0,0 +1,92 @@
+# get rid of that stupid cache mechanism
+rm -f config.cache
+
+AC_INIT(eina, 0.0.1, enlightenment-devel@lists.sourceforge.net)
+AC_PREREQ(2.52)
+AC_CONFIG_SRCDIR(configure.in)
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_ISC_POSIX
+
+AM_INIT_AUTOMAKE(1.6 dist-bzip2)
+AM_CONFIG_HEADER(config.h)
+
+AC_LIBTOOL_WIN32_DLL
+define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])dnl
+define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl
+AC_PROG_LIBTOOL
+
+VMAJ=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $1);}'`
+VMIN=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $2);}'`
+VMIC=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $3);}'`
+SNAP=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $4);}'`
+version_info=`expr $VMAJ + $VMIN`":$VMIC:$VMIN"
+AC_SUBST(version_info)
+
+# Checks for programs
+AC_PROG_CC
+
+# Checks for libraries
+
+# Checks for header files
+AC_HEADER_ASSERT
+AC_HEADER_DIRENT
+AC_HEADER_TIME
+
+# Checks for types
+
+# Checks for structures
+
+# Checks for compiler characteristics
+AC_C_CONST
+AC_C_BIGENDIAN
+AC_PROG_CC_STDC
+
+if ! test "${VMIC}" = "x" ; then
+   CFLAGS="${CFLAGS} -Wall -W -Wextra" # -Werror
+fi
+
+# Checks for linker characteristics
+lt_enable_auto_import=""
+case "$host_os" in
+   mingw*|cegcc*)
+      lt_enable_auto_import="-Wl,--enable-auto-import"
+   ;;
+esac
+AC_SUBST(lt_enable_auto_import)
+
+# Checks for library functions
+
+## Make the debug preprocessor configurable
+
+AC_CONFIG_FILES([
+Makefile
+eina.pc
+src/Makefile
+src/include/Makefile
+src/lib/Makefile
+src/modules/Makefile
+src/modules/mm_policies/Makefile
+])
+
+AC_OUTPUT
+
+#####################################################################
+## Info
+
+echo
+echo
+echo
+echo "------------------------------------------------------------------------"
+echo "$PACKAGE $VERSION"
+echo "------------------------------------------------------------------------"
+echo
+echo
+echo "Configuration Options Summary:"
+echo
+echo "Installation Path.........: $prefix"
+echo
+echo "Now type 'make' ('gmake' on some systems) to compile $PACKAGE,"
+echo "and then afterwards as root (or the user who will install this), type"
+echo "'make install'. Change users with 'su' or 'sudo' appropriately."
+echo
diff --git a/eina.pc.in b/eina.pc.in
new file mode 100644 (file)
index 0000000..7dc5465
--- /dev/null
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Eina
+Description: Eina
+Requires: 
+Version: @VERSION@
+Libs: -L${libdir} -leina
+Libs.private: -lm -ldl
+Cflags: -I${includedir} -I${includedir}/eina
diff --git a/gendoc b/gendoc
new file mode 100755 (executable)
index 0000000..d141024
--- /dev/null
+++ b/gendoc
@@ -0,0 +1,9 @@
+#!/bin/sh
+rm -rf ./doc/html ./doc/latex ./doc/man
+mkdir -p ./doc/html ./doc/latex ./doc/man 2>/dev/null
+doxygen
+#cp doc/img/*.png doc/html/
+rm -f edata_docs.tar ecore_docs.tar.gz
+tar -cvf edata_docs.tar doc/html doc/man doc/latex
+gzip -9f edata_docs.tar
+exit 0
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..7e99d0b
--- /dev/null
@@ -0,0 +1,3 @@
+SUBDIRS = lib include modules
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/src/include/Eina.h b/src/include/Eina.h
new file mode 100644 (file)
index 0000000..776cdc5
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef EINA_H_
+#define EINA_H_
+
+/**
+ * @mainpage Eina
+ * @file Eina.h
+ * @brief Contains list, hash, debugging and tree functions.
+ * TODO add debug functions, magic functions, etc
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "eina_types.h"
+#include "eina_f16p16.h"
+#include "eina_rectangle.h"
+#include "eina_inlist.h"
+#include "eina_file.h"
+#include "eina_list.h"
+#include "eina_hash.h"
+#include "eina_lalloc.h"
+#include "eina_module.h"
+#include "eina_mempool.h"
+#include "eina_error.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EINA_H */
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
new file mode 100644 (file)
index 0000000..cddfaad
--- /dev/null
@@ -0,0 +1,20 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+EINAHEADERS = \
+eina_error.h \
+eina_f16p16.h \
+eina_hash.h \
+eina_lalloc.h \
+eina_inlist.h \
+eina_list.h \
+eina_file.h \
+eina_mempool.h \
+eina_module.h \
+eina_rectangle.h \
+eina_types.h
+
+include_HEADERS = \
+Eina.h
+
+installed_headersdir = $(prefix)/include/eina
+installed_headers_DATA = $(EINAHEADERS)
diff --git a/src/include/eina_error.h b/src/include/eina_error.h
new file mode 100644 (file)
index 0000000..9534f27
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef EINA_ERROR_H_
+#define EINA_ERROR_H_
+
+#define EINA_ERROR_PERR(fmt, ...) \
+       eina_error_print(EINA_ERROR_LEVEL_ERR, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
+
+#define EINA_ERROR_PINFO(fmt, ...) \
+       eina_error_print(EINA_ERROR_LEVEL_INFO, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
+
+#define EINA_ERROR_PWARN(fmt, ...) \
+       eina_error_print(EINA_ERROR_LEVEL_WARN, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
+
+#define EINA_ERROR_PDBG(fmt, ...) \
+       eina_error_print(EINA_ERROR_LEVEL_DBG, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
+
+typedef enum _Eina_Error_Level
+{
+       EINA_ERROR_LEVEL_ERR,
+       EINA_ERROR_LEVEL_WARN,
+       EINA_ERROR_LEVEL_INFO,
+       EINA_ERROR_LEVEL_DBG,
+       EINA_ERROR_LEVELS
+} Eina_Error_Level;
+
+EAPI int eina_error_init(void);
+EAPI int eina_error_shutdown(void);
+EAPI int eina_error_register(const char *msg);
+EAPI const char * eina_error_msg_get(int error);
+EAPI void eina_error_print(Eina_Error_Level level, const char *file,
+               const char *function, int line, const char *fmt, ...);
+EAPI void eina_error_log_level_set(Eina_Error_Level level);
+
+#endif /*EINA_ERROR_H_*/
diff --git a/src/include/eina_f16p16.h b/src/include/eina_f16p16.h
new file mode 100644 (file)
index 0000000..b40907c
--- /dev/null
@@ -0,0 +1,105 @@
+#ifndef EINA_F16P16_H_
+#define EINA_F16P16_H_
+
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+typedef int32_t Eina_F16p16;
+
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_F16p16 eina_f16p16_int_from(int32_t v)
+{
+       return v << 16;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline int32_t eina_f16p16_int_to(Eina_F16p16 v)
+{
+       return v >> 16;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_F16p16 eina_f16p16_float_from(float v)
+{
+       Eina_F16p16 r;
+       r = (Eina_F16p16)(v * 65536.0 + (v < 0 ? -0.5 : 0.5));
+       return r;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline float eina_f16p16_float_to(Eina_F16p16 v)
+{
+       float r;
+       r = v / 65536.0;
+       return r;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_F16p16 eina_f16p16_add(Eina_F16p16 a, Eina_F16p16 b)
+{
+       return a + b;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_F16p16 eina_f16p16_sub(Eina_F16p16 a, Eina_F16p16 b)
+{
+       return a - b;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_F16p16 eina_f16p16_mul(Eina_F16p16 a, Eina_F16p16 b)
+{
+       return (a * b) >> 16;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_F16p16 eina_f16p16_sqrt(Eina_F16p16 a)
+{
+       unsigned int root, remHi, remLo, testDiv, count;
+
+       root = 0; /* Clear root */
+       remHi = 0; /* Clear high part of partial remainder */
+       remLo = a; /* Get argument into low part of partial remainder */
+       count = (15 + (16 >> 1)); /* Load loop counter */
+       do
+       {
+               remHi = (remHi << 2) | (remLo >> 30);
+               remLo <<= 2; /* get 2 bits of arg */
+               root <<= 1; /* Get ready for the next bit in the root */
+               testDiv = (root << 1) + 1; /* Test radical */
+               if (remHi >= testDiv)
+               {
+                       remHi -= testDiv;
+                       root++;
+               }
+       } while (count-- != 0);
+       return (root);
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline unsigned int eina_f16p16_fracc_get(Eina_F16p16 v)
+{
+       return (v & 0xffff);
+}
+
+#endif /*EINA_F16P16_H_*/
diff --git a/src/include/eina_file.h b/src/include/eina_file.h
new file mode 100644 (file)
index 0000000..d74167b
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef EINA_FILE_H_
+#define EINA_FILE_H_
+
+/**
+ * @defgroup File_Group Memory File
+ * @{
+ */
+
+typedef void (*Eina_File_Dir_List_Cb)(const char *name, const char *path, void *data);
+
+EAPI void eina_file_dir_list(const char *dir, int recursive, Eina_File_Dir_List_Cb cb, void *data);
+EAPI void eina_file_path_nth_get(const char *path, int n, char **left, char **right);
+
+/** @} */
+
+#endif /*EINA_FILE_H_*/
diff --git a/src/include/eina_hash.h b/src/include/eina_hash.h
new file mode 100644 (file)
index 0000000..36bbd43
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef EINA_HASH_H_
+#define EINA_HASH_H_
+
+/**
+ *
+ */
+typedef struct _Eina_Hash Eina_Hash;
+
+EAPI Eina_Hash *eina_hash_add (Eina_Hash *hash, const char *key, const void *data);
+EAPI Eina_Hash *eina_hash_direct_add (Eina_Hash *hash, const char *key, const void *data);
+EAPI Eina_Hash *eina_hash_del (Eina_Hash *hash, const char *key, const void *data);
+EAPI void *eina_hash_find(const Eina_Hash *hash, const char *key);
+EAPI void *eina_hash_modify(Eina_Hash *hash, const char *key, const void *data);
+EAPI int eina_hash_size(const Eina_Hash *hash);
+EAPI void eina_hash_free(Eina_Hash *hash);
+EAPI void eina_hash_foreach(const Eina_Hash *hash, Eina_Bool (*func) (const Eina_Hash *hash, const char *key, void *data, void *fdata),
+               const void *fdata);
+
+#endif /*EINA_HASH_H_*/
diff --git a/src/include/eina_inlist.h b/src/include/eina_inlist.h
new file mode 100644 (file)
index 0000000..0fc7eb7
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef EINA_INLIST_H_
+#define EINA_INLIST_H_
+
+/**
+ * @defgroup Inline_List_Group Inline List
+ * @{
+ */
+
+/* TODO change the prototype to use an Eina_Inlist */
+typedef struct _Eina_Inlist Eina_Inlist;
+
+struct _Eina_Inlist
+{
+   Eina_Inlist *next;
+   Eina_Inlist *prev;
+   Eina_Inlist *last;
+};
+
+EAPI void * eina_inlist_append(void *in_list, void *in_item);
+EAPI void * eina_inlist_prepend(void *in_list, void *in_item);
+EAPI void * eina_inlist_append_relative(void *in_list, void *in_item, void *in_relative);
+EAPI void * eina_inlist_prepend_relative(void *in_list, void *in_item, void *in_relative);
+EAPI void * eina_inlist_remove(void *in_list, void *in_item);
+EAPI void * eina_inlist_find(void *in_list, void *in_item);
+
+//typedef Eina_Bool (*Eina_Iterator_Func)(Eina_Inlist *l, void *data);
+
+#define EINA_ITER_NEXT(list, l) for (l = (Eina_Inlist *)list; l; l = l->next)
+#define EINA_ITER_LAST(list, l) for (l = ((Eina_Inlist *)list)->last; l; l = l->prev)
+
+/** @} */
+
+#endif /*EINA_INLIST_H_*/
diff --git a/src/include/eina_lalloc.h b/src/include/eina_lalloc.h
new file mode 100644 (file)
index 0000000..9d57930
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef EINA_LALLOC_H_
+#define EINA_LALLOC_H_
+
+/**
+ * @defgroup Array_Group Array
+ * @{
+ */
+
+typedef void (*Eina_Array_Alloc) (void *user_data, int num);
+#define EINA_ARRAY_ALLOC(function) ((Eina_Array_Alloc)function)
+typedef void (*Eina_Array_Free) (void *user_data);
+#define EINA_ARRAY_FREE(function) ((Eina_Array_Free)function)
+
+typedef struct _Eina_Array Eina_Array;
+EAPI void eina_array_free(Eina_Array *a);
+EAPI Eina_Array *eina_array_new(void *data, Eina_Array_Alloc alloc_cb, Eina_Array_Free free_cb, int num_init);
+EAPI void eina_array_elements_add(Eina_Array *a, int num);
+EAPI void eina_array_element_add(Eina_Array *a);
+
+/** @} */
+
+#endif
diff --git a/src/include/eina_list.h b/src/include/eina_list.h
new file mode 100644 (file)
index 0000000..64fd780
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef EINA_LIST_H_
+#define EINA_LIST_H_
+
+/**
+ * @defgroup List_Group List
+ * @{
+ */
+
+typedef struct _Eina_List Eina_List;
+
+EAPI Eina_List *eina_list_append (Eina_List *list, const void *data);
+EAPI Eina_List *eina_list_prepend (Eina_List *list, const void *data);
+EAPI Eina_List *eina_list_append_relative (Eina_List *list, const void *data, const void *relative);
+EAPI Eina_List *eina_list_append_relative_list (Eina_List *list, const void *data, Eina_List *relative);
+EAPI Eina_List *eina_list_prepend_relative (Eina_List *list, const void *data, const void *relative);
+EAPI Eina_List *eina_list_prepend_relative_list (Eina_List *list, const void *data, Eina_List *relative);
+EAPI Eina_List *eina_list_remove (Eina_List *list, const void *data);
+EAPI Eina_List *eina_list_remove_list (Eina_List *list, Eina_List *remove_list);
+EAPI Eina_List *eina_list_promote_list (Eina_List *list, Eina_List *move_list);
+EAPI void *eina_list_find(const Eina_List *list, const void *data);
+EAPI Eina_List *eina_list_find_list (const Eina_List *list, const void *data);
+EAPI Eina_List *eina_list_free (Eina_List *list);
+EAPI Eina_List *eina_list_last (const Eina_List *list);
+EAPI Eina_List *eina_list_next (const Eina_List *list);
+EAPI Eina_List *eina_list_prev (const Eina_List *list);
+EAPI void *eina_list_data(const Eina_List *list);
+EAPI int eina_list_count(const Eina_List *list);
+EAPI void *eina_list_nth(const Eina_List *list, int n);
+EAPI Eina_List *eina_list_nth_list (const Eina_List *list, int n);
+EAPI Eina_List *eina_list_reverse (Eina_List *list);
+EAPI Eina_List *eina_list_sort (Eina_List *list, int size, int(*func)(void*,void*));
+EAPI int eina_list_alloc_error(void);
+
+
+/** @} */
+
+#endif /* EINA_LIST_H_ */
diff --git a/src/include/eina_mempool.h b/src/include/eina_mempool.h
new file mode 100644 (file)
index 0000000..efca921
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef EINA_MEMPOOL_H_
+#define EINA_MEMPOOL_H_
+
+/**
+ * @defgroup Memory_Pool_Group Memory Pool
+ * @{
+ */
+typedef struct _Eina_Mempool Eina_Mempool;
+
+EAPI int eina_mempool_init(void);
+EAPI int eina_mempool_shutdown(void);
+EAPI void eina_mempool_delete(Eina_Mempool *mp);
+EAPI Eina_Mempool * eina_mempool_new_from_buffer(const char *name, void *buffer,
+               unsigned int size, const char *options, ...);
+EAPI Eina_Mempool * eina_mempool_new(const char *name, unsigned int size, const char 
+               *options, ...);
+EAPI void * eina_mempool_realloc(Eina_Mempool *mp, void *element, unsigned int size);
+EAPI void * eina_mempool_alloc(Eina_Mempool *mp, unsigned int size);
+EAPI void eina_mempool_free(Eina_Mempool *mp, void *element);
+
+/** @} */
+
+#endif /* EINA_MEMPOOL_H_ */
diff --git a/src/include/eina_module.h b/src/include/eina_module.h
new file mode 100644 (file)
index 0000000..2c938dd
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef EINA_MODULE_H_
+#define EINA_MODULE_H_
+
+/**
+ * @defgroup Module_Group Module
+ * @{
+ */
+
+typedef struct _Eina_Module Eina_Module;
+
+typedef int (*Eina_Module_Cb)(Eina_Module *m, void *data);
+
+EAPI Eina_Module * eina_module_new(const char *file);
+EAPI void eina_module_free(Eina_Module *m);
+EAPI void eina_module_unload(Eina_Module *m);
+EAPI char * eina_module_path_get(Eina_Module *m);
+EAPI char * eina_module_name_get(Eina_Module *m);
+EAPI void * eina_module_symbol_get(Eina_Module *m, const char *symbol);
+
+EAPI Eina_List * eina_module_list_get(const char *path, unsigned int recursive, Eina_Module_Cb cb, void *data);
+EAPI void eina_module_list_load(Eina_List *list);
+EAPI void eina_module_list_unload(Eina_List *list);
+EAPI void eina_module_list_free(Eina_List *list);
+
+/** @} */
+
+#endif /*EINA_MODULE_H_*/
diff --git a/src/include/eina_private.h b/src/include/eina_private.h
new file mode 100644 (file)
index 0000000..b84ad96
--- /dev/null
@@ -0,0 +1,148 @@
+#ifndef EINA_PRIVATE_H_
+#define EINA_PRIVATE_H_
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <dirent.h>
+
+
+#define DEBUG
+#include <assert.h>
+
+#ifndef PATH_MAX
+# define PATH_MAX 4096
+#endif
+
+#ifndef MIN
+# define MIN(x, y) (((x) > (y)) ? (y) : (x))
+#endif
+
+#ifndef MAX
+# define MAX(x, y) (((x) > (y)) ? (x) : (y))
+#endif
+
+#ifndef ABS
+# define ABS(x) ((x) < 0 ? -(x) : (x))
+#endif
+
+#ifndef CLAMP
+# define CLAMP(x, min, max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x)))
+#endif
+
+#define READBUFSIZ 65536
+
+#define EINA_MAGIC_NONE            0x1234fedc
+#define EINA_MAGIC_EXE             0xf7e812f5
+#define EINA_MAGIC_TIMER           0xf7d713f4
+#define EINA_MAGIC_IDLER           0xf7c614f3
+#define EINA_MAGIC_IDLE_ENTERER    0xf7b515f2
+#define EINA_MAGIC_IDLE_EXITER     0xf7601afd
+#define EINA_MAGIC_FD_HANDLER      0xf7a416f1
+#define EINA_MAGIC_EVENT_HANDLER   0xf79317f0
+#define EINA_MAGIC_EVENT_FILTER    0xf78218ff
+#define EINA_MAGIC_EVENT           0xf77119fe
+#define EINA_MAGIC_ANIMATOR        0xf7643ea5
+
+#define EINA_MAGIC                 Eina_Magic  __magic
+
+#define EINA_MAGIC_SET(d, m)       (d)->__magic = (m)
+#define EINA_MAGIC_CHECK(d, m)     ((d) && ((d)->__magic == (m)))
+#define EINA_MAGIC_FAIL(d, m, fn)  _eina_magic_fail((d), (d) ? (d)->__magic : 0, (m), (fn));
+
+/* undef the following, we want out version */
+#undef FREE
+#define FREE(ptr) free(ptr); ptr = NULL;
+
+#undef IF_FREE
+#define IF_FREE(ptr) if (ptr) free(ptr); ptr = NULL;
+
+#undef IF_FN_DEL
+#define IF_FN_DEL(_fn, ptr) if (ptr) { _fn(ptr); ptr = NULL; }
+
+inline void eina_print_warning(const char *function, const char *sparam);
+
+/* convenience macros for checking pointer parameters for non-NULL */
+#undef CHECK_PARAM_POINTER_RETURN
+#define CHECK_PARAM_POINTER_RETURN(sparam, param, ret) \
+     if (!(param)) \
+        { \
+           eina_print_warning(__FUNCTION__, sparam); \
+           return ret; \
+        }
+
+#undef CHECK_PARAM_POINTER
+#define CHECK_PARAM_POINTER(sparam, param) \
+     if (!(param)) \
+        { \
+           eina_print_warning(__FUNCTION__, sparam); \
+           return; \
+        }
+
+typedef unsigned int              Eina_Magic;
+
+typedef struct _Eina_List2       Eina_List2;
+typedef struct _Eina_List2_Data  Eina_List2_Data;
+
+struct _Eina_List2
+{
+   Eina_List2  *next, *prev;
+   Eina_List2  *last;
+};
+
+struct _Eina_List2_Data
+{
+   Eina_List2   __list_data;
+   void *data;
+};
+
+#ifndef EINA_H
+
+#endif
+
+EAPI void          _eina_magic_fail(void *d, Eina_Magic m, Eina_Magic req_m, const char *fname);
+
+EAPI void         *_eina_list2_append           (void *in_list, void *in_item);
+EAPI void         *_eina_list2_prepend          (void *in_list, void *in_item);
+EAPI void         *_eina_list2_append_relative  (void *in_list, void *in_item, void *in_relative);
+EAPI void         *_eina_list2_prepend_relative (void *in_list, void *in_item, void *in_relative);
+EAPI void         *_eina_list2_remove           (void *in_list, void *in_item);
+EAPI void         *_eina_list2_find             (void *in_list, void *in_item);
+
+void          _eina_fps_debug_init(void);
+void          _eina_fps_debug_shutdown(void);
+void          _eina_fps_debug_runtime_add(double t);
+
+
+
+extern int    _eina_fps_debug;
+
+
+/* old code finish */
+/* mp */
+typedef struct _Eina_Mempool_Backend
+{
+       void *(*init)(void *buffer, unsigned int size, const char *options, va_list args);
+       void (*free)(void *data, void *element);
+       void *(*alloc)(void *data, unsigned int size);
+       void *(*realloc)(void *data, void *element, unsigned int size);
+       void (*garbage_collect)(void);
+       void (*statistics)(void);
+       void (*shutdown)(void *data);
+} Eina_Mempool_Backend;
+
+
+#endif /* EINA_PRIVATE_H_ */
diff --git a/src/include/eina_rectangle.h b/src/include/eina_rectangle.h
new file mode 100644 (file)
index 0000000..839e871
--- /dev/null
@@ -0,0 +1,196 @@
+#ifndef EINA_RECTANGLE_H_
+#define EINA_RECTANGLE_H_
+
+/**
+ * @file
+ * @{
+ */
+
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+typedef struct _Eina_Rectangle
+{
+       int     x;
+       int     y;
+       int     w;
+       int     h;
+} Eina_Rectangle;
+
+/**
+ * To be documented
+ * FIXME: To be fixed
+ * Is it needed??
+ */
+static inline int
+eina_spans_intersect(int c1, int l1, int c2, int l2)
+{
+       return (!(((c2 + l2) <= c1) || (c2 >= (c1 + l1))));
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_Bool
+eina_rectangle_is_empty(Eina_Rectangle *r)
+{
+       return ((r->w < 1) || (r->h < 1));
+}
+
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline void
+eina_rectangle_coords_from(Eina_Rectangle *r, int x, int y, int w, int h)
+{
+       r->x = x;
+       r->y = y;
+       r->w = w;
+       r->h = h;
+}
+
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_Bool
+eina_rectangles_intersect(Eina_Rectangle *r1, Eina_Rectangle *r2)
+{
+       return (eina_spans_intersect(r1->x, r1->w, r2->x, r2->w) && eina_spans_intersect(r1->y, r1->h, r2->y, r2->h));
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_Bool
+eina_rectangle_hspan_inside(Eina_Rectangle *r, int x, int l)
+{
+
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_Bool
+eina_rectangle_vspan_inside(Eina_Rectangle *r, int y, int l)
+{
+
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_Bool
+eina_rectangle_xcoord_inside(Eina_Rectangle *r, int x)
+{
+       return ((x >= r->x) && (x < (r->x + r->w)));
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_Bool
+eina_rectangle_ycoord_inside(Eina_Rectangle *r, int y)
+{
+       return ((y >= r->y) && (y < (r->y + r->h)));
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_Bool
+eina_rectangle_coords_inside(Eina_Rectangle *r, int x, int y)
+{
+       return (eina_rectangle_xcoord_inside(r, x) && eina_rectangle_ycoord_inside(r, y));
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline void
+eina_rectangle_union(Eina_Rectangle *dst, Eina_Rectangle *src)
+{
+       /* left */
+       if (dst->x > src->x)
+       {
+               dst->w += dst->x - src->x;
+               dst->x = src->x;
+       }
+       /* right */
+       if ((dst->x + dst->w) < (src->x + src->w))
+               dst->w = src->x + src->w;
+       /* top */
+       if (dst->y > src->y)
+       {
+               dst->h += dst->y - src->y;
+               dst->y = src->y;
+       }
+       /* bottom */
+       if ((dst->y + dst->h) < (src->y + src->h))
+               dst->h = src->y + src->h;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline Eina_Bool
+eina_rectangle_intersection(Eina_Rectangle *dst, Eina_Rectangle *src)
+{
+       if (!(eina_rectangles_intersect(dst, src)))
+               return EINA_FALSE;
+
+       /* left */
+       if (dst->x < src->x)
+       {
+               dst->w += dst->x - src->x;
+               dst->x = src->x;
+               if (dst->w < 0)
+                       dst->w = 0;
+       }
+       /* right */
+       if ((dst->x + dst->w) > (src->x + src->w))
+               dst->w = src->x + src->w - dst->x;
+       /* top */
+       if (dst->y < src->y)
+       {
+               dst->h += dst->y - src->y;
+               dst->y = src->y;
+               if (dst->h < 0)
+                       dst->h = 0;
+       }
+       /* bottom */
+       if ((dst->y + dst->h) > (src->y + src->h))
+               dst->h = src->y + src->h - dst->y;
+
+       return EINA_TRUE;
+}
+
+/**
+ * Rescale the coordinates from @in as if it where relative to @out
+ */
+static inline void
+eina_rectangle_rescale_in(Eina_Rectangle *out, Eina_Rectangle *in, Eina_Rectangle *res)
+{
+       res->x = in->x - out->x;
+       res->y = in->y - out->y;
+       res->w = in->w;
+       res->h = in->h;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+static inline void
+eina_rectangle_rescale_out(Eina_Rectangle *out, Eina_Rectangle *in, Eina_Rectangle *res)
+{
+       res->x = out->x + in->x;
+       res->y = out->y + in->y;
+       res->w = out->w;
+       res->h = out->h;
+}
+
+/** @} */
+
+#endif /*_ENESIM_RECTANGLE_H_*/
diff --git a/src/include/eina_types.h b/src/include/eina_types.h
new file mode 100644 (file)
index 0000000..9dc7164
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef EINA_TYPES_H_
+#define EINA_TYPES_H_
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_EINA_BUILD
+#  ifdef DLL_EXPORT
+#   define EAPI __declspec(dllexport)
+#  else
+#   define EAPI
+#  endif /* ! DLL_EXPORT */
+# else
+#  define EAPI __declspec(dllimport)
+# endif /* ! EFL_EINA_BUILD */
+#else
+# ifdef __GNUC__
+#  if __GNUC__ >= 4
+#   define EAPI __attribute__ ((visibility("default")))
+#  else
+#   define EAPI
+#  endif
+# else
+#  define EAPI
+# endif
+#endif
+
+/* remove this TRUE/FALSE redifinitions */
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+typedef enum {
+       EINA_FALSE = 0,
+       EINA_TRUE = 1
+} Eina_Bool;
+
+EAPI extern const unsigned int eina_prime_table[];
+
+#define EINA_SORT_MIN 0
+#define EINA_SORT_MAX 1
+
+typedef void (*Eina_For_Each) (void *value, void *user_data);
+#define EINA_FOR_EACH(function) ((Eina_For_Each)function)
+
+typedef void (*Eina_Free_Cb) (void *data);
+#define EINA_FREE_CB(func) ((Eina_Free_Cb)func)
+
+typedef unsigned int (*Eina_Hash_Cb) (const void *key);
+#define EINA_HASH_CB(function) ((Eina_Hash_Cb)function)
+
+typedef int (*Eina_Compare_Cb) (const void *data1, const void *data2);
+#define EINA_COMPARE_CB(function) ((Eina_Compare_Cb)function)
+
+#endif /*EINA_TYPES_H_*/
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..666aed8
--- /dev/null
@@ -0,0 +1,21 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/include
+
+lib_LTLIBRARIES = libeina.la
+
+libeina_la_SOURCES = \
+eina_error.c \
+eina_hash.c \
+eina_lalloc.c \
+eina_inlist.c \
+eina_file.c \
+eina_mempool.c \
+eina_list.c \
+eina_module.c \
+eina_value.c
+
+libeina_la_LIBADD = -ldl
+libeina_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@
+libeina_la_DEPENDENCIES = $(top_builddir)/config.h
diff --git a/src/lib/eina_error.c b/src/lib/eina_error.c
new file mode 100644 (file)
index 0000000..b4e10db
--- /dev/null
@@ -0,0 +1,153 @@
+#include "Eina.h"
+#include "eina_private.h"
+/* TODO
+ * + printing errors to stdout or stderr can be implemented
+ * using a queue, usful for multiple threads printing
+ * + add a wapper for assert?
+ * + add common error numbers, messages
+ * + add a calltrace of erros, not only store the last error but a list of them
+ * and also store the function that set it
+ */
+/*============================================================================*
+ *                                  Local                                     * 
+ *============================================================================*/
+static int _curr = 1;
+static int _init_count = 0;
+static Eina_List *_error_list;
+static int _err;
+
+#define RED     "\033[31;1m"
+#define GREEN   "\033[32;1m"
+#define YELLOW  "\033[33;1m"
+#define WHITE   "\033[37;1m"
+#define NOTHING "\033[0m"
+
+
+#ifdef DEBUG
+static _error_level = EINA_ERROR_LEVEL_DBG;
+#else
+static _error_level = EINA_ERROR_LEVEL_ERR;
+#endif
+
+static char *_colors[EINA_ERROR_LEVELS] = {
+       [EINA_ERROR_LEVEL_ERR] = RED,
+       [EINA_ERROR_LEVEL_WARN] = YELLOW,
+       [EINA_ERROR_LEVEL_INFO] = NOTHING,
+       [EINA_ERROR_LEVEL_DBG] = GREEN,
+};
+
+static void _error_print(Eina_Error_Level level, const char *file,
+               const char *fnc, int line, const char *fmt, va_list args)
+{
+       if (level <= _error_level)
+       {
+               printf("%s", _colors[level]);
+               printf("[%s:%d] %s() ", file, line, fnc);
+               printf("%s", _colors[EINA_ERROR_LEVEL_INFO]);
+               vprintf(fmt, args);
+       }
+}
+/*============================================================================*
+ *                                 Global                                     * 
+ *============================================================================*/
+void eina_error_magic_check(unsigned int magic, unsigned int cmp)
+{
+       assert(magic == cmp);
+}
+/*============================================================================*
+ *                                   API                                      * 
+ *============================================================================*/
+/**
+ * 
+ */
+EAPI int eina_error_init(void)
+{
+       if (!_init_count) 
+       {
+               char *level;
+               /* TODO register the eina's basic errors */
+               /* TODO load the environment variable for getting the log level */
+               if (level = getenv("EINA_ERROR_LEVEL"))
+               {
+                       _error_level = atoi(level);
+               }
+       }
+       /* get all the modules */
+       return ++_init_count;
+}
+/**
+ * 
+ */
+EAPI int eina_error_shutdown(void)
+{
+       if (!_init_count)
+               return _init_count;
+       _init_count--;
+       if (!_init_count)
+       {
+               /* remove the error strings */
+               while (_error_list)
+               {
+                       free(eina_list_data(_error_list));
+                       _error_list = eina_list_free(_error_list);
+               }
+       }
+       return _init_count;
+}
+
+/**
+ * Register a new error type
+ * @param str The description of the error
+ * @return The unique number identifier for this error
+ */
+EAPI int eina_error_register(const char *msg)
+{
+       char *str;
+       
+       str = strdup(msg);
+       _error_list = eina_list_append(_error_list, str);
+       
+       return ++_curr;
+}
+/**
+ * 
+ */
+EAPI int eina_error_get(void)
+{
+       return _err;
+}
+/**
+ *  
+ */
+EAPI int eina_error_set(int err)
+{
+       _err = err;
+}
+/**
+ * Given an error number return the description of it
+ * @param error The error number
+ * @return The description of the error
+ */
+EAPI const char * eina_error_msg_get(int error)
+{
+       return eina_list_nth(_error_list, error);
+}
+/**
+ * 
+ */
+EAPI void eina_error_print(Eina_Error_Level level, const char *file, 
+               const char *fnc, int line, const char *fmt, ...)
+{
+       va_list args;
+
+       va_start(args, fmt);
+       _error_print(level, file, fnc, line, fmt, args);
+       va_end(args);
+}
+/**
+ * 
+ */
+EAPI void eina_error_log_level_set(Eina_Error_Level level)
+{
+       _error_level = level;
+}
diff --git a/src/lib/eina_file.c b/src/lib/eina_file.c
new file mode 100644 (file)
index 0000000..a69db84
--- /dev/null
@@ -0,0 +1,84 @@
+#include "Eina.h"
+#include "eina_private.h"
+/*============================================================================*
+ *                                   API                                      * 
+ *============================================================================*/
+/**
+ * Lis all files on the directory calling the function for every file found
+ * @param recursive Iterate recursively in the directory
+ */
+EAPI void eina_file_dir_list(const char *dir, int recursive, Eina_File_Dir_List_Cb cb, void *data)
+{
+       struct dirent *de;
+       DIR *d;
+
+       assert(cb);
+       
+       d = opendir(dir);
+       if (!d)
+               return;
+
+       while (de = readdir(d))
+       {
+               int length;
+
+               if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
+                       continue;
+               
+               cb(de->d_name, dir, data);
+               /* d_type is only available on linux and bsd (_BSD_SOURCE) */
+               if ((recursive) && (de->d_type == DT_DIR))
+               {
+                       char path[PATH_MAX];
+                       
+                       snprintf(path, PATH_MAX, "%s/%s", dir, de->d_name);
+                       eina_file_dir_list(path, recursive, cb, data);
+               }
+       }
+       closedir(d);
+}
+/**
+ * 
+ */
+EAPI void eina_file_path_nth_get(const char *path, int n, char **left, char **right)
+{
+       char *p;
+       char *end;
+       char *tmp;
+       char *delim;
+       int inc;
+       int num = 0;
+       
+       if (!left && !right)
+               return;
+       
+       if (n > 0)
+       {
+               p = (char *)path;
+               inc = 1;
+               end = (char *)path + strlen(path);
+       }
+       else
+       {
+               p = (char *)path + strlen(path);
+               inc = -1;
+               end = (char *)path;
+       }
+       for (tmp = p; tmp != end, num != n; tmp += inc)
+       {
+               if (*tmp == '/')
+               {
+                       num += inc;
+                       delim = tmp;
+               }
+       }
+       if (left)
+       {
+               *left = strndup(path, delim - path + 1);
+       }
+       if (right)
+       {
+               *right = strdup(delim + 1);
+       }
+}
+
diff --git a/src/lib/eina_hash.c b/src/lib/eina_hash.c
new file mode 100644 (file)
index 0000000..b897ba4
--- /dev/null
@@ -0,0 +1,473 @@
+#include "Eina.h"
+#include "eina_private.h"
+/*============================================================================*
+ *                                  Local                                     * 
+ *============================================================================*/
+typedef struct _Eina_Hash_El Eina_Hash_El;
+
+struct _Eina_Hash
+{
+   int population;
+   Eina_Inlist *buckets[256];
+};
+
+struct _Eina_Hash_El
+{
+   Eina_Inlist _list_data;
+   const char *key;
+   void *data;
+};
+
+static inline int _eina_hash_gen(const char *key);
+
+static int _eina_hash_alloc_error = 0;
+
+static inline int _eina_hash_gen(const char *key)
+{
+       unsigned int hash_num = 5381;
+       const unsigned char *ptr;
+
+       if (!key)
+               return 0;
+       for (ptr = (unsigned char *)key; *ptr; ptr++)
+               hash_num = (hash_num * 33) ^ *ptr;
+
+       hash_num &= 0xff;
+       return (int)hash_num;
+}
+/*============================================================================*
+ *                                 Global                                     * 
+ *============================================================================*/
+/*============================================================================*
+ *                                   API                                      * 
+ *============================================================================*/
+/**
+ * Adds an entry to the given hash table.
+ *
+ * @p key is expected to be a unique string within the hash table.
+ * Otherwise, you cannot be sure which inserted data pointer will be
+ * accessed with @ref eina_hash_find , and removed with
+ * @ref eina_hash_del .
+ *
+ * Key strings are case sensitive.
+ *
+ * @ref eina_hash_alloc_error should be used to determine if an
+ * allocation error occurred during this function.
+ *
+ * @param   hash The given hash table.  Can be @c NULL, in which case a
+ *               new hash table is allocated and returned.
+ * @param   key  A unique string.  Can be @c NULL.
+ * @param   data Data to associate with the string given by @p key.
+ * @return  Either the given hash table, or if the given value for @p
+ *          hash is @c NULL, then a new one.  @c NULL will be returned
+ *          if memory could not be allocated for a new table.
+ */
+EAPI Eina_Hash *
+eina_hash_add(Eina_Hash *hash, const char *key, const void *data)
+{
+       int hash_num;
+       Eina_Hash_El *el;
+
+       if ((!key) || (!data)) return hash;
+       _eina_hash_alloc_error = 0;
+       if (!hash)
+       {
+               hash = calloc(1, sizeof(struct _Eina_Hash));
+               if (!hash)
+               {
+                       _eina_hash_alloc_error = 1;
+                       return NULL;
+               }
+       }
+       if (!(el = malloc(sizeof(struct _Eina_Hash_El) + strlen(key) + 1)))
+       {
+               if (hash->population <= 0)
+               {
+                       free(hash);
+                       hash = NULL;
+               }
+               _eina_hash_alloc_error = 1;
+               return hash;
+       };
+       el->key = ((char *)el) + sizeof(struct _Eina_Hash_El);
+       strcpy((char *) el->key, key);
+       el->data = (void *)data;
+       hash_num = _eina_hash_gen(key);
+       hash->buckets[hash_num] = eina_inlist_prepend(hash->buckets[hash_num], el);
+       if (eina_list_alloc_error())
+       {
+               _eina_hash_alloc_error = 1;
+               free(el);
+               return hash;
+       }
+       hash->population++;
+       return hash;
+}
+/**
+ * Adds an entry to the given hash table and does not duplicate the string key.
+ *
+ * @p key is expected to be a unique string within the hash table.
+ * Otherwise, you cannot be sure which inserted data pointer will be
+ * accessed with @ref eina_hash_find , and removed with
+ * @ref eina_hash_del . This call does not make a copy of the key so it must
+ * be a string constant or stored elsewhere (in the object being added) etc.
+ *
+ * Key strings are case sensitive.
+ *
+ * @ref eina_hash_alloc_error should be used to determine if an
+ * allocation error occurred during this function.
+ *
+ * @param   hash The given hash table.  Can be @c NULL, in which case a
+ *               new hash table is allocated and returned.
+ * @param   key  A unique string.  Can be @c NULL.
+ * @param   data Data to associate with the string given by @p key.
+ * @return  Either the given hash table, or if the given value for @p
+ *          hash is @c NULL, then a new one.  @c NULL will be returned
+ *          if memory could not be allocated for a new table.
+ * @ingroup Eina_Hash_Data
+ */
+EAPI Eina_Hash *
+eina_hash_direct_add(Eina_Hash *hash, const char *key, const void *data)
+{
+       int hash_num;
+       Eina_Hash_El *el;
+
+       if ((!key) || (!data)) return hash;
+       _eina_hash_alloc_error = 0;
+       if (!hash)
+       {
+               hash = calloc(1, sizeof(struct _Eina_Hash));
+               if (!hash)
+               {
+                       _eina_hash_alloc_error = 1;
+                       return NULL;
+               }
+       }
+       if (!(el = malloc(sizeof(struct _Eina_Hash_El))))
+       {
+               if (hash->population <= 0)
+               {
+                       free(hash);
+                       hash = NULL;
+               }
+               _eina_hash_alloc_error = 1;
+               return hash;
+       };
+       el->key = key;
+       el->data = (void *)data;
+       hash_num = _eina_hash_gen(key);
+       hash->buckets[hash_num] = eina_inlist_prepend(hash->buckets[hash_num], el);
+       if (eina_list_alloc_error())
+       {
+               _eina_hash_alloc_error = 1;
+               free(el);
+               return hash;
+       }
+       hash->population++;
+       return hash;
+}
+
+/**
+ * Removes the entry identified by @p key or @p data from the given
+ * hash table.
+ *
+ * If @p key is @c NULL, then @p data is used to find a match to
+ * remove.
+ *
+ * @param   hash The given hash table.
+ * @param   key  The key string.  Can be @c NULL.
+ * @param   data The data pointer to remove if @p key is @c NULL.
+ *               Otherwise, not required and can be @c NULL.
+ * @return  The modified hash table.  If there are no entries left, the
+ *          hash table will be freed and @c NULL will be returned.
+ * @ingroup Eina_Hash_Data
+ */
+EAPI Eina_Hash *
+eina_hash_del(Eina_Hash *hash, const char *key, const void *data)
+{
+       int hash_num;
+       Eina_Hash_El *el;
+       Eina_Inlist *l;
+
+       if (!hash) return NULL;
+       if (!key)
+       {
+               int hash_num;
+
+               for (hash_num = 0; hash_num < 256; hash_num++)
+               {
+                       for (l = hash->buckets[hash_num]; l; l = l->next)
+                       {
+                               el = (Eina_Hash_El *)l;
+                               if (el->data == data)
+                               {
+                                       hash->buckets[hash_num] = eina_inlist_remove(hash->buckets[hash_num], el);
+                                       free(el);
+                                       hash->population--;
+                                       if (hash->population <= 0)
+                                       {
+                                               free(hash);
+                                               hash = NULL;
+                                       }
+                                       return hash;
+                               }
+                       }
+               }
+       }
+       else
+       {
+               hash_num = _eina_hash_gen(key);
+               for (l = hash->buckets[hash_num]; l; l = l->next)
+               {
+                       el = (Eina_Hash_El *)l;
+                       if (!strcmp(el->key, key))
+                       {
+                               hash->buckets[hash_num] = eina_inlist_remove(hash->buckets[hash_num], el);
+                               free(el);
+                               hash->population--;
+                               if (hash->population <= 0)
+                               {
+                                       free(hash);
+                                       hash = NULL;
+                               }
+                               return hash;
+                       }
+               }
+       }
+       return hash;
+}
+
+/**
+ * Retrieves a specific entry in the given hash table.
+ * @param   hash The given hash table.
+ * @param   key  The key string of the entry to find.
+ * @return  The data pointer for the stored entry, or @c NULL if not
+ *          found.
+ * @ingroup Eina_Hash_Data
+ */
+EAPI void * eina_hash_find(const Eina_Hash *hash, const char *key)
+{
+       int hash_num;
+       Eina_Hash_El *el;
+       Eina_Inlist *l;
+
+       _eina_hash_alloc_error = 0;
+       if ((!hash) || (!key))
+               return NULL;
+       hash_num = _eina_hash_gen(key);
+       for (l = hash->buckets[hash_num]; l; l = l->next) {
+               el = (Eina_Hash_El *)l;
+               if (!strcmp(el->key, key)) {
+                       if (l != hash->buckets[hash_num]) {
+                               Eina_Inlist *bucket;
+
+                               bucket = hash->buckets[hash_num];
+                               bucket = eina_inlist_remove(bucket, el);
+                               bucket = eina_inlist_prepend(bucket, el);
+                               ((Eina_Hash *)hash)->buckets[hash_num]
+                                               = bucket;
+                       }
+                       return el->data;
+               }
+       }
+       return NULL;
+}
+
+/**
+ * Modifies the entry pointer at the specified key and returns the old entry
+ * @param   hash The given hash table.
+ * @param   key  The key string of the entry to modify.
+ * @param   data The data to replace the old entry, if it exists.
+ * @return  The data pointer for the old stored entry, or @c NULL if not
+ *          found. If an existing entry is not found, nothing is added to the
+ *          hash.
+ * @ingroup Eina_Hash_Data
+ */
+EAPI void * eina_hash_modify(Eina_Hash *hash, const char *key, const void *data)
+{
+       int hash_num;
+       Eina_Hash_El *el;
+       Eina_Inlist *l;
+
+       _eina_hash_alloc_error = 0;
+       if (!hash)
+               return NULL;
+       hash_num = _eina_hash_gen(key);
+       for (l = hash->buckets[hash_num]; l; l = l->next) {
+               el = (Eina_Hash_El *)l;
+               if ((key) && (!strcmp(el->key, key))) {
+                       void *old_data;
+
+                       if (l != hash->buckets[hash_num]) {
+                               hash->buckets[hash_num]
+                                               = eina_inlist_remove(
+                                                               hash->buckets[hash_num],
+                                                               el);
+                               hash->buckets[hash_num]
+                                               = eina_inlist_prepend(
+                                                               hash->buckets[hash_num],
+                                                               el);
+                       }
+                       old_data = el->data;
+                       el->data = (void *) data;
+                       return old_data;
+               }
+       }
+       return NULL;
+}
+
+/**
+ * @defgroup Eina_Hash_General_Group Hash General Functions
+ *
+ * Miscellaneous functions that operate on hash objects.
+ */
+
+/**
+ * Retrieves the number of buckets available in the given hash table.
+ * @param hash The given hash table.
+ * @return @c 256 if @p hash is not @c NULL.  @c 0 otherwise.
+ * @ingroup Eina_Hash_General_Group
+ */
+EAPI int eina_hash_size(const Eina_Hash *hash)
+{
+       if (!hash)
+               return 0;
+       return 256;
+}
+
+/**
+ * @todo Complete polishing documentation for eina_hash.c. The
+ * functions' docs may be grouped, but they need some simplification.
+ */
+
+/**
+ * Free an entire hash table
+ * @param hash The hash table to be freed
+ *
+ * This function frees up all the memory allocated to storing the specified
+ * hash tale pointed to by @p hash. Any entries in the table that the program
+ * has no more pointers for elsewhere may now be lost, so this should only be
+ * called if the program has lready freed any allocated data in the hash table
+ * or has the pointers for data in teh table stored elswehere as well.
+ *
+ * Example:
+ * @code
+ * extern Eina_Hash *hash;
+ *
+ * eina_hash_free(hash);
+ * hash = NULL;
+ * @endcode
+ * @ingroup Eina_Hash_General_Group
+ */
+EAPI void eina_hash_free(Eina_Hash *hash)
+{
+       int i, size;
+
+       if (!hash)
+               return;
+       size = eina_hash_size(hash);
+       for (i = 0; i < size; i++) {
+               while (hash->buckets[i]) {
+                       Eina_Hash_El *el;
+
+                       el = (Eina_Hash_El *)hash->buckets[i];
+                       hash->buckets[i] = eina_inlist_remove(
+                                       hash->buckets[i], el);
+                       free(el);
+               }
+       }
+       free(hash);
+}
+
+/**
+ * Call a function on every member stored in the hash table
+ * @param hash The hash table whose members will be walked
+ * @param func The function to call on each parameter
+ * @param fdata The data pointer to pass to the function being called
+ *
+ * This function goes through every entry in the hash table @p hash and calls
+ * the function @p func on each member. The function should NOT modify the
+ * hash table contents if it returns 1. IF the hash table contents are
+ * modified by this function or the function wishes to stop processing it must
+ * return 0, otherwise return 1 to keep processing.
+ *
+ * Example:
+ * @code
+ * extern Eina_Hash *hash;
+ *
+ * Eina_Bool hash_fn(Eina_Hash *hash, const char *key, void *data, void *fdata)
+ * {
+ *   printf("Func data: %s, Hash entry: %s / %p\n", fdata, key, data);
+ *   return 1;
+ * }
+ *
+ * int main(int argc, char **argv)
+ * {
+ *   char *hash_fn_data;
+ *
+ *   hash_fn_data = strdup("Hello World");
+ *   eina_hash_foreach(hash, hash_fn, hash_fn_data);
+ *   free(hash_fn_data);
+ * }
+ * @endcode
+ * @ingroup Eina_Hash_General_Group
+ */
+EAPI void eina_hash_foreach(
+               const Eina_Hash *hash,
+               Eina_Bool (*func) (const Eina_Hash *hash, const char *key, void *data, void *fdata),
+               const void *fdata)
+{
+       int i, size;
+
+       if (!hash)
+               return;
+       size = eina_hash_size(hash);
+       for (i = 0; i < size; i++) {
+               Eina_Inlist *l, *next_l;
+
+               for (l = hash->buckets[i]; l;) {
+                       Eina_Hash_El *el;
+
+                       next_l = l->next;
+                       el = (Eina_Hash_El *)l;
+                       if (!func(hash, el->key, el->data, (void *)fdata))
+                               return;
+                       l = next_l;
+               }
+       }
+}
+
+/**
+ * Return memory allocation failure flag after an function requiring allocation
+ * @return The state of the allocation flag
+ *
+ * This function returns the state of the memory allocation flag. This flag is
+ * set if memory allocations fail during eina_hash_add() calls. If they do, 1
+ * will be returned, otherwise 0 will be returned. The flag will remain in its
+ * current state until the next call that requires allocation is called, and
+ * is then reset.
+ *
+ * Example:
+ * @code
+ * Eina_Hash *hash = NULL;
+ * extern void *my_data;
+ *
+ * hash = eina_hash_add(hash, "My Data", my_data);
+ * if (eina_hash_alloc_error())
+ *   {
+ *     fprintf(stderr, "ERROR: Memory is low. Hash allocation failed.\n");
+ *     exit(-1);
+ *   }
+ * if (eina_hash_find(hash, "My Data") == my_data)
+ *   {
+ *     printf("My Data inserted and successfully found.\n");
+ *   }
+ * @endcode
+ * @ingroup Eina_Hash_General_Group
+ */
+EAPI int eina_hash_alloc_error(void)
+{
+       return _eina_hash_alloc_error;
+}
+
+/* Common hash functions */
diff --git a/src/lib/eina_inlist.c b/src/lib/eina_inlist.c
new file mode 100644 (file)
index 0000000..582a714
--- /dev/null
@@ -0,0 +1,161 @@
+#include "Eina.h"
+#include "eina_private.h"
+
+/* TODO please, refactor this :) */
+
+/*============================================================================*
+ *                                   API                                      * 
+ *============================================================================*/
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void * eina_inlist_append(void *in_list, void *in_item) {
+       Eina_Inlist *l, *new_l;
+       Eina_Inlist *list;
+
+       list = in_list;
+       new_l = in_item;
+       new_l->next = NULL;
+       if (!list) {
+               new_l->prev = NULL;
+               new_l->last = new_l;
+               return new_l;
+       }
+       if (list->last)
+               l = list->last;
+       else
+               for (l = list; (l) && (l->next); l = l->next)
+                       ;
+       l->next = new_l;
+       new_l->prev = l;
+       list->last = new_l;
+       return list;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void * eina_inlist_prepend(void *in_list, void *in_item) {
+       Eina_Inlist *new_l;
+       Eina_Inlist *list;
+
+       list = in_list;
+       new_l = in_item;
+       new_l->prev = NULL;
+       if (!list) {
+               new_l->next = NULL;
+               new_l->last = new_l;
+               return new_l;
+       }
+       new_l->next = list;
+       list->prev = new_l;
+       new_l->last = list->last;
+       list->last = NULL;
+       return new_l;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void * eina_inlist_append_relative(void *in_list, void *in_item,
+               void *in_relative) {
+       Eina_Inlist *list, *relative, *new_l;
+
+       list = in_list;
+       new_l = in_item;
+       relative = in_relative;
+       if (relative) {
+               if (relative->next) {
+                       new_l->next = relative->next;
+                       relative->next->prev = new_l;
+               } else
+                       new_l->next = NULL;
+               relative->next = new_l;
+               new_l->prev = relative;
+               if (!new_l->next)
+                       list->last = new_l;
+               return list;
+       }
+       return eina_inlist_append(list, new_l);
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void * eina_inlist_prepend_relative(void *in_list, void *in_item,
+               void *in_relative) {
+       Eina_Inlist *list, *relative, *new_l;
+
+       list = in_list;
+       new_l = in_item;
+       relative = in_relative;
+       if (relative) {
+               new_l->prev = relative->prev;
+               new_l->next = relative;
+               relative->prev = new_l;
+               if (new_l->prev) {
+                       new_l->prev->next = new_l;
+                       if (!new_l->next)
+                               list->last = new_l;
+                       return list;
+               } else {
+                       if (!new_l->next)
+                               new_l->last = new_l;
+                       else {
+                               new_l->last = list->last;
+                               list->last = NULL;
+                       }
+                       return new_l;
+               }
+       }
+       return eina_inlist_prepend(list, new_l);
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void * eina_inlist_remove(void *in_list, void *in_item) {
+       Eina_Inlist *return_l;
+       Eina_Inlist *list, *item;
+
+       /* checkme */
+       if (!in_list)
+               return in_list;
+
+       list = in_list;
+       item = in_item;
+       if (!item)
+               return list;
+       if (item->next)
+               item->next->prev = item->prev;
+       if (item->prev) {
+               item->prev->next = item->next;
+               return_l = list;
+       } else {
+               return_l = item->next;
+               if (return_l)
+                       return_l->last = list->last;
+       }
+       if (item == list->last)
+               list->last = item->prev;
+       item->next = NULL;
+       item->prev = NULL;
+       return return_l;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void * eina_inlist_find(void *in_list, void *in_item) {
+       Eina_Inlist *l;
+       Eina_Inlist *list, *item;
+
+       list = in_list;
+       item = in_item;
+       for (l = list; l; l = l->next) {
+               if (l == item)
+                       return item;
+       }
+       return NULL;
+}
diff --git a/src/lib/eina_lalloc.c b/src/lib/eina_lalloc.c
new file mode 100644 (file)
index 0000000..f2ce80d
--- /dev/null
@@ -0,0 +1,78 @@
+#include "Eina.h"
+#include "eina_private.h"
+
+struct _Eina_Array
+{
+       void    *data;
+       int     num_allocated;
+       int     num_elements;
+       int     acc;
+       Eina_Array_Alloc alloc_cb;
+       Eina_Array_Free free_cb;
+};
+
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI Eina_Array * eina_array_new(void *data, Eina_Array_Alloc alloc_cb, Eina_Array_Free free_cb, int num_init)
+{
+       Eina_Array *a;
+
+       a = calloc(1, sizeof(Eina_Array));
+       a->data = data;
+       a->alloc_cb = alloc_cb;
+       a->free_cb = free_cb;
+       if (num_init > 0)
+       {
+               a->num_allocated = num_init;
+               a->alloc_cb(a->data, a->num_allocated);
+       }
+       return a;
+}
+
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void eina_array_element_add(Eina_Array *a)
+{
+       if (a->num_elements == a->num_allocated)
+       {
+               a->num_allocated = (1 << a->acc);
+               a->acc++;
+               a->alloc_cb(a->data, a->num_allocated);
+       }
+       a->num_elements++;
+}
+
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void eina_array_elements_add(Eina_Array *a, int num)
+{
+       int tmp;
+       
+       tmp = a->num_elements + num;
+       if (tmp > a->num_allocated)
+       {
+               while (tmp > a->num_allocated)
+               {
+                       a->num_allocated = (1 << a->acc);
+                       a->acc++;
+               }
+               a->alloc_cb(a->data, a->num_allocated);
+       }
+       a->num_elements += num;
+}
+
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void eina_array_free(Eina_Array *a)
+{
+       a->free_cb(a->data);
+       free(a);
+}
diff --git a/src/lib/eina_list.c b/src/lib/eina_list.c
new file mode 100644 (file)
index 0000000..0a5a627
--- /dev/null
@@ -0,0 +1,1052 @@
+#include "Eina.h"
+#include "eina_private.h"
+
+struct _Eina_List /** A linked list node */
+{
+   void      *data; /**< Pointer to list element payload */
+   Eina_List *next; /**< Next member in the list */
+   Eina_List *prev; /**< Previous member in the list */
+   struct _Eina_List_Accounting *accounting; /**< Private list accounting info - don't touch */
+};
+
+typedef struct _Eina_List_Accounting Eina_List_Accounting;
+
+struct _Eina_List_Accounting
+{
+   Eina_List *last;
+   int        count;
+};
+
+static int _eina_list_alloc_error = 0;
+
+typedef struct _Eina_Mempool2 Eina_Mempool2;
+
+struct _Eina_Mempool2
+{
+   int           item_size;
+   int           pool_size;
+   int           usage;
+   void         *first, *last;
+};
+
+void *_mempool2_malloc(Eina_Mempool2 *pool, int size)
+{
+       return malloc(size);
+}
+void  _mempool2_free(Eina_Mempool2 *pool, void *ptr)
+{
+       free(ptr);
+}
+void *_mempool2_calloc(Eina_Mempool2 *pool, int size)
+{
+       return calloc(1, size);
+}
+
+static Eina_Mempool2 _eina_list_mempool =
+{
+   sizeof(Eina_List),
+   320,
+   0, NULL, NULL
+};
+static Eina_Mempool2 _eina_list_accounting_mempool =
+{
+   sizeof(Eina_List_Accounting),
+   80,
+   0, NULL, NULL
+};
+   
+/**
+ * @defgroup Eina_List_Data_Group Linked List Creation Functions
+ *
+ * Functions that add data to an Eina_List.
+ */
+
+/**
+ * Appends the given data to the given linked list.
+ *
+ * The following example code demonstrates how to ensure that the
+ * given data has been successfully appended.
+ *
+ * @code
+ * Eina_List *list = NULL;
+ * extern void *my_data;
+ *
+ * list = eina_list_append(list, my_data);
+ * if (eina_list_alloc_error())
+ *   {
+ *     fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n");
+ *     exit(-1);
+ *   }
+ * @endcode
+ *
+ * @param   list The given list.  If @c NULL is given, then a new list
+ *               is created.
+ * @param   data The data to append.
+ * @return  A new list pointer that should be used in place of the one
+ *          given to this function if successful.  Otherwise, the old
+ *          pointer is returned.
+ * @ingroup Eina_List_Data_Group
+ */
+EAPI Eina_List *
+eina_list_append(Eina_List *list, const void *data)
+{
+   Eina_List *l, *new_l;
+
+   _eina_list_alloc_error = 0;
+   new_l = _mempool2_malloc(&_eina_list_mempool, sizeof(Eina_List));
+   if (!new_l)
+     {
+       _eina_list_alloc_error = 1;
+       return list;
+     }
+   new_l->next = NULL;
+   new_l->data = (void *)data;
+   if (!list)
+     {
+       new_l->prev = NULL;
+       new_l->accounting = _mempool2_malloc(&_eina_list_accounting_mempool, sizeof(Eina_List_Accounting));
+       if (!new_l->accounting)
+         {
+            _eina_list_alloc_error = 1;
+            _mempool2_free(&_eina_list_mempool, new_l);
+            return list;
+         }
+       new_l->accounting->last = new_l;
+       new_l->accounting->count = 1;
+       return new_l;
+     }
+   l = list->accounting->last;
+   l->next = new_l;
+   new_l->prev = l;
+   new_l->accounting = list->accounting;
+   list->accounting->last = new_l;
+   list->accounting->count++;
+   return list;
+}
+
+/**
+ * Prepends the given data to the given linked list.
+ *
+ * The following example code demonstrates how to ensure that the
+ * given data has been successfully prepended.
+ *
+ * Example:
+ * @code
+ * Eina_List *list = NULL;
+ * extern void *my_data;
+ *
+ * list = eina_list_prepend(list, my_data);
+ * if (eina_list_alloc_error())
+ *   {
+ *     fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n");
+ *     exit(-1);
+ *   }
+ * @endcode
+ *
+ * @param   list The given list.
+ * @param   data The given data.
+ * @return  A new list pointer that should be used in place of the one
+ *          given to this function, if successful.  Otherwise, the old
+ *          pointer is returned.
+ * @ingroup Eina_List_Data_Group
+ */
+EAPI Eina_List *
+eina_list_prepend(Eina_List *list, const void *data)
+{
+   Eina_List *new_l;
+
+   _eina_list_alloc_error = 0;
+   new_l = _mempool2_malloc(&_eina_list_mempool, sizeof(Eina_List));
+   if (!new_l)
+     {
+       _eina_list_alloc_error = 1;
+       return list;
+     }
+   new_l->prev = NULL;
+   new_l->data = (void *)data;
+   if (!list)
+     {
+       new_l->next = NULL;
+       new_l->accounting = _mempool2_malloc(&_eina_list_accounting_mempool, sizeof(Eina_List_Accounting));
+       if (!new_l->accounting)
+         {
+            _eina_list_alloc_error = 1;
+            _mempool2_free(&_eina_list_mempool, new_l);
+            return list;
+         }
+       new_l->accounting->last = new_l;
+       new_l->accounting->count = 1;
+       return new_l;
+     }
+   new_l->next = list;
+   list->prev = new_l;
+   new_l->accounting = list->accounting;
+   list->accounting->count++;
+   return new_l;
+}
+
+/**
+ * Inserts the given data into the given linked list after the specified data.
+ *
+ * If @p relative is not in the list, @p data is appended to the end of the
+ * list.  If there are multiple instances of @p relative in the list,
+ * @p data is inserted after the first instance.
+ *
+ * The following example code demonstrates how to ensure that the
+ * given data has been successfully inserted.
+ *
+ * @code
+ * Eina_List *list = NULL;
+ * extern void *my_data;
+ * extern void *relative_member;
+ *
+ * list = eina_list_append(list, relative_member);
+ * if (eina_list_alloc_error())
+ *   {
+ *     fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n");
+ *     exit(-1);
+ *   }
+ * list = eina_list_append_relative(list, my_data, relative_member);
+ * if (eina_list_alloc_error())
+ *   {
+ *     fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n");
+ *     exit(-1);
+ *   }
+ * @endcode
+ *
+ * @param   list The given linked list.
+ * @param   data The given data.
+ * @param   relative The data to insert after.
+ * @return  A new list pointer that should be used in place of the one
+ *          given to this function if successful.  Otherwise, the old pointer
+ *          is returned.
+ * @ingroup Eina_List_Data_Group
+ */
+EAPI Eina_List *
+eina_list_append_relative(Eina_List *list, const void *data, const void *relative)
+{
+   Eina_List *l;
+
+   for (l = list; l; l = l->next)
+     {
+       if (l->data == relative)
+         return eina_list_append_relative_list(list, data, l);
+     }
+   return eina_list_append(list, data);
+}
+
+EAPI Eina_List *
+eina_list_append_relative_list(Eina_List *list, const void *data, Eina_List *relative)
+{
+   Eina_List *new_l;
+   
+   if ((!list) || (!relative)) return eina_list_append(list, data);
+   _eina_list_alloc_error = 0;
+   new_l = _mempool2_malloc(&_eina_list_mempool, sizeof(Eina_List));
+   if (!new_l)
+     {
+       _eina_list_alloc_error = 1;
+       return list;
+     }
+   new_l->data = (void *)data;
+   if (relative->next)
+     {
+       new_l->next = relative->next;
+       relative->next->prev = new_l;
+     }
+   else
+     new_l->next = NULL;
+   
+   relative->next = new_l;
+   new_l->prev = relative;
+   new_l->accounting = list->accounting;
+   list->accounting->count++;
+   if (!new_l->next)
+     new_l->accounting->last = new_l;
+   return list;
+}
+
+/**
+ * Prepend a data pointer to a linked list before the memeber specified
+ * @param list The list handle to prepend @p data too
+ * @param data The data pointer to prepend to list @p list before @p relative
+ * @param relative The data pointer before which to insert @p data
+ * @return A new list handle to replace the old one
+
+ * Inserts the given data into the given linked list before the member
+ * specified.
+ *
+ * If @p relative is not in the list, @p data is prepended to the
+ * start of the list.  If there are multiple instances of @p relative
+ * in the list, @p data is inserted before the first instance.
+ *
+ * The following code example demonstrates how to ensure that the
+ * given data has been successfully inserted.
+ *
+ * @code
+ * Eina_List *list = NULL;
+ * extern void *my_data;
+ * extern void *relative_member;
+ *
+ * list = eina_list_append(list, relative_member);
+ * if (eina_list_alloc_error())
+ *   {
+ *     fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n");
+ *     exit(-1);
+ *   }
+ * list = eina_list_prepend_relative(list, my_data, relative_member);
+ * if (eina_list_alloc_error())
+ *   {
+ *     fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n");
+ *     exit(-1);
+ *   }
+ * @endcode
+ *
+ * @param   list The given linked list.
+ * @param   data The given data.
+ * @param   relative The data to insert before.
+ * @return  A new list pointer that should be used in place of the one
+ *          given to this function if successful.  Otherwise the old pointer
+ *          is returned.
+ * @ingroup Eina_List_Data_Group
+ */
+EAPI Eina_List *
+eina_list_prepend_relative(Eina_List *list, const void *data, const void *relative)
+{
+   Eina_List *l;
+
+   _eina_list_alloc_error = 0;
+   for (l = list; l; l = l->next)
+     {
+       if (l->data == relative)
+         return eina_list_prepend_relative_list(list, data, l);
+     }
+   return eina_list_prepend(list, data);
+}
+
+EAPI Eina_List *
+eina_list_prepend_relative_list(Eina_List *list, const void *data, Eina_List *relative)
+{
+   Eina_List *new_l;
+   
+   if ((!list) || (!relative)) return eina_list_prepend(list, data);
+   _eina_list_alloc_error = 0;
+   new_l = _mempool2_malloc(&_eina_list_mempool, sizeof(Eina_List));
+   if (!new_l)
+     {
+       _eina_list_alloc_error = 1;
+       return list;
+     }
+   new_l->data = (void *)data;
+   new_l->prev = relative->prev;
+   new_l->next = relative;
+   if (relative->prev) relative->prev->next = new_l;
+   relative->prev = new_l;
+   new_l->accounting = list->accounting;
+   list->accounting->count++;
+   if (new_l->prev)
+     return list;
+   return new_l;
+}
+
+/**
+ * @defgroup Eina_List_Remove_Group Linked List Remove Functions
+ *
+ * Functions that remove data from linked lists.
+ */
+
+/**
+ * Removes the first instance of the specified data from the given list.
+ *
+ * If the specified data is not in the given list, nothing is done.
+ *
+ * @param   list The given list.
+ * @param   data The specified data.
+ * @return  A new list pointer that should be used in place of the one
+ *          passed to this functions.
+ * @ingroup Eina_List_Remove_Group
+ */
+EAPI Eina_List *
+eina_list_remove(Eina_List *list, const void *data)
+{
+   Eina_List *l;
+
+   for (l = list; l; l = l->next)
+     {
+       if (l->data == data)
+         return eina_list_remove_list(list, l);
+     }
+   return list;
+}
+
+/**
+ * Removes the specified data
+ *
+ * Remove a specified member from a list
+ * @param list The list handle to remove @p remove_list from
+ * @param remove_list The list node which is to be removed
+ * @return A new list handle to replace the old one
+ *
+ * Calling this function takes the list node @p remove_list and removes it
+ * from the list @p list, freeing the list node structure @p remove_list.
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ * Eina_List *l;
+ * extern void *my_data;
+ *
+ * for (l = list; l; l= l->next)
+ *   {
+ *     if (l->data == my_data)
+ *       {
+ *         list = eina_list_remove_list(list, l);
+ *         break;
+ *       }
+ *   }
+ * @endcode
+ * @ingroup Eina_List_Remove_Group
+ */
+EAPI Eina_List *
+eina_list_remove_list(Eina_List *list, Eina_List *remove_list)
+{
+   Eina_List *return_l;
+
+   if (!list) return NULL;
+   if (!remove_list) return list;
+   if (remove_list->next) remove_list->next->prev = remove_list->prev;
+   if (remove_list->prev)
+     {
+       remove_list->prev->next = remove_list->next;
+       return_l = list;
+     }
+   else
+     return_l = remove_list->next;
+   if (remove_list == list->accounting->last)
+     list->accounting->last = remove_list->prev;
+   list->accounting->count--;
+   if (list->accounting->count == 0)
+     _mempool2_free(&_eina_list_accounting_mempool, list->accounting);
+   _mempool2_free(&_eina_list_mempool, remove_list);
+   return return_l;
+}
+
+/**
+ * Moves the specified data to the head of the list
+ *
+ * Move a specified member to the head of the list
+ * @param list The list handle to move @p inside
+ * @param move_list The list node which is to be moved
+ * @return A new list handle to replace the old one
+ *
+ * Calling this function takes the list node @p move_list and moves it
+ * to the front of the @p list.
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ * Eina_List *l;
+ * extern void *my_data;
+ *
+ * for (l = list; l; l= l->next)
+ *   {
+ *     if (l->data == my_data)
+ *       {
+ *         list = eina_list_promote_list(list, l);
+ *         break;
+ *       }
+ *   }
+ * @endcode
+ * @ingroup Eina_List_Promote_Group
+ */
+EAPI Eina_List *
+eina_list_promote_list(Eina_List *list, Eina_List *move_list)
+{
+   Eina_List *return_l;
+
+   if (!list) return NULL;
+   if (!move_list) return list;
+   if (move_list == list) return list;
+   if (move_list->next) move_list->next->prev = move_list->prev;
+   if (move_list->prev)
+     {
+       move_list->prev->next = move_list->next;
+       return_l = list;
+     }
+   else
+     return_l = move_list->next;
+   if (move_list == list->accounting->last)
+     list->accounting->last = move_list->prev;
+   move_list->prev = return_l->prev;
+   if (return_l->prev)
+     return_l->prev->next = move_list;
+   return_l->prev = move_list;
+   move_list->next = return_l;
+   return move_list;
+}
+
+
+
+/**
+ * @defgroup Eina_List_Find_Group Linked List Find Functions
+ *
+ * Functions that find specified data in a linked list.
+ */
+
+/**
+ * Find a member of a list and return the member
+ * @param list The list handle to search for @p data
+ * @param data The data pointer to find in the list @p list
+ * @return The found member data pointer
+ *
+ * A call to this function will search the list @p list from beginning to end
+ * for the first member whose data pointer is @p data. If it is found, @p data
+ * will be returned, otherwise NULL will be returned.
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ * extern void *my_data;
+ *
+ * if (eina_list_find(list, my_data) == my_data)
+ *   {
+ *     printf("Found member %p\n", my_data);
+ *   }
+ * @endcode
+ * @ingroup Eina_List_Find_Group
+ */
+EAPI void *
+eina_list_find(const Eina_List *list, const void *data)
+{
+   const Eina_List *l;
+
+   for (l = list; l; l = l->next)
+     {
+       if (l->data == data) return (void *)data;
+     }
+   return NULL;
+}
+
+/**
+ * Find a member of a list and return the list node containing that member
+ * @param list The list handle to search for @p data
+ * @param data The data pointer to find in the list @p list
+ * @return The found members list node
+ *
+ * A call to this function will search the list @p list from beginning to end
+ * for the first member whose data pointer is @p data. If it is found, the
+ * list node containing the specified member will be returned, otherwise NULL
+ * will be returned.
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ * extern void *my_data;
+ * Eina_List *found_node;
+ *
+ * found_node = eina_list_find_list(list, my_data);
+ * if (found_node)
+ *   {
+ *     printf("Found member %p\n", found_node->data);
+ *   }
+ * @endcode
+ * @ingroup Eina_List_Find_Group
+ */
+EAPI Eina_List *
+eina_list_find_list(const Eina_List *list, const void *data)
+{
+   const Eina_List *l;
+
+   for (l = list; l; l = l->next)
+     {
+       if (l->data == data) return (Eina_List *)l;
+     }
+   return NULL;
+}
+
+/**
+ * Free an entire list and all the nodes, ignoring the data contained
+ * @param list The list to free
+ * @return A NULL pointer
+ *
+ * This function will free all the list nodes in list specified by @p list.
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ *
+ * list = eina_list_free(list);
+ * @endcode
+ * @ingroup Eina_List_Remove_Group
+ */
+EAPI Eina_List *
+eina_list_free(Eina_List *list)
+{
+   Eina_List *l, *free_l;
+
+   if (!list) return NULL;
+   _mempool2_free(&_eina_list_accounting_mempool, list->accounting);
+   for (l = list; l;)
+     {
+       free_l = l;
+       l = l->next;
+       _mempool2_free(&_eina_list_mempool, free_l);
+     }
+   return NULL;
+}
+
+/**
+ * @defgroup Eina_List_Traverse_Group Linked List Traverse Functions
+ *
+ * Functions that you can use to traverse a linked list.
+ */
+
+/**
+ * Get the last list node in the list
+ * @param list The list to get the last list node from
+ * @return The last list node in the list @p list
+ *
+ * This function will return the last list node in the list (or NULL if the
+ * list is empty).
+ *
+ * NB: This is a order-1 operation (it takes the same short time regardless of
+ * the length of the list).
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ * Eina_List *last, *l;
+ *
+ * last = eina_list_last(list);
+ * printf("The list in reverse:\n");
+ * for (l = last; l; l = l->prev)
+ *   {
+ *     printf("%p\n", l->data);
+ *   }
+ * @endcode
+ * @ingroup Eina_List_Traverse_Group
+ */
+EAPI Eina_List *
+eina_list_last(const Eina_List *list)
+{
+   if (!list) return NULL;
+   return list->accounting->last;
+}
+
+/**
+ * Get the next list node after the specified list node
+ * @param list The list node to get the next list node from
+ * @return The next list node, or NULL if no next list node exists
+ *
+ * This function returns the next list node after the current one. It is
+ * equivalent to list->next.
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ * Eina_List *l;
+ *
+ * printf("The list:\n");
+ * for (l = list; l; l = eina_list_next(l))
+ *   {
+ *     printf("%p\n", l->data);
+ *   }
+ * @endcode
+ * @ingroup Eina_List_Traverse_Group
+ */
+EAPI Eina_List *
+eina_list_next(const Eina_List *list)
+{
+   if (!list) return NULL;
+   return list->next;
+}
+
+/**
+ * Get the previous list node before the specified list node
+ * @param list The list node to get the previous list node from
+ * @return The previous list node, or NULL if no previous list node exists
+ *
+ * This function returns the previous list node before the current one. It is
+ * equivalent to list->prev.
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ * Eina_List *last, *l;
+ *
+ * last = eina_list_last(list);
+ * printf("The list in reverse:\n");
+ * for (l = last; l; l = eina_list_prev(l))
+ *   {
+ *     printf("%p\n", l->data);
+ *   }
+ * @endcode
+ * @ingroup Eina_List_Traverse_Group
+ */
+EAPI Eina_List *
+eina_list_prev(const Eina_List *list)
+{
+   if (!list) return NULL;
+   return list->prev;
+}
+
+/**
+ * @defgroup Eina_List_General_Group Linked List General Functions
+ *
+ * Miscellaneous functions that work on linked lists.
+ */
+
+/**
+ * Get the list node data member
+ * @param list The list node to get the data member of
+ * @return The data member from the list node @p list
+ *
+ * This function returns the data member of the specified list node @p list.
+ * It is equivalent to list->data.
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ * Eina_List *l;
+ *
+ * printf("The list:\n");
+ * for (l = list; l; l = eina_list_next(l))
+ *   {
+ *     printf("%p\n", eina_list_data(l));
+ *   }
+ * @endcode
+ * @ingroup Eina_List_General_Group
+ */
+EAPI void *
+eina_list_data(const Eina_List *list)
+{
+   if (!list) return NULL;
+   return list->data;
+}
+
+/**
+ * Get the count of the number of items in a list
+ * @param list The list whose count to return
+ * @return The number of members in the list @p list
+ *
+ * This function returns how many members in the specified list: @p list. If
+ * the list is empty (NULL), 0 is returned.
+ *
+ * NB: This is an order-1 operation and takes the same tiem regardless of the
+ * length of the list.
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ *
+ * printf("The list has %i members\n", eina_list_count(list));
+ * @endcode
+ * @ingroup Eina_List_General_Group
+ */
+EAPI int
+eina_list_count(const Eina_List *list)
+{
+   if (!list) return 0;
+   return list->accounting->count;
+}
+
+/**
+ * Get the nth member's data pointer in a list
+ * @param list The list to get member number @p n from
+ * @param n The number of the element (0 being the first)
+ * @return The data pointer stored in the specified element
+ *
+ * This function returns the data pointer of element number @p n, in the list
+ * @p list. The first element in the array is element number 0. If the element
+ * number @p n does not exist, NULL will be returned.
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ * extern int number;
+ * void *data;
+ *
+ * data = eina_list_nth(list, number);
+ * if (data)
+ *   printf("Element number %i has data %p\n", number, data);
+ * @endcode
+ * @ingroup Eina_List_Find_Group
+ */
+EAPI void *
+eina_list_nth(const Eina_List *list, int n)
+{
+   Eina_List *l;
+   
+   l = eina_list_nth_list(list, n);
+   return l ? l->data : NULL;
+}
+
+/**
+ * Get the nth member's list node in a list
+ * @param list The list to get member number @p n from
+ * @param n The number of the element (0 being the first)
+ * @return The list node stored in the numbered element
+ *
+ * This function returns the list node of element number @p n, in the list
+ * @p list. The first element in the array is element number 0. If the element
+ * number @p n does not exist, NULL will be returned.
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ * extern int number;
+ * Eina_List *nth_list;
+ *
+ * nth_list = eina_list_nth_list(list, number);
+ * if (nth_list)
+ *   printf("Element number %i has data %p\n", number, nth_list->data);
+ * @endcode
+ * @ingroup Eina_List_Find_Group
+ */
+EAPI Eina_List *
+eina_list_nth_list(const Eina_List *list, int n)
+{
+   int i;
+   const Eina_List *l;
+
+   /* check for non-existing nodes */
+   if ((!list) || (n < 0) || 
+       (n > (list->accounting->count - 1)))
+     return NULL;
+
+   /* if the node is in the 2nd half of the list, search from the end
+    * else, search from the beginning.
+    */
+   if (n > (list->accounting->count / 2))
+     {
+       for (i = list->accounting->count - 1,
+            l = list->accounting->last;
+            l; 
+            l = l->prev, i--)
+         {
+            if (i == n) return (Eina_List *)l;
+         }
+     }
+   else
+     {
+       for (i = 0, l = list; l; l = l->next, i++)
+         {
+            if (i == n) return (Eina_List *)l;
+         }
+     }
+   return NULL;
+}
+
+/**
+ * @defgroup Eina_List_Ordering_Group Linked List Ordering Functions
+ *
+ * Functions that change the ordering of data in a linked list.
+ */
+
+/**
+ * Reverse all the elements in the list
+ * @param list The list to reverse
+ * @return The list after it has been reversed
+ *
+ * This takes a list @p list, and reverses the order of all elements in the
+ * list, so the last member is now first, and so on.
+ *
+ * Example:
+ * @code
+ * extern Eina_List *list;
+ *
+ * list = eina_list_reverse(list);
+ * @endcode
+ * @ingroup Eina_List_Ordering_Group
+ */
+EAPI Eina_List *
+eina_list_reverse(Eina_List *list)
+{
+   Eina_List *l1, *l2;
+
+   if (!list) return NULL;
+   l1 = list;
+   l2 = list->accounting->last;
+   while (l1 != l2)
+     {
+       void *data;
+
+       data = l1->data;
+       l1->data = l2->data;
+       l2->data = data;
+       l1 = l1->next;
+       if (l1 == l2) break;
+       l2 = l2->prev;
+     }
+
+   return list;
+}
+
+/**
+ * Sort a list according to the ordering func will return
+ * @param list The list handle to sort
+ * @param size The length of the list to sort
+ * @param func A function pointer that can handle comparing the list data
+ * nodes
+ * @return A new sorted list
+ *
+ * This function sorts your list.  The data in your nodes can be arbitrary,
+ * you just have to be smart enough to know what kind of data is in your
+ * lists
+ *
+ * Example:
+ * @code
+ * int
+ * sort_cb(void *d1, void *d2)
+ * {
+ *   const char *txt = NULL;
+ *    const char *txt2 = NULL;
+ *
+ *    if(!d1) return(1);
+ *    if(!d2) return(-1);
+ *
+ *    return(strcmp((const char*)d1, (const char*)d2));
+ * }
+ * extern Eina_List *list;
+ *
+ * list = eina_list_sort(list, eina_list_count(list), sort_cb);
+ * if (eina_list_alloc_error())
+ *   {
+ *     fprintf(stderr, "ERROR: Memory is low. List Sorting failed.\n");
+ *     exit(-1);
+ *   }
+ * @endcode
+ * @ingroup Eina_List_Ordering_Group
+ */
+EAPI Eina_List *
+eina_list_sort(Eina_List *list, int size, int (*func)(void *, void *))
+{
+   Eina_List*   last;
+   unsigned int        list_number;
+   unsigned int        middle;
+   int         list_size;
+
+   if (!list || !func)
+     return NULL;
+
+   /* if the caller specified an invalid size, sort the whole list */
+   if ((size <= 0) ||
+       (size > list->accounting->count))
+     size = list->accounting->count;
+
+   last = list->accounting->last;
+   middle = size - size / 2;
+
+   for (list_number = middle, list_size = 1;
+       list_size < middle * 2;
+       list_number >>= 1, list_size <<= 1)
+     {
+       Eina_List       *head1 = list;
+       unsigned int    limit = size;
+       unsigned int    process_list;
+       unsigned int    pass_number;
+       unsigned int    split_size = list_size;
+
+       for (process_list = 0; process_list < list_number + 1; ++process_list)
+         {
+            Eina_List          *head2;
+            unsigned int       size_sum;
+            int                size1, size2;
+            int                i;
+
+            size1 = limit < split_size ? limit : split_size;
+            limit -= size1;
+
+            size2 = limit < split_size ? limit : split_size;
+            limit -= size2;
+
+            size_sum = size1 + size2;
+
+            for (head2 = head1, i = 0; i < size1; ++i)
+              head2 = eina_list_next (head2);
+
+            for (pass_number = 0; pass_number < size_sum; ++pass_number)
+              {
+                 Eina_List     *next;
+                 Eina_List     *prev1;
+                 Eina_List     *prev2;
+
+                 if (size1 == 0 || head1 == NULL) /* List1 is empty, head1 is already at the end of the list. So only need to update head2 */
+                   {
+                      for (; pass_number < size_sum; ++pass_number)
+                        head2 = eina_list_next (head2);
+                      break;
+                   }
+                 else
+                   if (size2 == 0 || head2 == NULL) /* List2 is empty, just leave */
+                     break;
+                   else
+                     if (func (head1->data, head2->data) < 0)
+                       {
+                          head1 = eina_list_next (head1);
+                          --size1;
+                       }
+                     else
+                       {
+                          next = eina_list_next (head2);
+                          prev1 = eina_list_prev (head1);
+                          prev2 = eina_list_prev (head2);
+
+                          if (next)
+                            next->prev = prev2;
+                          if (prev1)
+                            prev1->next = head2;
+                          if (prev2)
+                            prev2->next = next;
+
+                          head2->prev = prev1;
+                          head2->next = head1;
+                          head1->prev = head2;
+
+                          --size2;
+
+                           if (head1 == list)
+                             list = head2;
+                           if (head2 == last)
+                             last = prev2;
+
+                          head2 = next;
+                       }
+              }
+            head1 = head2;
+         }
+     }
+
+   list->accounting->last = last;
+   return list;
+}
+/**
+ * Return the memory allocation failure flag after any operation needin allocation
+ * @return The state of the allocation flag
+ *
+ * This function returns the state of the memory allocation flag. This flag is
+ * set if memory allocations during eina_list_append(), eina_list_prepend(),
+ * eina_list_append_relative(), or eina_list_prepend_relative() fail. If they
+ * do fail, 1 will be returned, otherwise 0 will be returned. The flag will
+ * remain in its current state until the next call that requires allocation
+ * is called, and is then reset.
+ *
+ * Example:
+ * @code
+ * Eina_List *list = NULL;
+ * extern void *my_data;
+ *
+ * list = eina_list_append(list, my_data);
+ * if (eina_list_alloc_error())
+ *   {
+ *     fprintf(stderr, "ERROR: Memory is low. List allocation failed.\n");
+ *     exit(-1);
+ *   }
+ * @endcode
+ * @ingroup Eina_List_General_Group
+ */
+EAPI int
+eina_list_alloc_error(void)
+{
+   return _eina_list_alloc_error;
+}
diff --git a/src/lib/eina_mempool.c b/src/lib/eina_mempool.c
new file mode 100644 (file)
index 0000000..7d377e7
--- /dev/null
@@ -0,0 +1,151 @@
+#include "Eina.h"
+#include "eina_private.h"
+/*============================================================================*
+ *                                  Local                                     * 
+ *============================================================================*/
+static Eina_List *_modules;
+static int _init_count = 0;
+
+struct _Eina_Mempool
+{
+#ifdef DEBUG
+       unsigned int magic;
+#endif
+       Eina_Module *module;
+       Eina_Mempool_Backend *backend;
+       void *backend_data;
+};
+static Eina_Mempool * _new_from_buffer(const char *name, void *buffer,
+               unsigned int size, const char *options, va_list args)
+{
+       Eina_List *l;
+       
+       /* load the module with filename == name */
+       for (l = _modules; l; l = eina_list_next(l))
+       {
+               Eina_Module *m;
+
+               m = eina_list_data(l);
+               /* check if the requested module name exists */
+               if (!strncmp(eina_module_name_get(m), name, strlen(name)))
+               {
+                       Eina_Mempool *mp;
+
+                       mp = malloc(sizeof(Eina_Mempool));
+                       eina_module_load(m);
+                       mp->module = m;
+                       mp->backend = eina_module_symbol_get(m, "mp_backend");
+                       mp->backend_data = mp->backend->init(buffer, size, options, args);
+
+                       return mp;
+               }
+       }
+       return NULL;
+}
+/*============================================================================*
+ *                                   API                                      * 
+ *============================================================================*/
+/**
+ * 
+ */
+EAPI int eina_mempool_init(void)
+{
+       if (!_init_count) 
+       {
+               _modules = eina_module_list_get("/usr/local/lib/eina/mm_policies", 0, NULL, NULL);
+       }
+       /* get all the modules */
+       return ++_init_count;
+}
+/**
+ * 
+ */
+EAPI int eina_mempool_shutdown(void)
+{
+       if (!_init_count)
+               return _init_count;
+       _init_count--;
+       if (!_init_count)
+       {
+               /* remove the list of modules */
+               eina_module_list_free(_modules);
+       }
+       return _init_count;
+}
+/**
+ * 
+ */
+EAPI Eina_Mempool * eina_mempool_new_from_buffer(const char *name, void *buffer,
+               unsigned int size, const char *options, ...)
+{
+       Eina_Mempool *mp;
+       va_list args;
+       
+       assert(name);
+       assert(buffer);
+       
+       va_start(args, options);
+       mp = _new_from_buffer(name, buffer, size, options, args);
+       va_end(args);
+       
+       return mp;      
+}
+/**
+ * 
+ */
+EAPI Eina_Mempool * eina_mempool_new(const char *name, unsigned int size, const char 
+               *options, ...)
+{
+       Eina_Mempool *mp;
+       void *buffer;
+       va_list args;
+       
+       assert(name);
+       
+       buffer = malloc(sizeof(char) * size);
+       va_start(args, options);
+       mp = _new_from_buffer(name, buffer, size, options, args);
+       va_end(args);
+       
+       return mp;
+}
+/**
+ * 
+ */
+EAPI void eina_mempool_delete(Eina_Mempool *mp)
+{
+       Eina_List *l;
+       
+       assert(mp);
+       
+       mp->backend->shutdown(mp->backend_data);
+       eina_module_unload(mp->module);
+       free(mp);
+}
+/**
+ * 
+ */
+EAPI void * eina_mempool_realloc(Eina_Mempool *mp, void *element, unsigned int size)
+{
+       
+}
+/**
+ * 
+ */
+EAPI void * eina_mempool_alloc(Eina_Mempool *mp, unsigned int size)
+{
+       assert(mp);
+       assert(mp->backend->alloc);
+       
+       return mp->backend->alloc(mp->backend_data, size);
+}
+/**
+ * 
+ */
+EAPI void eina_mempool_free(Eina_Mempool *mp, void *element)
+{
+       assert(mp);
+       assert(mp->backend->free);
+       
+       mp->backend->free(mp->backend_data, element);
+}
diff --git a/src/lib/eina_module.c b/src/lib/eina_module.c
new file mode 100644 (file)
index 0000000..11f38ff
--- /dev/null
@@ -0,0 +1,280 @@
+#include "Eina.h"
+#include "eina_private.h"
+
+#include <dirent.h>
+#include <string.h>
+#include <dlfcn.h>
+/*============================================================================*
+ *                                  Local                                     * 
+ *============================================================================*/
+struct _Eina_Module
+{
+#ifdef DEBUG
+       unsigned int magic;
+#endif
+       void *handle;
+       char *file;
+};
+
+#define MODULE_EXTENSION ".so"
+
+
+typedef struct _Dir_List_Get_Cb_Data
+{
+       Eina_Module_Cb cb;
+       void *data;
+       Eina_List *list;
+} Dir_List_Get_Cb_Data;
+
+typedef struct _Dir_List_Cb_Data
+{
+       Eina_Module_Cb cb;
+       void *data;
+} Dir_List_Cb_Data;
+
+static int _dir_list_get_cb(Eina_Module *m, void *data)
+{
+       Dir_List_Get_Cb_Data *cb_data = data;
+       int ret = 1;
+       
+       if (cb_data->cb)
+       {
+               ret = cb_data->cb(m, cb_data->data);
+       }
+       if (ret)
+       {
+               cb_data->list = eina_list_append(cb_data->list, m);
+       }
+}
+
+static void _dir_list_cb(const char *name, const char *path, void *data)
+{
+       Dir_List_Cb_Data *cb_data = data;
+       int length;
+
+       length = strlen(name);
+       if (length < strlen(MODULE_EXTENSION) + 1) /* x.so */
+               return;
+       if (!strcmp(name + length - strlen(MODULE_EXTENSION),
+                       MODULE_EXTENSION))
+       {
+               char file[PATH_MAX];
+               Eina_Module *m;
+
+               snprintf(file, PATH_MAX, "%s/%s", path, name);
+               m = eina_module_new(file);
+               if (!m)
+                       return;
+               /* call the user provided cb on this module */
+               cb_data->cb(m, cb_data->data);
+       }
+}
+/*============================================================================*
+ *                                   API                                      * 
+ *============================================================================*/
+/**
+ * Calls the cb function for every module found on the directory path
+ * 
+ * @param path The directory's path to search for modules
+ * @param recursive Iterate recursively on the path
+ * @param cb Callback function to call
+ * @param data Data passed to the callback function
+ */
+EAPI void eina_module_list(const char *path, unsigned int recursive, Eina_Module_Cb cb, void *data)
+{
+       Dir_List_Cb_Data cb_data;
+               
+       assert(path);
+               
+       cb_data.cb = cb;
+       cb_data.data = data;
+       eina_file_dir_list(path, recursive, &_dir_list_cb, &cb_data);
+}
+/**
+ * Gets a list of modules found on the directory path
+ * 
+ * @param path The directory's path to search for modules
+ * @param recursive Iterate recursively on the path
+ * @param cb Callback function to call, if the return value of the callback is zero
+ * it won't be added to the list, if it is one, it will.
+ * @param data Data passed to the callback function
+ */
+EAPI Eina_List * eina_module_list_get(const char *path, unsigned int recursive, Eina_Module_Cb cb, void *data)
+{
+       Dir_List_Get_Cb_Data list_get_cb_data;
+       Dir_List_Cb_Data list_cb_data;
+       
+       assert(path);
+       
+       list_get_cb_data.list = NULL;
+       list_get_cb_data.cb = cb;
+       list_get_cb_data.data = data;
+       
+       list_cb_data.cb = &_dir_list_get_cb;
+       list_cb_data.data = &list_get_cb_data;
+       
+       eina_file_dir_list(path, recursive, &_dir_list_cb, &list_cb_data);
+       
+       return list_get_cb_data.list;
+}
+/**
+ * Load every module on the list of modules
+ * @param list The list of modules
+ */
+EAPI void eina_module_list_load(Eina_List *list)
+{
+       Eina_List *l;
+       
+       for (l = list; l; l = eina_list_next(l))
+       {
+               Eina_Module *m;
+               
+               m = eina_list_data(l);
+               eina_module_load(m);
+       }
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void eina_module_list_unload(Eina_List *list)
+{
+       Eina_List *l;
+       
+       for (l = list; l; l = eina_list_next(l))
+       {
+               Eina_Module *m;
+               
+               m = eina_list_data(l);
+               eina_module_unload(m);
+       }
+}
+/**
+ * Helper function that iterates over the list of modules and calls
+ * eina_module_delete on each
+ * 
+ */
+EAPI void eina_module_list_free(Eina_List *list)
+{
+       Eina_List *l;
+       
+       for (l = list; l; l = eina_list_next(l))
+       {
+               Eina_Module *m;
+               
+               m = eina_list_data(l);
+               eina_module_free(m);
+       }
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI int eina_module_load(Eina_Module *m)
+{
+       void *dl_handle;
+       
+       assert(m);
+       
+       if (m->handle) return 1;
+
+       dl_handle = dlopen(m->file, RTLD_LAZY);
+       if (!dl_handle) return 0;
+       
+       m->handle = dl_handle;
+       return 1;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI Eina_Module * eina_module_new(const char *file)
+{
+       Eina_Module *m;
+       
+       assert(file);
+       /* TODO check that the file exists */
+       
+       m = malloc(sizeof(Eina_Module));
+#ifdef DEBUG
+       /* TODO add the magic */
+#endif
+       m->file = strdup(file);
+       m->handle = NULL;
+       
+       return m;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void eina_module_free(Eina_Module *m)
+{
+       assert(m);
+
+#ifdef DEBUG
+       /* TODO check the magic */
+#endif
+       if (m->handle)
+               eina_module_unload(m);
+       free(m->file);
+       free(m);
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void eina_module_unload(Eina_Module *m)
+{
+       assert(m);
+#ifdef DEBUG
+       /* TODO check the magic */
+#endif
+       if (!m->handle)
+               return;
+       dlclose(m->handle);
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI void * eina_module_symbol_get(Eina_Module *m, const char *symbol)
+{
+       assert(m);
+#ifdef DEBUG
+       /* TODO check the magic */
+#endif
+       return dlsym(m->handle, symbol);        
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI char * eina_module_path_get(Eina_Module *m)
+{
+       char *path;
+       
+       assert(m);
+#ifdef DEBUG
+       /* TODO check the magic */
+#endif
+       eina_file_path_nth_get(m->file, -1, &path, NULL);
+       
+       return path;
+}
+/**
+ * To be documented
+ * FIXME: To be fixed
+ */
+EAPI char * eina_module_name_get(Eina_Module *m)
+{
+       char *name;
+       
+       assert(m);
+#ifdef DEBUG
+       /* TODO check the magic */
+#endif
+       eina_file_path_nth_get(m->file, -1, NULL, &name);
+       
+       return name;
+}
diff --git a/src/lib/eina_value.c b/src/lib/eina_value.c
new file mode 100644 (file)
index 0000000..6a5a4ac
--- /dev/null
@@ -0,0 +1,46 @@
+/* eina_value.c
+
+Copyright (C) 2001 Christopher Rosendahl    <smugg@fatelabs.com>
+                   Nathan Ingersoll         <ningerso@d.umn.edu>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies of the Software and its documentation and acknowledgment shall be
+given in the documentation and software packages that this Software was
+used.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "Eina.h"
+#include "eina_private.h"
+
+EAPI const unsigned int eina_prime_table[] =
+{
+   17, 31, 61, 127, 257, 509, 1021,
+     2053, 4093, 8191, 16381, 32771, 65537, 131071, 262147, 524287, 1048573,
+     2097143, 4194301, 8388617, 16777213
+};
+
+inline void eina_print_warning(const char *function, const char *sparam)
+{
+       fprintf(stderr, "***** Developer Warning ***** :\n"
+               "\tThis program is calling:\n\n"
+               "\t%s();\n\n"
+               "\tWith the parameter:\n\n"
+               "\t%s\n\n"
+               "\tbeing NULL. Please fix your program.\n", function, sparam);
+       fflush(stderr);
+}
diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am
new file mode 100644 (file)
index 0000000..38cd204
--- /dev/null
@@ -0,0 +1,4 @@
+SUBDIRS = mm_policies
+
+MAINTAINERCLEANFILES = \
+Makefile.in
\ No newline at end of file
diff --git a/src/modules/mm_policies/Makefile.am b/src/modules/mm_policies/Makefile.am
new file mode 100644 (file)
index 0000000..6e0b57f
--- /dev/null
@@ -0,0 +1,23 @@
+MAINTAINERCLEANFILES = \
+Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/include
+
+controllerdir = $(libdir)/eina/mm_policies
+controller_LTLIBRARIES = fixed.la ememoa.la
+
+fixed_la_SOURCES = \
+fixed.c
+
+fixed_la_LIBADD       = $(top_builddir)/src/lib/libeina.la
+fixed_la_LDFLAGS      = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+fixed_la_DEPENDENCIES = $(top_builddir)/src/lib/libeina.la
+
+ememoa_la_SOURCES = \
+ememoa.c
+
+ememoa_la_LIBADD       = $(top_builddir)/src/lib/libeina.la
+ememoa_la_LDFLAGS      = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+ememoa_la_DEPENDENCIES = $(top_builddir)/src/lib/libeina.la
diff --git a/src/modules/mm_policies/ememoa.c b/src/modules/mm_policies/ememoa.c
new file mode 100644 (file)
index 0000000..58874ad
--- /dev/null
@@ -0,0 +1,830 @@
+#include "Eina.h"
+#include "eina_private.h"
+
+#include "mempool_struct.h"
+/*============================================================================*
+ *                                  Local                                     * 
+ *============================================================================*/
+#define EMEMOA_MAGIC    0xDEAD5007
+
+#ifdef DEBUG
+#define EMEMOA_CHECK_MAGIC(Memory) \
+        assert(Memory->magic == EMEMOA_MAGIC);
+#else
+#define EMEMOA_CHECK_MAGIC(Memory) ;
+#endif
+
+static int total = 0;
+
+/**
+ * @defgroup Ememoa_Mempool_Base_64m Static buffer allocator.
+ *
+ */
+
+/**
+ * Global context for the static buffer allocator.
+ * @ingroup Ememoa_Mempool_Base_64m
+ * TODO this context is mempool relative
+ */
+//static struct ememoa_memory_base_s *base_64m = NULL;
+
+/**
+ * Remove an item from the base_64m free block list.
+ *
+ * @param       index   Item to be removed.
+ * @return     Will never fail.
+ * @ingroup    Ememoa_Mempool_Base_64m
+ */
+static void ememoa_memory_base_remove_from_list(struct ememoa_memory_base_s *base_64m, uint16_t index)
+{
+       uint16_t prev = base_64m->chunks[index].prev;
+       uint16_t next = base_64m->chunks[index].next;
+
+       if (prev != 0xFFFF)
+               base_64m->chunks[prev].next = next;
+       if (next != 0xFFFF)
+               base_64m->chunks[next].prev = prev;
+       if (base_64m->start == index)
+               base_64m->start = next;
+       if (base_64m->over == index)
+               base_64m->over = prev;
+
+       base_64m->chunks[index].prev = 0xFFFF;
+       base_64m->chunks[index].next = 0xFFFF;
+}
+
+/**
+ * Insert an item in the base_64m free block list.
+ *
+ * @param       index   Item to be inserted.
+ * @return     Will break completely if the item is already in the list.
+ * @ingroup    Ememoa_Mempool_Base_64m
+ */
+static void ememoa_memory_base_insert_in_list(struct ememoa_memory_base_s *base_64m, uint16_t index)
+{
+       uint16_t length = base_64m->chunks[index].length;
+       uint16_t prev = 0xFFFF;
+       uint16_t next;
+
+       if (base_64m->chunks[index].start == 0xFFFF)
+               return;
+
+       for (next = base_64m->start; next != 0xFFFF
+                       && base_64m->chunks[next].length > length; next
+                       = base_64m->chunks[next].next)
+               prev = next;
+
+       assert(index != next);
+       assert(index != prev);
+
+       base_64m->chunks[index].next = next;
+       base_64m->chunks[index].prev = prev;
+
+       if (next != 0xFFFF)
+               base_64m->chunks[next].prev = index;
+       else
+               base_64m->over = index;
+
+       if (prev != 0xFFFF)
+               base_64m->chunks[prev].next = index;
+       else
+               base_64m->start = index;
+}
+
+/**
+ * Merge two chunk of memory together. Choose the index of the resulting
+ * chunk as the one requiring less effort for committing the change. No
+ * requirement on parameters order or any other characteristic exist.
+ *
+ * @param       one     First part of the chunk to be merged.
+ * @param       two     Second part of the chunk to be merged.
+ * @return     Index of the new chunk.
+ * @ingroup    Ememoa_Mempool_Base_64m
+ */
+static uint16_t ememoa_memory_base_merge_64m(struct ememoa_memory_base_s *base_64m, uint16_t one, uint16_t two)
+{
+       uint16_t index;
+       uint16_t tmp;
+
+       if (base_64m->chunks[one].length < base_64m->chunks[two].length)
+       {
+               tmp = one;
+               one = two;
+               two = tmp;
+       }
+
+       /* All page refering to 'two' now refere to 'one'. */
+       for (index = base_64m->chunks[two].start; index
+                       != base_64m->chunks[two].end; ++index)
+               base_64m->pages[index] = one;
+       base_64m->pages[index] = one;
+
+       if (base_64m->chunks[one].start < base_64m->chunks[two].start)
+               base_64m->chunks[one].end = base_64m->chunks[two].end;
+       else
+               base_64m->chunks[one].start = base_64m->chunks[two].start;
+
+       base_64m->chunks[one].length += base_64m->chunks[two].length;
+
+       base_64m->chunks[two].start = 0xFFFF;
+       base_64m->chunks[two].use = 0;
+       if (base_64m->jump > two)
+               base_64m->jump = two;
+
+       return one;
+}
+
+/**
+ * Split a chunk in two, allocating a new one on the fly and doing as few as possible
+ * memory update. The new allocated chunk could be used as the left or right part of
+ * the splitted chunk depending on the fastest strategie. You will need to guess by your
+ * self what was our choice.
+ *
+ * @param       index   The item to split.
+ * @param       length  The required size for one of the two resulting chunk.
+ * @return     0xFFFF, if the chunk already has the right size otherwise the new allocated chunk.
+ * @ingroup    Ememoa_Mempool_Base_64m
+ */
+static uint16_t ememoa_memory_base_split_64m(struct ememoa_memory_base_s *base_64m, uint16_t index, unsigned int length)
+{
+       if (base_64m->chunks[index].length != length)
+       {
+               struct ememoa_memory_base_chunck_s a;
+               struct ememoa_memory_base_chunck_s b;
+               uint16_t i;
+               uint16_t splitted;
+
+               while (!(base_64m->chunks[base_64m->jump].start == 0xFFFF
+                               && base_64m->chunks[base_64m->jump].prev
+                                               == 0xFFFF
+                               && base_64m->chunks[base_64m->jump].next
+                                               == 0xFFFF))
+                       base_64m->jump++;
+
+               splitted = base_64m->jump++;
+               ememoa_memory_base_remove_from_list(base_64m, index);
+
+               a = base_64m->chunks[index];
+
+               b.length = a.length - length;
+               b.end = a.end;
+               b.start = a.start + length;
+               b.next = 0xFFFF;
+               b.prev = 0xFFFF;
+               b.use = 0;
+
+               a.length = length;
+               a.end = a.start + length - 1;
+               a.use = 1;
+
+               if (a.length < b.length)
+               {
+                       base_64m->chunks[index] = b;
+                       base_64m->chunks[splitted] = a;
+                       ememoa_memory_base_insert_in_list(base_64m, index);
+               } else
+               {
+                       base_64m->chunks[index] = a;
+                       base_64m->chunks[splitted] = b;
+                       ememoa_memory_base_insert_in_list(base_64m, splitted);
+               }
+
+               for (i = base_64m->chunks[splitted].start; i
+                               != base_64m->chunks[splitted].end; ++i)
+                       base_64m->pages[i] = splitted;
+               base_64m->pages[i] = splitted;
+
+               return splitted;
+       }
+       return 0xFFFF;
+}
+
+/**
+ * @defgroup Ememoa_Mempool_Base_Resize_List Function enabling manipulation of array with linked list properties.
+ *
+ */
+#define RESIZE_POOL_SIZE 128
+struct ememoa_memory_base_resize_list_pool_s {
+       struct ememoa_memory_base_resize_list_pool_s *next;
+
+       unsigned int count;
+#ifdef USE64
+       uint64_t map[2];
+#else
+       uint32_t map[4];
+#endif
+       struct ememoa_memory_base_resize_list_s array[RESIZE_POOL_SIZE];
+};
+
+static struct ememoa_memory_base_resize_list_pool_s *resize_pool = NULL;
+#if 0
+
+/**
+ * Allocate a new resizable list (it's an array now). It currently use to much memory
+ * when using the base_64m allocator, it could be fixed if really usefull (Not high priority at this time).
+ *
+ * @param       size    items size inside the list.
+ * @return     Will return a pointer to the base array.
+ * @ingroup    Ememoa_Mempool_Base_Resize_List
+ */
+struct ememoa_memory_base_resize_list_s* ememoa_memory_base_resize_list_new(
+               unsigned int size)
+{
+       struct ememoa_memory_base_resize_list_s *tmp;
+       struct ememoa_memory_base_resize_list_pool_s *over;
+       unsigned int i;
+       int pos;
+
+       if (size == 0)
+               return NULL;
+
+       for (over = resize_pool; over && over->count == RESIZE_POOL_SIZE; over
+                       = over->next)
+               ;
+
+       if (!over)
+       {
+               over
+                               = ememoa_memory_base_alloc(sizeof(struct ememoa_memory_base_resize_list_pool_s));
+               if (!over)
+                       return NULL;
+
+               over->next = resize_pool;
+               over->count = 0;
+
+#ifdef USE64
+               for (i = 0; i < 2; ++i)
+#else
+               for (i = 0; i < 4; ++i)
+#endif
+                       over->map[i] = ~0;
+
+               resize_pool = over;
+       }
+
+#ifdef USE64
+       for (i = 0, pos = 0; i < 2 && pos == 0; ++i)
+#else
+       for (i = 0, pos = 0; i < 4 && pos == 0; ++i)
+#endif
+#ifdef USE64
+               pos = ffsll (over->map[i]);
+#else
+               pos = ffs(over->map[i]);
+#endif
+
+       over->count++;
+       pos--;
+       i--;
+
+#ifdef USE64
+       assert(i >= 0 && i < 2);
+       assert(pos >= 0 && pos < 64);
+       tmp = over->array + pos + i * 64;
+#else
+       assert(i >= 0 && i < 4);
+       assert(pos >= 0 && pos < 32);
+       tmp = over->array + pos + i * 32;
+#endif
+
+       over->map[i] &= ~(1 << pos);
+
+       bzero(tmp, sizeof(struct ememoa_memory_base_resize_list_s));
+       tmp->size = size;
+
+#ifdef DEBUG
+       tmp->magic = EMEMOA_MAGIC;
+#endif
+
+       return tmp;
+}
+#endif
+/**
+ * Clean a list and all it's item.
+ *
+ * @param       base    List
+ * @ingroup    Ememoa_Mempool_Base_Resize_List
+ */
+void ememoa_memory_base_resize_list_clean(
+               struct ememoa_memory_base_resize_list_s* base)
+{
+       struct ememoa_memory_base_resize_list_pool_s *over;
+       int index;
+
+       if (!base)
+               return;
+
+       EMEMOA_CHECK_MAGIC(base);
+
+       ememoa_memory_base_free(base->pool);
+       ememoa_memory_base_free(base->bitmap);
+
+#ifdef DEBUG
+       if (base->actif != 0)
+       fprintf(stderr, "Warning some element where not freed from this list.\n");
+#endif
+
+#ifdef DEBUG
+       base->magic = 0;
+#endif
+
+       for (over = resize_pool; over && !(over->array <= base && base
+                       < over->array + RESIZE_POOL_SIZE); over = over->next)
+               ;
+
+       assert(over != NULL);
+
+       index = base - over->array;
+
+#ifdef USE64
+       over->map[index / 64] |= (1 << (index % 64));
+#else
+       over->map[index / 32] |= (1 << (index % 32));
+#endif
+}
+#if 0
+/**
+ * Allocate a new item in the list "base".
+ *
+ * @param       base    Pointer to a valid and activ list.
+ * @return     Will return the new item index.
+ * @ingroup    Ememoa_Mempool_Base_Resize_List
+ */
+int ememoa_memory_base_resize_list_new_item(
+               struct ememoa_memory_base_resize_list_s *base)
+{
+       int i;
+
+       if (base == NULL)
+               return -1;
+
+       EMEMOA_CHECK_MAGIC(base);
+
+       if (base->count < base->actif + 1)
+       {
+               unsigned int count;
+               uint32_t *tmp_bitmap;
+               void *tmp_pool;
+
+               count = base->count + 32;
+
+               tmp_pool = ememoa_memory_base_realloc(base->pool, count
+                               * base->size);
+               if (!tmp_pool)
+                       return -1;
+               base->pool = tmp_pool;
+
+               tmp_bitmap = ememoa_memory_base_realloc(base->bitmap, (count
+                               >> 5) * sizeof(uint32_t));
+               if (!tmp_bitmap)
+                       return -1;
+               base->bitmap = tmp_bitmap;
+
+               base->bitmap[base->count >> 5] = 0xFFFFFFFF;
+
+#ifdef DEBUG
+               memset ((uint8_t*) tmp_pool + base->count * base->size, 43, base->size * 32);
+#endif
+               base->count = count;
+
+       }
+
+       for (; base->jump < (base->count >> 5) && base->bitmap[base->jump] == 0; ++base->jump)
+               ;
+
+       assert(base->jump < (base->count >> 5));
+
+       i = ffs(base->bitmap[base->jump]) - 1;
+
+       assert(i >= 0 && i < 32);
+
+       base->bitmap[base->jump] &= ~(1 << i);
+       base->actif++;
+
+       return (base->jump << 5) + i;
+}
+#endif
+/**
+ * Give the pointer corresponding to an item index.
+ *
+ * @param       base    Pointer to a valid and activ list.
+ * @param       index   Item index given by ememoa_memory_base_resize_list_new_item.
+ * @return     Will return a pointer to the item.
+ * @ingroup    Ememoa_Mempool_Base_Resize_List
+ */
+void* ememoa_memory_base_resize_list_get_item(
+               struct ememoa_memory_base_resize_list_s *base, int index)
+{
+       EMEMOA_CHECK_MAGIC(base);
+
+       if (index < 0)
+               return NULL;
+
+       return (void*) ((uint8_t*) base->pool + index * base->size);
+}
+
+/**
+ * Give back an item to the list.
+ *
+ * @param       base    Pointer to a valid and activ list.
+ * @param       index   Item index given by ememoa_memory_base_resize_list_new_item.
+ * @ingroup    Ememoa_Mempool_Base_Resize_List
+ */
+void ememoa_memory_base_resize_list_back(
+               struct ememoa_memory_base_resize_list_s *base, int index)
+{
+       unsigned int shift;
+       unsigned int i;
+
+       EMEMOA_CHECK_MAGIC(base);
+
+       if (index < 0)
+               return;
+
+       shift = index >> 5;
+       i = index & 0x1F;
+
+       base->bitmap[shift] |= (1 << i);
+       base->actif--;
+
+       if (shift < base->jump)
+               base->jump = shift;
+
+#ifdef DEBUG
+       memset ((uint8_t*) base->pool + base->size * index, 44, base->size);
+#endif
+}
+#if 0
+/**
+ * Make some attempt to resize the size of the list.
+ *
+ * @param       base    Pointer to a valid and activ list.
+ * @return      Will 0 is nothing where freed, -1 if not enought memory
+ *              is available for the operation and anything else if successfull.
+ * @ingroup     Ememoa_Mempool_Base_Resize_List
+ */
+int ememoa_memory_base_resize_list_garbage_collect(
+               struct ememoa_memory_base_resize_list_s *base)
+{
+       uint32_t *tmp_bitmap;
+       void *tmp_pool;
+       unsigned int count;
+
+       EMEMOA_CHECK_MAGIC(base);
+
+       count = base->count;
+
+       for (; base->count > 0 && base->bitmap[(base->count >> 5)] == 0xFFFFFFFF; base->count -= 32)
+               ;
+
+       tmp_pool = ememoa_memory_base_realloc(base->pool, base->count
+                       * base->size);
+       if (!tmp_pool)
+               return -1;
+       base->pool = tmp_pool;
+
+       tmp_bitmap = ememoa_memory_base_realloc(base->bitmap,
+                       (base->count >> 5) * sizeof(uint32_t));
+       if (!tmp_bitmap)
+               return -1;
+       base->bitmap = tmp_bitmap;
+
+       return count != base->count;
+}
+#endif
+/**
+ * Call fct on all allocated item of the list and return the sum of fct result.
+ *
+ * @param       base    Pointer to a valid and activ list.
+ * @param       start   Index to start at.
+ * @param       end     Index to end the walk.
+ * @param       fct     The callback function.
+ * @param       ctx     An obscure pointer that will be directly passed, without any
+ *                      check/change to each fct call.
+ * @return      Will return the sum of fct result.
+ * @ingroup     Ememoa_Mempool_Base_Resize_List
+ */
+int ememoa_memory_base_resize_list_walk_over(
+               struct ememoa_memory_base_resize_list_s *base, int start,
+               int end, int (*fct)(void *ctx, int index, void *data), void *ctx)
+{
+       int bitmap;
+       int first;
+       int end_shift;
+       int end_i;
+       int shift;
+       int i;
+       int result = 0;
+
+       EMEMOA_CHECK_MAGIC(base);
+
+       i = start & 0x1F;
+
+       if (end < 0)
+               end = base->count - 1;
+
+       if (end == -1)
+               return 0;
+
+       end_shift = end >> 5;
+       end_i = end & 0x1F;
+
+       for (shift = start >> 5; shift < end_shift; ++shift)
+       {
+               bitmap = ~base->bitmap[shift];
+               first = ffs(bitmap) - 1;
+
+               i = i > first ? i : first;
+               for (bitmap >>= i; i < 32; ++i, bitmap >>= 1, ++start)
+                       if (bitmap & 0x1)
+                               result += fct(ctx, start, base->pool + start
+                                               * base->size);
+               i = 0;
+       }
+
+       bitmap = ~base->bitmap[shift];
+       for (bitmap >>= i; i < end_i; ++i, bitmap >>= 1, ++start)
+               if (bitmap & 0x1)
+                       result += fct(ctx, start, base->pool + start
+                                       * base->size);
+
+       return result;
+}
+
+/**
+ * Call fct as long as fct doesn't return a value different from 0.
+ *
+ * @param       base    Pointer to a valid and activ list.
+ * @param       start   Index to start at.
+ * @param       end     Index to end the walk.
+ * @param       fct     The callback function.
+ * @param       ctx     An obscure pointer that will be directly passed, without any
+ *                      check/change to each fct call.
+ * @param       index   If different from NULL, put the index on which we stop in it.
+ * @return      Will return a pointer to the item where we stop the search.
+ * @ingroup     Ememoa_Mempool_Base_Resize_List
+ */
+void* ememoa_memory_base_resize_list_search_over(
+               struct ememoa_memory_base_resize_list_s *base, int start,
+               int end, int (*fct)(void *ctx, int index, void *data), void *ctx,
+               int *index)
+{
+       int bitmap;
+       int first;
+       int end_shift;
+       int end_i;
+       int shift;
+       int i;
+
+       EMEMOA_CHECK_MAGIC(base);
+
+       i = start & 0x1F;
+
+       if (end < 0)
+               end = base->count - 1;
+
+       if (end == -1)
+               return NULL;
+
+       end_shift = end >> 5;
+       end_i = end & 0x1F;
+
+       for (shift = start >> 5; shift < end_shift; ++shift)
+       {
+               bitmap = ~base->bitmap[shift];
+               first = ffs(bitmap) - 1;
+
+               i = i > first ? i : first;
+               for (bitmap >>= i; i < 32; ++i, bitmap >>= 1, ++start)
+                       if (bitmap & 0x1)
+                               if (fct(ctx, start, base->pool + start
+                                               * base->size))
+                                       goto found;
+               i = 0;
+       }
+
+       bitmap = ~base->bitmap[shift];
+       for (bitmap >>= i; i < end_i; ++i, bitmap >>= 1, ++start)
+               if (bitmap & 0x1)
+                       if (fct(ctx, start, base->pool + start * base->size))
+                               goto found;
+
+       if (index)
+               *index = 0;
+       return NULL;
+
+       found: if (index)
+               *index = start;
+       return base->pool + start * base->size;
+}
+
+static void ememoa_free(void *data, void *element)
+{
+       struct ememoa_memory_base_s *base_64m = data;
+       unsigned int delta = element - base_64m->base;
+       uint16_t index;
+       uint16_t chunk_index;
+       uint16_t prev_chunk_index;
+       uint16_t next_chunk_index;
+
+       if (element == NULL)
+               return;
+
+       assert(element > base_64m->base);
+
+       index = delta >> 12;
+       chunk_index = base_64m->pages[index];
+
+       total -= base_64m->chunks[chunk_index].length;
+#ifdef ALLOC_REPORT
+       fprintf(stderr, "free %i [%i] => %p\n", base_64m->chunks[chunk_index].length, total << 12, ptr);
+#endif
+
+       prev_chunk_index = base_64m->pages[index - 1];
+       next_chunk_index
+                       = base_64m->pages[base_64m->chunks[chunk_index].end + 1];
+
+       if (index > 0 && prev_chunk_index < base_64m->chunks_count)
+               if (base_64m->chunks[prev_chunk_index].use == 0)
+               {
+                       ememoa_memory_base_remove_from_list(base_64m, prev_chunk_index);
+                       chunk_index = ememoa_memory_base_merge_64m(base_64m, chunk_index,
+                                       prev_chunk_index);
+               }
+
+       if (base_64m->chunks[chunk_index].end < base_64m->chunks_count
+                       && next_chunk_index < base_64m->chunks_count)
+               if (base_64m->chunks[next_chunk_index].use == 0)
+               {
+                       ememoa_memory_base_remove_from_list(base_64m, next_chunk_index);
+                       chunk_index = ememoa_memory_base_merge_64m(base_64m, chunk_index,
+                                       next_chunk_index);
+               }
+
+       ememoa_memory_base_insert_in_list(base_64m, chunk_index);
+       base_64m->chunks[chunk_index].use = 0;
+}
+static void * ememoa_alloc(void *data, unsigned int size)
+{
+       struct ememoa_memory_base_s *base_64m = data;
+       uint16_t real = (size >> 12) + (size & 0xFFF ? 1 : 0);
+       uint16_t jump = base_64m->start;
+       uint16_t prev = 0xFFFF;
+
+       while (jump != 0xFFFF && base_64m->chunks[jump].length > real)
+       {
+               prev = jump;
+               jump = base_64m->chunks[jump].next;
+       }
+
+       if (prev != 0xFFFF)
+       {
+               uint16_t splitted = ememoa_memory_base_split_64m(base_64m, prev, real);
+               uint16_t allocated;
+               uint16_t empty;
+
+               /* Guess who is who */
+               allocated = base_64m->chunks[prev].use == 1 ? prev : splitted;
+               empty = base_64m->chunks[prev].use == 1 ? splitted : prev;
+
+               total += real;
+#ifdef ALLOC_REPORT
+               fprintf(stderr, "alloc %i(%i) [%i] => %p\n", real << 12, size, total << 12, ((uint8_t*) base_64m->base) + (base_64m->chunks[allocated].start << 12));
+#endif
+               return ((uint8_t*) base_64m->base)
+                               + (base_64m->chunks[allocated].start << 12);
+       }
+       return NULL;
+}
+
+static void *ememoa_realloc(void *data, void *element, unsigned int size)
+{
+       struct ememoa_memory_base_s *base_64m = data;
+       void* tmp;
+       unsigned int delta = element - base_64m->base;
+       uint16_t real = (size >> 12) + (size & 0xFFF ? 1 : 0);
+       uint16_t index;
+       uint16_t chunk_index;
+       uint16_t next_chunk_index;
+
+       if (element == NULL)
+               return ememoa_alloc(base_64m, size);
+
+       assert(element > base_64m->base);
+
+       index = delta >> 12;
+       chunk_index = base_64m->pages[index];
+
+       /* FIXME: Not resizing when the size is big enough */
+       if (real <= base_64m->chunks[chunk_index].length)
+               return element;
+
+       next_chunk_index
+                       = base_64m->pages[base_64m->chunks[chunk_index].end + 1];
+
+       if (base_64m->chunks[next_chunk_index].use == 0)
+               if (real <= base_64m->chunks[next_chunk_index].length
+                               + base_64m->chunks[chunk_index].length)
+               {
+                       uint16_t splitted;
+                       uint16_t allocated;
+                       int tmp;
+
+                       total -= base_64m->chunks[chunk_index].length;
+                       tmp = base_64m->chunks[chunk_index].length;
+
+                       ememoa_memory_base_remove_from_list(base_64m, next_chunk_index);
+                       chunk_index = ememoa_memory_base_merge_64m(base_64m, chunk_index,
+                                       next_chunk_index);
+                       splitted = ememoa_memory_base_split_64m(base_64m, chunk_index,
+                                       real);
+
+                       allocated
+                                       = base_64m->chunks[chunk_index].use
+                                                       == 1 ? chunk_index
+                                                       : splitted;
+
+                       ememoa_memory_base_remove_from_list(base_64m, allocated);
+
+                       total += real;
+#ifdef ALLOC_REPORT
+                       fprintf(stderr, "realloc %i(%i) [%i] => %p\n", (real - tmp) << 12, size, total << 12, ((uint8_t*) base_64m->base) + (base_64m->chunks[allocated].start << 12));
+#endif
+
+                       return ((uint8_t*) base_64m->base)
+                                       + (base_64m->chunks[allocated].start
+                                                       << 12);
+               }
+
+       tmp = ememoa_alloc(base_64m, size);
+       if (!tmp)
+               return NULL;
+
+       memcpy(tmp, element, base_64m->chunks[chunk_index].length << 12);
+       ememoa_memory_base_free_64m(element);
+
+       return tmp;
+}
+
+static void *ememoa_init(void *buffer, unsigned int size, const char *options, va_list args)
+{
+       struct ememoa_memory_base_s *new_64m = buffer;
+       unsigned int temp_size;
+
+       temp_size = (size - sizeof(struct ememoa_memory_base_s)) >> 12;
+       if (temp_size <= 1)
+       {
+               /* TODO handle an error */
+               return NULL;
+       }
+
+#ifdef DEBUG
+       new_64m->magic = EMEMOA_MAGIC;
+#endif
+       new_64m->chunks
+                       = (struct ememoa_memory_base_chunck_s*) ((struct ememoa_memory_base_s*) new_64m
+                                       + 1);
+       new_64m->pages
+                       = (uint16_t*)((struct ememoa_memory_base_chunck_s*) new_64m->chunks
+                                       + temp_size + 1);
+       new_64m->base = ((uint16_t*) new_64m->pages + temp_size + 1);
+       new_64m->start = 0;
+
+       new_64m->chunks_count
+                       = (size - sizeof(struct ememoa_memory_base_s)
+                                       - temp_size
+                                                       * (sizeof(struct ememoa_memory_base_chunck_s)
+                                                                       + sizeof(uint16_t)))
+                                       / 4096;
+
+       memset(new_64m->chunks, 0xFF,
+                       sizeof(struct ememoa_memory_base_chunck_s) * temp_size);
+       memset(new_64m->pages, 0, sizeof(uint16_t) * temp_size);
+
+       new_64m->chunks[0].start = 0;
+       new_64m->chunks[0].end = new_64m->chunks_count - 1;
+       new_64m->chunks[0].length = new_64m->chunks_count;
+       new_64m->chunks[0].next = 0xFFFF;
+       new_64m->chunks[0].prev = 0xFFFF;
+       new_64m->chunks[0].use = 0;
+       new_64m->over = 0;
+       new_64m->start = 0;
+       new_64m->jump = 1;
+
+       return new_64m;
+}
+
+static void ememoa_shutdown(void *data)
+{
+
+}
+/*============================================================================*
+ *                                   API                                      * 
+ *============================================================================*/
+Eina_Mempool_Backend mp_backend = {
+               .init = &ememoa_init,
+               .shutdown = &ememoa_shutdown,
+               .realloc = &ememoa_realloc,
+               .alloc = &ememoa_alloc,
+               .free = &ememoa_free, 
+};
diff --git a/src/modules/mm_policies/ememoa_memory_base.h b/src/modules/mm_policies/ememoa_memory_base.h
new file mode 100644 (file)
index 0000000..516bbc5
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+** Copyright Cedric BAIL, 2006
+** contact: cedric.bail@free.fr
+**
+*/
+
+#ifndef         EMEMOA_MEMORY_BASE_H__
+# define        EMEMOA_MEMORY_BASE_H__
+
+#include <stdint.h>
+
+struct ememoa_memory_base_resize_list_s
+{
+#ifdef DEBUG
+   unsigned int                                 magic;
+#endif
+
+   void                                         *pool;
+   uint32_t                                     *bitmap;
+
+   unsigned int                                 jump;
+   unsigned int                                 count;
+   unsigned int                                 actif;
+   unsigned int                                 size;
+};
+
+/* Direct use of this two function is most of the time a bad idea. */
+//extern void*    (*ememoa_memory_base_alloc)(unsigned int size);
+//extern void     (*ememoa_memory_base_free)(void *ptr);
+//extern void*    (*ememoa_memory_base_realloc)(void* ptr, unsigned int size);
+
+int     ememoa_memory_base_init_64m(void* buffer, unsigned int size);
+
+struct ememoa_memory_base_resize_list_s*        ememoa_memory_base_resize_list_new (unsigned int size);
+void    ememoa_memory_base_resize_list_clean (struct ememoa_memory_base_resize_list_s*  base);
+int     ememoa_memory_base_resize_list_new_item (struct ememoa_memory_base_resize_list_s *base);
+void*   ememoa_memory_base_resize_list_get_item (struct ememoa_memory_base_resize_list_s *base, int index);
+void    ememoa_memory_base_resize_list_back (struct ememoa_memory_base_resize_list_s *base, int index);
+int     ememoa_memory_base_resize_list_walk_over (struct ememoa_memory_base_resize_list_s *base,
+                                                  int start,
+                                                  int end,
+                                                  int (*fct)(void *ctx, int index, void *data),
+                                                  void *ctx);
+void*   ememoa_memory_base_resize_list_search_over (struct ememoa_memory_base_resize_list_s *base,
+                                                    int start,
+                                                    int end,
+                                                    int (*fct)(void *ctx, int index, void *data),
+                                                    void *ctx,
+                                                    int *index);
+
+/* Be carefull when you call this function, you will loose all index mapping after this call. */
+int     ememoa_memory_base_resize_list_garbage_collect (struct ememoa_memory_base_resize_list_s *base);
+
+#endif          /* EMEMOA_MEMORY_BASE_H__ */
diff --git a/src/modules/mm_policies/ememoa_mempool_error.h b/src/modules/mm_policies/ememoa_mempool_error.h
new file mode 100644 (file)
index 0000000..ca4c8f3
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+** Copyright Cedric BAIL, 2006
+** contact: cedric.bail@free.fr
+**
+*/
+
+#ifndef                EMEMOA_MEMPOOL_ERROR_H__
+# define       EMEMOA_MEMPOOL_ERROR_H__
+
+typedef enum _ememoa_mempool_error_e
+  {
+    EMEMOA_NO_ERROR,
+    EMEMOA_ERROR_INIT_ALREADY_DONE,
+    EMEMOA_ERROR_REALLOC_AVAILABLE_OBJECTS_FAILED,
+    EMEMOA_ERROR_REALLOC_OBJECTS_USE_FAILED,
+    EMEMOA_ERROR_REALLOC_JUMP_OBJECT_FAILED,
+    EMEMOA_ERROR_REALLOC_OBJECTS_POOL_FAILED,
+    EMEMOA_ERROR_MALLOC_NEW_POOL,
+    EMEMOA_ERROR_PUSH_ADDRESS_NOT_FOUND,
+    EMEMOA_NO_EMPTY_POOL,
+    EMEMOA_DOUBLE_PUSH,
+    EMEMOA_NO_MORE_MEMORY,
+    EMEMOA_INVALID_MEMPOOL
+  } ememoa_mempool_error_t;
+
+const char*
+ememoa_mempool_error2string (ememoa_mempool_error_t error_code);
+
+#endif         /* EMEMOA_MEMPOOL_ERROR_H__ */
diff --git a/src/modules/mm_policies/fixed.c b/src/modules/mm_policies/fixed.c
new file mode 100644 (file)
index 0000000..0f37954
--- /dev/null
@@ -0,0 +1,29 @@
+#include "Eina.h"
+#include "eina_private.h"
+
+static void push(void *data, void *element)
+{
+       
+}
+static void * pop(void *data, unsigned int size)
+{
+       return NULL;
+}
+
+static void *init(unsigned int size)
+{
+       return NULL;
+}
+
+static void shutdown(void *data)
+{
+       
+}
+
+Eina_Mempool_Backend mp_backend = {
+       .init = &init,
+       .shutdown = &shutdown,
+       .alloc = &pop,
+       .free = &push,
+};
+
diff --git a/src/modules/mm_policies/mempool_struct.h b/src/modules/mm_policies/mempool_struct.h
new file mode 100644 (file)
index 0000000..2c2128a
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+** Copyright Cedric BAIL, 2006
+** contact: cedric.bail@free.fr
+**
+*/
+
+#ifndef                MEMPOOL_STRUCT_H__
+# define       MEMPOOL_STRUCT_H__
+
+#include       "config.h"
+
+#include       <stdint.h>
+
+#ifdef HAVE_PTHREAD
+# include      <pthread.h>
+#endif
+
+#include        "ememoa_memory_base.h"
+//#include        "ememoa_mempool_error.h"
+
+struct ememoa_memory_base_chunck_s
+{
+   uint16_t                                     start;
+   uint16_t                                     end;
+   uint16_t                                     length;
+
+   uint16_t                                     next;
+   uint16_t                                     prev;
+
+   uint8_t                                      use;
+};
+
+struct ememoa_memory_base_s
+{
+#ifdef DEBUG
+   unsigned int                                 magic;
+#endif
+   void                                         *base;
+
+   struct ememoa_memory_base_chunck_s           *chunks;
+   uint16_t                                     *pages;
+
+   unsigned int                                 chunks_count;
+
+   uint16_t                                     start;
+   uint16_t                                     over;
+   uint16_t                                     jump;
+};
+
+#endif         /* MEMPOOL_STRUCT_H__ */