forked from enlightenment/efl
Adding turran work to unify EFL data types and functions.
SVN revision: 35248
This commit is contained in:
parent
e20edb01e2
commit
a92e3d6c83
|
@ -0,0 +1,2 @@
|
|||
Jorge Luis "turran" Zapata <jorgeluis.zapata@gmail.com>
|
||||
Carsten Haitzler <raster@rasterman.com>
|
|
@ -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,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,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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
SUBDIRS = lib include modules
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
|
@ -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 */
|
|
@ -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)
|
|
@ -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_*/
|
|
@ -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_*/
|
|
@ -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_*/
|
|
@ -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_*/
|
|
@ -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_*/
|
|
@ -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
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_*/
|
|
@ -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_ */
|
|
@ -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_*/
|
|
@ -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_*/
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
SUBDIRS = mm_policies
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in
|
|
@ -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
|
|
@ -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,
|
||||
};
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -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__ */
|
Loading…
Reference in New Issue