Adding turran work to unify EFL data types and functions.

SVN revision: 35248
This commit is contained in:
Cedric BAIL 2008-07-30 12:46:55 +00:00
parent e20edb01e2
commit a92e3d6c83
44 changed files with 4595 additions and 0 deletions

2
legacy/eina/AUTHORS Normal file
View File

@ -0,0 +1,2 @@
Jorge Luis "turran" Zapata <jorgeluis.zapata@gmail.com>
Carsten Haitzler <raster@rasterman.com>

0
legacy/eina/COPYING Normal file
View File

0
legacy/eina/ChangeLog Normal file
View File

139
legacy/eina/Doxyfile Normal file
View File

@ -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

0
legacy/eina/INSTALL Normal file
View File

32
legacy/eina/Makefile.am Normal file
View File

@ -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

0
legacy/eina/NEWS Normal file
View File

0
legacy/eina/README Normal file
View File

14
legacy/eina/autogen.sh Executable file
View File

@ -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

92
legacy/eina/configure.in Normal file
View File

@ -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

12
legacy/eina/eina.pc.in Normal file
View File

@ -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

9
legacy/eina/gendoc Executable file
View File

@ -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

View File

@ -0,0 +1,3 @@
SUBDIRS = lib include modules
MAINTAINERCLEANFILES = Makefile.in

View File

@ -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 */

View File

@ -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)

View File

@ -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_*/

View File

@ -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_*/

View File

@ -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_*/

View File

@ -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_*/

View File

@ -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_*/

View File

@ -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

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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_*/

View File

@ -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_ */

View File

@ -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_*/

View File

@ -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_*/

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);
}

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -0,0 +1,4 @@
SUBDIRS = mm_policies
MAINTAINERCLEANFILES = \
Makefile.in

View File

@ -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

View File

@ -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,
};

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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,
};

View File

@ -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__ */