forked from enlightenment/efl
no more ecore-data - as warned before. going going oging... gone!
SVN revision: 46994
This commit is contained in:
parent
f883c94804
commit
755e44a6d9
|
@ -84,10 +84,6 @@ EXTRA_DIST = AUTHORS COPYING COPYING-PLAIN \
|
|||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = ecore.pc
|
||||
|
||||
if BUILD_ECORE_DATA
|
||||
pkgconfig_DATA += ecore-data.pc
|
||||
endif
|
||||
|
||||
if BUILD_ECORE_CON
|
||||
pkgconfig_DATA += ecore-con.pc
|
||||
endif
|
||||
|
|
|
@ -38,7 +38,6 @@ case "$host_os" in
|
|||
*)
|
||||
ecore_config_release_info="-release $release"
|
||||
ecore_con_release_info="-release $release"
|
||||
ecore_data_release_info="-release $release"
|
||||
ecore_directfb_release_info="-release $release"
|
||||
ecore_evas_release_info="-release $release"
|
||||
ecore_fb_release_info="-release $release"
|
||||
|
@ -57,7 +56,6 @@ case "$host_os" in
|
|||
esac
|
||||
AC_SUBST(ecore_config_release_info)
|
||||
AC_SUBST(ecore_con_release_info)
|
||||
AC_SUBST(ecore_data_release_info)
|
||||
AC_SUBST(ecore_directfb_release_info)
|
||||
AC_SUBST(ecore_evas_release_info)
|
||||
AC_SUBST(ecore_fb_release_info)
|
||||
|
@ -110,7 +108,6 @@ want_tslib="no"
|
|||
want_glib="no"
|
||||
|
||||
# core modules
|
||||
want_ecore_data="no"
|
||||
want_ecore_con="yes"
|
||||
want_ecore_ipc="no"
|
||||
want_ecore_file="yes"
|
||||
|
@ -228,7 +225,6 @@ esac
|
|||
requirements_ecore=""
|
||||
requirements_ecore_con=""
|
||||
requirements_ecore_config=""
|
||||
requirements_ecore_data=""
|
||||
requirements_ecore_directfb=""
|
||||
requirements_ecore_evas=""
|
||||
requirements_ecore_fb=""
|
||||
|
@ -397,7 +393,6 @@ PKG_CHECK_MODULES(EINA, [eina-0])
|
|||
requirements_ecore="eina-0 ${requirements_ecore}"
|
||||
requirements_ecore_con="ecore eina-0 ${requirements_ecore_con}"
|
||||
requirements_ecore_config="ecore eina-0 ${requirements_ecore_config}"
|
||||
requirements_ecore_data="ecore eina-0 ${requirements_ecore_data}"
|
||||
requirements_ecore_directfb="ecore eina-0 ${requirements_ecore_directfb}"
|
||||
requirements_ecore_evas="ecore eina-0 ${requirements_ecore_evas}"
|
||||
requirements_ecore_fb="ecore eina-0 ${requirements_ecore_fb}"
|
||||
|
@ -959,9 +954,6 @@ fi
|
|||
|
||||
## Core modules
|
||||
|
||||
# ecore_data
|
||||
ECORE_CHECK_MODULE([data], [${want_ecore_data}], [Data])
|
||||
|
||||
# ecore_con
|
||||
ECORE_CHECK_MODULE([con], [${want_ecore_con}], [Con], [${have_addrinfo}])
|
||||
|
||||
|
@ -1294,7 +1286,6 @@ ECORE_EVAS_CHECK_MODULE([software-16-wince],
|
|||
AC_SUBST(requirements_ecore)
|
||||
AC_SUBST(requirements_ecore_con)
|
||||
AC_SUBST(requirements_ecore_config)
|
||||
AC_SUBST(requirements_ecore_data)
|
||||
AC_SUBST(requirements_ecore_directfb)
|
||||
AC_SUBST(requirements_ecore_evas)
|
||||
AC_SUBST(requirements_ecore_fb)
|
||||
|
@ -1314,7 +1305,6 @@ AC_OUTPUT([
|
|||
Makefile
|
||||
ecore-con.pc
|
||||
ecore-config.pc
|
||||
ecore-data.pc
|
||||
ecore-directfb.pc
|
||||
ecore-evas.pc
|
||||
ecore-fb.pc
|
||||
|
@ -1338,7 +1328,6 @@ src/lib/Makefile
|
|||
src/lib/ecore/Makefile
|
||||
src/lib/ecore_con/Makefile
|
||||
src/lib/ecore_config/Makefile
|
||||
src/lib/ecore_data/Makefile
|
||||
src/lib/ecore_directfb/Makefile
|
||||
src/lib/ecore_evas/Makefile
|
||||
src/lib/ecore_fb/Makefile
|
||||
|
@ -1371,7 +1360,6 @@ echo
|
|||
echo " Ecore........................: always"
|
||||
echo " Thread support.............: $have_pthread"
|
||||
echo " GLib support...............: $have_glib"
|
||||
echo " Ecore_Data...................: $have_ecore_data (deprecated)"
|
||||
echo " Ecore_Con....................: $have_ecore_con"
|
||||
if test "x$have_ecore_con" = "xyes" ; then
|
||||
echo $ECHO_N " OpenSSL....................: $have_openssl $ECHO_C"
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: ecore-data
|
||||
Description: Ecore data library
|
||||
@pkgconfig_requires_private@: @requirements_ecore_data@
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lecore_data
|
||||
Cflags: -I${includedir}
|
|
@ -17,5 +17,4 @@ ecore_evas \
|
|||
ecore_config \
|
||||
ecore_file \
|
||||
ecore_imf \
|
||||
ecore_imf_evas \
|
||||
ecore_data
|
||||
ecore_imf_evas
|
||||
|
|
|
@ -1,516 +0,0 @@
|
|||
#ifndef _ECORE_DATA_H
|
||||
# define _ECORE_DATA_H
|
||||
|
||||
/* we need this for size_t */
|
||||
#include <stddef.h>
|
||||
|
||||
#include <Eina.h>
|
||||
#warning "this file is deprecated. use Eina.h instead."
|
||||
|
||||
#ifdef EAPI
|
||||
# undef EAPI
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef EFL_ECORE_BUILD
|
||||
# ifdef DLL_EXPORT
|
||||
# define EAPI __declspec(dllexport)
|
||||
# else
|
||||
# define EAPI
|
||||
# endif /* ! DLL_EXPORT */
|
||||
# else
|
||||
# define EAPI __declspec(dllimport)
|
||||
# endif /* ! EFL_ECORE_BUILD */
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# if __GNUC__ >= 4
|
||||
# define EAPI __attribute__ ((visibility("default")))
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
#endif /* ! _WIN32 */
|
||||
|
||||
/**
|
||||
* @file Ecore_Data.h
|
||||
* @brief Contains threading, list, hash, debugging and tree functions.
|
||||
*/
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# ifdef __sgi
|
||||
# define __FUNCTION__ "unknown"
|
||||
# ifndef __cplusplus
|
||||
# define inline
|
||||
# endif
|
||||
# endif
|
||||
|
||||
EAPI extern const unsigned int ecore_prime_table[];
|
||||
|
||||
# define ECORE_SORT_MIN 0
|
||||
# define ECORE_SORT_MAX 1
|
||||
|
||||
typedef void (*Ecore_For_Each) (void *value, void *user_data);
|
||||
# define ECORE_FOR_EACH(function) ((Ecore_For_Each)function)
|
||||
|
||||
typedef void (*Ecore_Free_Cb) (void *data);
|
||||
# define ECORE_FREE_CB(func) ((Ecore_Free_Cb)func)
|
||||
|
||||
typedef unsigned int (*Ecore_Hash_Cb) (const void *key);
|
||||
# define ECORE_HASH_CB(function) ((Ecore_Hash_Cb)function)
|
||||
|
||||
typedef int (*Ecore_Compare_Cb) (const void *data1, const void *data2);
|
||||
# define ECORE_COMPARE_CB(function) ((Ecore_Compare_Cb)function)
|
||||
|
||||
typedef struct _ecore_list Ecore_List;
|
||||
# define ECORE_LIST(list) ((Ecore_List *)list)
|
||||
|
||||
typedef struct _ecore_list_node Ecore_List_Node;
|
||||
# define ECORE_LIST_NODE(node) ((Ecore_List_Node *)node)
|
||||
|
||||
typedef Eina_Strbuf Ecore_Strbuf;
|
||||
# define ECORE_STRBUF(buf) ((Ecore_Strbuf *)buf)
|
||||
|
||||
struct _ecore_list_node {
|
||||
void *data;
|
||||
struct _ecore_list_node *next;
|
||||
};
|
||||
|
||||
struct _ecore_list {
|
||||
Ecore_List_Node *first; /* The first node in the list */
|
||||
Ecore_List_Node *last; /* The last node in the list */
|
||||
Ecore_List_Node *current; /* The current node in the list */
|
||||
|
||||
Ecore_Free_Cb free_func; /* The callback to free data in nodes */
|
||||
|
||||
int nodes; /* The number of nodes in the list */
|
||||
int index; /* The position from the front of the
|
||||
list of current node */
|
||||
};
|
||||
|
||||
EAPI int ecore_direct_compare(const void *key1, const void *key2) EINA_DEPRECATED;
|
||||
EAPI int ecore_str_compare(const void *key1, const void *key2) EINA_DEPRECATED;
|
||||
|
||||
EAPI unsigned int ecore_direct_hash(const void *key) EINA_DEPRECATED;
|
||||
EAPI unsigned int ecore_str_hash(const void *key) EINA_DEPRECATED;
|
||||
|
||||
/* Creating and initializing new list structures */
|
||||
EAPI Ecore_List *ecore_list_new(void) EINA_DEPRECATED;
|
||||
EAPI int ecore_list_init(Ecore_List *list) EINA_DEPRECATED;
|
||||
|
||||
/* Adding items to the list */
|
||||
EAPI int ecore_list_append(Ecore_List * list, void *_data) EINA_DEPRECATED;
|
||||
EAPI int ecore_list_prepend(Ecore_List * list, void *_data) EINA_DEPRECATED;
|
||||
EAPI int ecore_list_insert(Ecore_List * list, void *_data) EINA_DEPRECATED;
|
||||
EAPI int ecore_list_append_list(Ecore_List * list, Ecore_List * append) EINA_DEPRECATED;
|
||||
EAPI int ecore_list_prepend_list(Ecore_List * list, Ecore_List * prepend) EINA_DEPRECATED;
|
||||
|
||||
/* Removing items from the list */
|
||||
EAPI int ecore_list_remove_destroy(Ecore_List *list) EINA_DEPRECATED;
|
||||
EAPI void *ecore_list_remove(Ecore_List * list) EINA_DEPRECATED;
|
||||
EAPI void *ecore_list_first_remove(Ecore_List * list) EINA_DEPRECATED;
|
||||
EAPI void *ecore_list_last_remove(Ecore_List * list) EINA_DEPRECATED;
|
||||
|
||||
/* Retrieve the current position in the list */
|
||||
EAPI void *ecore_list_current(Ecore_List * list) EINA_DEPRECATED;
|
||||
EAPI void *ecore_list_first(Ecore_List * list) EINA_DEPRECATED;
|
||||
EAPI void *ecore_list_last(Ecore_List * list) EINA_DEPRECATED;
|
||||
EAPI int ecore_list_index(Ecore_List * list) EINA_DEPRECATED;
|
||||
EAPI int ecore_list_count(Ecore_List * list) EINA_DEPRECATED;
|
||||
|
||||
/* Traversing the list */
|
||||
EAPI int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function,
|
||||
void *user_data) EINA_DEPRECATED;
|
||||
EAPI void *ecore_list_first_goto(Ecore_List * list) EINA_DEPRECATED;
|
||||
EAPI void *ecore_list_last_goto(Ecore_List * list) EINA_DEPRECATED;
|
||||
EAPI void *ecore_list_index_goto(Ecore_List * list, int index) EINA_DEPRECATED;
|
||||
EAPI void *ecore_list_goto(Ecore_List * list, const void *_data) EINA_DEPRECATED;
|
||||
|
||||
/* Traversing the list and returning data */
|
||||
EAPI void *ecore_list_next(Ecore_List * list) EINA_DEPRECATED;
|
||||
EAPI void *ecore_list_find(Ecore_List *list, Ecore_Compare_Cb function,
|
||||
const void *user_data) EINA_DEPRECATED;
|
||||
|
||||
/* Sorting the list */
|
||||
EAPI int ecore_list_sort(Ecore_List *list, Ecore_Compare_Cb compare,
|
||||
char order) EINA_DEPRECATED;
|
||||
EAPI int ecore_list_mergesort(Ecore_List *list, Ecore_Compare_Cb compare,
|
||||
char order) EINA_DEPRECATED;
|
||||
EAPI int ecore_list_heapsort(Ecore_List *list, Ecore_Compare_Cb compare,
|
||||
char order) EINA_DEPRECATED;
|
||||
EAPI void ecore_list_merge(Ecore_List *list, Ecore_List *l2,
|
||||
Ecore_Compare_Cb, char order) EINA_DEPRECATED;
|
||||
|
||||
/* Check to see if there is any data in the list */
|
||||
EAPI int ecore_list_empty_is(Ecore_List * list) EINA_DEPRECATED;
|
||||
|
||||
/* Remove every node in the list without freeing the list itself */
|
||||
EAPI int ecore_list_clear(Ecore_List * list) EINA_DEPRECATED;
|
||||
/* Free the list and it's contents */
|
||||
EAPI void ecore_list_destroy(Ecore_List *list) EINA_DEPRECATED;
|
||||
|
||||
/* Creating and initializing list nodes */
|
||||
EAPI Ecore_List_Node *ecore_list_node_new(void) EINA_DEPRECATED;
|
||||
EAPI int ecore_list_node_init(Ecore_List_Node *newNode) EINA_DEPRECATED;
|
||||
|
||||
/* Destroying nodes */
|
||||
EAPI int ecore_list_node_destroy(Ecore_List_Node * _e_node, Ecore_Free_Cb free_func) EINA_DEPRECATED;
|
||||
|
||||
EAPI int ecore_list_free_cb_set(Ecore_List * list, Ecore_Free_Cb free_func) EINA_DEPRECATED;
|
||||
|
||||
typedef Ecore_List Ecore_DList;
|
||||
# define ECORE_DLIST(dlist) ((Ecore_DList *)dlist)
|
||||
|
||||
typedef struct _ecore_dlist_node Ecore_DList_Node;
|
||||
# define ECORE_DLIST_NODE(dlist) ((Ecore_DList_Node *)dlist)
|
||||
|
||||
struct _ecore_dlist_node {
|
||||
Ecore_List_Node single;
|
||||
Ecore_DList_Node *previous;
|
||||
};
|
||||
|
||||
/* Creating and initializing new list structures */
|
||||
EAPI Ecore_DList *ecore_dlist_new(void) EINA_DEPRECATED;
|
||||
EAPI int ecore_dlist_init(Ecore_DList *list) EINA_DEPRECATED;
|
||||
EAPI void ecore_dlist_destroy(Ecore_DList *list) EINA_DEPRECATED;
|
||||
|
||||
/* Adding items to the list */
|
||||
EAPI int ecore_dlist_append(Ecore_DList * _e_dlist, void *_data) EINA_DEPRECATED;
|
||||
EAPI int ecore_dlist_prepend(Ecore_DList * _e_dlist, void *_data) EINA_DEPRECATED;
|
||||
EAPI int ecore_dlist_insert(Ecore_DList * _e_dlist, void *_data) EINA_DEPRECATED;
|
||||
EAPI int ecore_dlist_append_list(Ecore_DList * _e_dlist, Ecore_DList * append) EINA_DEPRECATED;
|
||||
EAPI int ecore_dlist_prepend_list(Ecore_DList * _e_dlist, Ecore_DList * prepend) EINA_DEPRECATED;
|
||||
|
||||
/* Info about list's state */
|
||||
# define ecore_dlist_first(list) ecore_list_first(list)
|
||||
# define ecore_dlist_last(list) ecore_list_last(list)
|
||||
EAPI void *ecore_dlist_current(Ecore_DList *list) EINA_DEPRECATED;
|
||||
EAPI int ecore_dlist_index(Ecore_DList *list) EINA_DEPRECATED;
|
||||
# define ecore_dlist_count(list) ecore_list_count(list)
|
||||
|
||||
/* Removing items from the list */
|
||||
EAPI void *ecore_dlist_remove(Ecore_DList * _e_dlist) EINA_DEPRECATED;
|
||||
EAPI void *ecore_dlist_first_remove(Ecore_DList * _e_dlist) EINA_DEPRECATED;
|
||||
EAPI int ecore_dlist_remove_destroy(Ecore_DList *list) EINA_DEPRECATED;
|
||||
EAPI void *ecore_dlist_last_remove(Ecore_DList * _e_dlist) EINA_DEPRECATED;
|
||||
|
||||
/* Traversing the list */
|
||||
# define ecore_dlist_for_each(list, function, user_data) \
|
||||
ecore_list_for_each(list, function, user_data)
|
||||
EAPI void *ecore_dlist_first_goto(Ecore_DList * _e_dlist) EINA_DEPRECATED;
|
||||
EAPI void *ecore_dlist_last_goto(Ecore_DList * _e_dlist) EINA_DEPRECATED;
|
||||
EAPI void *ecore_dlist_index_goto(Ecore_DList * _e_dlist, int index) EINA_DEPRECATED;
|
||||
EAPI void *ecore_dlist_goto(Ecore_DList * _e_dlist, void *_data) EINA_DEPRECATED;
|
||||
|
||||
/* Traversing the list and returning data */
|
||||
EAPI void *ecore_dlist_next(Ecore_DList * list) EINA_DEPRECATED;
|
||||
EAPI void *ecore_dlist_previous(Ecore_DList * list) EINA_DEPRECATED;
|
||||
|
||||
/* Sorting the list */
|
||||
EAPI int ecore_dlist_sort(Ecore_DList *list, Ecore_Compare_Cb compare,
|
||||
char order) EINA_DEPRECATED;
|
||||
EAPI int ecore_dlist_mergesort(Ecore_DList *list, Ecore_Compare_Cb compare,
|
||||
char order) EINA_DEPRECATED;
|
||||
# define ecore_dlist_heapsort(list, compare, order) \
|
||||
ecore_list_heapsort(list, compare, order)
|
||||
EAPI void ecore_dlist_merge(Ecore_DList *list, Ecore_DList *l2,
|
||||
Ecore_Compare_Cb, char order) EINA_DEPRECATED;
|
||||
|
||||
/* Check to see if there is any data in the list */
|
||||
EAPI int ecore_dlist_empty_is(Ecore_DList * _e_dlist) EINA_DEPRECATED;
|
||||
|
||||
/* Remove every node in the list without free'ing it */
|
||||
EAPI int ecore_dlist_clear(Ecore_DList * _e_dlist) EINA_DEPRECATED;
|
||||
|
||||
/* Creating and initializing list nodes */
|
||||
EAPI int ecore_dlist_node_init(Ecore_DList_Node * node) EINA_DEPRECATED;
|
||||
EAPI Ecore_DList_Node *ecore_dlist_node_new(void) EINA_DEPRECATED;
|
||||
|
||||
/* Destroying nodes */
|
||||
EAPI int ecore_dlist_node_destroy(Ecore_DList_Node * node, Ecore_Free_Cb free_func) EINA_DEPRECATED;
|
||||
|
||||
EAPI int ecore_dlist_free_cb_set(Ecore_DList * dlist, Ecore_Free_Cb free_func) EINA_DEPRECATED;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Hash Table Implementation:
|
||||
*
|
||||
* Traditional hash table implementation. I had tried a list of tables
|
||||
* approach to save on the realloc's but it ended up being much slower than
|
||||
* the traditional approach.
|
||||
*/
|
||||
|
||||
typedef struct _ecore_hash_node Ecore_Hash_Node;
|
||||
# define ECORE_HASH_NODE(hash) ((Ecore_Hash_Node *)hash)
|
||||
|
||||
struct _ecore_hash_node {
|
||||
Ecore_Hash_Node *next; /* Pointer to the next node in the bucket list */
|
||||
void *key; /* The key for the data node */
|
||||
void *value; /* The value associated with this node */
|
||||
};
|
||||
|
||||
typedef struct _ecore_hash Ecore_Hash;
|
||||
# define ECORE_HASH(hash) ((Ecore_Hash *)hash)
|
||||
|
||||
struct _ecore_hash {
|
||||
Ecore_Hash_Node **buckets;
|
||||
int size; /* An index into the table of primes to
|
||||
determine size */
|
||||
int nodes; /* The number of nodes currently in the hash */
|
||||
|
||||
int index; /* The current index into the bucket table */
|
||||
|
||||
Ecore_Compare_Cb compare; /* The function used to compare node values */
|
||||
Ecore_Hash_Cb hash_func; /* The callback function to determine hash */
|
||||
|
||||
Ecore_Free_Cb free_key; /* The callback function to free key */
|
||||
Ecore_Free_Cb free_value; /* The callback function to free value */
|
||||
};
|
||||
|
||||
/* Create and initialize a hash */
|
||||
EAPI Ecore_Hash *ecore_hash_new(Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare) EINA_DEPRECATED;
|
||||
EAPI int ecore_hash_init(Ecore_Hash *hash, Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare) EINA_DEPRECATED;
|
||||
|
||||
/* Functions related to freeing the data in the hash table */
|
||||
EAPI int ecore_hash_free_key_cb_set(Ecore_Hash *hash, Ecore_Free_Cb function) EINA_DEPRECATED;
|
||||
EAPI int ecore_hash_free_value_cb_set(Ecore_Hash *hash, Ecore_Free_Cb function) EINA_DEPRECATED;
|
||||
EAPI void ecore_hash_destroy(Ecore_Hash *hash) EINA_DEPRECATED;
|
||||
|
||||
EAPI int ecore_hash_count(Ecore_Hash *hash) EINA_DEPRECATED;
|
||||
EAPI int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func,
|
||||
void *user_data) EINA_DEPRECATED;
|
||||
EAPI Ecore_List *ecore_hash_keys(Ecore_Hash *hash) EINA_DEPRECATED;
|
||||
|
||||
/* Retrieve and store data into the hash */
|
||||
EAPI void *ecore_hash_get(Ecore_Hash *hash, const void *key) EINA_DEPRECATED;
|
||||
EAPI int ecore_hash_set(Ecore_Hash *hash, void *key, void *value) EINA_DEPRECATED;
|
||||
EAPI int ecore_hash_hash_set(Ecore_Hash *hash, Ecore_Hash *set) EINA_DEPRECATED;
|
||||
EAPI void *ecore_hash_remove(Ecore_Hash *hash, const void *key) EINA_DEPRECATED;
|
||||
EAPI void *ecore_hash_find(Ecore_Hash *hash, Ecore_Compare_Cb compare, const void *value) EINA_DEPRECATED;
|
||||
EAPI void ecore_hash_dump_graph(Ecore_Hash *hash) EINA_DEPRECATED;
|
||||
EAPI void ecore_hash_dump_stats(Ecore_Hash *hash) EINA_DEPRECATED;
|
||||
|
||||
|
||||
typedef struct _ecore_path_group Ecore_Path_Group;
|
||||
# define ECORE_PATH_GROUP(group) ((Ecore_Path_Group *)(group))
|
||||
|
||||
struct _ecore_path_group
|
||||
{
|
||||
Eina_List *paths;
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a new path group
|
||||
*/
|
||||
EAPI Ecore_Path_Group *ecore_path_group_new(void) EINA_DEPRECATED;
|
||||
|
||||
/*
|
||||
* Destroy a previous path group
|
||||
*/
|
||||
EAPI void ecore_path_group_del(Ecore_Path_Group *group) EINA_DEPRECATED;
|
||||
|
||||
/*
|
||||
* Add a directory to be searched for files
|
||||
*/
|
||||
EAPI void ecore_path_group_add(Ecore_Path_Group *group, const char *path) EINA_DEPRECATED;
|
||||
|
||||
/*
|
||||
* Remove a directory to be searched for files
|
||||
*/
|
||||
EAPI void ecore_path_group_remove(Ecore_Path_Group *group, const char *path) EINA_DEPRECATED;
|
||||
|
||||
/*
|
||||
* Find the absolute path if it exists in the group of paths
|
||||
*/
|
||||
EAPI char * ecore_path_group_find(Ecore_Path_Group *group, const char *name) EINA_DEPRECATED;
|
||||
|
||||
/*
|
||||
* Get a list of all the available files in a path set
|
||||
*/
|
||||
EAPI Eina_List * ecore_path_group_available_get(Ecore_Path_Group *group) EINA_DEPRECATED;
|
||||
|
||||
|
||||
typedef struct _ecore_plugin Ecore_Plugin;
|
||||
struct _ecore_plugin
|
||||
{
|
||||
void *handle;
|
||||
};
|
||||
|
||||
/*
|
||||
* Load the specified plugin
|
||||
*/
|
||||
EAPI Ecore_Plugin *ecore_plugin_load(Ecore_Path_Group *group, const char *plugin, const char *version) EINA_DEPRECATED;
|
||||
|
||||
/*
|
||||
* Unload the specified plugin
|
||||
*/
|
||||
EAPI void ecore_plugin_unload(Ecore_Plugin * plugin) EINA_DEPRECATED;
|
||||
|
||||
/*
|
||||
* Lookup the specified symbol for the plugin
|
||||
*/
|
||||
EAPI void *ecore_plugin_symbol_get(Ecore_Plugin * plugin, const char *symbol_name) EINA_DEPRECATED;
|
||||
|
||||
EAPI Eina_List *ecore_plugin_available_get(Ecore_Path_Group *group) EINA_DEPRECATED;
|
||||
|
||||
|
||||
typedef struct _ecore_heap Ecore_Sheap;
|
||||
# define ECORE_HEAP(heap) ((Ecore_Sheap *)heap)
|
||||
|
||||
struct _ecore_heap {
|
||||
void **data;
|
||||
int size;
|
||||
int space;
|
||||
|
||||
char order, sorted;
|
||||
|
||||
/* Callback for comparing node values, default is direct comparison */
|
||||
Ecore_Compare_Cb compare;
|
||||
|
||||
/* Callback for freeing node data, default is NULL */
|
||||
Ecore_Free_Cb free_func;
|
||||
};
|
||||
|
||||
EAPI Ecore_Sheap *ecore_sheap_new(Ecore_Compare_Cb compare, int size) EINA_DEPRECATED;
|
||||
EAPI void ecore_sheap_destroy(Ecore_Sheap *heap) EINA_DEPRECATED;
|
||||
EAPI int ecore_sheap_init(Ecore_Sheap *heap, Ecore_Compare_Cb compare, int size) EINA_DEPRECATED;
|
||||
EAPI int ecore_sheap_free_cb_set(Ecore_Sheap *heap, Ecore_Free_Cb free_func) EINA_DEPRECATED;
|
||||
EAPI int ecore_sheap_insert(Ecore_Sheap *heap, void *data) EINA_DEPRECATED;
|
||||
EAPI void *ecore_sheap_extract(Ecore_Sheap *heap) EINA_DEPRECATED;
|
||||
EAPI void *ecore_sheap_extreme(Ecore_Sheap *heap) EINA_DEPRECATED;
|
||||
EAPI int ecore_sheap_change(Ecore_Sheap *heap, void *item, void *newval) EINA_DEPRECATED;
|
||||
EAPI int ecore_sheap_compare_set(Ecore_Sheap *heap, Ecore_Compare_Cb compare) EINA_DEPRECATED;
|
||||
EAPI void ecore_sheap_order_set(Ecore_Sheap *heap, char order) EINA_DEPRECATED;
|
||||
EAPI void ecore_sheap_sort(Ecore_Sheap *heap) EINA_DEPRECATED;
|
||||
|
||||
EAPI void *ecore_sheap_item(Ecore_Sheap *heap, int i) EINA_DEPRECATED;
|
||||
|
||||
#define ecore_string_init eina_init
|
||||
#define ecore_string_shutdown eina_shutdown
|
||||
#define ecore_string_instance eina_stringshare_add
|
||||
#define ecore_string_release eina_stringshare_del
|
||||
|
||||
#define ecore_string_hash_dump_graph (void)0
|
||||
#define ecore_string_hash_dump_stats (void)0
|
||||
|
||||
typedef struct _Ecore_Tree_Node Ecore_Tree_Node;
|
||||
# define ECORE_TREE_NODE(object) ((Ecore_Tree_Node *)object)
|
||||
struct _Ecore_Tree_Node {
|
||||
|
||||
/* The actual data for each node */
|
||||
void *key;
|
||||
void *value;
|
||||
|
||||
/* Pointers to surrounding nodes */
|
||||
Ecore_Tree_Node *parent;
|
||||
Ecore_Tree_Node *left_child;
|
||||
Ecore_Tree_Node *right_child;
|
||||
|
||||
/* Book keeping information for quicker balancing of the tree */
|
||||
int max_right;
|
||||
int max_left;
|
||||
};
|
||||
|
||||
typedef struct _Ecore_Tree Ecore_Tree;
|
||||
# define ECORE_TREE(object) ((Ecore_Tree *)object)
|
||||
struct _Ecore_Tree {
|
||||
/* Nodes of the tree */
|
||||
Ecore_Tree_Node *tree;
|
||||
|
||||
/* Callback for comparing node values, default is direct comparison */
|
||||
Ecore_Compare_Cb compare_func;
|
||||
|
||||
/* Callback for freeing node data, default is NULL */
|
||||
Ecore_Free_Cb free_value;
|
||||
/* Callback for freeing node key, default is NULL */
|
||||
Ecore_Free_Cb free_key;
|
||||
};
|
||||
|
||||
/* Some basic tree functions */
|
||||
/* Allocate and initialize a new tree */
|
||||
EAPI Ecore_Tree *ecore_tree_new(Ecore_Compare_Cb compare_func) EINA_DEPRECATED;
|
||||
/* Initialize a new tree */
|
||||
EAPI int ecore_tree_init(Ecore_Tree * tree, Ecore_Compare_Cb compare_func) EINA_DEPRECATED;
|
||||
|
||||
/* Free the tree */
|
||||
EAPI int ecore_tree_destroy(Ecore_Tree * tree) EINA_DEPRECATED;
|
||||
/* Check to see if the tree has any nodes in it */
|
||||
EAPI int ecore_tree_empty_is(Ecore_Tree * tree) EINA_DEPRECATED;
|
||||
|
||||
/* Retrieve the value associated with key */
|
||||
EAPI void *ecore_tree_get(Ecore_Tree * tree, const void *key) EINA_DEPRECATED;
|
||||
EAPI Ecore_Tree_Node *ecore_tree_get_node(Ecore_Tree * tree, const void *key) EINA_DEPRECATED;
|
||||
/* Retrieve the value of node with key greater than or equal to key */
|
||||
EAPI void *ecore_tree_closest_larger_get(Ecore_Tree * tree, const void *key) EINA_DEPRECATED;
|
||||
/* Retrieve the value of node with key less than or equal to key */
|
||||
EAPI void *ecore_tree_closest_smaller_get(Ecore_Tree * tree, const void *key) EINA_DEPRECATED;
|
||||
|
||||
/* Set the value associated with key to value */
|
||||
EAPI int ecore_tree_set(Ecore_Tree * tree, void *key, void *value) EINA_DEPRECATED;
|
||||
/* Remove the key from the tree */
|
||||
EAPI int ecore_tree_remove(Ecore_Tree * tree, const void *key) EINA_DEPRECATED;
|
||||
|
||||
/* Add a node to the tree */
|
||||
EAPI int ecore_tree_node_add(Ecore_Tree * tree, Ecore_Tree_Node * node) EINA_DEPRECATED;
|
||||
/* Remove a node from the tree */
|
||||
EAPI int ecore_tree_node_remove(Ecore_Tree * tree, Ecore_Tree_Node * node) EINA_DEPRECATED;
|
||||
|
||||
/* For each node in the tree perform the for_each_func function */
|
||||
/* For this one pass in the node */
|
||||
EAPI int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func,
|
||||
void *user_data) EINA_DEPRECATED;
|
||||
/* And here pass in the node's value */
|
||||
EAPI int ecore_tree_for_each_node_value(Ecore_Tree * tree,
|
||||
Ecore_For_Each for_each_func,
|
||||
void *user_data) EINA_DEPRECATED;
|
||||
|
||||
/* Some basic node functions */
|
||||
/* Initialize a node */
|
||||
EAPI int ecore_tree_node_init(Ecore_Tree_Node * new_node) EINA_DEPRECATED;
|
||||
/* Allocate and initialize a new node */
|
||||
EAPI Ecore_Tree_Node *ecore_tree_node_new(void) EINA_DEPRECATED;
|
||||
/* Free the desired node */
|
||||
EAPI int ecore_tree_node_destroy(Ecore_Tree_Node * node,
|
||||
Ecore_Free_Cb free_value, Ecore_Free_Cb free_key) EINA_DEPRECATED;
|
||||
|
||||
/* Set the node's key to key */
|
||||
EAPI int ecore_tree_node_key_set(Ecore_Tree_Node * node, void *key) EINA_DEPRECATED;
|
||||
/* Retrieve the key in node */
|
||||
EAPI void *ecore_tree_node_key_get(Ecore_Tree_Node * node) EINA_DEPRECATED;
|
||||
|
||||
/* Set the node's value to value */
|
||||
EAPI int ecore_tree_node_value_set(Ecore_Tree_Node * node, void *value) EINA_DEPRECATED;
|
||||
/* Retrieve the value in node */
|
||||
EAPI void *ecore_tree_node_value_get(Ecore_Tree_Node * node) EINA_DEPRECATED;
|
||||
|
||||
/* Add a function to free the data stored in nodes */
|
||||
EAPI int ecore_tree_free_value_cb_set(Ecore_Tree * tree, Ecore_Free_Cb free_value) EINA_DEPRECATED;
|
||||
/* Add a function to free the keys stored in nodes */
|
||||
EAPI int ecore_tree_free_key_cb_set(Ecore_Tree * tree, Ecore_Free_Cb free_key) EINA_DEPRECATED;
|
||||
|
||||
|
||||
EAPI Ecore_Strbuf * ecore_strbuf_new(void) EINA_DEPRECATED;
|
||||
EAPI void ecore_strbuf_free(Ecore_Strbuf *buf) EINA_DEPRECATED;
|
||||
EAPI void ecore_strbuf_append(Ecore_Strbuf *buf, const char *str) EINA_DEPRECATED;
|
||||
EAPI void ecore_strbuf_append_char(Ecore_Strbuf *buf, char c) EINA_DEPRECATED;
|
||||
EAPI void ecore_strbuf_insert(Ecore_Strbuf *buf, const char *str,
|
||||
size_t pos) EINA_DEPRECATED;
|
||||
# define ecore_strbuf_prepend(buf, str) ecore_strbuf_insert(buf, str, 0)
|
||||
EAPI const char * ecore_strbuf_string_get(Ecore_Strbuf *buf) EINA_DEPRECATED;
|
||||
EAPI size_t ecore_strbuf_length_get(Ecore_Strbuf *buf) EINA_DEPRECATED;
|
||||
EAPI int ecore_strbuf_replace(Ecore_Strbuf *buf, const char *str,
|
||||
const char *with, unsigned int n) EINA_DEPRECATED;
|
||||
# define ecore_strbuf_replace_first(buf, str, with) \
|
||||
ecore_strbuf_replace(buf, str, with, 1)
|
||||
EAPI int ecore_strbuf_replace_all(Ecore_Strbuf *buf, const char *str,
|
||||
const char *with) EINA_DEPRECATED;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _ECORE_DATA_H */
|
|
@ -1,124 +0,0 @@
|
|||
#ifndef _ECORE_STR_H
|
||||
# define _ECORE_STR_H
|
||||
|
||||
#include <Eina.h>
|
||||
#warning "this file is deprecated. use Eina.h instead."
|
||||
|
||||
#ifdef EAPI
|
||||
# undef EAPI
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef EFL_ECORE_BUILD
|
||||
# ifdef DLL_EXPORT
|
||||
# define EAPI __declspec(dllexport)
|
||||
# else
|
||||
# define EAPI
|
||||
# endif /* ! DLL_EXPORT */
|
||||
# else
|
||||
# define EAPI __declspec(dllimport)
|
||||
# endif /* ! EFL_ECORE_BUILD */
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# if __GNUC__ >= 4
|
||||
# define EAPI __attribute__ ((visibility("default")))
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
#endif /* ! _WIN32 */
|
||||
|
||||
/* we need this for size_t */
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* @file Ecore_Str.h
|
||||
* @brief Contains useful C string functions.
|
||||
*
|
||||
* @deprecated use Eina.h instead
|
||||
*/
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# ifdef __sgi
|
||||
# define __FUNCTION__ "unknown"
|
||||
# ifndef __cplusplus
|
||||
# define inline
|
||||
# endif
|
||||
# endif
|
||||
|
||||
|
||||
/* strlcpy implementation for libc's lacking it */
|
||||
EAPI size_t ecore_strlcpy(char *dst, const char *src, size_t siz) EINA_DEPRECATED;
|
||||
EAPI size_t ecore_strlcat(char *dst, const char *src, size_t siz) EINA_DEPRECATED;
|
||||
|
||||
EAPI int ecore_str_has_prefix(const char *str, const char *prefix) EINA_DEPRECATED;
|
||||
|
||||
EAPI int ecore_str_has_suffix(const char *str, const char *suffix) EINA_DEPRECATED;
|
||||
EAPI int ecore_str_has_extension(const char *str, const char *ext) EINA_DEPRECATED;
|
||||
|
||||
EAPI char **ecore_str_split(const char *string, const char *delimiter, int max_tokens) EINA_DEPRECATED;
|
||||
|
||||
EAPI size_t ecore_str_join_len(char *dst, size_t size, char sep, const char *a, size_t a_len, const char *b, size_t b_len) EINA_DEPRECATED;
|
||||
|
||||
|
||||
static inline size_t ecore_str_join(char *dst, size_t size, char sep, const char *a, const char *b) EINA_DEPRECATED;
|
||||
|
||||
/**
|
||||
* Join two strings and store the result in @a dst buffer.
|
||||
*
|
||||
* Similar to ecore_str_join_len(), but will compute the length of @a
|
||||
* and @a b using strlen().
|
||||
*
|
||||
* @param dst where to store the result.
|
||||
* @param size byte size of dst, will write at most (size - 1)
|
||||
* characters and then the '\0' (null terminator).
|
||||
* @param sep separator character to use.
|
||||
* @param a first string to use, before @a sep.
|
||||
* @param b second string to use, after @a sep.
|
||||
*
|
||||
* @return the number of characters printed (not including the
|
||||
* trailing '\0' used to end output to strings). Just like
|
||||
* snprintf(), it will not write more than @a size bytes, thus a
|
||||
* return value of @a size or more means that the output was
|
||||
* truncated.
|
||||
*
|
||||
* @see ecore_str_join_len() and ecore_str_join_static()
|
||||
*/
|
||||
static inline size_t ecore_str_join(char *dst, size_t size, char sep, const char *a, const char *b)
|
||||
{
|
||||
return ecore_str_join_len(dst, size, sep, a, strlen(a), b, strlen(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Join two static strings and store the result in static @a dst buffer.
|
||||
*
|
||||
* Similar to ecore_str_join_len(), but will assume string sizes are
|
||||
* know using sizeof(X).
|
||||
*
|
||||
* @param dst where to store the result.
|
||||
* @param sep separator character to use.
|
||||
* @param a first string to use, before @a sep.
|
||||
* @param b second string to use, after @a sep.
|
||||
*
|
||||
* @return the number of characters printed (not including the
|
||||
* trailing '\0' used to end output to strings). Just like
|
||||
* snprintf(), it will not write more than @a size bytes, thus a
|
||||
* return value of @a size or more means that the output was
|
||||
* truncated.
|
||||
*
|
||||
* @see ecore_str_join() and ecore_str_join_static()
|
||||
*/
|
||||
#define ecore_str_join_static(dst, sep, a, b) ecore_str_join_len(dst, sizeof(dst), sep, a, (sizeof(a) > 0) ? sizeof(a) - 1 : 0, b, (sizeof(b) > 0) ? sizeof(b) - 1 : 0)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ECORE_STR_H */
|
|
@ -1,31 +0,0 @@
|
|||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/lib/ecore \
|
||||
@EVIL_CFLAGS@ \
|
||||
@EINA_CFLAGS@ \
|
||||
@WIN32_CPPFLAGS@ \
|
||||
@EFL_ECORE_BUILD@
|
||||
|
||||
if BUILD_ECORE_DATA
|
||||
|
||||
lib_LTLIBRARIES = libecore_data.la
|
||||
include_HEADERS = \
|
||||
Ecore_Data.h \
|
||||
Ecore_Str.h
|
||||
|
||||
libecore_data_la_SOURCES = \
|
||||
ecore_hash.c \
|
||||
ecore_list.c \
|
||||
ecore_path.c \
|
||||
ecore_plugin.c \
|
||||
ecore_sheap.c \
|
||||
ecore_strbuf.c \
|
||||
ecore_str.c \
|
||||
ecore_tree.c \
|
||||
ecore_value.c
|
||||
|
||||
libecore_data_la_LIBADD = @dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ -lm
|
||||
libecore_data_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @ecore_release_info@
|
||||
|
||||
endif
|
|
@ -1,874 +0,0 @@
|
|||
/*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Ecore_Data.h"
|
||||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
|
||||
#define PRIME_TABLE_MAX 21
|
||||
#define PRIME_MIN 17
|
||||
#define PRIME_MAX 16777213
|
||||
|
||||
#define ECORE_HASH_CHAIN_MAX 3
|
||||
|
||||
#define ECORE_COMPUTE_HASH(hash, key) hash->hash_func(key) % \
|
||||
ecore_prime_table[hash->size];
|
||||
|
||||
#define ECORE_HASH_INCREASE(hash) ((hash && ecore_prime_table[hash->size] < PRIME_MAX) ? \
|
||||
(hash->nodes / ecore_prime_table[hash->size]) > \
|
||||
ECORE_HASH_CHAIN_MAX : EINA_FALSE)
|
||||
#define ECORE_HASH_REDUCE(hash) ((hash && ecore_prime_table[hash->size] > PRIME_MIN) ? \
|
||||
(double)hash->nodes / (double)ecore_prime_table[hash->size-1] \
|
||||
< ((double)ECORE_HASH_CHAIN_MAX * 0.375) : EINA_FALSE)
|
||||
|
||||
/* Private hash manipulation functions */
|
||||
static int _ecore_hash_node_add(Ecore_Hash *hash, Ecore_Hash_Node *node);
|
||||
static Ecore_Hash_Node * _ecore_hash_node_get(Ecore_Hash *hash, const void *key);
|
||||
static int _ecore_hash_increase(Ecore_Hash *hash);
|
||||
static int _ecore_hash_decrease(Ecore_Hash *hash);
|
||||
static inline int _ecore_hash_rehash(Ecore_Hash *hash, Ecore_Hash_Node **old_table, int old_size);
|
||||
static int _ecore_hash_bucket_destroy(Ecore_Hash_Node *list, Ecore_Free_Cb keyd,
|
||||
Ecore_Free_Cb valued);
|
||||
static inline Ecore_Hash_Node * _ecore_hash_bucket_get(Ecore_Hash *hash,
|
||||
Ecore_Hash_Node *bucket, const void *key);
|
||||
|
||||
static Ecore_Hash_Node *_ecore_hash_node_new(void *key, void *value);
|
||||
static int _ecore_hash_node_init(Ecore_Hash_Node *node, void *key, void *value);
|
||||
static int _ecore_hash_node_destroy(Ecore_Hash_Node *node, Ecore_Free_Cb keyd,
|
||||
Ecore_Free_Cb valued);
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Data_Hash_ADT_Creation_Group Hash Creation Functions
|
||||
*
|
||||
* Functions that create hash tables.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates and initializes a new hash
|
||||
* @param hash_func The function for determining hash position.
|
||||
* @param compare The function for comparing node keys.
|
||||
* @return @c NULL on error, a new hash on success.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Creation_Group
|
||||
*/
|
||||
EAPI Ecore_Hash *
|
||||
ecore_hash_new(Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare)
|
||||
{
|
||||
Ecore_Hash *new_hash = (Ecore_Hash *)malloc(sizeof(Ecore_Hash));
|
||||
EINA_LOG_ERR("use eina_hash_* instead. See eina's documentation examples.");
|
||||
if (!new_hash)
|
||||
return NULL;
|
||||
|
||||
if (!ecore_hash_init(new_hash, hash_func, compare))
|
||||
{
|
||||
FREE(new_hash);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new_hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the given hash.
|
||||
* @param hash The given hash.
|
||||
* @param hash_func The function used for hashing node keys.
|
||||
* @param compare The function used for comparing node keys.
|
||||
* @return @c EINA_TRUE on success, @c EINA_FALSE on an error.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Creation_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_init(Ecore_Hash *hash, Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, EINA_FALSE);
|
||||
|
||||
memset(hash, 0, sizeof(Ecore_Hash));
|
||||
|
||||
hash->hash_func = hash_func;
|
||||
hash->compare = compare;
|
||||
|
||||
hash->buckets = (Ecore_Hash_Node **)calloc(ecore_prime_table[0],
|
||||
sizeof(Ecore_Hash_Node *));
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Data_Hash_ADT_Destruction_Group Hash Destruction Functions
|
||||
*
|
||||
* Functions that destroy hash tables and their contents.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the function to destroy the keys of the given hash.
|
||||
* @param hash The given hash.
|
||||
* @param function The function used to free the node keys. NULL is a
|
||||
* valid value and means that no function will be called.
|
||||
* @return @c EINA_TRUE on success, @c EINA_FALSE on error.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Destruction_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_free_key_cb_set(Ecore_Hash *hash, Ecore_Free_Cb function)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, EINA_FALSE);
|
||||
|
||||
hash->free_key = function;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the function to destroy the values in the given hash.
|
||||
* @param hash The given hash.
|
||||
* @param function The function that will free the node values. NULL is a
|
||||
* valid value and means that no function will be called.
|
||||
* @return @c EINA_TRUE on success, @c EINA_FALSE on error
|
||||
* @ingroup Ecore_Data_Hash_ADT_Destruction_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_free_value_cb_set(Ecore_Hash *hash, Ecore_Free_Cb function)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, EINA_FALSE);
|
||||
|
||||
hash->free_value = function;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Data_Hash_ADT_Data_Group Hash Data Functions
|
||||
*
|
||||
* Functions that set, access and delete values from the hash tables.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets a key-value pair in the given hash table.
|
||||
* @param hash The given hash table.
|
||||
* @param key The key.
|
||||
* @param value The value.
|
||||
* @return @c EINA_TRUE if successful, @c EINA_FALSE if not.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Data_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_set(Ecore_Hash *hash, void *key, void *value)
|
||||
{
|
||||
int ret = EINA_FALSE;
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, EINA_FALSE);
|
||||
|
||||
node = _ecore_hash_node_get(hash, key);
|
||||
if (node)
|
||||
{
|
||||
if (hash->free_key) hash->free_key(key);
|
||||
if (node->value && hash->free_value) hash->free_value(node->value);
|
||||
node->value = value;
|
||||
ret = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
node = _ecore_hash_node_new(key, value);
|
||||
if (node)
|
||||
ret = _ecore_hash_node_add(hash, node);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all key-value pairs from set in the given hash table.
|
||||
* @param hash The given hash table.
|
||||
* @param set The hash table to import.
|
||||
* @return @c EINA_TRUE if successful, @c EINA_FALSE if not.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Data_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_hash_set(Ecore_Hash *hash, Ecore_Hash *set)
|
||||
{
|
||||
unsigned int i;
|
||||
Ecore_Hash_Node *node, *old;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, EINA_FALSE);
|
||||
CHECK_PARAM_POINTER_RETURN("set", set, EINA_FALSE);
|
||||
|
||||
for (i = 0; i < ecore_prime_table[set->size]; i++)
|
||||
{
|
||||
/* Hash into a new list to avoid loops of rehashing the same nodes */
|
||||
while ((old = set->buckets[i]))
|
||||
{
|
||||
set->buckets[i] = old->next;
|
||||
old->next = NULL;
|
||||
node = _ecore_hash_node_get(hash, old->key);
|
||||
if (node)
|
||||
{
|
||||
/* This key already exists. Delete the old and add the new
|
||||
* value */
|
||||
if (hash->free_key) hash->free_key(node->key);
|
||||
if (hash->free_value) hash->free_key(node->value);
|
||||
node->key = old->key;
|
||||
node->value = old->value;
|
||||
free(old);
|
||||
}
|
||||
else
|
||||
_ecore_hash_node_add(hash, old);
|
||||
}
|
||||
}
|
||||
FREE(set->buckets);
|
||||
ecore_hash_init(set, set->hash_func, set->compare);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the hash table and the data contained inside it.
|
||||
* @param hash The hash table to destroy.
|
||||
* @return @c EINA_TRUE on success, @c EINA_FALSE on error.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Destruction_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_hash_destroy(Ecore_Hash *hash)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
CHECK_PARAM_POINTER("hash", hash);
|
||||
|
||||
if (hash->buckets)
|
||||
{
|
||||
while (i < ecore_prime_table[hash->size])
|
||||
{
|
||||
if (hash->buckets[i])
|
||||
{
|
||||
Ecore_Hash_Node *bucket;
|
||||
|
||||
/*
|
||||
* Remove the bucket list to avoid possible recursion
|
||||
* on the free callbacks.
|
||||
*/
|
||||
bucket = hash->buckets[i];
|
||||
hash->buckets[i] = NULL;
|
||||
_ecore_hash_bucket_destroy(bucket,
|
||||
hash->free_key,
|
||||
hash->free_value);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
FREE(hash->buckets);
|
||||
}
|
||||
FREE(hash);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Data_Hash_ADT_Traverse_Group Hash Traverse Functions
|
||||
*
|
||||
* Functions that iterate through hash tables.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Counts the number of nodes in a hash table.
|
||||
* @param hash The hash table to count current nodes.
|
||||
* @return The number of nodes in the hash.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Destruction_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_count(Ecore_Hash *hash)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, 0);
|
||||
|
||||
return hash->nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the @p for_each_func function on each entry in the given hash.
|
||||
* @param hash The given hash.
|
||||
* @param for_each_func The function that each entry is passed to.
|
||||
* @param user_data a pointer passed to calls of for_each_func
|
||||
* @return EINA_TRUE on success, EINA_FALSE otherwise.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Traverse_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func, void *user_data)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, EINA_FALSE);
|
||||
CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, EINA_FALSE);
|
||||
|
||||
while (i < ecore_prime_table[hash->size])
|
||||
{
|
||||
if (hash->buckets[i])
|
||||
{
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
for (node = hash->buckets[i]; node; node = node->next)
|
||||
{
|
||||
for_each_func(node, user_data);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an ecore_list of all keys in the given hash.
|
||||
* @param hash The given hash.
|
||||
* @return new ecore_list on success, NULL otherwise
|
||||
* @ingroup Ecore_Data_Hash_ADT_Traverse_Group
|
||||
*/
|
||||
EAPI Ecore_List *
|
||||
ecore_hash_keys(Ecore_Hash *hash)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
Ecore_List *keys;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
|
||||
|
||||
keys = ecore_list_new();
|
||||
while (i < ecore_prime_table[hash->size])
|
||||
{
|
||||
if (hash->buckets[i])
|
||||
{
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
for (node = hash->buckets[i]; node; node = node->next)
|
||||
{
|
||||
ecore_list_append(keys, node->key);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
ecore_list_first_goto(keys);
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the distribution of the given hash table for graphing.
|
||||
* @param hash The given hash table.
|
||||
*/
|
||||
EAPI void
|
||||
ecore_hash_dump_graph(Ecore_Hash *hash)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ecore_prime_table[hash->size]; i++)
|
||||
if (hash->buckets[i])
|
||||
{
|
||||
int n = 0;
|
||||
Ecore_Hash_Node *node;
|
||||
for (node = hash->buckets[i]; node; node = node->next)
|
||||
n++;
|
||||
INF("%d\t%u", i, n);
|
||||
}
|
||||
else
|
||||
INF("%d\t0", i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the distribution of the given hash table for graphing.
|
||||
* @param hash The given hash table.
|
||||
*/
|
||||
EAPI void
|
||||
ecore_hash_dump_stats(Ecore_Hash *hash)
|
||||
{
|
||||
unsigned int i;
|
||||
double variance, sum_n_2 = 0, sum_n = 0;
|
||||
|
||||
for (i = 0; i < ecore_prime_table[hash->size]; i++)
|
||||
{
|
||||
if (hash->buckets[i])
|
||||
{
|
||||
int n = 0;
|
||||
Ecore_Hash_Node *node;
|
||||
for (node = hash->buckets[i]; node; node = node->next)
|
||||
n++;
|
||||
sum_n_2 += ((double)n * (double)n);
|
||||
sum_n += (double)n;
|
||||
}
|
||||
}
|
||||
variance = (sum_n_2 - ((sum_n * sum_n) / (double)i)) / (double)i;
|
||||
INF("Average length: %f\n\tvariance^2: %f", (sum_n / (double)i),
|
||||
variance);
|
||||
}
|
||||
|
||||
static int
|
||||
_ecore_hash_bucket_destroy(Ecore_Hash_Node *list, Ecore_Free_Cb keyd, Ecore_Free_Cb valued)
|
||||
{
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("list", list, EINA_FALSE);
|
||||
|
||||
for (node = list; node; node = list)
|
||||
{
|
||||
list = list->next;
|
||||
_ecore_hash_node_destroy(node, keyd, valued);
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Add the node to the hash table
|
||||
* @param hash: the hash table to add the key
|
||||
* @param node: the node to add to the hash table
|
||||
* @return Returns EINA_FALSE on error, EINA_TRUE on success
|
||||
*/
|
||||
static int
|
||||
_ecore_hash_node_add(Ecore_Hash *hash, Ecore_Hash_Node *node)
|
||||
{
|
||||
unsigned long hash_val;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, EINA_FALSE);
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, EINA_FALSE);
|
||||
|
||||
/* Check to see if the hash needs to be resized */
|
||||
if (ECORE_HASH_INCREASE(hash))
|
||||
_ecore_hash_increase(hash);
|
||||
|
||||
/* Compute the position in the table */
|
||||
if (!hash->hash_func)
|
||||
hash_val = (unsigned long)node->key % ecore_prime_table[hash->size];
|
||||
else
|
||||
hash_val = ECORE_COMPUTE_HASH(hash, node->key);
|
||||
|
||||
/* Prepend the node to the list at the index position */
|
||||
node->next = hash->buckets[hash_val];
|
||||
hash->buckets[hash_val] = node;
|
||||
hash->nodes++;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value associated with the given key from the given hash
|
||||
* table.
|
||||
* @param hash The given hash table.
|
||||
* @param key The key to search for.
|
||||
* @return The value corresponding to key on success, @c NULL otherwise.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Data_Group
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_hash_get(Ecore_Hash *hash, const void *key)
|
||||
{
|
||||
void *data;
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
|
||||
|
||||
node = _ecore_hash_node_get(hash, key);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
data = node->value;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the value associated with the given key in the given hash
|
||||
* table.
|
||||
* @param hash The given hash table.
|
||||
* @param key The key to search for.
|
||||
* @return The value corresponding to the key on success. @c NULL is
|
||||
* returned if there is an error.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Data_Group
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_hash_remove(Ecore_Hash *hash, const void *key)
|
||||
{
|
||||
Ecore_Hash_Node *node = NULL;
|
||||
Ecore_Hash_Node *list;
|
||||
unsigned long hash_val;
|
||||
void *ret = NULL;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
|
||||
|
||||
/* Compute the position in the table */
|
||||
if (!hash->hash_func)
|
||||
hash_val = (unsigned long )key % ecore_prime_table[hash->size];
|
||||
else
|
||||
hash_val = ECORE_COMPUTE_HASH(hash, key);
|
||||
|
||||
/*
|
||||
* If their is a list that could possibly hold the key/value pair
|
||||
* traverse it and remove the hash node.
|
||||
*/
|
||||
if (hash->buckets[hash_val])
|
||||
{
|
||||
list = hash->buckets[hash_val];
|
||||
|
||||
/*
|
||||
* Traverse the list to find the specified key
|
||||
*/
|
||||
node = list;
|
||||
if (hash->compare)
|
||||
{
|
||||
while ((node) && (hash->compare(node->key, key) != 0))
|
||||
{
|
||||
list = node;
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((node) && (node->key != key))
|
||||
{
|
||||
list = node;
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the node with the matching key and free it's memory
|
||||
*/
|
||||
if (node)
|
||||
{
|
||||
if (list == node)
|
||||
hash->buckets[hash_val] = node->next;
|
||||
else
|
||||
list->next = node->next;
|
||||
ret = node->value;
|
||||
node->value = NULL;
|
||||
_ecore_hash_node_destroy(node, hash->free_key, NULL);
|
||||
hash->nodes--;
|
||||
}
|
||||
}
|
||||
|
||||
if (ECORE_HASH_REDUCE(hash))
|
||||
_ecore_hash_decrease(hash);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the first value that matches
|
||||
* table.
|
||||
* @param hash The given hash table.
|
||||
* @param key The key to search for.
|
||||
* @return The value corresponding to key on success, @c NULL otherwise.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Data_Group
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_hash_find(Ecore_Hash *hash, Ecore_Compare_Cb compare, const void *value)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
|
||||
CHECK_PARAM_POINTER_RETURN("compare", compare, NULL);
|
||||
CHECK_PARAM_POINTER_RETURN("value", value, NULL);
|
||||
|
||||
while (i < ecore_prime_table[hash->size])
|
||||
{
|
||||
if (hash->buckets[i])
|
||||
{
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
for (node = hash->buckets[i]; node; node = node->next)
|
||||
{
|
||||
if (!compare(node->value, value)) return node->value;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Retrieve the node associated with key
|
||||
* @param hash: the hash table to search for the key
|
||||
* @param key: the key to search for in the hash table
|
||||
* @return Returns NULL on error, node corresponding to key on success
|
||||
*/
|
||||
static Ecore_Hash_Node *
|
||||
_ecore_hash_node_get(Ecore_Hash *hash, const void *key)
|
||||
{
|
||||
unsigned long hash_val;
|
||||
Ecore_Hash_Node *node = NULL;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
|
||||
|
||||
if (!hash->buckets)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Compute the position in the table */
|
||||
if (!hash->hash_func)
|
||||
hash_val = (unsigned long)key % ecore_prime_table[hash->size];
|
||||
else
|
||||
hash_val = ECORE_COMPUTE_HASH(hash, key);
|
||||
|
||||
/* Grab the bucket at the specified position */
|
||||
if (hash->buckets[hash_val])
|
||||
{
|
||||
node = _ecore_hash_bucket_get(hash, hash->buckets[hash_val], key);
|
||||
/*
|
||||
* Move matched node to the front of the list as it's likely
|
||||
* to be searched for again soon.
|
||||
*/
|
||||
if (node && node != hash->buckets[hash_val])
|
||||
{
|
||||
node->next = hash->buckets[hash_val];
|
||||
hash->buckets[hash_val] = node;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Search the hash bucket for a specified key
|
||||
* @param hash: the hash table to retrieve the comparison function
|
||||
* @param bucket: the list to search for the key
|
||||
* @param key: the key to search for in the list
|
||||
* @return Returns NULL on error or not found, the found node on success
|
||||
*/
|
||||
static inline Ecore_Hash_Node *
|
||||
_ecore_hash_bucket_get(Ecore_Hash *hash, Ecore_Hash_Node *bucket, const void *key)
|
||||
{
|
||||
Ecore_Hash_Node *prev = NULL;
|
||||
Ecore_Hash_Node *node = NULL;
|
||||
|
||||
/*
|
||||
* Traverse the list to find the desired node, if the node is in the
|
||||
* list, then return the node.
|
||||
*/
|
||||
if (hash->compare)
|
||||
{
|
||||
for (node = bucket; node; node = node->next)
|
||||
{
|
||||
if (hash->compare(node->key, key) == 0)
|
||||
break;
|
||||
prev = node;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (node = bucket; node; node = node->next)
|
||||
{
|
||||
if (node->key == key)
|
||||
break;
|
||||
prev = node;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove node from the list to replace it at the beginning.
|
||||
*/
|
||||
if (node && prev)
|
||||
{
|
||||
prev->next = node->next;
|
||||
node->next = NULL;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Increase the size of the hash table by approx. 2 * current size
|
||||
* @param hash: the hash table to increase the size of
|
||||
* @return Returns EINA_TRUE on success, EINA_FALSE on error
|
||||
*/
|
||||
static int
|
||||
_ecore_hash_increase(Ecore_Hash *hash)
|
||||
{
|
||||
void *old;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, EINA_FALSE);
|
||||
|
||||
/* Max size reached so return EINA_FALSE */
|
||||
if ((ecore_prime_table[hash->size] == PRIME_MAX) || (hash->size == PRIME_TABLE_MAX))
|
||||
return EINA_FALSE;
|
||||
|
||||
/*
|
||||
* Increase the size of the hash and save a pointer to the old data
|
||||
*/
|
||||
hash->size++;
|
||||
old = hash->buckets;
|
||||
|
||||
/*
|
||||
* Allocate a new bucket area, of the new larger size
|
||||
*/
|
||||
hash->buckets = calloc(ecore_prime_table[hash->size], sizeof(Ecore_Hash_Node *));
|
||||
|
||||
/*
|
||||
* Make sure the allocation succeeded, if not replace the old data and
|
||||
* return a failure.
|
||||
*/
|
||||
if (!hash->buckets)
|
||||
{
|
||||
hash->buckets = old;
|
||||
hash->size--;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
hash->nodes = 0;
|
||||
|
||||
/*
|
||||
* Now move all of the old data into the new bucket area
|
||||
*/
|
||||
if (_ecore_hash_rehash(hash, old, hash->size - 1))
|
||||
{
|
||||
FREE(old);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the old buckets regardless of success.
|
||||
*/
|
||||
FREE(old);
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Decrease the size of the hash table by < 1/2 * current size
|
||||
* @param hash: the hash table to decrease the size of
|
||||
* @return Returns EINA_TRUE on success, EINA_FALSE on error
|
||||
*/
|
||||
static int
|
||||
_ecore_hash_decrease(Ecore_Hash *hash)
|
||||
{
|
||||
Ecore_Hash_Node **old;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, EINA_FALSE);
|
||||
|
||||
if (ecore_prime_table[hash->size] == PRIME_MIN)
|
||||
return EINA_FALSE;
|
||||
|
||||
/*
|
||||
* Decrease the hash size and store a pointer to the old data
|
||||
*/
|
||||
hash->size--;
|
||||
old = hash->buckets;
|
||||
|
||||
/*
|
||||
* Allocate a new area to store the data
|
||||
*/
|
||||
hash->buckets = (Ecore_Hash_Node **)calloc(ecore_prime_table[hash->size],
|
||||
sizeof(Ecore_Hash_Node *));
|
||||
|
||||
/*
|
||||
* Make sure allocation succeeded otherwise rreturn to the previous
|
||||
* state
|
||||
*/
|
||||
if (!hash->buckets)
|
||||
{
|
||||
hash->buckets = old;
|
||||
hash->size++;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
hash->nodes = 0;
|
||||
|
||||
if (_ecore_hash_rehash(hash, old, hash->size + 1))
|
||||
{
|
||||
FREE(old);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Rehash the nodes of a table into the hash table
|
||||
* @param hash: the hash to place the nodes of the table
|
||||
* @param table: the table to remove the nodes from and place in hash
|
||||
* @return Returns EINA_TRUE on success, EINA_FALSE on error
|
||||
*/
|
||||
static inline int
|
||||
_ecore_hash_rehash(Ecore_Hash *hash, Ecore_Hash_Node **old_table, int old_size)
|
||||
{
|
||||
unsigned int i;
|
||||
Ecore_Hash_Node *old;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, EINA_FALSE);
|
||||
CHECK_PARAM_POINTER_RETURN("old_table", old_table, EINA_FALSE);
|
||||
|
||||
for (i = 0; i < ecore_prime_table[old_size]; i++)
|
||||
{
|
||||
/* Hash into a new list to avoid loops of rehashing the same nodes */
|
||||
while ((old = old_table[i]))
|
||||
{
|
||||
old_table[i] = old->next;
|
||||
old->next = NULL;
|
||||
_ecore_hash_node_add(hash, old);
|
||||
}
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Create a new hash node for key and value storage
|
||||
* @param key: the key for this node
|
||||
* @param value: the value that the key references
|
||||
* @return Returns NULL on error, a new hash node on success
|
||||
*/
|
||||
static Ecore_Hash_Node *
|
||||
_ecore_hash_node_new(void *key, void *value)
|
||||
{
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
node = (Ecore_Hash_Node *)malloc(sizeof(Ecore_Hash_Node));
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
if (!_ecore_hash_node_init(node, key, value))
|
||||
{
|
||||
FREE(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Initialize a hash node to some sane default values
|
||||
* @param node: the node to set the values
|
||||
* @param key: the key to reference this node
|
||||
* @param value: the value that key refers to
|
||||
* @return Returns EINA_TRUE on success, EINA_FALSE on error
|
||||
*/
|
||||
static int
|
||||
_ecore_hash_node_init(Ecore_Hash_Node *node, void *key, void *value)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, EINA_FALSE);
|
||||
|
||||
node->key = key;
|
||||
node->value = value;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Destroy a node and call the specified callbacks to free data
|
||||
* @param node: the node to be destroyed
|
||||
* @param keyd: the function to free the key
|
||||
* @param valued: the function to free the value
|
||||
* @return Returns EINA_TRUE on success, EINA_FALSE on error
|
||||
*/
|
||||
static int
|
||||
_ecore_hash_node_destroy(Ecore_Hash_Node *node, Ecore_Free_Cb keyd, Ecore_Free_Cb valued)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, EINA_FALSE);
|
||||
|
||||
if (keyd)
|
||||
keyd(node->key);
|
||||
|
||||
if (valued)
|
||||
valued(node->value);
|
||||
|
||||
FREE(node);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,207 +0,0 @@
|
|||
/*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
#include "Ecore_Data.h"
|
||||
#include "Ecore_Str.h"
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Path_Group Path Group Functions
|
||||
*
|
||||
* Functions that make it easier to find a file in a set of search paths.
|
||||
*
|
||||
* @todo Give this a better description.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a new path group.
|
||||
* @param group_name The name of the new group.
|
||||
* @return @c NULL on error, the handle of the new group on success.
|
||||
* @ingroup Ecore_Path_Group
|
||||
*/
|
||||
EAPI Ecore_Path_Group *
|
||||
ecore_path_group_new(void)
|
||||
{
|
||||
return calloc(1, sizeof(Ecore_Path_Group));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a previously created path group
|
||||
* @param group The group to delete.
|
||||
* @ingroup Ecore_Path_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_path_group_del(Ecore_Path_Group *group)
|
||||
{
|
||||
char *path;
|
||||
|
||||
CHECK_PARAM_POINTER("group", group);
|
||||
|
||||
EINA_LIST_FREE(group->paths, path)
|
||||
free(path);
|
||||
free(group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a directory to be searched for files.
|
||||
* @param group The group to add the path.
|
||||
* @param path The new path to be added to the group.
|
||||
* @ingroup Ecore_Path_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_path_group_add(Ecore_Path_Group *group, const char *path)
|
||||
{
|
||||
CHECK_PARAM_POINTER("group", group);
|
||||
CHECK_PARAM_POINTER("path", path);
|
||||
|
||||
group->paths = eina_list_append(group->paths, strdup(path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given directory from the given group.
|
||||
* @param group The group to remove the path from.
|
||||
* @param path The path of the directory to be removed.
|
||||
* @ingroup Ecore_Path_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_path_group_remove(Ecore_Path_Group *group, const char *path)
|
||||
{
|
||||
char *found;
|
||||
|
||||
CHECK_PARAM_POINTER("group", group);
|
||||
CHECK_PARAM_POINTER("path", path);
|
||||
|
||||
if (!group->paths)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Find the path in the list of available paths
|
||||
*/
|
||||
found = eina_list_search_unsorted(group->paths, EINA_COMPARE_CB(strcmp), path);
|
||||
|
||||
/*
|
||||
* If the path is found, remove and free it
|
||||
*/
|
||||
if (found)
|
||||
{
|
||||
group->paths = eina_list_remove(group->paths, found);
|
||||
free(found);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a file in a group of paths.
|
||||
* @param group The group to search.
|
||||
* @param name The name of the file to find.
|
||||
* @return A pointer to a newly allocated path location of the found file
|
||||
* on success. @c NULL on failure.
|
||||
* @ingroup Ecore_Path_Group
|
||||
*/
|
||||
EAPI char *
|
||||
ecore_path_group_find(Ecore_Path_Group *group, const char *name)
|
||||
{
|
||||
Eina_List *l;
|
||||
int r;
|
||||
char *p;
|
||||
struct stat st;
|
||||
char path[PATH_MAX];
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("group", group, NULL);
|
||||
CHECK_PARAM_POINTER_RETURN("name", name, NULL);
|
||||
|
||||
if (!group->paths)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Search the paths of the path group for the specified file name
|
||||
*/
|
||||
EINA_LIST_FOREACH(group->paths, l, p)
|
||||
{
|
||||
snprintf(path, PATH_MAX, "%s/%s", p, name);
|
||||
r = stat(path, &st);
|
||||
if ((r >= 0) && S_ISREG(st.st_mode))
|
||||
break;
|
||||
}
|
||||
|
||||
if (p)
|
||||
p = strdup(path);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of all available files in the given path.
|
||||
* @param group_id The identifier for the given path.
|
||||
* @return A pointer to a newly allocated list of all files found in the paths
|
||||
* identified by @p group_id. @c NULL otherwise.
|
||||
* @ingroup Ecore_Path_Group
|
||||
*/
|
||||
EAPI Eina_List *
|
||||
ecore_path_group_available_get(Ecore_Path_Group *group)
|
||||
{
|
||||
Eina_List *avail = NULL;
|
||||
Eina_List *l;
|
||||
char *path;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("group", group, NULL);
|
||||
|
||||
if (!group->paths || !eina_list_count(group->paths))
|
||||
return NULL;
|
||||
|
||||
EINA_LIST_FOREACH(group->paths, l, path)
|
||||
{
|
||||
DIR *dir;
|
||||
struct stat st;
|
||||
struct dirent *d;
|
||||
|
||||
stat(path, &st);
|
||||
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
continue;
|
||||
|
||||
dir = opendir(path);
|
||||
|
||||
if (!dir)
|
||||
continue;
|
||||
|
||||
while ((d = readdir(dir)) != NULL)
|
||||
{
|
||||
char ppath[PATH_MAX];
|
||||
/* char n[PATH_MAX];
|
||||
int l;
|
||||
*/
|
||||
if (!strncmp(d->d_name, ".", 1))
|
||||
continue;
|
||||
|
||||
snprintf(ppath, PATH_MAX, "%s/%s", path, d->d_name);
|
||||
|
||||
stat(ppath, &st);
|
||||
|
||||
if (!S_ISREG(st.st_mode))
|
||||
continue;
|
||||
/*
|
||||
l = strlen(d->d_name);
|
||||
|
||||
strncpy(n, d->d_name, l - 2);
|
||||
*/
|
||||
/* avail = eina_list_append(avail, strdup(n));*/
|
||||
avail = eina_list_append(avail, strdup(d->d_name));
|
||||
}
|
||||
}
|
||||
|
||||
return avail;
|
||||
}
|
||||
|
|
@ -1,241 +0,0 @@
|
|||
/*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
|
||||
|
||||
#ifdef HAVE_DLFCN_H
|
||||
# include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EVIL_H
|
||||
# include <Evil.h>
|
||||
#endif
|
||||
|
||||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
#include "Ecore_Data.h"
|
||||
#include "Ecore_Str.h"
|
||||
|
||||
static Eina_Bool _hash_keys(const Eina_Hash *hash,
|
||||
const char *key,
|
||||
void *list);
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Plugin Plugin Functions
|
||||
*
|
||||
* Functions that load modules of compiled code into memory.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Loads the specified plugin from the specified path group.
|
||||
* @param group The path group to search for the plugin to load
|
||||
* @param plugin_name The name of the plugin to load.
|
||||
* @param version The interface version of the plugin. With version
|
||||
* equal to NULL the default will be loaded.
|
||||
* @return A pointer to the newly loaded plugin on success, @c NULL on
|
||||
* failure.
|
||||
* @ingroup Ecore_Plugin
|
||||
*/
|
||||
EAPI Ecore_Plugin *
|
||||
ecore_plugin_load(Ecore_Path_Group *group, const char *plugin_name, const char *version)
|
||||
{
|
||||
char *path;
|
||||
char temp[PATH_MAX];
|
||||
|
||||
Ecore_Plugin *plugin;
|
||||
void *handle = NULL;
|
||||
|
||||
EINA_LOG_ERR("use eina_module instead. See eina's documentation examples.");
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("plugin_name", plugin_name, NULL);
|
||||
|
||||
if (!version || *version == '\0')
|
||||
snprintf(temp, sizeof(temp), "%s" SHARED_LIB_SUFFIX, plugin_name);
|
||||
else
|
||||
#ifndef _WIN32
|
||||
snprintf(temp, sizeof(temp), "%s" SHARED_LIB_SUFFIX ".%s", plugin_name, version);
|
||||
#else
|
||||
snprintf(temp, sizeof(temp), "%s-%s" SHARED_LIB_SUFFIX, plugin_name, version);
|
||||
#endif
|
||||
|
||||
path = ecore_path_group_find(group, temp);
|
||||
|
||||
if (!path && version)
|
||||
{
|
||||
/* if this file doesn't exist try a different order */
|
||||
snprintf(temp, sizeof(temp), "%s.%s" SHARED_LIB_SUFFIX, plugin_name, version);
|
||||
path = ecore_path_group_find(group, temp);
|
||||
}
|
||||
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
handle = dlopen(path, RTLD_LAZY);
|
||||
if (!handle)
|
||||
{
|
||||
FREE(path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate the new plugin and initialize it's fields
|
||||
*/
|
||||
plugin = malloc(sizeof(Ecore_Plugin));
|
||||
if (!plugin)
|
||||
{
|
||||
dlclose(handle);
|
||||
FREE(path);
|
||||
return NULL;
|
||||
}
|
||||
memset(plugin, 0, sizeof(Ecore_Plugin));
|
||||
|
||||
plugin->handle = handle;
|
||||
|
||||
FREE(path);
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads the given plugin from memory.
|
||||
* @param plugin The given plugin.
|
||||
* @ingroup Ecore_Plugin
|
||||
*/
|
||||
EAPI void
|
||||
ecore_plugin_unload(Ecore_Plugin *plugin)
|
||||
{
|
||||
CHECK_PARAM_POINTER("plugin", plugin);
|
||||
|
||||
if (plugin->handle)
|
||||
dlclose(plugin->handle);
|
||||
|
||||
FREE(plugin);
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches for the specified symbol in the given plugin.
|
||||
* @param plugin The given plugin.
|
||||
* @param symbol_name The symbol to search for.
|
||||
* @return Address of the given symbol if successful. Otherwise, @c NULL.
|
||||
* @ingroup Ecore_Plugin
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_plugin_symbol_get(Ecore_Plugin *plugin, const char *symbol_name)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("plugin", plugin, NULL);
|
||||
CHECK_PARAM_POINTER_RETURN("symbol_name", symbol_name, NULL);
|
||||
|
||||
if (!plugin->handle)
|
||||
return NULL;
|
||||
|
||||
ret = dlsym(plugin->handle, symbol_name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of all available plugins in the given path.
|
||||
* @param group_id The identifier for the given path.
|
||||
* @return A pointer to a newly allocated list of all plugins found in the
|
||||
* paths identified by @p group_id. @c NULL otherwise.
|
||||
* @ingroup Ecore_Plugin
|
||||
*/
|
||||
EAPI Eina_List *
|
||||
ecore_plugin_available_get(Ecore_Path_Group *group)
|
||||
{
|
||||
Eina_List *avail = NULL;
|
||||
Eina_List *l;
|
||||
Eina_Hash *plugins = NULL;
|
||||
Eina_Iterator *it = NULL;
|
||||
char *path;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("group", group, NULL);
|
||||
|
||||
if (!group->paths || !eina_list_count(group->paths))
|
||||
return NULL;
|
||||
|
||||
plugins = eina_hash_string_superfast_new(NULL);
|
||||
|
||||
EINA_LIST_FOREACH(group->paths, l, path)
|
||||
{
|
||||
DIR *dir;
|
||||
struct stat st;
|
||||
struct dirent *d;
|
||||
|
||||
if (stat(path, &st) < 0)
|
||||
continue;
|
||||
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
continue;
|
||||
|
||||
dir = opendir(path);
|
||||
|
||||
if (!dir)
|
||||
continue;
|
||||
|
||||
while ((d = readdir(dir)) != NULL)
|
||||
{
|
||||
char ppath[PATH_MAX];
|
||||
char *ext;
|
||||
|
||||
if (*d->d_name == '.')
|
||||
continue;
|
||||
|
||||
if (!ecore_str_has_suffix(d->d_name, SHARED_LIB_SUFFIX))
|
||||
continue;
|
||||
|
||||
snprintf(ppath, PATH_MAX, "%s/%s", path, d->d_name);
|
||||
|
||||
stat(ppath, &st);
|
||||
|
||||
if (!S_ISREG(st.st_mode))
|
||||
continue;
|
||||
|
||||
ecore_strlcpy(ppath, d->d_name, sizeof(ppath));
|
||||
ext = strrchr(ppath, '.');
|
||||
*ext = '\0';
|
||||
|
||||
if (!eina_hash_find(plugins, ppath))
|
||||
{
|
||||
char *key;
|
||||
|
||||
key = strdup(ppath);
|
||||
eina_hash_add(plugins, key, key);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
it = eina_hash_iterator_data_new(plugins);
|
||||
if (it)
|
||||
{
|
||||
eina_iterator_foreach(it, EINA_EACH(_hash_keys), &avail);
|
||||
eina_iterator_free(it);
|
||||
}
|
||||
|
||||
eina_hash_free(plugins);
|
||||
|
||||
|
||||
return avail;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_hash_keys(const Eina_Hash *hash __UNUSED__, const char *key, void *list)
|
||||
{
|
||||
*(Eina_List **)list = eina_list_append(*(Eina_List **)list, key);
|
||||
return EINA_TRUE;
|
||||
}
|
|
@ -1,457 +0,0 @@
|
|||
/*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
#include "Ecore_Data.h"
|
||||
|
||||
#define HEAP_INCREMENT 4096
|
||||
|
||||
#define PARENT(i) (i / 2)
|
||||
#define LEFT(i) (2 * i)
|
||||
#define RIGHT(i) (2 * i + 1)
|
||||
|
||||
static void _ecore_sheap_heapify(Ecore_Sheap *heap, int i);
|
||||
static void _ecore_sheap_update_data(Ecore_Sheap *heap);
|
||||
|
||||
/**
|
||||
* Allocate and initialize a new binary heap
|
||||
* @param compare The function for comparing keys, NULL for direct comparison
|
||||
* @param size The number of elements to allow in the heap
|
||||
* @return A pointer to the newly allocated binary heap on success, NULL on
|
||||
* failure.
|
||||
*/
|
||||
EAPI Ecore_Sheap *
|
||||
ecore_sheap_new(Ecore_Compare_Cb compare, int size)
|
||||
{
|
||||
Ecore_Sheap *heap = NULL;
|
||||
|
||||
heap = (Ecore_Sheap *)malloc(sizeof(Ecore_Sheap));
|
||||
if (!heap)
|
||||
return NULL;
|
||||
memset(heap, 0, sizeof(Ecore_Sheap));
|
||||
|
||||
if (!ecore_sheap_init(heap, compare, size))
|
||||
{
|
||||
FREE(heap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return heap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a binary heap to default values
|
||||
* @param heap The heap to initialize
|
||||
* @param compare The function for comparing keys, NULL for direct comparison
|
||||
* @param size The number of elements to allow in the heap
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure
|
||||
*/
|
||||
EAPI int
|
||||
ecore_sheap_init(Ecore_Sheap *heap, Ecore_Compare_Cb compare, int size)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("heap", heap, EINA_FALSE);
|
||||
|
||||
heap->space = size;
|
||||
if (!compare)
|
||||
heap->compare = ecore_direct_compare;
|
||||
else
|
||||
heap->compare = compare;
|
||||
heap->order = ECORE_SORT_MIN;
|
||||
|
||||
heap->data = (void **)malloc(heap->space * sizeof(void *));
|
||||
if (!heap->data)
|
||||
return EINA_FALSE;
|
||||
memset(heap->data, 0, heap->space * sizeof(void *));
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free up the memory used by the heap
|
||||
*
|
||||
* Frees the memory used by @a heap, calls the destroy function on each data
|
||||
* item if necessary.
|
||||
*
|
||||
* @param heap The heap to be freed
|
||||
*/
|
||||
EAPI void
|
||||
ecore_sheap_destroy(Ecore_Sheap *heap)
|
||||
{
|
||||
int i;
|
||||
|
||||
CHECK_PARAM_POINTER("heap", heap);
|
||||
|
||||
/*
|
||||
* Free data in heap
|
||||
*/
|
||||
if (heap->free_func)
|
||||
for (i = 0; i < heap->size; i++)
|
||||
heap->free_func(heap->data[i]);
|
||||
|
||||
FREE(heap->data);
|
||||
|
||||
FREE(heap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the function for freeing data.
|
||||
* @param heap The heap that will use this function when nodes are
|
||||
* destroyed.
|
||||
* @param free_func The function that will free the key data.
|
||||
* @return @c EINA_TRUE on successful set, @c EINA_FALSE otherwise.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_sheap_free_cb_set(Ecore_Sheap *heap, Ecore_Free_Cb free_func)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("heap", heap, EINA_FALSE);
|
||||
|
||||
heap->free_func = free_func;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert new data into the heap.
|
||||
* @param heap The heap to insert @a data.
|
||||
* @param data The data to add to @a heap.
|
||||
* @return EINA_TRUE on success, NULL on failure. Increases the size of the heap if
|
||||
* it becomes larger than available space.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_sheap_insert(Ecore_Sheap *heap, void *data)
|
||||
{
|
||||
int i;
|
||||
void *temp;
|
||||
int parent;
|
||||
int position;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("heap", heap, EINA_FALSE);
|
||||
|
||||
/*
|
||||
* Increase the size of the allocated data area if there isn't enough
|
||||
* space available to add this data
|
||||
*/
|
||||
if (heap->size >= heap->space)
|
||||
return EINA_FALSE;
|
||||
|
||||
heap->sorted = EINA_FALSE;
|
||||
|
||||
/*
|
||||
* Place the data at the end of the heap initially. Then determine the
|
||||
* parent and position in the array of it's parent.
|
||||
*/
|
||||
heap->data[heap->size] = data;
|
||||
position = heap->size;
|
||||
heap->size++;
|
||||
i = heap->size;
|
||||
parent = PARENT(i) - 1;
|
||||
|
||||
/*
|
||||
* Check the order of the heap to decide where to place the inserted
|
||||
* data. The loop is placed inside the if statement to reduce the
|
||||
* number of branching decisions that must be predicted.
|
||||
*/
|
||||
if (heap->order == ECORE_SORT_MIN)
|
||||
{
|
||||
while ((position > 0) && heap->compare(heap->data[parent],
|
||||
heap->data[position]) > 0)
|
||||
{
|
||||
|
||||
/*
|
||||
* Swap the data with it's parents to move it up in
|
||||
* the heap.
|
||||
*/
|
||||
temp = heap->data[position];
|
||||
heap->data[position] = heap->data[parent];
|
||||
heap->data[parent] = temp;
|
||||
|
||||
/*
|
||||
* Now determine the new position for the next
|
||||
* iteration of the loop, as well as it's parents
|
||||
* position.
|
||||
*/
|
||||
i = PARENT(i);
|
||||
position = i - 1;
|
||||
parent = PARENT(i) - 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((position > 0) && heap->compare(heap->data[parent],
|
||||
heap->data[position]) < 0)
|
||||
{
|
||||
|
||||
/*
|
||||
* Swap the data with it's parents to move it up in
|
||||
* the heap.
|
||||
*/
|
||||
temp = heap->data[position];
|
||||
heap->data[position] = heap->data[PARENT(i) - 1];
|
||||
heap->data[PARENT(i) - 1] = temp;
|
||||
|
||||
/*
|
||||
* Now determine the new position for the next
|
||||
* iteration of the loop, as well as it's parents
|
||||
* position.
|
||||
*/
|
||||
i = PARENT(i);
|
||||
position = i - 1;
|
||||
parent = PARENT(i) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the item at the top of the heap
|
||||
* @param heap The heap to remove the top item
|
||||
* @return The top item of the heap on success, NULL on failure.
|
||||
* @note The extract function maintains the heap properties after the
|
||||
* extract.
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_sheap_extract(Ecore_Sheap *heap)
|
||||
{
|
||||
void *extreme;
|
||||
|
||||
if (heap->size < 1)
|
||||
return NULL;
|
||||
|
||||
heap->sorted = EINA_FALSE;
|
||||
|
||||
extreme = heap->data[0];
|
||||
heap->size--;
|
||||
heap->data[0] = heap->data[heap->size];
|
||||
|
||||
_ecore_sheap_heapify(heap, 1);
|
||||
|
||||
return extreme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine the item at the top of the heap
|
||||
* @param heap The heap to examine the top item
|
||||
* @return The top item of the heap on success, NULL on failure.
|
||||
* @note The function does not alter the heap.
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_sheap_extreme(Ecore_Sheap *heap)
|
||||
{
|
||||
if (heap->size < 1)
|
||||
return NULL;
|
||||
|
||||
return heap->data[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the value of the specified item in the heap
|
||||
* @param heap The heap to search for the item to change
|
||||
* @param item The item in the heap to change
|
||||
* @param newval The new value assigned to the item in the heap
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure.
|
||||
* @note The heap does not free the old data since it must be passed
|
||||
* in, so the caller can perform the free if desired.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_sheap_change(Ecore_Sheap *heap, void *item, void *newval)
|
||||
{
|
||||
int i;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("heap", heap, EINA_FALSE);
|
||||
|
||||
for (i = 0; i < heap->size && heap->compare(heap->data[i], item); i++);
|
||||
|
||||
if (i < heap->size)
|
||||
heap->data[i] = newval;
|
||||
else
|
||||
return EINA_FALSE;
|
||||
|
||||
/*
|
||||
* FIXME: This is not the correct procedure when a change occurs.
|
||||
*/
|
||||
_ecore_sheap_heapify(heap, 1);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the comparison function for the heap
|
||||
* @param heap The heap to change comparison function
|
||||
* @param compare The new function for comparing nodes
|
||||
* @return EINA_TRUE on success, EINA_FALSE on failure.
|
||||
*
|
||||
* The comparison function is changed to @compare and the heap is heapified
|
||||
* by the new comparison.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_sheap_compare_set(Ecore_Sheap *heap, Ecore_Compare_Cb compare)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("heap", heap, EINA_FALSE);
|
||||
|
||||
if (!compare)
|
||||
heap->compare = ecore_direct_compare;
|
||||
else
|
||||
heap->compare = compare;
|
||||
|
||||
_ecore_sheap_update_data(heap);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the order of the heap
|
||||
* @param heap The heap to change the order
|
||||
* @param order The new order of the heap
|
||||
*
|
||||
* Changes the heap order of @heap and re-heapifies the data to this new
|
||||
* order. The default order is a min heap.
|
||||
*/
|
||||
EAPI void
|
||||
ecore_sheap_order_set(Ecore_Sheap *heap, char order)
|
||||
{
|
||||
CHECK_PARAM_POINTER("heap", heap);
|
||||
|
||||
heap->order = order;
|
||||
|
||||
_ecore_sheap_update_data(heap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the data in the heap
|
||||
* @param heap The heap to be sorted
|
||||
*
|
||||
* Sorts the data in the heap into the order that is used for the heap's
|
||||
* data.
|
||||
*/
|
||||
EAPI void
|
||||
ecore_sheap_sort(Ecore_Sheap *heap)
|
||||
{
|
||||
int i = 0;
|
||||
void **new_data;
|
||||
|
||||
CHECK_PARAM_POINTER("heap", heap);
|
||||
|
||||
new_data = (void **)malloc(heap->size * sizeof(void *));
|
||||
|
||||
/*
|
||||
* Extract the heap and insert into the new data array in order.
|
||||
*/
|
||||
while (heap->size > 0)
|
||||
new_data[i++] = ecore_sheap_extract(heap);
|
||||
|
||||
/*
|
||||
* Free the old data array and update the heap with the new data, also
|
||||
* mark as sorted.
|
||||
*/
|
||||
FREE(heap->data);
|
||||
heap->data = new_data;
|
||||
heap->size = i;
|
||||
heap->sorted = EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Access the item at the ith position in the heap
|
||||
* @param heap The heap to access the internal data
|
||||
* @param i The index of the data within the heap
|
||||
* @return The data located at the ith position within @heap on success,
|
||||
* NULL on failure.
|
||||
* @note The data is guaranteed to be in sorted order.
|
||||
*/
|
||||
EAPI inline void *
|
||||
ecore_sheap_item(Ecore_Sheap *heap, int i)
|
||||
{
|
||||
if (i >= heap->size)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Make sure the data is sorted so we return the correct value.
|
||||
*/
|
||||
if (!heap->sorted)
|
||||
ecore_sheap_sort(heap);
|
||||
|
||||
return heap->data[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* Regain the heap properties starting at position i
|
||||
* @param heap The heap to regain heap properties
|
||||
* @param i The position to start heapifying
|
||||
*/
|
||||
static void
|
||||
_ecore_sheap_heapify(Ecore_Sheap *heap, int i)
|
||||
{
|
||||
int extreme;
|
||||
int left = LEFT(i);
|
||||
int right = RIGHT(i);
|
||||
|
||||
if (heap->order == ECORE_SORT_MIN)
|
||||
{
|
||||
if (left <= heap->size && heap->compare(heap->data[left - 1],
|
||||
heap->data[i - 1]) < 0)
|
||||
extreme = left;
|
||||
else
|
||||
extreme = i;
|
||||
|
||||
if (right <= heap->size && heap->compare(heap->data[right - 1],
|
||||
heap->data[extreme - 1]) < 0)
|
||||
extreme = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left <= heap->size && heap->compare(heap->data[left - 1],
|
||||
heap->data[i - 1]) > 0)
|
||||
extreme = left;
|
||||
else
|
||||
extreme = i;
|
||||
|
||||
if (right <= heap->size && heap->compare(heap->data[right - 1],
|
||||
heap->data[extreme - 1]) > 0)
|
||||
extreme = right;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the data needs to be swapped down the heap, recurse on
|
||||
* heapifying it's new placement.
|
||||
*/
|
||||
if (extreme != i)
|
||||
{
|
||||
void *temp;
|
||||
|
||||
temp = heap->data[extreme - 1];
|
||||
heap->data[extreme - 1] = heap->data[i - 1];
|
||||
heap->data[i - 1] = temp;
|
||||
|
||||
_ecore_sheap_heapify(heap, extreme);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_sheap_update_data(Ecore_Sheap *heap)
|
||||
{
|
||||
int i, old_size;
|
||||
void **data;
|
||||
|
||||
/*
|
||||
* Track the old values from the heap
|
||||
*/
|
||||
old_size = heap->size;
|
||||
data = heap->data;
|
||||
|
||||
heap->size = 0;
|
||||
heap->data = malloc(heap->space * sizeof(void *));
|
||||
|
||||
for (i = 0; i < old_size; i++)
|
||||
ecore_sheap_insert(heap, data[i]);
|
||||
|
||||
FREE(data);
|
||||
}
|
|
@ -1,171 +0,0 @@
|
|||
/* Leave the OpenBSD version below so we can track upstream fixes */
|
||||
/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "Ecore_Str.h"
|
||||
|
||||
/**
|
||||
* @param dst the destination
|
||||
* @param src the source
|
||||
* @param siz the size of the destination
|
||||
* @return the length of the source string
|
||||
* @brief copy a c-string
|
||||
*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*
|
||||
* @deprecated use eina_strlcpy() instead.
|
||||
*/
|
||||
size_t
|
||||
ecore_strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
EINA_LOG_ERR("use eina_strlcpy() instead!");
|
||||
return eina_strlcpy(dst, src, siz);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dst the destination
|
||||
* @param src the source
|
||||
* @param siz the size of the destination
|
||||
* @return the length of the source string plus MIN(siz, strlen(initial dst))
|
||||
* @brief append a c-string
|
||||
*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||
* If retval >= siz, truncation occurred.
|
||||
*
|
||||
* @deprecated use eina_strlcat() instead.
|
||||
*/
|
||||
size_t
|
||||
ecore_strlcat(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
EINA_LOG_ERR("use eina_strlcat() instead!");
|
||||
return eina_strlcat(dst, src, siz);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param str the string to work with
|
||||
* @param prefix the prefix to check for
|
||||
* @return true if str has the given prefix
|
||||
* @brief checks if the string has the given prefix
|
||||
*
|
||||
* @deprecated use eina_str_has_prefix() instead.
|
||||
*/
|
||||
int
|
||||
ecore_str_has_prefix(const char *str, const char *prefix)
|
||||
{
|
||||
EINA_LOG_ERR("use eina_str_has_prefix() instead!");
|
||||
return eina_str_has_prefix(str, prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param str the string to work with
|
||||
* @param suffix the suffix to check for
|
||||
* @return true if str has the given suffix
|
||||
* @brief checks if the string has the given suffix
|
||||
*
|
||||
* @deprecated use eina_str_has_suffix() instead.
|
||||
*/
|
||||
int
|
||||
ecore_str_has_suffix(const char *str, const char *suffix)
|
||||
{
|
||||
EINA_LOG_ERR("use eina_str_has_suffix() instead!");
|
||||
return eina_str_has_suffix(str, suffix);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function does the same like ecore_str_has_suffix(), but with a
|
||||
* case insensitive compare.
|
||||
*
|
||||
* @param str the string to work with
|
||||
* @param ext the extension to check for
|
||||
* @return true if str has the given extension
|
||||
* @brief checks if the string has the given extension
|
||||
*
|
||||
* @deprecated use eina_str_has_extension() instead.
|
||||
*/
|
||||
int
|
||||
ecore_str_has_extension(const char *str, const char *ext)
|
||||
{
|
||||
EINA_LOG_ERR("use eina_str_has_extension() instead!");
|
||||
return eina_str_has_extension(str, ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a string into a maximum of max_tokens pieces, using the given
|
||||
* delimiter. If max_tokens is reached, the final string in the returned
|
||||
* string array contains the remainder of string.
|
||||
*
|
||||
* @param str A string to split.
|
||||
* @param delim A string which specifies the places at which to split the
|
||||
* string. The delimiter is not included in any of the
|
||||
* resulting strings, unless max_tokens is reached.
|
||||
* @param max_tokens The maximum number of strings to split string into.
|
||||
* If this is less than 1, the string is split completely.
|
||||
* @return A newly-allocated NULL-terminated array of strings.
|
||||
* To free it: free the first element of the array
|
||||
* and the array itself.
|
||||
*
|
||||
* @deprecated eina_str_split()
|
||||
*/
|
||||
char **
|
||||
ecore_str_split(const char *str, const char *delim, int max_tokens)
|
||||
{
|
||||
EINA_LOG_ERR("use eina_str_split() instead!");
|
||||
return eina_str_split(str, delim, max_tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Join two strings of known length and store the result in @a dst buffer.
|
||||
*
|
||||
* @param dst where to store the result.
|
||||
* @param size byte size of dst, will write at most (size - 1)
|
||||
* characters and then the '\0' (null terminator).
|
||||
* @param sep separator character to use.
|
||||
* @param a first string to use, before @a sep.
|
||||
* @param a_len length of @a a, not including '\0' (strlen()-like)
|
||||
* @param b second string to use, after @a sep.
|
||||
* @param b_len length of @a b, not including '\0' (strlen()-like)
|
||||
*
|
||||
* @return the number of characters printed (not including the
|
||||
* trailing '\0' used to end output to strings). Just like
|
||||
* snprintf(), it will not write more than @a size bytes, thus a
|
||||
* return value of @a size or more means that the output was
|
||||
* truncated.
|
||||
*
|
||||
* @see ecore_str_join() and ecore_str_join_static()
|
||||
*
|
||||
* @deprecated use eina_str_join_len() instead.
|
||||
*/
|
||||
size_t
|
||||
ecore_str_join_len(char *dst, size_t size, char sep, const char *a, size_t a_len, const char *b, size_t b_len)
|
||||
{
|
||||
EINA_LOG_ERR("use eina_str_join_len() instead!");
|
||||
return eina_str_join_len(dst, size, sep, a, a_len, b, b_len);
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "Ecore_Data.h"
|
||||
|
||||
/**
|
||||
* Create a new string buffer
|
||||
*
|
||||
* @deprecated use eina_strbuf_new() instead.
|
||||
*/
|
||||
EAPI Ecore_Strbuf *
|
||||
ecore_strbuf_new(void)
|
||||
{
|
||||
EINA_LOG_ERR("use eina_strbuf_new() instead!");
|
||||
return eina_strbuf_new();
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a string buffer
|
||||
* @param buf the buffer to free
|
||||
*
|
||||
* @deprecated use eina_strbuf_free() instead.
|
||||
*/
|
||||
EAPI void
|
||||
ecore_strbuf_free(Ecore_Strbuf *buf)
|
||||
{
|
||||
eina_strbuf_free(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a string to a buffer, reallocating as necessary.
|
||||
* @param buf the Ecore_Strbuf to append to
|
||||
* @param str the string to append
|
||||
*
|
||||
* @deprecated use eina_strbuf_append() instead.
|
||||
*/
|
||||
EAPI void
|
||||
ecore_strbuf_append(Ecore_Strbuf *buf, const char *str)
|
||||
{
|
||||
eina_strbuf_append(buf, str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a string to a buffer, reallocating as necessary.
|
||||
* @param buf the Ecore_Strbuf to insert
|
||||
* @param str the string to insert
|
||||
* @param pos the position to insert the string
|
||||
*
|
||||
* @deprecated use eina_strbuf_insert() instead.
|
||||
*/
|
||||
EAPI void
|
||||
ecore_strbuf_insert(Ecore_Strbuf *buf, const char *str, size_t pos)
|
||||
{
|
||||
eina_strbuf_insert(buf, str, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a character to a string buffer, reallocating as necessary.
|
||||
* @param buf the Ecore_Strbuf to append to
|
||||
* @param c the char to append
|
||||
*
|
||||
* @deprecated use eina_strbuf_append_char() instead.
|
||||
*/
|
||||
EAPI void
|
||||
ecore_strbuf_append_char(Ecore_Strbuf *buf, char c)
|
||||
{
|
||||
eina_strbuf_append_char(buf, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a pointer to the contents of a string buffer
|
||||
* @param buf the buffer
|
||||
*
|
||||
* This pointer must not be modified, and will no longer be valid if
|
||||
* the Ecore_Strbuf is modified.
|
||||
*
|
||||
* @deprecated use eina_strbuf_string_get() instead.
|
||||
*/
|
||||
EAPI const char *
|
||||
ecore_strbuf_string_get(Ecore_Strbuf *buf)
|
||||
{
|
||||
return eina_strbuf_string_get(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the length of the string buffer content
|
||||
* @param buf the buffer
|
||||
*
|
||||
* @deprecated use eina_strbuf_length_get() instead.
|
||||
*/
|
||||
EAPI size_t
|
||||
ecore_strbuf_length_get(Ecore_Strbuf *buf)
|
||||
{
|
||||
return eina_strbuf_length_get(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the n-th string with an other string.
|
||||
* @param buf the Ecore_Strbuf to work with
|
||||
* @param str the string to replace
|
||||
* @param with the replaceing string
|
||||
* @param n the number of the fitting string
|
||||
*
|
||||
* @return true on success
|
||||
*
|
||||
* @deprecated use eina_strbuf_replace() instead.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_strbuf_replace(Ecore_Strbuf *buf, const char *str, const char *with,
|
||||
unsigned int n)
|
||||
{
|
||||
return eina_strbuf_replace(buf, str, with, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all strings with an other string.
|
||||
* @param buf the Ecore_Strbuf to work with
|
||||
* @param str the string to replace
|
||||
* @param with the replaceing string
|
||||
*
|
||||
* @return how often the string was replaced
|
||||
*
|
||||
* @deprecated use eina_strbuf_replace_all() instead.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_strbuf_replace_all(Ecore_Strbuf *buf, const char *str, const char *with)
|
||||
{
|
||||
return eina_strbuf_replace_all(buf, str, with);
|
||||
}
|
|
@ -1,853 +0,0 @@
|
|||
/*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
#include "Ecore_Data.h"
|
||||
|
||||
/* A macro for determining the highest node at given branch */
|
||||
#define MAX_HEIGHT(node) (node ? MAX(node->max_left, node->max_right) : 0)
|
||||
|
||||
/* Utility functions for searching the tree and returning a node, or its
|
||||
* parent */
|
||||
static Ecore_Tree_Node *tree_node_find(Ecore_Tree * tree, const void *key);
|
||||
static Ecore_Tree_Node *tree_node_find_parent(Ecore_Tree * tree, const void *key);
|
||||
|
||||
/* Balancing functions, keep the tree balanced within a one node height
|
||||
* difference */
|
||||
static int tree_node_balance(Ecore_Tree * Tree, Ecore_Tree_Node * top_node);
|
||||
static int tree_node_rotate_right(Ecore_Tree * tree, Ecore_Tree_Node * top_node);
|
||||
static int tree_node_rotate_left(Ecore_Tree * tree, Ecore_Tree_Node * top_node);
|
||||
|
||||
/* Fucntions for executing a specified function on each node of a tree */
|
||||
static int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func,
|
||||
void *user_data);
|
||||
static int tree_for_each_node_value(Ecore_Tree_Node * node,
|
||||
Ecore_For_Each for_each_func, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Allocate a new tree structure.
|
||||
* @param compare_func: function used to compare the two values
|
||||
* @return Returns NULL if the operation fails, otherwise the new tree
|
||||
*/
|
||||
EAPI Ecore_Tree *
|
||||
ecore_tree_new(Ecore_Compare_Cb compare_func)
|
||||
{
|
||||
Ecore_Tree *new_tree;
|
||||
|
||||
EINA_LOG_ERR("use eina_rbtree instead. See eina's documentation examples.");
|
||||
|
||||
new_tree = ECORE_TREE(malloc(sizeof(Ecore_Tree)));
|
||||
if (!new_tree)
|
||||
return NULL;
|
||||
|
||||
if (!ecore_tree_init(new_tree, compare_func))
|
||||
{
|
||||
IF_FREE(new_tree);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new_tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize a tree structure to some sane initial values
|
||||
* @param new_tree: the new tree structure to be initialized
|
||||
* @param compare_func: the function used to compare node keys
|
||||
* @return Returns EINA_TRUE on successful initialization, EINA_FALSE on an error
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_init(Ecore_Tree *new_tree, Ecore_Compare_Cb compare_func)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("new_tree", new_tree, EINA_FALSE);
|
||||
|
||||
memset(new_tree, 0, sizeof(Ecore_Tree));
|
||||
|
||||
if (!compare_func)
|
||||
new_tree->compare_func = ecore_direct_compare;
|
||||
else
|
||||
new_tree->compare_func = compare_func;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Add a function to be called at node destroy time
|
||||
* @param tree: the tree that will use this function when nodes are destroyed
|
||||
* @param free_func: the function that will be passed the node being freed
|
||||
* @return Returns EINA_TRUE on successful set, EINA_FALSE otherwise.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_free_value_cb_set(Ecore_Tree *tree, Ecore_Free_Cb free_value)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, EINA_FALSE);
|
||||
|
||||
tree->free_value = free_value;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Add a function to be called at node destroy time
|
||||
* @param tree: the tree that will use this function when nodes are destroyed
|
||||
* @param free_key: the function that will be passed the node being freed
|
||||
* @return Returns EINA_TRUE on successful set, EINA_FALSE otherwise.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_free_key_cb_set(Ecore_Tree *tree, Ecore_Free_Cb free_key)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, EINA_FALSE);
|
||||
|
||||
tree->free_key = free_key;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Initialize a new tree node
|
||||
* @return Returns EINA_FALSE if the operation fails, otherwise EINA_TRUE
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_node_init(Ecore_Tree_Node *new_node)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("new_node", new_node, EINA_FALSE);
|
||||
|
||||
new_node->key = NULL;
|
||||
new_node->value = NULL;
|
||||
|
||||
new_node->parent = NULL;
|
||||
new_node->right_child = NULL;
|
||||
new_node->left_child = NULL;
|
||||
|
||||
new_node->max_left = new_node->max_right = 0;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Allocate a new tree node
|
||||
* @return Returns NULL if the operation fails, otherwise the new node.
|
||||
*/
|
||||
EAPI Ecore_Tree_Node *
|
||||
ecore_tree_node_new()
|
||||
{
|
||||
Ecore_Tree_Node *new_node;
|
||||
|
||||
new_node = ECORE_TREE_NODE(malloc(sizeof(Ecore_Tree_Node)));
|
||||
if (!new_node)
|
||||
return NULL;
|
||||
|
||||
if (!ecore_tree_node_init(new_node))
|
||||
{
|
||||
IF_FREE(new_node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new_node;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Free a tree node and it's children.
|
||||
* @param node: tree node to be free()'d
|
||||
* @param data_free: callback for destroying the data held in node
|
||||
* @return Returns EINA_TRUE if the node is destroyed successfully, EINA_FALSE if not.
|
||||
*
|
||||
* If you don't want the children free'd then you need to remove the node first.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_node_destroy(Ecore_Tree_Node *node, Ecore_Free_Cb value_free, Ecore_Free_Cb key_free)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, EINA_FALSE);
|
||||
|
||||
if (key_free)
|
||||
key_free(node->key);
|
||||
if (value_free)
|
||||
value_free(node->value);
|
||||
|
||||
FREE(node);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Set the value of the node to value
|
||||
* @param node: the node to be set
|
||||
* @param value: the value to set the node to.
|
||||
* @return Returns EINA_TRUE if the node is set successfully, EINA_FALSE if not.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_node_value_set(Ecore_Tree_Node *node, void *value)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, EINA_FALSE);
|
||||
|
||||
node->value = value;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Get the value of the node
|
||||
* @param node: the node that contains the desired value
|
||||
* @return Returns NULL if an error, otherwise the value associated with node
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_tree_node_value_get(Ecore_Tree_Node *node)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, NULL);
|
||||
ret = node->value;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Set the value of the node's key to key
|
||||
* @param node: the node to be set
|
||||
* @param key: the value to set it's key to.
|
||||
* @return Returns EINA_TRUE if the node is set successfully, EINA_FALSE if not.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_node_key_set(Ecore_Tree_Node *node, void *key)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, EINA_FALSE);
|
||||
|
||||
node->key = key;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Get the value of the node's key
|
||||
* @param node: the node that contains the desired key
|
||||
*
|
||||
* @return Returns NULL if an error occurs, otherwise the key is returned
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_tree_node_key_get(Ecore_Tree_Node *node)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, NULL);
|
||||
ret = node->key;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the tree and it's stored data
|
||||
* @param tree: the tree to destroy
|
||||
*
|
||||
* @return Returns EINA_TRUE if tree destroyed successfully, EINA_FALSE if not.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_destroy(Ecore_Tree *tree)
|
||||
{
|
||||
Ecore_Tree_Node *node;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, EINA_FALSE);
|
||||
|
||||
while ((node = tree->tree))
|
||||
{
|
||||
ecore_tree_node_remove(tree, node);
|
||||
ecore_tree_node_destroy(node, tree->free_value, tree->free_key);
|
||||
}
|
||||
|
||||
FREE(tree);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the node corresponding to key
|
||||
* @param tree: the tree to search
|
||||
* @param key: the key to search for in the tree
|
||||
*
|
||||
* @return Returns the node corresponding to the key if found, otherwise NULL.
|
||||
*/
|
||||
EAPI Ecore_Tree_Node *
|
||||
ecore_tree_get_node(Ecore_Tree *tree, const void *key)
|
||||
{
|
||||
Ecore_Tree_Node *ret;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, NULL);
|
||||
|
||||
ret = tree_node_find(tree, key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the value corresponding to key
|
||||
* @param tree: the tree to search
|
||||
* @param key: the key to search for in @a tree
|
||||
* @return Returns the value corresponding to the key if found, otherwise NULL.
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_tree_get(Ecore_Tree *tree, const void *key)
|
||||
{
|
||||
void *ret;
|
||||
Ecore_Tree_Node *node;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, NULL);
|
||||
|
||||
node = tree_node_find(tree, key);
|
||||
ret = (node ? node->value : NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find the closest value greater than or equal to the key.
|
||||
* @param tree The tree to search.
|
||||
* @param key The key to search for in @a tree.
|
||||
* @return NULL if no valid nodes, otherwise the node greater than or
|
||||
* equal to the key
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_tree_closest_larger_get(Ecore_Tree *tree, const void *key)
|
||||
{
|
||||
Ecore_Tree_Node *node;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, NULL);
|
||||
|
||||
node = tree_node_find(tree, key);
|
||||
if (node)
|
||||
return node;
|
||||
|
||||
node = tree_node_find_parent(tree, key);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
if (tree->compare_func(node->key, key) < 0)
|
||||
return NULL;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find the closest value <= key
|
||||
* @param tree the tree to search
|
||||
* @param key the key to search for in tree
|
||||
* @return Returns NULL if no valid nodes, otherwise the node <= key
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_tree_closest_smaller_get(Ecore_Tree *tree, const void *key)
|
||||
{
|
||||
Ecore_Tree_Node *node;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, NULL);
|
||||
|
||||
node = tree_node_find(tree, key);
|
||||
if (node)
|
||||
return node;
|
||||
|
||||
node = tree_node_find_parent(tree, key);
|
||||
if (node)
|
||||
node = node->right_child;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value associated with key to @a value.
|
||||
* @param tree The tree that contains the key/value pair.
|
||||
* @param key The key to identify which node to set a value.
|
||||
* @param value Value to set the found node.
|
||||
* @return EINA_TRUE if successful, EINA_FALSE if not.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_set(Ecore_Tree *tree, void *key, void *value)
|
||||
{
|
||||
Ecore_Tree_Node *node = NULL;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, EINA_FALSE);
|
||||
|
||||
node = tree_node_find(tree, key);
|
||||
if (!node)
|
||||
{
|
||||
node = ecore_tree_node_new();
|
||||
ecore_tree_node_key_set(node, key);
|
||||
if (!ecore_tree_node_add(tree, node))
|
||||
return EINA_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tree->free_key)
|
||||
tree->free_key(key);
|
||||
if (node->value && tree->free_value)
|
||||
tree->free_value(node->value);
|
||||
}
|
||||
|
||||
ecore_tree_node_value_set(node, value);
|
||||
|
||||
for (; node; node = node->parent)
|
||||
tree_node_balance(tree, node);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Place a node in the tree.
|
||||
* @param tree The tree to add @a node.
|
||||
* @param node The node to add to @a tree.
|
||||
* @return EINA_TRUE on a successful add, EINA_FALSE otherwise.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_node_add(Ecore_Tree *tree, Ecore_Tree_Node *node)
|
||||
{
|
||||
Ecore_Tree_Node *travel = NULL;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, EINA_FALSE);
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, EINA_FALSE);
|
||||
|
||||
/* Find where to put this new node. */
|
||||
if (!tree->tree)
|
||||
tree->tree = node;
|
||||
else
|
||||
{
|
||||
travel = tree_node_find_parent(tree, node->key);
|
||||
node->parent = travel;
|
||||
|
||||
/* The node is less than travel */
|
||||
if (tree->compare_func(node->key, travel->key) < 0)
|
||||
{
|
||||
travel->right_child = node;
|
||||
travel->max_left = 1;
|
||||
/* The node is greater than travel */
|
||||
}
|
||||
else
|
||||
{
|
||||
travel->left_child = node;
|
||||
travel->max_right = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the node from the tree.
|
||||
* @param tree The tree to remove @a node from.
|
||||
* @param node The node to remove from @a tree.
|
||||
* @return EINA_TRUE on a successful remove, EINA_FALSE otherwise.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_node_remove(Ecore_Tree *tree, Ecore_Tree_Node *node)
|
||||
{
|
||||
Ecore_Tree_Node *traverse;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, EINA_FALSE);
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, EINA_FALSE);
|
||||
|
||||
/*
|
||||
* Find the nearest value to the balanced one.
|
||||
*/
|
||||
if (node->left_child)
|
||||
{
|
||||
traverse = node->left_child;
|
||||
|
||||
/* Now work our way down right side of the traverse node.
|
||||
* This will give us the node with the next closest value
|
||||
* to the current node. If traverse had no right node, then
|
||||
* this will stop at node's left node. */
|
||||
while (traverse->right_child)
|
||||
{
|
||||
traverse = traverse->right_child;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hook any dropped leaves into the moved nodes spot
|
||||
*/
|
||||
if (traverse->parent)
|
||||
traverse->parent->left_child = traverse->left_child;
|
||||
}
|
||||
else if (node->right_child)
|
||||
{
|
||||
traverse = node->right_child;
|
||||
|
||||
/* Now work our way down left side of the traverse node.
|
||||
* This will give us the node with the next closest value
|
||||
* to the current node. If traverse had no left node, then
|
||||
* this will stop at node's right node. */
|
||||
while (traverse->left_child)
|
||||
{
|
||||
traverse = traverse->left_child;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hook any dropped leaves into the moved nodes spot
|
||||
*/
|
||||
if (traverse->right_child)
|
||||
traverse->right_child->parent = traverse->parent;
|
||||
|
||||
if (traverse->parent)
|
||||
traverse->parent->right_child = traverse->right_child;
|
||||
else
|
||||
tree->tree = traverse->right_child;
|
||||
}
|
||||
else
|
||||
traverse = NULL;
|
||||
|
||||
if (traverse)
|
||||
{
|
||||
|
||||
/*
|
||||
* Ensure that we don't get a recursive reference.
|
||||
*/
|
||||
if (node->right_child && node->right_child != traverse)
|
||||
{
|
||||
node->right_child->parent = traverse;
|
||||
traverse->right_child = node->right_child;
|
||||
}
|
||||
|
||||
if (node->left_child && node->left_child != traverse)
|
||||
{
|
||||
node->left_child->parent = traverse;
|
||||
traverse->left_child = node->left_child;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlink the node to be moved from it's parent.
|
||||
*/
|
||||
if (traverse->parent)
|
||||
{
|
||||
if (traverse->parent->left_child == traverse)
|
||||
traverse->parent->left_child = NULL;
|
||||
else
|
||||
traverse->parent->right_child = NULL;
|
||||
}
|
||||
traverse->parent = node->parent;
|
||||
}
|
||||
|
||||
if (node->parent)
|
||||
{
|
||||
if (node == node->parent->left_child)
|
||||
node->parent->left_child = traverse;
|
||||
else
|
||||
node->parent->right_child = traverse;
|
||||
}
|
||||
|
||||
if (tree->tree == node)
|
||||
tree->tree = traverse;
|
||||
|
||||
node->parent = node->left_child = node->right_child = NULL;
|
||||
|
||||
/*
|
||||
* Rebalance the tree to ensure short search paths.
|
||||
*/
|
||||
while (traverse)
|
||||
{
|
||||
tree_node_balance(tree, traverse);
|
||||
traverse = traverse->parent;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the key from the tree.
|
||||
* @param tree The tree to remove @a key.
|
||||
* @param key The key to remove from @a tree.
|
||||
* @return EINA_TRUE on a successful remove, EINA_FALSE otherwise.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_remove(Ecore_Tree *tree, const void *key)
|
||||
{
|
||||
Ecore_Tree_Node *node;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, EINA_FALSE);
|
||||
if (!tree->tree)
|
||||
return EINA_FALSE;
|
||||
|
||||
/* Find the node we need to remove */
|
||||
node = tree_node_find(tree, key);
|
||||
if (!node)
|
||||
return EINA_FALSE;
|
||||
|
||||
if (!ecore_tree_node_remove(tree, node))
|
||||
return EINA_FALSE;
|
||||
|
||||
ecore_tree_node_destroy(node, tree->free_value, tree->free_key);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test to see if the tree has any nodes
|
||||
* @param tree: the tree to check for nodes
|
||||
* @return Returns EINA_TRUE if no nodes exist, EINA_FALSE otherwise
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_empty_is(Ecore_Tree *tree)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, EINA_FALSE);
|
||||
|
||||
if (!tree->tree)
|
||||
return EINA_TRUE;
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Execute function for each value in the tree
|
||||
* @param tree: the tree to traverse
|
||||
* @param for_each_func: the function to execute for each value in the tree
|
||||
* @param user_data: data passed to each for_each_func call
|
||||
* @return Returns EINA_TRUE on success, EINA_FALSE on failure.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_for_each_node_value(Ecore_Tree *tree, Ecore_For_Each for_each_func, void *user_data)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, EINA_FALSE);
|
||||
CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, EINA_FALSE);
|
||||
|
||||
if (!tree->tree)
|
||||
return EINA_FALSE;
|
||||
|
||||
return tree_for_each_node_value(tree->tree, for_each_func, user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Execute the function for each node in the tree
|
||||
* @param tree: the tree to traverse
|
||||
* @param for_each_func: the function to execute for each node
|
||||
* @param user_data: data passed to each for_each_func call
|
||||
* @return Returns EINA_TRUE on success, EINA_FALSE on failure.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_tree_for_each_node(Ecore_Tree *tree, Ecore_For_Each for_each_func, void *user_data)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, EINA_FALSE);
|
||||
CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, EINA_FALSE);
|
||||
|
||||
if (!tree->tree)
|
||||
return EINA_FALSE;
|
||||
|
||||
return tree_for_each_node(tree->tree, for_each_func, user_data);
|
||||
}
|
||||
|
||||
/* Find the parent for the key */
|
||||
static Ecore_Tree_Node *
|
||||
tree_node_find_parent(Ecore_Tree *tree, const void *key)
|
||||
{
|
||||
Ecore_Tree_Node *parent, *travel;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, NULL);
|
||||
|
||||
parent = tree_node_find(tree, key);
|
||||
if (parent)
|
||||
parent = parent->parent;
|
||||
|
||||
travel = tree->tree;
|
||||
if (!travel)
|
||||
return NULL;
|
||||
|
||||
while (!parent)
|
||||
{
|
||||
if (tree->compare_func(key, travel->key) < 0)
|
||||
{
|
||||
if (!travel->right_child)
|
||||
parent = travel;
|
||||
travel = travel->right_child;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!travel->left_child)
|
||||
parent = travel;
|
||||
travel = travel->left_child;
|
||||
}
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
/* Search for the node with a specified key */
|
||||
static Ecore_Tree_Node *
|
||||
tree_node_find(Ecore_Tree *tree, const void *key)
|
||||
{
|
||||
int compare;
|
||||
Ecore_Tree_Node *node;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("tree", tree, NULL);
|
||||
|
||||
node = tree->tree;
|
||||
while (node && (compare = tree->compare_func(key, node->key)) != 0)
|
||||
{
|
||||
|
||||
if (compare < 0)
|
||||
{
|
||||
if (!node->right_child)
|
||||
return NULL;
|
||||
|
||||
node = node->right_child;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!node->left_child)
|
||||
return NULL;
|
||||
|
||||
node = node->left_child;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Balance the tree with respect to node */
|
||||
static int
|
||||
tree_node_balance(Ecore_Tree *tree, Ecore_Tree_Node *top_node)
|
||||
{
|
||||
int balance;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("top_node", top_node, EINA_FALSE);
|
||||
|
||||
/* Get the height of the left branch. */
|
||||
if (top_node->right_child)
|
||||
top_node->max_left = MAX_HEIGHT(top_node->right_child) + 1;
|
||||
else
|
||||
top_node->max_left = 0;
|
||||
|
||||
/* Get the height of the right branch. */
|
||||
if (top_node->left_child)
|
||||
top_node->max_right = MAX_HEIGHT(top_node->left_child) + 1;
|
||||
else
|
||||
top_node->max_right = 0;
|
||||
|
||||
/* Determine which side has a larger height. */
|
||||
balance = top_node->max_right - top_node->max_left;
|
||||
|
||||
/* if the left side has a height advantage >1 rotate right */
|
||||
if (balance < -1)
|
||||
tree_node_rotate_right(tree, top_node);
|
||||
/* else if the left side has a height advantage >1 rotate left */
|
||||
else if (balance > 1)
|
||||
tree_node_rotate_left(tree, top_node);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/* Tree is overbalanced to the left, so rotate nodes to the right. */
|
||||
static int
|
||||
tree_node_rotate_right(Ecore_Tree *tree, Ecore_Tree_Node *top_node)
|
||||
{
|
||||
Ecore_Tree_Node *temp;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("top_node", top_node, EINA_FALSE);
|
||||
|
||||
/* The left branch's right branch becomes the nodes left branch,
|
||||
* the left branch becomes the top node, and the node becomes the
|
||||
* right branch. */
|
||||
temp = top_node->right_child;
|
||||
top_node->right_child = temp->left_child;
|
||||
temp->left_child = top_node;
|
||||
|
||||
/* Make sure the nodes know who their new parents are and the tree
|
||||
* structure knows the start of the tree. */
|
||||
temp->parent = top_node->parent;
|
||||
if (temp->parent == NULL)
|
||||
tree->tree = temp;
|
||||
else
|
||||
{
|
||||
if (temp->parent->left_child == top_node)
|
||||
temp->parent->left_child = temp;
|
||||
else
|
||||
temp->parent->right_child = temp;
|
||||
}
|
||||
top_node->parent = temp;
|
||||
|
||||
/* And recalculate node heights */
|
||||
tree_node_balance(tree, top_node);
|
||||
tree_node_balance(tree, temp);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/* The tree is overbalanced to the right, so we rotate nodes to the left */
|
||||
static int
|
||||
tree_node_rotate_left(Ecore_Tree *tree, Ecore_Tree_Node *top_node)
|
||||
{
|
||||
Ecore_Tree_Node *temp;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("top_node", top_node, EINA_FALSE);
|
||||
|
||||
/*
|
||||
* The right branch's left branch becomes the nodes right branch,
|
||||
* the right branch becomes the top node, and the node becomes the
|
||||
* left branch.
|
||||
*/
|
||||
temp = top_node->left_child;
|
||||
top_node->left_child = temp->right_child;
|
||||
temp->right_child = top_node;
|
||||
|
||||
/* Make sure the nodes know who their new parents are. */
|
||||
temp->parent = top_node->parent;
|
||||
if (temp->parent == NULL)
|
||||
tree->tree = temp;
|
||||
else
|
||||
{
|
||||
if (temp->parent->left_child == top_node)
|
||||
temp->parent->left_child = temp;
|
||||
else
|
||||
temp->parent->right_child = temp;
|
||||
}
|
||||
top_node->parent = temp;
|
||||
|
||||
/* And recalculate node heights */
|
||||
tree_node_balance(tree, top_node);
|
||||
tree_node_balance(tree, temp);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Execute a function for each node below this point in the tree.
|
||||
* @param node: the highest node in the tree the function will be executed for
|
||||
* @param for_each_func: the function to pass the nodes as data into
|
||||
* @param user_data: data passed to each for_each_func call
|
||||
* @return Returns EINA_FALSE if an error condition occurs, otherwise EINA_TRUE
|
||||
*/
|
||||
static int
|
||||
tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func, void *user_data)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, EINA_FALSE);
|
||||
|
||||
if (node->right_child)
|
||||
tree_for_each_node(node->right_child, for_each_func, user_data);
|
||||
|
||||
if (node->left_child)
|
||||
tree_for_each_node(node->left_child, for_each_func, user_data);
|
||||
|
||||
for_each_func(node, user_data);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Execute a function for each node below this point in the tree.
|
||||
* @param node: the highest node in the tree the function will be executed for
|
||||
* @param for_each_func: the function to pass the nodes values as data
|
||||
* @return Returns EINA_FALSE if an error condition occurs, otherwise EINA_TRUE
|
||||
*/
|
||||
static int
|
||||
tree_for_each_node_value(Ecore_Tree_Node *node, Ecore_For_Each for_each_func, void *user_data)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, EINA_FALSE);
|
||||
|
||||
if (node->right_child)
|
||||
tree_for_each_node_value(node->right_child, for_each_func, user_data);
|
||||
|
||||
if (node->left_child)
|
||||
tree_for_each_node_value(node->left_child, for_each_func, user_data);
|
||||
|
||||
for_each_func(node->value, user_data);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
/* ecore_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.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
# include <Evil.h>
|
||||
#endif
|
||||
|
||||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
#include "Ecore_Data.h"
|
||||
|
||||
EAPI const unsigned int ecore_prime_table[] =
|
||||
{
|
||||
17, 31, 61, 127, 257, 509, 1021,
|
||||
2053, 4093, 8191, 16381, 32771, 65537, 131071, 262147, 524287, 1048573,
|
||||
2097143, 4194301, 8388617, 16777213
|
||||
};
|
||||
|
||||
/**
|
||||
* Just casts the key to an unsigned int
|
||||
* @param key The key to return compute a hash value
|
||||
* @return The key cast to an unsigned int.
|
||||
*/
|
||||
EAPI unsigned int
|
||||
ecore_direct_hash(const void *key)
|
||||
{
|
||||
#ifdef __LP64__
|
||||
unsigned long int val = (unsigned long int)key;
|
||||
|
||||
return (unsigned int) ((val >> 32) ^ val);
|
||||
#else
|
||||
return (unsigned int) key;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the hash value of a string
|
||||
* @param key A pointer to the string to compute a hash value
|
||||
* @return A computed hash value for @a key.
|
||||
*/
|
||||
EAPI unsigned int
|
||||
ecore_str_hash(const void *key)
|
||||
{
|
||||
int i;
|
||||
unsigned int mask;
|
||||
unsigned int value = 0;
|
||||
const char *k = key;
|
||||
|
||||
if (!k)
|
||||
return 0;
|
||||
|
||||
mask = (sizeof(unsigned int) * 8) - 1;
|
||||
|
||||
for (i = 0; k[i] != '\0'; i++)
|
||||
{
|
||||
value ^= ((unsigned int) k[i] << ((i * 5) & mask));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a direct comparison of two keys' values
|
||||
* @param key1 The first key to compare
|
||||
* @param key2 The second key to compare
|
||||
* @return A strcmp style value to indicate the larger key
|
||||
*/
|
||||
EAPI int
|
||||
ecore_direct_compare(const void *key1, const void *key2)
|
||||
{
|
||||
unsigned long k1, k2;
|
||||
|
||||
k1 = (unsigned long) key1;
|
||||
k2 = (unsigned long) key2;
|
||||
|
||||
if (k1 > k2)
|
||||
return 1;
|
||||
|
||||
if (k1 < k2)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a string comparison of two keys values
|
||||
* @param key1 The first key to compare
|
||||
* @param key2 The second key to compare
|
||||
* @return A strcmp style value to indicate the larger key
|
||||
*/
|
||||
EAPI int
|
||||
ecore_str_compare(const void *key1, const void *key2)
|
||||
{
|
||||
const char *k1, *k2;
|
||||
|
||||
if (!key1 || !key2)
|
||||
return ecore_direct_compare(key1, key2);
|
||||
else if (key1 == key2)
|
||||
return 0;
|
||||
|
||||
k1 = key1;
|
||||
k2 = key2;
|
||||
|
||||
return strcmp(k1, k2);
|
||||
}
|
Loading…
Reference in New Issue